// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories LAMMPS development team: developers@lammps.org Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains es certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include "npair_half_size_multi_newtoff.h" #include "atom.h" #include "atom_vec.h" #include "domain.h" #include "error.h" #include "molecule.h" #include "my_page.h" #include "neighbor.h" #include "neigh_list.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ NPairHalfSizeMultiNewtoff::NPairHalfSizeMultiNewtoff(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- size particles binned neighbor list construction with partial Newton's 3rd law multi stencil is icollection-jcollection dependent each owned atom i checks own bin and other bins in stencil pair stored once if i,j are both owned and i < j pair stored by me if j is ghost (also stored by proc owning j) ------------------------------------------------------------------------- */ void NPairHalfSizeMultiNewtoff::build(NeighList *list) { int i,j,jh,k,n,itype,jtype,icollection,jcollection,ibin,jbin,ns; int which,imol,iatom,moltemplate; tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; double radi,radsum,cutdistsq; int *neighptr,*s; int js; int *collection = neighbor->collection; double **x = atom->x; double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; tagint *tag = atom->tag; tagint *molecule = atom->molecule; tagint **special = atom->special; int **nspecial = atom->nspecial; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; int *molindex = atom->molindex; int *molatom = atom->molatom; Molecule **onemols = atom->avec->onemols; if (molecular == Atom::TEMPLATE) moltemplate = 1; else moltemplate = 0; int history = list->history; int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; int mask_history = 1 << HISTBITS; int inum = 0; ipage->reset(); for (i = 0; i < nlocal; i++) { n = 0; neighptr = ipage->vget(); itype = type[i]; icollection = collection[i]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; radi = radius[i]; if (moltemplate) { imol = molindex[i]; iatom = molatom[i]; tagprev = tag[i] - iatom - 1; } ibin = atom2bin[i]; // loop through stencils for all collections for (jcollection = 0; jcollection < ncollections; jcollection++) { // if same collection use own bin if (icollection == jcollection) jbin = ibin; else jbin = coord2bin(x[i], jcollection); // loop over all atoms in other bins in stencil including self // only store pair if i < j // stores own/own pairs only once // stores own/ghost pairs on both procs // use full stencil for all collection combinations s = stencil_multi[icollection][jcollection]; ns = nstencil_multi[icollection][jcollection]; for (k = 0; k < ns; k++) { js = binhead_multi[jcollection][jbin + s[k]]; for (j = js; j >= 0; j = bins[j]) { if (j <= i) continue; jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; radsum = radi + radius[j]; cutdistsq = (radsum+skin) * (radsum+skin); if (rsq <= cutdistsq) { jh = j; if (history && rsq < radsum*radsum) jh = jh ^ mask_history; if (molecular != Atom::ATOMIC) { if (!moltemplate) which = find_special(special[i],nspecial[i],tag[j]); else if (imol >= 0) which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom], tag[j]-tagprev); else which = 0; if (which == 0) neighptr[n++] = jh; else if (domain->minimum_image_check(delx,dely,delz)) neighptr[n++] = jh; else if (which > 0) neighptr[n++] = jh ^ (which << SBBITS); } else neighptr[n++] = jh; } } } } ilist[inum++] = i; firstneigh[i] = neighptr; numneigh[i] = n; ipage->vgot(n); if (ipage->status()) error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); } list->inum = inum; }