Merging atomonly npair styles, minor fixes

This commit is contained in:
jtclemm
2023-10-23 16:14:56 -06:00
parent 3536cf9db9
commit 51577eff2c
17 changed files with 540 additions and 821 deletions

View File

@ -1,202 +0,0 @@
// clang-format off
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
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_atomonly_omp.h"
#include "npair_omp.h"
#include "omp_compat.h"
#include "atom.h"
#include "error.h"
#include "force.h"
#include "my_page.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE>
NPairBinAtomonlyOmp<HALF, NEWTON, TRI, SIZE>::NPairBinAtomonlyOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
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<int HALF, int NEWTON, int TRI, int SIZE>
void NPairBinAtomonlyOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const double delta = 0.01 * force->angstrom;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i, j, jh, k, n, itype, jtype, ibin, bin_start;
tagint itag, jtag;
double xtmp, ytmp, ztmp, delx, dely, delz, rsq, 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;
int history = list->history;
int mask_history = 1 << HISTBITS;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over owned atoms, storing neighbors
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
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 = 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
// for triclinic, bin stencil is full in all 3 dims
// must use itag/jtag to eliminate half the I/J interactions
// cannot use I/J exact coord comparision
// b/c transforming orthog -> lambda -> orthog for ghost atoms
// with an added PBC offset can shift all 3 coords by epsilon
if (j <= i) continue;
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 (fabs(x[j][2] - ztmp) > delta) {
if (x[j][2] < ztmp) continue;
} else if (fabs(x[j][1] - ytmp) > delta) {
if (x[j][1] < ytmp) continue;
} else {
if (x[j][0] < xtmp) 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 (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;
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status()) error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
if (!HALF) list->gnum = 0;
}
namespace LAMMPS_NS {
template class NPairBinAtomonlyOmp<0,1,0,0>;
template class NPairBinAtomonlyOmp<1,0,0,0>;
template class NPairBinAtomonlyOmp<1,1,0,0>;
template class NPairBinAtomonlyOmp<1,1,1,0>;
template class NPairBinAtomonlyOmp<0,1,0,1>;
template class NPairBinAtomonlyOmp<1,0,0,1>;
template class NPairBinAtomonlyOmp<1,1,0,1>;
template class NPairBinAtomonlyOmp<1,1,1,1>;
}

View File

@ -1,78 +0,0 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
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 NPairBinAtomonlyOmp<0, 1, 0, 0> NPairFullBinAtomonlyOmp;
NPairStyle(full/bin/atomonly/omp,
NPairFullBinAtomonlyOmp,
NP_FULL | NP_BIN | NP_OMP | NP_ATOMONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinAtomonlyOmp<1, 0, 0, 0> NPairHalfBinNewtoffAtomonlyOmp;
NPairStyle(half/bin/newtoff/atomonly/omp,
NPairHalfBinNewtoffAtomonlyOmp,
NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinAtomonlyOmp<1, 1, 0, 0> NPairHalfBinNewtonAtomonlyOmp;
NPairStyle(half/bin/newton/atomonly/omp,
NPairHalfBinNewtonAtomonlyOmp,
NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBinAtomonlyOmp<1, 1, 1, 0> NPairHalfBinNewtonTriAtomonlyOmp;
NPairStyle(half/bin/newton/tri/atomonly/omp,
NPairHalfBinNewtonTriAtomonlyOmp,
NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_TRI);
typedef NPairBinAtomonlyOmp<0, 1, 0, 1> NPairFullSizeBinAtomonlyOmp;
NPairStyle(full/size/bin/atomonly/omp,
NPairFullSizeBinAtomonlyOmp,
NP_FULL | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinAtomonlyOmp<1, 0, 0, 1> NPairHalfSizeBinNewtoffAtomonlyOmp;
NPairStyle(half/size/bin/newtoff/atomonly/omp,
NPairHalfSizeBinNewtoffAtomonlyOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinAtomonlyOmp<1, 1, 0, 1> NPairHalfSizeBinNewtonAtomonlyOmp;
NPairStyle(half/size/bin/newton/atomonly/omp,
NPairHalfSizeBinNewtonAtomonlyOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBinAtomonlyOmp<1, 1, 1, 1> NPairHalfSizeBinNewtonTriAtomonlyOmp;
NPairStyle(half/size/bin/newton/tri/atomonly/omp,
NPairHalfSizeBinNewtonTriAtomonlyOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_BIN_ATOMONLY_OMP_H
#define LMP_NPAIR_BIN_ATOMONLY_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
template<int HALF, int NEWTON, int TRI, int SIZE>
class NPairBinAtomonlyOmp : public NPair {
public:
NPairBinAtomonlyOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -29,8 +29,8 @@ using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE>
NPairBinOmp<HALF, NEWTON, TRI, SIZE>::NPairBinOmp(LAMMPS *lmp) : NPair(lmp) {}
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
NPairBinOmp<HALF, NEWTON, TRI, SIZE, ATOMONLY>::NPairBinOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
Full:
@ -47,8 +47,8 @@ NPairBinOmp<HALF, NEWTON, TRI, SIZE>::NPairBinOmp(LAMMPS *lmp) : NPair(lmp) {}
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE>
void NPairBinOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
void NPairBinOmp<HALF, NEWTON, TRI, SIZE, ATOMONLY>::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
@ -101,11 +101,13 @@ void NPairBinOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (!ATOMONLY) {
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
}
// loop over all atoms in surrounding bins in stencil including self
// skip i = j
@ -114,8 +116,8 @@ void NPairBinOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
for (k = 0; k < nstencil; k++) {
bin_start = binhead[ibin + stencil[k]];
if (stencil[k] == 0) {
if (HALF && NEWTON && (!TRI)) {
if (stencil[k] == 0) {
// 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];
@ -187,6 +189,14 @@ void NPairBinOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
cut = radsum + skin;
cutsq = cut * cut;
if (ATOMONLY) {
if (rsq <= cutsq) {
jh = j;
if (history && rsq < radsum * radsum)
jh = jh ^ mask_history;
neighptr[n++] = jh;
}
} else {
if (rsq <= cutsq) {
jh = j;
if (history && rsq < radsum * radsum)
@ -209,6 +219,10 @@ void NPairBinOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
} else
neighptr[n++] = jh;
}
}
} else {
if (ATOMONLY) {
if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j;
} else {
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
@ -230,6 +244,7 @@ void NPairBinOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
}
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
@ -243,12 +258,20 @@ void NPairBinOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
}
namespace LAMMPS_NS {
template class NPairBinOmp<0,1,0,0>;
template class NPairBinOmp<1,0,0,0>;
template class NPairBinOmp<1,1,0,0>;
template class NPairBinOmp<1,1,1,0>;
template class NPairBinOmp<0,1,0,1>;
template class NPairBinOmp<1,0,0,1>;
template class NPairBinOmp<1,1,0,1>;
template class NPairBinOmp<1,1,1,1>;
template class NPairBinOmp<0,1,0,0,0>;
template class NPairBinOmp<1,0,0,0,0>;
template class NPairBinOmp<1,1,0,0,0>;
template class NPairBinOmp<1,1,1,0,0>;
template class NPairBinOmp<0,1,0,1,0>;
template class NPairBinOmp<1,0,0,1,0>;
template class NPairBinOmp<1,1,0,1,0>;
template class NPairBinOmp<1,1,1,1,0>;
template class NPairBinOmp<0,1,0,0,1>;
template class NPairBinOmp<1,0,0,0,1>;
template class NPairBinOmp<1,1,0,0,1>;
template class NPairBinOmp<1,1,1,0,1>;
template class NPairBinOmp<0,1,0,1,1>;
template class NPairBinOmp<1,0,0,1,1>;
template class NPairBinOmp<1,1,0,1,1>;
template class NPairBinOmp<1,1,1,1,1>;
}

View File

@ -13,47 +13,89 @@
#ifdef NPAIR_CLASS
// clang-format off
typedef NPairBinOmp<0, 1, 0, 0> NPairFullBinOmp;
typedef NPairBinOmp<0, 1, 0, 0, 0> NPairFullBinOmp;
NPairStyle(full/bin/omp,
NPairFullBinOmp,
NP_FULL | NP_BIN | NP_OMP | NP_MOLONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 0, 0, 0> NPairHalfBinNewtoffOmp;
typedef NPairBinOmp<1, 0, 0, 0, 0> NPairHalfBinNewtoffOmp;
NPairStyle(half/bin/newtoff/omp,
NPairHalfBinNewtoffOmp,
NP_HALF | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 1, 0, 0> NPairHalfBinNewtonOmp;
typedef NPairBinOmp<1, 1, 0, 0, 0> NPairHalfBinNewtonOmp;
NPairStyle(half/bin/newton/omp,
NPairHalfBinNewtonOmp,
NP_HALF | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBinOmp<1, 1, 1, 0> NPairHalfBinNewtonTriOmp;
typedef NPairBinOmp<1, 1, 1, 0, 0> NPairHalfBinNewtonTriOmp;
NPairStyle(half/bin/newton/tri/omp,
NPairHalfBinNewtonTriOmp,
NP_HALF | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_TRI);
typedef NPairBinOmp<0, 1, 0, 1> NPairFullSizeBinOmp;
typedef NPairBinOmp<0, 1, 0, 1, 0> NPairFullSizeBinOmp;
NPairStyle(full/size/bin/omp,
NPairFullSizeBinOmp,
NP_FULL | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 0, 0, 1> NPairHalfSizeBinNewtoffOmp;
typedef NPairBinOmp<1, 0, 0, 1, 0> NPairHalfSizeBinNewtoffOmp;
NPairStyle(half/size/bin/newtoff/omp,
NPairHalfSizeBinNewtoffOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 1, 0, 1> NPairHalfSizeBinNewtonOmp;
typedef NPairBinOmp<1, 1, 0, 1, 0> NPairHalfSizeBinNewtonOmp;
NPairStyle(half/size/bin/newton/omp,
NPairHalfSizeBinNewtonOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBinOmp<1, 1, 1, 1> NPairHalfSizeBinNewtonTriOmp;
typedef NPairBinOmp<1, 1, 1, 1, 0> NPairHalfSizeBinNewtonTriOmp;
NPairStyle(half/size/bin/newton/tri/omp,
NPairHalfSizeBinNewtonTriOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_TRI);
typedef NPairBinOmp<0, 1, 0, 0, 1> NPairFullBinAtomonlyOmp;
NPairStyle(full/bin/atomonly/omp,
NPairFullBinAtomonlyOmp,
NP_FULL | NP_BIN | NP_OMP | NP_ATOMONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 0, 0, 0, 1> NPairHalfBinNewtoffAtomonlyOmp;
NPairStyle(half/bin/newtoff/atomonly/omp,
NPairHalfBinNewtoffAtomonlyOmp,
NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 1, 0, 0, 1> NPairHalfBinNewtonAtomonlyOmp;
NPairStyle(half/bin/newton/atomonly/omp,
NPairHalfBinNewtonAtomonlyOmp,
NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBinOmp<1, 1, 1, 0, 1> NPairHalfBinNewtonTriAtomonlyOmp;
NPairStyle(half/bin/newton/tri/atomonly/omp,
NPairHalfBinNewtonTriAtomonlyOmp,
NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_TRI);
typedef NPairBinOmp<0, 1, 0, 1, 1> NPairFullSizeBinAtomonlyOmp;
NPairStyle(full/size/bin/atomonly/omp,
NPairFullSizeBinAtomonlyOmp,
NP_FULL | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 0, 0, 1, 1> NPairHalfSizeBinNewtoffAtomonlyOmp;
NPairStyle(half/size/bin/newtoff/atomonly/omp,
NPairHalfSizeBinNewtoffAtomonlyOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 1, 0, 1, 1> NPairHalfSizeBinNewtonAtomonlyOmp;
NPairStyle(half/size/bin/newton/atomonly/omp,
NPairHalfSizeBinNewtonAtomonlyOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBinOmp<1, 1, 1, 1, 1> NPairHalfSizeBinNewtonTriAtomonlyOmp;
NPairStyle(half/size/bin/newton/tri/atomonly/omp,
NPairHalfSizeBinNewtonTriAtomonlyOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_TRI);
// clang-format on
#else
@ -64,7 +106,7 @@ NPairStyle(half/size/bin/newton/tri/omp,
namespace LAMMPS_NS {
template<int HALF, int NEWTON, int TRI, int SIZE>
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
class NPairBinOmp : public NPair {
public:
NPairBinOmp(class LAMMPS *);

View File

@ -118,8 +118,8 @@ void NPairMultiOldOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
cutnsq = cutneighsq[itype];
ns = nstencil_multi_old[itype];
for (k = 0; k < ns; k++) {
bin_start = binhead[ibin+stencil[k]];
if (stencil[k] == 0) {
bin_start = binhead[ibin+s[k]];
if (s[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

View File

@ -30,8 +30,8 @@ using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE>
NPairMultiOmp<HALF, NEWTON, TRI, SIZE>::NPairMultiOmp(LAMMPS *lmp) : NPair(lmp) {}
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
NPairMultiOmp<HALF, NEWTON, TRI, SIZE, ATOMONLY>::NPairMultiOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
multi stencil is icollection-jcollection dependent
@ -49,8 +49,8 @@ NPairMultiOmp<HALF, NEWTON, TRI, SIZE>::NPairMultiOmp(LAMMPS *lmp) : NPair(lmp)
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE>
void NPairMultiOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
void NPairMultiOmp<HALF, NEWTON, TRI, SIZE, ATOMONLY>::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
@ -104,11 +104,13 @@ void NPairMultiOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (!ATOMONLY) {
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
}
ibin = atom2bin[i];
@ -214,6 +216,14 @@ void NPairMultiOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
cut = radsum + skin;
cutsq = cut * cut;
if (ATOMONLY) {
if (rsq <= cutsq) {
jh = j;
if (history && rsq < radsum * radsum)
jh = jh ^ mask_history;
neighptr[n++] = jh;
}
} else {
if (rsq <= cutsq) {
jh = j;
if (history && rsq < radsum * radsum)
@ -236,6 +246,10 @@ void NPairMultiOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
} else
neighptr[n++] = jh;
}
}
} else {
if (ATOMONLY) {
if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j;
} else {
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
@ -259,6 +273,7 @@ void NPairMultiOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
}
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
@ -272,12 +287,20 @@ void NPairMultiOmp<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
}
namespace LAMMPS_NS {
template class NPairMultiOmp<0,1,0,0>;
template class NPairMultiOmp<1,0,0,0>;
template class NPairMultiOmp<1,1,0,0>;
template class NPairMultiOmp<1,1,1,0>;
template class NPairMultiOmp<0,1,0,1>;
template class NPairMultiOmp<1,0,0,1>;
template class NPairMultiOmp<1,1,0,1>;
template class NPairMultiOmp<1,1,1,1>;
template class NPairMultiOmp<0,1,0,0,0>;
template class NPairMultiOmp<1,0,0,0,0>;
template class NPairMultiOmp<1,1,0,0,0>;
template class NPairMultiOmp<1,1,1,0,0>;
template class NPairMultiOmp<0,1,0,1,0>;
template class NPairMultiOmp<1,0,0,1,0>;
template class NPairMultiOmp<1,1,0,1,0>;
template class NPairMultiOmp<1,1,1,1,0>;
template class NPairMultiOmp<0,1,0,0,1>;
template class NPairMultiOmp<1,0,0,0,1>;
template class NPairMultiOmp<1,1,0,0,1>;
template class NPairMultiOmp<1,1,1,0,1>;
template class NPairMultiOmp<0,1,0,1,1>;
template class NPairMultiOmp<1,0,0,1,1>;
template class NPairMultiOmp<1,1,0,1,1>;
template class NPairMultiOmp<1,1,1,1,1>;
}

View File

@ -13,45 +13,85 @@
#ifdef NPAIR_CLASS
// clang-format off
typedef NPairMultiOmp<0, 1, 0, 0> NPairFullMultiOmp;
typedef NPairMultiOmp<0, 1, 0, 0, 0> NPairFullMultiOmp;
NPairStyle(full/multi/omp,
NPairFullMultiOmp,
NP_FULL | NP_MULTI | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
NP_FULL | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMultiOmp<1, 0, 0, 0> NPairHalfMultiNewtoffOmp;
typedef NPairMultiOmp<1, 0, 0, 0, 0> NPairHalfMultiNewtoffOmp;
NPairStyle(half/multi/newtoff/omp,
NPairHalfMultiNewtoffOmp,
NP_HALF | NP_MULTI | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI);
NP_HALF | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMultiOmp<1, 1, 0, 0> NPairHalfMultiNewtonOmp;
typedef NPairMultiOmp<1, 1, 0, 0, 0> NPairHalfMultiNewtonOmp;
NPairStyle(half/multi/newton/omp,
NPairHalfMultiNewtonOmp,
NP_HALF | NP_MULTI | NP_OMP | NP_NEWTON | NP_ORTHO);
NP_HALF | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_ORTHO);
typedef NPairMultiOmp<1, 1, 1, 0> NPairHalfMultiNewtonTriOmp;
typedef NPairMultiOmp<1, 1, 1, 0, 0> NPairHalfMultiNewtonTriOmp;
NPairStyle(half/multi/newton/tri/omp,
NPairHalfMultiNewtonTriOmp,
NP_HALF | NP_MULTI | NP_OMP | NP_NEWTON | NP_TRI);
NP_HALF | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_TRI);
typedef NPairMultiOmp<0, 1, 0, 1> NPairFullSizeMultiOmp;
typedef NPairMultiOmp<0, 1, 0, 1, 0> NPairFullSizeMultiOmp;
NPairStyle(full/size/multi/omp,
NPairFullSizeMultiOmp,
NP_FULL | NP_SIZE | NP_MULTI | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
NP_FULL | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMultiOmp<1, 0, 0, 1> NPairHalfSizeMultiNewtoffOmp;
typedef NPairMultiOmp<1, 0, 0, 1, 0> NPairHalfSizeMultiNewtoffOmp;
NPairStyle(half/size/multi/newtoff/omp,
NPairHalfSizeMultiNewtoffOmp,
NP_HALF | NP_SIZE | NP_MULTI | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI);
NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMultiOmp<1, 1, 0, 1> NPairHalfSizeMultiNewtonOmp;
typedef NPairMultiOmp<1, 1, 0, 1, 0> NPairHalfSizeMultiNewtonOmp;
NPairStyle(half/size/multi/newton/omp,
NPairHalfSizeMultiNewtonOmp,
NP_HALF | NP_SIZE | NP_MULTI | NP_OMP | NP_NEWTON | NP_ORTHO);
NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_ORTHO);
typedef NPairMultiOmp<1, 1, 1, 1> NPairHalfSizeMultiNewtonTriOmp;
typedef NPairMultiOmp<1, 1, 1, 1, 0> NPairHalfSizeMultiNewtonTriOmp;
NPairStyle(half/size/multi/newton/tri/omp,
NPairHalfSizeMultiNewtonTriOmp,
NP_HALF | NP_SIZE | NP_MULTI | NP_OMP | NP_NEWTON | NP_TRI);
NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_OMP | NP_NEWTON | NP_TRI);
typedef NPairMultiOmp<0, 1, 0, 0, 1> NPairFullMultiAtomonlyOmp;
NPairStyle(full/multi/atomonly/omp,
NPairFullMultiAtomonlyOmp,
NP_FULL | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMultiOmp<1, 0, 0, 0, 1> NPairHalfMultiAtomonlyNewtoffOmp;
NPairStyle(half/multi/atomonly/newtoff/omp,
NPairHalfMultiAtomonlyNewtoffOmp,
NP_HALF | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMultiOmp<1, 1, 0, 0, 1> NPairHalfMultiAtomonlyNewtonOmp;
NPairStyle(half/multi/atomonly/newton/omp,
NPairHalfMultiAtomonlyNewtonOmp,
NP_HALF | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_ORTHO);
typedef NPairMultiOmp<1, 1, 1, 0, 1> NPairHalfMultiAtomonlyNewtonTriOmp;
NPairStyle(half/multi/atomonly/newton/tri/omp,
NPairHalfMultiAtomonlyNewtonTriOmp,
NP_HALF | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_TRI);
typedef NPairMultiOmp<0, 1, 0, 1, 1> NPairFullSizeMultiAtomonlyOmp;
NPairStyle(full/size/multi/atomonly/omp,
NPairFullSizeMultiAtomonlyOmp,
NP_FULL | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMultiOmp<1, 0, 0, 1, 1> NPairHalfSizeMultiAtomonlyNewtoffOmp;
NPairStyle(half/size/multi/atomonly/newtoff/omp,
NPairHalfSizeMultiAtomonlyNewtoffOmp,
NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMultiOmp<1, 1, 0, 1, 1> NPairHalfSizeMultiAtomonlyNewtonOmp;
NPairStyle(half/size/multi/atomonly/newton/omp,
NPairHalfSizeMultiAtomonlyNewtonOmp,
NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_ORTHO);
typedef NPairMultiOmp<1, 1, 1, 1, 1> NPairHalfSizeMultiAtomonlyNewtonTriOmp;
NPairStyle(half/size/multi/atomonly/newton/tri/omp,
NPairHalfSizeMultiAtomonlyNewtonTriOmp,
NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_OMP | NP_NEWTON | NP_TRI);
// clang-format on
#else
@ -62,7 +102,7 @@ NPairStyle(half/size/multi/newton/tri/omp,
namespace LAMMPS_NS {
template<int HALF, int NEWTON, int TRI, int SIZE>
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
class NPairMultiOmp : public NPair {
public:
NPairMultiOmp(class LAMMPS *);

View File

@ -134,8 +134,8 @@ void NPairRespaBinOmp<NEWTON, TRI>::build(NeighList *list)
for (k = 0; k < nstencil; k++) {
bin_start = binhead[ibin+stencil[k]];
if (stencil[k] == 0) {
if (NEWTON && (!TRI)) {
if (stencil[k] == 0) {
// 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];

View File

@ -28,8 +28,8 @@ using namespace NeighConst;
/* ---------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE>
NPairBin<HALF, NEWTON, TRI, SIZE>::NPairBin(LAMMPS *lmp) : NPair(lmp) {}
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
NPairBin<HALF, NEWTON, TRI, SIZE, ATOMONLY>::NPairBin(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
Full:
@ -46,8 +46,8 @@ NPairBin<HALF, NEWTON, TRI, SIZE>::NPairBin(LAMMPS *lmp) : NPair(lmp) {}
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE>
void NPairBin<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
void NPairBin<HALF, NEWTON, TRI, SIZE, ATOMONLY>::build(NeighList *list)
{
int i, j, jh, k, n, itype, jtype, ibin, bin_start, which, imol, iatom, moltemplate;
tagint itag, jtag, tagprev;
@ -70,10 +70,12 @@ void NPairBin<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
if (!ATOMONLY) {
if (molecular == Atom::TEMPLATE)
moltemplate = 1;
else
moltemplate = 0;
}
int history = list->history;
int mask_history = 1 << HISTBITS;
@ -95,18 +97,20 @@ void NPairBin<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (!ATOMONLY) {
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)) {
if (stencil[k] == 0) {
// 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];
@ -177,9 +181,17 @@ void NPairBin<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
cut = radsum + skin;
cutsq = cut * cut;
if (ATOMONLY) {
if (rsq <= cutsq) {
jh = j;
if (history && rsq < radsum * radsum)
if (history && rsq < (radsum * radsum))
jh = jh ^ mask_history;
neighptr[n++] = jh;
}
} else {
if (rsq <= cutsq) {
jh = j;
if (history && rsq < (radsum * radsum))
jh = jh ^ mask_history;
if (molecular != Atom::ATOMIC) {
@ -199,6 +211,10 @@ void NPairBin<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
} else
neighptr[n++] = jh;
}
}
} else {
if (ATOMONLY) {
if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j;
} else {
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
@ -221,6 +237,7 @@ void NPairBin<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
}
}
}
}
ilist[inum++] = i;
firstneigh[i] = neighptr;
@ -234,12 +251,20 @@ void NPairBin<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
}
namespace LAMMPS_NS {
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>;
template class NPairBin<0,1,0,0,0>;
template class NPairBin<1,0,0,0,0>;
template class NPairBin<1,1,0,0,0>;
template class NPairBin<1,1,1,0,0>;
template class NPairBin<0,1,0,1,0>;
template class NPairBin<1,0,0,1,0>;
template class NPairBin<1,1,0,1,0>;
template class NPairBin<1,1,1,1,0>;
template class NPairBin<0,1,0,0,1>;
template class NPairBin<1,0,0,0,1>;
template class NPairBin<1,1,0,0,1>;
template class NPairBin<1,1,1,0,1>;
template class NPairBin<0,1,0,1,1>;
template class NPairBin<1,0,0,1,1>;
template class NPairBin<1,1,0,1,1>;
template class NPairBin<1,1,1,1,1>;
}

View File

@ -13,47 +13,83 @@
#ifdef NPAIR_CLASS
// clang-format off
typedef NPairBin<0, 1, 0, 0> NPairFullBin;
typedef NPairBin<0, 1, 0, 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, 0> NPairHalfBinNewtoff;
typedef NPairBin<1, 0, 0, 0, 0> NPairHalfBinNewtoff;
NPairStyle(half/bin/newtoff,
NPairHalfBinNewtoff,
NP_HALF | NP_BIN | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBin<1, 1, 0, 0> NPairHalfBinNewton;
typedef NPairBin<1, 1, 0, 0, 0> NPairHalfBinNewton;
NPairStyle(half/bin/newton,
NPairHalfBinNewton,
NP_HALF | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBin<1, 1, 1, 0> NPairHalfBinNewtonTri;
typedef NPairBin<1, 1, 1, 0, 0> NPairHalfBinNewtonTri;
NPairStyle(half/bin/newton/tri,
NPairHalfBinNewtonTri,
NP_HALF | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_TRI);
typedef NPairBin<0, 1, 0, 1> NPairFullSizeBin;
typedef NPairBin<0, 1, 0, 1, 0> 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;
typedef NPairBin<1, 0, 0, 1, 0> 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;
typedef NPairBin<1, 1, 0, 1, 0> 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;
typedef NPairBin<1, 1, 1, 1, 0> NPairHalfSizeBinNewtonTri;
NPairStyle(half/size/bin/newton/tri,
NPairHalfSizeBinNewtonTri,
NP_HALF | NP_SIZE | NP_BIN | NP_MOLONLY | NP_NEWTON | NP_TRI);
typedef NPairBin<1, 0, 0, 0, 1> NPairHalfBinAtomonlyNewtoff;
NPairStyle(half/bin/atomonly/newtoff,
NPairHalfBinAtomonlyNewtoff,
NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBin<1, 1, 0, 0, 1> NPairHalfBinAtomonlyNewton;
NPairStyle(half/bin/atomonly/newton,
NPairHalfBinAtomonlyNewton,
NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBin<1, 1, 1, 0, 1> NPairHalfBinAtomonlyNewtonTri;
NPairStyle(half/bin/atomonly/newton/tri,
NPairHalfBinAtomonlyNewtonTri,
NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_TRI);
typedef NPairBin<0, 1, 0, 1, 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 NPairBin<1, 0, 0, 1, 1> NPairHalfSizeBinAtomonlyNewtoff;
NPairStyle(half/size/bin/atomonly/newtoff,
NPairHalfSizeBinAtomonlyNewtoff,
NP_HALF | NP_SIZE | NP_BIN | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBin<1, 1, 0, 1, 1> NPairHalfSizeBinAtomonlyNewton;
NPairStyle(half/size/bin/atomonly/newton,
NPairHalfSizeBinAtomonlyNewton,
NP_HALF | NP_SIZE | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBin<1, 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
@ -64,7 +100,7 @@ NPairStyle(half/size/bin/newton/tri,
namespace LAMMPS_NS {
template<int HALF, int NEWTON, int TRI, int SIZE>
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
class NPairBin : public NPair {
public:
NPairBin(class LAMMPS *);

View File

@ -1,180 +0,0 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
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_atomonly.h"
#include "atom.h"
#include "error.h"
#include "neighbor.h"
#include "my_page.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
using namespace NeighConst;
/* ---------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE>
NPairBinAtomonly<HALF, NEWTON, TRI, SIZE>::NPairBinAtomonly(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
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<int HALF, int NEWTON, int TRI, int SIZE>
void NPairBinAtomonly<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
{
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;
MyPage<int> *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];
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 = 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 (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;
neighptr[n++] = jh;
}
} else {
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 = inum;
if (!HALF) list->gnum = 0;
}
namespace LAMMPS_NS {
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>;
}

View File

@ -1,77 +0,0 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
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 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, 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
#ifndef LMP_NPAIR_BIN_ATOMONLY_H
#define LMP_NPAIR_BIN_ATOMONLY_H
#include "npair.h"
namespace LAMMPS_NS {
template<int HALF, int NEWTON, int TRI, int SIZE>
class NPairBinAtomonly : public NPair {
public:
NPairBinAtomonly(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -29,8 +29,8 @@ using namespace NeighConst;
/* ---------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE>
NPairMulti<HALF, NEWTON, TRI, SIZE>::NPairMulti(LAMMPS *lmp) : NPair(lmp) {}
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
NPairMulti<HALF, NEWTON, TRI, SIZE, ATOMONLY>::NPairMulti(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
multi stencil is icollection-jcollection dependent
@ -48,8 +48,8 @@ NPairMulti<HALF, NEWTON, TRI, SIZE>::NPairMulti(LAMMPS *lmp) : NPair(lmp) {}
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE>
void NPairMulti<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
void NPairMulti<HALF, NEWTON, TRI, SIZE, ATOMONLY>::build(NeighList *list)
{
int i, j, jh, js, k, n, itype, jtype, ibin, jbin, icollection, jcollection, which, ns, imol, iatom, moltemplate;
tagint itag, jtag, tagprev;
@ -73,10 +73,12 @@ void NPairMulti<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
if (!ATOMONLY) {
if (molecular == Atom::TEMPLATE)
moltemplate = 1;
else
moltemplate = 0;
}
int history = list->history;
int mask_history = 1 << HISTBITS;
@ -99,11 +101,13 @@ void NPairMulti<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (!ATOMONLY) {
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
}
ibin = atom2bin[i];
@ -209,6 +213,14 @@ void NPairMulti<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
cut = radsum + skin;
cutsq = cut * cut;
if (ATOMONLY) {
if (rsq <= cutsq) {
jh = j;
if (history && rsq < (radsum * radsum))
jh = jh ^ mask_history;
neighptr[n++] = jh;
}
} else {
if (rsq <= cutsq) {
jh = j;
if (history && rsq < radsum * radsum)
@ -231,6 +243,10 @@ void NPairMulti<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
} else
neighptr[n++] = jh;
}
}
} else {
if (ATOMONLY) {
if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j;
} else {
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
@ -254,6 +270,7 @@ void NPairMulti<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
}
}
}
}
ilist[inum++] = i;
firstneigh[i] = neighptr;
@ -267,12 +284,20 @@ void NPairMulti<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
}
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>;
template class NPairMulti<0,1,0,0,0>;
template class NPairMulti<1,0,0,0,0>;
template class NPairMulti<1,1,0,0,0>;
template class NPairMulti<1,1,1,0,0>;
template class NPairMulti<0,1,0,1,0>;
template class NPairMulti<1,0,0,1,0>;
template class NPairMulti<1,1,0,1,0>;
template class NPairMulti<1,1,1,1,0>;
template class NPairMulti<0,1,0,0,1>;
template class NPairMulti<1,0,0,0,1>;
template class NPairMulti<1,1,0,0,1>;
template class NPairMulti<1,1,1,0,1>;
template class NPairMulti<0,1,0,1,1>;
template class NPairMulti<1,0,0,1,1>;
template class NPairMulti<1,1,0,1,1>;
template class NPairMulti<1,1,1,1,1>;
}

View File

@ -13,47 +13,89 @@
#ifdef NPAIR_CLASS
// clang-format off
typedef NPairMulti<0, 1, 0, 0> NPairFullMulti;
typedef NPairMulti<0, 1, 0, 0, 0> NPairFullMulti;
NPairStyle(full/multi,
NPairFullMulti,
NP_FULL | NP_MULTI |
NP_FULL | NP_MULTI | NP_MOLONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMulti<1, 0, 0, 0> NPairHalfMultiNewtoff;
typedef NPairMulti<1, 0, 0, 0, 0> NPairHalfMultiNewtoff;
NPairStyle(half/multi/newtoff,
NPairHalfMultiNewtoff,
NP_HALF | NP_MULTI | NP_NEWTOFF | NP_ORTHO | NP_TRI);
NP_HALF | NP_MULTI | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMulti<1, 1, 0, 0> NPairHalfMultiNewton;
typedef NPairMulti<1, 1, 0, 0, 0> NPairHalfMultiNewton;
NPairStyle(half/multi/newton,
NPairHalfMultiNewton,
NP_HALF | NP_MULTI | NP_NEWTON | NP_ORTHO);
NP_HALF | NP_MULTI | NP_MOLONLY | NP_NEWTON | NP_ORTHO);
typedef NPairMulti<1, 1, 1, 0> NPairHalfMultiNewtonTri;
typedef NPairMulti<1, 1, 1, 0, 0> NPairHalfMultiNewtonTri;
NPairStyle(half/multi/newton/tri,
NPairHalfMultiNewtonTri,
NP_HALF | NP_MULTI | NP_NEWTON | NP_TRI);
NP_HALF | NP_MULTI | NP_MOLONLY | NP_NEWTON | NP_TRI);
typedef NPairMulti<0, 1, 0, 1> NPairFullSizeMulti;
typedef NPairMulti<0, 1, 0, 1, 0> NPairFullSizeMulti;
NPairStyle(full/size/multi,
NPairFullSizeMulti,
NP_FULL | NP_SIZE | NP_MULTI |
NP_FULL | NP_SIZE | NP_MULTI | NP_MOLONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMulti<1, 0, 0, 1> NPairHalfSizeMultiNewtoff;
typedef NPairMulti<1, 0, 0, 1, 0> NPairHalfSizeMultiNewtoff;
NPairStyle(half/size/multi/newtoff,
NPairHalfSizeMultiNewtoff,
NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTOFF | NP_ORTHO | NP_TRI);
NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMulti<1, 1, 0, 1> NPairHalfSizeMultiNewton;
typedef NPairMulti<1, 1, 0, 1, 0> NPairHalfSizeMultiNewton;
NPairStyle(half/size/multi/newton,
NPairHalfSizeMultiNewton,
NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTON | NP_ORTHO);
NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_NEWTON | NP_ORTHO);
typedef NPairMulti<1, 1, 1, 1> NPairHalfSizeMultiNewtonTri;
typedef NPairMulti<1, 1, 1, 1, 0> NPairHalfSizeMultiNewtonTri;
NPairStyle(half/size/multi/newton/tri,
NPairHalfSizeMultiNewtonTri,
NP_HALF | NP_SIZE | NP_MULTI | NP_NEWTON | NP_TRI);
NP_HALF | NP_SIZE | NP_MULTI | NP_MOLONLY | NP_NEWTON | NP_TRI);
typedef NPairMulti<0, 1, 0, 0, 1> NPairFullMultiAtomonly;
NPairStyle(full/multi/atomonly,
NPairFullMultiAtomonly,
NP_FULL | NP_MULTI | NP_ATOMONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMulti<1, 0, 0, 0, 1> NPairHalfMultiAtomonlyNewtoff;
NPairStyle(half/multi/atomonly/newtoff,
NPairHalfMultiAtomonlyNewtoff,
NP_HALF | NP_MULTI | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMulti<1, 1, 0, 0, 1> NPairHalfMultiAtomonlyNewton;
NPairStyle(half/multi/atomonly/newton,
NPairHalfMultiAtomonlyNewton,
NP_HALF | NP_MULTI | NP_ATOMONLY | NP_NEWTON | NP_ORTHO);
typedef NPairMulti<1, 1, 1, 0, 1> NPairHalfMultiAtomonlyNewtonTri;
NPairStyle(half/multi/atomonly/newton/tri,
NPairHalfMultiAtomonlyNewtonTri,
NP_HALF | NP_MULTI | NP_ATOMONLY | NP_NEWTON | NP_TRI);
typedef NPairMulti<0, 1, 0, 1, 1> NPairFullSizeMultiAtomonly;
NPairStyle(full/size/multi/atomonly,
NPairFullSizeMultiAtomonly,
NP_FULL | NP_SIZE | NP_MULTI | NP_ATOMONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMulti<1, 0, 0, 1, 1> NPairHalfSizeMultiAtomonlyNewtoff;
NPairStyle(half/size/multi/atomonly/newtoff,
NPairHalfSizeMultiAtomonlyNewtoff,
NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairMulti<1, 1, 0, 1, 1> NPairHalfSizeMultiAtomonlyNewton;
NPairStyle(half/size/multi/atomonly/newton,
NPairHalfSizeMultiAtomonlyNewton,
NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_NEWTON | NP_ORTHO);
typedef NPairMulti<1, 1, 1, 1, 1> NPairHalfSizeMultiAtomonlyNewtonTri;
NPairStyle(half/size/multi/atomonly/newton/tri,
NPairHalfSizeMultiAtomonlyNewtonTri,
NP_HALF | NP_SIZE | NP_MULTI | NP_ATOMONLY | NP_NEWTON | NP_TRI);
// clang-format on
#else
@ -64,7 +106,7 @@ NPairStyle(half/size/multi/newton/tri,
namespace LAMMPS_NS {
template<int HALF, int NEWTON, int TRI, int SIZE>
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
class NPairMulti : public NPair {
public:
NPairMulti(class LAMMPS *);

View File

@ -111,9 +111,9 @@ void NPairMultiOld<HALF, NEWTON, TRI, SIZE>::build(NeighList *list)
cutnsq = cutneighsq[itype];
ns = nstencil_multi_old[itype];
for (k = 0; k < ns; k++) {
bin_start = binhead[ibin+stencil[k]];
if (stencil[k] == 0) {
bin_start = binhead[ibin + s[k]];
if (HALF && NEWTON && (!TRI)) {
if (s[k] == 0) {
// 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];

View File

@ -122,8 +122,8 @@ void NPairRespaBin<NEWTON, TRI>::build(NeighList *list)
for (k = 0; k < nstencil; k++) {
bin_start = binhead[ibin+stencil[k]];
if (stencil[k] == 0) {
if (NEWTON && (!TRI)) {
if (stencil[k] == 0) {
// 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];

View File

@ -69,7 +69,7 @@ void NStencilMultiOld<HALF, DIM_3D, TRI>::create()
if (HALF && DIM_3D && (!TRI))
if (! (k > 0 || j > 0 || (j == 0 && i > 0))) continue;
rsq = bin_distance(i, j, 0);
rsq = bin_distance(i, j, k);
if (rsq < typesq) {
distsq[n] = rsq;
s[n++] = k * mbiny * mbinx + j * mbinx + i;