diff --git a/src/compute_cluster_atom.cpp b/src/compute_cluster_atom.cpp
index 146f8fd1b3c7d64491e1213038b94c4ba9d0a32a..85934c5e6d20df3a6eaa915d8269d32988147120 100644
--- a/src/compute_cluster_atom.cpp
+++ b/src/compute_cluster_atom.cpp
@@ -31,6 +31,8 @@
 
 using namespace LAMMPS_NS;
 
+enum{CLUSTER,MASK,COORDS};
+
 /* ---------------------------------------------------------------------- */
 
 ComputeClusterAtom::ComputeClusterAtom(LAMMPS *lmp, int narg, char **arg) :
@@ -44,7 +46,7 @@ ComputeClusterAtom::ComputeClusterAtom(LAMMPS *lmp, int narg, char **arg) :
 
   peratom_flag = 1;
   size_peratom_cols = 0;
-  comm_forward = 1;
+  comm_forward = 3;
 
   nmax = 0;
 }
@@ -122,10 +124,19 @@ void ComputeClusterAtom::compute_peratom()
   numneigh = list->numneigh;
   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->dynamic[igroup]) {
-    commflag = 0;
+    commflag = MASK;
     comm->forward_comm_compute(this);
   }
 
@@ -147,7 +158,7 @@ void ComputeClusterAtom::compute_peratom()
   // iterate until no changes in my atoms
   // then check if any proc made changes
 
-  commflag = 1;
+  commflag = CLUSTER;
   double **x = atom->x;
 
   int change,done,anychange;
@@ -203,17 +214,25 @@ int ComputeClusterAtom::pack_forward_comm(int n, int *list, double *buf,
   int i,j,m;
 
   m = 0;
-  if (commflag) {
+  if (commflag == CLUSTER) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = clusterID[j];
     }
-  } else {
+  } else if (commflag == MASK) {
     int *mask = atom->mask;
     for (i = 0; i < n; i++) {
       j = list[i];
       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;
@@ -227,11 +246,18 @@ void ComputeClusterAtom::unpack_forward_comm(int n, int first, double *buf)
 
   m = 0;
   last = first + n;
-  if (commflag)
+  if (commflag == CLUSTER) {
     for (i = first; i < last; i++) clusterID[i] = buf[m++];
-  else {
+  } else if (commflag == MASK) {
     int *mask = atom->mask;
     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++];
+    }
   }
 }
 
diff --git a/src/fix_group.cpp b/src/fix_group.cpp
index 68d74b8b1f961e264a51336389f7f96aec4767d5..10736964e788d5b76d47ea392737c35f714fedb9 100644
--- a/src/fix_group.cpp
+++ b/src/fix_group.cpp
@@ -204,17 +204,22 @@ void FixGroup::set_group()
   int nlocal = atom->nlocal;
 
   // 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;
   int *ivector = NULL;
   double *dvector = NULL;
 
-
   if (varflag) {
+    update->post_integrate = 1;
     modify->clearstep_compute();
     memory->create(var,nlocal,"fix/group:varvalue");
     input->variable->compute_atom(ivar,igroup,var,1,0);
     modify->addstep_compute(update->ntimestep + nevery);
+    update->post_integrate = 0;
   }
 
   // invoke per-atom property if defined
diff --git a/src/update.cpp b/src/update.cpp
index aa152a850857e729f78da1db98e678e41140f1d7..6f9c2c9a076ff8b911431bf623efd4a47301f6fe 100644
--- a/src/update.cpp
+++ b/src/update.cpp
@@ -46,11 +46,11 @@ Update::Update(LAMMPS *lmp) : Pointers(lmp)
   whichflag = 0;
   firststep = laststep = 0;
   beginstep = endstep = 0;
+  restrict_output = 0;
   setupflag = 0;
+  post_integrate = 0;
   multireplica = 0;
 
-  restrict_output = 0;
-
   eflag_global = vflag_global = -1;
 
   unit_style = NULL;
diff --git a/src/update.h b/src/update.h
index 79964403182db7add9289a3dc4945ef14eaf9386..d3602ef21e98b0dfcbc036e29625831d3a27be3a 100644
--- a/src/update.h
+++ b/src/update.h
@@ -35,6 +35,7 @@ class Update : protected Pointers {
   int max_eval;                   // max force evaluations for minimizer
   int restrict_output;            // 1 if output should not write dump/restart
   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
 
   bigint eflag_global,eflag_atom;  // timestep global/peratom eng is tallied on