diff --git a/src/comm.cpp b/src/comm.cpp index b6f905d9a2..ad0c836432 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -76,7 +76,7 @@ Comm::Comm(LAMMPS *lmp) : Pointers(lmp) grid2proc = nullptr; xsplit = ysplit = zsplit = nullptr; rcbnew = 0; - multi_tiered = 0; + multi2 = 0; // use of OpenMP threads // query OpenMP for number of threads/process set by user at run-time @@ -242,9 +242,9 @@ void Comm::init() for (int i = 0; i < nfix; i++) if (fix[i]->maxexchange_dynamic) maxexchange_fix_dynamic = 1; - // Can't used multi/tiered communication with Newton off - if (force->newton == 0 && multi_tiered) - error->all(FLERR,"Cannot use multi/tiered communication with Newton off"); + // Can't used multi2 communication with Newton off + if (force->newton == 0 && multi2) + error->all(FLERR,"Cannot use multi2 communication with Newton off"); } /* ---------------------------------------------------------------------- @@ -331,10 +331,10 @@ void Comm::modify_params(int narg, char **arg) for (i=nlo; i<=nhi; ++i) cutusermulti[i] = cut; iarg += 3; - } else if (strcmp(arg[iarg],"cutoff/tiered") == 0) { + } else if (strcmp(arg[iarg],"cutoff/multi2") == 0) { if (mode == Comm::SINGLE) - error->all(FLERR,"Use cutoff/tiered in mode multi only"); - multi_tiered = 1; + error->all(FLERR,"Use cutoff/multi2 in mode multi only"); + multi2 = 1; iarg += 1; } else if (strcmp(arg[iarg],"vel") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal comm_modify command"); diff --git a/src/comm.h b/src/comm.h index 037eaab348..d8d842ace5 100644 --- a/src/comm.h +++ b/src/comm.h @@ -161,7 +161,7 @@ class Comm : protected Pointers { int (*)(int, char *, int &, int *&, char *&, void *), int, char *&, int, void *, int); void rendezvous_stats(int, int, int, int, int, int, bigint); - int multi_tiered; // 1 if multi cutoff is intra-type cutoff + int multi2; // 1 if multi cutoff is intra-type cutoff public: enum{MULTIPLE}; diff --git a/src/comm_brick.cpp b/src/comm_brick.cpp index c9fd00e9f5..981e86c2a4 100644 --- a/src/comm_brick.cpp +++ b/src/comm_brick.cpp @@ -174,8 +174,8 @@ void CommBrick::setup() cutghost[0] = cutghost[1] = cutghost[2] = cut; if (mode == Comm::MULTI) { - if (multi_tiered) { - // If using tiered binlists, use the itype-itype interaction distance for communication + if (multi2) { + // If using multi2 binlists, use the itype-itype interaction distance for communication double **cutneighsq = neighbor->cutneighsq; for (i = 1; i <= ntypes; i++) { cut = 0.0; diff --git a/src/comm_tiled.cpp b/src/comm_tiled.cpp index b82d54b3ab..16ae86b4a3 100644 --- a/src/comm_tiled.cpp +++ b/src/comm_tiled.cpp @@ -176,8 +176,8 @@ void CommTiled::setup() if (mode == Comm::MULTI) { double cut; - if (multi_tiered) { - // If using tiered binlists, use the itype-itype interaction distance for communication + if (multi2) { + // If using multi2 binlists, use the itype-itype interaction distance for communication double **cutneighsq = neighbor->cutneighsq; for (i = 1; i <= ntypes; i++) { cut = 0.0; diff --git a/src/nbin.cpp b/src/nbin.cpp index 64ae7e7b83..4ab3270287 100644 --- a/src/nbin.cpp +++ b/src/nbin.cpp @@ -31,6 +31,21 @@ NBin::NBin(LAMMPS *lmp) : Pointers(lmp) bins = nullptr; atom2bin = nullptr; + nbinx_tiered = nullptr; nbiny_tiered = nullptr; nbinz_tiered = nullptr; + mbins_tiered = nullptr; + mbinx_tiered = nullptr; mbiny_tiered = nullptr, mbinz_tiered = nullptr; + mbinxlo_tiered = nullptr; + mbinylo_tiered = nullptr; + mbinzlo_tiered = nullptr; + binsizex_tiered = nullptr; binsizey_tiered = nullptr; binsizez_tiered = nullptr; + bininvx_tiered = nullptr; bininvy_tiered = nullptr; bininvz_tiered = nullptr; + binhead_tiered = nullptr; + bins_tiered = nullptr; + atom2bin_tiered = nullptr; + maxbins_tiered = nullptr; + + maxtypes = 0; + neighbor->last_setup_bins = -1; // geometry settings @@ -48,6 +63,37 @@ NBin::~NBin() memory->destroy(binhead); memory->destroy(bins); memory->destroy(atom2bin); + + if (!bins_tiered) return; + + memory->destroy(nbinx_tiered); + memory->destroy(nbiny_tiered); + memory->destroy(nbinz_tiered); + memory->destroy(mbins_tiered); + memory->destroy(mbinx_tiered); + memory->destroy(mbiny_tiered); + memory->destroy(mbinz_tiered); + memory->destroy(mbinxlo_tiered); + memory->destroy(mbinylo_tiered); + memory->destroy(mbinzlo_tiered); + + memory->destroy(binsizex_tiered); + memory->destroy(binsizey_tiered); + memory->destroy(binsizez_tiered); + memory->destroy(bininvx_tiered); + memory->destroy(bininvy_tiered); + memory->destroy(bininvz_tiered); + + for (int n = 1; n <= maxtypes; n++) { + memory->destroy(binhead_tiered[n]); + memory->destroy(bins_tiered[n]); + memory->destroy(atom2bin_tiered[n]); + } + delete [] binhead_tiered; + delete [] bins_tiered; + delete [] atom2bin_tiered; + + memory->destroy(maxbins_tiered); } /* ---------------------------------------------------------------------- */ @@ -77,95 +123,3 @@ void NBin::copy_neighbor_info() if (cutoff_custom > 0.0) cutneighmax = cutoff_custom; } - -/* ---------------------------------------------------------------------- - setup for bin_atoms() -------------------------------------------------------------------------- */ - -void NBin::bin_atoms_setup(int nall) -{ - // binhead = per-bin vector, mbins in length - // add 1 bin for USER-INTEL package - - if (mbins > maxbin) { - maxbin = mbins; - memory->destroy(binhead); - memory->create(binhead,maxbin,"neigh:binhead"); - } - - // bins and atom2bin = per-atom vectors - // for both local and ghost atoms - - if (nall > maxatom) { - maxatom = nall; - memory->destroy(bins); - memory->create(bins,maxatom,"neigh:bins"); - memory->destroy(atom2bin); - memory->create(atom2bin,maxatom,"neigh:atom2bin"); - } -} - -/* ---------------------------------------------------------------------- - convert atom coords into local bin # - for orthogonal, only ghost atoms will have coord >= bboxhi or coord < bboxlo - take special care to insure ghosts are in correct bins even w/ roundoff - hi ghost atoms = nbin,nbin+1,etc - owned atoms = 0 to nbin-1 - lo ghost atoms = -1,-2,etc - this is necessary so that both procs on either side of PBC - treat a pair of atoms straddling the PBC in a consistent way - for triclinic, doesn't matter since stencil & neigh list built differently -------------------------------------------------------------------------- */ - -int NBin::coord2bin(double *x) -{ - int ix,iy,iz; - - if (!std::isfinite(x[0]) || !std::isfinite(x[1]) || !std::isfinite(x[2])) - error->one(FLERR,"Non-numeric positions - simulation unstable"); - - if (x[0] >= bboxhi[0]) - ix = static_cast ((x[0]-bboxhi[0])*bininvx) + nbinx; - else if (x[0] >= bboxlo[0]) { - ix = static_cast ((x[0]-bboxlo[0])*bininvx); - ix = MIN(ix,nbinx-1); - } else - ix = static_cast ((x[0]-bboxlo[0])*bininvx) - 1; - - if (x[1] >= bboxhi[1]) - iy = static_cast ((x[1]-bboxhi[1])*bininvy) + nbiny; - else if (x[1] >= bboxlo[1]) { - iy = static_cast ((x[1]-bboxlo[1])*bininvy); - iy = MIN(iy,nbiny-1); - } else - iy = static_cast ((x[1]-bboxlo[1])*bininvy) - 1; - - if (x[2] >= bboxhi[2]) - iz = static_cast ((x[2]-bboxhi[2])*bininvz) + nbinz; - else if (x[2] >= bboxlo[2]) { - iz = static_cast ((x[2]-bboxlo[2])*bininvz); - iz = MIN(iz,nbinz-1); - } else - iz = static_cast ((x[2]-bboxlo[2])*bininvz) - 1; - - return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); -} -/* ---------------------------------------------------------------------- - to be overridden by NBinType - ------------------------------------------------------------------------- */ - -int NBin::coord2bin(double * x, int itype) -{ - error->all(FLERR,"coord2bin(x, itype) not available.\n"); - return -1; -} - -/* ---------------------------------------------------------------------- */ - -double NBin::memory_usage() -{ - double bytes = 0; - bytes += maxbin*sizeof(int); - bytes += 2*maxatom*sizeof(int); - return bytes; -} diff --git a/src/nbin.h b/src/nbin.h index 96cc7eac64..33b93ef79c 100644 --- a/src/nbin.h +++ b/src/nbin.h @@ -22,6 +22,9 @@ class NBin : protected Pointers { public: int istyle; // 1-N index into binnames bigint last_bin; // last timestep atoms were binned + double cutoff_custom; // cutoff set by requestor + + // Variables for NBinStandard int nbinx,nbiny,nbinz; // # of global bins int mbins; // # of local bins and offset on this proc @@ -35,35 +38,32 @@ class NBin : protected Pointers { int *bins; // index of next atom in same bin int *atom2bin; // bin assignment for each atom (local+ghost) - double cutoff_custom; // cutoff set by requestor - - // Analogues for NBinType - int * nbinx_type, * nbiny_type, * nbinz_type; - int * mbins_type; - int * mbinx_type, * mbiny_type, * mbinz_type; - int * mbinxlo_type, * mbinylo_type, * mbinzlo_type; - double * binsizex_type, * binsizey_type, * binsizez_type; - double * bininvx_type, * bininvy_type, * bininvz_type; - - int ** binhead_type; - int ** bins_type; - int ** atom2bin_type; + // Analogues for NBinMultimulti2 + + int *nbinx_multi2, *nbiny_multi2, *nbinz_multi2; + int *mbins_multi2; + int *mbinx_multi2, *mbiny_multi2, *mbinz_multi2; + int *mbinxlo_multi2, *mbinylo_multi2, *mbinzlo_multi2; + double *binsizex_multi2, *binsizey_multi2, *binsizez_multi2; + double *bininvx_multi2, *bininvy_multi2, *bininvz_multi2; + int **binhead_multi2; + int **bins_multi2; + int **atom2bin_multi2; + NBin(class LAMMPS *); ~NBin(); void post_constructor(class NeighRequest *); virtual void copy_neighbor_info(); - virtual void bin_atoms_setup(int); - double memory_usage(); + virtual void bin_atoms_setup(int) = 0; virtual void setup_bins(int) = 0; virtual void bin_atoms() = 0; + virtual double memory_usage() {return 0.0;} // Kokkos package int kokkos; // 1 if class stores Kokkos data - // For NBinType - virtual int coord2bin(double *, int); protected: @@ -81,12 +81,23 @@ class NBin : protected Pointers { int dimension; int triclinic; - int maxbin; // size of binhead array + // data for standard NBin + int maxatom; // size of bins array + // data for standard NBin + + int maxbin; // size of binhead array + + // data for multi/multi2 NBin + + int maxtypes; // size of multi2 arrays + int * maxbins_multi2; // size of 2nd dimension of binhead_multi2 array + // methods int coord2bin(double *); + int coord2bin(double *, int); }; } diff --git a/src/nbin_multi2.cpp b/src/nbin_multi2.cpp new file mode 100644 index 0000000000..7a87ba940c --- /dev/null +++ b/src/nbin_multi2.cpp @@ -0,0 +1,414 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, 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 "nbin_multi2.h" +#include "neighbor.h" +#include "atom.h" +#include "group.h" +#include "domain.h" +#include "comm.h" +#include "update.h" +#include "error.h" +#include "memory.h" + +using namespace LAMMPS_NS; + +#define SMALL 1.0e-6 +#define CUT2BIN_RATIO 100 + +/* ---------------------------------------------------------------------- */ + +NBinMulti2::NBinMulti2(LAMMPS *lmp) : NBin(lmp) {} + +/* ---------------------------------------------------------------------- + setup for bin_atoms() +------------------------------------------------------------------------- */ + +void NBinMulti2::bin_atoms_setup(int nall) +{ + // binhead_multi2[n] = per-bin vector mbins in length mbins_multi2[n] + + for (int n = 1; n <= maxtypes; n++) { + if (mbins_multi2[n] > maxbins_multi2[n]) { + maxbins_multi2[n] = mbins_multi2[n]; + memory->destroy(binhead_multi2[n]); + memory->create(binhead_multi2[n], mbins_multi2[n], "neigh:mbins_multi2"); + } + } + + // bins_multi2[n] and atom2bin_multi2[n] = per-atom vectors + // for both local and ghost atoms + + if (nall > maxatom) { + maxatom = nall; + for (int n = 1; n <= maxtypes; n++) { + memory->destroy(bins_multi2[n]); + memory->destroy(atom2bin_multi2[n]); + memory->create(bins_multi2[n], maxatom, "neigh:bin_multi2"); + memory->create(atom2bin_multi2[n], maxatom, "neigh:atom2bin_multi2"); + } + } +} + +/* --------------------------------------------------------------------- + Identify index of type with smallest cutoff +------------------------------------------------------------------------ */ + +int NBinMulti2::itype_min() { + + int itypemin = 1; + double ** cutneighsq; + + cutneighsq = neighbor->cutneighsq; + + for (int n = 1; n <= atom->ntypes; n++) { + if (cutneighsq[n][n] < cutneighsq[itypemin][itypemin]) { + itypemin = n; + } + } + + return itypemin; +} + +/* ---------------------------------------------------------------------- + setup neighbor binning geometry + ---------------------------------------------------------------------- */ + +void NBinMulti2::setup_bins(int style) +{ + int n; + int itypemin; + + // Initialize arrays + + if (atom->ntypes > maxtypes) { + + // Clear any/all memory for existing types + + for (n = 1; n <= maxtypes; n++) { + memory->destroy(atom2bin_multi2[n]); + memory->destroy(binhead_multi2[n]); + memory->destroy(bins_multi2[n]); + } + delete [] atom2bin_multi2; + delete [] binhead_multi2; + delete [] bins_multi2; + + // Realloacte at updated maxtypes + + maxtypes = atom->ntypes; + + atom2bin_multi2 = new int*[maxtypes+1](); + binhead_multi2 = new int*[maxtypes+1](); + bins_multi2 = new int*[maxtypes+1](); + + memory->destroy(nbinx_multi2); + memory->destroy(nbiny_multi2); + memory->destroy(nbinz_multi2); + memory->create(nbinx_multi2, maxtypes+1, "neigh:nbinx_multi2"); + memory->create(nbiny_multi2, maxtypes+1, "neigh:nbiny_multi2"); + memory->create(nbinz_multi2, maxtypes+1, "neigh:nbinz_multi2"); + + memory->destroy(mbins_multi2); + memory->destroy(mbinx_multi2); + memory->destroy(mbiny_multi2); + memory->destroy(mbinz_multi2); + memory->create(mbins_multi2, maxtypes+1, "neigh:mbins_multi2"); + memory->create(mbinx_multi2, maxtypes+1, "neigh:mbinx_multi2"); + memory->create(mbiny_multi2, maxtypes+1, "neigh:mbiny_multi2"); + memory->create(mbinz_multi2, maxtypes+1, "neigh:mbinz_multi2"); + + memory->destroy(mbinxlo_multi2); + memory->destroy(mbinylo_multi2); + memory->destroy(mbinzlo_multi2); + memory->create(mbinxlo_multi2, maxtypes+1, "neigh:mbinxlo_multi2"); + memory->create(mbinylo_multi2, maxtypes+1, "neigh:mbinylo_multi2"); + memory->create(mbinzlo_multi2, maxtypes+1, "neigh:mbinzlo_multi2"); + + memory->destroy(binsizex_multi2); + memory->destroy(binsizey_multi2); + memory->destroy(binsizez_multi2); + memory->create(binsizex_multi2, maxtypes+1, "neigh:binsizex_multi2"); + memory->create(binsizey_multi2, maxtypes+1, "neigh:binsizey_multi2"); + memory->create(binsizez_multi2, maxtypes+1, "neigh:binsizez_multi2"); + + memory->destroy(bininvx_multi2); + memory->destroy(bininvy_multi2); + memory->destroy(bininvz_multi2); + memory->create(bininvx_multi2, maxtypes+1, "neigh:bininvx_multi2"); + memory->create(bininvy_multi2, maxtypes+1, "neigh:bininvy_multi2"); + memory->create(bininvz_multi2, maxtypes+1, "neigh:bininvz_multi2"); + + memory->destroy(maxbins_multi2); + memory->create(maxbins_multi2, maxtypes+1, "neigh:maxbins_multi2"); + // make sure reallocation occurs in bin_atoms_setup() + for (n = 1; n <= maxtypes; n++) { + maxbins_multi2[n] = 0; + } + maxatom = 0; + } + + itypemin = itype_min(); + + // bbox = size of bbox of entire domain + // bsubbox lo/hi = bounding box of my subdomain extended by comm->cutghost + // for triclinic: + // bbox bounds all 8 corners of tilted box + // subdomain is in lamda coords + // include dimension-dependent extension via comm->cutghost + // domain->bbox() converts lamda extent to box coords and computes bbox + + double bbox[3],bsubboxlo[3],bsubboxhi[3]; + double *cutghost = comm->cutghost; + + if (triclinic == 0) { + bsubboxlo[0] = domain->sublo[0] - cutghost[0]; + bsubboxlo[1] = domain->sublo[1] - cutghost[1]; + bsubboxlo[2] = domain->sublo[2] - cutghost[2]; + bsubboxhi[0] = domain->subhi[0] + cutghost[0]; + bsubboxhi[1] = domain->subhi[1] + cutghost[1]; + bsubboxhi[2] = domain->subhi[2] + cutghost[2]; + } else { + double lo[3],hi[3]; + lo[0] = domain->sublo_lamda[0] - cutghost[0]; + lo[1] = domain->sublo_lamda[1] - cutghost[1]; + lo[2] = domain->sublo_lamda[2] - cutghost[2]; + hi[0] = domain->subhi_lamda[0] + cutghost[0]; + hi[1] = domain->subhi_lamda[1] + cutghost[1]; + hi[2] = domain->subhi_lamda[2] + cutghost[2]; + domain->bbox(lo,hi,bsubboxlo,bsubboxhi); + } + + bbox[0] = bboxhi[0] - bboxlo[0]; + bbox[1] = bboxhi[1] - bboxlo[1]; + bbox[2] = bboxhi[2] - bboxlo[2]; + + // For each type... + + for (n = 1; n <= atom->ntypes; n++) { + // binsize_user only relates to smallest type + // optimal bin size is roughly 1/2 the type-type cutoff + // special case of all cutoffs = 0.0, binsize = box size + + double binsize_optimal; + if (n == itypemin && binsizeflag) binsize_optimal = binsize_user; + else binsize_optimal = 0.5*sqrt(neighbor->cutneighsq[n][n]); + if (binsize_optimal == 0.0) binsize_optimal = bbox[0]; + double binsizeinv = 1.0/binsize_optimal; + + // test for too many global bins in any dimension due to huge global domain + + if (bbox[0]*binsizeinv > MAXSMALLINT || bbox[1]*binsizeinv > MAXSMALLINT || + bbox[2]*binsizeinv > MAXSMALLINT) + error->all(FLERR,"Domain too large for neighbor bins"); + + // create actual bins + // always have one bin even if cutoff > bbox + // for 2d, nbinz_multi2[n] = 1 + + nbinx_multi2[n] = static_cast (bbox[0]*binsizeinv); + nbiny_multi2[n] = static_cast (bbox[1]*binsizeinv); + if (dimension == 3) nbinz_multi2[n] = static_cast (bbox[2]*binsizeinv); + else nbinz_multi2[n] = 1; + + if (nbinx_multi2[n] == 0) nbinx_multi2[n] = 1; + if (nbiny_multi2[n] == 0) nbiny_multi2[n] = 1; + if (nbinz_multi2[n] == 0) nbinz_multi2[n] = 1; + + // compute actual bin size for nbins to fit into box exactly + // error if actual bin size << cutoff, since will create a zillion bins + // this happens when nbin = 1 and box size << cutoff + // typically due to non-periodic, flat system in a particular dim + // in that extreme case, should use NSQ not BIN neighbor style + + binsizex_multi2[n] = bbox[0]/nbinx_multi2[n]; + binsizey_multi2[n] = bbox[1]/nbiny_multi2[n]; + binsizez_multi2[n] = bbox[2]/nbinz_multi2[n]; + + bininvx_multi2[n] = 1.0 / binsizex_multi2[n]; + bininvy_multi2[n] = 1.0 / binsizey_multi2[n]; + bininvz_multi2[n] = 1.0 / binsizez_multi2[n]; + + if (binsize_optimal*bininvx_multi2[n] > CUT2BIN_RATIO || + binsize_optimal*bininvy_multi2[n] > CUT2BIN_RATIO || + binsize_optimal*bininvz_multi2[n] > CUT2BIN_RATIO) + error->all(FLERR,"Cannot use neighbor bins - box size << cutoff"); + + // mbinlo/hi = lowest and highest global bins my ghost atoms could be in + // coord = lowest and highest values of coords for my ghost atoms + // static_cast(-1.5) = -1, so subract additional -1 + // add in SMALL for round-off safety + + int mbinxhi,mbinyhi,mbinzhi; + double coord; + + coord = bsubboxlo[0] - SMALL*bbox[0]; + mbinxlo_multi2[n] = static_cast ((coord-bboxlo[0])*bininvx_multi2[n]); + if (coord < bboxlo[0]) mbinxlo_multi2[n] = mbinxlo_multi2[n] - 1; + coord = bsubboxhi[0] + SMALL*bbox[0]; + mbinxhi = static_cast ((coord-bboxlo[0])*bininvx_multi2[n]); + + coord = bsubboxlo[1] - SMALL*bbox[1]; + mbinylo_multi2[n] = static_cast ((coord-bboxlo[1])*bininvy_multi2[n]); + if (coord < bboxlo[1]) mbinylo_multi2[n] = mbinylo_multi2[n] - 1; + coord = bsubboxhi[1] + SMALL*bbox[1]; + mbinyhi = static_cast ((coord-bboxlo[1])*bininvy_multi2[n]); + + if (dimension == 3) { + coord = bsubboxlo[2] - SMALL*bbox[2]; + mbinzlo_multi2[n] = static_cast ((coord-bboxlo[2])*bininvz_multi2[n]); + if (coord < bboxlo[2]) mbinzlo_multi2[n] = mbinzlo_multi2[n] - 1; + coord = bsubboxhi[2] + SMALL*bbox[2]; + mbinzhi = static_cast ((coord-bboxlo[2])*bininvz_multi2[n]); + } + + // extend bins by 1 to insure stencil extent is included + // for 2d, only 1 bin in z + + mbinxlo_multi2[n] = mbinxlo_multi2[n] - 1; + mbinxhi = mbinxhi + 1; + mbinx_multi2[n] = mbinxhi - mbinxlo_multi2[n] + 1; + + mbinylo_multi2[n] = mbinylo_multi2[n] - 1; + mbinyhi = mbinyhi + 1; + mbiny_multi2[n] = mbinyhi - mbinylo_multi2[n] + 1; + + if (dimension == 3) { + mbinzlo_multi2[n] = mbinzlo_multi2[n] - 1; + mbinzhi = mbinzhi + 1; + } else mbinzlo_multi2[n] = mbinzhi = 0; + mbinz_multi2[n] = mbinzhi - mbinzlo_multi2[n] + 1; + + bigint bbin = ((bigint) mbinx_multi2[n]) + * ((bigint) mbiny_multi2[n]) * ((bigint) mbinz_multi2[n]) + 1; + if (bbin > MAXSMALLINT) error->one(FLERR,"Too many neighbor bins"); + mbins_multi2[n] = bbin; + } + +} + +/* ---------------------------------------------------------------------- + bin owned and ghost atoms by type +------------------------------------------------------------------------- */ + +void NBinMulti2::bin_atoms() +{ + int i,ibin,n; + + last_bin = update->ntimestep; + for (n = 1; n <= maxtypes; n++) { + for (i = 0; i < mbins_multi2[n]; i++) binhead_multi2[n][i] = -1; + } + + // bin in reverse order so linked list will be in forward order + // also puts ghost atoms at end of list, which is necessary + + double **x = atom->x; + int *mask = atom->mask; + int *type = atom->type; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + + if (includegroup) { + int bitmask = group->bitmask[includegroup]; + for (i = nall-1; i >= nlocal; i--) { + if (mask[i] & bitmask) { + n = type[i]; + ibin = coord2bin(x[i], n); + atom2bin_multi2[n][i] = ibin; + bins_multi2[n][i] = binhead_multi2[n][ibin]; + binhead_multi2[n][ibin] = i; + } + } + for (i = atom->nfirst-1; i >= 0; i--) { + n = type[i]; + ibin = coord2bin(x[i], n); + atom2bin_multi2[n][i] = ibin; + bins_multi2[n][i] = binhead_multi2[n][ibin]; + binhead_multi2[n][ibin] = i; + } + } else { + for (i = nall-1; i >= 0; i--) { + n = type[i]; + ibin = coord2bin(x[i], n); + atom2bin_multi2[n][i] = ibin; + bins_multi2[n][i] = binhead_multi2[n][ibin]; + binhead_multi2[n][ibin] = i; + } + } +} + +/* ---------------------------------------------------------------------- + convert atom coords into local bin # for a particular type + for orthogonal, only ghost atoms will have coord >= bboxhi or coord < bboxlo + take special care to insure ghosts are in correct bins even w/ roundoff + hi ghost atoms = nbin,nbin+1,etc + owned atoms = 0 to nbin-1 + lo ghost atoms = -1,-2,etc + this is necessary so that both procs on either side of PBC + treat a pair of atoms straddling the PBC in a consistent way + for triclinic, doesn't matter since stencil & neigh list built differently +------------------------------------------------------------------------- */ + +int NBinMulti2::coord2bin(double *x, int it) +{ + int ix,iy,iz; + int ibin; + + if (!std::isfinite(x[0]) || !std::isfinite(x[1]) || !std::isfinite(x[2])) + error->one(FLERR,"Non-numeric positions - simulation unstable"); + + if (x[0] >= bboxhi[0]) + ix = static_cast ((x[0]-bboxhi[0])*bininvx_multi2[it]) + nbinx_multi2[it]; + else if (x[0] >= bboxlo[0]) { + ix = static_cast ((x[0]-bboxlo[0])*bininvx_multi2[it]); + ix = MIN(ix,nbinx_multi2[it]-1); + } else + ix = static_cast ((x[0]-bboxlo[0])*bininvx_multi2[it]) - 1; + + if (x[1] >= bboxhi[1]) + iy = static_cast ((x[1]-bboxhi[1])*bininvy_multi2[it]) + nbiny_multi2[it]; + else if (x[1] >= bboxlo[1]) { + iy = static_cast ((x[1]-bboxlo[1])*bininvy_multi2[it]); + iy = MIN(iy,nbiny_multi2[it]-1); + } else + iy = static_cast ((x[1]-bboxlo[1])*bininvy_multi2[it]) - 1; + + if (x[2] >= bboxhi[2]) + iz = static_cast ((x[2]-bboxhi[2])*bininvz_multi2[it]) + nbinz_multi2[it]; + else if (x[2] >= bboxlo[2]) { + iz = static_cast ((x[2]-bboxlo[2])*bininvz_multi2[it]); + iz = MIN(iz,nbinz_multi2[it]-1); + } else + iz = static_cast ((x[2]-bboxlo[2])*bininvz_multi2[it]) - 1; + + + ibin = (iz-mbinzlo_multi2[it])*mbiny_multi2[it]*mbinx_multi2[it] + + (iy-mbinylo_multi2[it])*mbinx_multi2[it] + + (ix-mbinxlo_multi2[it]); + return ibin; +} + + +/* ---------------------------------------------------------------------- */ + +double NBinMulti2::memory_usage() +{ + double bytes = 0; + + for (int m = 1; m < maxtypes; m++) { + bytes += maxbins_multi2[m]*sizeof(int); + bytes += 2*maxatom*sizeof(int); + } + return bytes; +} diff --git a/src/nbin_multi_tiered.h b/src/nbin_multi2.h similarity index 75% rename from src/nbin_multi_tiered.h rename to src/nbin_multi2.h index ad2b95ef4b..8cca7b1023 100644 --- a/src/nbin_multi_tiered.h +++ b/src/nbin_multi2.h @@ -13,36 +13,32 @@ #ifdef NBIN_CLASS -NBinStyle(bytype, - NBinBytype, - NB_BYTYPE) +NBinStyle(multi2, + NBinMulti2, + NB_MULTI2) #else -#ifndef LMP_NBIN_BYTYPE_H -#define LMP_NBIN_BYTYPE_H +#ifndef LMP_NBIN_MULTI2_H +#define LMP_NBIN_MULTI2_H #include "nbin.h" namespace LAMMPS_NS { -class NBinBytype : public NBin { +class NBinMulti2 : public NBin { public: - NBinBytype(class LAMMPS *); - ~NBinBytype(); + NBinMulti2(class LAMMPS *); + ~NBinMulti2() {} void bin_atoms_setup(int); void setup_bins(int); - void bin_atoms(); - - int coord2bin(double *x, int itype); - bigint memory_usage(); + void bin_atoms(); + double memory_usage(); private: - int maxtypes; - int * maxbins_type; - void setup_types(); + int coord2bin(double *, int); int itype_min(); }; diff --git a/src/nbin_multi_tiered.cpp b/src/nbin_multi_tiered.cpp deleted file mode 100644 index 70732a4b97..0000000000 --- a/src/nbin_multi_tiered.cpp +++ /dev/null @@ -1,464 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, 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 "nbin_bytype.h" -#include "neighbor.h" -#include "atom.h" -#include "group.h" -#include "domain.h" -#include "comm.h" -#include "update.h" -#include "error.h" -#include "memory.h" - -using namespace LAMMPS_NS; - -#define SMALL 1.0e-6 -#define CUT2BIN_RATIO 100 - -/* ---------------------------------------------------------------------- */ - -NBinBytype::NBinBytype(LAMMPS *lmp) : NBin(lmp) { - - nbinx_type = NULL; nbiny_type = NULL; nbinz_type = NULL; - mbins_type = NULL; - mbinx_type = NULL; mbiny_type = NULL, mbinz_type = NULL; - mbinxlo_type = NULL; - mbinylo_type = NULL; - mbinzlo_type = NULL; - binsizex_type = NULL; binsizey_type = NULL; binsizez_type = NULL; - bininvx_type = NULL; bininvy_type = NULL; bininvz_type = NULL; - binhead_type = NULL; - bins_type = NULL; - atom2bin_type = NULL; - maxtypes = 0; - maxbins_type = NULL; -} - -NBinBytype::~NBinBytype() { - - memory->destroy(nbinx_type); - memory->destroy(nbiny_type); - memory->destroy(nbinz_type); - memory->destroy(mbins_type); - memory->destroy(mbinx_type); - memory->destroy(mbiny_type); - memory->destroy(mbinz_type); - memory->destroy(mbinxlo_type); - memory->destroy(mbinylo_type); - memory->destroy(mbinzlo_type); - - memory->destroy(binsizex_type); - memory->destroy(binsizey_type); - memory->destroy(binsizez_type); - memory->destroy(bininvx_type); - memory->destroy(bininvy_type); - memory->destroy(bininvz_type); - - for (int n = 1; n <= maxtypes; n++) { - memory->destroy(binhead_type[n]); - memory->destroy(bins_type[n]); - memory->destroy(atom2bin_type[n]); - } - delete [] binhead_type; - delete [] bins_type; - delete [] atom2bin_type; - - memory->destroy(maxbins_type); -} - -/* ---------------------------------------------------------------------- - arrange storage for types - allows ntypes to change, but not currently expected after initialisation - ------------------------------------------------------------------------- */ - -void NBinBytype::setup_types() { - - int n; - - if (atom->ntypes > maxtypes) { - - // Clear any/all memory for existing types - - for (n = 1; n <= maxtypes; n++) { - memory->destroy(atom2bin_type[n]); - memory->destroy(binhead_type[n]); - memory->destroy(bins_type[n]); - } - delete [] atom2bin_type; - delete [] binhead_type; - delete [] bins_type; - - // Realloacte at updated maxtypes - - maxtypes = atom->ntypes; - - atom2bin_type = new int*[maxtypes+1](); - binhead_type = new int*[maxtypes+1](); - bins_type = new int*[maxtypes+1](); - - memory->destroy(nbinx_type); - memory->destroy(nbiny_type); - memory->destroy(nbinz_type); - memory->create(nbinx_type, maxtypes+1, "nBinType:nbinx_type"); - memory->create(nbiny_type, maxtypes+1, "nBinType:nbiny_type"); - memory->create(nbinz_type, maxtypes+1, "nBinType:nbinz_type"); - - memory->destroy(mbins_type); - memory->destroy(mbinx_type); - memory->destroy(mbiny_type); - memory->destroy(mbinz_type); - memory->create(mbins_type, maxtypes+1, "nBinType:mbins_type"); - memory->create(mbinx_type, maxtypes+1, "nBinType:mbinx_type"); - memory->create(mbiny_type, maxtypes+1, "nBinType:mbiny_type"); - memory->create(mbinz_type, maxtypes+1, "nBinType:mbinz_type"); - - memory->destroy(mbinxlo_type); - memory->destroy(mbinylo_type); - memory->destroy(mbinzlo_type); - memory->create(mbinxlo_type, maxtypes+1, "nBinType:mbinxlo_type"); - memory->create(mbinylo_type, maxtypes+1, "nBinType:mbinylo_type"); - memory->create(mbinzlo_type, maxtypes+1, "nBinType:mbinzlo_type"); - - memory->destroy(binsizex_type); - memory->destroy(binsizey_type); - memory->destroy(binsizez_type); - memory->create(binsizex_type, maxtypes+1, "nBinType:binsizex_type"); - memory->create(binsizey_type, maxtypes+1, "nBinType:binsizey_type"); - memory->create(binsizez_type, maxtypes+1, "nBinType:binsizez_type"); - - memory->destroy(bininvx_type); - memory->destroy(bininvy_type); - memory->destroy(bininvz_type); - memory->create(bininvx_type, maxtypes+1, "nBinType:bininvx_type"); - memory->create(bininvy_type, maxtypes+1, "nBinType:bininvy_type"); - memory->create(bininvz_type, maxtypes+1, "nBinType:bininvz_type"); - - memory->destroy(maxbins_type); - memory->create(maxbins_type, maxtypes+1, "nBinType:maxbins_type"); - // make sure reallocation occurs in bin_atoms_setup() - for (n = 1; n <= maxtypes; n++) { - maxbins_type[n] = 0; - } - maxatom = 0; - } - -} - -/* --------------------------------------------------------------------- - identify index of type with smallest cutoff - --------------------------------------------------------------------- */ - -int NBinBytype::itype_min() { - - int itypemin = 1; - double ** cutneighsq; - - cutneighsq = neighbor->cutneighsq; - - for (int n = 1; n <= atom->ntypes; n++) { - if (cutneighsq[n][n] < cutneighsq[itypemin][itypemin]) { - itypemin = n; - } - } - - return itypemin; -} - -/* ---------------------------------------------------------------------- - setup neighbor binning geometry - ---------------------------------------------------------------------- */ - -void NBinBytype::setup_bins(int style) -{ - int n; - int itypemin; - - setup_types(); - itypemin = itype_min(); - - // bbox = size of bbox of entire domain - // bsubbox lo/hi = bounding box of my subdomain extended by comm->cutghost - // for triclinic: - // bbox bounds all 8 corners of tilted box - // subdomain is in lamda coords - // include dimension-dependent extension via comm->cutghost - // domain->bbox() converts lamda extent to box coords and computes bbox - - double bbox[3],bsubboxlo[3],bsubboxhi[3]; - double *cutghost = comm->cutghost; - - if (triclinic == 0) { - bsubboxlo[0] = domain->sublo[0] - cutghost[0]; - bsubboxlo[1] = domain->sublo[1] - cutghost[1]; - bsubboxlo[2] = domain->sublo[2] - cutghost[2]; - bsubboxhi[0] = domain->subhi[0] + cutghost[0]; - bsubboxhi[1] = domain->subhi[1] + cutghost[1]; - bsubboxhi[2] = domain->subhi[2] + cutghost[2]; - } else { - double lo[3],hi[3]; - lo[0] = domain->sublo_lamda[0] - cutghost[0]; - lo[1] = domain->sublo_lamda[1] - cutghost[1]; - lo[2] = domain->sublo_lamda[2] - cutghost[2]; - hi[0] = domain->subhi_lamda[0] + cutghost[0]; - hi[1] = domain->subhi_lamda[1] + cutghost[1]; - hi[2] = domain->subhi_lamda[2] + cutghost[2]; - domain->bbox(lo,hi,bsubboxlo,bsubboxhi); - } - - bbox[0] = bboxhi[0] - bboxlo[0]; - bbox[1] = bboxhi[1] - bboxlo[1]; - bbox[2] = bboxhi[2] - bboxlo[2]; - - // For each type... - - for (n = 1; n <= atom->ntypes; n++) { - // binsize_user only relates to smallest type - // optimal bin size is roughly 1/2 the type-type cutoff - // special case of all cutoffs = 0.0, binsize = box size - - double binsize_optimal; - if (n == itypemin && binsizeflag) binsize_optimal = binsize_user; - else binsize_optimal = 0.5*sqrt(neighbor->cutneighsq[n][n]); - if (binsize_optimal == 0.0) binsize_optimal = bbox[0]; - double binsizeinv = 1.0/binsize_optimal; - - // test for too many global bins in any dimension due to huge global domain - - if (bbox[0]*binsizeinv > MAXSMALLINT || bbox[1]*binsizeinv > MAXSMALLINT || - bbox[2]*binsizeinv > MAXSMALLINT) - error->all(FLERR,"Domain too large for neighbor bins"); - - // create actual bins - // always have one bin even if cutoff > bbox - // for 2d, nbinz_type[n] = 1 - - nbinx_type[n] = static_cast (bbox[0]*binsizeinv); - nbiny_type[n] = static_cast (bbox[1]*binsizeinv); - if (dimension == 3) nbinz_type[n] = static_cast (bbox[2]*binsizeinv); - else nbinz_type[n] = 1; - - if (nbinx_type[n] == 0) nbinx_type[n] = 1; - if (nbiny_type[n] == 0) nbiny_type[n] = 1; - if (nbinz_type[n] == 0) nbinz_type[n] = 1; - - // compute actual bin size for nbins to fit into box exactly - // error if actual bin size << cutoff, since will create a zillion bins - // this happens when nbin = 1 and box size << cutoff - // typically due to non-periodic, flat system in a particular dim - // in that extreme case, should use NSQ not BIN neighbor style - - binsizex_type[n] = bbox[0]/nbinx_type[n]; - binsizey_type[n] = bbox[1]/nbiny_type[n]; - binsizez_type[n] = bbox[2]/nbinz_type[n]; - - bininvx_type[n] = 1.0 / binsizex_type[n]; - bininvy_type[n] = 1.0 / binsizey_type[n]; - bininvz_type[n] = 1.0 / binsizez_type[n]; - - if (binsize_optimal*bininvx_type[n] > CUT2BIN_RATIO || - binsize_optimal*bininvy_type[n] > CUT2BIN_RATIO || - binsize_optimal*bininvz_type[n] > CUT2BIN_RATIO) - error->all(FLERR,"Cannot use neighbor bins - box size << cutoff"); - - // mbinlo/hi = lowest and highest global bins my ghost atoms could be in - // coord = lowest and highest values of coords for my ghost atoms - // static_cast(-1.5) = -1, so subract additional -1 - // add in SMALL for round-off safety - - int mbinxhi,mbinyhi,mbinzhi; - double coord; - - coord = bsubboxlo[0] - SMALL*bbox[0]; - mbinxlo_type[n] = static_cast ((coord-bboxlo[0])*bininvx_type[n]); - if (coord < bboxlo[0]) mbinxlo_type[n] = mbinxlo_type[n] - 1; - coord = bsubboxhi[0] + SMALL*bbox[0]; - mbinxhi = static_cast ((coord-bboxlo[0])*bininvx_type[n]); - - coord = bsubboxlo[1] - SMALL*bbox[1]; - mbinylo_type[n] = static_cast ((coord-bboxlo[1])*bininvy_type[n]); - if (coord < bboxlo[1]) mbinylo_type[n] = mbinylo_type[n] - 1; - coord = bsubboxhi[1] + SMALL*bbox[1]; - mbinyhi = static_cast ((coord-bboxlo[1])*bininvy_type[n]); - - if (dimension == 3) { - coord = bsubboxlo[2] - SMALL*bbox[2]; - mbinzlo_type[n] = static_cast ((coord-bboxlo[2])*bininvz_type[n]); - if (coord < bboxlo[2]) mbinzlo_type[n] = mbinzlo_type[n] - 1; - coord = bsubboxhi[2] + SMALL*bbox[2]; - mbinzhi = static_cast ((coord-bboxlo[2])*bininvz_type[n]); - } - - // extend bins by 1 to insure stencil extent is included - // for 2d, only 1 bin in z - - mbinxlo_type[n] = mbinxlo_type[n] - 1; - mbinxhi = mbinxhi + 1; - mbinx_type[n] = mbinxhi - mbinxlo_type[n] + 1; - - mbinylo_type[n] = mbinylo_type[n] - 1; - mbinyhi = mbinyhi + 1; - mbiny_type[n] = mbinyhi - mbinylo_type[n] + 1; - - if (dimension == 3) { - mbinzlo_type[n] = mbinzlo_type[n] - 1; - mbinzhi = mbinzhi + 1; - } else mbinzlo_type[n] = mbinzhi = 0; - mbinz_type[n] = mbinzhi - mbinzlo_type[n] + 1; - - bigint bbin = ((bigint) mbinx_type[n]) - * ((bigint) mbiny_type[n]) * ((bigint) mbinz_type[n]) + 1; - if (bbin > MAXSMALLINT) error->one(FLERR,"Too many neighbor bins"); - mbins_type[n] = bbin; - } - -} - -/* ---------------------------------------------------------------------- - bin owned and ghost atoms by type -------------------------------------------------------------------------- */ - -void NBinBytype::bin_atoms() -{ - int i,ibin,n; - - last_bin = update->ntimestep; - for (n = 1; n <= maxtypes; n++) { - for (i = 0; i < mbins_type[n]; i++) binhead_type[n][i] = -1; - } - - // bin in reverse order so linked list will be in forward order - // also puts ghost atoms at end of list, which is necessary - - double **x = atom->x; - int *mask = atom->mask; - int *type = atom->type; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - - if (includegroup) { - int bitmask = group->bitmask[includegroup]; - for (i = nall-1; i >= nlocal; i--) { - if (mask[i] & bitmask) { - n = type[i]; - ibin = coord2bin(x[i], n); - atom2bin_type[n][i] = ibin; - bins_type[n][i] = binhead_type[n][ibin]; - binhead_type[n][ibin] = i; - } - } - for (i = atom->nfirst-1; i >= 0; i--) { - n = type[i]; - ibin = coord2bin(x[i], n); - atom2bin_type[n][i] = ibin; - bins_type[n][i] = binhead_type[n][ibin]; - binhead_type[n][ibin] = i; - } - } else { - for (i = nall-1; i >= 0; i--) { - n = type[i]; - ibin = coord2bin(x[i], n); - atom2bin_type[n][i] = ibin; - bins_type[n][i] = binhead_type[n][ibin]; - binhead_type[n][ibin] = i; - } - } -} - - -/* ---------------------------------------------------------------------- - allocate/reallocate vectors -------------------------------------------------------------------------- */ - -void NBinBytype::bin_atoms_setup(int nall) { - - // all atom2bin, bins must be of length nall - if (nall > maxatom) { - for (int n = 1; n <= maxtypes; n++) { - memory->destroy(bins_type[n]); - memory->destroy(atom2bin_type[n]); - memory->create(bins_type[n], nall, "NBinBytype:bin_type"); - memory->create(atom2bin_type[n], nall, "NBinBytype:atom2bin_type"); - } - maxatom = nall; - } - - for (int n = 1; n <= maxtypes; n++) { - if (mbins_type[n] > maxbins_type[n]) { - maxbins_type[n] = mbins_type[n]; - memory->destroy(binhead_type[n]); - memory->create(binhead_type[n], mbins_type[n], "NBinBytype:mbins_type"); - } - } - -} - - -/* ---------------------------------------------------------------------- - convert atom coords into local bin # for bin type it -------------------------------------------------------------------------- */ - -int NBinBytype::coord2bin(double *x, int it) -{ - int ix,iy,iz; - int ibin; - - if (!std::isfinite(x[0]) || !std::isfinite(x[1]) || !std::isfinite(x[2])) - error->one(FLERR,"Non-numeric positions - simulation unstable"); - - if (x[0] >= bboxhi[0]) - ix = static_cast ((x[0]-bboxhi[0])*bininvx_type[it]) + nbinx_type[it]; - else if (x[0] >= bboxlo[0]) { - ix = static_cast ((x[0]-bboxlo[0])*bininvx_type[it]); - ix = MIN(ix,nbinx_type[it]-1); - } else - ix = static_cast ((x[0]-bboxlo[0])*bininvx_type[it]) - 1; - - if (x[1] >= bboxhi[1]) - iy = static_cast ((x[1]-bboxhi[1])*bininvy_type[it]) + nbiny_type[it]; - else if (x[1] >= bboxlo[1]) { - iy = static_cast ((x[1]-bboxlo[1])*bininvy_type[it]); - iy = MIN(iy,nbiny_type[it]-1); - } else - iy = static_cast ((x[1]-bboxlo[1])*bininvy_type[it]) - 1; - - if (x[2] >= bboxhi[2]) - iz = static_cast ((x[2]-bboxhi[2])*bininvz_type[it]) + nbinz_type[it]; - else if (x[2] >= bboxlo[2]) { - iz = static_cast ((x[2]-bboxlo[2])*bininvz_type[it]); - iz = MIN(iz,nbinz_type[it]-1); - } else - iz = static_cast ((x[2]-bboxlo[2])*bininvz_type[it]) - 1; - - - ibin = (iz-mbinzlo_type[it])*mbiny_type[it]*mbinx_type[it] - + (iy-mbinylo_type[it])*mbinx_type[it] - + (ix-mbinxlo_type[it]); - return ibin; -} - - -/* ---------------------------------------------------------------------- - tot up for types - ---------------------------------------------------------------------- */ - -bigint NBinBytype::memory_usage() -{ - bigint bytes = 0; - - for (int m = 1; m < maxtypes; m++) { - bytes += 2*maxatom*sizeof(int); - bytes += maxbins_type[m]*sizeof(int); - } - return bytes; -} diff --git a/src/nbin_standard.cpp b/src/nbin_standard.cpp index 9a28121384..e63c8dcd56 100644 --- a/src/nbin_standard.cpp +++ b/src/nbin_standard.cpp @@ -29,6 +29,33 @@ using namespace LAMMPS_NS; NBinStandard::NBinStandard(LAMMPS *lmp) : NBin(lmp) {} +/* ---------------------------------------------------------------------- + setup for bin_atoms() +------------------------------------------------------------------------- */ + +void NBinStandard::bin_atoms_setup(int nall) +{ + // binhead = per-bin vector, mbins in length + // add 1 bin for USER-INTEL package + + if (mbins > maxbin) { + maxbin = mbins; + memory->destroy(binhead); + memory->create(binhead,maxbin,"neigh:binhead"); + } + + // bins and atom2bin = per-atom vectors + // for both local and ghost atoms + + if (nall > maxatom) { + maxatom = nall; + memory->destroy(bins); + memory->create(bins,maxatom,"neigh:bins"); + memory->destroy(atom2bin); + memory->create(atom2bin,maxatom,"neigh:atom2bin"); + } +} + /* ---------------------------------------------------------------------- setup neighbor binning geometry bin numbering in each dimension is global: @@ -230,3 +257,61 @@ void NBinStandard::bin_atoms() } } } + + +/* ---------------------------------------------------------------------- + convert atom coords into local bin # + for orthogonal, only ghost atoms will have coord >= bboxhi or coord < bboxlo + take special care to insure ghosts are in correct bins even w/ roundoff + hi ghost atoms = nbin,nbin+1,etc + owned atoms = 0 to nbin-1 + lo ghost atoms = -1,-2,etc + this is necessary so that both procs on either side of PBC + treat a pair of atoms straddling the PBC in a consistent way + for triclinic, doesn't matter since stencil & neigh list built differently +------------------------------------------------------------------------- */ + +int NBinStandard::coord2bin(double *x) +{ + int ix,iy,iz; + + if (!std::isfinite(x[0]) || !std::isfinite(x[1]) || !std::isfinite(x[2])) + error->one(FLERR,"Non-numeric positions - simulation unstable"); + + if (x[0] >= bboxhi[0]) + ix = static_cast ((x[0]-bboxhi[0])*bininvx) + nbinx; + else if (x[0] >= bboxlo[0]) { + ix = static_cast ((x[0]-bboxlo[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x[0]-bboxlo[0])*bininvx) - 1; + + if (x[1] >= bboxhi[1]) + iy = static_cast ((x[1]-bboxhi[1])*bininvy) + nbiny; + else if (x[1] >= bboxlo[1]) { + iy = static_cast ((x[1]-bboxlo[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((x[1]-bboxlo[1])*bininvy) - 1; + + if (x[2] >= bboxhi[2]) + iz = static_cast ((x[2]-bboxhi[2])*bininvz) + nbinz; + else if (x[2] >= bboxlo[2]) { + iz = static_cast ((x[2]-bboxlo[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((x[2]-bboxlo[2])*bininvz) - 1; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); +} + + +/* ---------------------------------------------------------------------- */ + +double NBinStandard::memory_usage() +{ + double bytes = 0; + bytes += maxbin*sizeof(int); + bytes += 2*maxatom*sizeof(int); + return bytes; +} diff --git a/src/nbin_standard.h b/src/nbin_standard.h index 06defdb101..d8ecb435b7 100644 --- a/src/nbin_standard.h +++ b/src/nbin_standard.h @@ -30,8 +30,14 @@ class NBinStandard : public NBin { public: NBinStandard(class LAMMPS *); ~NBinStandard() {} + void bin_atoms_setup(int); void setup_bins(int); void bin_atoms(); + double memory_usage(); + + private: + + int coord2bin(double *); }; } diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 740b16b66e..d4a2727662 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -1620,12 +1620,12 @@ int Neighbor::choose_bin(NeighRequest *rq) if (!rq->kokkos_device != !(mask & NB_KOKKOS_DEVICE)) continue; if (!rq->kokkos_host != !(mask & NB_KOKKOS_HOST)) continue; - // neighbor style is BIN or MULTI or MULTI/TIERED and must match + // neighbor style is BIN or MULTI or MULTI2 and must match if (style == Neighbor::BIN || style == Neighbor::MULTI) { if (!(mask & NB_STANDARD)) continue; - } else if (style == Neighbor::MULTI_TIERED) { - if (!(mask & NB_MULTI_TIERED)) continue; + } else if (style == Neighbor::MULTI2) { + if (!(mask & NB_MULTI2)) continue; } return i+1; @@ -1698,14 +1698,14 @@ int Neighbor::choose_stencil(NeighRequest *rq) if (!rq->ghost != !(mask & NS_GHOST)) continue; if (!rq->ssa != !(mask & NS_SSA)) continue; - // neighbor style is one of BIN, MULTI, or MULT/TIERED and must match + // neighbor style is one of BIN, MULTI, or MULTI2 and must match if (style == Neighbor::BIN) { if (!(mask & NS_BIN)) continue; } else if (style == Neighbor::MULTI) { if (!(mask & NS_MULTI)) continue; - } else if (style == Neighbor::MULT_TIERED) { - if (!(mask & NS_MULT_TIERED)) continue; + } else if (style == Neighbor::MULTI2) { + if (!(mask & NS_MULTI2)) continue; } // dimension is 2 or 3 and must match @@ -1835,7 +1835,7 @@ int Neighbor::choose_pair(NeighRequest *rq) if (!rq->halffull != !(mask & NP_HALF_FULL)) continue; if (!rq->off2on != !(mask & NP_OFF2ON)) continue; - // neighbor style is one of NSQ, BIN, MULTI, or MULTI/TIERED and must match + // neighbor style is one of NSQ, BIN, MULTI, or MULTI2 and must match if (style == Neighbor::NSQ) { if (!(mask & NP_NSQ)) continue; @@ -1843,8 +1843,8 @@ int Neighbor::choose_pair(NeighRequest *rq) if (!(mask & NP_BIN)) continue; } else if (style == Neighbor::MULTI) { if (!(mask & NP_MULTI)) continue; - } else if (style == Neighbor::MULT_TIERED) { - if (!(mask & NP_MULT_TIERED)) continue; + } else if (style == Neighbor::MULTI2) { + if (!(mask & NP_MULTI2)) continue; } // domain triclinic flag is on or off and must match @@ -2211,7 +2211,7 @@ void Neighbor::set(int narg, char **arg) if (strcmp(arg[1],"nsq") == 0) style = Neighbor::NSQ; else if (strcmp(arg[1],"bin") == 0) style = Neighbor::BIN; else if (strcmp(arg[1],"multi") == 0) style = Neighbor::MULTI; - else if (strcmp(arg[1],"multi/tiered") == 0) style = Neighbor::MULT_TIERED; + else if (strcmp(arg[1],"multi2") == 0) style = Neighbor::MULTI2; else error->all(FLERR,"Illegal neighbor command"); if (style == Neighbor::MULTI && lmp->citeme) lmp->citeme->add(cite_neigh_multi); diff --git a/src/neighbor.h b/src/neighbor.h index fd8cc49067..0012cb29fa 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -20,7 +20,7 @@ namespace LAMMPS_NS { class Neighbor : protected Pointers { public: - enum{NSQ,BIN,MULTI,MULTI_TIERED}; + enum{NSQ,BIN,MULTI,MULTI2}; int style; // 0,1,2 = nsq, bin, multi int every; // build every this many steps int delay; // delay build for this many steps @@ -239,7 +239,7 @@ namespace NeighConst { static const int NB_KOKKOS_DEVICE = 1<<1; static const int NB_KOKKOS_HOST = 1<<2; static const int NB_SSA = 1<<3; - static const int NB_MULTI_TIERED = 1<<4; + static const int NB_MULTI2 = 1<<4; static const int NB_STANDARD = 1<<5; static const int NS_BIN = 1<<0; @@ -254,7 +254,7 @@ namespace NeighConst { static const int NS_TRI = 1<<9; static const int NS_GHOST = 1<<10; static const int NS_SSA = 1<<11; - static const int NS_MULTI_TIERED = 1<<12; + static const int NS_MULTI2 = 1<<12; static const int NP_NSQ = 1<<0; static const int NP_BIN = 1<<1; @@ -281,7 +281,7 @@ namespace NeighConst { static const int NP_SKIP = 1<<22; static const int NP_HALF_FULL = 1<<23; static const int NP_OFF2ON = 1<<24; - static const int NP_MULTI_TIERED = 1<<25; + static const int NP_MULTI2 = 1<<25; } } diff --git a/src/npair_half_multi_tiered_newton.cpp b/src/npair_half_multi2_newton.cpp similarity index 100% rename from src/npair_half_multi_tiered_newton.cpp rename to src/npair_half_multi2_newton.cpp diff --git a/src/npair_half_multi_tiered_newton.h b/src/npair_half_multi2_newton.h similarity index 100% rename from src/npair_half_multi_tiered_newton.h rename to src/npair_half_multi2_newton.h diff --git a/src/npair_half_multi_tiered_newton_tri.cpp b/src/npair_half_multi2_newton_tri.cpp similarity index 100% rename from src/npair_half_multi_tiered_newton_tri.cpp rename to src/npair_half_multi2_newton_tri.cpp diff --git a/src/npair_half_multi_tiered_newton_tri.h b/src/npair_half_multi2_newton_tri.h similarity index 100% rename from src/npair_half_multi_tiered_newton_tri.h rename to src/npair_half_multi2_newton_tri.h diff --git a/src/npair_half_size_multi_tiered_newtoff.cpp b/src/npair_half_size_multi2_newtoff.cpp similarity index 100% rename from src/npair_half_size_multi_tiered_newtoff.cpp rename to src/npair_half_size_multi2_newtoff.cpp diff --git a/src/npair_half_size_multi_tiered_newtoff.h b/src/npair_half_size_multi2_newtoff.h similarity index 100% rename from src/npair_half_size_multi_tiered_newtoff.h rename to src/npair_half_size_multi2_newtoff.h diff --git a/src/npair_half_size_multi_tiered_newton.cpp b/src/npair_half_size_multi2_newton.cpp similarity index 100% rename from src/npair_half_size_multi_tiered_newton.cpp rename to src/npair_half_size_multi2_newton.cpp diff --git a/src/npair_half_size_multi_tiered_newton.h b/src/npair_half_size_multi2_newton.h similarity index 100% rename from src/npair_half_size_multi_tiered_newton.h rename to src/npair_half_size_multi2_newton.h diff --git a/src/npair_half_size_multi_tiered_newton_tri.cpp b/src/npair_half_size_multi2_newton_tri.cpp similarity index 100% rename from src/npair_half_size_multi_tiered_newton_tri.cpp rename to src/npair_half_size_multi2_newton_tri.cpp diff --git a/src/npair_half_size_multi_tiered_newton_tri.h b/src/npair_half_size_multi2_newton_tri.h similarity index 100% rename from src/npair_half_size_multi_tiered_newton_tri.h rename to src/npair_half_size_multi2_newton_tri.h diff --git a/src/nstencil.cpp b/src/nstencil.cpp index 861fcd537e..3518b7db55 100644 --- a/src/nstencil.cpp +++ b/src/nstencil.cpp @@ -51,6 +51,15 @@ using namespace LAMMPS_NS; stencil follows same rules for half/full, newton on/off, triclinic cutoff is not cutneighmaxsq, but max cutoff for that atom type no versions that allow ghost on (any need for it?) + for multi/tiered: + create one stencil for each itype-jtype pairing + stencils do not generally follow the same rules for half/full or newton on/off + whole stencils including all surrounding bins are always used except + for same-type stencils with newton on which uses a split stencil + for orthogonal boxes, a split stencil includes bins to the "upper right" of central bin + for triclinic, a split stencil includes bins in the z (3D) or y (2D) plane of self and above + cutoff is not cutneighmaxsq, but max cutoff for that atom type + no versions that allow ghost on (any need for it?) ------------------------------------------------------------------------- */ NStencil::NStencil(LAMMPS *lmp) : Pointers(lmp) @@ -64,6 +73,11 @@ NStencil::NStencil(LAMMPS *lmp) : Pointers(lmp) nstencil_multi = nullptr; stencil_multi = nullptr; distsq_multi = nullptr; + + stencil_split = nullptr; + stencil_skip = nullptr; + stencil_bin_type = nullptr; + stencil_cut = nullptr; dimension = domain->dimension; } @@ -75,16 +89,44 @@ NStencil::~NStencil() memory->destroy(stencil); memory->destroy(stencilxyz); - if (!stencil_multi) return; + if (stencil_multi) { - int n = atom->ntypes; - for (int i = 1; i <= n; i++) { - memory->destroy(stencil_multi[i]); - memory->destroy(distsq_multi[i]); + int n = atom->ntypes; + for (int i = 1; i <= n; i++) { + memory->destroy(stencil_multi[i]); + memory->destroy(distsq_multi[i]); + } + delete [] nstencil_multi; + delete [] stencil_multi; + delete [] distsq_multi; + } + + if (stencil_multi_tiered) { + + int n = atom->ntypes; + memory->destroy(nstencil_multi_tiered); + for (int i = 1; i <= n; i++) { + for (int j = 0; j <= n; j++) { + if (! stencil_skip[i][j]) + memory->destroy(stencil_multi_tiered[i][j]); + } + delete [] stencil_multi_tiered[i]; + } + delete [] stencil_multi_tiered; + memory->destroy(maxstencil_multi_tiered); + memory->destroy(stencil_split); + memory->destroy(stencil_skip); + memory->destroy(stencil_bin_type); + memory->destroy(stencil_cut); + + memory->destroy(sx_multi_tiered); + memory->destroy(sy_multi_tiered); + memory->destroy(sz_multi_tiered); + + memory->destroy(binsizex_multi_tiered); + memory->destroy(binsizey_multi_tiered); + memory->destroy(binsizez_multi_tiered); } - delete [] nstencil_multi; - delete [] stencil_multi; - delete [] distsq_multi; } /* ---------------------------------------------------------------------- */ @@ -105,6 +147,7 @@ void NStencil::copy_neighbor_info() cutneighmax = neighbor->cutneighmax; cutneighmaxsq = neighbor->cutneighmaxsq; cuttypesq = neighbor->cuttypesq; + cutneighsq = neighbor->cutneighsq; // overwrite Neighbor cutoff with custom value set by requestor // only works for style = BIN (checked by Neighbor class) @@ -132,6 +175,23 @@ void NStencil::copy_bin_info() bininvz = nb->bininvz; } +/* ---------------------------------------------------------------------- + copy needed info for a given type from NBin class to this stencil class +------------------------------------------------------------------------- */ + +void NStencil::copy_bin_info_multi_tiered(int type) +{ + mbinx = nb->mbinx_tiered[type]; + mbiny = nb->mbiny_tiered[type]; + mbinz = nb->mbinz_tiered[type]; + binsizex = nb->binsizex_tiered[type]; + binsizey = nb->binsizey_tiered[type]; + binsizez = nb->binsizez_tiered[type]; + bininvx = nb->bininvx_tiered[type]; + bininvy = nb->bininvy_tiered[type]; + bininvz = nb->bininvz_tiered[type]; +} + /* ---------------------------------------------------------------------- insure NBin data is current insure stencils are allocated large enough @@ -139,59 +199,131 @@ void NStencil::copy_bin_info() void NStencil::create_setup() { - if (nb) copy_bin_info(); - last_stencil = update->ntimestep; - - // sx,sy,sz = max range of stencil in each dim - // smax = max possible size of entire 3d stencil - // stencil will be empty if cutneighmax = 0.0 - - sx = static_cast (cutneighmax*bininvx); - if (sx*binsizex < cutneighmax) sx++; - sy = static_cast (cutneighmax*bininvy); - if (sy*binsizey < cutneighmax) sy++; - sz = static_cast (cutneighmax*bininvz); - if (sz*binsizez < cutneighmax) sz++; - if (dimension == 2) sz = 0; - - int smax = (2*sx+1) * (2*sy+1) * (2*sz+1); - - // reallocate stencil structs if necessary - // for BIN and MULTI styles - - if (neighstyle == Neighbor::BIN) { - if (smax > maxstencil) { - maxstencil = smax; - memory->destroy(stencil); - memory->create(stencil,maxstencil,"neighstencil:stencil"); - if (xyzflag) { - memory->destroy(stencilxyz); - memory->create(stencilxyz,maxstencil,3,"neighstencil:stencilxyz"); + + if (neighstyle != Neighbor::MULTI_TIERED){ + if (nb) copy_bin_info(); + last_stencil = update->ntimestep; + + // sx,sy,sz = max range of stencil in each dim + // smax = max possible size of entire 3d stencil + // stencil will be empty if cutneighmax = 0.0 + + sx = static_cast (cutneighmax*bininvx); + if (sx*binsizex < cutneighmax) sx++; + sy = static_cast (cutneighmax*bininvy); + if (sy*binsizey < cutneighmax) sy++; + sz = static_cast (cutneighmax*bininvz); + if (sz*binsizez < cutneighmax) sz++; + if (dimension == 2) sz = 0; + + int smax = (2*sx+1) * (2*sy+1) * (2*sz+1); + + // reallocate stencil structs if necessary + // for BIN and MULTI styles + + if (neighstyle == Neighbor::BIN) { + if (smax > maxstencil) { + maxstencil = smax; + memory->destroy(stencil); + memory->create(stencil,maxstencil,"neighstencil:stencil"); + if (xyzflag) { + memory->destroy(stencilxyz); + memory->create(stencilxyz,maxstencil,3,"neighstencil:stencilxyz"); + } + } + + } else { + int i; + int n = atom->ntypes; + if (maxstencil_multi == 0) { + nstencil_multi = new int[n+1]; + stencil_multi = new int*[n+1]; + distsq_multi = new double*[n+1]; + for (i = 1; i <= n; i++) { + nstencil_multi[i] = 0; + stencil_multi[i] = nullptr; + distsq_multi[i] = nullptr; + } + } + if (smax > maxstencil_multi) { + maxstencil_multi = smax; + for (i = 1; i <= n; i++) { + memory->destroy(stencil_multi[i]); + memory->destroy(distsq_multi[i]); + memory->create(stencil_multi[i],maxstencil_multi, + "neighstencil:stencil_multi"); + memory->create(distsq_multi[i],maxstencil_multi, + "neighstencil:distsq_multi"); + } } } - } else { - int i; + int i, j, bin_type, smax; + double stencil_range; int n = atom->ntypes; - if (maxstencil_multi == 0) { - nstencil_multi = new int[n+1]; - stencil_multi = new int*[n+1]; - distsq_multi = new double*[n+1]; - for (i = 1; i <= n; i++) { - nstencil_multi[i] = 0; - stencil_multi[i] = nullptr; - distsq_multi[i] = nullptr; - } - } - if (smax > maxstencil_multi) { - maxstencil_multi = smax; - for (i = 1; i <= n; i++) { - memory->destroy(stencil_multi[i]); - memory->destroy(distsq_multi[i]); - memory->create(stencil_multi[i],maxstencil_multi, - "neighstencil:stencil_multi"); - memory->create(distsq_multi[i],maxstencil_multi, - "neighstencil:distsq_multi"); + + // Allocate arrays to store stencil information + memory->create(stencil_split, n, n, + "neighstencil:stencil_split");" + memory->create(stencil_skip, n, n, + "neighstencil:stencil_skip");" + memory->create(stencil_bin_type, n, n, + "neighstencil:stencil_bin_type");" + memory->create(stencil_cut, n, n, + "neighstencil:stencil_cut");" + + memory->create(sx_multi_tiered, n, n, + "neighstencil:sx_multi_tiered");" + memory->create(sy_multi_tiered, n, n, + "neighstencil:sy_multi_tiered");" + memory->create(sz_multi_tiered, n, n, + "neighstencil:sz_multi_tiered");" + + memory->create(binsizex_multi_tiered, n, n, + "neighstencil:binsizex_multi_tiered");" + memory->create(binsizey_multi_tiered, n, n, + "neighstencil:binsizey_multi_tiered");" + memory->create(binsizez_multi_tiered, n, n, + "neighstencil:binsizez_multi_tiered");" + + // Determine which stencils need to be built + set_stencil_properties(); + + for (i = 1; i <= n; ++i) { + for (j = 1; j <= n; ++j) { + + // Skip creation of unused stencils + if (stencil_skip[i][j]) continue; + + // Copy bin info for this particular pair of types + bin_type = stencil_bin_type[i][j]; + copy_bin_info_bytype(bin_type); + + binsizex_multi_tiered[i][j] = binsizex; + binsizey_multi_tiered[i][j] = binsizey; + binsizez_multi_tiered[i][j] = binsizez; + + stencil_range = stencil_cut[i][j]; + + sx = static_cast (stencil_range*bininvx); + if (sx*binsizex < stencil_range) sx++; + sy = static_cast (stencil_range*bininvy); + if (sy*binsizey < stencil_range) sy++; + sz = static_cast (stencil_range*bininvz); + if (sz*binsizez < stencil_range) sz++; + + sx_multi_tiered[i][j] = sx; + sy_multi_tiered[i][j] = sy; + sz_multi_tiered[i][j] = sz; + + smax = ((2*sx+1) * (2*sy+1) * (2*sz+1)); + + if (smax > maxstencil_multi_tiered[i][j]) { + maxstencil_multi_tiered[i][j] = smax; + memory->destroy(stencil_multi_tiered[i][j]); + memory->create(stencil_multi_tiered[i][j], smax, + "neighstencil::stencil_multi_tiered"); + } } } } @@ -231,6 +363,10 @@ double NStencil::memory_usage() } else if (neighstyle == Neighbor::MULTI) { bytes += atom->ntypes*maxstencil_multi * sizeof(int); bytes += atom->ntypes*maxstencil_multi * sizeof(double); + } else if (neighstyle == Neighbor::MULTI_TIERED) { + bytes += atom->ntypes*maxstencil_multi * sizeof(int); + bytes += atom->ntypes*maxstencil_multi * sizeof(int); + bytes += atom->ntypes*maxstencil_multi * sizeof(double); } return bytes; } diff --git a/src/nstencil.h b/src/nstencil.h index bdd656b937..58c39ee13c 100644 --- a/src/nstencil.h +++ b/src/nstencil.h @@ -29,14 +29,22 @@ class NStencil : protected Pointers { int **stencilxyz; // bin offsets in xyz dims int *nstencil_multi; // # bins in each type-based multi stencil int **stencil_multi; // list of bin offsets in each stencil + int ** nstencil_multi_tiered; // # bins bins in each itype-jtype tiered multi stencil + int *** stencil_multi_tiered; // list of bin offsets in each tiered multi stencil + int ** maxstencil_type; // max double **distsq_multi; // sq distances to bins in each stencil int sx,sy,sz; // extent of stencil in each dim + int **sx_multi_tiered; // analogs for multi tiered + int **sy_multi_tiered; + int **sz_multi_tiered; - double cutoff_custom; // cutoff set by requestor - - // BYTYPE stencils - int ** nstencil_type; // No. of bins for stencil[itype][jtype] - int *** stencil_type; // Stencil for [itype][jtype] + double cutoff_custom; // cutoff set by requestor + + // Arrays to store options for multi/tiered itype-jtype stencils + bool **stencil_half; // flag creation of a half stencil for itype-jtype + bool **stencil_skip; // skip creation of itype-jtype stencils (for newton on) + int **stencil_bin_type; // what type to use for bin information + double **stencil_cut; // cutoff used for stencil size NStencil(class LAMMPS *); virtual ~NStencil(); @@ -57,12 +65,19 @@ class NStencil : protected Pointers { double cutneighmax; double cutneighmaxsq; double *cuttypesq; + double *cutneighsq; // data from NBin class int mbinx,mbiny,mbinz; double binsizex,binsizey,binsizez; double bininvx,bininvy,bininvz; + + // analogs for multi-tiered + + double **binsizex_multi_tiered; + double **binsizey_multi_tiered; + double **binsizez_multi_tiered; // data common to all NStencil variants @@ -76,6 +91,11 @@ class NStencil : protected Pointers { void copy_bin_info(); // copy info from NBin class double bin_distance(int, int, int); // distance between bin corners + + // methods for multi/tiered NStencil + + void copy_bin_info_multi_tiered(int); // copy mult/tiered info from NBin class + void set_stencil_properties(); // determine which stencils to build and how }; } diff --git a/src/nstencil_full_multi_tiered_3d.cpp b/src/nstencil_full_multi2_3d.cpp similarity index 90% rename from src/nstencil_full_multi_tiered_3d.cpp rename to src/nstencil_full_multi2_3d.cpp index cecccdfb14..099e2adeb8 100644 --- a/src/nstencil_full_multi_tiered_3d.cpp +++ b/src/nstencil_full_multi2_3d.cpp @@ -46,23 +46,9 @@ NStencilFullBytype3d::~NStencilFullBytype3d() { } } -/* ---------------------------------------------------------------------- */ - -void NStencilFullBytype3d::copy_bin_info_bytype(int itype) { - - mbinx = nb->mbinx_type[itype]; - mbiny = nb->mbiny_type[itype]; - mbinz = nb->mbinz_type[itype]; - binsizex = nb->binsizex_type[itype]; - binsizey = nb->binsizey_type[itype]; - binsizez = nb->binsizez_type[itype]; - bininvx = nb->bininvx_type[itype]; - bininvy = nb->bininvy_type[itype]; - bininvz = nb->bininvz_type[itype]; -} /* ---------------------------------------------------------------------- */ - +INCORPORTE INTO CREATE THEN DELETE, NOTE NAME OF CUTNEIGHMAX ETC int NStencilFullBytype3d::copy_neigh_info_bytype(int itype) { cutneighmaxsq = neighbor->cutneighsq[itype][itype]; @@ -104,13 +90,13 @@ void NStencilFullBytype3d::create_setup() maxstencil_type[itype][jtype] = 0; } } - } + } MOVE TO PARENT CLASS // like -> like => use standard newtoff stencil at bin for (itype = 1; itype <= maxtypes; ++itype) { copy_bin_info_bytype(itype); - smax = copy_neigh_info_bytype(itype); + smax = copy_neigh_info_bytype(itype); uses cutneighsq[itype][itype] to create s's if (smax > maxstencil_type[itype][itype]) { maxstencil_type[itype][itype] = smax; memory->destroy(stencil_type[itype][itype]); @@ -127,7 +113,7 @@ void NStencilFullBytype3d::create_setup() for (itype = 1; itype <= maxtypes; ++itype) { for (jtype = 1; jtype <= maxtypes; ++jtype) { if (itype == jtype) continue; - if (cuttypesq[itype] <= cuttypesq[jtype]) { + if (cuttypesq[itype] <= cuttypesq[jtype]) { This does work to say which prticle is smller // Potential destroy/create problem? nstencil_type[itype][jtype] = nstencil_type[jtype][jtype]; stencil_type[itype][jtype] = stencil_type[jtype][jtype]; @@ -136,7 +122,7 @@ void NStencilFullBytype3d::create_setup() copy_bin_info_bytype(jtype); // smax = copy_neigh_info_bytype(jtype); - cutneighmaxsq = cuttypesq[jtype]; + cutneighmaxsq = cuttypesq[jtype]; Does it need to be this big? Can't I use cutneighsq[i][j]? cutneighmax = sqrt(cutneighmaxsq); sx = static_cast (cutneighmax*bininvx); if (sx*binsizex < cutneighmax) sx++; diff --git a/src/nstencil_full_multi_tiered_3d.h b/src/nstencil_full_multi2_3d.h similarity index 83% rename from src/nstencil_full_multi_tiered_3d.h rename to src/nstencil_full_multi2_3d.h index 6e61365d17..b9b835fd24 100644 --- a/src/nstencil_full_multi_tiered_3d.h +++ b/src/nstencil_full_multi2_3d.h @@ -13,15 +13,15 @@ #ifdef NSTENCIL_CLASS -NStencilStyle(full/bytype/3d, - NStencilFullBytype3d, - NS_FULL | NS_BYTYPE | NS_3D | +NStencilStyle(full/multi/tiered/3d, + NStencilFullMultiTiered3d, + NS_FULL | NS_Multi_Tiered | NS_3D | NS_NEWTON | NS_NEWTOFF | NS_ORTHO | NS_TRI) #else -#ifndef LMP_NSTENCIL_FULL_BYTYPE_3D_H -#define LMP_NSTENCIL_FULL_BYTYPE_3D_H +#ifndef LMP_NSTENCIL_FULL_MULTI_TIERED_3D_H +#define LMP_NSTENCIL_FULL_MULTI_TIERED_3D_H #include "nstencil.h" @@ -37,7 +37,6 @@ class NStencilFullBytype3d : public NStencil { private: int ** maxstencil_type; - void copy_bin_info_bytype(int); int copy_neigh_info_bytype(int); void create_newtoff(int, int, double); diff --git a/src/nstencil_half_multi_tiered_2d_newton.cpp b/src/nstencil_half_multi2_2d_newton.cpp similarity index 100% rename from src/nstencil_half_multi_tiered_2d_newton.cpp rename to src/nstencil_half_multi2_2d_newton.cpp diff --git a/src/nstencil_half_multi_tiered_2d_newton.h b/src/nstencil_half_multi2_2d_newton.h similarity index 100% rename from src/nstencil_half_multi_tiered_2d_newton.h rename to src/nstencil_half_multi2_2d_newton.h diff --git a/src/nstencil_half_multi_tiered_3d_newtoff.cpp b/src/nstencil_half_multi2_3d_newtoff.cpp similarity index 100% rename from src/nstencil_half_multi_tiered_3d_newtoff.cpp rename to src/nstencil_half_multi2_3d_newtoff.cpp diff --git a/src/nstencil_half_multi_tiered_3d_newtoff.h b/src/nstencil_half_multi2_3d_newtoff.h similarity index 100% rename from src/nstencil_half_multi_tiered_3d_newtoff.h rename to src/nstencil_half_multi2_3d_newtoff.h diff --git a/src/nstencil_half_multi_tiered_3d_newton.cpp b/src/nstencil_half_multi2_3d_newton.cpp similarity index 100% rename from src/nstencil_half_multi_tiered_3d_newton.cpp rename to src/nstencil_half_multi2_3d_newton.cpp diff --git a/src/nstencil_half_multi_tiered_3d_newton.h b/src/nstencil_half_multi2_3d_newton.h similarity index 100% rename from src/nstencil_half_multi_tiered_3d_newton.h rename to src/nstencil_half_multi2_3d_newton.h diff --git a/src/nstencil_half_multi_tiered_3d_newton_tri.cpp b/src/nstencil_half_multi2_3d_newton_tri.cpp similarity index 100% rename from src/nstencil_half_multi_tiered_3d_newton_tri.cpp rename to src/nstencil_half_multi2_3d_newton_tri.cpp diff --git a/src/nstencil_half_multi_tiered_3d_newton_tri.h b/src/nstencil_half_multi2_3d_newton_tri.h similarity index 100% rename from src/nstencil_half_multi_tiered_3d_newton_tri.h rename to src/nstencil_half_multi2_3d_newton_tri.h