From b421c3d67652aa6fd0657542e5914a633c73bf47 Mon Sep 17 00:00:00 2001 From: Joel Clemmer Date: Tue, 22 Dec 2020 10:20:06 -0700 Subject: [PATCH] Adding arguments, initialization, and communication for custom groupings --- src/comm_brick.cpp | 44 ++++++++++++----------- src/comm_tiled.cpp | 46 +++++++++++++----------- src/neighbor.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++++- src/neighbor.h | 9 ++++- 4 files changed, 143 insertions(+), 43 deletions(-) diff --git a/src/comm_brick.cpp b/src/comm_brick.cpp index 7f84d619e4..528456ab7c 100644 --- a/src/comm_brick.cpp +++ b/src/comm_brick.cpp @@ -175,10 +175,11 @@ void CommBrick::setup() if (mode == Comm::MULTI) { if (multi_reduce) { - // If using multi/reduce binlists, communicate itype particles a distance - // equal to the max of itype-jtype interaction given smaller jtype particles - double **cutneighsq = neighbor->cutneighsq; - double *cuttypesq = neighbor->cuttypesq; + // If using multi/reduce, communicate itype particles a distance equal + // to the max of itype-jtype group interaction given smaller jtype group + int igroup, jgroup; + double **cutmultisq = neighbor->cutmultisq; + int *map_type_multi = neighbor->map_type_multi; for (i = 1; i <= ntypes; i++) { if (cutusermulti) { @@ -191,11 +192,14 @@ void CommBrick::setup() cutghostmulti[i][2] = 0.0; } + igroup = map_type_multi[i]; for (j = 1; j <= ntypes; j++){ - if(cutneighsq[j][j] > cutneighsq[i][i]) continue; - cutghostmulti[i][0] = MAX(cutghostmulti[i][0],sqrt(cutneighsq[i][j])); - cutghostmulti[i][1] = MAX(cutghostmulti[i][1],sqrt(cutneighsq[i][j])); - cutghostmulti[i][2] = MAX(cutghostmulti[i][2],sqrt(cutneighsq[i][j])); + jgroup = map_type_multi[j]; + + if(cutmultisq[jgroup][jgroup] > cutmultisq[igroup][igroup]) continue; + cutghostmulti[i][0] = MAX(cutghostmulti[i][0],sqrt(cutmultisq[igroup][jgroup])); + cutghostmulti[i][1] = MAX(cutghostmulti[i][1],sqrt(cutmultisq[igroup][jgroup])); + cutghostmulti[i][2] = MAX(cutghostmulti[i][2],sqrt(cutmultisq[igroup][jgroup])); } } } else { @@ -226,10 +230,11 @@ void CommBrick::setup() if (mode == Comm::MULTI) { if (multi_reduce) { - // If using multi/reduce binlists, communicate itype particles a distance - // equal to the max of itype-jtype interaction given smaller jtype particles - double **cutneighsq = neighbor->cutneighsq; - double *cuttypesq = neighbor->cuttypesq; + // If using multi/reduce, communicate itype particles a distance equal + // to the max of itype-jtype group interaction given smaller jtype group + int igroup, jgroup; + double **cutmultisq = neighbor->cutmultisq; + int *map_type_multi = neighbor->map_type_multi; for (i = 1; i <= ntypes; i++) { if (cutusermulti) { @@ -242,16 +247,15 @@ void CommBrick::setup() cutghostmulti[i][2] = 0.0; } + igroup = map_type_multi[i]; for (j = 1; j <= ntypes; j++){ - if(cutneighsq[j][j] > cutneighsq[i][i]) continue; - cutghostmulti[i][0] = MAX(cutghostmulti[i][0],sqrt(cutneighsq[i][j])); - cutghostmulti[i][1] = MAX(cutghostmulti[i][1],sqrt(cutneighsq[i][j])); - cutghostmulti[i][2] = MAX(cutghostmulti[i][2],sqrt(cutneighsq[i][j])); + jgroup = map_type_multi[j]; + + if(cutmultisq[jgroup][jgroup] > cutmultisq[igroup][igroup]) continue; + cutghostmulti[i][0] = MAX(cutghostmulti[i][0],sqrt(cutmultisq[igroup][jgroup])); + cutghostmulti[i][1] = MAX(cutghostmulti[i][1],sqrt(cutmultisq[igroup][jgroup])); + cutghostmulti[i][2] = MAX(cutghostmulti[i][2],sqrt(cutmultisq[igroup][jgroup])); } - - cutghostmulti[i][0] *= length0; - cutghostmulti[i][1] *= length1; - cutghostmulti[i][2] *= length2; } } else { // If using a single binlist, use the max itype-jtype interaction distance for communication diff --git a/src/comm_tiled.cpp b/src/comm_tiled.cpp index ce76fa7442..64d1207a64 100644 --- a/src/comm_tiled.cpp +++ b/src/comm_tiled.cpp @@ -177,29 +177,33 @@ void CommTiled::setup() if (mode == Comm::MULTI) { double cut; if (multi_reduce) { - // If using multi/reduce binlists, communicate itype particles a distance - // equal to the max of itype-jtype interaction given smaller jtype particles - double **cutneighsq = neighbor->cutneighsq; - double *cuttypesq = neighbor->cuttypesq; - for (i = 1; i <= ntypes; i++) { + // If using multi/reduce, communicate itype particles a distance equal + // to the max of itype-jtype group interaction given smaller jtype group + int igroup, jgroup; + double **cutmultisq = neighbor->cutmultisq; + int *map_type_multi = neighbor->map_type_multi; + for (i = 1; i <= ntypes; i++) { - if (cutusermulti) { - cutghostmulti[i][0] = cutusermulti[i]; - cutghostmulti[i][1] = cutusermulti[i]; - cutghostmulti[i][2] = cutusermulti[i]; - } else { - cutghostmulti[i][0] = 0.0; - cutghostmulti[i][1] = 0.0; - cutghostmulti[i][2] = 0.0; - } - - for (j = 1; j <= ntypes; j++){ - if(cutneighsq[j][j] > cutneighsq[i][i]) continue; - cutghostmulti[i][0] = MAX(cutghostmulti[i][0],sqrt(cutneighsq[i][j])); - cutghostmulti[i][1] = MAX(cutghostmulti[i][1],sqrt(cutneighsq[i][j])); - cutghostmulti[i][2] = MAX(cutghostmulti[i][2],sqrt(cutneighsq[i][j])); - } + if (cutusermulti) { + cutghostmulti[i][0] = cutusermulti[i]; + cutghostmulti[i][1] = cutusermulti[i]; + cutghostmulti[i][2] = cutusermulti[i]; + } else { + cutghostmulti[i][0] = 0.0; + cutghostmulti[i][1] = 0.0; + cutghostmulti[i][2] = 0.0; } + + igroup = map_type_multi[i]; + for (j = 1; j <= ntypes; j++){ + jgroup = map_type_multi[j]; + + if(cutmultisq[jgroup][jgroup] > cutmultisq[igroup][igroup]) continue; + cutghostmulti[i][0] = MAX(cutghostmulti[i][0],sqrt(cutmultisq[igroup][jgroup])); + cutghostmulti[i][1] = MAX(cutghostmulti[i][1],sqrt(cutmultisq[igroup][jgroup])); + cutghostmulti[i][2] = MAX(cutghostmulti[i][2],sqrt(cutmultisq[igroup][jgroup])); + } + } } else { // If using a single binlist, use the max itype-jtype interaction distance for communication double *cuttype = neighbor->cuttype; diff --git a/src/neighbor.cpp b/src/neighbor.cpp index d130219931..b08de6cb02 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -188,6 +188,12 @@ pairclass(nullptr), pairnames(nullptr), pairmasks(nullptr) nex_mol = maxex_mol = 0; ex_mol_group = ex_mol_bit = ex_mol_intra = nullptr; + // Multi data + + map_type_multi = nullptr; + cutmultisq = nullptr; + multi_groups = 0; + // Kokkos setting copymode = 0; @@ -253,6 +259,9 @@ Neighbor::~Neighbor() memory->destroy(ex_mol_group); delete [] ex_mol_bit; memory->destroy(ex_mol_intra); + + memory->destroy(map_type_multi); + memory->destroy(cutmultisq); } /* ---------------------------------------------------------------------- */ @@ -336,6 +345,35 @@ void Neighbor::init() } cutneighmaxsq = cutneighmax * cutneighmax; + // multi cutoffs + if(style == Neighbor::MULTI){ + int igroup, jgroup; + // If not defined, create default mapping + if(not map_type_multi) { + memory->create(map_type_multi,n+1,"neigh:map_type_multi"); + n_multi_groups = n; + for(i = 1; i <= n; i++) + map_type_multi[i] = i-1; + } + + // Define maximum interaction distance for each pair of groups + memory->grow(cutmultisq, n_multi_groups, n_multi_groups, "neigh:cutmultisq"); + for(i = 0; i < n_multi_groups; i++) + for(j = 0; j < n_multi_groups; j++) + cutmultisq[i][j] = 0.0; + + for(i = 1; i <= n; i++){ + igroup = map_type_multi[i]; + for(j = 1; j <= n; j++){ + jgroup = map_type_multi[j]; + if(cutneighsq[i][j] > cutmultisq[igroup][jgroup]) { + cutmultisq[igroup][jgroup] = cutneighsq[i][j]; + cutmultisq[jgroup][igroup] = cutneighsq[i][j]; + } + } + } + } + // rRESPA cutoffs int respa = 0; @@ -1934,6 +1972,7 @@ NPair *Neighbor::pair_creator(LAMMPS *lmp) /* ---------------------------------------------------------------------- setup neighbor binning and neighbor stencils called before run and every reneighbor if box size/shape changes + initialize default settings for multi before run only operates on perpetual lists build_one() operates on occasional lists ------------------------------------------------------------------------- */ @@ -2379,9 +2418,55 @@ void Neighbor::modify_params(int narg, char **arg) } else if (strcmp(arg[iarg+1],"none") == 0) { nex_type = nex_group = nex_mol = 0; iarg += 2; - + } else error->all(FLERR,"Illegal neigh_modify command"); + } else if (strcmp(arg[iarg],"multi/custom") == 0) { + if(style != Neighbor::MULTI) + error->all(FLERR,"Cannot use multi/custom command without multi setting"); + + if(iarg+2 > narg) + error->all(FLERR,"Invalid multi/custom command"); + int nextra = utils::inumeric(FLERR,arg[iarg+1],false,lmp); + if(iarg+1+nextra > narg) + error->all(FLERR,"Invalid multi/custom command"); + int ntypes = atom->ntypes; + int n, nlo, nhi, i, j, igroup, jgroup; + + if(not map_type_multi) + memory->create(map_type_multi,ntypes+1,"neigh:map_type_multi"); + + // Erase previous mapping + for(i = 1; i <= ntypes; i++) + map_type_multi[i] = -1; + + // For each custom range, define mapping for types in interval + n_multi_groups = 0; + char *id; + for(i = 0; i < nextra; i++){ + n = strlen(arg[iarg+2+i]) + 1; + id = new char[n]; + strcpy(id,arg[iarg+2+i]); + utils::bounds(FLERR,id,1,ntypes,nlo,nhi,error); + delete [] id; + + for (j = nlo; j <= nhi; j++) { + if(map_type_multi[j] != -1) + error->all(FLERR,"Type specified more than once in multi/custom commnd"); + map_type_multi[j] = n_multi_groups; + } + n_multi_groups += 1; + } + + // Create seprate group for each undefined atom type + for(i = 1; i <= ntypes; i++){ + if(map_type_multi[i] == -1){ + map_type_multi[i] = n_multi_groups; + n_multi_groups += 1; + } + } + + iarg += 2 + nextra; } else error->all(FLERR,"Illegal neigh_modify command"); } } diff --git a/src/neighbor.h b/src/neighbor.h index d1a5cf9112..ad3de851cf 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -21,7 +21,7 @@ namespace LAMMPS_NS { class Neighbor : protected Pointers { public: enum{NSQ,BIN,MULTI_OLD,MULTI}; - int style; // 0,1,2 = nsq, bin, multi/old, multi + int style; // 0,1,2,3 = nsq, bin, multi/old, multi int every; // build every this many steps int delay; // delay build for this many steps int dist_check; // 0 = always build, 1 = only if 1/2 dist @@ -102,6 +102,13 @@ class Neighbor : protected Pointers { int nimproperlist; // list of impropers to compute int **improperlist; + // optional type grouping for multi + + int multi_groups; // 1 if custom groupings are defined for multi + int n_multi_groups; // # of custom groupings + int *map_type_multi; // ntype array mapping types to custom groupings + double **cutmultisq; // cutoffs for each combination of custom groupings + // public methods Neighbor(class LAMMPS *);