diff --git a/src/ASPHERE/Install.csh b/src/ASPHERE/Install.csh
new file mode 100644
index 0000000000000000000000000000000000000000..8a45b90fa3727eca19f2fa7b1b00a5fcc3b2639f
--- /dev/null
+++ b/src/ASPHERE/Install.csh
@@ -0,0 +1,40 @@
+# Install/unInstall package classes in LAMMPS
+
+if ($1 == 1) then
+
+  cp style_asphere.h ..
+
+  cp atom_vec_ellipsoid.cpp ..
+  cp compute_temp_asphere.cpp ..
+  cp fix_npt_asphere.cpp ..
+  cp fix_nve_asphere.cpp ..
+  cp fix_nvt_asphere.cpp ..
+  cp pair_gayberne.cpp ..
+
+  cp atom_vec_ellipsoid.h ..
+  cp compute_temp_asphere.h ..
+  cp fix_npt_asphere.h ..
+  cp fix_nve_asphere.h ..
+  cp fix_nvt_asphere.h ..
+  cp pair_gayberne.h ..
+
+else if ($1 == 0) then
+
+  rm ../style_asphere.h
+  touch ../style_asphere.h
+
+  rm ../atom_vec_ellipsoid.cpp
+  rm ../compute_temp_asphere.cpp
+  rm ../fix_npt_asphere.cpp
+  rm ../fix_nve_asphere.cpp
+  rm ../fix_nvt_asphere.cpp
+  rm ../pair_gayberne.cpp
+
+  rm ../atom_vec_ellipsoid.h
+  rm ../compute_temp_asphere.h
+  rm ../fix_npt_asphere.h
+  rm ../fix_nve_asphere.h
+  rm ../fix_nvt_asphere.h
+  rm ../pair_gayberne.h
+
+endif
diff --git a/src/ASPHERE/atom_vec_ellipsoid.cpp b/src/ASPHERE/atom_vec_ellipsoid.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..e85b699decadf9bfd4c90d9913c4e2554dcd5b5b
--- /dev/null
+++ b/src/ASPHERE/atom_vec_ellipsoid.cpp
@@ -0,0 +1,609 @@
+/* ----------------------------------------------------------------------
+   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 "stdlib.h"
+#include "atom_vec_ellipsoid.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "force.h"
+#include "domain.h"
+#include "modify.h"
+#include "fix.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define DELTA 10000
+
+/* ---------------------------------------------------------------------- */
+
+AtomVecEllipsoid::AtomVecEllipsoid(LAMMPS *lmp, int narg, char **arg) :
+  AtomVec(lmp, narg, arg)
+{
+  mass_type = 1;
+  shape_type = 1;
+  comm_x_only = comm_f_only = 0;
+  size_comm = 7;
+  size_reverse = 6;
+  size_border = 10;
+  size_data_atom = 9;
+  size_data_vel = 7;
+  xcol_data = 3;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecEllipsoid::init()
+{
+  if (force->dimension == 2)
+    error->all("Cannot use atom style ellipsoid for 2d simulation");
+}
+
+/* ----------------------------------------------------------------------
+   grow atom arrays
+   n = 0 grows arrays by DELTA
+   n > 0 allocates arrays to size n
+------------------------------------------------------------------------- */
+
+void AtomVecEllipsoid::grow(int n)
+{
+  if (n == 0) nmax += DELTA;
+  else nmax = n;
+  atom->nmax = nmax;
+
+  tag = atom->tag = (int *)
+    memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
+  type = atom->type = (int *)
+    memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
+  mask = atom->mask = (int *)
+    memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
+  image = atom->image = (int *)
+    memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
+  x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
+  v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
+  f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
+
+  quat = atom->quat = 
+    memory->grow_2d_double_array(atom->quat,nmax,4,"atom:quat");
+  angmom = atom->angmom = 
+    memory->grow_2d_double_array(atom->angmom,nmax,3,"atom:angmom");
+  torque = atom->torque = 
+    memory->grow_2d_double_array(atom->torque,nmax,3,"atom:torque");
+  
+  if (atom->nextra_grow)
+    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+      modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecEllipsoid::copy(int i, int j)
+{
+  tag[j] = tag[i];
+  type[j] = type[i];
+  mask[j] = mask[i];
+  image[j] = image[i];
+  x[j][0] = x[i][0];
+  x[j][1] = x[i][1];
+  x[j][2] = x[i][2];
+  v[j][0] = v[i][0];
+  v[j][1] = v[i][1];
+  v[j][2] = v[i][2];
+
+  quat[j][0] = quat[i][0];
+  quat[j][1] = quat[i][1];
+  quat[j][2] = quat[i][2];
+  quat[j][3] = quat[i][3];
+  angmom[j][0] = angmom[i][0];
+  angmom[j][1] = angmom[i][1];
+  angmom[j][2] = angmom[i][2];
+
+  if (atom->nextra_grow)
+    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+      modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecEllipsoid::pack_comm(int n, int *list, double *buf,
+			     int pbc_flag, int *pbc)
+{
+  int i,j,m;
+  double dx,dy,dz;
+
+  m = 0;
+  if (pbc_flag == 0) {
+    for (i = 0; i < n; i++) {
+      j = list[i];
+      buf[m++] = x[j][0];
+      buf[m++] = x[j][1];
+      buf[m++] = x[j][2];
+      buf[m++] = quat[j][0];
+      buf[m++] = quat[j][1];
+      buf[m++] = quat[j][2];
+      buf[m++] = quat[j][3];
+    }
+  } else {
+    if (domain->triclinic == 0) {
+      dx = pbc[0]*domain->xprd;
+      dy = pbc[1]*domain->yprd;
+      dz = pbc[2]*domain->zprd;
+    } else {
+      dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
+      dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
+      dz = pbc[2]*domain->zprd;
+    }
+    for (i = 0; i < n; i++) {
+      j = list[i];
+      buf[m++] = x[j][0] + dx;
+      buf[m++] = x[j][1] + dy;
+      buf[m++] = x[j][2] + dz;
+      buf[m++] = quat[j][0];
+      buf[m++] = quat[j][1];
+      buf[m++] = quat[j][2];
+      buf[m++] = quat[j][3];
+    }
+  }
+  return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecEllipsoid::unpack_comm(int n, int first, double *buf)
+{
+  int i,m,last;
+
+  m = 0;
+  last = first + n;
+  for (i = first; i < last; i++) {
+    x[i][0] = buf[m++];
+    x[i][1] = buf[m++];
+    x[i][2] = buf[m++];
+    quat[i][0] = buf[m++];
+    quat[i][1] = buf[m++];
+    quat[i][2] = buf[m++];
+    quat[i][3] = buf[m++];
+  }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecEllipsoid::pack_reverse(int n, int first, double *buf)
+{
+  int i,m,last;
+
+  m = 0;
+  last = first + n;
+  for (i = first; i < last; i++) {
+    buf[m++] = f[i][0];
+    buf[m++] = f[i][1];
+    buf[m++] = f[i][2];
+    buf[m++] = torque[i][0];
+    buf[m++] = torque[i][1];
+    buf[m++] = torque[i][2];
+  }
+  return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecEllipsoid::unpack_reverse(int n, int *list, double *buf)
+{
+  int i,j,m;
+
+  m = 0;
+  for (i = 0; i < n; i++) {
+    j = list[i];
+    f[j][0] += buf[m++];
+    f[j][1] += buf[m++];
+    f[j][2] += buf[m++];
+    torque[j][0] += buf[m++];
+    torque[j][1] += buf[m++];
+    torque[j][2] += buf[m++];
+  }
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecEllipsoid::pack_border(int n, int *list, double *buf,
+				  int pbc_flag, int *pbc)
+{
+  int i,j,m;
+  double dx,dy,dz;
+
+  m = 0;
+  if (pbc_flag == 0) {
+    for (i = 0; i < n; i++) {
+      j = list[i];
+      buf[m++] = x[j][0];
+      buf[m++] = x[j][1];
+      buf[m++] = x[j][2];
+      buf[m++] = tag[j];
+      buf[m++] = type[j];
+      buf[m++] = mask[j];
+      buf[m++] = quat[j][0];
+      buf[m++] = quat[j][1];
+      buf[m++] = quat[j][2];
+      buf[m++] = quat[j][3];
+    }
+  } else {
+    if (domain->triclinic == 0) {
+      dx = pbc[0]*domain->xprd;
+      dy = pbc[1]*domain->yprd;
+      dz = pbc[2]*domain->zprd;
+    } else {
+      dx = pbc[0];
+      dy = pbc[1];
+      dz = pbc[2];
+    }
+    for (i = 0; i < n; i++) {
+      j = list[i];
+      buf[m++] = x[j][0] + dx;
+      buf[m++] = x[j][1] + dy;
+      buf[m++] = x[j][2] + dz;
+      buf[m++] = tag[j];
+      buf[m++] = type[j];
+      buf[m++] = mask[j];
+      buf[m++] = quat[j][0];
+      buf[m++] = quat[j][1];
+      buf[m++] = quat[j][2];
+      buf[m++] = quat[j][3];
+    }
+  }
+  return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AtomVecEllipsoid::unpack_border(int n, int first, double *buf)
+{
+  int i,m,last;
+
+  m = 0;
+  last = first + n;
+  for (i = first; i < last; i++) {
+    if (i == nmax) grow(0);
+    x[i][0] = buf[m++];
+    x[i][1] = buf[m++];
+    x[i][2] = buf[m++];
+    tag[i] = static_cast<int> (buf[m++]);
+    type[i] = static_cast<int> (buf[m++]);
+    mask[i] = static_cast<int> (buf[m++]);
+    quat[i][0] = buf[m++];
+    quat[i][1] = buf[m++];
+    quat[i][2] = buf[m++];
+    quat[i][3] = buf[m++];
+  }
+}
+
+/* ----------------------------------------------------------------------
+   pack data for atom I for sending to another proc
+   xyz must be 1st 3 values, so comm::exchange() can test on them
+------------------------------------------------------------------------- */
+
+int AtomVecEllipsoid::pack_exchange(int i, double *buf)
+{
+  int m = 1;
+  buf[m++] = x[i][0];
+  buf[m++] = x[i][1];
+  buf[m++] = x[i][2];
+  buf[m++] = v[i][0];
+  buf[m++] = v[i][1];
+  buf[m++] = v[i][2];
+  buf[m++] = tag[i];
+  buf[m++] = type[i];
+  buf[m++] = mask[i];
+  buf[m++] = image[i];
+
+  buf[m++] = quat[i][0];
+  buf[m++] = quat[i][1];
+  buf[m++] = quat[i][2];
+  buf[m++] = quat[i][3];
+  buf[m++] = angmom[i][0];
+  buf[m++] = angmom[i][1];
+  buf[m++] = angmom[i][2];
+  
+  if (atom->nextra_grow)
+    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+      m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
+
+  buf[0] = m;
+  return m;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int AtomVecEllipsoid::unpack_exchange(double *buf)
+{
+  int nlocal = atom->nlocal;
+  if (nlocal == nmax) grow(0);
+
+  int m = 1;
+  x[nlocal][0] = buf[m++];
+  x[nlocal][1] = buf[m++];
+  x[nlocal][2] = buf[m++];
+  v[nlocal][0] = buf[m++];
+  v[nlocal][1] = buf[m++];
+  v[nlocal][2] = buf[m++];
+  tag[nlocal] = static_cast<int> (buf[m++]);
+  type[nlocal] = static_cast<int> (buf[m++]);
+  mask[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<int> (buf[m++]);
+
+  quat[nlocal][0] = buf[m++];
+  quat[nlocal][1] = buf[m++];
+  quat[nlocal][2] = buf[m++];
+  quat[nlocal][3] = buf[m++];
+  angmom[nlocal][0] = buf[m++];
+  angmom[nlocal][1] = buf[m++];
+  angmom[nlocal][2] = buf[m++];
+  
+  if (atom->nextra_grow)
+    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+      m += modify->fix[atom->extra_grow[iextra]]->
+	unpack_exchange(nlocal,&buf[m]);
+
+  atom->nlocal++;
+  return m;
+}
+
+/* ----------------------------------------------------------------------
+   size of restart data for all atoms owned by this proc
+   include extra data stored by fixes
+------------------------------------------------------------------------- */
+
+int AtomVecEllipsoid::size_restart()
+{
+  int i;
+
+  int nlocal = atom->nlocal;
+  int n = 18 * nlocal;
+
+  if (atom->nextra_restart)
+    for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+      for (i = 0; i < nlocal; i++)
+	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
+
+  return n;
+}
+
+/* ----------------------------------------------------------------------
+   pack atom I's data for restart file including extra quantities
+   xyz must be 1st 3 values, so that read_restart can test on them
+   molecular types may be negative, but write as positive
+------------------------------------------------------------------------- */
+
+int AtomVecEllipsoid::pack_restart(int i, double *buf)
+{
+  int m = 1;
+  buf[m++] = x[i][0];
+  buf[m++] = x[i][1];
+  buf[m++] = x[i][2];
+  buf[m++] = tag[i];
+  buf[m++] = type[i];
+  buf[m++] = mask[i];
+  buf[m++] = image[i];
+  buf[m++] = v[i][0];
+  buf[m++] = v[i][1];
+  buf[m++] = v[i][2];
+
+  buf[m++] = quat[i][0];
+  buf[m++] = quat[i][1];
+  buf[m++] = quat[i][2];
+  buf[m++] = quat[i][3];
+  buf[m++] = angmom[i][0];
+  buf[m++] = angmom[i][1];
+  buf[m++] = angmom[i][2];
+  
+  if (atom->nextra_restart)
+    for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+      m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
+
+  buf[0] = m;
+  return m;
+}
+
+/* ----------------------------------------------------------------------
+   unpack data for one atom from restart file including extra quantities
+------------------------------------------------------------------------- */
+
+int AtomVecEllipsoid::unpack_restart(double *buf)
+{
+  int nlocal = atom->nlocal;
+  if (nlocal == nmax) {
+    grow(0);
+    if (atom->nextra_store) 
+      atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
+						 atom->nextra_store,
+						 "atom:extra");
+  }
+
+  int m = 1;
+  x[nlocal][0] = buf[m++];
+  x[nlocal][1] = buf[m++];
+  x[nlocal][2] = buf[m++];
+  tag[nlocal] = static_cast<int> (buf[m++]);
+  type[nlocal] = static_cast<int> (buf[m++]);
+  mask[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<int> (buf[m++]);
+  v[nlocal][0] = buf[m++];
+  v[nlocal][1] = buf[m++];
+  v[nlocal][2] = buf[m++];
+
+  quat[nlocal][0] = buf[m++];
+  quat[nlocal][1] = buf[m++];
+  quat[nlocal][2] = buf[m++];
+  quat[nlocal][3] = buf[m++];
+  angmom[nlocal][0] = buf[m++];
+  angmom[nlocal][1] = buf[m++];
+  angmom[nlocal][2] = buf[m++];
+  
+  double **extra = atom->extra;
+  if (atom->nextra_store) {
+    int size = static_cast<int> (buf[0]) - m;
+    for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
+  }
+
+  atom->nlocal++;
+  return m;
+}
+
+/* ----------------------------------------------------------------------
+   create one atom of itype at coord
+   set other values to defaults
+------------------------------------------------------------------------- */
+
+void AtomVecEllipsoid::create_atom(int itype, double *coord)
+{
+  int nlocal = atom->nlocal;
+  if (nlocal == nmax) grow(0);
+
+  tag[nlocal] = 0;
+  type[nlocal] = itype;
+  x[nlocal][0] = coord[0];
+  x[nlocal][1] = coord[1];
+  x[nlocal][2] = coord[2];
+  mask[nlocal] = 1;
+  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  v[nlocal][0] = 0.0;
+  v[nlocal][1] = 0.0;
+  v[nlocal][2] = 0.0;
+
+  quat[nlocal][0] = 1.0;
+  quat[nlocal][1] = 0.0;
+  quat[nlocal][2] = 0.0;
+  quat[nlocal][3] = 0.0;
+  angmom[nlocal][0] = 0.0;
+  angmom[nlocal][1] = 0.0;
+  angmom[nlocal][2] = 0.0;
+
+  atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+   unpack one line from Atoms section of data file
+   initialize other atom quantities
+------------------------------------------------------------------------- */
+
+void AtomVecEllipsoid::data_atom(double *coord, int imagetmp, char **values)
+{
+  int nlocal = atom->nlocal;
+  if (nlocal == nmax) grow(0);
+
+  tag[nlocal] = atoi(values[0]);
+  if (tag[nlocal] <= 0)
+    error->one("Invalid atom ID in Atoms section of data file");
+
+  type[nlocal] = atoi(values[1]);
+  if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
+    error->one("Invalid atom type in Atoms section of data file");
+
+  x[nlocal][0] = coord[0];
+  x[nlocal][1] = coord[1];
+  x[nlocal][2] = coord[2];
+
+  quat[nlocal][0] = atof(values[5]);
+  quat[nlocal][1] = atof(values[6]);
+  quat[nlocal][2] = atof(values[7]);
+  quat[nlocal][3] = atof(values[8]);
+  MathExtra::normalize4(quat[nlocal]);
+
+  image[nlocal] = imagetmp;
+
+  mask[nlocal] = 1;
+  v[nlocal][0] = 0.0;
+  v[nlocal][1] = 0.0;
+  v[nlocal][2] = 0.0;
+  angmom[nlocal][0] = 0.0;
+  angmom[nlocal][1] = 0.0;
+  angmom[nlocal][2] = 0.0;
+
+  atom->nlocal++;
+}
+
+/* ----------------------------------------------------------------------
+   unpack hybrid quantities from one line in Atoms section of data file
+   initialize other atom quantities for this sub-style
+------------------------------------------------------------------------- */
+
+int AtomVecEllipsoid::data_atom_hybrid(int nlocal, char **values)
+{
+  quat[nlocal][0] = atof(values[0]);
+  quat[nlocal][1] = atof(values[1]);
+  quat[nlocal][2] = atof(values[2]);
+  quat[nlocal][3] = atof(values[3]);
+  MathExtra::normalize4(quat[nlocal]);
+
+  v[nlocal][0] = 0.0;
+  v[nlocal][1] = 0.0;
+  v[nlocal][2] = 0.0;
+  angmom[nlocal][0] = 0.0;
+  angmom[nlocal][1] = 0.0;
+  angmom[nlocal][2] = 0.0;
+
+  return 0;
+}
+
+/* ----------------------------------------------------------------------
+   unpack one line from Velocities section of data file
+------------------------------------------------------------------------- */
+
+void AtomVecEllipsoid::data_vel(int m, char **values)
+{
+  v[m][0] = atof(values[0]);
+  v[m][1] = atof(values[1]);
+  v[m][2] = atof(values[2]);
+  angmom[m][0] = atof(values[3]);
+  angmom[m][1] = atof(values[4]);
+  angmom[m][2] = atof(values[5]);
+}
+
+/* ----------------------------------------------------------------------
+   unpack hybrid quantities from one line in Velocities section of data file
+------------------------------------------------------------------------- */
+
+int AtomVecEllipsoid::data_vel_hybrid(int m, char **values)
+{
+  angmom[m][0] = atof(values[0]);
+  angmom[m][1] = atof(values[1]);
+  angmom[m][2] = atof(values[2]);
+  return 3;
+}
+
+/* ----------------------------------------------------------------------
+   return # of bytes of allocated memory
+------------------------------------------------------------------------- */
+
+int AtomVecEllipsoid::memory_usage()
+{
+  int bytes = 0;
+
+  if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
+  if (atom->memcheck("type")) bytes += nmax * sizeof(int);
+  if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
+  if (atom->memcheck("image")) bytes += nmax * sizeof(int);
+  if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
+  if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
+  if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
+
+  if (atom->memcheck("quat")) bytes += nmax*4 * sizeof(double);
+  if (atom->memcheck("angmom")) bytes += nmax*3 * sizeof(double);
+  if (atom->memcheck("torque")) bytes += nmax*3 * sizeof(double);
+
+  return bytes;
+}
diff --git a/src/ASPHERE/atom_vec_ellipsoid.h b/src/ASPHERE/atom_vec_ellipsoid.h
new file mode 100755
index 0000000000000000000000000000000000000000..ce0c0bfe2722065c1e9bcccd2c01c90145019d75
--- /dev/null
+++ b/src/ASPHERE/atom_vec_ellipsoid.h
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------
+   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.
+------------------------------------------------------------------------- */
+
+#ifndef ATOM_VEC_ELLIPSOID_H
+#define ATOM_VEC_ELLIPSOID_H
+
+#include "atom_vec.h"
+
+namespace LAMMPS_NS {
+
+class AtomVecEllipsoid : public AtomVec {
+ public:
+  AtomVecEllipsoid(class LAMMPS *, int, char **);
+  virtual ~AtomVecEllipsoid() {}
+  void init();
+  void grow(int);
+  void copy(int, int);
+  virtual int pack_comm(int, int *, double *, int, int *);
+  virtual void unpack_comm(int, int, double *);
+  int pack_reverse(int, int, double *);
+  void unpack_reverse(int, int *, double *);
+  virtual int pack_border(int, int *, double *, int, int *);
+  virtual void unpack_border(int, int, double *);
+  int pack_exchange(int, double *);
+  int unpack_exchange(double *);
+  int size_restart();
+  int pack_restart(int, double *);
+  int unpack_restart(double *);
+  void create_atom(int, double *);
+  void data_atom(double *, int, char **);
+  int data_atom_hybrid(int, char **);
+  void data_vel(int, char **);
+  int data_vel_hybrid(int, char **);
+  int memory_usage();
+
+ private:
+  int *tag,*type,*mask,*image;
+  double **x,**v,**f;
+  double **angmom,**torque,**quat;
+};
+
+}
+
+#endif
diff --git a/src/ASPHERE/compute_temp_asphere.cpp b/src/ASPHERE/compute_temp_asphere.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..65dc36ad10b7895cbe6cf1eef93291fd45eff09f
--- /dev/null
+++ b/src/ASPHERE/compute_temp_asphere.cpp
@@ -0,0 +1,227 @@
+/* ----------------------------------------------------------------------
+   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 "compute_temp_asphere.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "force.h"
+#include "modify.h"
+#include "fix.h"
+#include "group.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+ComputeTempAsphere::ComputeTempAsphere(LAMMPS *lmp, int narg, char **arg) :
+  Compute(lmp, narg, arg)
+{
+  if (narg != 3) error->all("Illegal compute temp command");
+
+  if (atom->quat == NULL || atom->angmom == NULL)
+    error->all("Compute temp/asphere requires atom attributes quat, angmom");
+
+  scalar_flag = vector_flag = 1;
+  size_vector = 6;
+  extensive = 0;
+  tempflag = 1;
+
+  vector = new double[6];
+  inertia = 
+    memory->create_2d_double_array(atom->ntypes+1,3,"fix_temp_sphere:inertia");
+}
+
+/* ---------------------------------------------------------------------- */
+
+ComputeTempAsphere::~ComputeTempAsphere()
+{
+  delete [] vector;
+  memory->destroy_2d_double_array(inertia);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputeTempAsphere::init()
+{
+  fix_dof = 0;
+  for (int i = 0; i < modify->nfix; i++)
+    fix_dof += modify->fix[i]->dof(igroup);
+  recount();
+
+  calculate_inertia();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputeTempAsphere::recount()
+{
+  double natoms = group->count(igroup);
+  dof = force->dimension * natoms;
+  dof -= extra_dof + fix_dof;
+
+  // add rotational degrees of freedom
+  // 0 for sphere, 2 for uniaxial, 3 for biaxial
+
+  double **shape = atom->shape;
+  int *type = atom->type;
+  int *mask = atom->mask;
+  int nlocal = atom->nlocal;
+
+  int itype;
+  int rot_dof = 0;
+  for (int i = 0; i < nlocal; i++)
+    if (mask[i] & groupbit) {
+      itype = type[i];
+      if (shape[itype][0] == shape[itype][1] && 
+	  shape[itype][1] == shape[itype][2]) continue;
+      else if (shape[itype][0] == shape[itype][1] || 
+	       shape[itype][1] == shape[itype][2] ||
+	       shape[itype][0] == shape[itype][2]) rot_dof += 2;
+      else rot_dof += 3;
+    }
+
+  int rot_total;
+  MPI_Allreduce(&rot_dof,&rot_total,1,MPI_INT,MPI_SUM,world);
+  dof += rot_total;
+    
+  if (dof > 0) tfactor = force->mvv2e / (dof * force->boltz);
+  else tfactor = 0.0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+double ComputeTempAsphere::compute_scalar()
+{
+  double **v = atom->v;
+  double **quat = atom->quat;
+  double **angmom = atom->angmom;
+  double *mass = atom->mass;
+  int *type = atom->type;
+  int *mask = atom->mask;
+  int nlocal = atom->nlocal;
+
+  int itype;
+  double wbody[3];
+  double rot[3][3];
+  double t = 0.0;
+
+  for (int i = 0; i < nlocal; i++)
+    if (mask[i] & groupbit) {
+
+      // translational kinetic energy
+      
+      itype = type[i];
+      t += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) * mass[itype];
+
+      // wbody = angular velocity in body frame
+
+      MathExtra::quat_to_mat(quat[i],rot);
+      MathExtra::transpose_times_column3(rot,angmom[i],wbody);
+      wbody[0] /= inertia[itype][0];
+      wbody[1] /= inertia[itype][1];
+      wbody[2] /= inertia[itype][2];
+
+      // rotational kinetic energy
+
+      t += inertia[itype][0]*wbody[0]*wbody[0]+
+           inertia[itype][1]*wbody[1]*wbody[1]+
+           inertia[itype][2]*wbody[2]*wbody[2];
+    }
+
+  MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
+  if (dynamic) recount();
+  scalar *= tfactor;
+  return scalar;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void ComputeTempAsphere::compute_vector()
+{
+  int i;
+
+  double **v = atom->v;
+  double **quat = atom->quat;
+  double **angmom = atom->angmom;
+  double *mass = atom->mass;
+  int *type = atom->type;
+  int *mask = atom->mask;
+  int nlocal = atom->nlocal;
+
+  int itype;
+  double wbody[3];
+  double rot[3][3];
+  double massone,t[6];
+  for (i = 0; i < 6; i++) t[i] = 0.0;
+
+  for (i = 0; i < nlocal; i++)
+    if (mask[i] & groupbit) {
+
+      // translational kinetic energy
+
+      itype = type[i];
+      massone = mass[itype];
+      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];
+
+      // wbody = angular velocity in body frame
+
+      MathExtra::quat_to_mat(quat[i],rot);
+      MathExtra::transpose_times_column3(rot,angmom[i],wbody);
+      wbody[0] /= inertia[itype][0];
+      wbody[1] /= inertia[itype][1];
+      wbody[2] /= inertia[itype][2];
+
+      // rotational kinetic energy
+
+      t[0] += inertia[itype][0]*wbody[0]*wbody[0];
+      t[1] += inertia[itype][1]*wbody[1]*wbody[1];
+      t[2] += inertia[itype][2]*wbody[2]*wbody[2];
+      t[3] += inertia[itype][0]*wbody[0]*wbody[1];
+      t[4] += inertia[itype][1]*wbody[0]*wbody[2];
+      t[5] += inertia[itype][2]*wbody[1]*wbody[2];
+    }
+
+  MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world);
+  for (i = 0; i < 6; i++) vector[i] *= force->mvv2e;
+}
+
+/* ----------------------------------------------------------------------
+   principal moments of inertia for ellipsoids
+------------------------------------------------------------------------- */
+
+void ComputeTempAsphere::calculate_inertia()
+{
+  double *mass = atom->mass;
+  double **shape = atom->shape;
+
+  for (int i = 1; i <= atom->ntypes; i++) {
+    inertia[i][0] = mass[i] * 
+      (shape[i][1]*shape[i][1]+shape[i][2]*shape[i][2]) / 5.0;
+    inertia[i][1] = mass[i] * 
+      (shape[i][0]*shape[i][0]+shape[i][2]*shape[i][2]) / 5.0;
+    inertia[i][2] = mass[i] * 
+      (shape[i][0]*shape[i][0]+shape[i][1]*shape[i][1]) / 5.0;
+  }
+}
diff --git a/src/ASPHERE/compute_temp_asphere.h b/src/ASPHERE/compute_temp_asphere.h
new file mode 100755
index 0000000000000000000000000000000000000000..651f409853c33a0006b42decf0ddcd122b1e8ca9
--- /dev/null
+++ b/src/ASPHERE/compute_temp_asphere.h
@@ -0,0 +1,40 @@
+/* ----------------------------------------------------------------------
+   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.
+------------------------------------------------------------------------- */
+
+#ifndef COMPUTE_TEMP_ASPHERE_H
+#define COMPUTE_TEMP_ASPHERE_H
+
+#include "compute.h"
+
+namespace LAMMPS_NS {
+
+class ComputeTempAsphere : public Compute {
+ public:
+  ComputeTempAsphere(class LAMMPS *, int, char **);
+  ~ComputeTempAsphere();
+  void init();
+  double compute_scalar();
+  void compute_vector();
+
+ private:
+  int fix_dof;
+  double tfactor;
+  double **inertia;
+
+  void recount();
+  void calculate_inertia();
+};
+
+}
+
+#endif
diff --git a/src/ASPHERE/fix_nve_asphere.cpp b/src/ASPHERE/fix_nve_asphere.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..17fdb23f029dc947ff30cb81e1e02fbc0819a2e3
--- /dev/null
+++ b/src/ASPHERE/fix_nve_asphere.cpp
@@ -0,0 +1,236 @@
+/* ----------------------------------------------------------------------
+   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 "math.h"
+#include "stdio.h"
+#include "string.h"
+#include "fix_nve_asphere.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "force.h"
+#include "update.h"
+#include "memory.h"
+#include "error.h"
+
+#define TOLERANCE 1.0e-6
+#define EPSILON 1.0e-7
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+FixNVEASphere::FixNVEASphere(LAMMPS *lmp, int narg, char **arg) : 
+  Fix(lmp, narg, arg)
+{
+  if (narg < 3) error->all("Illegal fix nve/asphere command");
+  if (atom->quat == NULL || atom->angmom == NULL || atom->torque == NULL)
+    error->all("Fix nve/asphere requires atom attributes "
+	       "quat, angmom, torque");
+  inertia = 
+    memory->create_2d_double_array(atom->ntypes+1,3,"fix_temp_sphere:inertia");
+}
+
+/* ---------------------------------------------------------------------- */
+
+FixNVEASphere::~FixNVEASphere()
+{
+  memory->destroy_2d_double_array(inertia);
+}
+
+/* ---------------------------------------------------------------------- */
+
+int FixNVEASphere::setmask()
+{
+  int mask = 0;
+  mask |= INITIAL_INTEGRATE;
+  mask |= FINAL_INTEGRATE;
+  return mask;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixNVEASphere::init()
+{
+  dtv = update->dt;
+  dtf = 0.5 * update->dt * force->ftm2v;
+  dtq = 0.5 * update->dt;
+
+  calculate_inertia();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixNVEASphere::initial_integrate()
+{
+  double dtfm;
+
+  double **x = atom->x;
+  double **v = atom->v;
+  double **f = atom->f;
+  double **quat = atom->quat;
+  double **angmom = atom->angmom;
+  double **torque = atom->torque;
+  double *mass = atom->mass;
+  int *type = atom->type;
+  int *mask = atom->mask;
+  int nlocal = atom->nlocal;
+
+  for (int i = 0; i < atom->nlocal; i++)
+    if (mask[i] & groupbit) {
+      dtfm = dtf / mass[type[i]];
+      v[i][0] += dtfm * f[i][0];
+      v[i][1] += dtfm * f[i][1];
+      v[i][2] += dtfm * f[i][2];
+      x[i][0] += dtv * v[i][0];
+      x[i][1] += dtv * v[i][1];
+      x[i][2] += dtv * v[i][2];
+
+      // update angular momentum by 1/2 step
+      // update quaternion a full step via Richardson iteration
+      // returns new normalized quaternion
+      
+      angmom[i][0] += dtf * torque[i][0];
+      angmom[i][1] += dtf * torque[i][1];
+      angmom[i][2] += dtf * torque[i][2];
+
+      richardson(quat[i],angmom[i],inertia[type[i]]);
+    }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void FixNVEASphere::final_integrate()
+{
+  double dtfm;
+
+  double **v = atom->v;
+  double **f = atom->f;
+  double **angmom = atom->angmom;
+  double **torque = atom->torque;
+  double *mass = atom->mass;
+  int *type = atom->type;
+  int *mask = atom->mask;
+  int nlocal = atom->nlocal;
+  
+  for (int i = 0; i < nlocal; i++)
+    if (mask[i] & groupbit) {
+      dtfm = dtf / mass[atom->type[i]];
+      v[i][0] += dtfm * f[i][0];
+      v[i][1] += dtfm * f[i][1];
+      v[i][2] += dtfm * f[i][2];
+  
+      angmom[i][0] += dtf * torque[i][0];
+      angmom[i][1] += dtf * torque[i][1];
+      angmom[i][2] += dtf * torque[i][2];
+    }
+}
+
+/* ----------------------------------------------------------------------
+   Richardson iteration to update quaternion accurately
+------------------------------------------------------------------------- */
+
+void FixNVEASphere::richardson(double *q, double *m, double *moments)
+{
+  // compute omega at 1/2 step from m at 1/2 step and q at 0
+
+  double w[3];
+  omega_from_mq(q,m,moments,w);
+
+  // full update from dq/dt = 1/2 w q
+
+  double wq[4];
+  MathExtra::multiply_vec_quat(w,q,wq);
+
+  double qfull[4];
+  qfull[0] = q[0] + dtq * wq[0];
+  qfull[1] = q[1] + dtq * wq[1];
+  qfull[2] = q[2] + dtq * wq[2];
+  qfull[3] = q[3] + dtq * wq[3];
+  MathExtra::normalize4(qfull);
+
+  // 1st half of update from dq/dt = 1/2 w q
+
+  double qhalf[4];
+  qhalf[0] = q[0] + 0.5*dtq * wq[0];
+  qhalf[1] = q[1] + 0.5*dtq * wq[1];
+  qhalf[2] = q[2] + 0.5*dtq * wq[2];
+  qhalf[3] = q[3] + 0.5*dtq * wq[3];
+  MathExtra::normalize4(qhalf);
+
+  // re-compute omega at 1/2 step from m at 1/2 step and q at 1/2 step
+  // recompute wq
+
+  omega_from_mq(qhalf,m,moments,w);
+  MathExtra::multiply_vec_quat(w,qhalf,wq);
+
+  // 2nd half of update from dq/dt = 1/2 w q
+
+  qhalf[0] += 0.5*dtq * wq[0];
+  qhalf[1] += 0.5*dtq * wq[1];
+  qhalf[2] += 0.5*dtq * wq[2];
+  qhalf[3] += 0.5*dtq * wq[3];
+  MathExtra::normalize4(qhalf);
+
+  // corrected Richardson update
+
+  q[0] = 2.0*qhalf[0] - qfull[0];
+  q[1] = 2.0*qhalf[1] - qfull[1];
+  q[2] = 2.0*qhalf[2] - qfull[2];
+  q[3] = 2.0*qhalf[3] - qfull[3];
+  MathExtra::normalize4(q);
+}
+
+/* ----------------------------------------------------------------------
+   compute omega from angular momentum
+   w = omega = angular velocity in space frame
+   wbody = angular velocity in body frame
+   project space-frame angular momentum onto body axes
+     and divide by principal moments
+------------------------------------------------------------------------- */
+
+void FixNVEASphere::omega_from_mq(double *q, double *m, double *moments,
+				  double *w)
+{
+  double rot[3][3];
+  MathExtra::quat_to_mat(q,rot);
+  
+  double wbody[3];
+  MathExtra::transpose_times_column3(rot,m,wbody);
+  wbody[0] /= moments[0];
+  wbody[1] /= moments[1];
+  wbody[2] /= moments[2];
+  MathExtra::times_column3(rot,wbody,w);
+}
+
+/* ----------------------------------------------------------------------
+   principal moments of inertia for ellipsoids
+------------------------------------------------------------------------- */
+
+void FixNVEASphere::calculate_inertia()
+{
+  double *mass = atom->mass;
+  double **shape = atom->shape;
+
+  for (int i = 1; i <= atom->ntypes; i++) {
+    inertia[i][0] = mass[i] * 
+      (shape[i][1]*shape[i][1]+shape[i][2]*shape[i][2]) / 5.0;
+    inertia[i][1] = mass[i] * 
+      (shape[i][0]*shape[i][0]+shape[i][2]*shape[i][2]) / 5.0;
+    inertia[i][2] = mass[i] * 
+      (shape[i][0]*shape[i][0]+shape[i][1]*shape[i][1]) / 5.0;
+  }
+}
diff --git a/src/ASPHERE/fix_nve_asphere.h b/src/ASPHERE/fix_nve_asphere.h
new file mode 100755
index 0000000000000000000000000000000000000000..4b7573ee18552a284d114f64e8571840f627c290
--- /dev/null
+++ b/src/ASPHERE/fix_nve_asphere.h
@@ -0,0 +1,40 @@
+/* ----------------------------------------------------------------------
+   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.
+------------------------------------------------------------------------- */
+
+#ifndef FIX_NVE_ASPHERE_H
+#define FIX_NVE_ASPHERE_H
+
+#include "fix.h"
+
+namespace LAMMPS_NS {
+
+class FixNVEASphere : public Fix {
+ public:
+  FixNVEASphere(class LAMMPS *, int, char **);
+  ~FixNVEASphere();
+  int setmask();
+  void init();
+  void initial_integrate();
+  void final_integrate();
+
+ private:
+  double dtv,dtf,dtq;
+  double **inertia;
+
+  void richardson(double *, double *, double *);
+  void omega_from_mq(double *, double *, double *, double *);
+  void calculate_inertia();
+};
+
+}
+#endif
diff --git a/src/ASPHERE/pair_gayberne.cpp b/src/ASPHERE/pair_gayberne.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..222adc85539f1da32f9322b9502ed3dde2d55270
--- /dev/null
+++ b/src/ASPHERE/pair_gayberne.cpp
@@ -0,0 +1,698 @@
+/* ----------------------------------------------------------------------
+   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 "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "pair_gayberne.h"
+#include "math_extra.h"
+#include "atom.h"
+#include "comm.h"
+#include "force.h"
+#include "neighbor.h"
+#include "update.h"
+#include "integrate.h"
+#include "respa.h"
+#include "memory.h"
+#include "error.h"
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+using namespace LAMMPS_NS;
+
+enum{SPHERE_SPHERE,SPHERE_ELLIPSE,ELLIPSE_ELLIPSE};
+
+/* ---------------------------------------------------------------------- */
+
+PairGayBerne::PairGayBerne(LAMMPS *lmp) : Pair(lmp)
+{
+  respa_enable = 0;
+  single_enable = 0;
+}
+
+/* ----------------------------------------------------------------------
+   free all arrays
+------------------------------------------------------------------------- */
+
+PairGayBerne::~PairGayBerne()
+{
+  if (allocated) {
+    memory->destroy_2d_int_array(setflag);
+    memory->destroy_2d_double_array(cutsq);
+
+    memory->destroy_2d_int_array(form);
+    memory->destroy_2d_double_array(epsi);
+    memory->destroy_2d_double_array(sig);
+    memory->destroy_2d_double_array(shape);
+    memory->destroy_2d_double_array(well);
+    memory->destroy_2d_double_array(cut);
+    memory->destroy_2d_double_array(lj1);
+    memory->destroy_2d_double_array(lj2);
+    memory->destroy_2d_double_array(lj3);
+    memory->destroy_2d_double_array(lj4);
+    delete [] lshape;
+  }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairGayBerne::compute(int eflag, int vflag)
+{
+  int i,j,k,m,numneigh;
+  double one_eng,rsq;
+  double fforce[3],ttor[3],rtor[3],r12[3];
+  double a1[3][3],b1[3][3],g1[3][3],a2[3][3],b2[3][3],g2[3][3],temp[3][3];
+  int *neighs;
+  double factor_lj;
+  double **f;
+
+  eng_vdwl = 0.0;
+  if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0;
+
+  if (vflag == 2) f = update->f_pair;
+  else f = atom->f;
+  double **x = atom->x;
+  double **quat = atom->quat;
+  double **tor = atom->torque;
+  int *type = atom->type;
+  int nlocal = atom->nlocal;
+  int nall = atom->nlocal + atom->nghost;
+  double *special_lj = force->special_lj;
+  int newton_pair = force->newton_pair;
+
+  // loop over neighbors of my atoms
+
+  for (i = 0; i < nlocal; i++) {
+    neighs = neighbor->firstneigh[i];
+    numneigh = neighbor->numneigh[i];
+
+    // precomputations for force calculation
+
+    MathExtra::quat_to_mat_trans(quat[i],a1);
+    MathExtra::diag_times3(well[type[i]],a1,temp);
+    MathExtra::transpose_times3(a1,temp,b1);
+    MathExtra::diag_times3(shape[type[i]],a1,temp);
+    MathExtra::transpose_times3(a1,temp,g1);
+
+    for (k = 0; k < numneigh; k++) {
+      j = neighs[k];
+
+      if (j < nall) factor_lj = 1.0;
+      else {
+        factor_lj = special_lj[j/nall];
+        j %= nall;
+      }
+
+      // r12 = center to center vector
+
+      r12[0] = x[j][0]-x[i][0];
+      r12[1] = x[j][1]-x[i][1];
+      r12[2] = x[j][2]-x[i][2];
+      rsq = MathExtra::dot3(r12,r12);
+
+      // compute if less than cutoff
+
+      if (rsq < cutsq[type[i]][type[j]]) {
+
+	switch (form[itype][jtype]) {
+	case SPHERE_SPHERE: 
+	  r2inv = 1.0/rsq;
+	  r6inv = r2inv*r2inv*r2inv;
+	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+	  forcelj *= -r2inv;
+	  if (eflag) phi = r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) -
+		       offset[itype][jtype];
+	  fforce[0] = r12[0]*forcelj;
+	  fforce[1] = r12[1]*forcelj;
+	  fforce[2] = r12[2]*forcelj;
+	  ttor[0] = ttor[1] = ttor[2] = 0.0;
+	  break;
+
+	case SPHERE_ELLIPSE:
+	  MathExtra::quat_to_mat_trans(quat[j],a2);
+	  MathExtra::diag_times3(well[type[j]],a2,temp);
+	  MathExtra::transpose_times3(a2,temp,b2);
+	  MathExtra::diag_times3(shape[type[j]],a2,temp);
+	  MathExtra::transpose_times3(a2,temp,g2);
+	  one_eng = gayberne_analytic(i,j,a1,a2,b1,b2,g1,g2,r12,rsq,
+				      fforce,ttor,rtor);
+	  break;
+
+	case ELLIPSE_ELLIPSE:
+	  MathExtra::quat_to_mat_trans(quat[j],a2);
+	  MathExtra::diag_times3(well[type[j]],a2,temp);
+	  MathExtra::transpose_times3(a2,temp,b2);
+	  MathExtra::diag_times3(shape[type[j]],a2,temp);
+	  MathExtra::transpose_times3(a2,temp,g2);
+	  one_eng = gayberne_analytic(i,j,a1,a2,b1,b2,g1,g2,r12,rsq,
+				      fforce,ttor,rtor);
+	  break;
+	}
+
+        fforce[0] *= factor_lj;
+	fforce[1] *= factor_lj;
+	fforce[2] *= factor_lj;
+        ttor[0] *= factor_lj;
+	ttor[1] *= factor_lj;
+	ttor[2] *= factor_lj;
+
+        f[i][0] += fforce[0];
+	f[i][1] += fforce[1];
+	f[i][2] += fforce[2];
+        tor[i][0] += ttor[0];
+	tor[i][1] += ttor[1];
+	tor[i][2] += ttor[2];
+
+        if (newton_pair || j < nlocal) {
+          rtor[0] *= factor_lj;
+	  rtor[1] *= factor_lj;
+	  rtor[2] *= factor_lj;
+          f[j][0] -= fforce[0];
+	  f[j][1] -= fforce[1];
+	  f[j][2] -= fforce[2];
+          tor[j][0] += rtor[0];
+	  tor[j][1] += rtor[1];
+	  tor[j][2] += rtor[2];
+        }
+
+        if (eflag) {
+	  if (newton_pair || j < nlocal) eng_vdwl += factor_lj*one_eng;
+	  else eng_vdwl += 0.5*factor_lj*one_eng;
+        }
+
+        if (vflag == 1) {
+	  if (newton_pair == 0 && j >= nlocal) 
+	    for (m = 0; m < 6; m++) fforce[m] *= 0.5;
+	  virial[0] += r12[0]*r12[0]*fforce[0];
+	  virial[1] += r12[1]*r12[1]*fforce[1];
+	  virial[2] += r12[2]*r12[2]*fforce[2];
+	  virial[3] += r12[0]*r12[1]*fforce[0];
+	  virial[4] += r12[0]*r12[2]*fforce[1];
+	  virial[5] += r12[1]*r12[2]*fforce[2];
+	}
+      }
+    }
+  }
+  if (vflag == 2) virial_compute();
+}
+
+/* ----------------------------------------------------------------------
+   allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairGayBerne::allocate()
+{
+  allocated = 1;
+  int n = atom->ntypes;
+
+  setflag = memory->create_2d_int_array(n+1,n+1,"pair:setflag");
+  for (int i = 1; i <= n; i++)
+    for (int j = i; j <= n; j++)
+      setflag[i][j] = 0;
+
+  cutsq = memory->create_2d_double_array(n+1,n+1,"pair:cutsq");
+
+  form = memory->create_2d_int_array(n+1,n+1,"pair:form");
+  epsi = memory->create_2d_double_array(n+1,n+1,"pair:epsi");
+  sig = memory->create_2d_double_array(n+1,n+1,"pair:sig");
+  shape = memory->create_2d_double_array(n+1,3,"pair:shape");
+  well = memory->create_2d_double_array(n+1,3,"pair:well");
+  cut = memory->create_2d_double_array(n+1,n+1,"pair:cut");
+  lj1 = memory->create_2d_double_array(n+1,n+1,"pair:lj1");
+  lj2 = memory->create_2d_double_array(n+1,n+1,"pair:lj2");
+  lj3 = memory->create_2d_double_array(n+1,n+1,"pair:lj3");
+  lj4 = memory->create_2d_double_array(n+1,n+1,"pair:lj4");
+  lshape = new double[n+1];
+}
+
+/* ----------------------------------------------------------------------
+   global settings
+------------------------------------------------------------------------- */
+
+void PairGayBerne::settings(int narg, char **arg)
+{
+  if (narg != 4) error->all("Illegal pair_style command");
+
+  gamma = atof(arg[0]);
+  upsilon = atof(arg[1])/2.0;
+  mu = atof(arg[2]);
+  cut_global = atof(arg[3]);
+  
+  // reset cutoffs that have been explicitly set
+
+  if (allocated) {
+    int i,j;
+    for (i = 1; i <= atom->ntypes; i++)
+      for (j = i+1; j <= atom->ntypes; j++)
+	if (setflag[i][j]) cut[i][j] = cut_global;
+  }
+}
+
+/* ----------------------------------------------------------------------
+   set coeffs for one or more type pairs
+------------------------------------------------------------------------- */
+
+void PairGayBerne::coeff(int narg, char **arg)
+{
+  if (narg < 10 || narg > 11)
+    error->all("Incorrect args for pair coefficients");
+  if (!allocated) allocate();
+
+  int ilo,ihi,jlo,jhi;
+  force->bounds(arg[0],atom->ntypes,ilo,ihi);
+  force->bounds(arg[1],atom->ntypes,jlo,jhi);
+
+  double epsi_one = atof(arg[2]);
+  double sig_one = atof(arg[3]);
+  double eia_one = atof(arg[4]);
+  double eib_one = atof(arg[5]);
+  double eic_one = atof(arg[6]);
+  double eja_one = atof(arg[7]);
+  double ejb_one = atof(arg[8]);
+  double ejc_one = atof(arg[9]);
+  
+  double cut_one = cut_global;
+  if (narg == 11) cut_one = atof(arg[10]);
+
+  int count = 0;
+  for (int i = ilo; i <= ihi; i++) {
+    for (int j = MAX(jlo,i); j <= jhi; j++) {
+      epsi[i][j] = epsi_one;
+      sig[i][j] = sig_one;
+      cut[i][j] = cut_one;
+      if (i == j) {
+	well[i][0] = pow(ea_one,-1.0/mu);
+        well[i][1] = pow(eb_one,-1.0/mu);
+	well[i][2] = pow(ec_one,-1.0/mu);
+      }
+      setflag[i][j] = 1;
+      count++;
+    }
+  }
+
+  if (count == 0) error->all("Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+   init for one type pair i,j and corresponding j,i
+------------------------------------------------------------------------- */
+
+double PairGayBerne::init_one(int i, int j)
+{
+  if (setflag[i][j] == 0) {
+    epsi[i][j] = mix_energy(epsi[i][i],epsi[j][j],sig[i][i],sig[j][j]);
+    sig[i][j] = mix_distance(sig[i][i],sig[j][j]);
+    cut[i][j] = mix_distance(cut[i][i],cut[j][j]);
+  }
+  
+  int itype = 0;
+  if (atom->shape[i][0] != atom->shape[i][1] || 
+      atom->shape[i][0] != atom->shape[i][2] || 
+      atom->shape[i][1] != atom->shape[i][2]) itype = 0;
+  if (atom->shape[i][0] != atom->shape[i][1] || 
+      atom->shape[i][0] != atom->shape[i][2] || 
+      atom->shape[i][1] != atom->shape[i][2]) itype = 0;
+  
+  if (itype = 0 && jtype = 0) form[i][j] = SPHERE_SPHERE;
+  else if (itype = 0 || jtype == 0) form[i][j] = SPHERE_ELLIPSE;
+  else form[i][j] = ELLIPSE_ELLIPSE;
+
+  form[j][i] = form[i][j];
+  epsi[j][i] = epsi[i][j];
+  sig[j][i] = sig[i][j];
+  cut[j][i] = cut[i][j];
+
+  return cut[i][j];
+}
+
+/* ----------------------------------------------------------------------
+   check for necessary atom arrays
+------------------------------------------------------------------------- */
+
+void PairGayBerne::init_style()
+{
+  if (atom->quat == NULL || atom->torque == NULL)
+    error->all("Pair gayberne requires atom attributes quat, torque");
+
+  // per-type shape precalculations
+
+  for (int i = 1; i <= atom->ntypes; i++) {
+    double *one = atom->shape[i];
+    shape[i][0] = one[0]*one[0];
+    shape[i][1] = one[1]*one[1];
+    shape[i][2] = one[2]*one[2];
+    lshape[i] = (one[0]*one[1]+one[2]*one[2])*sqrt(one[0]*one[1]);
+  }
+}
+
+/* ----------------------------------------------------------------------
+   proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairGayBerne::write_restart(FILE *fp)
+{
+  write_restart_settings(fp);
+
+  int i,j;
+  for (i = 1; i <= atom->ntypes; i++) {
+    fwrite(&well[i][0],sizeof(double),3,fp);
+    for (j = i; j <= atom->ntypes; j++) {
+      fwrite(&setflag[i][j],sizeof(int),1,fp);
+      if (setflag[i][j]) {
+        fwrite(&epsi[i][j],sizeof(double),1,fp);
+        fwrite(&sig[i][j],sizeof(double),1,fp);
+        fwrite(&cut[i][j],sizeof(double),1,fp);
+      }
+    }
+  }
+}
+
+/* ----------------------------------------------------------------------
+   proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairGayBerne::read_restart(FILE *fp)
+{
+  read_restart_settings(fp);
+
+  allocate();
+
+  int i,j;
+  int me = comm->me;
+  for (i = 1; i <= atom->ntypes; i++) {
+    if (me == 0) fread(&well[i][0],sizeof(double),3,fp);
+    MPI_Bcast(&well[i][0],3,MPI_DOUBLE,0,world);
+    for (j = i; j <= atom->ntypes; j++) {
+      if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
+      MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
+      if (setflag[i][j]) {
+        if (me == 0) {
+          fread(&epsi[i][j],sizeof(double),1,fp);
+          fread(&sig[i][j],sizeof(double),1,fp);
+          fread(&cut[i][j],sizeof(double),1,fp);
+        }
+        MPI_Bcast(&epsi[i][j],1,MPI_DOUBLE,0,world);
+        MPI_Bcast(&sig[i][j],1,MPI_DOUBLE,0,world);
+        MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
+      }
+    }
+  }
+}
+
+/* ----------------------------------------------------------------------
+   proc 0 writes to restart file
+------------------------------------------------------------------------- */
+
+void PairGayBerne::write_restart_settings(FILE *fp)
+{
+  fwrite(&gamma,sizeof(double),1,fp);
+  fwrite(&upsilon,sizeof(double),1,fp);
+  fwrite(&mu,sizeof(double),1,fp);
+  fwrite(&cut_global,sizeof(double),1,fp);
+  fwrite(&mix_flag,sizeof(int),1,fp);
+}
+
+/* ----------------------------------------------------------------------
+   proc 0 reads from restart file, bcasts
+------------------------------------------------------------------------- */
+
+void PairGayBerne::read_restart_settings(FILE *fp)
+{
+  int me = comm->me;
+  if (me == 0) {
+    fread(&gamma,sizeof(double),1,fp);
+    fread(&upsilon,sizeof(double),1,fp);
+    fread(&mu,sizeof(double),1,fp);
+    fread(&cut_global,sizeof(double),1,fp);
+    fread(&mix_flag,sizeof(int),1,fp);
+  }
+  MPI_Bcast(&gamma,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&upsilon,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&mu,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
+}
+
+/* ----------------------------------------------------------------------
+   compute analytic energy, force (fforce), and torque (ttor & rtor)
+   based on rotation matrices a and precomputed matrices b and g
+   if newton is off, rtor is not calculated for ghost atoms
+------------------------------------------------------------------------- */
+
+double PairGayBerne::gayberne_analytic(const int i,const int j,double a1[3][3],
+                                       double a2[3][3], double b1[3][3],
+                                       double b2[3][3], double g1[3][3],
+                                       double g2[3][3], double *r12,
+                                       const double rsq, double *fforce,
+                                       double *ttor, double *rtor)
+{
+  double tempv[3], tempv2[3];
+  double temp[3][3];
+  double temp1,temp2,temp3;
+
+  int *type = atom->type;
+  int newton_pair = force->newton_pair;
+  int nlocal = atom->nlocal;
+
+  double r12hat[3];
+  MathExtra::normalize3(r12,r12hat);
+  double r = sqrt(rsq);
+
+  // compute distance of closest approach
+
+  double g12[3][3];
+  MathExtra::plus3(g1,g2,g12);
+  double kappa[3];
+  MathExtra::mldivide3(g12,r12,kappa,error);
+
+  // tempv = G12^-1*r12hat
+
+  tempv[0] = kappa[0]/r;
+  tempv[1] = kappa[1]/r;
+  tempv[2] = kappa[2]/r;
+  double sigma12 = MathExtra::dot3(r12hat,tempv);
+  sigma12 = pow(0.5*sigma12,-0.5);
+  double h12 = r-sigma12;
+
+  // energy
+  // compute u_r
+
+  double varrho = sig[type[i]][type[j]]/(h12+gamma*sig[type[i]][type[j]]);
+  double varrho6 = pow(varrho,6.0);
+  double varrho12 = varrho6*varrho6;
+  double u_r = 4.0*epsi[type[i]][type[j]]*(varrho12-varrho6);
+
+  // compute eta_12
+
+  double eta = 2.0*lshape[type[i]]*lshape[type[j]];
+  double det_g12 = MathExtra::det3(g12);
+  eta = pow(eta/det_g12,upsilon);
+
+  // compute chi_12
+
+  double b12[3][3];
+  double iota[3];
+  MathExtra::plus3(b1,b2,b12);
+  MathExtra::mldivide3(b12,r12,iota,error);
+
+  // tempv = G12^-1*r12hat
+
+  tempv[0] = iota[0]/r;
+  tempv[1] = iota[1]/r;
+  tempv[2] = iota[2]/r;
+  double chi = MathExtra::dot3(r12hat,tempv);
+  chi = pow(chi*2.0,mu);
+
+  // force
+  // compute dUr/dr
+
+  temp1 = (2.0*varrho12*varrho-varrho6*varrho)/sig[type[i]][type[j]];
+  temp1 = temp1*24.0*epsi[type[i]][type[j]];
+  double u_slj = temp1*pow(sigma12,3.0)/2.0;
+  double dUr[3];
+  temp2 = MathExtra::dot3(kappa,r12hat);
+  double uslj_rsq = u_slj/rsq;
+  dUr[0] = temp1*r12hat[0]+uslj_rsq*(kappa[0]-temp2*r12hat[0]);
+  dUr[1] = temp1*r12hat[1]+uslj_rsq*(kappa[1]-temp2*r12hat[1]);
+  dUr[2] = temp1*r12hat[2]+uslj_rsq*(kappa[2]-temp2*r12hat[2]);
+
+  // compute dChi_12/dr
+
+  double dchi[3];
+  temp1 = MathExtra::dot3(iota,r12hat);
+  temp2 = -4.0/rsq*mu*pow(chi,(mu-1.0)/mu);
+  dchi[0] = temp2*(iota[0]-temp1*r12hat[0]);
+  dchi[1] = temp2*(iota[1]-temp1*r12hat[1]);
+  dchi[2] = temp2*(iota[2]-temp1*r12hat[2]);
+
+  temp1 = -eta*u_r;
+  temp2 = eta*chi;
+  fforce[0] = temp1*dchi[0]-temp2*dUr[0];
+  fforce[1] = temp1*dchi[1]-temp2*dUr[1];
+  fforce[2] = temp1*dchi[2]-temp2*dUr[2];
+
+  // torque for particle 1 and 2
+  // compute dUr
+
+  tempv[0] = -uslj_rsq*kappa[0];
+  tempv[1] = -uslj_rsq*kappa[1];
+  tempv[2] = -uslj_rsq*kappa[2];
+  MathExtra::row_times3(kappa,g1,tempv2);
+  MathExtra::cross3(tempv,tempv2,dUr);
+  double dUr2[3];
+
+  if (newton_pair || j < nlocal) {
+    MathExtra::row_times3(kappa,g2,tempv2);
+    MathExtra::cross3(tempv,tempv2,dUr2);
+  }
+
+  // compute d_chi
+
+  MathExtra::row_times3(iota,b1,tempv);
+  MathExtra::cross3(tempv,iota,dchi);
+  temp1 = -4.0/rsq;
+  dchi[0] *= temp1;
+  dchi[1] *= temp1;
+  dchi[2] *= temp1;
+  double dchi2[3];
+
+  if (newton_pair || j < nlocal) {
+    MathExtra::row_times3(iota,b2,tempv);
+    MathExtra::cross3(tempv,iota,dchi2);
+    dchi2[0] *= temp1;
+    dchi2[1] *= temp1;
+    dchi2[2] *= temp1;
+  }
+
+  // compute d_eta
+
+  double deta[3];
+  deta[0] = deta[1] = deta[2] = 0.0;
+  compute_eta_torque(g12,a1,shape[type[i]],temp);
+  temp1 = -eta*upsilon;
+  for (unsigned m = 0; m < 3; m++) {
+    for (unsigned y = 0; y < 3; y++) tempv[y] = temp1*temp[m][y];
+    MathExtra::cross3(a1[m],tempv,tempv2);
+    deta[0] += tempv2[0];
+    deta[1] += tempv2[1];
+    deta[2] += tempv2[2];
+  }
+
+  // compute d_eta for particle 2
+
+  double deta2[3];
+  if (newton_pair || j < nlocal) {
+    deta2[0] = deta2[1] = deta2[2] = 0.0;
+    compute_eta_torque(g12,a2,shape[type[j]],temp);
+    for (unsigned m = 0; m < 3; m++) {
+      for (unsigned y = 0; y < 3; y++) tempv[y] = temp1*temp[m][y];
+      MathExtra::cross3(a2[m],tempv,tempv2);
+      deta2[0] += tempv2[0];
+      deta2[1] += tempv2[1];
+      deta2[2] += tempv2[2];
+    }
+  }
+
+  // torque
+
+  temp1 = u_r*eta;
+  temp2 = u_r*chi;
+  temp3 = chi*eta;
+
+  ttor[0] = (temp1*dchi[0]+temp2*deta[0]+temp3*dUr[0]) * -1.0;
+  ttor[1] = (temp1*dchi[1]+temp2*deta[1]+temp3*dUr[1]) * -1.0;
+  ttor[2] = (temp1*dchi[2]+temp2*deta[2]+temp3*dUr[2]) * -1.0;
+
+  if (newton_pair || j < nlocal) {
+    rtor[0] = (temp1*dchi2[0]+temp2*deta2[0]+temp3*dUr2[0]) * -1.0;
+    rtor[1] = (temp1*dchi2[1]+temp2*deta2[1]+temp3*dUr2[1]) * -1.0;
+    rtor[2] = (temp1*dchi2[2]+temp2*deta2[2]+temp3*dUr2[2]) * -1.0;
+  }
+
+  return temp1*chi;
+}
+
+/* ----------------------------------------------------------------------
+   torque contribution from eta
+   computes trace in the last doc equation for the torque derivative
+   code comes from symbolic solver dump
+   m is g12, m2 is a_i, s is the shape for the particle
+------------------------------------------------------------------------- */
+
+void PairGayBerne::compute_eta_torque(double m[3][3], double m2[3][3],
+                                      double *s, double ans[3][3])
+{
+  double den = m[1][0]*m[0][2]*m[2][1]-m[0][0]*m[1][2]*m[2][1]-
+    m[0][2]*m[2][0]*m[1][1]+m[0][1]*m[2][0]*m[1][2]-
+    m[1][0]*m[0][1]*m[2][2]+m[0][0]*m[1][1]*m[2][2];
+  
+  ans[0][0] = s[0]*(m[1][2]*m[0][1]*m2[0][2]+2.0*m[1][1]*m[2][2]*m2[0][0]-
+		    m[1][1]*m2[0][2]*m[0][2]-2.0*m[1][2]*m2[0][0]*m[2][1]+
+		    m2[0][1]*m[0][2]*m[2][1]-m2[0][1]*m[0][1]*m[2][2]-
+		    m[1][0]*m[2][2]*m2[0][1]+m[2][0]*m[1][2]*m2[0][1]+
+		    m[1][0]*m2[0][2]*m[2][1]-m2[0][2]*m[2][0]*m[1][1])/den;
+  
+  ans[0][1] = s[0]*(m[0][2]*m2[0][0]*m[2][1]-m[2][2]*m2[0][0]*m[0][1]+
+		    2.0*m[0][0]*m[2][2]*m2[0][1]-m[0][0]*m2[0][2]*m[1][2]-
+		    2.0*m[2][0]*m[0][2]*m2[0][1]+m2[0][2]*m[1][0]*m[0][2]-
+		    m[2][2]*m[1][0]*m2[0][0]+m[2][0]*m2[0][0]*m[1][2]+
+		    m[2][0]*m2[0][2]*m[0][1]-m2[0][2]*m[0][0]*m[2][1])/den;
+  
+  ans[0][2] = s[0]*(m[0][1]*m[1][2]*m2[0][0]-m[0][2]*m2[0][0]*m[1][1]-
+		    m[0][0]*m[1][2]*m2[0][1]+m[1][0]*m[0][2]*m2[0][1]-
+		    m2[0][1]*m[0][0]*m[2][1]-m[2][0]*m[1][1]*m2[0][0]+
+		    2.0*m[1][1]*m[0][0]*m2[0][2]-2.0*m[1][0]*m2[0][2]*m[0][1]+
+		    m[1][0]*m[2][1]*m2[0][0]+m[2][0]*m2[0][1]*m[0][1])/den;
+  
+  ans[1][0] = s[1]*(-m[1][1]*m2[1][2]*m[0][2]+2.0*m[1][1]*m[2][2]*m2[1][0]+
+		    m[1][2]*m[0][1]*m2[1][2]-2.0*m[1][2]*m2[1][0]*m[2][1]+
+		    m2[1][1]*m[0][2]*m[2][1]-m2[1][1]*m[0][1]*m[2][2]-
+		    m[1][0]*m[2][2]*m2[1][1]+m[2][0]*m[1][2]*m2[1][1]-
+		    m2[1][2]*m[2][0]*m[1][1]+m[1][0]*m2[1][2]*m[2][1])/den;
+  
+  ans[1][1] = s[1]*(m[0][2]*m2[1][0]*m[2][1]-m[0][1]*m[2][2]*m2[1][0]+
+		    2.0*m[2][2]*m[0][0]*m2[1][1]-m2[1][2]*m[0][0]*m[1][2]-
+		    2.0*m[2][0]*m2[1][1]*m[0][2]-m[1][0]*m[2][2]*m2[1][0]+
+		    m[2][0]*m[1][2]*m2[1][0]+m[1][0]*m2[1][2]*m[0][2]-
+		    m[0][0]*m2[1][2]*m[2][1]+m2[1][2]*m[0][1]*m[2][0])/den;
+  
+  ans[1][2] = s[1]*(m[0][1]*m[1][2]*m2[1][0]-m[0][2]*m2[1][0]*m[1][1]-
+		    m[0][0]*m[1][2]*m2[1][1]+m[1][0]*m[0][2]*m2[1][1]+
+		    2.0*m[1][1]*m[0][0]*m2[1][2]-m[0][0]*m2[1][1]*m[2][1]+
+		    m[0][1]*m[2][0]*m2[1][1]-m2[1][0]*m[2][0]*m[1][1]-
+		    2.0*m[1][0]*m[0][1]*m2[1][2]+m[1][0]*m2[1][0]*m[2][1])/den;
+  
+  ans[2][0] = s[2]*(-m[1][1]*m[0][2]*m2[2][2]+m[0][1]*m[1][2]*m2[2][2]+
+		    2.0*m[1][1]*m2[2][0]*m[2][2]-m[0][1]*m2[2][1]*m[2][2]+
+		    m[0][2]*m[2][1]*m2[2][1]-2.0*m2[2][0]*m[2][1]*m[1][2]-
+		    m[1][0]*m2[2][1]*m[2][2]+m[1][2]*m[2][0]*m2[2][1]-
+		    m[1][1]*m[2][0]*m2[2][2]+m[2][1]*m[1][0]*m2[2][2])/den;
+  
+  ans[2][1] = s[2]*-(m[0][1]*m[2][2]*m2[2][0]-m[0][2]*m2[2][0]*m[2][1]-
+		     2.0*m2[2][1]*m[0][0]*m[2][2]+m[1][2]*m2[2][2]*m[0][0]+
+		     2.0*m2[2][1]*m[0][2]*m[2][0]+m[1][0]*m2[2][0]*m[2][2]-
+		     m[1][0]*m[0][2]*m2[2][2]-m[1][2]*m[2][0]*m2[2][0]+
+		     m[0][0]*m2[2][2]*m[2][1]-m2[2][2]*m[0][1]*m[2][0])/den;
+  
+  ans[2][2] = s[2]*(m[0][1]*m[1][2]*m2[2][0]-m[0][2]*m2[2][0]*m[1][1]-
+		    m[0][0]*m[1][2]*m2[2][1]+m[1][0]*m[0][2]*m2[2][1]-
+		    m[1][1]*m[2][0]*m2[2][0]-m[2][1]*m2[2][1]*m[0][0]+
+		    2.0*m[1][1]*m2[2][2]*m[0][0]+m[2][1]*m[1][0]*m2[2][0]+
+		    m[2][0]*m[0][1]*m2[2][1]-2.0*m2[2][2]*m[1][0]*m[0][1])/den;
+}
diff --git a/src/ASPHERE/pair_gayberne.h b/src/ASPHERE/pair_gayberne.h
new file mode 100755
index 0000000000000000000000000000000000000000..f2c262e7caa9910490fa03e321bdd3e6a14d5228
--- /dev/null
+++ b/src/ASPHERE/pair_gayberne.h
@@ -0,0 +1,57 @@
+/* ----------------------------------------------------------------------
+   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.
+------------------------------------------------------------------------- */
+
+#ifndef PAIR_GAYBERNE_H
+#define PAIR_GAYBERNE_H
+
+#include "pair.h"
+
+namespace LAMMPS_NS {
+
+class PairGayBerne : public Pair {
+ public:
+  PairGayBerne(LAMMPS *lmp);
+  ~PairGayBerne();
+  void compute(int, int);
+  void settings(int, char **);
+  void coeff(int, char **);
+  double init_one(int, int);
+  void init_style();
+  void write_restart(FILE *);
+  void read_restart(FILE *);
+  void write_restart_settings(FILE *);
+  void read_restart_settings(FILE *);
+
+ protected:
+  double cut_global;
+  double **cut;
+
+  double gamma,upsilon,mu;   // Gay-Berne parameters
+  double **shape;            // radii in x, y and z SQUARED
+  double *lshape;            // precalculation based on the shape
+  double **well;             // well depth scaling along each axis
+                             //   raised to -1.0/mu
+  double **epsi,**sig;       // epsilon and sigma values for atom-type pairs
+
+  void allocate();
+  double gayberne_analytic(const int i, const int j, double a1[3][3],
+                           double a2[3][3], double b1[3][3], double b2[3][3],
+                           double g1[3][3], double g2[3][3], double *r12, 
+                           const double rsq, double *fforce, double *ttor, 
+                           double *rtor);
+  void compute_eta_torque(double m[3][3], double m2[3][3],
+                          double *s, double ans[3][3]);
+};
+
+}
+#endif
diff --git a/src/ASPHERE/style_asphere.h b/src/ASPHERE/style_asphere.h
new file mode 100644
index 0000000000000000000000000000000000000000..f67f9033ee6e70a24aa638888bd17a288a4aa843
--- /dev/null
+++ b/src/ASPHERE/style_asphere.h
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------
+   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.
+------------------------------------------------------------------------- */
+
+#ifdef AtomInclude
+#include "atom_vec_ellipsoid.h"
+#endif
+
+#ifdef AtomClass
+AtomStyle(ellipsoid,AtomVecEllipsoid)
+# endif
+
+#ifdef ComputeInclude
+#include "compute_temp_asphere.h"
+#endif
+
+#ifdef ComputeClass
+ComputeStyle(temp/asphere,ComputeTempAsphere)
+#endif
+
+#ifdef FixInclude
+#include "fix_nve_asphere.h"
+#include "fix_nvt_asphere.h"
+#include "fix_npt_asphere.h"
+#endif
+
+#ifdef FixClass
+FixStyle(nve/asphere,FixNVEASphere)
+FixStyle(nvt/asphere,FixNVTASphere)
+FixStyle(npt/asphere,FixNPTASphere)
+#endif
+
+#ifdef PairInclude
+#include "pair_gayberne.h"
+#endif
+
+#ifdef PairClass
+PairStyle(gayberne,PairGayBerne)
+#endif
diff --git a/src/CLASS2/pair_lj_class2.cpp b/src/CLASS2/pair_lj_class2.cpp
index 093a6947fd16d9dd624f805050f3cfe7de496f24..18f0005e2f35081dcea198fed1b21a9b732f5816 100644
--- a/src/CLASS2/pair_lj_class2.cpp
+++ b/src/CLASS2/pair_lj_class2.cpp
@@ -123,21 +123,13 @@ void PairLJClass2::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/CLASS2/pair_lj_class2_coul_cut.cpp b/src/CLASS2/pair_lj_class2_coul_cut.cpp
index 7a8bf0b5b0489d5b71385b4980b81999a995d8ef..d8783b6af67e0a38eabe0957fb7987be3e7cfbbe 100644
--- a/src/CLASS2/pair_lj_class2_coul_cut.cpp
+++ b/src/CLASS2/pair_lj_class2_coul_cut.cpp
@@ -147,21 +147,13 @@ void PairLJClass2CoulCut::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -335,10 +327,8 @@ double PairLJClass2CoulCut::init_one(int i, int j)
 
 void PairLJClass2CoulCut::init_style()
 {
-  // require an atom style with charge defined
-
   if (atom->q == NULL)
-    error->all("Must use charged atom style with this pair style");
+    error->all("Pair style lj/class2/coul/cut requires atom attribute q");
 }
 
 /* ----------------------------------------------------------------------
diff --git a/src/CLASS2/pair_lj_class2_coul_long.cpp b/src/CLASS2/pair_lj_class2_coul_long.cpp
index 004c8b3640fb580e178996fee1b5f085ef4f4446..86f2c36ed0b28a48145685bef9db6b3d91340f86 100644
--- a/src/CLASS2/pair_lj_class2_coul_long.cpp
+++ b/src/CLASS2/pair_lj_class2_coul_long.cpp
@@ -164,21 +164,13 @@ void PairLJClass2CoulLong::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -341,10 +333,8 @@ double PairLJClass2CoulLong::init_one(int i, int j)
 
 void PairLJClass2CoulLong::init_style()
 {
-  // require an atom style with charge defined
-
   if (atom->q == NULL)
-    error->all("Must use charged atom style with this pair style");
+    error->all("Pair style lj/class2/coul/long requires atom attribute q");
 
   cut_coulsq = cut_coul * cut_coul;
 
diff --git a/src/DPD/atom_vec_dpd.cpp b/src/DPD/atom_vec_dpd.cpp
index f292e7f01d99cc2670257c9889ad9826bd8168e6..040e2e375a953bfdcd6a20eae794ef17fd6314cb 100644
--- a/src/DPD/atom_vec_dpd.cpp
+++ b/src/DPD/atom_vec_dpd.cpp
@@ -39,23 +39,6 @@ AtomVecDPD::AtomVecDPD(LAMMPS *lmp, int narg, char **arg) :
   xcol_data = 3;
 }
 
-/* ----------------------------------------------------------------------
-   zero auxiliary data for n ghost atoms
-   data in border(), not including x,tag,type,mask
-   grow() is here since zero_ghost called first in hybrid::unpack_border()
-------------------------------------------------------------------------- */
-
-void AtomVecDPD::zero_ghost(int n, int first)
-{
-  int last = first + n;
-  for (int i = first; i < last; i++) {
-    if (i == nmax) atom->avec->grow(0);
-    v[i][0] = 0.0;
-    v[i][1] = 0.0;
-    v[i][2] = 0.0;
-  }
-}
-
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDPD::pack_comm(int n, int *list, double *buf,
@@ -225,4 +208,3 @@ int AtomVecDPD::unpack_border_one(int i, double *buf)
   v[i][2] = buf[2];
   return 3;
 }
-
diff --git a/src/DPD/pair_dpd.cpp b/src/DPD/pair_dpd.cpp
index 0c226a756382f60ea32bde0011967ca471fd27b9..286963b42775dd4c41115903fb05d11a47336357 100644
--- a/src/DPD/pair_dpd.cpp
+++ b/src/DPD/pair_dpd.cpp
@@ -147,21 +147,13 @@ void PairDPD::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -277,14 +269,14 @@ double PairDPD::init_one(int i, int j)
 
 void PairDPD::init_style()
 {
-  // check that atom style is dpd
+  // check that atom style is dpd or hybrid with dpd
   // else compute() will not have ghost atom velocities
 
-  if (atom->check_style("dpd") == 0)
-    error->all("Must use atom style dpd with pair style dpd");
+  if (atom->style_match("dpd") == 0)
+    error->all("Pair style dpd requires atom style dpd");
 
   // if newton off, forces between atoms ij will be double computed
-  //   using different random numbers
+  // using different random numbers
 
   if (force->newton_pair == 0 && comm->me == 0) error->warning(
       "DPD potential needs newton pair on for momentum conservation");
diff --git a/src/GRANULAR/atom_vec_granular.cpp b/src/GRANULAR/atom_vec_granular.cpp
index 9bb5f055198e89866d87108bed2973efe6ec7bc2..f68d00412b14d97c76017070c5e817cd9f2726fe 100644
--- a/src/GRANULAR/atom_vec_granular.cpp
+++ b/src/GRANULAR/atom_vec_granular.cpp
@@ -87,66 +87,6 @@ void AtomVecGranular::grow(int n)
 
 /* ---------------------------------------------------------------------- */
 
-void AtomVecGranular::reset_ptrs()
-{
-  tag = atom->tag;
-  type = atom->type;
-  mask = atom->mask;
-  image = atom->image;
-  x = atom->x;
-  v = atom->v;
-  f = atom->f;
-
-  radius = atom->radius;
-  density = atom->density;
-  rmass = atom->rmass;
-  xphi = atom->xphi;
-  omega = atom->omega;
-  torque = atom->torque;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for owned atom I
-   data in copy(), not including tag,type,mask,image,x,v
-------------------------------------------------------------------------- */
-
-void AtomVecGranular::zero_owned(int i)
-{
-  radius[i] = 0.0;
-  density[i] = 0.0;
-  rmass[i] = 0.0;
-  xphi[i][0] = 0.0;
-  xphi[i][1] = 0.0;
-  xphi[i][2] = 0.0;
-  omega[i][0] = 0.0;
-  omega[i][1] = 0.0;
-  omega[i][2] = 0.0;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for n ghost atoms
-   data in border(), not including x,tag,type,mask
-   grow() is here since zero_ghost called first in hybrid::unpack_border()
-------------------------------------------------------------------------- */
-
-void AtomVecGranular::zero_ghost(int n, int first)
-{
-  int last = first + n;
-  for (int i = first; i < last; i++) {
-    if (i == nmax) atom->avec->grow(0);
-    v[i][0] = 0.0;
-    v[i][1] = 0.0;
-    v[i][2] = 0.0;
-    radius[i] = 0.0;
-    rmass[i] = 0.0;
-    omega[i][0] = 0.0;
-    omega[i][1] = 0.0;
-    omega[i][2] = 0.0;
-  }
-}
-
-/* ---------------------------------------------------------------------- */
-
 void AtomVecGranular::copy(int i, int j)
 {
   tag[j] = tag[i];
@@ -537,16 +477,6 @@ int AtomVecGranular::size_restart()
   return n;
 }
 
-/* ----------------------------------------------------------------------
-   size of restart data for atom I
-   do not include extra data stored by fixes, included by caller
-------------------------------------------------------------------------- */
-
-int AtomVecGranular::size_restart_one(int i)
-{
-  return 19;
-}
-
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
@@ -641,7 +571,7 @@ int AtomVecGranular::unpack_restart(double *buf)
    set other values to defaults
 ------------------------------------------------------------------------- */
 
-void AtomVecGranular::create_atom(int itype, double *coord, int ihybrid)
+void AtomVecGranular::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -679,8 +609,7 @@ void AtomVecGranular::create_atom(int itype, double *coord, int ihybrid)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecGranular::data_atom(double *coord, int imagetmp, char **values,
-				int ihybrid)
+void AtomVecGranular::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -722,15 +651,57 @@ void AtomVecGranular::data_atom(double *coord, int imagetmp, char **values,
 }
 
 /* ----------------------------------------------------------------------
-   unpack a single line from Velocity section of data file
+   unpack hybrid quantities from one line in Atoms section of data file
+   initialize other atom quantities for this sub-style
 ------------------------------------------------------------------------- */
 
-void AtomVecGranular::data_vel(int m, char *line, int ihybrid)
+int AtomVecGranular::data_atom_hybrid(int nlocal, char **values)
 {
-  int tmp;
-  sscanf(line,"%d %lg %lg %lg %lg %lg %lg",
-	 &tmp,&v[m][0],&v[m][1],&v[m][2],
-	 &omega[m][0],&omega[m][1],&omega[m][2]);
+  radius[nlocal] = 0.5 * atof(values[0]);
+  density[nlocal] = atof(values[1]);
+  if (force->dimension == 3)
+    rmass[nlocal] = 4.0*PI/3.0 *
+      radius[nlocal]*radius[nlocal]*radius[nlocal] * density[nlocal];
+  else
+    rmass[nlocal] = PI * radius[nlocal]*radius[nlocal] * density[nlocal];
+
+  v[nlocal][0] = 0.0;
+  v[nlocal][1] = 0.0;
+  v[nlocal][2] = 0.0;
+  xphi[nlocal][0] = 0.0;
+  xphi[nlocal][1] = 0.0;
+  xphi[nlocal][2] = 0.0;
+  omega[nlocal][0] = 0.0;
+  omega[nlocal][1] = 0.0;
+  omega[nlocal][2] = 0.0;
+
+  return 2;
+}
+
+/* ----------------------------------------------------------------------
+   unpack one line from Velocities section of data file
+------------------------------------------------------------------------- */
+
+void AtomVecGranular::data_vel(int m, char **values)
+{
+  v[m][0] = atof(values[0]);
+  v[m][1] = atof(values[1]);
+  v[m][2] = atof(values[2]);
+  omega[m][0] = atof(values[3]);
+  omega[m][1] = atof(values[4]);
+  omega[m][2] = atof(values[5]);
+}
+
+/* ----------------------------------------------------------------------
+   unpack hybrid quantities from one line in Velocities section of data file
+------------------------------------------------------------------------- */
+
+int AtomVecGranular::data_vel_hybrid(int m, char **values)
+{
+  omega[m][0] = atof(values[0]);
+  omega[m][1] = atof(values[1]);
+  omega[m][2] = atof(values[2]);
+  return 3;
 }
 
 /* ----------------------------------------------------------------------
diff --git a/src/GRANULAR/atom_vec_granular.h b/src/GRANULAR/atom_vec_granular.h
index 61e6d7d8f439a4e4c8fb060da3057704f5ac83b6..fc87ddf60b40b8718ecb6ad0fd2db2fd578de5f2 100644
--- a/src/GRANULAR/atom_vec_granular.h
+++ b/src/GRANULAR/atom_vec_granular.h
@@ -23,9 +23,6 @@ class AtomVecGranular : public AtomVec {
   AtomVecGranular(class LAMMPS *, int, char **);
   ~AtomVecGranular() {}
   void grow(int);
-  void reset_ptrs();
-  void zero_owned(int);
-  void zero_ghost(int, int);
   void copy(int, int);
   int pack_comm(int, int *, double *, int, int *);
   int pack_comm_one(int, double *);
@@ -42,12 +39,13 @@ class AtomVecGranular : public AtomVec {
   int pack_exchange(int, double *);
   int unpack_exchange(double *);
   int size_restart();
-  int size_restart_one(int);
   int pack_restart(int, double *);
   int unpack_restart(double *);
-  void create_atom(int, double *, int);
-  void data_atom(double *, int, char **, int);
-  void data_vel(int, char *, int);
+  void create_atom(int, double *);
+  void data_atom(double *, int, char **);
+  int data_atom_hybrid(int, char **);
+  void data_vel(int, char **);
+  int data_vel_hybrid(int, char **);
   int memory_usage();
 
  private:
diff --git a/src/GRANULAR/fix_freeze.cpp b/src/GRANULAR/fix_freeze.cpp
index 34e8a4014c1efaf068796e664f312041c1965382..cc5161c6f3b761e01452840b647ace24831f2940 100644
--- a/src/GRANULAR/fix_freeze.cpp
+++ b/src/GRANULAR/fix_freeze.cpp
@@ -27,8 +27,8 @@ FixFreeze::FixFreeze(LAMMPS *lmp, int narg, char **arg) :
 {
   if (narg != 3) error->all("Illegal fix freeze command");
 
-  if (atom->check_style("granular") == 0)
-    error->all("Must use fix freeze with atom style granular");
+  if (atom->torque == NULL)
+    error->all("Fix freeze requires atom attribute torque");
 }
 
 /* ---------------------------------------------------------------------- */
@@ -50,7 +50,7 @@ void FixFreeze::init()
   int count = 0;
   for (int i = 0; i < modify->nfix; i++)
     if (strcmp(modify->fix[i]->style,"freeze") == 0) count++;
-  if (count > 1) error->all("More than one freeze fix");
+  if (count > 1) error->all("More than one fix freeze");
 }
 
 /* ---------------------------------------------------------------------- */
diff --git a/src/GRANULAR/fix_gran_diag.cpp b/src/GRANULAR/fix_gran_diag.cpp
index f606d5ee204105b2a2d1181dd2db9cda68b7ba06..51a41e61b56c5cb41d7c274c8903c262f8ad5ac3 100644
--- a/src/GRANULAR/fix_gran_diag.cpp
+++ b/src/GRANULAR/fix_gran_diag.cpp
@@ -46,8 +46,8 @@ FixGranDiag::FixGranDiag(LAMMPS *lmp, int narg, char **arg) :
   if (nevery <= 0) error->all("Illegal fix gran/diag command");
   first = 1;
 
-  if (atom->check_style("granular") == 0)
-    error->all("Must use fix gran/diag with atom style granular");
+  if (atom->radius == NULL || atom->rmass == NULL || atom->omega == NULL)
+    error->all("Fix gran/diag requires atom attributes radius, rmass, omega");
 
   MPI_Comm_rank(world,&me);
   if (me == 0) {
diff --git a/src/GRANULAR/fix_nve_gran.cpp b/src/GRANULAR/fix_nve_gran.cpp
index 8febb2314505f0b4228f81293229d2fa34bb7d49..d9c6193bb362f4250d97d4caa07500eada7f9d2b 100644
--- a/src/GRANULAR/fix_nve_gran.cpp
+++ b/src/GRANULAR/fix_nve_gran.cpp
@@ -33,8 +33,9 @@ FixNVEGran::FixNVEGran(LAMMPS *lmp, int narg, char **arg) :
 {
   if (narg != 3) error->all("Illegal fix nve/gran command");
 
-  if (atom->check_style("granular") == 0)
-    error->all("Must use fix nve/gran with atom style granular");
+  if (atom->xphi == NULL || atom->omega == NULL || atom->torque == NULL)
+    error->all("Fix nve/gran requires atom attributes "
+	       "xphi, omega, torque");
 }
 
 /* ---------------------------------------------------------------------- */
diff --git a/src/GRANULAR/fix_pour.cpp b/src/GRANULAR/fix_pour.cpp
index a9f474769eb5e114d32704576b5b82ffcbec648c..4cdbda2074f1607cf2e0d29cdcf72ab811b0f48a 100644
--- a/src/GRANULAR/fix_pour.cpp
+++ b/src/GRANULAR/fix_pour.cpp
@@ -42,8 +42,10 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) :
 {
   if (narg < 6) error->all("Illegal fix pour command");
 
-  if (atom->check_style("granular") == 0)
-    error->all("Must use fix pour with atom style granular");
+  /*
+  if (atom->radius == NULL || atom->rmass == NULL)
+    error->all("Fix pour requires atom attributes radius, rmass");
+  */
 
   if (domain->triclinic) error->all("Cannot use fix pour with triclinic box");
 
@@ -71,10 +73,8 @@ FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) :
   while (iarg < narg) {
     if (strcmp(arg[iarg],"region") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix pour command");
-      for (iregion = 0; iregion < domain->nregion; iregion++)
-	if (strcmp(arg[iarg+1],domain->regions[iregion]->id) == 0) break;
-      if (iregion == domain->nregion) 
-	error->all("Fix pour region ID does not exist");
+      iregion = domain->find_region(arg[iarg+1]);
+      if (iregion == -1) error->all("Fix pour region ID does not exist");
       iarg += 2;
     } else if (strcmp(arg[iarg],"diam") == 0) {
       if (iarg+3 > narg) error->all("Illegal fix pour command");
@@ -455,7 +455,7 @@ void FixPour::pre_exchange()
 	     coord[0] >= sublo[0] && coord[0] < subhi[0]) flag = 1;
 
     if (flag) {
-      avec->create_atom(ntype,coord,0);
+      avec->create_atom(ntype,coord);
       m = atom->nlocal - 1;
       atom->type[m] = ntype;
       atom->radius[m] = radtmp;
diff --git a/src/GRANULAR/fix_wall_gran.cpp b/src/GRANULAR/fix_wall_gran.cpp
index a9d329f8d4a09266e18263dfea6757b42a63aecf..92f9126a1bdbb57bad6488e4ca6135b67b8c17d1 100644
--- a/src/GRANULAR/fix_wall_gran.cpp
+++ b/src/GRANULAR/fix_wall_gran.cpp
@@ -44,9 +44,9 @@ FixWallGran::FixWallGran(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 4) error->all("Illegal fix wall/gran command");
-  
-  if (atom->check_style("granular") == 0)
-    error->all("Must use fix wall/gran with atom style granular");
+
+  if (atom->radius == NULL || atom->omega == NULL || atom->torque == NULL)
+    error->all("Fix wall/gran requires atom attributes radius, omega, torque");
 
   restart_peratom = 1;
   
diff --git a/src/GRANULAR/pair_gran_history.cpp b/src/GRANULAR/pair_gran_history.cpp
index 8b6666212f6711430fc0a14bb23d206fafa6e1f5..ecf91bab8f51857e0bb790919983e0963af4d69e 100644
--- a/src/GRANULAR/pair_gran_history.cpp
+++ b/src/GRANULAR/pair_gran_history.cpp
@@ -325,6 +325,9 @@ void PairGranHistory::init_style()
 {
   int i;
 
+  if (atom->radius == NULL || atom->omega == NULL || atom->torque == NULL)
+    error->all("Pair granular requires atom attributes radius, omega, torque");
+
   xkkt = xkk * 2.0/7.0;
   dt = update->dt;
   double gammas = 0.5*gamman;
@@ -332,12 +335,6 @@ void PairGranHistory::init_style()
   gamman_dl = gamman/dt;
   gammas_dl = gammas/dt;
 
-  // check that atom style is granular
-  // else compute() will update illegal arrays
-
-  if (atom->check_style("granular") == 0)
-    error->all("Must use atom style granular with pair style granular");
-
   // if shear history is stored:
   // check if newton flag is valid
   // if first init, create Fix needed for storing shear history
diff --git a/src/KSPACE/pair_buck_coul_long.cpp b/src/KSPACE/pair_buck_coul_long.cpp
index 3d6710b1d67ea1e2d49b5ec5dc8746efb9b186b2..30a48bb2bd5e2829ae6d10f47b18c4801658c92c 100644
--- a/src/KSPACE/pair_buck_coul_long.cpp
+++ b/src/KSPACE/pair_buck_coul_long.cpp
@@ -164,21 +164,13 @@ void PairBuckCoulLong::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -308,10 +300,8 @@ double PairBuckCoulLong::init_one(int i, int j)
 
 void PairBuckCoulLong::init_style()
 {
-  // require an atom style with charge defined
-
   if (atom->q == NULL)
-    error->all("Must use charged atom style with this pair style");
+    error->all("Pair style buck/coul/long requires atom attribute q");
 
   cut_coulsq = cut_coul * cut_coul;
 
diff --git a/src/KSPACE/pair_lj_charmm_coul_long.cpp b/src/KSPACE/pair_lj_charmm_coul_long.cpp
index a0d3b40875638e152e8aa08e77c9d476f6b7da19..c64d69440562f6a221c154b93324eccb5c45704a 100644
--- a/src/KSPACE/pair_lj_charmm_coul_long.cpp
+++ b/src/KSPACE/pair_lj_charmm_coul_long.cpp
@@ -208,21 +208,13 @@ void PairLJCharmmCoulLong::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -614,22 +606,14 @@ void PairLJCharmmCoulLong::compute_outer(int eflag, int vflag)
 	  }
 	  
 	  fforce = (forcecoul + factor_lj*forcelj) * r2inv;
-	  
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -763,10 +747,8 @@ double PairLJCharmmCoulLong::init_one(int i, int j)
 
 void PairLJCharmmCoulLong::init_style()
 {
-  // require an atom style with charge defined
-
   if (atom->q == NULL)
-    error->all("Must use charged atom style with this pair style");
+    error->all("Pair style lj/charmm/coul/long requires atom attribute q");
 
   // require cut_lj_inner < cut_lj
 
diff --git a/src/KSPACE/pair_lj_cut_coul_long.cpp b/src/KSPACE/pair_lj_cut_coul_long.cpp
index 5b776d69c5f87e13b4c76e763b42a3afbeabdf86..f13f6368d59640a5416794978ce0ae10c0e2cf79 100644
--- a/src/KSPACE/pair_lj_cut_coul_long.cpp
+++ b/src/KSPACE/pair_lj_cut_coul_long.cpp
@@ -193,21 +193,13 @@ void PairLJCutCoulLong::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -562,22 +554,14 @@ void PairLJCutCoulLong::compute_outer(int eflag, int vflag)
 	    forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
 
           fforce = (forcecoul + factor_lj*forcelj) * r2inv;
-	  
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -737,10 +721,8 @@ void PairLJCutCoulLong::init_style()
 {
   int i,j;
 
-  // require an atom style with charge defined
-
   if (atom->q == NULL)
-    error->all("Must use charged atom style with this pair style");
+    error->all("Pair style lj/cut/coul/long requires atom attribute q");
 
   cut_coulsq = cut_coul * cut_coul;
 
diff --git a/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp b/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp
index 540f9d5d64c03011a878a90962cbb23717f8ebad..e994db763ba0fb6d74869ca2d44d5b5eaccf6e1d 100644
--- a/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp
+++ b/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp
@@ -411,7 +411,7 @@ void PairLJCutCoulLongTIP4P::init_style()
   if (!force->newton_pair) 
     error->all("Pair style lj/cut/coul/long/tip4p requires newton pair on");
   if (atom->q == NULL)
-    error->all("Must use charged atom style with this pair style");
+    error->all("Pair style lj/cut/coul/long/tip4p requires atom attribute q");
 
   cut_coulsq = cut_coul * cut_coul;
 
diff --git a/src/MANYBODY/Install.csh b/src/MANYBODY/Install.csh
index 3ac57d2ba8c130a5d5df9667ff17e1afdb5cd062..5cfed7a791b0b365fbdd66cd0e0ae2355e8a475e 100644
--- a/src/MANYBODY/Install.csh
+++ b/src/MANYBODY/Install.csh
@@ -4,12 +4,14 @@ if ($1 == 1) then
 
   cp style_manybody.h ..
 
+  cp pair_airebo.cpp ..
   cp pair_eam.cpp ..
   cp pair_eam_alloy.cpp ..
   cp pair_eam_fs.cpp ..
   cp pair_sw.cpp ..
   cp pair_tersoff.cpp ..
 
+  cp pair_airebo.h ..
   cp pair_eam.h ..
   cp pair_eam_alloy.h ..
   cp pair_eam_fs.h ..
@@ -21,12 +23,14 @@ else if ($1 == 0) then
   rm ../style_manybody.h
   touch ../style_manybody.h
 
+  rm ../pair_airebo.cpp
   rm ../pair_eam.cpp
   rm ../pair_eam_alloy.cpp
   rm ../pair_eam_fs.cpp
   rm ../pair_sw.cpp
   rm ../pair_tersoff.cpp
 
+  rm ../pair_airebo.h
   rm ../pair_eam.h
   rm ../pair_eam_alloy.h
   rm ../pair_eam_fs.h
diff --git a/src/MANYBODY/pair_eam.cpp b/src/MANYBODY/pair_eam.cpp
index 317d55be74c402e12e5bf9cf66fb0b03bd0bb423..5de299b8899137011f9835123ef848da765413f7 100644
--- a/src/MANYBODY/pair_eam.cpp
+++ b/src/MANYBODY/pair_eam.cpp
@@ -266,15 +266,15 @@ void PairEAM::compute(int eflag, int vflag)
 	phi = z2*recip;
 	phip = z2p*recip - phi*recip;
 	psip = fp[i]*rhojp + fp[j]*rhoip + phip;
-	fforce = psip*recip;
+	fforce = -psip*recip;
 
-	f[i][0] -= delx*fforce;
-	f[i][1] -= dely*fforce;
-	f[i][2] -= delz*fforce;
+	f[i][0] += delx*fforce;
+	f[i][1] += dely*fforce;
+	f[i][2] += delz*fforce;
 	if (newton_pair || j < nlocal) {
-	  f[j][0] += delx*fforce;
-	  f[j][1] += dely*fforce;
-	  f[j][2] += delz*fforce;
+	  f[j][0] -= delx*fforce;
+	  f[j][1] -= dely*fforce;
+	  f[j][2] -= delz*fforce;
 	}
 
 	if (eflag) {
@@ -283,21 +283,13 @@ void PairEAM::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] -= delx*delx*fforce;
-	    virial[1] -= dely*dely*fforce;
-	    virial[2] -= delz*delz*fforce;
-	    virial[3] -= delx*dely*fforce;
-	    virial[4] -= delx*delz*fforce;
-	    virial[5] -= dely*delz*fforce;
-	  } else {
-	    virial[0] -= 0.5*delx*delx*fforce;
-	    virial[1] -= 0.5*dely*dely*fforce;
-	    virial[2] -= 0.5*delz*delz*fforce;
-	    virial[3] -= 0.5*delx*dely*fforce;
-	    virial[4] -= 0.5*delx*delz*fforce;
-	    virial[5] -= 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/MANYBODY/style_manybody.h b/src/MANYBODY/style_manybody.h
index 449895a530bda93bceec6121c7916241778dad46..c564993e3e15f702de884738ddd93a4edb2350ac 100644
--- a/src/MANYBODY/style_manybody.h
+++ b/src/MANYBODY/style_manybody.h
@@ -12,6 +12,7 @@
 ------------------------------------------------------------------------- */
 
 #ifdef PairInclude
+#include "pair_airebo.h"
 #include "pair_eam.h"
 #include "pair_eam_alloy.h"
 #include "pair_eam_fs.h"
@@ -20,6 +21,7 @@
 #endif
 
 #ifdef PairClass
+PairStyle(airebo,PairAIREBO)
 PairStyle(eam,PairEAM)
 PairStyle(eam/alloy,PairEAMAlloy)
 PairStyle(eam/fs,PairEAMFS)
diff --git a/src/MOLECULE/atom_vec_angle.cpp b/src/MOLECULE/atom_vec_angle.cpp
index ad2243860deb9ab22b2d0d3f98ccc9b8db74831f..2b7296c718337dac429861b617b3f1250b4917af 100644
--- a/src/MOLECULE/atom_vec_angle.cpp
+++ b/src/MOLECULE/atom_vec_angle.cpp
@@ -108,59 +108,9 @@ void AtomVecAngle::grow(int n)
 
 /* ---------------------------------------------------------------------- */
 
-void AtomVecAngle::reset_ptrs()
+void AtomVecAngle::reset_special()
 {
-  tag = atom->tag;
-  type = atom->type;
-  mask = atom->mask;
-  image = atom->image;
-  x = atom->x;
-  v = atom->v;
-  f = atom->f;
-
-  molecule = atom->molecule;
-  nspecial = atom->nspecial;
   special = atom->special;
-
-  num_bond = atom->num_bond;
-  bond_type = atom->bond_type;
-  bond_atom = atom->bond_atom;
-
-  num_angle = atom->num_angle;
-  angle_type = atom->angle_type;
-  angle_atom1 = atom->angle_atom1;
-  angle_atom2 = atom->angle_atom2;
-  angle_atom3 = atom->angle_atom3;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for owned atom I
-   data in copy(), not including tag,type,mask,image,x,v
-------------------------------------------------------------------------- */
-
-void AtomVecAngle::zero_owned(int i)
-{
-  molecule[i] = 0;
-  num_bond[i] = 0;
-  num_angle[i] = 0;
-  nspecial[i][0] = 0;
-  nspecial[i][1] = 0;
-  nspecial[i][2] = 0;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for n ghost atoms
-   data in border(), not including x,tag,type,mask
-   grow() is here since zero_ghost called first in hybrid::unpack_border()
-------------------------------------------------------------------------- */
-
-void AtomVecAngle::zero_ghost(int n, int first)
-{
-  int last = first + n;
-  for (int i = first; i < last; i++) {
-    if (i == nmax) atom->avec->grow(0);
-    molecule[i] = 0;
-  }
 }
 
 /* ---------------------------------------------------------------------- */
@@ -492,17 +442,6 @@ int AtomVecAngle::size_restart()
   return n;
 }
 
-/* ----------------------------------------------------------------------
-   size of restart data for atom I
-   do not include extra data stored by fixes, included by caller
-------------------------------------------------------------------------- */
-
-int AtomVecAngle::size_restart_one(int i)
-{
-  int n = 14 + 2*num_bond[i] + 4*num_angle[i];
-  return n;
-}
-
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
@@ -609,7 +548,7 @@ int AtomVecAngle::unpack_restart(double *buf)
    set other values to defaults
 ------------------------------------------------------------------------- */
 
-void AtomVecAngle::create_atom(int itype, double *coord, int ihybrid)
+void AtomVecAngle::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -637,8 +576,7 @@ void AtomVecAngle::create_atom(int itype, double *coord, int ihybrid)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecAngle::data_atom(double *coord, int imagetmp, char **values,
-			     int ihybrid)
+void AtomVecAngle::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -669,6 +607,24 @@ void AtomVecAngle::data_atom(double *coord, int imagetmp, char **values,
   atom->nlocal++;
 }
 
+/* ----------------------------------------------------------------------
+   unpack hybrid quantities from one line in Atoms section of data file
+   initialize other atom quantities for this sub-style
+------------------------------------------------------------------------- */
+
+int AtomVecAngle::data_atom_hybrid(int nlocal, char **values)
+{
+  molecule[nlocal] = atoi(values[0]);
+
+  v[nlocal][0] = 0.0;
+  v[nlocal][1] = 0.0;
+  v[nlocal][2] = 0.0;
+  num_bond[nlocal] = 0;
+  num_angle[nlocal] = 0;
+
+  return 1;
+}
+
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
diff --git a/src/MOLECULE/atom_vec_angle.h b/src/MOLECULE/atom_vec_angle.h
index a1a5aea9257946d728be4f9baf29ab1c8965614b..b270ef168c35799b9f01626c1f582720cb4514da 100644
--- a/src/MOLECULE/atom_vec_angle.h
+++ b/src/MOLECULE/atom_vec_angle.h
@@ -22,9 +22,7 @@ class AtomVecAngle : public AtomVec {
  public:
   AtomVecAngle(class LAMMPS *, int, char **);
   void grow(int);
-  void reset_ptrs();
-  void zero_owned(int);
-  void zero_ghost(int, int);
+  void reset_special();
   void copy(int, int);
   int pack_comm(int, int *, double *, int, int *);
   void unpack_comm(int, int, double *);
@@ -37,11 +35,11 @@ class AtomVecAngle : public AtomVec {
   int pack_exchange(int, double *);
   int unpack_exchange(double *);
   int size_restart();
-  int size_restart_one(int);
   int pack_restart(int, double *);
   int unpack_restart(double *);
-  void create_atom(int, double *, int);
-  void data_atom(double *, int, char **, int);
+  void create_atom(int, double *);
+  void data_atom(double *, int, char **);
+  int data_atom_hybrid(int, char **);
   int memory_usage();
 
  private:
diff --git a/src/MOLECULE/atom_vec_bond.cpp b/src/MOLECULE/atom_vec_bond.cpp
index d276a7cea5c78ab5cc82c2a54b821fa688bf3bd7..a86afc3bab8d92067916f7c9e5406986fb8cc36e 100644
--- a/src/MOLECULE/atom_vec_bond.cpp
+++ b/src/MOLECULE/atom_vec_bond.cpp
@@ -92,52 +92,9 @@ void AtomVecBond::grow(int n)
 
 /* ---------------------------------------------------------------------- */
 
-void AtomVecBond::reset_ptrs()
+void AtomVecBond::reset_special()
 {
-  tag = atom->tag;
-  type = atom->type;
-  mask = atom->mask;
-  image = atom->image;
-  x = atom->x;
-  v = atom->v;
-  f = atom->f;
-
-  molecule = atom->molecule;
-  nspecial = atom->nspecial;
   special = atom->special;
-
-  num_bond = atom->num_bond;
-  bond_type = atom->bond_type;
-  bond_atom = atom->bond_atom;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for owned atom I
-   data in copy(), not including tag,type,mask,image,x,v
-------------------------------------------------------------------------- */
-
-void AtomVecBond::zero_owned(int i)
-{
-  molecule[i] = 0;
-  num_bond[i] = 0;
-  nspecial[i][0] = 0;
-  nspecial[i][1] = 0;
-  nspecial[i][2] = 0;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for n ghost atoms
-   data in border(), not including x,tag,type,mask
-   grow() is here since zero_ghost called first in hybrid::unpack_border()
-------------------------------------------------------------------------- */
-
-void AtomVecBond::zero_ghost(int n, int first)
-{
-  int last = first + n;
-  for (int i = first; i < last; i++) {
-    if (i == nmax) atom->avec->grow(0);
-    molecule[i] = 0;
-  }
 }
 
 /* ---------------------------------------------------------------------- */
@@ -445,17 +402,6 @@ int AtomVecBond::size_restart()
   return n;
 }
 
-/* ----------------------------------------------------------------------
-   size of restart data for atom I
-   do not include extra data stored by fixes, included by caller
-------------------------------------------------------------------------- */
-
-int AtomVecBond::size_restart_one(int i)
-{
-  int n = 13 + 2*num_bond[i];
-  return n;
-}
-
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
@@ -546,7 +492,7 @@ int AtomVecBond::unpack_restart(double *buf)
    set other values to defaults
 ------------------------------------------------------------------------- */
 
-void AtomVecBond::create_atom(int itype, double *coord, int ihybrid)
+void AtomVecBond::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -573,8 +519,7 @@ void AtomVecBond::create_atom(int itype, double *coord, int ihybrid)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecBond::data_atom(double *coord, int imagetmp, char **values,
-			      int ihybrid)
+void AtomVecBond::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -604,6 +549,23 @@ void AtomVecBond::data_atom(double *coord, int imagetmp, char **values,
   atom->nlocal++;
 }
 
+/* ----------------------------------------------------------------------
+   unpack hybrid quantities from one line in Atoms section of data file
+   initialize other atom quantities for this sub-style
+------------------------------------------------------------------------- */
+
+int AtomVecBond::data_atom_hybrid(int nlocal, char **values)
+{
+  molecule[nlocal] = atoi(values[0]);
+
+  v[nlocal][0] = 0.0;
+  v[nlocal][1] = 0.0;
+  v[nlocal][2] = 0.0;
+  num_bond[nlocal] = 0;
+
+  return 1;
+}
+
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
diff --git a/src/MOLECULE/atom_vec_bond.h b/src/MOLECULE/atom_vec_bond.h
index a5c5c77cb2bfac145f551895ea8f6bc2e6cc1d20..ddac9848a07a642d613c57ac7af33b01fed32876 100644
--- a/src/MOLECULE/atom_vec_bond.h
+++ b/src/MOLECULE/atom_vec_bond.h
@@ -22,9 +22,7 @@ class AtomVecBond : public AtomVec {
  public:
   AtomVecBond(class LAMMPS *, int, char **);
   void grow(int);
-  void reset_ptrs();
-  void zero_owned(int);
-  void zero_ghost(int, int);
+  void reset_special();
   void copy(int, int);
   int pack_comm(int, int *, double *, int, int *);
   void unpack_comm(int, int, double *);
@@ -37,11 +35,11 @@ class AtomVecBond : public AtomVec {
   int pack_exchange(int, double *);
   int unpack_exchange(double *);
   int size_restart();
-  int size_restart_one(int);
   int pack_restart(int, double *);
   int unpack_restart(double *);
-  void create_atom(int, double *, int);
-  void data_atom(double *, int, char **, int);
+  void create_atom(int, double *);
+  void data_atom(double *, int, char **);
+  int data_atom_hybrid(int, char **);
   int memory_usage();
 
  private:
diff --git a/src/MOLECULE/atom_vec_full.cpp b/src/MOLECULE/atom_vec_full.cpp
index 4ae64fb7a5f2aeacd0c8911849e91f74a19143fe..5595849688f10d22e84780e6154eb94abc63a41f 100644
--- a/src/MOLECULE/atom_vec_full.cpp
+++ b/src/MOLECULE/atom_vec_full.cpp
@@ -148,78 +148,9 @@ void AtomVecFull::grow(int n)
 
 /* ---------------------------------------------------------------------- */
 
-void AtomVecFull::reset_ptrs()
+void AtomVecFull::reset_special()
 {
-  tag = atom->tag;
-  type = atom->type;
-  mask = atom->mask;
-  image = atom->image;
-  x = atom->x;
-  v = atom->v;
-  f = atom->f;
-
-  q = atom->q;
-  molecule = atom->molecule;
-  nspecial = atom->nspecial;
   special = atom->special;
-  
-  num_bond = atom->num_bond;
-  bond_type = atom->bond_type;
-  bond_atom = atom->bond_atom;
-
-  num_angle = atom->num_angle;
-  angle_type = atom->angle_type;
-  angle_atom1 = atom->angle_atom1;
-  angle_atom2 = atom->angle_atom2;
-  angle_atom3 = atom->angle_atom3;
-
-  num_dihedral = atom->num_dihedral;
-  dihedral_type = atom->dihedral_type;
-  dihedral_atom1 = atom->dihedral_atom1;
-  dihedral_atom2 = atom->dihedral_atom2;
-  dihedral_atom3 = atom->dihedral_atom3;
-  dihedral_atom4 = atom->dihedral_atom4;
-
-  num_improper = atom->num_improper;
-  improper_type = atom->improper_type;
-  improper_atom1 = atom->improper_atom1;
-  improper_atom2 = atom->improper_atom2;
-  improper_atom3 = atom->improper_atom3;
-  improper_atom4 = atom->improper_atom4;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for owned atom I
-   data in copy(), not including tag,type,mask,image,x,v
-------------------------------------------------------------------------- */
-
-void AtomVecFull::zero_owned(int i)
-{
-  q[i] = 0.0;
-  molecule[i] = 0;
-  num_bond[i] = 0;
-  num_angle[i] = 0;
-  num_dihedral[i] = 0;
-  num_improper[i] = 0;
-  nspecial[i][0] = 0;
-  nspecial[i][1] = 0;
-  nspecial[i][2] = 0;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for n ghost atoms
-   data in border(), not including x,tag,type,mask
-   grow() is here since zero_ghost called first in hybrid::unpack_border()
-------------------------------------------------------------------------- */
-
-void AtomVecFull::zero_ghost(int n, int first)
-{
-  int last = first + n;
-  for (int i = first; i < last; i++) {
-    if (i == nmax) atom->avec->grow(0);
-    q[i] = 0.0;
-    molecule[i] = 0;
-  }
 }
 
 /* ---------------------------------------------------------------------- */
@@ -614,18 +545,6 @@ int AtomVecFull::size_restart()
   return n;
 }
 
-/* ----------------------------------------------------------------------
-   size of restart data for atom I
-   do not include extra data stored by fixes, included by caller
-------------------------------------------------------------------------- */
-
-int AtomVecFull::size_restart_one(int i)
-{
-  int n = 17 + 2*num_bond[i] + 4*num_angle[i] + 
-    5*num_dihedral[i] + 5*num_improper[i];
-  return n;
-}
-
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
@@ -770,7 +689,7 @@ int AtomVecFull::unpack_restart(double *buf)
    set other values to defaults
 ------------------------------------------------------------------------- */
 
-void AtomVecFull::create_atom(int itype, double *coord, int ihybrid)
+void AtomVecFull::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -801,8 +720,7 @@ void AtomVecFull::create_atom(int itype, double *coord, int ihybrid)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecFull::data_atom(double *coord, int imagetmp, char **values,
-			    int ihybrid)
+void AtomVecFull::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -837,6 +755,27 @@ void AtomVecFull::data_atom(double *coord, int imagetmp, char **values,
   atom->nlocal++;
 }
 
+/* ----------------------------------------------------------------------
+   unpack hybrid quantities from one line in Atoms section of data file
+   initialize other atom quantities for this sub-style
+------------------------------------------------------------------------- */
+
+int AtomVecFull::data_atom_hybrid(int nlocal, char **values)
+{
+  molecule[nlocal] = atoi(values[1]);
+  q[nlocal] = atof(values[3]);
+
+  v[nlocal][0] = 0.0;
+  v[nlocal][1] = 0.0;
+  v[nlocal][2] = 0.0;
+  num_bond[nlocal] = 0;
+  num_angle[nlocal] = 0;
+  num_dihedral[nlocal] = 0;
+  num_improper[nlocal] = 0;
+
+  return 2;
+}
+
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
diff --git a/src/MOLECULE/atom_vec_full.h b/src/MOLECULE/atom_vec_full.h
index 22a35091d2f0c6f61d08f90994bbd52892f7e13f..5e384fe98b4bd82a3683b8a023bfae0bdb6eda69 100644
--- a/src/MOLECULE/atom_vec_full.h
+++ b/src/MOLECULE/atom_vec_full.h
@@ -22,9 +22,7 @@ class AtomVecFull : public AtomVec {
  public:
   AtomVecFull(class LAMMPS *, int, char **);
   void grow(int);
-  void reset_ptrs();
-  void zero_owned(int);
-  void zero_ghost(int, int);
+  void reset_special();
   void copy(int, int);
   int pack_comm(int, int *, double *, int, int *);
   void unpack_comm(int, int, double *);
@@ -37,11 +35,11 @@ class AtomVecFull : public AtomVec {
   int pack_exchange(int, double *);
   int unpack_exchange(double *);
   int size_restart();
-  int size_restart_one(int);
   int pack_restart(int, double *);
   int unpack_restart(double *);
-  void create_atom(int, double *, int);
-  void data_atom(double *, int, char **, int);
+  void create_atom(int, double *);
+  void data_atom(double *, int, char **);
+  int data_atom_hybrid(int, char **);
   int memory_usage();
 
  private:
diff --git a/src/MOLECULE/atom_vec_molecular.cpp b/src/MOLECULE/atom_vec_molecular.cpp
index 8cb26b1033c54ee34089b74a6e19c10019e590d0..489d009ef8adb5bc04bc6311744dcebaa8fbe15d 100644
--- a/src/MOLECULE/atom_vec_molecular.cpp
+++ b/src/MOLECULE/atom_vec_molecular.cpp
@@ -146,75 +146,9 @@ void AtomVecMolecular::grow(int n)
 
 /* ---------------------------------------------------------------------- */
 
-void AtomVecMolecular::reset_ptrs()
+void AtomVecMolecular::reset_special()
 {
-  tag = atom->tag;
-  type = atom->type;
-  mask = atom->mask;
-  image = atom->image;
-  x = atom->x;
-  v = atom->v;
-  f = atom->f;
-
-  molecule = atom->molecule;
-  nspecial = atom->nspecial;
   special = atom->special;
-  
-  num_bond = atom->num_bond;
-  bond_type = atom->bond_type;
-  bond_atom = atom->bond_atom;
-
-  num_angle = atom->num_angle;
-  angle_type = atom->angle_type;
-  angle_atom1 = atom->angle_atom1;
-  angle_atom2 = atom->angle_atom2;
-  angle_atom3 = atom->angle_atom3;
-
-  num_dihedral = atom->num_dihedral;
-  dihedral_type = atom->dihedral_type;
-  dihedral_atom1 = atom->dihedral_atom1;
-  dihedral_atom2 = atom->dihedral_atom2;
-  dihedral_atom3 = atom->dihedral_atom3;
-  dihedral_atom4 = atom->dihedral_atom4;
-
-  num_improper = atom->num_improper;
-  improper_type = atom->improper_type;
-  improper_atom1 = atom->improper_atom1;
-  improper_atom2 = atom->improper_atom2;
-  improper_atom3 = atom->improper_atom3;
-  improper_atom4 = atom->improper_atom4;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for owned atom I
-   data in copy(), not including tag,type,mask,image,x,v
-------------------------------------------------------------------------- */
-
-void AtomVecMolecular::zero_owned(int i)
-{
-  molecule[i] = 0;
-  num_bond[i] = 0;
-  num_angle[i] = 0;
-  num_dihedral[i] = 0;
-  num_improper[i] = 0;
-  nspecial[i][0] = 0;
-  nspecial[i][1] = 0;
-  nspecial[i][2] = 0;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for n ghost atoms
-   data in border(), not including x,tag,type,mask
-   grow() is here since zero_ghost called first in hybrid::unpack_border()
-------------------------------------------------------------------------- */
-
-void AtomVecMolecular::zero_ghost(int n, int first)
-{
-  int last = first + n;
-  for (int i = first; i < last; i++) {
-    if (i == nmax) atom->avec->grow(0);
-    molecule[i] = 0;
-  }
 }
 
 /* ---------------------------------------------------------------------- */
@@ -601,18 +535,6 @@ int AtomVecMolecular::size_restart()
   return n;
 }
 
-/* ----------------------------------------------------------------------
-   size of restart data for atom I
-   do not include extra data stored by fixes, included by caller
-------------------------------------------------------------------------- */
-
-int AtomVecMolecular::size_restart_one(int i)
-{
-  int n = 16 + 2*num_bond[i] + 4*num_angle[i] + 
-    5*num_dihedral[i] + 5*num_improper[i];
-  return n;
-}
-
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
@@ -755,7 +677,7 @@ int AtomVecMolecular::unpack_restart(double *buf)
    set other values to defaults
 ------------------------------------------------------------------------- */
 
-void AtomVecMolecular::create_atom(int itype, double *coord, int ihybrid)
+void AtomVecMolecular::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -785,8 +707,7 @@ void AtomVecMolecular::create_atom(int itype, double *coord, int ihybrid)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecMolecular::data_atom(double *coord, int imagetmp, char **values,
-				 int ihybrid)
+void AtomVecMolecular::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -819,6 +740,26 @@ void AtomVecMolecular::data_atom(double *coord, int imagetmp, char **values,
   atom->nlocal++;
 }
 
+/* ----------------------------------------------------------------------
+   unpack hybrid quantities from one line in Atoms section of data file
+   initialize other atom quantities for this sub-style
+------------------------------------------------------------------------- */
+
+int AtomVecMolecular::data_atom_hybrid(int nlocal, char **values)
+{
+  molecule[nlocal] = atoi(values[0]);
+
+  v[nlocal][0] = 0.0;
+  v[nlocal][1] = 0.0;
+  v[nlocal][2] = 0.0;
+  num_bond[nlocal] = 0;
+  num_angle[nlocal] = 0;
+  num_dihedral[nlocal] = 0;
+  num_improper[nlocal] = 0;
+
+  return 1;
+}
+
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
diff --git a/src/MOLECULE/atom_vec_molecular.h b/src/MOLECULE/atom_vec_molecular.h
index c436afa45c0180c972f377242c74d54be70c4893..8b1eeaf9292599990e84e16ada1aa6ffc06aa844 100644
--- a/src/MOLECULE/atom_vec_molecular.h
+++ b/src/MOLECULE/atom_vec_molecular.h
@@ -22,9 +22,7 @@ class AtomVecMolecular : public AtomVec {
  public:
   AtomVecMolecular(class LAMMPS *, int, char **);
   void grow(int);
-  void reset_ptrs();
-  void zero_owned(int);
-  void zero_ghost(int, int);
+  void reset_special();
   void copy(int, int);
   int pack_comm(int, int *, double *, int, int *);
   void unpack_comm(int, int, double *);
@@ -37,11 +35,11 @@ class AtomVecMolecular : public AtomVec {
   int pack_exchange(int, double *);
   int unpack_exchange(double *);
   int size_restart();
-  int size_restart_one(int);
   int pack_restart(int, double *);
   int unpack_restart(double *);
-  void create_atom(int, double *, int);
-  void data_atom(double *, int, char **, int);
+  void create_atom(int, double *);
+  void data_atom(double *, int, char **);
+  int data_atom_hybrid(int, char **);
   int memory_usage();
 
  private:
diff --git a/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp b/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp
index 2dc98fa4bd6e887f9551270c950968af5e2ee779..aed79757d44524f509aa38b7e6ffb829a8fd6065 100644
--- a/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp
+++ b/src/MOLECULE/pair_lj_charmm_coul_charmm.cpp
@@ -175,21 +175,13 @@ void PairLJCharmmCoulCharmm::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -331,10 +323,8 @@ double PairLJCharmmCoulCharmm::init_one(int i, int j)
 
 void PairLJCharmmCoulCharmm::init_style()
 {
-  // require an atom style with charge defined
-
   if (atom->q == NULL)
-    error->all("Must use charged atom style with this pair style");
+    error->all("Pair style lj/charmm/coul/charmm requires atom attribute q");
 
   // require cut_lj_inner < cut_lj, cut_coul_inner < cut_coul
 
diff --git a/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.cpp b/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.cpp
index 6c0743cdccbf9979e1e02a3e11f0db121eda370a..422c4b50755931a383378d5a432bee7baa67df5a 100644
--- a/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.cpp
+++ b/src/MOLECULE/pair_lj_charmm_coul_charmm_implicit.cpp
@@ -141,21 +141,13 @@ void PairLJCharmmCoulCharmmImplicit::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/Makefile b/src/Makefile
index 6b4ad3f36f9c02f450b40575178d13f7a552bb7e..84748319a4d4525a9b781d8c3f2ad397b6009151 100755
--- a/src/Makefile
+++ b/src/Makefile
@@ -43,21 +43,23 @@ makelist:
 
 package:
 	@echo 'Available packages:'
-	@echo '  class2, dpd, granular, kspace, manybody,'
-	@echo '  meam, molecule, opt, poems, xtc'
+	@echo '  asphere, class2, colloid, dipole, dpd, granular,'
+	@echo '  kspace, manybody, meam, molecule, opt, poems, xtc'
 	@echo 'make yes-name     to include a package'
 	@echo 'make no-name      to exclude a package'
 	@echo 'make yes-all      to include all packages'
 	@echo 'make no-all       to exclude all packages'
 
 yes-all:
-	make yes-class2 yes-dpd yes-granular yes-kspace \
-	yes-manybody yes-meam yes-molecule yes-opt yes-poems yes-xtc
+	make yes-asphere yes-class2 yes-colloid yes-dpd yes-granular \
+	yes-kspace yes-manybody yes-meam yes-molecule yes-opt yes-poems yes-xtc
 
 no-all:
 	@echo 'Removing files, ignore any rm errors ...'
-#	@cd ASPHERE; csh -f Install.csh 0
+	@cd ASPHERE; csh -f Install.csh 0
 	@cd CLASS2; csh -f Install.csh 0
+	@cd COLLOID; csh -f Install.csh 0
+	@cd DIPOLE; csh -f Install.csh 0
 	@cd DPD; csh -f Install.csh 0
 	@cd GRANULAR; csh -f Install.csh 0
 	@cd KSPACE; csh -f Install.csh 0
@@ -69,12 +71,12 @@ no-all:
 	@cd XTC; csh -f Install.csh 0
 	@make clean
 
-#yes-asphere:
-#	@cd ASPHERE; csh -f Install.csh 1
-#no-asphere:
-#	@echo 'Removing files, ignore any rm errors ...'
-#	@cd ASPHERE; csh -f Install.csh 0
-#	@make clean
+yes-asphere:
+	@cd ASPHERE; csh -f Install.csh 1
+no-asphere:
+	@echo 'Removing files, ignore any rm errors ...'
+	@cd ASPHERE; csh -f Install.csh 0
+	@make clean
 
 yes-class2:
 	@cd CLASS2; csh -f Install.csh 1
@@ -83,6 +85,20 @@ no-class2:
 	@cd CLASS2; csh -f Install.csh 0
 	@make clean
 
+yes-colloid:
+	@cd COLLOID; csh -f Install.csh 1
+no-colloid:
+	@echo 'Removing files, ignore any rm errors ...'
+	@cd COLLOID; csh -f Install.csh 0
+	@make clean
+
+yes-dipole:
+	@cd DIPOLE; csh -f Install.csh 1
+no-dipole:
+	@echo 'Removing files, ignore any rm errors ...'
+	@cd DIPOLE; csh -f Install.csh 0
+	@make clean
+
 yes-dpd:
 	@cd DPD; csh -f Install.csh 1
 no-dpd:
@@ -149,8 +165,10 @@ no-xtc:
 # update src files with package files
 
 package-update:
-#	@csh -f Package.csh ASPHERE update
+	@csh -f Package.csh ASPHERE update
 	@csh -f Package.csh CLASS2 update
+	@csh -f Package.csh COLLOID update
+	@csh -f Package.csh DIPOLE update
 	@csh -f Package.csh DPD update
 	@csh -f Package.csh GRANULAR update
 	@csh -f Package.csh KSPACE update
@@ -164,8 +182,10 @@ package-update:
 # overwrite package files with src files
 
 package-overwrite:
-#	@csh -f Package.csh ASPHERE overwrite
+	@csh -f Package.csh ASPHERE overwrite
 	@csh -f Package.csh CLASS2 overwrite
+	@csh -f Package.csh COLLOID overwrite
+	@csh -f Package.csh DIPOLE overwrite
 	@csh -f Package.csh DPD overwrite
 	@csh -f Package.csh GRANULAR overwrite
 	@csh -f Package.csh KSPACE overwrite
@@ -179,8 +199,10 @@ package-overwrite:
 # check differences between src and pacakge files
 
 package-check:
-#	@csh -f Package.csh ASPHERE check
+	@csh -f Package.csh ASPHERE check
 	@csh -f Package.csh CLASS2 check
+	@csh -f Package.csh COLLOID check
+	@csh -f Package.csh DIPOLE check
 	@csh -f Package.csh DPD check
 	@csh -f Package.csh GRANULAR check
 	@csh -f Package.csh KSPACE check
diff --git a/src/Makefile.lib b/src/Makefile.lib
index 2ff8e80688bccf5d7633cb124c869c1a55bab8da..7aa15204e9f1063864612c6b8c65939796c6ad37 100644
--- a/src/Makefile.lib
+++ b/src/Makefile.lib
@@ -7,9 +7,9 @@ SHELL = /bin/sh
 ROOT =	lmp
 EXE =	lib$(ROOT)_$@.a
 
-SRC =	angle.cpp angle_charmm.cpp angle_cosine.cpp angle_cosine_squared.cpp angle_harmonic.cpp angle_hybrid.cpp atom.cpp atom_vec.cpp atom_vec_angle.cpp atom_vec_atomic.cpp atom_vec_bond.cpp atom_vec_charge.cpp atom_vec_full.cpp atom_vec_hybrid.cpp atom_vec_molecular.cpp bond.cpp bond_fene.cpp bond_fene_expand.cpp bond_harmonic.cpp bond_hybrid.cpp bond_morse.cpp bond_nonlinear.cpp bond_quartic.cpp comm.cpp compute.cpp compute_centro_atom.cpp compute_epair_atom.cpp compute_etotal_atom.cpp compute_ke_atom.cpp compute_pressure.cpp compute_rotate_dipole.cpp compute_rotate_gran.cpp compute_stress_atom.cpp compute_temp.cpp compute_temp_partial.cpp compute_temp_ramp.cpp compute_temp_region.cpp create_atoms.cpp create_box.cpp delete_atoms.cpp delete_bonds.cpp dihedral.cpp dihedral_charmm.cpp dihedral_harmonic.cpp dihedral_helix.cpp dihedral_hybrid.cpp dihedral_multi_harmonic.cpp dihedral_opls.cpp displace_atoms.cpp domain.cpp dump.cpp dump_atom.cpp dump_bond.cpp dump_custom.cpp dump_dcd.cpp dump_xyz.cpp error.cpp ewald.cpp fft3d.cpp fft3d_wrap.cpp finish.cpp fix.cpp fix_add_force.cpp fix_ave_force.cpp fix_com.cpp fix_deposit.cpp fix_drag.cpp fix_efield.cpp fix_enforce2d.cpp fix_gravity.cpp fix_gyration.cpp fix_indent.cpp fix_langevin.cpp fix_line_force.cpp fix_minimize.cpp fix_momentum.cpp fix_msd.cpp fix_nph.cpp fix_npt.cpp fix_nve.cpp fix_nvt.cpp fix_orient_fcc.cpp fix_plane_force.cpp fix_print.cpp fix_rdf.cpp fix_recenter.cpp fix_respa.cpp fix_rigid.cpp fix_set_force.cpp fix_shake.cpp fix_shear_history.cpp fix_spring.cpp fix_spring_rg.cpp fix_spring_self.cpp fix_temp_rescale.cpp fix_tmd.cpp fix_uniaxial.cpp fix_viscous.cpp fix_volume_rescale.cpp fix_wall_lj126.cpp fix_wall_lj93.cpp fix_wall_reflect.cpp fix_wiggle.cpp force.cpp group.cpp improper.cpp improper_cvff.cpp improper_harmonic.cpp improper_hybrid.cpp input.cpp kspace.cpp lammps.cpp lattice.cpp library.cpp memory.cpp min.cpp min_cg.cpp min_cg_fr.cpp min_sd.cpp minimize.cpp modify.cpp neigh_bond.cpp neigh_full.cpp neigh_gran.cpp neigh_half.cpp neigh_respa.cpp neighbor.cpp output.cpp pack.cpp pair.cpp pair_buck.cpp pair_buck_coul_cut.cpp pair_buck_coul_long.cpp pair_eam.cpp pair_eam_alloy.cpp pair_eam_fs.cpp pair_hybrid.cpp pair_lj_charmm_coul_charmm.cpp pair_lj_charmm_coul_charmm_implicit.cpp pair_lj_charmm_coul_long.cpp pair_lj_cut.cpp pair_lj_cut_coul_cut.cpp pair_lj_cut_coul_debye.cpp pair_lj_cut_coul_long.cpp pair_lj_cut_coul_long_tip4p.cpp pair_lj_expand.cpp pair_lj_smooth.cpp pair_morse.cpp pair_soft.cpp pair_sw.cpp pair_table.cpp pair_tersoff.cpp pair_yukawa.cpp pppm.cpp pppm_tip4p.cpp random_mars.cpp random_park.cpp read_data.cpp read_restart.cpp region.cpp region_block.cpp region_cylinder.cpp region_intersect.cpp region_prism.cpp region_sphere.cpp region_union.cpp remap.cpp remap_wrap.cpp replicate.cpp respa.cpp run.cpp set.cpp shell.cpp special.cpp temper.cpp thermo.cpp timer.cpp universe.cpp update.cpp variable.cpp velocity.cpp verlet.cpp write_restart.cpp
+SRC =	angle.cpp angle_charmm.cpp angle_class2.cpp angle_cosine.cpp angle_cosine_squared.cpp angle_harmonic.cpp angle_hybrid.cpp atom.cpp atom_vec.cpp atom_vec_angle.cpp atom_vec_atomic.cpp atom_vec_bond.cpp atom_vec_charge.cpp atom_vec_dpd.cpp atom_vec_ellipsoid.cpp atom_vec_full.cpp atom_vec_granular.cpp atom_vec_hybrid.cpp atom_vec_molecular.cpp bond.cpp bond_class2.cpp bond_fene.cpp bond_fene_expand.cpp bond_harmonic.cpp bond_hybrid.cpp bond_morse.cpp bond_nonlinear.cpp bond_quartic.cpp comm.cpp compute.cpp compute_centro_atom.cpp compute_coord_atom.cpp compute_epair_atom.cpp compute_etotal_atom.cpp compute_ke_atom.cpp compute_pressure.cpp compute_rotate_dipole.cpp compute_rotate_gran.cpp compute_stress_atom.cpp compute_temp.cpp compute_temp_asphere.cpp compute_temp_partial.cpp compute_temp_ramp.cpp compute_temp_region.cpp compute_variable.cpp compute_variable_atom.cpp create_atoms.cpp create_box.cpp delete_atoms.cpp delete_bonds.cpp dihedral.cpp dihedral_charmm.cpp dihedral_class2.cpp dihedral_harmonic.cpp dihedral_helix.cpp dihedral_hybrid.cpp dihedral_multi_harmonic.cpp dihedral_opls.cpp displace_atoms.cpp domain.cpp dump.cpp dump_atom.cpp dump_bond.cpp dump_custom.cpp dump_dcd.cpp dump_xtc.cpp dump_xyz.cpp error.cpp ewald.cpp fft3d.cpp fft3d_wrap.cpp finish.cpp fix.cpp fix_add_force.cpp fix_ave_force.cpp fix_ave_spatial.cpp fix_ave_time.cpp fix_com.cpp fix_deposit.cpp fix_drag.cpp fix_efield.cpp fix_enforce2d.cpp fix_freeze.cpp fix_gran_diag.cpp fix_gravity.cpp fix_gyration.cpp fix_heat.cpp fix_indent.cpp fix_langevin.cpp fix_line_force.cpp fix_minimize.cpp fix_momentum.cpp fix_msd.cpp fix_nph.cpp fix_npt.cpp fix_npt_asphere.cpp fix_nve.cpp fix_nve_asphere.cpp fix_nve_gran.cpp fix_nve_noforce.cpp fix_nvt.cpp fix_nvt_asphere.cpp fix_orient_fcc.cpp fix_plane_force.cpp fix_pour.cpp fix_print.cpp fix_rdf.cpp fix_recenter.cpp fix_respa.cpp fix_rigid.cpp fix_set_force.cpp fix_shake.cpp fix_shear_history.cpp fix_spring.cpp fix_spring_rg.cpp fix_spring_self.cpp fix_temp_rescale.cpp fix_tmd.cpp fix_uniaxial.cpp fix_viscous.cpp fix_volume_rescale.cpp fix_wall_gran.cpp fix_wall_lj126.cpp fix_wall_lj93.cpp fix_wall_reflect.cpp fix_wiggle.cpp force.cpp group.cpp improper.cpp improper_class2.cpp improper_cvff.cpp improper_harmonic.cpp improper_hybrid.cpp input.cpp kspace.cpp lammps.cpp lattice.cpp library.cpp memory.cpp min.cpp min_cg.cpp min_cg_fr.cpp min_sd.cpp minimize.cpp modify.cpp neigh_bond.cpp neigh_full.cpp neigh_gran.cpp neigh_half.cpp neigh_respa.cpp neigh_stencil.cpp neighbor.cpp output.cpp pack.cpp pair.cpp pair_airebo.cpp pair_buck.cpp pair_buck_coul_cut.cpp pair_buck_coul_long.cpp pair_dpd.cpp pair_eam.cpp pair_eam_alloy.cpp pair_eam_alloy_opt.cpp pair_eam_fs.cpp pair_eam_fs_opt.cpp pair_eam_opt.cpp pair_gayberne.cpp pair_gran_hertzian.cpp pair_gran_history.cpp pair_gran_no_history.cpp pair_hybrid.cpp pair_lj_charmm_coul_charmm.cpp pair_lj_charmm_coul_charmm_implicit.cpp pair_lj_charmm_coul_long.cpp pair_lj_charmm_coul_long_opt.cpp pair_lj_class2.cpp pair_lj_class2_coul_cut.cpp pair_lj_class2_coul_long.cpp pair_lj_cut.cpp pair_lj_cut_coul_cut.cpp pair_lj_cut_coul_debye.cpp pair_lj_cut_coul_long.cpp pair_lj_cut_coul_long_tip4p.cpp pair_lj_cut_opt.cpp pair_lj_expand.cpp pair_lj_smooth.cpp pair_morse.cpp pair_morse_opt.cpp pair_soft.cpp pair_sw.cpp pair_table.cpp pair_tersoff.cpp pair_yukawa.cpp pppm.cpp pppm_tip4p.cpp random_mars.cpp random_park.cpp read_data.cpp read_restart.cpp region.cpp region_block.cpp region_cylinder.cpp region_intersect.cpp region_prism.cpp region_sphere.cpp region_union.cpp remap.cpp remap_wrap.cpp replicate.cpp respa.cpp run.cpp set.cpp shell.cpp special.cpp temper.cpp thermo.cpp timer.cpp universe.cpp update.cpp variable.cpp velocity.cpp verlet.cpp write_restart.cpp
 
-INC =	angle.h angle_charmm.h angle_cosine.h angle_cosine_squared.h angle_harmonic.h angle_hybrid.h atom.h atom_vec.h atom_vec_angle.h atom_vec_atomic.h atom_vec_bond.h atom_vec_charge.h atom_vec_full.h atom_vec_hybrid.h atom_vec_molecular.h bond.h bond_fene.h bond_fene_expand.h bond_harmonic.h bond_hybrid.h bond_morse.h bond_nonlinear.h bond_quartic.h comm.h compute.h compute_centro_atom.h compute_epair_atom.h compute_etotal_atom.h compute_ke_atom.h compute_pressure.h compute_rotate_dipole.h compute_rotate_gran.h compute_stress_atom.h compute_temp.h compute_temp_partial.h compute_temp_ramp.h compute_temp_region.h create_atoms.h create_box.h delete_atoms.h delete_bonds.h dihedral.h dihedral_charmm.h dihedral_harmonic.h dihedral_helix.h dihedral_hybrid.h dihedral_multi_harmonic.h dihedral_opls.h displace_atoms.h domain.h dump.h dump_atom.h dump_bond.h dump_custom.h dump_dcd.h dump_xyz.h error.h ewald.h fft3d.h fft3d_wrap.h finish.h fix.h fix_add_force.h fix_ave_force.h fix_com.h fix_deposit.h fix_drag.h fix_efield.h fix_enforce2d.h fix_gravity.h fix_gyration.h fix_indent.h fix_langevin.h fix_line_force.h fix_minimize.h fix_momentum.h fix_msd.h fix_nph.h fix_npt.h fix_nve.h fix_nvt.h fix_orient_fcc.h fix_plane_force.h fix_print.h fix_rdf.h fix_recenter.h fix_respa.h fix_rigid.h fix_set_force.h fix_shake.h fix_shear_history.h fix_spring.h fix_spring_rg.h fix_spring_self.h fix_temp_rescale.h fix_tmd.h fix_uniaxial.h fix_viscous.h fix_volume_rescale.h fix_wall_lj126.h fix_wall_lj93.h fix_wall_reflect.h fix_wiggle.h force.h group.h improper.h improper_cvff.h improper_harmonic.h improper_hybrid.h input.h integrate.h kspace.h lammps.h lattice.h library.h memory.h min.h min_cg.h min_cg_fr.h min_sd.h minimize.h modify.h neighbor.h output.h pack.h pair.h pair_buck.h pair_buck_coul_cut.h pair_buck_coul_long.h pair_eam.h pair_eam_alloy.h pair_eam_fs.h pair_hybrid.h pair_lj_charmm_coul_charmm.h pair_lj_charmm_coul_charmm_implicit.h pair_lj_charmm_coul_long.h pair_lj_cut.h pair_lj_cut_coul_cut.h pair_lj_cut_coul_debye.h pair_lj_cut_coul_long.h pair_lj_cut_coul_long_tip4p.h pair_lj_expand.h pair_lj_smooth.h pair_morse.h pair_soft.h pair_sw.h pair_table.h pair_tersoff.h pair_yukawa.h pointers.h pppm.h pppm_tip4p.h random_mars.h random_park.h read_data.h read_restart.h region.h region_block.h region_cylinder.h region_intersect.h region_prism.h region_sphere.h region_union.h remap.h remap_wrap.h replicate.h respa.h run.h set.h shell.h special.h style.h style_class2.h style_dpd.h style_granular.h style_kspace.h style_manybody.h style_meam.h style_molecule.h style_opt.h style_poems.h style_user.h style_xtc.h temper.h thermo.h timer.h universe.h update.h variable.h velocity.h verlet.h write_restart.h
+INC =	angle.h angle_charmm.h angle_class2.h angle_cosine.h angle_cosine_squared.h angle_harmonic.h angle_hybrid.h atom.h atom_vec.h atom_vec_angle.h atom_vec_atomic.h atom_vec_bond.h atom_vec_charge.h atom_vec_dpd.h atom_vec_ellipsoid.h atom_vec_full.h atom_vec_granular.h atom_vec_hybrid.h atom_vec_molecular.h bond.h bond_class2.h bond_fene.h bond_fene_expand.h bond_harmonic.h bond_hybrid.h bond_morse.h bond_nonlinear.h bond_quartic.h comm.h compute.h compute_centro_atom.h compute_coord_atom.h compute_epair_atom.h compute_etotal_atom.h compute_ke_atom.h compute_pressure.h compute_rotate_dipole.h compute_rotate_gran.h compute_stress_atom.h compute_temp.h compute_temp_asphere.h compute_temp_partial.h compute_temp_ramp.h compute_temp_region.h compute_variable.h compute_variable_atom.h create_atoms.h create_box.h delete_atoms.h delete_bonds.h dihedral.h dihedral_charmm.h dihedral_class2.h dihedral_harmonic.h dihedral_helix.h dihedral_hybrid.h dihedral_multi_harmonic.h dihedral_opls.h displace_atoms.h domain.h dump.h dump_atom.h dump_bond.h dump_custom.h dump_dcd.h dump_xtc.h dump_xyz.h error.h ewald.h fft3d.h fft3d_wrap.h finish.h fix.h fix_add_force.h fix_ave_force.h fix_ave_spatial.h fix_ave_time.h fix_com.h fix_deposit.h fix_drag.h fix_efield.h fix_enforce2d.h fix_freeze.h fix_gran_diag.h fix_gravity.h fix_gyration.h fix_heat.h fix_indent.h fix_langevin.h fix_line_force.h fix_minimize.h fix_momentum.h fix_msd.h fix_nph.h fix_npt.h fix_npt_asphere.h fix_nve.h fix_nve_asphere.h fix_nve_gran.h fix_nve_noforce.h fix_nvt.h fix_nvt_asphere.h fix_orient_fcc.h fix_plane_force.h fix_pour.h fix_print.h fix_rdf.h fix_recenter.h fix_respa.h fix_rigid.h fix_set_force.h fix_shake.h fix_shear_history.h fix_spring.h fix_spring_rg.h fix_spring_self.h fix_temp_rescale.h fix_tmd.h fix_uniaxial.h fix_viscous.h fix_volume_rescale.h fix_wall_gran.h fix_wall_lj126.h fix_wall_lj93.h fix_wall_reflect.h fix_wiggle.h force.h group.h improper.h improper_class2.h improper_cvff.h improper_harmonic.h improper_hybrid.h input.h integrate.h kspace.h lammps.h lattice.h library.h math_extra.h matho.h memory.h min.h min_cg.h min_cg_fr.h min_sd.h minimize.h modify.h neighbor.h output.h pack.h pair.h pair_airebo.h pair_buck.h pair_buck_coul_cut.h pair_buck_coul_long.h pair_dpd.h pair_eam.h pair_eam_alloy.h pair_eam_alloy_opt.h pair_eam_fs.h pair_eam_fs_opt.h pair_eam_opt.h pair_gayberne.h pair_gran_hertzian.h pair_gran_history.h pair_gran_no_history.h pair_hybrid.h pair_lj_charmm_coul_charmm.h pair_lj_charmm_coul_charmm_implicit.h pair_lj_charmm_coul_long.h pair_lj_charmm_coul_long_opt.h pair_lj_class2.h pair_lj_class2_coul_cut.h pair_lj_class2_coul_long.h pair_lj_cut.h pair_lj_cut_coul_cut.h pair_lj_cut_coul_debye.h pair_lj_cut_coul_long.h pair_lj_cut_coul_long_tip4p.h pair_lj_cut_opt.h pair_lj_expand.h pair_lj_smooth.h pair_morse.h pair_morse_opt.h pair_soft.h pair_sw.h pair_table.h pair_tersoff.h pair_yukawa.h pointers.h pppm.h pppm_tip4p.h random_mars.h random_park.h read_data.h read_restart.h region.h region_block.h region_cylinder.h region_intersect.h region_prism.h region_sphere.h region_union.h remap.h remap_wrap.h replicate.h respa.h run.h set.h shell.h special.h style.h style_asphere.h style_class2.h style_dpd.h style_granular.h style_kspace.h style_manybody.h style_meam.h style_molecule.h style_opt.h style_poems.h style_user.h style_xtc.h temper.h thermo.h timer.h universe.h update.h variable.h vector.h velocity.h verlet.h write_restart.h
 
 OBJ = 	$(SRC:.cpp=.o)
 
diff --git a/src/OPT/pair_eam_opt.h b/src/OPT/pair_eam_opt.h
index 1e48f194a23b5c443cf78f38e987c5a76ceaced1..25f1c4c27b846991741538a0316d1329de5dd8c0 100644
--- a/src/OPT/pair_eam_opt.h
+++ b/src/OPT/pair_eam_opt.h
@@ -286,15 +286,15 @@ void PairEAMOpt::eval()
 	double phi = z2*recip;
 	double phip = z2p*recip - phi*recip;
 	double psip = fp[i]*rhojp + fp[j]*rhoip + phip;
-	double fforce = psip*recip;
+	double fforce = -psip*recip;
 	
 	tmpfx += delx*fforce;
 	tmpfy += dely*fforce;
 	tmpfz += delz*fforce;
 	if (NEWTON_PAIR || j < nlocal) {
-	  ff[j].x += delx*fforce;
-	  ff[j].y += dely*fforce;
-	  ff[j].z += delz*fforce;
+	  ff[j].x -= delx*fforce;
+	  ff[j].y -= dely*fforce;
+	  ff[j].z -= delz*fforce;
 	}
 	
 	if (EFLAG) {
@@ -303,27 +303,19 @@ void PairEAMOpt::eval()
 	}
 	
 	if (VFLAG == 1) {
-	  if (NEWTON_PAIR || j < nlocal) {
-	    virial[0] -= delx*delx*fforce;
-	    virial[1] -= dely*dely*fforce;
-	    virial[2] -= delz*delz*fforce;
-	    virial[3] -= delx*dely*fforce;
-	    virial[4] -= delx*delz*fforce;
-	    virial[5] -= dely*delz*fforce;
-	  } else {
-	    virial[0] -= 0.5*delx*delx*fforce;
-	    virial[1] -= 0.5*dely*dely*fforce;
-	    virial[2] -= 0.5*delz*delz*fforce;
-	    virial[3] -= 0.5*delx*dely*fforce;
-	    virial[4] -= 0.5*delx*delz*fforce;
-	    virial[5] -= 0.5*dely*delz*fforce;
-	  }
+	  if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
-    ff[i].x -= tmpfx;
-    ff[i].y -= tmpfy;
-    ff[i].z -= tmpfz;
+    ff[i].x += tmpfx;
+    ff[i].y += tmpfy;
+    ff[i].z += tmpfz;
   }
   
   free(fast_alpha); fast_alpha = 0;
diff --git a/src/OPT/pair_lj_charmm_coul_long_opt.h b/src/OPT/pair_lj_charmm_coul_long_opt.h
index 3c555f8d138fe0e96dfd53b2ecd11f9784eb1c0c..41446c9a4a4444f0375929eed0f009f6a9b7eee9 100644
--- a/src/OPT/pair_lj_charmm_coul_long_opt.h
+++ b/src/OPT/pair_lj_charmm_coul_long_opt.h
@@ -218,21 +218,13 @@ void PairLJCharmmCoulLongOpt::eval()
 	  }
 	  
 	  if (VFLAG == 1) {
-	    if (NEWTON_PAIR || j < nlocal) {
-	      virial[0] += delx*delx*fforce;
-	      virial[1] += dely*dely*fforce;
-	      virial[2] += delz*delz*fforce;
-	      virial[3] += delx*dely*fforce;
-	      virial[4] += delx*delz*fforce;
-	      virial[5] += dely*delz*fforce;
-	    } else {
-	      virial[0] += 0.5*delx*delx*fforce;
-	      virial[1] += 0.5*dely*dely*fforce;
-	      virial[2] += 0.5*delz*delz*fforce;
-	      virial[3] += 0.5*delx*dely*fforce;
-	      virial[4] += 0.5*delx*delz*fforce;
-	      virial[5] += 0.5*dely*delz*fforce;
-	    }
+	    if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5;
+	    virial[0] += delx*delx*fforce;
+	    virial[1] += dely*dely*fforce;
+	    virial[2] += delz*delz*fforce;
+	    virial[3] += delx*dely*fforce;
+	    virial[4] += delx*delz*fforce;
+	    virial[5] += dely*delz*fforce;
 	  }
 	}
       } else {
@@ -330,21 +322,13 @@ void PairLJCharmmCoulLongOpt::eval()
 	  }
 	  
 	  if (VFLAG == 1) {
-	    if (NEWTON_PAIR || j < nlocal) {
-	      virial[0] += delx*delx*fforce;
-	      virial[1] += dely*dely*fforce;
-	      virial[2] += delz*delz*fforce;
-	      virial[3] += delx*dely*fforce;
-	      virial[4] += delx*delz*fforce;
-	      virial[5] += dely*delz*fforce;
-	    } else {
-	      virial[0] += 0.5*delx*delx*fforce;
-	      virial[1] += 0.5*dely*dely*fforce;
-	      virial[2] += 0.5*delz*delz*fforce;
-	      virial[3] += 0.5*delx*dely*fforce;
-	      virial[4] += 0.5*delx*delz*fforce;
-	      virial[5] += 0.5*dely*delz*fforce;
-	    }
+	    if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5;
+	    virial[0] += delx*delx*fforce;
+	    virial[1] += dely*dely*fforce;
+	    virial[2] += delz*delz*fforce;
+	    virial[3] += delx*dely*fforce;
+	    virial[4] += delx*delz*fforce;
+	    virial[5] += dely*delz*fforce;
 	  }
 	}
       }
diff --git a/src/OPT/pair_lj_cut_opt.h b/src/OPT/pair_lj_cut_opt.h
index bef048157a1881ab05665f0f0f5ba2da2658396a..8b7f2a56657ac33172474c8ddffab3ec1ac9b5c9 100644
--- a/src/OPT/pair_lj_cut_opt.h
+++ b/src/OPT/pair_lj_cut_opt.h
@@ -135,21 +135,13 @@ void PairLJCutOpt::eval()
 	  }
 	  
 	  if (VFLAG == 1) {
-	    if (NEWTON_PAIR || j < nlocal) {
-	      virial[0] += delx*delx*fforce;
-	      virial[1] += dely*dely*fforce;
-	      virial[2] += delz*delz*fforce;
-	      virial[3] += delx*dely*fforce;
-	      virial[4] += delx*delz*fforce;
-	      virial[5] += dely*delz*fforce;
-	    } else {
-	      virial[0] += 0.5*delx*delx*fforce;
-	      virial[1] += 0.5*dely*dely*fforce;
-	      virial[2] += 0.5*delz*delz*fforce;
-	      virial[3] += 0.5*delx*dely*fforce;
-	      virial[4] += 0.5*delx*delz*fforce;
-	      virial[5] += 0.5*dely*delz*fforce;
-	    }
+	    if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5;
+	    virial[0] += delx*delx*fforce;
+	    virial[1] += dely*dely*fforce;
+	    virial[2] += delz*delz*fforce;
+	    virial[3] += delx*dely*fforce;
+	    virial[4] += delx*delz*fforce;
+	    virial[5] += dely*delz*fforce;
 	  }
 	}
 
@@ -191,21 +183,13 @@ void PairLJCutOpt::eval()
 	  }
 	  
 	  if (VFLAG == 1) {
-	    if (NEWTON_PAIR || j < nlocal) {
-	      virial[0] += delx*delx*fforce;
-	      virial[1] += dely*dely*fforce;
-	      virial[2] += delz*delz*fforce;
-	      virial[3] += delx*dely*fforce;
-	      virial[4] += delx*delz*fforce;
-	      virial[5] += dely*delz*fforce;
-	    } else {
-	      virial[0] += 0.5*delx*delx*fforce;
-	      virial[1] += 0.5*dely*dely*fforce;
-	      virial[2] += 0.5*delz*delz*fforce;
-	      virial[3] += 0.5*delx*dely*fforce;
-	      virial[4] += 0.5*delx*delz*fforce;
-	      virial[5] += 0.5*dely*delz*fforce;
-	    }
+	    if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5;
+	    virial[0] += delx*delx*fforce;
+	    virial[1] += dely*dely*fforce;
+	    virial[2] += delz*delz*fforce;
+	    virial[3] += delx*dely*fforce;
+	    virial[4] += delx*delz*fforce;
+	    virial[5] += dely*delz*fforce;
 	  }
 	}
       }
diff --git a/src/OPT/pair_morse_opt.h b/src/OPT/pair_morse_opt.h
index 6343882cc4ba6e5ff1a9e1525b01b87f577366e7..5f3f129a42da8692ae24f563a439fe3adf9fe46d 100644
--- a/src/OPT/pair_morse_opt.h
+++ b/src/OPT/pair_morse_opt.h
@@ -143,21 +143,13 @@ void PairMorseOpt::eval()
 	  }
 	  
 	  if (VFLAG == 1) {
-	    if (NEWTON_PAIR || j < nlocal) {
-	      virial[0] += delx*delx*fforce;
-	      virial[1] += dely*dely*fforce;
-	      virial[2] += delz*delz*fforce;
-	      virial[3] += delx*dely*fforce;
-	      virial[4] += delx*delz*fforce;
-	      virial[5] += dely*delz*fforce;
-	    } else {
-	      virial[0] += 0.5*delx*delx*fforce;
-	      virial[1] += 0.5*dely*dely*fforce;
-	      virial[2] += 0.5*delz*delz*fforce;
-	      virial[3] += 0.5*delx*dely*fforce;
-	      virial[4] += 0.5*delx*delz*fforce;
-	      virial[5] += 0.5*dely*delz*fforce;
-	    }
+	    if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5;
+	    virial[0] += delx*delx*fforce;
+	    virial[1] += dely*dely*fforce;
+	    virial[2] += delz*delz*fforce;
+	    virial[3] += delx*dely*fforce;
+	    virial[4] += delx*delz*fforce;
+	    virial[5] += dely*delz*fforce;
 	  }
 	}
       } else {
@@ -196,21 +188,13 @@ void PairMorseOpt::eval()
 	  }
 	  
 	  if (VFLAG == 1) {
-	    if (NEWTON_PAIR || j < nlocal) {
-	      virial[0] += delx*delx*fforce;
-	      virial[1] += dely*dely*fforce;
-	      virial[2] += delz*delz*fforce;
-	      virial[3] += delx*dely*fforce;
-	      virial[4] += delx*delz*fforce;
-	      virial[5] += dely*delz*fforce;
-	    } else {
-	      virial[0] += 0.5*delx*delx*fforce;
-	      virial[1] += 0.5*dely*dely*fforce;
-	      virial[2] += 0.5*delz*delz*fforce;
-	      virial[3] += 0.5*delx*dely*fforce;
-	      virial[4] += 0.5*delx*delz*fforce;
-	      virial[5] += 0.5*dely*delz*fforce;
-	    }
+	    if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5;
+	    virial[0] += delx*delx*fforce;
+	    virial[1] += dely*dely*fforce;
+	    virial[2] += delz*delz*fforce;
+	    virial[3] += delx*dely*fforce;
+	    virial[4] += delx*delz*fforce;
+	    virial[5] += dely*delz*fforce;
 	  }
 	}
       }
diff --git a/src/POEMS/fix_poems.cpp b/src/POEMS/fix_poems.cpp
index d4a8ca3dc9006bbda70e9cbe4a67a917f4e41a20..ed704cce13b79bbdad49e83d0cdcb1e1b1ece424 100644
--- a/src/POEMS/fix_poems.cpp
+++ b/src/POEMS/fix_poems.cpp
@@ -55,6 +55,8 @@ FixPOEMS::FixPOEMS(LAMMPS *lmp, int narg, char **arg) :
 {
   int i,j,ibody;
 
+  rigid_flag = 1;
+  virial_flag = 1;
   MPI_Comm_rank(world,&me);
 
   // can't use with pure granular style since mass arrays are different
diff --git a/src/atom.cpp b/src/atom.cpp
index f66c6d6c96c4252af15e9cd73970f73960df2850..0eebda62f1840bfdb46f4eec8f3b56f8b7fa934d 100644
--- a/src/atom.cpp
+++ b/src/atom.cpp
@@ -61,7 +61,7 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
   molecule = NULL;
   q = NULL;
   mu = NULL;
-  xphi = omega = torque = NULL;
+  xphi = quat = omega = angmom = torque = NULL;
   radius = density = rmass = vfrac = NULL;
 
   maxspecial = 1;
@@ -82,12 +82,12 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
   improper_type = improper_atom1 = improper_atom2 = NULL;
   improper_atom3 = improper_atom4 = NULL;
 
-  hybrid = NULL;
-
   // ntype-length arrays
 
   mass = NULL;
   mass_setflag = NULL;
+  shape = NULL;
+  shape_setflag = NULL;
   dipole = NULL;
   dipole_setflag = NULL;
 
@@ -143,8 +143,11 @@ Atom::~Atom()
   memory->sfree(q);
   memory->destroy_2d_double_array(mu);
   memory->destroy_2d_double_array(xphi);
+  memory->destroy_2d_double_array(quat);
   memory->destroy_2d_double_array(omega);
+  memory->destroy_2d_double_array(angmom);
   memory->destroy_2d_double_array(torque);
+
   memory->sfree(radius);
   memory->sfree(density);
   memory->sfree(rmass);
@@ -179,12 +182,12 @@ Atom::~Atom()
   memory->destroy_2d_int_array(improper_atom3);
   memory->destroy_2d_int_array(improper_atom4);
 
-  memory->sfree(hybrid);
-
   // delete per-type arrays
 
   delete [] mass;
   delete [] mass_setflag;
+  memory->destroy_2d_double_array(shape);
+  delete [] shape_setflag;
   delete [] dipole;
   delete [] dipole_setflag;
 
@@ -250,6 +253,7 @@ void Atom::init()
   // check arrays that are atom type in length
 
   check_mass();
+  check_shape();
   check_dipole();
 
   // init sub-style
@@ -258,11 +262,11 @@ void Atom::init()
 }
 
 /* ----------------------------------------------------------------------
-   check if atom style matches style
-   if hybrid, any sub-style can be a match
+   return 1 if style matches atom style hybrid sub-style
+   else return 0
 ------------------------------------------------------------------------- */
 
-int Atom::check_style(char *style)
+int Atom::style_match(char *style)
 {
   if (strcmp(atom_style,style) == 0) return 1;
   else if (strcmp(atom_style,"hybrid") == 0) {
@@ -612,10 +616,10 @@ int Atom::count_words(char *line)
 
 /* ----------------------------------------------------------------------
    unpack n lines from Atom section of data file
-   set all atom values and defaults
+   call style-specific routine to parse line
 ------------------------------------------------------------------------- */
 
-void Atom::data_atoms(int n, char *buf, int ihybrid)
+void Atom::data_atoms(int n, char *buf)
 {
   int m,imagedata,xptr,iptr;
   double xdata[3],lamda[3],sublo[3],subhi[3];
@@ -627,7 +631,6 @@ void Atom::data_atoms(int n, char *buf, int ihybrid)
   int nwords = count_words(buf);
   *next = '\n';
 
-  avec->data_params(ihybrid);
   if (nwords != avec->size_data_atom && nwords != avec->size_data_atom + 3)
     error->all("Incorrect atom format in data file");
 
@@ -671,7 +674,8 @@ void Atom::data_atoms(int n, char *buf, int ihybrid)
 
   // loop over lines of atom data
   // tokenize the line into values
-  // extract xyz coords and image flags, remap them
+  // extract xyz coords and image flags
+  // remap atom into simulation box
   // if atom is in my sub-domain, unpack its values
 
   for (int i = 0; i < n; i++) {
@@ -699,7 +703,7 @@ void Atom::data_atoms(int n, char *buf, int ihybrid)
     if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
 	coord[1] >= sublo[1] && coord[1] < subhi[1] &&
 	coord[2] >= sublo[2] && coord[2] < subhi[2])
-      avec->data_atom(xdata,imagedata,values,ihybrid);
+      avec->data_atom(xdata,imagedata,values);
 
     buf = next + 1;
   }
@@ -713,9 +717,9 @@ void Atom::data_atoms(int n, char *buf, int ihybrid)
    call style-specific routine to parse line
 ------------------------------------------------------------------------- */
 
-void Atom::data_vels(int n, char *buf, int ihybrid)
+void Atom::data_vels(int n, char *buf)
 {
-  int m,tagtmp;
+  int j,m,tagdata;
   char *next;
 
   next = strchr(buf,'\n');
@@ -723,19 +727,31 @@ void Atom::data_vels(int n, char *buf, int ihybrid)
   int nwords = count_words(buf);
   *next = '\n';
 
-  avec->data_params(ihybrid);
   if (nwords != avec->size_data_vel)
     error->all("Incorrect velocity format in data file");
 
+  char **values = new char*[nwords];
+
+  // loop over lines of atom velocities
+  // tokenize the line into values
+  // if I own atom tag, unpack its values
+
   for (int i = 0; i < n; i++) {
     next = strchr(buf,'\n');
-    *next = '\0';
-    sscanf(buf,"%d",&tagtmp);
-    if (tagtmp <= 0 || tagtmp > map_tag_max)
+
+    values[0] = strtok(buf," \t\n\r\f");
+    for (j = 1; j < nwords; j++)
+      values[j] = strtok(NULL," \t\n\r\f");
+
+    tagdata = atoi(values[0]);
+    if (tagdata <= 0 || tagdata > map_tag_max)
       error->one("Invalid atom ID in Velocities section of data file");
-    if ((m = map(tagtmp)) >= 0) avec->data_vel(m,buf,ihybrid);
+    if ((m = map(tagdata)) >= 0) avec->data_vel(m,&values[1]);
+
     buf = next + 1;
   }
+
+  delete [] values;
 }
 
 /* ----------------------------------------------------------------------
@@ -950,6 +966,11 @@ void Atom::allocate_type_arrays()
     mass_setflag = new int[ntypes+1];
     for (int itype = 1; itype <= ntypes; itype++) mass_setflag[itype] = 0;
   }
+  if (avec->shape_type) {
+    shape = memory->create_2d_double_array(ntypes+1,3,"atom:shape");
+    shape_setflag = new int[ntypes+1];
+    for (int itype = 1; itype <= ntypes; itype++) shape_setflag[itype] = 0;
+  }    
   if (avec->dipole_type) {
     dipole = new double[ntypes+1];
     dipole_setflag = new int[ntypes+1];
@@ -968,7 +989,8 @@ void Atom::set_mass(char *str)
 
   int itype;
   double mass_one;
-  sscanf(str,"%d %lg",&itype,&mass_one);
+  int n = sscanf(str,"%d %lg",&itype,&mass_one);
+  if (n != 2) error->all("Invalid mass line in data file");
 
   if (itype < 1 || itype > ntypes) error->all("Invalid type for mass set");
 
@@ -1032,6 +1054,79 @@ void Atom::check_mass()
     if (mass_setflag[itype] == 0) error->all("All masses are not set");
 }
 
+/* ----------------------------------------------------------------------
+   set particle shape and flag it as set
+   called from reading of data file
+------------------------------------------------------------------------- */
+
+void Atom::set_shape(char *str)
+{
+  if (shape == NULL) error->all("Cannot set shape for this atom style");
+
+  int itype;
+  double a,b,c;
+  int n = sscanf(str,"%d %lg %lg %lg",&itype,&a,&b,&c);
+  if (n != 4) error->all("Invalid shape line in data file");
+
+  if (itype < 1 || itype > ntypes) error->all("Invalid type for shape set");
+
+  // store shape as radius, though specified as diameter
+
+  shape[itype][0] = 0.5*a;
+  shape[itype][1] = 0.5*b;
+  shape[itype][2] = 0.5*c;
+  shape_setflag[itype] = 1;
+}
+
+/* ----------------------------------------------------------------------
+   set one or more particle shapes and flag them as set
+   called from reading of input script
+------------------------------------------------------------------------- */
+
+void Atom::set_shape(int narg, char **arg)
+{
+  if (shape == NULL) error->all("Cannot set shape for this atom style");
+
+  int lo,hi;
+  force->bounds(arg[0],ntypes,lo,hi);
+  if (lo < 1 || hi > ntypes) 
+	error->all("Invalid type for shape set");
+
+  // store shape as radius, though specified as diameter
+
+  for (int itype = lo; itype <= hi; itype++) {
+    shape[itype][0] = 0.5*atof(arg[1]);
+    shape[itype][1] = 0.5*atof(arg[2]);
+    shape[itype][2] = 0.5*atof(arg[3]);
+    shape_setflag[itype] = 1;
+  }
+}
+
+/* ----------------------------------------------------------------------
+   set all particle shapes as read in from restart file
+------------------------------------------------------------------------- */
+
+void Atom::set_shape(double **values)
+{
+  for (int itype = 1; itype <= ntypes; itype++) {
+    shape[itype][0] = values[itype][0];
+    shape[itype][1] = values[itype][1];
+    shape[itype][2] = values[itype][2];
+    shape_setflag[itype] = 1;
+  }
+}
+
+/* ----------------------------------------------------------------------
+   check that all particle shapes have been set
+------------------------------------------------------------------------- */
+
+void Atom::check_shape()
+{
+  if (shape == NULL) return;
+  for (int itype = 1; itype <= ntypes; itype++)
+    if (shape_setflag[itype] == 0) error->all("All shapes are not set");
+}
+
 /* ----------------------------------------------------------------------
    set a dipole moment and flag it as set
    called from reading of data file
@@ -1043,7 +1138,8 @@ void Atom::set_dipole(char *str)
 
   int i;
   double dipole_one;
-  sscanf(str,"%d %lg",&i,&dipole_one);
+  int n = sscanf(str,"%d %lg",&i,&dipole_one);
+  if (n != 2) error->all("Invalid shape line in data file");
 
   dipole[i] = dipole_one;
   dipole_setflag[i] = 1;
diff --git a/src/atom.h b/src/atom.h
index 1ec3e8dbba67f94234f31214d6b1883765ba4e4d..cf96cd953e7b606bb65f83654e061c623d8e1dcb 100644
--- a/src/atom.h
+++ b/src/atom.h
@@ -43,7 +43,7 @@ class Atom : protected Pointers {
 
   int *molecule;
   double *q,**mu;
-  double **xphi,**omega,**torque;
+  double **xphi,**quat,**omega,**angmom,**torque;
   double *radius,*density,*rmass,*vfrac;
 
   int maxspecial;
@@ -65,18 +65,14 @@ class Atom : protected Pointers {
   int **improper_type;
   int **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4;
 
-  int *hybrid;
-
   // extra peratom info in restart file destined for fix & diag 
 
   double **extra;
 
   // per-type arrays
 
-  double *mass;
-  int *mass_setflag;
-  double *dipole;
-  int *dipole_setflag;
+  double *mass,**shape,*dipole;
+  int *mass_setflag,*shape_setflag,*dipole_setflag;
 
   // callback ptrs for atom arrays managed by fix classes
 
@@ -97,8 +93,7 @@ class Atom : protected Pointers {
   class AtomVec *new_avec(char *, int, char **);
   void init();
 
-  int check_style(char *);
-  int style2arg(char **);
+  int style_match(char *);
   void modify_params(int, char **);
   void tag_extend();
   int tag_consecutive();
@@ -106,8 +101,8 @@ class Atom : protected Pointers {
   int parse_data(char *);
   int count_words(char *);
 
-  void data_atoms(int, char *, int);
-  void data_vels(int, char *, int);
+  void data_atoms(int, char *);
+  void data_vels(int, char *);
   void data_bonds(int, char *);
   void data_angles(int, char *);
   void data_dihedrals(int, char *);
@@ -119,6 +114,10 @@ class Atom : protected Pointers {
   void set_mass(int, char **);
   void set_mass(double *);
   void check_mass();
+  void set_shape(char *);
+  void set_shape(int, char **);
+  void set_shape(double **);
+  void check_shape();
   void set_dipole(char *);
   void set_dipole(int, char **);
   void set_dipole(double *);
diff --git a/src/atom_vec.cpp b/src/atom_vec.cpp
index 539e8570bdd314dacd6340e3e8fe819bf5c56aad..7da3e3c7c78567897514d0cd2f6867f8dd97c279 100644
--- a/src/atom_vec.cpp
+++ b/src/atom_vec.cpp
@@ -11,7 +11,7 @@
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
-#include "string.h"
+#include "stdlib.h"
 #include "atom_vec.h"
 #include "atom.h"
 
@@ -24,19 +24,19 @@ AtomVec::AtomVec(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
   nmax = 0;
   molecular = 0;
   bonds_allow = angles_allow = dihedrals_allow = impropers_allow = 0;
-  mass_type = dipole_type = 0;
+  mass_type = shape_type = dipole_type = 0;
   comm_x_only = comm_f_only = 1;
   size_comm = size_reverse = size_border = 0;
 }
 
 /* ----------------------------------------------------------------------
-   unpack a single line from Velocity section of data file
-   individual style may override this
+   unpack one line from Velocities section of data file
 ------------------------------------------------------------------------- */
 
-void AtomVec::data_vel(int m, char *line, int ihybrid)
+void AtomVec::data_vel(int m, char **values)
 {
-  int tmp;
   double **v = atom->v;
-  sscanf(line,"%d %lg %lg %lg",&tmp,&v[m][0],&v[m][1],&v[m][2]);
+  v[m][0] = atof(values[0]);
+  v[m][1] = atof(values[1]);
+  v[m][2] = atof(values[2]);
 }
diff --git a/src/atom_vec.h b/src/atom_vec.h
index 59972d8a07586248caa62889ac6face0ac41d70d..44ec381fbe166261fc52a3b8fb2c31b8493adb2d 100644
--- a/src/atom_vec.h
+++ b/src/atom_vec.h
@@ -24,6 +24,7 @@ class AtomVec : protected Pointers {
   int bonds_allow,angles_allow;        // 1 if bonds, angles are used
   int dihedrals_allow,impropers_allow; // 1 if dihedrals, impropers used
   int mass_type;                       // 1 if per-type masses
+  int shape_type;                      // 1 if per-type shape array
   int dipole_type;                     // 1 if per-type dipole moments
   int comm_x_only;                     // 1 if only exchange x in forward comm
   int comm_f_only;                     // 1 if only exchange f in reverse comm
@@ -39,9 +40,7 @@ class AtomVec : protected Pointers {
   virtual void init() {}
 
   virtual void grow(int) = 0;
-  virtual void reset_ptrs() = 0;
-  virtual void zero_owned(int) {}
-  virtual void zero_ghost(int,int) {}
+  virtual void reset_special() {}
   virtual void copy(int, int) = 0;
 
   virtual int pack_comm(int, int *, double *, int, int *) = 0;
@@ -63,14 +62,14 @@ class AtomVec : protected Pointers {
   virtual int unpack_exchange(double *) = 0;
 
   virtual int size_restart() = 0;
-  virtual int size_restart_one(int) = 0;
   virtual int pack_restart(int, double *) = 0;
   virtual int unpack_restart(double *) = 0;
 
-  virtual void create_atom(int, double *, int) = 0;
-  virtual void data_atom(double *, int, char **, int) = 0;
-  virtual void data_vel(int, char *, int);
-  virtual void data_params(int) {}
+  virtual void create_atom(int, double *) = 0;
+  virtual void data_atom(double *, int, char **) = 0;
+  virtual int data_atom_hybrid(int, char **) = 0;
+  virtual void data_vel(int, char **);
+  virtual int data_vel_hybrid(int, char **) {return 0;}
 
   virtual int memory_usage() = 0;
 
diff --git a/src/atom_vec_atomic.cpp b/src/atom_vec_atomic.cpp
index 562dea42d3994a5d88fe144ff19cce87c5e2916d..b53b2f44fd033c1ee480ecb8fade174cbd1b07b8 100644
--- a/src/atom_vec_atomic.cpp
+++ b/src/atom_vec_atomic.cpp
@@ -69,19 +69,6 @@ void AtomVecAtomic::grow(int n)
 
 /* ---------------------------------------------------------------------- */
 
-void AtomVecAtomic::reset_ptrs()
-{
-  tag = atom->tag;
-  type = atom->type;
-  mask = atom->mask;
-  image = atom->image;
-  x = atom->x;
-  v = atom->v;
-  f = atom->f;
-}
-
-/* ---------------------------------------------------------------------- */
-
 void AtomVecAtomic::copy(int i, int j)
 {
   tag[j] = tag[i];
@@ -318,16 +305,6 @@ int AtomVecAtomic::size_restart()
   return n;
 }
 
-/* ----------------------------------------------------------------------
-   size of restart data for atom I
-   do not include extra data stored by fixes, included by caller
-------------------------------------------------------------------------- */
-
-int AtomVecAtomic::size_restart_one(int i)
-{
-  return 11;
-}
-
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
@@ -398,7 +375,7 @@ int AtomVecAtomic::unpack_restart(double *buf)
    set other values to defaults
 ------------------------------------------------------------------------- */
 
-void AtomVecAtomic::create_atom(int itype, double *coord, int ihybrid)
+void AtomVecAtomic::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -422,8 +399,7 @@ void AtomVecAtomic::create_atom(int itype, double *coord, int ihybrid)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecAtomic::data_atom(double *coord, int imagetmp, char **values,
-			      int ihybrid)
+void AtomVecAtomic::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -450,6 +426,20 @@ void AtomVecAtomic::data_atom(double *coord, int imagetmp, char **values,
   atom->nlocal++;
 }
 
+/* ----------------------------------------------------------------------
+   unpack hybrid quantities from one line in Atoms section of data file
+   initialize other atom quantities for this sub-style
+------------------------------------------------------------------------- */
+
+int AtomVecAtomic::data_atom_hybrid(int nlocal, char **values)
+{
+  v[nlocal][0] = 0.0;
+  v[nlocal][1] = 0.0;
+  v[nlocal][2] = 0.0;
+
+  return 0;
+}
+
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
diff --git a/src/atom_vec_atomic.h b/src/atom_vec_atomic.h
index 3158e22077f2fc6a8d4a4b88736887f29c789db8..2edddb21e0154b92e7e117a3497f27b32e8ae77e 100644
--- a/src/atom_vec_atomic.h
+++ b/src/atom_vec_atomic.h
@@ -23,7 +23,6 @@ class AtomVecAtomic : public AtomVec {
   AtomVecAtomic(class LAMMPS *, int, char **);
   virtual ~AtomVecAtomic() {}
   void grow(int);
-  void reset_ptrs();
   void copy(int, int);
   virtual int pack_comm(int, int *, double *, int, int *);
   virtual void unpack_comm(int, int, double *);
@@ -34,11 +33,11 @@ class AtomVecAtomic : public AtomVec {
   int pack_exchange(int, double *);
   int unpack_exchange(double *);
   int size_restart();
-  int size_restart_one(int);
   int pack_restart(int, double *);
   int unpack_restart(double *);
-  void create_atom(int, double *, int);
-  void data_atom(double *, int, char **, int);
+  void create_atom(int, double *);
+  void data_atom(double *, int, char **);
+  int data_atom_hybrid(int, char **);
   int memory_usage();
 
  protected:
diff --git a/src/atom_vec_charge.cpp b/src/atom_vec_charge.cpp
index 631697eb7c2e56b932500eb4566ef9386b0b759e..25ba6147b786eea055e9ffc3212efceb5fb471e5 100644
--- a/src/atom_vec_charge.cpp
+++ b/src/atom_vec_charge.cpp
@@ -72,46 +72,6 @@ void AtomVecCharge::grow(int n)
 
 /* ---------------------------------------------------------------------- */
 
-void AtomVecCharge::reset_ptrs()
-{
-  tag = atom->tag;
-  type = atom->type;
-  mask = atom->mask;
-  image = atom->image;
-  x = atom->x;
-  v = atom->v;
-  f = atom->f;
-
-  q = atom->q;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for owned atom I
-   data in copy(), not including tag,type,mask,image,x,v
-------------------------------------------------------------------------- */
-
-void AtomVecCharge::zero_owned(int i)
-{
-  q[i] = 0.0;
-}
-
-/* ----------------------------------------------------------------------
-   zero auxiliary data for n ghost atoms
-   data in border(), not including x,tag,type,mask
-   grow() is here since zero_ghost called first in hybrid::unpack_border()
-------------------------------------------------------------------------- */
-
-void AtomVecCharge::zero_ghost(int n, int first)
-{
-  int last = first + n;
-  for (int i = first; i < last; i++) {
-    if (i == nmax) atom->avec->grow(0);
-    q[i] = 0.0;
-  }
-}
-
-/* ---------------------------------------------------------------------- */
-
 void AtomVecCharge::copy(int i, int j)
 {
   tag[j] = tag[i];
@@ -373,16 +333,6 @@ int AtomVecCharge::size_restart()
   return n;
 }
 
-/* ----------------------------------------------------------------------
-   size of restart data for atom I
-   do not include extra data stored by fixes, included by caller
-------------------------------------------------------------------------- */
-
-int AtomVecCharge::size_restart_one(int i)
-{
-  return 12;
-}
-
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
@@ -457,7 +407,7 @@ int AtomVecCharge::unpack_restart(double *buf)
    set other values to defaults
 ------------------------------------------------------------------------- */
 
-void AtomVecCharge::create_atom(int itype, double *coord, int ihybrid)
+void AtomVecCharge::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -483,8 +433,7 @@ void AtomVecCharge::create_atom(int itype, double *coord, int ihybrid)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecCharge::data_atom(double *coord, int imagetmp, char **values,
-			      int ihybrid)
+void AtomVecCharge::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -513,6 +462,22 @@ void AtomVecCharge::data_atom(double *coord, int imagetmp, char **values,
   atom->nlocal++;
 }
 
+/* ----------------------------------------------------------------------
+   unpack hybrid quantities from one line in Atoms section of data file
+   initialize other atom quantities for this sub-style
+------------------------------------------------------------------------- */
+
+int AtomVecCharge::data_atom_hybrid(int nlocal, char **values)
+{
+  q[nlocal] = atof(values[0]);
+
+  v[nlocal][0] = 0.0;
+  v[nlocal][1] = 0.0;
+  v[nlocal][2] = 0.0;
+
+  return 1;
+}
+
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
diff --git a/src/atom_vec_charge.h b/src/atom_vec_charge.h
index 5b6efb9de7fe5ac05ba0415fbd7cf7f4a8f67107..3b41efbba345fa74102d709677a832787a507f89 100644
--- a/src/atom_vec_charge.h
+++ b/src/atom_vec_charge.h
@@ -22,9 +22,6 @@ class AtomVecCharge : public AtomVec {
  public:
   AtomVecCharge(class LAMMPS *, int, char **);
   void grow(int);
-  void reset_ptrs();
-  void zero_owned(int);
-  void zero_ghost(int, int);
   void copy(int, int);
   int pack_comm(int, int *, double *, int, int *);
   void unpack_comm(int, int, double *);
@@ -37,11 +34,11 @@ class AtomVecCharge : public AtomVec {
   int pack_exchange(int, double *);
   int unpack_exchange(double *);
   int size_restart();
-  int size_restart_one(int);
   int pack_restart(int, double *);
   int unpack_restart(double *);
-  void create_atom(int, double *, int);
-  void data_atom(double *, int, char **, int);
+  void create_atom(int, double *);
+  void data_atom(double *, int, char **);
+  int data_atom_hybrid(int, char **);
   int memory_usage();
 
  private:
diff --git a/src/atom_vec_hybrid.cpp b/src/atom_vec_hybrid.cpp
index 4ca9ec81b6c937988ce394b08112d1f340146be4..774e2b3dbcf59c0f9ad840f471bd64f8d2fbf82c 100644
--- a/src/atom_vec_hybrid.cpp
+++ b/src/atom_vec_hybrid.cpp
@@ -1,4 +1,3 @@
-
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
@@ -12,6 +11,7 @@
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
+#include "stdlib.h"
 #include "string.h"
 #include "atom_vec_hybrid.h"
 #include "atom.h"
@@ -33,7 +33,7 @@ using namespace LAMMPS_NS;
 AtomVecHybrid::AtomVecHybrid(LAMMPS *lmp, int narg, char **arg) :
   AtomVec(lmp, narg, arg)
 {
-  int i,m;
+  int i,k;
 
   if (narg < 1) error->all("Illegal atom_style command");
 
@@ -44,8 +44,8 @@ AtomVecHybrid::AtomVecHybrid(LAMMPS *lmp, int narg, char **arg) :
   keywords = new char*[nstyles];
 
   for (i = 0; i < narg; i++) {
-    for (m = 0; m < i; m++)
-      if (strcmp(arg[i],keywords[m]) == 0) 
+    for (k = 0; k < i; k++)
+      if (strcmp(arg[i],keywords[k]) == 0) 
 	error->all("Atom style hybrid cannot use same atom style twice");
     if (strcmp(arg[i],"hybrid") == 0) 
       error->all("Atom style hybrid cannot have hybrid as an argument");
@@ -55,21 +55,31 @@ AtomVecHybrid::AtomVecHybrid(LAMMPS *lmp, int narg, char **arg) :
   }
 
   // hybrid settings are MAX or MIN of sub-style settings
-  // size_border has +1 for hybrid[] value that is also communicated
-
-  for (m = 0; m < nstyles; m++) {
-    molecular = MAX(molecular,styles[m]->molecular);
-    bonds_allow = MAX(bonds_allow,styles[m]->bonds_allow);
-    angles_allow = MAX(angles_allow,styles[m]->angles_allow);
-    dihedrals_allow = MAX(dihedrals_allow,styles[m]->dihedrals_allow);
-    impropers_allow = MAX(impropers_allow,styles[m]->impropers_allow);
-    mass_type = MAX(mass_type,styles[m]->mass_type);
-    dipole_type = MAX(dipole_type,styles[m]->dipole_type);
-    comm_x_only = MIN(comm_x_only,styles[m]->comm_x_only);
-    comm_f_only = MIN(comm_f_only,styles[m]->comm_f_only);
-    size_comm = MAX(size_comm,styles[m]->size_comm);
-    size_reverse = MAX(size_reverse,styles[m]->size_reverse);
-    size_border = MAX(size_border,styles[m]->size_border) + 1;
+  // hybrid sizes are minimial values plus extra values for each sub-style
+
+  size_comm = 3;
+  size_reverse = 3;
+  size_border = 6;
+  size_data_atom = 5;
+  size_data_vel = 4;
+  xcol_data = 3;
+
+  for (k = 0; k < nstyles; k++) {
+    molecular = MAX(molecular,styles[k]->molecular);
+    bonds_allow = MAX(bonds_allow,styles[k]->bonds_allow);
+    angles_allow = MAX(angles_allow,styles[k]->angles_allow);
+    dihedrals_allow = MAX(dihedrals_allow,styles[k]->dihedrals_allow);
+    impropers_allow = MAX(impropers_allow,styles[k]->impropers_allow);
+    mass_type = MAX(mass_type,styles[k]->mass_type);
+    shape_type = MAX(shape_type,styles[k]->shape_type);
+    dipole_type = MAX(dipole_type,styles[k]->dipole_type);
+    comm_x_only = MIN(comm_x_only,styles[k]->comm_x_only);
+    comm_f_only = MIN(comm_f_only,styles[k]->comm_f_only);
+    size_comm += styles[k]->size_comm - 3;
+    size_reverse += styles[k]->size_reverse - 3;
+    size_border += styles[k]->size_border - 6;
+    size_data_atom += styles[k]->size_data_atom - 5;
+    size_data_vel += styles[k]->size_data_vel - 4;
   }
 }
 
@@ -77,9 +87,9 @@ AtomVecHybrid::AtomVecHybrid(LAMMPS *lmp, int narg, char **arg) :
 
 AtomVecHybrid::~AtomVecHybrid()
 {
-  for (int m = 0; m < nstyles; m++) delete styles[m];
+  for (int k = 0; k < nstyles; k++) delete styles[k];
   delete [] styles;
-  for (int m = 0; m < nstyles; m++) delete [] keywords[m];
+  for (int k = 0; k < nstyles; k++) delete [] keywords[k];
   delete [] keywords;
 }
 
@@ -97,7 +107,7 @@ void AtomVecHybrid::grow(int n)
 
   int tmp = atom->nextra_grow;
   atom->nextra_grow = 0;
-  for (int m = 0; m < nstyles; m++) styles[m]->grow(nmax);
+  for (int k = 0; k < nstyles; k++) styles[k]->grow(nmax);
   atom->nextra_grow = tmp;
 
   // pointers for arrays used directly by hybrid style
@@ -110,9 +120,6 @@ void AtomVecHybrid::grow(int n)
   v = atom->v;
   f = atom->f;
 
-  hybrid = atom->hybrid = (int *) 
-    memory->srealloc(atom->hybrid,nmax*sizeof(int),"atom:hybrid");
-
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
@@ -120,33 +127,25 @@ void AtomVecHybrid::grow(int n)
 
 /* ---------------------------------------------------------------------- */
 
-void AtomVecHybrid::reset_ptrs()
+void AtomVecHybrid::reset_special()
 {
-  for (int m = 0; m < nstyles; m++) styles[m]->reset_ptrs();
-
-  tag = atom->tag;
-  type = atom->type;
-  mask = atom->mask;
-  image = atom->image;
-  x = atom->x;
-  v = atom->v;
-  f = atom->f;
-
-  hybrid = atom->hybrid;
+  for (int k = 0; k < nstyles; k++) styles[k]->reset_special();
 }
 
 /* ----------------------------------------------------------------------
-   copy array values based on hybrid style of atom i
-   zero auxiliary arrays for all other styles before copy
+   copy array values for all sub-styles
 ------------------------------------------------------------------------- */
 
 void AtomVecHybrid::copy(int i, int j)
 {
-  int ihybrid = hybrid[i];
-  for (int m = 0; m < nstyles; m++)
-    if (m != ihybrid) styles[m]->zero_owned(j);
-  styles[ihybrid]->copy(i,j);
-  hybrid[j] = ihybrid;
+  int tmp = atom->nextra_grow;
+  atom->nextra_grow = 0;
+  for (int k = 0; k < nstyles; k++) styles[k]->copy(i,j);
+  atom->nextra_grow = tmp;
+
+  if (atom->nextra_grow)
+    for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
+      modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
@@ -154,7 +153,7 @@ void AtomVecHybrid::copy(int i, int j)
 int AtomVecHybrid::pack_comm(int n, int *list, double *buf,
 			     int pbc_flag, int *pbc)
 {
-  int i,j,m;
+  int i,j,k,m;
   double dx,dy,dz;
 
   m = 0;
@@ -164,7 +163,8 @@ int AtomVecHybrid::pack_comm(int n, int *list, double *buf,
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
-      m += styles[hybrid[j]]->pack_comm_one(j,&buf[m]);
+      for (k = 0; k < nstyles; k++)
+	m += styles[k]->pack_comm_one(j,&buf[m]);
     }
   } else {
     if (domain->triclinic == 0) {
@@ -181,7 +181,8 @@ int AtomVecHybrid::pack_comm(int n, int *list, double *buf,
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
-      m += styles[hybrid[j]]->pack_comm_one(j,&buf[m]);
+      for (k = 0; k < nstyles; k++)
+	m += styles[k]->pack_comm_one(j,&buf[m]);
     }
   }
   return m;
@@ -191,15 +192,16 @@ int AtomVecHybrid::pack_comm(int n, int *list, double *buf,
 
 void AtomVecHybrid::unpack_comm(int n, int first, double *buf)
 {
-  int i,m,last;
+  int i,k,last;
 
-  m = 0;
+  int m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    m += styles[hybrid[i]]->unpack_comm_one(i,&buf[m]);
+    for (k = 0; k < nstyles; k++)
+      m += styles[k]->unpack_comm_one(i,&buf[m]);
   }
 }
 
@@ -207,15 +209,16 @@ void AtomVecHybrid::unpack_comm(int n, int first, double *buf)
 
 int AtomVecHybrid::pack_reverse(int n, int first, double *buf)
 {
-  int i,m,last;
+  int i,k,last;
 
-  m = 0;
+  int m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
-    m += styles[hybrid[i]]->pack_reverse_one(i,&buf[m]);
+    for (k = 0; k < nstyles; k++)
+      m += styles[k]->pack_reverse_one(i,&buf[m]);
   }
   return m;
 }
@@ -224,7 +227,7 @@ int AtomVecHybrid::pack_reverse(int n, int first, double *buf)
 
 void AtomVecHybrid::unpack_reverse(int n, int *list, double *buf)
 {
-  int i,j,m;
+  int i,j,k,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
@@ -232,7 +235,8 @@ void AtomVecHybrid::unpack_reverse(int n, int *list, double *buf)
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
-    m += styles[hybrid[j]]->unpack_reverse_one(j,&buf[m]);
+    for (k = 0; k < nstyles; k++)
+      m += styles[k]->unpack_reverse_one(j,&buf[m]);
   }
 }
 
@@ -241,7 +245,7 @@ void AtomVecHybrid::unpack_reverse(int n, int *list, double *buf)
 int AtomVecHybrid::pack_border(int n, int *list, double *buf,
 			       int pbc_flag, int *pbc)
 {
-  int i,j,m;
+  int i,j,k,m;
   double dx,dy,dz;
 
   m = 0;
@@ -254,8 +258,8 @@ int AtomVecHybrid::pack_border(int n, int *list, double *buf,
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
-      buf[m++] = hybrid[j];
-      m += styles[hybrid[j]]->pack_border_one(j,&buf[m]);
+      for (k = 0; k < nstyles; k++)
+	m += styles[k]->pack_border_one(j,&buf[m]);
     }
   } else {
     if (domain->triclinic == 0) {
@@ -275,24 +279,18 @@ int AtomVecHybrid::pack_border(int n, int *list, double *buf,
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
-      buf[m++] = hybrid[j];
-      m += styles[hybrid[j]]->pack_border_one(j,&buf[m]);
+      for (k = 0; k < nstyles; k++)
+	m += styles[k]->pack_border_one(j,&buf[m]);
     }
   }
   return m;
 }
 
-/* ----------------------------------------------------------------------
-   unpack border ghost atom data
-   zero auxiliary ghost arrays for all styles before unpack
-   grow() is called in zero_ghost() and here (in case zero_ghost is no-op)
-------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------- */
 
 void AtomVecHybrid::unpack_border(int n, int first, double *buf)
 {
-  int i,m,last;
-
-  for (m = 0; m < nstyles; m++) styles[m]->zero_ghost(n,first);
+  int i,k,m,last;
 
   m = 0;
   last = first + n;
@@ -304,30 +302,40 @@ void AtomVecHybrid::unpack_border(int n, int first, double *buf)
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
-    hybrid[i] = static_cast<int> (buf[m++]);
-    m += styles[hybrid[i]]->unpack_border_one(i,&buf[m]);
+    for (k = 0; k < nstyles; k++)
+      m += styles[k]->unpack_border_one(i,&buf[m]);
   }
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
-   sub-style does packing
-   append hybrid[i] and increment count stored in buf[0]
+   pack each sub-style one after the other
 ------------------------------------------------------------------------- */
 
 int AtomVecHybrid::pack_exchange(int i, double *buf)
 {
-  int m = styles[hybrid[i]]->pack_exchange(i,buf);
-  buf[m++] = hybrid[i];
-  buf[0] = m;
+  int k;
+
+  int tmp = atom->nextra_grow;
+  atom->nextra_grow = 0;
+
+  int m = 0;
+  for (k = 0; k < nstyles; k++) 
+    m += styles[k]->pack_exchange(i,&buf[m]);
+
+  atom->nextra_grow = tmp;
+
+  if (atom->nextra_grow)
+    for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
+      m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
+
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for single atom received from another proc
-   sub-style does unpacking
-   grow() must occur here so arrays for all sub-styles are grown
-   extract hybrid[nlocal] from end of buf
+   unpack each sub-style one after the other
+   grow() occurs here so arrays for all sub-styles are grown
 ------------------------------------------------------------------------- */
 
 int AtomVecHybrid::unpack_exchange(double *buf)
@@ -335,9 +343,23 @@ int AtomVecHybrid::unpack_exchange(double *buf)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  int m = static_cast<int> (buf[0]);
-  hybrid[nlocal] = static_cast<int> (buf[m-1]);
-  int tmp = styles[hybrid[nlocal]]->unpack_exchange(buf);
+  int tmp = atom->nextra_grow;
+  atom->nextra_grow = 0;
+
+  int m = 0;
+  for (int k = 0; k < nstyles; k++) {
+    m += styles[k]->unpack_exchange(buf);
+    atom->nlocal--;
+  }
+
+  atom->nextra_grow = tmp;
+
+  if (atom->nextra_grow)
+    for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
+      m += modify->fix[atom->extra_grow[iextra]]->
+	unpack_exchange(nlocal,&buf[m]);
+
+  atom->nlocal++;
   return m;
 }
 
@@ -348,19 +370,19 @@ int AtomVecHybrid::unpack_exchange(double *buf)
 
 int AtomVecHybrid::size_restart()
 {
-  int i;
-  int nlocal = atom->nlocal;
-
-  // nlocal is added for per-atom hybrid value appended by pack_restart()
+  int tmp = atom->nextra_restart;
+  atom->nextra_restart = 0;
 
   int n = 0;
-  for (i = 0; i < nlocal; i++)
-    n += styles[hybrid[i]]->size_restart_one(i);
-  n += nlocal;
+  for (int k = 0; k < nstyles; k++)
+    n += styles[k]->size_restart();
+
+  atom->nextra_restart = tmp;
 
+  int nlocal = atom->nlocal;
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
-      for (i = 0; i < nlocal; i++)
+      for (int i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
@@ -368,24 +390,33 @@ int AtomVecHybrid::size_restart()
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
-   sub-style does packing
-   append hybrid[i] and increment count stored in buf[0]
+   xyz must be 1st 3 values, so that read_restart can test on them
+   pack each sub-style one after the other
 ------------------------------------------------------------------------- */
 
 int AtomVecHybrid::pack_restart(int i, double *buf)
 {
-  int m = styles[hybrid[i]]->pack_restart(i,buf);
-  buf[m++] = hybrid[i];
+  int tmp = atom->nextra_restart;
+  atom->nextra_restart = 0;
+
+  int m = 0;
+  for (int k = 0; k < nstyles; k++)
+    m += styles[k]->pack_restart(i,&buf[m]);
+
+  atom->nextra_restart = tmp;
+
+  if (atom->nextra_restart)
+    for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
+      m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
+
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
-   sub-style does unpacking
-   grow() must occur here so arrays for all sub-styles are grown
-   zero auxiliary arrays for all other styles before unpack
-   extract hybrid[nlocal] from end of buf
+   unpack each sub-style one after the other
+   grow() occurs here so arrays for all sub-styles are grown
 ------------------------------------------------------------------------- */
 
 int AtomVecHybrid::unpack_restart(double *buf)
@@ -399,74 +430,93 @@ int AtomVecHybrid::unpack_restart(double *buf)
 						 "atom:extra");
   }
 
-  int m = static_cast<int> (buf[0]);
-  int ihybrid = static_cast<int> (buf[m-1]);
-  for (int m = 0; m < nstyles; m++)
-    if (m != ihybrid) styles[m]->zero_owned(nlocal);
-  hybrid[nlocal] = ihybrid;
+  int tmp = atom->nextra_store;
+  atom->nextra_store = 0;
 
-  // size of extra unpack in sub-style includes end-of-buf entry of hybrid
-  // avoid this by resetting buf[0] to one less
+  int m = 0;
+  for (int k = 0; k < nstyles; k++) {
+    m += styles[k]->unpack_restart(&buf[m]);
+    atom->nlocal--;
+  }
+  atom->nextra_store = tmp;
 
-  buf[0] = m-1;
-  int tmp = styles[ihybrid]->unpack_restart(buf);
+  double **extra = atom->extra;
+  if (atom->nextra_store) {
+    int size = static_cast<int> (buf[0]) - m;
+    for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
+  }
+
+  atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
-   create one atom of itype at coord for ihybrid style
-   sub-style does create
-   grow() must occur here so arrays for all sub-styles are grown
-   zero auxiliary arrays for all other styles before create
+   create one atom of itype at coord
+   create each sub-style one after the other
+   grow() occurs here so arrays for all sub-styles are grown
 ------------------------------------------------------------------------- */
 
-void AtomVecHybrid::create_atom(int itype, double *coord, int ihybrid)
+void AtomVecHybrid::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  for (int m = 0; m < nstyles; m++)
-    if (m != ihybrid) styles[m]->zero_owned(nlocal);
-  hybrid[nlocal] = ihybrid;
-  styles[ihybrid]->create_atom(itype,coord,0);
+  for (int k = 0; k < nstyles; k++) {
+    styles[k]->create_atom(itype,coord);
+    atom->nlocal--;
+  }
+  atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
-   zero auxiliary arrays for all other styles before unpack
-   sub-style will increment nlocal
+   grow() occurs here so arrays for all sub-styles are grown
 ------------------------------------------------------------------------- */
 
-void AtomVecHybrid::data_atom(double *coord, int imagetmp, char **values,
-			      int ihybrid)
+void AtomVecHybrid::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  for (int m = 0; m < nstyles; m++)
-    if (m != ihybrid) styles[m]->zero_owned(nlocal);
-  hybrid[nlocal] = ihybrid;
-  styles[ihybrid]->data_atom(coord,imagetmp,values,0);
+  tag[nlocal] = atoi(values[0]);
+  if (tag[nlocal] <= 0)
+    error->one("Invalid atom ID in Atoms section of data file");
+
+  type[nlocal] = atoi(values[1]);
+  if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
+    error->one("Invalid atom type in Atoms section of data file");
+
+  x[nlocal][0] = coord[0];
+  x[nlocal][1] = coord[1];
+  x[nlocal][2] = coord[2];
+
+  image[nlocal] = imagetmp;
+  mask[nlocal] = 1;
+
+  // each sub-style parses sub-style specific values
+
+  int m = 5;
+  for (int k = 0; k < nstyles; k++) 
+    m += styles[k]->data_atom_hybrid(nlocal,&values[m]);
+
+  atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Velocities section of data file
 ------------------------------------------------------------------------- */
 
-void AtomVecHybrid::data_vel(int m, char *line, int ihybrid)
+void AtomVecHybrid::data_vel(int m, char **values)
 {
-  styles[ihybrid]->data_vel(m,line,0);
-}
+  v[m][0] = atof(values[0]);
+  v[m][1] = atof(values[1]);
+  v[m][2] = atof(values[2]);
 
-/* ----------------------------------------------------------------------
-   set data file parameters for ihybrid sub-style
-------------------------------------------------------------------------- */
+  // each sub-style parses sub-style specific values
 
-void AtomVecHybrid::data_params(int ihybrid)
-{
-  size_data_atom = styles[ihybrid]->size_data_atom;
-  size_data_vel = styles[ihybrid]->size_data_vel;
-  xcol_data = styles[ihybrid]->xcol_data;
+  int n = 3;
+  for (int k = 0; k < nstyles; k++) 
+    n += styles[k]->data_vel_hybrid(m,&values[n]);
 }
 
 /* ----------------------------------------------------------------------
@@ -476,8 +526,6 @@ void AtomVecHybrid::data_params(int ihybrid)
 int AtomVecHybrid::memory_usage()
 {
   int bytes = 0;
-  for (int m = 0; m < nstyles; m++)
-    bytes += styles[m]->memory_usage();
-  if (atom->memcheck("hybrid")) bytes += nmax * sizeof(int);
+  for (int k = 0; k < nstyles; k++) bytes += styles[k]->memory_usage();
   return bytes;
 }
diff --git a/src/atom_vec_hybrid.h b/src/atom_vec_hybrid.h
index 50e688830dae9ab82a323c73c6cf9ed5ba7a0962..456363a844251b42f4d62e67adca2365204dfae9 100644
--- a/src/atom_vec_hybrid.h
+++ b/src/atom_vec_hybrid.h
@@ -27,7 +27,7 @@ class AtomVecHybrid : public AtomVec {
   AtomVecHybrid(class LAMMPS *, int, char **);
   ~AtomVecHybrid();
   void grow(int);
-  void reset_ptrs();
+  void reset_special();
   void copy(int, int);
   int pack_comm(int, int *, double *, int, int *);
   void unpack_comm(int, int, double *);
@@ -38,19 +38,17 @@ class AtomVecHybrid : public AtomVec {
   int pack_exchange(int, double *);
   int unpack_exchange(double *);
   int size_restart();
-  int size_restart_one(int) {return 0;}
   int pack_restart(int, double *);
   int unpack_restart(double *);
-  void create_atom(int, double *, int);
-  void data_atom(double *, int, char **, int);
-  void data_vel(int, char *, int);
-  void data_params(int);
+  void create_atom(int, double *);
+  void data_atom(double *, int, char **);
+  int data_atom_hybrid(int, char **) {return 0;}
+  void data_vel(int, char **);
   int memory_usage();
 
  private:
   int *tag,*type,*mask,*image;
   double **x,**v,**f;
-  int *hybrid;
 };
 
 }
diff --git a/src/comm.cpp b/src/comm.cpp
index 425ea1265f8467446a7b5318d5665bea8cf6e69b..c955e0ce14d4ff20b478ddb1fa5b16bfdecdac7f 100644
--- a/src/comm.cpp
+++ b/src/comm.cpp
@@ -11,6 +11,10 @@
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
+/* ----------------------------------------------------------------------
+   Contributing author (triclinic) : Pieter in 't Veld (SNL)
+------------------------------------------------------------------------- */
+
 #include "math.h"
 #include "string.h"
 #include "stdio.h"
diff --git a/src/compute_centro_atom.cpp b/src/compute_centro_atom.cpp
index e9779fd45e91513ead1650ccd5f3fbc24cd9bc45..04b9383f3282ea6e8e8c0761e936e173a228897b 100644
--- a/src/compute_centro_atom.cpp
+++ b/src/compute_centro_atom.cpp
@@ -60,7 +60,7 @@ void ComputeCentroAtom::init()
   for (int i = 0; i < modify->ncompute; i++)
     if (strcmp(modify->compute[i]->style,"centro/atom") == 0) count++;
   if (count > 1 && comm->me == 0)
-    error->warning("More than one compute centro/atom defined");
+    error->warning("More than one compute centro/atom");
 }
 
 /* ---------------------------------------------------------------------- */
diff --git a/src/compute_coord_atom.cpp b/src/compute_coord_atom.cpp
index 8a4de20b3de46a9749619689ed17f773c7eedcb0..f101c4b38f105313f0d225adfe3bdb51edec6c12 100644
--- a/src/compute_coord_atom.cpp
+++ b/src/compute_coord_atom.cpp
@@ -60,7 +60,7 @@ void ComputeCoordAtom::init()
   for (int i = 0; i < modify->ncompute; i++)
     if (strcmp(modify->compute[i]->style,"coord/atom") == 0) count++;
   if (count > 1 && comm->me == 0)
-    error->warning("More than one compute coord/atom defined");
+    error->warning("More than one compute coord/atom");
 }
 
 /* ---------------------------------------------------------------------- */
diff --git a/src/compute_epair_atom.cpp b/src/compute_epair_atom.cpp
index 31e05f22c8e5555bb7a31304e63c5a16e09a957e..a4a81602024ddbd576c63cb755067bbd0ed635e8 100644
--- a/src/compute_epair_atom.cpp
+++ b/src/compute_epair_atom.cpp
@@ -65,7 +65,7 @@ void ComputeEpairAtom::init()
   for (int i = 0; i < modify->ncompute; i++)
     if (strcmp(modify->compute[i]->style,"epair/atom") == 0) count++;
   if (count > 1 && comm->me == 0)
-    error->warning("More than one compute epair/atom defined");
+    error->warning("More than one compute epair/atom");
 }
 
 /* ---------------------------------------------------------------------- */
diff --git a/src/compute_etotal_atom.cpp b/src/compute_etotal_atom.cpp
index bc460b77bf98d927155cc7a9391d4d9fdc042851..ddf92f9c283ec7471cb6efdb53149ddcef3f99fd 100644
--- a/src/compute_etotal_atom.cpp
+++ b/src/compute_etotal_atom.cpp
@@ -58,7 +58,7 @@ void ComputeEtotalAtom::init()
   for (int i = 0; i < modify->ncompute; i++)
     if (strcmp(modify->compute[i]->style,"etotal/atom") == 0) count++;
   if (count > 1 && comm->me == 0)
-    error->warning("More than one compute etotal/atom defined");
+    error->warning("More than one compute etotal/atom");
 
   // set epair Compute used by this compute
 
diff --git a/src/compute_ke_atom.cpp b/src/compute_ke_atom.cpp
index 22c8573233458f0a4fc90a7934ed153b2bba8353..9734594165bed771c7b83e9ad13692d3e81ee901 100644
--- a/src/compute_ke_atom.cpp
+++ b/src/compute_ke_atom.cpp
@@ -51,7 +51,7 @@ void ComputeKEAtom::init()
   for (int i = 0; i < modify->ncompute; i++)
     if (strcmp(modify->compute[i]->style,"ke/atom") == 0) count++;
   if (count > 1 && comm->me == 0)
-    error->warning("More than one compute ke/atom defined");
+    error->warning("More than one compute ke/atom");
 }
 
 /* ---------------------------------------------------------------------- */
diff --git a/src/compute_pressure.cpp b/src/compute_pressure.cpp
index 16ee3c7ca988db4233e7e57cae5a8ea737d089f2..687d893fedc5e673b1dfdf4a83ceecd597e28523 100644
--- a/src/compute_pressure.cpp
+++ b/src/compute_pressure.cpp
@@ -58,6 +58,8 @@ ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) :
   pressflag = 1;
 
   vector = new double[6];
+  nvirial = 0;
+  vptr = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
@@ -66,6 +68,7 @@ ComputePressure::~ComputePressure()
 {
   delete [] id_pre;
   delete [] vector;
+  delete [] vptr;
 }
 
 /* ---------------------------------------------------------------------- */
@@ -81,57 +84,41 @@ void ComputePressure::init()
   if (icompute < 0) error->all("Could not find compute pressure temp ID");
   temperature = modify->compute[icompute];
 
-  // set flags/ptrs for all contributions to virial
-    
-  pairflag = bondflag = angleflag = dihedralflag = improperflag = 0;
-  kspaceflag = 0;
-  shakeflag = bodyflag = rigidflag = poemsflag = 0;
-
-  if (force->pair) {
-    pairflag = 1;
-    pair_virial = force->pair->virial;
-  }
-  if (atom->molecular) {
-    if (force->bond) {
-      bondflag = 1;
-      bond_virial = force->bond->virial;
-    }
-    if (force->angle) {
-      angleflag = 1;
-      angle_virial = force->angle->virial;
-    }
-    if (force->dihedral) {
-      dihedralflag = 1;
-      dihedral_virial = force->dihedral->virial;
-    }
-    if (force->improper) {
-      improperflag = 1;
-      improper_virial = force->improper->virial;
-    }
+  // detect contributions to virial
+  // vptr points to all virial[6] contributions
+
+  delete [] vptr;
+  nvirial = 0;
+  vptr = NULL;
+
+  if (force->pair) nvirial++;
+  if (atom->molecular && force->bond) nvirial++;
+  if (atom->molecular && force->angle) nvirial++;
+  if (atom->molecular && force->dihedral) nvirial++;
+  if (atom->molecular && force->improper) nvirial++;
+  for (int i = 0; i < modify->nfix; i++)
+    if (modify->fix[i]->virial_flag) nvirial++;
+
+  if (nvirial) {
+    vptr = new double*[nvirial];
+    nvirial = 0;
+    if (force->pair) vptr[nvirial++] = force->pair->virial;
+    if (force->bond) vptr[nvirial++] = force->bond->virial;
+    if (force->angle) vptr[nvirial++] = force->angle->virial;
+    if (force->dihedral) vptr[nvirial++] = force->dihedral->virial;
+    if (force->improper) vptr[nvirial++] = force->improper->virial;
+    for (int i = 0; i < modify->nfix; i++)
+      if (modify->fix[i]->virial_flag)
+	vptr[nvirial++] = modify->fix[i]->virial;
   }
 
+  // flag Kspace contribution separately, since not summed across procs
+
+  kspaceflag = 0;
   if (force->kspace) {
     kspaceflag = 1;
     kspace_virial = force->kspace->virial;
   }
-
-  for (int i = 0; i < modify->nfix; i++) {
-    if (strcmp(modify->fix[i]->style,"shake") == 0) {
-      shakeflag = 1;
-      shake_virial = modify->fix[i]->virial;
-    }
-    if (strcmp(modify->fix[i]->style,"rigid") == 0 ||
-	strcmp(modify->fix[i]->style,"poems") == 0) {
-      bodyflag = 1;
-      if (strcmp(modify->fix[i]->style,"rigid") == 0) {
-	rigidflag = 1;
-	rigid_virial = modify->fix[i]->virial;
-      } else {
-	poemsflag = 1;
-	poems_virial = modify->fix[i]->virial;
-      }
-    }
-  }
 }
 
 /* ----------------------------------------------------------------------
@@ -166,32 +153,16 @@ void ComputePressure::compute_vector()
 
 void ComputePressure::virial_compute(int n)
 {
-  int i;
-  double v[6];
+  int i,j;
+  double v[6],*vcomponent;
 
   for (i = 0; i < n; i++) v[i] = 0.0;
 
-  // sum contributions to virial from various forces and fixes
-
-  if (pairflag)
-    for (i = 0; i < n; i++) v[i] += pair_virial[i];
-
-  if (atom->molecular) {
-    if (bondflag)
-      for (i = 0; i < n; i++) v[i] += bond_virial[i];
-    if (angleflag)
-      for (i = 0; i < n; i++) v[i] += angle_virial[i];
-    if (dihedralflag)
-      for (i = 0; i < n; i++) v[i] += dihedral_virial[i];
-    if (improperflag)
-      for (i = 0; i < n; i++) v[i] += improper_virial[i];
-    if (shakeflag)
-      for (i = 0; i < n; i++) v[i] += shake_virial[i];
-  }
+  // sum contributions to virial from forces and fixes
 
-  if (bodyflag) {
-    if (rigidflag) for (i = 0; i < n; i++) v[i] += rigid_virial[i];
-    if (poemsflag) for (i = 0; i < n; i++) v[i] += poems_virial[i];
+  for (j = 0; j < nvirial; j++) {
+    vcomponent = vptr[j];
+    for (i = 0; i < n; i++) v[i] += vcomponent[i];
   }
 
   // sum virial across procs
diff --git a/src/compute_pressure.h b/src/compute_pressure.h
index 03c018140ced86c3c427539afbbd2a917ec18c5c..2ebe6a68532820ccd204ea43667fc743580f69e8 100644
--- a/src/compute_pressure.h
+++ b/src/compute_pressure.h
@@ -28,11 +28,10 @@ class ComputePressure : public Compute {
 
  private:
   double boltz,nktv2p,inv_volume;
-  double *pair_virial,*bond_virial,*angle_virial;
-  double *dihedral_virial,*improper_virial,*kspace_virial;
-  double *shake_virial,*rigid_virial,*poems_virial;
-  int pairflag,bondflag,angleflag,dihedralflag,improperflag,kspaceflag;
-  int shakeflag,bodyflag,rigidflag,poemsflag;
+  int nvirial;
+  double **vptr;
+  int kspaceflag;
+  double *kspace_virial;
   Compute *temperature;
   double virial[6];
 
diff --git a/src/compute_rotate_dipole.cpp b/src/compute_rotate_dipole.cpp
index e20eee7e8085464d831d101acbe0cd81eb36e653..74c510ed1356a6c611d3914e5e2e8e103ae92a61 100644
--- a/src/compute_rotate_dipole.cpp
+++ b/src/compute_rotate_dipole.cpp
@@ -15,7 +15,6 @@
 #include "compute_rotate_dipole.h"
 #include "atom.h"
 #include "force.h"
-#include "pair.h"
 #include "group.h"
 #include "error.h"
 
@@ -31,8 +30,8 @@ ComputeRotateDipole::ComputeRotateDipole(LAMMPS *lmp, int narg, char **arg) :
 {
   if (narg != 3) error->all("Illegal compute rotate/dipole command");
 
-  if (atom->check_style("dipole") == 0)
-    error->all("Must use atom style dipole with compute rotate/dipole");
+  if (atom->dipole == NULL || atom->omega == NULL)
+    error->all("Compute rotate/dipole requires atom attributes dipole, omega");
 
   scalar_flag = 1;
   extensive = 1;
@@ -53,23 +52,16 @@ void ComputeRotateDipole::init()
 {
   delete [] inertia;
   inertia = new double[atom->ntypes+1];
-  double *mass = atom->mass;
-
-  // insure use of dipole pair_style
-  // set sigma to Pair's sigma
 
-  Pair *pair = force->pair_match("dipole");
-  if (pair == NULL)
-    error->all("Pair style is incompatible with compute rotate/dipole");
-  double **sigma;
-  pair->extract_dipole(&sigma);
+  double *mass = atom->mass;
+  double **shape = atom->shape;
 
   if (force->dimension == 3)
     for (int i = 1; i <= atom->ntypes; i++)
-      inertia[i] = INERTIA3D * mass[i] * 0.25*sigma[i][i]*sigma[i][i];
+      inertia[i] = INERTIA3D * mass[i] * 0.25*shape[i][0]*shape[i][0];
   else
     for (int i = 1; i <= atom->ntypes; i++)
-      inertia[i] = INERTIA2D * mass[i] * 0.25*sigma[i][i]*sigma[i][i];
+      inertia[i] = INERTIA2D * mass[i] * 0.25*shape[i][0]*shape[i][0];
 }
 
 /* ---------------------------------------------------------------------- */
diff --git a/src/compute_rotate_gran.cpp b/src/compute_rotate_gran.cpp
index db31531b9a917bd7f20940c314a94540a556e77f..7707d0eef3ae108d2cccc9b3ab3862a981744c76 100644
--- a/src/compute_rotate_gran.cpp
+++ b/src/compute_rotate_gran.cpp
@@ -30,8 +30,9 @@ ComputeRotateGran::ComputeRotateGran(LAMMPS *lmp, int narg, char **arg) :
 {
   if (narg != 3) error->all("Illegal compute rotate/gran command");
 
-  if (atom->check_style("granular") == 0)
-    error->all("Must use atom style granular with compute rotate/gran");
+  if (atom->radius == NULL || atom->rmass == NULL || atom->omega == NULL)
+    error->all("Compute rotate/gran requires atom attributes "
+	       "radius, rmass, omega");
 
   scalar_flag = 1;
   extensive = 1;
diff --git a/src/compute_stress_atom.cpp b/src/compute_stress_atom.cpp
index 32fd21495a9cc78ba3808464f6beb16c76f94fef..7353c3272319fff0657a0950eafbc96d152e4639 100644
--- a/src/compute_stress_atom.cpp
+++ b/src/compute_stress_atom.cpp
@@ -62,7 +62,7 @@ void ComputeStressAtom::init()
   for (int i = 0; i < modify->ncompute; i++)
     if (strcmp(modify->compute[i]->style,"stress/atom") == 0) count++;
   if (count > 1 && comm->me == 0)
-    error->warning("More than one compute stress/atom defined");
+    error->warning("More than one compute stress/atom");
 }
 
 /* ---------------------------------------------------------------------- */
diff --git a/src/compute_temp_ramp.cpp b/src/compute_temp_ramp.cpp
index a22714b2943c3713bd0c03c3046f0c69bdbd541f..d7025caa53d7b4854afcbe1453645ed43f781416 100644
--- a/src/compute_temp_ramp.cpp
+++ b/src/compute_temp_ramp.cpp
@@ -139,7 +139,7 @@ void ComputeTempRamp::recount()
 
 double ComputeTempRamp::compute_scalar()
 {
-  double fraction,vramp,vtmp[3];
+  double fraction,vramp,vthermal[3];
 
   double **x = atom->x;
   double **v = atom->v;
@@ -156,15 +156,16 @@ double ComputeTempRamp::compute_scalar()
       fraction = MAX(fraction,0.0);
       fraction = MIN(fraction,1.0);
       vramp = v_lo + fraction*(v_hi - v_lo);
-      vtmp[0] = v[i][0];
-      vtmp[1] = v[i][1];
-      vtmp[2] = v[i][2];
-      vtmp[v_dim] -= vramp;
+      vthermal[0] = v[i][0];
+      vthermal[1] = v[i][1];
+      vthermal[2] = v[i][2];
+      vthermal[v_dim] -= vramp;
       if (mass)
-	t += (vtmp[0]*vtmp[0] + vtmp[1]*vtmp[1] + vtmp[2]*vtmp[2]) * 
-	  mass[type[i]];
+	t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] + 
+	      vthermal[2]*vthermal[2]) * mass[type[i]];
       else
-	t += (vtmp[0]*vtmp[0] + vtmp[1]*vtmp[1] + vtmp[2]*vtmp[2]) * rmass[i];
+	t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] + 
+	      vthermal[2]*vthermal[2]) * rmass[i];
     }
 
   MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
@@ -178,7 +179,7 @@ double ComputeTempRamp::compute_scalar()
 void ComputeTempRamp::compute_vector()
 {
   int i;
-  double fraction,vramp,vtmp[3];
+  double fraction,vramp,vthermal[3];
 
   double **x = atom->x;
   double **v = atom->v;
@@ -197,19 +198,19 @@ void ComputeTempRamp::compute_vector()
       fraction = MAX(fraction,0.0);
       fraction = MIN(fraction,1.0);
       vramp = v_lo + fraction*(v_hi - v_lo);
-      vtmp[0] = v[i][0];
-      vtmp[1] = v[i][1];
-      vtmp[2] = v[i][2];
-      vtmp[v_dim] -= vramp;
+      vthermal[0] = v[i][0];
+      vthermal[1] = v[i][1];
+      vthermal[2] = v[i][2];
+      vthermal[v_dim] -= vramp;
 
       if (mass) massone = mass[type[i]];
       else massone = rmass[i];
-      t[0] += massone * vtmp[0]*vtmp[0];
-      t[1] += massone * vtmp[1]*vtmp[1];
-      t[2] += massone * vtmp[2]*vtmp[2];
-      t[3] += massone * vtmp[0]*vtmp[1];
-      t[4] += massone * vtmp[0]*vtmp[2];
-      t[5] += massone * vtmp[1]*vtmp[2];
+      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);
diff --git a/src/compute_temp_region.cpp b/src/compute_temp_region.cpp
index 04e7117ae5e13183fe0d558dc3282d54c1a19417..fa781859b0c6b15bbddf1ab23fbad12630eeafeb 100644
--- a/src/compute_temp_region.cpp
+++ b/src/compute_temp_region.cpp
@@ -29,10 +29,8 @@ ComputeTempRegion::ComputeTempRegion(LAMMPS *lmp, int narg, char **arg) :
 {
   if (narg != 4) error->all("Illegal compute temp/region command");
 
-  for (iregion = 0; iregion < domain->nregion; iregion++)
-    if (strcmp(arg[3],domain->regions[iregion]->id) == 0) break;
-  if (iregion == domain->nregion)
-    error->all("Temperature region ID does not exist");
+  iregion = domain->find_region(arg[3]);
+  if (iregion == -1) error->all("Temperature region ID does not exist");
 
   scalar_flag = vector_flag = 1;
   size_vector = 6;
diff --git a/src/create_atoms.cpp b/src/create_atoms.cpp
index 33bf007b5f9660a5411de5041b070e41908ec6d0..52f8d163667bca57396dba08da432ebd1090051f 100644
--- a/src/create_atoms.cpp
+++ b/src/create_atoms.cpp
@@ -17,7 +17,6 @@
 #include "create_atoms.h"
 #include "atom.h"
 #include "atom_vec.h"
-#include "atom_vec_hybrid.h"
 #include "comm.h"
 #include "domain.h"
 #include "lattice.h"
@@ -30,6 +29,8 @@ using namespace LAMMPS_NS;
 #define BIG      1.0e30
 #define EPSILON  1.0e-6
 
+enum{BOX,REGION,SINGLE};
+
 /* ---------------------------------------------------------------------- */
 
 CreateAtoms::CreateAtoms(LAMMPS *lmp) : Pointers(lmp) {}
@@ -40,36 +41,48 @@ void CreateAtoms::command(int narg, char **arg)
 {
   if (domain->box_exist == 0) 
     error->all("Create_atoms command before simulation box is defined");
-  if (domain->lattice == NULL)
-    error->all("Cannot create atoms with undefined lattice");
 
   // parse arguments
 
-  int nbasis = domain->lattice->nbasis;
-  int *basistype = new int[nbasis];
-
-  if (narg < 1) error->all("Illegal create_atoms command");
-  int itype = atoi(arg[0]);
+  if (narg < 2) error->all("Illegal create_atoms command");
+  itype = atoi(arg[0]);
   if (itype <= 0 || itype > atom->ntypes) 
     error->all("Invalid atom type in create_atoms command");
-  for (int i = 0; i < nbasis; i++) basistype[i] = itype;
 
-  int regionflag = -1;
-  int nhybrid = 0;
+  int iarg;
+  if (strcmp(arg[1],"box") == 0) {
+    style = BOX;
+    iarg = 2;
+  } else if (strcmp(arg[1],"region") == 0) {
+    style = REGION;
+    if (narg < 3) error->all("Illegal create_atoms command");
+    int iregion = domain->find_region(arg[2]);
+    if (iregion == -1) error->all("Create_atoms region ID does not exist");
+    iarg = 3;;
+  } else if (strcmp(arg[1],"single") == 0) {
+    style = SINGLE;
+    if (narg < 5) error->all("Illegal create_atoms command");
+    xone[0] = atof(arg[2]);
+    xone[1] = atof(arg[3]);
+    xone[2] = atof(arg[4]);
+    iarg = 5;
+  } else error->all("Illegal create_atoms command");
+
+  // process optional keywords
+
+  int scaleflag = 1;
+
+  if (domain->lattice) {
+    nbasis = domain->lattice->nbasis;
+    basistype = new int[nbasis];
+    for (int i = 0; i < nbasis; i++) basistype[i] = itype;
+  }
 
-  int iarg = 1;
   while (iarg < narg) {
-    if (strcmp(arg[iarg],"region") == 0) {
-      if (iarg+2 > narg) error->all("Illegal create_atoms command");
-      int iregion;
-      for (iregion = 0; iregion < domain->nregion; iregion++)
-	if (strcmp(arg[iarg+1],domain->regions[iregion]->id) == 0) break;
-      if (iregion == domain->nregion)
-	error->all("Create_atoms region ID does not exist");
-      regionflag = iregion;
-      iarg += 2;
-    } else if (strcmp(arg[iarg],"basis") == 0) {
+    if (strcmp(arg[iarg],"basis") == 0) {
       if (iarg+3 > narg) error->all("Illegal create_atoms command");
+      if (domain->lattice == NULL)
+	error->all("Cannot create atoms with undefined lattice");
       int ibasis = atoi(arg[iarg+1]);
       itype = atoi(arg[iarg+2]);
       if (ibasis <= 0 || ibasis > nbasis || 
@@ -77,19 +90,121 @@ void CreateAtoms::command(int narg, char **arg)
 	error->all("Illegal create_atoms command");
       basistype[ibasis-1] = itype;
       iarg += 3;
-    } else if (strcmp(arg[iarg],"hybrid") == 0) {
-      if (iarg+3 > narg) error->all("Illegal create_atoms command");
-      AtomVecHybrid *avec_hybrid = (AtomVecHybrid *) atom->avec;
-      int ihybrid;
-      for (ihybrid = 0; ihybrid < avec_hybrid->nstyles; ihybrid++)
-	if (strcmp(avec_hybrid->keywords[ihybrid],arg[iarg+1]) == 0) break;
-      if (ihybrid == avec_hybrid->nstyles)
-	error->all("Create atoms hybrid sub-style does not exist");
-      nhybrid = ihybrid;
-      iarg += 3;
+    } else if (strcmp(arg[iarg],"units") == 0) {
+      if (iarg+2 > narg) error->all("Illegal create_atoms command");
+      if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
+      else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
+      else error->all("Illegal create_atoms command");
+      iarg += 2;
     } else error->all("Illegal create_atoms command");
   }
 
+  // demand lattice be defined
+  // else setup scaling for single atom
+  // could use domain->lattice->lattice2box() to do conversion of
+  //   lattice to box, but not consistent with other uses of units=lattice
+  // triclinic remapping occurs in add_single()
+
+  if (style == BOX || style == REGION) {
+    if (domain->lattice == NULL)
+      error->all("Cannot create atoms with undefined lattice");
+  } else if (scaleflag == 1) {
+    if (domain->lattice == NULL)
+      error->all("Cannot create atoms with undefined lattice");
+    xone[0] *= domain->lattice->xlattice;
+    xone[1] *= domain->lattice->ylattice;
+    xone[2] *= domain->lattice->zlattice;
+  }
+
+  // add atoms
+
+  double natoms_previous = atom->natoms;
+  int nlocal_previous = atom->nlocal;
+
+  if (style == SINGLE) add_single();
+  else add_many();
+
+  // clean up
+
+  if (domain->lattice) delete [] basistype;
+
+  // new total # of atoms
+
+  double rlocal = atom->nlocal;
+  MPI_Allreduce(&rlocal,&atom->natoms,1,MPI_DOUBLE,MPI_SUM,world);
+
+  // print status
+
+  if (comm->me == 0) {
+    if (screen)
+      fprintf(screen,"Created %.15g atoms\n",atom->natoms-natoms_previous);
+    if (logfile)
+      fprintf(logfile,"Created %.15g atoms\n",atom->natoms-natoms_previous);
+  }
+
+  // reset simulation now that more atoms are defined
+  // add tags for newly created atoms if possible
+  // if global map exists, reset it
+  // if a molecular system, set nspecial to 0 for new atoms
+
+  if (atom->natoms > MAXATOMS) atom->tag_enable = 0;
+  if (atom->natoms <= MAXATOMS) atom->tag_extend();
+
+  if (atom->map_style) {
+    atom->map_init();
+    atom->map_set();
+  }
+  if (atom->molecular) {
+    int **nspecial = atom->nspecial;
+    for (int i = nlocal_previous; i < atom->nlocal; i++) {
+      nspecial[i][0] = 0;
+      nspecial[i][1] = 0;
+      nspecial[i][2] = 0;
+    }
+  }
+}
+
+/* ----------------------------------------------------------------------
+   add single atom with coords at xone if it's in my sub-box
+   if triclinic, xone is in lamda coords
+------------------------------------------------------------------------- */
+
+void CreateAtoms::add_single()
+{
+  double sublo[3],subhi[3];
+
+  if (domain->triclinic == 0) {
+    sublo[0] = domain->sublo[0]; subhi[0] = domain->subhi[0];
+    sublo[1] = domain->sublo[1]; subhi[1] = domain->subhi[1];
+    sublo[2] = domain->sublo[2]; subhi[2] = domain->subhi[2];
+  } else {
+    sublo[0] = domain->sublo_lamda[0]; subhi[0] = domain->subhi_lamda[0];
+    sublo[1] = domain->sublo_lamda[1]; subhi[1] = domain->subhi_lamda[1];
+    sublo[2] = domain->sublo_lamda[2]; subhi[2] = domain->subhi_lamda[2];
+  }
+
+  // if triclinic, convert to lamda coords (0-1)
+
+  double lamda[3],*coord;
+  if (domain->triclinic) {
+    domain->x2lamda(xone,lamda);
+    coord = lamda;
+  } else coord = xone;
+
+  // if atom is in my subbox, create it
+
+  if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
+      coord[1] >= sublo[1] && coord[1] < subhi[1] &&
+      coord[2] >= sublo[2] && coord[2] < subhi[2])
+    atom->avec->create_atom(itype,xone);
+}
+
+/* ----------------------------------------------------------------------
+   add many atoms by looping over lattice
+------------------------------------------------------------------------- */
+
+void CreateAtoms::add_many()
+{
   // convert 8 corners of my subdomain from box coords to lattice coords
   // for orthogonal, use corner pts of my subbox
   // for triclinic, use bounding box of my subbox
@@ -176,12 +291,9 @@ void CreateAtoms::command(int narg, char **arg)
 
   // iterate on 3d periodic lattice using loop bounds
   // invoke add_atom for nbasis atoms in each unit cell
-  // converts lattice coords to box coords
+  // convert lattice coords to box coords
   // add atom if it meets all criteria 
 
-  double natoms_previous = atom->natoms;
-  int nlocal_previous = atom->nlocal;
-
   double **basis = domain->lattice->basis;
   double x[3],lamda[3];
   double *coord;
@@ -202,8 +314,8 @@ void CreateAtoms::command(int narg, char **arg)
 
 	  // if a region was specified, test if atom is in it
 
-	  if (regionflag >= 0)
-	    if (!domain->regions[regionflag]->match(x[0],x[1],x[2])) continue;
+	  if (style == REGION)
+	    if (!domain->regions[iregion]->match(x[0],x[1],x[2])) continue;
 
 	  // test if atom is in my subbox
 	  
@@ -218,45 +330,6 @@ void CreateAtoms::command(int narg, char **arg)
 
 	  // add the atom to my list of atoms
 
-	  atom->avec->create_atom(basistype[m],x,nhybrid);
+	  atom->avec->create_atom(basistype[m],x);
 	}
-
-  // clean up
-
-  delete [] basistype;
-
-  // new total # of atoms
-
-  double rlocal = atom->nlocal;
-  MPI_Allreduce(&rlocal,&atom->natoms,1,MPI_DOUBLE,MPI_SUM,world);
-
-  // print status
-
-  if (comm->me == 0) {
-    if (screen)
-      fprintf(screen,"Created %.15g atoms\n",atom->natoms-natoms_previous);
-    if (logfile)
-      fprintf(logfile,"Created %.15g atoms\n",atom->natoms-natoms_previous);
-  }
-
-  // reset simulation now that more atoms are defined
-  // add tags for newly created atoms if possible
-  // if global map exists, reset it
-  // if a molecular system, set nspecial to 0 for new atoms
-
-  if (atom->natoms > MAXATOMS) atom->tag_enable = 0;
-  if (atom->natoms <= MAXATOMS) atom->tag_extend();
-
-  if (atom->map_style) {
-    atom->map_init();
-    atom->map_set();
-  }
-  if (atom->molecular) {
-    int **nspecial = atom->nspecial;
-    for (i = nlocal_previous; i < atom->nlocal; i++) {
-      nspecial[i][0] = 0;
-      nspecial[i][1] = 0;
-      nspecial[i][2] = 0;
-    }
-  }
 }
diff --git a/src/create_atoms.h b/src/create_atoms.h
index c91ab74e9746b1d3411ab2c275f51b369a24be8e..38ced4e09ba642a2dbe2e4e2c63df0c8d33adb67 100644
--- a/src/create_atoms.h
+++ b/src/create_atoms.h
@@ -22,6 +22,14 @@ class CreateAtoms : protected Pointers {
  public:
   CreateAtoms(class LAMMPS *);
   void command(int, char **);
+
+ private:
+  int itype,style,iregion,nbasis;
+  int *basistype;
+  double xone[3];
+
+  void add_single();
+  void add_many();
 };
 
 }
diff --git a/src/create_box.cpp b/src/create_box.cpp
index d947854bfc3788799762ac0a75b8abc21b0896e2..398d28f968cbd39d3803239df60923297c9efed6 100644
--- a/src/create_box.cpp
+++ b/src/create_box.cpp
@@ -42,14 +42,10 @@ void CreateBox::command(int narg, char **arg)
 
   domain->box_exist = 1;
 
-  // find region ID
-
-  int iregion;
-  for (iregion = 0; iregion < domain->nregion; iregion++)
-    if (strcmp(arg[1],domain->regions[iregion]->id) == 0) break;
-  if (iregion == domain->nregion) 
-    error->all("Create_box region ID does not exist");
+  // region check
 
+  int iregion = domain->find_region(arg[1]);
+  if (iregion == -1) error->all("Create_box region ID does not exist");
   if (domain->regions[iregion]->interior == 0)
     error->all("Create_box region must be of type inside");
 
diff --git a/src/delete_atoms.cpp b/src/delete_atoms.cpp
index 660f31e2afff4c0a421452ac1949a280b9483c35..081741541a6d8102e64fb54f651bf68180a2d2ea 100644
--- a/src/delete_atoms.cpp
+++ b/src/delete_atoms.cpp
@@ -143,11 +143,8 @@ void DeleteAtoms::delete_region(int narg, char **arg, int *list)
 {
   if (narg != 2) error->all("Illegal delete_atoms command");
   
-  int iregion;
-  for (iregion = 0; iregion < domain->nregion; iregion++)
-    if (strcmp(arg[1],domain->regions[iregion]->id) == 0) break;
-  if (iregion == domain->nregion)
-    error->all("Could not find delete_atoms region ID");
+  int iregion = domain->find_region(arg[1]);
+  if (iregion == -1) error->all("Could not find delete_atoms region ID");
 
   double **x = atom->x;
   int nlocal = atom->nlocal;
diff --git a/src/displace_atoms.cpp b/src/displace_atoms.cpp
index 2b10cf40aba9c1cdd439fda83a8479984f69337f..77e03a0c5636f063721408d73127fabd56821170 100644
--- a/src/displace_atoms.cpp
+++ b/src/displace_atoms.cpp
@@ -20,12 +20,12 @@
 #include "lattice.h"
 #include "comm.h"
 #include "group.h"
+#include "random_park.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
-#define MOVE 1
-#define RAMP 2
+enum{MOVE,RAMP,RANDOM};
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
@@ -62,6 +62,7 @@ void DisplaceAtoms::command(int narg, char **arg)
   int style;
   if (strcmp(arg[1],"move") == 0) style = MOVE;
   else if (strcmp(arg[1],"ramp") == 0) style = RAMP;
+  else if (strcmp(arg[1],"random") == 0) style = RANDOM;
   else error->all("Illegal displace_atoms command");
 
   // set option defaults
@@ -72,6 +73,7 @@ void DisplaceAtoms::command(int narg, char **arg)
 
   if (style == MOVE) options(narg-5,&arg[5]);
   else if (style == RAMP) options(narg-8,&arg[8]);
+  else if (style == RANDOM) options(narg-6,&arg[6]);
 
   // setup scaling
 
@@ -86,14 +88,13 @@ void DisplaceAtoms::command(int narg, char **arg)
   }
   else xscale = yscale = zscale = 1.0;
 
-  // move atoms by specified 3-vector distance
+  // move atoms by 3-vector
 
   if (style == MOVE) {
 
-    double delx,dely,delz;
-    delx = xscale*atof(arg[2]);
-    dely = yscale*atof(arg[3]);
-    delz = zscale*atof(arg[4]);
+    double delx = xscale*atof(arg[2]);
+    double dely = yscale*atof(arg[3]);
+    double delz = zscale*atof(arg[4]);
 
     double **x = atom->x;
     int *mask = atom->mask;
@@ -165,6 +166,33 @@ void DisplaceAtoms::command(int narg, char **arg)
     }
   }
 
+  // move atoms randomly
+    
+  if (style == RANDOM) {
+    RanPark *random = new RanPark(lmp,1);
+
+    double dx = xscale*atof(arg[2]);
+    double dy = yscale*atof(arg[3]);
+    double dz = zscale*atof(arg[4]);
+    int seed = atoi(arg[5]);
+
+    double **x = atom->x;
+    int *mask = atom->mask;
+    int nlocal = atom->nlocal;
+
+    int j;
+    for (i = 0; i < nlocal; i++) {
+      if (mask[i] & groupbit) {
+	random->reset(seed,x[i]);
+	x[i][0] += dx * 2.0*(random->uniform()-0.5);
+	x[i][1] += dy * 2.0*(random->uniform()-0.5);
+	x[i][2] += dz * 2.0*(random->uniform()-0.5);
+      }
+    }
+
+    delete random;
+  }
+
   // move atoms back inside simulation box and to new processors
   // use remap() instead of pbc() in case atoms moved a long distance
   // use irregular() instead of exchange() in case atoms moved a long distance
diff --git a/src/domain.cpp b/src/domain.cpp
index ba2b5515fe95fb23015a426eaf67344a89dda3ab..2d7bd34fef2cee2242dc4dec345b80735d926820 100644
--- a/src/domain.cpp
+++ b/src/domain.cpp
@@ -26,6 +26,7 @@
 #include "update.h"
 #include "modify.h"
 #include "fix.h"
+#include "fix_deform.h"
 #include "region.h"
 #include "lattice.h"
 #include "comm.h"
@@ -44,6 +45,8 @@ using namespace LAMMPS_NS;
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
+enum{NO_REMAP,X_REMAP,V_REMAP};                   // same as fix_deform.cpp
+
 /* ----------------------------------------------------------------------
    default is periodic 
 ------------------------------------------------------------------------- */
@@ -67,6 +70,12 @@ Domain::Domain(LAMMPS *lmp) : Pointers(lmp)
   boxhi[0] = boxhi[1] = boxhi[2] = 0.5;
   xy = xz = yz = 0.0;
 
+  h[3] = h[4] = h[5] = 0.0;
+  h_inv[3] = h_inv[4] = h_inv[5] = 0.0;
+  h_rate[0] = h_rate[1] = h_rate[2] = 
+    h_rate[3] = h_rate[4] = h_rate[5] = 0.0;
+  h_ratelo[0] = h_ratelo[1] = h_ratelo[2] = 0.0;
+  
   prd_lamda[0] = prd_lamda[1] = prd_lamda[2] = 1.0;
   boxlo_lamda[0] = boxlo_lamda[1] = boxlo_lamda[2] = 0.0;
   boxhi_lamda[0] = boxhi_lamda[1] = boxhi_lamda[2] = 1.0;
@@ -96,6 +105,18 @@ void Domain::init()
   if (nonperiodic == 2) box_change = 1;
   for (int i = 0; i < modify->nfix; i++)
     if (modify->fix[i]->box_change) box_change = 1;
+
+  // check for fix deform
+
+  deform_flag = deform_remap = 0;
+  for (int i = 0; i < modify->nfix; i++)
+    if (strcmp(modify->fix[i]->style,"deform") == 0) {
+      deform_flag = 1;
+      if (((FixDeform *) modify->fix[i])->remapflag == V_REMAP) {
+	deform_remap = 1;
+	deform_groupbit = modify->fix[i]->groupbit;
+      } else deform_remap = 0;
+    }
 }
 
 /* ----------------------------------------------------------------------
@@ -120,11 +141,11 @@ void Domain::set_initial_box()
     if (yz != 0.0 && (!yperiodic || !zperiodic))
       error->all("Triclinic box must be periodic in skewed dimensions");
 
-    if (fabs(xy/(boxhi[1]-boxlo[1])) > 0.5)
+    if (fabs(xy/(boxhi[0]-boxlo[0])) > 0.5)
       error->all("Triclinic box skew is too large");
-    if (fabs(xz/(boxhi[2]-boxlo[2])) > 0.5)
+    if (fabs(xz/(boxhi[0]-boxlo[0])) > 0.5)
       error->all("Triclinic box skew is too large");
-    if (fabs(yz/(boxhi[2]-boxlo[2])) > 0.5)
+    if (fabs(yz/(boxhi[1]-boxlo[1])) > 0.5)
       error->all("Triclinic box skew is too large");
   }
 
@@ -157,21 +178,21 @@ void Domain::set_global_box()
   prd[1] = yprd = boxhi[1] - boxlo[1];
   prd[2] = zprd = boxhi[2] - boxlo[2];
 
+  h[0] = xprd;
+  h[1] = yprd;
+  h[2] = zprd;
+  h_inv[0] = 1.0/h[0];
+  h_inv[1] = 1.0/h[1];
+  h_inv[2] = 1.0/h[2];
+
   xprd_half = 0.5*xprd;
   yprd_half = 0.5*yprd;
   zprd_half = 0.5*zprd;
 
   if (triclinic) {
-    h[0] = xprd;
-    h[1] = yprd;
-    h[2] = zprd;
     h[3] = yz;
     h[4] = xz;
     h[5] = xy;
-  
-    h_inv[0] = 1.0/h[0];
-    h_inv[1] = 1.0/h[1];
-    h_inv[2] = 1.0/h[2];
     h_inv[3] = -h[3] / (h[1]*h[2]);
     h_inv[4] = (h[3]*h[5] - h[1]*h[4]) / (h[0]*h[1]*h[2]);
     h_inv[5] = -h[5] / (h[0]*h[1]);
@@ -318,6 +339,7 @@ void Domain::reset_box()
    called every reneighboring and by other commands that change atoms
    resulting coord must satisfy lo <= coord < hi
    MAX is important since coord - prd < lo can happen when coord = hi
+   if fix deform, remap velocity of fix group atoms by box edge velocities
    for triclinic, atoms must be in lamda coords (0-1) before pbc is called
    image = 10 bits for each dimension
    increment/decrement in wrap-around fashion
@@ -329,6 +351,8 @@ void Domain::pbc()
   double *lo,*hi,*period;
   int nlocal = atom->nlocal;
   double **x = atom->x;
+  double **v = atom->v;
+  int *mask = atom->mask;
   int *image = atom->image;
 
   if (triclinic == 0) {
@@ -345,6 +369,7 @@ void Domain::pbc()
     if (xperiodic) {
       if (x[i][0] < lo[0]) {
 	x[i][0] += period[0];
+	if (deform_remap && mask[i] & deform_groupbit) v[i][0] += h_rate[0];
 	idim = image[i] & 1023;
         otherdims = image[i] ^ idim;
 	idim--;
@@ -354,6 +379,7 @@ void Domain::pbc()
       if (x[i][0] >= hi[0]) {
 	x[i][0] -= period[0];
 	x[i][0] = MAX(x[i][0],lo[0]);
+	if (deform_remap && mask[i] & deform_groupbit) v[i][0] -= h_rate[0];
 	idim = image[i] & 1023;
 	otherdims = image[i] ^ idim;
 	idim++;
@@ -365,6 +391,10 @@ void Domain::pbc()
     if (yperiodic) {
       if (x[i][1] < lo[1]) {
 	x[i][1] += period[1];
+	if (deform_remap && mask[i] & deform_groupbit) {
+	  v[i][0] += h_rate[5];
+	  v[i][1] += h_rate[1];
+	}
 	idim = (image[i] >> 10) & 1023;
         otherdims = image[i] ^ (idim << 10);
 	idim--;
@@ -374,6 +404,10 @@ void Domain::pbc()
       if (x[i][1] >= hi[1]) {
 	x[i][1] -= period[1];
 	x[i][1] = MAX(x[i][1],lo[1]);
+	if (deform_remap && mask[i] & deform_groupbit) {
+	  v[i][0] -= h_rate[5];
+	  v[i][1] -= h_rate[1];
+	}
 	idim = (image[i] >> 10) & 1023;
         otherdims = image[i] ^ (idim << 10);
 	idim++;
@@ -385,6 +419,11 @@ void Domain::pbc()
     if (zperiodic) {
       if (x[i][2] < lo[2]) {
 	x[i][2] += period[2];
+	if (deform_remap && mask[i] & deform_groupbit) {
+	  v[i][0] += h_rate[4];
+	  v[i][1] += h_rate[3];
+	  v[i][2] += h_rate[2];
+	}
 	idim = image[i] >> 20;
         otherdims = image[i] ^ (idim << 20);
 	idim--;
@@ -394,6 +433,11 @@ void Domain::pbc()
       if (x[i][2] >= hi[2]) {
 	x[i][2] -= period[2];
 	x[i][2] = MAX(x[i][2],lo[2]);
+	if (deform_remap && mask[i] & deform_groupbit) {
+	  v[i][0] -= h_rate[4];
+	  v[i][1] -= h_rate[3];
+	  v[i][2] -= h_rate[2];
+	}
 	idim = image[i] >> 20;
         otherdims = image[i] ^ (idim << 20);
 	idim++;
@@ -533,7 +577,7 @@ void Domain::minimum_image(double *delta)
    adjust image accordingly
    resulting coord must satisfy lo <= coord < hi
    MAX is important since coord - prd < lo can happen when coord = hi
-   for triclinic, convert atom to lamda coords (0-1) before doing remap
+   for triclinic, atom is converted to lamda coords (0-1) before doing remap
    image = 10 bits for each dimension
    increment/decrement in wrap-around fashion
 ------------------------------------------------------------------------- */
diff --git a/src/domain.h b/src/domain.h
index e3ac10c32b130c1cc2ae2c8a7cb744c57116be4e..4f2a7c600518fdbfe11717a882536192c248295d 100644
--- a/src/domain.h
+++ b/src/domain.h
@@ -67,8 +67,12 @@ class Domain : protected Pointers {
                                          // triclinic box
   double xy,xz,yz;                       // 3 tilt factors
   double h[6],h_inv[6];	          	 // shape matrix in Voigt notation
+  double h_rate[6],h_ratelo[3];          // rate of box size/shape change
 
   int box_change;                 // 1 if box bounds ever change, 0 if fixed
+  int deform_flag;                // 1 if fix deform exist, else 0
+  int deform_remap;               // 1 if fix deform remaps v, else 0
+  int deform_groupbit;            // atom group to perform v remap for
 
   class Lattice *lattice;                  // user-defined lattice
 
diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp
index ac5b7b69236e709ccc0f3be5790dc5a29c3a2036..6cf71381d7d7ff235f56b7154bd295e7e18244aa 100644
--- a/src/dump_custom.cpp
+++ b/src/dump_custom.cpp
@@ -31,7 +31,8 @@ using namespace LAMMPS_NS;
 
 enum{TAG,MOL,TYPE,X,Y,Z,XS,YS,ZS,XU,YU,ZU,IX,IY,IZ,
      VX,VY,VZ,FX,FY,FZ,
-     Q,MUX,MUY,MUZ,TQX,TQY,TQZ,
+     Q,MUX,MUY,MUZ,
+     QUATW,QUATI,QUATJ,QUATK,TQX,TQY,TQZ,
      EPAIR,KE,ETOTAL,CENTRO,SXX,SYY,SZZ,SXY,SXZ,SYZ,
      COMPUTE};
 enum{LT,LE,GT,GE,EQ,NEQ};
@@ -405,6 +406,18 @@ int DumpCustom::count()
       } else if (thresh_array[ithresh] == MUZ) {
 	ptr = &atom->mu[0][2];
 	nstride = 3;
+      } else if (thresh_array[ithresh] == QUATW) {
+	ptr = &atom->quat[0][0];
+	nstride = 4;
+      } else if (thresh_array[ithresh] == QUATI) {
+	ptr = &atom->quat[0][1];
+	nstride = 4;
+      } else if (thresh_array[ithresh] == QUATJ) {
+	ptr = &atom->quat[0][2];
+	nstride = 4;
+      } else if (thresh_array[ithresh] == QUATK) {
+	ptr = &atom->quat[0][3];
+	nstride = 4;
       } else if (thresh_array[ithresh] == TQX) {
 	ptr = &atom->torque[0][0];
 	nstride = 3;
@@ -455,27 +468,29 @@ int DumpCustom::count()
 	}
       }
 
+      // unselect atoms that don't meet threshhold criterion
+
       value = thresh_value[ithresh];
 
-      if (thresh_op[ithresh] == GE) {
+      if (thresh_op[ithresh] == LT) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
 	  if (choose[i] && *ptr >= value) {
 	    choose[i] = 0;
 	    nmine--;
 	  }
-      } else if (thresh_op[ithresh] == GT) {
+      } else if (thresh_op[ithresh] == LE) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
 	  if (choose[i] && *ptr > value) {
 	    choose[i] = 0;
 	    nmine--;
 	  }
-      } else if (thresh_op[ithresh] == LE) {
+      } else if (thresh_op[ithresh] == GT) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
 	  if (choose[i] && *ptr <= value) {
 	    choose[i] = 0;
 	    nmine--;
 	  }
-      } else if (thresh_op[ithresh] == LT) {
+      } else if (thresh_op[ithresh] == GE) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
 	  if (choose[i] && *ptr < value) {
 	    choose[i] = 0;
@@ -483,13 +498,13 @@ int DumpCustom::count()
 	  }
       } else if (thresh_op[ithresh] == EQ) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
-	  if (choose[i] && *ptr == value) {
+	  if (choose[i] && *ptr != value) {
 	    choose[i] = 0;
 	    nmine--;
 	  }
       } else if (thresh_op[ithresh] == NEQ) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
-	  if (choose[i] && *ptr != value) {
+	  if (choose[i] && *ptr == value) {
 	    choose[i] = 0;
 	    nmine--;
 	  }
@@ -645,6 +660,27 @@ void DumpCustom::parse_fields(int narg, char **arg)
 	error->all("Dumping an atom quantity that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_muz;
       vtype[i] = DOUBLE;
+
+    } else if (strcmp(arg[iarg],"quatw") == 0) {
+      if (atom->quat == NULL)
+	error->all("Dumping an atom quantity that isn't allocated");
+      pack_choice[i] = &DumpCustom::pack_quatw;
+      vtype[i] = DOUBLE;
+    } else if (strcmp(arg[iarg],"quati") == 0) {
+      if (atom->quat == NULL)
+	error->all("Dumping an atom quantity that isn't allocated");
+      pack_choice[i] = &DumpCustom::pack_quati;
+      vtype[i] = DOUBLE;
+    } else if (strcmp(arg[iarg],"quatj") == 0) {
+      if (atom->quat == NULL)
+	error->all("Dumping an atom quantity that isn't allocated");
+      pack_choice[i] = &DumpCustom::pack_quatj;
+      vtype[i] = DOUBLE;
+    } else if (strcmp(arg[iarg],"quatk") == 0) {
+      if (atom->quat == NULL)
+	error->all("Dumping an atom quantity that isn't allocated");
+      pack_choice[i] = &DumpCustom::pack_quatk;
+      vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"tqx") == 0) {
       if (atom->torque == NULL)
 	error->all("Dumping an atom quantity that isn't allocated");
@@ -825,10 +861,8 @@ int DumpCustom::modify_param(int narg, char **arg)
     if (narg < 2) error->all("Illegal dump_modify command");
     if (strcmp(arg[1],"none") == 0) iregion = -1;
     else {
-      for (iregion = 0; iregion < domain->nregion; iregion++)
-	if (strcmp(arg[1],domain->regions[iregion]->id) == 0) break;
-      if (iregion == domain->nregion)
-	error->all("Dump_modify region ID does not exist");
+      iregion = domain->find_region(arg[1]);
+      if (iregion == -1) error->all("Dump_modify region ID does not exist");
     }
     return 2;
     
@@ -896,6 +930,10 @@ int DumpCustom::modify_param(int narg, char **arg)
     else if (strcmp(arg[1],"mux") == 0) thresh_array[nthresh] = MUX;
     else if (strcmp(arg[1],"muy") == 0) thresh_array[nthresh] = MUY;
     else if (strcmp(arg[1],"muz") == 0) thresh_array[nthresh] = MUZ;
+    else if (strcmp(arg[1],"quatw") == 0) thresh_array[nthresh] = QUATW;
+    else if (strcmp(arg[1],"quati") == 0) thresh_array[nthresh] = QUATI;
+    else if (strcmp(arg[1],"quatj") == 0) thresh_array[nthresh] = QUATJ;
+    else if (strcmp(arg[1],"quatk") == 0) thresh_array[nthresh] = QUATK;
     else if (strcmp(arg[1],"tqx") == 0) thresh_array[nthresh] = TQX;
     else if (strcmp(arg[1],"tqy") == 0) thresh_array[nthresh] = TQY;
     else if (strcmp(arg[1],"tqz") == 0) thresh_array[nthresh] = TQZ;
@@ -1013,12 +1051,12 @@ int DumpCustom::modify_param(int narg, char **arg)
 
     // set operation type of threshhold
 
-    if (strcmp(arg[2],">=") == 0) thresh_op[nthresh] = LT;
-    else if (strcmp(arg[2],">") == 0) thresh_op[nthresh] = LE;
-    else if (strcmp(arg[2],"<=") == 0) thresh_op[nthresh] = GT;
-    else if (strcmp(arg[2],"<") == 0) thresh_op[nthresh] = GE;
-    else if (strcmp(arg[2],"=") == 0) thresh_op[nthresh] = NEQ;
-    else if (strcmp(arg[2],"<>") == 0) thresh_op[nthresh] = EQ;
+    if (strcmp(arg[2],"<") == 0) thresh_op[nthresh] = LT;
+    else if (strcmp(arg[2],"<=") == 0) thresh_op[nthresh] = LE;
+    else if (strcmp(arg[2],">") == 0) thresh_op[nthresh] = GT;
+    else if (strcmp(arg[2],">=") == 0) thresh_op[nthresh] = GE;
+    else if (strcmp(arg[2],"==") == 0) thresh_op[nthresh] = EQ;
+    else if (strcmp(arg[2],"!=") == 0) thresh_op[nthresh] = NEQ;
     else error->all("Invalid dump_modify threshhold operator");
 
     // set threshhold value
@@ -1441,6 +1479,62 @@ void DumpCustom::pack_muz(int n)
 
 /* ---------------------------------------------------------------------- */
 
+void DumpCustom::pack_quatw(int n)
+{
+  double **quat = atom->quat;
+  int nlocal = atom->nlocal;
+
+  for (int i = 0; i < nlocal; i++)
+    if (choose[i]) {
+      buf[n] = quat[i][0];
+      n += size_one;
+    }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void DumpCustom::pack_quati(int n)
+{
+  double **quat = atom->quat;
+  int nlocal = atom->nlocal;
+
+  for (int i = 0; i < nlocal; i++)
+    if (choose[i]) {
+      buf[n] = quat[i][1];
+      n += size_one;
+    }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void DumpCustom::pack_quatj(int n)
+{
+  double **quat = atom->quat;
+  int nlocal = atom->nlocal;
+
+  for (int i = 0; i < nlocal; i++)
+    if (choose[i]) {
+      buf[n] = quat[i][2];
+      n += size_one;
+    }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void DumpCustom::pack_quatk(int n)
+{
+  double **quat = atom->quat;
+  int nlocal = atom->nlocal;
+
+  for (int i = 0; i < nlocal; i++)
+    if (choose[i]) {
+      buf[n] = quat[i][3];
+      n += size_one;
+    }
+}
+
+/* ---------------------------------------------------------------------- */
+
 void DumpCustom::pack_tqx(int n)
 {
   double **torque = atom->torque;
diff --git a/src/dump_custom.h b/src/dump_custom.h
index 1340c12af8e4b9a35a5bccfbd4d66a8cb7f75886..62a4801e27941d8792e15b1f1ef57ddfc2b0160a 100644
--- a/src/dump_custom.h
+++ b/src/dump_custom.h
@@ -107,6 +107,10 @@ class DumpCustom : public Dump {
   void pack_mux(int);
   void pack_muy(int);
   void pack_muz(int);
+  void pack_quatw(int);
+  void pack_quati(int);
+  void pack_quatj(int);
+  void pack_quatk(int);
   void pack_tqx(int);
   void pack_tqy(int);
   void pack_tqz(int);
diff --git a/src/fix.cpp b/src/fix.cpp
index be6813c75f5b31360a16c2b1c002f4d2f6785295..a844a8c818f2af6bfcb09243834a560797ebe80b 100644
--- a/src/fix.cpp
+++ b/src/fix.cpp
@@ -39,6 +39,8 @@ Fix::Fix(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
   box_change = 0;
   thermo_energy = 0;
   pressure_every = 0;
+  rigid_flag = 0;
+  virial_flag = 0;
 
   comm_forward = comm_reverse = 0;
   neigh_half_once = neigh_half_every = 0;
diff --git a/src/fix.h b/src/fix.h
index 73049a200fbecaad04832b162c53e6fe05be0c8f..a83c34b9eaf778a36cd173ee8717a139198efe30 100644
--- a/src/fix.h
+++ b/src/fix.h
@@ -31,6 +31,8 @@ class Fix : protected Pointers {
   int thermo_energy;             // 1 if ThEng enabled via fix_modify, 0 if not
   int nevery;                    // how often to call an end_of_step fix
   int pressure_every;            // how often fix needs virial computed
+  int rigid_flag;                // 1 if Fix integrates rigid bodies, 0 if not
+  int virial_flag;               // 1 if Fix contributes to virial, 0 if not
 
   int comm_forward;              // size of forward communication (0 if none)
   int comm_reverse;              // size of reverse communication (0 if none)
diff --git a/src/fix_deposit.cpp b/src/fix_deposit.cpp
index 5a0ed002805effe7cd76fed683ad9d029e9f81fc..46a077e0a6de4f7adf5880e914bb7a9a70953b82 100644
--- a/src/fix_deposit.cpp
+++ b/src/fix_deposit.cpp
@@ -280,7 +280,7 @@ void FixDeposit::pre_exchange()
 	     newcoord[0] >= sublo[0] && newcoord[0] < subhi[0]) flag = 1;
 
     if (flag) {
-      atom->avec->create_atom(ntype,coord,0);
+      atom->avec->create_atom(ntype,coord);
       int m = atom->nlocal - 1;
       atom->type[m] = ntype;
       atom->mask[m] = 1 | groupbit;
@@ -329,10 +329,8 @@ void FixDeposit::options(int narg, char **arg)
   while (iarg < narg) {
     if (strcmp(arg[iarg],"region") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix deposit command");
-      for (iregion = 0; iregion < domain->nregion; iregion++)
-	if (strcmp(arg[iarg+1],domain->regions[iregion]->id) == 0) break;
-      if (iregion == domain->nregion) 
-	error->all("Fix deposit region ID does not exist");
+      iregion = domain->find_region(arg[iarg+1]);
+      if (iregion == -1) error->all("Fix deposit region ID does not exist");
       iarg += 2;
     } else if (strcmp(arg[iarg],"global") == 0) {
       if (iarg+3 > narg) error->all("Illegal fix deposit command");
diff --git a/src/fix_gravity.cpp b/src/fix_gravity.cpp
index 211b89870133650285fdfa2066f83f8a5bd4fbf7..f96e63614c230da6ac4b2d1e4db4cad07d850730 100644
--- a/src/fix_gravity.cpp
+++ b/src/fix_gravity.cpp
@@ -31,24 +31,18 @@ FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) :
 
   if (strcmp(arg[3],"chute") == 0) {
     if (narg != 5) error->all("Illegal fix gravity command");
-    if (atom->check_style("granular") == 0)
-      error->all("Must use fix gravity chute with atom style granular");
     dynamic = 0;
     granular = 1;
     phi = 0.0;
     theta = 180.0 - atof(arg[4]);
   } else if (strcmp(arg[3],"spherical") == 0) {
     if (narg != 6) error->all("Illegal fix gravity command");
-    if (atom->check_style("granular") == 0)
-      error->all("Must use fix gravity spherical with atom style granular");
     dynamic = 0;
     granular = 1;
     phi = atof(arg[4]);
     theta = atof(arg[5]);
   } else if (strcmp(arg[3],"gradient") == 0) {
     if (narg != 8) error->all("Illegal fix gravity command");
-    if (atom->check_style("granular") == 0)
-      error->all("Must use fix gravity gradient with atom style granular");
     dynamic = 1;
     granular = 1;
     phi = atof(arg[4]);
@@ -57,8 +51,6 @@ FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) :
     thetagrad = atof(arg[7]);
   } else if (strcmp(arg[3],"vector") == 0) {
     if (narg != 8) error->all("Illegal fix gravity command");
-    if (atom->check_style("granular") != 0)
-      error->all("Cannot use fix gravity vector with atom style granular");
     dynamic = 0;
     granular = 0;
     magnitude = atof(arg[4]);
@@ -130,14 +122,7 @@ void FixGravity::post_force(int vflag)
   int nlocal = atom->nlocal;
   double massone;
 
-  if (granular) {
-    for (int i = 0; i < nlocal; i++)
-      if (mask[i] & groupbit) {
-	f[i][0] += rmass[i]*xgrav;
-	f[i][1] += rmass[i]*ygrav;
-	f[i][2] += rmass[i]*zgrav;
-      }
-  } else {
+  if (mass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	massone = mass[type[i]];
@@ -145,5 +130,12 @@ void FixGravity::post_force(int vflag)
 	f[i][1] += massone*ygrav;
 	f[i][2] += massone*zgrav;
       }
+  } else {
+    for (int i = 0; i < nlocal; i++)
+      if (mask[i] & groupbit) {
+	f[i][0] += rmass[i]*xgrav;
+	f[i][1] += rmass[i]*ygrav;
+	f[i][2] += rmass[i]*zgrav;
+      }
   }
 }
diff --git a/src/fix_langevin.cpp b/src/fix_langevin.cpp
index 2d2fc0a210c50679d42a117311e694da3fda2f74..237b0b2b4bb00dc2d89ddbc45c3a5c8531736bbe 100644
--- a/src/fix_langevin.cpp
+++ b/src/fix_langevin.cpp
@@ -77,10 +77,8 @@ FixLangevin::FixLangevin(LAMMPS *lmp, int narg, char **arg) :
       ratio[itype] = scale;
       iarg += 3;
     } else if (strcmp(arg[iarg],"region") == 0) {
-      for (iregion = 0; iregion < domain->nregion; iregion++)
-	if (strcmp(arg[iarg+1],domain->regions[iregion]->id) == 0) break;
-      if (iregion == domain->nregion)
-	error->all("Fix langevin region ID does not exist");
+      iregion = domain->find_region(arg[iarg+1]);
+      if (iregion == -1) error->all("Fix langevin region ID does not exist");
       iarg += 2;
     } else error->all("Illegal fix langevin command");
   }
diff --git a/src/fix_msd.cpp b/src/fix_msd.cpp
index 097a8eaed3380edf27639622b59b983b01bbba9b..4da1d816fffd3ccbc7ac66c8a0a44c890cdc7998 100644
--- a/src/fix_msd.cpp
+++ b/src/fix_msd.cpp
@@ -129,7 +129,7 @@ void FixMSD::init()
   int count = 0;
   for (int i = 0; i < modify->nfix; i++)
     if (strcmp(modify->fix[i]->style,"msd") == 0) count++;
-  if (count > 1 && me == 0) error->warning("More than one msd fix");
+  if (count > 1 && me == 0) error->warning("More than one fix msd");
 }
 
 /* ---------------------------------------------------------------------- */
diff --git a/src/fix_nph.cpp b/src/fix_nph.cpp
index 3032c84fe025d994a1ea61cc960999396d702a37..0b38c5037b87bd4354ec5fe6973b050abe244b57 100644
--- a/src/fix_nph.cpp
+++ b/src/fix_nph.cpp
@@ -263,10 +263,6 @@ void FixNPH::init()
   }
   nkt = atom->natoms * boltz * t_initial;
 
-  double mass = 0.0;
-  for (int i = 0; i < atom->nlocal; i++) mass += atom->mass[atom->type[i]];
-  MPI_Allreduce(&mass,&total_mass,1,MPI_DOUBLE,MPI_SUM,world);
-
   if (force->kspace) kspace_flag = 1;
   else kspace_flag = 0;
 
@@ -275,7 +271,7 @@ void FixNPH::init()
     step_respa = ((Respa *) update->integrate)->step;
   }
 
-  // detect if any fix rigid exist so rigid bodies move when box is dilated
+  // detect if any rigid fixes exist so rigid bodies move when box is dilated
   // rfix[] = indices to each fix rigid
 
   delete [] rfix;
@@ -283,14 +279,12 @@ void FixNPH::init()
   rfix = NULL;
 
   for (int i = 0; i < modify->nfix; i++)
-    if (strcmp(modify->fix[i]->style,"rigid") == 0 ||
-	strcmp(modify->fix[i]->style,"poems") == 0) nrigid++;
+    if (modify->fix[i]->rigid_flag) nrigid++;
   if (nrigid) {
     rfix = new int[nrigid];
     nrigid = 0;
     for (int i = 0; i < modify->nfix; i++)
-      if (strcmp(modify->fix[i]->style,"rigid") == 0 ||
-	  strcmp(modify->fix[i]->style,"poems") == 0) rfix[nrigid++] = i;
+      if (modify->fix[i]->rigid_flag) rfix[nrigid++] = i;
   }
 }
 
diff --git a/src/fix_nph.h b/src/fix_nph.h
index 351e81f0c85a02d0fcfea817fde2e57f0f266d37..23642311045a5ef8e2e968ae8cf332ee4642a576 100644
--- a/src/fix_nph.h
+++ b/src/fix_nph.h
@@ -37,7 +37,7 @@ class FixNPH : public Fix {
  private:
   double dtv,dtf,dthalf;
   double boltz,nktv2p;
-  double total_mass,vol0,nkt;
+  double vol0,nkt;
 
   int press_couple,dilate_partial;
   int p_flag[3];                   // 1 if control P on this dim, 0 if not
diff --git a/src/fix_npt.cpp b/src/fix_npt.cpp
index c568e3a8b4a49b08229acfdc7e5dcf73ca5e229e..532c668e201d0d1f39f1d4e2c6974f7ee09780d3 100644
--- a/src/fix_npt.cpp
+++ b/src/fix_npt.cpp
@@ -162,7 +162,8 @@ FixNPT::FixNPT(LAMMPS *lmp, int narg, char **arg) :
   char **newarg = new char*[3];
   newarg[0] = id_temp;
   newarg[1] = "all";
-  newarg[2] = "temp";
+  if (strcmp(style,"npt") == 0) newarg[2] = "temp";
+  else if (strcmp(style,"npt/asphere") == 0) newarg[2] = "temp/asphere";
   modify->add_compute(3,newarg);
   delete [] newarg;
   tflag = 1;
@@ -251,6 +252,7 @@ void FixNPT::init()
   // set timesteps and frequencies
 
   dtv = update->dt;
+  dtq = 0.5 * update->dt;
   dtf = 0.5 * update->dt * force->ftm2v;
   dthalf = 0.5 * update->dt;
 
@@ -262,10 +264,6 @@ void FixNPT::init()
   nktv2p = force->nktv2p;
   vol0 = domain->xprd * domain->yprd * domain->zprd;
 
-  double mass = 0.0;
-  for (int i = 0; i < atom->nlocal; i++) mass += atom->mass[atom->type[i]];
-  MPI_Allreduce(&mass,&total_mass,1,MPI_DOUBLE,MPI_SUM,world);
-
   if (force->kspace) kspace_flag = 1;
   else kspace_flag = 0;
 
@@ -274,7 +272,7 @@ void FixNPT::init()
     step_respa = ((Respa *) update->integrate)->step;
   }
 
-  // detect if any fix rigid exist so rigid bodies move when box is dilated
+  // detect if any rigid fixes exist so rigid bodies move when box is dilated
   // rfix[] = indices to each fix rigid
 
   delete [] rfix;
@@ -282,14 +280,12 @@ void FixNPT::init()
   rfix = NULL;
 
   for (int i = 0; i < modify->nfix; i++)
-    if (strcmp(modify->fix[i]->style,"rigid") == 0 ||
-	strcmp(modify->fix[i]->style,"poems") == 0) nrigid++;
+    if (modify->fix[i]->rigid_flag) nrigid++;
   if (nrigid) {
     rfix = new int[nrigid];
     nrigid = 0;
     for (int i = 0; i < modify->nfix; i++)
-      if (strcmp(modify->fix[i]->style,"rigid") == 0 ||
-	  strcmp(modify->fix[i]->style,"poems") == 0) rfix[nrigid++] = i;
+      if (modify->fix[i]->rigid_flag) rfix[nrigid++] = i;
   }
 }
 
diff --git a/src/fix_npt.h b/src/fix_npt.h
index dd066bc28e6f797ea2c6c3e05679278a3677266e..5bde03c9bf213ec0dc7f00529fce44c4970cd471 100644
--- a/src/fix_npt.h
+++ b/src/fix_npt.h
@@ -21,12 +21,12 @@ namespace LAMMPS_NS {
 class FixNPT : public Fix {
  public:
   FixNPT(class LAMMPS *, int, char **);
-  ~FixNPT();
+  virtual ~FixNPT();
   int setmask();
-  void init();
+  virtual void init();
   void setup();
-  void initial_integrate();
-  void final_integrate();
+  virtual void initial_integrate();
+  virtual void final_integrate();
   void initial_integrate_respa(int, int);
   void final_integrate_respa(int);
   double thermo(int);
@@ -34,10 +34,10 @@ class FixNPT : public Fix {
   void restart(char *);
   int modify_param(int, char **);
 
- private:
-  double dtv,dtf,dthalf;
+ protected:
+  double dtv,dtq,dtf,dthalf;
   double boltz,nktv2p;
-  double total_mass,vol0;
+  double vol0;
 
   double t_start,t_stop;
   double t_current,t_target;
diff --git a/src/fix_nvt.cpp b/src/fix_nvt.cpp
index 1eee6e9bdb9c98756ce1c05ece5c8a0dd34dc459..11aa45dbefa0fb13f1495b0a381e1ded53fb5ec3 100644
--- a/src/fix_nvt.cpp
+++ b/src/fix_nvt.cpp
@@ -69,7 +69,9 @@ FixNVT::FixNVT(LAMMPS *lmp, int narg, char **arg) :
   char **newarg = new char*[3];
   newarg[0] = id_temp;
   newarg[1] = group->names[igroup];
-  newarg[2] = "temp";
+  if (strcmp(style,"nvt") == 0) newarg[2] = "temp";
+  else if (strcmp(style,"nvt/asphere") == 0) newarg[2] = "temp/asphere";
+  else if (strcmp(style,"nvt/deform") == 0) newarg[2] = "temp/deform";
   modify->add_compute(3,newarg);
   delete [] newarg;
   tflag = 1;
@@ -245,29 +247,16 @@ void FixNVT::initial_integrate_respa(int ilevel, int flag)
     eta_dot *= drag_factor;
     eta += dtv*eta_dot;
     factor = exp(-dthalf*eta_dot);
+  } else factor = 1.0;
 
-    // update v of only atoms in NVT group
-
-    for (int i = 0; i < nlocal; i++) {
-      if (mask[i] & groupbit) {
-	dtfm = dtf / mass[type[i]];
-	v[i][0] = v[i][0]*factor + dtfm*f[i][0];
-	v[i][1] = v[i][1]*factor + dtfm*f[i][1];
-	v[i][2] = v[i][2]*factor + dtfm*f[i][2];
-      }
-    }
-
-  } else {
-
-    // update v of only atoms in NVT group
+  // update v of only atoms in NVT group
 
-    for (int i = 0; i < nlocal; i++) {
-      if (mask[i] & groupbit) {
-	dtfm = dtf / mass[type[i]];
-	v[i][0] += dtfm*f[i][0];
-	v[i][1] += dtfm*f[i][1];
-	v[i][2] += dtfm*f[i][2];
-      }
+  for (int i = 0; i < nlocal; i++) {
+    if (mask[i] & groupbit) {
+      dtfm = dtf / mass[type[i]];
+      v[i][0] = v[i][0]*factor + dtfm*f[i][0];
+      v[i][1] = v[i][1]*factor + dtfm*f[i][1];
+      v[i][2] = v[i][2]*factor + dtfm*f[i][2];
     }
   }
 
diff --git a/src/fix_nvt.h b/src/fix_nvt.h
index 64f4e82492466b5048222c291d0fcd67814d1e6b..7cd50c68a6ddde486908e91857a52bc83f3007e1 100644
--- a/src/fix_nvt.h
+++ b/src/fix_nvt.h
@@ -21,13 +21,13 @@ namespace LAMMPS_NS {
 class FixNVT : public Fix {
  public:
   FixNVT(class LAMMPS *, int, char **);
-  ~FixNVT();
+  virtual ~FixNVT();
   int setmask();
-  void init();
+  virtual void init();
   void setup();
-  void initial_integrate();
-  void final_integrate();
-  void initial_integrate_respa(int,int);
+  virtual void initial_integrate();
+  virtual void final_integrate();
+  virtual void initial_integrate_respa(int,int);
   void final_integrate_respa(int);
   double thermo(int);
   void write_restart(FILE *);
@@ -35,7 +35,7 @@ class FixNVT : public Fix {
   int modify_param(int, char **);
   void reset_target(double);
 
- private:
+ protected:
   double t_start,t_stop;
   double t_current,t_target;
   double t_freq,drag,drag_factor;
diff --git a/src/fix_rigid.cpp b/src/fix_rigid.cpp
index 85b93f3a49273d2c28d06a62c33c1f01f24f523d..5de40253baf41ce6b35dec657ef805f26403f0ff 100644
--- a/src/fix_rigid.cpp
+++ b/src/fix_rigid.cpp
@@ -43,6 +43,9 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
 {
   int i,ibody;
 
+  rigid_flag = 1;
+  virial_flag = 1;
+
   // perform initial allocation of atom-based arrays
   // register with Atom class
   
@@ -269,7 +272,7 @@ void FixRigid::init()
   int count = 0;
   for (int i = 0; i < modify->nfix; i++)
     if (strcmp(modify->fix[i]->style,"rigid") == 0) count++;
-  if (count > 1 && comm->me == 0) error->warning("More than one rigid fix");
+  if (count > 1 && comm->me == 0) error->warning("More than one fix rigid");
 
   // error if npt,nph fix comes before rigid fix
 
diff --git a/src/fix_shake.cpp b/src/fix_shake.cpp
index 8e83c4311c4e5829c263e14a240c1d6680d119ba..69e1f2686b5f3fea65452dccf05eb7870a64881f 100644
--- a/src/fix_shake.cpp
+++ b/src/fix_shake.cpp
@@ -43,6 +43,7 @@ using namespace LAMMPS_NS;
 FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
+  virial_flag = 1;
   MPI_Comm_rank(world,&me);
   MPI_Comm_size(world,&nprocs);
 
@@ -275,7 +276,7 @@ void FixShake::init()
   int count = 0;
   for (i = 0; i < modify->nfix; i++)
     if (strcmp(modify->fix[i]->style,"shake") == 0) count++;
-  if (count > 1) error->all("More than one shake fix");
+  if (count > 1) error->all("More than one fix shake");
 
   // cannot use with minimization since SHAKE turns off bonds
   // that should contribute to potential energy
diff --git a/src/fix_temp_rescale.cpp b/src/fix_temp_rescale.cpp
index 65e3b2a89bf898329c7f380f62576158e1fe8af2..400c8193ec1858e165715142983e9d5b5632a0ea 100644
--- a/src/fix_temp_rescale.cpp
+++ b/src/fix_temp_rescale.cpp
@@ -49,9 +49,8 @@ FixTempRescale::FixTempRescale(LAMMPS *lmp, int narg, char **arg) :
   int iarg = 8;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"region") == 0) {
-      for (iregion = 0; iregion < domain->nregion; iregion++)
-	if (strcmp(arg[iarg+1],domain->regions[iregion]->id) == 0) break;
-      if (iregion == domain->nregion)
+      iregion = domain->find_region(arg[iarg+1]);
+      if (iregion == -1) 
 	error->all("Fix temp/rescale region ID does not exist");
       iarg += 2;
     } else error->all("Illegal fix temp/rescale command");
diff --git a/src/group.cpp b/src/group.cpp
index a59d2e682105686796164b8a7f8ecc8d4158d2dd..9b21a54f75bdd2505455a55b53d2e12874f486ad 100644
--- a/src/group.cpp
+++ b/src/group.cpp
@@ -19,7 +19,6 @@
 #include "group.h"
 #include "domain.h"
 #include "atom.h"
-#include "atom_vec_hybrid.h"
 #include "force.h"
 #include "region.h"
 #include "memory.h"
@@ -29,15 +28,8 @@ using namespace LAMMPS_NS;
 
 #define MAX_GROUP 32
 
-#define TYPE      1
-#define MOLECULE  2
-#define ID        3
-
-#define LESS_THAN      1
-#define GREATER_THAN   2
-#define LESS_EQUAL     3
-#define GREATER_EQUAL  4
-#define BETWEEN        5
+enum{TYPE,MOLECULE,ID};
+enum{LT,LE,GT,GE,EQ,NEQ,BETWEEN};
 
 #define BIG 1.0e20
 
@@ -111,45 +103,19 @@ void Group::assign(int narg, char **arg)
   int bit = bitmask[igroup];
     
   // style = region
+  // add to group if atom is in region
 
   if (strcmp(arg[1],"region") == 0) {
 
     if (narg != 3) error->all("Illegal group command");
     
-    int iregion;
-    for (iregion = 0; iregion < domain->nregion; iregion++) 
-      if (strcmp(arg[2],domain->regions[iregion]->id) == 0) break;
-    if (iregion == domain->nregion)
-      error->all("Group region ID does not exist");
-
-    // add to group if atom is in region
+    int iregion = domain->find_region(arg[2]);
+    if (iregion == -1) error->all("Group region ID does not exist");
 
     for (i = 0; i < nlocal; i++)
       if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
 	mask[i] |= bit;
 
-  // style = hybrid
-
-  } else if (strcmp(arg[1],"hybrid") == 0) {
-
-    if (narg != 3) error->all("Illegal group command");
-    if (strcmp(atom->atom_style,"hybrid") != 0)
-      error->all("Group hybrid command requires atom style hybrid");
-    
-    AtomVecHybrid *avec_hybrid = (AtomVecHybrid *) atom->avec;
-    int ihybrid;
-    for (ihybrid = 0; ihybrid < avec_hybrid->nstyles; ihybrid++)
-      if (strcmp(avec_hybrid->keywords[ihybrid],arg[2]) == 0) break;
-    if (ihybrid == avec_hybrid->nstyles)
-      error->all("Group hybrid sub-style does not exist");
-
-    // add to group if atom matches hybrid sub-style
-
-    int *hybrid = atom->hybrid;
-
-    for (i = 0; i < nlocal; i++)
-      if (hybrid[i] == ihybrid)	mask[i] |= bit;
-
   // style = logical condition
 
   } else if (narg >= 3 && 
@@ -165,10 +131,12 @@ void Group::assign(int narg, char **arg)
     else if (strcmp(arg[1],"id") == 0) category = ID;
     else error->all("Illegal group command");
     
-    if (strcmp(arg[2],"<") == 0) condition = LESS_THAN;
-    else if (strcmp(arg[2],">") == 0) condition = GREATER_THAN;
-    else if (strcmp(arg[2],"<=") == 0) condition = LESS_EQUAL;
-    else if (strcmp(arg[2],">=") == 0) condition = GREATER_EQUAL;
+    if (strcmp(arg[2],"<") == 0) condition = LT;
+    else if (strcmp(arg[2],"<=") == 0) condition = LE;
+    else if (strcmp(arg[2],">") == 0) condition = GT;
+    else if (strcmp(arg[2],">=") == 0) condition = GE;
+    else if (strcmp(arg[2],"==") == 0) condition = EQ;
+    else if (strcmp(arg[2],"!=") == 0) condition = NEQ;
     else if (strcmp(arg[2],"<>") == 0) condition = BETWEEN;
     else error->all("Illegal group command");
 
@@ -187,14 +155,18 @@ void Group::assign(int narg, char **arg)
 
     // add to group if meets condition
 
-    if (condition == LESS_THAN) {
+    if (condition == LT) {
       for (i = 0; i < nlocal; i++) if (attribute[i] < bound1) mask[i] |= bit;
-    } else if (condition == GREATER_THAN) {
-      for (i = 0; i < nlocal; i++) if (attribute[i] > bound1) mask[i] |= bit;
-    } else if (condition == LESS_EQUAL) {
+    } else if (condition == LE) {
       for (i = 0; i < nlocal; i++) if (attribute[i] <= bound1) mask[i] |= bit;
-    } else if (condition == GREATER_EQUAL) {
+    } else if (condition == GT) {
+      for (i = 0; i < nlocal; i++) if (attribute[i] > bound1) mask[i] |= bit;
+    } else if (condition == GE) {
       for (i = 0; i < nlocal; i++) if (attribute[i] >= bound1) mask[i] |= bit;
+    } else if (condition == EQ) {
+      for (i = 0; i < nlocal; i++) if (attribute[i] == bound1) mask[i] |= bit;
+    } else if (condition == NEQ) {
+      for (i = 0; i < nlocal; i++) if (attribute[i] != bound1) mask[i] |= bit;
     } else if (condition == BETWEEN) {
       for (i = 0; i < nlocal; i++)
 	if (attribute[i] >= bound1 && attribute[i] <= bound2) mask[i] |= bit;
@@ -542,9 +514,9 @@ void Group::bounds(int igroup, double *minmax)
   
   MPI_Allreduce(extent,minmax,6,MPI_DOUBLE,MPI_MAX,world);
 
-  extent[0] = -extent[0];
-  extent[2] = -extent[2];
-  extent[4] = -extent[4];
+  minmax[0] = -minmax[0];
+  minmax[2] = -minmax[2];
+  minmax[4] = -minmax[4];
 }
 
 /* ----------------------------------------------------------------------
diff --git a/src/input.cpp b/src/input.cpp
index c9d0721712e54e503f6f31517855f4b2fb996866..76f4387d7fcc77bf82a20c1e7362256dbf4954bc 100644
--- a/src/input.cpp
+++ b/src/input.cpp
@@ -196,7 +196,7 @@ void Input::file()
    process all input from filename
 ------------------------------------------------------------------------- */
 
-void Input::file(char *filename)
+void Input::file(const char *filename)
 {
   // error if another nested file still open
   // if single open file is not stdin, close it
@@ -223,7 +223,7 @@ void Input::file(char *filename)
    return command name to caller
 ------------------------------------------------------------------------- */
 
-char *Input::one(char *single)
+char *Input::one(const char *single)
 {
   strcpy(line,single);
 
@@ -417,7 +417,6 @@ int Input::execute_command()
   else if (!strcmp(command,"dipole")) dipole();
   else if (!strcmp(command,"dump")) dump();
   else if (!strcmp(command,"dump_modify")) dump_modify();
-  // else if (!strcmp(command,"ellipsoid")) ellipsoid();
   else if (!strcmp(command,"fix")) fix();
   else if (!strcmp(command,"fix_modify")) fix_modify();
   else if (!strcmp(command,"group")) group_command();
@@ -441,6 +440,7 @@ int Input::execute_command()
   else if (!strcmp(command,"reset_timestep")) reset_timestep();
   else if (!strcmp(command,"restart")) restart();
   else if (!strcmp(command,"run_style")) run_style();
+  else if (!strcmp(command,"shape")) shape();
   else if (!strcmp(command,"special_bonds")) special_bonds();
   else if (!strcmp(command,"thermo")) thermo();
   else if (!strcmp(command,"thermo_modify")) thermo_modify();
@@ -824,18 +824,6 @@ void Input::dump_modify()
 
 /* ---------------------------------------------------------------------- */
 
-/*
-void Input::ellipsoid()
-{
-  if (narg != 4) error->all("Illegal ellipsoid command");
-  if (domain->box_exist == 0)
-    error->all("Ellipsoid command before simulation box is defined");
-  atom->set_radii3(narg,arg);
-}
-*/
-
-/* ---------------------------------------------------------------------- */
-
 void Input::fix()
 {
   modify->add_fix(narg,arg);
@@ -1067,6 +1055,16 @@ void Input::run_style()
 
 /* ---------------------------------------------------------------------- */
 
+void Input::shape()
+{
+  if (narg != 4) error->all("Illegal shape command");
+  if (domain->box_exist == 0)
+    error->all("Shape command before simulation box is defined");
+  atom->set_shape(narg,arg);
+}
+
+/* ---------------------------------------------------------------------- */
+
 void Input::special_bonds()
 {
   // store 1-3,1-4 values before change
diff --git a/src/input.h b/src/input.h
index 1ee2ce28b20b88d3d157f980c358f0503c5afc52..93147217daa9a8b1295e2fc5c295fcccf25542d7 100644
--- a/src/input.h
+++ b/src/input.h
@@ -29,8 +29,8 @@ class Input : protected Pointers {
   Input(class LAMMPS *, int, char **);
   ~Input();
   void file();                   // process all input
-  void file(char *);             // process an input script
-  char *one(char *);             // process a single command
+  void file(const char *);       // process an input script
+  char *one(const char *);       // process a single command
   void substitute(char *, int);  // substitute for variables in a string
 
  private:
@@ -78,7 +78,6 @@ class Input : protected Pointers {
   void dipole();
   void dump();
   void dump_modify();
-  // void ellipsoid();
   void fix();
   void fix_modify();
   void group_command();
@@ -102,6 +101,7 @@ class Input : protected Pointers {
   void reset_timestep();
   void restart();
   void run_style();
+  void shape();
   void special_bonds();
   void thermo();
   void thermo_modify();
diff --git a/src/memory.cpp b/src/memory.cpp
index 930e08bf02e704a29ec93cc99fc89438a7ea7e96..430f7d8165a3ce9fb71f8ad1e3ce0c5237e8a3ac 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -131,8 +131,7 @@ double **Memory::grow_2d_double_array(double **array,
   if (array == NULL) return create_2d_double_array(n1,n2,name);
 
   double *data = (double *) srealloc(array[0],n1*n2*sizeof(double),name);
-  sfree(array);
-  array = (double **) smalloc(n1*sizeof(double *),name);
+  array = (double **) srealloc(array,n1*sizeof(double *),name);
 
   int n = 0;
   for (int i = 0; i < n1; i++) {
@@ -194,8 +193,7 @@ int **Memory::grow_2d_int_array(int **array, int n1, int n2, char *name)
   if (array == NULL) return create_2d_int_array(n1,n2,name);
 
   int *data = (int *) srealloc(array[0],n1*n2*sizeof(int),name);
-  sfree(array);
-  array = (int **) smalloc(n1*sizeof(int *),name);
+  array = (int **) srealloc(array,n1*sizeof(int *),name);
 
   int n = 0;
   for (int i = 0; i < n1; i++) {
@@ -285,10 +283,8 @@ double ***Memory::grow_3d_double_array(double ***array,
   if (array == NULL) return create_3d_double_array(n1,n2,n3,name);
 
   double *data = (double *) srealloc(array[0][0],n1*n2*n3*sizeof(double),name);
-  sfree(array[0]);
-  double **plane = (double **) smalloc(n1*n2*sizeof(double *),name);
-  sfree(array);
-  array = (double ***) smalloc(n1*sizeof(double **),name);
+  double **plane = (double **) srealloc(array[0],n1*n2*sizeof(double *),name);
+  array = (double ***) srealloc(array,n1*sizeof(double **),name);
 
   int n = 0;
   for (i = 0; i < n1; i++) {
diff --git a/src/neighbor.cpp b/src/neighbor.cpp
index aab9421397e054a92269278b1ca18e25dc207e9f..21f93eb86188f0fe35ded225316ebba60dc120b3 100644
--- a/src/neighbor.cpp
+++ b/src/neighbor.cpp
@@ -11,6 +11,10 @@
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
+/* ----------------------------------------------------------------------
+   Contributing author (triclinic and multi-neigh) : Pieter in 't Veld (SNL)
+------------------------------------------------------------------------- */
+
 #include "mpi.h"
 #include "math.h"
 #include "stdlib.h"
@@ -508,7 +512,7 @@ void Neighbor::init()
   // set ptrs to half/full/multi/triclinic build & stencil functions
 
   if (half) {
-    if (atom->radius) {
+    if (fix_history) {
       if (style == NSQ) {
 	if (force->newton_pair == 0) 
 	  half_build = &Neighbor::granular_nsq_no_newton;
diff --git a/src/output.cpp b/src/output.cpp
index d3e5dfe7a6907143be4a6ede8e56c0fbcac038a6..31f31e370207330ef8c284ff12d7db579da7c267 100644
--- a/src/output.cpp
+++ b/src/output.cpp
@@ -45,8 +45,23 @@ using namespace LAMMPS_NS;
 
 Output::Output(LAMMPS *lmp) : Pointers(lmp)
 {
-  thermo = NULL;
-  char **newarg = new char*[1];
+  // create 2 default computes for temp and pressure
+
+  char **newarg = new char*[4];
+  newarg[0] = "thermo_temp";
+  newarg[1] = "all";
+  newarg[2] = "temp";
+  modify->add_compute(3,newarg);
+  newarg[0] = "thermo_pressure";
+  newarg[1] = "all";
+  newarg[2] = "pressure";
+  newarg[3] = "thermo_temp";
+  modify->add_compute(4,newarg);
+  delete [] newarg;
+
+  // create default Thermo class
+
+  newarg = new char*[1];
   newarg[0] = "one";
   thermo = new Thermo(lmp,1,newarg);
   delete [] newarg;
diff --git a/src/pair_buck.cpp b/src/pair_buck.cpp
index b7ddec570a1048ece60e8dfa0015ef5cb9e40a34..5fe48f4189d81e3245def0fef088e06a9dd11135 100644
--- a/src/pair_buck.cpp
+++ b/src/pair_buck.cpp
@@ -124,21 +124,13 @@ void PairBuck::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/pair_buck_coul_cut.cpp b/src/pair_buck_coul_cut.cpp
index 3d30f41b8cd12e44c89dea716789d655ba1bc781..a32a911e3c115f8071a51e35fadf56f112e97ec7 100644
--- a/src/pair_buck_coul_cut.cpp
+++ b/src/pair_buck_coul_cut.cpp
@@ -151,21 +151,13 @@ void PairBuckCoulCut::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -305,10 +297,8 @@ double PairBuckCoulCut::init_one(int i, int j)
 
 void PairBuckCoulCut::init_style()
 {
-  // require an atom style with charge defined
-
   if (atom->q == NULL)
-    error->all("Must use charged atom style with this pair style");
+    error->all("Pair style buck/coul/cut requires atom attribute q");
 }
 
 /* ----------------------------------------------------------------------
diff --git a/src/pair_lj_cut.cpp b/src/pair_lj_cut.cpp
index ebff9cac81c5d0ac1bc89c2b19a726ce55d33621..7d0c40923d1a8c41646e914cf9f75a2e2514ff38 100644
--- a/src/pair_lj_cut.cpp
+++ b/src/pair_lj_cut.cpp
@@ -131,21 +131,13 @@ void PairLJCut::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -403,21 +395,13 @@ void PairLJCut::compute_outer(int eflag, int vflag)
 	  } else if (rsq < cut_in_on_sq)
 	    fforce = factor_lj*forcelj*r2inv;
 
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/pair_lj_cut_coul_cut.cpp b/src/pair_lj_cut_coul_cut.cpp
index 1d0cb8dc68627d521fbd3ab442790b68e0572056..f3a0d0142f0a0edce98af737fddc18eb544da95c 100644
--- a/src/pair_lj_cut_coul_cut.cpp
+++ b/src/pair_lj_cut_coul_cut.cpp
@@ -146,21 +146,13 @@ void PairLJCutCoulCut::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
@@ -330,10 +322,8 @@ double PairLJCutCoulCut::init_one(int i, int j)
 
 void PairLJCutCoulCut::init_style()
 {
-  // require an atom style with charge defined
-
   if (atom->q == NULL)
-    error->all("Must use charged atom style with this pair style");
+    error->all("Pair style lj/cut/coul/cut requires atom attribute q");
 }
 
 /* ----------------------------------------------------------------------
diff --git a/src/pair_lj_cut_coul_debye.cpp b/src/pair_lj_cut_coul_debye.cpp
index d044ce9c5338cade8da50510a9d33c6e7271ea94..4331a11e612c9e94625eb60445a523b9c712c35c 100644
--- a/src/pair_lj_cut_coul_debye.cpp
+++ b/src/pair_lj_cut_coul_debye.cpp
@@ -122,21 +122,13 @@ void PairLJCutCoulDebye::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/pair_lj_expand.cpp b/src/pair_lj_expand.cpp
index a5a225dfef12b1f9a7960b3cc7a2bf86c140eb64..3050307ead8ecb9629c054b9dd698bb826b6b63d 100644
--- a/src/pair_lj_expand.cpp
+++ b/src/pair_lj_expand.cpp
@@ -126,21 +126,13 @@ void PairLJExpand::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/pair_lj_smooth.cpp b/src/pair_lj_smooth.cpp
index 1b150d9657690be26d4e9025316163f55a8fa9ae..0ee2c06649f6bb881d36f5722a6300a576d1a07e 100644
--- a/src/pair_lj_smooth.cpp
+++ b/src/pair_lj_smooth.cpp
@@ -148,21 +148,13 @@ void PairLJSmooth::compute(int eflag, int vflag)
 	}
 	
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/pair_morse.cpp b/src/pair_morse.cpp
index bba446998abfddaec75128c160bcfb7b96209c2a..f09d29c509554e886af2f9134752c774fc191c14 100644
--- a/src/pair_morse.cpp
+++ b/src/pair_morse.cpp
@@ -119,21 +119,13 @@ void PairMorse::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/pair_soft.cpp b/src/pair_soft.cpp
index fe39ffa997f06987a09171d3a63a4fa1a6618ac0..744c77795299dcdff3e95953791127c436f24b83 100644
--- a/src/pair_soft.cpp
+++ b/src/pair_soft.cpp
@@ -135,21 +135,13 @@ void PairSoft::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/pair_table.cpp b/src/pair_table.cpp
index 2aefa1baf65f712ccc817df0f797baca43ab0d25..7972d42db53e4d7fb3584309533e864b9565bfa2 100644
--- a/src/pair_table.cpp
+++ b/src/pair_table.cpp
@@ -175,21 +175,13 @@ void PairTable::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/pair_yukawa.cpp b/src/pair_yukawa.cpp
index beeaf87b9e7393212980bcc02bd0c4f0fcb0691e..b6db7c04e297e1b2b4e4910ac9dddfdbfd7bcc04 100644
--- a/src/pair_yukawa.cpp
+++ b/src/pair_yukawa.cpp
@@ -118,21 +118,13 @@ void PairYukawa::compute(int eflag, int vflag)
 	}
 
 	if (vflag == 1) {
-	  if (newton_pair || j < nlocal) {
-	    virial[0] += delx*delx*fforce;
-	    virial[1] += dely*dely*fforce;
-	    virial[2] += delz*delz*fforce;
-	    virial[3] += delx*dely*fforce;
-	    virial[4] += delx*delz*fforce;
-	    virial[5] += dely*delz*fforce;
-	  } else {
-	    virial[0] += 0.5*delx*delx*fforce;
-	    virial[1] += 0.5*dely*dely*fforce;
-	    virial[2] += 0.5*delz*delz*fforce;
-	    virial[3] += 0.5*delx*dely*fforce;
-	    virial[4] += 0.5*delx*delz*fforce;
-	    virial[5] += 0.5*dely*delz*fforce;
-	  }
+	  if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
+	  virial[0] += delx*delx*fforce;
+	  virial[1] += dely*dely*fforce;
+	  virial[2] += delz*delz*fforce;
+	  virial[3] += delx*dely*fforce;
+	  virial[4] += delx*delz*fforce;
+	  virial[5] += dely*delz*fforce;
 	}
       }
     }
diff --git a/src/random_park.cpp b/src/random_park.cpp
index 71fcb7a90a72f804135d5627b1c8dcc2b0ec9265..47c408e7fabcc1e5aa1c94e706402d9443773526 100644
--- a/src/random_park.cpp
+++ b/src/random_park.cpp
@@ -15,6 +15,8 @@
 
 #include "math.h"
 #include "random_park.h"
+#include "domain.h"
+#include "error.h"
 
 using namespace LAMMPS_NS;
 
@@ -24,10 +26,21 @@ using namespace LAMMPS_NS;
 #define IQ 127773
 #define IR 2836
 
+#define IA1 1366
+#define IC1 150889
+#define IM1 714025
+#define IA2 8121
+#define IC2 28411
+#define IM2 134456
+#define IA3 7141
+#define IC3 54773
+#define IM3 259200
+
 /* ---------------------------------------------------------------------- */
 
 RanPark::RanPark(LAMMPS *lmp, int seed_init) : Pointers(lmp)
 {
+  if (seed_init == 0) error->all("Invalid seed for Park random # generator");
   seed = seed_init;
   save = 0;
 }
@@ -73,11 +86,52 @@ double RanPark::gaussian()
 }
 
 /* ----------------------------------------------------------------------
-   reset the seed to a fractional (0-1) value of the total IM 
+   reset the seed based on atom position within box and ibase = caller seed
+   combine 3 RNGs based on fractional position in box into one new seed
 ------------------------------------------------------------------------- */
 
-void RanPark::reset(double fraction)
+void RanPark::reset(int ibase, double *coord)
 {
+  // for orthogonal box, lamda = fractional position in box
+  // for triclinic box, convert to lamda coords
+
+  double lamda[3];
+
+  if (domain->triclinic == 0) {
+    lamda[0] = (coord[0] - domain->boxlo[0]) / domain->prd[0];
+    lamda[1] = (coord[1] - domain->boxlo[1]) / domain->prd[1];
+    lamda[2] = (coord[2] - domain->boxlo[2]) / domain->prd[2];
+  } else domain->x2lamda(coord,lamda);
+
+  // seed 1,2,3 = combination of atom coord in each dim and user-input seed
+  // map geometric extent into range of each of 3 RNGs
+  // warm-up each RNG by calling it twice
+
+  int seed1,seed2,seed3;
+
+  seed1 = static_cast<int> (lamda[0] * IM1);
+  seed1 = (seed1+ibase) % IM1;
+  seed1 = (seed1*IA1+IC1) % IM1;
+  seed1 = (seed1*IA1+IC1) % IM1;
+
+  seed2 = static_cast<int> (lamda[1] * IM2);
+  seed2 = (seed2+ibase) % IM2;
+  seed2 = (seed2*IA2+IC2) % IM2;
+  seed2 = (seed2*IA2+IC2) % IM2;
+
+  seed3 = static_cast<int> (lamda[2] * IM3);
+  seed3 = (seed3+ibase) % IM3;
+  seed3 = (seed3*IA3+IC3) % IM3;
+  seed3 = (seed3*IA3+IC3) % IM3;
+
+  // fraction = 0-1 with giving each dim an equal weighting
+  // use fraction to reset Park/Miller RNG seed
+  // warm-up master RNG with new seed by calling it twice
+
+  double fraction = 1.0*seed1/(3*IM1) + 1.0*seed2/(3*IM2) + 1.0*seed3/(3*IM3);
   seed = static_cast<int> (fraction*IM) + 1;
   if (seed >= IM) seed = IM-1;
+
+  uniform();
+  uniform();
 }
diff --git a/src/random_park.h b/src/random_park.h
index a9132c7954790ef60cac2dccec10b1c63bb23fff..e78b8c4f6083ee9c79f650cc606cbfc83a2efdf7 100644
--- a/src/random_park.h
+++ b/src/random_park.h
@@ -23,7 +23,7 @@ class RanPark : protected Pointers {
   RanPark(class LAMMPS *, int);
   double uniform();
   double gaussian();
-  void reset(double);
+  void reset(int, double *);
 
  private:
   int seed,save;
diff --git a/src/read_data.cpp b/src/read_data.cpp
index 83926fe31d877482e6d7fc3b852069537e5bc3a3..40e4dfdc18771109ce3c775c671c3446ec8b2d07 100644
--- a/src/read_data.cpp
+++ b/src/read_data.cpp
@@ -18,7 +18,6 @@
 #include "read_data.h"
 #include "atom.h"
 #include "atom_vec.h"
-#include "atom_vec_hybrid.h"
 #include "comm.h"
 #include "update.h"
 #include "force.h"
@@ -123,42 +122,17 @@ void ReadData::command(int narg, char **arg)
   domain->set_local_box();
 
   // read rest of file in free format
-  // Atoms and Velocities keywords can have trailing hybrid sub-style
 
   int atomflag = 0;
-  int hybridflag = 0;
-  if (strcmp(atom->atom_style,"hybrid") == 0) hybridflag = 1;
-
   parse_keyword(1,1);
 
   while (strlen(keyword)) {
     if (strcmp(keyword,"Atoms") == 0) {
-      atoms(0);
-      atomflag = 1;
-    } else if (hybridflag && strstr(keyword,"Atoms") == keyword) {
-      strtok(keyword," \t");
-      char *substyle = strtok(NULL," \t");
-      AtomVecHybrid *avec_hybrid = (AtomVecHybrid *) atom->avec;
-      if (substyle == NULL) error->all("Invalid data file section: Atoms");
-      int ihybrid;
-      for (ihybrid = 0; ihybrid < avec_hybrid->nstyles; ihybrid++)
-	if (strcmp(avec_hybrid->keywords[ihybrid],substyle) == 0) break;
-      atoms(ihybrid);
+      atoms();
       atomflag = 1;
     } else if (strcmp(keyword,"Velocities") == 0) {
       if (atomflag == 0) error->all("Must read Atoms before Velocities");
-      velocities(0);
-    } else if (hybridflag && strstr(keyword,"Velocities") == keyword) {
-      if (atomflag == 0) error->all("Must read Atoms before Velocities");
-      strtok(keyword," \t");
-      char *substyle = strtok(NULL," \t");
-      AtomVecHybrid *avec_hybrid = (AtomVecHybrid *) atom->avec;
-      if (substyle == NULL)
-	error->all("Invalid data file section: Velocities");
-      int ihybrid;
-      for (ihybrid = 0; ihybrid < avec_hybrid->nstyles; ihybrid++)
-	if (strcmp(avec_hybrid->keywords[ihybrid],substyle) == 0) break;
-      velocities(ihybrid);
+      velocities();
     } else if (strcmp(keyword,"Bonds") == 0) {
       if (atom->avec->bonds_allow == 0) 
 	error->all("Invalid data file section: Bonds");
@@ -182,6 +156,8 @@ void ReadData::command(int narg, char **arg)
 
     } else if (strcmp(keyword,"Masses") == 0) {
       mass();
+    } else if (strcmp(keyword,"Shapes") == 0) {
+      shape();
     } else if (strcmp(keyword,"Dipoles") == 0) {
       dipole();
     } else if (strcmp(keyword,"Pair Coeffs") == 0) {
@@ -391,12 +367,11 @@ void ReadData::header(int flag)
 }
 
 /* ----------------------------------------------------------------------
-   read all atoms of a sub-style ihybrid (0 if not atom style hybrid)
-   to find atoms, must build atom map if not a molecular system 
+   read all atoms
    accumulate nread in double precision to allow natoms > 2^31
 ------------------------------------------------------------------------- */
 
-void ReadData::atoms(int ihybrid)
+void ReadData::atoms()
 {
   int i,m,nchunk;
   
@@ -419,7 +394,7 @@ void ReadData::atoms(int ihybrid)
     MPI_Bcast(&m,1,MPI_INT,0,world);
     MPI_Bcast(buffer,m,MPI_CHAR,0,world);
 
-    atom->data_atoms(nchunk,buffer,ihybrid);
+    atom->data_atoms(nchunk,buffer);
     nread += nchunk;
   }
 
@@ -472,12 +447,12 @@ void ReadData::atoms(int ihybrid)
 }
 
 /* ----------------------------------------------------------------------
-   read all velocities of a sub-style ihybrid (0 if not atom style hybrid)
+   read all velocities
    to find atoms, must build atom map if not a molecular system 
    accumulate nread in double precision to allow natoms > 2^31
 ------------------------------------------------------------------------- */
 
-void ReadData::velocities(int ihybrid)
+void ReadData::velocities()
 {
   int i,m,nchunk;
 
@@ -508,7 +483,7 @@ void ReadData::velocities(int ihybrid)
     MPI_Bcast(&m,1,MPI_INT,0,world);
     MPI_Bcast(buffer,m,MPI_CHAR,0,world);
 
-    atom->data_vels(nchunk,buffer,ihybrid);
+    atom->data_vels(nchunk,buffer);
     nread += nchunk;
   }
 
@@ -724,6 +699,35 @@ void ReadData::mass()
 
 /* ---------------------------------------------------------------------- */
 
+void ReadData::shape()
+{
+  int i,m;
+  char *buf = new char[atom->ntypes*MAXLINE];
+  char *original = buf;
+
+  if (me == 0) {
+    char *eof;
+    m = 0;
+    for (i = 0; i < atom->ntypes; i++) {
+      eof = fgets(&buf[m],MAXLINE,fp);
+      if (eof == NULL) error->one("Unexpected end of data file");
+      m += strlen(&buf[m]);
+      buf[m-1] = '\0';
+    }
+  }
+
+  MPI_Bcast(&m,1,MPI_INT,0,world);
+  MPI_Bcast(buf,m,MPI_CHAR,0,world);
+
+  for (i = 0; i < atom->ntypes; i++) {
+    atom->set_shape(buf);
+    buf += strlen(buf) + 1;
+  }
+  delete [] original;
+}
+
+/* ---------------------------------------------------------------------- */
+
 void ReadData::dipole()
 {
   int i,m;
diff --git a/src/read_data.h b/src/read_data.h
index 03d27e718b45f669952d5fbe07cc33f10375f3ef..c18b23002f4942377b47b99a9d518c9e1a6f1632 100644
--- a/src/read_data.h
+++ b/src/read_data.h
@@ -40,14 +40,15 @@ class ReadData : protected Pointers {
   void skip_lines(int);
   void parse_coeffs(int, char *);
 
-  void atoms(int);
-  void velocities(int);
+  void atoms();
+  void velocities();
   void bonds();
   void angles();
   void dihedrals();
   void impropers();
 
   void mass();
+  void shape();
   void dipole();
 
   void paircoeffs();
diff --git a/src/read_restart.cpp b/src/read_restart.cpp
index 1bf143359c00c3993c02171826a13090d8e46731..b64ba974bb3da2817a50353c6492f65bb3bef556 100644
--- a/src/read_restart.cpp
+++ b/src/read_restart.cpp
@@ -37,6 +37,23 @@
 
 using namespace LAMMPS_NS;
 
+// same as write_restart.cpp
+
+enum{VERSION,UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2,
+       NEWTON_PAIR,NEWTON_BOND,XPERIODIC,YPERIODIC,ZPERIODIC,
+       BOUNDARY_00,BOUNDARY_01,BOUNDARY_10,BOUNDARY_11,BOUNDARY_20,BOUNDARY_21,
+       ATOM_STYLE,NATOMS,NTYPES,
+       NBONDS,NBONDTYPES,BOND_PER_ATOM,
+       NANGLES,NANGLETYPES,ANGLE_PER_ATOM,
+       NDIHEDRALS,NDIHEDRALTYPES,DIHEDRAL_PER_ATOM,
+       NIMPROPERS,NIMPROPERTYPES,IMPROPER_PER_ATOM,
+       BOXLO_0,BOXHI_0,BOXLO_1,BOXHI_1,BOXLO_2,BOXHI_2,
+       SPECIAL_LJ_1,SPECIAL_LJ_2,SPECIAL_LJ_3,
+       SPECIAL_COUL_1,SPECIAL_COUL_2,SPECIAL_COUL_3,
+       XY,XZ,YZ};
+enum{MASS,SHAPE,DIPOLE};
+enum{PAIR,BOND,ANGLE,DIHEDRAL,IMPROPER};
+
 #define LB_FACTOR 1.1
 
 /* ---------------------------------------------------------------------- */
@@ -112,8 +129,7 @@ void ReadRestart::command(int narg, char **arg)
   // nextra = max # of extra quantities stored with each atom
 
   group->read_restart(fp);
-  if (atom->mass) mass();
-  if (atom->dipole) dipole();
+  type_arrays();
   force_fields();
 
   int nextra = modify->read_restart(fp);
@@ -336,7 +352,7 @@ void ReadRestart::header()
 
     // check restart file version, compare to LAMMPS version
 
-    if (flag == 0) {
+    if (flag == VERSION) {
       char *version = read_char();
       if (strcmp(version,universe->version) != 0) {
 	error->warning("Restart file version does not match LAMMPS version");
@@ -348,19 +364,19 @@ void ReadRestart::header()
       // reset unit_style only if different
       // so that timestep,neighbor-skin are not changed
 
-    } else if (flag == 1) {
+    } else if (flag == UNITS) {
       char *style = read_char();
       if (strcmp(style,update->unit_style) != 0 && me == 0)
 	error->warning("Resetting unit_style to restart file value");
       if (strcmp(style,update->unit_style) != 0) update->set_units(style);
       delete [] style;
 
-    } else if (flag == 2) {
+    } else if (flag == NTIMESTEP) {
       update->ntimestep = read_int();
 
       // set dimension from restart file, warn if different
 
-    } else if (flag == 3) {
+    } else if (flag == DIMENSION) {
       int dimension = read_int();
       if (dimension != force->dimension && me == 0)
 	error->warning("Resetting dimension to restart file value");
@@ -370,18 +386,18 @@ void ReadRestart::header()
 
       // read nprocs_file from restart file, warn if different
 
-    } else if (flag == 4) {
+    } else if (flag == NPROCS) {
       nprocs_file = read_int();
       if (nprocs_file != comm->nprocs && me == 0)
 	error->warning("Restart file used different # of processors");
 
       // don't set procgrid, warn if different
 
-    } else if (flag == 5) {
+    } else if (flag == PROCGRID_0) {
       px = read_int();
-    } else if (flag == 6) {
+    } else if (flag == PROCGRID_1) {
       py = read_int();
-    } else if (flag == 7) {
+    } else if (flag == PROCGRID_2) {
       pz = read_int();
       if (comm->user_procgrid[0] != 0 && 
 	  (px != comm->user_procgrid[0] || py != comm->user_procgrid[1] || 
@@ -391,11 +407,11 @@ void ReadRestart::header()
       // don't set newton_pair, warn if different
       // set newton_bond from restart file, warn if different
 
-    } else if (flag == 8) {
+    } else if (flag == NEWTON_PAIR) {
       int newton_pair = read_int();
       if (newton_pair != force->newton_pair && me == 0)
 	error->warning("Restart file used different newton pair setting");
-    } else if (flag == 9) {
+    } else if (flag == NEWTON_BOND) {
       int newton_bond = read_int();
       if (newton_bond != force->newton_bond && me == 0)
 	error->warning("Resetting newton bond to restart file value");
@@ -405,23 +421,23 @@ void ReadRestart::header()
 
       // set boundary settings from restart file, warn if different
 
-    } else if (flag == 10) {
+    } else if (flag == XPERIODIC) {
       xperiodic = read_int();
-    } else if (flag == 11) {
+    } else if (flag == YPERIODIC) {
       yperiodic = read_int();
-    } else if (flag == 12) {
+    } else if (flag == ZPERIODIC) {
       zperiodic = read_int();
-    } else if (flag == 13) {
+    } else if (flag == BOUNDARY_00) {
       boundary[0][0] = read_int();
-    } else if (flag == 14) {
+    } else if (flag == BOUNDARY_01) {
       boundary[0][1] = read_int();
-    } else if (flag == 15) {
+    } else if (flag == BOUNDARY_10) {
       boundary[1][0] = read_int();
-    } else if (flag == 16) {
+    } else if (flag == BOUNDARY_11) {
       boundary[1][1] = read_int();
-    } else if (flag == 17) {
+    } else if (flag == BOUNDARY_20) {
       boundary[2][0] = read_int();
-    } else if (flag == 18) {
+    } else if (flag == BOUNDARY_21) {
       boundary[2][1] = read_int();
 
       int flag = 0;
@@ -459,7 +475,7 @@ void ReadRestart::header()
       // create new AtomVec class
       // if style = hybrid, read additional sub-class arguments
 
-    } else if (flag == 19) {
+    } else if (flag == ATOM_STYLE) {
       char *style = read_char();
 
       int nwords = 0;
@@ -476,72 +492,72 @@ void ReadRestart::header()
       delete [] words;
       delete [] style;
 
-    } else if (flag == 20) {
+    } else if (flag == NATOMS) {
       atom->natoms = read_double();
-    } else if (flag == 21) {
+    } else if (flag == NTYPES) {
       atom->ntypes = read_int();
-    } else if (flag == 22) {
+    } else if (flag == NBONDS) {
       atom->nbonds = read_int();
-    } else if (flag == 23) {
+    } else if (flag == NBONDTYPES) {
       atom->nbondtypes = read_int();
-    } else if (flag == 24) {
+    } else if (flag == BOND_PER_ATOM) {
       atom->bond_per_atom = read_int();
-    } else if (flag == 25) {
+    } else if (flag == NANGLES) {
       atom->nangles = read_int();
-    } else if (flag == 26) {
+    } else if (flag == NANGLETYPES) {
       atom->nangletypes = read_int();
-    } else if (flag == 27) {
+    } else if (flag == ANGLE_PER_ATOM) {
       atom->angle_per_atom = read_int();
-    } else if (flag == 28) {
+    } else if (flag == NDIHEDRALS) {
       atom->ndihedrals = read_int();
-    } else if (flag == 29) {
+    } else if (flag == NDIHEDRALTYPES) {
       atom->ndihedraltypes = read_int();
-    } else if (flag == 30) {
+    } else if (flag == DIHEDRAL_PER_ATOM) {
       atom->dihedral_per_atom = read_int();
-    } else if (flag == 31) {
+    } else if (flag == NIMPROPERS) {
       atom->nimpropers = read_int();
-    } else if (flag == 32) {
+    } else if (flag == NIMPROPERTYPES) {
       atom->nimpropertypes = read_int();
-    } else if (flag == 33) {
+    } else if (flag == IMPROPER_PER_ATOM) {
       atom->improper_per_atom = read_int();
 
-    } else if (flag == 34) {
+    } else if (flag == BOXLO_0) {
       domain->boxlo[0] = read_double();
-    } else if (flag == 35) {
+    } else if (flag == BOXHI_0) {
       domain->boxhi[0] = read_double();
-    } else if (flag == 36) {
+    } else if (flag == BOXLO_1) {
       domain->boxlo[1] = read_double();
-    } else if (flag == 37) {
+    } else if (flag == BOXHI_1) {
       domain->boxhi[1] = read_double();
-    } else if (flag == 38) {
+    } else if (flag == BOXLO_2) {
       domain->boxlo[2] = read_double();
-    } else if (flag == 39) {
+    } else if (flag == BOXHI_2) {
       domain->boxhi[2] = read_double();
 
-    } else if (flag == 40) {
+    } else if (flag == SPECIAL_LJ_1) {
       force->special_lj[1] = read_double();
-    } else if (flag == 41) {
+    } else if (flag == SPECIAL_LJ_2) {
       force->special_lj[2] = read_double();
-    } else if (flag == 42) {
+    } else if (flag == SPECIAL_LJ_3) {
       force->special_lj[3] = read_double();
-    } else if (flag == 43) {
+    } else if (flag == SPECIAL_COUL_1) {
       force->special_coul[1] = read_double();
-    } else if (flag == 44) {
+    } else if (flag == SPECIAL_COUL_2) {
       force->special_coul[2] = read_double();
-    } else if (flag == 45) {
+    } else if (flag == SPECIAL_COUL_3) {
       force->special_coul[3] = read_double();
 
-    } else if (flag == 46) {
+    } else if (flag == XY) {
       domain->triclinic = 1;
       domain->xy = read_double();
-    } else if (flag == 47) {
+    } else if (flag == XZ) {
       domain->triclinic = 1;
       domain->xz = read_double();
-    } else if (flag == 48) {
+    } else if (flag == YZ) {
       domain->triclinic = 1;
       domain->yz = read_double();
 
-    } else error->all("Invalid flag in header of restart file");
+    } else error->all("Invalid flag in header section of restart file");
 
     flag = read_int();
   }
@@ -549,24 +565,37 @@ void ReadRestart::header()
 
 /* ---------------------------------------------------------------------- */
 
-void ReadRestart::mass()
+void ReadRestart::type_arrays()
 {
-  double *mass = new double[atom->ntypes+1];
-  if (me == 0) fread(&mass[1],sizeof(double),atom->ntypes,fp);
-  MPI_Bcast(&mass[1],atom->ntypes,MPI_DOUBLE,0,world);
-  atom->set_mass(mass);
-  delete [] mass;
-}
+  int flag = read_int();
+  while (flag >= 0) {
 
-/* ---------------------------------------------------------------------- */
+    if (flag == MASS) {
+      double *mass = new double[atom->ntypes+1];
+      if (me == 0) fread(&mass[1],sizeof(double),atom->ntypes,fp);
+      MPI_Bcast(&mass[1],atom->ntypes,MPI_DOUBLE,0,world);
+      atom->set_mass(mass);
+      delete [] mass;
+
+    } else if (flag == SHAPE) {
+      double **shape =
+	memory->create_2d_double_array(atom->ntypes+1,3,"restart:shape");
+      if (me == 0) fread(&shape[1][0],sizeof(double),atom->ntypes*3,fp);
+      MPI_Bcast(&shape[1][0],atom->ntypes*3,MPI_DOUBLE,0,world);
+      atom->set_shape(shape);
+      memory->destroy_2d_double_array(shape);
+
+    } else if (flag == DIPOLE) {
+      double *dipole = new double[atom->ntypes+1];
+      if (me == 0) fread(&dipole[1],sizeof(double),atom->ntypes,fp);
+      MPI_Bcast(&dipole[1],atom->ntypes,MPI_DOUBLE,0,world);
+      atom->set_dipole(dipole);
+      delete [] dipole;
+
+    } else error->all("Invalid flag in type arrays section of restart file");
 
-void ReadRestart::dipole()
-{
-  double *dipole = new double[atom->ntypes+1];
-  if (me == 0) fread(&dipole[1],sizeof(double),atom->ntypes,fp);
-  MPI_Bcast(&dipole[1],atom->ntypes,MPI_DOUBLE,0,world);
-  atom->set_dipole(dipole);
-  delete [] dipole;
+    flag = read_int();
+  }
 }
 
 /* ---------------------------------------------------------------------- */
@@ -576,47 +605,45 @@ void ReadRestart::force_fields()
   int n;
   char *style;
 
-  if (me == 0) fread(&n,sizeof(int),1,fp);
-  MPI_Bcast(&n,1,MPI_INT,0,world);
-  if (n) {
-    style = (char *) memory->smalloc(n*sizeof(char),"read_restart:style");
-    if (me == 0) fread(style,sizeof(char),n,fp);
-    MPI_Bcast(style,n,MPI_CHAR,0,world);
-
-    if (force->pair == NULL || strcmp(style,force->pair_style)) {
-      if (force->pair && me == 0)
-	error->warning("Resetting pair_style to restart file value");
-      force->create_pair(style);
-    }
-      
-    memory->sfree(style);
-    force->pair->read_restart(fp);
-  } else force->create_pair("none");
+  int flag = read_int();
+  while (flag >= 0) {
 
-  if (atom->avec->bonds_allow) {
-    if (me == 0) fread(&n,sizeof(int),1,fp);
-    MPI_Bcast(&n,1,MPI_INT,0,world);
-    if (n) {
-      style = (char *) memory->smalloc(n*sizeof(char),"read_restart:style");
+    if (flag == PAIR) {
+      if (me == 0) fread(&n,sizeof(int),1,fp);
+      MPI_Bcast(&n,1,MPI_INT,0,world);
+      style = new char[n];
       if (me == 0) fread(style,sizeof(char),n,fp);
       MPI_Bcast(style,n,MPI_CHAR,0,world);
 
+      if (force->pair == NULL || strcmp(style,force->pair_style)) {
+	if (force->pair && me == 0)
+	  error->warning("Resetting pair_style to restart file value");
+	force->create_pair(style);
+      }
+      
+      delete [] style;
+      force->pair->read_restart(fp);
+
+    } else if (flag == BOND) {
+      if (me == 0) fread(&n,sizeof(int),1,fp);
+      MPI_Bcast(&n,1,MPI_INT,0,world);
+      style = new char[n];
+      if (me == 0) fread(style,sizeof(char),n,fp);
+      MPI_Bcast(style,n,MPI_CHAR,0,world);
+      
       if (force->bond == NULL || strcmp(style,force->bond_style)) {
 	if (force->bond && me == 0)
 	  error->warning("Resetting bond_style to restart file value");
 	force->create_bond(style);
       }
       
-      memory->sfree(style);
+      delete [] style;
       force->bond->read_restart(fp);
-    } else force->create_bond("none");
-  }
 
-  if (atom->avec->angles_allow) {
-    if (me == 0) fread(&n,sizeof(int),1,fp);
-    MPI_Bcast(&n,1,MPI_INT,0,world);
-    if (n) {
-      style = (char *) memory->smalloc(n*sizeof(char),"read_restart:style");
+    } else if (flag == ANGLE) {
+      if (me == 0) fread(&n,sizeof(int),1,fp);
+      MPI_Bcast(&n,1,MPI_INT,0,world);
+      style = new char[n];
       if (me == 0) fread(style,sizeof(char),n,fp);
       MPI_Bcast(style,n,MPI_CHAR,0,world);
 
@@ -626,16 +653,13 @@ void ReadRestart::force_fields()
 	force->create_angle(style);
       }
 
-      memory->sfree(style);
+      delete [] style;
       force->angle->read_restart(fp);
-    } else force->create_angle("none");
-  }
 
-  if (atom->avec->dihedrals_allow) {
-    if (me == 0) fread(&n,sizeof(int),1,fp);
-    MPI_Bcast(&n,1,MPI_INT,0,world);
-    if (n) {
-      style = (char *) memory->smalloc(n*sizeof(char),"read_restart:style");
+    } else if (flag == DIHEDRAL) {
+      if (me == 0) fread(&n,sizeof(int),1,fp);
+      MPI_Bcast(&n,1,MPI_INT,0,world);
+      style = new char[n];
       if (me == 0) fread(style,sizeof(char),n,fp);
       MPI_Bcast(style,n,MPI_CHAR,0,world);
 
@@ -645,16 +669,13 @@ void ReadRestart::force_fields()
 	force->create_dihedral(style);
       }
 
-      memory->sfree(style);
+      delete [] style;
       force->dihedral->read_restart(fp);
-    } else force->create_dihedral("none");
-  }
 
-  if (atom->avec->impropers_allow) {
-    if (me == 0) fread(&n,sizeof(int),1,fp);
-    MPI_Bcast(&n,1,MPI_INT,0,world);
-    if (n) {
-      style = (char *) memory->smalloc(n*sizeof(char),"read_restart:style");
+    } else if (flag == IMPROPER) {
+      if (me == 0) fread(&n,sizeof(int),1,fp);
+      MPI_Bcast(&n,1,MPI_INT,0,world);
+      style = new char[n];
       if (me == 0) fread(style,sizeof(char),n,fp);
       MPI_Bcast(style,n,MPI_CHAR,0,world);
 
@@ -664,9 +685,12 @@ void ReadRestart::force_fields()
 	force->create_improper(style);
       }
 
-      memory->sfree(style);
+      delete [] style;
       force->improper->read_restart(fp);
-    } else force->create_improper("none");
+
+    } else error->all("Invalid flag in force field section of restart file");
+
+    flag = read_int();
   }
 }
 
diff --git a/src/read_restart.h b/src/read_restart.h
index af10ce9123f4d57277628a960830b1dd1efc1ed3..e45af62530dc12715e8f9aaa33128b76bb5a0328 100644
--- a/src/read_restart.h
+++ b/src/read_restart.h
@@ -31,8 +31,7 @@ class ReadRestart : protected Pointers {
 
   void file_search(char *, char *);
   void header();
-  void mass();
-  void dipole();
+  void type_arrays();
   void force_fields();
 
   int read_int();
diff --git a/src/region_intersect.cpp b/src/region_intersect.cpp
index 8100439d051047f67655f01f56c73c3911488b7b..872cc3cc04b618db336359f0fb7ccdcd5b609f93 100644
--- a/src/region_intersect.cpp
+++ b/src/region_intersect.cpp
@@ -39,10 +39,8 @@ RegIntersect::RegIntersect(LAMMPS *lmp, int narg, char **arg) :
 
   int iregion;
   for (int iarg = 0; iarg < n; iarg++) {
-    for (iregion = 0; iregion < domain->nregion; iregion++)
-      if (strcmp(arg[iarg+3],domain->regions[iregion]->id) == 0) break;
-    if (iregion == domain->nregion)
-      error->all("Region union region ID does not exist");
+    iregion = domain->find_region(arg[iarg+3]);
+    if (iregion == -1) error->all("Region intersect region ID does not exist");
     list[nregion++] = iregion;
   }
 
diff --git a/src/region_union.cpp b/src/region_union.cpp
index 834a72d0996ab1f7d1d62ca6ec7435b5f16846f3..a0ff63e523268b21102d5eb9a85ff0bed5dc36a3 100644
--- a/src/region_union.cpp
+++ b/src/region_union.cpp
@@ -40,10 +40,8 @@ RegUnion::RegUnion(LAMMPS *lmp, int narg, char **arg) : Region(lmp, narg, arg)
 
   int iregion;
   for (int iarg = 0; iarg < n; iarg++) {
-    for (iregion = 0; iregion < domain->nregion; iregion++)
-      if (strcmp(arg[iarg+3],domain->regions[iregion]->id) == 0) break;
-    if (iregion == domain->nregion)
-      error->all("Region union region ID does not exist");
+    iregion = domain->find_region(arg[iarg+3]);
+    if (iregion == -1) error->all("Region union region ID does not exist");
     list[nregion++] = iregion;
   }
 
diff --git a/src/respa.cpp b/src/respa.cpp
index 79a51be07635d50dc77255c3a5b062159e87301e..73836703a5ba7a21394d5b32d9b627036d27f77b 100644
--- a/src/respa.cpp
+++ b/src/respa.cpp
@@ -251,11 +251,6 @@ void Respa::init()
   if (modify->nfix == 0)
     error->warning("No fixes defined, atoms won't move");
 
-  // respa not allowed with granular atom style
-
-  if (atom->check_style("granular"))
-    error->all("Respa not allowed with atom style granular");
-
   // create fix needed for storing atom-based respa level forces
   // will delete it at end of run
 
diff --git a/src/set.cpp b/src/set.cpp
index de7ed0a4a072ddce7dd61365ca5abd0014cf6a61..617d9c1510c63b1ef842813dace19b72451a4252 100644
--- a/src/set.cpp
+++ b/src/set.cpp
@@ -19,6 +19,7 @@
 #include "atom.h"
 #include "atom_vec.h"
 #include "domain.h"
+#include "region.h"
 #include "group.h"
 #include "comm.h"
 #include "neighbor.h"
@@ -29,16 +30,11 @@
 
 using namespace LAMMPS_NS;
 
-#define ONEATOM  0
-#define ATOM     1
-#define BOND     2
-#define ANGLE    3
-#define DIHEDRAL 4
-#define IMPROPER 5
-#define CHARGE   6
-#define DIPOLE   7
-
-#define WARMUP 100
+enum{ATOM,GROUP,REGION};
+enum{TYPE,TYPE_FRACTION,MOLECULE,
+     X,Y,Z,VX,VY,VZ,CHARGE,
+     DIPOLE,DIPOLE_RANDOM,QUAT,QUAT_RANDOM,
+     BOND,ANGLE,DIHEDRAL,IMPROPER};
 
 /* ---------------------------------------------------------------------- */
 
@@ -52,112 +48,402 @@ void Set::command(int narg, char **arg)
     error->all("Set command before simulation box is defined");
   if (atom->natoms == 0)
     error->all("Set command with no atoms existing");
-  if (narg != 3) error->all("Illegal set command");
-
-  // set style
-
-  int style;
-  if (strcmp(arg[1],"atom") == 0) style = ATOM;
-  else if (strcmp(arg[1],"bond") == 0) style = BOND;
-  else if (strcmp(arg[1],"angle") == 0) style = ANGLE;
-  else if (strcmp(arg[1],"dihedral") == 0) style = DIHEDRAL;
-  else if (strcmp(arg[1],"improper") == 0) style = IMPROPER;
-  else if (strcmp(arg[1],"charge") == 0) style = CHARGE;
-  else if (strcmp(arg[1],"dipole") == 0) style = DIPOLE;
-  else style = ONEATOM;
-
-  // set atom or group
-
-  int atomid,igroup,groupbit;
-  if (style == ONEATOM) atomid = atoi(arg[0]);
-  else {
-    igroup = group->find(arg[0]);
-    if (igroup == -1) error->all("Cannot find set command group ID");
-    groupbit = group->bitmask[igroup];
+  if (narg < 3) error->all("Illegal set command");
+
+  // style and ID
+
+  if (strcmp(arg[0],"atom") == 0) style = ATOM;
+  else if (strcmp(arg[0],"group") == 0) style = GROUP;
+  else if (strcmp(arg[0],"region") == 0) style = REGION;
+  else error->all("Illegal set command");
+
+  int n = strlen(arg[1]) + 1;
+  id = new char[n];
+  strcpy(id,arg[1]);
+  select = NULL;
+
+  // loop over keyword/value pairs
+  // call appropriate routine to reset attributes
+
+  if (comm->me == 0 && screen) fprintf(screen,"Setting atom values ...\n");
+
+  int allcount,origarg;
+
+  int iarg = 2;
+  while (iarg < narg) {
+    count = 0;
+    origarg = iarg;
+    
+    if (strcmp(arg[iarg],"type") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      ivalue = atoi(arg[iarg+1]);
+      if (ivalue <= 0 || ivalue > atom->ntypes)
+	error->all("Invalid value in set command");
+      set(TYPE);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"type/fraction") == 0) {
+      if (iarg+4 > narg) error->all("Illegal set command");
+      newtype = atoi(arg[iarg+1]);
+      fraction = atof(arg[iarg+2]);
+      ivalue = atoi(arg[iarg+3]);
+      if (fraction < 0.0 || fraction > 1.0) 
+	error->all("Invalid value in set command");
+      if (ivalue <= 0) error->all("Invalid random number seed in set command");
+      setrandom(TYPE_FRACTION);
+      iarg += 4;
+    } else if (strcmp(arg[iarg],"mol") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      ivalue = atoi(arg[iarg+1]);
+      if (atom->molecule == NULL)
+	error->all("Cannot set this attribute for this atom style");
+      set(MOLECULE);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"x") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      dvalue = atof(arg[iarg+1]);
+      set(X);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"y") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      dvalue = atof(arg[iarg+1]);
+      set(Y);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"z") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      dvalue = atof(arg[iarg+1]);
+      set(Z);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"vx") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      dvalue = atof(arg[iarg+1]);
+      set(VX);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"vy") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      dvalue = atof(arg[iarg+1]);
+      set(VY);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"vz") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      dvalue = atof(arg[iarg+1]);
+      set(VZ);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"charge") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      dvalue = atof(arg[iarg+1]);
+      if (atom->q == NULL)
+	error->all("Cannot set this attribute for this atom style");
+      set(CHARGE);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"dipole") == 0) {
+      if (iarg+4 > narg) error->all("Illegal set command");
+      xvalue = atof(arg[iarg+1]);
+      yvalue = atof(arg[iarg+2]);
+      zvalue = atof(arg[iarg+3]);
+      if (atom->mu == NULL || atom->dipole == NULL)
+	error->all("Cannot set this attribute for this atom style");
+      set(DIPOLE);
+      iarg += 4;
+    } else if (strcmp(arg[iarg],"dipole/random") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      ivalue = atoi(arg[iarg+1]);
+      if (atom->mu == NULL || atom->shape == NULL)
+	error->all("Cannot set this attribute for this atom style");
+      if (ivalue <= 0) error->all("Invalid random number seed in set command");
+      setrandom(DIPOLE_RANDOM);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"quat") == 0) {
+      if (iarg+4 > narg) error->all("Illegal set command");
+      xvalue = atof(arg[iarg+1]);
+      yvalue = atof(arg[iarg+2]);
+      zvalue = atof(arg[iarg+3]);
+      if (atom->quat == NULL)
+	error->all("Cannot set this attribute for this atom style");
+      set(QUAT);
+      iarg += 4;
+    } else if (strcmp(arg[iarg],"quat/random") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      ivalue = atoi(arg[iarg+1]);
+      if (atom->quat == NULL)
+	error->all("Cannot set this attribute for this atom style");
+      if (ivalue <= 0) error->all("Invalid random number seed in set command");
+      setrandom(QUAT_RANDOM);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"bond") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      ivalue = atoi(arg[iarg+1]);
+      if (atom->avec->bonds_allow == 0)
+	error->all("Cannot set this attribute for this atom style");
+      if (ivalue <= 0 || ivalue > atom->nbondtypes)
+	error->all("Invalid value in set command");
+      topology(BOND);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"angle") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      ivalue = atoi(arg[iarg+1]);
+      if (atom->avec->angles_allow == 0)
+	error->all("Cannot set this attribute for this atom style");
+      if (ivalue <= 0 || ivalue > atom->nangletypes)
+	error->all("Invalid value in set command");
+      topology(ANGLE);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"dihedral") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      ivalue = atoi(arg[iarg+1]);
+      if (atom->avec->dihedrals_allow == 0)
+	error->all("Cannot set this attribute for this atom style");
+      if (ivalue <= 0 || ivalue > atom->ndihedraltypes)
+	error->all("Invalid value in set command");
+      topology(DIHEDRAL);
+      iarg += 2;
+    } else if (strcmp(arg[iarg],"improper") == 0) {
+      if (iarg+2 > narg) error->all("Illegal set command");
+      ivalue = atoi(arg[iarg+1]);
+      if (atom->avec->impropers_allow == 0)
+	error->all("Cannot set this attribute for this atom style");
+      if (ivalue <= 0 || ivalue > atom->nimpropertypes)
+	error->all("Invalid value in set command");
+      topology(IMPROPER);
+      iarg += 2;
+    } else error->all("Illegal set command");    
+
+    // statistics
+
+    MPI_Allreduce(&count,&allcount,1,MPI_INT,MPI_SUM,world);
+    
+    if (comm->me == 0) {
+      if (screen) fprintf(screen,"  %d settings made for %s\n",
+			  allcount,arg[origarg]);
+      if (logfile) fprintf(logfile,"  %d settings made for %s\n",
+			   allcount,arg[origarg]);
+    }
   }
-  
-  // consistency checks
 
-  if ((style == BOND && atom->avec->bonds_allow == 0) ||
-      (style == ANGLE && atom->avec->angles_allow == 0) ||
-      (style == DIHEDRAL && atom->avec->dihedrals_allow == 0) ||
-      (style == IMPROPER && atom->avec->impropers_allow == 0) ||
-      (style == CHARGE && atom->q == NULL) ||
-      (style == DIPOLE && atom->dipole == NULL))
-    error->all("Cannot set this attribute for this atom style");
+  // free local memory
+
+  delete [] id;
+  delete [] select;
+}
+
+/* ----------------------------------------------------------------------
+   select atoms according to ATOM, GROUP, REGION style
+   n = nlocal or nlocal+nghost depending on keyword
+------------------------------------------------------------------------- */
 
-  if (style == ONEATOM && strcmp(arg[1],"q") == 0 && atom->q == NULL)
-    error->all("Cannot set this attribute for this atom style");
+void Set::selection(int n)
+{
+  delete [] select;
+  select = new int[n];
 
-  if (style == ONEATOM && strcmp(arg[1],"mol") == 0 && atom->molecular == 0)
-    error->all("Cannot set this attribute for this atom style");
+  if (style == ATOM) {
+    if (atom->tag_enable == 0)
+      error->all("Cannot use set atom with no atom IDs defined");
+    int idatom = atoi(id);
 
-  // border swap to insure type and mask is current for off-proc atoms
-  // only needed for BOND, ANGLE, etc types
-  // enforce PBC before in case atoms are outside box
-  // init entire system since comm->exchange is done
-  // comm::init needs neighbor::init needs pair::init needs kspace::init, etc
-  
-  if (style == BOND || style == ANGLE || 
-      style == DIHEDRAL || style == IMPROPER) {
-    if (comm->me == 0 && screen) fprintf(screen,"System init for set ...\n");
-    lmp->init();
-
-    if (domain->triclinic) domain->x2lamda(atom->nlocal);
-    domain->pbc();
-    domain->reset_box();
-    comm->setup();
-    comm->exchange();
-    comm->borders();
-    if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
+    int *tag = atom->tag;
+    for (int i = 0; i < n; i++)
+      if (idatom == tag[i]) select[i] = 1;
+      else select[i] = 0;
+
+  } else if (style == GROUP) {
+    int igroup = group->find(id);
+    if (igroup == -1) error->all("Could not find set group ID");
+    int groupbit = group->bitmask[igroup];
+
+    int *mask = atom->mask;
+    for (int i = 0; i < n; i++)
+      if (mask[i] & groupbit) select[i] = 1;
+      else select[i] = 0;
+
+  } else {
+    int iregion = domain->find_region(id);
+    if (iregion == -1) error->all("Set region ID does not exist");
+
+    double **x = atom->x;
+    for (int i = 0; i < n; i++)
+      if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
+	select[i] = 1;
+      else select[i] = 0;
   }
+}
 
-  if (comm->me == 0 && screen) fprintf(screen,"Setting atom values ...\n");
-  
-  // set new values
+/* ----------------------------------------------------------------------
+   set an owned atom property directly
+------------------------------------------------------------------------- */
+
+void Set::set(int keyword)
+{
+  if (keyword == DIPOLE) atom->check_dipole();
+
+  selection(atom->nlocal);
 
-  int *mask = atom->mask;
   int nlocal = atom->nlocal;
-  int m,atom1,atom2,atom3,atom4;
+  for (int i = 0; i < nlocal; i++)
+    if (select[i]) {
+      if (keyword == TYPE) atom->type[i] = ivalue;
+      else if (keyword == MOLECULE) atom->molecule[i] = ivalue;
+      else if (keyword == X) atom->x[i][0] = dvalue;
+      else if (keyword == Y) atom->x[i][1] = dvalue;
+      else if (keyword == Z) atom->x[i][2] = dvalue;
+      else if (keyword == VX) atom->v[i][0] = dvalue;
+      else if (keyword == VY) atom->v[i][1] = dvalue;
+      else if (keyword == VZ) atom->v[i][2] = dvalue;
+      else if (keyword == CHARGE) atom->q[i] = dvalue;
+
+      else if (keyword == DIPOLE) {
+	if (atom->dipole[atom->type[i]] > 0.0) {
+	  double **mu = atom->mu;
+	  mu[i][0] = xvalue;
+	  mu[i][1] = yvalue;
+	  mu[i][2] = zvalue;
+	  double lensq = 
+	    mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2];
+	  double scale = atom->dipole[atom->type[i]]/sqrt(lensq);
+	  mu[i][0] *= scale;
+	  mu[i][1] *= scale;
+	  mu[i][2] *= scale;
+	}
 
-  int count = 0;
+      } else if (keyword == QUAT) {
+	// need to set orientation correctly and normalize quat
+	double **quat = atom->quat;
+	quat[i][0] = xvalue;
+	quat[i][1] = yvalue;
+	quat[i][2] = zvalue;
+      }
+      count++;
+    }
+}
 
-  // for style ATOM, atom must be in group
+/* ----------------------------------------------------------------------
+   set an owned atom property randomly
+   set seed based on atom tag
+   makes atom's result independent of what proc owns it
+------------------------------------------------------------------------- */
 
-  if (style == ATOM) {
-    int ivalue = atoi(arg[2]);
-    if (ivalue < 1 || ivalue > atom->ntypes)
-      error->all("Invalid type in set command");
-    for (int i = 0; i < nlocal; i++)
-      if (mask[i] & groupbit) {
-	atom->type[i] = ivalue;
-	count++;
+void Set::setrandom(int keyword)
+{
+  int i,j;
+
+  if (keyword == DIPOLE_RANDOM) atom->check_dipole();
+
+  selection(atom->nlocal);
+  RanPark *random = new RanPark(lmp,1);
+  double **x = atom->x;
+  int seed = ivalue;
+
+  // set fraction of atom types to newtype
+
+  if (keyword == TYPE_FRACTION) {
+    int nlocal = atom->nlocal;
+
+    for (i = 0; i < nlocal; i++)
+      if (select[i]) {
+	random->reset(seed,x[i]);
+	if (random->uniform() > fraction) continue;
+	atom->type[i] = newtype;
+        count++;
+      }
+
+  // set dipole moments to random orientations
+  // dipole length is determined by dipole type array
+
+  } else if (keyword == DIPOLE) {
+    int *type = atom->type;
+    double *dipole = atom->dipole;
+    double **mu = atom->mu;
+    int nlocal = atom->nlocal;
+
+    double msq,scale;
+    for (i = 0; i < nlocal; i++)
+      if (select[i]) {
+	if (dipole[type[i]] > 0.0) {
+	  random->reset(seed,x[i]);
+	  mu[i][0] = random->uniform() - 0.5;
+	  mu[i][1] = random->uniform() - 0.5;
+	  mu[i][2] = random->uniform() - 0.5;
+	  msq = mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2];
+	  scale = dipole[type[i]]/sqrt(msq);
+	  mu[i][0] *= scale;
+	  mu[i][1] *= scale;
+	  mu[i][2] *= scale;
+	  count++;
+	}
+      }
+
+  // set quaternions to random orientations
+
+  } else if (keyword == QUAT) {
+    double **quat = atom->quat;
+    int nlocal = atom->nlocal;
+
+    double s,t1,t2,theta1,theta2;
+    double PI = 4.0*atan(1.0);
+
+    for (i = 0; i < nlocal; i++)
+      if (select[i]) {
+	random->reset(seed,x[i]);
+	s = random->uniform();
+	t1 = sqrt(1.0-s);
+	t2 = sqrt(s);
+	theta1 = 2.0*PI*random->uniform();
+	theta2 = 2.0*PI*random->uniform();
+	quat[i][0] = cos(theta2)*t2;
+	quat[i][1] = sin(theta1)*t1;
+	quat[i][2] = cos(theta1)*t1;
+	quat[i][3] = sin(theta2)*t2;
+        count++;
       }
   }
 
-  // for style BOND, each of 2 atoms must be in group
+  delete random;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void Set::topology(int keyword)
+{
+  int m,atom1,atom2,atom3,atom4;
+
+  // border swap to acquire ghost atom info
+  // enforce PBC before in case atoms are outside box
+  // init entire system since comm->exchange is done
+  // comm::init needs neighbor::init needs pair::init needs kspace::init, etc
+  
+  if (comm->me == 0 && screen) fprintf(screen,"  system init for set ...\n");
+  lmp->init();
+
+  if (domain->triclinic) domain->x2lamda(atom->nlocal);
+  domain->pbc();
+  domain->reset_box();
+  comm->setup();
+  comm->exchange();
+  comm->borders();
+  if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
+
+  // select both owned and ghost atoms
 
-  if (style == BOND) {
-    int ivalue = atoi(arg[2]);
-    if (ivalue < 1 || ivalue > atom->nbondtypes)
-      error->all("Invalid type in set command");
+  selection(atom->nlocal + atom->nghost);
+
+  // for BOND, each of 2 atoms must be in group
+
+  if (keyword == BOND) {
+    int nlocal = atom->nlocal;
     for (int i = 0; i < nlocal; i++)
       for (m = 0; m < atom->num_bond[i]; m++) {
 	atom1 = atom->map(atom->bond_atom[i][m]);
 	if (atom1 == -1) error->one("Bond atom missing in set command");
-	if (mask[i] & groupbit && mask[atom1] & groupbit) {
+	if (select[i] && select[atom1]) {
 	  atom->bond_type[i][m] = ivalue;
 	  count++;
 	}
       }
   }
 
-  // for style ANGLE, each of 3 atoms must be in group
+  // for ANGLE, each of 3 atoms must be in group
 
-  if (style == ANGLE) {
-    int ivalue = atoi(arg[2]);
-    if (ivalue < 1 || ivalue > atom->nangletypes)
-      error->all("Invalid type in set command");
+  if (keyword == ANGLE) {
+    int nlocal = atom->nlocal;
     for (int i = 0; i < nlocal; i++)
       for (m = 0; m < atom->num_angle[i]; m++) {
 	atom1 = atom->map(atom->angle_atom1[i][m]);
@@ -165,20 +451,17 @@ void Set::command(int narg, char **arg)
 	atom3 = atom->map(atom->angle_atom3[i][m]);
 	if (atom1 == -1 || atom2 == -1 || atom3 == -1)
 	  error->one("Angle atom missing in set command");
-	if (mask[atom1] & groupbit && mask[atom2] & groupbit &&
-	    mask[atom3] & groupbit) {
+	if (select[atom1] && select[atom2] && select[atom3]) {
 	  atom->angle_type[i][m] = ivalue;
 	  count++;
 	}
       }
   }
 
-  // for style DIHEDRAL, each of 4 atoms must be in group
+  // for DIHEDRAL, each of 4 atoms must be in group
 
-  if (style == DIHEDRAL) {
-    int ivalue = atoi(arg[2]);
-    if (ivalue < 1 || ivalue > atom->ndihedraltypes)
-      error->all("Invalid type in set command");
+  if (keyword == DIHEDRAL) {
+    int nlocal = atom->nlocal;
     for (int i = 0; i < nlocal; i++)
       for (m = 0; m < atom->num_dihedral[i]; m++) {
 	atom1 = atom->map(atom->dihedral_atom1[i][m]);
@@ -187,20 +470,17 @@ void Set::command(int narg, char **arg)
 	atom4 = atom->map(atom->dihedral_atom4[i][m]);
 	if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1)
 	  error->one("Dihedral atom missing in set command");
-	if (mask[atom1] & groupbit && mask[atom2] & groupbit &&
-	    mask[atom3] & groupbit && mask[atom4] & groupbit) {
+	if (select[atom1] && select[atom2] && select[atom3] && select[atom4]) {
 	  atom->dihedral_type[i][m] = ivalue;
 	  count++;
 	}
       }
   }
 
-  // for style IMPROPER, each of 4 atoms must be in group
+  // for IMPROPER, each of 4 atoms must be in group
 
-  if (style == IMPROPER) {
-    int ivalue = atoi(arg[2]);
-    if (ivalue < 1 || ivalue > atom->nimpropertypes)
-      error->all("Invalid type in set command");
+  if (keyword == IMPROPER) {
+    int nlocal = atom->nlocal;
     for (int i = 0; i < nlocal; i++)
       for (m = 0; m < atom->num_improper[i]; m++) {
 	atom1 = atom->map(atom->improper_atom1[i][m]);
@@ -209,84 +489,10 @@ void Set::command(int narg, char **arg)
 	atom4 = atom->map(atom->improper_atom4[i][m]);
 	if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1)
 	  error->one("Improper atom missing in set command");
-	if (mask[atom1] & groupbit && mask[atom2] & groupbit &&
-	    mask[atom3] & groupbit && mask[atom4] & groupbit) {
+	if (select[atom1] && select[atom2] && select[atom3] && select[atom4]) {
 	  atom->improper_type[i][m] = ivalue;
 	  count++;
 	}
       }
   }
-
-  // for style CHARGE, set charge of all atoms in group
-
-  if (style == CHARGE) {
-    double value = atof(arg[2]);
-    double *q = atom->q;
-    for (int i = 0; i < nlocal; i++)
-      if (mask[i] & groupbit) {
-	q[i] = value;
-	count++;
-      }
-  }
-
-  // for style DIPOLE, create unique random number stream for each proc
-  // set dipole moment of each atom in group to random orientation
-  // dipole length is determined by dipole type array
-
-  if (style == DIPOLE) {
-    int ivalue = atoi(arg[2]);
-    if (ivalue <= 0) error->all("Invalid random number seed in set command");
-    double msq,scale;
-    RanPark *random = new RanPark(lmp,ivalue + comm->me);
-    for (int i = 0; i < WARMUP; i++) random->uniform();
-    int *type = atom->type;
-    double *dipole = atom->dipole;
-    double **mu = atom->mu;
-    for (int i = 0; i < nlocal; i++)
-      if (mask[i] & groupbit) {
-	mu[i][0] = random->uniform() - 0.5;
-	mu[i][1] = random->uniform() - 0.5;
-	mu[i][2] = random->uniform() - 0.5;
-	msq = mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2];
-	scale = dipole[type[i]]/sqrt(msq);
-	mu[i][0] *= scale;
-	mu[i][1] *= scale;
-	mu[i][2] *= scale;
-	count++;
-      }
-    delete random;
-  }
-
-  // for style ONEATOM, set attribute of single atom ID
-
-  if (style == ONEATOM) {
-    int *tag = atom->tag;
-    for (int i = 0; i < nlocal; i++)
-      if (atomid == tag[i]) {
-	if (strcmp(arg[1],"type") == 0) {
-	  atom->type[i] = atoi(arg[2]);
-	  if (atom->type[i] < 1 || atom->type[i] > atom->ntypes)
-	    error->one("Invalid type in set command");
-	} else if (strcmp(arg[1],"mol") == 0) atom->molecule[i] = atoi(arg[2]);
-	else if (strcmp(arg[1],"x") == 0) atom->x[i][0] = atof(arg[2]);
-	else if (strcmp(arg[1],"y") == 0) atom->x[i][1] = atof(arg[2]);
-	else if (strcmp(arg[1],"z") == 0) atom->x[i][2] = atof(arg[2]);
-	else if (strcmp(arg[1],"vx") == 0) atom->v[i][0] = atof(arg[2]);
-	else if (strcmp(arg[1],"vy") == 0) atom->v[i][1] = atof(arg[2]);
-	else if (strcmp(arg[1],"vz") == 0) atom->v[i][2] = atof(arg[2]);
-	else if (strcmp(arg[1],"q") == 0) atom->q[i] = atof(arg[2]);
-	else error->one("Illegal set command");
-	count++;
-      }
-  }
-
-  // statistics
-
-  int allcount;
-  MPI_Allreduce(&count,&allcount,1,MPI_INT,MPI_SUM,world);
-  
-  if (comm->me == 0) {
-    if (screen) fprintf(screen,"  %d settings made\n",allcount);
-    if (logfile) fprintf(logfile,"  %d settings made\n",allcount);
-  }
 }
diff --git a/src/set.h b/src/set.h
index 055bda48403fc208ed78de6ab76685077f4eefa0..f5327b117f28befeb84df57d078489e2d9316fe7 100644
--- a/src/set.h
+++ b/src/set.h
@@ -22,6 +22,17 @@ class Set : protected Pointers {
  public:
   Set(class LAMMPS *);
   void command(int, char **);
+
+ private:
+  char *id;
+  int *select;
+  int style,ivalue,newtype,count;
+  double dvalue,xvalue,yvalue,zvalue,fraction;
+
+  void selection(int);
+  void set(int);
+  void setrandom(int);
+  void topology(int);
 };
 
 }
diff --git a/src/special.cpp b/src/special.cpp
index c5212594c268b36c10d85dd3c737ad2860ddfae3..96dc1d5302b86de9ff9399c4aeb9df60f17be4f2 100644
--- a/src/special.cpp
+++ b/src/special.cpp
@@ -636,7 +636,7 @@ void Special::combine()
 
   atom->special = 
     memory->create_2d_int_array(atom->nmax,atom->maxspecial,"atom:special");
-  atom->avec->reset_ptrs();
+  atom->avec->reset_special();
   int **special = atom->special;
 
   // ----------------------------------------------------
diff --git a/src/style.h b/src/style.h
index 2302a116d86dcd0ce08e115e519799cd21ac2869..da988dd2bb10f84c3d0af184783941988e0f16b7 100644
--- a/src/style.h
+++ b/src/style.h
@@ -82,6 +82,7 @@ CommandStyle(write_restart,WriteRestart)
 #include "compute_rotate_gran.h"
 #include "compute_stress_atom.h"
 #include "compute_temp.h"
+#include "compute_temp_deform.h"
 #include "compute_temp_partial.h"
 #include "compute_temp_ramp.h"
 #include "compute_temp_region.h"
@@ -100,6 +101,7 @@ ComputeStyle(rotate/dipole,ComputeRotateDipole)
 ComputeStyle(rotate/gran,ComputeRotateGran)
 ComputeStyle(stress/atom,ComputeStressAtom)
 ComputeStyle(temp,ComputeTemp)
+ComputeStyle(temp/deform,ComputeTempDeform)
 ComputeStyle(temp/partial,ComputeTempPartial)
 ComputeStyle(temp/ramp,ComputeTempRamp)
 ComputeStyle(temp/region,ComputeTempRegion)
@@ -134,6 +136,7 @@ DumpStyle(xyz,DumpXYZ)
 #include "fix_ave_time.h"
 #include "fix_com.h"
 #include "fix_drag.h"
+#include "fix_deform.h"
 #include "fix_deposit.h"
 #include "fix_efield.h"
 #include "fix_enforce2d.h"
@@ -166,9 +169,7 @@ DumpStyle(xyz,DumpXYZ)
 #include "fix_spring_self.h"
 #include "fix_temp_rescale.h"
 #include "fix_tmd.h"
-#include "fix_uniaxial.h"
 #include "fix_viscous.h"
-#include "fix_volume_rescale.h"
 #include "fix_wall_lj126.h"
 #include "fix_wall_lj93.h"
 #include "fix_wall_reflect.h"
@@ -182,6 +183,7 @@ FixStyle(ave/spatial,FixAveSpatial)
 FixStyle(ave/time,FixAveTime)
 FixStyle(com,FixCOM)
 FixStyle(drag,FixDrag)
+FixStyle(deform,FixDeform)
 FixStyle(deposit,FixDeposit)
 FixStyle(efield,FixEfield)
 FixStyle(enforce2d,FixEnforce2D)
@@ -214,9 +216,7 @@ FixStyle(spring/rg,FixSpringRG)
 FixStyle(spring/self,FixSpringSelf)
 FixStyle(temp/rescale,FixTempRescale)
 FixStyle(tmd,FixTMD)
-FixStyle(uniaxial,FixUniaxial)
 FixStyle(viscous,FixViscous)
-FixStyle(volume/rescale,FixVolRescale)
 FixStyle(wall/lj126,FixWallLJ126)
 FixStyle(wall/lj93,FixWallLJ93)
 FixStyle(wall/reflect,FixWallReflect)
@@ -307,8 +307,10 @@ RegionStyle(union,RegUnion)
 
 // style files for optional packages
 
-//#include "style_asphere.h"
+#include "style_asphere.h"
 #include "style_class2.h"
+#include "style_colloid.h"
+#include "style_dipole.h"
 #include "style_dpd.h"
 #include "style_granular.h"
 #include "style_kspace.h"
diff --git a/src/style_manybody.h b/src/style_manybody.h
index 449895a530bda93bceec6121c7916241778dad46..c564993e3e15f702de884738ddd93a4edb2350ac 100644
--- a/src/style_manybody.h
+++ b/src/style_manybody.h
@@ -12,6 +12,7 @@
 ------------------------------------------------------------------------- */
 
 #ifdef PairInclude
+#include "pair_airebo.h"
 #include "pair_eam.h"
 #include "pair_eam_alloy.h"
 #include "pair_eam_fs.h"
@@ -20,6 +21,7 @@
 #endif
 
 #ifdef PairClass
+PairStyle(airebo,PairAIREBO)
 PairStyle(eam,PairEAM)
 PairStyle(eam/alloy,PairEAMAlloy)
 PairStyle(eam/fs,PairEAMFS)
diff --git a/src/thermo.cpp b/src/thermo.cpp
index af53a25ffaa35c38d9f038f36b11746344fe6533..ffc5fc4ad710df22c8ac78bb66040de5efedf849 100644
--- a/src/thermo.cpp
+++ b/src/thermo.cpp
@@ -110,7 +110,7 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
 
   } else error->all("Illegal thermo style command");
 
-  // ptrs, flags, IDs for compute objects thermo may create
+  // ptrs, flags, IDs for compute objects thermo may use or create
 
   temperature = NULL;
   pressure = NULL;
@@ -118,10 +118,10 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
   rotate_gran = NULL;
 
   index_temp = index_press = index_drot = index_grot = -1;
-  internal_temp = internal_press = internal_drot = internal_grot = 0;
+  internal_drot = internal_grot = 0;
 
   id_temp = "thermo_temp";
-  id_press = "thermo_press";
+  id_press = "thermo_pressure";
   id_drot = "thermo_rotate_dipole";
   id_grot = "thermo_rotate_gran";
 
@@ -134,15 +134,8 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
   parse_fields(line);
 
   // create the requested compute styles
+  // temperature and pressure always exist b/c Output class created them
 
-  if (index_temp >= 0) {
-    create_compute(id_temp,"temp",NULL);
-    internal_temp = 1;
-  }
-  if (index_press >= 0) {
-    create_compute(id_press,"pressure",id_temp);
-    internal_press = 1;
-  }
   if (index_drot >= 0) {
     create_compute(id_drot,"rotate/dipole",NULL);
     internal_drot = 1;
@@ -181,10 +174,6 @@ Thermo::~Thermo()
 
   // delete Compute classes if thermo created them
 
-  if (index_temp >= 0 && internal_temp)
-    modify->delete_compute(id_compute[index_temp]);
-  if (index_press >= 0 && internal_press)
-    modify->delete_compute(id_compute[index_press]);
   if (index_drot >= 0 && internal_drot)
     modify->delete_compute(id_compute[index_drot]);
   if (index_grot >= 0 && internal_grot)
@@ -255,7 +244,7 @@ void Thermo::init()
   int icompute;
   for (i = 0; i < ncompute; i++) {
     icompute = modify->find_compute(id_compute[i]);
-    if (icompute < 0) error->all("Could not find thermo custom compute ID");
+    if (icompute < 0) error->all("Could not find thermo compute ID");
     computes[i] = modify->compute[icompute];
   }
 
@@ -264,7 +253,7 @@ void Thermo::init()
   int ifix;
   for (i = 0; i < nfix; i++) {
     ifix = modify->find_fix(id_fix[i]);
-    if (ifix < 0) error->all("Could not find thermo custom fix ID");
+    if (ifix < 0) error->all("Could not find thermo fix ID");
     fixes[i] = modify->fix[ifix];
   }
 
@@ -395,10 +384,6 @@ void Thermo::modify_params(int narg, char **arg)
     if (strcmp(arg[iarg],"temp") == 0) {
       if (iarg+2 > narg) error->all("Illegal thermo_modify command");
       if (index_temp < 0) error->all("Thermo style does not use temp");
-      if (internal_temp) {
-	modify->delete_compute(id_compute[index_temp]);
-	internal_temp = 0;
-      }
       delete [] id_compute[index_temp];
       int n = strlen(arg[iarg+1]) + 1;
       id_compute[index_temp] = new char[n];
@@ -413,26 +398,23 @@ void Thermo::modify_params(int narg, char **arg)
       if (temperature->igroup != 0 && comm->me == 0)
 	error->warning("Temperature for thermo pressure is not for group all");
 
-      // if pressure being computed by thermo:
       // reset id_pre of pressure to new temp ID
+      // either pressure currently being used by thermo or "thermo_pressure"
 
       if (index_press >= 0) {
 	icompute = modify->find_compute(id_compute[index_press]);
 	if (icompute < 0) error->all("Press ID for thermo does not exist");
-	delete [] modify->compute[icompute]->id_pre;
-	modify->compute[icompute]->id_pre = new char[n];
-	strcpy(modify->compute[icompute]->id_pre,arg[iarg+1]);
-      }
+      } else icompute = modify->find_compute("thermo_pressure");
+
+      delete [] modify->compute[icompute]->id_pre;
+      modify->compute[icompute]->id_pre = new char[n];
+      strcpy(modify->compute[icompute]->id_pre,arg[iarg+1]);
 
       iarg += 2;
 
     } else if (strcmp(arg[iarg],"press") == 0) {
       if (iarg+2 > narg) error->all("Illegal thermo_modify command");
       if (index_press < 0) error->all("Thermo style does not use press");
-      if (internal_press) {
-	modify->delete_compute(id_compute[index_press]);
-	internal_press = 0;
-      }
       delete [] id_compute[index_press];
       int n = strlen(arg[iarg+1]) + 1;
       id_compute[index_press] = new char[n];
diff --git a/src/thermo.h b/src/thermo.h
index 241ab294caa04d175c0976efad8c745ca4e49fb8..3e330d39eeceabfa913bd07c3c16865ee9f7759d 100644
--- a/src/thermo.h
+++ b/src/thermo.h
@@ -72,7 +72,7 @@ class Thermo : protected Pointers {
                          // id = ID of Compute objects
                          // Compute * = ptrs to the Compute objects
   int index_temp,index_press,index_drot,index_grot;
-  int internal_temp,internal_press,internal_drot,internal_grot;
+  int internal_drot,internal_grot;
   char *id_temp,*id_press,*id_drot,*id_grot;
   class Compute *temperature,*pressure,*rotate_dipole,*rotate_gran;
 
@@ -88,7 +88,7 @@ class Thermo : protected Pointers {
   int nvariable;         // # of variables evaulated by thermo
   char **id_variable;    // list of variable names
 
-  int nwindow;            // time averaged values
+  int nwindow;           // time averaged values
   int npartial_t,ncurrent_t,npartial_p,ncurrent_p;
   int npartial_e,ncurrent_e,npartial_pe,ncurrent_pe;
   double tsum,psum,esum,pesum;
diff --git a/src/velocity.cpp b/src/velocity.cpp
index e2bf4b9b3a78745986a71a79e57631b3efa410f9..ab400ad78d8ae4f50f949a399ab97aad321fbe26 100644
--- a/src/velocity.cpp
+++ b/src/velocity.cpp
@@ -278,12 +278,22 @@ void Velocity::create(int narg, char **arg)
     }
 
   } else if (loop_flag == GEOM) {
-    random = new RanPark(lmp,seed);
+    random = new RanPark(lmp,1);
     double **x = atom->x;
     
     for (i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
-	triple(x[i],&vx,&vy,&vz,seed,random);
+	random->reset(seed,x[i]);
+	if (dist_flag == 0) {
+	  vx = random->uniform();
+	  vy = random->uniform();
+	  vz = random->uniform();
+	} else {
+	  vx = random->gaussian();
+	  vy = random->gaussian();
+	  vz = random->gaussian();
+	}
+
 	if (mass) factor = 1.0/sqrt(mass[type[i]]);
 	else factor = 1.0/sqrt(rmass[i]);
 	v[i][0] = vx * factor;
@@ -648,72 +658,3 @@ void Velocity::options(int narg, char **arg)
     } else error->all("Illegal velocity command");
   }
 }
-
-/* ---------------------------------------------------------------------- */
-
-#define IA1 1366
-#define IC1 150889
-#define IM1 714025
-#define IA2 8121
-#define IC2 28411
-#define IM2 134456
-#define IA3 7141
-#define IC3 54773
-#define IM3 259200
-
-void Velocity::triple(double *x, double *vx, double *vy, double *vz,
-		      int seed, RanPark *random)
-{
-  // for orthogonal box, lamda = fractional position in box
-  // for triclinic box, convert to lamda coords
-
-  double lamda[3];
-
-  if (domain->triclinic == 0) {
-    lamda[0] = (x[0] - domain->boxlo[0]) / domain->prd[0];
-    lamda[1] = (x[1] - domain->boxlo[1]) / domain->prd[1];
-    lamda[2] = (x[2] - domain->boxlo[2]) / domain->prd[2];
-  } else domain->x2lamda(x,lamda);
-
-  // seed 1,2,3 = combination of atom coord in each dim and user-input seed
-  // map geometric extent into range of each of 3 RNGs
-  // warm-up each RNG by calling it twice
-
-  int seed1,seed2,seed3;
-
-  seed1 = static_cast<int> (lamda[0] * IM1);
-  seed1 = (seed1+seed) % IM1;
-  seed1 = (seed1*IA1+IC1) % IM1;
-  seed1 = (seed1*IA1+IC1) % IM1;
-
-  seed2 = static_cast<int> (lamda[1] * IM2);
-  seed2 = (seed2+seed) % IM2;
-  seed2 = (seed2*IA2+IC2) % IM2;
-  seed2 = (seed2*IA2+IC2) % IM2;
-
-  seed3 = static_cast<int> (lamda[2] * IM3);
-  seed3 = (seed3+seed) % IM3;
-  seed3 = (seed3*IA3+IC3) % IM3;
-  seed3 = (seed3*IA3+IC3) % IM3;
-
-  // fraction = 0-1 with giving each dim an equal weighting
-  // use fraction to reset Park/Miller RNG seed
-
-  double fraction = 1.0*seed1/(3*IM1) + 1.0*seed2/(3*IM2) + 1.0*seed3/(3*IM3);
-  random->reset(fraction);
-
-  // use RNG to set velocities after warming up twice
-
-  random->uniform();
-  random->uniform();
-
-  if (dist_flag == 0) {
-    *vx = random->uniform();
-    *vy = random->uniform();
-    *vz = random->uniform();
-  } else {
-    *vx = random->gaussian();
-    *vy = random->gaussian();
-    *vz = random->gaussian();
-  }
-}
diff --git a/src/velocity.h b/src/velocity.h
index bc11f863c21a289c8ff64cf6aa6bb5315077a447..01661fdff9d90608e5778b5030a953fbf9e50c90 100644
--- a/src/velocity.h
+++ b/src/velocity.h
@@ -41,8 +41,6 @@ class Velocity : protected Pointers {
   void zero_rotation();
 
   void options(int, char **);
-  void triple(double *, double *, double *, double *,
-	      int, class RanPark *);
 };
 
 }
diff --git a/src/write_restart.cpp b/src/write_restart.cpp
index d31ce8d085489da53e8165b4f88a893ed43ba141..1d76cbd379bd79c2afddae1025aa90d1f571a039 100644
--- a/src/write_restart.cpp
+++ b/src/write_restart.cpp
@@ -36,7 +36,24 @@
 
 using namespace LAMMPS_NS;
 
-enum{IGNORE,WARN,ERROR};     // same as thermo.cpp
+// same as write_restart.cpp
+
+enum{VERSION,UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2,
+       NEWTON_PAIR,NEWTON_BOND,XPERIODIC,YPERIODIC,ZPERIODIC,
+       BOUNDARY_00,BOUNDARY_01,BOUNDARY_10,BOUNDARY_11,BOUNDARY_20,BOUNDARY_21,
+       ATOM_STYLE,NATOMS,NTYPES,
+       NBONDS,NBONDTYPES,BOND_PER_ATOM,
+       NANGLES,NANGLETYPES,ANGLE_PER_ATOM,
+       NDIHEDRALS,NDIHEDRALTYPES,DIHEDRAL_PER_ATOM,
+       NIMPROPERS,NIMPROPERTYPES,IMPROPER_PER_ATOM,
+       BOXLO_0,BOXHI_0,BOXLO_1,BOXHI_1,BOXLO_2,BOXHI_2,
+       SPECIAL_LJ_1,SPECIAL_LJ_2,SPECIAL_LJ_3,
+       SPECIAL_COUL_1,SPECIAL_COUL_2,SPECIAL_COUL_3,
+       XY,XZ,YZ};
+enum{MASS,SHAPE,DIPOLE};
+enum{PAIR,BOND,ANGLE,DIHEDRAL,IMPROPER};
+
+enum{IGNORE,WARN,ERROR};                    // same as thermo.cpp
 
 /* ---------------------------------------------------------------------- */
 
@@ -129,13 +146,13 @@ void WriteRestart::write(char *file)
     if (multiproc) delete [] hfile;
   }
 
-  // write header, groups, ntype-length arrays, force field, fix info
+  // proc 0 writes header, groups, ntype-length arrays, force field
+  // all procs write fix info
 
   if (me == 0) {
     header();
     group->write_restart(fp);
-    if (atom->mass) mass();
-    if (atom->dipole) dipole();
+    type_arrays();
     force_fields();
   }
 
@@ -219,31 +236,31 @@ void WriteRestart::write(char *file)
 
 void WriteRestart::header()
 {
-  write_char(0,universe->version);
-  write_char(1,update->unit_style);
-  write_int(2,update->ntimestep);
-  write_int(3,force->dimension);
-  write_int(4,nprocs);
-  write_int(5,comm->procgrid[0]);
-  write_int(6,comm->procgrid[1]);
-  write_int(7,comm->procgrid[2]);
-  write_int(8,force->newton_pair);
-  write_int(9,force->newton_bond);
-  write_int(10,domain->xperiodic);
-  write_int(11,domain->yperiodic);
-  write_int(12,domain->zperiodic);
-  write_int(13,domain->boundary[0][0]);
-  write_int(14,domain->boundary[0][1]);
-  write_int(15,domain->boundary[1][0]);
-  write_int(16,domain->boundary[1][1]);
-  write_int(17,domain->boundary[2][0]);
-  write_int(18,domain->boundary[2][1]);
+  write_char(VERSION,universe->version);
+  write_char(UNITS,update->unit_style);
+  write_int(NTIMESTEP,update->ntimestep);
+  write_int(DIMENSION,force->dimension);
+  write_int(NPROCS,nprocs);
+  write_int(PROCGRID_0,comm->procgrid[0]);
+  write_int(PROCGRID_1,comm->procgrid[1]);
+  write_int(PROCGRID_2,comm->procgrid[2]);
+  write_int(NEWTON_PAIR,force->newton_pair);
+  write_int(NEWTON_BOND,force->newton_bond);
+  write_int(XPERIODIC,domain->xperiodic);
+  write_int(YPERIODIC,domain->yperiodic);
+  write_int(ZPERIODIC,domain->zperiodic);
+  write_int(BOUNDARY_00,domain->boundary[0][0]);
+  write_int(BOUNDARY_01,domain->boundary[0][1]);
+  write_int(BOUNDARY_10,domain->boundary[1][0]);
+  write_int(BOUNDARY_11,domain->boundary[1][1]);
+  write_int(BOUNDARY_20,domain->boundary[2][0]);
+  write_int(BOUNDARY_21,domain->boundary[2][1]);
 
   // atom_style must be written before atom class values
   // so read_restart can create class before reading class values
   // if style = hybrid, also write sub-class styles
 
-  write_char(19,atom->atom_style);
+  write_char(ATOM_STYLE,atom->atom_style);
 
   if (strcmp(atom->atom_style,"hybrid") == 0) {
     AtomVecHybrid *avec_hybrid = (AtomVecHybrid *) atom->avec;
@@ -257,39 +274,39 @@ void WriteRestart::header()
     }
   }
 
-  write_double(20,natoms);
-  write_int(21,atom->ntypes);
-  write_int(22,atom->nbonds);
-  write_int(23,atom->nbondtypes);
-  write_int(24,atom->bond_per_atom);
-  write_int(25,atom->nangles);
-  write_int(26,atom->nangletypes);
-  write_int(27,atom->angle_per_atom);
-  write_int(28,atom->ndihedrals);
-  write_int(29,atom->ndihedraltypes);
-  write_int(30,atom->dihedral_per_atom);
-  write_int(31,atom->nimpropers);
-  write_int(32,atom->nimpropertypes);
-  write_int(33,atom->improper_per_atom);
-
-  write_double(34,domain->boxlo[0]);
-  write_double(35,domain->boxhi[0]);
-  write_double(36,domain->boxlo[1]);
-  write_double(37,domain->boxhi[1]);
-  write_double(38,domain->boxlo[2]);
-  write_double(39,domain->boxhi[2]);
-
-  write_double(40,force->special_lj[1]);
-  write_double(41,force->special_lj[2]);
-  write_double(42,force->special_lj[3]);
-  write_double(43,force->special_coul[1]);
-  write_double(44,force->special_coul[2]);
-  write_double(45,force->special_coul[3]);
+  write_double(NATOMS,natoms);
+  write_int(NTYPES,atom->ntypes);
+  write_int(NBONDS,atom->nbonds);
+  write_int(NBONDTYPES,atom->nbondtypes);
+  write_int(BOND_PER_ATOM,atom->bond_per_atom);
+  write_int(NANGLES,atom->nangles);
+  write_int(NANGLETYPES,atom->nangletypes);
+  write_int(ANGLE_PER_ATOM,atom->angle_per_atom);
+  write_int(NDIHEDRALS,atom->ndihedrals);
+  write_int(NDIHEDRALTYPES,atom->ndihedraltypes);
+  write_int(DIHEDRAL_PER_ATOM,atom->dihedral_per_atom);
+  write_int(NIMPROPERS,atom->nimpropers);
+  write_int(NIMPROPERTYPES,atom->nimpropertypes);
+  write_int(IMPROPER_PER_ATOM,atom->improper_per_atom);
+
+  write_double(BOXLO_0,domain->boxlo[0]);
+  write_double(BOXHI_0,domain->boxhi[0]);
+  write_double(BOXLO_1,domain->boxlo[1]);
+  write_double(BOXHI_1,domain->boxhi[1]);
+  write_double(BOXLO_2,domain->boxlo[2]);
+  write_double(BOXHI_2,domain->boxhi[2]);
+
+  write_double(SPECIAL_LJ_1,force->special_lj[1]);
+  write_double(SPECIAL_LJ_2,force->special_lj[2]);
+  write_double(SPECIAL_LJ_3,force->special_lj[3]);
+  write_double(SPECIAL_COUL_1,force->special_coul[1]);
+  write_double(SPECIAL_COUL_2,force->special_coul[2]);
+  write_double(SPECIAL_COUL_3,force->special_coul[3]);
 
   if (domain->triclinic) {
-    write_double(46,domain->xy);
-    write_double(47,domain->xz);
-    write_double(48,domain->yz);
+    write_double(XY,domain->xy);
+    write_double(XZ,domain->xz);
+    write_double(YZ,domain->yz);
   }
 
   // -1 flag signals end of header
@@ -299,78 +316,84 @@ void WriteRestart::header()
 }
 
 /* ----------------------------------------------------------------------
-   proc 0 writes out atom masses 
+   proc 0 writes out any type-based arrays that are defined
 ------------------------------------------------------------------------- */
 
-void WriteRestart::mass()
+void WriteRestart::type_arrays()
 {
-  fwrite(&atom->mass[1],sizeof(double),atom->ntypes,fp);
-}
+  if (atom->mass) {
+    int flag = MASS;
+    fwrite(&flag,sizeof(int),1,fp);
+    fwrite(&atom->mass[1],sizeof(double),atom->ntypes,fp);
+  }
+  if (atom->shape) {
+    int flag = SHAPE;
+    fwrite(&flag,sizeof(int),1,fp);
+    fwrite(&atom->shape[1][0],sizeof(double),atom->ntypes*3,fp);
+  }
+  if (atom->dipole) {
+    int flag = DIPOLE;
+    fwrite(&flag,sizeof(int),1,fp);
+    fwrite(&atom->dipole[1],sizeof(double),atom->ntypes,fp);
+  }
 
-/* ----------------------------------------------------------------------
-   proc 0 writes out dipole moments 
-------------------------------------------------------------------------- */
+  // -1 flag signals end of type arrays
 
-void WriteRestart::dipole()
-{
-  fwrite(&atom->dipole[1],sizeof(double),atom->ntypes,fp);
+  int flag = -1;
+  fwrite(&flag,sizeof(int),1,fp);
 }
 
 /* ----------------------------------------------------------------------
-   proc 0 writes out force field styles and data 
+   proc 0 writes out and force field styles and data that are defined
 ------------------------------------------------------------------------- */
 
 void WriteRestart::force_fields()
 {
-  int n;
-
-  if (force->pair) n = strlen(force->pair_style) + 1;
-  else n = 0;
-  fwrite(&n,sizeof(int),1,fp);
-  if (n) {
+  if (force->pair) {
+    int flag = PAIR;
+    fwrite(&flag,sizeof(int),1,fp);
+    int n = strlen(force->pair_style) + 1;
+    fwrite(&n,sizeof(int),1,fp);
     fwrite(force->pair_style,sizeof(char),n,fp);
     force->pair->write_restart(fp);
   }
-
-  if (atom->avec->bonds_allow) {
-    if (force->bond) n = strlen(force->bond_style) + 1;
-    else n = 0;
+  if (atom->avec->bonds_allow && force->bond) {
+    int flag = BOND;
+    fwrite(&flag,sizeof(int),1,fp);
+    int n = strlen(force->bond_style) + 1;
     fwrite(&n,sizeof(int),1,fp);
-    if (n) {
-      fwrite(force->bond_style,sizeof(char),n,fp);
-      force->bond->write_restart(fp);
-    }
+    fwrite(force->bond_style,sizeof(char),n,fp);
+    force->bond->write_restart(fp);
   }
-
-  if (atom->avec->angles_allow) {
-    if (force->angle) n = strlen(force->angle_style) + 1;
-    else n = 0;
+  if (atom->avec->angles_allow && force->angle) {
+    int flag = ANGLE;
+    fwrite(&flag,sizeof(int),1,fp);
+    int n = strlen(force->angle_style) + 1;
     fwrite(&n,sizeof(int),1,fp);
-    if (n) {
-      fwrite(force->angle_style,sizeof(char),n,fp);
-      force->angle->write_restart(fp);
-    }
+    fwrite(force->angle_style,sizeof(char),n,fp);
+    force->angle->write_restart(fp);
   }
-
-  if (atom->avec->dihedrals_allow) {
-    if (force->dihedral) n = strlen(force->dihedral_style) + 1;
-    else n = 0;
+  if (atom->avec->dihedrals_allow && force->dihedral) {
+    int flag = DIHEDRAL;
+    fwrite(&flag,sizeof(int),1,fp);
+    int n = strlen(force->dihedral_style) + 1;
     fwrite(&n,sizeof(int),1,fp);
-    if (n) {
-      fwrite(force->dihedral_style,sizeof(char),n,fp);
-      force->dihedral->write_restart(fp);
-    }
+    fwrite(force->dihedral_style,sizeof(char),n,fp);
+    force->dihedral->write_restart(fp);
   }
-
-  if (atom->avec->impropers_allow) {
-    if (force->improper) n = strlen(force->improper_style) + 1;
-    else n = 0;
+  if (atom->avec->impropers_allow && force->improper) {
+    int flag = IMPROPER;
+    fwrite(&flag,sizeof(int),1,fp);
+    int n = strlen(force->improper_style) + 1;
     fwrite(&n,sizeof(int),1,fp);
-    if (n) {
-      fwrite(force->improper_style,sizeof(char),n,fp);
-      force->improper->write_restart(fp);
-    }
+    fwrite(force->improper_style,sizeof(char),n,fp);
+    force->improper->write_restart(fp);
   }
+
+  // -1 flag signals end of force field info
+
+  int flag = -1;
+  fwrite(&flag,sizeof(int),1,fp);
 }
 
 /* ----------------------------------------------------------------------
diff --git a/src/write_restart.h b/src/write_restart.h
index 96c9f863a7d897d02b8a0bcfb1e679dcc5fcce69..b8929c168bd788c194484791cb138c4deffc70d1 100644
--- a/src/write_restart.h
+++ b/src/write_restart.h
@@ -32,8 +32,7 @@ class WriteRestart : protected Pointers {
   double natoms;         // natoms (sum of nlocal) to write into file
 
   void header();
-  void mass();
-  void dipole();
+  void type_arrays();
   void force_fields();
 
   void write_int(int, int);