--- /home/sjplimp/oldlammps/src/delete_atoms.cpp	2006-04-11 18:20:56.000000000 -0600
+++ /home/sjplimp/lammps/src/delete_atoms.cpp	2006-05-31 16:37:38.000000000 -0600
@@ -16,8 +16,12 @@
 #include "atom.h"
 #include "comm.h"
 #include "domain.h"
+#include "force.h"
 #include "group.h"
 #include "region.h"
+#include "neighbor.h"
+#include "comm.h"
+#include "force.h"
 #include "error.h"
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -31,7 +35,6 @@
 {
   if (domain->box_exist == 0) 
     error->all("Delete_atoms command before simulation box is defined");
-
   if (narg < 1) error->all("Illegal delete_atoms command");
 
   // store state before delete
@@ -42,79 +45,52 @@
   int natoms_previous = static_cast<int> (atom->natoms);
   int tag_lowest = natoms_previous + 1;
 
-  // delete group: delete all atoms in group, group still exists
-
-  if (strcmp(arg[0],"group") == 0) {
-
-    if (narg != 2) error->all("Illegal delete_atoms group command");
-
-    int igroup = group->find(arg[1]);
-    if (igroup == -1) error->all("Could not find delete_atoms group ID");
-
-    int *mask = atom->mask;
-    int *tag = atom->tag;
-    int nlocal = atom->nlocal;
-    int groupbit = group->bitmask[igroup];
-
-    int i = 0;
-    while (i < nlocal) {
-      if (mask[i] & groupbit) {
-	tag_lowest = MIN(tag_lowest,tag[i]);
-	atom->copy(nlocal-1,i);
-	nlocal--;
-      } else i++;
-    }
-    atom->nlocal = nlocal;
-
-    // delete region: delete an atom if it is in region
-
-  } else if (strcmp(arg[0],"region") == 0) {
-
-    if (narg != 2) error->all("Illegal delete_atoms region 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("Delete_atoms region ID does not exist");
-
-    double **x = atom->x;
-    int *tag = atom->tag;
-    int nlocal = atom->nlocal;
-
-    int i = 0;
-    while (i < nlocal) {
-      if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2])) {
-	tag_lowest = MIN(tag_lowest,tag[i]);
-	atom->copy(nlocal-1,i);
-	nlocal--;
-      } else i++;
-    }
-    atom->nlocal = nlocal;
-
-  // delete overlap: delete one of any 2 atoms within overlap
-
-  } else if (strcmp(arg[0],"overlap") == 0) {
-
-    error->all("Delete_atoms overlap not yet implemented");
+  // allocate and initialize deletion list
+  
+  int nlocal = atom->nlocal;
+  int *list = new int[nlocal];
+
+  for (int i = 0; i < nlocal; i++) list[i] = 0;
+
+  // delete the atoms
+  // return tag_lowest = min tag of each proc's deleted atoms
+
+  if (strcmp(arg[0],"group") == 0) delete_group(narg,arg,list);
+  else if (strcmp(arg[0],"region") == 0) delete_region(narg,arg,list);
+  else if (strcmp(arg[0],"overlap") == 0) delete_overlap(narg,arg,list);
+  else error->all("Illegal delete_atoms command");
+
+  // delete local atoms in list
+  // reset nlocal
+  // tag_lowest_all = smallest deleted atom tag on any proc
+
+  int *tag = atom->tag;
+
+  int i = 0;
+  while (i < nlocal) {
+    if (list[i]) {
+      tag_lowest = MIN(tag_lowest,tag[i]);
+      atom->copy(nlocal-1,i);
+      list[i] = list[nlocal-1];
+      nlocal--;
+    } else i++;
+  }
+  atom->nlocal = nlocal;
+  delete [] list;
 
-  } else error->all("Illegal delete_atoms command");
+  int tag_lowest_all;
+  MPI_Allreduce(&tag_lowest,&tag_lowest_all,1,MPI_INT,MPI_MIN,world);
 
   // if non-molecular system, reset atom tags to be contiguous
-  // tag_lowest_all = lowest atom ID of a deleted atom
   // set all atom IDs >= tag_lowest_all to 0
-  // tag_extend to reset tags for all those atoms
+  // tag_extend() will reset tags for those atoms
 
   if (atom->molecular == 0) {
-    int tag_lowest_all;
-    MPI_Allreduce(&tag_lowest,&tag_lowest_all,1,MPI_INT,MPI_MIN,world);
-
     int *tag = atom->tag;
     int nlocal = atom->nlocal;
  
-    for (int i = 0; i < nlocal; i++)
+    for (i = 0; i < nlocal; i++)
       if (tag[i] >= tag_lowest_all) tag[i] = 0;
-
     atom->tag_extend();
   }
 
@@ -130,7 +106,7 @@
     atom->map_set();
   }
 
-  // print atoms before and after
+  // print before and after atom count
 
   int ndelete = static_cast<int> (natoms_previous - atom->natoms);
 
@@ -141,3 +117,181 @@
 			 ndelete,atom->natoms);
   }
 }
+
+/* ----------------------------------------------------------------------
+   delete all atoms in group
+   group will still exist
+------------------------------------------------------------------------- */
+
+void DeleteAtoms::delete_group(int narg, char **arg, int *list)
+{
+  if (narg != 2) error->all("Illegal delete_atoms command");
+
+  int igroup = group->find(arg[1]);
+  if (igroup == -1) error->all("Could not find delete_atoms group ID");
+
+  int *mask = atom->mask;
+  int nlocal = atom->nlocal;
+  int groupbit = group->bitmask[igroup];
+
+  for (int i = 0; i < nlocal; i++)
+    if (mask[i] & groupbit) list[i] = 1;
+}
+
+/* ----------------------------------------------------------------------
+   delete all atoms in region
+------------------------------------------------------------------------- */
+
+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");
+
+  double **x = atom->x;
+  int nlocal = atom->nlocal;
+
+  for (int i = 0; i < nlocal; i++)
+    if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2])) list[i] = 1;
+}
+
+/* ----------------------------------------------------------------------
+   delete atoms so there are no pairs within cutoff
+   which atoms are deleted depends on ordering of atoms within proc
+   deletions can vary with processor count
+   no guarantee that minimium number of atoms will be deleted
+------------------------------------------------------------------------- */
+
+void DeleteAtoms::delete_overlap(int narg, char **arg, int *list)
+{
+  if (narg < 2) error->all("Illegal delete_atoms command");
+    
+  // read args including optional type info
+
+  double cut = atof(arg[1]);
+  double cutsq = cut*cut;
+
+  int typeflag,type1,type2;
+  if (narg == 2) typeflag = 0;
+  else if (narg == 3) {
+    typeflag = 1;
+    type1 = atoi(arg[2]);
+  } else if (narg == 4) {
+    typeflag = 2;
+    type1 = atoi(arg[2]);
+    type2 = atoi(arg[3]);
+  } else error->all("Illegal delete_atoms command");
+
+  // init entire system since comm->borders and neighbor->build is done
+  // comm::init needs neighbor::init needs pair::init needs kspace::init, etc
+
+  if (comm->me == 0 && screen)
+    fprintf(screen,"System init for delete_atoms ...\n");
+  System::init();
+
+  // setup domain, communication and neighboring
+  // acquire ghosts
+  // build neighbor lists
+    
+  domain->pbc();
+  domain->reset_box();
+  comm->setup();
+  if (neighbor->style) neighbor->setup_bins();
+  comm->exchange();
+  comm->borders();
+  neighbor->build();
+
+  // error check on cutoff
+
+  if (cut > neighbor->cutneigh) 
+    error->all("Delete_atoms cutoff > neighbor cutoff");
+
+  // create an atom map if one doesn't exist already
+
+  int mapflag = 0;
+  if (atom->map_style == 0) {
+    mapflag = 1;
+    atom->map_style = 1;
+    atom->map_init();
+    atom->map_set();
+  }
+
+  // double loop over owned atoms and their neighbors
+  // at end of loop, there are no more overlaps
+  // criteria for i,j to undergo a deletion event:
+  //   weighting factor != 0.0 for this pair
+  //     could be 0 and still be in neigh list for long-range Coulombics
+  //   local copy of j (map[tag[j]]) has not already been deleted
+  //   distance between i,j is less than cutoff
+  //   i,j are of valid types
+  // if all criteria met, delete i and skip to next i in outer loop
+  //   unless j is ghost and newton_pair off and tag[j] < tag[i]
+  //   then rely on other proc to delete
+
+  int *tag = atom->tag;
+  int *type = atom->type;
+  double **x = atom->x;
+  int nlocal = atom->nlocal;
+  int nall = atom->nlocal + atom->nghost;
+  double *special_coul = force->special_coul;
+  double *special_lj = force->special_lj;
+  int newton_pair = force->newton_pair;
+
+  int i,j,k,m,itype,jtype,numneigh;
+  double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
+  int *neighs;
+
+  for (i = 0; i < nlocal; i++) {
+    xtmp = x[i][0];
+    ytmp = x[i][1];
+    ztmp = x[i][2];
+    itype = type[i];
+    neighs = neighbor->firstneigh[i];
+    numneigh = neighbor->numneigh[i];
+    
+    for (k = 0; k < numneigh; k++) {
+      j = neighs[k];
+      list[i] = 1;
+      if (j >= nall) {
+	if (special_coul[j/nall] == 0.0 && special_lj[j/nall] == 0.0) continue;
+	j %= nall;
+      }
+
+      if (j < nlocal) {
+	if (list[j]) continue;
+      } else {
+	m = atom->map(tag[j]);
+	if (m < nlocal && list[m]) continue;
+      }
+
+      delx = xtmp - x[j][0];
+      dely = ytmp - x[j][1];
+      delz = ztmp - x[j][2];
+      rsq = delx*delx + dely*dely + delz*delz;
+      if (rsq >= cutsq) continue;
+
+      if (typeflag) {
+	jtype = type[j];
+	if (typeflag == 1 && itype != type1 && jtype != type1) continue;
+	if (typeflag == 2 && !(itype == type1 && jtype == type2) && 
+	    !(itype == type2 && jtype == type1)) continue;
+      }
+
+      if (j >= nlocal && newton_pair == 0 && tag[j] < tag[i]) continue;
+
+      list[i] = 1;
+      break;
+    }
+  }
+
+  // delete temporary atom map
+
+  if (mapflag) {
+    atom->map_delete();
+    atom->map_style = 0;
+  }
+}
--- /home/sjplimp/oldlammps/src/delete_atoms.h	2006-04-11 18:20:56.000000000 -0600
+++ /home/sjplimp/lammps/src/delete_atoms.h	2006-05-19 10:21:59.000000000 -0600
@@ -21,6 +21,11 @@
   DeleteAtoms() {}
   ~DeleteAtoms() {}
   void command(int, char **);
+
+ private:
+  void delete_group(int, char **, int *);
+  void delete_region(int, char **, int *);
+  void delete_overlap(int, char **, int *);
 };
 
 #endif
--- /home/sjplimp/oldlammps/src/thermo.cpp	2006-05-31 16:57:18.000000000 -0600
+++ /home/sjplimp/lammps/src/thermo.cpp	2006-05-31 16:54:58.000000000 -0600
@@ -218,12 +218,12 @@
   if ((tempflag || pressflag) && atom->check_style("granular"))
     error->all("Cannot use atom style granular with chosen thermo settings");
 
-  // set normflag to default value unless user has specified a setting
+  // set normvalue to default setting unless user has specified it
 
-  if (normuserflag) normflag = normuser;
-  else if (strcmp(style,"granular") == 0) normflag = 0;
-  else if (strcmp(update->unit_style,"lj") == 0) normflag = 1;
-  else normflag = 0;
+  if (normuserflag) normvalue = normuser;
+  else if (strcmp(style,"granular") == 0) normvalue = 0;
+  else if (strcmp(update->unit_style,"lj") == 0) normvalue = 1;
+  else normvalue = 0;
 
   // check for granular freeze Fix and set freeze_group_bit
 
@@ -340,9 +340,14 @@
 {
   firststep = flag;
 
-  // check for lost atoms and compute requested thermo quantities
+  // check for lost atoms
+  // turn off normflag if natoms = 0 to avoid divide by 0
+  // compute requested thermo quantities
 
   natoms = lost_check();
+  if (natoms == 0) normflag = 0;
+  else normflag = normvalue;
+
   if (tempflag) tempvalue = temperature->compute();
   if (pressflag) pressure->compute(temperature);
   if (nextra) {
--- /home/sjplimp/oldlammps/src/thermo.h	2006-05-31 16:57:18.000000000 -0600
+++ /home/sjplimp/lammps/src/thermo.h	2006-05-31 16:53:19.000000000 -0600
@@ -55,6 +55,7 @@
   char **format;
 
   int normflag;          // 0 if do not normalize by atoms, 1 if normalize
+  int normvalue;         // use this for normflag unless natoms = 0
   int normuserflag;      // 0 if user has not set, 1 if has
   int normuser;
 
--- /home/sjplimp/oldlammps/doc/delete_atoms.txt	2006-04-11 18:20:56.000000000 -0600
+++ /home/sjplimp/lammps/doc/delete_atoms.txt	2006-05-31 16:36:29.000000000 -0600
@@ -15,32 +15,61 @@
 style = {group} or {region} or {overlap} :ulb,l
   {group} args = group-ID
   {region} args = region-ID
-  {overlap} args = distance (distance units) :pre
+  {overlap} args = distance type1 type2
+    distance = delete atoms with neighbors within this cutoff (distance units)
+    type1 = type of first atom in pair (optional)
+    type2 = type of other atom in pair (optional)
+:pre
 :ule
 
 [Examples:]
 
 delete_atoms group edge
-delete_atoms region regsphere
-delete_atoms overlap 0.3 :pre
+delete_atoms region sphere
+delete_atoms overlap 0.3
+delete_atoms overlap 0.3 1 1 :pre
 
 [Description:]
 
-Delete the specfied atoms.  For style {group}, it is all atoms
-belonging to the group.  For style {region}, it is any atom that is in
-the region volume.  For style {overlap}, pairs of atoms within the
-specified distance are searched for, and one of the 2 atoms is
-deleted.  See the "units"_units.txt command for a discussion of
-distance units.
-
-This command can be used to carve out voids from a block of material.
+Delete the specfied atoms.  This command can be used to carve out
+voids from a block of material or to delete created atoms that are too
+close to each other (e.g. at a grain boundary).
+
+For style {group}, all atoms belonging to the group are deleted.
+
+For style {region}, all atoms in the region volume are deleted.
+
+For style {overlap}, pairs of atoms within the specified cutoff
+distance are searched for, and one of the 2 atoms is deleted.  If no
+atom types are specified, an atom will always be deleted if the cutoff
+criterion is met.  If a single atom type is specified, then one or
+both of the atoms in the pair must be of the specified type for a
+deletion to occur.  If two atom types are specified, the two atoms in
+the pair must be of the specified types for a deletion to occur.  For
+a given configuration of atoms, the only guarantee is that at the end
+of the deletion operation, enough deletions will have occurred that no
+atom pairs within the cutoff (and with the specified types) will
+remain.  There is no guarantee that the minimum number of atoms will
+be deleted, or that the same atoms will be deleted when running on
+different numbers of processors.
 
 After atoms are deleted, if the system is not molecular (no bonds),
 then atom IDs are re-assigned so that they run from 1 to the number of
 atoms in the system.  This is not done for molecular systems, since it
 would foul up the bond connectivity that has already been assigned.
 
-[Restrictions:] none
+[Restrictions:]
+
+The {overlap} style requires inter-processor communication to acquire
+ghost atoms and setup a neighbor list.  This means that your system
+must be ready to perform a simulation before using this command (force
+fields setup, atom masses set, etc).
+
+If the "special_bonds"_special_bonds.html command is used with a
+setting of 0, then a pair of bonded atoms (1-2, 1-3, or 1-4) will not
+appear in the neighbor list, and thus will not be considered for
+deltion by the {overlap} style.  You probably don't want to be
+deleting one atom in a bonded pair anyway.
 
 [Related commands:]
 
--- /home/sjplimp/oldlammps/doc/delete_atoms.html	2006-04-11 18:20:56.000000000 -0600
+++ /home/sjplimp/lammps/doc/delete_atoms.html	2006-05-31 16:09:48.000000000 -0600
@@ -19,26 +19,44 @@
 
 <PRE>  <I>group</I> args = group-ID
   <I>region</I> args = region-ID
-  <I>overlap</I> args = distance (distance units) 
+  <I>overlap</I> args = distance type1 type2
+    distance = no atom pair will remain within this cutoff (distance units)
+    type1 = type of first atom in pair (optional)
+    type2 = type of other atom in pair (optional)
+
 </PRE>
 
 </UL>
 <P><B>Examples:</B>
 </P>
 <PRE>delete_atoms group edge
-delete_atoms region regsphere
-delete_atoms overlap 0.3 
+delete_atoms region sphere
+delete_atoms overlap 0.3
+delete_atoms overlap 0.3 1 1 
 </PRE>
 <P><B>Description:</B>
 </P>
-<P>Delete the specfied atoms.  For style <I>group</I>, it is all atoms
-belonging to the group.  For style <I>region</I>, it is any atom that is in
-the region volume.  For style <I>overlap</I>, pairs of atoms within the
-specified distance are searched for, and one of the 2 atoms is
-deleted.  See the <A HREF = "units.txt">units</A> command for a discussion of
-distance units.
-</P>
-<P>This command can be used to carve out voids from a block of material.
+<P>Delete the specfied atoms.  This command can be used to carve out
+voids from a block of material or to delete atoms at a created grain
+boundary that are too close to each other.
+</P>
+<P>For style <I>group</I>, all atoms belonging to the group are deleted.
+</P>
+<P>For style <I>region</I>, all atoms in the region volume are deleted.
+</P>
+<P>For style <I>overlap</I>, pairs of atoms within the specified cutoff
+distance are searched for, and one of the 2 atoms is deleted.  If no
+atom types are specified, an atom will always be deleted if the cutoff
+criterion is met.  If a single atom type is specified, then one or
+both of the atoms in the pair must be of the specified type for a
+deletion to occur.  If two atom types are specified, the two atoms in
+the pair must be of the specified types for a deletion to occur.  For
+a given configuration of atoms, the only guarantee is that at the end
+of the deletion operation, enough deletions will have occurred that no
+atom pairs within the cutoff (and with the specified types) will
+remain.  There is no guarantee that the minimum number of atoms will
+be deleted, or that the same atoms will be deleted when running on
+different numbers of processors.
 </P>
 <P>After atoms are deleted, if the system is not molecular (no bonds),
 then atom IDs are re-assigned so that they run from 1 to the number of