diff --git a/src/ASPHERE/compute_temp_asphere.cpp b/src/ASPHERE/compute_temp_asphere.cpp
index 48b443f04..0f2fea035 100755
--- a/src/ASPHERE/compute_temp_asphere.cpp
+++ b/src/ASPHERE/compute_temp_asphere.cpp
@@ -1,401 +1,401 @@
 /* ----------------------------------------------------------------------
    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.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "string.h"
 #include "compute_temp_asphere.h"
 #include "math_extra.h"
 #include "atom.h"
 #include "atom_vec_ellipsoid.h"
 #include "update.h"
 #include "force.h"
 #include "domain.h"
 #include "modify.h"
 #include "group.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{ROTATE,ALL};
 
 #define INERTIA 0.2          // moment of inertia prefactor for ellipsoid
 
 /* ---------------------------------------------------------------------- */
 
 ComputeTempAsphere::ComputeTempAsphere(LAMMPS *lmp, int narg, char **arg) :
   Compute(lmp, narg, arg)
 {
   if (narg < 3) error->all(FLERR,"Illegal compute temp/asphere command");
 
   scalar_flag = vector_flag = 1;
   size_vector = 6;
   extscalar = 0;
   extvector = 1;
   tempflag = 1;
 
   tempbias = 0;
   id_bias = NULL;
   mode = ALL;
 
   int iarg = 3;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"bias") == 0) {
       if (iarg+2 > narg) 
         error->all(FLERR,"Illegal compute temp/asphere command");
       tempbias = 1;
       int n = strlen(arg[iarg+1]) + 1;
       id_bias = new char[n];
       strcpy(id_bias,arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"dof") == 0) {
       if (iarg+2 > narg) 
         error->all(FLERR,"Illegal compute temp/asphere command");
       if (strcmp(arg[iarg+1],"rotate") == 0) mode = ROTATE;
       else if (strcmp(arg[iarg+1],"all") == 0) mode = ALL;
       else error->all(FLERR,"Illegal compute temp/asphere command");
       iarg += 2;
     } else error->all(FLERR,"Illegal compute temp/asphere command");
   }
 
   vector = new double[6];
 
 }
 
 /* ---------------------------------------------------------------------- */
 
 ComputeTempAsphere::~ComputeTempAsphere()
 {
   delete [] id_bias;
   delete [] vector;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempAsphere::init()
 {
   // error check
 
   avec = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
   if (!avec)
     error->all(FLERR,"Compute temp/asphere requires atom style ellipsoid");
 
   // check that all particles are finite-size, no point particles allowed
 
   int *ellipsoid = atom->ellipsoid;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit)
       if (ellipsoid[i] < 0)
         error->one(FLERR,"Compute temp/asphere requires extended particles");
 
   if (tempbias) {
     int i = modify->find_compute(id_bias);
     if (i < 0) 
       error->all(FLERR,"Could not find compute ID for temperature bias");
     tbias = modify->compute[i];
     if (tbias->tempflag == 0)
       error->all(FLERR,"Bias compute does not calculate temperature");
     if (tbias->tempbias == 0)
       error->all(FLERR,"Bias compute does not calculate a velocity bias");
     if (tbias->igroup != igroup)
       error->all(FLERR,"Bias compute group does not match compute group");
     if (strcmp(tbias->style,"temp/region") == 0) tempbias = 2;
     else tempbias = 1;
 
     // init and setup bias compute because
     // this compute's setup()->dof_compute() may be called first
 
     tbias->init();
     tbias->setup();
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempAsphere::setup()
 {
   dynamic = 0;
   if (dynamic_user || group->dynamic[igroup]) dynamic = 1;
   dof_compute();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempAsphere::dof_compute()
 {
   adjust_dof_fix();
 
   // 6 dof for 3d, 3 dof for 2d
   // which dof are included also depends on mode
   // assume full rotation of extended particles
   // user should correct this via compute_modify if needed
 
-  double natoms = group->count(igroup);
+  natoms_temp = group->count(igroup);
   int nper;
   if (domain->dimension == 3) {
     if (mode == ALL) nper = 6;
     else nper = 3;
   } else {
     if (mode == ALL) nper = 3;
     else nper = 1;
   }
-  dof = nper*natoms;
+  dof = nper*natoms_temp;
 
   // additional adjustments to dof
 
   if (tempbias == 1) {
-    if (mode == ALL) dof -= tbias->dof_remove(-1) * natoms;
+    if (mode == ALL) dof -= tbias->dof_remove(-1) * natoms_temp;
 
   } else if (tempbias == 2) {
     int *mask = atom->mask;
     int nlocal = atom->nlocal;
 
     tbias->dof_remove_pre();
 
     int count = 0;
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit)
         if (tbias->dof_remove(i)) count++;
     int count_all;
     MPI_Allreduce(&count,&count_all,1,MPI_INT,MPI_SUM,world);
     dof -= nper*count_all;
   }
 
   dof -= extra_dof + fix_dof;
-  if (dof < 0.0 && natoms > 0.0) 
-    error->all(FLERR,"Temperature compute degrees of freedom < 0");
   if (dof > 0) tfactor = force->mvv2e / (dof * force->boltz);
   else tfactor = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 double ComputeTempAsphere::compute_scalar()
 {
   invoked_scalar = update->ntimestep;
 
   if (tempbias) {
     if (tbias->invoked_scalar != update->ntimestep) tbias->compute_scalar();
     tbias->remove_bias_all();
   }
 
   AtomVecEllipsoid::Bonus *bonus = avec->bonus;
   double **v = atom->v;
   double **angmom = atom->angmom;
   double *rmass = atom->rmass;
   int *ellipsoid = atom->ellipsoid;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   double *shape,*quat;
   double wbody[3],inertia[3];
   double rot[3][3];
 
   // sum translational and rotational energy for each particle
   // no point particles since divide by inertia
 
   double t = 0.0;
 
   if (mode == ALL) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
         t += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * rmass[i];
 
         // principal moments of inertia
 
         shape = bonus[ellipsoid[i]].shape;
         quat = bonus[ellipsoid[i]].quat;
 
         inertia[0] = INERTIA*rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]);
         inertia[1] = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]);
         inertia[2] = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]);
 
         // wbody = angular velocity in body frame
 
         MathExtra::quat_to_mat(quat,rot);
         MathExtra::transpose_matvec(rot,angmom[i],wbody);
         wbody[0] /= inertia[0];
         wbody[1] /= inertia[1];
         wbody[2] /= inertia[2];
 
         t += inertia[0]*wbody[0]*wbody[0] +
           inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2];
       }
 
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 
         // principal moments of inertia
 
         shape = bonus[ellipsoid[i]].shape;
         quat = bonus[ellipsoid[i]].quat;
 
         inertia[0] = INERTIA*rmass[i] * (shape[1]*shape[1]+shape[2]*shape[2]);
         inertia[1] = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[2]*shape[2]);
         inertia[2] = INERTIA*rmass[i] * (shape[0]*shape[0]+shape[1]*shape[1]);
 
         // wbody = angular velocity in body frame
 
         MathExtra::quat_to_mat(quat,rot);
         MathExtra::transpose_matvec(rot,angmom[i],wbody);
         wbody[0] /= inertia[0];
         wbody[1] /= inertia[1];
         wbody[2] /= inertia[2];
 
         t += inertia[0]*wbody[0]*wbody[0] +
           inertia[1]*wbody[1]*wbody[1] + inertia[2]*wbody[2]*wbody[2];
       }
   }
 
   if (tempbias) tbias->restore_bias_all();
 
   MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
   if (dynamic || tempbias == 2) dof_compute();
+  if (dof < 0.0 && natoms_temp > 0.0) 
+    error->all(FLERR,"Temperature compute degrees of freedom < 0");
   scalar *= tfactor;
   return scalar;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempAsphere::compute_vector()
 {
   int i;
 
   invoked_vector = update->ntimestep;
 
   if (tempbias) {
     if (tbias->invoked_vector != update->ntimestep) tbias->compute_vector();
     tbias->remove_bias_all();
   }
 
   AtomVecEllipsoid::Bonus *bonus = avec->bonus;
   double **v = atom->v;
   double **angmom = atom->angmom;
   double *rmass = atom->rmass;
   int *ellipsoid = atom->ellipsoid;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   double *shape,*quat;
   double wbody[3],inertia[3],t[6];
   double rot[3][3];
   double massone;
 
   // sum translational and rotational energy for each particle
   // no point particles since divide by inertia
 
   for (i = 0; i < 6; i++) t[i] = 0.0;
 
   if (mode == ALL) {
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
         massone = rmass[i];
         t[0] += massone * v[i][0]*v[i][0];
         t[1] += massone * v[i][1]*v[i][1];
         t[2] += massone * v[i][2]*v[i][2];
         t[3] += massone * v[i][0]*v[i][1];
         t[4] += massone * v[i][0]*v[i][2];
         t[5] += massone * v[i][1]*v[i][2];
 
         // principal moments of inertia
 
         shape = bonus[ellipsoid[i]].shape;
         quat = bonus[ellipsoid[i]].quat;
 
         inertia[0] = INERTIA*massone * (shape[1]*shape[1]+shape[2]*shape[2]);
         inertia[1] = INERTIA*massone * (shape[0]*shape[0]+shape[2]*shape[2]);
         inertia[2] = INERTIA*massone * (shape[0]*shape[0]+shape[1]*shape[1]);
 
         // wbody = angular velocity in body frame
 
         MathExtra::quat_to_mat(quat,rot);
         MathExtra::transpose_matvec(rot,angmom[i],wbody);
         wbody[0] /= inertia[0];
         wbody[1] /= inertia[1];
         wbody[2] /= inertia[2];
 
         // rotational kinetic energy
 
         t[0] += inertia[0]*wbody[0]*wbody[0];
         t[1] += inertia[1]*wbody[1]*wbody[1];
         t[2] += inertia[2]*wbody[2]*wbody[2];
         t[3] += inertia[0]*wbody[0]*wbody[1];
         t[4] += inertia[1]*wbody[0]*wbody[2];
         t[5] += inertia[2]*wbody[1]*wbody[2];
       }
 
   } else {
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 
         // principal moments of inertia
 
         shape = bonus[ellipsoid[i]].shape;
         quat = bonus[ellipsoid[i]].quat;
         massone = rmass[i];
 
         inertia[0] = INERTIA*massone * (shape[1]*shape[1]+shape[2]*shape[2]);
         inertia[1] = INERTIA*massone * (shape[0]*shape[0]+shape[2]*shape[2]);
         inertia[2] = INERTIA*massone * (shape[0]*shape[0]+shape[1]*shape[1]);
 
         // wbody = angular velocity in body frame
 
         MathExtra::quat_to_mat(quat,rot);
         MathExtra::transpose_matvec(rot,angmom[i],wbody);
         wbody[0] /= inertia[0];
         wbody[1] /= inertia[1];
         wbody[2] /= inertia[2];
 
         // rotational kinetic energy
 
         t[0] += inertia[0]*wbody[0]*wbody[0];
         t[1] += inertia[1]*wbody[1]*wbody[1];
         t[2] += inertia[2]*wbody[2]*wbody[2];
         t[3] += inertia[0]*wbody[0]*wbody[1];
         t[4] += inertia[1]*wbody[0]*wbody[2];
         t[5] += inertia[2]*wbody[1]*wbody[2];
       }
   }
 
   if (tempbias) tbias->restore_bias_all();
 
   MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world);
   for (i = 0; i < 6; i++) vector[i] *= force->mvv2e;
 }
 
 /* ----------------------------------------------------------------------
    remove velocity bias from atom I to leave thermal velocity
 ------------------------------------------------------------------------- */
 
 void ComputeTempAsphere::remove_bias(int i, double *v)
 {
   if (tbias) tbias->remove_bias(i,v);
 }
 
 /* ----------------------------------------------------------------------
    add back in velocity bias to atom I removed by remove_bias()
    assume remove_bias() was previously called
 ------------------------------------------------------------------------- */
 
 void ComputeTempAsphere::restore_bias(int i, double *v)
 {
   if (tbias) tbias->restore_bias(i,v);
 }
diff --git a/src/CORESHELL/compute_temp_cs.cpp b/src/CORESHELL/compute_temp_cs.cpp
index 807a132e9..cd577291f 100644
--- a/src/CORESHELL/compute_temp_cs.cpp
+++ b/src/CORESHELL/compute_temp_cs.cpp
@@ -1,499 +1,499 @@
 /* ----------------------------------------------------------------------
    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.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Hendrik Heenen (Technical University of Munich)
                         (hendrik.heenen at mytum.com)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "stdlib.h"
 #include "string.h"
 #include "math.h"
 #include "compute_temp_cs.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "domain.h"
 #include "update.h"
 #include "force.h"
 #include "group.h"
 #include "modify.h"
 #include "fix.h"
 #include "fix_store.h"
 #include "comm.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 ComputeTempCS::ComputeTempCS(LAMMPS *lmp, int narg, char **arg) :
   Compute(lmp, narg, arg)
 {
   if (narg != 5) error->all(FLERR,"Illegal compute temp/cs command");
 
   if (atom->avec->bonds_allow == 0)
     error->all(FLERR,"Compute temp/cs used when bonds are not allowed");
 
   scalar_flag = vector_flag = 1;
   size_vector = 6;
   extscalar = 0;
   extvector = 1;
   tempflag = 1;
   tempbias = 1;
   extarray = 0;
 
   // find and define groupbits for core and shell groups
 
   cgroup = group->find(arg[3]);
   if (cgroup == -1) 
     error->all(FLERR,"Cannot find specified group ID for core particles");
   groupbit_c = group->bitmask[cgroup];
 
   sgroup = group->find(arg[4]);
   if (sgroup == -1) 
     error->all(FLERR,"Cannot find specified group ID for shell particles");
   groupbit_s = group->bitmask[sgroup];
 
   // create a new fix STORE style
   // id = compute-ID + COMPUTE_STORE, fix group = compute group
 
   int n = strlen(id) + strlen("_COMPUTE_STORE") + 1;
   id_fix = new char[n];
   strcpy(id_fix,id);
   strcat(id_fix,"_COMPUTE_STORE");
 
   char **newarg = new char*[5];
   newarg[0] = id_fix;
   newarg[1] = group->names[igroup];
   newarg[2] = (char *) "STORE";
   newarg[3] = (char *) "0";
   newarg[4] = (char *) "1";
   modify->add_fix(5,newarg);
   fix = (FixStore *) modify->fix[modify->nfix-1];
   delete [] newarg;
 
   // set fix store values = 0 for now
   // fill them in via setup() once Comm::borders() has been called
   // skip if resetting from restart file
 
   if (fix->restart_reset) {
     fix->restart_reset = 0;
     firstflag = 0;
   } else {
     double *partner = fix->vstore;
     int nlocal = atom->nlocal;
     for (int i = 0; i < nlocal; i++) partner[i] = ubuf(0).d;
     firstflag = 1;
   }
 
   // allocate memory
 
   vector = new double[6];
   maxatom = 0;
   vint = NULL;
 
   // set comm size needed by this Compute
 
   comm_reverse = 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 ComputeTempCS::~ComputeTempCS()
 {
   // check nfix in case all fixes have already been deleted
 
   if (modify->nfix) modify->delete_fix(id_fix);
 
   delete [] id_fix;
   delete [] vector;
   memory->destroy(vint);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempCS::init()
 {
   if (comm->ghost_velocity == 0)
     error->all(FLERR,"Compute temp/cs requires ghost atoms store velocity");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempCS::setup()
 {
   if (firstflag) {
     firstflag = 0;
 
     // insure # of core atoms = # of shell atoms
 
     int ncores = group->count(cgroup);
     nshells = group->count(sgroup);
     if (ncores != nshells)
       error->all(FLERR,"Number of core atoms != number of shell atoms");
 
     // for each C/S pair:
     // set partner IDs of both atoms if this atom stores bond between them
     // will set partner IDs for ghost atoms if needed by another proc
     // nall loop insures all ghost atom partner IDs are set before reverse comm
 
     int *num_bond = atom->num_bond;
     tagint **bond_atom = atom->bond_atom;
     tagint *tag = atom->tag;
     int *mask = atom->mask;
     int nlocal = atom->nlocal;
 
     double *partner = fix->vstore;
     tagint partnerID;
 
     int nall = nlocal + atom->nghost;
     for (int i = nlocal; i < nall; i++) partner[i] = ubuf(0).d;
 
     int i,j,m,match;
     for (i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit_c || mask[i] & groupbit_s) {
         for (m = 0; m < num_bond[i]; m++) {
           partnerID = bond_atom[i][m];
           j = atom->map(partnerID);
           if (j == -1) error->one(FLERR,"Core/shell partner atom not found");
           match = 0;
           if (mask[i] & groupbit_c && mask[j] & groupbit_s) match = 1;
           if (mask[i] & groupbit_s && mask[j] & groupbit_c) match = 1;
           if (match) {
             partner[i] = ubuf(partnerID).d;
             partner[j] = ubuf(tag[i]).d;
           }
         }
       }
     }
 
     // reverse comm to acquire unknown partner IDs from ghost atoms
     // only needed if newton_bond = on
 
     if (force->newton_bond) comm->reverse_comm_compute(this);
 
     // check that all C/S partners were found
 
     int flag = 0;
     for (i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit_c || mask[i] & groupbit_s) {
         partnerID = (tagint) ubuf(partner[i]).i;
         if (partnerID == 0) flag = 1;
       }
     }
 
     int flagall;
     MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
     if (flagall) error->all(FLERR,"Core/shell partners were not all found");
   }
 
   // calculate DOF for temperature
 
   dof_compute();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempCS::dof_compute()
 {
   adjust_dof_fix();
   int nper = domain->dimension;
-  double natoms = group->count(igroup);
-  dof = nper * natoms;
+  natoms_temp = group->count(igroup);
+  dof = nper * natoms_temp;
   dof -= nper * nshells;
   dof -= extra_dof + fix_dof;
-  if (dof < 0.0 && natoms > 0.0) 
-    error->all(FLERR,"Temperature compute degrees of freedom < 0");
   if (dof > 0) tfactor = force->mvv2e / (dof * force->boltz);
   else tfactor = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 double ComputeTempCS::compute_scalar()
 {
   double vthermal[3];
 
   invoked_scalar = update->ntimestep;
 
   vcm_pairs();
 
   // calculate thermal scalar in respect to atom velocities as center-of-mass 
   // velocities of its according core/shell pairs
   
   double **v = atom->v;
   int *mask = atom->mask;
   int *type = atom->type;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   double t = 0.0;
 
   for (int i = 0; i < nlocal; i++){
     if (mask[i] & groupbit) {
       vthermal[0] = v[i][0] - vint[i][0];
       vthermal[1] = v[i][1] - vint[i][1];
       vthermal[2] = v[i][2] - vint[i][2];
       if (rmass)
         t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] +
               vthermal[2]*vthermal[2]) * rmass[i];
       else
         t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] +
               vthermal[2]*vthermal[2]) * mass[type[i]];
     }
   }
 
   MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
   if (dynamic) dof_compute();
+  if (dof < 0.0 && natoms_temp > 0.0) 
+    error->all(FLERR,"Temperature compute degrees of freedom < 0");
   scalar *= tfactor;
   return scalar;
 }
     
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempCS::compute_vector()
 {
   double vthermal[3];
 
   invoked_vector = update->ntimestep;
 
   vcm_pairs();
 
   // calculate thermal vector in respect to atom velocities as center-of-mass 
   // velocities of its according C/S pairs
 
   double **v = atom->v;
   int *mask = atom->mask;
   int *type = atom->type;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
   double massone;
 
   double t[6];
   for (int i = 0; i < 6; i++) t[i] = 0.0;
 
   for (int i = 0; i < nlocal; i++){
     if (mask[i] & groupbit) {
       vthermal[0] = v[i][0] - vint[i][0];
       vthermal[1] = v[i][1] - vint[i][1];
       vthermal[2] = v[i][2] - vint[i][2];
       if (rmass) massone = rmass[i];
       else massone = mass[type[i]];
       t[0] += massone * vthermal[0]*vthermal[0];
       t[1] += massone * vthermal[1]*vthermal[1];
       t[2] += massone * vthermal[2]*vthermal[2];
       t[3] += massone * vthermal[0]*vthermal[1];
       t[4] += massone * vthermal[0]*vthermal[2];
       t[5] += massone * vthermal[1]*vthermal[2];
     }
   }
 
   MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world);
   for (int i = 0; i < 6; i++) vector[i] *= force->mvv2e;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempCS::vcm_pairs()
 {
   int i,j;
   double massone,masstwo;
   double vcm[3];
 
   // reallocate vint if necessary
 
   int nlocal = atom->nlocal;
 
   if (nlocal > maxatom) {
     memory->destroy(vint);
     maxatom = atom->nmax;
     memory->create(vint,maxatom,3,"temp/cs:vint");
   }
   
   // vcm = COM velocity of each CS pair
   // vint = internal velocity of each C/S atom, used as bias
 
   double **v = atom->v;
   int *mask = atom->mask;
   int *type = atom->type;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
 
   double *partner = fix->vstore;
   tagint partnerID;
 
   for (i = 0; i < nlocal; i++) {
     if ((mask[i] & groupbit) && 
         (mask[i] & groupbit_c || mask[i] & groupbit_s)) {
       if (rmass) massone = rmass[i];
       else massone = mass[type[i]];
       vcm[0] = v[i][0]*massone;
       vcm[1] = v[i][1]*massone;
       vcm[2] = v[i][2]*massone;
 
       partnerID = (tagint) ubuf(partner[i]).i;
       j = atom->map(partnerID);
       if (j == -1) error->one(FLERR,"Core/shell partner atom not found");
 
       if (rmass) masstwo = rmass[j];
       else masstwo = mass[type[j]];
       vcm[0] += v[j][0]*masstwo;
       vcm[1] += v[j][1]*masstwo;
       vcm[2] += v[j][2]*masstwo;
       vcm[0] /= (massone + masstwo);
       vcm[1] /= (massone + masstwo);
       vcm[2] /= (massone + masstwo);
 
       vint[i][0] = v[i][0] - vcm[0];
       vint[i][1] = v[i][1] - vcm[1];
       vint[i][2] = v[i][2] - vcm[2];
     } else vint[i][0] = vint[i][1] = vint[i][2] = 0.0;
   }
 }
 
 /* ----------------------------------------------------------------------
    remove velocity bias from atom I to leave thermal velocity
    thermal velocity in this case is COM velocity of C/S pair
 ------------------------------------------------------------------------- */
 
 void ComputeTempCS::remove_bias(int i, double *v)
 {
   v[0] -= vint[i][0];
   v[1] -= vint[i][1];
   v[2] -= vint[i][2];
 }
 
 /* ----------------------------------------------------------------------
    remove velocity bias from all atoms to leave thermal velocity
    thermal velocity in this case is COM velocity of C/S pair
 ------------------------------------------------------------------------- */
 
 void ComputeTempCS::remove_bias_all()
 {
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       v[i][0] -= vint[i][0];
       v[i][1] -= vint[i][1];
       v[i][2] -= vint[i][2];
     }
 }
 
 /* ----------------------------------------------------------------------
    reset thermal velocity of all atoms to be consistent with bias
    called from velocity command after it creates thermal velocities
    this resets each atom's velocity to COM velocity of C/S pair
 ------------------------------------------------------------------------- */
 
 void ComputeTempCS::reapply_bias_all()
 {
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   // recalculate current COM velocities
 
   vcm_pairs();
 
   // zero vint after using ti so that Velocity call to restore_bias_all()
   // will not further alter the velocities within a C/S pair
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       v[i][0] -= vint[i][0];
       v[i][1] -= vint[i][1];
       v[i][2] -= vint[i][2];
       vint[i][0] = 0.0;
       vint[i][1] = 0.0;
       vint[i][2] = 0.0;
     }
 }
 
 /* ----------------------------------------------------------------------
    add back in velocity bias to atom I removed by remove_bias()
    assume remove_bias() was previously called
 ------------------------------------------------------------------------- */
 
 void ComputeTempCS::restore_bias(int i, double *v)
 {
   v[0] += vint[i][0];
   v[1] += vint[i][1];
   v[2] += vint[i][2];
 }
 
 /* ----------------------------------------------------------------------
    add back in velocity bias to all atoms removed by remove_bias_all()
    assume remove_bias_all() was previously called
 ------------------------------------------------------------------------- */
 
 void ComputeTempCS::restore_bias_all()
 {
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       v[i][0] += vint[i][0];
       v[i][1] += vint[i][1];
       v[i][2] += vint[i][2];
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int ComputeTempCS::pack_reverse_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   double *partner = fix->vstore;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) buf[m++] = partner[i];
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempCS::unpack_reverse_comm(int n, int *list, double *buf)
 {
   int i,j,m;
 
   double *partner = fix->vstore;
   tagint partnerID;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     partnerID = (tagint) ubuf(buf[m++]).i;
     if (partnerID) partner[j] = ubuf(partnerID).d;
   }
 }
 
 /* ----------------------------------------------------------------------
    memory usage of local data
 ------------------------------------------------------------------------- */
 
 double ComputeTempCS::memory_usage()
 {
   double bytes = (bigint) maxatom * 3 * sizeof(double);
   return bytes;
 }
diff --git a/src/USER-EFF/compute_temp_deform_eff.cpp b/src/USER-EFF/compute_temp_deform_eff.cpp
index 92ebdb298..8ff1d6f76 100644
--- a/src/USER-EFF/compute_temp_deform_eff.cpp
+++ b/src/USER-EFF/compute_temp_deform_eff.cpp
@@ -1,327 +1,327 @@
 /* ----------------------------------------------------------------------
    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.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Andres Jaramillo-Botero (Caltech)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "string.h"
 #include "stdlib.h"
 #include "compute_temp_deform_eff.h"
 #include "domain.h"
 #include "atom.h"
 #include "update.h"
 #include "force.h"
 #include "modify.h"
 #include "fix.h"
 #include "fix_deform.h"
 #include "group.h"
 #include "comm.h"
 #include "memory.h"
 #include "error.h"
 
 
 using namespace LAMMPS_NS;
 
 enum{NO_REMAP,X_REMAP,V_REMAP};                   // same as fix_deform.cpp
 
 /* ---------------------------------------------------------------------- */
 
 ComputeTempDeformEff::ComputeTempDeformEff(LAMMPS *lmp, int narg, char **arg) :
   Compute(lmp, narg, arg)
 {
   if (narg != 3) error->all(FLERR,"Illegal compute temp/deform/eff command");
 
   if (!atom->electron_flag)
     error->all(FLERR,"Compute temp/deform/eff requires atom style electron");
 
   scalar_flag = vector_flag = 1;
   size_vector = 6;
   extscalar = 0;
   extvector = 1;
   tempflag = 1;
   tempbias = 1;
 
   maxbias = 0;
   vbiasall = NULL;
   vector = new double[6];
 }
 
 /* ---------------------------------------------------------------------- */
 
 ComputeTempDeformEff::~ComputeTempDeformEff()
 {
   memory->destroy(vbiasall);
   delete [] vector;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempDeformEff::init()
 {
   // check fix deform remap settings
 
   int i;
   for (i = 0; i < modify->nfix; i++)
     if (strcmp(modify->fix[i]->style,"deform") == 0) {
       if (((FixDeform *) modify->fix[i])->remapflag == X_REMAP &&
           comm->me == 0)
         error->warning(FLERR,"Using compute temp/deform/eff with inconsistent "
                        "fix deform remap option");
       break;
     }
   if (i == modify->nfix && comm->me == 0)
     error->warning(FLERR,
                    "Using compute temp/deform/eff with no fix deform defined");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempDeformEff::setup()
 {
   dynamic = 0;
   if (dynamic_user || group->dynamic[igroup]) dynamic = 1;
   dof_compute();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempDeformEff::dof_compute()
 {
   adjust_dof_fix();
-  double natoms = group->count(igroup);
-  dof = domain->dimension * natoms;
+  natoms_temp = group->count(igroup);
+  dof = domain->dimension * natoms_temp;
   dof -= extra_dof + fix_dof;
 
   // just include nuclear dof
 
   int *spin = atom->spin;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int one = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       if (abs(spin[i]) == 1) one++;
     }
   int nelectrons;
   MPI_Allreduce(&one,&nelectrons,1,MPI_INT,MPI_SUM,world);
 
   // Assume 3/2 k T per nucleus
 
   dof -= domain->dimension * nelectrons;
 
-  if (dof < 0.0 && natoms > 0.0) 
-    error->all(FLERR,"Temperature compute degrees of freedom < 0");
   if (dof > 0) tfactor = force->mvv2e / (dof * force->boltz);
   else tfactor = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 double ComputeTempDeformEff::compute_scalar()
 {
   double lamda[3],vstream[3],vthermal[3];
 
   invoked_scalar = update->ntimestep;
 
   double **x = atom->x;
   double **v = atom->v;
   double *ervel = atom->ervel;
   double *mass = atom->mass;
   int *spin = atom->spin;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   double mefactor = domain->dimension/4.0;
 
   // lamda = 0-1 triclinic lamda coords
   // vstream = streaming velocity = Hrate*lamda + Hratelo
   // vthermal = thermal velocity = v - vstream
 
   double *h_rate = domain->h_rate;
   double *h_ratelo = domain->h_ratelo;
 
   double t = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       domain->x2lamda(x[i],lamda);
       vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
         h_rate[4]*lamda[2] + h_ratelo[0];
       vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
       vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
       vthermal[0] = v[i][0] - vstream[0];
       vthermal[1] = v[i][1] - vstream[1];
       vthermal[2] = v[i][2] - vstream[2];
 
       if (mass) {
         t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] +
               vthermal[2]*vthermal[2])* mass[type[i]];
         if (abs(spin[i])==1) t += mefactor*mass[type[i]]*ervel[i]*ervel[i];
       }
     }
 
   MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
   if (dynamic) dof_compute();
+  if (dof < 0.0 && natoms_temp > 0.0) 
+    error->all(FLERR,"Temperature compute degrees of freedom < 0");
   scalar *= tfactor;
   return scalar;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempDeformEff::compute_vector()
 {
   double lamda[3],vstream[3],vthermal[3];
 
   invoked_vector = update->ntimestep;
 
   double **x = atom->x;
   double **v = atom->v;
   double *ervel = atom->ervel;
   double *mass = atom->mass;
   int *spin = atom->spin;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   double mefactor = domain->dimension/4.0;
 
   double *h_rate = domain->h_rate;
   double *h_ratelo = domain->h_ratelo;
 
   double massone,t[6];
   for (int i = 0; i < 6; i++) t[i] = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       domain->x2lamda(x[i],lamda);
       vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
         h_rate[4]*lamda[2] + h_ratelo[0];
       vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
       vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
       vthermal[0] = v[i][0] - vstream[0];
       vthermal[1] = v[i][1] - vstream[1];
       vthermal[2] = v[i][2] - vstream[2];
 
       massone = mass[type[i]];
       t[0] += massone * vthermal[0]*vthermal[0];
       t[1] += massone * vthermal[1]*vthermal[1];
       t[2] += massone * vthermal[2]*vthermal[2];
       t[3] += massone * vthermal[0]*vthermal[1];
       t[4] += massone * vthermal[0]*vthermal[2];
       t[5] += massone * vthermal[1]*vthermal[2];
       if (abs(spin[i])==1) {
         t[0] += mefactor * massone * ervel[i]*ervel[i];
         t[1] += mefactor * massone * ervel[i]*ervel[i];
         t[2] += mefactor * massone * ervel[i]*ervel[i];
       }
     }
 
   MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world);
   for (int i = 0; i < 6; i++) vector[i] *= force->mvv2e;
 }
 
 /* ----------------------------------------------------------------------
    remove velocity bias from atom I to leave thermal velocity
 ------------------------------------------------------------------------- */
 
 void ComputeTempDeformEff::remove_bias(int i, double *v)
 {
   double lamda[3];
   double *h_rate = domain->h_rate;
   double *h_ratelo = domain->h_ratelo;
 
   domain->x2lamda(atom->x[i],lamda);
   vbias[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
     h_rate[4]*lamda[2] + h_ratelo[0];
   vbias[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
   vbias[2] = h_rate[2]*lamda[2] + h_ratelo[2];
   v[0] -= vbias[0];
   v[1] -= vbias[1];
   v[2] -= vbias[2];
 }
 
 /* ----------------------------------------------------------------------
    remove velocity bias from all atoms to leave thermal velocity
    NOTE: only removes translational velocity bias from electrons
 ------------------------------------------------------------------------- */
 
 void ComputeTempDeformEff::remove_bias_all()
 {
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   if (nlocal > maxbias) {
     memory->destroy(vbiasall);
     maxbias = atom->nmax;
     memory->create(vbiasall,maxbias,3,"temp/deform/eff:vbiasall");
   }
 
   double lamda[3];
   double *h_rate = domain->h_rate;
   double *h_ratelo = domain->h_ratelo;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       domain->x2lamda(atom->x[i],lamda);
       vbiasall[i][0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
         h_rate[4]*lamda[2] + h_ratelo[0];
       vbiasall[i][1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
       vbiasall[i][2] = h_rate[2]*lamda[2] + h_ratelo[2];
       v[i][0] -= vbiasall[i][0];
       v[i][1] -= vbiasall[i][1];
       v[i][2] -= vbiasall[i][2];
     }
 }
 
 /* ----------------------------------------------------------------------
    add back in velocity bias to atom I removed by remove_bias()
    assume remove_bias() was previously called
 ------------------------------------------------------------------------- */
 
 void ComputeTempDeformEff::restore_bias(int i, double *v)
 {
   v[0] += vbias[0];
   v[1] += vbias[1];
   v[2] += vbias[2];
 }
 
 /* ----------------------------------------------------------------------
    add back in velocity bias to all atoms removed by remove_bias_all()
    assume remove_bias_all() was previously called
 ------------------------------------------------------------------------- */
 
 void ComputeTempDeformEff::restore_bias_all()
 {
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       v[i][0] += vbiasall[i][0];
       v[i][1] += vbiasall[i][1];
       v[i][2] += vbiasall[i][2];
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double ComputeTempDeformEff::memory_usage()
 {
   double bytes = maxbias * sizeof(double);
   return bytes;
 }
diff --git a/src/USER-EFF/compute_temp_eff.cpp b/src/USER-EFF/compute_temp_eff.cpp
index 9b24e0a70..2b4e50709 100644
--- a/src/USER-EFF/compute_temp_eff.cpp
+++ b/src/USER-EFF/compute_temp_eff.cpp
@@ -1,167 +1,167 @@
 /* ----------------------------------------------------------------------
    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.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Andres Jaramillo-Botero (Caltech)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "string.h"
 #include "stdlib.h"
 #include "compute_temp_eff.h"
 #include "atom.h"
 #include "update.h"
 #include "force.h"
 #include "domain.h"
 #include "group.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 ComputeTempEff::ComputeTempEff(LAMMPS *lmp, int narg, char **arg) :
   Compute(lmp, narg, arg)
 {
   if (!atom->electron_flag)
     error->all(FLERR,"Compute temp/eff requires atom style electron");
 
   scalar_flag = vector_flag = 1;
   size_vector = 6;
   extscalar = 0;
   extvector = 1;
   tempflag = 1;
 
   vector = new double[size_vector];
 }
 
 /* ---------------------------------------------------------------------- */
 
 ComputeTempEff::~ComputeTempEff()
 {
   delete [] vector;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempEff::setup()
 {
   dynamic = 0;
   if (dynamic_user || group->dynamic[igroup]) dynamic = 1;
   dof_compute();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempEff::dof_compute()
 {
   adjust_dof_fix();
-  double natoms = group->count(igroup);
-  dof = domain->dimension * natoms;
+  natoms_temp = group->count(igroup);
+  dof = domain->dimension * natoms_temp;
   dof -= extra_dof + fix_dof;
 
   int *spin = atom->spin;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int one = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       if (abs(spin[i])==1) one++;
     }
   int nelectrons;
   MPI_Allreduce(&one,&nelectrons,1,MPI_INT,MPI_SUM,world);
 
   // Assume 3/2 k T per nucleus
 
   dof -= domain->dimension * nelectrons;
 
-  if (dof < 0.0 && natoms > 0.0) 
-    error->all(FLERR,"Temperature compute degrees of freedom < 0");
   if (dof > 0.0) tfactor = force->mvv2e / (dof * force->boltz);
   else tfactor = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 double ComputeTempEff::compute_scalar()
 {
   invoked_scalar = update->ntimestep;
 
   double **v = atom->v;
   double *ervel = atom->ervel;
   double *mass = atom->mass;
   int *spin = atom->spin;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   double mefactor = domain->dimension/4.0;
 
   double t = 0.0;
 
   if (mass) {
     for (int i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
         t += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) *
           mass[type[i]];
         if (abs(spin[i])==1) t += mefactor*mass[type[i]]*ervel[i]*ervel[i];
       }
     }
   }
 
   MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
   if (dynamic) dof_compute();
+  if (dof < 0.0 && natoms_temp > 0.0) 
+    error->all(FLERR,"Temperature compute degrees of freedom < 0");
   scalar *= tfactor;
   return scalar;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempEff::compute_vector()
 {
   int i;
 
   invoked_vector = update->ntimestep;
 
   double **v = atom->v;
   double *ervel = atom->ervel;
   double *mass = atom->mass;
   int *spin = atom->spin;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   double mefactor = domain->dimension/4.0;
 
   double massone,t[6];
   for (i = 0; i < 6; i++) t[i] = 0.0;
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       massone = mass[type[i]];
       t[0] += massone * v[i][0]*v[i][0];
       t[1] += massone * v[i][1]*v[i][1];
       t[2] += massone * v[i][2]*v[i][2];
       t[3] += massone * v[i][0]*v[i][1];
       t[4] += massone * v[i][0]*v[i][2];
       t[5] += massone * v[i][1]*v[i][2];
       if (abs(spin[i])==1) {
         t[0] += mefactor*massone*ervel[i]*ervel[i];
         t[1] += mefactor*massone*ervel[i]*ervel[i];
         t[2] += mefactor*massone*ervel[i]*ervel[i];
       }
     }
 
   MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world);
   for (i = 0; i < 6; i++) vector[i] *= force->mvv2e;
 }
diff --git a/src/USER-EFF/compute_temp_region_eff.cpp b/src/USER-EFF/compute_temp_region_eff.cpp
index d2517d879..3c762e5d7 100644
--- a/src/USER-EFF/compute_temp_region_eff.cpp
+++ b/src/USER-EFF/compute_temp_region_eff.cpp
@@ -1,296 +1,298 @@
 /* ----------------------------------------------------------------------
    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.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Andres Jaramillo-Botero (Caltech)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "string.h"
 #include "stdlib.h"
 #include "compute_temp_region_eff.h"
 #include "atom.h"
 #include "update.h"
 #include "force.h"
 #include "modify.h"
 #include "domain.h"
 #include "region.h"
 #include "group.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 ComputeTempRegionEff::ComputeTempRegionEff(LAMMPS *lmp, int narg, char **arg) :
   Compute(lmp, narg, arg)
 {
   if (!atom->electron_flag)
     error->all(FLERR,"Compute temp/region/eff requires atom style electron");
 
   if (narg != 4) error->all(FLERR,"Illegal compute temp/region/eff command");
 
   iregion = domain->find_region(arg[3]);
   if (iregion == -1)
     error->all(FLERR,"Region ID for compute temp/region/eff does not exist");
   int n = strlen(arg[3]) + 1;
   idregion = new char[n];
   strcpy(idregion,arg[3]);
 
   scalar_flag = vector_flag = 1;
   size_vector = 6;
   extscalar = 0;
   extvector = 1;
   tempflag = 1;
   tempbias = 1;
 
   maxbias = 0;
   vbiasall = NULL;
   vector = new double[6];
 }
 
 /* ---------------------------------------------------------------------- */
 
 ComputeTempRegionEff::~ComputeTempRegionEff()
 {
   delete [] idregion;
   memory->destroy(vbiasall);
   delete [] vector;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempRegionEff::init()
 {
   // set index and check validity of region
 
   iregion = domain->find_region(idregion);
   if (iregion == -1)
     error->all(FLERR,"Region ID for compute temp/region/eff does not exist");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempRegionEff::setup()
 {
   dynamic = 0;
   if (dynamic_user || group->dynamic[igroup]) dynamic = 1;
   dof = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempRegionEff::dof_remove_pre()
 {
   domain->regions[iregion]->prematch();
 }
 
 /* ---------------------------------------------------------------------- */
 
 int ComputeTempRegionEff::dof_remove(int i)
 {
   double *x = atom->x[i];
   if (domain->regions[iregion]->match(x[0],x[1],x[2])) return 0;
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 double ComputeTempRegionEff::compute_scalar()
 {
   invoked_scalar = update->ntimestep;
 
   double **x = atom->x;
   double **v = atom->v;
   double *ervel = atom->ervel;
   double *mass = atom->mass;
   int *spin = atom->spin;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   double mefactor = domain->dimension/4.0;
 
   Region *region = domain->regions[iregion];
   region->prematch();
 
   int count = 0;
   int ecount = 0;
   double t = 0.0;
 
   if (mass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
         count++;
         t += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) *
           mass[type[i]];
         if (abs(spin[i])==1) {
           t += mefactor*mass[type[i]]*ervel[i]*ervel[i];
           ecount++;
         }
       }
   }
 
   double tarray[2],tarray_all[2];
   // Assume 3/2 k T per nucleus
   tarray[0] = count-ecount;
   tarray[1] = t;
   MPI_Allreduce(tarray,tarray_all,2,MPI_DOUBLE,MPI_SUM,world);
   dof = domain->dimension * tarray_all[0] - extra_dof;
+  if (dof < 0.0 && tarray_all[0] > 0.0) 
+    error->all(FLERR,"Temperature compute degrees of freedom < 0");
 
   int one = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
       if (abs(spin[i])==1) one++;
     }
 
-  if (dof > 0) scalar = force->mvv2e * tarray_all[1] / (dof * force->boltz);
+  if (dof > 0.0) scalar = force->mvv2e * tarray_all[1] / (dof * force->boltz);
   else scalar = 0.0;
   return scalar;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeTempRegionEff::compute_vector()
 {
   int i;
 
   invoked_vector = update->ntimestep;
 
   double **x = atom->x;
   double **v = atom->v;
   double *ervel = atom->ervel;
   double *mass = atom->mass;
   int *spin = atom->spin;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   double mefactor = domain->dimension/4.0;
 
   Region *region = domain->regions[iregion];
   region->prematch();
 
   double massone,t[6];
   for (i = 0; i < 6; i++) t[i] = 0.0;
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
       massone = mass[type[i]];
 
       t[0] += massone * v[i][0]*v[i][0];
       t[1] += massone * v[i][1]*v[i][1];
       t[2] += massone * v[i][2]*v[i][2];
       t[3] += massone * v[i][0]*v[i][1];
       t[4] += massone * v[i][0]*v[i][2];
       t[5] += massone * v[i][1]*v[i][2];
 
       if (abs(spin[i])==1) {
         t[0] += mefactor * massone * ervel[i]*ervel[i];
         t[1] += mefactor * massone * ervel[i]*ervel[i];
         t[2] += mefactor * massone * ervel[i]*ervel[i];
       }
     }
 
   MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world);
   for (i = 0; i < 6; i++) vector[i] *= force->mvv2e;
 }
 
 /* ----------------------------------------------------------------------
    remove velocity bias from atom I to leave thermal velocity
    NOTE: the following commands do not bias the radial electron velocities
 ------------------------------------------------------------------------- */
 
 void ComputeTempRegionEff::remove_bias(int i, double *v)
 {
   double *x = atom->x[i];
   if (domain->regions[iregion]->match(x[0],x[1],x[2]))
     vbias[0] = vbias[1] = vbias[2] = 0.0;
   else {
     vbias[0] = v[0];
     vbias[1] = v[1];
     vbias[2] = v[2];
     v[0] = v[1] = v[2] = 0.0;
   }
 }
 
 /* ----------------------------------------------------------------------
    remove velocity bias from all atoms to leave thermal velocity
 ------------------------------------------------------------------------- */
 
 void ComputeTempRegionEff::remove_bias_all()
 {
   double **x = atom->x;
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   if (nlocal > maxbias) {
     memory->destroy(vbiasall);
     maxbias = atom->nmax;
     memory->create(vbiasall,maxbias,3,"temp/region:vbiasall");
   }
 
   Region *region = domain->regions[iregion];
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       if (region->match(x[i][0],x[i][1],x[i][2]))
         vbiasall[i][0] = vbiasall[i][1] = vbiasall[i][2] = 0.0;
       else {
         vbiasall[i][0] = v[i][0];
         vbiasall[i][1] = v[i][1];
         vbiasall[i][2] = v[i][2];
         v[i][0] = v[i][1] = v[i][2] = 0.0;
       }
     }
 }
 
 /* ----------------------------------------------------------------------
    add back in velocity bias to atom I removed by remove_bias()
    assume remove_bias() was previously called
 ------------------------------------------------------------------------- */
 
 void ComputeTempRegionEff::restore_bias(int i, double *v)
 {
   v[0] += vbias[0];
   v[1] += vbias[1];
   v[2] += vbias[2];
 }
 
 /* ----------------------------------------------------------------------
    add back in velocity bias to all atoms removed by remove_bias_all()
    assume remove_bias_all() was previously called
 ------------------------------------------------------------------------- */
 
 void ComputeTempRegionEff::restore_bias_all()
 {
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       v[i][0] += vbiasall[i][0];
       v[i][1] += vbiasall[i][1];
       v[i][2] += vbiasall[i][2];
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double ComputeTempRegionEff::memory_usage()
 {
   double bytes = maxbias * sizeof(double);
   return bytes;
 }