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); }
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; }
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); }
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; } } }
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(); }
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 */ } } }
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); } } }
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; }