bug fix for compute cluster/atom when computing values used to update a dynamic group

This commit is contained in:
Steven J. Plimpton
2018-08-08 09:31:16 -06:00
parent 985318203d
commit 9202896e75
4 changed files with 43 additions and 11 deletions

View File

@ -31,6 +31,8 @@
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
enum{CLUSTER,MASK,COORDS};
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeClusterAtom::ComputeClusterAtom(LAMMPS *lmp, int narg, char **arg) : ComputeClusterAtom::ComputeClusterAtom(LAMMPS *lmp, int narg, char **arg) :
@ -44,7 +46,7 @@ ComputeClusterAtom::ComputeClusterAtom(LAMMPS *lmp, int narg, char **arg) :
peratom_flag = 1; peratom_flag = 1;
size_peratom_cols = 0; size_peratom_cols = 0;
comm_forward = 1; comm_forward = 3;
nmax = 0; nmax = 0;
} }
@ -122,10 +124,19 @@ void ComputeClusterAtom::compute_peratom()
numneigh = list->numneigh; numneigh = list->numneigh;
firstneigh = list->firstneigh; firstneigh = list->firstneigh;
// if update->post_integrate set:
// a dynamic group in FixGroup is invoking a variable with this compute
// thus ghost atom coords need to be up-to-date after initial_integrate()
if (update->post_integrate) {
commflag = COORDS;
comm->forward_comm_compute(this);
}
// if group is dynamic, insure ghost atom masks are current // if group is dynamic, insure ghost atom masks are current
if (group->dynamic[igroup]) { if (group->dynamic[igroup]) {
commflag = 0; commflag = MASK;
comm->forward_comm_compute(this); comm->forward_comm_compute(this);
} }
@ -147,7 +158,7 @@ void ComputeClusterAtom::compute_peratom()
// iterate until no changes in my atoms // iterate until no changes in my atoms
// then check if any proc made changes // then check if any proc made changes
commflag = 1; commflag = CLUSTER;
double **x = atom->x; double **x = atom->x;
int change,done,anychange; int change,done,anychange;
@ -203,17 +214,25 @@ int ComputeClusterAtom::pack_forward_comm(int n, int *list, double *buf,
int i,j,m; int i,j,m;
m = 0; m = 0;
if (commflag) { if (commflag == CLUSTER) {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
j = list[i]; j = list[i];
buf[m++] = clusterID[j]; buf[m++] = clusterID[j];
} }
} else { } else if (commflag == MASK) {
int *mask = atom->mask; int *mask = atom->mask;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
j = list[i]; j = list[i];
buf[m++] = ubuf(mask[j]).d; buf[m++] = ubuf(mask[j]).d;
} }
} else if (commflag == COORDS) {
double **x = atom->x;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = x[j][0];
buf[m++] = x[j][1];
buf[m++] = x[j][2];
}
} }
return m; return m;
@ -227,11 +246,18 @@ void ComputeClusterAtom::unpack_forward_comm(int n, int first, double *buf)
m = 0; m = 0;
last = first + n; last = first + n;
if (commflag) if (commflag == CLUSTER) {
for (i = first; i < last; i++) clusterID[i] = buf[m++]; for (i = first; i < last; i++) clusterID[i] = buf[m++];
else { } else if (commflag == MASK) {
int *mask = atom->mask; int *mask = atom->mask;
for (i = first; i < last; i++) mask[i] = (int) ubuf(buf[m++]).i; for (i = first; i < last; i++) mask[i] = (int) ubuf(buf[m++]).i;
} else if (commflag == COORDS) {
double **x = atom->x;
for (i = first; i < last; i++) {
x[i][0] = buf[m++];
x[i][1] = buf[m++];
x[i][2] = buf[m++];
}
} }
} }

View File

@ -204,17 +204,22 @@ void FixGroup::set_group()
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
// invoke atom-style variable if defined // invoke atom-style variable if defined
// set post_integrate flag to 1, then unset after
// this is for any compute to check if it needs to
// operate differently due to invocation this early in timestep
// e.g. perform ghost comm update due to atoms having just moved
double *var = NULL; double *var = NULL;
int *ivector = NULL; int *ivector = NULL;
double *dvector = NULL; double *dvector = NULL;
if (varflag) { if (varflag) {
update->post_integrate = 1;
modify->clearstep_compute(); modify->clearstep_compute();
memory->create(var,nlocal,"fix/group:varvalue"); memory->create(var,nlocal,"fix/group:varvalue");
input->variable->compute_atom(ivar,igroup,var,1,0); input->variable->compute_atom(ivar,igroup,var,1,0);
modify->addstep_compute(update->ntimestep + nevery); modify->addstep_compute(update->ntimestep + nevery);
update->post_integrate = 0;
} }
// invoke per-atom property if defined // invoke per-atom property if defined

View File

@ -46,10 +46,10 @@ Update::Update(LAMMPS *lmp) : Pointers(lmp)
whichflag = 0; whichflag = 0;
firststep = laststep = 0; firststep = laststep = 0;
beginstep = endstep = 0; beginstep = endstep = 0;
setupflag = 0;
multireplica = 0;
restrict_output = 0; restrict_output = 0;
setupflag = 0;
post_integrate = 0;
multireplica = 0;
eflag_global = vflag_global = -1; eflag_global = vflag_global = -1;

View File

@ -35,6 +35,7 @@ class Update : protected Pointers {
int max_eval; // max force evaluations for minimizer int max_eval; // max force evaluations for minimizer
int restrict_output; // 1 if output should not write dump/restart int restrict_output; // 1 if output should not write dump/restart
int setupflag; // set when setup() is computing forces int setupflag; // set when setup() is computing forces
int post_integrate; // 1 if now at post_integrate() in timestep
int multireplica; // 1 if min across replicas, else 0 int multireplica; // 1 if min across replicas, else 0
bigint eflag_global,eflag_atom; // timestep global/peratom eng is tallied on bigint eflag_global,eflag_atom; // timestep global/peratom eng is tallied on