/// Creates atom positions on a face centered cubic (FCC) lattice with /// nx * ny * nz unit cells and lattice constant lat. /// Set momenta to zero. void createFccLattice(int nx, int ny, int nz, real_t lat, SimFlat* s) { const real_t* localMin = s->domain->localMin; // alias const real_t* localMax = s->domain->localMax; // alias int nb = 4; // number of atoms in the basis real3 basis[4] = { {0.25, 0.25, 0.25}, {0.25, 0.75, 0.75}, {0.75, 0.25, 0.75}, {0.75, 0.75, 0.25} }; // create and place atoms int begin[3]; int end[3]; for (int ii=0; ii<3; ++ii) { begin[ii] = floor(localMin[ii]/lat); end[ii] = ceil (localMax[ii]/lat); } real_t px,py,pz; px=py=pz=0.0; for (int ix=begin[0]; ix<end[0]; ++ix) for (int iy=begin[1]; iy<end[1]; ++iy) for (int iz=begin[2]; iz<end[2]; ++iz) for (int ib=0; ib<nb; ++ib) { real_t rx = (ix+basis[ib][0]) * lat; real_t ry = (iy+basis[ib][1]) * lat; real_t rz = (iz+basis[ib][2]) * lat; if (rx < localMin[0] || rx >= localMax[0]) continue; if (ry < localMin[1] || ry >= localMax[1]) continue; if (rz < localMin[2] || rz >= localMax[2]) continue; int id = ib+nb*(iz+nz*(iy+ny*(ix))); putAtomInBox(s->boxes, s->atoms, id, 0, rx, ry, rz, px, py, pz); } // set total atoms in simulation startTimer(commReduceTimer); addIntParallel(&s->atoms->nLocal, &s->atoms->nGlobal, 1); stopTimer(commReduceTimer); assert(s->atoms->nGlobal == nb*nx*ny*nz); }
/// The unloadBuffer function for a halo exchange of atom data. /// Iterates the receive buffer and places each atom that was received /// into the link cell that corresponds to the atom coordinate. Note /// that this naturally accomplishes transfer of ownership of atoms that /// have moved from one spatial domain to another. Atoms with /// coordinates in local link cells automatically become local /// particles. Atoms that are owned by other ranks are automatically /// placed in halo kink cells. /// \see HaloExchangeSt::unloadBuffer for an explanation of the /// unloadBuffer parameters. void unloadAtomsBuffer(void* vparms, void* data, int face, int bufSize, char* charBuf) { AtomExchangeParms* parms = (AtomExchangeParms*) vparms; SimFlat* s = (SimFlat*) data; AtomMsg* buf = (AtomMsg*) charBuf; int nBuf = bufSize / sizeof(AtomMsg); assert(bufSize % sizeof(AtomMsg) == 0); for (int ii=0; ii<nBuf; ++ii) { int gid = buf[ii].gid; int type = buf[ii].type; real_t rx = buf[ii].rx; real_t ry = buf[ii].ry; real_t rz = buf[ii].rz; real_t px = buf[ii].px; real_t py = buf[ii].py; real_t pz = buf[ii].pz; putAtomInBox(s->boxes, s->atoms, gid, type, rx, ry, rz, px, py, pz); } }
/// The unloadBuffer function for a halo exchange of atom data. /// Iterates the receive buffer and places each atom that was received /// into the link cell that corresponds to the atom coordinate. Note /// that this naturally accomplishes transfer of ownership of atoms that /// have moved from one spatial domain to another. Atoms with /// coordinates in local link cells automatically become local /// particles. Atoms that are owned by other ranks are automatically /// placed in halo kink cells. /// \see HaloExchangeSt::unloadBuffer for an explanation of the /// unloadBuffer parameters. /// @param face Not used for this function. The only reason we keep it is to match the unloadForcesBuffer declaration void unloadAtomsBuffer(void* vparms, void* data, int face, int bufSize, char* charBuf) { AtomExchangeParms* parms = (AtomExchangeParms*) vparms; SimFlat* sim = (SimFlat*) data; assert(bufSize % sizeof(AtomMsg) == 0); int nBuf = bufSize / sizeof(AtomMsg); if(sim->method == CPU_NL) { AtomMsg* buf = (AtomMsg*) charBuf; // const int nlUpdateRequired = neighborListUpdateRequired(s->atoms->neighborList,s->boxes,s->atoms); const int nlUpdateRequired = neighborListUpdateRequired(sim); for (int ii=0; ii<nBuf; ++ii) { int gid = buf[ii].gid; int type = buf[ii].type; real_t rx = buf[ii].rx; real_t ry = buf[ii].ry; real_t rz = buf[ii].rz; real_t px = buf[ii].px; real_t py = buf[ii].py; real_t pz = buf[ii].pz; if(nlUpdateRequired){ int iOff = putAtomInBox(sim->boxes, sim->atoms, gid, type, rx, ry, rz, px, py, pz); if(iOff >= (MAXATOMS*sim->boxes->nLocalBoxes)) hashTablePut(sim->atomExchange->hashTable, iOff); //remember iOff only for particles which are mapped to haloCells else //putting particle to local sim->atoms->neighborList->updateLinkCellsRequired = 1; }else{ int iOff = hashTableGet(sim->atomExchange->hashTable); updateAtomInBoxAt(sim->boxes, sim->atoms, gid, type, rx, ry, rz, px, py, pz,iOff); } } }else{ unloadAtomsBufferToGpu(charBuf, nBuf, sim, sim->gpu_atoms_buf, sim->boundary_stream); } }