예제 #1
0
파일: imd_stress.c 프로젝트: CBegau/imd
void read_stress(str255 infilename)

{
  cell *to;
  FILE *infile;
  char buf[512];
  int p,nr,typ;
  double mass;
  vektor pos, sigma, sigma_offdia;
  ivektor cellc;

  infile = fopen(infilename,"r");

  if (NULL==infile) {
    sprintf(error_msg,"Cannot open atoms file %s",infilename);
    error(error_msg);
  }

  natoms=0;
  
  /* Read the input file line by line */
  while(!feof(infile)) {

    buf[0] = (char) NULL;
    fgets(buf,sizeof(buf),infile);
    while ('#'==buf[1]) fgets(buf,sizeof(buf),infile); /* eat comments */

#ifdef TWOD
    p = sscanf(buf,"%lf %lf %lf %lf %lf",
               &pos.x,&pos.y,&sigma.x,&sigma.y,&sigma_offdia.x);
#else
    p = sscanf(buf,"%d %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
               &nr,&typ,&mass,&pos.x,&pos.y,&pos.z,&sigma.x,&sigma.y,&sigma.z,
               &sigma_offdia.x,&sigma_offdia.y,&sigma_offdia.z);
#endif

    if (p>0) {
      /* compute target cell */
      cellc = cell_coord(pos);
      to = PTR_VV(cell_array,cellc,cell_dim);
      /* enlarge it if necessary */
      if (to->n >= to->n_max) alloc_cell(to,to->n_max+CSTEP);
      /* put the data */
      to->nummer[to->n] = nr;
      to->sorte[to->n] = typ;
      to->masse[to->n] = mass;
      to->ort[to->n] = pos;
      to->stress[to->n] = sigma;
      to->stress_offdia[to->n] = sigma_offdia;
      to->n++;
      natoms++;
    }
  }
  fclose(infile);  

}
예제 #2
0
void compute_buffer_size(int dim) {

//---------------------------------------------------------------------
//---------------------------------------------------------------------

      int  c, face_size;

      if (ncells == 1) return;

//---------------------------------------------------------------------
//     compute the actual sizes of the buffers; note that there is 
//     always one cell face that doesn't need buffer space, because it 
//     is at the boundary of the grid
//---------------------------------------------------------------------
      west_size = 0;
      east_size = 0;

      for (c = 1; c <= ncells; c++) {
         face_size = cell_size(2,c) * cell_size(3,c) * dim * 2;
         if (cell_coord(1,c)!=1) west_size = west_size + face_size;
         if (cell_coord(1,c)!=ncells) east_size = east_size + 
              face_size ;
      }

      north_size = 0;
      south_size = 0;
      for (c = 1; c <= ncells; c++) {
         face_size = cell_size(1,c)*cell_size(3,c) * dim * 2;
         if (cell_coord(2,c)!=1) south_size = south_size + face_size;
         if (cell_coord(2,c)!=ncells) north_size = north_size + 
              face_size ;
      }

      top_size = 0;
      bottom_size = 0;
      for (c = 1; c <= ncells; c++) {
         face_size = cell_size(1,c) * cell_size(2,c) * dim * 2;
         if (cell_coord(3,c)!=1) bottom_size = bottom_size + 
              face_size;
         if (cell_coord(3,c)!=ncells) top_size = top_size +
              face_size     ;
      }

      start_send_west   = 1;
      start_send_east   = start_send_west   + west_size;
      start_send_south  = start_send_east   + east_size;
      start_send_north  = start_send_south  + south_size;
      start_send_bottom = start_send_north  + north_size;
      start_send_top    = start_send_bottom + bottom_size;
      start_recv_west   = 1;
      start_recv_east   = start_recv_west   + west_size;
      start_recv_south  = start_recv_east   + east_size;
      start_recv_north  = start_recv_south  + south_size;
      start_recv_bottom = start_recv_north  + north_size;
      start_recv_top    = start_recv_bottom + bottom_size;

      return;
}
예제 #3
0
파일: imd_strain.c 프로젝트: CBegau/imd
void read_displacement(str255 infilename)
{
  FILE *infile;
  char buf[512];
  int p;
  vektor pos;
  vektor u;
  cell *to;
  ivektor cellc;

  infile = fopen(infilename,"r");
  if (NULL==infile) {
    sprintf(error_msg,"Cannot open atoms file %s",infilename);
    error(error_msg);
  }

  natoms=0;
  
  /* Read the input file line by line */
  while (!feof(infile)) {

    buf[0] = (char) NULL;
    fgets(buf,sizeof(buf),infile);
    while ('#'==buf[1]) fgets(buf,sizeof(buf),infile); /* eat comments */

#ifdef TWOD
    p = sscanf(buf,"%lf %lf %lf %lf",&pos.x,&pos.y,&u.x,&u.y);
#else
    p = sscanf(buf,"%lf %lf %lf %lf %lf %lf",
               &pos.x,&pos.y,&pos.z,&u.x,&u.y,&u.z);
#endif

    if (p>0) {
      /* compute target cell */
      cellc = cell_coord(pos);
      to = PTR_VV(cell_array,cellc,cell_dim);
      /* enlarge it if necessary */
      if (to->n >= to->n_max) alloc_cell(to,to->n_max+CSTEP);
      /* put the data */
      to->ort[to->n] = pos;
      to->dsp[to->n] = u;
      to->n++;
      natoms++;
    }
  }
  fclose(infile);  

}
예제 #4
0
void fix_cells(void)
{
  int i,j,k,l,clone;
  cell *p, *q;
  ivektor coord, lcoord;

  /* apply periodic boundary conditions */
  do_boundaries();

  /* for each cell in bulk */
  for (i=cellmin.x; i < cellmax.x; ++i)
    for (j=cellmin.y; j < cellmax.y; ++j)
      for (k=cellmin.z; k < cellmax.z; ++k) {

	p = PTR_3D_V(cell_array, i, j, k, cell_dim);
	/*printf(" cell %d %d %d \n",i,j,k);fflush(stdout);*/
	/* loop over atoms in cell */
	l=0;
	while( l<p->n ) {
          coord = cell_coord( ORT(p,l,X), ORT(p,l,Y), ORT(p,l,Z) );
          q = PTR_3D_VV(cell_array,coord,cell_dim);
          /* if it's in the wrong cell, move it to the right cell */
          if (p != q) {
            MOVE_ATOM(q,p,l); 
#ifdef CLONE
            if (l < p->n-nclones)
              for (clone=1; clone<nclones; clone++)
                MOVE_ATOM(q, p, l+clone);
            else /* we are dealing with the last in the stack */
              for (clone=1; clone<nclones; clone++)
                MOVE_ATOM(q, p, l);
#endif
	  }
          else ++l;
	}
      }
}
예제 #5
0
void fix_cells(void)
{
  int i,j,l,clone;
  cell *p, *q;
  ivektor coord, lcoord, dcpu, to_coord;
  msgbuf *buf;

  empty_mpi_buffers();

  /* apply periodic boundary conditions */
  do_boundaries();

  /* for each cell in bulk */
  for (i=cellmin.x; i < cellmax.x; ++i)
    for (j=cellmin.y; j < cellmax.y; ++j) {

      p = PTR_2D_V(cell_array, i, j, cell_dim);

      /* loop over atoms in cell */
      l=0;
      while( l < p->n ) {

        coord = cell_coord( ORT(p,l,X), ORT(p,l,Y) );
        lcoord = local_cell_coord( coord );
	/* see if atom is in wrong cell */
        if ((lcoord.x == i) && (lcoord.y == j)) {
          l++;
        } else {

          /* Calculate distance on CPU grid */
          to_coord = cpu_coord_v( coord );
          dcpu.x = to_coord.x - my_coord.x;
          dcpu.y = to_coord.y - my_coord.y;

          /* Consider PBC */
          if (pbc_dirs.x == 1) {
            if (cpu_dim.x == 1) dcpu.x = 0; 
            else dcpu.x -= ((int) (dcpu.x / (cpu_dim.x/2)) * cpu_dim.x);
          }
          if (pbc_dirs.y == 1) {
            if (cpu_dim.y == 1) dcpu.y = 0;
            else dcpu.y -= ((int) (dcpu.y / (cpu_dim.y/2)) * cpu_dim.y);
          }

          /* Check, if atom is on my cpu */
          /* If not, copy into send buffer else move to correct cell */
          buf   = NULL;
          if      ((0<dcpu.x) && (cpu_dim.x>1)) {
            buf = &send_buf_west; 
          }
          else if ((0>dcpu.x) && (cpu_dim.x>1)) { 
            buf = &send_buf_east;
          }
          else if (0<dcpu.y) { 
            buf = &send_buf_south;
          }
          else if (0>dcpu.y) { 
            buf = &send_buf_north;
          }
          else { /* atom is on my cpu */
            q = PTR_VV(cell_array,lcoord,cell_dim);
            MOVE_ATOM(q, p, l);
#ifdef CLONE
            if (l < p->n-nclones)
              for (clone=1; clone<nclones; clone++) 
                MOVE_ATOM(q, p, l+clone);
            else /* we are dealing with the last in the stack */
              for (clone=1; clone<nclones; clone++) 
                MOVE_ATOM(q, p, l); 
#endif
          }
          if (buf != NULL) {
            int to_cpu = cpu_coord( coord );
            copy_one_atom( buf, to_cpu, p, l, 1); 
#ifdef CLONE
            if (l < p->n-nclones)
              for (clone=1; clone<nclones; clone++)
                copy_one_atom( buf, to_cpu, p, l+clone, 1);
            else /* we are dealing with the last in the stack */
              for (clone=1; clone<nclones; clone++)
                copy_one_atom( buf, to_cpu, p, l, 1);
#endif
	  }
        }
      }
    }

  /* send atoms to neighbbour CPUs */
  send_atoms();

}
예제 #6
0
void fix_cells(void)
{
  int i,j,k,l,clone,to_cpu, ii;
  minicell *p, *q;
  ivektor coord, lcoord;
  msgbuf *buf;

#ifdef MPI
  empty_mpi_buffers();
#endif

  /* apply periodic boundary conditions */
  do_boundaries();

  /* for each cell in bulk */
  for (i=cellmin.x; i < cellmax.x; ++i)
    for (j=cellmin.y; j < cellmax.y; ++j)
      for (k=cellmin.z; k < cellmax.z; ++k) {

	p = PTR_3D_V(cell_array, i, j, k, cell_dim);
#ifdef LOADBALANCE
	/* Only check content in real cells */
	if (p->lb_cell_type != LB_REAL_CELL) continue;
#endif
	/* loop over atoms in cell */
	l=0;
	while( l<p->n ) {

          coord  = cell_coord( ORT(p,l,X), ORT(p,l,Y), ORT(p,l,Z) );
	  lcoord = local_cell_coord( coord );

#ifdef LOADBALANCE
  	/* Wrap around pbcs if necessary to get the correct index using the loadbalance scheme*/
   if (cpu_dim.x >= 2 && pbc_dirs.x == 1) {
		if (lcoord.x >= global_cell_dim.x) lcoord.x -= global_cell_dim.x;
		if (lcoord.x < 0) lcoord.x += global_cell_dim.x;
	}
	if (cpu_dim.y >= 2 && pbc_dirs.y == 1) {
		if (lcoord.y >= global_cell_dim.y) lcoord.y -= global_cell_dim.y;
		if (lcoord.y < 0) lcoord.y += global_cell_dim.y;
	}
	if (cpu_dim.z >= 2 && pbc_dirs.z == 1) {
		if (lcoord.z >= global_cell_dim.z) lcoord.z -= global_cell_dim.z;
		if (lcoord.z < 0) lcoord.z += global_cell_dim.z;
	}
#endif

 	  /* see if atom is in wrong cell */
	  if ((lcoord.x == i) && (lcoord.y == j) && (lcoord.z == k)) {
            l++;
          } 
          else {

#ifdef LOADBALANCE
        	  if (lcoord.x< 0 || lcoord.x >= cell_dim.x ||
        			  lcoord.y < 0 || lcoord.y >= cell_dim.y ||
        			  lcoord.z < 0 || lcoord.z >= cell_dim.z ||
        			  (PTR_VV(cell_array,lcoord,cell_dim))->lb_cell_type == LB_EMPTY_CELL) {
        		  error("LB: Illegal cell accessed, Atom jumped multiple CPUs");
        	  }
        	  to_cpu = (PTR_VV(cell_array,lcoord,cell_dim))->lb_cpu_affinity;
#else
            to_cpu = cpu_coord(coord);
#endif
            buf    = NULL;

            /* atom is on my cpu */
	    if (to_cpu==myid) {
               q = PTR_VV(cell_array,lcoord,cell_dim);
               MOVE_ATOM(q, p, l);
#ifdef CLONE
               if (l < p->n-nclones)
                 for (clone=1; clone<nclones; clone++) 
                   MOVE_ATOM(q, p, l+clone);
               else /* we are dealing with the last in the stack */
                 for (clone=1; clone<nclones; clone++) 
                   MOVE_ATOM(q, p, l); 
#endif
            }
#ifdef MPI
#ifdef LOADBALANCE
	    else {
			buf = &lb_send_buf[(PTR_VV(cell_array,lcoord,cell_dim))->lb_neighbor_index];
	    }
#else
            /* west */
            else if ((cpu_dim.x>1) && 
               ((to_cpu==nbwest) || (to_cpu==nbnw)  || (to_cpu==nbws) ||
                (to_cpu==nbuw  ) || (to_cpu==nbunw) || (to_cpu==nbuws)||
                (to_cpu==nbdw  ) || (to_cpu==nbdwn) || (to_cpu==nbdsw))) {
              buf = &send_buf_west;
            }
            
            /* east */
            else if ((cpu_dim.x>1) &&
                ((to_cpu==nbeast) || (to_cpu==nbse)  || (to_cpu==nben) ||
                 (to_cpu==nbue  ) || (to_cpu==nbuse) || (to_cpu==nbuen)||
                 (to_cpu==nbde  ) || (to_cpu==nbdes) || (to_cpu==nbdne))) {
              buf = &send_buf_east;
            }
                   
            /* south  */
            else if ((cpu_dim.y>1) &&
                ((to_cpu==nbsouth) || (to_cpu==nbus)  || (to_cpu==nbds))) {
              buf = &send_buf_south;
            }
                   
            /* north  */
            else if ((cpu_dim.y>1) &&
                ((to_cpu==nbnorth) || (to_cpu==nbun)  || (to_cpu==nbdn))) {
              buf = &send_buf_north;
            }
            
            /* down  */
            else if ((cpu_dim.z>1) && (to_cpu==nbdown)) {
              buf = &send_buf_down;
            }
            
            /* up  */
            else if ((cpu_dim.z>1) && (to_cpu==nbup)) {
              buf = &send_buf_up;
            }
            
            else {
#ifdef SHOCK
              /* remove atom from simulation */
              buf = &dump_buf;
              dump_buf.n = 0;
              natoms  -= nclones;
              nactive -= nclones * DIM;
              num_sort [ SORTE(p,l)] -= nclones;
              num_vsort[VSORTE(p,l)] -= nclones;
              warning("Atom jumped multiple CPUs");
#else
              error("Atom jumped multiple CPUs");
#endif
	    }
#endif /* not LOADBALANCE*/

            if (buf != NULL) {
              copy_one_atom( buf, to_cpu, p, l, 1);
#ifdef CLONE
              if (l < p->n-nclones)
                for (clone=1; clone<nclones; clone++)
                  copy_one_atom( buf, to_cpu, p, l+clone, 1);
              else /* we are dealing with the last in the stack */
                for (clone=1; clone<nclones; clone++)
                  copy_one_atom( buf, to_cpu, p, l, 1);
#endif
            }
#endif /* MPI */
	  }
	}
      }
예제 #7
0
파일: imd_qc.c 프로젝트: CBegau/imd
void sortin (int ifeld[])
{
  int typ,sign,icell,i,hv,it,to_cpu;
  ivektor cellc;
  real x,y,z,dx,dy,dz,dist;
  cell *p, *q;
  
  x=tx[0]*ifeld[0]+tx[1]*ifeld[1]+tx[2]*ifeld[2]+
    tx[3]*ifeld[3]+tx[4]*ifeld[4]+tx[5]*ifeld[5]+0.1-2.*gmin.x;
  y=ty[0]*ifeld[0]+ty[1]*ifeld[1]+ty[2]*ifeld[2]+
    ty[3]*ifeld[3]+ty[4]*ifeld[4]+ty[5]*ifeld[5]+0.1-2.*gmin.y;
  z=tz[0]*ifeld[0]+tz[1]*ifeld[1]+tz[2]*ifeld[2]+
    tz[3]*ifeld[3]+tz[4]*ifeld[4]+tz[5]*ifeld[5]+0.1-2.*gmin.z;

  if (x < perp[0] && y < perp[1] && z < perp[2] && 
      x > perm[0] && y > perm[1] && z > perm[2]) 
    {   
      cellc = cell_coord(x, y, z);
#ifdef BUFCELLS
      cellc = local_cell_coord(cellc);
#endif
      p = PTR_3D_VV(cell_array,cellc,cell_dim);
      
      hv=1;

      for (i = 0 ; i < p->n; i++) {
	 dx = x - ORT(p,i,X);
	 dy = y - ORT(p,i,Y);
	 dz = z - ORT(p,i,Z);
	 dist = dx*dx+dy*dy+dz*dz;
	
	 if (dist < 0.01) {
	     hv=0;
	     break;
	 }
      }

      if (hv == 1) {

	      natoms++;
              nactive +=3;

	      input->n = 1;
	      ORT(input,0,X)  = x;
	      ORT(input,0,Y)  = y;
	      ORT(input,0,Z)  = z;
	      NUMMER(input,0) = natoms;
	      typ=ifeld[6]-1;

	      if (FABS(x+2.*gmin.x) < 0.0001 && FABS(y+2.*gmin.y) < 0.0001 && 
		  FABS(z+2.*gmin.z) < 0.0001) typ=0;

	      if (typ == 1) typ=0; 
	      if (typ == 2) typ=1;

	      SORTE (input,0) = typ;
	      VSORTE(input,0) = typ;
              MASSE(input,0)  = masses[typ];
              INSERT_ATOM(p, input, 0);
      }
    }
}
예제 #8
0
int lb_isGeometryChangeValid(){
	int i,j,k,x,y,z;
	int i2,j2,k2;
	int minCell[3];
	int maxCell[3];
	ivektor index, newDomainOffset, newDomainSize;
	cell *cell;

	/*Basic check of the geometry*/
	if (!lb_isGeometryValid(&lb_domain)) return 0;

	/* Further checks are not based on the geometry of the domain, but on the level
	 * of cells directly to identify special cases if the geometry has changed to fast*/
	maxCell[0] = 0; maxCell[1] = 0; maxCell[2] = 0;
	minCell[0] = global_cell_dim.x;  minCell[1] = global_cell_dim.y; minCell[2] = global_cell_dim.z;

	/*Compute the boundaries of the modified domain*/
	for (i=0; i<8; i++){
		index = cell_coord(lb_domain.corners[i].discretizedP.x,
						   lb_domain.corners[i].discretizedP.y,
						   lb_domain.corners[i].discretizedP.z);

		if (index.x<minCell[0]) minCell[0] = index.x;
		if (index.y<minCell[1]) minCell[1] = index.y;
		if (index.z<minCell[2]) minCell[2] = index.z;
		if (index.x>maxCell[0]) maxCell[0] = index.x;
		if (index.y>maxCell[1]) maxCell[1] = index.y;
		if (index.z>maxCell[2]) maxCell[2] = index.z;
	}

	newDomainOffset.x = minCell[0]-1;
	newDomainOffset.y = minCell[1]-1;
	newDomainOffset.z = minCell[2]-1;

	newDomainSize.x = maxCell[0]-minCell[0]+3;
	newDomainSize.y = maxCell[1]-minCell[1]+3;
	newDomainSize.z = maxCell[2]-minCell[2]+3;
	/*Check if the domain size has been modified more than one layer of cells*/
	if (abs(lb_cell_offset.x - newDomainOffset.x) > 1 ||
		abs(lb_cell_offset.y - newDomainOffset.y) > 1 ||
		abs(lb_cell_offset.z - newDomainOffset.z) > 1 )
		return 0;

	if (abs(lb_cell_offset.x-newDomainOffset.x)-abs(cell_dim.x - newDomainSize.x) > 1 ||
		abs(lb_cell_offset.y-newDomainOffset.y)-abs(cell_dim.y - newDomainSize.y) > 1 ||
		abs(lb_cell_offset.z-newDomainOffset.z)-abs(cell_dim.z - newDomainSize.z) > 1 )
			return 0;

	/* Check if an empty cell has been turned into a real cell in the new domain.
	 * Reject geometry if variable communication is disabled*/
	if (lb_balancingType==0){
		for (i = 0; i<newDomainSize.x; i++){
			for (j = 0; j<newDomainSize.y; j++){
				for (k = 0; k<newDomainSize.z; k++){
					x = i+newDomainOffset.x - lb_cell_offset.x;
					y = j+newDomainOffset.y - lb_cell_offset.y;
					z = k+newDomainOffset.z - lb_cell_offset.z;
					cell = lb_accessCell(cell_array,x,y,z, cell_dim);
					if (cell == NULL || cell->lb_cell_type == LB_EMPTY_CELL){
						if (lb_isPointInDomain(lb_getCellCenter(x+lb_cell_offset.x, y+lb_cell_offset.y, z+lb_cell_offset.z),&lb_domain)){
							return 0;
						}
					}
				}
			}
		}
		/* Check if a real cell has been turned into an empty cell in the new domain
		 * This is the case, if not at least the cell or one of its 26 neighbors was inside*/
		for (i = 1; i<cell_dim.x-1; i++){
			for (j = 1; j<cell_dim.y-1; j++){
				for (k = 1; k<cell_dim.z-1; k++){
					x = i+lb_cell_offset.x;
					y = j+lb_cell_offset.y;
					z = k+lb_cell_offset.z;
					cell = lb_accessCell(cell_array,i,j,k, cell_dim);
					if (cell->lb_cell_type == LB_REAL_CELL){
						int oneInside = 0;
						for (i2=-1; i2<=1; i2++){
							for (j2=-1; j2<=1; j2++){
								for (k2=-1; k2<=1; k2++){
									if (oneInside==0 && lb_isPointInDomain(lb_getCellCenter(x+i2, y+j2, z+k2),&lb_domain)) oneInside++;
								}
							}
						}
						if (oneInside==0) return 0;
					}
				}
			}
		}
	}

	/*All test successful, new geometry seems valid*/
	return 1;
}