diff --git a/src/CLASS2/dihedral_class2.cpp b/src/CLASS2/dihedral_class2.cpp
index aab7f3cd86ebed9c05622503eb73c3675bf0ebc8..e4f58e0560d8df4c9cdb16232c022bc23e234db7 100644
--- a/src/CLASS2/dihedral_class2.cpp
+++ b/src/CLASS2/dihedral_class2.cpp
@@ -205,7 +205,9 @@ void DihedralClass2::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/CLASS2/improper_class2.cpp b/src/CLASS2/improper_class2.cpp
index 628a1063008e297968afa31b97d66ab77ceac52d..b4ccd77e77c87d48636d0a440f222d0e2d888ce1 100644
--- a/src/CLASS2/improper_class2.cpp
+++ b/src/CLASS2/improper_class2.cpp
@@ -156,8 +156,9 @@ void ImproperClass2::compute(int eflag, int vflag)
         MPI_Comm_rank(world,&me);
         if (screen) {
           char str[128];
-          sprintf(str,
-                  "Improper problem: %d " BIGINT_FORMAT " %d %d %d %d",
+          sprintf(str,"Improper problem: %d " BIGINT_FORMAT " " 
+                  TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                  TAGINT_FORMAT " " TAGINT_FORMAT,
                   me,update->ntimestep,
                   atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
           error->warning(FLERR,str,0);
diff --git a/src/DIPOLE/atom_vec_dipole.cpp b/src/DIPOLE/atom_vec_dipole.cpp
index 59d8b5e8eb778aa8023c5195cf87619aeeff1f6d..08067d567d7d448684d842c0e864275ad0b633c1 100644
--- a/src/DIPOLE/atom_vec_dipole.cpp
+++ b/src/DIPOLE/atom_vec_dipole.cpp
@@ -512,7 +512,7 @@ void AtomVecDipole::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     q[i] = buf[m++];
@@ -541,7 +541,7 @@ void AtomVecDipole::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     q[i] = buf[m++];
@@ -625,7 +625,7 @@ int AtomVecDipole::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -716,7 +716,7 @@ int AtomVecDipole::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -781,10 +781,7 @@ void AtomVecDipole::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -872,9 +869,10 @@ int AtomVecDipole::pack_data_hybrid(int i, double *buf)
 void AtomVecDipole::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e "
+    fprintf(fp,TAGINT_FORMAT \
+            " %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e "
             "%-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             buf[i][2],buf[i][3],buf[i][4],
             buf[i][5],buf[i][6],buf[i][7],buf[i][8],
             (int) ubuf(buf[i][9]).i,(int) ubuf(buf[i][10]).i,
diff --git a/src/DIPOLE/atom_vec_dipole.h b/src/DIPOLE/atom_vec_dipole.h
index aaa8801acac50b6c33b2f73a436145b54716305a..436973f3ac2a7f17d3c46ad7215a546fb8726565 100644
--- a/src/DIPOLE/atom_vec_dipole.h
+++ b/src/DIPOLE/atom_vec_dipole.h
@@ -59,7 +59,8 @@ class AtomVecDipole : public AtomVec {
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   double *q,**mu,**omega,**torque;
diff --git a/src/FLD/pair_lubricateU.cpp b/src/FLD/pair_lubricateU.cpp
index 4fda2811403f69e0ed13524582ba3eae1a35a3dc..4a48800697895f90655c3ed5c77053de07d6f8ee 100644
--- a/src/FLD/pair_lubricateU.cpp
+++ b/src/FLD/pair_lubricateU.cpp
@@ -40,7 +40,6 @@
 #include "memory.h"
 #include "error.h"
 
-
 using namespace LAMMPS_NS;
 using namespace MathConst;
 
diff --git a/src/GRANULAR/fix_pour.cpp b/src/GRANULAR/fix_pour.cpp
index 562edd42c291d5997bc359de87358b4cb2df3749..9a439d87d6b987a3f9db5e4b93a1ded74b8d7338 100644
--- a/src/GRANULAR/fix_pour.cpp
+++ b/src/GRANULAR/fix_pour.cpp
@@ -630,12 +630,16 @@ void FixPour::pre_exchange()
 
   if (ninserted_atoms) {
     atom->natoms += ninserted_atoms;
+    if (atom->natoms < 0 || atom->natoms > MAXBIGINT)
+      error->all(FLERR,"Too many total atoms");
     if (mode == MOLECULE) {
       atom->nbonds += onemol->nbonds * ninserted_mols;
       atom->nangles += onemol->nangles * ninserted_mols;
       atom->ndihedrals += onemol->ndihedrals * ninserted_mols;
       atom->nimpropers += onemol->nimpropers * ninserted_mols;
     }
+    if (maxtag_all >= MAXTAGINT)
+      error->all(FLERR,"New atom IDs exceed maximum allowed ID");
     if (atom->map_style) {
       atom->nghost = 0;
       atom->map_init();
@@ -661,13 +665,13 @@ void FixPour::pre_exchange()
 
 void FixPour::find_maxid()
 {
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
 
-  int max = 0;
+  tagint max = 0;
   for (int i = 0; i < nlocal; i++) max = MAX(max,tag[i]);
-  MPI_Allreduce(&max,&maxtag_all,1,MPI_INT,MPI_MAX,world);
+  MPI_Allreduce(&max,&maxtag_all,1,MPI_LMP_TAGINT,MPI_MAX,world);
 
   if (mode == MOLECULE && molecule) {
     max = 0;
diff --git a/src/GRANULAR/fix_pour.h b/src/GRANULAR/fix_pour.h
index 6b955fd801db7e0cf90505c63535a14c647b5c6c..34d13da9855fb3aa68d5e1176b6004aa38baec15 100644
--- a/src/GRANULAR/fix_pour.h
+++ b/src/GRANULAR/fix_pour.h
@@ -62,7 +62,8 @@ class FixPour : public Fix {
   int *recvcounts,*displs;
   int nfreq,nfirst,ninserted,nper;
   double lo_current,hi_current;
-  int maxtag_all,maxmol_all;
+  tagint maxtag_all;
+  int maxmol_all;
   class RanPark *random,*random2;
 
   void find_maxid();
diff --git a/src/KSPACE/pair_lj_cut_tip4p_long.cpp b/src/KSPACE/pair_lj_cut_tip4p_long.cpp
index a6881c86f5c1cc8513251708068a41f58eb43693..05aa14e2c6737dca6c2cfc7c851a70f177390c67 100644
--- a/src/KSPACE/pair_lj_cut_tip4p_long.cpp
+++ b/src/KSPACE/pair_lj_cut_tip4p_long.cpp
@@ -117,6 +117,7 @@ void PairLJCutTIP4PLong::compute(int eflag, int vflag)
   double **f = atom->f;
   double **x = atom->x;
   double *q = atom->q;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
@@ -144,8 +145,8 @@ void PairLJCutTIP4PLong::compute(int eflag, int vflag)
 
     if (itype == typeO) {
       if (hneigh[i][0] < 0) {
-        hneigh[i][0] = iH1 = atom->map(atom->tag[i] + 1);
-        hneigh[i][1] = iH2 = atom->map(atom->tag[i] + 2);
+        hneigh[i][0] = iH1 = atom->map(tag[i] + 1);
+        hneigh[i][1] = iH2 = atom->map(tag[i] + 2);
         hneigh[i][2] = 1;
         if (iH1 == -1 || iH2 == -1)
           error->one(FLERR,"TIP4P hydrogen is missing");
@@ -214,8 +215,8 @@ void PairLJCutTIP4PLong::compute(int eflag, int vflag)
 
           if (jtype == typeO) {
             if (hneigh[j][0] < 0) {
-              hneigh[j][0] = jH1 = atom->map(atom->tag[j] + 1);
-              hneigh[j][1] = jH2 = atom->map(atom->tag[j] + 2);
+              hneigh[j][0] = jH1 = atom->map(tag[j] + 1);
+              hneigh[j][1] = jH2 = atom->map(tag[j] + 2);
               hneigh[j][2] = 1;
               if (jH1 == -1 || jH2 == -1)
                 error->one(FLERR,"TIP4P hydrogen is missing");
diff --git a/src/KSPACE/pair_lj_long_tip4p_long.cpp b/src/KSPACE/pair_lj_long_tip4p_long.cpp
index 31623fc7323da86b034cb7fb956e2d50bd7086b7..04723a27a19a1678ca4547b5a5a06775d402d80b 100755
--- a/src/KSPACE/pair_lj_long_tip4p_long.cpp
+++ b/src/KSPACE/pair_lj_long_tip4p_long.cpp
@@ -116,6 +116,7 @@ void PairLJLongTIP4PLong::compute(int eflag, int vflag)
   double **f = atom->f;
   double **x = atom->x;
   double *q = atom->q;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
@@ -144,8 +145,8 @@ void PairLJLongTIP4PLong::compute(int eflag, int vflag)
     itype = type[i];
     if (itype == typeO) {
       if (hneigh[i][0] < 0) {
-        hneigh[i][0] = iH1 = atom->map(atom->tag[i] + 1);
-        hneigh[i][1] = iH2 = atom->map(atom->tag[i] + 2);
+        hneigh[i][0] = iH1 = atom->map(tag[i] + 1);
+        hneigh[i][1] = iH2 = atom->map(tag[i] + 2);
         hneigh[i][2] = 1;
         if (iH1 == -1 || iH2 == -1)
           error->one(FLERR,"TIP4P hydrogen is missing");
@@ -253,8 +254,8 @@ void PairLJLongTIP4PLong::compute(int eflag, int vflag)
         if (itype == typeO || jtype == typeO) { 
 	  if (jtype == typeO) {
             if (hneigh[j][0] < 0) {
-              hneigh[j][0] = jH1 = atom->map(atom->tag[j] + 1);
-              hneigh[j][1] = jH2 = atom->map(atom->tag[j] + 2);
+              hneigh[j][0] = jH1 = atom->map(tag[j] + 1);
+              hneigh[j][1] = jH2 = atom->map(tag[j] + 2);
               hneigh[j][2] = 1;
               if (jH1 == -1 || jH2 == -1)
                 error->one(FLERR,"TIP4P hydrogen is missing");
@@ -499,6 +500,7 @@ void PairLJLongTIP4PLong::compute_inner()
   double **f = atom->f;
   double **x = atom->x;
   double *q = atom->q;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
@@ -526,8 +528,8 @@ void PairLJLongTIP4PLong::compute_inner()
     itype = type[i];
     if (itype == typeO && order1) {
       if (hneigh[i][0] < 0) {
-        hneigh[i][0] = iH1 = atom->map(atom->tag[i] + 1);
-        hneigh[i][1] = iH2 = atom->map(atom->tag[i] + 2);
+        hneigh[i][0] = iH1 = atom->map(tag[i] + 1);
+        hneigh[i][1] = iH2 = atom->map(tag[i] + 2);
         hneigh[i][2] = 1;
         if (iH1 == -1 || iH2 == -1)
           error->one(FLERR,"TIP4P hydrogen is missing");
@@ -594,8 +596,8 @@ void PairLJLongTIP4PLong::compute_inner()
         if (itype == typeO || jtype == typeO) { 
 	  if (jtype == typeO) {
             if (hneigh[j][0] < 0) {
-              hneigh[j][0] = jH1 = atom->map(atom->tag[j] + 1);
-              hneigh[j][1] = jH2 = atom->map(atom->tag[j] + 2);
+              hneigh[j][0] = jH1 = atom->map(tag[j] + 1);
+              hneigh[j][1] = jH2 = atom->map(tag[j] + 2);
               hneigh[j][2] = 1;
               if (jH1 == -1 || jH2 == -1)
                 error->one(FLERR,"TIP4P hydrogen is missing");
@@ -749,6 +751,7 @@ void PairLJLongTIP4PLong::compute_middle()
   double **f = atom->f;
   double **x = atom->x;
   double *q = atom->q;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
@@ -777,8 +780,8 @@ void PairLJLongTIP4PLong::compute_middle()
     itype = type[i];
     if (itype == typeO && order1) {
       if (hneigh[i][0] < 0) {
-        hneigh[i][0] = iH1 = atom->map(atom->tag[i] + 1);
-        hneigh[i][1] = iH2 = atom->map(atom->tag[i] + 2);
+        hneigh[i][0] = iH1 = atom->map(tag[i] + 1);
+        hneigh[i][1] = iH2 = atom->map(tag[i] + 2);
         hneigh[i][2] = 1;
         if (iH1 == -1 || iH2 == -1)
           error->one(FLERR,"TIP4P hydrogen is missing");
@@ -849,8 +852,8 @@ void PairLJLongTIP4PLong::compute_middle()
         if (itype == typeO || jtype == typeO) { 
 	  if (jtype == typeO) {
             if (hneigh[j][0] < 0) {
-              hneigh[j][0] = jH1 = atom->map(atom->tag[j] + 1);
-              hneigh[j][1] = jH2 = atom->map(atom->tag[j] + 2);
+              hneigh[j][0] = jH1 = atom->map(tag[j] + 1);
+              hneigh[j][1] = jH2 = atom->map(tag[j] + 2);
               hneigh[j][2] = 1;
               if (jH1 == -1 || jH2 == -1)
                 error->one(FLERR,"TIP4P hydrogen is missing");
@@ -1017,6 +1020,7 @@ void PairLJLongTIP4PLong::compute_outer(int eflag, int vflag)
   double **f = atom->f;
   double **x = atom->x;
   double *q = atom->q;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
@@ -1053,8 +1057,8 @@ void PairLJLongTIP4PLong::compute_outer(int eflag, int vflag)
     itype = type[i];
     if (itype == typeO) {
       if (hneigh[i][0] < 0) {
-        hneigh[i][0] = iH1 = atom->map(atom->tag[i] + 1);
-        hneigh[i][1] = iH2 = atom->map(atom->tag[i] + 2);
+        hneigh[i][0] = iH1 = atom->map(tag[i] + 1);
+        hneigh[i][1] = iH2 = atom->map(tag[i] + 2);
         hneigh[i][2] = 1;
         if (iH1 == -1 || iH2 == -1)
           error->one(FLERR,"TIP4P hydrogen is missing");
@@ -1174,8 +1178,8 @@ void PairLJLongTIP4PLong::compute_outer(int eflag, int vflag)
         if (itype == typeO || jtype == typeO) { 
 	  if (jtype == typeO) {
             if (hneigh[j][0] < 0) {
-              hneigh[j][0] = jH1 = atom->map(atom->tag[j] + 1);
-              hneigh[j][1] = jH2 = atom->map(atom->tag[j] + 2);
+              hneigh[j][0] = jH1 = atom->map(tag[j] + 1);
+              hneigh[j][1] = jH2 = atom->map(tag[j] + 2);
               hneigh[j][2] = 1;
               if (jH1 == -1 || jH2 == -1)
                 error->one(FLERR,"TIP4P hydrogen is missing");
diff --git a/src/KSPACE/pair_tip4p_long.cpp b/src/KSPACE/pair_tip4p_long.cpp
index b6b6ef0034ebdd60dd71f94f95e0595de38f2473..c08b4222297f88b363f348947522afd697c8c0cc 100644
--- a/src/KSPACE/pair_tip4p_long.cpp
+++ b/src/KSPACE/pair_tip4p_long.cpp
@@ -115,6 +115,7 @@ void PairTIP4PLong::compute(int eflag, int vflag)
   double **f = atom->f;
   double **x = atom->x;
   double *q = atom->q;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   double *special_coul = force->special_coul;
   int newton_pair = force->newton_pair;
@@ -141,8 +142,8 @@ void PairTIP4PLong::compute(int eflag, int vflag)
 
     if (itype == typeO) {
       if (hneigh[i][0] < 0) {
-        hneigh[i][0] = iH1 = atom->map(atom->tag[i] + 1);
-        hneigh[i][1] = iH2 = atom->map(atom->tag[i] + 2);
+        hneigh[i][0] = iH1 = atom->map(tag[i] + 1);
+        hneigh[i][1] = iH2 = atom->map(tag[i] + 2);
         hneigh[i][2] = 1;
         if (iH1 == -1 || iH2 == -1)
           error->one(FLERR,"TIP4P hydrogen is missing");
@@ -185,8 +186,8 @@ void PairTIP4PLong::compute(int eflag, int vflag)
 
           if (jtype == typeO) {
             if (hneigh[j][0] < 0) {
-              hneigh[j][0] = jH1 = atom->map(atom->tag[j] + 1);
-              hneigh[j][1] = jH2 = atom->map(atom->tag[j] + 2);
+              hneigh[j][0] = jH1 = atom->map(tag[j] + 1);
+              hneigh[j][1] = jH2 = atom->map(tag[j] + 2);
               hneigh[j][2] = 1;
               if (jH1 == -1 || jH2 == -1)
                 error->one(FLERR,"TIP4P hydrogen is missing");
diff --git a/src/MANYBODY/fix_qeq_comb.cpp b/src/MANYBODY/fix_qeq_comb.cpp
index 54d6b49e01afc7d2c4e2fe810a94095ac3f34ee2..05264d350201ec91bc290b3a72bf125210b55012 100644
--- a/src/MANYBODY/fix_qeq_comb.cpp
+++ b/src/MANYBODY/fix_qeq_comb.cpp
@@ -212,7 +212,6 @@ void FixQEQComb::post_force(int vflag)
 
   double *q = atom->q;
   int *mask = atom->mask;
-  int *tag = atom->tag;
   int nlocal = atom->nlocal;
 
  if (comb) {
diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp
index f6555063dc42ca3b261cd257e111842214a92c97..be96881bc526dae2946e8dc9e23443671e8d47b6 100644
--- a/src/MANYBODY/pair_airebo.cpp
+++ b/src/MANYBODY/pair_airebo.cpp
@@ -391,7 +391,8 @@ void PairAIREBO::REBO_neigh()
 
 void PairAIREBO::FREBO(int eflag, int vflag)
 {
-  int i,j,k,m,ii,inum,itype,jtype,itag,jtag;
+  int i,j,k,m,ii,inum,itype,jtype;
+  tagint itag,jtag;
   double delx,dely,delz,evdwl,fpair,xtmp,ytmp,ztmp;
   double rsq,rij,wij;
   double Qij,Aij,alphaij,VR,pre,dVRdi,VA,term,bij,dVAdi,dVA;
@@ -403,7 +404,7 @@ void PairAIREBO::FREBO(int eflag, int vflag)
   double **x = atom->x;
   double **f = atom->f;
   int *type = atom->type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
   int newton_pair = force->newton_pair;
 
@@ -489,9 +490,10 @@ void PairAIREBO::FREBO(int eflag, int vflag)
 
 void PairAIREBO::FLJ(int eflag, int vflag)
 {
-  int i,j,k,m,ii,jj,kk,mm,inum,jnum,itype,jtype,ktype,mtype,itag,jtag;
+  int i,j,k,m,ii,jj,kk,mm,inum,jnum,itype,jtype,ktype,mtype;
   int atomi,atomj,atomk,atomm;
   int testpath,npath,done;
+  tagint itag,jtag;
   double evdwl,fpair,xtmp,ytmp,ztmp;
   double rsq,best,wik,wkm,cij,rij,dwij,dwik,dwkj,dwkm,dwmj;
   double delij[3],rijsq,delik[3],rik,deljk[3];
@@ -520,7 +522,7 @@ void PairAIREBO::FLJ(int eflag, int vflag)
 
   double **x = atom->x;
   double **f = atom->f;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int newton_pair = force->newton_pair;
@@ -855,7 +857,8 @@ void PairAIREBO::FLJ(int eflag, int vflag)
 
 void PairAIREBO::TORSION(int eflag, int vflag)
 {
-  int i,j,k,l,ii,inum,itag,jtag;
+  int i,j,k,l,ii,inum;
+  tagint itag,jtag;
   double evdwl,fpair,xtmp,ytmp,ztmp;
   double cos321;
   double w21,dw21,cos234,w34,dw34;
@@ -880,7 +883,7 @@ void PairAIREBO::TORSION(int eflag, int vflag)
   double **x = atom->x;
   double **f = atom->f;
   int *type = atom->type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   inum = list->inum;
   ilist = list->ilist;
diff --git a/src/MANYBODY/pair_bop.cpp b/src/MANYBODY/pair_bop.cpp
index 2f72fc8be09d667a258522808d9812cf1d4f5102..e9b41c23759e31a0181513976dc3b29ddda6599e 100644
--- a/src/MANYBODY/pair_bop.cpp
+++ b/src/MANYBODY/pair_bop.cpp
@@ -274,7 +274,8 @@ void PairBOP::compute(int eflag, int vflag)
   int ago,delay,every;
   int i,j,ii,jj,iij;
   int n,inum,temp_ij,ks;
-  int itype,jtype,i_tag,j_tag;
+  int itype,jtype;
+  tagint i_tag,j_tag;
   int *ilist,*iilist,*numneigh;
   int **firstneigh;
   double dpr1,ps;
@@ -288,7 +289,7 @@ void PairBOP::compute(int eflag, int vflag)
   double **f = atom->f;
   double **x = atom->x;
   int *type = atom->type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int newton_pair = force->newton_pair;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
@@ -846,7 +847,7 @@ void PairBOP::sigmaBo()
   int n,i,j,k,kp,m,pp,kkp;
   int iij,ji,ki;
   int itmp,jtmp,ktmp,ltmp,mtmp;
-  int i_tag,j_tag;
+  tagint i_tag,j_tag;
   int ngi,ngj,ngk,nglkp,ngli,nglj,ngl;
   int ngji,ngjk,nikj,ngki,ngkj,ngjkp;
   int ngkpk,ngkpj,ngkkp,nglk;
@@ -890,7 +891,7 @@ void PairBOP::sigmaBo()
   double ftmp[3];
   double **x = atom->x;
   double **f = atom->f;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int newton_pair = force->newton_pair;
   int *type = atom->type;
 
@@ -2401,7 +2402,7 @@ void PairBOP::sigmaBo_noa()
   int n,i,j,k,kp,m,pp;
   int iij,ji,ki;
   int itmp,jtmp,ktmp,ltmp,mtmp;
-  int i_tag,j_tag;
+  tagint i_tag,j_tag;
   int ngi,ngj,ngk,ngli,nglj,ngl;
   int ngji,ngjk,nikj,ngki,ngkj;
   int njik,nijk,nikkp,nkp,nijkp;
@@ -2437,7 +2438,7 @@ void PairBOP::sigmaBo_noa()
   double ftmp[3];
   double **x = atom->x;
   double **f = atom->f;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int newton_pair = force->newton_pair;
   int *type = atom->type;
 
@@ -3379,7 +3380,7 @@ void PairBOP::sigmaBo_otf()
   int nb_t,new_n_tot;
   int n,i,j,k,kp,m,pp,kpj,kpk,kkp;
   int itmp,jtmp,ktmp,ltmp,mtmp;
-  int i_tag,j_tag;
+  tagint i_tag,j_tag;
   int kp1,kp2,kp1type;
   int iij,iik,ijk,ikkp,ji,iikp,ijkp;
   int nkp;
@@ -3448,7 +3449,7 @@ void PairBOP::sigmaBo_otf()
   double ftmp[3],xtmp[3];
   double **x = atom->x;
   double **f = atom->f;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int newton_pair = force->newton_pair;
   int *type = atom->type;
 
@@ -5303,7 +5304,7 @@ void PairBOP::sigmaBo_noa_otf()
   int nb_t,new_n_tot;
   int n,i,j,k,kp,m,pp;
   int itmp,jtmp,ktmp,ltmp,mtmp;
-  int i_tag,j_tag;
+  tagint i_tag,j_tag;
   int kp1,kp2,kp1type;
   int iij,iik,ijk,ikkp,ji,iikp,ijkp;
   int nkp;
@@ -5368,7 +5369,7 @@ void PairBOP::sigmaBo_noa_otf()
   double ftmp[3],xtmp[3];
   double **x = atom->x;
   double **f = atom->f;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int newton_pair = force->newton_pair;
   int *type = atom->type;
 
@@ -6541,7 +6542,7 @@ void PairBOP::PiBo()
   int i,j,k,kp,m,n,pp,nb_t;
   int iij,ji,ki;
   int nsearch,ncmp;
-  int i_tag,j_tag;
+  tagint i_tag,j_tag;
   int njik,ngj,ngk,nglj,ngl,ngi;
   int nkjkp,nijkp,ngli,nkikp,njikp;
   int itmp,ltmp,jtmp,ktmp;
@@ -6570,7 +6571,7 @@ void PairBOP::PiBo()
   double **f = atom->f;
   double **x = atom->x;
   int *type = atom->type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int newton_pair = force->newton_pair;
 
   nlocal = atom->nlocal;
@@ -7265,7 +7266,7 @@ void PairBOP::PiBo_otf()
   int i,j,k,kp,m,n,pp,nb_t;
   int iij,iik,iikp,ji,ki,ijkp,ijk;
   int nsearch,ncmp;
-  int i_tag,j_tag;
+  tagint i_tag,j_tag;
   int itmp,ltmp,jtmp,ktmp;
   int pi_flag,ks;
   int nlocal;
@@ -7317,7 +7318,7 @@ void PairBOP::PiBo_otf()
   double **f = atom->f;
   double **x = atom->x;
   int *type = atom->type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   nlocal = atom->nlocal;
   numneigh = list->numneigh;
diff --git a/src/MANYBODY/pair_comb.cpp b/src/MANYBODY/pair_comb.cpp
index 02096c00028e999e5173b99cba4c180355aa3412..7c18ccd3fc4acdb4b7140bf3501ada300b41b385 100644
--- a/src/MANYBODY/pair_comb.cpp
+++ b/src/MANYBODY/pair_comb.cpp
@@ -125,7 +125,8 @@ PairComb::~PairComb()
 void PairComb::compute(int eflag, int vflag)
 {
   int i,j,k,ii,jj,kk,inum,jnum,iparam_i;
-  int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk;
+  int itype,jtype,ktype,iparam_ij,iparam_ijk;
+  tagint itag,jtag;
   double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
   double rsq,rsq1,rsq2;
   double delr1[3],delr2[3],fi[3],fj[3],fk[3];
@@ -151,7 +152,7 @@ void PairComb::compute(int eflag, int vflag)
   double **x = atom->x;
   double **f = atom->f;
   double *q = atom->q;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int newton_pair = force->newton_pair;
@@ -1630,8 +1631,9 @@ void PairComb::field(Param *param, double rsq, double iq,double jq,
 
 double PairComb::yasu_char(double *qf_fix, int &igroup)
 {
-  int i,j,ii,jj,jnum,itag,jtag;
+  int i,j,ii,jj,jnum;
   int itype,jtype,iparam_i,iparam_ij;
+  tagint itag,jtag;
   double xtmp,ytmp,ztmp;
   double rsq1,delr1[3];
   int *ilist,*jlist,*numneigh,**firstneigh;
@@ -1643,7 +1645,7 @@ double PairComb::yasu_char(double *qf_fix, int &igroup)
   double **x = atom->x;
   double *q = atom->q;
   int *type = atom->type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   int inum = list->inum;
   ilist = list->ilist;
diff --git a/src/MANYBODY/pair_comb3.cpp b/src/MANYBODY/pair_comb3.cpp
index afc0adf0218a2722a19bed7654c904d71295feba..2d6bf9f9ef32db401cd629c3e68ec3ea2c139f2c 100644
--- a/src/MANYBODY/pair_comb3.cpp
+++ b/src/MANYBODY/pair_comb3.cpp
@@ -860,12 +860,11 @@ void PairComb3::Short_neigh()
   int n,nj,*neighptrj,icontrol;
   int iparam_ij,iparam_ji,iparam_jk,*ilist,*jlist,*numneigh,**firstneigh;
   int inum,jnum,i,j,k,l,ii,jj,kk,ll,itype,jtype,ktype,ltype;
-  int itag, jtag;
+  tagint itag,jtag;
   double rr1,rr2,rsq1,rsq2,delrj[3],delrk[3];
   int sht_knum,*sht_klist;
 
   double **x = atom->x;
-  int *tag  = atom->tag;
   int *type  = atom->type;
   int ntype = atom->ntypes;
   int nlocal = atom->nlocal;
@@ -896,7 +895,6 @@ void PairComb3::Short_neigh()
 
   for (ii = 0; ii < inum; ii++) {
     i = ilist[ii];
-    itag = tag[i];
     dpl[i][0] = dpl[i][1] = dpl[i][2] = 0.0;
 
     nj = 0;
@@ -913,7 +911,6 @@ void PairComb3::Short_neigh()
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
-      jtag = tag[j];
 
       delrj[0] = x[i][0] - x[j][0];
       delrj[1] = x[i][1] - x[j][1];
@@ -957,12 +954,13 @@ void PairComb3::Short_neigh()
 
 void PairComb3::compute(int eflag, int vflag)
 {
-  int i,ii,k,kk,j,jj,im,inum,jnum,itag,jtag,itype,jtype,ktype;
+  int i,ii,k,kk,j,jj,im,inum,jnum,itype,jtype,ktype;
   int iparam_i,iparam_ij,iparam_ji;
   int iparam_ijk,iparam_jik,iparam_ikj,iparam_jli,iparam_jki,iparam_ikl;
   int sht_jnum,*sht_jlist,sht_lnum,*sht_llist;
   int sht_mnum,*sht_mlist,sht_pnum,*sht_plist;
   int *ilist,*jlist,*numneigh,**firstneigh,mr1,mr2,mr3,inty,nj;
+  tagint itag,jtag;
   double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
   double rr,rsq,rsq1,rsq2,rsq3,iq,jq,yaself;
   double fqi,fqij,eng_tmp,vionij,fvionij,sr1,sr2,sr3; 
@@ -975,7 +973,7 @@ void PairComb3::compute(int eflag, int vflag)
   int nlocal = atom->nlocal;
   int newton_pair = force->newton_pair;
   int ntype = atom->ntypes;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   double **x = atom->x;
   double **f = atom->f;
@@ -1833,11 +1831,12 @@ void PairComb3::force_zeta(Param *parami, Param *paramj, double rsq,
   double boij, dbij1, dbij2, dbij3, dbij4, dbij5;
   double boji, dbji1, dbji2, dbji3, dbji4, dbji5;
   double pradx, prady;
+
   int inti=parami->ielement;
   int intj=paramj->ielement;
-  int *tag=atom->tag;
-  int itag=tag[i];
-  int jtag=tag[j];
+  tagint *tag=atom->tag;
+  tagint itag=tag[i];
+  tagint jtag=tag[j];
   r = sqrt(rsq);
 
   if (r > parami->bigr + parami->bigd) return;
@@ -3348,10 +3347,11 @@ void PairComb3::tor_force(int torindx, Param *paramk, Param *paraml,
 
 double PairComb3::combqeq(double *qf_fix, int &igroup)
 {
-  int i,j,ii, jj,itag,jtag,itype,jtype,jnum;
+  int i,j,ii,jj,itype,jtype,jnum;
   int iparam_i,iparam_ji,iparam_ij;
   int *ilist,*jlist,*numneigh,**firstneigh;
   int mr1,mr2,mr3,inty,nj;
+  tagint itag,jtag;
   double xtmp,ytmp,ztmp,rr,rsq,rsq1,rsq2,delrj[3],zeta_ij;
   double iq,jq,fqi,fqj,fqij,fqji,yaself,yaself_d,sr1,sr2,sr3;
   double rr_sw,ij_sw,ji_sw,fq_swi,fq_swj;
@@ -3360,7 +3360,7 @@ double PairComb3::combqeq(double *qf_fix, int &igroup)
   
   double **x = atom->x;
   double *q = atom->q;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int inum = list->inum;
   int *mask = atom->mask;
@@ -3507,7 +3507,7 @@ double PairComb3::combqeq(double *qf_fix, int &igroup)
     i = ilist[ii];
     if (mask[i] & groupbit){
       eneg += qf[i];
-	  itag=tag[i];
+      itag=tag[i];
     }
   }
 
diff --git a/src/MANYBODY/pair_lcbop.cpp b/src/MANYBODY/pair_lcbop.cpp
index cc511d59a40064ee8fe1a164534b2a94717c4816..8ccb7ee8aac2aff5a876177d4343218ef5fbddfb 100644
--- a/src/MANYBODY/pair_lcbop.cpp
+++ b/src/MANYBODY/pair_lcbop.cpp
@@ -355,7 +355,8 @@ void PairLCBOP::SR_neigh()
 
 void PairLCBOP::FSR(int eflag, int vflag)
 {
-  int i,j,jj,ii,inum,itag,jtag;
+  int i,j,jj,ii,inum;
+  tagint itag,jtag;
   double delx,dely,delz,fpair,xtmp,ytmp,ztmp;
   double r_sq,rijmag,f_c_ij,df_c_ij;
   double VR,dVRdi,VA,Bij,dVAdi,dVA;
@@ -364,7 +365,7 @@ void PairLCBOP::FSR(int eflag, int vflag)
 
   double **x = atom->x;
   double **f = atom->f;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
   int newton_pair = force->newton_pair;
 
@@ -450,19 +451,18 @@ void PairLCBOP::FSR(int eflag, int vflag)
 
 void PairLCBOP::FLR(int eflag, int vflag)
 {
-
-  int i,j,jj,m,ii,itag,jtag;
+  int i,j,jj,m,ii;
+  tagint itag,jtag;
   double delx,dely,delz,fpair,xtmp,ytmp,ztmp;
   double r_sq,rijmag,f_c_ij,df_c_ij;
   double V,dVdi;
 
   double **x = atom->x;
   double **f = atom->f;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
   int newton_pair = force->newton_pair;
 
-
   int inum = list->inum;
   int *ilist = list->ilist;
   int *numneigh = list->numneigh;
diff --git a/src/MANYBODY/pair_nb3b_harmonic.cpp b/src/MANYBODY/pair_nb3b_harmonic.cpp
index 1130479d3fac45fed2bc9e229ebb6e64c8bbe09d..d2121b07529e09755e7a1ec637760e3cf868deb2 100644
--- a/src/MANYBODY/pair_nb3b_harmonic.cpp
+++ b/src/MANYBODY/pair_nb3b_harmonic.cpp
@@ -77,8 +77,9 @@ PairNb3bHarmonic::~PairNb3bHarmonic()
 
 void PairNb3bHarmonic::compute(int eflag, int vflag)
 {
-  int i,j,k,ii,jj,kk,inum,jnum,jnumm1,itag,jtag;
+  int i,j,k,ii,jj,kk,inum,jnum,jnumm1;
   int itype,jtype,ktype,ijparam,ikparam,ijkparam;
+  tagint itag,jtag;
   double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
   double rsq,rsq1,rsq2;
   double delr1[3],delr2[3],fj[3],fk[3];
@@ -90,7 +91,7 @@ void PairNb3bHarmonic::compute(int eflag, int vflag)
 
   double **x = atom->x;
   double **f = atom->f;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int newton_pair = force->newton_pair;
diff --git a/src/MANYBODY/pair_sw.cpp b/src/MANYBODY/pair_sw.cpp
index d3cc168389a1ff4c305153e2b989a07a75730b18..3928ff0d0b6dc3cbf781de1b1b92628464f0e28e 100755
--- a/src/MANYBODY/pair_sw.cpp
+++ b/src/MANYBODY/pair_sw.cpp
@@ -75,8 +75,9 @@ PairSW::~PairSW()
 
 void PairSW::compute(int eflag, int vflag)
 {
-  int i,j,k,ii,jj,kk,inum,jnum,jnumm1,itag,jtag;
+  int i,j,k,ii,jj,kk,inum,jnum,jnumm1;
   int itype,jtype,ktype,ijparam,ikparam,ijkparam;
+  tagint itag,jtag;
   double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
   double rsq,rsq1,rsq2;
   double delr1[3],delr2[3],fj[3],fk[3];
@@ -88,7 +89,7 @@ void PairSW::compute(int eflag, int vflag)
 
   double **x = atom->x;
   double **f = atom->f;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int newton_pair = force->newton_pair;
diff --git a/src/MANYBODY/pair_tersoff.cpp b/src/MANYBODY/pair_tersoff.cpp
index fbbe857f09a71eaf4e6323a21b78cef75b19f925..fe02371fec8b9f4ab5b83648bb9f049534b0c13c 100755
--- a/src/MANYBODY/pair_tersoff.cpp
+++ b/src/MANYBODY/pair_tersoff.cpp
@@ -77,7 +77,8 @@ PairTersoff::~PairTersoff()
 void PairTersoff::compute(int eflag, int vflag)
 {
   int i,j,k,ii,jj,kk,inum,jnum;
-  int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk;
+  int itype,jtype,ktype,iparam_ij,iparam_ijk;
+  tagint itag,jtag;
   double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
   double rsq,rsq1,rsq2;
   double delr1[3],delr2[3],fi[3],fj[3],fk[3];
@@ -90,7 +91,7 @@ void PairTersoff::compute(int eflag, int vflag)
 
   double **x = atom->x;
   double **f = atom->f;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int newton_pair = force->newton_pair;
diff --git a/src/MC/fix_bond_break.cpp b/src/MC/fix_bond_break.cpp
index 0ae5ae94be4c4a180dd36392639c45612aef5670..50f718492cc83b263c491c4ffc91c2ddd2bc644c 100755
--- a/src/MC/fix_bond_break.cpp
+++ b/src/MC/fix_bond_break.cpp
@@ -155,7 +155,7 @@ void FixBondBreak::post_integrate()
 {
   int i,j,k,m,n,i1,i2,n1,n3,type;
   double delx,dely,delz,rsq;
-  int *slist;
+  tagint *slist;
 
   if (update->ntimestep % nevery) return;
 
@@ -188,7 +188,7 @@ void FixBondBreak::post_integrate()
   // setup possible partner list of bonds to break
 
   double **x = atom->x;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int **bondlist = neighbor->bondlist;
   int nbondlist = neighbor->nbondlist;
@@ -237,10 +237,10 @@ void FixBondBreak::post_integrate()
   // and probability constraint is satisfied
 
   int **bond_type = atom->bond_type;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
   int *num_bond = atom->num_bond;
   int **nspecial = atom->nspecial;
-  int **special = atom->special;
+  tagint **special = atom->special;
 
   int nbreak = 0;
   for (i = 0; i < nlocal; i++) {
@@ -333,7 +333,7 @@ void FixBondBreak::unpack_comm(int n, int first, double *buf)
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
-    partner[i] = static_cast<int> (buf[m++]);
+    partner[i] = static_cast<tagint> (buf[m++]);
     probability[i] = buf[m++];
   }
 }
@@ -363,7 +363,7 @@ void FixBondBreak::unpack_reverse_comm(int n, int *list, double *buf)
   for (i = 0; i < n; i++) {
     j = list[i];
     if (buf[m+1] > distsq[j]) {
-      partner[j] = static_cast<int> (buf[m++]);
+      partner[j] = static_cast<tagint> (buf[m++]);
       distsq[j] = buf[m++];
     } else m += 2;
   }
diff --git a/src/MC/fix_bond_break.h b/src/MC/fix_bond_break.h
index a625e0ff80501c4fcb6ac10bca09eddb849a93e3..6c8f74986186c1b0f439c450748c79104c248a53 100755
--- a/src/MC/fix_bond_break.h
+++ b/src/MC/fix_bond_break.h
@@ -47,7 +47,7 @@ class FixBondBreak : public Fix {
 
   int breakcount,breakcounttotal;
   int nmax;
-  int *partner;
+  tagint *partner;
   double *distsq,*probability;
 
   class RanMars *random;
diff --git a/src/MC/fix_bond_create.cpp b/src/MC/fix_bond_create.cpp
index 7d0850c57eed9d4154b96a6837aaff9eb2fadcd5..015a52701521fe2e7007ce1c5d076afd067f83a1 100755
--- a/src/MC/fix_bond_create.cpp
+++ b/src/MC/fix_bond_create.cpp
@@ -235,7 +235,7 @@ void FixBondCreate::setup(int vflag)
 
   int *num_bond = atom->num_bond;
   int **bond_type = atom->bond_type;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
   int nlocal = atom->nlocal;
   int nghost = atom->nghost;
   int nall = nlocal + nghost;
@@ -269,7 +269,8 @@ void FixBondCreate::post_integrate()
 {
   int i,j,m,ii,jj,inum,jnum,itype,jtype,n1,n3,possible;
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
-  int *ilist,*jlist,*numneigh,**firstneigh,*slist;
+  int *ilist,*jlist,*numneigh,**firstneigh;
+  tagint *slist;
 
   if (update->ntimestep % nevery) return;
 
@@ -307,7 +308,7 @@ void FixBondCreate::post_integrate()
   // each atom sets one closest eligible partner atom ID to bond with
 
   double **x = atom->x;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int *type = atom->type;
 
@@ -385,10 +386,10 @@ void FixBondCreate::post_integrate()
   // and probability constraint is satisfied
 
   int **bond_type = atom->bond_type;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
   int *num_bond = atom->num_bond;
   int **nspecial = atom->nspecial;
-  int **special = atom->special;
+  tagint **special = atom->special;
   int newton_bond = force->newton_bond;
 
   int ncreate = 0;
@@ -506,7 +507,7 @@ void FixBondCreate::unpack_comm(int n, int first, double *buf)
 
   } else {
     for (i = first; i < last; i++) {
-      partner[i] = static_cast<int> (buf[m++]);
+      partner[i] = static_cast<tagint> (buf[m++]);
       probability[i] = buf[m++];
     }
   }
@@ -554,7 +555,7 @@ void FixBondCreate::unpack_reverse_comm(int n, int *list, double *buf)
       j = list[i];
       if (buf[m] < distsq[j]) {
         distsq[j] = buf[m++];
-        partner[j] = static_cast<int> (buf[m++]);
+        partner[j] = static_cast<tagint> (buf[m++]);
       } else m += 2;
     }
   }
diff --git a/src/MC/fix_bond_create.h b/src/MC/fix_bond_create.h
index 36519d7741a441336868e1bab9ac5822c3ebaffc..52f9b09de2b1e1b5d4fcdfb81e658360c983cf69 100755
--- a/src/MC/fix_bond_create.h
+++ b/src/MC/fix_bond_create.h
@@ -58,7 +58,7 @@ class FixBondCreate : public Fix {
 
   int nmax;
   int *bondcount;        // count of created bonds this atom is part of
-  int *partner;          // ID of preferred atom for this atom to bond to
+  tagint *partner;       // ID of preferred atom for this atom to bond to
   double *distsq;        // distance to preferred bond partner
   double *probability;   // random # to use in decision to form bond
 
diff --git a/src/MC/fix_bond_swap.cpp b/src/MC/fix_bond_swap.cpp
index 24474052f5eaacecd5291d1d17c6d5b5db858613..31bdb75682a3ea094373357a06010fefe286cb7c 100644
--- a/src/MC/fix_bond_swap.cpp
+++ b/src/MC/fix_bond_swap.cpp
@@ -179,9 +179,9 @@ void FixBondSwap::pre_neighbor()
 {
   int i,j,ii,jj,m,inum,jnum;
   int inext,iprev,ilast,jnext,jprev,jlast,ibond,iangle,jbond,jangle;
-  int itag,inexttag,iprevtag,ilasttag,jtag,jnexttag,jprevtag,jlasttag;
   int ibondtype,jbondtype,iangletype,inextangletype,jangletype,jnextangletype;
-  int i1,i2,i3,j1,j2,j3,tmp;
+  tagint itag,inexttag,iprevtag,ilasttag,jtag,jnexttag,jprevtag,jlasttag;
+  tagint i1,i2,i3,j1,j2,j3;
   int *ilist,*jlist,*numneigh,**firstneigh;
   double delta,factor;
 
@@ -191,19 +191,19 @@ void FixBondSwap::pre_neighbor()
 
   // local ptrs to atom arrays
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int *num_bond = atom->num_bond;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
   int **bond_type = atom->bond_type;
   int *num_angle = atom->num_angle;
-  int **angle_atom1 = atom->angle_atom1;
-  int **angle_atom2 = atom->angle_atom2;
-  int **angle_atom3 = atom->angle_atom3;
+  tagint **angle_atom1 = atom->angle_atom1;
+  tagint **angle_atom2 = atom->angle_atom2;
+  tagint **angle_atom3 = atom->angle_atom3;
   int **angle_type = atom->angle_type;
   int **nspecial = atom->nspecial;
-  int **special = atom->special;
+  tagint **special = atom->special;
   int newton_bond = force->newton_bond;
   int nlocal = atom->nlocal;
 
@@ -231,6 +231,7 @@ void FixBondSwap::pre_neighbor()
       alist[neligible++] = i;
   }
 
+  int tmp;
   for (i = 0; i < neligible; i++) {
     j = static_cast<int> (random->uniform() * neligible);
     tmp = alist[i];
diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp
index eb8fba2daf1b263673039b5a54b6d559c55e97d6..ab85e6e21b619ee800480fcbf9c1d45183a873f4 100644
--- a/src/MC/fix_gcmc.cpp
+++ b/src/MC/fix_gcmc.cpp
@@ -282,9 +282,10 @@ void FixGCMC::init()
   }
 
   if ((molflag && (atom->molecule_flag == 0)) || 
-      (molflag && ((!atom->tag_enable) || (!atom->map_style))))
+      (molflag && (!atom->tag_enable || !atom->map_style)))
     error->all(FLERR,
-     "Fix gcmc molecule command requires that atoms have molecule attributes");
+               "Fix gcmc molecule command requires that "
+               "atoms have molecule attributes");
 
   if (force->pair->single_enable == 0)
     error->all(FLERR,"Fix gcmc incompatible with given pair_style");
@@ -805,18 +806,18 @@ void FixGCMC::attempt_molecule_insertion()
     if (maxmol >= MAXSMALLINT) 
       error->all(FLERR,"Fix gcmc ran out of available molecule IDs");
 
-    int maxtag = 0;
+    tagint maxtag = 0;
     for (int i = 0; i < atom->nlocal; i++) maxtag = MAX(maxtag,atom->tag[i]);
-    int maxtag_all;
-    MPI_Allreduce(&maxtag,&maxtag_all,1,MPI_INT,MPI_MAX,world);
-    int atom_offset = maxtag_all;
+    tagint maxtag_all;
+    MPI_Allreduce(&maxtag,&maxtag_all,1,MPI_LMP_TAGINT,MPI_MAX,world);
+    tagint atom_offset = maxtag_all;
 
     int k = 0;
     double **x = atom->x;
     double **v = atom->v;
     imageint *image = atom->image;
     int *molecule = atom->molecule;
-    int *tag = atom->tag;
+    tagint *tag = atom->tag;
     for (int i = 0; i < natoms_per_molecule; i++) {
       k += atom->avec->unpack_exchange(&model_atom_buf[k]);
       if (procflag[i]) {
@@ -1165,9 +1166,9 @@ void FixGCMC::get_model_molecule()
     x[i][2] -= com[2];
   }
 
-  int mintag = atom->tag[0];
+  tagint mintag = atom->tag[0];
   for (int i = 0; i < atom->nlocal; i++) mintag = MIN(mintag,atom->tag[i]);
-  int atom_offset = mintag - 1;
+  tagint atom_offset = mintag - 1;
   
   for (int i = 0; i < nlocal; i++) {
     atom->mask[i] = 1 | groupbit;
diff --git a/src/MISC/fix_deposit.cpp b/src/MISC/fix_deposit.cpp
index fa8dbf6c6963bff0362359da01029abb27bdc962..ea8fb37be9a4578ff80258fd93910e92d93e1d38 100644
--- a/src/MISC/fix_deposit.cpp
+++ b/src/MISC/fix_deposit.cpp
@@ -488,16 +488,18 @@ void FixDeposit::pre_exchange()
 
   if (success) {
     atom->natoms += natom;
+    if (atom->natoms < 0 || atom->natoms > MAXBIGINT)
+      error->all(FLERR,"Too many total atoms");
     if (mode == MOLECULE) {
       atom->nbonds += onemol->nbonds;
       atom->nangles += onemol->nangles;
       atom->ndihedrals += onemol->ndihedrals;
       atom->nimpropers += onemol->nimpropers;
     }
-    if (idnext) {
-      maxtag_all += natom;
-      if (mode == MOLECULE && atom->molecule_flag) maxmol_all++;
-    }
+    maxtag_all += natom;
+    if (maxtag_all >= MAXTAGINT)
+      error->all(FLERR,"New atom IDs exceed maximum allowed ID");
+    if (mode == MOLECULE && atom->molecule_flag) maxmol_all++;
     if (atom->map_style) {
       atom->nghost = 0;
       atom->map_init();
@@ -520,13 +522,13 @@ void FixDeposit::pre_exchange()
 
 void FixDeposit::find_maxid()
 {
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
 
-  int max = 0;
+  tagint max = 0;
   for (int i = 0; i < nlocal; i++) max = MAX(max,tag[i]);
-  MPI_Allreduce(&max,&maxtag_all,1,MPI_INT,MPI_MAX,world);
+  MPI_Allreduce(&max,&maxtag_all,1,MPI_LMP_TAGINT,MPI_MAX,world);
 
   if (mode == MOLECULE && molecule) {
     max = 0;
diff --git a/src/MISC/fix_deposit.h b/src/MISC/fix_deposit.h
index 7e9bea0f37715aade1a3e9301755b3aeed0c7b0a..56bf34c6ddaf0cedd1fc2ae84eea3c656932ea1c 100644
--- a/src/MISC/fix_deposit.h
+++ b/src/MISC/fix_deposit.h
@@ -55,7 +55,8 @@ class FixDeposit : public Fix {
   class Fix *fixrigid,*fixshake;
 
   int nfirst,ninserted;
-  int maxtag_all,maxmol_all;
+  tagint maxtag_all;
+  int maxmol_all;
   class RanPark *random;
 
   void find_maxid();
diff --git a/src/MISC/fix_evaporate.cpp b/src/MISC/fix_evaporate.cpp
index 5fe5c1412fa66b82f2b45acdfe6ea2ecd542ba2e..ab153f805e63c5ab7ba9fbfe2fac87d720df23d0 100644
--- a/src/MISC/fix_evaporate.cpp
+++ b/src/MISC/fix_evaporate.cpp
@@ -186,7 +186,7 @@ void FixEvaporate::pre_exchange()
 
   double **x = atom->x;
   int *mask = atom->mask;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
 
   int ncount = 0;
diff --git a/src/MISC/fix_orient_fcc.cpp b/src/MISC/fix_orient_fcc.cpp
index a7fc2eceaa9e6c234c221445b776c33852d5a542..722dc0485436674c8fba5be0674a6f7c7e027118 100644
--- a/src/MISC/fix_orient_fcc.cpp
+++ b/src/MISC/fix_orient_fcc.cpp
@@ -243,7 +243,8 @@ void FixOrientFCC::setup(int vflag)
 
 void FixOrientFCC::post_force(int vflag)
 {
-  int i,j,k,ii,jj,inum,jnum,m,n,nn,nsort,id_self;
+  int i,j,k,ii,jj,inum,jnum,m,n,nn,nsort;
+  tagint id_self;
   int *ilist,*jlist,*numneigh,**firstneigh;
   double edelta,omega;
   double dx,dy,dz,rsq,xismooth,xi_sq,duxi,duxi_other;
@@ -256,7 +257,7 @@ void FixOrientFCC::post_force(int vflag)
   double **x = atom->x;
   double **f = atom->f;
   int *mask = atom->mask;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
   int nall = atom->nlocal + atom->nghost;
 
@@ -480,8 +481,10 @@ double FixOrientFCC::compute_scalar()
 int FixOrientFCC::pack_comm(int n, int *list, double *buf,
                             int pbc_flag, int *pbc)
 {
-  int i,j,k,id,num;
-  int *tag = atom->tag;
+  int i,j,k,num;
+  tagint id;
+
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
   int m = 0;
 
@@ -531,7 +534,7 @@ void FixOrientFCC::unpack_comm(int n, int first, double *buf)
       nbr[i].dxi[j][0] = buf[m++];
       nbr[i].dxi[j][1] = buf[m++];
       nbr[i].dxi[j][2] = buf[m++];
-      nbr[i].id[j] = static_cast<int> (buf[m++]);
+      nbr[i].id[j] = static_cast<tagint> (buf[m++]);
     }
 
     m += (12-num) * 3;
diff --git a/src/MISC/fix_orient_fcc.h b/src/MISC/fix_orient_fcc.h
index 727be005396f4ea8daff8c4b45c1790b4ba6be58..399c34970eafc0927131c4f295cf6dd715eab9ae 100644
--- a/src/MISC/fix_orient_fcc.h
+++ b/src/MISC/fix_orient_fcc.h
@@ -28,7 +28,7 @@ class FixOrientFCC : public Fix {
  public:
   struct Nbr {              // neighbor info for each owned and ghost atom
     int n;                  // # of closest neighbors (up to 12)
-    int id[12];             // IDs of each neighbor
+    tagint id[12];          // IDs of each neighbor
                             // if center atom is owned, these are local IDs
                             // if center atom is ghost, these are global IDs
     double xismooth[12];    // distance weighting factor for each neighbors
@@ -37,7 +37,7 @@ class FixOrientFCC : public Fix {
   };
 
   struct Sort {             // data structure for sorting to find 12 closest
-    int id;                 // ID of neighbor atom
+    int id;                 // local ID of neighbor atom
     double rsq;             // distance between center and neighbor atom
     double delta[3];        // displacement between center and neighbor atom
     double xismooth;        // distance weighting factor
diff --git a/src/MOLECULE/atom_vec_angle.cpp b/src/MOLECULE/atom_vec_angle.cpp
index 224c25605a47aef078487e291c714e2bf5252ee7..9b303451c3bdd94fde16efe9cb16cbf50b109832 100644
--- a/src/MOLECULE/atom_vec_angle.cpp
+++ b/src/MOLECULE/atom_vec_angle.cpp
@@ -475,7 +475,7 @@ void AtomVecAngle::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     molecule[i] = (int) ubuf(buf[m++]).i;
@@ -500,7 +500,7 @@ void AtomVecAngle::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     molecule[i] = (int) ubuf(buf[m++]).i;
@@ -594,7 +594,7 @@ int AtomVecAngle::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -604,22 +604,22 @@ int AtomVecAngle::unpack_exchange(double *buf)
   num_bond[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    bond_atom[nlocal][k] = (int) ubuf(buf[m++]).i;
+    bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   num_angle[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_angle[nlocal]; k++) {
     angle_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom1[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom2[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom3[nlocal][k] = (int) ubuf(buf[m++]).i;
+    angle_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    angle_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    angle_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   nspecial[nlocal][0] = (int) ubuf(buf[m++]).i;
   nspecial[nlocal][1] = (int) ubuf(buf[m++]).i;
   nspecial[nlocal][2] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < nspecial[nlocal][2]; k++)
-    special[nlocal][k] = (int) ubuf(buf[m++]).i;
+    special[nlocal][k] = (tagint) ubuf(buf[m++]).i;
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
@@ -666,28 +666,28 @@ int AtomVecAngle::pack_restart(int i, double *buf)
   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];
-  *((imageint *) &buf[m++]) = image[i];
+  buf[m++] = ubuf(tag[i]).d;
+  buf[m++] = ubuf(type[i]).d;
+  buf[m++] = ubuf(mask[i]).d;
+  buf[m++] = ubuf(image[i]).d;
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
 
-  buf[m++] = molecule[i];
+  buf[m++] = ubuf(molecule[i]).d;
 
-  buf[m++] = num_bond[i];
+  buf[m++] = ubuf(num_bond[i]).d;
   for (k = 0; k < num_bond[i]; k++) {
-    buf[m++] = MAX(bond_type[i][k],-bond_type[i][k]);
-    buf[m++] = bond_atom[i][k];
+    buf[m++] = ubuf(MAX(bond_type[i][k],-bond_type[i][k])).d;
+    buf[m++] = ubuf(bond_atom[i][k]).d;
   }
 
-  buf[m++] = num_angle[i];
+  buf[m++] = ubuf(num_angle[i]).d;
   for (k = 0; k < num_angle[i]; k++) {
-    buf[m++] = MAX(angle_type[i][k],-angle_type[i][k]);
-    buf[m++] = angle_atom1[i][k];
-    buf[m++] = angle_atom2[i][k];
-    buf[m++] = angle_atom3[i][k];
+    buf[m++] = ubuf(MAX(angle_type[i][k],-angle_type[i][k])).d;
+    buf[m++] = ubuf(angle_atom1[i][k]).d;
+    buf[m++] = ubuf(angle_atom2[i][k]).d;
+    buf[m++] = ubuf(angle_atom3[i][k]).d;
   }
 
   if (atom->nextra_restart)
@@ -717,7 +717,7 @@ int AtomVecAngle::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -730,15 +730,15 @@ int AtomVecAngle::unpack_restart(double *buf)
   num_bond[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    bond_atom[nlocal][k] = (int) ubuf(buf[m++]).i;
+    bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   num_angle[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_angle[nlocal]; k++) {
     angle_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom1[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom2[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom3[nlocal][k] = (int) ubuf(buf[m++]).i;
+    angle_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    angle_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    angle_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0;
@@ -793,12 +793,8 @@ void AtomVecAngle::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   molecule[nlocal] = atoi(values[1]);
-
   type[nlocal] = atoi(values[2]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -871,8 +867,8 @@ int AtomVecAngle::pack_data_hybrid(int i, double *buf)
 void AtomVecAngle::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT " %d %d %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             (int) ubuf(buf[i][2]).i,
             buf[i][3],buf[i][4],buf[i][5],
             (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i,
diff --git a/src/MOLECULE/atom_vec_angle.h b/src/MOLECULE/atom_vec_angle.h
index b269fda174334fe9bc3491d18ffa7db11cbc1fb4..d33dbcd013681a2a127fee849d6a3051f89b6fc0 100644
--- a/src/MOLECULE/atom_vec_angle.h
+++ b/src/MOLECULE/atom_vec_angle.h
@@ -58,16 +58,19 @@ class AtomVecAngle : public AtomVec {
   bigint memory_usage();
 
  protected:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   int *molecule;
-  int **nspecial,**special;
+  int **nspecial;
+  tagint **special;
   int *num_bond;
-  int **bond_type,**bond_atom;
+  int **bond_type;
+  tagint **bond_atom;
   int *num_angle;
   int **angle_type;
-  int **angle_atom1,**angle_atom2,**angle_atom3;
+  tagint **angle_atom1,**angle_atom2,**angle_atom3;
 };
 
 }
diff --git a/src/MOLECULE/atom_vec_bond.cpp b/src/MOLECULE/atom_vec_bond.cpp
index c06d3eed299306ddd2015971bd8e494ac8f09ace..7e5e63991895a1a898d73972e61782cb99bc9434 100644
--- a/src/MOLECULE/atom_vec_bond.cpp
+++ b/src/MOLECULE/atom_vec_bond.cpp
@@ -454,7 +454,7 @@ void AtomVecBond::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     molecule[i] = (int) ubuf(buf[m++]).i;
@@ -479,7 +479,7 @@ void AtomVecBond::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     molecule[i] = (int) ubuf(buf[m++]).i;
@@ -565,7 +565,7 @@ int AtomVecBond::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -575,14 +575,14 @@ int AtomVecBond::unpack_exchange(double *buf)
   num_bond[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    bond_atom[nlocal][k] = (int) ubuf(buf[m++]).i;
+    bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   nspecial[nlocal][0] = (int) ubuf(buf[m++]).i;
   nspecial[nlocal][1] = (int) ubuf(buf[m++]).i;
   nspecial[nlocal][2] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < nspecial[nlocal][2]; k++)
-    special[nlocal][k] = (int) ubuf(buf[m++]).i;
+    special[nlocal][k] = (tagint) ubuf(buf[m++]).i;
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
@@ -672,7 +672,7 @@ int AtomVecBond::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -685,7 +685,7 @@ int AtomVecBond::unpack_restart(double *buf)
   num_bond[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    bond_atom[nlocal][k] = (int) ubuf(buf[m++]).i;
+    bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0;
@@ -739,12 +739,8 @@ void AtomVecBond::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   molecule[nlocal] = atoi(values[1]);
-
   type[nlocal] = atoi(values[2]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -815,8 +811,8 @@ int AtomVecBond::pack_data_hybrid(int i, double *buf)
 void AtomVecBond::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT " %d %d %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             (int) ubuf(buf[i][2]).i,
             buf[i][3],buf[i][4],buf[i][5],
             (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i,
diff --git a/src/MOLECULE/atom_vec_bond.h b/src/MOLECULE/atom_vec_bond.h
index 4e98d21e813cb2fb4b3a9de0620425023b24da7b..7e8b538d5eb7aece518bd2ff293de02bedd54408 100644
--- a/src/MOLECULE/atom_vec_bond.h
+++ b/src/MOLECULE/atom_vec_bond.h
@@ -57,13 +57,16 @@ class AtomVecBond : public AtomVec {
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   int *molecule;
-  int **nspecial,**special;
+  int **nspecial;
+  tagint **special;
   int *num_bond;
-  int **bond_type,**bond_atom;
+  int **bond_type;
+  tagint **bond_atom;
 };
 
 }
diff --git a/src/MOLECULE/atom_vec_full.cpp b/src/MOLECULE/atom_vec_full.cpp
index 6d44289d4e0a0a4c80dceea05e8881515dafd00b..09175dd0346a2d66018db849de628bf7ef8a0035 100644
--- a/src/MOLECULE/atom_vec_full.cpp
+++ b/src/MOLECULE/atom_vec_full.cpp
@@ -469,9 +469,9 @@ int AtomVecFull::pack_border_vel(int n, int *list, double *buf,
         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++] = ubuf(tag[j]).d;
+        buf[m++] = ubuf(type[j]).d;
+        buf[m++] = ubuf(mask[j]).d;
         buf[m++] = q[j];
         buf[m++] = molecule[j];
         buf[m++] = v[j][0];
@@ -540,7 +540,7 @@ void AtomVecFull::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     q[i] = buf[m++];
@@ -566,7 +566,7 @@ void AtomVecFull::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     q[i] = buf[m++];
@@ -682,7 +682,7 @@ int AtomVecFull::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -693,40 +693,40 @@ int AtomVecFull::unpack_exchange(double *buf)
   num_bond[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    bond_atom[nlocal][k] = (int) ubuf(buf[m++]).i;
+    bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   num_angle[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_angle[nlocal]; k++) {
     angle_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom1[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom2[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom3[nlocal][k] = (int) ubuf(buf[m++]).i;
+    angle_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    angle_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    angle_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   num_dihedral[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_dihedral[nlocal]; k++) {
     dihedral_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    dihedral_atom1[nlocal][k] = (int) ubuf(buf[m++]).i;
-    dihedral_atom2[nlocal][k] = (int) ubuf(buf[m++]).i;
-    dihedral_atom3[nlocal][k] = (int) ubuf(buf[m++]).i;
-    dihedral_atom4[nlocal][k] = (int) ubuf(buf[m++]).i;
+    dihedral_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    dihedral_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    dihedral_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    dihedral_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   num_improper[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_improper[nlocal]; k++) {
     improper_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    improper_atom1[nlocal][k] = (int) ubuf(buf[m++]).i;
-    improper_atom2[nlocal][k] = (int) ubuf(buf[m++]).i;
-    improper_atom3[nlocal][k] = (int) ubuf(buf[m++]).i;
-    improper_atom4[nlocal][k] = (int) ubuf(buf[m++]).i;
+    improper_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    improper_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    improper_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    improper_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   nspecial[nlocal][0] = (int) ubuf(buf[m++]).i;
   nspecial[nlocal][1] = (int) ubuf(buf[m++]).i;
   nspecial[nlocal][2] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < nspecial[nlocal][2]; k++)
-    special[nlocal][k] = (int) ubuf(buf[m++]).i;
+    special[nlocal][k] = (tagint) ubuf(buf[m++]).i;
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
@@ -844,7 +844,7 @@ int AtomVecFull::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -858,33 +858,33 @@ int AtomVecFull::unpack_restart(double *buf)
   num_bond[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    bond_atom[nlocal][k] = (int) ubuf(buf[m++]).i;
+    bond_atom[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   num_angle[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_angle[nlocal]; k++) {
     angle_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom1[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom2[nlocal][k] = (int) ubuf(buf[m++]).i;
-    angle_atom3[nlocal][k] = (int) ubuf(buf[m++]).i;
+    angle_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    angle_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    angle_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   num_dihedral[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_dihedral[nlocal]; k++) {
     dihedral_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    dihedral_atom1[nlocal][k] = (int) ubuf(buf[m++]).i;
-    dihedral_atom2[nlocal][k] = (int) ubuf(buf[m++]).i;
-    dihedral_atom3[nlocal][k] = (int) ubuf(buf[m++]).i;
-    dihedral_atom4[nlocal][k] = (int) ubuf(buf[m++]).i;
+    dihedral_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    dihedral_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    dihedral_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    dihedral_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   num_improper[nlocal] = (int) ubuf(buf[m++]).i;
   for (k = 0; k < num_improper[nlocal]; k++) {
     improper_type[nlocal][k] = (int) ubuf(buf[m++]).i;
-    improper_atom1[nlocal][k] = (int) ubuf(buf[m++]).i;
-    improper_atom2[nlocal][k] = (int) ubuf(buf[m++]).i;
-    improper_atom3[nlocal][k] = (int) ubuf(buf[m++]).i;
-    improper_atom4[nlocal][k] = (int) ubuf(buf[m++]).i;
+    improper_atom1[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    improper_atom2[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    improper_atom3[nlocal][k] = (tagint) ubuf(buf[m++]).i;
+    improper_atom4[nlocal][k] = (tagint) ubuf(buf[m++]).i;
   }
 
   nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0;
@@ -942,12 +942,8 @@ void AtomVecFull::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   molecule[nlocal] = atoi(values[1]);
-
   type[nlocal] = atoi(values[2]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -1029,8 +1025,9 @@ int AtomVecFull::pack_data_hybrid(int i, double *buf)
 void AtomVecFull::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT 
+            " %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             (int) ubuf(buf[i][2]).i,
             buf[i][3],buf[i][4],buf[i][5],buf[i][6],
             (int) ubuf(buf[i][7]).i,(int) ubuf(buf[i][8]).i,
diff --git a/src/MOLECULE/atom_vec_full.h b/src/MOLECULE/atom_vec_full.h
index c8987e289484c2ac78c9d39cf28c8e25cce10dc8..f42072322d1f41f9a04172dccc5693bc85ecaaa5 100644
--- a/src/MOLECULE/atom_vec_full.h
+++ b/src/MOLECULE/atom_vec_full.h
@@ -58,23 +58,26 @@ class AtomVecFull : public AtomVec {
   bigint memory_usage();
 
  protected:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   double *q;
   int *molecule;
-  int **nspecial,**special;
+  int **nspecial;
+  tagint **special;
   int *num_bond;
-  int **bond_type,**bond_atom;
+  int **bond_type;
+  tagint **bond_atom;
   int *num_angle;
   int **angle_type;
-  int **angle_atom1,**angle_atom2,**angle_atom3;
+  tagint **angle_atom1,**angle_atom2,**angle_atom3;
   int *num_dihedral;
   int **dihedral_type;
-  int **dihedral_atom1,**dihedral_atom2,**dihedral_atom3,**dihedral_atom4;
+  tagint **dihedral_atom1,**dihedral_atom2,**dihedral_atom3,**dihedral_atom4;
   int *num_improper;
   int **improper_type;
-  int **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4;
+  tagint **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4;
 };
 
 }
diff --git a/src/MOLECULE/atom_vec_molecular.cpp b/src/MOLECULE/atom_vec_molecular.cpp
index 9feb31e1c299dab2c71e5a2d7cc8d44a409c1189..2f2265b5df43cae19d40284281b85014ea016137 100644
--- a/src/MOLECULE/atom_vec_molecular.cpp
+++ b/src/MOLECULE/atom_vec_molecular.cpp
@@ -532,7 +532,7 @@ void AtomVecMolecular::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     molecule[i] = (int) ubuf(buf[m++]).i;
@@ -557,7 +557,7 @@ void AtomVecMolecular::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     molecule[i] = (int) ubuf(buf[m++]).i;
@@ -669,7 +669,7 @@ int AtomVecMolecular::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -829,7 +829,7 @@ int AtomVecMolecular::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -920,17 +920,14 @@ void AtomVecMolecular::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecMolecular::data_atom(double *coord, imageint imagetmp, char **values)
+void AtomVecMolecular::data_atom(double *coord, imageint imagetmp, 
+                                 char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   molecule[nlocal] = atoi(values[1]);
-
   type[nlocal] = atoi(values[2]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -1007,8 +1004,8 @@ int AtomVecMolecular::pack_data_hybrid(int i, double *buf)
 void AtomVecMolecular::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT " %d %d %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             (int) ubuf(buf[i][2]).i,
             buf[i][3],buf[i][4],buf[i][5],
             (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i,
diff --git a/src/MOLECULE/atom_vec_molecular.h b/src/MOLECULE/atom_vec_molecular.h
index dcd87721d56fd13fc29fbd405688c944d99ff492..58aa039e1e3c2f2883b9d0fc8f966d1520ea3e26 100644
--- a/src/MOLECULE/atom_vec_molecular.h
+++ b/src/MOLECULE/atom_vec_molecular.h
@@ -57,22 +57,25 @@ class AtomVecMolecular : public AtomVec {
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   int *molecule;
-  int **nspecial,**special;
+  int **nspecial;
+  tagint **special;
   int *num_bond;
-  int **bond_type,**bond_atom;
+  int **bond_type;
+  tagint **bond_atom;
   int *num_angle;
   int **angle_type;
-  int **angle_atom1,**angle_atom2,**angle_atom3;
+  tagint **angle_atom1,**angle_atom2,**angle_atom3;
   int *num_dihedral;
   int **dihedral_type;
-  int **dihedral_atom1,**dihedral_atom2,**dihedral_atom3,**dihedral_atom4;
+  tagint **dihedral_atom1,**dihedral_atom2,**dihedral_atom3,**dihedral_atom4;
   int *num_improper;
   int **improper_type;
-  int **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4;
+  tagint **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4;
 };
 
 }
diff --git a/src/MOLECULE/bond_fene.cpp b/src/MOLECULE/bond_fene.cpp
index 8eca809d1b674939b4035520cc1f3d4e0c367e24..fb69de6e5682dd986c6f79d630b4086e1bbb3e85 100644
--- a/src/MOLECULE/bond_fene.cpp
+++ b/src/MOLECULE/bond_fene.cpp
@@ -85,7 +85,8 @@ void BondFENE::compute(int eflag, int vflag)
 
     if (rlogarg < 0.1) {
       char str[128];
-      sprintf(str,"FENE bond too long: " BIGINT_FORMAT " %d %d %g",
+      sprintf(str,"FENE bond too long: " BIGINT_FORMAT " " 
+              TAGINT_FORMAT " " TAGINT_FORMAT " %g",
               update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
       error->warning(FLERR,str,0);
       if (rlogarg <= -3.0) error->one(FLERR,"Bad FENE bond");
diff --git a/src/MOLECULE/bond_fene_expand.cpp b/src/MOLECULE/bond_fene_expand.cpp
index 214e632795cf9d1724875a1dd4003786f7b22f2b..439b09a5a76ab140d728cbaafc22830b1eb52dc9 100644
--- a/src/MOLECULE/bond_fene_expand.cpp
+++ b/src/MOLECULE/bond_fene_expand.cpp
@@ -90,7 +90,8 @@ void BondFENEExpand::compute(int eflag, int vflag)
 
     if (rlogarg < 0.1) {
       char str[128];
-      sprintf(str,"FENE bond too long: " BIGINT_FORMAT " %d %d %g",
+      sprintf(str,"FENE bond too long: " BIGINT_FORMAT " " 
+              TAGINT_FORMAT " " TAGINT_FORMAT " %g",
               update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
       error->warning(FLERR,str,0);
       if (rlogarg <= -3.0) error->one(FLERR,"Bad FENE bond");
diff --git a/src/MOLECULE/dihedral_charmm.cpp b/src/MOLECULE/dihedral_charmm.cpp
index 8029e7b4fac09c9486faa9cc192c8bc6daecd07c..671514fc5d4f8c1f4dc0a3cd0ba899e64b858293 100644
--- a/src/MOLECULE/dihedral_charmm.cpp
+++ b/src/MOLECULE/dihedral_charmm.cpp
@@ -150,7 +150,9 @@ void DihedralCharmm::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/MOLECULE/dihedral_harmonic.cpp b/src/MOLECULE/dihedral_harmonic.cpp
index a7f353269b51a53cd09bcbb4aa4a77958c0d808e..0c0ff327ba456f9728ef96a9ecbb48d66ee4090d 100644
--- a/src/MOLECULE/dihedral_harmonic.cpp
+++ b/src/MOLECULE/dihedral_harmonic.cpp
@@ -137,7 +137,9 @@ void DihedralHarmonic::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/MOLECULE/dihedral_helix.cpp b/src/MOLECULE/dihedral_helix.cpp
index fd5d72e84508c13e35eb7e97f41e6cde1d295e50..744f3b4915e9e38aa91898ad05c94538ee070b12 100644
--- a/src/MOLECULE/dihedral_helix.cpp
+++ b/src/MOLECULE/dihedral_helix.cpp
@@ -165,7 +165,9 @@ void DihedralHelix::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/MOLECULE/dihedral_multi_harmonic.cpp b/src/MOLECULE/dihedral_multi_harmonic.cpp
index 2e3b4e79dcf845a47c129a6b4599ecd02c85d83a..48f4f2b45fcb32785ccf279b8933d36c7f98c957 100644
--- a/src/MOLECULE/dihedral_multi_harmonic.cpp
+++ b/src/MOLECULE/dihedral_multi_harmonic.cpp
@@ -155,7 +155,9 @@ void DihedralMultiHarmonic::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/MOLECULE/dihedral_opls.cpp b/src/MOLECULE/dihedral_opls.cpp
index 074c8bf15c1efe1feb0f13eb9a35d977cab8e4ac..f73b85f9b421964826baee2ad6795f278509b29d 100644
--- a/src/MOLECULE/dihedral_opls.cpp
+++ b/src/MOLECULE/dihedral_opls.cpp
@@ -164,7 +164,9 @@ void DihedralOPLS::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/MOLECULE/improper_cvff.cpp b/src/MOLECULE/improper_cvff.cpp
index 06485e918962c5f00e6219967dfe624e6529f621..3d33b3b9f7a1eb94767ffccd1a97b00f0ca54894 100644
--- a/src/MOLECULE/improper_cvff.cpp
+++ b/src/MOLECULE/improper_cvff.cpp
@@ -151,8 +151,9 @@ void ImproperCvff::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,
-                "Improper problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Improper problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/MOLECULE/improper_harmonic.cpp b/src/MOLECULE/improper_harmonic.cpp
index 4db32456b351bacac10aad744eb446af0311c321..19f845452a64f65cd23749507241639235a3eb12 100644
--- a/src/MOLECULE/improper_harmonic.cpp
+++ b/src/MOLECULE/improper_harmonic.cpp
@@ -125,8 +125,9 @@ void ImproperHarmonic::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,
-                "Improper problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Improper problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/MOLECULE/improper_umbrella.cpp b/src/MOLECULE/improper_umbrella.cpp
index ef8c1a13524b883e196472a5d88967b97f213ade..a3b7295b3d4eb4700979d86cfc9fb599844881e8 100644
--- a/src/MOLECULE/improper_umbrella.cpp
+++ b/src/MOLECULE/improper_umbrella.cpp
@@ -128,8 +128,9 @@ void ImproperUmbrella::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,
-                "Improper problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Improper problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/MOLECULE/pair_hbond_dreiding_lj.cpp b/src/MOLECULE/pair_hbond_dreiding_lj.cpp
index 381629e161960f9f53cc12d01db7f7074b40aa7e..a25e116e961f618390430ffa201759e2ddfab9dd 100644
--- a/src/MOLECULE/pair_hbond_dreiding_lj.cpp
+++ b/src/MOLECULE/pair_hbond_dreiding_lj.cpp
@@ -84,7 +84,8 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag)
   double fi[3],fj[3],delr1[3],delr2[3];
   double r2inv,r10inv;
   double switch1,switch2;
-  int *ilist,*jlist,*klist,*numneigh,**firstneigh;
+  int *ilist,*jlist,*numneigh,**firstneigh;
+  tagint *klist;
 
   evdwl = ehbond = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
@@ -92,7 +93,7 @@ void PairHbondDreidingLJ::compute(int eflag, int vflag)
 
   double **x = atom->x;
   double **f = atom->f;
-  int **special = atom->special;
+  tagint **special = atom->special;
   int *type = atom->type;
   int **nspecial = atom->nspecial;
   double *special_lj = force->special_lj;
@@ -457,10 +458,10 @@ double PairHbondDreidingLJ::single(int i, int j, int itype, int jtype,
   double rsq1,rsq2,r1,r2,c,s,ac,r2inv,r10inv,factor_hb;
   double switch1,switch2;
   double delr1[3],delr2[3];
-  int *klist;
+  tagint *klist;
 
   double **x = atom->x;
-  int **special = atom->special;
+  tagint **special = atom->special;
   int *type = atom->type;
   int **nspecial = atom->nspecial;
   double *special_lj = force->special_lj;
diff --git a/src/MOLECULE/pair_hbond_dreiding_morse.cpp b/src/MOLECULE/pair_hbond_dreiding_morse.cpp
index e3c26a5dc24f0df5892d4b4e0b4f2cba679aa9dc..975bc94331b3a1c9677312c2d9130f19e4c037b5 100644
--- a/src/MOLECULE/pair_hbond_dreiding_morse.cpp
+++ b/src/MOLECULE/pair_hbond_dreiding_morse.cpp
@@ -54,7 +54,8 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag)
   double c,s,a,b,d,ac,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2;
   double fi[3],fj[3],delr1[3],delr2[3];
   double r,dr,dexp,eng_morse,switch1,switch2;
-  int *ilist,*jlist,*klist,*numneigh,**firstneigh;
+  int *ilist,*jlist,*numneigh,**firstneigh;
+  tagint *klist;
 
   evdwl = ehbond = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
@@ -62,7 +63,7 @@ void PairHbondDreidingMorse::compute(int eflag, int vflag)
 
   double **x = atom->x;
   double **f = atom->f;
-  int **special = atom->special;
+  tagint **special = atom->special;
   int *type = atom->type;
   int **nspecial = atom->nspecial;
   double *special_lj = force->special_lj;
@@ -360,10 +361,10 @@ double PairHbondDreidingMorse::single(int i, int j, int itype, int jtype,
   double rsq1,rsq2,r1,r2,c,s,ac,r,dr,dexp,factor_hb;
   double switch1,switch2;
   double delr1[3],delr2[3];
-  int *klist;
+  tagint *klist;
 
   double **x = atom->x;
-  int **special = atom->special;
+  tagint **special = atom->special;
   int *type = atom->type;
   int **nspecial = atom->nspecial;
   double *special_lj = force->special_lj;
diff --git a/src/MOLECULE/pair_lj_cut_tip4p_cut.cpp b/src/MOLECULE/pair_lj_cut_tip4p_cut.cpp
index 04b37635b60cf2ebfc3b56cd0074d6068099e1d9..39f8a3c1f9e366ad6e591984939d058f79433913 100644
--- a/src/MOLECULE/pair_lj_cut_tip4p_cut.cpp
+++ b/src/MOLECULE/pair_lj_cut_tip4p_cut.cpp
@@ -114,6 +114,7 @@ void PairLJCutTIP4PCut::compute(int eflag, int vflag)
   double **f = atom->f;
   double **x = atom->x;
   double *q = atom->q;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   double *special_lj = force->special_lj;
   double *special_coul = force->special_coul;
@@ -137,8 +138,8 @@ void PairLJCutTIP4PCut::compute(int eflag, int vflag)
 
     if (itype == typeO) {
       if (hneigh[i][0] < 0) {
-        hneigh[i][0] = iH1 = atom->map(atom->tag[i] + 1);
-        hneigh[i][1] = iH2 = atom->map(atom->tag[i] + 2);
+        hneigh[i][0] = iH1 = atom->map(tag[i] + 1);
+        hneigh[i][1] = iH2 = atom->map(tag[i] + 2);
         hneigh[i][2] = 1;
         if (iH1 == -1 || iH2 == -1)
           error->one(FLERR,"TIP4P hydrogen is missing");
@@ -207,8 +208,8 @@ void PairLJCutTIP4PCut::compute(int eflag, int vflag)
 
           if (jtype == typeO) {
             if (hneigh[j][0] < 0) {
-              hneigh[j][0] = jH1 = atom->map(atom->tag[j] + 1);
-              hneigh[j][1] = jH2 = atom->map(atom->tag[j] + 2);
+              hneigh[j][0] = jH1 = atom->map(tag[j] + 1);
+              hneigh[j][1] = jH2 = atom->map(tag[j] + 2);
               hneigh[j][2] = 1;
               if (jH1 == -1 || jH2 == -1)
                 error->one(FLERR,"TIP4P hydrogen is missing");
diff --git a/src/MOLECULE/pair_tip4p_cut.cpp b/src/MOLECULE/pair_tip4p_cut.cpp
index d1ce9b25692a1134ce7a49daa817ee9b96c597aa..57bb72da8b6b25faddc6eb5acd1a36a4a32010f0 100644
--- a/src/MOLECULE/pair_tip4p_cut.cpp
+++ b/src/MOLECULE/pair_tip4p_cut.cpp
@@ -103,6 +103,7 @@ void PairTIP4PCut::compute(int eflag, int vflag)
   double **f = atom->f;
   double **x = atom->x;
   double *q = atom->q;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   double *special_coul = force->special_coul;
   int newton_pair = force->newton_pair;
@@ -125,8 +126,8 @@ void PairTIP4PCut::compute(int eflag, int vflag)
 
     if (itype == typeO) {
       if (hneigh[i][0] < 0) {
-        hneigh[i][0] = iH1 = atom->map(atom->tag[i] + 1);
-        hneigh[i][1] = iH2 = atom->map(atom->tag[i] + 2);
+        hneigh[i][0] = iH1 = atom->map(tag[i] + 1);
+        hneigh[i][1] = iH2 = atom->map(tag[i] + 2);
         hneigh[i][2] = 1;
         if (iH1 == -1 || iH2 == -1)
           error->one(FLERR,"TIP4P hydrogen is missing");
@@ -169,8 +170,8 @@ void PairTIP4PCut::compute(int eflag, int vflag)
 
           if (jtype == typeO) {
             if (hneigh[j][0] < 0) {
-              hneigh[j][0] = jH1 = atom->map(atom->tag[j] + 1);
-              hneigh[j][1] = jH2 = atom->map(atom->tag[j] + 2);
+              hneigh[j][0] = jH1 = atom->map(tag[j] + 1);
+              hneigh[j][1] = jH2 = atom->map(tag[j] + 2);
               hneigh[j][2] = 1;
               if (jH1 == -1 || jH2 == -1)
                 error->one(FLERR,"TIP4P hydrogen is missing");
diff --git a/src/OPT/pair_lj_cut_tip4p_long_opt.cpp b/src/OPT/pair_lj_cut_tip4p_long_opt.cpp
index 30ef31879940982ab0fa2d764b049d97e30edb01..e045eeec75a6f321839679d96e50358e7697950c 100644
--- a/src/OPT/pair_lj_cut_tip4p_long_opt.cpp
+++ b/src/OPT/pair_lj_cut_tip4p_long_opt.cpp
@@ -125,6 +125,7 @@ void PairLJCutTIP4PLongOpt::eval()
   const double * const * const x = atom->x;
   double * const * const f = atom->f;
   const double * const q = atom->q;
+  const tagint * const tag = atom->tag;
   const int * const type = atom->type;
   const int nlocal = atom->nlocal;
   const double * const special_coul = force->special_coul;
@@ -154,8 +155,8 @@ void PairLJCutTIP4PLongOpt::eval()
 
     if (itype == typeO) {
       if (hneigh[i][0] < 0) {
-        hneigh[i][0] = iH1 = atom->map(atom->tag[i] + 1);
-        hneigh[i][1] = iH2 = atom->map(atom->tag[i] + 2);
+        hneigh[i][0] = iH1 = atom->map(tag[i] + 1);
+        hneigh[i][1] = iH2 = atom->map(tag[i] + 2);
         hneigh[i][2] = 1;
         if (iH1 == -1 || iH2 == -1)
           error->one(FLERR,"TIP4P hydrogen is missing");
@@ -225,8 +226,8 @@ void PairLJCutTIP4PLongOpt::eval()
 
           if (jtype == typeO) {
             if (hneigh[j][0] < 0) {
-              hneigh[j][0] = jH1 = atom->map(atom->tag[j] + 1);
-              hneigh[j][1] = jH2 = atom->map(atom->tag[j] + 2);
+              hneigh[j][0] = jH1 = atom->map(tag[j] + 1);
+              hneigh[j][1] = jH2 = atom->map(tag[j] + 2);
               hneigh[j][2] = 1;
               if (jH1 == -1 || jH2 == -1)
                 error->one(FLERR,"TIP4P hydrogen is missing");
diff --git a/src/PERI/atom_vec_peri.cpp b/src/PERI/atom_vec_peri.cpp
index 28e7ff1db997451a0688b4f7cef8e986d355a7c1..c2791ce01fb674dc4ab9083526f94f3848e034bd 100644
--- a/src/PERI/atom_vec_peri.cpp
+++ b/src/PERI/atom_vec_peri.cpp
@@ -517,7 +517,7 @@ void AtomVecPeri::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     vfrac[i] = buf[m++];
@@ -546,7 +546,7 @@ void AtomVecPeri::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     vfrac[i] = buf[m++];
@@ -631,7 +631,7 @@ int AtomVecPeri::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -725,7 +725,7 @@ int AtomVecPeri::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -792,10 +792,7 @@ void AtomVecPeri::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -881,8 +878,9 @@ int AtomVecPeri::pack_data_hybrid(int i, double *buf)
 void AtomVecPeri::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT 
+            " %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             buf[i][2],buf[i][3],buf[i][4],buf[i][5],buf[i][6],
             (int) ubuf(buf[i][7]).i,(int) ubuf(buf[i][8]).i,
             (int) ubuf(buf[i][9]).i);
diff --git a/src/PERI/atom_vec_peri.h b/src/PERI/atom_vec_peri.h
index 253c054e7340ff439b5e7f1fe6de713fbc771213..57dfe41807b1193f72078d15fd4d7db83abbb54c 100755
--- a/src/PERI/atom_vec_peri.h
+++ b/src/PERI/atom_vec_peri.h
@@ -59,7 +59,8 @@ class AtomVecPeri : public AtomVec {
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   double *vfrac,*density,*rmass,*s0,**x0;
diff --git a/src/PERI/compute_damage_atom.cpp b/src/PERI/compute_damage_atom.cpp
index bd8228faf516c07c4e54e3a46c12554284bb732a..9b51cd34b3533a016ca3c43f01b10a64842a3b7a 100644
--- a/src/PERI/compute_damage_atom.cpp
+++ b/src/PERI/compute_damage_atom.cpp
@@ -90,7 +90,7 @@ void ComputeDamageAtom::compute_peratom()
   int *mask = atom->mask;
   double *vfrac = atom->vfrac;
   double *vinter = ((FixPeriNeigh *) modify->fix[ifix_peri])->vinter;
-  int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
+  tagint **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
   int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
   int i,j,jj,jnum;
 
diff --git a/src/PERI/fix_peri_neigh.cpp b/src/PERI/fix_peri_neigh.cpp
index a7ef294140613f3aa7483feee98722d1a934d2d6..cd6e3d5c812da86464d063e3b4b6c653a44fb7c9 100644
--- a/src/PERI/fix_peri_neigh.cpp
+++ b/src/PERI/fix_peri_neigh.cpp
@@ -152,7 +152,7 @@ void FixPeriNeigh::setup(int vflag)
   double **x = atom->x;
   double *vfrac = atom->vfrac;
   int *type = atom->type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
 
  // only build list of bonds on very first run
@@ -450,7 +450,7 @@ int FixPeriNeigh::unpack_exchange(int nlocal, double *buf)
   int m = 0;
   npartner[nlocal] = static_cast<int> (buf[m++]);
   for (int n = 0; n < npartner[nlocal]; n++) {
-    partner[nlocal][n] = static_cast<int> (buf[m++]);
+    partner[nlocal][n] = static_cast<tagint> (buf[m++]);
     if (isVES) {   
       deviatorextention[nlocal][n] = buf[m++];
       deviatorBackextention[nlocal][n] = buf[m++];
@@ -565,7 +565,7 @@ void FixPeriNeigh::unpack_restart(int nlocal, int nth)
 
   npartner[nlocal] = static_cast<int> (extra[nlocal][m++]);
   for (int n = 0; n < npartner[nlocal]; n++) {
-    partner[nlocal][n] = static_cast<int> (extra[nlocal][m++]);
+    partner[nlocal][n] = static_cast<tagint> (extra[nlocal][m++]);
     if (isVES) { 
       deviatorextention[nlocal][n] = extra[nlocal][m++];
       deviatorBackextention[nlocal][n] = extra[nlocal][m++];
diff --git a/src/PERI/fix_peri_neigh.h b/src/PERI/fix_peri_neigh.h
index 0640bbccdef87939218afe0ff3be765b33b8d7e8..bfa815be6b0bbbf24a5fd315009487029e39b635 100644
--- a/src/PERI/fix_peri_neigh.h
+++ b/src/PERI/fix_peri_neigh.h
@@ -60,7 +60,7 @@ class FixPeriNeigh : public Fix {
   int first;                 // flag for first time initialization
   int maxpartner;            // max # of peridynamic neighs for any atom
   int *npartner;             // # of neighbors for each atom
-  int **partner;             // neighs for each atom, stored as global IDs
+  tagint **partner;          // neighs for each atom, stored as global IDs
   double **deviatorextention; // Deviatoric extention     
   double **deviatorBackextention; // Deviatoric back extention 
   double **r0;               // initial distance to partners
diff --git a/src/PERI/pair_peri_lps.cpp b/src/PERI/pair_peri_lps.cpp
index a140c77e5cda25d4f67f25f3d14ff19fe40dbb34..639ac6fb43d6edbe72659f2ef8a033b1797f269d 100644
--- a/src/PERI/pair_peri_lps.cpp
+++ b/src/PERI/pair_peri_lps.cpp
@@ -104,7 +104,7 @@ void PairPeriLPS::compute(int eflag, int vflag)
   double *s0 = atom->s0;
   double **x0 = atom->x0;
   double **r0   = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
-  int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
+  tagint **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
   int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
   double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume;
 
@@ -550,7 +550,7 @@ void PairPeriLPS::compute_dilatation()
   double half_lc = 0.5*lc;
 
   double **r0   = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
-  int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
+  tagint **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
   int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
   double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume;
 
diff --git a/src/PERI/pair_peri_pmb.cpp b/src/PERI/pair_peri_pmb.cpp
index 439f4b5d09653e2b518e68097dbecab1cc48aa0e..77ca26d1e3e0ad83510e4c569b8d9345b690ff32 100644
--- a/src/PERI/pair_peri_pmb.cpp
+++ b/src/PERI/pair_peri_pmb.cpp
@@ -96,7 +96,7 @@ void PairPeriPMB::compute(int eflag, int vflag)
   double *s0 = atom->s0;
   double **x0 = atom->x0;
   double **r0   = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
-  int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
+  tagint **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
   int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
 
   // lc = lattice constant
@@ -450,7 +450,7 @@ double PairPeriPMB::single(int i, int j, int itype, int jtype, double rsq,
   double *vfrac = atom->vfrac;
   double **x0 = atom->x0;
   double **r0   = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
-  int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
+  tagint **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
   int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
 
   double lc = domain->lattice->xlattice;
diff --git a/src/PERI/pair_peri_ves.cpp b/src/PERI/pair_peri_ves.cpp
index 5586abc965110869fa2510173bcf7aaab52434dd..ec7852feb539a452c08a5ade2c98cd2b751772ea 100644
--- a/src/PERI/pair_peri_ves.cpp
+++ b/src/PERI/pair_peri_ves.cpp
@@ -115,7 +115,7 @@ void PairPeriVES::compute(int eflag, int vflag)
     ((FixPeriNeigh *) modify->fix[ifix_peri])->deviatorextention;
   double **deviatorBackextention = 
     ((FixPeriNeigh *) modify->fix[ifix_peri])->deviatorBackextention;
-  int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
+  tagint **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
   int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
   double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume;
 
@@ -621,7 +621,7 @@ void PairPeriVES::compute_dilatation()
   double half_lc = 0.5*lc;
 
   double **r0   = ((FixPeriNeigh *) modify->fix[ifix_peri])->r0;
-  int **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
+  tagint **partner = ((FixPeriNeigh *) modify->fix[ifix_peri])->partner;
   int *npartner = ((FixPeriNeigh *) modify->fix[ifix_peri])->npartner;
   double *wvolume = ((FixPeriNeigh *) modify->fix[ifix_peri])->wvolume;
 
diff --git a/src/REPLICA/neb.cpp b/src/REPLICA/neb.cpp
index d374c89e9792e2b057ef6769db00b807bb2cd38b..7754bd7a100267ba87b775d3831cc14449c01c64 100644
--- a/src/REPLICA/neb.cpp
+++ b/src/REPLICA/neb.cpp
@@ -335,8 +335,8 @@ void NEB::run()
 
 void NEB::readfile(char *file, int flag)
 {
-  int i,j,m,nchunk,tag,eofflag;
-  int nlines;
+  int i,j,m,nchunk,eofflag,nlines;
+  tagint tag;
   char *eof,*start,*next,*buf;
   char line[MAXLINE];
   double xx,yy,zz,delx,dely,delz;
@@ -430,7 +430,7 @@ void NEB::readfile(char *file, int flag)
       //     will be remapped back into box when simulation starts
       //     its image flags will then be adjusted
 
-      tag = atoi(values[0]);
+      tag = ATOTAGINT(values[0]);
       m = atom->map(tag);
       if (m >= 0 && m < nlocal) {
         ncount++;
diff --git a/src/REPLICA/prd.cpp b/src/REPLICA/prd.cpp
index 3e70e7a3b8b70121ee0aff88aa78be91c254e2ad..145435e1a124fe2ac38d30b8a9e1ca7b1ab25d5b 100644
--- a/src/REPLICA/prd.cpp
+++ b/src/REPLICA/prd.cpp
@@ -737,8 +737,8 @@ void PRD::replicate(int ireplica)
       displacements[0] = 0;
       for (i = 0; i < nprocs-1; i++)
         displacements[i+1] = displacements[i] + counts[i];
-      MPI_Gatherv(atom->tag,atom->nlocal,MPI_INT,
-                  tagall,counts,displacements,MPI_INT,0,world);
+      MPI_Gatherv(atom->tag,atom->nlocal,MPI_LMP_TAGINT,
+                  tagall,counts,displacements,MPI_LMP_TAGINT,0,world);
       MPI_Gatherv(atom->image,atom->nlocal,MPI_INT,
                         imageall,counts,displacements,MPI_INT,0,world);
       for (i = 0; i < nprocs; i++) counts[i] *= 3;
diff --git a/src/REPLICA/prd.h b/src/REPLICA/prd.h
index dabaffafa8fe8a1ff2c5bdd0425fae344d3ee0a4..07af513d9123ab26accefd547cffc2dc1c6d2be8 100644
--- a/src/REPLICA/prd.h
+++ b/src/REPLICA/prd.h
@@ -46,7 +46,8 @@ class PRD : protected Pointers {
   double time_start;
 
   MPI_Comm comm_replica;
-  int *tagall,*displacements,*imageall;
+  tagint *tagall;
+  int *displacements,*imageall;
   double **xall;
 
   int ncoincident;
diff --git a/src/REPLICA/verlet_split.cpp b/src/REPLICA/verlet_split.cpp
index b9eadde447bbfedbe4d75505a308cc7a7acaed26..1ede274a76afa285f671cf5b9b58fd6837865869 100644
--- a/src/REPLICA/verlet_split.cpp
+++ b/src/REPLICA/verlet_split.cpp
@@ -471,7 +471,8 @@ void VerletSplit::rk_setup()
   if (tip4p_flag) {
     //r2k_comm();
     MPI_Gatherv(atom->type,n,MPI_INT,atom->type,qsize,qdisp,MPI_INT,0,block);
-    MPI_Gatherv(atom->tag,n,MPI_INT,atom->tag,qsize,qdisp,MPI_INT,0,block);
+    MPI_Gatherv(atom->tag,n,MPI_LMP_TAGINT,
+                atom->tag,qsize,qdisp,MPI_LMP_TAGINT,0,block);
     if (!master) {
       if (triclinic) domain->x2lamda(atom->nlocal);
       if (domain->box_change) comm->setup();
diff --git a/src/RIGID/fix_rigid_small.cpp b/src/RIGID/fix_rigid_small.cpp
index 33fff6a7beb004004d15703478f96520507c2635..46809d1b344c4f0c32daaae3064dec81b1122db6 100644
--- a/src/RIGID/fix_rigid_small.cpp
+++ b/src/RIGID/fix_rigid_small.cpp
@@ -182,7 +182,7 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) :
 
   // set nlocal_body and allocate bodies I own
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   nlocal_body = nghost_body = 0;
   for (i = 0; i < nlocal; i++)
@@ -1350,14 +1350,14 @@ void FixRigidSmall::create_bodies()
 
   // pack my atoms into buffer as molecule ID, atom ID, unwrapped coords
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   m = 0;
   for (i = 0; i < nlocal; i++) {
     if (!(mask[i] & groupbit)) continue;
     domain->unmap(x[i],image[i],unwrap);
     buf[m++] = molecule[i];
-    buf[m++] = tag[i];
+    buf[m++] = ubuf(tag[i]).d;
     buf[m++] = unwrap[0];
     buf[m++] = unwrap[1];
     buf[m++] = unwrap[2];
@@ -1388,7 +1388,7 @@ void FixRigidSmall::create_bodies()
   for (i = 0; i < nlocal; i++) {
     if (!(mask[i] & groupbit)) continue;
     domain->unmap(x[i],image[i],unwrap);
-    buf[m++] = bodytag[i];
+    buf[m++] = ubuf(bodytag[i]).i;
     buf[m++] = unwrap[0];
     buf[m++] = unwrap[1];
     buf[m++] = unwrap[2];
@@ -1460,13 +1460,14 @@ void FixRigidSmall::ring_nearest(int n, char *cbuf)
 {
   std::map<int,int> *hash = frsptr->hash;
   double **ctr = frsptr->ctr;
-  int *idclose = frsptr->idclose;
+  tagint *idclose = frsptr->idclose;
   double *rsqclose = frsptr->rsqclose;
 
   double *buf = (double *) cbuf;
   int ndatums = n/5;
 
-  int j,imol,tag;
+  int j,imol;
+  tagint tag;
   double delx,dely,delz,rsq;
   double *x;
 
@@ -1475,7 +1476,7 @@ void FixRigidSmall::ring_nearest(int n, char *cbuf)
     imol = static_cast<int> (buf[m]);
     if (hash->find(imol) != hash->end()) {
       j = hash->find(imol)->second;
-      tag = static_cast<int> (buf[m+1]);
+      tag = (tagint) ubuf(buf[m+1]).i;
       x = &buf[m+2];
       delx = x[0] - ctr[j][0];
       dely = x[1] - ctr[j][1];
@@ -1504,15 +1505,16 @@ void FixRigidSmall::ring_farthest(int n, char *cbuf)
   double *buf = (double *) cbuf;
   int ndatums = n/4;
 
-  int itag,iowner;
+  int iowner;
+  tagint tag;
   double delx,dely,delz,rsq;
   double *xx;
   double unwrap[3];
 
   int m = 0;
   for (int i = 0; i < ndatums; i++, m += 4) {
-    itag = static_cast<int> (buf[m]);
-    iowner = frsptr->atom->map(itag);
+    tag = (tagint) ubuf(buf[m]).i;
+    iowner = frsptr->atom->map(tag);
     if (iowner < 0 || iowner >= nlocal) continue;
     frsptr->domain->unmap(x[iowner],image[iowner],unwrap);
     xx = &buf[m+1];
@@ -2439,7 +2441,7 @@ void FixRigidSmall::set_arrays(int i)
           relative to template in Molecule class
 ------------------------------------------------------------------------- */
 
-void FixRigidSmall::set_molecule(int nlocalprev, int tagprev, 
+void FixRigidSmall::set_molecule(int nlocalprev, tagint tagprev, 
                                  double *xgeom, double *vcm, double *quat)
 {
   int m;
@@ -2450,7 +2452,7 @@ void FixRigidSmall::set_molecule(int nlocalprev, int tagprev,
   if (nlocalprev == nlocal) return;
 
   double **x = atom->x;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   for (int i = nlocalprev; i < nlocal; i++) {
     bodytag[i] = tagprev + onemol->comatom;
@@ -2510,7 +2512,7 @@ void FixRigidSmall::set_molecule(int nlocalprev, int tagprev,
 
 int FixRigidSmall::pack_exchange(int i, double *buf)
 {
-  buf[0] = bodytag[i];
+  buf[0] = ubuf(bodytag[i]).d;
   buf[1] = displace[i][0];
   buf[2] = displace[i][1];
   buf[3] = displace[i][2];
@@ -2554,7 +2556,7 @@ int FixRigidSmall::pack_exchange(int i, double *buf)
 
 int FixRigidSmall::unpack_exchange(int nlocal, double *buf)
 {
-  bodytag[nlocal] = static_cast<int> (buf[0]);
+  bodytag[nlocal] = (tagint) ubuf(buf[0]).i;
   displace[nlocal][0] = buf[1];
   displace[nlocal][1] = buf[2];
   displace[nlocal][2] = buf[3];
@@ -2839,7 +2841,6 @@ void FixRigidSmall::unpack_reverse_comm(int n, int *list, double *buf)
   int i,j,k;
   double *fcm,*torque,*vcm,*angmom,*xcm;
 
-  int *tag = atom->tag;
   int nlocal = atom->nlocal;
 
   int m = 0;
@@ -2940,8 +2941,8 @@ void FixRigidSmall::reset_atom2body()
       if (iowner == -1) {
         char str[128];
         sprintf(str,
-                "Rigid body atoms %d %d missing on proc %d at step " 
-                BIGINT_FORMAT,
+                "Rigid body atoms " TAGINT_FORMAT " " TAGINT_FORMAT 
+                " missing on proc %d at step " BIGINT_FORMAT,
                 atom->tag[i],bodytag[i],comm->me,update->ntimestep);
         error->one(FLERR,str);
         
diff --git a/src/RIGID/fix_rigid_small.h b/src/RIGID/fix_rigid_small.h
index 5cc63c3dd6ec50ec5eba62f69fc03df59fbe0874..6f73a9c03a0ed4a360a940f0831fc1fa2fd3305a 100644
--- a/src/RIGID/fix_rigid_small.h
+++ b/src/RIGID/fix_rigid_small.h
@@ -48,7 +48,7 @@ class FixRigidSmall : public Fix {
   void grow_arrays(int);
   void copy_arrays(int, int, int);
   void set_arrays(int);
-  void set_molecule(int, int, double *, double *, double *);
+  void set_molecule(int, tagint, double *, double *, double *);
 
   int pack_exchange(int, double *);
   int unpack_exchange(int, double *);
@@ -112,7 +112,7 @@ class FixRigidSmall : public Fix {
   // only defined for owned atoms, except bodyown for own+ghost
 
   int *bodyown;         // index of body if atom owns a body, -1 if not
-  int *bodytag;         // ID of body this atom is in, 0 if none
+  tagint *bodytag;      // ID of body this atom is in, 0 if none
                         // ID = tag of atom that owns body
   int *atom2body;       // index of owned/ghost body this atom is in, -1 if not
                         // can point to original or any image of the body
@@ -160,7 +160,7 @@ class FixRigidSmall : public Fix {
   std::map<int,int> *hash;
   double **bbox;
   double **ctr;
-  int *idclose;
+  tagint *idclose;
   double *rsqclose;
   double rsqfar;
 
diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp
index 301cfd815a0d62ae28a64bd3d78009059927a77b..7024f0281b1cd63451e91e2617ad9120873d3afe 100644
--- a/src/RIGID/fix_shake.cpp
+++ b/src/RIGID/fix_shake.cpp
@@ -66,7 +66,8 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) :
   // register with Atom class
 
   shake_flag = NULL;
-  shake_atom = shake_type = NULL;
+  shake_atom = NULL;
+  shake_type = NULL;
   xshake = NULL;
 
   grow_arrays(atom->nmax);
@@ -493,8 +494,8 @@ void FixShake::pre_neighbor()
         atom2 = atom->map(shake_atom[i][1]);
         if (atom1 == -1 || atom2 == -1) {
           char str[128];
-          sprintf(str,
-                  "Shake atoms %d %d missing on proc %d at step " BIGINT_FORMAT,
+          sprintf(str,"Shake atoms " TAGINT_FORMAT " " TAGINT_FORMAT 
+                  " missing on proc %d at step " BIGINT_FORMAT,
                   shake_atom[i][0],shake_atom[i][1],me,update->ntimestep);
           error->one(FLERR,str);
         }
@@ -505,9 +506,9 @@ void FixShake::pre_neighbor()
         atom3 = atom->map(shake_atom[i][2]);
         if (atom1 == -1 || atom2 == -1 || atom3 == -1) {
           char str[128];
-          sprintf(str,
-                  "Shake atoms %d %d %d missing on proc %d at step "
-                  BIGINT_FORMAT,
+          sprintf(str,"Shake atoms " 
+                  TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT
+                  " missing on proc %d at step " BIGINT_FORMAT,
                   shake_atom[i][0],shake_atom[i][1],shake_atom[i][2],
                   me,update->ntimestep);
           error->one(FLERR,str);
@@ -520,9 +521,10 @@ void FixShake::pre_neighbor()
         atom4 = atom->map(shake_atom[i][3]);
         if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) {
           char str[128];
-          sprintf(str,
-                  "Shake atoms %d %d %d %d missing on proc %d at step "
-                  BIGINT_FORMAT,
+          sprintf(str,"Shake atoms " 
+                  TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                  TAGINT_FORMAT " " TAGINT_FORMAT
+                  " missing on proc %d at step " BIGINT_FORMAT,
                   shake_atom[i][0],shake_atom[i][1],
                   shake_atom[i][2],shake_atom[i][3],
                   me,update->ntimestep);
@@ -618,7 +620,7 @@ int FixShake::dof(int igroup)
   int groupbit = group->bitmask[igroup];
 
   int *mask = atom->mask;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
 
   // count dof in a cluster if and only if
@@ -653,7 +655,7 @@ void FixShake::find_clusters()
   int i,j,m,n;
   int flag,flag_all,messtag,loop,nbuf,nbufmax,size;
   double massone;
-  int *buf,*bufcopy;
+  tagint *buf;
   MPI_Request request;
   MPI_Status status;
 
@@ -661,7 +663,7 @@ void FixShake::find_clusters()
 
   // local copies of atom ptrs
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   double *mass = atom->mass;
@@ -669,7 +671,7 @@ void FixShake::find_clusters()
   int **bond_type = atom->bond_type;
   int **angle_type = atom->angle_type;
   int **nspecial = atom->nspecial;
-  int **special = atom->special;
+  tagint **special = atom->special;
   int nlocal = atom->nlocal;
 
   int angles_allow = atom->avec->angles_allow;
@@ -702,8 +704,9 @@ void FixShake::find_clusters()
   memory->create(npartner,nlocal,"shake:npartner");
   memory->create(nshake,nlocal,"shake:nshake");
 
-  int **partner_tag,**partner_mask,**partner_type,**partner_massflag;
-  int ** partner_bondtype,**partner_shake,**partner_nshake;
+  tagint **partner_tag;
+  int **partner_mask,**partner_type,**partner_massflag;
+  int **partner_bondtype,**partner_shake,**partner_nshake;
   memory->create(partner_tag,nlocal,max,"shake:partner_tag");
   memory->create(partner_mask,nlocal,max,"shake:partner_mask");
   memory->create(partner_type,nlocal,max,"shake:partner_type");
@@ -718,7 +721,8 @@ void FixShake::find_clusters()
 
   for (i = 0; i < nlocal; i++) {
     npartner[i] = nspecial[i][0];
-    for (j = 0; j < npartner[i]; j++) partner_tag[i][j] = special[i][j];
+    for (j = 0; j < npartner[i]; j++)
+      partner_tag[i][j] = special[i][j];
   }
 
   // -----------------------------------------------------
@@ -786,7 +790,7 @@ void FixShake::find_clusters()
   // cycle buffer around ring of procs back to self
 
   fsptr = this;
-  comm->ring(size,sizeof(int),buf,1,ring_bonds,buf);
+  comm->ring(size,sizeof(tagint),buf,1,ring_bonds,buf);
 
   // store partner info returned to me
 
@@ -912,7 +916,7 @@ void FixShake::find_clusters()
   // cycle buffer around ring of procs back to self
 
   fsptr = this;
-  comm->ring(size,sizeof(int),buf,2,ring_nshake,buf);
+  comm->ring(size,sizeof(tagint),buf,2,ring_nshake,buf);
 
   // store partner info returned to me
   
@@ -1066,7 +1070,7 @@ void FixShake::find_clusters()
   // cycle buffer around ring of procs back to self
 
   fsptr = this;
-  comm->ring(size,sizeof(int),buf,3,ring_shake,NULL);
+  comm->ring(size,sizeof(tagint),buf,3,ring_shake,NULL);
 
   memory->destroy(buf);
 
@@ -1173,7 +1177,7 @@ void FixShake::ring_bonds(int ndatum, char *cbuf)
   int nlocal = atom->nlocal;
   int nmass = fsptr->nmass;
 
-  int *buf = (int *) cbuf;
+  tagint *buf = (tagint *) cbuf;
   int m,n;
   double massone;
 
@@ -1207,7 +1211,7 @@ void FixShake::ring_nshake(int ndatum, char *cbuf)
 
   int *nshake = fsptr->nshake;
 
-  int *buf = (int *) cbuf;
+  tagint *buf = (tagint *) cbuf;
   int m;
 
   for (int i = 0; i < ndatum; i += 3) {
@@ -1227,10 +1231,10 @@ void FixShake::ring_shake(int ndatum, char *cbuf)
   int nlocal = atom->nlocal;
 
   int *shake_flag = fsptr->shake_flag;
-  int **shake_atom = fsptr->shake_atom;
+  tagint **shake_atom = fsptr->shake_atom;
   int **shake_type = fsptr->shake_type;
 
-  int *buf = (int *) cbuf;
+  tagint *buf = (tagint *) cbuf;
   int m;
 
   for (int i = 0; i < ndatum; i += 9) {
@@ -2234,10 +2238,10 @@ void FixShake::stats()
    return bond index if do find it
 ------------------------------------------------------------------------- */
 
-int FixShake::bondfind(int i, int n1, int n2)
+int FixShake::bondfind(int i, tagint n1, tagint n2)
 {
-  int *tag = atom->tag;
-  int **bond_atom = atom->bond_atom;
+  tagint *tag = atom->tag;
+  tagint **bond_atom = atom->bond_atom;
   int nbonds = atom->num_bond[i];
 
   int m;
@@ -2255,10 +2259,10 @@ int FixShake::bondfind(int i, int n1, int n2)
    return angle index if do find it
 ------------------------------------------------------------------------- */
 
-int FixShake::anglefind(int i, int n1, int n2)
+int FixShake::anglefind(int i, tagint n1, tagint n2)
 {
-  int **angle_atom1 = atom->angle_atom1;
-  int **angle_atom3 = atom->angle_atom3;
+  tagint **angle_atom1 = atom->angle_atom1;
+  tagint **angle_atom3 = atom->angle_atom3;
   int nangles = atom->num_angle[i];
 
   int m;
@@ -2379,7 +2383,7 @@ void FixShake::update_arrays(int i, int atom_offset)
    xgeom,vcm,quat ignored
 ------------------------------------------------------------------------- */
 
-void FixShake::set_molecule(int nlocalprev, int tagprev, 
+void FixShake::set_molecule(int nlocalprev, tagint tagprev, 
                             double *xgeom, double *vcm, double *quat)
 {
   int m,flag;
@@ -2387,7 +2391,7 @@ void FixShake::set_molecule(int nlocalprev, int tagprev,
   int nlocal = atom->nlocal;
   if (nlocalprev == nlocal) return;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int **mol_shake_atom = onemol->shake_atom;
   int **mol_shake_type = onemol->shake_type;
 
@@ -2472,27 +2476,27 @@ int FixShake::unpack_exchange(int nlocal, double *buf)
   int m = 0;
   int flag = shake_flag[nlocal] = static_cast<int> (buf[m++]);
   if (flag == 1) {
-    shake_atom[nlocal][0] = static_cast<int> (buf[m++]);
-    shake_atom[nlocal][1] = static_cast<int> (buf[m++]);
-    shake_atom[nlocal][2] = static_cast<int> (buf[m++]);
+    shake_atom[nlocal][0] = static_cast<tagint> (buf[m++]);
+    shake_atom[nlocal][1] = static_cast<tagint> (buf[m++]);
+    shake_atom[nlocal][2] = static_cast<tagint> (buf[m++]);
     shake_type[nlocal][0] = static_cast<int> (buf[m++]);
     shake_type[nlocal][1] = static_cast<int> (buf[m++]);
     shake_type[nlocal][2] = static_cast<int> (buf[m++]);
   } else if (flag == 2) {
-    shake_atom[nlocal][0] = static_cast<int> (buf[m++]);
-    shake_atom[nlocal][1] = static_cast<int> (buf[m++]);
+    shake_atom[nlocal][0] = static_cast<tagint> (buf[m++]);
+    shake_atom[nlocal][1] = static_cast<tagint> (buf[m++]);
     shake_type[nlocal][0] = static_cast<int> (buf[m++]);
   } else if (flag == 3) {
-    shake_atom[nlocal][0] = static_cast<int> (buf[m++]);
-    shake_atom[nlocal][1] = static_cast<int> (buf[m++]);
-    shake_atom[nlocal][2] = static_cast<int> (buf[m++]);
+    shake_atom[nlocal][0] = static_cast<tagint> (buf[m++]);
+    shake_atom[nlocal][1] = static_cast<tagint> (buf[m++]);
+    shake_atom[nlocal][2] = static_cast<tagint> (buf[m++]);
     shake_type[nlocal][0] = static_cast<int> (buf[m++]);
     shake_type[nlocal][1] = static_cast<int> (buf[m++]);
   } else if (flag == 4) {
-    shake_atom[nlocal][0] = static_cast<int> (buf[m++]);
-    shake_atom[nlocal][1] = static_cast<int> (buf[m++]);
-    shake_atom[nlocal][2] = static_cast<int> (buf[m++]);
-    shake_atom[nlocal][3] = static_cast<int> (buf[m++]);
+    shake_atom[nlocal][0] = static_cast<tagint> (buf[m++]);
+    shake_atom[nlocal][1] = static_cast<tagint> (buf[m++]);
+    shake_atom[nlocal][2] = static_cast<tagint> (buf[m++]);
+    shake_atom[nlocal][3] = static_cast<tagint> (buf[m++]);
     shake_type[nlocal][0] = static_cast<int> (buf[m++]);
     shake_type[nlocal][1] = static_cast<int> (buf[m++]);
     shake_type[nlocal][2] = static_cast<int> (buf[m++]);
diff --git a/src/RIGID/fix_shake.h b/src/RIGID/fix_shake.h
index a1cfe0e2f4fd69c5daa93b9884361f70fa751d16..2077d79936b6e893a3cefcb2c3c072f30f094bc3 100644
--- a/src/RIGID/fix_shake.h
+++ b/src/RIGID/fix_shake.h
@@ -40,7 +40,7 @@ class FixShake : public Fix {
   void copy_arrays(int, int, int);
   void set_arrays(int);
   void update_arrays(int, int);
-  void set_molecule(int, int, double *, double *, double *);
+  void set_molecule(int, tagint, double *, double *, double *);
 
   int pack_exchange(int, double *);
   int unpack_exchange(int, double *);
@@ -79,7 +79,7 @@ class FixShake : public Fix {
   int *shake_flag;                       // 0 if atom not in SHAKE cluster
                                          // 1 = size 3 angle cluster
                                          // 2,3,4 = size of bond-only cluster
-  int **shake_atom;                      // global IDs of atoms in cluster
+  tagint **shake_atom;                   // global IDs of atoms in cluster
                                          // central atom is 1st
                                          // lowest global ID is 1st for size 2
   int **shake_type;                      // bondtype of each bond in cluster
@@ -115,8 +115,8 @@ class FixShake : public Fix {
   void shake4(int);
   void shake3angle(int);
   void stats();
-  int bondfind(int, int, int);
-  int anglefind(int, int, int);
+  int bondfind(int, tagint, tagint);
+  int anglefind(int, tagint, tagint);
 
   // static variable for ring communication callback to access class data
   // callback functions for ring communication
diff --git a/src/SHOCK/fix_append_atoms.cpp b/src/SHOCK/fix_append_atoms.cpp
index af9056bb7f1e3f003c92bafa46f3c68388541162..295337e6f0d4424469a178339b71567f23637030 100644
--- a/src/SHOCK/fix_append_atoms.cpp
+++ b/src/SHOCK/fix_append_atoms.cpp
@@ -495,14 +495,14 @@ void FixAppendAtoms::pre_exchange()
 
     if (addtotal) {
       domain->reset_box();
-      if (atom->tag_enable) {
-        atom->tag_extend();
-        atom->natoms += addtotal;
-        if (atom->map_style) {
-          atom->nghost = 0;
-          atom->map_init();
-          atom->map_set();
-        }
+      atom->natoms += addtotal;
+      if (atom->natoms < 0 || atom->natoms > MAXBIGINT)
+        error->all(FLERR,"Too many total atoms");
+      if (atom->tag_enable) atom->tag_extend();
+      if (atom->map_style) {
+        atom->nghost = 0;
+        atom->map_init();
+        atom->map_set();
       }
     }
   }
diff --git a/src/SRD/fix_srd.cpp b/src/SRD/fix_srd.cpp
index 01ff4e8f2ae2096919d6f078ed50e9b6491aadc7..c100fb69fe1a8e5467d5e5486025c72f36b290a3 100644
--- a/src/SRD/fix_srd.cpp
+++ b/src/SRD/fix_srd.cpp
@@ -572,10 +572,12 @@ void FixSRD::pre_neighbor()
 
           if (jx < 0 || jx >= nbin2x || jy < 0 || jy >= nbin2y ||
               jz < 0 || jz >= nbin2z) {
-            printf("Big particle %d %d %g %g %g\n",
-                   atom->tag[i],i,x[i][0],x[i][1],x[i][2]);
-            printf("Bin indices: %d %d %d, %d %d %d, %d %d %d\n",
-                   ix,iy,iz,jx,jy,jz,nbin2x,nbin2y,nbin2z);
+            if (screen) {
+              fprintf(screen,"Big particle " TAGINT_FORMAT " %d %g %g %g\n",
+                      atom->tag[i],i,x[i][0],x[i][1],x[i][2]);
+              fprintf(screen,"Bin indices: %d %d %d, %d %d %d, %d %d %d\n",
+                      ix,iy,iz,jx,jy,jz,nbin2x,nbin2y,nbin2z);
+            }
             error->one(FLERR,"Fix SRD: bad stencil bin for big particle");
           }
           rsq = point_bin_distance(x[i],jx,jy,jz);
@@ -742,7 +744,8 @@ void FixSRD::post_force(int vflag)
         if (ix < 0 || ix >= nbin2x || iy < 0 || iy >= nbin2y ||
             iz < 0 || iz >= nbin2z) {
           if (screen) {
-            fprintf(screen,"SRD particle %d on step " BIGINT_FORMAT "\n",
+            fprintf(screen,"SRD particle " TAGINT_FORMAT 
+                    " on step " BIGINT_FORMAT "\n",
                     atom->tag[i],update->ntimestep);
             fprintf(screen,"v = %g %g %g\n",v[i][0],v[i][1],v[i][2]);
             fprintf(screen,"x = %g %g %g\n",x[i][0],x[i][1],x[i][2]);
@@ -1224,15 +1227,15 @@ void FixSRD::collisions_single()
               char str[128];
               if (type != WALL)
                 sprintf(str,
-                        "SRD particle %d started "
-                        "inside big particle %d on step " BIGINT_FORMAT
-                        " bounce %d",
+                        "SRD particle " TAGINT_FORMAT " started "
+                        "inside big particle " TAGINT_FORMAT 
+                        " on step " BIGINT_FORMAT " bounce %d",
                         atom->tag[i],atom->tag[j],update->ntimestep,ibounce+1);
               else
                 sprintf(str,
-                        "SRD particle %d started "
-                        "inside big particle %d on step " BIGINT_FORMAT
-                        " bounce %d",
+                        "SRD particle " TAGINT_FORMAT " started "
+                        "inside big particle " TAGINT_FORMAT 
+                        " on step " BIGINT_FORMAT " bounce %d",
                         atom->tag[i],atom->tag[j],update->ntimestep,ibounce+1);
               if (insideflag == INSIDE_ERROR) error->one(FLERR,str);
               error->warning(FLERR,str);
@@ -1380,9 +1383,9 @@ void FixSRD::collisions_multi()
             if (insideflag == INSIDE_ERROR || insideflag == INSIDE_WARN) {
               char str[128];
               sprintf(str,
-                      "SRD particle %d started "
-                      "inside big particle %d on step " BIGINT_FORMAT
-                      " bounce %d",
+                      "SRD particle " TAGINT_FORMAT " started "
+                      "inside big particle " TAGINT_FORMAT 
+                      " on step " BIGINT_FORMAT " bounce %d",
                       atom->tag[i],atom->tag[j],update->ntimestep,ibounce+1);
               if (insideflag == INSIDE_ERROR) error->one(FLERR,str);
               error->warning(FLERR,str);
@@ -2381,7 +2384,8 @@ int FixSRD::update_srd(int i, double dt, double *xscoll, double *vsnew,
       xs[2] < srdlo[2] || xs[2] > srdhi[2]) {
     if (screen) {
       error->warning(FLERR,"Fix srd particle moved outside valid domain");
-      fprintf(screen,"  particle %d on proc %d at timestep " BIGINT_FORMAT,
+      fprintf(screen,"  particle " TAGINT_FORMAT 
+              " on proc %d at timestep " BIGINT_FORMAT,
               atom->tag[i],me,update->ntimestep);
       fprintf(screen,"  xnew %g %g %g\n",xs[0],xs[1],xs[2]);
       fprintf(screen,"  srdlo/hi x %g %g\n",srdlo[0],srdhi[0]);
@@ -3883,7 +3887,8 @@ void FixSRD::print_collision(int i, int j, int ibounce,
   double **v = atom->v;
 
   if (type != WALL) {
-    printf("COLLISION between SRD %d and BIG %d\n",atom->tag[i],atom->tag[j]);
+    printf("COLLISION between SRD " TAGINT_FORMAT 
+           " and BIG " TAGINT_FORMAT "\n",atom->tag[i],atom->tag[j]);
     printf("  bounce # = %d\n",ibounce+1);
     printf("  local indices: %d %d\n",i,j);
     printf("  timestep = %g\n",dt);
@@ -3928,7 +3933,8 @@ void FixSRD::print_collision(int i, int j, int ibounce,
   } else {
     int dim = wallwhich[j] / 2;
 
-    printf("COLLISION between SRD %d and WALL %d\n",atom->tag[i],j);
+    printf("COLLISION between SRD " TAGINT_FORMAT " and WALL %d\n",
+           atom->tag[i],j);
     printf("  bounce # = %d\n",ibounce+1);
     printf("  local indices: %d %d\n",i,j);
     printf("  timestep = %g\n",dt);
diff --git a/src/USER-AWPMD/atom_vec_wavepacket.cpp b/src/USER-AWPMD/atom_vec_wavepacket.cpp
index 35c6e582d90c12dc11615ed203dbd145091f9750..9903e889fac873988cade0f9e25d1db695ecbf91 100644
--- a/src/USER-AWPMD/atom_vec_wavepacket.cpp
+++ b/src/USER-AWPMD/atom_vec_wavepacket.cpp
@@ -618,7 +618,7 @@ void AtomVecWavepacket::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     q[i] = buf[m++];
@@ -646,7 +646,7 @@ void AtomVecWavepacket::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     q[i] = buf[m++];
@@ -737,7 +737,7 @@ int AtomVecWavepacket::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -834,7 +834,7 @@ int AtomVecWavepacket::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -902,17 +902,14 @@ void AtomVecWavepacket::create_atom(int itype, double *coord)
    AWPMD: 0-tag 1-type 2-q 3-spin 4-eradius 5-etag 6-cs_re 7-cs_im
 ------------------------------------------------------------------------- */
 
-void AtomVecWavepacket::data_atom(double *coord, imageint imagetmp, char **values)
+void AtomVecWavepacket::data_atom(double *coord, imageint imagetmp, 
+                                  char **values)
 {
   int nlocal = atom->nlocal;
 
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of "
-               "data file (ID tag must be >0)");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -923,12 +920,10 @@ void AtomVecWavepacket::data_atom(double *coord, imageint imagetmp, char **value
   if (eradius[nlocal] < 0.0)
     error->one(FLERR,"Invalid eradius in Atoms section of data file");
 
-
   etag[nlocal] = atoi(values[5]);
   cs[2*nlocal] = atoi(values[6]);
   cs[2*nlocal+1] = atof(values[7]);
 
-
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
@@ -961,7 +956,6 @@ int AtomVecWavepacket::data_atom_hybrid(int nlocal, char **values)
   cs[2*nlocal] = atoi(values[4]);
   cs[2*nlocal+1] = atof(values[5]);
 
-
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -1039,9 +1033,10 @@ int AtomVecWavepacket::pack_data_hybrid(int i, double *buf)
 void AtomVecWavepacket::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %-1.16e %d %-1.16e %d %-1.16e %-1.16e %-1.16e "
+    fprintf(fp,TAGINT_FORMAT 
+            " %d %-1.16e %d %-1.16e %d %-1.16e %-1.16e %-1.16e "
             "%-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             buf[i][2],(int) ubuf(buf[i][3]).i,buf[i][4],
             (int) ubuf(buf[i][5]).i,buf[i][6],buf[i][8],
             buf[i][8],buf[i][9],buf[i][10],
@@ -1094,8 +1089,8 @@ int AtomVecWavepacket::pack_vel_hybrid(int i, double *buf)
 void AtomVecWavepacket::write_vel(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e\n",
-            (int) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],buf[i][4]);
+    fprintf(fp,TAGINT_FORMAT " %-1.16e %-1.16e %-1.16e %-1.16e\n",
+            (tagint) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],buf[i][4]);
 }
 
 /* ----------------------------------------------------------------------
diff --git a/src/USER-AWPMD/atom_vec_wavepacket.h b/src/USER-AWPMD/atom_vec_wavepacket.h
index c4fe70f1331acb7808ce02691901587ea505ded9..8265e817e7de42b1c6bb1345867b568cf408f0aa 100644
--- a/src/USER-AWPMD/atom_vec_wavepacket.h
+++ b/src/USER-AWPMD/atom_vec_wavepacket.h
@@ -73,7 +73,8 @@ public:
   bigint memory_usage();
 
 private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
 
diff --git a/src/USER-EFF/atom_vec_electron.cpp b/src/USER-EFF/atom_vec_electron.cpp
index 1658d48921a9b773ae352f777dc387cfe3f75a09..c68e34803513e1202541f92b960f3feba3e2aff0 100644
--- a/src/USER-EFF/atom_vec_electron.cpp
+++ b/src/USER-EFF/atom_vec_electron.cpp
@@ -534,7 +534,7 @@ void AtomVecElectron::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     q[i] = buf[m++];
@@ -561,7 +561,7 @@ void AtomVecElectron::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     q[i] = buf[m++];
@@ -639,7 +639,7 @@ int AtomVecElectron::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -727,7 +727,7 @@ int AtomVecElectron::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -791,10 +791,7 @@ void AtomVecElectron::data_atom(double *coord, imageint imagetmp, char **values)
 
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -904,8 +901,9 @@ int AtomVecElectron::pack_data_hybrid(int i, double *buf)
 void AtomVecElectron::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %-1.16e %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,buf[i][2],
+    fprintf(fp,TAGINT_FORMAT 
+            " %d %-1.16e %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,buf[i][2],
             (int) ubuf(buf[i][3]).i,buf[i][4],buf[i][5],buf[i][6],buf[i][7],
             (int) ubuf(buf[i][8]).i,(int) ubuf(buf[i][9]).i,
             (int) ubuf(buf[i][10]).i);
@@ -954,8 +952,8 @@ int AtomVecElectron::pack_vel_hybrid(int i, double *buf)
 void AtomVecElectron::write_vel(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e\n",
-            (int) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],buf[i][4]);
+    fprintf(fp,TAGINT_FORMAT " %-1.16e %-1.16e %-1.16e %-1.16e\n",
+            (tagint) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],buf[i][4]);
 }
 
 /* ----------------------------------------------------------------------
diff --git a/src/USER-EFF/atom_vec_electron.h b/src/USER-EFF/atom_vec_electron.h
index 64ba79865ef00dfd5c61d20474155e8b0c6327a4..f604613599f1a3297276638b152eb13e3d18fdc1 100644
--- a/src/USER-EFF/atom_vec_electron.h
+++ b/src/USER-EFF/atom_vec_electron.h
@@ -68,7 +68,8 @@ class AtomVecElectron : public AtomVec {
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   int *spin;
diff --git a/src/USER-EFF/pair_eff_cut.cpp b/src/USER-EFF/pair_eff_cut.cpp
index 12467b57bca3f55bf69d348c37f7af1b04fa64a8..121217751c06a588004be639781fabe6459ee1ac 100644
--- a/src/USER-EFF/pair_eff_cut.cpp
+++ b/src/USER-EFF/pair_eff_cut.cpp
@@ -93,8 +93,6 @@ void PairEffCut::compute(int eflag, int vflag)
   int *type = atom->type;
   int nlocal = atom->nlocal;
 
-  int *id = atom->tag;
-
   int newton_pair = force->newton_pair;
   double qqrd2e = force->qqrd2e;
 
diff --git a/src/USER-MISC/dihedral_cosine_shift_exp.cpp b/src/USER-MISC/dihedral_cosine_shift_exp.cpp
index ea2c5e51e77db95048d065ddd32c0baaf71cba88..ec6cc01fb9818e16079029f61a22d5d867b6f6cf 100644
--- a/src/USER-MISC/dihedral_cosine_shift_exp.cpp
+++ b/src/USER-MISC/dihedral_cosine_shift_exp.cpp
@@ -137,7 +137,9 @@ void DihedralCosineShiftExp::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/USER-MISC/dihedral_fourier.cpp b/src/USER-MISC/dihedral_fourier.cpp
index 3ddf4cd2460fb1f8b85c47f89b29059f2b74d54d..c00dcfcfa52fa842f057e008214b65b11efcc32e 100644
--- a/src/USER-MISC/dihedral_fourier.cpp
+++ b/src/USER-MISC/dihedral_fourier.cpp
@@ -149,7 +149,9 @@ void DihedralFourier::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/USER-MISC/dihedral_nharmonic.cpp b/src/USER-MISC/dihedral_nharmonic.cpp
index d06ef08a9f3d4a4dae1dd57d1f2e027ac62b4f08..6370b8573925341c157c9d72b9cd6dd6d5db4f70 100644
--- a/src/USER-MISC/dihedral_nharmonic.cpp
+++ b/src/USER-MISC/dihedral_nharmonic.cpp
@@ -156,7 +156,9 @@ void DihedralNHarmonic::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
         char str[128];
-        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
+        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
                 me,update->ntimestep,
                 atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
         error->warning(FLERR,str,0);
diff --git a/src/USER-MISC/dihedral_quadratic.cpp b/src/USER-MISC/dihedral_quadratic.cpp
index 06391b71281256bf7b11afd54d3c19a9563ba8e4..bec383f214903298e7afc3c4ed83decb164d6f69 100644
--- a/src/USER-MISC/dihedral_quadratic.cpp
+++ b/src/USER-MISC/dihedral_quadratic.cpp
@@ -161,8 +161,10 @@ void DihedralQuadratic::compute(int eflag, int vflag)
       MPI_Comm_rank(world,&me);
       if (screen) {
 	char str[128];
-	sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " %d %d %d %d",
-		me,update->ntimestep,
+        sprintf(str,"Dihedral problem: %d " BIGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                TAGINT_FORMAT " " TAGINT_FORMAT,
+                me,update->ntimestep,
 		atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
 	error->warning(FLERR,str,0);
 	fprintf(screen,"  1st atom: %d %g %g %g\n",
diff --git a/src/USER-MISC/improper_cossq.cpp b/src/USER-MISC/improper_cossq.cpp
index 36aeb61138782bb51f8fa72a75d5c7086d1151ed..53fd31e02c2e077e3107eb1aea55078770b50960 100644
--- a/src/USER-MISC/improper_cossq.cpp
+++ b/src/USER-MISC/improper_cossq.cpp
@@ -110,8 +110,11 @@ void ImproperCossq::compute(int eflag, int vflag)
          MPI_Comm_rank(world,&me);
          if (screen) {
             char str[128];
-            sprintf(str,"Improper problem: %d " BIGINT_FORMAT " %d %d %d %d",
-               me,update->ntimestep,atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+            sprintf(str,"Improper problem: %d " BIGINT_FORMAT " " 
+                    TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                    TAGINT_FORMAT " " TAGINT_FORMAT,
+                    me,update->ntimestep,
+                    atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
             error->warning(FLERR,str,0);
             fprintf(screen,"  1st atom: %d %g %g %g\n",me,x[i1][0],x[i1][1],x[i1][2]);
             fprintf(screen,"  2nd atom: %d %g %g %g\n",me,x[i2][0],x[i2][1],x[i2][2]);
@@ -120,7 +123,6 @@ void ImproperCossq::compute(int eflag, int vflag)
             }
       }
 
-
       /* Apply corrections to round-off errors. */
       if (cosphi > 1.0)  cosphi -= SMALL;
       if (cosphi < -1.0) cosphi += SMALL;
diff --git a/src/USER-MISC/improper_fourier.cpp b/src/USER-MISC/improper_fourier.cpp
index 43944727ff6b12c543ad0ef98ab9e133b6cd01c7..a4be0ea35c33e6457bcc0e9fe16a56880c5fe057 100644
--- a/src/USER-MISC/improper_fourier.cpp
+++ b/src/USER-MISC/improper_fourier.cpp
@@ -157,8 +157,9 @@ void ImproperFourier::addone(const int &i1,const int &i2,const int &i3,const int
     MPI_Comm_rank(world,&me);
     if (screen) {
       char str[128];
-      sprintf(str,
-              "Improper problem: %d " BIGINT_FORMAT " %d %d %d %d",
+      sprintf(str,"Improper problem: %d " BIGINT_FORMAT " " 
+              TAGINT_FORMAT " " TAGINT_FORMAT " " 
+              TAGINT_FORMAT " " TAGINT_FORMAT,
               me,update->ntimestep,
               atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
       error->warning(FLERR,str,0);
diff --git a/src/USER-MISC/pair_edip.cpp b/src/USER-MISC/pair_edip.cpp
index a9938f409ac77840a83eaa4d7d7ce2ac55be4a59..4c236649a25369593927bd36d132f223e02da3e6 100755
--- a/src/USER-MISC/pair_edip.cpp
+++ b/src/USER-MISC/pair_edip.cpp
@@ -841,8 +841,6 @@ void PairEDIP::coeff(int narg, char **arg)
 
 void PairEDIP::init_style()
 {
-  if (atom->tag_enable == 0)
-    error->all(FLERR,"Pair style EDIP requires atom IDs");
   if (force->newton_pair == 0)
     error->all(FLERR,"Pair style EDIP requires newton pair on");
 
diff --git a/src/USER-MISC/pair_list.cpp b/src/USER-MISC/pair_list.cpp
index 3b6f5c2d1026c418f6df41065348c1f58d994932..265532e56f13570d683a03cba3ef1da3cdd945d7 100644
--- a/src/USER-MISC/pair_list.cpp
+++ b/src/USER-MISC/pair_list.cpp
@@ -233,7 +233,9 @@ void PairList::settings(int narg, char **arg)
   // now read and parse pair list file for real
   npairs = 0;
   char *ptr;
-  int id1, id2, nharm=0, nmorse=0, nlj126=0;
+  tagint id1, id2;
+  int nharm=0, nmorse=0, nlj126=0;
+
   while(fgets(line,1024,fp)) {
     ptr = strtok(line," \t\n\r\f");
 
@@ -244,11 +246,11 @@ void PairList::settings(int narg, char **arg)
     if (*ptr == '#') continue;
 
     // get atom ids of pair
-    id1 = atoi(ptr);
+    id1 = ATOTAGINT(ptr);
     ptr = strtok(NULL," \t\n\r\f");
     if (!ptr)
       error->all(FLERR,"Incorrectly formatted pair list file");
-    id2 = atoi(ptr);
+    id2 = ATOTAGINT(ptr);
 
     // get potential type
     ptr = strtok(NULL," \t\n\r\f");
diff --git a/src/USER-MISC/pair_list.h b/src/USER-MISC/pair_list.h
index 9d199f5ba7ba014ce7e227f2ef2fd8d7d8b883d9..4059b0ef29e895d9bab9fb8ab70d4f66bf2f1ec0 100644
--- a/src/USER-MISC/pair_list.h
+++ b/src/USER-MISC/pair_list.h
@@ -53,7 +53,7 @@ class PairList : public Pair {
   };
 
   typedef struct {
-    int id1,id2;        // global atom ids
+    tagint id1,id2;        // global atom ids
     double cutsq;       // cutoff**2 for this pair
     double offset;      // energy offset
     union parm_u parm;  // parameters for style
diff --git a/src/USER-MISC/pair_tersoff_table.cpp b/src/USER-MISC/pair_tersoff_table.cpp
index d5850ac81cc6d221fe062a808acf8d1b4a77a2e0..db58c023b1722e019bcc11ce17809e97ab61d543 100644
--- a/src/USER-MISC/pair_tersoff_table.cpp
+++ b/src/USER-MISC/pair_tersoff_table.cpp
@@ -815,8 +815,6 @@ void PairTersoffTable::coeff(int narg, char **arg)
 
 void PairTersoffTable::init_style()
 {
-  if (atom->tag_enable == 0)
-    error->all(FLERR,"Pair style Tersoff requires atom IDs");
   if (force->newton_pair == 0)
     error->all(FLERR,"Pair style Tersoff requires newton pair on");
 
diff --git a/src/USER-SPH/atom_vec_meso.cpp b/src/USER-SPH/atom_vec_meso.cpp
index 4df4b1503c3653102848d1575dc6488173815404..bca14645d5964a1fca2980f7b3ed49bbabbe8715 100644
--- a/src/USER-SPH/atom_vec_meso.cpp
+++ b/src/USER-SPH/atom_vec_meso.cpp
@@ -578,7 +578,7 @@ void AtomVecMeso::unpack_border(int n, int first, double *buf) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     rho[i] = buf[m++];
@@ -609,7 +609,7 @@ void AtomVecMeso::unpack_border_vel(int n, int first, double *buf) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     v[i][0] = buf[m++];
@@ -677,7 +677,7 @@ int AtomVecMeso::unpack_exchange(double *buf) {
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -765,7 +765,7 @@ int AtomVecMeso::unpack_restart(double *buf) {
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -830,13 +830,9 @@ void AtomVecMeso::create_atom(int itype, double *coord) {
 
 void AtomVecMeso::data_atom(double *coord, imageint imagetmp, char **values) {
   int nlocal = atom->nlocal;
-  if (nlocal == nmax)
-    grow(0);
-
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
+  if (nlocal == nmax) grow(0);
 
+  tag[nlocal] = ATOTAGINT(values[0]);
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -923,9 +919,10 @@ int AtomVecMeso::pack_data_hybrid(int i, double *buf)
 void AtomVecMeso::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e "
+    fprintf(fp,TAGINT_FORMAT 
+            " %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e "
             "%d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             buf[i][2],buf[i][3],buf[i][4],
             buf[i][5],buf[i][6],buf[i][7],
             (int) ubuf(buf[i][8]).i,(int) ubuf(buf[i][9]).i,
diff --git a/src/USER-SPH/atom_vec_meso.h b/src/USER-SPH/atom_vec_meso.h
index 945e4a42ccc145da147bb226cbd5106653150d8b..7da470fdb68612986826d87c58679080a628bd18 100644
--- a/src/USER-SPH/atom_vec_meso.h
+++ b/src/USER-SPH/atom_vec_meso.h
@@ -62,7 +62,8 @@ class AtomVecMeso : public AtomVec {
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask;
+  int *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   double *rho, *drho, *e, *de, *cv;
diff --git a/src/XTC/dump_xtc.cpp b/src/XTC/dump_xtc.cpp
index 80f1013afebb604cff6d05593356ab62c9febce2..f7c2f8ec0a2179262af1c39cf6a308426a1388e9 100644
--- a/src/XTC/dump_xtc.cpp
+++ b/src/XTC/dump_xtc.cpp
@@ -190,11 +190,11 @@ void DumpXTC::write_header(bigint nbig)
 
 /* ---------------------------------------------------------------------- */
 
-void DumpXTC::pack(int *ids)
+void DumpXTC::pack(tagint *ids)
 {
   int m,n;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   double **x = atom->x;
   imageint *image = atom->image;
   int *mask = atom->mask;
diff --git a/src/XTC/dump_xtc.h b/src/XTC/dump_xtc.h
index 081891b22420bea1274f5396dcf9ee3d2cbcab3c..f1e960af6c031ecb89dc197d7b121e48ccfbe22d 100644
--- a/src/XTC/dump_xtc.h
+++ b/src/XTC/dump_xtc.h
@@ -49,7 +49,7 @@ class DumpXTC : public Dump {
   int modify_param(int, char **);
   void openfile();
   void write_header(bigint);
-  void pack(int *);
+  void pack(tagint *);
   void write_data(int, double *);
   bigint memory_usage();
 
diff --git a/src/atom.cpp b/src/atom.cpp
index 75c2bf4a833fd1922f8b665c9fb4b6acc042da78..aba59b819ac9a2fd6a254bab3b0fc8b83ad968b6 100644
--- a/src/atom.cpp
+++ b/src/atom.cpp
@@ -57,8 +57,6 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
   ntypes = 0;
   nbondtypes = nangletypes = ndihedraltypes = nimpropertypes = 0;
   nbonds = nangles = ndihedrals = nimpropers = 0;
-  bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0;
-  extra_bond_per_atom = 0;
 
   firstgroupname = NULL;
   sortfreq = 1000;
@@ -71,7 +69,8 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
   // initialize atom arrays
   // customize by adding new array
 
-  tag = type = mask = NULL;
+  tag = NULL;
+  type = mask = NULL;
   image = NULL;
   x = v = f = NULL;
 
@@ -92,23 +91,29 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
   cv = NULL;
   vest = NULL;
 
-  maxspecial = 1;
-  nspecial = NULL;
-  special = NULL;
-
+  bond_per_atom =  extra_bond_per_atom = 0;
   num_bond = NULL;
-  bond_type = bond_atom = NULL;
+  bond_type = NULL;
+  bond_atom = NULL;
 
+  angle_per_atom = extra_angle_per_atom = 0;
   num_angle = NULL;
-  angle_type = angle_atom1 = angle_atom2 = angle_atom3 = NULL;
+  angle_type = NULL;
+  angle_atom1 = angle_atom2 = angle_atom3 = NULL;
 
+  dihedral_per_atom = extra_dihedral_per_atom = 0;
   num_dihedral = NULL;
-  dihedral_type = dihedral_atom1 = dihedral_atom2 = NULL;
-  dihedral_atom3 = dihedral_atom4 = NULL;
+  dihedral_type = NULL;
+  dihedral_atom1 = dihedral_atom2 = dihedral_atom3 = dihedral_atom4 = NULL;
 
+  improper_per_atom = extra_improper_per_atom = 0;
   num_improper = NULL;
-  improper_type = improper_atom1 = improper_atom2 = NULL;
-  improper_atom3 = improper_atom4 = NULL;
+  improper_type = NULL;
+  improper_atom1 = improper_atom2 = improper_atom3 = improper_atom4 = NULL;
+
+  maxspecial = 1;
+  nspecial = NULL;
+  special = NULL;
 
   // user-defined molecules
 
@@ -148,14 +153,14 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
   nextra_store = 0;
   extra = NULL;
 
-  // default mapping values
+  // default atom ID and mapping values
 
   tag_enable = 1;
-  map_style = 0;
+  map_style = map_user = 0;
   map_tag_max = 0;
   map_nhash = 0;
 
-  smax = 0;
+  max_same = 0;
   sametag = NULL;
   map_array = NULL;
   map_bucket = NULL;
@@ -283,7 +288,8 @@ Atom::~Atom()
 
 void Atom::settings(Atom *old)
 {
-  map_style = old->map_style;
+  tag_enable = old->tag_enable;
+  map_user = old->map_user;
 }
 
 /* ----------------------------------------------------------------------
@@ -333,10 +339,11 @@ void Atom::create_avec(const char *style, int narg, char **arg, char *suffix)
     strcpy(atom_style,style);
   }
 
-  // if molecular system, default is to have array map
+  // if molecular system, atom IDs must be defined
 
   molecular = avec->molecular;
-  if (map_style == 0 && molecular) map_style = 1;
+  if (molecular && tag_enable == 0)
+    error->all(FLERR,"Atom IDs must be used for molecular systems");
 }
 
 /* ----------------------------------------------------------------------
@@ -444,14 +451,23 @@ void Atom::modify_params(int narg, char **arg)
 
   int iarg = 0;
   while (iarg < narg) {
-    if (strcmp(arg[iarg],"map") == 0) {
+    if (strcmp(arg[iarg],"id") == 0) {
       if (iarg+2 > narg) error->all(FLERR,"Illegal atom_modify command");
-      if (strcmp(arg[iarg+1],"array") == 0) map_style = 1;
-      else if (strcmp(arg[iarg+1],"hash") == 0) map_style = 2;
+      if (domain->box_exist)
+        error->all(FLERR,
+                   "Atom_modify id command after simulation box is defined");
+      if (strcmp(arg[iarg+1],"yes") == 0) tag_enable = 1;
+      else if (strcmp(arg[iarg+1],"no") == 0) tag_enable = 2;
       else error->all(FLERR,"Illegal atom_modify command");
+      iarg += 2;
+    } if (strcmp(arg[iarg],"map") == 0) {
+      if (iarg+2 > narg) error->all(FLERR,"Illegal atom_modify command");
       if (domain->box_exist)
         error->all(FLERR,
                    "Atom_modify map command after simulation box is defined");
+      if (strcmp(arg[iarg+1],"array") == 0) map_user = 1;
+      else if (strcmp(arg[iarg+1],"hash") == 0) map_user = 2;
+      else error->all(FLERR,"Illegal atom_modify command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"first") == 0) {
       if (iarg+2 > narg) error->all(FLERR,"Illegal atom_modify command");
@@ -479,37 +495,82 @@ void Atom::modify_params(int narg, char **arg)
   }
 }
 
+/* ----------------------------------------------------------------------
+   check that atom IDs are valid
+   error if any atom ID < 0 or atom ID = MAXTAGINT
+   if any atom ID > 0, error if any atom ID == 0
+   if all atom IDs = 0, tag_enable must be 0
+   OK if atom IDs > natoms
+   NOTE: not checking that atom IDs are unique
+------------------------------------------------------------------------- */
+
+void Atom::tag_check()
+{
+  int nlocal = atom->nlocal;
+  tagint *tag = atom->tag;
+
+  tagint min = MAXTAGINT;
+  tagint max = 0;
+
+  for (int i = 0; i < nlocal; i++) {
+    min = MIN(min,tag[i]);
+    max = MAX(max,tag[i]);
+  }
+
+  tagint minall,maxall;
+  MPI_Allreduce(&min,&minall,1,MPI_LMP_TAGINT,MPI_MIN,world);
+  MPI_Allreduce(&max,&maxall,1,MPI_LMP_TAGINT,MPI_MAX,world);
+
+  if (minall < 0) error->all(FLERR,"Atom ID is negative");
+  if (maxall >= MAXTAGINT) error->all(FLERR,"Atom ID is too big");
+  if (maxall > 0 && minall == 0) error->all(FLERR,"Atom ID is zero");
+  if (maxall == 0 && tag_enable && natoms) 
+    error->all(FLERR,"Not all atom IDs are 0");
+}
+
 /* ----------------------------------------------------------------------
    add unique tags to any atoms with tag = 0
    new tags are grouped by proc and start after max current tag
    called after creating new atoms
+   error if new tags will exceed MAXTAGINT
 ------------------------------------------------------------------------- */
 
 void Atom::tag_extend()
 {
   // maxtag_all = max tag for all atoms
 
-  int maxtag = 0;
+  tagint maxtag = 0;
   for (int i = 0; i < nlocal; i++) maxtag = MAX(maxtag,tag[i]);
-  int maxtag_all;
-  MPI_Allreduce(&maxtag,&maxtag_all,1,MPI_INT,MPI_MAX,world);
+  tagint maxtag_all;
+  MPI_Allreduce(&maxtag,&maxtag_all,1,MPI_LMP_TAGINT,MPI_MAX,world);
+
+  // DEBUG: useful for generating 64-bit IDs even for small systems
+  // use only when LAMMPS is compiled with BIGBIG
+
+  //maxtag_all += 1000000000000;
 
   // notag = # of atoms I own with no tag (tag = 0)
   // notag_sum = # of total atoms on procs <= me with no tag
 
-  int notag = 0;
+  bigint notag = 0;
   for (int i = 0; i < nlocal; i++) if (tag[i] == 0) notag++;
-  int notag_sum;
-  MPI_Scan(&notag,&notag_sum,1,MPI_INT,MPI_SUM,world);
+
+  bigint notag_total;
+  MPI_Allreduce(&notag,&notag_total,1,MPI_LMP_BIGINT,MPI_SUM,world);
+  if (notag_total >= MAXTAGINT)
+    error->all(FLERR,"New atom IDs exceed maximum allowed ID");
+
+  bigint notag_sum;
+  MPI_Scan(&notag,&notag_sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
 
   // itag = 1st new tag that my untagged atoms should use
 
-  int itag = maxtag_all + notag_sum - notag + 1;
+  tagint itag = maxtag_all + notag_sum - notag + 1;
   for (int i = 0; i < nlocal; i++) if (tag[i] == 0) tag[i] = itag++;
 }
 
 /* ----------------------------------------------------------------------
-   check that atom IDs span range from 1 to Natoms
+   check that atom IDs span range from 1 to Natoms inclusive
    return 0 if mintag != 1 or maxtag != Natoms
    return 1 if OK
    doesn't actually check if all tag values are used
@@ -517,20 +578,18 @@ void Atom::tag_extend()
 
 int Atom::tag_consecutive()
 {
-  // change this when allow tagint = bigint
-  //int idmin = MAXTAGINT;
-  int idmin = MAXSMALLINT;
-  int idmax = 0;
+  tagint idmin = MAXTAGINT;
+  tagint idmax = 0;
 
   for (int i = 0; i < nlocal; i++) {
     idmin = MIN(idmin,tag[i]);
     idmax = MAX(idmax,tag[i]);
   }
-  int idminall,idmaxall;
-  MPI_Allreduce(&idmin,&idminall,1,MPI_INT,MPI_MIN,world);
-  MPI_Allreduce(&idmax,&idmaxall,1,MPI_INT,MPI_MAX,world);
+  tagint idminall,idmaxall;
+  MPI_Allreduce(&idmin,&idminall,1,MPI_LMP_TAGINT,MPI_MIN,world);
+  MPI_Allreduce(&idmax,&idmaxall,1,MPI_LMP_TAGINT,MPI_MAX,world);
 
-  if (idminall != 1 || idmaxall != static_cast<int> (natoms)) return 0;
+  if (idminall != 1 || idmaxall != natoms) return 0;
   return 1;
 }
 
@@ -683,7 +742,8 @@ void Atom::data_atoms(int n, char *buf)
 
 void Atom::data_vels(int n, char *buf)
 {
-  int j,m,tagdata;
+  int j,m;
+  tagint tagdata;
   char *next;
 
   next = strchr(buf,'\n');
@@ -707,7 +767,7 @@ void Atom::data_vels(int n, char *buf)
     for (j = 1; j < nwords; j++)
       values[j] = strtok(NULL," \t\n\r\f");
 
-    tagdata = atoi(values[0]);
+    tagdata = ATOTAGINT(values[0]);
     if (tagdata <= 0 || tagdata > map_tag_max)
       error->one(FLERR,"Invalid atom ID in Velocities section of data file");
     if ((m = map(tagdata)) >= 0) avec->data_vel(m,&values[1]);
@@ -719,120 +779,45 @@ void Atom::data_vels(int n, char *buf)
 }
 
 /* ----------------------------------------------------------------------
-   unpack n lines from atom-style specific section of data file
-   check that atom IDs are > 0 and <= map_tag_max
-   call style-specific routine to parse line
-------------------------------------------------------------------------- */
-
-void Atom::data_bonus(int n, char *buf, AtomVec *avec_bonus)
-{
-  int j,m,tagdata;
-  char *next;
-
-  next = strchr(buf,'\n');
-  *next = '\0';
-  int nwords = count_words(buf);
-  *next = '\n';
-
-  if (nwords != avec_bonus->size_data_bonus)
-    error->all(FLERR,"Incorrect bonus data format in data file");
-
-  char **values = new char*[nwords];
-
-  // loop over lines of bonus atom data
-  // tokenize the line into values
-  // if I own atom tag, unpack its values
-
-  for (int i = 0; i < n; i++) {
-    next = strchr(buf,'\n');
-
-    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(FLERR,"Invalid atom ID in Bonus section of data file");
-
-    // ok to call child's data_atom_bonus() method thru parent avec_bonus,
-    // since data_bonus() was called with child ptr, and method is virtual
-
-    if ((m = map(tagdata)) >= 0) avec_bonus->data_atom_bonus(m,&values[1]);
-
-    buf = next + 1;
-  }
-
-  delete [] values;
-}
-
-/* ----------------------------------------------------------------------
-   unpack n lines from atom-style specific section of data file
+   process N bonds read into buf from data files
+   if count is non-NULL, just count bonds per atom
+   else store them with atoms
    check that atom IDs are > 0 and <= map_tag_max
-   call style-specific routine to parse line
 ------------------------------------------------------------------------- */
 
-void Atom::data_bodies(int n, char *buf, AtomVecBody *avec_body)
+void Atom::data_bonds(int n, char *buf, int *count)
 {
-  int j,m,tagdata,ninteger,ndouble;
-
-  char **ivalues = new char*[10*MAXBODY];
-  char **dvalues = new char*[10*MAXBODY];
-
-  // loop over lines of body data
-  // tokenize the lines into ivalues and dvalues
-  // if I own atom tag, unpack its values
-
-  for (int i = 0; i < n; i++) {
-    if (i == 0) tagdata = atoi(strtok(buf," \t\n\r\f"));
-    else tagdata = atoi(strtok(NULL," \t\n\r\f"));
-    ninteger = atoi(strtok(NULL," \t\n\r\f"));
-    ndouble = atoi(strtok(NULL," \t\n\r\f"));
-
-    for (j = 0; j < ninteger; j++)
-      ivalues[j] = strtok(NULL," \t\n\r\f");
-    for (j = 0; j < ndouble; j++)
-      dvalues[j] = strtok(NULL," \t\n\r\f");
-
-    if (tagdata <= 0 || tagdata > map_tag_max)
-      error->one(FLERR,"Invalid atom ID in Bodies section of data file");
-
-    if ((m = map(tagdata)) >= 0)
-      avec_body->data_body(m,ninteger,ndouble,ivalues,dvalues);
-  }
-
-  delete [] ivalues;
-  delete [] dvalues;
-}
-
-/* ----------------------------------------------------------------------
-   check that atom IDs are > 0 and <= map_tag_max
-------------------------------------------------------------------------- */
-
-void Atom::data_bonds(int n, char *buf)
-{
-  int m,tmp,itype,atom1,atom2;
+  int m,tmp,itype;
+  tagint atom1,atom2;
   char *next;
   int newton_bond = force->newton_bond;
 
   for (int i = 0; i < n; i++) {
     next = strchr(buf,'\n');
     *next = '\0';
-    sscanf(buf,"%d %d %d %d",&tmp,&itype,&atom1,&atom2);
+    sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT,
+           &tmp,&itype,&atom1,&atom2);
     if (atom1 <= 0 || atom1 > map_tag_max ||
         atom2 <= 0 || atom2 > map_tag_max)
       error->one(FLERR,"Invalid atom ID in Bonds section of data file");
     if (itype <= 0 || itype > nbondtypes)
       error->one(FLERR,"Invalid bond type in Bonds section of data file");
     if ((m = map(atom1)) >= 0) {
-      bond_type[m][num_bond[m]] = itype;
-      bond_atom[m][num_bond[m]] = atom2;
-      num_bond[m]++;
+      if (count) count[m]++;
+      else {
+        bond_type[m][num_bond[m]] = itype;
+        bond_atom[m][num_bond[m]] = atom2;
+        num_bond[m]++;
+      }
     }
     if (newton_bond == 0) {
       if ((m = map(atom2)) >= 0) {
-        bond_type[m][num_bond[m]] = itype;
-        bond_atom[m][num_bond[m]] = atom1;
-        num_bond[m]++;
+        if (count) count[m]++;
+        else {
+          bond_type[m][num_bond[m]] = itype;
+          bond_atom[m][num_bond[m]] = atom1;
+          num_bond[m]++;
+        }
       }
     }
     buf = next + 1;
@@ -840,19 +825,24 @@ void Atom::data_bonds(int n, char *buf)
 }
 
 /* ----------------------------------------------------------------------
+   process N angles read into buf from data files
+   if count is non-NULL, just count angles per atom
+   else store them with atoms
    check that atom IDs are > 0 and <= map_tag_max
 ------------------------------------------------------------------------- */
 
-void Atom::data_angles(int n, char *buf)
+void Atom::data_angles(int n, char *buf, int *count)
 {
-  int m,tmp,itype,atom1,atom2,atom3;
+  int m,tmp,itype;
+  tagint atom1,atom2,atom3;
   char *next;
   int newton_bond = force->newton_bond;
 
   for (int i = 0; i < n; i++) {
     next = strchr(buf,'\n');
     *next = '\0';
-    sscanf(buf,"%d %d %d %d %d",&tmp,&itype,&atom1,&atom2,&atom3);
+    sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT,
+           &tmp,&itype,&atom1,&atom2,&atom3);
     if (atom1 <= 0 || atom1 > map_tag_max ||
         atom2 <= 0 || atom2 > map_tag_max ||
         atom3 <= 0 || atom3 > map_tag_max)
@@ -860,26 +850,35 @@ void Atom::data_angles(int n, char *buf)
     if (itype <= 0 || itype > nangletypes)
       error->one(FLERR,"Invalid angle type in Angles section of data file");
     if ((m = map(atom2)) >= 0) {
-      angle_type[m][num_angle[m]] = itype;
-      angle_atom1[m][num_angle[m]] = atom1;
-      angle_atom2[m][num_angle[m]] = atom2;
-      angle_atom3[m][num_angle[m]] = atom3;
-      num_angle[m]++;
-    }
-    if (newton_bond == 0) {
-      if ((m = map(atom1)) >= 0) {
+      if (count) count[m]++;
+      else {
         angle_type[m][num_angle[m]] = itype;
         angle_atom1[m][num_angle[m]] = atom1;
         angle_atom2[m][num_angle[m]] = atom2;
         angle_atom3[m][num_angle[m]] = atom3;
         num_angle[m]++;
       }
+    }
+    if (newton_bond == 0) {
+      if ((m = map(atom1)) >= 0) {
+        if (count) count[m]++;
+        else {
+          angle_type[m][num_angle[m]] = itype;
+          angle_atom1[m][num_angle[m]] = atom1;
+          angle_atom2[m][num_angle[m]] = atom2;
+          angle_atom3[m][num_angle[m]] = atom3;
+          num_angle[m]++;
+        }
+      }
       if ((m = map(atom3)) >= 0) {
-        angle_type[m][num_angle[m]] = itype;
-        angle_atom1[m][num_angle[m]] = atom1;
-        angle_atom2[m][num_angle[m]] = atom2;
-        angle_atom3[m][num_angle[m]] = atom3;
-        num_angle[m]++;
+        if (count) count[m]++;
+        else {
+          angle_type[m][num_angle[m]] = itype;
+          angle_atom1[m][num_angle[m]] = atom1;
+          angle_atom2[m][num_angle[m]] = atom2;
+          angle_atom3[m][num_angle[m]] = atom3;
+          num_angle[m]++;
+        }
       }
     }
     buf = next + 1;
@@ -887,19 +886,25 @@ void Atom::data_angles(int n, char *buf)
 }
 
 /* ----------------------------------------------------------------------
+   process N dihedrals read into buf from data files
+   if count is non-NULL, just count diihedrals per atom
+   else store them with atoms
    check that atom IDs are > 0 and <= map_tag_max
 ------------------------------------------------------------------------- */
 
-void Atom::data_dihedrals(int n, char *buf)
+void Atom::data_dihedrals(int n, char *buf, int *count)
 {
-  int m,tmp,itype,atom1,atom2,atom3,atom4;
+  int m,tmp,itype;
+  tagint atom1,atom2,atom3,atom4;
   char *next;
   int newton_bond = force->newton_bond;
 
   for (int i = 0; i < n; i++) {
     next = strchr(buf,'\n');
     *next = '\0';
-    sscanf(buf,"%d %d %d %d %d %d",&tmp,&itype,&atom1,&atom2,&atom3,&atom4);
+    sscanf(buf,"%d %d " 
+           TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT,
+           &tmp,&itype,&atom1,&atom2,&atom3,&atom4);
     if (atom1 <= 0 || atom1 > map_tag_max ||
         atom2 <= 0 || atom2 > map_tag_max ||
         atom3 <= 0 || atom3 > map_tag_max ||
@@ -909,15 +914,8 @@ void Atom::data_dihedrals(int n, char *buf)
       error->one(FLERR,
                  "Invalid dihedral type in Dihedrals section of data file");
     if ((m = map(atom2)) >= 0) {
-      dihedral_type[m][num_dihedral[m]] = itype;
-      dihedral_atom1[m][num_dihedral[m]] = atom1;
-      dihedral_atom2[m][num_dihedral[m]] = atom2;
-      dihedral_atom3[m][num_dihedral[m]] = atom3;
-      dihedral_atom4[m][num_dihedral[m]] = atom4;
-      num_dihedral[m]++;
-    }
-    if (newton_bond == 0) {
-      if ((m = map(atom1)) >= 0) {
+      if (count) count[m]++;
+      else {
         dihedral_type[m][num_dihedral[m]] = itype;
         dihedral_atom1[m][num_dihedral[m]] = atom1;
         dihedral_atom2[m][num_dihedral[m]] = atom2;
@@ -925,21 +923,40 @@ void Atom::data_dihedrals(int n, char *buf)
         dihedral_atom4[m][num_dihedral[m]] = atom4;
         num_dihedral[m]++;
       }
+    }
+    if (newton_bond == 0) {
+      if ((m = map(atom1)) >= 0) {
+        if (count) count[m]++;
+        else {
+          dihedral_type[m][num_dihedral[m]] = itype;
+          dihedral_atom1[m][num_dihedral[m]] = atom1;
+          dihedral_atom2[m][num_dihedral[m]] = atom2;
+          dihedral_atom3[m][num_dihedral[m]] = atom3;
+          dihedral_atom4[m][num_dihedral[m]] = atom4;
+          num_dihedral[m]++;
+        }
+      }
       if ((m = map(atom3)) >= 0) {
-        dihedral_type[m][num_dihedral[m]] = itype;
-        dihedral_atom1[m][num_dihedral[m]] = atom1;
-        dihedral_atom2[m][num_dihedral[m]] = atom2;
-        dihedral_atom3[m][num_dihedral[m]] = atom3;
-        dihedral_atom4[m][num_dihedral[m]] = atom4;
-        num_dihedral[m]++;
+        if (count) count[m]++;
+        else {
+          dihedral_type[m][num_dihedral[m]] = itype;
+          dihedral_atom1[m][num_dihedral[m]] = atom1;
+          dihedral_atom2[m][num_dihedral[m]] = atom2;
+          dihedral_atom3[m][num_dihedral[m]] = atom3;
+          dihedral_atom4[m][num_dihedral[m]] = atom4;
+          num_dihedral[m]++;
+        }
       }
       if ((m = map(atom4)) >= 0) {
-        dihedral_type[m][num_dihedral[m]] = itype;
-        dihedral_atom1[m][num_dihedral[m]] = atom1;
-        dihedral_atom2[m][num_dihedral[m]] = atom2;
-        dihedral_atom3[m][num_dihedral[m]] = atom3;
-        dihedral_atom4[m][num_dihedral[m]] = atom4;
-        num_dihedral[m]++;
+        if (count) count[m]++;
+        else {
+          dihedral_type[m][num_dihedral[m]] = itype;
+          dihedral_atom1[m][num_dihedral[m]] = atom1;
+          dihedral_atom2[m][num_dihedral[m]] = atom2;
+          dihedral_atom3[m][num_dihedral[m]] = atom3;
+          dihedral_atom4[m][num_dihedral[m]] = atom4;
+          num_dihedral[m]++;
+        }
       }
     }
     buf = next + 1;
@@ -947,19 +964,25 @@ void Atom::data_dihedrals(int n, char *buf)
 }
 
 /* ----------------------------------------------------------------------
+   process N impropers read into buf from data files
+   if count is non-NULL, just count impropers per atom
+   else store them with atoms
    check that atom IDs are > 0 and <= map_tag_max
 ------------------------------------------------------------------------- */
 
-void Atom::data_impropers(int n, char *buf)
+void Atom::data_impropers(int n, char *buf, int *count)
 {
-  int m,tmp,itype,atom1,atom2,atom3,atom4;
+  int m,tmp,itype;
+  tagint atom1,atom2,atom3,atom4;
   char *next;
   int newton_bond = force->newton_bond;
 
   for (int i = 0; i < n; i++) {
     next = strchr(buf,'\n');
     *next = '\0';
-    sscanf(buf,"%d %d %d %d %d %d",&tmp,&itype,&atom1,&atom2,&atom3,&atom4);
+    sscanf(buf,"%d %d " 
+           TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT,
+           &tmp,&itype,&atom1,&atom2,&atom3,&atom4);
     if (atom1 <= 0 || atom1 > map_tag_max ||
         atom2 <= 0 || atom2 > map_tag_max ||
         atom3 <= 0 || atom3 > map_tag_max ||
@@ -969,15 +992,8 @@ void Atom::data_impropers(int n, char *buf)
       error->one(FLERR,
                  "Invalid improper type in Impropers section of data file");
     if ((m = map(atom2)) >= 0) {
-      improper_type[m][num_improper[m]] = itype;
-      improper_atom1[m][num_improper[m]] = atom1;
-      improper_atom2[m][num_improper[m]] = atom2;
-      improper_atom3[m][num_improper[m]] = atom3;
-      improper_atom4[m][num_improper[m]] = atom4;
-      num_improper[m]++;
-    }
-    if (newton_bond == 0) {
-      if ((m = map(atom1)) >= 0) {
+      if (count) count[m]++;
+      else {
         improper_type[m][num_improper[m]] = itype;
         improper_atom1[m][num_improper[m]] = atom1;
         improper_atom2[m][num_improper[m]] = atom2;
@@ -985,27 +1001,132 @@ void Atom::data_impropers(int n, char *buf)
         improper_atom4[m][num_improper[m]] = atom4;
         num_improper[m]++;
       }
+    }
+    if (newton_bond == 0) {
+      if ((m = map(atom1)) >= 0) {
+        if (count) count[m]++;
+        else {
+          improper_type[m][num_improper[m]] = itype;
+          improper_atom1[m][num_improper[m]] = atom1;
+          improper_atom2[m][num_improper[m]] = atom2;
+          improper_atom3[m][num_improper[m]] = atom3;
+          improper_atom4[m][num_improper[m]] = atom4;
+          num_improper[m]++;
+        }
+      }
       if ((m = map(atom3)) >= 0) {
-        improper_type[m][num_improper[m]] = itype;
-        improper_atom1[m][num_improper[m]] = atom1;
-        improper_atom2[m][num_improper[m]] = atom2;
-        improper_atom3[m][num_improper[m]] = atom3;
-        improper_atom4[m][num_improper[m]] = atom4;
-        num_improper[m]++;
+        if (count) count[m]++;
+        else {
+          improper_type[m][num_improper[m]] = itype;
+          improper_atom1[m][num_improper[m]] = atom1;
+          improper_atom2[m][num_improper[m]] = atom2;
+          improper_atom3[m][num_improper[m]] = atom3;
+          improper_atom4[m][num_improper[m]] = atom4;
+          num_improper[m]++;
+        }
       }
       if ((m = map(atom4)) >= 0) {
-        improper_type[m][num_improper[m]] = itype;
-        improper_atom1[m][num_improper[m]] = atom1;
-        improper_atom2[m][num_improper[m]] = atom2;
-        improper_atom3[m][num_improper[m]] = atom3;
-        improper_atom4[m][num_improper[m]] = atom4;
-        num_improper[m]++;
+        if (count) count[m]++;
+        else {
+          improper_type[m][num_improper[m]] = itype;
+          improper_atom1[m][num_improper[m]] = atom1;
+          improper_atom2[m][num_improper[m]] = atom2;
+          improper_atom3[m][num_improper[m]] = atom3;
+          improper_atom4[m][num_improper[m]] = atom4;
+          num_improper[m]++;
+        }
       }
     }
     buf = next + 1;
   }
 }
 
+/* ----------------------------------------------------------------------
+   unpack n lines from atom-style specific section of data file
+   check that atom IDs are > 0 and <= map_tag_max
+   call style-specific routine to parse line
+------------------------------------------------------------------------- */
+
+void Atom::data_bonus(int n, char *buf, AtomVec *avec_bonus)
+{
+  int j,m,tagdata;
+  char *next;
+
+  next = strchr(buf,'\n');
+  *next = '\0';
+  int nwords = count_words(buf);
+  *next = '\n';
+
+  if (nwords != avec_bonus->size_data_bonus)
+    error->all(FLERR,"Incorrect bonus data format in data file");
+
+  char **values = new char*[nwords];
+
+  // loop over lines of bonus atom data
+  // tokenize the line into values
+  // if I own atom tag, unpack its values
+
+  for (int i = 0; i < n; i++) {
+    next = strchr(buf,'\n');
+
+    values[0] = strtok(buf," \t\n\r\f");
+    for (j = 1; j < nwords; j++)
+      values[j] = strtok(NULL," \t\n\r\f");
+
+    tagdata = ATOTAGINT(values[0]);
+    if (tagdata <= 0 || tagdata > map_tag_max)
+      error->one(FLERR,"Invalid atom ID in Bonus section of data file");
+
+    // ok to call child's data_atom_bonus() method thru parent avec_bonus,
+    // since data_bonus() was called with child ptr, and method is virtual
+
+    if ((m = map(tagdata)) >= 0) avec_bonus->data_atom_bonus(m,&values[1]);
+
+    buf = next + 1;
+  }
+
+  delete [] values;
+}
+
+/* ----------------------------------------------------------------------
+   unpack n lines from atom-style specific section of data file
+   check that atom IDs are > 0 and <= map_tag_max
+   call style-specific routine to parse line
+------------------------------------------------------------------------- */
+
+void Atom::data_bodies(int n, char *buf, AtomVecBody *avec_body)
+{
+  int j,m,tagdata,ninteger,ndouble;
+
+  char **ivalues = new char*[10*MAXBODY];
+  char **dvalues = new char*[10*MAXBODY];
+
+  // loop over lines of body data
+  // tokenize the lines into ivalues and dvalues
+  // if I own atom tag, unpack its values
+
+  for (int i = 0; i < n; i++) {
+    if (i == 0) tagdata = ATOTAGINT(strtok(buf," \t\n\r\f"));
+    else tagdata = ATOTAGINT(strtok(NULL," \t\n\r\f"));
+    ninteger = atoi(strtok(NULL," \t\n\r\f"));
+    ndouble = atoi(strtok(NULL," \t\n\r\f"));
+
+    for (j = 0; j < ninteger; j++)
+      ivalues[j] = strtok(NULL," \t\n\r\f");
+    for (j = 0; j < ndouble; j++)
+      dvalues[j] = strtok(NULL," \t\n\r\f");
+
+    if (tagdata <= 0 || tagdata > map_tag_max)
+      error->one(FLERR,"Invalid atom ID in Bodies section of data file");
+
+    if ((m = map(tagdata)) >= 0)
+      avec_body->data_body(m,ninteger,ndouble,ivalues,dvalues);
+  }
+
+  delete [] ivalues;
+  delete [] dvalues;
+}
+
 /* ----------------------------------------------------------------------
    allocate arrays of length ntypes
    only done after ntypes is set
@@ -1210,7 +1331,7 @@ int Atom::find_molecule(char *id)
 ------------------------------------------------------------------------- */
 
 void Atom::add_molecule_atom(Molecule *onemol, int iatom,
-                             int ilocal, int offset)
+                             int ilocal, tagint offset)
 {
   if (onemol->qflag) q[ilocal] = onemol->q[iatom];
   if (onemol->radiusflag) radius[ilocal] = onemol->radius[iatom];
@@ -1709,9 +1830,9 @@ bigint Atom::memory_usage()
   bigint bytes = avec->memory_usage();
   memory->destroy(memstr);
 
-  bytes += smax*sizeof(int);
+  bytes += max_same*sizeof(int);
   if (map_style == 1)
-    bytes += memory->usage(map_array,map_tag_max+1);
+    bytes += memory->usage(map_array,max_array);
   else if (map_style == 2) {
     bytes += map_nbucket*sizeof(int);
     bytes += map_nhash*sizeof(HashElem);
diff --git a/src/atom.h b/src/atom.h
index 3dfc010d5b556fcee021a14003074c3e363405cc..8a5a0b643f524e4e57a244f068a691bf37072041 100644
--- a/src/atom.h
+++ b/src/atom.h
@@ -45,7 +45,8 @@ class Atom : protected Pointers {
   // per-atom arrays
   // customize by adding new array
 
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
 
@@ -65,24 +66,24 @@ class Atom : protected Pointers {
   double *cv;
 
   int **nspecial;               // 0,1,2 = cummulative # of 1-2,1-3,1-4 neighs
-  int **special;                // IDs of 1-2,1-3,1-4 neighs of each atom
+  tagint **special;             // IDs of 1-2,1-3,1-4 neighs of each atom
   int maxspecial;               // special[nlocal][maxspecial]
 
   int *num_bond;
   int **bond_type;
-  int **bond_atom;
+  tagint **bond_atom;
 
   int *num_angle;
   int **angle_type;
-  int **angle_atom1,**angle_atom2,**angle_atom3;
+  tagint **angle_atom1,**angle_atom2,**angle_atom3;
 
   int *num_dihedral;
   int **dihedral_type;
-  int **dihedral_atom1,**dihedral_atom2,**dihedral_atom3,**dihedral_atom4;
+  tagint **dihedral_atom1,**dihedral_atom2,**dihedral_atom3,**dihedral_atom4;
 
   int *num_improper;
   int **improper_type;
-  int **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4;
+  tagint **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4;
 
   // custom arrays used by fix property/atom
 
@@ -133,9 +134,9 @@ class Atom : protected Pointers {
   int nextra_border_max;
   int nextra_store;
 
-  int map_style;                  // default or user-specified style of map
-                                  // 0 = none, 1 = array, 2 = hash
-  int map_tag_max;                // max atom ID that map() is setup for
+  int map_style;                  // style of atom map: 0=none, 1=array, 2=hash
+  int map_user;                   // user selected style = same 0,1,2
+  tagint map_tag_max;             // max atom ID that map() is setup for
 
   // spatial sorting of atoms
 
@@ -159,6 +160,7 @@ class Atom : protected Pointers {
 
   class AtomVec *style_match(const char *);
   void modify_params(int, char **);
+  void tag_check();
   void tag_extend();
   int tag_consecutive();
 
@@ -167,14 +169,15 @@ class Atom : protected Pointers {
 
   void data_atoms(int, char *);
   void data_vels(int, char *);
+
+  void data_bonds(int, char *, int *);
+  void data_angles(int, char *, int *);
+  void data_dihedrals(int, char *, int *);
+  void data_impropers(int, char *, int *);
+
   void data_bonus(int, char *, class AtomVec *);
   void data_bodies(int, char *, class AtomVecBody *);
 
-  void data_bonds(int, char *);
-  void data_angles(int, char *);
-  void data_dihedrals(int, char *);
-  void data_impropers(int, char *);
-
   void allocate_type_arrays();
   void set_mass(const char *);
   void set_mass(int, double);
@@ -187,7 +190,7 @@ class Atom : protected Pointers {
 
   void add_molecule(int, char **);
   int find_molecule(char *);
-  void add_molecule_atom(class Molecule *, int, int, int);
+  void add_molecule_atom(class Molecule *, int, int, tagint);
 
   void first_reorder();
   void sort();
@@ -212,7 +215,7 @@ class Atom : protected Pointers {
   // map lookup function inlined for efficiency
   // return -1 if no map defined
 
-  inline int map(int global) {
+  inline int map(tagint global) {
     if (map_style == 1) return map_array[global];
     else if (map_style == 2) return map_find_hash(global);
     else return -1;
@@ -221,28 +224,31 @@ class Atom : protected Pointers {
   void map_init();
   void map_clear();
   void map_set();
-  void map_one(int, int);
+  void map_one(tagint, int);
   void map_delete();
-  int map_find_hash(int);
+  int map_find_hash(tagint);
 
  private:
 
   // global to local ID mapping
 
   int *map_array;       // direct map of length map_tag_max + 1
-  int smax;             // max size of sametag
 
   struct HashElem {
-    int global;                   // key to search on = global ID
-    int local;                    // value associated with key = local index
-    int next;                     // next entry in this bucket, -1 if last
+    tagint global;      // key to search on = global ID
+    int local;          // value associated with key = local index
+    int next;           // next entry in this bucket, -1 if last
   };
-  int map_nhash;                  // # of entries hash table can hold
-  int map_nused;                  // # of actual entries in hash table
-  int map_free;                   // ptr to 1st unused entry in hash table
-  int map_nbucket;                // # of hash buckets
-  int *map_bucket;                // ptr to 1st entry in each bucket
-  HashElem *map_hash;             // hash table
+  int map_nhash;        // # of entries hash table can hold
+  int map_nused;        // # of actual entries in hash table
+  int map_free;         // ptr to 1st unused entry in hash table
+  int map_nbucket;      // # of hash buckets
+  int *map_bucket;      // ptr to 1st entry in each bucket
+  HashElem *map_hash;   // hash table
+
+  int max_array;        // allocated size of map_array (+1)
+  int max_nhash;        // allocated size of hash table
+  int max_same;         // allocated size of sametag
 
   // spatial sorting of atoms
 
diff --git a/src/atom_map.cpp b/src/atom_map.cpp
index 93c377b81ea8dbfe7997681543a5a23a5b5ea5d2..eab9b226f358964399f9f3498ffa360bc40c4f6a 100644
--- a/src/atom_map.cpp
+++ b/src/atom_map.cpp
@@ -25,61 +25,100 @@ using namespace LAMMPS_NS;
    allocate and initialize array or hash table for global -> local map
    set map_tag_max = largest atom ID (may be larger than natoms)
    for array option:
-     array length = 1 to largest tag of any atom
+     array length = 1 to map_tag_max
      set entire array to -1 as initial values
    for hash option:
      map_nhash = length of hash table
-     map_nbucket = # of hash buckets, prime larger than map_nhash
+     map_nbucket = # of hash buckets, prime larger than map_nhash * 2
        so buckets will only be filled with 0 or 1 atoms on average
 ------------------------------------------------------------------------- */
 
 void Atom::map_init()
 {
-  map_delete();
-
   if (tag_enable == 0)
     error->all(FLERR,"Cannot create an atom map unless atoms have IDs");
 
-  int max = 0;
-  for (int i = 0; i < nlocal; i++) max = MAX(max,tag[i]);
-  MPI_Allreduce(&max,&map_tag_max,1,MPI_INT,MPI_MAX,world);
-
-  memory->destroy(sametag);
-  smax = nlocal + nghost + EXTRA;
-  memory->create(sametag,smax,"atom:sametag");
-
-  if (map_style == 1) {
-    memory->create(map_array,map_tag_max+1,"atom:map_array");
-    for (int i = 0; i <= map_tag_max; i++) map_array[i] = -1;
-
-  } else {
-
-    // map_nhash = max # of atoms that can be hashed on this proc
-    // set to max of ave atoms/proc or atoms I can store
-    // multiply by 2, require at least 1000
-    // doubling means hash table will be re-init only rarely
+  int map_style_old = map_style;
 
-    int nper = static_cast<int> (natoms/comm->nprocs);
-    map_nhash = MAX(nper,nmax);
-    map_nhash *= 2;
-    map_nhash = MAX(map_nhash,1000);
+  // map_tag_max = max ID of any atom that will be in new map
 
-    // map_nbucket = prime just larger than map_nhash
-
-    map_nbucket = next_prime(map_nhash);
-
-    // set all buckets to empty
-    // set hash to map_nhash in length
-    // put all hash entries in free list and point them to each other
+  tagint max = 0;
+  for (int i = 0; i < nlocal; i++) max = MAX(max,tag[i]);
+  MPI_Allreduce(&max,&map_tag_max,1,MPI_LMP_TAGINT,MPI_MAX,world);
+
+  // set map_style for new map
+  // if user-selected, use that setting
+  // else if map_tag_max > 1M, use hash
+  // else use array
+  
+  if (map_user) map_style = map_user;
+  else if (map_tag_max > 1000000) map_style = 2;
+  else map_style = 1;
+
+  // recreate = 1 if must delete old map and create new map
+  // recreate = 0 if can re-use old map w/out realloc and just adjust settings
+
+  int recreate = 0;
+  if (map_style != map_style_old) recreate = 1;
+  else if (map_style == 1 && map_tag_max > max_array) recreate = 1;
+  else if (map_style == 2 && nlocal+nghost > map_nhash) recreate = 1;
+
+  // if not recreating:
+  // for array, just initialize current map_tag_max values
+  // for hash, set all buckets to empty, put all entries in free list 
+
+  if (!recreate) {
+    if (map_style == 1) {
+      for (int i = 0; i <= map_tag_max; i++) map_array[i] = -1;
+    } else {
+      for (int i = 0; i < map_nbucket; i++) map_bucket[i] = -1;
+      map_nused = 0;
+      map_free = 0;
+      for (int i = 0; i < map_nhash; i++) map_hash[i].next = i+1;
+      map_hash[map_nhash-1].next = -1;
+    }
 
-    map_bucket = new int[map_nbucket];
-    for (int i = 0; i < map_nbucket; i++) map_bucket[i] = -1;
+  // delete old map and create new one for array or hash
 
-    map_hash = new HashElem[map_nhash];
-    map_nused = 0;
-    map_free = 0;
-    for (int i = 0; i < map_nhash; i++) map_hash[i].next = i+1;
-    map_hash[map_nhash-1].next = -1;
+  } else {
+    map_delete();
+
+    if (map_style == 1) {
+      max_array = map_tag_max;
+      memory->create(map_array,max_array+1,"atom:map_array");
+      for (int i = 0; i <= map_tag_max; i++) map_array[i] = -1;
+      
+    } else {
+
+      // map_nhash = max # of atoms that can be hashed on this proc
+      // set to max of ave atoms/proc or atoms I can store
+      // multiply by 2, require at least 1000
+      // doubling means hash table will need to be re-init only rarely
+
+      int nper = static_cast<int> (natoms/comm->nprocs);
+      map_nhash = MAX(nper,nmax);
+      map_nhash *= 2;
+      map_nhash = MAX(map_nhash,1000);
+
+      // map_nbucket = prime just larger than map_nhash
+      // next_prime() should be fast enough,
+      //   about 10% of odd integers are prime above 1M
+
+      map_nbucket = next_prime(map_nhash);
+
+      // set all buckets to empty
+      // set hash to map_nhash in length
+      // put all hash entries in free list and point them to each other
+      
+      map_bucket = new int[map_nbucket];
+      for (int i = 0; i < map_nbucket; i++) map_bucket[i] = -1;
+
+      map_hash = new HashElem[map_nhash];
+      map_nused = 0;
+      map_free = 0;
+      for (int i = 0; i < map_nhash; i++) map_hash[i].next = i+1;
+      map_hash[map_nhash-1].next = -1;
+    }
   }
 }
 
@@ -99,7 +138,8 @@ void Atom::map_clear()
     }
 
   } else {
-    int previous,global,ibucket,index;
+    int previous,ibucket,index;
+    tagint global;
     int nall = nlocal + nghost;
     for (int i = 0; i < nall; i++) {
       sametag[i] = -1;
@@ -144,21 +184,37 @@ void Atom::map_clear()
 void Atom::map_set()
 {
   int nall = nlocal + nghost;
-  if (nall > smax) {
-    smax = nall + EXTRA;
-    memory->destroy(sametag);
-    memory->create(sametag,smax,"atom:sametag");
-  }
 
   if (map_style == 1) {
+
+    // possible reallocation of sametag must come before loop over atoms
+    // since loop sets sametag
+
+    if (nall > max_same) {
+      max_same = nall + EXTRA;
+      memory->destroy(sametag);
+      memory->create(sametag,max_same,"atom:sametag");
+    }
+
     for (int i = nall-1; i >= 0 ; i--) {
       sametag[i] = map_array[tag[i]];
       map_array[tag[i]] = i;
     }
 
   } else {
-    int previous,global,ibucket,index;
+
+    // possible reallocation of sametag must come after map_init()
+    // since map_init() will invoke map_delete(), whacking sametag
+
     if (nall > map_nhash) map_init();
+    if (nall > max_same) {
+      max_same = nall + EXTRA;
+      memory->destroy(sametag);
+      memory->create(sametag,max_same,"atom:sametag");
+    }
+
+    int previous,ibucket,index;
+    tagint global;
 
     for (int i = nall-1; i >= 0 ; i--) {
       sametag[i] = map_find_hash(tag[i]);
@@ -203,7 +259,7 @@ void Atom::map_set()
    called by Special class
 ------------------------------------------------------------------------- */
 
-void Atom::map_one(int global, int local)
+void Atom::map_one(tagint global, int local)
 {
   if (map_style == 1) map_array[global] = local;
   else {
@@ -246,6 +302,7 @@ void Atom::map_delete()
 {
   memory->destroy(sametag);
   sametag = NULL;
+  max_same = 0;
 
   if (map_style == 1) {
     memory->destroy(map_array);
@@ -259,7 +316,6 @@ void Atom::map_delete()
     }
     map_nhash = 0;
   }
-  map_tag_max = 0;
 }
 
 /* ----------------------------------------------------------------------
@@ -267,7 +323,7 @@ void Atom::map_delete()
    called by map() in atom.h
 ------------------------------------------------------------------------- */
 
-int Atom::map_find_hash(int global)
+int Atom::map_find_hash(tagint global)
 {
   int local = -1;
   int index = map_bucket[global % map_nbucket];
diff --git a/src/atom_vec.cpp b/src/atom_vec.cpp
index 04964d5d1c8d71a615caa110e8c506dbfa62eae0..fba68e808e08ec820d3741d0351c7ff900179b6a 100644
--- a/src/atom_vec.cpp
+++ b/src/atom_vec.cpp
@@ -82,7 +82,7 @@ void AtomVec::data_vel(int m, char **values)
 void AtomVec::pack_vel(double **buf)
 {
   double **v = atom->v;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
@@ -100,8 +100,8 @@ void AtomVec::pack_vel(double **buf)
 void AtomVec::write_vel(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %-1.16e %-1.16e %-1.16e\n",
-            (int) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3]);
+    fprintf(fp,TAGINT_FORMAT " %-1.16e %-1.16e %-1.16e\n",
+            (tagint) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3]);
 }
 
 /* ----------------------------------------------------------------------
@@ -111,12 +111,12 @@ void AtomVec::write_vel(FILE *fp, int n, double **buf)
    if bondtype is negative, flip back to positive
 ------------------------------------------------------------------------- */
 
-int AtomVec::pack_bond(int **buf)
+int AtomVec::pack_bond(tagint **buf)
 {
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *num_bond = atom->num_bond;
   int **bond_type = atom->bond_type;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
@@ -154,10 +154,11 @@ int AtomVec::pack_bond(int **buf)
    write bond info to data file
 ------------------------------------------------------------------------- */
 
-void AtomVec::write_bond(FILE *fp, int n, int **buf, int index)
+void AtomVec::write_bond(FILE *fp, int n, tagint **buf, int index)
 {
   for (int i = 0; i < n; i++) {
-    fprintf(fp,"%d %d %d %d\n",index,buf[i][0],buf[i][1],buf[i][2]);
+    fprintf(fp,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT "\n",
+            index,buf[i][0],buf[i][1],buf[i][2]);
     index++;
   }
 }
@@ -169,14 +170,14 @@ void AtomVec::write_bond(FILE *fp, int n, int **buf, int index)
    if angletype is negative, flip back to positive
 ------------------------------------------------------------------------- */
 
-int AtomVec::pack_angle(int **buf)
+int AtomVec::pack_angle(tagint **buf)
 {
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *num_angle = atom->num_angle;
   int **angle_type = atom->angle_type;
-  int **angle_atom1 = atom->angle_atom1;
-  int **angle_atom2 = atom->angle_atom2;
-  int **angle_atom3 = atom->angle_atom3;
+  tagint **angle_atom1 = atom->angle_atom1;
+  tagint **angle_atom2 = atom->angle_atom2;
+  tagint **angle_atom3 = atom->angle_atom3;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
@@ -216,11 +217,12 @@ int AtomVec::pack_angle(int **buf)
    write angle info to data file
 ------------------------------------------------------------------------- */
 
-void AtomVec::write_angle(FILE *fp, int n, int **buf, int index)
+void AtomVec::write_angle(FILE *fp, int n, tagint **buf, int index)
 {
   for (int i = 0; i < n; i++) {
-    fprintf(fp,"%d %d %d %d %d\n",index,
-            buf[i][0],buf[i][1],buf[i][2],buf[i][3]);
+    fprintf(fp,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " " 
+            TAGINT_FORMAT " " TAGINT_FORMAT "\n",
+            index,buf[i][0],buf[i][1],buf[i][2],buf[i][3]);
     index++;
   }
 }
@@ -229,15 +231,15 @@ void AtomVec::write_angle(FILE *fp, int n, int **buf, int index)
    pack dihedral info for data file
 ------------------------------------------------------------------------- */
 
-void AtomVec::pack_dihedral(int **buf)
+void AtomVec::pack_dihedral(tagint **buf)
 {
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *num_dihedral = atom->num_dihedral;
   int **dihedral_type = atom->dihedral_type;
-  int **dihedral_atom1 = atom->dihedral_atom1;
-  int **dihedral_atom2 = atom->dihedral_atom2;
-  int **dihedral_atom3 = atom->dihedral_atom3;
-  int **dihedral_atom4 = atom->dihedral_atom4;
+  tagint **dihedral_atom1 = atom->dihedral_atom1;
+  tagint **dihedral_atom2 = atom->dihedral_atom2;
+  tagint **dihedral_atom3 = atom->dihedral_atom3;
+  tagint **dihedral_atom4 = atom->dihedral_atom4;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
@@ -271,11 +273,12 @@ void AtomVec::pack_dihedral(int **buf)
    write dihedral info to data file
 ------------------------------------------------------------------------- */
 
-void AtomVec::write_dihedral(FILE *fp, int n, int **buf, int index)
+void AtomVec::write_dihedral(FILE *fp, int n, tagint **buf, int index)
 {
   for (int i = 0; i < n; i++) {
-    fprintf(fp,"%d %d %d %d %d %d\n",index,
-            buf[i][0],buf[i][1],buf[i][2],buf[i][3],buf[i][4]);
+    fprintf(fp,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " " 
+            TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT "\n",
+            index,buf[i][0],buf[i][1],buf[i][2],buf[i][3],buf[i][4]);
     index++;
   }
 }
@@ -284,15 +287,15 @@ void AtomVec::write_dihedral(FILE *fp, int n, int **buf, int index)
    pack improper info for data file
 ------------------------------------------------------------------------- */
 
-void AtomVec::pack_improper(int **buf)
+void AtomVec::pack_improper(tagint **buf)
 {
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *num_improper = atom->num_improper;
   int **improper_type = atom->improper_type;
-  int **improper_atom1 = atom->improper_atom1;
-  int **improper_atom2 = atom->improper_atom2;
-  int **improper_atom3 = atom->improper_atom3;
-  int **improper_atom4 = atom->improper_atom4;
+  tagint **improper_atom1 = atom->improper_atom1;
+  tagint **improper_atom2 = atom->improper_atom2;
+  tagint **improper_atom3 = atom->improper_atom3;
+  tagint **improper_atom4 = atom->improper_atom4;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
@@ -326,11 +329,12 @@ void AtomVec::pack_improper(int **buf)
    write improper info to data file
 ------------------------------------------------------------------------- */
 
-void AtomVec::write_improper(FILE *fp, int n, int **buf, int index)
+void AtomVec::write_improper(FILE *fp, int n, tagint **buf, int index)
 {
   for (int i = 0; i < n; i++) {
-    fprintf(fp,"%d %d %d %d %d %d\n",index,
-            buf[i][0],buf[i][1],buf[i][2],buf[i][3],buf[i][4]);
+    fprintf(fp,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " " 
+            TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT "\n",
+            index,buf[i][0],buf[i][1],buf[i][2],buf[i][3],buf[i][4]);
     index++;
   }
 }
diff --git a/src/atom_vec.h b/src/atom_vec.h
index 0d0ba775f5515eedb3ff4733580437a4b9d3df19..b9683d38fbef29bc380bd439905cfb340003d699 100644
--- a/src/atom_vec.h
+++ b/src/atom_vec.h
@@ -99,14 +99,14 @@ class AtomVec : protected Pointers {
   virtual int write_vel_hybrid(FILE *, double *) {return 0;}
 
   void reset();
-  int pack_bond(int **);
-  void write_bond(FILE *, int, int **, int);
-  int pack_angle(int **);
-  void write_angle(FILE *, int, int **, int);
-  void pack_dihedral(int **);
-  void write_dihedral(FILE *, int, int **, int);
-  void pack_improper(int **);
-  void write_improper(FILE *, int, int **, int);
+  int pack_bond(tagint **);
+  void write_bond(FILE *, int, tagint **, int);
+  int pack_angle(tagint **);
+  void write_angle(FILE *, int, tagint **, int);
+  void pack_dihedral(tagint **);
+  void write_dihedral(FILE *, int, tagint **, int);
+  void pack_improper(tagint **);
+  void write_improper(FILE *, int, tagint **, int);
 
   virtual bigint memory_usage() = 0;
 
@@ -128,8 +128,8 @@ class AtomVec : protected Pointers {
   //   the cast prevents compiler warnings about possible truncation
 
   union ubuf {
-    double   d;
-    int64_t  i;
+    double d;
+    int64_t i;
     ubuf(double arg) : d(arg) {}
     ubuf(int64_t arg) : i(arg) {}
     ubuf(int arg) : i(arg) {}
diff --git a/src/atom_vec_atomic.cpp b/src/atom_vec_atomic.cpp
index f27178b8fd0084f141d1ddbb4f001740799e5e21..5d96dc139e39124cf02a9cb9594b0f9e5e6d226c 100644
--- a/src/atom_vec_atomic.cpp
+++ b/src/atom_vec_atomic.cpp
@@ -402,7 +402,7 @@ void AtomVecAtomic::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
   }
@@ -426,7 +426,7 @@ void AtomVecAtomic::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     v[i][0] = buf[m++];
@@ -481,7 +481,7 @@ int AtomVecAtomic::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -560,7 +560,7 @@ int AtomVecAtomic::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -613,10 +613,7 @@ void AtomVecAtomic::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -661,8 +658,8 @@ void AtomVecAtomic::pack_data(double **buf)
 void AtomVecAtomic::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             buf[i][2],buf[i][3],buf[i][4],
             (int) ubuf(buf[i][5]).i,(int) ubuf(buf[i][6]).i,
             (int) ubuf(buf[i][7]).i);
diff --git a/src/atom_vec_atomic.h b/src/atom_vec_atomic.h
index b19ecdd85cee948aeb0bc50222eb07401994a08c..86914f760ba6cc4c473410b9bc71194c8159d02b 100644
--- a/src/atom_vec_atomic.h
+++ b/src/atom_vec_atomic.h
@@ -53,7 +53,8 @@ class AtomVecAtomic : public AtomVec {
   bigint memory_usage();
 
  protected:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
 };
diff --git a/src/atom_vec_body.cpp b/src/atom_vec_body.cpp
index b91ecdde9c8b2325ee80469773b6a9abf540a85d..429ac3913707bf1ff14b39990113ea382a289d76 100644
--- a/src/atom_vec_body.cpp
+++ b/src/atom_vec_body.cpp
@@ -834,7 +834,7 @@ void AtomVecBody::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     body[i] = (int) ubuf(buf[m++]).i;
@@ -882,7 +882,7 @@ void AtomVecBody::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     body[i] = (int) ubuf(buf[m++]).i;
@@ -1027,7 +1027,7 @@ int AtomVecBody::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -1176,7 +1176,7 @@ int AtomVecBody::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -1305,10 +1305,7 @@ void AtomVecBody::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -1442,8 +1439,8 @@ int AtomVecBody::pack_data_hybrid(int i, double *buf)
 void AtomVecBody::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %d %g %g %g %g %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT " %d %d %g %g %g %g %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             (int) ubuf(buf[i][2]).i,
             buf[i][3],buf[i][4],buf[i][5],buf[i][6],
             (int) ubuf(buf[i][7]).i,(int) ubuf(buf[i][8]).i,
@@ -1497,8 +1494,8 @@ int AtomVecBody::pack_vel_hybrid(int i, double *buf)
 void AtomVecBody::write_vel(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %g %g %g %g %g %g\n",
-            (int) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],
+    fprintf(fp,TAGINT_FORMAT " %g %g %g %g %g %g\n",
+            (tagint) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],
             buf[i][4],buf[i][5],buf[i][6]);
 }
 
diff --git a/src/atom_vec_body.h b/src/atom_vec_body.h
index aad592fe4d0393282872f6e213204a3054965fc3..c16be4e2c8c4e0a496a806eb2fcf8b25e9d73e96 100644
--- a/src/atom_vec_body.h
+++ b/src/atom_vec_body.h
@@ -90,7 +90,8 @@ class AtomVecBody : public AtomVec {
   void data_body(int, int, int, char **, char **);
 
  private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   double *rmass;
diff --git a/src/atom_vec_charge.cpp b/src/atom_vec_charge.cpp
index 38b4385c9b13096e8c1d79b634e2231362984b91..d8b4b7430c4e3c2482dd61612ed31006104eacdf 100644
--- a/src/atom_vec_charge.cpp
+++ b/src/atom_vec_charge.cpp
@@ -428,7 +428,7 @@ void AtomVecCharge::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     q[i] = buf[m++];
@@ -453,7 +453,7 @@ void AtomVecCharge::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     q[i] = buf[m++];
@@ -524,7 +524,7 @@ int AtomVecCharge::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -607,7 +607,7 @@ int AtomVecCharge::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -664,10 +664,7 @@ void AtomVecCharge::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -737,8 +734,8 @@ int AtomVecCharge::pack_data_hybrid(int i, double *buf)
 void AtomVecCharge::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             buf[i][2],buf[i][3],buf[i][4],buf[i][5],
             (int) ubuf(buf[i][6]).i,(int) ubuf(buf[i][7]).i,
             (int) ubuf(buf[i][8]).i);
diff --git a/src/atom_vec_charge.h b/src/atom_vec_charge.h
index ac36ab943926f39abd832b864e2a0b156a96c171..3e019d21e390b6b07fc53790716527e7e29b1f48 100644
--- a/src/atom_vec_charge.h
+++ b/src/atom_vec_charge.h
@@ -58,7 +58,8 @@ class AtomVecCharge : public AtomVec {
   bigint memory_usage();
 
  protected:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   double *q;
diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp
index 2eda8b0e6aab02e0af3f18e356a30cc9596b8f34..512f3ba74b51d20d0751ba2937edfe56fdec5228 100755
--- a/src/atom_vec_ellipsoid.cpp
+++ b/src/atom_vec_ellipsoid.cpp
@@ -768,7 +768,7 @@ void AtomVecEllipsoid::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     ellipsoid[i] = (int) ubuf(buf[m++]).i;
@@ -811,7 +811,7 @@ void AtomVecEllipsoid::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     ellipsoid[i] = (int) ubuf(buf[m++]).i;
@@ -939,7 +939,7 @@ int AtomVecEllipsoid::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -1061,7 +1061,7 @@ int AtomVecEllipsoid::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -1143,10 +1143,7 @@ void AtomVecEllipsoid::data_atom(double *coord, imageint imagetmp,
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -1307,8 +1304,9 @@ int AtomVecEllipsoid::pack_data_hybrid(int i, double *buf)
 void AtomVecEllipsoid::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT 
+            " %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             (int) ubuf(buf[i][2]).i,
             buf[i][3],buf[i][4],buf[i][5],buf[i][6],
             (int) ubuf(buf[i][7]).i,(int) ubuf(buf[i][8]).i,
@@ -1362,8 +1360,9 @@ int AtomVecEllipsoid::pack_vel_hybrid(int i, double *buf)
 void AtomVecEllipsoid::write_vel(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n",
-            (int) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],
+    fprintf(fp,TAGINT_FORMAT 
+            " %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n",
+            (tagint) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],
             buf[i][4],buf[i][5],buf[i][6]);
 }
 
diff --git a/src/atom_vec_ellipsoid.h b/src/atom_vec_ellipsoid.h
index b23597e35aa03acf88c04d22eac9a7fb3926112d..cc8ba2e85de86fc6e48790e0e6431c9173951906 100755
--- a/src/atom_vec_ellipsoid.h
+++ b/src/atom_vec_ellipsoid.h
@@ -84,7 +84,8 @@ class AtomVecEllipsoid : public AtomVec {
   void set_shape(int, double, double, double);
 
  private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   double *rmass;
diff --git a/src/atom_vec_hybrid.cpp b/src/atom_vec_hybrid.cpp
index 710d15e2bd4838d9b0fd46ce7d6464d3b4bb7ede..d88f67a8543079662bda6e3c4694a86aea5f9f44 100644
--- a/src/atom_vec_hybrid.cpp
+++ b/src/atom_vec_hybrid.cpp
@@ -616,7 +616,7 @@ void AtomVecHybrid::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
   }
@@ -647,7 +647,7 @@ void AtomVecHybrid::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     v[i][0] = buf[m++];
@@ -864,10 +864,7 @@ void AtomVecHybrid::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -954,8 +951,8 @@ void AtomVecHybrid::write_data(FILE *fp, int n, double **buf)
   int k,m;
 
   for (int i = 0; i < n; i++) {
-    fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT " %d %-1.16e %-1.16e %-1.16e",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             buf[i][2],buf[i][3],buf[i][4]);
 
     m = 5;
@@ -998,8 +995,8 @@ void AtomVecHybrid::write_vel(FILE *fp, int n, double **buf)
   int k,m;
 
   for (int i = 0; i < n; i++) {
-    fprintf(fp,"%d %g %g %g",
-            (int) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3]);
+    fprintf(fp,TAGINT_FORMAT " %g %g %g",
+            (tagint) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3]);
 
     m = 4;
     for (k = 0; k < nstyles; k++)
diff --git a/src/atom_vec_hybrid.h b/src/atom_vec_hybrid.h
index 016a1316807e28a5df249fcb946cb47561e9ba7e..2a5113d4d8666cfe0b20d4c664ad1405c1aebbe3 100644
--- a/src/atom_vec_hybrid.h
+++ b/src/atom_vec_hybrid.h
@@ -67,7 +67,8 @@ class AtomVecHybrid : public AtomVec {
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   double **omega,**angmom;
diff --git a/src/atom_vec_line.cpp b/src/atom_vec_line.cpp
index f8785eed9f4c6e0b27b5d0fb5b64984f2f24e084..5c89d237fc7ec51e68927b1c654fe3c86dcec1c3 100644
--- a/src/atom_vec_line.cpp
+++ b/src/atom_vec_line.cpp
@@ -666,7 +666,7 @@ void AtomVecLine::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     molecule[i] = (int) ubuf(buf[m++]).i;
@@ -702,7 +702,7 @@ void AtomVecLine::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     molecule[i] = (int) ubuf(buf[m++]).i;
@@ -811,7 +811,7 @@ int AtomVecLine::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -923,7 +923,7 @@ int AtomVecLine::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -999,12 +999,8 @@ void AtomVecLine::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   molecule[nlocal] = atoi(values[1]);
-
   type[nlocal] = atoi(values[2]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -1170,8 +1166,9 @@ int AtomVecLine::pack_data_hybrid(int i, double *buf)
 void AtomVecLine::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT 
+            " %d %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             (int) ubuf(buf[i][2]).i,(int) ubuf(buf[i][3]).i,
             buf[i][4],buf[i][5],buf[i][6],buf[i][7],
             (int) ubuf(buf[i][8]).i,(int) ubuf(buf[i][9]).i,
@@ -1225,8 +1222,9 @@ int AtomVecLine::pack_vel_hybrid(int i, double *buf)
 void AtomVecLine::write_vel(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n",
-            (int) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],
+    fprintf(fp,TAGINT_FORMAT 
+            " %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n",
+            (tagint) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],
             buf[i][4],buf[i][5],buf[i][6]);
 }
 
diff --git a/src/atom_vec_line.h b/src/atom_vec_line.h
index b266c91f364320130f25d5d4776e8482f1611e0f..8aec9ea8d1df76c3cf92a9eaf0eaee80f6dab56e 100644
--- a/src/atom_vec_line.h
+++ b/src/atom_vec_line.h
@@ -84,7 +84,8 @@ class AtomVecLine : public AtomVec {
   void set_length(int, double);
 
  private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   int *molecule;
diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp
index c1d7e3a1d824327b13eadcbf24acae02f3b03aab..acb12519816669edeadb481728149f2c4725acd1 100644
--- a/src/atom_vec_sphere.cpp
+++ b/src/atom_vec_sphere.cpp
@@ -702,7 +702,7 @@ void AtomVecSphere::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     radius[i] = buf[m++];
@@ -729,7 +729,7 @@ void AtomVecSphere::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     radius[i] = buf[m++];
@@ -810,7 +810,7 @@ int AtomVecSphere::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -901,7 +901,7 @@ int AtomVecSphere::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -966,10 +966,7 @@ void AtomVecSphere::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -1095,8 +1092,9 @@ int AtomVecSphere::pack_data_hybrid(int i, double *buf)
 void AtomVecSphere::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT 
+            " %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             buf[i][2],buf[i][3],
             buf[i][4],buf[i][5],buf[i][6],
             (int) ubuf(buf[i][7]).i,(int) ubuf(buf[i][8]).i,
@@ -1150,8 +1148,9 @@ int AtomVecSphere::pack_vel_hybrid(int i, double *buf)
 void AtomVecSphere::write_vel(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n",
-            (int) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],
+    fprintf(fp,TAGINT_FORMAT 
+            " %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n",
+            (tagint) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],
             buf[i][4],buf[i][5],buf[i][6]);
 }
 
diff --git a/src/atom_vec_sphere.h b/src/atom_vec_sphere.h
index b1600625fa8fa0dc67237871fd2b16bc253d13a4..e7ba894e592ffd8d7d077774bb911ab25bb69fe2 100644
--- a/src/atom_vec_sphere.h
+++ b/src/atom_vec_sphere.h
@@ -69,7 +69,8 @@ class AtomVecSphere : public AtomVec {
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   double *radius,*density,*rmass;
diff --git a/src/atom_vec_tri.cpp b/src/atom_vec_tri.cpp
index 591ad3197649a6da87a079735f752aaeb400ad38..d170c8b5d0efa1ff28881b1bd836a9c3f7d2c2e9 100644
--- a/src/atom_vec_tri.cpp
+++ b/src/atom_vec_tri.cpp
@@ -882,7 +882,7 @@ void AtomVecTri::unpack_border(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     molecule[i] = (int) ubuf(buf[m++]).i;
@@ -938,7 +938,7 @@ void AtomVecTri::unpack_border_vel(int n, int first, double *buf)
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
-    tag[i] = (int) ubuf(buf[m++]).i;
+    tag[i] = (tagint) ubuf(buf[m++]).i;
     type[i] = (int) ubuf(buf[m++]).i;
     mask[i] = (int) ubuf(buf[m++]).i;
     molecule[i] = (int) ubuf(buf[m++]).i;
@@ -1105,7 +1105,7 @@ int AtomVecTri::unpack_exchange(double *buf)
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -1255,7 +1255,7 @@ int AtomVecTri::unpack_restart(double *buf)
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
-  tag[nlocal] = (int) ubuf(buf[m++]).i;
+  tag[nlocal] = (tagint) ubuf(buf[m++]).i;
   type[nlocal] = (int) ubuf(buf[m++]).i;
   mask[nlocal] = (int) ubuf(buf[m++]).i;
   image[nlocal] = (imageint) ubuf(buf[m++]).i;
@@ -1350,12 +1350,8 @@ void AtomVecTri::data_atom(double *coord, imageint imagetmp, char **values)
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
-  tag[nlocal] = atoi(values[0]);
-  if (tag[nlocal] <= 0)
-    error->one(FLERR,"Invalid atom ID in Atoms section of data file");
-
+  tag[nlocal] = ATOTAGINT(values[0]);
   molecule[nlocal] = atoi(values[1]);
-
   type[nlocal] = atoi(values[2]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one(FLERR,"Invalid atom type in Atoms section of data file");
@@ -1618,8 +1614,9 @@ int AtomVecTri::pack_data_hybrid(int i, double *buf)
 void AtomVecTri::write_data(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %d %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
-            (int) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
+    fprintf(fp,TAGINT_FORMAT 
+            " %d %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d\n",
+            (tagint) ubuf(buf[i][0]).i,(int) ubuf(buf[i][1]).i,
             (int) ubuf(buf[i][2]).i,(int) ubuf(buf[i][3]).i,
             buf[i][4],buf[i][5],buf[i][6],buf[i][7],
             (int) ubuf(buf[i][8]).i,(int) ubuf(buf[i][9]).i,
@@ -1673,8 +1670,9 @@ int AtomVecTri::pack_vel_hybrid(int i, double *buf)
 void AtomVecTri::write_vel(FILE *fp, int n, double **buf)
 {
   for (int i = 0; i < n; i++)
-    fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n",
-            (int) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],
+    fprintf(fp,TAGINT_FORMAT 
+            " %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e\n",
+            (tagint) ubuf(buf[i][0]).i,buf[i][1],buf[i][2],buf[i][3],
             buf[i][4],buf[i][5],buf[i][6]);
 }
 
diff --git a/src/atom_vec_tri.h b/src/atom_vec_tri.h
index c0c5b35ae01286a799e051a320cfbd96d8c59977..cf4af31cc27ba53371564f94da00421edbe08cb6 100644
--- a/src/atom_vec_tri.h
+++ b/src/atom_vec_tri.h
@@ -86,7 +86,8 @@ class AtomVecTri : public AtomVec {
   void set_equilateral(int, double);
 
  private:
-  int *tag,*type,*mask;
+  tagint *tag;
+  int *type,*mask;
   imageint *image;
   double **x,**v,**f;
   int *molecule;
diff --git a/src/compute_angle_local.cpp b/src/compute_angle_local.cpp
index 626fc7df84b1f13be01869576f7e577a49c2aa50..6e2cd57322040f126ab927a6f81dc86ff7656b20 100644
--- a/src/compute_angle_local.cpp
+++ b/src/compute_angle_local.cpp
@@ -116,11 +116,11 @@ int ComputeAngleLocal::compute_angles(int flag)
 
   double **x = atom->x;
   int *num_angle = atom->num_angle;
-  int **angle_atom1 = atom->angle_atom1;
-  int **angle_atom2 = atom->angle_atom2;
-  int **angle_atom3 = atom->angle_atom3;
+  tagint **angle_atom1 = atom->angle_atom1;
+  tagint **angle_atom2 = atom->angle_atom2;
+  tagint **angle_atom3 = atom->angle_atom3;
   int **angle_type = atom->angle_type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
diff --git a/src/compute_bond_local.cpp b/src/compute_bond_local.cpp
index 344157eec434136606c74fc9618922d7cb6422dd..ad6697e0488189e6377b3605dcc2f9294dc83247 100644
--- a/src/compute_bond_local.cpp
+++ b/src/compute_bond_local.cpp
@@ -122,9 +122,9 @@ int ComputeBondLocal::compute_bonds(int flag)
 
   double **x = atom->x;
   int *num_bond = atom->num_bond;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
   int **bond_type = atom->bond_type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
diff --git a/src/compute_cluster_atom.cpp b/src/compute_cluster_atom.cpp
index 030090dcb2dcecff874f30729b62b9a4eddb730d..b1713873b2cba4a18e663c88b85d1c12b5080eda 100644
--- a/src/compute_cluster_atom.cpp
+++ b/src/compute_cluster_atom.cpp
@@ -120,7 +120,7 @@ void ComputeClusterAtom::compute_peratom()
 
   // every atom starts in its own cluster, with clusterID = atomID
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
 
   for (ii = 0; ii < inum; ii++) {
diff --git a/src/compute_dihedral_local.cpp b/src/compute_dihedral_local.cpp
index e0f600521c1866523ac874a4fc8ee5da2d9e5d39..438f665da69ee434ab7516ab9f6f88416d328ce8 100644
--- a/src/compute_dihedral_local.cpp
+++ b/src/compute_dihedral_local.cpp
@@ -115,11 +115,11 @@ int ComputeDihedralLocal::compute_dihedrals(int flag)
 
   double **x = atom->x;
   int *num_dihedral = atom->num_dihedral;
-  int **dihedral_atom1 = atom->dihedral_atom1;
-  int **dihedral_atom2 = atom->dihedral_atom2;
-  int **dihedral_atom3 = atom->dihedral_atom3;
-  int **dihedral_atom4 = atom->dihedral_atom4;
-  int *tag = atom->tag;
+  tagint **dihedral_atom1 = atom->dihedral_atom1;
+  tagint **dihedral_atom2 = atom->dihedral_atom2;
+  tagint **dihedral_atom3 = atom->dihedral_atom3;
+  tagint **dihedral_atom4 = atom->dihedral_atom4;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
diff --git a/src/compute_improper_local.cpp b/src/compute_improper_local.cpp
index 862169fbbc9557c7b9fffb68a37d5d738a5da996..4e66856df302cf715d22ccb9be3e18ac92f78316 100644
--- a/src/compute_improper_local.cpp
+++ b/src/compute_improper_local.cpp
@@ -116,11 +116,11 @@ int ComputeImproperLocal::compute_impropers(int flag)
 
   double **x = atom->x;
   int *num_improper = atom->num_improper;
-  int **improper_atom1 = atom->improper_atom1;
-  int **improper_atom2 = atom->improper_atom2;
-  int **improper_atom3 = atom->improper_atom3;
-  int **improper_atom4 = atom->improper_atom4;
-  int *tag = atom->tag;
+  tagint **improper_atom1 = atom->improper_atom1;
+  tagint **improper_atom2 = atom->improper_atom2;
+  tagint **improper_atom3 = atom->improper_atom3;
+  tagint **improper_atom4 = atom->improper_atom4;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp
index 9b3dc754bcad66fe9aa401927e3ad6bf873071f8..250451950ea8384c0db602ba023cbb4b70a49111 100644
--- a/src/compute_property_atom.cpp
+++ b/src/compute_property_atom.cpp
@@ -434,7 +434,7 @@ double ComputePropertyAtom::memory_usage()
 
 void ComputePropertyAtom::pack_id(int n)
 {
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
diff --git a/src/compute_property_local.cpp b/src/compute_property_local.cpp
index fa1fbbabde547f289f4d1dc92c7e6d92b6fc382a..b9fc3ab4d09268ebe49e80af83d1c64c340bc61b 100644
--- a/src/compute_property_local.cpp
+++ b/src/compute_property_local.cpp
@@ -334,7 +334,6 @@ int ComputePropertyLocal::count_pairs(int allflag, int forceflag)
   int *ilist,*jlist,*numneigh,**firstneigh;
 
   double **x = atom->x;
-  int *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
@@ -407,9 +406,9 @@ int ComputePropertyLocal::count_bonds(int flag)
   int i,atom1,atom2;
 
   int *num_bond = atom->num_bond;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
   int **bond_type = atom->bond_type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
@@ -448,11 +447,11 @@ int ComputePropertyLocal::count_angles(int flag)
   int i,atom1,atom2,atom3;
 
   int *num_angle = atom->num_angle;
-  int **angle_atom1 = atom->angle_atom1;
-  int **angle_atom2 = atom->angle_atom2;
-  int **angle_atom3 = atom->angle_atom3;
+  tagint **angle_atom1 = atom->angle_atom1;
+  tagint **angle_atom2 = atom->angle_atom2;
+  tagint **angle_atom3 = atom->angle_atom3;
   int **angle_type = atom->angle_type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -490,11 +489,11 @@ int ComputePropertyLocal::count_dihedrals(int flag)
   int i,atom1,atom2,atom3,atom4;
 
   int *num_dihedral = atom->num_dihedral;
-  int **dihedral_atom1 = atom->dihedral_atom1;
-  int **dihedral_atom2 = atom->dihedral_atom2;
-  int **dihedral_atom3 = atom->dihedral_atom3;
-  int **dihedral_atom4 = atom->dihedral_atom4;
-  int *tag = atom->tag;
+  tagint **dihedral_atom1 = atom->dihedral_atom1;
+  tagint **dihedral_atom2 = atom->dihedral_atom2;
+  tagint **dihedral_atom3 = atom->dihedral_atom3;
+  tagint **dihedral_atom4 = atom->dihedral_atom4;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -533,11 +532,11 @@ int ComputePropertyLocal::count_impropers(int flag)
   int i,atom1,atom2,atom3,atom4;
 
   int *num_improper = atom->num_improper;
-  int **improper_atom1 = atom->improper_atom1;
-  int **improper_atom2 = atom->improper_atom2;
-  int **improper_atom3 = atom->improper_atom3;
-  int **improper_atom4 = atom->improper_atom4;
-  int *tag = atom->tag;
+  tagint **improper_atom1 = atom->improper_atom1;
+  tagint **improper_atom2 = atom->improper_atom2;
+  tagint **improper_atom3 = atom->improper_atom3;
+  tagint **improper_atom4 = atom->improper_atom4;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -607,7 +606,7 @@ double ComputePropertyLocal::memory_usage()
 void ComputePropertyLocal::pack_patom1(int n)
 {
   int i;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -621,7 +620,7 @@ void ComputePropertyLocal::pack_patom1(int n)
 void ComputePropertyLocal::pack_patom2(int n)
 {
   int i;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][1];
@@ -663,7 +662,7 @@ void ComputePropertyLocal::pack_ptype2(int n)
 void ComputePropertyLocal::pack_batom1(int n)
 {
   int i;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -677,7 +676,7 @@ void ComputePropertyLocal::pack_batom1(int n)
 void ComputePropertyLocal::pack_batom2(int n)
 {
   int i,j;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -707,7 +706,7 @@ void ComputePropertyLocal::pack_btype(int n)
 void ComputePropertyLocal::pack_aatom1(int n)
 {
   int i,j;
-  int **angle_atom1 = atom->angle_atom1;
+  tagint **angle_atom1 = atom->angle_atom1;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -722,7 +721,7 @@ void ComputePropertyLocal::pack_aatom1(int n)
 void ComputePropertyLocal::pack_aatom2(int n)
 {
   int i,j;
-  int **angle_atom2 = atom->angle_atom2;
+  tagint **angle_atom2 = atom->angle_atom2;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -737,7 +736,7 @@ void ComputePropertyLocal::pack_aatom2(int n)
 void ComputePropertyLocal::pack_aatom3(int n)
 {
   int i,j;
-  int **angle_atom3 = atom->angle_atom3;
+  tagint **angle_atom3 = atom->angle_atom3;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -767,7 +766,7 @@ void ComputePropertyLocal::pack_atype(int n)
 void ComputePropertyLocal::pack_datom1(int n)
 {
   int i,j;
-  int **dihedral_atom1 = atom->dihedral_atom1;
+  tagint **dihedral_atom1 = atom->dihedral_atom1;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -782,7 +781,7 @@ void ComputePropertyLocal::pack_datom1(int n)
 void ComputePropertyLocal::pack_datom2(int n)
 {
   int i,j;
-  int **dihedral_atom2 = atom->dihedral_atom2;
+  tagint **dihedral_atom2 = atom->dihedral_atom2;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -797,7 +796,7 @@ void ComputePropertyLocal::pack_datom2(int n)
 void ComputePropertyLocal::pack_datom3(int n)
 {
   int i,j;
-  int **dihedral_atom3 = atom->dihedral_atom3;
+  tagint **dihedral_atom3 = atom->dihedral_atom3;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -812,7 +811,7 @@ void ComputePropertyLocal::pack_datom3(int n)
 void ComputePropertyLocal::pack_datom4(int n)
 {
   int i,j;
-  int **dihedral_atom4 = atom->dihedral_atom4;
+  tagint **dihedral_atom4 = atom->dihedral_atom4;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -842,7 +841,7 @@ void ComputePropertyLocal::pack_dtype(int n)
 void ComputePropertyLocal::pack_iatom1(int n)
 {
   int i,j;
-  int **improper_atom1 = atom->improper_atom1;
+  tagint **improper_atom1 = atom->improper_atom1;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -857,7 +856,7 @@ void ComputePropertyLocal::pack_iatom1(int n)
 void ComputePropertyLocal::pack_iatom2(int n)
 {
   int i,j;
-  int **improper_atom2 = atom->improper_atom2;
+  tagint **improper_atom2 = atom->improper_atom2;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -872,7 +871,7 @@ void ComputePropertyLocal::pack_iatom2(int n)
 void ComputePropertyLocal::pack_iatom3(int n)
 {
   int i,j;
-  int **improper_atom3 = atom->improper_atom3;
+  tagint **improper_atom3 = atom->improper_atom3;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
@@ -887,7 +886,7 @@ void ComputePropertyLocal::pack_iatom3(int n)
 void ComputePropertyLocal::pack_iatom4(int n)
 {
   int i,j;
-  int **improper_atom4 = atom->improper_atom4;
+  tagint **improper_atom4 = atom->improper_atom4;
 
   for (int m = 0; m < ncount; m++) {
     i = indices[m][0];
diff --git a/src/create_atoms.cpp b/src/create_atoms.cpp
index f83edfa638eec76d92573ec4f754f3ebbfb21eb5..1e1f5716da8962526a8d2617f2f6e44756a87788 100644
--- a/src/create_atoms.cpp
+++ b/src/create_atoms.cpp
@@ -22,6 +22,7 @@
 #include "irregular.h"
 #include "modify.h"
 #include "force.h"
+#include "special.h"
 #include "fix.h"
 #include "domain.h"
 #include "lattice.h"
@@ -121,7 +122,7 @@ void CreateAtoms::command(int narg, char **arg)
       else error->all(FLERR,"Illegal create_atoms command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"mol") == 0) {
-      if (iarg+3 > narg) error->all(FLERR,"Illegal fix create_atoms command");
+      if (iarg+3 > narg) error->all(FLERR,"Illegal create_atoms command");
       int imol = atom->find_molecule(arg[iarg+1]);
       if (imol == -1)
         error->all(FLERR,"Molecule ID for create_atoms does not exist");
@@ -152,20 +153,21 @@ void CreateAtoms::command(int narg, char **arg)
 
   ranmol = NULL;
   if (mode == MOLECULE) {
-    if (atom->molecule_flag == 0)
-      error->all(FLERR,"Create_atoms mol requires atom attribute molecule");
     if (onemol->xflag == 0)
       error->all(FLERR,"Create_atoms molecule must have coordinates");
     if (onemol->typeflag == 0)
       error->all(FLERR,"Create_atoms molecule must have atom types");
     if (ntype+onemol->maxtype <= 0 || ntype+onemol->maxtype > atom->ntypes)
       error->all(FLERR,"Invalid atom type in create_atoms mol command");
+    if (onemol->tag_require && !atom->tag_enable)
+      error->all(FLERR,
+                 "Create_atoms molecule has atom IDs, but system does not");
 
     // create_atoms uses geoemetric center of molecule for insertion
 
     onemol->compute_center();
 
-    // molecule random number generator, same for all procs
+    // molecule random number generator, different for each proc
     
     ranmol = new RanMars(lmp,molseed+comm->me);
   }
@@ -251,99 +253,88 @@ void CreateAtoms::command(int narg, char **arg)
         fix->set_arrays(i);
   }
 
-  // new total # of atoms and error check
-  // for MOLECULE mode, require atom IDs
+  // set new total # of atoms and error check
 
   bigint nblocal = atom->nlocal;
   MPI_Allreduce(&nblocal,&atom->natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
-  if (atom->natoms < 0 || atom->natoms > MAXBIGINT)
+  if (atom->natoms < 0 || atom->natoms >= MAXBIGINT)
     error->all(FLERR,"Too many total atoms");
-  if (atom->natoms > MAXSMALLINT) {
-    if (mode == ATOM) {
-      if (comm->me == 0) 
-        error->warning(FLERR,"Total atom count exceeds ID limit, "
-                       "atoms will not have individual IDs");
-      atom->tag_enable = 0;
-    } else error->all(FLERR,"Total atom count exceeds ID limit");
-  }
 
-  // for ATOM mode:
-  // add IDs for newly created atoms if IDs are still enabled
-  // if global map exists, reset it
+  // add IDs for newly created atoms
+  // check that atom IDs are valid
 
-  if (mode == ATOM) {
-    if (atom->natoms <= MAXSMALLINT) atom->tag_extend();
-    if (atom->map_style) {
-      atom->nghost = 0;
-      atom->map_init();
-      atom->map_set();
-    }
+  if (atom->tag_enable) atom->tag_extend();
+  atom->tag_check();
+
+  // if molecular system or user-requested, create global mapping of atoms
+  // zero nghost in case are adding new atoms to existing atoms
+
+  if (atom->molecular || atom->map_user) {
+    atom->nghost = 0;
+    atom->map_init();
+    atom->map_set();
   }
 
   // for MOLECULE mode:
-  // set atom and molecule IDs for created atoms
+  // set molecule IDs for created atoms if used
+  // reset new molecule bond,angle,etc and special values
   // send atoms to new owning procs via irregular comm
-  //   since not all created atoms will be within my sub-domain
+  //   since not all atoms I created will be within my sub-domain
+  // perform special list build if needed
 
   if (mode == MOLECULE) {
 
-    // add atom IDs for newly created atoms and reset global map
-    // global map must exist since atom->molecular is required to be set
-
-    atom->tag_extend();
-    atom->nghost = 0;
-    atom->map_init();
-    atom->map_set();
-    
-    // maxmol = max molecule ID across all procs, for previous atoms
+    // molcreate = # of molecules I created
 
-    int *molecule = atom->molecule;
+    int molcreate = (atom->nlocal - nlocal_previous) / onemol->natoms;
 
-    int max = 0;
-    for (int i = 0; i < nlocal_previous; i++) max = MAX(max,molecule[i]);
-    int maxmol;
-    MPI_Allreduce(&max,&maxmol,1,MPI_INT,MPI_MAX,world);
-    
-    // molcreate = # of molecules I created
+    // maxmol = max molecule ID across all procs, for previous atoms
     // moloffset = max molecule ID for all molecules owned by previous procs
     //             including molecules existing before this creation
 
-    int molcreate = (atom->nlocal - nlocal_previous) / onemol->natoms;
     int moloffset;
-    MPI_Scan(&molcreate,&moloffset,1,MPI_INT,MPI_SUM,world);
-    moloffset = moloffset - molcreate + maxmol;
+    int *molecule = atom->molecule;
+    if (molecule) {
+      int max = 0;
+      for (int i = 0; i < nlocal_previous; i++) max = MAX(max,molecule[i]);
+      int maxmol;
+      MPI_Allreduce(&max,&maxmol,1,MPI_INT,MPI_MAX,world);
+      MPI_Scan(&molcreate,&moloffset,1,MPI_INT,MPI_SUM,world);
+      moloffset = moloffset - molcreate + maxmol;
+    }
 
     // loop over molecules I created
     // set their molecule ID
     // reset their bond,angle,etc and special values
 
     int natoms = onemol->natoms;
+    tagint offset = 0;
 
-    int *tag = atom->tag;
+    tagint *tag = atom->tag;
     int *num_bond = atom->num_bond;
     int *num_angle = atom->num_angle;
     int *num_dihedral = atom->num_dihedral;
     int *num_improper = atom->num_improper;
-    int **bond_atom = atom->bond_atom;
-    int **angle_atom1 = atom->angle_atom1;
-    int **angle_atom2 = atom->angle_atom2;
-    int **angle_atom3 = atom->angle_atom3;
-    int **dihedral_atom1 = atom->dihedral_atom1;
-    int **dihedral_atom2 = atom->dihedral_atom2;
-    int **dihedral_atom3 = atom->dihedral_atom3;
-    int **dihedral_atom4 = atom->dihedral_atom4;
-    int **improper_atom1 = atom->improper_atom1;
-    int **improper_atom2 = atom->improper_atom2;
-    int **improper_atom3 = atom->improper_atom3;
-    int **improper_atom4 = atom->improper_atom4;
+    tagint **bond_atom = atom->bond_atom;
+    tagint **angle_atom1 = atom->angle_atom1;
+    tagint **angle_atom2 = atom->angle_atom2;
+    tagint **angle_atom3 = atom->angle_atom3;
+    tagint **dihedral_atom1 = atom->dihedral_atom1;
+    tagint **dihedral_atom2 = atom->dihedral_atom2;
+    tagint **dihedral_atom3 = atom->dihedral_atom3;
+    tagint **dihedral_atom4 = atom->dihedral_atom4;
+    tagint **improper_atom1 = atom->improper_atom1;
+    tagint **improper_atom2 = atom->improper_atom2;
+    tagint **improper_atom3 = atom->improper_atom3;
+    tagint **improper_atom4 = atom->improper_atom4;
     int **nspecial = atom->nspecial;
-    int **special = atom->special;
+    tagint **special = atom->special;
 
     int ilocal = nlocal_previous;
     for (int i = 0; i < molcreate; i++) {
-      int offset = tag[ilocal]-1;
+      if (tag) offset = tag[ilocal]-1;
       for (int m = 0; m < natoms; m++) {
-        molecule[ilocal] = moloffset + i+1;
+        if (molecule) molecule[ilocal] = moloffset + i+1;
         if (onemol->bondflag)
           for (int j = 0; j < num_bond[ilocal]; j++)
             bond_atom[ilocal][j] += offset;
@@ -404,6 +395,17 @@ void CreateAtoms::command(int narg, char **arg)
       fprintf(logfile,"Created " BIGINT_FORMAT " atoms\n",
               atom->natoms-natoms_previous);
   }
+
+  // for MOLECULE mode:
+  // create special bond lists for molecular systems
+  // only if onemol added bonds but not special info
+
+  if (mode == MOLECULE) {
+    if (atom->molecular && onemol->bondflag && !onemol->specialflag) {
+      Special special(lmp);
+      special.build();
+    }
+  }
 }
 
 /* ----------------------------------------------------------------------
@@ -439,7 +441,6 @@ void CreateAtoms::add_single()
   }
 }
 
-
 /* ----------------------------------------------------------------------
    add Nrandom atoms at random locations
 ------------------------------------------------------------------------- */
diff --git a/src/delete_atoms.cpp b/src/delete_atoms.cpp
index db752d0b2c97eeb1ebe1a9cace87d5866a0917da..ac1c354d2907c89f06ce6941d6214c1130952424 100644
--- a/src/delete_atoms.cpp
+++ b/src/delete_atoms.cpp
@@ -85,7 +85,7 @@ void DeleteAtoms::command(int narg, char **arg)
   // set all atom IDs to 0, call tag_extend()
 
   if (atom->molecular == 0 && compress_flag) {
-    int *tag = atom->tag;
+    tagint *tag = atom->tag;
     for (i = 0; i < nlocal; i++) tag[i] = 0;
     atom->tag_extend();
   }
@@ -292,7 +292,7 @@ void DeleteAtoms::delete_overlap(int narg, char **arg)
   // at end of loop, there are no more overlaps
   // only ever delete owned atom I, never J even if owned
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   double **x = atom->x;
   double *special_coul = force->special_coul;
diff --git a/src/domain.cpp b/src/domain.cpp
index a2d88c94cf50ca93a2fdbd0223346633af4786a5..c3f78ff873fd2a05b0af086e317cdca8444e4b38 100644
--- a/src/domain.cpp
+++ b/src/domain.cpp
@@ -582,7 +582,7 @@ void Domain::image_check()
   //   which means image flags in that dimension were different
 
   int *num_bond = atom->num_bond;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
 
   double delx,dely,delz;
 
@@ -654,7 +654,7 @@ void Domain::box_too_small_check()
   //   assuming 2 atoms have consistent image flags
 
   int *num_bond = atom->num_bond;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
   int **bond_type = atom->bond_type;
   double **x = atom->x;
   int nlocal = atom->nlocal;
diff --git a/src/dump.cpp b/src/dump.cpp
index c37a32456484925d4c4ce348fbb4975eeb52257d..965aa29a759ff40f9d2f582b472c17bcfee23fb0 100644
--- a/src/dump.cpp
+++ b/src/dump.cpp
@@ -34,7 +34,6 @@ using namespace LAMMPS_NS;
 Dump *Dump::dumpptr;
 
 #define BIG 1.0e20
-#define IBIG 2147483647
 #define EPSILON 1.0e-6
 
 enum{ASCEND,DESCEND};
@@ -77,7 +76,8 @@ Dump::Dump(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
 
   maxbuf = maxids = maxsort = maxproc = 0;
   buf = bufsort = NULL;
-  ids = idsort = index = proclist = NULL;
+  ids = idsort = NULL;
+  index = proclist = NULL;
   irregular = NULL;
 
   maxsbuf = 0;
@@ -177,7 +177,8 @@ void Dump::init()
 
     maxids = maxsort = maxproc = 0;
     bufsort = NULL;
-    ids = idsort = index = proclist = NULL;
+    ids = idsort = NULL;
+    index = proclist = NULL;
     irregular = NULL;
   }
 
@@ -194,6 +195,7 @@ void Dump::init()
 
     bigint size = group->count(igroup);
     if (size > MAXSMALLINT) error->all(FLERR,"Too many atoms to dump sort");
+    int isize = static_cast<int> (size);
 
     // set reorderflag = 1 if can simply reorder local atoms rather than sort
     // criteria: sorting by ID, atom IDs are consecutive from 1 to Natoms
@@ -202,32 +204,31 @@ void Dump::init()
 
     reorderflag = 0;
     if (sortcol == 0 && atom->tag_consecutive()) {
-      int *tag = atom->tag;
+      tagint *tag = atom->tag;
       int *mask = atom->mask;
       int nlocal = atom->nlocal;
 
-      int min = IBIG;
-      int max = 0;
+      tagint min = MAXTAGINT;
+      tagint max = 0;
       for (int i = 0; i < nlocal; i++)
         if (mask[i] & groupbit) {
           min = MIN(min,tag[i]);
           max = MAX(max,tag[i]);
         }
-      int minall,maxall;
-      MPI_Allreduce(&min,&minall,1,MPI_INT,MPI_MIN,world);
-      MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world);
-      int isize = static_cast<int> (size);
+      tagint minall,maxall;
+      MPI_Allreduce(&min,&minall,1,MPI_LMP_TAGINT,MPI_MIN,world);
+      MPI_Allreduce(&max,&maxall,1,MPI_LMP_TAGINT,MPI_MAX,world);
 
       if (maxall-minall+1 == isize) {
         reorderflag = 1;
         double range = maxall-minall + EPSILON;
         idlo = static_cast<int> (range*me/nprocs + minall);
-        int idhi = static_cast<int> (range*(me+1)/nprocs + minall);
+        tagint idhi = static_cast<tagint> (range*(me+1)/nprocs + minall);
 
-        int lom1 = static_cast<int> ((idlo-1-minall)/range * nprocs);
-        int lo = static_cast<int> ((idlo-minall)/range * nprocs);
-        int him1 = static_cast<int> ((idhi-1-minall)/range * nprocs);
-        int hi = static_cast<int> ((idhi-minall)/range * nprocs);
+        tagint lom1 = static_cast<tagint> ((idlo-1-minall)/range * nprocs);
+        tagint lo = static_cast<tagint> ((idlo-minall)/range * nprocs);
+        tagint him1 = static_cast<tagint> ((idhi-1-minall)/range * nprocs);
+        tagint hi = static_cast<tagint> ((idhi-minall)/range * nprocs);
         if (me && me == lom1) idlo--;
         else if (me && me != lo) idlo++;
         if (me+1 == him1) idhi--;
@@ -513,7 +514,7 @@ void Dump::sort()
     bufsort = dptr;
 
     if (sortcol == 0) {
-      int *iptr = ids;
+      tagint *iptr = ids;
       ids = idsort;
       idsort = iptr;
     }
@@ -533,16 +534,21 @@ void Dump::sort()
     // proclist[i] = which proc Ith datum will be sent to
 
     if (sortcol == 0) {
-      int min = IBIG;
-      int max = 0;
+      tagint min = MAXTAGINT;
+      tagint max = 0;
       for (i = 0; i < nme; i++) {
         min = MIN(min,ids[i]);
         max = MAX(max,ids[i]);
       }
-      int minall,maxall;
-      MPI_Allreduce(&min,&minall,1,MPI_INT,MPI_MIN,world);
-      MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world);
-      double range = maxall-minall + EPSILON;
+      tagint minall,maxall;
+      MPI_Allreduce(&min,&minall,1,MPI_LMP_TAGINT,MPI_MIN,world);
+      MPI_Allreduce(&max,&maxall,1,MPI_LMP_TAGINT,MPI_MAX,world);
+
+      // use 0.5 instead of EPSILON since atom IDs are integers
+      // if use EPSILON, it can be lost if 64-bit maxall-minall is too big
+      // then iproc == nprocs for largest ID, causing irregular to crash
+
+      double range = maxall-minall + 0.5;
       for (i = 0; i < nme; i++) {
         iproc = static_cast<int> ((ids[i]-minall)/range * nprocs);
         proclist[i] = iproc;
@@ -589,7 +595,7 @@ void Dump::sort()
     irregular->exchange_data((char *) buf,size_one*sizeof(double),
                              (char *) bufsort);
     if (sortcol == 0)
-      irregular->exchange_data((char *) ids,sizeof(int),(char *) idsort);
+      irregular->exchange_data((char *) ids,sizeof(tagint),(char *) idsort);
     irregular->destroy_data();
   }
 
@@ -645,7 +651,7 @@ void Dump::sort()
 
 int Dump::idcompare(const void *pi, const void *pj)
 {
-  int *idsort = dumpptr->idsort;
+  tagint *idsort = dumpptr->idsort;
 
   int i = *((int *) pi);
   int j = *((int *) pj);
diff --git a/src/dump.h b/src/dump.h
index ce2f0dc4e729eaf883e16c6b1dbfcabde2dd58d0..1c8017ee9a0834f7177bdbc77de5a8b2fa508098 100644
--- a/src/dump.h
+++ b/src/dump.h
@@ -95,7 +95,7 @@ class Dump : protected Pointers {
   int reorderflag;           // 1 if OK to reorder instead of sort
   int ntotal_reorder;        // # of atoms that must be in snapshot
   int nme_reorder;           // # of atoms I must own in snapshot
-  int idlo;                  // lowest ID I own when reordering
+  tagint idlo;               // lowest ID I own when reordering
 
   int maxbuf;                // size of buf
   double *buf;               // memory for atom quantities
@@ -106,9 +106,10 @@ class Dump : protected Pointers {
   int maxids;                // size of ids
   int maxsort;               // size of bufsort, idsort, index
   int maxproc;               // size of proclist
-  int *ids;                  // list of atom IDs, if sorting on IDs
+  tagint *ids;               // list of atom IDs, if sorting on IDs
   double *bufsort;
-  int *idsort,*index,*proclist;
+  tagint *idsort;
+  int *index,*proclist;
 
   class Irregular *irregular;
 
@@ -117,7 +118,7 @@ class Dump : protected Pointers {
   virtual int modify_param(int, char **) {return 0;}
   virtual void write_header(bigint) = 0;
   virtual int count();
-  virtual void pack(int *) = 0;
+  virtual void pack(tagint *) = 0;
   virtual int convert_string(int, double *) {return 0;}
   virtual void write_data(int, double *) = 0;
 
diff --git a/src/dump_atom.cpp b/src/dump_atom.cpp
index 1a1313e3a3561dcd2d2709de09389ec041adfdba..068c4e3dff4fbe0931845859443eeb0faa181a15 100644
--- a/src/dump_atom.cpp
+++ b/src/dump_atom.cpp
@@ -55,8 +55,8 @@ void DumpAtom::init_style()
     strcat(format,"\n");
   } else {
     char *str;
-    if (image_flag == 0) str = (char *) "%d %d %g %g %g";
-    else str = (char *) "%d %d %g %g %g %d %d %d";
+    if (image_flag == 0) str = (char *) TAGINT_FORMAT " %d %g %g %g";
+    else str = (char *) TAGINT_FORMAT " %d %g %g %g %d %d %d";
     int n = strlen(str) + 2;
     format = new char[n];
     strcpy(format,str);
@@ -145,7 +145,7 @@ void DumpAtom::write_header(bigint ndump)
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::pack(int *ids)
+void DumpAtom::pack(tagint *ids)
 {
   (this->*pack_choice)(ids);
 }
@@ -237,11 +237,11 @@ void DumpAtom::header_item_triclinic(bigint ndump)
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::pack_scale_image(int *ids)
+void DumpAtom::pack_scale_image(tagint *ids)
 {
   int m,n;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   imageint *image = atom->image;
   int *mask = atom->mask;
@@ -269,11 +269,11 @@ void DumpAtom::pack_scale_image(int *ids)
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::pack_scale_noimage(int *ids)
+void DumpAtom::pack_scale_noimage(tagint *ids)
 {
   int m,n;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   double **x = atom->x;
@@ -297,11 +297,11 @@ void DumpAtom::pack_scale_noimage(int *ids)
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::pack_scale_image_triclinic(int *ids)
+void DumpAtom::pack_scale_image_triclinic(tagint *ids)
 {
   int m,n;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   imageint *image = atom->image;
   int *mask = atom->mask;
@@ -328,11 +328,11 @@ void DumpAtom::pack_scale_image_triclinic(int *ids)
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::pack_scale_noimage_triclinic(int *ids)
+void DumpAtom::pack_scale_noimage_triclinic(tagint *ids)
 {
   int m,n;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   double **x = atom->x;
@@ -355,11 +355,11 @@ void DumpAtom::pack_scale_noimage_triclinic(int *ids)
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::pack_noscale_image(int *ids)
+void DumpAtom::pack_noscale_image(tagint *ids)
 {
   int m,n;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   imageint *image = atom->image;
   int *mask = atom->mask;
@@ -383,11 +383,11 @@ void DumpAtom::pack_noscale_image(int *ids)
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::pack_noscale_noimage(int *ids)
+void DumpAtom::pack_noscale_noimage(tagint *ids)
 {
   int m,n;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   double **x = atom->x;
@@ -422,7 +422,7 @@ int DumpAtom::convert_image(int n, double *mybuf)
     }
 
     offset += sprintf(&sbuf[offset],format,
-                      static_cast<int> (mybuf[m]), 
+                      static_cast<tagint> (mybuf[m]), 
                       static_cast<int> (mybuf[m+1]),
                       mybuf[m+2],mybuf[m+3],mybuf[m+4], 
                       static_cast<int> (mybuf[m+5]),
@@ -448,7 +448,7 @@ int DumpAtom::convert_noimage(int n, double *mybuf)
     }
 
     offset += sprintf(&sbuf[offset],format,
-                      static_cast<int> (mybuf[m]),
+                      static_cast<tagint> (mybuf[m]),
                       static_cast<int> (mybuf[m+1]),
                       mybuf[m+2],mybuf[m+3],mybuf[m+4]);
     m += size_one;
@@ -480,7 +480,7 @@ void DumpAtom::write_lines_image(int n, double *mybuf)
   int m = 0;
   for (int i = 0; i < n; i++) {
     fprintf(fp,format,
-            static_cast<int> (mybuf[m]), static_cast<int> (mybuf[m+1]),
+            static_cast<tagint> (mybuf[m]), static_cast<int> (mybuf[m+1]),
             mybuf[m+2],mybuf[m+3],mybuf[m+4], static_cast<int> (mybuf[m+5]),
             static_cast<int> (mybuf[m+6]), static_cast<int> (mybuf[m+7]));
     m += size_one;
@@ -494,7 +494,7 @@ void DumpAtom::write_lines_noimage(int n, double *mybuf)
   int m = 0;
   for (int i = 0; i < n; i++) {
     fprintf(fp,format,
-            static_cast<int> (mybuf[m]), static_cast<int> (mybuf[m+1]),
+            static_cast<tagint> (mybuf[m]), static_cast<int> (mybuf[m+1]),
             mybuf[m+2],mybuf[m+3],mybuf[m+4]);
     m += size_one;
   }
diff --git a/src/dump_atom.h b/src/dump_atom.h
index 8b2548a964dcf326c7530724d2ee7957d9abb088..4f8762effd5629906d476a7d22c2cafb7e00a640 100644
--- a/src/dump_atom.h
+++ b/src/dump_atom.h
@@ -37,7 +37,7 @@ class DumpAtom : public Dump {
   void init_style();
   int modify_param(int, char **);
   void write_header(bigint);
-  void pack(int *);
+  void pack(tagint *);
   int convert_string(int, double *);
   void write_data(int, double *);
 
@@ -48,14 +48,14 @@ class DumpAtom : public Dump {
   void header_item(bigint);
   void header_item_triclinic(bigint);
 
-  typedef void (DumpAtom::*FnPtrPack)(int *);
+  typedef void (DumpAtom::*FnPtrPack)(tagint *);
   FnPtrPack pack_choice;               // ptr to pack functions
-  void pack_scale_image(int *);
-  void pack_scale_noimage(int *);
-  void pack_noscale_image(int *);
-  void pack_noscale_noimage(int *);
-  void pack_scale_image_triclinic(int *);
-  void pack_scale_noimage_triclinic(int *);
+  void pack_scale_image(tagint *);
+  void pack_scale_noimage(tagint *);
+  void pack_noscale_image(tagint *);
+  void pack_noscale_noimage(tagint *);
+  void pack_scale_image_triclinic(tagint *);
+  void pack_scale_noimage_triclinic(tagint *);
 
   typedef int (DumpAtom::*FnPtrConvert)(int, double *);
   FnPtrConvert convert_choice;          // ptr to convert data functions
diff --git a/src/dump_cfg.cpp b/src/dump_cfg.cpp
index e5aa145e1cbf7f9901278f41402bdce7214d29fe..a6f05dcfcf794e9336c5f448d55f3eb2bc45e796 100755
--- a/src/dump_cfg.cpp
+++ b/src/dump_cfg.cpp
@@ -33,7 +33,7 @@
 
 using namespace LAMMPS_NS;
 
-enum{INT,DOUBLE,STRING};   // same as in DumpCustom
+enum{INT,DOUBLE,STRING,BIGINT};   // same as in DumpCustom
 
 #define UNWRAPEXPAND 10.0
 #define ONEFIELD 32
@@ -200,6 +200,9 @@ int DumpCFG::convert_string(int n, double *mybuf)
           else if (vtype[j] == STRING) 
             offset += 
               sprintf(&sbuf[offset],vformat[j],typenames[(int) mybuf[m]]);
+          else if (vtype[j] == BIGINT) 
+            offset += 
+              sprintf(&sbuf[offset],vformat[j],static_cast<bigint> (mybuf[m]));
         }
         m++;
       }
@@ -232,6 +235,9 @@ int DumpCFG::convert_string(int n, double *mybuf)
           else if (vtype[j] == STRING) 
             offset += 
               sprintf(&sbuf[offset],vformat[j],typenames[(int) mybuf[m]]);
+          else if (vtype[j] == BIGINT) 
+            offset += 
+              sprintf(&sbuf[offset],vformat[j],static_cast<bigint> (mybuf[m]));
         }
         m++;
       }
@@ -277,6 +283,8 @@ void DumpCFG::write_lines(int n, double *mybuf)
             fprintf(fp,vformat[j],mybuf[m]);
           else if (vtype[j] == STRING) 
             fprintf(fp,vformat[j],typenames[(int) mybuf[m]]);
+          else if (vtype[j] == BIGINT) 
+            fprintf(fp,vformat[j],static_cast<bigint> (mybuf[m]));
         }
         m++;
       }
@@ -301,6 +309,8 @@ void DumpCFG::write_lines(int n, double *mybuf)
             fprintf(fp,vformat[j],mybuf[m]);
           else if (vtype[j] == STRING) 
             fprintf(fp,vformat[j],typenames[(int) mybuf[m]]);
+          else if (vtype[j] == BIGINT) 
+            fprintf(fp,vformat[j],static_cast<bigint> (mybuf[m]));
         }
         m++;
       }
diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp
index 32b3e4eb3356225eb328c20790ae55f180da1ca9..f0c0371044e5fee6b5c689336772712dac174507 100644
--- a/src/dump_custom.cpp
+++ b/src/dump_custom.cpp
@@ -44,7 +44,7 @@ enum{ID,MOL,TYPE,ELEMENT,MASS,
      TQX,TQY,TQZ,SPIN,ERADIUS,ERVEL,ERFORCE,
      COMPUTE,FIX,VARIABLE};
 enum{LT,LE,GT,GE,EQ,NEQ};
-enum{INT,DOUBLE,STRING};    // same as in DumpCFG
+enum{INT,DOUBLE,STRING,BIGINT};    // same as in DumpCFG
 
 #define INVOKED_PERATOM 8
 #define ONEFIELD 32
@@ -128,6 +128,7 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) :
     if (vtype[i] == INT) strcat(format_default,"%d ");
     else if (vtype[i] == DOUBLE) strcat(format_default,"%g ");
     else if (vtype[i] == STRING) strcat(format_default,"%s ");
+    else if (vtype[i] == BIGINT) strcat(format_default,BIGINT_FORMAT " ");
     vformat[i] = NULL;
   }
 
@@ -437,7 +438,7 @@ int DumpCustom::count()
       // customize by adding to if statement
 
       if (thresh_array[ithresh] == ID) {
-        int *tag = atom->tag;
+        tagint *tag = atom->tag;
         for (i = 0; i < nlocal; i++) dchoose[i] = tag[i];
         ptr = dchoose;
         nstride = 1;
@@ -894,11 +895,11 @@ int DumpCustom::count()
 
 /* ---------------------------------------------------------------------- */
 
-void DumpCustom::pack(int *ids)
+void DumpCustom::pack(tagint *ids)
 {
   for (int n = 0; n < size_one; n++) (this->*pack_choice[n])(n);
   if (ids) {
-    int *tag = atom->tag;
+    tagint *tag = atom->tag;
     for (int i = 0; i < nchoose; i++)
       ids[i] = tag[clist[i]];
   }
@@ -929,6 +930,9 @@ int DumpCustom::convert_string(int n, double *mybuf)
         offset += sprintf(&sbuf[offset],vformat[j],mybuf[m]);
       else if (vtype[j] == STRING)
         offset += sprintf(&sbuf[offset],vformat[j],typenames[(int) mybuf[m]]);
+      else if (vtype[j] == BIGINT) 
+        offset += sprintf(&sbuf[offset],vformat[j],
+                          static_cast<bigint> (mybuf[m]));
       m++;
     }
     offset += sprintf(&sbuf[offset],"\n");
@@ -973,6 +977,8 @@ void DumpCustom::write_lines(int n, double *mybuf)
       else if (vtype[j] == DOUBLE) fprintf(fp,vformat[j],mybuf[m]);
       else if (vtype[j] == STRING)
         fprintf(fp,vformat[j],typenames[(int) mybuf[m]]);
+      else if (vtype[j] == BIGINT) 
+        fprintf(fp,vformat[j],static_cast<bigint> (mybuf[m]));
       m++;
     }
     fprintf(fp,"\n");
@@ -991,7 +997,8 @@ int DumpCustom::parse_fields(int narg, char **arg)
 
     if (strcmp(arg[iarg],"id") == 0) {
       pack_choice[i] = &DumpCustom::pack_id;
-      vtype[i] = INT;
+      if (sizeof(tagint) == sizeof(smallint)) vtype[i] = INT;
+      else vtype[i] = BIGINT;
     } else if (strcmp(arg[iarg],"mol") == 0) {
       if (!atom->molecule_flag)
         error->all(FLERR,"Dumping an atom property that isn't allocated");
@@ -1706,7 +1713,7 @@ void DumpCustom::pack_variable(int n)
 
 void DumpCustom::pack_id(int n)
 {
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   for (int i = 0; i < nchoose; i++) {
     buf[n] = tag[clist[i]];
diff --git a/src/dump_custom.h b/src/dump_custom.h
index 9cfe9188ee5c8c07e4b6b2083117cfefc38639d8..a873a97f21fc24fa28874f082b544044f06dff20 100644
--- a/src/dump_custom.h
+++ b/src/dump_custom.h
@@ -77,7 +77,7 @@ class DumpCustom : public Dump {
   virtual void init_style();
   virtual void write_header(bigint);
   int count();
-  void pack(int *);
+  void pack(tagint *);
   virtual int convert_string(int, double *);
   virtual void write_data(int, double *);
   bigint memory_usage();
diff --git a/src/dump_dcd.cpp b/src/dump_dcd.cpp
index 877d8a3f10913fa3a0570036bf1998341bf74048..a4a6e4f70468d0d7097e2bd30da9c9a3f70df4d2 100644
--- a/src/dump_dcd.cpp
+++ b/src/dump_dcd.cpp
@@ -175,11 +175,11 @@ void DumpDCD::write_header(bigint n)
 
 /* ---------------------------------------------------------------------- */
 
-void DumpDCD::pack(int *ids)
+void DumpDCD::pack(tagint *ids)
 {
   int m,n;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   double **x = atom->x;
   imageint *image = atom->image;
   int *mask = atom->mask;
diff --git a/src/dump_dcd.h b/src/dump_dcd.h
index a5b88f3cafc3fdc30586504e42ee000a18ea57e5..47b6afe0be2e2ee4c98f3f7e0148fc78c9767a31 100644
--- a/src/dump_dcd.h
+++ b/src/dump_dcd.h
@@ -39,7 +39,7 @@ class DumpDCD : public Dump {
   void init_style();
   void openfile();
   void write_header(bigint);
-  void pack(int *);
+  void pack(tagint *);
   void write_data(int, double *);
   int modify_param(int, char **);
   bigint memory_usage();
diff --git a/src/dump_image.cpp b/src/dump_image.cpp
index 05a7486c5086aa382828e4f7f04f7459717bd629..53f09b02a8593018ac44927b6acfcee01f89ccbd 100644
--- a/src/dump_image.cpp
+++ b/src/dump_image.cpp
@@ -696,8 +696,8 @@ void DumpImage::create_image()
 
   if (bondflag) {
     double **x = atom->x;
-    int *tag = atom->tag;
-    int **bond_atom = atom->bond_atom;
+    tagint *tag = atom->tag;
+    tagint **bond_atom = atom->bond_atom;
     int **bond_type = atom->bond_type;
     int *num_bond = atom->num_bond;
     int *type = atom->type;
diff --git a/src/dump_local.cpp b/src/dump_local.cpp
index fd914563d5a9934b5e562b93298e700a4ac82bf2..f4d7fb260e2bcf3b41c01a8758515ed43dd7b030 100644
--- a/src/dump_local.cpp
+++ b/src/dump_local.cpp
@@ -265,7 +265,7 @@ int DumpLocal::count()
 
 /* ---------------------------------------------------------------------- */
 
-void DumpLocal::pack(int *dummy)
+void DumpLocal::pack(tagint *dummy)
 {
   for (int n = 0; n < size_one; n++) (this->*pack_choice[n])(n);
 }
diff --git a/src/dump_local.h b/src/dump_local.h
index 4861141f2d19d7980afbb980a4174ec65316cf06..dec5e27834cf2e40f611a8227b2fbc6ca2ec1d19 100644
--- a/src/dump_local.h
+++ b/src/dump_local.h
@@ -57,7 +57,7 @@ class DumpLocal : public Dump {
   int modify_param(int, char **);
   void write_header(bigint);
   int count();
-  void pack(int *);
+  void pack(tagint *);
   int convert_string(int, double *);
   void write_data(int, double *);
 
diff --git a/src/dump_xyz.cpp b/src/dump_xyz.cpp
index f3ef0178ce28f2934e95c5053ed321dcd2f1f0b8..273ec06e443ef43f97e527c76ec16e9996cf91f5 100644
--- a/src/dump_xyz.cpp
+++ b/src/dump_xyz.cpp
@@ -140,11 +140,11 @@ void DumpXYZ::write_header(bigint n)
 
 /* ---------------------------------------------------------------------- */
 
-void DumpXYZ::pack(int *ids)
+void DumpXYZ::pack(tagint *ids)
 {
   int m,n;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   double **x = atom->x;
diff --git a/src/dump_xyz.h b/src/dump_xyz.h
index eb28e4fee8b13e3cc04e0eb232900ee781c89c1d..879b46e05184fbda664fa2fded7e009e8fdbb247 100644
--- a/src/dump_xyz.h
+++ b/src/dump_xyz.h
@@ -35,7 +35,7 @@ class DumpXYZ : public Dump {
 
   void init_style();
   void write_header(bigint);
-  void pack(int *);
+  void pack(tagint *);
   int convert_string(int, double *);
   void write_data(int, double *);
   int modify_param(int, char **);
diff --git a/src/fix.h b/src/fix.h
index 459479d999c773f88afd40c30f2573a4ec1da806..6f11272be6130d63842dc712f1e35674f13d4532 100644
--- a/src/fix.h
+++ b/src/fix.h
@@ -116,7 +116,7 @@ class Fix : protected Pointers {
   virtual void copy_arrays(int, int, int) {}
   virtual void set_arrays(int) {}
   virtual void update_arrays(int, int) {}
-  virtual void set_molecule(int, int, double *, double *, double *) {}
+  virtual void set_molecule(int, tagint, double *, double *, double *) {}
 
   virtual int pack_border(int, int *, double *) {return 0;}
   virtual int unpack_border(int, int, double *) {return 0;}
@@ -195,6 +195,17 @@ class Fix : protected Pointers {
 
   void v_setup(int);
   void v_tally(int, int *, double, double *);
+
+  // union data struct for packing 32-bit and 64-bit ints into double bufs
+  // see atom_vec.h for documentation
+
+  union ubuf {
+    double d;
+    int64_t i;
+    ubuf(double arg) : d(arg) {}
+    ubuf(int64_t arg) : i(arg) {}
+    ubuf(int arg) : i(arg) {}
+  };
 };
 
 namespace FixConst {
diff --git a/src/fix_external.h b/src/fix_external.h
index 3e38f09c42da3f518436abc48882920ffcd4cc11..118a6784491e04919f8bd2ebf6bef598d66d79c5 100644
--- a/src/fix_external.h
+++ b/src/fix_external.h
@@ -46,7 +46,7 @@ class FixExternal : public Fix {
   int pack_exchange(int, double *);
   int unpack_exchange(int, double *);
 
-  typedef void (*FnPtr)(void *, bigint, int, int *, double **, double **);
+  typedef void (*FnPtr)(void *, bigint, int, tagint *, double **, double **);
   void set_callback(FnPtr, void *);
 
  private:
diff --git a/src/fix_property_atom.cpp b/src/fix_property_atom.cpp
index 91f8bce591889a82d355ca63583eaa615bee537d..a1be2b556bb5c6ca30a00da16763d7a4fb77d951 100644
--- a/src/fix_property_atom.cpp
+++ b/src/fix_property_atom.cpp
@@ -174,12 +174,16 @@ void FixPropertyAtom::init()
 
 void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf)
 {
-  int j,m,tagdata;
+  int j,m;
+  tagint itag;
   char *next;
 
-  if (atom->map_style == 0) 
-    error->all(FLERR,"Fix property/atom cannot read from data file "
-               "unless an atom map is defined");
+  int mapflag = 0;
+  if (atom->map_style == 0) {
+    mapflag = 1;
+    atom->map_init();
+    atom->map_set();
+  }
 
   next = strchr(buf,'\n');
   *next = '\0';
@@ -198,7 +202,7 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf)
   // tokenize the line into values
   // if I own atom tag, unpack its values
 
-  int map_tag_max = atom->map_tag_max;
+  tagint map_tag_max = atom->map_tag_max;
 
   for (int i = 0; i < n; i++) {
     next = strchr(buf,'\n');
@@ -207,8 +211,8 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf)
     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) {
+    itag = ATOTAGINT(values[0]);
+    if (itag <= 0 || itag > map_tag_max) {
       char str[128];
       sprintf(str,"Invalid atom ID in %s section of data file",keyword);
       error->one(FLERR,str);
@@ -216,7 +220,7 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf)
 
     // assign words in line to per-atom vectors
 
-    if ((m = atom->map(tagdata)) >= 0) {
+    if ((m = atom->map(itag)) >= 0) {
       for (j = 0; j < nvalue; j++) {
         if (style[j] == MOLECULE) atom->molecule[m] = atoi(values[j+1]);
         else if (style[j] == CHARGE) atom->q[m] = atof(values[j+1]);
@@ -231,6 +235,11 @@ void FixPropertyAtom::read_data_section(char *keyword, int n, char *buf)
   }
 
   delete [] values;
+
+  if (mapflag) {
+    atom->map_delete();
+    atom->map_style = 0;
+  }
 }
 
 /* ----------------------------------------------------------------------
@@ -267,7 +276,7 @@ void FixPropertyAtom::write_data_section_pack(int mth, double **buf)
   // 1st column = atom tag
   // rest of columns = per-atom values
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
 
   for (i = 0; i < nlocal; i++) buf[i][0] = ubuf(tag[i]).d;
@@ -316,7 +325,7 @@ void FixPropertyAtom::write_data_section(int mth, FILE *fp,
   int m;
 
   for (int i = 0; i < n; i++) {
-    fprintf(fp,"%d",(int) ubuf(buf[i][0]).i);
+    fprintf(fp,TAGINT_FORMAT,(tagint) ubuf(buf[i][0]).i);
     for (m = 0; m < nvalue; m++) {
       if (style[m] == MOLECULE || style[m] == INTEGER)
         fprintf(fp," %d",(int) ubuf(buf[i][m+1]).i);
diff --git a/src/fix_property_atom.h b/src/fix_property_atom.h
index 12ecb9694bc2b372d2aba3d364c633bcd16b6fee..e8b0d67d71cd40386233d12d94dc58f782047405 100644
--- a/src/fix_property_atom.h
+++ b/src/fix_property_atom.h
@@ -57,18 +57,6 @@ class FixPropertyAtom : public Fix {
   char *astyle;
 
   int nmax_old;         // length of peratom arrays the last time they grew
-
-  // union data struct for packing 32-bit and 64-bit ints into double bufs
-  // see atom_vec.h for documentation
-
-  union ubuf {
-    double   d;
-    int64_t  i;
-    ubuf(double arg) : d(arg) {}
-    ubuf(int64_t arg) : i(arg) {}
-    ubuf(int arg) : i(arg) {}
-  };
-
 };
 
 }
diff --git a/src/fix_restrain.cpp b/src/fix_restrain.cpp
index 33f717c8967df8d9299ffabdadd7c63663ac6fba..70b0d72d0220a05cee33e731a943764478ec57b9 100644
--- a/src/fix_restrain.cpp
+++ b/src/fix_restrain.cpp
@@ -512,7 +512,9 @@ void FixRestrain::restrain_dihedral(int m)
     MPI_Comm_rank(world,&me);
     if (screen) {
       char str[128];
-      sprintf(str,"Restrain problem: %d " BIGINT_FORMAT " %d %d %d %d",
+      sprintf(str,"Restrain problem: %d " BIGINT_FORMAT " " 
+              TAGINT_FORMAT " " TAGINT_FORMAT " " 
+              TAGINT_FORMAT " " TAGINT_FORMAT,
               me,update->ntimestep,
               atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
       error->warning(FLERR,str);
diff --git a/src/fix_shear_history.cpp b/src/fix_shear_history.cpp
index bebd23386d127859f8df13ee392f8d58ae450698..96461d2930a38b586c3b75f3197ddb5155f2ee51 100644
--- a/src/fix_shear_history.cpp
+++ b/src/fix_shear_history.cpp
@@ -119,7 +119,7 @@ void FixShearHistory::allocate_pages()
     pgsize = neighbor->pgsize;
     oneatom = neighbor->oneatom;
     int nmypage = comm->nthreads;
-    ipage = new MyPage<int>[nmypage];
+    ipage = new MyPage<tagint>[nmypage];
     dpage = new MyPage<double[3]>[nmypage];
     for (int i = 0; i < nmypage; i++) {
       ipage[i].init(oneatom,pgsize);
@@ -177,7 +177,7 @@ void FixShearHistory::pre_exchange()
   // calculate npartner for each owned atom
   // nlocal_neigh = nlocal when neigh list was built, may be smaller than nlocal
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   NeighList *list = pair->list;
   inum = list->inum;
   ilist = list->ilist;
@@ -302,8 +302,8 @@ double FixShearHistory::memory_usage()
 void FixShearHistory::grow_arrays(int nmax)
 {
   memory->grow(npartner,nmax,"shear_history:npartner");
-  partner = (int **) memory->srealloc(partner,nmax*sizeof(int *),
-                                      "shear_history:partner");
+  partner = (tagint **) memory->srealloc(partner,nmax*sizeof(tagint *),
+                                         "shear_history:partner");
   typedef double (*sptype)[3];
   shearpartner = (sptype *) 
     memory->srealloc(shearpartner,nmax*sizeof(sptype),
@@ -370,7 +370,7 @@ int FixShearHistory::unpack_exchange(int nlocal, double *buf)
   partner[nlocal] = ipage->get(npartner[nlocal]);
   shearpartner[nlocal] = dpage->get(npartner[nlocal]);
   for (int n = 0; n < npartner[nlocal]; n++) {
-    partner[nlocal][n] = static_cast<int> (buf[m++]);
+    partner[nlocal][n] = static_cast<tagint> (buf[m++]);
     shearpartner[nlocal][n][0] = buf[m++];
     shearpartner[nlocal][n][1] = buf[m++];
     shearpartner[nlocal][n][2] = buf[m++];
@@ -421,7 +421,7 @@ void FixShearHistory::unpack_restart(int nlocal, int nth)
   partner[nlocal] = ipage->get(npartner[nlocal]);
   shearpartner[nlocal] = dpage->get(npartner[nlocal]);
   for (int n = 0; n < npartner[nlocal]; n++) {
-    partner[nlocal][n] = static_cast<int> (extra[nlocal][m++]);
+    partner[nlocal][n] = static_cast<tagint> (extra[nlocal][m++]);
     shearpartner[nlocal][n][0] = extra[nlocal][m++];
     shearpartner[nlocal][n][1] = extra[nlocal][m++];
     shearpartner[nlocal][n][2] = extra[nlocal][m++];
diff --git a/src/fix_shear_history.h b/src/fix_shear_history.h
index 0dc150c090c409943437ec2c69d1e58a29cd52d0..06b58ac60724e88d27abe250647d2ce5b7c89124 100644
--- a/src/fix_shear_history.h
+++ b/src/fix_shear_history.h
@@ -52,7 +52,7 @@ class FixShearHistory : public Fix {
 
  protected:
   int *npartner;                // # of touching partners of each atom
-  int **partner;                // tags for the partners
+  tagint **partner;             // global atom IDs for the partners
   double (**shearpartner)[3];   // 3 shear values with the partner
   int maxtouch;                 // max # of touching partners for my atoms
 
@@ -60,7 +60,7 @@ class FixShearHistory : public Fix {
   int *computeflag;             // computeflag in PairGranHookeHistory
 
   int pgsize,oneatom;           // copy of settings in Neighbor
-  MyPage<int> *ipage;           // pages of partner atom IDs
+  MyPage<tagint> *ipage;        // pages of partner atom IDs
   MyPage<double[3]> *dpage;     // pages of shear history with partners
 
   void allocate_pages();
diff --git a/src/fix_store_state.cpp b/src/fix_store_state.cpp
index bd95daf7a218f55daa30bb6a96acbfa99ffa07c9..addcffcab477cb5332a9cfd657ca1938a588b12c 100644
--- a/src/fix_store_state.cpp
+++ b/src/fix_store_state.cpp
@@ -588,7 +588,7 @@ int FixStoreState::size_restart(int nlocal)
 
 void FixStoreState::pack_id(int n)
 {
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
diff --git a/src/fix_tmd.cpp b/src/fix_tmd.cpp
index 1a10594478a1bf8cb0a9815ff38745249618ccbc..8ac0533fffe943942799b76904c7818cef80b938 100644
--- a/src/fix_tmd.cpp
+++ b/src/fix_tmd.cpp
@@ -394,7 +394,8 @@ void FixTMD::readfile(char *file)
 
   char *buffer = new char[CHUNK*MAXLINE];
   char *next,*bufptr;
-  int i,m,nlines,tag,imageflag,ix,iy,iz;
+  int i,m,nlines,imageflag,ix,iy,iz;
+  tagint itag;
   double x,y,z,xprd,yprd,zprd;
 
   int firstline = 1;
@@ -457,11 +458,12 @@ void FixTMD::readfile(char *file)
       }
 
       if (imageflag)
-        sscanf(bufptr,"%d %lg %lg %lg %d %d %d",&tag,&x,&y,&z,&ix,&iy,&iz);
+        sscanf(bufptr,TAGINT_FORMAT " %lg %lg %lg %d %d %d",
+               &itag,&x,&y,&z,&ix,&iy,&iz);
       else
-        sscanf(bufptr,"%d %lg %lg %lg",&tag,&x,&y,&z);
+        sscanf(bufptr,TAGINT_FORMAT " %lg %lg %lg",&itag,&x,&y,&z);
 
-      m = atom->map(tag);
+      m = atom->map(itag);
       if (m >= 0 && m < nlocal && mask[m] & groupbit) {
         if (imageflag) {
           xf[m][0] = x + ix*xprd;
diff --git a/src/force.cpp b/src/force.cpp
index 23699fdb2aa16822d64a99cadfeb5764a0a60e0f..d486493c92b47624c83b2818be734d4ff5c25dcf 100644
--- a/src/force.cpp
+++ b/src/force.cpp
@@ -690,6 +690,40 @@ void Force::bounds(char *str, int nmax, int &nlo, int &nhi, int nmin)
     error->all(FLERR,"Numeric index is out of bounds");
 }
 
+/* ----------------------------------------------------------------------
+   compute bounds implied by numeric str with a possible wildcard asterik
+   1 = lower bound, nmax = upper bound
+   5 possibilities:
+     (1) i = i to i, (2) * = nmin to nmax,
+     (3) i* = i to nmax, (4) *j = nmin to j, (5) i*j = i to j
+   return nlo,nhi
+------------------------------------------------------------------------- */
+
+void Force::boundsbig(char *str, bigint nmax, bigint &nlo, bigint &nhi, 
+                      bigint nmin)
+{
+  char *ptr = strchr(str,'*');
+
+  if (ptr == NULL) {
+    nlo = nhi = ATOBIGINT(str);
+  } else if (strlen(str) == 1) {
+    nlo = nmin;
+    nhi = nmax;
+  } else if (ptr == str) {
+    nlo = nmin;
+    nhi = ATOBIGINT(ptr+1);
+  } else if (strlen(ptr+1) == 0) {
+    nlo = ATOBIGINT(str);
+    nhi = nmax;
+  } else {
+    nlo = ATOBIGINT(str);
+    nhi = ATOBIGINT(ptr+1);
+  }
+
+  if (nlo < nmin || nhi > nmax) 
+    error->all(FLERR,"Numeric index is out of bounds");
+}
+
 /* ----------------------------------------------------------------------
    read a floating point value from a string
    generate an error if not a legitimate floating point value
@@ -728,6 +762,24 @@ int Force::inumeric(const char *file, int line, char *str)
   return atoi(str);
 }
 
+/* ----------------------------------------------------------------------
+   read a big integer value from a string
+   generate an error if not a legitimate integer value
+   called by various commands to check validity of their arguments
+------------------------------------------------------------------------- */
+
+bigint Force::bnumeric(const char *file, int line, char *str)
+{
+  int n = strlen(str);
+  for (int i = 0; i < n; i++) {
+    if (isdigit(str[i]) || str[i] == '-' || str[i] == '+') continue;
+    error->all(file,line,
+               "Expected integer parameter in input script or data file");
+  }
+
+  return ATOLL(str);
+}
+
 /* ----------------------------------------------------------------------
    memory usage of force classes
 ------------------------------------------------------------------------- */
diff --git a/src/force.h b/src/force.h
index c866656def488720ff2dbc2b0e28be2b1d09aea3..c2109d089932d10cfcfe4ca8c6a7d302149a3c0d 100644
--- a/src/force.h
+++ b/src/force.h
@@ -100,8 +100,10 @@ class Force : protected Pointers {
 
   void set_special(int, char **);
   void bounds(char *, int, int &, int &, int nmin=1);
+  void boundsbig(char *, bigint, bigint &, bigint &, bigint nmin=1);
   double numeric(const char *, int, char *);
   int inumeric(const char *, int, char *);
+  bigint bnumeric(const char *, int, char *);
   bigint memory_usage();
 
  private:
diff --git a/src/group.cpp b/src/group.cpp
index d525c79281a7740120da687db698282e567f2118..22b9035cc4eedfecc21438b1d0d5296a38229169 100644
--- a/src/group.cpp
+++ b/src/group.cpp
@@ -174,7 +174,7 @@ void Group::assign(int narg, char **arg)
          strcmp(arg[2],"<=") == 0 || strcmp(arg[2],">=") == 0 ||
          strcmp(arg[2],"<>") == 0)) {
 
-      int condition,bound1,bound2;
+      int condition;
       if (strcmp(arg[2],"<") == 0) condition = LT;
       else if (strcmp(arg[2],"<=") == 0) condition = LE;
       else if (strcmp(arg[2],">") == 0) condition = GT;
@@ -184,66 +184,127 @@ void Group::assign(int narg, char **arg)
       else if (strcmp(arg[2],"<>") == 0) condition = BETWEEN;
       else error->all(FLERR,"Illegal group command");
       
-      bound1 = force->inumeric(FLERR,arg[3]);
+      tagint bound1,bound2;
+      if (sizeof(tagint) == sizeof(smallint))
+        bound1 = force->inumeric(FLERR,arg[3]);
+      else
+        bound1 = force->bnumeric(FLERR,arg[3]);
       bound2 = -1;
 
       if (condition == BETWEEN) {
         if (narg != 5) error->all(FLERR,"Illegal group command");
-        bound2 = force->inumeric(FLERR,arg[4]);
+        if (sizeof(tagint) == sizeof(smallint))
+          bound2 = force->inumeric(FLERR,arg[4]);
+        else
+          bound2 = force->bnumeric(FLERR,arg[4]);
       } else if (narg != 4) error->all(FLERR,"Illegal group command");
 
+      tagint *tag = atom->tag;
       int *attribute;
       if (category == TYPE) attribute = atom->type;
       else if (category == MOLECULE) attribute = atom->molecule;
-      else if (category == ID) attribute = atom->tag;
+      else if (category == ID) attribute = NULL;
 
       // add to group if meets condition
 
-      if (condition == LT) {
-        for (i = 0; i < nlocal; i++) if (attribute[i] < bound1) mask[i] |= bit;
-      } else if (condition == LE) {
-        for (i = 0; i < nlocal; i++) if (attribute[i] <= bound1) mask[i] |= bit;
-      } 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;
+      if (attribute) {
+        if (condition == LT) {
+          for (i = 0; i < nlocal; i++) 
+            if (attribute[i] < bound1) mask[i] |= bit;
+        } else if (condition == LE) {
+          for (i = 0; i < nlocal; i++) 
+            if (attribute[i] <= bound1) mask[i] |= bit;
+        } 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;
+        }
+      } else {
+        if (condition == LT) {
+          for (i = 0; i < nlocal; i++) 
+            if (tag[i] < bound1) mask[i] |= bit;
+        } else if (condition == LE) {
+          for (i = 0; i < nlocal; i++) 
+            if (tag[i] <= bound1) mask[i] |= bit;
+        } else if (condition == GT) {
+          for (i = 0; i < nlocal; i++) 
+            if (tag[i] > bound1) mask[i] |= bit;
+        } else if (condition == GE) {
+          for (i = 0; i < nlocal; i++) 
+            if (tag[i] >= bound1) mask[i] |= bit;
+        } else if (condition == EQ) {
+          for (i = 0; i < nlocal; i++) 
+            if (tag[i] == bound1) mask[i] |= bit;
+        } else if (condition == NEQ) {
+          for (i = 0; i < nlocal; i++) 
+            if (tag[i] != bound1) mask[i] |= bit;
+        } else if (condition == BETWEEN) {
+          for (i = 0; i < nlocal; i++)
+            if (tag[i] >= bound1 && tag[i] <= bound2)
+              mask[i] |= bit;
+        }
       }
-      
+
     // args = list of values
       
     } else {
+      tagint *tag = atom->tag;
       int *attribute;
       if (category == TYPE) attribute = atom->type;
       else if (category == MOLECULE) attribute = atom->molecule;
-      else if (category == ID) attribute = atom->tag;
-
+      else if (category == ID) attribute = NULL;
+                                 
       char *ptr;
-      int start,stop,delta;
+      tagint start,stop,delta;
 
       for (int iarg = 2; iarg < narg; iarg++) {
-        if (strchr(arg[iarg],':')) {
-          start = atoi(strtok(arg[iarg],":")); 
-          stop = atoi(strtok(NULL,":"));
-          ptr = strtok(NULL,":");
-          if (ptr) delta = atoi(ptr);
-          else delta = 1;
+        if (attribute) {
+          if (strchr(arg[iarg],':')) {
+            start = atoi(strtok(arg[iarg],":")); 
+            stop = atoi(strtok(NULL,":"));
+            ptr = strtok(NULL,":");
+            if (ptr) delta = atoi(ptr);
+            else delta = 1;
+          } else {
+            start = stop = atoi(arg[iarg]);
+            delta = 1;
+          }
         } else {
-          start = stop = atoi(arg[iarg]);
-          delta = 1;
+          if (strchr(arg[iarg],':')) {
+            start = ATOTAGINT(strtok(arg[iarg],":")); 
+            stop = ATOTAGINT(strtok(NULL,":"));
+            ptr = strtok(NULL,":");
+            if (ptr) delta = ATOTAGINT(ptr);
+            else delta = 1;
+          } else {
+            start = stop = ATOTAGINT(arg[iarg]);
+            delta = 1;
+          }
         }
 
         // add to group if attribute matches value or sequence
       
-        for (i = 0; i < nlocal; i++)
-          if (attribute[i] >= start && attribute[i] <= stop &&
-              (attribute[i]-start) % delta == 0) mask[i] |= bit;
+        if (attribute) {
+          for (i = 0; i < nlocal; i++)
+            if (attribute[i] >= start && attribute[i] <= stop &&
+                (attribute[i]-start) % delta == 0) mask[i] |= bit;
+        } else {
+          for (i = 0; i < nlocal; i++)
+            if (tag[i] >= start && tag[i] <= stop &&
+                (tag[i]-start) % delta == 0) mask[i] |= bit;
+        }
       }
     }
 
diff --git a/src/lammps.cpp b/src/lammps.cpp
index 618ac92c3be405a268691b02a3a8e199e1f46f2b..a896c752d2564f521a6a129dad9d125ca2d28f77 100644
--- a/src/lammps.cpp
+++ b/src/lammps.cpp
@@ -374,7 +374,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator)
     error->all(FLERR,"Imageint setting in lmptype.h is invalid");
   if (sizeof(tagint) < sizeof(smallint))
     error->all(FLERR,"Tagint setting in lmptype.h is invalid");
-  if (sizeof(bigint) < sizeof(tagint))
+  if (sizeof(bigint) < sizeof(imageint) || sizeof(bigint) < sizeof(tagint))
     error->all(FLERR,"Bigint setting in lmptype.h is invalid");
 
   int mpisize;
@@ -386,17 +386,17 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator)
 #ifdef LAMMPS_SMALLBIG
   if (sizeof(smallint) != 4 || sizeof(imageint) != 4 || 
       sizeof(tagint) != 4 || sizeof(bigint) != 8)
-    error->all(FLERR,"Small, tag, big integers are not sized correctly");
+    error->all(FLERR,"Small to big integers are not sized correctly");
 #endif
 #ifdef LAMMPS_BIGBIG
   if (sizeof(smallint) != 4 || sizeof(imageint) != 8 || 
       sizeof(tagint) != 8 || sizeof(bigint) != 8)
-    error->all(FLERR,"Small, tag, big integers are not sized correctly");
+    error->all(FLERR,"Small to big integers are not sized correctly");
 #endif
 #ifdef LAMMPS_SMALLSMALL
   if (sizeof(smallint) != 4 || sizeof(imageint) != 4 || 
       sizeof(tagint) != 4 || sizeof(bigint) != 4)
-    error->all(FLERR,"Small, tag, big integers are not sized correctly");
+    error->all(FLERR,"Small to big integers are not sized correctly");
 #endif
 
   // create CUDA class if USER-CUDA installed, unless explicitly switched off
diff --git a/src/library.cpp b/src/library.cpp
index f31f43b929955f28d6d2593ac626f9704333774b..60b07548dd01e2e5f721d1f153a82fd64e889971 100644
--- a/src/library.cpp
+++ b/src/library.cpp
@@ -315,7 +315,7 @@ void *lammps_extract_fix(void *ptr, char *id, int style, int type,
      which the caller can cast to a (double *) which points to the values
    returns a NULL if name is not recognized or not equal-style or atom-style
    IMPORTANT: for both equal-style and atom-style variables,
-     this function allocates memory to store the variable data,
+     this function allocates memory to store the variable data in
      so the caller must free this memory to avoid a leak
      e.g. for equal-style variables
        double *dptr = (double *) lammps_extract_variable();
@@ -412,7 +412,7 @@ void lammps_gather_atoms(void *ptr, char *name,
     lmp->memory->create(copy,count*natoms,"lib/gather:copy");
     for (i = 0; i < count*natoms; i++) copy[i] = 0;
 
-    int *tag = lmp->atom->tag;
+    tagint *tag = lmp->atom->tag;
     int nlocal = lmp->atom->nlocal;
 
     if (count == 1)
@@ -438,7 +438,7 @@ void lammps_gather_atoms(void *ptr, char *name,
     lmp->memory->create(copy,count*natoms,"lib/gather:copy");
     for (i = 0; i < count*natoms; i++) copy[i] = 0.0;
 
-    int *tag = lmp->atom->tag;
+    tagint *tag = lmp->atom->tag;
     int nlocal = lmp->atom->nlocal;
 
     if (count == 1) {
diff --git a/src/lmptype.h b/src/lmptype.h
index 1c3b783e26836a7b8a62200af72808ccc41ef674..a23aa9113b13cfdd46110ee6ec633bb6c43e5952 100644
--- a/src/lmptype.h
+++ b/src/lmptype.h
@@ -54,7 +54,7 @@ namespace LAMMPS_NS {
 #define SBBITS 30
 #define NEIGHMASK 0x3FFFFFFF
 
-// default to 32-bit smallint and tagint, 64-bit bigint
+// default to 32-bit smallint and other ints, 64-bit bigint
 
 #if !defined(LAMMPS_SMALLSMALL) && !defined(LAMMPS_BIGBIG) && !defined(LAMMPS_SMALLBIG)
 #define LAMMPS_SMALLBIG
@@ -71,7 +71,7 @@ namespace LAMMPS_NS {
 #endif
 
 // for atomic problems that exceed 2 billion (2^31) atoms
-// 32-bit smallint and imageint and tagint, 64-bit bigint
+// 32-bit smallint/imageint/tagint, 64-bit bigint
 
 #ifdef LAMMPS_SMALLBIG
 
@@ -84,6 +84,7 @@ typedef int64_t bigint;
 #define MAXTAGINT INT_MAX
 #define MAXBIGINT INT64_MAX
 
+#define MPI_LMP_TAGINT MPI_INT
 #define MPI_LMP_BIGINT MPI_LL
 
 #define TAGINT_FORMAT "%d"
@@ -101,7 +102,7 @@ typedef int64_t bigint;
 
 // for molecular problems that exceed 2 billion (2^31) atoms
 // or problems where atoms wrap around the periodic box more than 512 times
-// 32-bit smallint, 64-bit imageint and tagint and bigint
+// 32-bit smallint, 64-bit imageint/tagint/bigint
 
 #ifdef LAMMPS_BIGBIG
 
@@ -114,6 +115,7 @@ typedef int64_t bigint;
 #define MAXTAGINT INT64_MAX
 #define MAXBIGINT INT64_MAX
 
+#define MPI_LMP_TAGINT MPI_LL
 #define MPI_LMP_BIGINT MPI_LL
 
 #define TAGINT_FORMAT "%" PRId64
@@ -130,7 +132,7 @@ typedef int64_t bigint;
 #endif
 
 // for machines that do not support 64-bit ints
-// 32-bit smallint and imageint and tagint and bigint
+// 32-bit smallint/imageint/tagint/bigint
 
 #ifdef LAMMPS_SMALLSMALL
 
@@ -143,6 +145,7 @@ typedef int bigint;
 #define MAXTAGINT INT_MAX
 #define MAXBIGINT INT_MAX
 
+#define MPI_LMP_TAGINT MPI_INT
 #define MPI_LMP_BIGINT MPI_INT
 
 #define TAGINT_FORMAT "%d"
diff --git a/src/molecule.cpp b/src/molecule.cpp
index 669a34ce13653730b315c865bf0059a18d13e633..389a9cf797be0f487e84472fccf3865b847eaa4d 100644
--- a/src/molecule.cpp
+++ b/src/molecule.cpp
@@ -402,29 +402,29 @@ void Molecule::read(int flag)
     } else if (strcmp(keyword,"Bonds") == 0) {
       if (nbonds == 0)
 	error->all(FLERR,"Molecule file has bonds but no nbonds setting");
-      bondflag = 1;
+      bondflag = tag_require = 1;
       bonds(flag,line);
     } else if (strcmp(keyword,"Angles") == 0) {
       if (nangles == 0) 
 	error->all(FLERR,"Molecule file has angles but no nangles setting");
-      angleflag = 1;
+      angleflag = tag_require = 1;
       angles(flag,line);
     } else if (strcmp(keyword,"Dihedrals") == 0) {
       if (ndihedrals == 0) error->all(FLERR,"Molecule file has dihedrals "
 				      "but no ndihedrals setting");
-      dihedralflag = 1;
+      dihedralflag = tag_require = 1;
       dihedrals(flag,line);
     } else if (strcmp(keyword,"Impropers") == 0) {
       if (nimpropers == 0) error->all(FLERR,"Molecule file has impropers "
 				      "but no nimpropers setting");
-      improperflag = 1;
+      improperflag = tag_require = 1;
       impropers(flag,line);
 
     } else if (strcmp(keyword,"Special Bond Counts") == 0) {
       nspecialflag = 1;
       nspecial_read(flag,line);
     } else if (strcmp(keyword,"Special Bonds") == 0) {
-      specialflag = 1;
+      specialflag = tag_require = 1;
       if (flag) special_read(line);
       else skip_lines(natoms,line);
 
@@ -433,7 +433,7 @@ void Molecule::read(int flag)
       if (flag) shakeflag_read(line);
       else skip_lines(natoms,line);
     } else if (strcmp(keyword,"Shake Atoms") == 0) {
-      shakeatomflag = 1;
+      shakeatomflag = tag_require = 1;
       if (shaketypeflag) shakeflag = 1;
       if (!shakeflagflag) 
 	error->all(FLERR,"Molecule file shake flags not before shake atoms");
@@ -1007,6 +1007,7 @@ void Molecule::initialize()
   shakeflag = shakeflagflag = shakeatomflag = shaketypeflag = 0;
 
   centerflag = massflag = comflag = inertiaflag = 0;
+  tag_require = 0;
 
   x = NULL;
   type = NULL;
diff --git a/src/molecule.h b/src/molecule.h
index 11a9c9a22df8e1624b2dde21f8482085ea1670be..7b35f77d1f1d7bc930b9848d7ecfb10ffedfaf29 100644
--- a/src/molecule.h
+++ b/src/molecule.h
@@ -44,6 +44,10 @@ class Molecule : protected Pointers {
 
   int centerflag,massflag,comflag,inertiaflag;
 
+  // 1 if molecule fields require atom IDs
+
+  int tag_require;
+
   // attributes
 
   double **x;          // displacement of each atom from origin
diff --git a/src/neigh_bond.cpp b/src/neigh_bond.cpp
index a73ed41b44af9c8c5b1bb0f7526cbf75ce071b67..17a6e55fd877b9b25f0695079b5d5788dda34cbc 100644
--- a/src/neigh_bond.cpp
+++ b/src/neigh_bond.cpp
@@ -41,9 +41,9 @@ void Neighbor::bond_all()
 
   int nlocal = atom->nlocal;
   int *num_bond = atom->num_bond;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
   int **bond_type = atom->bond_type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int newton_bond = force->newton_bond;
 
   int lostbond = output->thermo->lostbond;
@@ -57,8 +57,8 @@ void Neighbor::bond_all()
         nmissing++;
         if (lostbond == ERROR) {
           char str[128];
-          sprintf(str,
-                  "Bond atoms %d %d missing on proc %d at step " BIGINT_FORMAT,
+          sprintf(str,"Bond atoms " TAGINT_FORMAT " " TAGINT_FORMAT 
+                  " missing on proc %d at step " BIGINT_FORMAT,
                   tag[i],bond_atom[i][m],me,update->ntimestep);
           error->one(FLERR,str);
         }
@@ -98,9 +98,9 @@ void Neighbor::bond_partial()
 
   int nlocal = atom->nlocal;
   int *num_bond = atom->num_bond;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
   int **bond_type = atom->bond_type;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int newton_bond = force->newton_bond;
 
   int lostbond = output->thermo->lostbond;
@@ -115,8 +115,8 @@ void Neighbor::bond_partial()
         nmissing++;
         if (lostbond == ERROR) {
           char str[128];
-          sprintf(str,
-                  "Bond atoms %d %d missing on proc %d at step " BIGINT_FORMAT,
+          sprintf(str,"Bond atoms " TAGINT_FORMAT " " TAGINT_FORMAT 
+                  " missing on proc %d at step " BIGINT_FORMAT,
                   tag[i],bond_atom[i][m],me,update->ntimestep);
           error->one(FLERR,str);
         }
@@ -181,9 +181,9 @@ void Neighbor::angle_all()
 
   int nlocal = atom->nlocal;
   int *num_angle = atom->num_angle;
-  int **angle_atom1 = atom->angle_atom1;
-  int **angle_atom2 = atom->angle_atom2;
-  int **angle_atom3 = atom->angle_atom3;
+  tagint **angle_atom1 = atom->angle_atom1;
+  tagint **angle_atom2 = atom->angle_atom2;
+  tagint **angle_atom3 = atom->angle_atom3;
   int **angle_type = atom->angle_type;
   int newton_bond = force->newton_bond;
 
@@ -200,9 +200,9 @@ void Neighbor::angle_all()
         nmissing++;
         if (lostbond == ERROR) {
           char str[128];
-          sprintf(str,
-                  "Angle atoms %d %d %d missing on proc %d at step "
-                  BIGINT_FORMAT,
+          sprintf(str,"Angle atoms "
+                  TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT 
+                  " missing on proc %d at step " BIGINT_FORMAT,
                   angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m],
                   me,update->ntimestep);
           error->one(FLERR,str);
@@ -246,9 +246,9 @@ void Neighbor::angle_partial()
 
   int nlocal = atom->nlocal;
   int *num_angle = atom->num_angle;
-  int **angle_atom1 = atom->angle_atom1;
-  int **angle_atom2 = atom->angle_atom2;
-  int **angle_atom3 = atom->angle_atom3;
+  tagint **angle_atom1 = atom->angle_atom1;
+  tagint **angle_atom2 = atom->angle_atom2;
+  tagint **angle_atom3 = atom->angle_atom3;
   int **angle_type = atom->angle_type;
   int newton_bond = force->newton_bond;
 
@@ -266,9 +266,9 @@ void Neighbor::angle_partial()
         nmissing++;
         if (lostbond == ERROR) {
           char str[128];
-          sprintf(str,
-                  "Angle atoms %d %d %d missing on proc %d at step "
-                  BIGINT_FORMAT,
+          sprintf(str,"Angle atoms "
+                  TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT 
+                  " missing on proc %d at step " BIGINT_FORMAT,
                   angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m],
                   me,update->ntimestep);
           error->one(FLERR,str);
@@ -351,10 +351,10 @@ void Neighbor::dihedral_all()
 
   int nlocal = atom->nlocal;
   int *num_dihedral = atom->num_dihedral;
-  int **dihedral_atom1 = atom->dihedral_atom1;
-  int **dihedral_atom2 = atom->dihedral_atom2;
-  int **dihedral_atom3 = atom->dihedral_atom3;
-  int **dihedral_atom4 = atom->dihedral_atom4;
+  tagint **dihedral_atom1 = atom->dihedral_atom1;
+  tagint **dihedral_atom2 = atom->dihedral_atom2;
+  tagint **dihedral_atom3 = atom->dihedral_atom3;
+  tagint **dihedral_atom4 = atom->dihedral_atom4;
   int **dihedral_type = atom->dihedral_type;
   int newton_bond = force->newton_bond;
 
@@ -372,9 +372,10 @@ void Neighbor::dihedral_all()
         nmissing++;
         if (lostbond == ERROR) {
           char str[128];
-          sprintf(str,
-                  "Dihedral atoms %d %d %d %d missing on proc %d at step "
-                  BIGINT_FORMAT,
+          sprintf(str,"Dihedral atoms "
+                  TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                  TAGINT_FORMAT " " TAGINT_FORMAT 
+                  " missing on proc %d at step " BIGINT_FORMAT,
                   dihedral_atom1[i][m],dihedral_atom2[i][m],
                   dihedral_atom3[i][m],dihedral_atom4[i][m],
                   me,update->ntimestep);
@@ -422,10 +423,10 @@ void Neighbor::dihedral_partial()
 
   int nlocal = atom->nlocal;
   int *num_dihedral = atom->num_dihedral;
-  int **dihedral_atom1 = atom->dihedral_atom1;
-  int **dihedral_atom2 = atom->dihedral_atom2;
-  int **dihedral_atom3 = atom->dihedral_atom3;
-  int **dihedral_atom4 = atom->dihedral_atom4;
+  tagint **dihedral_atom1 = atom->dihedral_atom1;
+  tagint **dihedral_atom2 = atom->dihedral_atom2;
+  tagint **dihedral_atom3 = atom->dihedral_atom3;
+  tagint **dihedral_atom4 = atom->dihedral_atom4;
   int **dihedral_type = atom->dihedral_type;
   int newton_bond = force->newton_bond;
 
@@ -444,9 +445,10 @@ void Neighbor::dihedral_partial()
         nmissing++;
         if (lostbond == ERROR) {
           char str[128];
-          sprintf(str,
-                  "Dihedral atoms %d %d %d %d missing on proc %d at step "
-                  BIGINT_FORMAT,
+          sprintf(str,"Dihedral atoms "
+                  TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                  TAGINT_FORMAT " " TAGINT_FORMAT 
+                  " missing on proc %d at step " BIGINT_FORMAT,
                   dihedral_atom1[i][m],dihedral_atom2[i][m],
                   dihedral_atom3[i][m],dihedral_atom4[i][m],
                   me,update->ntimestep);
@@ -550,10 +552,10 @@ void Neighbor::improper_all()
 
   int nlocal = atom->nlocal;
   int *num_improper = atom->num_improper;
-  int **improper_atom1 = atom->improper_atom1;
-  int **improper_atom2 = atom->improper_atom2;
-  int **improper_atom3 = atom->improper_atom3;
-  int **improper_atom4 = atom->improper_atom4;
+  tagint **improper_atom1 = atom->improper_atom1;
+  tagint **improper_atom2 = atom->improper_atom2;
+  tagint **improper_atom3 = atom->improper_atom3;
+  tagint **improper_atom4 = atom->improper_atom4;
   int **improper_type = atom->improper_type;
   int newton_bond = force->newton_bond;
 
@@ -571,9 +573,10 @@ void Neighbor::improper_all()
         nmissing++;
         if (lostbond == ERROR) {
           char str[128];
-          sprintf(str,
-                  "Improper atoms %d %d %d %d missing on proc %d at step "
-                  BIGINT_FORMAT,
+          sprintf(str,"Improper atoms "
+                  TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                  TAGINT_FORMAT " " TAGINT_FORMAT 
+                  " missing on proc %d at step " BIGINT_FORMAT,
                   improper_atom1[i][m],improper_atom2[i][m],
                   improper_atom3[i][m],improper_atom4[i][m],
                   me,update->ntimestep);
@@ -621,10 +624,10 @@ void Neighbor::improper_partial()
 
   int nlocal = atom->nlocal;
   int *num_improper = atom->num_improper;
-  int **improper_atom1 = atom->improper_atom1;
-  int **improper_atom2 = atom->improper_atom2;
-  int **improper_atom3 = atom->improper_atom3;
-  int **improper_atom4 = atom->improper_atom4;
+  tagint **improper_atom1 = atom->improper_atom1;
+  tagint **improper_atom2 = atom->improper_atom2;
+  tagint **improper_atom3 = atom->improper_atom3;
+  tagint **improper_atom4 = atom->improper_atom4;
   int **improper_type = atom->improper_type;
   int newton_bond = force->newton_bond;
 
@@ -643,9 +646,10 @@ void Neighbor::improper_partial()
         nmissing++;
         if (lostbond == ERROR) {
           char str[128];
-          sprintf(str,
-                  "Improper atoms %d %d %d %d missing on proc %d at step "
-                  BIGINT_FORMAT,
+          sprintf(str,"Improper atoms "
+                  TAGINT_FORMAT " " TAGINT_FORMAT " " 
+                  TAGINT_FORMAT " " TAGINT_FORMAT 
+                  " missing on proc %d at step " BIGINT_FORMAT,
                   improper_atom1[i][m],improper_atom2[i][m],
                   improper_atom3[i][m],improper_atom4[i][m],
                   me,update->ntimestep);
diff --git a/src/neigh_full.cpp b/src/neigh_full.cpp
index 0c830b372026cef0f86d8793bb225806967bd393..7b536f469991dde548abf30be86acce65653aa60 100644
--- a/src/neigh_full.cpp
+++ b/src/neigh_full.cpp
@@ -32,9 +32,9 @@ void Neighbor::full_nsq(NeighList *list)
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   int *neighptr;
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -115,9 +115,9 @@ void Neighbor::full_nsq_ghost(NeighList *list)
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   int *neighptr;
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -212,9 +212,9 @@ void Neighbor::full_bin(NeighList *list)
 
   bin_atoms();
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -303,9 +303,9 @@ void Neighbor::full_bin_ghost(NeighList *list)
 
   bin_atoms();
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -424,9 +424,9 @@ void Neighbor::full_multi(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
diff --git a/src/neigh_gran.cpp b/src/neigh_gran.cpp
index 204988e23049d31aec75fa2ed91eb269688d74f0..465e6af863fdf20b07eed6860e4df5ea2cf30b6d 100644
--- a/src/neigh_gran.cpp
+++ b/src/neigh_gran.cpp
@@ -37,7 +37,8 @@ void Neighbor::granular_nsq_no_newton(NeighList *list)
   double *shearptr;
 
   NeighList *listgranhistory;
-  int *npartner,**partner;
+  int *npartner;
+  tagint **partner;
   double (**shearpartner)[3];
   int **firsttouch;
   double **firstshear;
@@ -46,7 +47,7 @@ void Neighbor::granular_nsq_no_newton(NeighList *list)
 
   double **x = atom->x;
   double *radius = atom->radius;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   int *molecule = atom->molecule;
@@ -174,7 +175,7 @@ void Neighbor::granular_nsq_newton(NeighList *list)
 
   double **x = atom->x;
   double *radius = atom->radius;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   int *molecule = atom->molecule;
@@ -264,7 +265,8 @@ void Neighbor::granular_bin_no_newton(NeighList *list)
   double *shearptr;
 
   NeighList *listgranhistory;
-  int *npartner,**partner;
+  int *npartner;
+  tagint **partner;
   double (**shearpartner)[3];
   int **firsttouch;
   double **firstshear;
@@ -279,7 +281,7 @@ void Neighbor::granular_bin_no_newton(NeighList *list)
 
   double **x = atom->x;
   double *radius = atom->radius;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   int *molecule = atom->molecule;
diff --git a/src/neigh_half_bin.cpp b/src/neigh_half_bin.cpp
index ef55cb5ba145de4461e40f873919bee496946077..75736e97d28ce31b300440ba1a7c46ef8eb09d33 100644
--- a/src/neigh_half_bin.cpp
+++ b/src/neigh_half_bin.cpp
@@ -39,9 +39,9 @@ void Neighbor::half_bin_no_newton(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -134,9 +134,9 @@ void Neighbor::half_bin_no_newton_ghost(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -256,9 +256,9 @@ void Neighbor::half_bin_newton(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -375,9 +375,9 @@ void Neighbor::half_bin_newton_tri(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
diff --git a/src/neigh_half_multi.cpp b/src/neigh_half_multi.cpp
index 46a76be6dbd45fa2d58b47feaa3856912b3df0d0..fddc683fb7c8d9fbd7e04dd06fea4b86cb3475ec 100644
--- a/src/neigh_half_multi.cpp
+++ b/src/neigh_half_multi.cpp
@@ -41,9 +41,9 @@ void Neighbor::half_multi_no_newton(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -140,9 +140,9 @@ void Neighbor::half_multi_newton(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -267,9 +267,9 @@ void Neighbor::half_multi_newton_tri(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
diff --git a/src/neigh_half_nsq.cpp b/src/neigh_half_nsq.cpp
index 8446c9d982ff1f1f2065e25d33bb18ac85064a57..f8fad972bbd96d85db547cc8eeb4d8b716149f77 100644
--- a/src/neigh_half_nsq.cpp
+++ b/src/neigh_half_nsq.cpp
@@ -32,9 +32,9 @@ void Neighbor::half_nsq_no_newton(NeighList *list)
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   int *neighptr;
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -116,9 +116,9 @@ void Neighbor::half_nsq_no_newton_ghost(NeighList *list)
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   int *neighptr;
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -221,9 +221,9 @@ void Neighbor::half_nsq_newton(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
diff --git a/src/neigh_respa.cpp b/src/neigh_respa.cpp
index 8d1ea14ae5e5d88d2f374082ee3a762659ea4969..738426abdb2e2ac5f8be83760d8347f9288bfcc6 100644
--- a/src/neigh_respa.cpp
+++ b/src/neigh_respa.cpp
@@ -36,9 +36,9 @@ void Neighbor::respa_nsq_no_newton(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -179,9 +179,9 @@ void Neighbor::respa_nsq_newton(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -344,9 +344,9 @@ void Neighbor::respa_bin_no_newton(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -497,9 +497,9 @@ void Neighbor::respa_bin_newton(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
@@ -691,9 +691,9 @@ void Neighbor::respa_bin_newton_tri(NeighList *list)
 
   // loop over each atom, storing neighbors
 
-  int **special = atom->special;
+  tagint **special = atom->special;
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
 
   double **x = atom->x;
   int *type = atom->type;
diff --git a/src/neighbor.h b/src/neighbor.h
index 13590dd473586597ff34432b53126406d2c20e0c..751e15523165ec6d435a17db248b2166ca6609be 100644
--- a/src/neighbor.h
+++ b/src/neighbor.h
@@ -284,8 +284,8 @@ class Neighbor : protected Pointers {
   // if it is and special flag is 2 (otherwise), return 1,2,3
   //   for which level of neighbor it is (and which coeff it maps to)
 
-  inline int find_special(const int *list, const int *nspecial,
-                          const int tag) const {
+  inline int find_special(const tagint *list, const int *nspecial,
+                          const tagint tag) const {
     const int n1 = nspecial[0];
     const int n2 = nspecial[1];
     const int n3 = nspecial[2];
diff --git a/src/read_data.cpp b/src/read_data.cpp
index 52f7f5082046127671636451b1957bf3e2a9e4ea..c32976d28a6c2bd14b785bfaf64f86f316018e3b 100644
--- a/src/read_data.cpp
+++ b/src/read_data.cpp
@@ -138,243 +138,338 @@ void ReadData::command(int narg, char **arg)
     } else error->all(FLERR,"Illegal read_data command");
   }
 
-  // scan data file to determine max topology needed per atom
-  // allocate initial topology arrays
 
-  if (atom->molecular) {
-    if (me == 0) {
-      if (screen) fprintf(screen,"Scanning data file ...\n");
-      open(arg[0]);
-      header(0);
-      scan(atom->bond_per_atom,atom->angle_per_atom,
-           atom->dihedral_per_atom,atom->improper_per_atom);
-      if (compressed) pclose(fp);
-      else fclose(fp);
-      atom->bond_per_atom += atom->extra_bond_per_atom;
-      atom->angle_per_atom += atom->extra_angle_per_atom;
-      atom->dihedral_per_atom += atom->extra_dihedral_per_atom;
-      atom->improper_per_atom += atom->extra_improper_per_atom;
-    }
+  // perform 1-pass read if no molecular topoogy in file
+  // perform 2-pass read if molecular topology
+  //   1st pass calculates max topology/atom
 
-    MPI_Bcast(&atom->bond_per_atom,1,MPI_INT,0,world);
-    MPI_Bcast(&atom->angle_per_atom,1,MPI_INT,0,world);
-    MPI_Bcast(&atom->dihedral_per_atom,1,MPI_INT,0,world);
-    MPI_Bcast(&atom->improper_per_atom,1,MPI_INT,0,world);
+  int atomflag,topoflag;
+  int bondflag,angleflag,dihedralflag,improperflag;
+  int ellipsoidflag,lineflag,triflag,bodyflag;
 
-  } else
-    atom->bond_per_atom = atom->angle_per_atom =
-      atom->dihedral_per_atom = atom->improper_per_atom = 0;
+  atomflag = topoflag = 0;
+  bondflag = angleflag = dihedralflag = improperflag = 0;
+  ellipsoidflag = lineflag = triflag = bodyflag = 0;
 
-  // read header info
+  int firstpass = 1;
 
-  if (me == 0) {
-    if (screen) fprintf(screen,"Reading data file ...\n");
-    open(arg[0]);
-  } else fp = NULL;
-  header(1);
-  domain->box_exist = 1;
-
-  // problem setup using info from header
+  while (1) {
 
-  update->ntimestep = 0;
+    // open file on proc 0
 
-  int n;
-  if (comm->nprocs == 1) n = static_cast<int> (atom->natoms);
-  else n = static_cast<int> (LB_FACTOR * atom->natoms / comm->nprocs);
+    if (me == 0) {
+      if (firstpass && screen) fprintf(screen,"Reading data file ...\n");
+      open(arg[0]);
+    } else fp = NULL;
+    
+    // read header info
+    
+    header();
+
+    // problem setup using info from header
+    // 1st pass only
+
+    if (firstpass) {
+      domain->box_exist = 1;
+      update->ntimestep = 0;
+    
+      int n;
+      if (comm->nprocs == 1) n = static_cast<int> (atom->natoms);
+      else n = static_cast<int> (LB_FACTOR * atom->natoms / comm->nprocs);
+
+      atom->allocate_type_arrays();
+      atom->avec->grow(n);
+      n = atom->nmax;
+
+      domain->print_box("  ");
+      domain->set_initial_box();
+      domain->set_global_box();
+      comm->set_proc_grid();
+      domain->set_local_box();
+    }
 
-  atom->allocate_type_arrays();
-  atom->avec->grow(n);
-  n = atom->nmax;
+    // customize for new sections
+    // read rest of file in free format
 
-  domain->print_box("  ");
-  domain->set_initial_box();
-  domain->set_global_box();
-  comm->set_proc_grid();
-  domain->set_local_box();
+    while (strlen(keyword)) {
 
-  // customize for new sections
-  // read rest of file in free format
+      // if special fix matches, it processes section
 
-  int atomflag = 0;
+      if (nfix) {
+        int i;
+        for (i = 0; i < nfix; i++)
+          if (strcmp(keyword,fix_section[i]) == 0) {
+            if (firstpass) fix(i,keyword);
+            else skip_lines(modify->fix[fix_index[i]]->
+                            read_data_skip_lines(keyword));
+            parse_keyword(0);
+            break;
+          }
+        if (i < nfix) continue;
+      }
 
-  while (strlen(keyword)) {
+      if (strcmp(keyword,"Atoms") == 0) {
+        atomflag = 1;
+        if (firstpass) atoms();
+        else skip_lines(atom->natoms);
+      } else if (strcmp(keyword,"Velocities") == 0) {
+        if (atomflag == 0) 
+          error->all(FLERR,"Must read Atoms before Velocities");
+        if (firstpass) velocities();
+        else skip_lines(atom->natoms);
+
+      } else if (strcmp(keyword,"Bonds") == 0) {
+        topoflag = bondflag = 1;
+        if (atom->avec->bonds_allow == 0)
+          error->all(FLERR,"Invalid data file section: Bonds");
+        if (atomflag == 0) error->all(FLERR,"Must read Atoms before Bonds");
+        bonds(firstpass);
+      } else if (strcmp(keyword,"Angles") == 0) {
+        topoflag = angleflag = 1;
+        if (atom->avec->angles_allow == 0)
+          error->all(FLERR,"Invalid data file section: Angles");
+        if (atomflag == 0) error->all(FLERR,"Must read Atoms before Angles");
+        angles(firstpass);
+      } else if (strcmp(keyword,"Dihedrals") == 0) {
+        topoflag = dihedralflag = 1;
+        if (atom->avec->dihedrals_allow == 0)
+          error->all(FLERR,"Invalid data file section: Dihedrals");
+        if (atomflag == 0) error->all(FLERR,"Must read Atoms before Dihedrals");
+        dihedrals(firstpass);
+      } else if (strcmp(keyword,"Impropers") == 0) {
+        topoflag = improperflag = 1;
+        if (atom->avec->impropers_allow == 0)
+          error->all(FLERR,"Invalid data file section: Impropers");
+        if (atomflag == 0) error->all(FLERR,"Must read Atoms before Impropers");
+        impropers(firstpass);
+        
+      } else if (strcmp(keyword,"Ellipsoids") == 0) {
+        ellipsoidflag = 1;
+        if (!avec_ellipsoid)
+          error->all(FLERR,"Invalid data file section: Ellipsoids");
+        if (atomflag == 0) 
+          error->all(FLERR,"Must read Atoms before Ellipsoids");
+        if (firstpass) 
+          bonus(nellipsoids,(AtomVec *) avec_ellipsoid,"ellipsoids");
+        else skip_lines(nellipsoids);
+      } else if (strcmp(keyword,"Lines") == 0) {
+        lineflag = 1;
+        if (!avec_line)
+          error->all(FLERR,"Invalid data file section: Lines");
+        if (atomflag == 0) error->all(FLERR,"Must read Atoms before Lines");
+        if (firstpass) bonus(nlines,(AtomVec *) avec_line,"lines");
+        else skip_lines(nlines);
+      } else if (strcmp(keyword,"Triangles") == 0) {
+        triflag = 1;
+        if (!avec_tri)
+          error->all(FLERR,"Invalid data file section: Triangles");
+        if (atomflag == 0) error->all(FLERR,"Must read Atoms before Triangles");
+        if (firstpass) bonus(ntris,(AtomVec *) avec_tri,"triangles");
+        else skip_lines(ntris);
+      } else if (strcmp(keyword,"Bodies") == 0) {
+        bodyflag = 1;
+        if (!avec_body)
+          error->all(FLERR,"Invalid data file section: Bodies");
+        if (atomflag == 0) error->all(FLERR,"Must read Atoms before Bodies");
+        bodies(firstpass);
+
+      } else if (strcmp(keyword,"Masses") == 0) {
+        if (firstpass) mass();
+        else skip_lines(atom->ntypes);
+      } else if (strcmp(keyword,"Pair Coeffs") == 0) {
+        if (force->pair == NULL)
+          error->all(FLERR,"Must define pair_style before Pair Coeffs");
+        if (firstpass) paircoeffs();
+        else skip_lines(atom->ntypes);
+      } else if (strcmp(keyword,"PairIJ Coeffs") == 0) {
+        if (force->pair == NULL)
+          error->all(FLERR,"Must define pair_style before PairIJ Coeffs");
+        if (firstpass) pairIJcoeffs();
+        else skip_lines(atom->ntypes*(atom->ntypes+1)/2);
+      } else if (strcmp(keyword,"Bond Coeffs") == 0) {
+        if (atom->avec->bonds_allow == 0)
+          error->all(FLERR,"Invalid data file section: Bond Coeffs");
+        if (force->bond == NULL)
+          error->all(FLERR,"Must define bond_style before Bond Coeffs");
+        if (firstpass) bondcoeffs();
+        else skip_lines(atom->nbondtypes);
+      } else if (strcmp(keyword,"Angle Coeffs") == 0) {
+        if (atom->avec->angles_allow == 0)
+          error->all(FLERR,"Invalid data file section: Angle Coeffs");
+        if (force->angle == NULL)
+          error->all(FLERR,"Must define angle_style before Angle Coeffs");
+        if (firstpass) anglecoeffs(0);
+        else skip_lines(atom->nangletypes);
+      } else if (strcmp(keyword,"Dihedral Coeffs") == 0) {
+        if (atom->avec->dihedrals_allow == 0)
+          error->all(FLERR,"Invalid data file section: Dihedral Coeffs");
+        if (force->dihedral == NULL)
+          error->all(FLERR,"Must define dihedral_style before Dihedral Coeffs");
+        if (firstpass) dihedralcoeffs(0);
+        else skip_lines(atom->ndihedraltypes);
+      } else if (strcmp(keyword,"Improper Coeffs") == 0) {
+        if (atom->avec->impropers_allow == 0)
+          error->all(FLERR,"Invalid data file section: Improper Coeffs");
+        if (force->improper == NULL)
+          error->all(FLERR,"Must define improper_style before Improper Coeffs");
+        if (firstpass) impropercoeffs(0);
+        else skip_lines(atom->nimpropertypes);
+
+      } else if (strcmp(keyword,"BondBond Coeffs") == 0) {
+        if (atom->avec->angles_allow == 0)
+          error->all(FLERR,"Invalid data file section: BondBond Coeffs");
+        if (force->angle == NULL)
+          error->all(FLERR,"Must define angle_style before BondBond Coeffs");
+        if (firstpass) anglecoeffs(1);
+        else skip_lines(atom->nangletypes);
+      } else if (strcmp(keyword,"BondAngle Coeffs") == 0) {
+        if (atom->avec->angles_allow == 0)
+          error->all(FLERR,"Invalid data file section: BondAngle Coeffs");
+        if (force->angle == NULL)
+          error->all(FLERR,"Must define angle_style before BondAngle Coeffs");
+        if (firstpass) anglecoeffs(2);
+        else skip_lines(atom->nangletypes);
+
+      } else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) {
+        if (atom->avec->dihedrals_allow == 0)
+          error->all(FLERR,
+                     "Invalid data file section: MiddleBondTorsion Coeffs");
+        if (force->dihedral == NULL)
+          error->all(FLERR,
+                     "Must define dihedral_style before "
+                     "MiddleBondTorsion Coeffs");
+        if (firstpass) dihedralcoeffs(1);
+        else skip_lines(atom->ndihedraltypes);
+      } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
+        if (atom->avec->dihedrals_allow == 0)
+          error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
+        if (force->dihedral == NULL)
+          error->all(FLERR,
+                     "Must define dihedral_style before EndBondTorsion Coeffs");
+        if (firstpass) dihedralcoeffs(2);
+        else skip_lines(atom->ndihedraltypes);
+      } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
+        if (atom->avec->dihedrals_allow == 0)
+          error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs");
+        if (force->dihedral == NULL)
+          error->all(FLERR,
+                     "Must define dihedral_style before AngleTorsion Coeffs");
+        if (firstpass) dihedralcoeffs(3);
+        else skip_lines(atom->ndihedraltypes);
+      } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
+        if (atom->avec->dihedrals_allow == 0)
+          error->all(FLERR,
+                     "Invalid data file section: AngleAngleTorsion Coeffs");
+        if (force->dihedral == NULL)
+          error->all(FLERR,
+                     "Must define dihedral_style before "
+                     "AngleAngleTorsion Coeffs");
+        if (firstpass) dihedralcoeffs(4);
+        else skip_lines(atom->ndihedraltypes);
+      } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
+        if (atom->avec->dihedrals_allow == 0)
+          error->all(FLERR,"Invalid data file section: BondBond13 Coeffs");
+        if (force->dihedral == NULL)
+          error->all(FLERR,
+                     "Must define dihedral_style before BondBond13 Coeffs");
+        if (firstpass) dihedralcoeffs(5);
+        else skip_lines(atom->ndihedraltypes);
+        
+      } else if (strcmp(keyword,"AngleAngle Coeffs") == 0) {
+        if (atom->avec->impropers_allow == 0)
+          error->all(FLERR,"Invalid data file section: AngleAngle Coeffs");
+        if (force->improper == NULL)
+          error->all(FLERR,
+                     "Must define improper_style before AngleAngle Coeffs");
+        if (firstpass) impropercoeffs(1);
+        else skip_lines(atom->nimpropertypes);
+
+      } else {
+        char str[128];
+        sprintf(str,"Unknown identifier in data file: %s",keyword);
+        error->all(FLERR,str);
+      }
+      
+      parse_keyword(0);
+    }
 
-    // allow special fixes first chance to match and process the section
-    // if fix matches, continue to next section
+    // error if natoms > 0 yet no atoms were read
 
-    if (nfix) {
-      for (n = 0; n < nfix; n++)
-        if (strcmp(keyword,fix_section[n]) == 0) {
-          fix(n,keyword);
-          parse_keyword(0,1);
-          break;
-        }
-      if (n < nfix) continue;
+    if (atom->natoms > 0 && atomflag == 0)
+      error->all(FLERR,"No atoms in data file");
+    
+    // close file
+    
+    if (me == 0) {
+      if (compressed) pclose(fp);
+      else fclose(fp);
     }
 
-    if (strcmp(keyword,"Atoms") == 0) {
-      atoms();
-      atomflag = 1;
-    } else if (strcmp(keyword,"Velocities") == 0) {
-      if (atomflag == 0) error->all(FLERR,"Must read Atoms before Velocities");
-      velocities();
-
-    } else if (strcmp(keyword,"Ellipsoids") == 0) {
-      if (!avec_ellipsoid)
-        error->all(FLERR,"Invalid data file section: Ellipsoids");
-      if (atomflag == 0) error->all(FLERR,"Must read Atoms before Ellipsoids");
-      bonus(nellipsoids,(AtomVec *) avec_ellipsoid,"ellipsoids");
-    } else if (strcmp(keyword,"Lines") == 0) {
-      if (!avec_line)
-        error->all(FLERR,"Invalid data file section: Lines");
-      if (atomflag == 0) error->all(FLERR,"Must read Atoms before Lines");
-      bonus(nlines,(AtomVec *) avec_line,"lines");
-    } else if (strcmp(keyword,"Triangles") == 0) {
-      if (!avec_tri)
-        error->all(FLERR,"Invalid data file section: Triangles");
-      if (atomflag == 0) error->all(FLERR,"Must read Atoms before Triangles");
-      bonus(ntris,(AtomVec *) avec_tri,"triangles");
-    } else if (strcmp(keyword,"Bodies") == 0) {
-      if (!avec_body)
-        error->all(FLERR,"Invalid data file section: Bodies");
-      if (atomflag == 0) error->all(FLERR,"Must read Atoms before Bodies");
-      bodies();
-
-    } else if (strcmp(keyword,"Bonds") == 0) {
-      if (atom->avec->bonds_allow == 0)
-        error->all(FLERR,"Invalid data file section: Bonds");
-      if (atomflag == 0) error->all(FLERR,"Must read Atoms before Bonds");
-      bonds();
-    } else if (strcmp(keyword,"Angles") == 0) {
-      if (atom->avec->angles_allow == 0)
-        error->all(FLERR,"Invalid data file section: Angles");
-      if (atomflag == 0) error->all(FLERR,"Must read Atoms before Angles");
-      angles();
-    } else if (strcmp(keyword,"Dihedrals") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->all(FLERR,"Invalid data file section: Dihedrals");
-      if (atomflag == 0) error->all(FLERR,"Must read Atoms before Dihedrals");
-      dihedrals();
-    } else if (strcmp(keyword,"Impropers") == 0) {
-      if (atom->avec->impropers_allow == 0)
-        error->all(FLERR,"Invalid data file section: Impropers");
-      if (atomflag == 0) error->all(FLERR,"Must read Atoms before Impropers");
-      impropers();
-
-    } else if (strcmp(keyword,"Masses") == 0) {
-      mass();
-    } else if (strcmp(keyword,"Pair Coeffs") == 0) {
-      if (force->pair == NULL)
-        error->all(FLERR,"Must define pair_style before Pair Coeffs");
-      paircoeffs();
-    } else if (strcmp(keyword,"PairIJ Coeffs") == 0) {
-      if (force->pair == NULL)
-        error->all(FLERR,"Must define pair_style before PairIJ Coeffs");
-      pairIJcoeffs();
-    } else if (strcmp(keyword,"Bond Coeffs") == 0) {
-      if (atom->avec->bonds_allow == 0)
-        error->all(FLERR,"Invalid data file section: Bond Coeffs");
-      if (force->bond == NULL)
-        error->all(FLERR,"Must define bond_style before Bond Coeffs");
-      bondcoeffs();
-    } else if (strcmp(keyword,"Angle Coeffs") == 0) {
-      if (atom->avec->angles_allow == 0)
-        error->all(FLERR,"Invalid data file section: Angle Coeffs");
-      if (force->angle == NULL)
-        error->all(FLERR,"Must define angle_style before Angle Coeffs");
-      anglecoeffs(0);
-    } else if (strcmp(keyword,"Dihedral Coeffs") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->all(FLERR,"Invalid data file section: Dihedral Coeffs");
-      if (force->dihedral == NULL)
-        error->all(FLERR,"Must define dihedral_style before Dihedral Coeffs");
-      dihedralcoeffs(0);
-    } else if (strcmp(keyword,"Improper Coeffs") == 0) {
-      if (atom->avec->impropers_allow == 0)
-        error->all(FLERR,"Invalid data file section: Improper Coeffs");
-      if (force->improper == NULL)
-        error->all(FLERR,"Must define improper_style before Improper Coeffs");
-      impropercoeffs(0);
-
-    } else if (strcmp(keyword,"BondBond Coeffs") == 0) {
-      if (atom->avec->angles_allow == 0)
-        error->all(FLERR,"Invalid data file section: BondBond Coeffs");
-      if (force->angle == NULL)
-        error->all(FLERR,"Must define angle_style before BondBond Coeffs");
-      anglecoeffs(1);
-    } else if (strcmp(keyword,"BondAngle Coeffs") == 0) {
-      if (atom->avec->angles_allow == 0)
-        error->all(FLERR,"Invalid data file section: BondAngle Coeffs");
-      if (force->angle == NULL)
-        error->all(FLERR,"Must define angle_style before BondAngle Coeffs");
-      anglecoeffs(2);
-
-    } else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs");
-      if (force->dihedral == NULL)
-        error->all(FLERR,
-                   "Must define dihedral_style before "
-                   "MiddleBondTorsion Coeffs");
-      dihedralcoeffs(1);
-    } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
-      if (force->dihedral == NULL)
-        error->all(FLERR,
-                   "Must define dihedral_style before EndBondTorsion Coeffs");
-      dihedralcoeffs(2);
-    } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs");
-      if (force->dihedral == NULL)
-        error->all(FLERR,
-                   "Must define dihedral_style before AngleTorsion Coeffs");
-      dihedralcoeffs(3);
-    } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs");
-      if (force->dihedral == NULL)
-        error->all(FLERR,
-                   "Must define dihedral_style before "
-                   "AngleAngleTorsion Coeffs");
-      dihedralcoeffs(4);
-    } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->all(FLERR,"Invalid data file section: BondBond13 Coeffs");
-      if (force->dihedral == NULL)
-        error->all(FLERR,"Must define dihedral_style before BondBond13 Coeffs");
-      dihedralcoeffs(5);
-
-    } else if (strcmp(keyword,"AngleAngle Coeffs") == 0) {
-      if (atom->avec->impropers_allow == 0)
-        error->all(FLERR,"Invalid data file section: AngleAngle Coeffs");
-      if (force->improper == NULL)
-        error->all(FLERR,"Must define improper_style before AngleAngle Coeffs");
-      impropercoeffs(1);
+    // done if this was 2nd pass
 
-    } else {
-      char str[128];
-      sprintf(str,"Unknown identifier in data file: %s",keyword);
-      error->all(FLERR,str);
-    }
+    if (!firstpass) break;
 
-    parse_keyword(0,1);
-  }
+    // at end of 1st pass, error check for required sections
+    // customize for new sections
 
-  // close file
+    if ((atom->nbonds && !bondflag) || (atom->nangles && !angleflag) ||
+        (atom->ndihedrals && !dihedralflag) ||
+        (atom->nimpropers && !improperflag))
+      error->one(FLERR,"Needed molecular topology not in data file");
 
-  if (me == 0) {
-    if (compressed) pclose(fp);
-    else fclose(fp);
-  }
+    if ((nellipsoids && !ellipsoidflag) || (nlines && !lineflag) ||
+        (ntris && !triflag) || (nbodies && !bodyflag))
+      error->one(FLERR,"Needed bonus data not in data file");
 
-  // error if natoms > 0 yet no atoms were read
+    // break out of loop if no molecular topology in file
+    // else make 2nd pass
+    
+    if (!topoflag) break;
+    firstpass = 0;
 
-  if (atom->natoms > 0 && atomflag == 0)
-    error->all(FLERR,"No atoms in data file");
+    // reallocate bond,angle,diehdral,improper arrays via grow(),
+    // using new bond,angle,dihedral,improper per-atom values from 1st pass
+    // should leave other atom arrays unchanged, since already nmax in length
 
-  // create bond topology now that system is defined
+    if (bondflag) {
+      memory->destroy(atom->bond_type);
+      memory->destroy(atom->bond_atom);
+      atom->bond_type = NULL;
+      atom->bond_atom = NULL;
+    }
+    if (angleflag) {
+      memory->destroy(atom->angle_type);
+      memory->destroy(atom->angle_atom1);
+      memory->destroy(atom->angle_atom2);
+      memory->destroy(atom->angle_atom3);
+      atom->angle_type = NULL;
+      atom->angle_atom1 = atom->angle_atom2 = atom->angle_atom3 = NULL;
+    }
+    if (dihedralflag) {
+      memory->destroy(atom->dihedral_type);
+      memory->destroy(atom->dihedral_atom1);
+      memory->destroy(atom->dihedral_atom2);
+      memory->destroy(atom->dihedral_atom3);
+      memory->destroy(atom->dihedral_atom4);
+      atom->dihedral_type = NULL;
+      atom->dihedral_atom1 = atom->dihedral_atom2 = 
+        atom->dihedral_atom3 = atom->dihedral_atom4 = NULL;
+    }
+    if (improperflag) {
+      memory->destroy(atom->improper_type);
+      memory->destroy(atom->improper_atom1);
+      memory->destroy(atom->improper_atom2);
+      memory->destroy(atom->improper_atom3);
+      memory->destroy(atom->improper_atom4);
+      atom->improper_type = NULL;
+      atom->improper_atom1 = atom->improper_atom2 = 
+        atom->improper_atom3 = atom->improper_atom4 = NULL;
+    }
+
+    atom->avec->grow(atom->nmax);
+  }
+
+  // create special bond lists for molecular systems
 
   if (atom->molecular) {
     Special special(lmp);
@@ -384,8 +479,6 @@ void ReadData::command(int narg, char **arg)
 
 /* ----------------------------------------------------------------------
    read free-format header of data file
-   if flag = 0, only called by proc 0
-   if flag = 1, called by all procs so bcast lines as read them
    1st line and blank lines are skipped
    non-blank lines are checked for header keywords and leading value is read
    header ends with EOF or non-blank line containing no header keyword
@@ -393,7 +486,7 @@ void ReadData::command(int narg, char **arg)
      else line has first keyword line for rest of file
 ------------------------------------------------------------------------- */
 
-void ReadData::header(int flag)
+void ReadData::header()
 {
   int n;
   char *ptr;
@@ -426,7 +519,7 @@ void ReadData::header(int flag)
       if (fgets(line,MAXLINE,fp) == NULL) n = 0;
       else n = strlen(line) + 1;
     }
-    if (flag) MPI_Bcast(&n,1,MPI_INT,0,world);
+    MPI_Bcast(&n,1,MPI_INT,0,world);
 
     // if n = 0 then end-of-file so return with blank line
 
@@ -435,9 +528,7 @@ void ReadData::header(int flag)
       return;
     }
 
-    // bcast line if flag is set
-
-    if (flag) MPI_Bcast(line,n,MPI_CHAR,0,world);
+    MPI_Bcast(line,n,MPI_CHAR,0,world);
 
     // trim anything from '#' onward
     // if line is blank, continue
@@ -525,17 +616,17 @@ void ReadData::header(int flag)
 
   // error check on total system size
 
-  if (atom->natoms < 0 || atom->natoms > MAXBIGINT ||
-      atom->nbonds < 0 || atom->nbonds > MAXBIGINT ||
-      atom->nangles < 0 || atom->nangles > MAXBIGINT ||
-      atom->ndihedrals < 0 || atom->ndihedrals > MAXBIGINT ||
-      atom->nimpropers < 0 || atom->nimpropers > MAXBIGINT) {
+  if (atom->natoms < 0 || atom->natoms >= MAXBIGINT ||
+      atom->nbonds < 0 || atom->nbonds >= MAXBIGINT ||
+      atom->nangles < 0 || atom->nangles >= MAXBIGINT ||
+      atom->ndihedrals < 0 || atom->ndihedrals >= MAXBIGINT ||
+      atom->nimpropers < 0 || atom->nimpropers >= MAXBIGINT) {
     if (me == 0) error->one(FLERR,"System in data file is too big");
   }
 
   // check that exiting string is a valid section keyword
 
-  parse_keyword(1,flag);
+  parse_keyword(1);
   for (n = 0; n < NSECTIONS; n++)
     if (strcmp(keyword,section_keywords[n]) == 0) break;
   if (n == NSECTIONS && me == 0) {
@@ -577,6 +668,11 @@ void ReadData::atoms()
 {
   int i,m,nchunk,eof;
 
+  if (me == 0) {
+    if (screen) fprintf(screen,"  reading atoms ...\n");
+    if (logfile) fprintf(logfile,"  reading atoms ...\n");
+  }
+
   bigint nread = 0;
   bigint natoms = atom->natoms;
 
@@ -600,41 +696,14 @@ void ReadData::atoms()
 
   if (natoms != atom->natoms)
     error->all(FLERR,"Did not assign all atoms correctly");
+  
+  // check that atom IDs are valid
 
-  // if any atom ID < 0, error
-  // if all atom IDs = 0, tag_enable = 0
-  // if any atom ID > 0, error if any atom ID == 0
-  // not checking if atom IDs > natoms or are unique
-
-  int nlocal = atom->nlocal;
-  int *tag = atom->tag;
-
-  int flag = 0;
-  for (int i = 0; i < nlocal; i++)
-    if (tag[i] < 0) flag = 1;
-  int flag_all;
-  MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
-  if (flag_all)
-    error->all(FLERR,"Invalid atom ID in Atoms section of data file");
-
-  flag = 0;
-  for (int i = 0; i < nlocal; i++)
-    if (tag[i] > 0) flag = 1;
-  MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world);
-  if (flag_all == 0) atom->tag_enable = 0;
-
-  if (atom->tag_enable) {
-    flag = 0;
-    for (int i = 0; i < nlocal; i++)
-      if (tag[i] == 0) flag = 1;
-    MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
-    if (flag_all)
-      error->all(FLERR,"Invalid atom ID in Atoms section of data file");
-  }
+  atom->tag_check();
 
-  // create global mapping
+  // if molecular system or user-requested, create global mapping of atoms
 
-  if (atom->map_style) {
+  if (atom->molecular || atom->map_user) {
     atom->map_init();
     atom->map_set();
   }
@@ -649,10 +718,14 @@ void ReadData::velocities()
 {
   int i,m,nchunk,eof;
 
+  if (me == 0) {
+    if (screen) fprintf(screen,"  reading velocities ...\n");
+    if (logfile) fprintf(logfile,"  reading velocities ...\n");
+  }
+
   int mapflag = 0;
   if (atom->map_style == 0) {
     mapflag = 1;
-    atom->map_style = 1;
     atom->map_init();
     atom->map_set();
   }
@@ -680,149 +753,66 @@ void ReadData::velocities()
 }
 
 /* ----------------------------------------------------------------------
-   read all bonus data
-   to find atoms, must build atom map if not a molecular system
+   scan or read all bonds
 ------------------------------------------------------------------------- */
 
-void ReadData::bonus(bigint nbonus, AtomVec *ptr, const char *type)
+void ReadData::bonds(int firstpass)
 {
-  int i,m,nchunk,eof;
-
-  int mapflag = 0;
-  if (atom->map_style == 0) {
-    mapflag = 1;
-    atom->map_style = 1;
-    atom->map_init();
-    atom->map_set();
-  }
-
-  bigint nread = 0;
-  bigint natoms = nbonus;
-
-  while (nread < natoms) {
-    nchunk = MIN(natoms-nread,CHUNK);
-    eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
-    if (eof) error->all(FLERR,"Unexpected end of data file");
-    atom->data_bonus(nchunk,buffer,ptr);
-    nread += nchunk;
-  }
-
-  if (mapflag) {
-    atom->map_delete();
-    atom->map_style = 0;
-  }
-
   if (me == 0) {
-    if (screen) fprintf(screen,"  " BIGINT_FORMAT " %s\n",natoms,type);
-    if (logfile) fprintf(logfile,"  " BIGINT_FORMAT " %s\n",natoms,type);
-  }
-}
-
-/* ----------------------------------------------------------------------
-   read all body data
-   variable amount of info per body, described by ninteger and ndouble
-   to find atoms, must build atom map if not a molecular system
-------------------------------------------------------------------------- */
-
-void ReadData::bodies()
-{
-  int i,m,nchunk,nmax,ninteger,ndouble,tmp,onebody;
-  char *eof;
-
-  int mapflag = 0;
-  if (atom->map_style == 0) {
-    mapflag = 1;
-    atom->map_style = 1;
-    atom->map_init();
-    atom->map_set();
-  }
-
-  // nmax = max # of bodies to read in this chunk
-  // nchunk = actual # read
-
-  bigint nread = 0;
-  bigint natoms = nbodies;
-
-  while (nread < natoms) {
-    if (natoms-nread > CHUNK) nmax = CHUNK;
-    else nmax = natoms-nread;
-
-    if (me == 0) {
-      nchunk = 0;
-      nlines = 0;
-      m = 0;
-
-      while (nchunk < nmax && nlines <= CHUNK-MAXBODY) {
-        eof = fgets(&buffer[m],MAXLINE,fp);
-        if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
-        sscanf(&buffer[m],"%d %d %d",&tmp,&ninteger,&ndouble);
-        m += strlen(&buffer[m]);
-
-        onebody = 0;
-        if (ninteger) onebody += (ninteger-1)/10 + 1;
-        if (ndouble) onebody += (ndouble-1)/10 + 1;
-        if (onebody+1 > MAXBODY)
-          error->one(FLERR,
-                     "Too many lines in one body in data file - boost MAXBODY");
-
-        for (i = 0; i < onebody; i++) {
-          eof = fgets(&buffer[m],MAXLINE,fp);
-          if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
-          m += strlen(&buffer[m]);
-        }
-
-        nchunk++;
-        nlines += onebody+1;
-      }
-
-      if (buffer[m-1] != '\n') strcpy(&buffer[m++],"\n");
-      m++;
+    if (firstpass) {
+      if (screen) fprintf(screen,"  scanning bonds ...\n");
+      if (logfile) fprintf(logfile,"  scanning bonds ...\n");
+    } else {
+      if (screen) fprintf(screen,"  reading bonds ...\n");
+      if (logfile) fprintf(logfile,"  reading bonds ...\n");
     }
-
-    MPI_Bcast(&nchunk,1,MPI_INT,0,world);
-    MPI_Bcast(&m,1,MPI_INT,0,world);
-    MPI_Bcast(buffer,m,MPI_CHAR,0,world);
-
-    atom->data_bodies(nchunk,buffer,avec_body);
-    nread += nchunk;
   }
 
-  if (mapflag) {
-    atom->map_delete();
-    atom->map_style = 0;
-  }
+  // allocate count if firstpass
 
-  if (me == 0) {
-    if (screen) fprintf(screen,"  " BIGINT_FORMAT " bodies\n",natoms);
-    if (logfile) fprintf(logfile,"  " BIGINT_FORMAT " bodies\n",natoms);
+  int nlocal = atom->nlocal;
+  int *count = NULL;
+  if (firstpass) {
+    memory->create(count,nlocal,"read_data:count");
+    for (int i = 0; i < nlocal; i++) count[i] = 0;
   }
-}
 
-/* ---------------------------------------------------------------------- */
-
-void ReadData::bonds()
-{
-  int i,m,nchunk,eof;
+  // read and process bonds
 
+  int nchunk,eof;
   bigint nread = 0;
   bigint nbonds = atom->nbonds;
 
-  bigint natoms = atom->natoms;
-
   while (nread < nbonds) {
     nchunk = MIN(nbonds-nread,CHUNK);
     eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
     if (eof) error->all(FLERR,"Unexpected end of data file");
-    atom->data_bonds(nchunk,buffer);
+    atom->data_bonds(nchunk,buffer,count);
     nread += nchunk;
   }
 
-  // check that bonds were assigned correctly
+  // if firstpass: tally max bond/atom and return
+
+  if (firstpass) {
+    int max = 0;
+    for (int i = 0; i < nlocal; i++) max = MAX(max,count[i]);
+    int maxall;
+    MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world);
+
+    if (me == 0) {
+      if (screen) fprintf(screen,"  %d = max bonds/atom\n",maxall);
+      if (logfile) fprintf(logfile,"  %d = max bonds/atom\n",maxall);
+    }
+    atom->bond_per_atom = maxall;
+    memory->destroy(count);
+    return;
+  }
+
+  // if 2nd pass: check that bonds were assigned correctly
 
-  int nlocal = atom->nlocal;
-  bigint sum;
   bigint n = 0;
-  for (i = 0; i < nlocal; i++) n += atom->num_bond[i];
+  for (int i = 0; i < nlocal; i++) n += atom->num_bond[i];
+  bigint sum;
   MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
   int factor = 1;
   if (!force->newton_bond) factor = 2;
@@ -831,16 +821,39 @@ void ReadData::bonds()
     if (screen) fprintf(screen,"  " BIGINT_FORMAT " bonds\n",sum/factor);
     if (logfile) fprintf(logfile,"  " BIGINT_FORMAT " bonds\n",sum/factor);
   }
+
   if (sum != factor*atom->nbonds)
     error->all(FLERR,"Bonds assigned incorrectly");
 }
 
-/* ---------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+   scan or read all angles
+------------------------------------------------------------------------- */
 
-void ReadData::angles()
+void ReadData::angles(int firstpass)
 {
-  int i,m,nchunk,eof;
+  if (me == 0) {
+    if (firstpass) {
+      if (screen) fprintf(screen,"  scanning angles ...\n");
+      if (logfile) fprintf(logfile,"  scanning angles ...\n");
+    } else {
+      if (screen) fprintf(screen,"  reading angles ...\n");
+      if (logfile) fprintf(logfile,"  reading angles ...\n");
+    }
+  }
+
+  // allocate count if firstpass
 
+  int nlocal = atom->nlocal;
+  int *count = NULL;
+  if (firstpass) {
+    memory->create(count,nlocal,"read_data:count");
+    for (int i = 0; i < nlocal; i++) count[i] = 0;
+  }
+
+  // read and process angles
+
+  int nchunk,eof;
   bigint nread = 0;
   bigint nangles = atom->nangles;
 
@@ -848,16 +861,32 @@ void ReadData::angles()
     nchunk = MIN(nangles-nread,CHUNK);
     eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
     if (eof) error->all(FLERR,"Unexpected end of data file");
-    atom->data_angles(nchunk,buffer);
+    atom->data_angles(nchunk,buffer,count);
     nread += nchunk;
   }
 
-  // check that ang
+  // if firstpass: tally max angle/atom and return
+
+  if (firstpass) {
+    int max = 0;
+    for (int i = 0; i < nlocal; i++) max = MAX(max,count[i]);
+    int maxall;
+    MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world);
+
+    if (me == 0) {
+      if (screen) fprintf(screen,"  %d = max angles/atom\n",maxall);
+      if (logfile) fprintf(logfile,"  %d = max angles/atom\n",maxall);
+    }
+    atom->angle_per_atom = maxall;
+    memory->destroy(count);
+    return;
+  }
+
+  // if 2nd pass: check that angles were assigned correctly
 
-  int nlocal = atom->nlocal;
-  bigint sum;
   bigint n = 0;
-  for (i = 0; i < nlocal; i++) n += atom->num_angle[i];
+  for (int i = 0; i < nlocal; i++) n += atom->num_angle[i];
+  bigint sum;
   MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
   int factor = 1;
   if (!force->newton_bond) factor = 3;
@@ -866,16 +895,39 @@ void ReadData::angles()
     if (screen) fprintf(screen,"  " BIGINT_FORMAT " angles\n",sum/factor);
     if (logfile) fprintf(logfile,"  " BIGINT_FORMAT " angles\n",sum/factor);
   }
+
   if (sum != factor*atom->nangles)
     error->all(FLERR,"Angles assigned incorrectly");
 }
 
-/* ---------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+   scan or read all dihedrals
+------------------------------------------------------------------------- */
 
-void ReadData::dihedrals()
+void ReadData::dihedrals(int firstpass)
 {
-  int i,m,nchunk,eof;
+  if (me == 0) {
+    if (firstpass) {
+      if (screen) fprintf(screen,"  scanning dihedrals ...\n");
+      if (logfile) fprintf(logfile,"  scanning dihedrals ...\n");
+    } else {
+      if (screen) fprintf(screen,"  reading dihedrals ...\n");
+      if (logfile) fprintf(logfile,"  reading dihedrals ...\n");
+    }
+  }
+
+  // allocate count if firstpass
 
+  int nlocal = atom->nlocal;
+  int *count = NULL;
+  if (firstpass) {
+    memory->create(count,nlocal,"read_data:count");
+    for (int i = 0; i < nlocal; i++) count[i] = 0;
+  }
+
+  // read and process dihedrals
+
+  int nchunk,eof;
   bigint nread = 0;
   bigint ndihedrals = atom->ndihedrals;
 
@@ -883,16 +935,32 @@ void ReadData::dihedrals()
     nchunk = MIN(ndihedrals-nread,CHUNK);
     eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
     if (eof) error->all(FLERR,"Unexpected end of data file");
-    atom->data_dihedrals(nchunk,buffer);
+    atom->data_dihedrals(nchunk,buffer,count);
     nread += nchunk;
   }
 
-  // check that dihedrals were assigned correctly
+  // if firstpass: tally max dihedral/atom and return
+
+  if (firstpass) {
+    int max = 0;
+    for (int i = 0; i < nlocal; i++) max = MAX(max,count[i]);
+    int maxall;
+    MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world);
+
+    if (me == 0) {
+      if (screen) fprintf(screen,"  %d = max dihedrals/atom\n",maxall);
+      if (logfile) fprintf(logfile,"  %d = max dihedrals/atom\n",maxall);
+    }
+    atom->dihedral_per_atom = maxall;
+    memory->destroy(count);
+    return;
+  }
+
+  // if 2nd pass: check that dihedrals were assigned correctly
 
-  int nlocal = atom->nlocal;
-  bigint sum;
   bigint n = 0;
-  for (i = 0; i < nlocal; i++) n += atom->num_dihedral[i];
+  for (int i = 0; i < nlocal; i++) n += atom->num_dihedral[i];
+  bigint sum;
   MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
   int factor = 1;
   if (!force->newton_bond) factor = 4;
@@ -901,16 +969,39 @@ void ReadData::dihedrals()
     if (screen) fprintf(screen,"  " BIGINT_FORMAT " dihedrals\n",sum/factor);
     if (logfile) fprintf(logfile,"  " BIGINT_FORMAT " dihedrals\n",sum/factor);
   }
+
   if (sum != factor*atom->ndihedrals)
     error->all(FLERR,"Dihedrals assigned incorrectly");
 }
 
-/* ---------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+   scan or read all impropers
+------------------------------------------------------------------------- */
 
-void ReadData::impropers()
+void ReadData::impropers(int firstpass)
 {
-  int i,m,nchunk,eof;
+  if (me == 0) {
+    if (firstpass) {
+      if (screen) fprintf(screen,"  scanning impropers ...\n");
+      if (logfile) fprintf(logfile,"  scanning impropers ...\n");
+    } else {
+      if (screen) fprintf(screen,"  reading impropers ...\n");
+      if (logfile) fprintf(logfile,"  reading impropers ...\n");
+    }
+  }
+
+  // allocate count if firstpass
+
+  int nlocal = atom->nlocal;
+  int *count = NULL;
+  if (firstpass) {
+    memory->create(count,nlocal,"read_data:count");
+    for (int i = 0; i < nlocal; i++) count[i] = 0;
+  }
 
+  // read and process impropers
+
+  int nchunk,eof;
   bigint nread = 0;
   bigint nimpropers = atom->nimpropers;
 
@@ -918,16 +1009,32 @@ void ReadData::impropers()
     nchunk = MIN(nimpropers-nread,CHUNK);
     eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
     if (eof) error->all(FLERR,"Unexpected end of data file");
-    atom->data_impropers(nchunk,buffer);
+    atom->data_impropers(nchunk,buffer,count);
     nread += nchunk;
   }
 
-  // check that impropers were assigned correctly
+  // if firstpass: tally max improper/atom and return
+
+  if (firstpass) {
+    int max = 0;
+    for (int i = 0; i < nlocal; i++) max = MAX(max,count[i]);
+    int maxall;
+    MPI_Allreduce(&max,&maxall,1,MPI_INT,MPI_MAX,world);
+
+    if (me == 0) {
+      if (screen) fprintf(screen,"  %d = max impropers/atom\n",maxall);
+      if (logfile) fprintf(logfile,"  %d = max impropers/atom\n",maxall);
+    }
+    atom->improper_per_atom = maxall;
+    memory->destroy(count);
+    return;
+  }
+
+  // if 2nd pass: check that impropers were assigned correctly
 
-  int nlocal = atom->nlocal;
-  bigint sum;
   bigint n = 0;
-  for (i = 0; i < nlocal; i++) n += atom->num_improper[i];
+  for (int i = 0; i < nlocal; i++) n += atom->num_improper[i];
+  bigint sum;
   MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
   int factor = 1;
   if (!force->newton_bond) factor = 4;
@@ -936,10 +1043,129 @@ void ReadData::impropers()
     if (screen) fprintf(screen,"  " BIGINT_FORMAT " impropers\n",sum/factor);
     if (logfile) fprintf(logfile,"  " BIGINT_FORMAT " impropers\n",sum/factor);
   }
+
   if (sum != factor*atom->nimpropers)
     error->all(FLERR,"Impropers assigned incorrectly");
 }
 
+/* ----------------------------------------------------------------------
+   read all bonus data
+   to find atoms, must build atom map if not a molecular system
+------------------------------------------------------------------------- */
+
+void ReadData::bonus(bigint nbonus, AtomVec *ptr, const char *type)
+{
+  int i,m,nchunk,eof;
+
+  int mapflag = 0;
+  if (atom->map_style == 0) {
+    mapflag = 1;
+    atom->map_init();
+    atom->map_set();
+  }
+
+  bigint nread = 0;
+  bigint natoms = nbonus;
+
+  while (nread < natoms) {
+    nchunk = MIN(natoms-nread,CHUNK);
+    eof = comm->read_lines_from_file(fp,nchunk,MAXLINE,buffer);
+    if (eof) error->all(FLERR,"Unexpected end of data file");
+    atom->data_bonus(nchunk,buffer,ptr);
+    nread += nchunk;
+  }
+
+  if (mapflag) {
+    atom->map_delete();
+    atom->map_style = 0;
+  }
+
+  if (me == 0) {
+    if (screen) fprintf(screen,"  " BIGINT_FORMAT " %s\n",natoms,type);
+    if (logfile) fprintf(logfile,"  " BIGINT_FORMAT " %s\n",natoms,type);
+  }
+}
+
+/* ----------------------------------------------------------------------
+   read all body data
+   variable amount of info per body, described by ninteger and ndouble
+   to find atoms, must build atom map if not a molecular system
+   if not firstpass, just read but no processing of data
+------------------------------------------------------------------------- */
+
+void ReadData::bodies(int firstpass)
+{
+  int i,m,nchunk,nmax,ninteger,ndouble,tmp,onebody;
+  char *eof;
+
+  int mapflag = 0;
+  if (atom->map_style == 0 && firstpass) {
+    mapflag = 1;
+    atom->map_init();
+    atom->map_set();
+  }
+
+  // nmax = max # of bodies to read in this chunk
+  // nchunk = actual # read
+
+  bigint nread = 0;
+  bigint natoms = nbodies;
+
+  while (nread < natoms) {
+    if (natoms-nread > CHUNK) nmax = CHUNK;
+    else nmax = natoms-nread;
+
+    if (me == 0) {
+      nchunk = 0;
+      nlines = 0;
+      m = 0;
+
+      while (nchunk < nmax && nlines <= CHUNK-MAXBODY) {
+        eof = fgets(&buffer[m],MAXLINE,fp);
+        if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
+        sscanf(&buffer[m],"%d %d %d",&tmp,&ninteger,&ndouble);
+        m += strlen(&buffer[m]);
+
+        onebody = 0;
+        if (ninteger) onebody += (ninteger-1)/10 + 1;
+        if (ndouble) onebody += (ndouble-1)/10 + 1;
+        if (onebody+1 > MAXBODY)
+          error->one(FLERR,
+                     "Too many lines in one body in data file - boost MAXBODY");
+
+        for (i = 0; i < onebody; i++) {
+          eof = fgets(&buffer[m],MAXLINE,fp);
+          if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
+          m += strlen(&buffer[m]);
+        }
+
+        nchunk++;
+        nlines += onebody+1;
+      }
+
+      if (buffer[m-1] != '\n') strcpy(&buffer[m++],"\n");
+      m++;
+    }
+
+    MPI_Bcast(&nchunk,1,MPI_INT,0,world);
+    MPI_Bcast(&m,1,MPI_INT,0,world);
+    MPI_Bcast(buffer,m,MPI_CHAR,0,world);
+
+    if (firstpass) atom->data_bodies(nchunk,buffer,avec_body);
+    nread += nchunk;
+  }
+
+  if (mapflag && firstpass) {
+    atom->map_delete();
+    atom->map_style = 0;
+  }
+
+  if (me == 0 && firstpass) {
+    if (screen) fprintf(screen,"  " BIGINT_FORMAT " bodies\n",natoms);
+    if (logfile) fprintf(logfile,"  " BIGINT_FORMAT " bodies\n",natoms);
+  }
+}
+
 /* ---------------------------------------------------------------------- */
 
 void ReadData::mass()
@@ -1120,314 +1346,6 @@ void ReadData::fix(int ifix, char *keyword)
   }
 }
 
-/* ----------------------------------------------------------------------
-   proc 0 scans the data file for topology maximums
-------------------------------------------------------------------------- */
-
-void ReadData::scan(int &bond_per_atom, int &angle_per_atom,
-                    int &dihedral_per_atom, int &improper_per_atom)
-{
-  int i,tmp1,tmp2,atom1,atom2,atom3,atom4;
-  char *eof;
-
-  if (atom->natoms > MAXSMALLINT)
-    error->one(FLERR,"Molecular data file has too many atoms");
-
-  // customize for new sections
-
-  int natoms = static_cast<int> (atom->natoms);
-  bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0;
-  int ellipsoid_flag = 0;
-  int line_flag = 0;
-  int tri_flag = 0;
-  int body_flag = 0;
-
-  // customize for new sections
-  // allocate topology counting vector
-  // initially, array length = 1 to natoms
-  // will grow via reallocate() if atom IDs > natoms
-
-  int cmax = natoms + 1;
-  int *count;
-  memory->create(count,cmax,"read_data:count");
-
-  while (strlen(keyword)) {
-
-    // allow special fixes first chance to match and process the section
-    // if fix matches, continue to next section
-
-    if (nfix) {
-      for (i = 0; i < nfix; i++) {
-        if (strcmp(keyword,fix_section[i]) == 0) {
-          int n = modify->fix[fix_index[i]]->read_data_skip_lines(keyword);
-          skip_lines(n);
-          parse_keyword(0,0);
-          break;
-        }
-      }
-      if (i < nfix) continue;
-    }
-
-    if (strcmp(keyword,"Masses") == 0) skip_lines(atom->ntypes);
-    else if (strcmp(keyword,"Atoms") == 0) skip_lines(natoms);
-    else if (strcmp(keyword,"Velocities") == 0) skip_lines(natoms);
-
-    else if (strcmp(keyword,"Ellipsoids") == 0) {
-      if (!avec_ellipsoid)
-        error->one(FLERR,"Invalid data file section: Ellipsoids");
-      ellipsoid_flag = 1;
-      skip_lines(nellipsoids);
-    } else if (strcmp(keyword,"Lines") == 0) {
-      if (!avec_line) error->one(FLERR,"Invalid data file section: Lines");
-      line_flag = 1;
-      skip_lines(nlines);
-    } else if (strcmp(keyword,"Triangles") == 0) {
-      if (!avec_tri) error->one(FLERR,"Invalid data file section: Triangles");
-      tri_flag = 1;
-      skip_lines(ntris);
-    } else if (strcmp(keyword,"Bodies") == 0) {
-      if (!avec_body) error->one(FLERR,"Invalid data file section: Bodies");
-      body_flag = 1;
-      skip_lines(nbodies);
-
-    } else if (strcmp(keyword,"Pair Coeffs") == 0) {
-      if (force->pair == NULL)
-        error->one(FLERR,"Must define pair_style before Pair Coeffs");
-      skip_lines(atom->ntypes);
-    } else if (strcmp(keyword,"PairIJ Coeffs") == 0) {
-      if (force->pair == NULL)
-        error->one(FLERR,"Must define pair_style before Pair Coeffs");
-      skip_lines(atom->ntypes*(atom->ntypes+1)/2);
-    } else if (strcmp(keyword,"Bond Coeffs") == 0) {
-      if (atom->avec->bonds_allow == 0)
-        error->one(FLERR,"Invalid data file section: Bond Coeffs");
-      if (force->bond == NULL)
-        error->one(FLERR,"Must define bond_style before Bond Coeffs");
-      skip_lines(atom->nbondtypes);
-    } else if (strcmp(keyword,"Angle Coeffs") == 0) {
-      if (atom->avec->angles_allow == 0)
-        error->one(FLERR,"Invalid data file section: Angle Coeffs");
-      if (force->angle == NULL)
-        error->one(FLERR,"Must define angle_style before Angle Coeffs");
-      skip_lines(atom->nangletypes);
-    } else if (strcmp(keyword,"Dihedral Coeffs") == 0) {
-      skip_lines(atom->ndihedraltypes);
-      if (atom->avec->dihedrals_allow == 0)
-        error->one(FLERR,"Invalid data file section: Dihedral Coeffs");
-      if (force->dihedral == NULL)
-        error->one(FLERR,"Must define dihedral_style before Dihedral Coeffs");
-    }  else if (strcmp(keyword,"Improper Coeffs") == 0) {
-      if (atom->avec->impropers_allow == 0)
-        error->one(FLERR,"Invalid data file section: Improper Coeffs");
-      if (force->improper == NULL)
-        error->one(FLERR,"Must define improper_style before Improper Coeffs");
-      skip_lines(atom->nimpropertypes);
-
-    } else if (strcmp(keyword,"BondBond Coeffs") == 0) {
-      if (atom->avec->angles_allow == 0)
-        error->one(FLERR,"Invalid data file section: BondBond Coeffs");
-      if (force->angle == NULL)
-        error->one(FLERR,"Must define angle_style before BondBond Coeffs");
-      skip_lines(atom->nangletypes);
-    } else if (strcmp(keyword,"BondAngle Coeffs") == 0) {
-      if (atom->avec->angles_allow == 0)
-        error->one(FLERR,"Invalid data file section: BondAngle Coeffs");
-      if (force->angle == NULL)
-        error->one(FLERR,"Must define angle_style before BondAngle Coeffs");
-      skip_lines(atom->nangletypes);
-    } else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->one(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs");
-      if (force->dihedral == NULL)
-        error->one(FLERR,
-                   "Must define dihedral_style before "
-                   "MiddleBondTorsion Coeffs");
-      skip_lines(atom->ndihedraltypes);
-    } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->one(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
-      if (force->dihedral == NULL)
-        error->one(FLERR,
-                   "Must define dihedral_style before EndBondTorsion Coeffs");
-      skip_lines(atom->ndihedraltypes);
-    } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->one(FLERR,"Invalid data file section: AngleTorsion Coeffs");
-      if (force->dihedral == NULL)
-        error->one(FLERR,
-                   "Must define dihedral_style before AngleTorsion Coeffs");
-      skip_lines(atom->ndihedraltypes);
-    } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->one(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs");
-      if (force->dihedral == NULL)
-        error->one(FLERR,
-                   "Must define dihedral_style before "
-                   "AngleAngleTorsion Coeffs");
-      skip_lines(atom->ndihedraltypes);
-    } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
-      if (atom->avec->dihedrals_allow == 0)
-        error->one(FLERR,"Invalid data file section: BondBond13 Coeffs");
-      if (force->dihedral == NULL)
-        error->one(FLERR,"Must define dihedral_style before BondBond13 Coeffs");
-      skip_lines(atom->ndihedraltypes);
-    } else if (strcmp(keyword,"AngleAngle Coeffs") == 0) {
-      if (atom->avec->impropers_allow == 0)
-        error->one(FLERR,"Invalid data file section: AngleAngle Coeffs");
-      if (force->improper == NULL)
-        error->one(FLERR,"Must define improper_style before AngleAngle Coeffs");
-      skip_lines(atom->nimpropertypes);
-
-    } else if (strcmp(keyword,"Bonds") == 0) {
-      for (i = 1; i < cmax; i++) count[i] = 0;
-      if (force->newton_bond)
-        for (i = 0; i < atom->nbonds; i++) {
-          eof = fgets(line,MAXLINE,fp);
-          if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
-          sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2);
-          if (atom1 >= cmax) cmax = reallocate(&count,cmax,atom1);
-          count[atom1]++;
-        }
-      else
-        for (i = 0; i < atom->nbonds; i++) {
-          eof = fgets(line,MAXLINE,fp);
-          if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
-          sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2);
-          int amax = MAX(atom1,atom2);
-          if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
-          count[atom1]++;
-          count[atom2]++;
-        }
-      for (i = 1; i < cmax; i++) bond_per_atom = MAX(bond_per_atom,count[i]);
-      if (screen) fprintf(screen,"  %d = max bonds/atom\n",bond_per_atom);
-      if (logfile) fprintf(logfile,"  %d = max bonds/atom\n",bond_per_atom);
-
-    } else if (strcmp(keyword,"Angles") == 0) {
-      for (i = 1; i < cmax; i++) count[i] = 0;
-      if (force->newton_bond)
-        for (i = 0; i < atom->nangles; i++) {
-          eof = fgets(line,MAXLINE,fp);
-          if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
-          sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3);
-          if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
-          count[atom2]++;
-        }
-      else
-        for (i = 0; i < atom->nangles; i++) {
-          eof = fgets(line,MAXLINE,fp);
-          if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
-          sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3);
-          int amax = MAX(atom1,atom2);
-          amax = MAX(amax,atom3);
-          if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
-          count[atom1]++;
-          count[atom2]++;
-          count[atom3]++;
-        }
-      for (i = 1; i < cmax; i++) angle_per_atom = MAX(angle_per_atom,count[i]);
-      if (screen) fprintf(screen,"  %d = max angles/atom\n",angle_per_atom);
-      if (logfile) fprintf(logfile,"  %d = max angles/atom\n",angle_per_atom);
-
-    } else if (strcmp(keyword,"Dihedrals") == 0) {
-      for (i = 1; i < cmax; i++) count[i] = 0;
-      if (force->newton_bond)
-        for (i = 0; i < atom->ndihedrals; i++) {
-          eof = fgets(line,MAXLINE,fp);
-          if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
-          sscanf(line,"%d %d %d %d %d %d",
-                 &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
-          if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
-          count[atom2]++;
-        }
-      else
-        for (i = 0; i < atom->ndihedrals; i++) {
-          eof = fgets(line,MAXLINE,fp);
-          if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
-          sscanf(line,"%d %d %d %d %d %d",
-                 &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
-          int amax = MAX(atom1,atom2);
-          amax = MAX(amax,atom3);
-          amax = MAX(amax,atom4);
-          if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
-          count[atom1]++;
-          count[atom2]++;
-          count[atom3]++;
-          count[atom4]++;
-        }
-      for (i = 1; i < cmax; i++)
-        dihedral_per_atom = MAX(dihedral_per_atom,count[i]);
-      if (screen)
-        fprintf(screen,"  %d = max dihedrals/atom\n",dihedral_per_atom);
-      if (logfile)
-        fprintf(logfile,"  %d = max dihedrals/atom\n",dihedral_per_atom);
-
-    } else if (strcmp(keyword,"Impropers") == 0) {
-      for (i = 1; i < cmax; i++) count[i] = 0;
-      if (force->newton_bond)
-        for (i = 0; i < atom->nimpropers; i++) {
-          eof = fgets(line,MAXLINE,fp);
-          if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
-          sscanf(line,"%d %d %d %d %d %d",
-                 &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
-          if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
-          count[atom2]++;
-        }
-      else
-        for (i = 0; i < atom->nimpropers; i++) {
-          eof = fgets(line,MAXLINE,fp);
-          if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
-          sscanf(line,"%d %d %d %d %d %d",
-                 &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
-          int amax = MAX(atom1,atom2);
-          amax = MAX(amax,atom3);
-          amax = MAX(amax,atom4);
-          if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
-          count[atom1]++;
-          count[atom2]++;
-          count[atom3]++;
-          count[atom4]++;
-        }
-      for (i = 1; i < cmax; i++)
-        improper_per_atom = MAX(improper_per_atom,count[i]);
-      if (screen)
-        fprintf(screen,"  %d = max impropers/atom\n",improper_per_atom);
-      if (logfile)
-        fprintf(logfile,"  %d = max impropers/atom\n",improper_per_atom);
-
-    } else {
-      char str[128];
-      sprintf(str,"Unknown identifier in data file: %s",keyword);
-      error->one(FLERR,str);
-    }
-
-    parse_keyword(0,0);
-  }
-
-  // free topology counting vector
-
-  memory->destroy(count);
-
-  // error check that topology was specified in file
-
-  if ((atom->nbonds && !bond_per_atom) ||
-      (atom->nangles && !angle_per_atom) ||
-      (atom->ndihedrals && !dihedral_per_atom) ||
-      (atom->nimpropers && !improper_per_atom))
-    error->one(FLERR,"Needed topology not in data file");
-
-  // customize for new sections
-  // error check that Bonus sections were speficied in file
-
-  if (nellipsoids && !ellipsoid_flag)
-    error->one(FLERR,"Needed bonus data not in data file");
-  if (nlines && !line_flag)
-    error->one(FLERR,"Needed bonus data not in data file");
-  if (ntris && !tri_flag)
-    error->one(FLERR,"Needed bonus data not in data file");
-  if (nbodies && !body_flag)
-    error->one(FLERR,"Needed bonus data not in data file");
-}
-
 /* ----------------------------------------------------------------------
    reallocate the count vector from cmax to amax+1 and return new length
    zero new locations
@@ -1477,11 +1395,9 @@ void ReadData::open(char *file)
    read one additional line (assumed blank)
    if any read hits EOF, set keyword to empty
    if first = 1, line variable holds non-blank line that ended header
-   if flag = 0, only proc 0 is calling so no bcast
-   else flag = 1, bcast keyword line to all procs
 ------------------------------------------------------------------------- */
 
-void ReadData::parse_keyword(int first, int flag)
+void ReadData::parse_keyword(int first)
 {
   int eof = 0;
 
@@ -1500,7 +1416,7 @@ void ReadData::parse_keyword(int first, int flag)
 
   // if eof, set keyword empty and return
 
-  if (flag) MPI_Bcast(&eof,1,MPI_INT,0,world);
+  MPI_Bcast(&eof,1,MPI_INT,0,world);
   if (eof) {
     keyword[0] = '\0';
     return;
@@ -1508,12 +1424,10 @@ void ReadData::parse_keyword(int first, int flag)
 
   // bcast keyword line to all procs
 
-  if (flag) {
-    int n;
-    if (me == 0) n = strlen(line) + 1;
-    MPI_Bcast(&n,1,MPI_INT,0,world);
-    MPI_Bcast(line,n,MPI_CHAR,0,world);
-  }
+  int n;
+  if (me == 0) n = strlen(line) + 1;
+  MPI_Bcast(&n,1,MPI_INT,0,world);
+  MPI_Bcast(line,n,MPI_CHAR,0,world);
 
   // copy non-whitespace portion of line into keyword
 
@@ -1527,14 +1441,14 @@ void ReadData::parse_keyword(int first, int flag)
 
 /* ----------------------------------------------------------------------
    proc 0 reads N lines from file
-   NOTE: needs to be called with bigint in some cases
-         if called with int, will it be promoted to bigint?
+   could be skipping Natoms lines, so use bigints
 ------------------------------------------------------------------------- */
 
-void ReadData::skip_lines(int n)
+void ReadData::skip_lines(bigint n)
 {
+  if (me) return;
   char *eof;
-  for (int i = 0; i < n; i++) eof = fgets(line,MAXLINE,fp);
+  for (bigint i = 0; i < n; i++) eof = fgets(line,MAXLINE,fp);
   if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
 }
 
diff --git a/src/read_data.h b/src/read_data.h
index 48602c30ff629cf72c8c66d13c51f005c9a9075c..95c5b547053cb8f6b69bd739f83c6c18718b153b 100644
--- a/src/read_data.h
+++ b/src/read_data.h
@@ -38,7 +38,7 @@ class ReadData : protected Pointers {
   int narg,maxarg,compressed;
   char **arg;
 
-  int nfix;           // # of extra fixes that process/store info in data file
+  int nfix;         // # of extra fixes that process/store info in data file
   int *fix_index;
   char **fix_header;
   char **fix_section;
@@ -55,20 +55,22 @@ class ReadData : protected Pointers {
   void open(char *);
   void scan(int &, int &, int &, int &);
   int reallocate(int **, int, int);
-  void header(int);
-  void parse_keyword(int, int);
-  void skip_lines(int);
+  void header();
+  void parse_keyword(int);
+  void skip_lines(bigint);
   void parse_coeffs(char *, const char *, int);
 
   void atoms();
   void velocities();
-  void bonus(bigint, class AtomVec *, const char *);
-  void bodies();
 
-  void bonds();
-  void angles();
-  void dihedrals();
-  void impropers();
+  void bonds(int);
+  void bond_scan(int, char *, int *);
+  void angles(int);
+  void dihedrals(int);
+  void impropers(int);
+
+  void bonus(bigint, class AtomVec *, const char *);
+  void bodies(int);
 
   void mass();
   void paircoeffs();
diff --git a/src/read_dump.cpp b/src/read_dump.cpp
index 6196f876c1c9feb69ad9e020855e2730e3bcc4ec..3256d28a46112ffa121ccf379b6f3f6a5229038b 100644
--- a/src/read_dump.cpp
+++ b/src/read_dump.cpp
@@ -444,7 +444,6 @@ void ReadDump::atoms()
   int mapflag = 0;
   if (atom->map_style == 0) {
     mapflag = 1;
-    atom->map_style = 1;
     atom->map_init();
     atom->map_set();
   }
@@ -477,11 +476,9 @@ void ReadDump::atoms()
   if (addflag) {
     bigint nblocal = atom->nlocal;
     MPI_Allreduce(&nblocal,&atom->natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
-    if (atom->natoms < 0 || atom->natoms > MAXBIGINT)
+    if (atom->natoms < 0 || atom->natoms >= MAXBIGINT)
       error->all(FLERR,"Too many total atoms");
-    // change these to MAXTAGINT when allow tagint = bigint
-    if (atom->natoms > MAXSMALLINT) atom->tag_enable = 0;
-    if (atom->natoms <= MAXSMALLINT) atom->tag_extend();
+    if (atom->tag_enable) atom->tag_extend();
   }
 
   // if trimflag set, delete atoms not replaced by snapshot atoms
@@ -553,6 +550,10 @@ void ReadDump::atoms()
   irregular->migrate_atoms();
   delete irregular;
   if (triclinic) domain->lamda2x(atom->nlocal);
+
+  // check that atom IDs are valid
+
+  atom->tag_check();
 }
 
 /* ----------------------------------------------------------------------
@@ -710,24 +711,27 @@ int ReadDump::fields_and_keywords(int narg, char **arg)
 
 void ReadDump::process_atoms(int n)
 {
-  int i,m,ifield,itype,itag;;
+  int i,m,ifield,itype;
   int xbox,ybox,zbox;
+  tagint tag;
 
   double **x = atom->x;
   double **v = atom->v;
   double *q = atom->q;
   imageint *image = atom->image;
   int nlocal = atom->nlocal;
-  int map_tag_max = atom->map_tag_max;
+  tagint map_tag_max = atom->map_tag_max;
 
   for (i = 0; i < n; i++) {
     ucflag[i] = 0;
 
     // check if new atom matches one I own
     // setting m = -1 forces new atom not to match
+    // NOTE: atom ID in fields is stored as double, not as ubuf
+    //       so can only cast it to tagint, thus cannot be full 64-bit ID
 
-    itag = static_cast<int> (fields[i][0]);
-    if (itag <= map_tag_max) m = atom->map(static_cast<int> (fields[i][0]));
+    tag = static_cast<tagint> (fields[i][0]);
+    if (tag <= map_tag_max) m = atom->map(tag);
     else m = -1;
     if (m < 0 || m >= nlocal) continue;
 
diff --git a/src/read_restart.cpp b/src/read_restart.cpp
index 937b10548bbdef4352811b762d2eefcda6b749c8..31549b69dc0e3452990d5339769e83ceba21bcb5 100644
--- a/src/read_restart.cpp
+++ b/src/read_restart.cpp
@@ -503,20 +503,19 @@ void ReadRestart::command(int narg, char **arg)
     }
   }
 
-  // check if tags are being used
-  // create global mapping and bond topology now that system is defined
+  // check that atom IDs are valid
 
-  flag = 0;
-  for (int i = 0; i < atom->nlocal; i++)
-    if (atom->tag[i] > 0) flag = 1;
-  int flag_all;
-  MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world);
-  if (flag_all == 0) atom->tag_enable = 0;
+  atom->tag_check();
 
-  if (atom->map_style) {
+  // if molecular system or user-requested, create global mapping of atoms
+
+  if (atom->molecular || atom->map_user) {
     atom->map_init();
     atom->map_set();
   }
+
+  // create special bond lists for molecular systems
+
   if (atom->molecular) {
     Special special(lmp);
     special.build();
diff --git a/src/replicate.cpp b/src/replicate.cpp
index d0b3b71ab2e26400711d63998c22bb05d7b76afb..9b4e9bcf4852e062b75a4eeeb0e75187586421f5 100644
--- a/src/replicate.cpp
+++ b/src/replicate.cpp
@@ -73,11 +73,13 @@ void Replicate::command(int narg, char **arg)
 
   // maxtag = largest atom tag across all existing atoms
 
-  int maxtag = 0;
-  for (i = 0; i < atom->nlocal; i++) maxtag = MAX(atom->tag[i],maxtag);
-  int maxtag_all;
-  MPI_Allreduce(&maxtag,&maxtag_all,1,MPI_INT,MPI_MAX,world);
-  maxtag = maxtag_all;
+  tagint maxtag = 0;
+  if (atom->tag_enable) {
+    for (i = 0; i < atom->nlocal; i++) maxtag = MAX(atom->tag[i],maxtag);
+    tagint maxtag_all;
+    MPI_Allreduce(&maxtag,&maxtag_all,1,MPI_LMP_TAGINT,MPI_MAX,world);
+    maxtag = maxtag_all;
+  }
 
   // maxmol = largest molecule tag across all existing atoms
 
@@ -124,25 +126,20 @@ void Replicate::command(int narg, char **arg)
   atom->create_avec(old->atom_style,nstyles,keywords);
 
   // check that new system will not be too large
-  // if molecular and N > MAXTAGINT, error
-  // if atomic and new N > MAXTAGINT, turn off tags for existing and new atoms
-  // new system cannot exceed MAXBIGINT
-  // NOTE: change these 2 to MAXTAGINT when allow tagint = bigint
-
-  if (atom->molecular && 
-      (nrep*old->natoms < 0 || nrep*old->natoms > MAXSMALLINT))
-    error->all(FLERR,"Replicated molecular system atom IDs are too big");
-  if (nrep*old->natoms < 0 || nrep*old->natoms > MAXSMALLINT)
-    atom->tag_enable = 0;
-  if (atom->tag_enable == 0)
-    for (int i = 0; i < atom->nlocal; i++)
-      atom->tag[i] = 0;
-
-  if (nrep*old->natoms < 0 || nrep*old->natoms > MAXBIGINT ||
-      nrep*old->nbonds < 0 || nrep*old->nbonds > MAXBIGINT ||
-      nrep*old->nangles < 0 || nrep*old->nangles > MAXBIGINT ||
-      nrep*old->ndihedrals < 0 || nrep*old->ndihedrals > MAXBIGINT ||
-      nrep*old->nimpropers < 0 || nrep*old->nimpropers > MAXBIGINT)
+  // new tags cannot exceed MAXTAGINT
+  // new system sizes cannot exceed MAXBIGINT
+
+  if (atom->tag_enable) {
+    bigint maxnewtag = maxtag + (nrep-1)*old->natoms;
+    if (maxnewtag < 0 || maxnewtag >= MAXTAGINT)
+      error->all(FLERR,"Replicated system atom IDs are too big");
+  }
+
+  if (nrep*old->natoms < 0 || nrep*old->natoms >= MAXBIGINT ||
+      nrep*old->nbonds < 0 || nrep*old->nbonds >= MAXBIGINT ||
+      nrep*old->nangles < 0 || nrep*old->nangles >= MAXBIGINT ||
+      nrep*old->ndihedrals < 0 || nrep*old->ndihedrals >= MAXBIGINT ||
+      nrep*old->nimpropers < 0 || nrep*old->nimpropers >= MAXBIGINT)
     error->all(FLERR,"Replicated system is too big");
 
   // assign atom and topology counts in new class from old one
@@ -257,7 +254,8 @@ void Replicate::command(int narg, char **arg)
   AtomVec *old_avec = old->avec;
   AtomVec *avec = atom->avec;
 
-  int ix,iy,iz,atom_offset,mol_offset;
+  int ix,iy,iz,mol_offset;
+  tagint atom_offset;
   imageint image;
   double x[3],lamda[3];
   double *coord;
@@ -393,13 +391,19 @@ void Replicate::command(int narg, char **arg)
     }
   }
 
-  // create global mapping and bond topology now that system is defined
+  // check that atom IDs are valid
 
-  if (atom->map_style) {
-    atom->nghost = 0;
+  atom->tag_check();
+
+  // if molecular system or user-requested, create global mapping of atoms
+
+  if (atom->molecular || atom->map_user) {
     atom->map_init();
     atom->map_set();
   }
+
+  // create special bond lists for molecular systems
+
   if (atom->molecular) {
     Special special(lmp);
     special.build();
diff --git a/src/set.cpp b/src/set.cpp
index 046dc67f485e529a18800ceafb65af6aa74482c4..562b8f94cedb0b5a0688175379f0abf37beb3074 100644
--- a/src/set.cpp
+++ b/src/set.cpp
@@ -440,11 +440,12 @@ void Set::selection(int n)
   if (style == ATOM_SELECT) {
     if (atom->tag_enable == 0)
       error->all(FLERR,"Cannot use set atom with no atom IDs defined");
-    force->bounds(id,BIG,nlo,nhi);
+    bigint nlobig,nhibig;
+    force->boundsbig(id,MAXTAGINT,nlobig,nhibig);
 
-    int *tag = atom->tag;
+    tagint *tag = atom->tag;
     for (int i = 0; i < n; i++)
-      if (tag[i] >= nlo && tag[i] <= nhi) select[i] = 1;
+      if (tag[i] >= nlobig && tag[i] <= nhibig) select[i] = 1;
       else select[i] = 0;
 
   } else if (style == MOL_SELECT) {
@@ -711,7 +712,7 @@ void Set::set(int keyword)
 
 /* ----------------------------------------------------------------------
    set an owned atom property randomly
-   set seed based on atom tag
+   set seed based on atom coordinates
    make atom result independent of what proc owns it
 ------------------------------------------------------------------------- */
 
diff --git a/src/special.cpp b/src/special.cpp
index 170115521f631ea1b63aa0c244e052a3d1b47861..d081a82abe7d45ecbcabad4b5f573945c232b5e2 100644
--- a/src/special.cpp
+++ b/src/special.cpp
@@ -56,15 +56,15 @@ void Special::build()
 {
   int i,j,k,size;
   int max,maxall,nbuf;
-  int *buf;
+  tagint *buf;
 
   MPI_Barrier(world);
 
   int nlocal = atom->nlocal;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *num_bond = atom->num_bond;
-  int **bond_atom = atom->bond_atom;
+  tagint **bond_atom = atom->bond_atom;
   int **nspecial = atom->nspecial;
 
   if (me == 0 && screen) fprintf(screen,"Finding 1-2 1-3 1-4 neighbors ...\n");
@@ -109,7 +109,7 @@ void Special::build()
     // when find one, increment nspecial count for that atom
 
     sptr = this;
-    comm->ring(size,sizeof(int),buf,1,ring_one,NULL);
+    comm->ring(size,sizeof(tagint),buf,1,ring_one,NULL);
 
     memory->destroy(buf);
   }
@@ -167,7 +167,7 @@ void Special::build()
     // when find one, add 1st-atom tag to onetwo list for 2nd atom
 
     sptr = this;
-    comm->ring(size,sizeof(int),buf,2,ring_two,NULL);
+    comm->ring(size,sizeof(tagint),buf,2,ring_two,NULL);
 
     memory->destroy(buf);
   }
@@ -214,7 +214,7 @@ void Special::build()
   //   subtracting one since my list will contain original atom
 
   sptr = this;
-  comm->ring(size,sizeof(int),buf,3,ring_three,buf);
+  comm->ring(size,sizeof(tagint),buf,3,ring_three,buf);
 
   // extract count from buffer that has cycled back to me
   // nspecial[i][1] = # of 1-3 neighbors of atom i
@@ -275,7 +275,7 @@ void Special::build()
   //   this process may include duplicates but they will be culled later
 
   sptr = this;
-  comm->ring(size,sizeof(int),buf,4,ring_four,buf);
+  comm->ring(size,sizeof(tagint),buf,4,ring_four,buf);
 
   // fill onethree with buffer values that have been returned to me
   // sanity check: accumulated buf[i+3] count should equal
@@ -330,7 +330,7 @@ void Special::build()
   //   may include duplicates and original atom but they will be culled later
 
   sptr = this;
-  comm->ring(size,sizeof(int),buf,5,ring_five,buf);
+  comm->ring(size,sizeof(tagint),buf,5,ring_five,buf);
 
   // extract count from buffer that has cycled back to me
   // nspecial[i][2] = # of 1-4 neighbors of atom i
@@ -389,7 +389,7 @@ void Special::build()
   //   this process may include duplicates but they will be culled later
 
   sptr = this;
-  comm->ring(size,sizeof(int),buf,6,ring_six,buf);
+  comm->ring(size,sizeof(tagint),buf,6,ring_six,buf);
 
   // fill onefour with buffer values that have been returned to me
   // sanity check: accumulated buf[i+2] count should equal
@@ -418,7 +418,8 @@ void Special::build()
 
 void Special::dedup()
 {
-  int i,j,m;
+  int i,j;
+  tagint m;
 
   // clear map so it can be used as scratch space
 
@@ -430,7 +431,7 @@ void Special::dedup()
   // must unset map for each atom
 
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
 
   int unique;
@@ -494,13 +495,14 @@ void Special::dedup()
 
 void Special::combine()
 {
-  int i,j,m;
+  int i,j;
+  tagint m;
 
   int me;
   MPI_Comm_rank(world,&me);
 
   int **nspecial = atom->nspecial;
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int nlocal = atom->nlocal;
 
   // ----------------------------------------------------
@@ -574,7 +576,7 @@ void Special::combine()
 
   memory->create(atom->special,atom->nmax,atom->maxspecial,"atom:special");
   atom->avec->grow_reset();
-  int **special = atom->special;
+  tagint **special = atom->special;
 
   // ----------------------------------------------------
   // fill special array with 1-2, 1-3, 1-4 neighs for each atom
@@ -638,12 +640,12 @@ void Special::angle_trim()
 
   int *num_angle = atom->num_angle;
   int *num_dihedral = atom->num_dihedral;
-  int **angle_atom1 = atom->angle_atom1;
-  int **angle_atom3 = atom->angle_atom3;
-  int **dihedral_atom1 = atom->dihedral_atom1;
-  int **dihedral_atom2 = atom->dihedral_atom2;
-  int **dihedral_atom3 = atom->dihedral_atom3;
-  int **dihedral_atom4 = atom->dihedral_atom4;
+  tagint **angle_atom1 = atom->angle_atom1;
+  tagint **angle_atom3 = atom->angle_atom3;
+  tagint **dihedral_atom1 = atom->dihedral_atom1;
+  tagint **dihedral_atom2 = atom->dihedral_atom2;
+  tagint **dihedral_atom3 = atom->dihedral_atom3;
+  tagint **dihedral_atom4 = atom->dihedral_atom4;
   int **nspecial = atom->nspecial;
   int nlocal = atom->nlocal;
 
@@ -716,7 +718,7 @@ void Special::angle_trim()
     // when find one, scan its 1-3 neigh list and mark I,J as in an angle
 
     sptr = this;
-    comm->ring(size,sizeof(int),buf,7,ring_seven,NULL);
+    comm->ring(size,sizeof(tagint),buf,7,ring_seven,NULL);
 
     // delete 1-3 neighbors if they are not flagged in dflag
 
@@ -764,8 +766,8 @@ void Special::dihedral_trim()
   int i,j,m,n;
 
   int *num_dihedral = atom->num_dihedral;
-  int **dihedral_atom1 = atom->dihedral_atom1;
-  int **dihedral_atom4 = atom->dihedral_atom4;
+  tagint **dihedral_atom1 = atom->dihedral_atom1;
+  tagint **dihedral_atom4 = atom->dihedral_atom4;
   int **nspecial = atom->nspecial;
   int nlocal = atom->nlocal;
 
@@ -822,7 +824,7 @@ void Special::dihedral_trim()
     // when find one, scan its 1-4 neigh list and mark I,J as in a dihedral
 
     sptr = this;
-    comm->ring(size,sizeof(int),buf,8,ring_eight,NULL);
+    comm->ring(size,sizeof(tagint),buf,8,ring_eight,NULL);
 
     // delete 1-4 neighbors if they are not flagged in dflag
 
@@ -871,7 +873,7 @@ void Special::ring_one(int ndatum, char *cbuf)
   int **nspecial = atom->nspecial;
   int nlocal = atom->nlocal;
 
-  int *buf = (int *) cbuf;
+  tagint *buf = (tagint *) cbuf;
   int m;
 
   for (int i = 0; i < ndatum; i++) {
@@ -890,10 +892,10 @@ void Special::ring_two(int ndatum, char *cbuf)
   Atom *atom = sptr->atom;
   int nlocal = atom->nlocal;
 
-  int **onetwo = sptr->onetwo;
+  tagint **onetwo = sptr->onetwo;
   int *count = sptr->count;
 
-  int *buf = (int *) cbuf;
+  tagint *buf = (tagint *) cbuf;
   int m;
 
   for (int i = 1; i < ndatum; i += 2) {
@@ -914,7 +916,7 @@ void Special::ring_three(int ndatum, char *cbuf)
   int **nspecial = atom->nspecial;
   int nlocal = atom->nlocal;
 
-  int *buf = (int *) cbuf;
+  tagint *buf = (tagint *) cbuf;
   int i,j,m,n,num12;
 
   i = 0;
@@ -945,10 +947,11 @@ void Special::ring_four(int ndatum, char *cbuf)
   int **nspecial = atom->nspecial;
   int nlocal = atom->nlocal;
 
-  int **onetwo = sptr->onetwo;
+  tagint **onetwo = sptr->onetwo;
 
-  int *buf = (int *) cbuf;
-  int i,j,k,m,n,original,num12,num13;
+  tagint *buf = (tagint *) cbuf;
+  tagint original;
+  int i,j,k,m,n,num12,num13;
 
   i = 0;
   while (i < ndatum) {
@@ -980,7 +983,7 @@ void Special::ring_five(int ndatum, char *cbuf)
   int **nspecial = atom->nspecial;
   int nlocal = atom->nlocal;
 
-  int *buf = (int *) cbuf;
+  tagint *buf = (tagint *) cbuf;
   int i,j,m,n,num13;
 
   i = 0;
@@ -1009,9 +1012,9 @@ void Special::ring_six(int ndatum, char *cbuf)
   int **nspecial = atom->nspecial;
   int nlocal = atom->nlocal;
 
-  int **onetwo = sptr->onetwo;
+  tagint **onetwo = sptr->onetwo;
 
-  int *buf = (int *) cbuf;
+  tagint *buf = (tagint *) cbuf;
   int i,j,k,m,n,num13,num14;
 
   i = 0;
@@ -1041,11 +1044,12 @@ void Special::ring_seven(int ndatum, char *cbuf)
   int **nspecial = atom->nspecial;
   int nlocal = atom->nlocal;
 
-  int **onethree = sptr->onethree;
+  tagint **onethree = sptr->onethree;
   int **dflag = sptr->dflag;
 
-  int *buf = (int *) cbuf;
-  int i,m,iglobal,jglobal,ilocal,jlocal;
+  tagint *buf = (tagint *) cbuf;
+  tagint iglobal,jglobal;
+  int i,m,ilocal,jlocal;
 
   i = 0;
   while (i < ndatum) {
@@ -1080,11 +1084,12 @@ void Special::ring_eight(int ndatum, char *cbuf)
   int **nspecial = atom->nspecial;
   int nlocal = atom->nlocal;
 
-  int **onefour = sptr->onefour;
+  tagint **onefour = sptr->onefour;
   int **dflag = sptr->dflag;
 
-  int *buf = (int *) cbuf;
-  int i,m,iglobal,jglobal,ilocal,jlocal;
+  tagint *buf = (tagint *) cbuf;
+  tagint iglobal,jglobal;
+  int i,m,ilocal,jlocal;
 
   i = 0;
   while (i < ndatum) {
diff --git a/src/special.h b/src/special.h
index 3ebf6206904d6db15a46179e43c43055d9ed1980..90a23a3408b487bafe923056e74c3f9580dd1d46 100644
--- a/src/special.h
+++ b/src/special.h
@@ -26,7 +26,7 @@ class Special : protected Pointers {
 
  private:
   int me,nprocs;
-  int **onetwo,**onethree,**onefour;
+  tagint **onetwo,**onethree,**onefour;
   int dihedral_flag;
 
   // data used by ring callback methods
diff --git a/src/variable.cpp b/src/variable.cpp
index 33163ba7332f0abf7fdeead9c5efc523c1477493..87fed075c1839b79125a9499781a0f5477460275 100644
--- a/src/variable.cpp
+++ b/src/variable.cpp
@@ -60,7 +60,7 @@ enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY,
      SQRT,EXP,LN,LOG,ABS,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2,
      RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,STRIDE,
      VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,GRMASK,
-     VALUE,ATOMARRAY,TYPEARRAY,INTARRAY};
+     VALUE,ATOMARRAY,TYPEARRAY,INTARRAY,BIGINTARRAY};
 
 // customize by adding a special function
 
@@ -1685,7 +1685,8 @@ double Variable::evaluate(char *str, Tree **tree)
 /* ----------------------------------------------------------------------
    one-time collapse of an atom-style variable parse tree
    tree was created by one-time parsing of formula string via evaulate()
-   only keep tree nodes that depend on ATOMARRAY, TYPEARRAY, INTARRAY
+   only keep tree nodes that depend on 
+     ATOMARRAY, TYPEARRAY, INTARRAY, BIGINTARRAY
    remainder is converted to single VALUE
    this enables optimal eval_tree loop over atoms
    customize by adding a function:
@@ -1704,6 +1705,7 @@ double Variable::collapse_tree(Tree *tree)
   if (tree->type == ATOMARRAY) return 0.0;
   if (tree->type == TYPEARRAY) return 0.0;
   if (tree->type == INTARRAY) return 0.0;
+  if (tree->type == BIGINTARRAY) return 0.0;
 
   if (tree->type == ADD) {
     arg1 = collapse_tree(tree->left);
@@ -2149,6 +2151,7 @@ double Variable::eval_tree(Tree *tree, int i)
   if (tree->type == ATOMARRAY) return tree->array[i*tree->nstride];
   if (tree->type == TYPEARRAY) return tree->array[atom->type[i]];
   if (tree->type == INTARRAY) return (double) tree->iarray[i*tree->nstride];
+  if (tree->type == BIGINTARRAY) return (double) tree->barray[i*tree->nstride];
 
   if (tree->type == ADD)
     return eval_tree(tree->left,i) + eval_tree(tree->right,i);
@@ -3510,9 +3513,14 @@ void Variable::atom_vector(char *word, Tree **tree,
   treestack[ntreestack++] = newtree;
 
   if (strcmp(word,"id") == 0) {
-    newtree->type = INTARRAY;
+    if (sizeof(tagint) == sizeof(smallint)) {
+      newtree->type = INTARRAY;
+      newtree->iarray = (int *) atom->tag;
+    } else {
+      newtree->type = BIGINTARRAY;
+      newtree->barray = (bigint *) atom->tag;
+    }
     newtree->nstride = 1;
-    newtree->iarray = atom->tag;
   } else if (strcmp(word,"mass") == 0) {
     if (atom->rmass) {
       newtree->nstride = 1;
@@ -3998,7 +4006,8 @@ int VarReader::read_scalar(char *str)
 
 int VarReader::read_peratom()
 {
-  int i,m,n,tagdata,nchunk,eof;
+  int i,m,n,nchunk,eof;
+  tagint tag;
   char *ptr,*next;
   double value;
 
@@ -4031,7 +4040,7 @@ int VarReader::read_peratom()
 
   MPI_Bcast(str,n,MPI_CHAR,0,world);
   bigint nlines = ATOBIGINT(str);
-  int map_tag_max = atom->map_tag_max;
+  tagint map_tag_max = atom->map_tag_max;
 
   bigint nread = 0;
   while (nread < nlines) {
@@ -4043,10 +4052,10 @@ int VarReader::read_peratom()
     for (i = 0; i < nchunk; i++) {
       next = strchr(buf,'\n');
       *next = '\0';
-      sscanf(buf,"%d %lg",&tagdata,&value);
-      if (tagdata <= 0 || tagdata > map_tag_max)
+      sscanf(buf,TAGINT_FORMAT " %lg",&tag,&value);
+      if (tag <= 0 || tag > map_tag_max)
         error->one(FLERR,"Invalid atom ID in variable file");
-      if ((m = atom->map(tagdata)) >= 0) vstore[m] = value;
+      if ((m = atom->map(tag)) >= 0) vstore[m] = value;
       buf = next + 1;
     }
 
diff --git a/src/variable.h b/src/variable.h
index 0d70232233fdf92657019371937843724c481714..b3a57436f87c0e61ee1fa870d1863c3825e4703d 100644
--- a/src/variable.h
+++ b/src/variable.h
@@ -63,6 +63,7 @@ class Variable : protected Pointers {
     double value;          // single scalar  
     double *array;         // per-atom or per-type list of doubles
     int *iarray;           // per-atom list of ints
+    bigint *barray;        // per-atom list of bigints
     int type;              // operation, see enum{} in variable.cpp
     int nstride;           // stride between atoms if array is a 2d array
     int selfalloc;         // 1 if array is allocated here, else 0
diff --git a/src/velocity.cpp b/src/velocity.cpp
index 1d44bcaf58f4aea8ec2d49c137d8749615b144fe..f27aa57058f40da5cd3b4ac50c4ba357f24dc69c 100644
--- a/src/velocity.cpp
+++ b/src/velocity.cpp
@@ -205,7 +205,6 @@ void Velocity::create(double t_desired, int seed)
     int mapflag = 0;
     if (atom->map_style == 0) {
       mapflag = 1;
-      atom->map_style = 1;
       atom->nghost = 0;
       atom->map_init();
       atom->map_set();
diff --git a/src/write_data.cpp b/src/write_data.cpp
index a0868d700b5d0faa5e7b01984ff48137cdcc2d9d..6c9cd49894c159365c75dc44246cee4ba31d79eb 100644
--- a/src/write_data.cpp
+++ b/src/write_data.cpp
@@ -415,7 +415,7 @@ void WriteData::bonds()
   int maxrow;
   MPI_Allreduce(&sendrow,&maxrow,1,MPI_INT,MPI_MAX,world);
 
-  int **buf;
+  tagint **buf;
   if (me == 0) memory->create(buf,MAX(1,maxrow),ncol,"write_data:buf");
   else memory->create(buf,MAX(1,sendrow),ncol,"write_data:buf");
 
@@ -436,10 +436,10 @@ void WriteData::bonds()
     fprintf(fp,"\nBonds\n\n");
     for (int iproc = 0; iproc < nprocs; iproc++) {
       if (iproc) {
-        MPI_Irecv(&buf[0][0],maxrow*ncol,MPI_INT,iproc,0,world,&request);
+        MPI_Irecv(&buf[0][0],maxrow*ncol,MPI_LMP_TAGINT,iproc,0,world,&request);
         MPI_Send(&tmp,0,MPI_INT,iproc,0,world);
         MPI_Wait(&request,&status);
-        MPI_Get_count(&status,MPI_INT,&recvrow);
+        MPI_Get_count(&status,MPI_LMP_TAGINT,&recvrow);
         recvrow /= ncol;
       } else recvrow = sendrow;
 
@@ -449,7 +449,7 @@ void WriteData::bonds()
     
   } else {
     MPI_Recv(&tmp,0,MPI_INT,0,0,world,&status);
-    MPI_Rsend(&buf[0][0],sendrow*ncol,MPI_INT,0,0,world);
+    MPI_Rsend(&buf[0][0],sendrow*ncol,MPI_LMP_TAGINT,0,0,world);
   }
 
   memory->destroy(buf);
@@ -468,7 +468,7 @@ void WriteData::angles()
   int maxrow;
   MPI_Allreduce(&sendrow,&maxrow,1,MPI_INT,MPI_MAX,world);
 
-  int **buf;
+  tagint **buf;
   if (me == 0) memory->create(buf,MAX(1,maxrow),ncol,"write_data:buf");
   else memory->create(buf,MAX(1,sendrow),ncol,"write_data:buf");
 
@@ -489,10 +489,10 @@ void WriteData::angles()
     fprintf(fp,"\nAngles\n\n");
     for (int iproc = 0; iproc < nprocs; iproc++) {
       if (iproc) {
-        MPI_Irecv(&buf[0][0],maxrow*ncol,MPI_INT,iproc,0,world,&request);
+        MPI_Irecv(&buf[0][0],maxrow*ncol,MPI_LMP_TAGINT,iproc,0,world,&request);
         MPI_Send(&tmp,0,MPI_INT,iproc,0,world);
         MPI_Wait(&request,&status);
-        MPI_Get_count(&status,MPI_INT,&recvrow);
+        MPI_Get_count(&status,MPI_LMP_TAGINT,&recvrow);
         recvrow /= ncol;
       } else recvrow = sendrow;
       
@@ -502,7 +502,7 @@ void WriteData::angles()
     
   } else {
     MPI_Recv(&tmp,0,MPI_INT,0,0,world,&status);
-    MPI_Rsend(&buf[0][0],sendrow*ncol,MPI_INT,0,0,world);
+    MPI_Rsend(&buf[0][0],sendrow*ncol,MPI_LMP_TAGINT,0,0,world);
   }
 
   memory->destroy(buf);
@@ -519,9 +519,9 @@ void WriteData::dihedrals()
 
   int ncol = 5;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *num_dihedral = atom->num_dihedral;
-  int **dihedral_atom2 = atom->dihedral_atom2;
+  tagint **dihedral_atom2 = atom->dihedral_atom2;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
@@ -539,7 +539,7 @@ void WriteData::dihedrals()
   int maxrow;
   MPI_Allreduce(&sendrow,&maxrow,1,MPI_INT,MPI_MAX,world);
 
-  int **buf;
+  tagint **buf;
   if (me == 0) memory->create(buf,MAX(1,maxrow),ncol,"write_data:buf");
   else memory->create(buf,MAX(1,sendrow),ncol,"write_data:buf");
 
@@ -560,10 +560,10 @@ void WriteData::dihedrals()
     fprintf(fp,"\nDihedrals\n\n");
     for (int iproc = 0; iproc < nprocs; iproc++) {
       if (iproc) {
-        MPI_Irecv(&buf[0][0],maxrow*ncol,MPI_INT,iproc,0,world,&request);
+        MPI_Irecv(&buf[0][0],maxrow*ncol,MPI_LMP_TAGINT,iproc,0,world,&request);
         MPI_Send(&tmp,0,MPI_INT,iproc,0,world);
         MPI_Wait(&request,&status);
-        MPI_Get_count(&status,MPI_INT,&recvrow);
+        MPI_Get_count(&status,MPI_LMP_TAGINT,&recvrow);
         recvrow /= ncol;
       } else recvrow = sendrow;
       
@@ -573,7 +573,7 @@ void WriteData::dihedrals()
     
   } else {
     MPI_Recv(&tmp,0,MPI_INT,0,0,world,&status);
-    MPI_Rsend(&buf[0][0],sendrow*ncol,MPI_INT,0,0,world);
+    MPI_Rsend(&buf[0][0],sendrow*ncol,MPI_LMP_TAGINT,0,0,world);
   }
 
   memory->destroy(buf);
@@ -590,9 +590,9 @@ void WriteData::impropers()
 
   int ncol = 5;
 
-  int *tag = atom->tag;
+  tagint *tag = atom->tag;
   int *num_improper = atom->num_improper;
-  int **improper_atom2 = atom->improper_atom2;
+  tagint **improper_atom2 = atom->improper_atom2;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
@@ -610,7 +610,7 @@ void WriteData::impropers()
   int maxrow;
   MPI_Allreduce(&sendrow,&maxrow,1,MPI_INT,MPI_MAX,world);
 
-  int **buf;
+  tagint **buf;
   if (me == 0) memory->create(buf,MAX(1,maxrow),ncol,"write_data:buf");
   else memory->create(buf,MAX(1,sendrow),ncol,"write_data:buf");
 
@@ -631,10 +631,10 @@ void WriteData::impropers()
     fprintf(fp,"\nImpropers\n\n");
     for (int iproc = 0; iproc < nprocs; iproc++) {
       if (iproc) {
-        MPI_Irecv(&buf[0][0],maxrow*ncol,MPI_INT,iproc,0,world,&request);
+        MPI_Irecv(&buf[0][0],maxrow*ncol,MPI_LMP_TAGINT,iproc,0,world,&request);
         MPI_Send(&tmp,0,MPI_INT,iproc,0,world);
         MPI_Wait(&request,&status);
-        MPI_Get_count(&status,MPI_INT,&recvrow);
+        MPI_Get_count(&status,MPI_LMP_TAGINT,&recvrow);
         recvrow /= ncol;
       } else recvrow = sendrow;
       
@@ -644,7 +644,7 @@ void WriteData::impropers()
     
   } else {
     MPI_Recv(&tmp,0,MPI_INT,0,0,world,&status);
-    MPI_Rsend(&buf[0][0],sendrow*ncol,MPI_INT,0,0,world);
+    MPI_Rsend(&buf[0][0],sendrow*ncol,MPI_LMP_TAGINT,0,0,world);
   }
 
   memory->destroy(buf);