Renamed to multi2, initial stencil edits

This commit is contained in:
Joel Clemmer
2020-11-10 16:39:56 -07:00
parent 12288630f5
commit 943a187be7
35 changed files with 845 additions and 702 deletions

View File

@ -76,7 +76,7 @@ Comm::Comm(LAMMPS *lmp) : Pointers(lmp)
grid2proc = nullptr; grid2proc = nullptr;
xsplit = ysplit = zsplit = nullptr; xsplit = ysplit = zsplit = nullptr;
rcbnew = 0; rcbnew = 0;
multi_tiered = 0; multi2 = 0;
// use of OpenMP threads // use of OpenMP threads
// query OpenMP for number of threads/process set by user at run-time // 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++) for (int i = 0; i < nfix; i++)
if (fix[i]->maxexchange_dynamic) maxexchange_fix_dynamic = 1; if (fix[i]->maxexchange_dynamic) maxexchange_fix_dynamic = 1;
// Can't used multi/tiered communication with Newton off // Can't used multi2 communication with Newton off
if (force->newton == 0 && multi_tiered) if (force->newton == 0 && multi2)
error->all(FLERR,"Cannot use multi/tiered communication with Newton off"); 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) for (i=nlo; i<=nhi; ++i)
cutusermulti[i] = cut; cutusermulti[i] = cut;
iarg += 3; iarg += 3;
} else if (strcmp(arg[iarg],"cutoff/tiered") == 0) { } else if (strcmp(arg[iarg],"cutoff/multi2") == 0) {
if (mode == Comm::SINGLE) if (mode == Comm::SINGLE)
error->all(FLERR,"Use cutoff/tiered in mode multi only"); error->all(FLERR,"Use cutoff/multi2 in mode multi only");
multi_tiered = 1; multi2 = 1;
iarg += 1; iarg += 1;
} else if (strcmp(arg[iarg],"vel") == 0) { } else if (strcmp(arg[iarg],"vel") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal comm_modify command"); if (iarg+2 > narg) error->all(FLERR,"Illegal comm_modify command");

View File

@ -161,7 +161,7 @@ class Comm : protected Pointers {
int (*)(int, char *, int &, int *&, char *&, void *), int (*)(int, char *, int &, int *&, char *&, void *),
int, char *&, int, void *, int); int, char *&, int, void *, int);
void rendezvous_stats(int, int, int, int, int, int, bigint); 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: public:
enum{MULTIPLE}; enum{MULTIPLE};

View File

@ -174,8 +174,8 @@ void CommBrick::setup()
cutghost[0] = cutghost[1] = cutghost[2] = cut; cutghost[0] = cutghost[1] = cutghost[2] = cut;
if (mode == Comm::MULTI) { if (mode == Comm::MULTI) {
if (multi_tiered) { if (multi2) {
// If using tiered binlists, use the itype-itype interaction distance for communication // If using multi2 binlists, use the itype-itype interaction distance for communication
double **cutneighsq = neighbor->cutneighsq; double **cutneighsq = neighbor->cutneighsq;
for (i = 1; i <= ntypes; i++) { for (i = 1; i <= ntypes; i++) {
cut = 0.0; cut = 0.0;

View File

@ -176,8 +176,8 @@ void CommTiled::setup()
if (mode == Comm::MULTI) { if (mode == Comm::MULTI) {
double cut; double cut;
if (multi_tiered) { if (multi2) {
// If using tiered binlists, use the itype-itype interaction distance for communication // If using multi2 binlists, use the itype-itype interaction distance for communication
double **cutneighsq = neighbor->cutneighsq; double **cutneighsq = neighbor->cutneighsq;
for (i = 1; i <= ntypes; i++) { for (i = 1; i <= ntypes; i++) {
cut = 0.0; cut = 0.0;

View File

@ -31,6 +31,21 @@ NBin::NBin(LAMMPS *lmp) : Pointers(lmp)
bins = nullptr; bins = nullptr;
atom2bin = 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; neighbor->last_setup_bins = -1;
// geometry settings // geometry settings
@ -48,6 +63,37 @@ NBin::~NBin()
memory->destroy(binhead); memory->destroy(binhead);
memory->destroy(bins); memory->destroy(bins);
memory->destroy(atom2bin); 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; 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<int> ((x[0]-bboxhi[0])*bininvx) + nbinx;
else if (x[0] >= bboxlo[0]) {
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx);
ix = MIN(ix,nbinx-1);
} else
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1;
if (x[1] >= bboxhi[1])
iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny;
else if (x[1] >= bboxlo[1]) {
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy);
iy = MIN(iy,nbiny-1);
} else
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1;
if (x[2] >= bboxhi[2])
iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz;
else if (x[2] >= bboxlo[2]) {
iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz);
iz = MIN(iz,nbinz-1);
} else
iz = static_cast<int> ((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;
}

View File

@ -22,6 +22,9 @@ class NBin : protected Pointers {
public: public:
int istyle; // 1-N index into binnames int istyle; // 1-N index into binnames
bigint last_bin; // last timestep atoms were binned 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 nbinx,nbiny,nbinz; // # of global bins
int mbins; // # of local bins and offset on this proc 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 *bins; // index of next atom in same bin
int *atom2bin; // bin assignment for each atom (local+ghost) int *atom2bin; // bin assignment for each atom (local+ghost)
double cutoff_custom; // cutoff set by requestor // Analogues for NBinMultimulti2
// Analogues for NBinType int *nbinx_multi2, *nbiny_multi2, *nbinz_multi2;
int * nbinx_type, * nbiny_type, * nbinz_type; int *mbins_multi2;
int * mbins_type; int *mbinx_multi2, *mbiny_multi2, *mbinz_multi2;
int * mbinx_type, * mbiny_type, * mbinz_type; int *mbinxlo_multi2, *mbinylo_multi2, *mbinzlo_multi2;
int * mbinxlo_type, * mbinylo_type, * mbinzlo_type; double *binsizex_multi2, *binsizey_multi2, *binsizez_multi2;
double * binsizex_type, * binsizey_type, * binsizez_type; double *bininvx_multi2, *bininvy_multi2, *bininvz_multi2;
double * bininvx_type, * bininvy_type, * bininvz_type;
int ** binhead_type;
int ** bins_type;
int ** atom2bin_type;
int **binhead_multi2;
int **bins_multi2;
int **atom2bin_multi2;
NBin(class LAMMPS *); NBin(class LAMMPS *);
~NBin(); ~NBin();
void post_constructor(class NeighRequest *); void post_constructor(class NeighRequest *);
virtual void copy_neighbor_info(); 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 setup_bins(int) = 0;
virtual void bin_atoms() = 0; virtual void bin_atoms() = 0;
virtual double memory_usage() {return 0.0;}
// Kokkos package // Kokkos package
int kokkos; // 1 if class stores Kokkos data int kokkos; // 1 if class stores Kokkos data
// For NBinType
virtual int coord2bin(double *, int);
protected: protected:
@ -81,12 +81,23 @@ class NBin : protected Pointers {
int dimension; int dimension;
int triclinic; int triclinic;
int maxbin; // size of binhead array // data for standard NBin
int maxatom; // size of bins array 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 // methods
int coord2bin(double *); int coord2bin(double *);
int coord2bin(double *, int);
}; };
} }

414
src/nbin_multi2.cpp Normal file
View File

@ -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<int> (bbox[0]*binsizeinv);
nbiny_multi2[n] = static_cast<int> (bbox[1]*binsizeinv);
if (dimension == 3) nbinz_multi2[n] = static_cast<int> (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<int> ((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<int> ((coord-bboxlo[0])*bininvx_multi2[n]);
coord = bsubboxlo[1] - SMALL*bbox[1];
mbinylo_multi2[n] = static_cast<int> ((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<int> ((coord-bboxlo[1])*bininvy_multi2[n]);
if (dimension == 3) {
coord = bsubboxlo[2] - SMALL*bbox[2];
mbinzlo_multi2[n] = static_cast<int> ((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<int> ((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<int> ((x[0]-bboxhi[0])*bininvx_multi2[it]) + nbinx_multi2[it];
else if (x[0] >= bboxlo[0]) {
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx_multi2[it]);
ix = MIN(ix,nbinx_multi2[it]-1);
} else
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx_multi2[it]) - 1;
if (x[1] >= bboxhi[1])
iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy_multi2[it]) + nbiny_multi2[it];
else if (x[1] >= bboxlo[1]) {
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy_multi2[it]);
iy = MIN(iy,nbiny_multi2[it]-1);
} else
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy_multi2[it]) - 1;
if (x[2] >= bboxhi[2])
iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz_multi2[it]) + nbinz_multi2[it];
else if (x[2] >= bboxlo[2]) {
iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz_multi2[it]);
iz = MIN(iz,nbinz_multi2[it]-1);
} else
iz = static_cast<int> ((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;
}

View File

@ -13,36 +13,32 @@
#ifdef NBIN_CLASS #ifdef NBIN_CLASS
NBinStyle(bytype, NBinStyle(multi2,
NBinBytype, NBinMulti2,
NB_BYTYPE) NB_MULTI2)
#else #else
#ifndef LMP_NBIN_BYTYPE_H #ifndef LMP_NBIN_MULTI2_H
#define LMP_NBIN_BYTYPE_H #define LMP_NBIN_MULTI2_H
#include "nbin.h" #include "nbin.h"
namespace LAMMPS_NS { namespace LAMMPS_NS {
class NBinBytype : public NBin { class NBinMulti2 : public NBin {
public: public:
NBinBytype(class LAMMPS *); NBinMulti2(class LAMMPS *);
~NBinBytype(); ~NBinMulti2() {}
void bin_atoms_setup(int); void bin_atoms_setup(int);
void setup_bins(int); void setup_bins(int);
void bin_atoms(); void bin_atoms();
double memory_usage();
int coord2bin(double *x, int itype);
bigint memory_usage();
private: private:
int maxtypes;
int * maxbins_type;
void setup_types(); int coord2bin(double *, int);
int itype_min(); int itype_min();
}; };

View File

@ -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<int> (bbox[0]*binsizeinv);
nbiny_type[n] = static_cast<int> (bbox[1]*binsizeinv);
if (dimension == 3) nbinz_type[n] = static_cast<int> (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<int> ((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<int> ((coord-bboxlo[0])*bininvx_type[n]);
coord = bsubboxlo[1] - SMALL*bbox[1];
mbinylo_type[n] = static_cast<int> ((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<int> ((coord-bboxlo[1])*bininvy_type[n]);
if (dimension == 3) {
coord = bsubboxlo[2] - SMALL*bbox[2];
mbinzlo_type[n] = static_cast<int> ((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<int> ((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<int> ((x[0]-bboxhi[0])*bininvx_type[it]) + nbinx_type[it];
else if (x[0] >= bboxlo[0]) {
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx_type[it]);
ix = MIN(ix,nbinx_type[it]-1);
} else
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx_type[it]) - 1;
if (x[1] >= bboxhi[1])
iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy_type[it]) + nbiny_type[it];
else if (x[1] >= bboxlo[1]) {
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy_type[it]);
iy = MIN(iy,nbiny_type[it]-1);
} else
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy_type[it]) - 1;
if (x[2] >= bboxhi[2])
iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz_type[it]) + nbinz_type[it];
else if (x[2] >= bboxlo[2]) {
iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz_type[it]);
iz = MIN(iz,nbinz_type[it]-1);
} else
iz = static_cast<int> ((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;
}

View File

@ -29,6 +29,33 @@ using namespace LAMMPS_NS;
NBinStandard::NBinStandard(LAMMPS *lmp) : NBin(lmp) {} 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 setup neighbor binning geometry
bin numbering in each dimension is global: 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<int> ((x[0]-bboxhi[0])*bininvx) + nbinx;
else if (x[0] >= bboxlo[0]) {
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx);
ix = MIN(ix,nbinx-1);
} else
ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1;
if (x[1] >= bboxhi[1])
iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny;
else if (x[1] >= bboxlo[1]) {
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy);
iy = MIN(iy,nbiny-1);
} else
iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1;
if (x[2] >= bboxhi[2])
iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz;
else if (x[2] >= bboxlo[2]) {
iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz);
iz = MIN(iz,nbinz-1);
} else
iz = static_cast<int> ((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;
}

View File

@ -30,8 +30,14 @@ class NBinStandard : public NBin {
public: public:
NBinStandard(class LAMMPS *); NBinStandard(class LAMMPS *);
~NBinStandard() {} ~NBinStandard() {}
void bin_atoms_setup(int);
void setup_bins(int); void setup_bins(int);
void bin_atoms(); void bin_atoms();
double memory_usage();
private:
int coord2bin(double *);
}; };
} }

View File

@ -1620,12 +1620,12 @@ int Neighbor::choose_bin(NeighRequest *rq)
if (!rq->kokkos_device != !(mask & NB_KOKKOS_DEVICE)) continue; if (!rq->kokkos_device != !(mask & NB_KOKKOS_DEVICE)) continue;
if (!rq->kokkos_host != !(mask & NB_KOKKOS_HOST)) 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 (style == Neighbor::BIN || style == Neighbor::MULTI) {
if (!(mask & NB_STANDARD)) continue; if (!(mask & NB_STANDARD)) continue;
} else if (style == Neighbor::MULTI_TIERED) { } else if (style == Neighbor::MULTI2) {
if (!(mask & NB_MULTI_TIERED)) continue; if (!(mask & NB_MULTI2)) continue;
} }
return i+1; return i+1;
@ -1698,14 +1698,14 @@ int Neighbor::choose_stencil(NeighRequest *rq)
if (!rq->ghost != !(mask & NS_GHOST)) continue; if (!rq->ghost != !(mask & NS_GHOST)) continue;
if (!rq->ssa != !(mask & NS_SSA)) 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 (style == Neighbor::BIN) {
if (!(mask & NS_BIN)) continue; if (!(mask & NS_BIN)) continue;
} else if (style == Neighbor::MULTI) { } else if (style == Neighbor::MULTI) {
if (!(mask & NS_MULTI)) continue; if (!(mask & NS_MULTI)) continue;
} else if (style == Neighbor::MULT_TIERED) { } else if (style == Neighbor::MULTI2) {
if (!(mask & NS_MULT_TIERED)) continue; if (!(mask & NS_MULTI2)) continue;
} }
// dimension is 2 or 3 and must match // 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->halffull != !(mask & NP_HALF_FULL)) continue;
if (!rq->off2on != !(mask & NP_OFF2ON)) 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 (style == Neighbor::NSQ) {
if (!(mask & NP_NSQ)) continue; if (!(mask & NP_NSQ)) continue;
@ -1843,8 +1843,8 @@ int Neighbor::choose_pair(NeighRequest *rq)
if (!(mask & NP_BIN)) continue; if (!(mask & NP_BIN)) continue;
} else if (style == Neighbor::MULTI) { } else if (style == Neighbor::MULTI) {
if (!(mask & NP_MULTI)) continue; if (!(mask & NP_MULTI)) continue;
} else if (style == Neighbor::MULT_TIERED) { } else if (style == Neighbor::MULTI2) {
if (!(mask & NP_MULT_TIERED)) continue; if (!(mask & NP_MULTI2)) continue;
} }
// domain triclinic flag is on or off and must match // 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; if (strcmp(arg[1],"nsq") == 0) style = Neighbor::NSQ;
else if (strcmp(arg[1],"bin") == 0) style = Neighbor::BIN; 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") == 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"); else error->all(FLERR,"Illegal neighbor command");
if (style == Neighbor::MULTI && lmp->citeme) lmp->citeme->add(cite_neigh_multi); if (style == Neighbor::MULTI && lmp->citeme) lmp->citeme->add(cite_neigh_multi);

View File

@ -20,7 +20,7 @@ namespace LAMMPS_NS {
class Neighbor : protected Pointers { class Neighbor : protected Pointers {
public: public:
enum{NSQ,BIN,MULTI,MULTI_TIERED}; enum{NSQ,BIN,MULTI,MULTI2};
int style; // 0,1,2 = nsq, bin, multi int style; // 0,1,2 = nsq, bin, multi
int every; // build every this many steps int every; // build every this many steps
int delay; // delay build for 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_DEVICE = 1<<1;
static const int NB_KOKKOS_HOST = 1<<2; static const int NB_KOKKOS_HOST = 1<<2;
static const int NB_SSA = 1<<3; 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 NB_STANDARD = 1<<5;
static const int NS_BIN = 1<<0; static const int NS_BIN = 1<<0;
@ -254,7 +254,7 @@ namespace NeighConst {
static const int NS_TRI = 1<<9; static const int NS_TRI = 1<<9;
static const int NS_GHOST = 1<<10; static const int NS_GHOST = 1<<10;
static const int NS_SSA = 1<<11; 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_NSQ = 1<<0;
static const int NP_BIN = 1<<1; static const int NP_BIN = 1<<1;
@ -281,7 +281,7 @@ namespace NeighConst {
static const int NP_SKIP = 1<<22; static const int NP_SKIP = 1<<22;
static const int NP_HALF_FULL = 1<<23; static const int NP_HALF_FULL = 1<<23;
static const int NP_OFF2ON = 1<<24; static const int NP_OFF2ON = 1<<24;
static const int NP_MULTI_TIERED = 1<<25; static const int NP_MULTI2 = 1<<25;
} }
} }

View File

@ -51,6 +51,15 @@ using namespace LAMMPS_NS;
stencil follows same rules for half/full, newton on/off, triclinic stencil follows same rules for half/full, newton on/off, triclinic
cutoff is not cutneighmaxsq, but max cutoff for that atom type cutoff is not cutneighmaxsq, but max cutoff for that atom type
no versions that allow ghost on (any need for it?) 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) NStencil::NStencil(LAMMPS *lmp) : Pointers(lmp)
@ -64,6 +73,11 @@ NStencil::NStencil(LAMMPS *lmp) : Pointers(lmp)
nstencil_multi = nullptr; nstencil_multi = nullptr;
stencil_multi = nullptr; stencil_multi = nullptr;
distsq_multi = nullptr; distsq_multi = nullptr;
stencil_split = nullptr;
stencil_skip = nullptr;
stencil_bin_type = nullptr;
stencil_cut = nullptr;
dimension = domain->dimension; dimension = domain->dimension;
} }
@ -75,16 +89,44 @@ NStencil::~NStencil()
memory->destroy(stencil); memory->destroy(stencil);
memory->destroy(stencilxyz); memory->destroy(stencilxyz);
if (!stencil_multi) return; if (stencil_multi) {
int n = atom->ntypes; int n = atom->ntypes;
for (int i = 1; i <= n; i++) { for (int i = 1; i <= n; i++) {
memory->destroy(stencil_multi[i]); memory->destroy(stencil_multi[i]);
memory->destroy(distsq_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; cutneighmax = neighbor->cutneighmax;
cutneighmaxsq = neighbor->cutneighmaxsq; cutneighmaxsq = neighbor->cutneighmaxsq;
cuttypesq = neighbor->cuttypesq; cuttypesq = neighbor->cuttypesq;
cutneighsq = neighbor->cutneighsq;
// overwrite Neighbor cutoff with custom value set by requestor // overwrite Neighbor cutoff with custom value set by requestor
// only works for style = BIN (checked by Neighbor class) // only works for style = BIN (checked by Neighbor class)
@ -132,6 +175,23 @@ void NStencil::copy_bin_info()
bininvz = nb->bininvz; 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 NBin data is current
insure stencils are allocated large enough insure stencils are allocated large enough
@ -139,59 +199,131 @@ void NStencil::copy_bin_info()
void NStencil::create_setup() void NStencil::create_setup()
{ {
if (nb) copy_bin_info();
last_stencil = update->ntimestep; if (neighstyle != Neighbor::MULTI_TIERED){
if (nb) copy_bin_info();
// sx,sy,sz = max range of stencil in each dim last_stencil = update->ntimestep;
// smax = max possible size of entire 3d stencil
// stencil will be empty if cutneighmax = 0.0 // sx,sy,sz = max range of stencil in each dim
// smax = max possible size of entire 3d stencil
sx = static_cast<int> (cutneighmax*bininvx); // stencil will be empty if cutneighmax = 0.0
if (sx*binsizex < cutneighmax) sx++;
sy = static_cast<int> (cutneighmax*bininvy); sx = static_cast<int> (cutneighmax*bininvx);
if (sy*binsizey < cutneighmax) sy++; if (sx*binsizex < cutneighmax) sx++;
sz = static_cast<int> (cutneighmax*bininvz); sy = static_cast<int> (cutneighmax*bininvy);
if (sz*binsizez < cutneighmax) sz++; if (sy*binsizey < cutneighmax) sy++;
if (dimension == 2) sz = 0; sz = static_cast<int> (cutneighmax*bininvz);
if (sz*binsizez < cutneighmax) sz++;
int smax = (2*sx+1) * (2*sy+1) * (2*sz+1); if (dimension == 2) sz = 0;
// reallocate stencil structs if necessary int smax = (2*sx+1) * (2*sy+1) * (2*sz+1);
// for BIN and MULTI styles
// reallocate stencil structs if necessary
if (neighstyle == Neighbor::BIN) { // for BIN and MULTI styles
if (smax > maxstencil) {
maxstencil = smax; if (neighstyle == Neighbor::BIN) {
memory->destroy(stencil); if (smax > maxstencil) {
memory->create(stencil,maxstencil,"neighstencil:stencil"); maxstencil = smax;
if (xyzflag) { memory->destroy(stencil);
memory->destroy(stencilxyz); memory->create(stencil,maxstencil,"neighstencil:stencil");
memory->create(stencilxyz,maxstencil,3,"neighstencil:stencilxyz"); 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 { } else {
int i; int i, j, bin_type, smax;
double stencil_range;
int n = atom->ntypes; int n = atom->ntypes;
if (maxstencil_multi == 0) {
nstencil_multi = new int[n+1]; // Allocate arrays to store stencil information
stencil_multi = new int*[n+1]; memory->create(stencil_split, n, n,
distsq_multi = new double*[n+1]; "neighstencil:stencil_split");"
for (i = 1; i <= n; i++) { memory->create(stencil_skip, n, n,
nstencil_multi[i] = 0; "neighstencil:stencil_skip");"
stencil_multi[i] = nullptr; memory->create(stencil_bin_type, n, n,
distsq_multi[i] = nullptr; "neighstencil:stencil_bin_type");"
} memory->create(stencil_cut, n, n,
} "neighstencil:stencil_cut");"
if (smax > maxstencil_multi) {
maxstencil_multi = smax; memory->create(sx_multi_tiered, n, n,
for (i = 1; i <= n; i++) { "neighstencil:sx_multi_tiered");"
memory->destroy(stencil_multi[i]); memory->create(sy_multi_tiered, n, n,
memory->destroy(distsq_multi[i]); "neighstencil:sy_multi_tiered");"
memory->create(stencil_multi[i],maxstencil_multi, memory->create(sz_multi_tiered, n, n,
"neighstencil:stencil_multi"); "neighstencil:sz_multi_tiered");"
memory->create(distsq_multi[i],maxstencil_multi,
"neighstencil:distsq_multi"); 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<int> (stencil_range*bininvx);
if (sx*binsizex < stencil_range) sx++;
sy = static_cast<int> (stencil_range*bininvy);
if (sy*binsizey < stencil_range) sy++;
sz = static_cast<int> (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) { } else if (neighstyle == Neighbor::MULTI) {
bytes += atom->ntypes*maxstencil_multi * sizeof(int); bytes += atom->ntypes*maxstencil_multi * sizeof(int);
bytes += atom->ntypes*maxstencil_multi * sizeof(double); 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; return bytes;
} }

View File

@ -29,14 +29,22 @@ class NStencil : protected Pointers {
int **stencilxyz; // bin offsets in xyz dims int **stencilxyz; // bin offsets in xyz dims
int *nstencil_multi; // # bins in each type-based multi stencil int *nstencil_multi; // # bins in each type-based multi stencil
int **stencil_multi; // list of bin offsets in each 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 double **distsq_multi; // sq distances to bins in each stencil
int sx,sy,sz; // extent of stencil in each dim 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 double cutoff_custom; // cutoff set by requestor
// BYTYPE stencils // Arrays to store options for multi/tiered itype-jtype stencils
int ** nstencil_type; // No. of bins for stencil[itype][jtype] bool **stencil_half; // flag creation of a half stencil for itype-jtype
int *** stencil_type; // 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 *); NStencil(class LAMMPS *);
virtual ~NStencil(); virtual ~NStencil();
@ -57,12 +65,19 @@ class NStencil : protected Pointers {
double cutneighmax; double cutneighmax;
double cutneighmaxsq; double cutneighmaxsq;
double *cuttypesq; double *cuttypesq;
double *cutneighsq;
// data from NBin class // data from NBin class
int mbinx,mbiny,mbinz; int mbinx,mbiny,mbinz;
double binsizex,binsizey,binsizez; double binsizex,binsizey,binsizez;
double bininvx,bininvy,bininvz; 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 // data common to all NStencil variants
@ -76,6 +91,11 @@ class NStencil : protected Pointers {
void copy_bin_info(); // copy info from NBin class void copy_bin_info(); // copy info from NBin class
double bin_distance(int, int, int); // distance between bin corners 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
}; };
} }

View File

@ -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) { int NStencilFullBytype3d::copy_neigh_info_bytype(int itype) {
cutneighmaxsq = neighbor->cutneighsq[itype][itype]; cutneighmaxsq = neighbor->cutneighsq[itype][itype];
@ -104,13 +90,13 @@ void NStencilFullBytype3d::create_setup()
maxstencil_type[itype][jtype] = 0; maxstencil_type[itype][jtype] = 0;
} }
} }
} } MOVE TO PARENT CLASS
// like -> like => use standard newtoff stencil at bin // like -> like => use standard newtoff stencil at bin
for (itype = 1; itype <= maxtypes; ++itype) { for (itype = 1; itype <= maxtypes; ++itype) {
copy_bin_info_bytype(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]) { if (smax > maxstencil_type[itype][itype]) {
maxstencil_type[itype][itype] = smax; maxstencil_type[itype][itype] = smax;
memory->destroy(stencil_type[itype][itype]); memory->destroy(stencil_type[itype][itype]);
@ -127,7 +113,7 @@ void NStencilFullBytype3d::create_setup()
for (itype = 1; itype <= maxtypes; ++itype) { for (itype = 1; itype <= maxtypes; ++itype) {
for (jtype = 1; jtype <= maxtypes; ++jtype) { for (jtype = 1; jtype <= maxtypes; ++jtype) {
if (itype == jtype) continue; 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? // Potential destroy/create problem?
nstencil_type[itype][jtype] = nstencil_type[jtype][jtype]; nstencil_type[itype][jtype] = nstencil_type[jtype][jtype];
stencil_type[itype][jtype] = stencil_type[jtype][jtype]; stencil_type[itype][jtype] = stencil_type[jtype][jtype];
@ -136,7 +122,7 @@ void NStencilFullBytype3d::create_setup()
copy_bin_info_bytype(jtype); copy_bin_info_bytype(jtype);
// smax = copy_neigh_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); cutneighmax = sqrt(cutneighmaxsq);
sx = static_cast<int> (cutneighmax*bininvx); sx = static_cast<int> (cutneighmax*bininvx);
if (sx*binsizex < cutneighmax) sx++; if (sx*binsizex < cutneighmax) sx++;

View File

@ -13,15 +13,15 @@
#ifdef NSTENCIL_CLASS #ifdef NSTENCIL_CLASS
NStencilStyle(full/bytype/3d, NStencilStyle(full/multi/tiered/3d,
NStencilFullBytype3d, NStencilFullMultiTiered3d,
NS_FULL | NS_BYTYPE | NS_3D | NS_FULL | NS_Multi_Tiered | NS_3D |
NS_NEWTON | NS_NEWTOFF | NS_ORTHO | NS_TRI) NS_NEWTON | NS_NEWTOFF | NS_ORTHO | NS_TRI)
#else #else
#ifndef LMP_NSTENCIL_FULL_BYTYPE_3D_H #ifndef LMP_NSTENCIL_FULL_MULTI_TIERED_3D_H
#define LMP_NSTENCIL_FULL_BYTYPE_3D_H #define LMP_NSTENCIL_FULL_MULTI_TIERED_3D_H
#include "nstencil.h" #include "nstencil.h"
@ -37,7 +37,6 @@ class NStencilFullBytype3d : public NStencil {
private: private:
int ** maxstencil_type; int ** maxstencil_type;
void copy_bin_info_bytype(int);
int copy_neigh_info_bytype(int); int copy_neigh_info_bytype(int);
void create_newtoff(int, int, double); void create_newtoff(int, int, double);