Beispiel #1
0
void InitSim(char const *fileName)
{
  std::cout << "Loading file \"" << fileName << "\"..." << std::endl;
  std::ifstream file(fileName, std::ios::binary);
  if(!file) {
    std::cerr << "Error opening file. Aborting." << std::endl;
    exit(1);
  }

  //Always use single precision float variables b/c file format uses single precision
  float restParticlesPerMeter_le;
  int numParticles_le;
  file.read((char *)&restParticlesPerMeter_le, FILE_SIZE_FLOAT);
  file.read((char *)&numParticles_le, FILE_SIZE_INT);
  if(!isLittleEndian()) {
    restParticlesPerMeter = bswap_float(restParticlesPerMeter_le);
    numParticles          = bswap_int32(numParticles_le);
  } else {
    restParticlesPerMeter = restParticlesPerMeter_le;
    numParticles          = numParticles_le;
  }
  cellpool_init(&pool, numParticles);

  h = kernelRadiusMultiplier / restParticlesPerMeter;
  hSq = h*h;

#ifndef ENABLE_DOUBLE_PRECISION
  fptype coeff1 = 315.0 / (64.0*pi*powf(h,9.0));
  fptype coeff2 = 15.0 / (pi*powf(h,6.0));
  fptype coeff3 = 45.0 / (pi*powf(h,6.0));
#else
  fptype coeff1 = 315.0 / (64.0*pi*pow(h,9.0));
  fptype coeff2 = 15.0 / (pi*pow(h,6.0));
  fptype coeff3 = 45.0 / (pi*pow(h,6.0));
#endif //ENABLE_DOUBLE_PRECISION
  fptype particleMass = 0.5*doubleRestDensity / (restParticlesPerMeter*restParticlesPerMeter*restParticlesPerMeter);
  densityCoeff = particleMass * coeff1;
  pressureCoeff = 3.0*coeff2 * 0.50*stiffnessPressure * particleMass;
  viscosityCoeff = viscosity * coeff3 * particleMass;

  Vec3 range = domainMax - domainMin;
  nx = (int)(range.x / h);
  ny = (int)(range.y / h);
  nz = (int)(range.z / h);
  assert(nx >= 1 && ny >= 1 && nz >= 1);
  numCells = nx*ny*nz;
  std::cout << "Number of cells: " << numCells << std::endl;
  delta.x = range.x / nx;
  delta.y = range.y / ny;
  delta.z = range.z / nz;
  assert(delta.x >= h && delta.y >= h && delta.z >= h);

  //make sure Cell structure is multiple of estiamted cache line size
  assert(sizeof(Cell) % CACHELINE_SIZE == 0);
  //make sure helper Cell structure is in sync with real Cell structure
#pragma warning( disable : 1684) // warning #1684: conversion from pointer to same-sized integral type (potential portability problem)
  assert(offsetof(struct Cell_aux, padding) == offsetof(struct Cell, padding));

#if defined(WIN32)
  cells = (struct Cell*)_aligned_malloc(sizeof(struct Cell) * numCells, CACHELINE_SIZE);
  cells2 = (struct Cell*)_aligned_malloc(sizeof(struct Cell) * numCells, CACHELINE_SIZE);
  cnumPars = (int*)_aligned_malloc(sizeof(int) * numCells, CACHELINE_SIZE);
  cnumPars2 = (int*)_aligned_malloc(sizeof(int) * numCells, CACHELINE_SIZE);
  last_cells = (struct Cell **)_aligned_malloc(sizeof(struct Cell *) * numCells, CACHELINE_SIZE);
  assert((cells!=NULL) && (cells2!=NULL) && (cnumPars!=NULL) && (cnumPars2!=NULL) && (last_cells!=NULL)); 
#else
  int rv0 = posix_memalign((void **)(&cells), CACHELINE_SIZE, sizeof(struct Cell) * numCells);
  int rv1 = posix_memalign((void **)(&cells2), CACHELINE_SIZE, sizeof(struct Cell) * numCells);
  int rv2 = posix_memalign((void **)(&cnumPars), CACHELINE_SIZE, sizeof(int) * numCells);
  int rv3 = posix_memalign((void **)(&cnumPars2), CACHELINE_SIZE, sizeof(int) * numCells);
  int rv4 = posix_memalign((void **)(&last_cells), CACHELINE_SIZE, sizeof(struct Cell *) * numCells);
  assert((rv0==0) && (rv1==0) && (rv2==0) && (rv3==0) && (rv4==0));
#endif

  // because cells and cells2 are not allocated via new
  // we construct them here
  for(int i=0; i<numCells; ++i) {
	  new (&cells[i]) Cell;
	  new (&cells2[i]) Cell;
  }

  memset(cnumPars, 0, numCells*sizeof(int));

  //Always use single precision float variables b/c file format uses single precision
  float px, py, pz, hvx, hvy, hvz, vx, vy, vz;
  for(int i = 0; i < numParticles; ++i) {
    file.read((char *)&px, FILE_SIZE_FLOAT);
    file.read((char *)&py, FILE_SIZE_FLOAT);
    file.read((char *)&pz, FILE_SIZE_FLOAT);
    file.read((char *)&hvx, FILE_SIZE_FLOAT);
    file.read((char *)&hvy, FILE_SIZE_FLOAT);
    file.read((char *)&hvz, FILE_SIZE_FLOAT);
    file.read((char *)&vx, FILE_SIZE_FLOAT);
    file.read((char *)&vy, FILE_SIZE_FLOAT);
    file.read((char *)&vz, FILE_SIZE_FLOAT);
    if(!isLittleEndian()) {
      px  = bswap_float(px);
      py  = bswap_float(py);
      pz  = bswap_float(pz);
      hvx = bswap_float(hvx);
      hvy = bswap_float(hvy);
      hvz = bswap_float(hvz);
      vx  = bswap_float(vx);
      vy  = bswap_float(vy);
      vz  = bswap_float(vz);
    }
    int ci = (int)(((fptype)px - domainMin.x) / delta.x);
    int cj = (int)(((fptype)py - domainMin.y) / delta.y);
    int ck = (int)(((fptype)pz - domainMin.z) / delta.z);

    if(ci < 0) ci = 0; else if(ci >= nx) ci = nx-1;
    if(cj < 0) cj = 0; else if(cj >= ny) cj = ny-1;
    if(ck < 0) ck = 0; else if(ck >= nz) ck = nz-1;

    int index = (ck*ny + cj)*nx + ci;
    Cell *cell = &cells[index];

    //go to last cell structure in list
    int np = cnumPars[index];
    while(np > PARTICLES_PER_CELL) {
      cell = cell->next;
      np = np - PARTICLES_PER_CELL;
    }
    //add another cell structure if everything full
    if( (np % PARTICLES_PER_CELL == 0) && (cnumPars[index] != 0) ) {
      cell->next = cellpool_getcell(&pool);
      cell = cell->next;
      np = np - PARTICLES_PER_CELL; // np = 0;
    }

    //add particle to cell
    cell->p[np].x = px;
    cell->p[np].y = py;
    cell->p[np].z = pz;
    cell->hv[np].x = hvx;
    cell->hv[np].y = hvy;
    cell->hv[np].z = hvz;
    cell->v[np].x = vx;
    cell->v[np].y = vy;
    cell->v[np].z = vz;
#ifdef ENABLE_VISUALIZATION
	vMin.x = std::min(vMin.x, cell->v[np].x);
	vMax.x = std::max(vMax.x, cell->v[np].x);
	vMin.y = std::min(vMin.y, cell->v[np].y);
	vMax.y = std::max(vMax.y, cell->v[np].y);
	vMin.z = std::min(vMin.z, cell->v[np].z);
	vMax.z = std::max(vMax.z, cell->v[np].z);
#endif
    ++cnumPars[index];
  }

  std::cout << "Number of particles: " << numParticles << std::endl;
}
Beispiel #2
0
extern void import_cnfg_ildg(char *in)
{
   int my_rank,np[4],n,ie,tag,status,prec=0;
   int i,l,ix,iy,iz,it,ixx;
   n_uint64_t read_bytes,nbytes=0;
   double plaq1,eps;
   MPI_Status stat;
   LimeReader *reader=NULL;
   FILE *fin;
   char lime_type_target[100]="ildg-binary-data";
   char *lime_type;
   MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);

   /* allocate IO-buffers */
   if (ubuf==NULL)
      alloc_ubuf_ildg(my_rank);

   error(pud[VOLUME/2][0]==NULL,1,"import_cnfg [archive_ildg.c]",
         "Double-precision gauge field is not allocated");
   ie=check_machine();   

   if (my_rank==0)
   {
     fin=fopen(in,"rb");
     error_root(fin==NULL,1,"import_cnfg  [archive_ildg.c]",
               	"Unable to open input file");
     reader=limeCreateReader(fin);
     error( reader == (LimeReader *)NULL ,1,"import_cnfg [archive_ildg.c]",
    		"Unable to open LimeReader");
     nbytes = (n_uint64_t)0;

     /* set the file-pointer to the beginning of the "ildg-binary-data" tag
      * in the LIME file */
     while( (status = limeReaderNextRecord(reader)) != LIME_EOF ){
       nbytes    = limeReaderBytes(reader);
       lime_type = limeReaderType(reader);
       error((status!=LIME_SUCCESS),1,"import_cnfg [archive_ildg.c]",
       	     "limeReaderNextRecord returned status %d and LIME_SUCCESS %d\n",
       status,LIME_SUCCESS);
       if (strcmp(lime_type,lime_type_target) != 0) continue;
        break;
     }
     /* Decide whether the gauge file is stored in single or
      * double precision format */
     if ((int)nbytes==8*VOLUME*NPROC*3*3*4*2){
       prec=8; 
       message("ILDG-file contains double precision gauge field\n");
     }
     else if ((int)nbytes==4*VOLUME*NPROC*3*3*4*2){
       prec=4; 
       message("ILDG-file contains single precision gauge field\n");
     }
     else
     error(1!=0,1,"import_cnfg [archive_ildg]",
		"Lattice geometry doesn't match size of gauge field %d %d\n");
   }
   /* Now read the gauge file in steps of 4 SU(3) matrices */
   for (it=0;it<N0;it++){
    for (iz=0;iz<N3;iz++){
     for (iy=0;iy<N2;iy++){
      for (ix=0;ix<N1;ix++){
	if(my_rank==0){
         if(prec==8){
          read_bytes = (n_uint64_t)(4*18*sizeof(double));
          status = limeReaderReadData((double *)vbuf,&read_bytes, reader);
	  bswap_double(4*18,(double *)(vbuf));/* ILDG always big endian */
         }
	 else if(prec==4){
          read_bytes = (n_uint64_t)(4*18*sizeof(float));
          status = limeReaderReadData((void *)vbuf_s,&read_bytes, reader);
	  bswap_float(4*18,(float *)(vbuf_s)); /* ILDG always big endian */
         for (i=0;i<4;i++)
	  su3_copy_singletodouble((vbuf_s+i),(vbuf+i));
         }
	}
        np[0]=it;
        np[1]=ix;
        np[2]=iy;
        np[3]=iz;
        n=ipr_global(np);
        MPI_Barrier(MPI_COMM_WORLD);
            if (n>0)
            {
               tag=mpi_tag();

               if (my_rank==0)
                  MPI_Send((double*)(vbuf),4*18,MPI_DOUBLE,n,tag,
                           MPI_COMM_WORLD);

               if (my_rank==n)
                  MPI_Recv((double*)(ubuf),4*18,MPI_DOUBLE,0,tag,
                           MPI_COMM_WORLD,&stat);
            }
            else if (my_rank==0)
               for (l=0;l<(4);l++)
                  ubuf[l]=vbuf[l];

            ixx = ((iy%L2)*L3 + (ix%L1)*L3*L2 + (it%L0)*L1*L2*L3);
            if (my_rank==n)
               set_links_ildg(ixx,iz);
      }
     }
    }
   }

   plaq1=plaq_sum_dble()/(double)(6*NPROC*VOLUME);
   message("Plaquette   %f\n",plaq1);
   message("Plaquette/3 %f\n",plaq1/3);
   message("Please check consistency of average plaquette by hand\n");
   eps=sqrt((double)(6*NPROC*VOLUME))*DBL_EPSILON;
}
Beispiel #3
0
void SaveFile(char const *fileName)
{
  std::cout << "Saving file \"" << fileName << "\"..." << std::endl;

  std::ofstream file(fileName, std::ios::binary);
  assert(file);

  //Always use single precision float variables b/c file format uses single precision
  if(!isLittleEndian()) {
    float restParticlesPerMeter_le;
    int   numParticles_le;

    restParticlesPerMeter_le = bswap_float((float)restParticlesPerMeter);
    numParticles_le      = bswap_int32(numParticles);
    file.write((char *)&restParticlesPerMeter_le, FILE_SIZE_FLOAT);
    file.write((char *)&numParticles_le,      FILE_SIZE_INT);
  } else {
    file.write((char *)&restParticlesPerMeter, FILE_SIZE_FLOAT);
    file.write((char *)&numParticles, FILE_SIZE_INT);
  }

  int count = 0;
  for(int i = 0; i < numCells; ++i) {
    Cell *cell = &cells[i];
    int np = cnumPars[i];
    for(int j = 0; j < np; ++j) {
      //Always use single precision float variables b/c file format uses single precision
      float px, py, pz, hvx, hvy, hvz, vx,vy, vz;
      if(!isLittleEndian()) {
        px  = bswap_float((float)(cell->p[j % PARTICLES_PER_CELL].x));
        py  = bswap_float((float)(cell->p[j % PARTICLES_PER_CELL].y));
        pz  = bswap_float((float)(cell->p[j % PARTICLES_PER_CELL].z));
        hvx = bswap_float((float)(cell->hv[j % PARTICLES_PER_CELL].x));
        hvy = bswap_float((float)(cell->hv[j % PARTICLES_PER_CELL].y));
        hvz = bswap_float((float)(cell->hv[j % PARTICLES_PER_CELL].z));
        vx  = bswap_float((float)(cell->v[j % PARTICLES_PER_CELL].x));
        vy  = bswap_float((float)(cell->v[j % PARTICLES_PER_CELL].y));
        vz  = bswap_float((float)(cell->v[j % PARTICLES_PER_CELL].z));
      } else {
        px  = (float)(cell->p[j % PARTICLES_PER_CELL].x);
        py  = (float)(cell->p[j % PARTICLES_PER_CELL].y);
        pz  = (float)(cell->p[j % PARTICLES_PER_CELL].z);
        hvx = (float)(cell->hv[j % PARTICLES_PER_CELL].x);
        hvy = (float)(cell->hv[j % PARTICLES_PER_CELL].y);
        hvz = (float)(cell->hv[j % PARTICLES_PER_CELL].z);
        vx  = (float)(cell->v[j % PARTICLES_PER_CELL].x);
        vy  = (float)(cell->v[j % PARTICLES_PER_CELL].y);
        vz  = (float)(cell->v[j % PARTICLES_PER_CELL].z);
      }
      file.write((char *)&px,  FILE_SIZE_FLOAT);
      file.write((char *)&py,  FILE_SIZE_FLOAT);
      file.write((char *)&pz,  FILE_SIZE_FLOAT);
      file.write((char *)&hvx, FILE_SIZE_FLOAT);
      file.write((char *)&hvy, FILE_SIZE_FLOAT);
      file.write((char *)&hvz, FILE_SIZE_FLOAT);
      file.write((char *)&vx,  FILE_SIZE_FLOAT);
      file.write((char *)&vy,  FILE_SIZE_FLOAT);
      file.write((char *)&vz,  FILE_SIZE_FLOAT);
      ++count;

      //move pointer to next cell in list if end of array is reached
      if(j % PARTICLES_PER_CELL == PARTICLES_PER_CELL-1) {
        cell = cell->next;
      }
    }
  }
  assert(count == numParticles);
}
Beispiel #4
0
void ReadFile(char const *fileName, fluid_t *f)
{
  assert(fileName);
  assert(f);

  std::ifstream file(fileName, std::ios::binary);
  if(!file) {
    std::cerr << "Error opening file. Aborting." << std::endl;
    exit(1);
  }

  //Always use single precision float variables b/c file format uses single precision
  float restParticlesPerMeter_le;
  int numParticles_le;
  file.read((char *)&restParticlesPerMeter_le, FILE_SIZE_FLOAT);
  file.read((char *)&numParticles_le, FILE_SIZE_INT);
  if(!isLittleEndian()) {
    f->restParticlesPerMeter = bswap_float(restParticlesPerMeter_le);
    f->numParticles          = bswap_int32(numParticles_le);
  } else {
    f->restParticlesPerMeter = restParticlesPerMeter_le;
    f->numParticles          = numParticles_le;
  }
#if defined(SPARC_SOLARIS)
  f->bbox.min.x = MAXFLOAT;
  f->bbox.min.y = MAXFLOAT;
  f->bbox.min.z = MAXFLOAT;
  f->bbox.max.x = -MAXFLOAT;
  f->bbox.max.y = -MAXFLOAT;
  f->bbox.max.z = -MAXFLOAT;
#else
  f->bbox.min.x = INFINITY;
  f->bbox.min.y = INFINITY;
  f->bbox.min.z = INFINITY;
  f->bbox.max.x = -INFINITY;
  f->bbox.max.y = -INFINITY;
  f->bbox.max.z = -INFINITY;
#endif
  malloc_fluid(f, f->numParticles);

  //Always use single precision float variables b/c file format uses single precision
  float px, py, pz, hvx, hvy, hvz, vx, vy, vz;
  for(int i = 0; i < f->numParticles; ++i)
  {
    file.read((char *)&px, FILE_SIZE_FLOAT);
    file.read((char *)&py, FILE_SIZE_FLOAT);
    file.read((char *)&pz, FILE_SIZE_FLOAT);
    file.read((char *)&hvx, FILE_SIZE_FLOAT);
    file.read((char *)&hvy, FILE_SIZE_FLOAT);
    file.read((char *)&hvz, FILE_SIZE_FLOAT);
    file.read((char *)&vx, FILE_SIZE_FLOAT);
    file.read((char *)&vy, FILE_SIZE_FLOAT);
    file.read((char *)&vz, FILE_SIZE_FLOAT);
    if(!isLittleEndian()) {
      px  = bswap_float(px);
      py  = bswap_float(py);
      pz  = bswap_float(pz);
      hvx = bswap_float(hvx);
      hvy = bswap_float(hvy);
      hvz = bswap_float(hvz);
      vx  = bswap_float(vx);
      vy  = bswap_float(vy);
      vz  = bswap_float(vz);
    }

    //add particle to fluid structure
    f->p[i].x = px;
    f->p[i].y = py;
    f->p[i].z = pz;
    f->hv[i].x = hvx;
    f->hv[i].y = hvy;
    f->hv[i].z = hvz;
    f->v[i].x = vx;
    f->v[i].y = vy;
    f->v[i].z = vz;

    //update bounding box
    if(px < f->bbox.min.x) f->bbox.min.x = px;
    if(py < f->bbox.min.y) f->bbox.min.y = py;
    if(pz < f->bbox.min.z) f->bbox.min.z = pz;
    if(px > f->bbox.max.x) f->bbox.max.x = px;
    if(py > f->bbox.max.y) f->bbox.max.y = py;
    if(pz > f->bbox.max.z) f->bbox.max.z = pz;
  }
}