/// \details /// This is the first step in returning data structures to a consistent /// state after the atoms move each time step. First we discard all /// atoms in the halo link cells. These are all atoms that are /// currently stored on other ranks and so any information we have about /// them is stale. Next, we move any atoms that have crossed link cell /// boundaries into their new link cells. It is likely that some atoms /// will be moved into halo link cells. Since we have deleted halo /// atoms from other tasks, it is clear that any atoms that are in halo /// cells at the end of this routine have just transitioned from local /// to halo atoms. Such atom must be sent to other tasks by a halo /// exchange to avoid being lost. /// \see redistributeAtoms void updateLinkCells(LinkCell* boxes, Atoms* atoms) { emptyHaloCells(boxes); for (int iBox=0; iBox<boxes->nLocalBoxes; ++iBox) { int iOff = iBox*MAXATOMS; int ii=0; while (ii < boxes->nAtoms[iBox]) { int jBox = getBoxFromCoord(boxes, atoms->r[iOff+ii]); if (jBox != iBox) moveAtom(boxes, atoms, ii, iBox, jBox); else ++ii; } } }
void reBoxAll(simflat_t *s) { int ibox; for(ibox=0; ibox<s->nboxes; ibox++) { int i; int ixold[3]; int ioff; getIxyz3(s, ibox, ixold); i=0; ioff = ibox*MAXATOMS; while(i<s->natoms[ibox]) { int ixnew[3]; int jbox; int k; real3 rnew; memcpy(rnew,s->r[ioff],sizeof(rnew)); for(k=0; k<3; k++) { if(s->r[ioff][k] < 0.0) { ixnew[k] = ixold[k]-1; rnew[k] += s->boxsize[k]; } else if(s->r[ioff][k] >= s->boxsize[k]) { ixnew[k] = ixold[k]+1; rnew[k] -= s->boxsize[k]; } else { ixnew[k] = ixold[k]; } } jbox = getIBoxFromIxyz3NP(s,ixnew); if((jbox<0)||(jbox==ibox)) { /* do nothing if same box or non-periodic boundary */ i++; ioff++; } else { /* move atom to new box */ memcpy(s->r[ioff],rnew,sizeof(rnew)); moveAtom(s,i,ibox,jbox); } } } return; }
static void reBox(simulation_t *s) { extern int getBoxID(simulation_t *s, real_t x, real_t y, real_t z); extern void moveAtom(simulation_t *s, int iId, int iBox, int jBox); int iBox; for(iBox=s->boxes.nboxes-1; iBox>=0; iBox--) { int id; int n; int jBox; domain_t *idm; real_t *x, *y, *z; idm = s->boxes.domains[iBox]; n = idm->nAtoms[0]; x = idm->x; y = idm->y; z = idm->z; id = 0; while ( id < idm->nAtoms[0]) { jBox = getBoxID(s,x[id],y[id],z[id]); if(jBox == iBox) id++; else moveAtom(s,id,iBox,jBox); } } return; }