Renamed to multi2, initial stencil edits
This commit is contained in:
14
src/comm.cpp
14
src/comm.cpp
@ -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");
|
||||||
|
|||||||
@ -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};
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
138
src/nbin.cpp
138
src/nbin.cpp
@ -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;
|
|
||||||
}
|
|
||||||
|
|||||||
47
src/nbin.h
47
src/nbin.h
@ -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
414
src/nbin_multi2.cpp
Normal 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;
|
||||||
|
}
|
||||||
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@ -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 *);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
250
src/nstencil.cpp
250
src/nstencil.cpp
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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++;
|
||||||
@ -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);
|
||||||
|
|
||||||
Reference in New Issue
Block a user