Adding arguments, initialization, and communication for custom groupings

This commit is contained in:
Joel Clemmer
2020-12-22 10:20:06 -07:00
parent 5ae32146eb
commit b421c3d676
4 changed files with 143 additions and 43 deletions

View File

@ -175,10 +175,11 @@ void CommBrick::setup()
if (mode == Comm::MULTI) { if (mode == Comm::MULTI) {
if (multi_reduce) { if (multi_reduce) {
// If using multi/reduce binlists, communicate itype particles a distance // If using multi/reduce, communicate itype particles a distance equal
// equal to the max of itype-jtype interaction given smaller jtype particles // to the max of itype-jtype group interaction given smaller jtype group
double **cutneighsq = neighbor->cutneighsq; int igroup, jgroup;
double *cuttypesq = neighbor->cuttypesq; double **cutmultisq = neighbor->cutmultisq;
int *map_type_multi = neighbor->map_type_multi;
for (i = 1; i <= ntypes; i++) { for (i = 1; i <= ntypes; i++) {
if (cutusermulti) { if (cutusermulti) {
@ -191,11 +192,14 @@ void CommBrick::setup()
cutghostmulti[i][2] = 0.0; cutghostmulti[i][2] = 0.0;
} }
igroup = map_type_multi[i];
for (j = 1; j <= ntypes; j++){ for (j = 1; j <= ntypes; j++){
if(cutneighsq[j][j] > cutneighsq[i][i]) continue; jgroup = map_type_multi[j];
cutghostmulti[i][0] = MAX(cutghostmulti[i][0],sqrt(cutneighsq[i][j]));
cutghostmulti[i][1] = MAX(cutghostmulti[i][1],sqrt(cutneighsq[i][j])); if(cutmultisq[jgroup][jgroup] > cutmultisq[igroup][igroup]) continue;
cutghostmulti[i][2] = MAX(cutghostmulti[i][2],sqrt(cutneighsq[i][j])); 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 { } else {
@ -226,10 +230,11 @@ void CommBrick::setup()
if (mode == Comm::MULTI) { if (mode == Comm::MULTI) {
if (multi_reduce) { if (multi_reduce) {
// If using multi/reduce binlists, communicate itype particles a distance // If using multi/reduce, communicate itype particles a distance equal
// equal to the max of itype-jtype interaction given smaller jtype particles // to the max of itype-jtype group interaction given smaller jtype group
double **cutneighsq = neighbor->cutneighsq; int igroup, jgroup;
double *cuttypesq = neighbor->cuttypesq; double **cutmultisq = neighbor->cutmultisq;
int *map_type_multi = neighbor->map_type_multi;
for (i = 1; i <= ntypes; i++) { for (i = 1; i <= ntypes; i++) {
if (cutusermulti) { if (cutusermulti) {
@ -242,16 +247,15 @@ void CommBrick::setup()
cutghostmulti[i][2] = 0.0; cutghostmulti[i][2] = 0.0;
} }
igroup = map_type_multi[i];
for (j = 1; j <= ntypes; j++){ for (j = 1; j <= ntypes; j++){
if(cutneighsq[j][j] > cutneighsq[i][i]) continue; jgroup = map_type_multi[j];
cutghostmulti[i][0] = MAX(cutghostmulti[i][0],sqrt(cutneighsq[i][j]));
cutghostmulti[i][1] = MAX(cutghostmulti[i][1],sqrt(cutneighsq[i][j])); if(cutmultisq[jgroup][jgroup] > cutmultisq[igroup][igroup]) continue;
cutghostmulti[i][2] = MAX(cutghostmulti[i][2],sqrt(cutneighsq[i][j])); 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 { } else {
// If using a single binlist, use the max itype-jtype interaction distance for communication // If using a single binlist, use the max itype-jtype interaction distance for communication

View File

@ -177,29 +177,33 @@ void CommTiled::setup()
if (mode == Comm::MULTI) { if (mode == Comm::MULTI) {
double cut; double cut;
if (multi_reduce) { if (multi_reduce) {
// If using multi/reduce binlists, communicate itype particles a distance // If using multi/reduce, communicate itype particles a distance equal
// equal to the max of itype-jtype interaction given smaller jtype particles // to the max of itype-jtype group interaction given smaller jtype group
double **cutneighsq = neighbor->cutneighsq; int igroup, jgroup;
double *cuttypesq = neighbor->cuttypesq; double **cutmultisq = neighbor->cutmultisq;
for (i = 1; i <= ntypes; i++) { int *map_type_multi = neighbor->map_type_multi;
for (i = 1; i <= ntypes; i++) {
if (cutusermulti) { if (cutusermulti) {
cutghostmulti[i][0] = cutusermulti[i]; cutghostmulti[i][0] = cutusermulti[i];
cutghostmulti[i][1] = cutusermulti[i]; cutghostmulti[i][1] = cutusermulti[i];
cutghostmulti[i][2] = cutusermulti[i]; cutghostmulti[i][2] = cutusermulti[i];
} else { } else {
cutghostmulti[i][0] = 0.0; cutghostmulti[i][0] = 0.0;
cutghostmulti[i][1] = 0.0; cutghostmulti[i][1] = 0.0;
cutghostmulti[i][2] = 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]));
}
} }
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 { } else {
// If using a single binlist, use the max itype-jtype interaction distance for communication // If using a single binlist, use the max itype-jtype interaction distance for communication
double *cuttype = neighbor->cuttype; double *cuttype = neighbor->cuttype;

View File

@ -188,6 +188,12 @@ pairclass(nullptr), pairnames(nullptr), pairmasks(nullptr)
nex_mol = maxex_mol = 0; nex_mol = maxex_mol = 0;
ex_mol_group = ex_mol_bit = ex_mol_intra = nullptr; ex_mol_group = ex_mol_bit = ex_mol_intra = nullptr;
// Multi data
map_type_multi = nullptr;
cutmultisq = nullptr;
multi_groups = 0;
// Kokkos setting // Kokkos setting
copymode = 0; copymode = 0;
@ -253,6 +259,9 @@ Neighbor::~Neighbor()
memory->destroy(ex_mol_group); memory->destroy(ex_mol_group);
delete [] ex_mol_bit; delete [] ex_mol_bit;
memory->destroy(ex_mol_intra); memory->destroy(ex_mol_intra);
memory->destroy(map_type_multi);
memory->destroy(cutmultisq);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -336,6 +345,35 @@ void Neighbor::init()
} }
cutneighmaxsq = cutneighmax * cutneighmax; 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 // rRESPA cutoffs
int respa = 0; int respa = 0;
@ -1934,6 +1972,7 @@ NPair *Neighbor::pair_creator(LAMMPS *lmp)
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
setup neighbor binning and neighbor stencils setup neighbor binning and neighbor stencils
called before run and every reneighbor if box size/shape changes called before run and every reneighbor if box size/shape changes
initialize default settings for multi before run
only operates on perpetual lists only operates on perpetual lists
build_one() operates on occasional 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) { } else if (strcmp(arg[iarg+1],"none") == 0) {
nex_type = nex_group = nex_mol = 0; nex_type = nex_group = nex_mol = 0;
iarg += 2; iarg += 2;
} else error->all(FLERR,"Illegal neigh_modify command"); } 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"); } else error->all(FLERR,"Illegal neigh_modify command");
} }
} }

View File

@ -21,7 +21,7 @@ namespace LAMMPS_NS {
class Neighbor : protected Pointers { class Neighbor : protected Pointers {
public: public:
enum{NSQ,BIN,MULTI_OLD,MULTI}; 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 every; // build every this many steps
int delay; // delay build for this many steps int delay; // delay build for this many steps
int dist_check; // 0 = always build, 1 = only if 1/2 dist 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 nimproperlist; // list of impropers to compute
int **improperlist; 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 // public methods
Neighbor(class LAMMPS *); Neighbor(class LAMMPS *);