diff --git a/src/npair_bin.cpp b/src/npair_bin.cpp index 294336a03a..83f8c53ecc 100644 --- a/src/npair_bin.cpp +++ b/src/npair_bin.cpp @@ -27,23 +27,35 @@ using namespace NeighConst; /* ---------------------------------------------------------------------- */ -template -NPairBin::NPairBin(LAMMPS *lmp) : NPair(lmp) {} +template +NPairBin::NPairBin(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - every neighbor pair appears in list of both atoms i and j + Full: + binned neighbor list construction for all neighbors + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + binned neighbor list construction with partial Newton's 3rd law + 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) + Half + Newton: + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor ------------------------------------------------------------------------- */ -template -void NPairBin::build(NeighList *list) +template +void NPairBin::build(NeighList *list) { - int i,j,k,n,itype,jtype,ibin,bin_start,which,imol,iatom,moltemplate; + int i,j,jh,k,n,itype,jtype,ibin,bin_start,which,imol,iatom,moltemplate; tagint tagprev; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radsum,cut,cutsq; int *neighptr; double **x = atom->x; + double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; tagint *tag = atom->tag; @@ -59,6 +71,9 @@ void NPairBin::build(NeighList *list) if (molecular == Atom::TEMPLATE) moltemplate = 1; else moltemplate = 0; + int history = list->history; + int mask_history = 1 << HISTBITS; + int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; @@ -141,22 +156,48 @@ void NPairBin::build(NeighList *list) delx = xtmp - x[j][0]; dely = ytmp - x[j][1]; delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; + rsq = delx * delx + dely * dely + delz * delz; - if (rsq <= cutneighsq[itype][jtype]) { - 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++] = j; - else if (domain->minimum_image_check(delx,dely,delz)) - neighptr[n++] = j; - else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); - } else neighptr[n++] = j; + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (rsq <= cutsq) { + 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; + } + } else { + if (rsq <= cutneighsq[itype][jtype]) { + 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++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } } } } @@ -174,8 +215,12 @@ void NPairBin::build(NeighList *list) } namespace LAMMPS_NS { -template class NPairBin<0,1,0>; -template class NPairBin<1,0,0>; -template class NPairBin<1,1,0>; -template class NPairBin<1,1,1>; +template class NPairBin<0,1,0,0>; +template class NPairBin<1,0,0,0>; +template class NPairBin<1,1,0,0>; +template class NPairBin<1,1,1,0>; +template class NPairBin<0,1,0,1>; +template class NPairBin<1,0,0,1>; +template class NPairBin<1,1,0,1>; +template class NPairBin<1,1,1,1>; } diff --git a/src/npair_bin.h b/src/npair_bin.h index af23880db7..92e3243397 100644 --- a/src/npair_bin.h +++ b/src/npair_bin.h @@ -13,26 +13,47 @@ #ifdef NPAIR_CLASS // clang-format off -typedef NPairBin<0, 1, 0> NPairFullBin; +typedef NPairBin<0, 1, 0, 0> NPairFullBin; NPairStyle(full/bin, NPairFullBin, NP_FULL | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); -typedef NPairBin<1, 0, 0> NPairHalfBinNewtoff; +typedef NPairBin<1, 0, 0, 0> NPairHalfBinNewtoff; NPairStyle(half/bin/newtoff, NPairHalfBinNewtoff, - NP_HALF | NP_BIN | NP_NEWTOFF | NP_ORTHO | NP_TRI); + NP_HALF | NP_BIN | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); -typedef NPairBin<1, 1, 0> NPairHalfBinNewton; +typedef NPairBin<1, 1, 0, 0> NPairHalfBinNewton; NPairStyle(half/bin/newton, NPairHalfBinNewton, NP_HALF | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_ORTHO); -typedef NPairBin<1, 1, 1> NPairHalfBinNewtonTri; +typedef NPairBin<1, 1, 1, 0> NPairHalfBinNewtonTri; NPairStyle(half/bin/newton/tri, NPairHalfBinNewtonTri, - NP_HALF | NP_BIN | NP_NEWTON | NP_TRI); + NP_HALF | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_TRI); + +typedef NPairBin<0, 1, 0, 1> NPairFullSizeBin; +NPairStyle(full/size/bin, + NPairFullSizeBin, + NP_FULL | NP_SIZE | NP_BIN | NP_MOLONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBin<1, 0, 0, 1> NPairHalfSizeBinNewtoff; +NPairStyle(half/size/bin/newtoff, + NPairHalfSizeBinNewtoff, + NP_HALF | NP_SIZE | NP_BIN | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBin<1, 1, 0, 1> NPairHalfSizeBinNewton; +NPairStyle(half/size/bin/newton, + NPairHalfSizeBinNewton, + NP_HALF | NP_SIZE | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairBin<1, 1, 1, 1> NPairHalfSizeBinNewtonTri; +NPairStyle(half/size/bin/newton/tri, + NPairHalfSizeBinNewtonTri, + NP_HALF | NP_SIZE | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_TRI); // clang-format on #else @@ -43,7 +64,7 @@ NPairStyle(half/bin/newton/tri, namespace LAMMPS_NS { -template +template class NPairBin : public NPair { public: NPairBin(class LAMMPS *); diff --git a/src/npair_bin_atomonly.cpp b/src/npair_bin_atomonly.cpp index aa66089fc5..3b15580264 100644 --- a/src/npair_bin_atomonly.cpp +++ b/src/npair_bin_atomonly.cpp @@ -25,28 +25,43 @@ using namespace NeighConst; /* ---------------------------------------------------------------------- */ -template -NPairBinAtomonly::NPairBinAtomonly(LAMMPS *lmp) : NPair(lmp) {} +template +NPairBinAtomonly::NPairBinAtomonly(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - every neighbor pair appears in list of both atoms i and j + Full: + binned neighbor list construction for all neighbors + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + binned neighbor list construction with partial Newton's 3rd law + 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) + Half + Newton: + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor ------------------------------------------------------------------------- */ -template -void NPairBinAtomonly::build(NeighList *list) +template +void NPairBinAtomonly::build(NeighList *list) { - int i,j,k,n,itype,jtype,ibin,bin_start; + int i,j,jh,k,n,itype,jtype,ibin,bin_start; double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radsum,cut,cutsq; int *neighptr; double **x = atom->x; + double *radius = atom->radius; int *type = atom->type; int *mask = atom->mask; tagint *molecule = atom->molecule; int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; + int history = list->history; + int mask_history = 1 << HISTBITS; + int *ilist = list->ilist; int *numneigh = list->numneigh; int **firstneigh = list->firstneigh; @@ -126,7 +141,20 @@ void NPairBinAtomonly::build(NeighList *list) delz = ztmp - x[j][2]; rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (rsq <= cutsq) { + jh = j; + if (history && rsq < radsum * radsum) + jh = jh ^ mask_history; + neighptr[n++] = jh; + } + } else { + if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; + } } } @@ -143,6 +171,12 @@ void NPairBinAtomonly::build(NeighList *list) } namespace LAMMPS_NS { -template class NPairBinAtomonly<0,1,0>; -template class NPairBinAtomonly<1,1,0>; +template class NPairBinAtomonly<0,1,0,0>; +template class NPairBinAtomonly<1,0,0,0>; +template class NPairBinAtomonly<1,1,0,0>; +template class NPairBinAtomonly<1,1,1,0>; +template class NPairBinAtomonly<0,1,0,1>; +template class NPairBinAtomonly<1,0,0,1>; +template class NPairBinAtomonly<1,1,0,1>; +template class NPairBinAtomonly<1,1,1,1>; } diff --git a/src/npair_bin_atomonly.h b/src/npair_bin_atomonly.h index ae64863138..581700af7d 100644 --- a/src/npair_bin_atomonly.h +++ b/src/npair_bin_atomonly.h @@ -13,16 +13,47 @@ #ifdef NPAIR_CLASS // clang-format off -typedef NPairBinAtomonly<0, 1, 0> NPairFullBinAtomonly; +typedef NPairBinAtomonly<0, 1, 0, 0> NPairFullBinAtomonly; NPairStyle(full/bin/atomonly, NPairFullBinAtomonly, NP_FULL | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); -typedef NPairBinAtomonly<1, 1, 0> NPairHalfBinAtomonlyNewton; +typedef NPairBinAtomonly<1, 0, 0, 0> NPairHalfBinAtomonlyNewtoff; +NPairStyle(half/bin/atomonly/newtoff, + NPairHalfBinAtomonlyNewtoff, + NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinAtomonly<1, 1, 0, 0> NPairHalfBinAtomonlyNewton; NPairStyle(half/bin/atomonly/newton, NPairHalfBinAtomonlyNewton, NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairBinAtomonly<1, 1, 1, 0> NPairHalfBinAtomonlyNewtonTri; +NPairStyle(half/bin/atomonly/newton/tri, + NPairHalfBinAtomonlyNewtonTri, + NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_TRI); + +typedef NPairBinAtomonly<0, 1, 0, 1> NPairFullSizeBinAtomonly; +NPairStyle(full/size/bin/atomonly, + NPairFullSizeBinAtomonly, + NP_FULL | NP_SIZE | NP_BIN | NP_ATOMONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinAtomonly<1, 0, 0, 1> NPairHalfSizeBinAtomonlyNewtoff; +NPairStyle(half/size/bin/atomonly/newtoff, + NPairHalfSizeBinAtomonlyNewtoff, + NP_HALF | NP_SIZE | NP_BIN | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairBinAtomonly<1, 1, 0, 1> NPairHalfSizeBinAtomonlyNewton; +NPairStyle(half/size/bin/atomonly/newton, + NPairHalfSizeBinAtomonlyNewton, + NP_HALF | NP_SIZE | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairBinAtomonly<1, 1, 1, 1> NPairHalfSizeBinAtomonlyNewtonTri; +NPairStyle(half/size/bin/atomonly/newton/tri, + NPairHalfSizeBinAtomonlyNewtonTri, + NP_HALF | NP_SIZE | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_TRI); // clang-format on #else @@ -33,7 +64,7 @@ NPairStyle(half/bin/atomonly/newton, namespace LAMMPS_NS { -template +template class NPairBinAtomonly : public NPair { public: NPairBinAtomonly(class LAMMPS *); diff --git a/src/npair_bin_ghost.cpp b/src/npair_bin_ghost.cpp new file mode 100644 index 0000000000..5be3352095 --- /dev/null +++ b/src/npair_bin_ghost.cpp @@ -0,0 +1,188 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_bin_ghost.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "neighbor.h" +#include "domain.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +template +NPairBinGhost::NPairBinGhost(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + Full: + binned neighbor list construction for all neighbors + include neighbors of ghost atoms, but no "special neighbors" for ghosts + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + binned neighbor list construction with partial Newton's 3rd law + include neighbors of ghost atoms, but no "special neighbors" for ghosts + owned and ghost atoms check own bin and other bins in stencil + pair stored once if i,j are both owned and i < j + pair stored by me if i owned and j ghost (also stored by proc owning j) + pair stored once if i,j are both ghost and i < j +------------------------------------------------------------------------- */ + + +template +void NPairBinGhost::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,bin_start,which,imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int xbin,ybin,zbin,xbin2,ybin2,zbin2; + int *neighptr; + + double **x = atom->x; + 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; + int nall = nlocal + atom->nghost; + 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 *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + // loop over owned & ghost atoms, storing neighbors + for (i = 0; i < nall; i++) { + n = 0; + neighptr = ipage->vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + if (i < nlocal) { + ibin = atom2bin[i]; + + // loop over all atoms in surrounding bins in stencil including self + // when i is a ghost atom, must check if stencil bin is out of bounds + // no molecular test when i = ghost atom + for (k = 0; k < nstencil; k++) { + bin_start = binhead[ibin+stencil[k]]; + for (j = bin_start; j >= 0; j = bins[j]) { + if (!HALF) { + // Full neighbor list + // only skip i = j + if (i == j) continue; + } else { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + // stores ghost/ghost pairs only once + 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; + + if (rsq <= cutneighsq[itype][jtype]) { + 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++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } + } + } else { + ibin = coord2bin(x[i],xbin,ybin,zbin); + for (k = 0; k < nstencil; k++) { + xbin2 = xbin + stencilxyz[k][0]; + ybin2 = ybin + stencilxyz[k][1]; + zbin2 = zbin + stencilxyz[k][2]; + if (xbin2 < 0 || xbin2 >= mbinx || + ybin2 < 0 || ybin2 >= mbiny || + zbin2 < 0 || zbin2 >= mbinz) continue; + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + if (!HALF) { + if (i == j) continue; + } else { + 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; + + if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j; + } + } + } + + 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 = atom->nlocal; + list->gnum = inum - atom->nlocal; +} + +namespace LAMMPS_NS { +template class NPairBinGhost<0>; +template class NPairBinGhost<1>; +} diff --git a/src/npair_bin_ghost.h b/src/npair_bin_ghost.h new file mode 100644 index 0000000000..602aaf986e --- /dev/null +++ b/src/npair_bin_ghost.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairBinGhost<0> NPairFullBinGhost; +NPairStyle(full/bin/ghost, + NPairFullBinGhost, + NP_FULL | NP_BIN | NP_NEWTON | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI); + +typedef NPairBinGhost<1> NPairHalfBinGhostNewtoff; +NPairStyle(half/bin/ghost/newtoff, + NPairHalfBinGhostNewtoff, + NP_HALF | NP_BIN | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_BIN_GHOST_H +#define LMP_NPAIR_BIN_GHOST_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairBinGhost : public NPair { + public: + NPairBinGhost(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/npair_halffull.cpp b/src/npair_halffull.cpp new file mode 100644 index 0000000000..b9652484ce --- /dev/null +++ b/src/npair_halffull.cpp @@ -0,0 +1,142 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_halffull.h" + +#include "atom.h" +#include "error.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NPairHalffull::NPairHalffull(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build half list from full list + pair stored once if i,j are both owned and i < j + works if full list is a skip list + + Newtoff: + pair stored by me if j is ghost (also stored by proc owning j) + works for owned (non-ghost) list, also for ghost list + if ghost, also store neighbors of ghost atoms & set inum,gnum correctly + Newton: + if j is ghost, only store if j coords are "above and to the right" of i +------------------------------------------------------------------------- */ + +template +void NPairHalffull::build(NeighList *list) +{ + int i,j,ii,jj,n,jnum,joriginal; + int *neighptr,*jlist; + double xtmp,ytmp,ztmp; + double delx,dely,delz,rsq; + + double **x = atom->x; + int nlocal = atom->nlocal; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_full = list->listfull->ilist; + int *numneigh_full = list->listfull->numneigh; + int **firstneigh_full = list->listfull->firstneigh; + int inum_full = list->listfull->inum; + if (!NEWTON) + if (list->ghost) inum_full += list->listfull->gnum; + + int inum = 0; + ipage->reset(); + + double cutsq_custom = cutoff_custom * cutoff_custom; + + // loop over atoms in full list + + for (ii = 0; ii < inum_full; ii++) { + n = 0; + neighptr = ipage->vget(); + + // loop over parent full list + + i = ilist_full[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + + jlist = firstneigh_full[i]; + jnum = numneigh_full[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (NEWTON) { + if (j < nlocal) { + if (i > j) continue; + } else { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (rsq > cutsq_custom) continue; + } + neighptr[n++] = joriginal; + } else { + if (j > i) { + if (TRIM) { + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx * delx + dely * dely + delz * delz; + + if (rsq > cutsq_custom) continue; + } + neighptr[n++] = joriginal; + } + } + } + + 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; + if (!NEWTON) + if (list->ghost) list->gnum = list->listfull->gnum; +} + +namespace LAMMPS_NS { +template class NPairHalffull<0,0>; +template class NPairHalffull<1,0>; +template class NPairHalffull<0,1>; +template class NPairHalffull<1,1>; +} diff --git a/src/npair_halffull.h b/src/npair_halffull.h new file mode 100644 index 0000000000..519cb0ced1 --- /dev/null +++ b/src/npair_halffull.h @@ -0,0 +1,115 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairHalffull<0, 0> NPairHalffullNewtoff; +NPairStyle(halffull/newtoff, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI); + +typedef NPairHalffull<0, 0> NPairHalffullNewtoff; +NPairStyle(halffull/newtoff/skip, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP); + +typedef NPairHalffull<0, 0> NPairHalffullNewtoff; +NPairStyle(halffull/newtoff/ghost, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_GHOST); + +typedef NPairHalffull<0, 0> NPairHalffullNewtoff; +NPairStyle(halffull/newtoff/skip/ghost, + NPairHalffullNewtoff, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST); + +typedef NPairHalffull<1, 0> NPairHalffullNewton; +NPairStyle(halffull/newton, + NPairHalffullNewton, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO | NP_TRI); + +typedef NPairHalffull<1, 0> NPairHalffullNewton; +NPairStyle(halffull/newton/skip, + NPairHalffullNewton, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO | NP_TRI | NP_SKIP); + +typedef NPairHalffull<0, 1> NPairHalffullNewtoffTrim; +NPairStyle(halffull/newtoff/trim, + NPairHalffullNewtoffTrim, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_TRIM); + +typedef NPairHalffull<0, 1> NPairHalffullNewtoffTrim; +NPairStyle(halffull/newtoff/skip/trim, + NPairHalffullNewtoffTrim, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM); + +typedef NPairHalffull<0, 1> NPairHalffullNewtoffTrim; +NPairStyle(halffull/newtoff/ghost/trim, + NPairHalffullNewtoffTrim, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_GHOST | NP_TRIM); + +typedef NPairHalffull<0, 1> NPairHalffullNewtoffTrim; +NPairStyle(halffull/newtoff/skip/ghost/trim, + NPairHalffullNewtoffTrim, + NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_HALF | + NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST | NP_TRIM); + +typedef NPairHalffull<1, 1> NPairHalffullNewtonTrim; +NPairStyle(halffull/newton/trim, + NPairHalffullNewtonTrim, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO | NP_TRI | NP_TRIM); + +typedef NPairHalffull<1, 1> NPairHalffullNewtonTrim; +NPairStyle(halffull/newton/skip/trim, + NPairHalffullNewtonTrim, + NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM); +// clang-format on +#else + +#ifndef LMP_NPAIR_HALFFULL_H +#define LMP_NPAIR_HALFFULL_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairHalffull : public NPair { + public: + NPairHalffull(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/npair_multi.cpp b/src/npair_multi.cpp new file mode 100644 index 0000000000..76e90ec674 --- /dev/null +++ b/src/npair_multi.cpp @@ -0,0 +1,205 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_multi.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; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +template +NPairMulti::NPairMulti(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multi stencil is icollection-jcollection dependent + Full: + binned neighbor list construction for all neighbors + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + binned neighbor list construction with partial Newton's 3rd law + 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) + Half + Newton: + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +template +void NPairMulti::build(NeighList *list) +{ + int i,j,jh,js,k,n,itype,jtype,icollection,jcollection,ibin,jbin,which,ns,imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radsum,cut,cutsq; + int *neighptr,*s; + + 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 mask_history = 1 << HISTBITS; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + 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]; + 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); + + 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 (!HALF) { + // Full neighbor list + // only skip i = j + if (i == j) continue; + } else if (!NEWTON) { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + if (j <= i) continue; + } else if (TRI) { + // Half neighbor list, newton on, triclinic + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp) { + if (x[j][0] < xtmp) continue; + if (x[j][0] == xtmp && j <= i) continue; + } + } + } else { + // Half neighbor list, newton on, orthonormal + // store every pair for every bin in stencil,except for i's bin + + if (stencil[k] == 0) { + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the "right" of i + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) 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; + + if (rsq <= cutneighsq[itype][jtype]) { + 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++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } + } + } + + 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; + list->gnum = 0; +} + +namespace LAMMPS_NS { +template class NPairMulti<0,1,0,0>; +template class NPairMulti<1,0,0,0>; +template class NPairMulti<1,1,0,0>; +template class NPairMulti<1,1,1,0>; +template class NPairMulti<0,1,0,1>; +template class NPairMulti<1,0,0,1>; +template class NPairMulti<1,1,0,1>; +template class NPairMulti<1,1,1,1>; +} diff --git a/src/npair_multi.h b/src/npair_multi.h new file mode 100644 index 0000000000..288498dc00 --- /dev/null +++ b/src/npair_multi.h @@ -0,0 +1,85 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairMulti<0, 1, 0, 0> NPairFullMulti; +NPairStyle(full/Multi, + NPairFullMulti, + NP_FULL | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 0, 0, 0> NPairHalfMultiNewtoff; +NPairStyle(half/multi/newtoff, + NPairHalfMultiNewtoff, + NP_HALF | NP_MULTI | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 1, 0, 0> NPairHalfMultiNewton; +NPairStyle(half/multi/newton, + NPairHalfMultiNewton, + NP_HALF | NP_MULTI | NP_NEWTON | NP_ORTHO); + +typedef NPairMulti<1, 1, 1, 0> NPairHalfMultiNewtonTri; +NPairStyle(half/multi/newton/tri, + NPairHalfMultiNewtonTri, + NP_HALF | NP_MULTI | NP_NEWTON | NP_TRI); + +typedef NPairMulti<0, 1, 0, 1> NPairFullSizeMulti; +NPairStyle(full/size/Multi, + NPairFullSizeMulti, + NP_FULL | NP_SIZE | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 0, 0, 1> NPairHalfSizeMultiNewtoff; +NPairStyle(half/size/multi/newtoff, + NPairHalfSizeMultiNewtoff, + NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMulti<1, 1, 0, 1> NPairHalfSizeMultiNewton; +NPairStyle(half/size/multi/newton, + NPairHalfSizeMultiNewton, + NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTON | NP_ORTHO); + +typedef NPairMulti<1, 1, 1, 1> NPairHalfSizeMultiNewtonTri; +NPairStyle(half/size/multi/newton/tri, + NPairHalfSizeMultiNewtonTri, + NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTON | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_MULTI_H +#define LMP_NPAIR_MULTI_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairMulti : public NPair { + public: + NPairMulti(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/npair_multi_old.cpp b/src/npair_multi_old.cpp new file mode 100644 index 0000000000..28efc16797 --- /dev/null +++ b/src/npair_multi_old.cpp @@ -0,0 +1,236 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_multi_old.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "molecule.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NPairMultiOld::NPairMultiOld(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multi/old-type stencil is itype dependent and is distance checked + Full: + binned neighbor list construction for all neighbors + multi-type stencil is itype dependent and is distance checked + every neighbor pair appears in list of both atoms i and j + Half + newtoff: + binned neighbor list construction with partial Newton's 3rd law + each owned atom i checks own bin and other bins in stencil + multi-type stencil is itype dependent and is distance checked + 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) + Half + newton: + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + multi-type stencil is itype dependent and is distance checked + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +template +void NPairMultiOld::build(NeighList *list) +{ + int i,j,jh,k,n,itype,jtype,ibin,bin_start,which,ns,imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radsum,cut,cutsq; + int *neighptr,*s; + double *cutsq,*distsq; + + 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 mask_history = 1 << HISTBITS; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; i++) { + n = 0; + neighptr = ipage->vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + ibin = atom2bin[i]; + s = stencil_multi_old[itype]; + distsq = distsq_multi_old[itype]; + cutsq = cutneighsq[itype]; + ns = nstencil_multi_old[itype]; + for (k = 0; k < ns; k++) { + bin_start = binhead[ibin+stencil[k]]; + if (stencil[k] == 0) { + if (HALF && NEWTON && (!TRI)) { + // Half neighbor list, newton on, orthonormal + // loop over rest of atoms in i's bin, ghosts are at end of linked list + bin_start = bins[i]; + } + } + + for (j = bin_start; j >= 0; j = bins[j]) { + if (!HALF) { + // Full neighbor list + // only skip i = j + if (i == j) continue; + } else if (!NEWTON) { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + if (j <= i) continue; + } else if (TRI) { + // Half neighbor list, newton on, triclinic + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp) { + if (x[j][0] < xtmp) continue; + if (x[j][0] == xtmp && j <= i) continue; + } + } + } else { + // Half neighbor list, newton on, orthonormal + // store every pair for every bin in stencil,except for i's bin + + if (stencil[k] == 0) { + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the "right" of i + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + } + } + + jtype = type[j]; + if (cutsq[jtype] < distsq[k]) continue; + if (i == j) continue; + + 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; + + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (rsq <= cutsq) { + 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; + } + } else { + if (rsq <= cutneighsq[itype][jtype]) { + 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++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } + } + } + + 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; + list->gnum = 0; +} + +namespace LAMMPS_NS { +template class NPairMultiOld<0,1,0,0>; +template class NPairMultiOld<1,0,0,0>; +template class NPairMultiOld<1,1,0,0>; +template class NPairMultiOld<1,1,1,0>; +template class NPairMultiOld<0,1,0,1>; +template class NPairMultiOld<1,0,0,1>; +template class NPairMultiOld<1,1,0,1>; +template class NPairMultiOld<1,1,1,1>; +} diff --git a/src/npair_multi_old.h b/src/npair_multi_old.h new file mode 100644 index 0000000000..52b071ebc5 --- /dev/null +++ b/src/npair_multi_old.h @@ -0,0 +1,85 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairMultiOld<0, 1, 0, 0> NPairFullMultiOld; +NPairStyle(full/multi/old, + NPairFullMultiOld, + NP_FULL | NP_MULTI_OLD | NP_MOLONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOld<1, 0, 0, 0> NPairHalfMultiOldNewtoff; +NPairStyle(half/multi/old/newtoff, + NPairHalfMultiOldNewtoff, + NP_HALF | NP_MULTI_OLD | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOld<1, 1, 0, 0> NPairHalfMultiOldNewton; +NPairStyle(half/multi/old/newton, + NPairHalfMultiOldNewton, + NP_HALF | NP_MULTI_OLD | NP_MOLONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairMultiOld<1, 1, 1, 0> NPairHalfMultiOldNewtonTri; +NPairStyle(half/multi/old/newton/tri, + NPairHalfMultiOldNewtonTri, + NP_HALF | NP_MULTI_OLD | NP_MOLONLY | NP_NEWTON | NP_TRI); + +typedef NPairMultiOld<0, 1, 0, 1> NPairFullSizeMultiOld; +NPairStyle(full/size/multi/old, + NPairFullSizeMultiOld, + NP_FULL | NP_SIZE | NP_MULTI_OLD | NP_MOLONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOld<1, 0, 0, 1> NPairHalfSizeMultiOldNewtoff; +NPairStyle(half/size/multi/old/newtoff, + NPairHalfSizeMultiOldNewtoff, + NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairMultiOld<1, 1, 0, 1> NPairHalfSizeMultiOldNewton; +NPairStyle(half/size/multi/old/newton, + NPairHalfSizeMultiOldNewton, + NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_MOLONLY | NP_NEWTON | NP_ORTHO); + +typedef NPairMultiOld<1, 1, 1, 1> NPairHalfSizeMultiOldNewtonTri; +NPairStyle(half/size/multi/old/newton/tri, + NPairHalfSizeMultiOldNewtonTri, + NP_HALF | NP_SIZE | NP_MULTI_OLD | NP_MOLONLY | NP_NEWTON | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_MULTI_OLD_H +#define LMP_NPAIR_MULTI_OLD_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairMultiOld : public NPair { + public: + NPairMultiOld(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/npair_nsq.cpp b/src/npair_nsq.cpp new file mode 100644 index 0000000000..87a05e8136 --- /dev/null +++ b/src/npair_nsq.cpp @@ -0,0 +1,205 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_nsq.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "neighbor.h" +#include "domain.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +template +NPairNsq::NPairNsq(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + Full: + N^2 search for all neighbors + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + N^2 / 2 search for neighbor pairs with partial Newton's 3rd law + 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) + Half + Newton: + N^2 / 2 search for neighbor pairs with full Newton's 3rd law + every pair stored exactly once by some processor + decision on ghost atoms based on itag,jtag tests +------------------------------------------------------------------------- */ + +template +void NPairNsq::build(NeighList *list) +{ + int i,j,jh,jstart,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; + tagint itag,jtag,tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radsum,cut,cutsq; + int *neighptr; + + 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; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + 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 mask_history = 1 << HISTBITS; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; i++) { + n = 0; + neighptr = ipage->vget(); + + itag = tag[i]; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // Full: loop over all atoms, owned and ghost, skip i = j + // Half: loop over remaining atoms, owned and ghost + // Newtoff: only store pair if i < j + // Newton: itag = jtag is possible for long cutoffs that include images of self + + if (!HALF) jstart = 0; + else jstart = i + 1; + + for (j = jstart; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; + + if (!HALF) { + // Full neighbor list + if (i == j) continue; + } else if (NEWTON) { + // Half neighbor list, newton on + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag+jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag+jtag) % 2 == 1) continue; + } else { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) 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; + + if (SIZE) { + radsum = radius[i] + radius[j]; + cut = radsum + skin; + cutsq = cut * cut; + + if (rsq <= cutsq) { + 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; + } + } else { + if (rsq <= cutneighsq[itype][jtype]) { + 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++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } + } + + 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; + if (!HALF) list->gnum = 0; +} + +namespace LAMMPS_NS { +template class NPairNsq<0,1,0>; +template class NPairNsq<1,0,0>; +template class NPairNsq<1,1,0>; +template class NPairNsq<0,1,1>; +template class NPairNsq<1,0,1>; +template class NPairNsq<1,1,1>; +} diff --git a/src/npair_nsq.h b/src/npair_nsq.h new file mode 100644 index 0000000000..4d616d33f2 --- /dev/null +++ b/src/npair_nsq.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairNsq<0, 1, 0> NPairFullNsq; +NPairStyle(full/nsq, + NPairFullNsq, + NP_FULL | NP_NSQ | NP_MOLONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsq<1, 0, 0> NPairHalfNsqNewtoff; +NPairStyle(half/nsq/newtoff, + NPairHalfNsqNewtoff, + NP_HALF | NP_NSQ | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsq<1, 1, 0> NPairHalfNsqNewton; +NPairStyle(half/nsq/newton, + NPairHalfNsqNewton, + NP_HALF | NP_NSQ | NP_MOLONLY | NP_NEWTON | NP_ORTHO | NP_TRI); + +typedef NPairNsq<0, 1, 1> NPairFullSizeNsq; +NPairStyle(full/size/nsq, + NPairFullSizeNsq, + NP_FULL | NP_SIZE | NP_NSQ | NP_MOLONLY | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsq<1, 0, 1> NPairHalfSizeNsqNewtoff; +NPairStyle(half/size/nsq/newtoff, + NPairHalfSizeNsqNewtoff, + NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairNsq<1, 1, 1> NPairHalfSizeNsqNewton; +NPairStyle(half/size/nsq/newton, + NPairHalfSizeNsqNewton, + NP_HALF | NP_SIZE | NP_NSQ | NP_MOLONLY | NP_NEWTON | NP_ORTHO | NP_TRI); + +// clang-format on +#else + +#ifndef LMP_NPAIR_Nsq_H +#define LMP_NPAIR_Nsq_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairNsq : public NPair { + public: + NPairNsq(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/npair_nsq_ghost.cpp b/src/npair_nsq_ghost.cpp new file mode 100644 index 0000000000..4a733047c4 --- /dev/null +++ b/src/npair_nsq_ghost.cpp @@ -0,0 +1,176 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_nsq_ghost.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "neighbor.h" +#include "domain.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +template +NPairNsqGhost::NPairNsqGhost(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + Full: + N^2 search for all neighbors + include neighbors of ghost atoms, but no "special neighbors" for ghosts + every neighbor pair appears in list of both atoms i and j + Half + Newtoff: + N^2 / 2 search for neighbor pairs with partial Newton's 3rd law + include neighbors of ghost atoms, but no "special neighbors" for ghosts + pair stored once if i,j are both owned and i < j + pair stored by me if i owned and j ghost (also stored by proc owning j) + pair stored once if i,j are both ghost and i < j +------------------------------------------------------------------------- */ + + +template +void NPairNsqGhost::build(NeighList *list) +{ + int i,j,jstart,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int *neighptr; + + double **x = atom->x; + 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; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + // loop over owned & ghost atoms, storing neighbors + for (i = 0; i < nall; i++) { + n = 0; + neighptr = ipage->vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over all atoms, owned and ghost + // Full: + // skip i = j + // Half: + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs with owned atom only, on both procs + // stores ghost/ghost pairs only once + // no molecular test when i = ghost atom + + if (!HALF) jstart = 0; + else jstart = i + 1; + + if (i < nlocal) { + for (j = jstart; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; // JTC: missing in original full version + if (!HALF) { + if (i == j) 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; + + if (rsq <= cutneighsq[itype][jtype]) { + 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++] = j; + else if (domain->minimum_image_check(delx,dely,delz)) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + } + } + } else { + for (j = jstart; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; // JTC: missing in original full version + if (!HALF) { + if (i == j) 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; + + if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j; + } + } + + 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 = atom->nlocal; + list->gnum = inum - atom->nlocal; +} + +namespace LAMMPS_NS { +template class NPairNsqGhost<0>; +template class NPairNsqGhost<1>; +} diff --git a/src/npair_nsq_ghost.h b/src/npair_nsq_ghost.h new file mode 100644 index 0000000000..d1f34969d5 --- /dev/null +++ b/src/npair_nsq_ghost.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairNsqGhost<0> NPairFullNsqGhost; +NPairStyle(full/nsq/ghost, + NPairFullNsqGhost, + NP_FULL | NP_NSQ | NP_NEWTON | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI); + +typedef NPairNsqGhost<1> NPairHalfNsqGhostNewtoff; +NPairStyle(half/nsq/ghost/newtoff, + NPairHalfNsqGhostNewtoff, + NP_HALF | NP_NSQ | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_NSQ_GHOST_H +#define LMP_NPAIR_NSQ_GHOST_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairNsqGhost : public NPair { + public: + NPairNsqGhost(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/npair_respa_bin.cpp b/src/npair_respa_bin.cpp new file mode 100644 index 0000000000..7e8f79df5f --- /dev/null +++ b/src/npair_respa_bin.cpp @@ -0,0 +1,240 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_respa_bin.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "domain.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NPairRespaBin::NPairRespaBin(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multiple respa lists + Newtoff + binned neighbor list construction with partial Newton's 3rd law + each owned atom i checks own bin and surrounding bins in non-Newton 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) + Newton + binned neighbor list construction with full Newton's 3rd law + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +template +void NPairRespaBin::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,bin_start,n_inner,n_middle,imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int *neighptr,*neighptr_inner,*neighptr_middle; + + double **x = atom->x; + 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 *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_inner = list->ilist_inner; + int *numneigh_inner = list->numneigh_inner; + int **firstneigh_inner = list->firstneigh_inner; + MyPage *ipage_inner = list->ipage_inner; + + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage *ipage_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + ilist_middle = list->ilist_middle; + numneigh_middle = list->numneigh_middle; + firstneigh_middle = list->firstneigh_middle; + ipage_middle = list->ipage_middle; + } + + int inum = 0; + int which = 0; + int minchange = 0; + ipage->reset(); + ipage_inner->reset(); + if (respamiddle) ipage_middle->reset(); + + for (i = 0; i < nlocal; i++) { + n = n_inner = 0; + neighptr = ipage->vget(); + neighptr_inner = ipage_inner->vget(); + if (respamiddle) { + n_middle = 0; + neighptr_middle = ipage_middle->vget(); + } + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + ibin = atom2bin[i]; + + for (k = 0; k < nstencil; k++) { + bin_start = binhead[ibin+stencil[k]]; + if (stencil[k] == 0) { + if (HALF && NEWTON && (!TRI)) { + // Half neighbor list, newton on, orthonormal + // loop over rest of atoms in i's bin, ghosts are at end of linked list + bin_start = bins[i]; + } + } + + for (j = binstart; j >= 0; j = bins[j]) { + if (!NEWTON) { + // Half neighbor list, newton off + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + if (j <= i) continue; + } else if (TRI) { + // Half neighbor list, newton on, triclinic + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp) { + if (x[j][0] < xtmp) continue; + if (x[j][0] == xtmp && j <= i) continue; + } + } + } else { + // Half neighbor list, newton on, orthonormal + // store every pair for every bin in stencil,except for i's bin + + if (stencil[k] == 0) { + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the "right" of i + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) 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; + + if (rsq <= cutneighsq[itype][jtype]) { + 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++] = j; + else if ((minchange = domain->minimum_image_check(delx,dely,delz))) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + + if (rsq < cut_inner_sq) { + if (which == 0) neighptr_inner[n_inner++] = j; + else if (minchange) neighptr_inner[n_inner++] = j; + else if (which > 0) + neighptr_inner[n_inner++] = j ^ (which << SBBITS); + } + + if (respamiddle && + rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { + if (which == 0) neighptr_middle[n_middle++] = j; + else if (minchange) neighptr_middle[n_middle++] = j; + else if (which > 0) + neighptr_middle[n_middle++] = j ^ (which << SBBITS); + } + } + } + } + + 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"); + + ilist_inner[inum] = i; + firstneigh_inner[i] = neighptr_inner; + numneigh_inner[i] = n_inner; + ipage_inner->vgot(n_inner); + if (ipage_inner->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (respamiddle) { + ilist_middle[inum] = i; + firstneigh_middle[i] = neighptr_middle; + numneigh_middle[i] = n_middle; + ipage_middle->vgot(n_middle); + if (ipage_middle->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + inum++; + } + + list->inum = inum; + list->inum_inner = inum; + if (respamiddle) list->inum_middle = inum; +} + +namespace LAMMPS_NS { +template class NPairRespaBin<0,0>; +template class NPairRespaBin<1,0>; +template class NPairRespaBin<1,1>; +} diff --git a/src/npair_respa_bin.h b/src/npair_respa_bin.h new file mode 100644 index 0000000000..bf52ebcadc --- /dev/null +++ b/src/npair_respa_bin.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairRespaBin<0, 0> NPairHalfRespaBinNewtoff; +NPairStyle(half/respa/bin/newtoff, + NPairHalfRespaBinNewtoff, + NP_HALF | NP_RESPA | NP_BIN | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairRespaBin<1, 0> NPairHalfRespaBinNewton; +NPairStyle(half/respa/bin/newton, + NPairHalfRespaBinNewton, + NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_ORTHO); + +typedef NPairRespaBin<1, 1> NPairHalfRespaBinNewtonTri; +NPairStyle(half/respa/bin/newton/tri, + NPairHalfRespaBinNewtonTri, + NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_RESPA_BIN_H +#define LMP_NPAIR_RESPA_BIN_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairRespaBin : public NPair { + public: + NPairRespaBin(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/npair_respa_nsq.cpp b/src/npair_respa_nsq.cpp new file mode 100644 index 0000000000..5587758cd4 --- /dev/null +++ b/src/npair_respa_nsq.cpp @@ -0,0 +1,214 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_respa_nsq.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "group.h" +#include "molecule.h" +#include "domain.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +template +NPairRespaNsq::NPairRespaNsq(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multiple respa lists + Newtoff + N^2 / 2 search for neighbor pairs with partial Newton's 3rd law + pair added to list if atoms i and j are both owned and i < j + pair added if j is ghost (also stored by proc owning j) + Newton + N^2 / 2 search for neighbor pairs with full Newton's 3rd law + pair added to list if atoms i and j are both owned and i < j + if j is ghost only me or other proc adds pair + decision based on itag,jtag tests +------------------------------------------------------------------------- */ + +template +void NPairRespaNsq::build(NeighList *list) +{ + int i,j,n,itype,jtype,n_inner,n_middle,bitmask,imol,iatom,moltemplate; + tagint itag,jtag,tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int *neighptr,*neighptr_inner,*neighptr_middle; + + double **x = atom->x; + 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; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == Atom::TEMPLATE) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_inner = list->ilist_inner; + int *numneigh_inner = list->numneigh_inner; + int **firstneigh_inner = list->firstneigh_inner; + MyPage *ipage_inner = list->ipage_inner; + + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage *ipage_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + ilist_middle = list->ilist_middle; + numneigh_middle = list->numneigh_middle; + firstneigh_middle = list->firstneigh_middle; + ipage_middle = list->ipage_middle; + } + + int inum = 0; + int which = 0; + int minchange = 0; + ipage->reset(); + ipage_inner->reset(); + if (respamiddle) ipage_middle->reset(); + + for (i = 0; i < nlocal; i++) { + n = n_inner = 0; + neighptr = ipage->vget(); + neighptr_inner = ipage_inner->vget(); + if (respamiddle) { + n_middle = 0; + neighptr_middle = ipage_middle->vget(); + } + + itype = type[i]; + itag = tag[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over remaining atoms, owned and ghost + + for (j = i+1; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; + + if (NEWTON) { + if (j >= nlocal) { + jtag = tag[j]; + if (itag > jtag) { + if ((itag+jtag) % 2 == 0) continue; + } else if (itag < jtag) { + if ((itag+jtag) % 2 == 1) continue; + } else { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) 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; + + if (rsq <= cutneighsq[itype][jtype]) { + 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++] = j; + else if ((minchange = domain->minimum_image_check(delx,dely,delz))) + neighptr[n++] = j; + else if (which > 0) neighptr[n++] = j ^ (which << SBBITS); + } else neighptr[n++] = j; + + if (rsq < cut_inner_sq) { + if (which == 0) neighptr_inner[n_inner++] = j; + else if (minchange) neighptr_inner[n_inner++] = j; + else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS); + } + + if (respamiddle && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) { + if (which == 0) neighptr_middle[n_middle++] = j; + else if (minchange) neighptr_middle[n_middle++] = j; + else if (which > 0) + neighptr_middle[n_middle++] = j ^ (which << SBBITS); + } + } + } + + 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"); + + ilist_inner[inum] = i; + firstneigh_inner[i] = neighptr_inner; + numneigh_inner[i] = n_inner; + ipage_inner->vgot(n_inner); + if (ipage_inner->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (respamiddle) { + ilist_middle[inum] = i; + firstneigh_middle[i] = neighptr_middle; + numneigh_middle[i] = n_middle; + ipage_middle->vgot(n_middle); + if (ipage_middle->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + inum++; + } + + list->inum = inum; + list->inum_inner = inum; + if (respamiddle) list->inum_middle = inum; +} + +namespace LAMMPS_NS { +template class NPairRespaNsq<0>; +template class NPairRespaNsq<1>; +} diff --git a/src/npair_respa_nsq.h b/src/npair_respa_nsq.h new file mode 100644 index 0000000000..5d6ea60465 --- /dev/null +++ b/src/npair_respa_nsq.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +typedef NPairRespaNsq<0> NPairHalfRespaNsqNewtoff; +NPairStyle(half/respa/nsq/newtoff, + NPairHalfRespaNsqNewtoff, + NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +typedef NPairRespaNsq<1> NPairHalfRespaNsqNewton; +NPairStyle(half/respa/nsq/newton, + NPairHalfRespaNsqNewton, + NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTON | NP_ORTHO | NP_TRI); //JTC: Originally didn't have TRI +// clang-format on +#else + +#ifndef LMP_NPAIR_RESPA_NSQ_H +#define LMP_NPAIR_RESPA_NSQ_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairRespaNsq : public NPair { + public: + NPairRespaNsq(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/npair_skip.cpp b/src/npair_skip.cpp new file mode 100644 index 0000000000..4ef0573dbb --- /dev/null +++ b/src/npair_skip.cpp @@ -0,0 +1,102 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_skip.h" + +#include "atom.h" +#include "error.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairSkip::NPairSkip(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build skip list for subset of types from parent list + works for half and full lists + works for owned (non-ghost) list, also for ghost list + iskip and ijskip flag which atom types and type pairs to skip + if ghost, also store neighbors of ghost atoms & set inum,gnum correctly +------------------------------------------------------------------------- */ + +void NPairSkip::build(NeighList *list) +{ + int i,j,ii,jj,n,itype,jnum,joriginal; + int *neighptr,*jlist; + + int *type = atom->type; + int nlocal = atom->nlocal; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_skip = list->listskip->ilist; + int *numneigh_skip = list->listskip->numneigh; + int **firstneigh_skip = list->listskip->firstneigh; + int num_skip = list->listskip->inum; + if (list->ghost) num_skip += list->listskip->gnum; + + int *iskip = list->iskip; + int **ijskip = list->ijskip; + + int inum = 0; + ipage->reset(); + + // loop over atoms in other list + // skip I atom entirely if iskip is set for type[I] + // skip I,J pair if ijskip is set for type[I],type[J] + + for (ii = 0; ii < num_skip; ii++) { + i = ilist_skip[ii]; + itype = type[i]; + if (iskip[itype]) continue; + + n = 0; + neighptr = ipage->vget(); + + // loop over parent non-skip list + + jlist = firstneigh_skip[i]; + jnum = numneigh_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + neighptr[n++] = joriginal; + } + + 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; + if (list->ghost) { + int num = 0; + for (i = 0; i < inum; i++) + if (ilist[i] < nlocal) num++; + else break; + list->inum = num; + list->gnum = inum - num; + } +} diff --git a/src/npair_skip.h b/src/npair_skip.h new file mode 100644 index 0000000000..b2a0752117 --- /dev/null +++ b/src/npair_skip.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +NPairStyle(skip, + NPairSkip, + NP_SKIP | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); + +NPairStyle(skip/ghost, + NPairSkip, + NP_SKIP | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_GHOST); + +NPairStyle(skip/half/size, + NPairSkip, + NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_SKIP_H +#define LMP_NPAIR_SKIP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairSkip : public NPair { + public: + NPairSkip(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/npair_skip_respa.cpp b/src/npair_skip_respa.cpp new file mode 100644 index 0000000000..373fe3f8db --- /dev/null +++ b/src/npair_skip_respa.cpp @@ -0,0 +1,163 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_skip_respa.h" + +#include "atom.h" +#include "error.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairSkipRespa::NPairSkipRespa(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build skip list for subset of types from parent list + iskip and ijskip flag which atom types and type pairs to skip + this is for respa lists, copy the inner/middle values from parent +------------------------------------------------------------------------- */ + +void NPairSkipRespa::build(NeighList *list) +{ + int i,j,ii,jj,n,itype,jnum,joriginal,n_inner,n_middle; + int *neighptr,*jlist,*neighptr_inner,*neighptr_middle; + + int *type = atom->type; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_skip = list->listskip->ilist; + int *numneigh_skip = list->listskip->numneigh; + int **firstneigh_skip = list->listskip->firstneigh; + int inum_skip = list->listskip->inum; + + int *iskip = list->iskip; + int **ijskip = list->ijskip; + + int *ilist_inner = list->ilist_inner; + int *numneigh_inner = list->numneigh_inner; + int **firstneigh_inner = list->firstneigh_inner; + MyPage *ipage_inner = list->ipage_inner; + int *numneigh_inner_skip = list->listskip->numneigh_inner; + int **firstneigh_inner_skip = list->listskip->firstneigh_inner; + + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage *ipage_middle; + int *numneigh_middle_skip,**firstneigh_middle_skip; + int respamiddle = list->respamiddle; + if (respamiddle) { + ilist_middle = list->ilist_middle; + numneigh_middle = list->numneigh_middle; + firstneigh_middle = list->firstneigh_middle; + ipage_middle = list->ipage_middle; + numneigh_middle_skip = list->listskip->numneigh_middle; + firstneigh_middle_skip = list->listskip->firstneigh_middle; + } + + int inum = 0; + ipage->reset(); + ipage_inner->reset(); + if (respamiddle) ipage_middle->reset(); + + // loop over atoms in other list + // skip I atom entirely if iskip is set for type[I] + // skip I,J pair if ijskip is set for type[I],type[J] + + for (ii = 0; ii < inum_skip; ii++) { + i = ilist_skip[ii]; + itype = type[i]; + if (iskip[itype]) continue; + + n = n_inner = 0; + neighptr = ipage->vget(); + neighptr_inner = ipage_inner->vget(); + if (respamiddle) { + n_middle = 0; + neighptr_middle = ipage_middle->vget(); + } + + // loop over parent outer rRESPA list + + jlist = firstneigh_skip[i]; + jnum = numneigh_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + neighptr[n++] = joriginal; + } + + // loop over parent inner rRESPA list + + jlist = firstneigh_inner_skip[i]; + jnum = numneigh_inner_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + neighptr_inner[n_inner++] = joriginal; + } + + // loop over parent middle rRESPA list + + if (respamiddle) { + jlist = firstneigh_middle_skip[i]; + jnum = numneigh_middle_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + neighptr_middle[n_middle++] = joriginal; + } + } + + 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"); + + ilist_inner[inum] = i; + firstneigh_inner[i] = neighptr_inner; + numneigh_inner[i] = n_inner; + ipage_inner->vgot(n); + if (ipage_inner->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (respamiddle) { + ilist_middle[inum] = i; + firstneigh_middle[i] = neighptr_middle; + numneigh_middle[i] = n_middle; + ipage_middle->vgot(n); + if (ipage_middle->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + inum++; + } + + list->inum = inum; + list->inum_inner = inum; + if (respamiddle) list->inum_middle = inum; +} diff --git a/src/npair_skip_respa.h b/src/npair_skip_respa.h new file mode 100644 index 0000000000..b0938287b5 --- /dev/null +++ b/src/npair_skip_respa.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +NPairStyle(skip/half/respa, + NPairSkipRespa, + NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_SKIP_RESPA_H +#define LMP_NPAIR_SKIP_RESPA_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairSkipRespa : public NPair { + public: + NPairSkipRespa(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/npair_skip_size_off2on.cpp b/src/npair_skip_size_off2on.cpp new file mode 100644 index 0000000000..e48ca345ff --- /dev/null +++ b/src/npair_skip_size_off2on.cpp @@ -0,0 +1,100 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_skip_size_off2on.h" + +#include "atom.h" +#include "error.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairSkipSizeOff2on::NPairSkipSizeOff2on(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build skip list for subset of types from parent list + iskip and ijskip flag which atom types and type pairs to skip + parent non-skip list used newton off, this skip list is newton on +------------------------------------------------------------------------- */ + +void NPairSkipSizeOff2on::build(NeighList *list) +{ + int i,j,ii,jj,n,itype,jnum,joriginal; + tagint itag,jtag; + int *neighptr,*jlist; + + tagint *tag = atom->tag; + int *type = atom->type; + int nlocal = atom->nlocal; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_skip = list->listskip->ilist; + int *numneigh_skip = list->listskip->numneigh; + int **firstneigh_skip = list->listskip->firstneigh; + int inum_skip = list->listskip->inum; + + int *iskip = list->iskip; + int **ijskip = list->ijskip; + + int inum = 0; + ipage->reset(); + + // loop over atoms in other list + // skip I atom entirely if iskip is set for type[I] + // skip I,J pair if ijskip is set for type[I],type[J] + + for (ii = 0; ii < inum_skip; ii++) { + i = ilist_skip[ii]; + itype = type[i]; + if (iskip[itype]) continue; + itag = tag[i]; + + n = 0; + neighptr = ipage->vget(); + + // loop over parent non-skip size list and optionally its history info + + jlist = firstneigh_skip[i]; + jnum = numneigh_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + + // only keep I,J when J = ghost if Itag < Jtag + + jtag = tag[j]; + if (j >= nlocal && jtag < itag) continue; + + neighptr[n++] = joriginal; + } + + 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; +} diff --git a/src/npair_skip_size_off2on.h b/src/npair_skip_size_off2on.h new file mode 100644 index 0000000000..39aee76b09 --- /dev/null +++ b/src/npair_skip_size_off2on.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +NPairStyle(skip/size/off2on, + NPairSkipSizeOff2on, + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_SKIP_SIZE_OFF2ON_H +#define LMP_NPAIR_SKIP_SIZE_OFF2ON_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairSkipSizeOff2on : public NPair { + public: + NPairSkipSizeOff2on(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/npair_skip_size_off2on_oneside.cpp b/src/npair_skip_size_off2on_oneside.cpp new file mode 100644 index 0000000000..1e4b4ac78d --- /dev/null +++ b/src/npair_skip_size_off2on_oneside.cpp @@ -0,0 +1,163 @@ +// clang-format off +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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_skip_size_off2on_oneside.h" + +#include "atom.h" +#include "domain.h" +#include "error.h" +#include "my_page.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairSkipSizeOff2onOneside::NPairSkipSizeOff2onOneside(LAMMPS *lmp) : + NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build skip list for subset of types from parent list + iskip and ijskip flag which atom types and type pairs to skip + parent non-skip list used newton off and was not onesided, + this skip list is newton on and onesided +------------------------------------------------------------------------- */ + +void NPairSkipSizeOff2onOneside::build(NeighList *list) +{ + int i,j,ii,jj,n,itype,jnum,joriginal,flip,tmp; + int *surf,*jlist; + + int *type = atom->type; + int nlocal = atom->nlocal; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_skip = list->listskip->ilist; + int *numneigh_skip = list->listskip->numneigh; + int **firstneigh_skip = list->listskip->firstneigh; + int inum_skip = list->listskip->inum; + + int *iskip = list->iskip; + int **ijskip = list->ijskip; + + if (domain->dimension == 2) surf = atom->line; + else surf = atom->tri; + + int inum = 0; + ipage->reset(); + + // two loops over parent list required, one to count, one to store + // because onesided constraint means pair I,J may be stored with I or J + // so don't know in advance how much space to alloc for each atom's neighs + + // first loop over atoms in other list to count neighbors + // skip I atom entirely if iskip is set for type[I] + // skip I,J pair if ijskip is set for type[I],type[J] + + for (i = 0; i < nlocal; i++) numneigh[i] = 0; + + for (ii = 0; ii < inum_skip; ii++) { + i = ilist_skip[ii]; + itype = type[i]; + if (iskip[itype]) continue; + + n = 0; + + // loop over parent non-skip size list + + jlist = firstneigh_skip[i]; + jnum = numneigh_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + + // flip I,J if necessary to satisfy onesided constraint + // do not keep if I is now ghost + + if (surf[i] >= 0) { + if (j >= nlocal) continue; + tmp = i; + i = j; + j = tmp; + flip = 1; + } else flip = 0; + + numneigh[i]++; + if (flip) i = j; + } + } + + // allocate all per-atom neigh list chunks + + for (i = 0; i < nlocal; i++) { + if (numneigh[i] == 0) continue; + n = numneigh[i]; + firstneigh[i] = ipage->get(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + // second loop over atoms in other list to store neighbors + // skip I atom entirely if iskip is set for type[I] + // skip I,J pair if ijskip is set for type[I],type[J] + + for (i = 0; i < nlocal; i++) numneigh[i] = 0; + + for (ii = 0; ii < inum_skip; ii++) { + i = ilist_skip[ii]; + itype = type[i]; + if (iskip[itype]) continue; + + // loop over parent non-skip size list and optionally its history info + + jlist = firstneigh_skip[i]; + jnum = numneigh_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + + // flip I,J if necessary to satisfy onesided constraint + // do not keep if I is now ghost + + if (surf[i] >= 0) { + if (j >= nlocal) continue; + tmp = i; + i = j; + j = tmp; + flip = 1; + } else flip = 0; + + // store j in neigh list, not joriginal, like other neigh methods + // OK, b/c there is no special list flagging for surfs + + firstneigh[i][numneigh[i]] = j; + numneigh[i]++; + if (flip) i = j; + } + + // only add atom I to ilist if it has neighbors + + if (numneigh[i]) ilist[inum++] = i; + } + + list->inum = inum; +} diff --git a/src/npair_skip_size_off2on_oneside.h b/src/npair_skip_size_off2on_oneside.h new file mode 100644 index 0000000000..3f1cd6ef34 --- /dev/null +++ b/src/npair_skip_size_off2on_oneside.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + 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. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS +// clang-format off +NPairStyle(skip/size/off2on/oneside, + NPairSkipSizeOff2onOneside, + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | + NP_NSQ | NP_BIN | NP_MULTI | NP_MULTI_OLD | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI); +// clang-format on +#else + +#ifndef LMP_NPAIR_SKIP_SIZE_OFF2ON_ONESIDE_H +#define LMP_NPAIR_SKIP_SIZE_OFF2ON_ONESIDE_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairSkipSizeOff2onOneside : public NPair { + public: + NPairSkipSizeOff2onOneside(class LAMMPS *); + void build(class NeighList *) override; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Neighbor list overflow, boost neigh_modify one + +UNDOCUMENTED + +*/ diff --git a/src/nstencil_ghost_bin.h b/src/nstencil_ghost_bin.h index 31268cc30d..cab6e6714c 100644 --- a/src/nstencil_ghost_bin.h +++ b/src/nstencil_ghost_bin.h @@ -16,32 +16,32 @@ typedef NStencilGhostBin<0, 0, 0> NStencilFullGhostBin2d; NStencilStyle(full/ghost/bin/2d, NStencilFullGhostBin2d, - NS_FULL | NS_GhostBin | NS_2D | NS_ORTHO | NS_TRI); + NS_FULL | NS_GHOST | NS_BIN | NS_2D | NS_ORTHO | NS_TRI); typedef NStencilGhostBin<0, 1, 0> NStencilFullGhostBin3d; NStencilStyle(full/ghost/bin/3d, NStencilFullGhostBin3d, - NS_FULL | NS_GhostBin | NS_3D | NS_ORTHO | NS_TRI); + NS_FULL | NS_GHOST | NS_BIN | NS_3D | NS_ORTHO | NS_TRI); typedef NStencilGhostBin<1, 0, 0> NStencilHalfGhostBin2d; NStencilStyle(half/ghost/bin/2d, NStencilHalfGhostBin2d, - NS_HALF | NS_GhostBin | NS_2D | NS_ORTHO); + NS_HALF | NS_GHOST | NS_BIN | NS_2D | NS_ORTHO); typedef NStencilGhostBin<1, 0, 1> NStencilHalfGhostBin2dTri; NStencilStyle(half/ghost/bin/2d/tri, NStencilHalfGhostBin2dTri, - NS_HALF | NS_GhostBin | NS_2D | NS_TRI); + NS_HALF | NS_GHOST | NS_BIN | NS_2D | NS_TRI); typedef NStencilGhostBin<1, 1, 0> NStencilHalfGhostBin3d; NStencilStyle(half/ghost/bin/3d, NStencilHalfGhostBin3d, - NS_HALF | NS_GhostBin | NS_3D | NS_ORTHO); + NS_HALF | NS_GHOST | NS_BIN | NS_3D | NS_ORTHO); typedef NStencilGhostBin<1, 1, 1> NStencilHalfGhostBin3dTri; NStencilStyle(half/ghost/bin/3d/tri, NStencilHalfGhostBin3dTri, - NS_HALF | NS_GhostBin | NS_3D | NS_TRI); + NS_HALF | NS_GHOST | NS_BIN | NS_3D | NS_TRI); // clang-format on #else