diff --git a/src/KSPACE/pair_lj_cut_tip4p_long.cpp b/src/KSPACE/pair_lj_cut_tip4p_long.cpp
index f0ec607e0..d5d85a6bc 100644
--- a/src/KSPACE/pair_lj_cut_tip4p_long.cpp
+++ b/src/KSPACE/pair_lj_cut_tip4p_long.cpp
@@ -1,602 +1,601 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing authors: Amalie Frischknecht and Ahmed Ismail (SNL)
    simpler force assignment added by Rolf Isele-Holder (Aachen University)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "string.h"
 #include "pair_lj_cut_tip4p_long.h"
 #include "angle.h"
 #include "atom.h"
 #include "bond.h"
 #include "comm.h"
 #include "domain.h"
 #include "force.h"
 #include "kspace.h"
 #include "update.h"
 #include "respa.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "neigh_request.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define EWALD_F   1.12837917
 #define EWALD_P   0.3275911
 #define A1        0.254829592
 #define A2       -0.284496736
 #define A3        1.421413741
 #define A4       -1.453152027
 #define A5        1.061405429
 
 /* ---------------------------------------------------------------------- */
 
 PairLJCutTIP4PLong::PairLJCutTIP4PLong(LAMMPS *lmp) :
   PairLJCutCoulLong(lmp)
 {
   single_enable = 0;
   respa_enable = 0;
   tip4pflag = 1;
 
   nmax = 0;
   hneigh = NULL;
   newsite = NULL;
 
   // TIP4P cannot compute virial as F dot r
   // due to finding bonded H atoms which are not near O atom
 
   no_virial_fdotr_compute = 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 PairLJCutTIP4PLong::~PairLJCutTIP4PLong()
 {
   memory->destroy(hneigh);
   memory->destroy(newsite);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJCutTIP4PLong::compute(int eflag, int vflag)
 {
   int i,j,ii,jj,inum,jnum,itype,jtype,itable,key;
   int n,vlist[6];
   int iH1,iH2,jH1,jH2;
   double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul;
   double fraction,table;
   double delxOM, delyOM, delzOM;
   double r,r2inv,r6inv,forcecoul,forcelj,cforce;
   double factor_coul,factor_lj;
   double grij,expm2,prefactor,t,erfc,ddotf;
   double xiM[3],xjM[3],fO[3],fH[3],fd[3],f1[3],v[6],xH1[3],xH2[3];
   double *x1,*x2;
   int *ilist,*jlist,*numneigh,**firstneigh;
   double rsq;
 
   evdwl = ecoul = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = vflag_fdotr = 0;
 
   // reallocate hneigh & newsite if necessary
   // initialize hneigh[0] to -1 on steps when reneighboring occurred
   // initialize hneigh[2] to 0 every step
 
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
 
   if (atom->nmax > nmax) {
     nmax = atom->nmax;
     memory->destroy(hneigh);
     memory->create(hneigh,nmax,3,"pair:hneigh");
     memory->destroy(newsite);
     memory->create(newsite,nmax,3,"pair:newsite");
   }
   if (neighbor->ago == 0)
     for (i = 0; i < nall; i++) hneigh[i][0] = -1;
   for (i = 0; i < nall; i++) hneigh[i][2] = 0;
 
   double **f = atom->f;
   double **x = atom->x;
   double *q = atom->q;
   int *type = atom->type;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
   int newton_pair = force->newton_pair;
   double qqrd2e = force->qqrd2e;
   double cut_coulsqplus = (cut_coul+2.0*qdist) * (cut_coul+2.0*qdist);
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
 
   // loop over neighbors of my atoms
 
   for (ii = 0; ii < inum; ii++) {
     i = ilist[ii];
     qtmp = q[i];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
 
     // if atom I = water O, set x1 = offset charge site
     // else x1 = x of atom 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][2] = 1;
         if (iH1 == -1 || iH2 == -1)
           error->one(FLERR,"TIP4P hydrogen is missing");
         if (atom->type[iH1] != typeH || atom->type[iH2] != typeH)
           error->one(FLERR,"TIP4P hydrogen has incorrect atom type");
         compute_newsite(x[i],x[iH1],x[iH2],newsite[i]);
       } else {
         iH1 = hneigh[i][0];
         iH2 = hneigh[i][1];
         if (hneigh[i][2] == 0) {
           hneigh[i][2] = 1;
           compute_newsite(x[i],x[iH1],x[iH2],newsite[i]);
         }
       }
       x1 = newsite[i];
     } else x1 = x[i];
 
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
       factor_lj = special_lj[sbmask(j)];
       factor_coul = special_coul[sbmask(j)];
       j &= NEIGHMASK;
 
       delx = xtmp - x[j][0];
       dely = ytmp - x[j][1];
       delz = ztmp - x[j][2];
       rsq = delx*delx + dely*dely + delz*delz;
       jtype = type[j];
 
       // LJ interaction based on true rsq
 
       if (rsq < cut_ljsq[itype][jtype]) {
         r2inv = 1.0/rsq;
         r6inv = r2inv*r2inv*r2inv;
         forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
         forcelj *= factor_lj * r2inv;
 
         f[i][0] += delx*forcelj;
         f[i][1] += dely*forcelj;
         f[i][2] += delz*forcelj;
         f[j][0] -= delx*forcelj;
         f[j][1] -= dely*forcelj;
         f[j][2] -= delz*forcelj;
 
         if (eflag) {
           evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
             offset[itype][jtype];
           evdwl *= factor_lj;
         } else evdwl = 0.0;
 
         if (evflag) ev_tally(i,j,nlocal,newton_pair,
                              evdwl,0.0,forcelj,delx,dely,delz);
       }
 
       // adjust rsq and delxyz for off-site O charge(s) if necessary
       // but only if they are within reach
 
       if (rsq < cut_coulsqplus) {
         if (itype == typeO || jtype == typeO) {
 
           // if atom J = water O, set x2 = offset charge site
           // else x2 = x of atom J
 
           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][2] = 1;
               if (jH1 == -1 || jH2 == -1)
                 error->one(FLERR,"TIP4P hydrogen is missing");
               if (atom->type[jH1] != typeH || atom->type[jH2] != typeH)
                 error->one(FLERR,"TIP4P hydrogen has incorrect atom type");
               compute_newsite(x[j],x[jH1],x[jH2],newsite[j]);
             } else {
               jH1 = hneigh[j][0];
               jH2 = hneigh[j][1];
               if (hneigh[j][2] == 0) {
                 hneigh[j][2] = 1;
                 compute_newsite(x[j],x[jH1],x[jH2],newsite[j]);
               }
             }
             x2 = newsite[j];
           } else x2 = x[j];
 
           delx = x1[0] - x2[0];
           dely = x1[1] - x2[1];
           delz = x1[2] - x2[2];
           rsq = delx*delx + dely*dely + delz*delz;
         }
 
         // Coulombic interaction based on modified rsq
 
         if (rsq < cut_coulsq) {
           r2inv = 1 / rsq;
           if (!ncoultablebits || rsq <= tabinnersq) {
             r = sqrt(rsq);
             grij = g_ewald * r;
             expm2 = exp(-grij*grij);
             t = 1.0 / (1.0 + EWALD_P*grij);
             erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
             prefactor = qqrd2e * qtmp*q[j]/r;
             forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
             if (factor_coul < 1.0) {
               forcecoul -= (1.0-factor_coul)*prefactor;
             }
           } else {
             union_int_float_t rsq_lookup;
             rsq_lookup.f = rsq;
             itable = rsq_lookup.i & ncoulmask;
             itable >>= ncoulshiftbits;
             fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
             table = ftable[itable] + fraction*dftable[itable];
             forcecoul = qtmp*q[j] * table;
             if (factor_coul < 1.0) {
               table = ctable[itable] + fraction*dctable[itable];
               prefactor = qtmp*q[j] * table;
               forcecoul -= (1.0-factor_coul)*prefactor;
             }
           }
 
           cforce = forcecoul * r2inv;
 
           // if i,j are not O atoms, force is applied directly
           // if i or j are O atoms, force is on fictitious atom & partitioned
           // force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999)
           // f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f
           // preserves total force and torque on water molecule
           // virial = sum(r x F) where each water's atoms are near xi and xj
           // vlist stores 2,4,6 atoms whose forces contribute to virial
 
           n = 0;
           key = 0;
 
           if (itype != typeO) {
             f[i][0] += delx * cforce;
             f[i][1] += dely * cforce;
             f[i][2] += delz * cforce;
 
             if (vflag) {
               v[0] = x[i][0] * delx * cforce;
               v[1] = x[i][1] * dely * cforce;
               v[2] = x[i][2] * delz * cforce;
               v[3] = x[i][0] * dely * cforce;
               v[4] = x[i][0] * delz * cforce;
               v[5] = x[i][1] * delz * cforce;
             }
             vlist[n++] = i;
 
           } else {
             key++;
 
             fd[0] = delx*cforce;
             fd[1] = dely*cforce;
             fd[2] = delz*cforce;
 
             fO[0] = fd[0]*(1 - alpha);
             fO[1] = fd[1]*(1 - alpha);
             fO[2] = fd[2]*(1 - alpha);
 
             fH[0] = 0.5 * alpha * fd[0];
             fH[1] = 0.5 * alpha * fd[1];
             fH[2] = 0.5 * alpha * fd[2];
 
             f[i][0] += fO[0];
             f[i][1] += fO[1];
             f[i][2] += fO[2];
 
             f[iH1][0] += fH[0];
             f[iH1][1] += fH[1];
             f[iH1][2] += fH[2];
 
             f[iH2][0] += fH[0];
             f[iH2][1] += fH[1];
             f[iH2][2] += fH[2];
 
             if (vflag) {
               domain->closest_image(x[i],x[iH1],xH1);
               domain->closest_image(x[i],x[iH2],xH2);
 
               v[0] = x[i][0]*fO[0] + xH1[0]*fH[0] + xH2[0]*fH[0];
               v[1] = x[i][1]*fO[1] + xH1[1]*fH[1] + xH2[1]*fH[1];
               v[2] = x[i][2]*fO[2] + xH1[2]*fH[2] + xH2[2]*fH[2];
               v[3] = x[i][0]*fO[1] + xH1[0]*fH[1] + xH2[0]*fH[1];
               v[4] = x[i][0]*fO[2] + xH1[0]*fH[2] + xH2[0]*fH[2];
               v[5] = x[i][1]*fO[2] + xH1[1]*fH[2] + xH2[1]*fH[2];
             }
             vlist[n++] = i;
             vlist[n++] = iH1;
             vlist[n++] = iH2;
           }
 
           if (jtype != typeO) {
             f[j][0] -= delx * cforce;
             f[j][1] -= dely * cforce;
             f[j][2] -= delz * cforce;
 
             if (vflag) {
               v[0] -= x[j][0] * delx * cforce;
               v[1] -= x[j][1] * dely * cforce;
               v[2] -= x[j][2] * delz * cforce;
               v[3] -= x[j][0] * dely * cforce;
               v[4] -= x[j][0] * delz * cforce;
               v[5] -= x[j][1] * delz * cforce;
             }
             vlist[n++] = j;
 
           } else {
             key += 2;
 
             fd[0] = -delx*cforce;
             fd[1] = -dely*cforce;
             fd[2] = -delz*cforce;
 
             fO[0] = fd[0]*(1 - alpha);
             fO[1] = fd[1]*(1 - alpha);
             fO[2] = fd[2]*(1 - alpha);
 
             fH[0] = 0.5 * alpha * fd[0];
             fH[1] = 0.5 * alpha * fd[1];
             fH[2] = 0.5 * alpha * fd[2];
 
             f[j][0] += fO[0];
             f[j][1] += fO[1];
             f[j][2] += fO[2];
 
             f[jH1][0] += fH[0];
             f[jH1][1] += fH[1];
             f[jH1][2] += fH[2];
 
             f[jH2][0] += fH[0];
             f[jH2][1] += fH[1];
             f[jH2][2] += fH[2];
 
             if (vflag) {
               domain->closest_image(x[j],x[jH1],xH1);
               domain->closest_image(x[j],x[jH2],xH2);
 
               v[0] += x[j][0]*fO[0] + xH1[0]*fH[0] + xH2[0]*fH[0];
               v[1] += x[j][1]*fO[1] + xH1[1]*fH[1] + xH2[1]*fH[1];
               v[2] += x[j][2]*fO[2] + xH1[2]*fH[2] + xH2[2]*fH[2];
               v[3] += x[j][0]*fO[1] + xH1[0]*fH[1] + xH2[0]*fH[1];
               v[4] += x[j][0]*fO[2] + xH1[0]*fH[2] + xH2[0]*fH[2];
               v[5] += x[j][1]*fO[2] + xH1[1]*fH[2] + xH2[1]*fH[2];
             }
             vlist[n++] = j;
             vlist[n++] = jH1;
             vlist[n++] = jH2;
           }
 
           if (eflag) {
             if (!ncoultablebits || rsq <= tabinnersq)
               ecoul = prefactor*erfc;
             else {
               table = etable[itable] + fraction*detable[itable];
               ecoul = qtmp*q[j] * table;
             }
             if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
           } else ecoul = 0.0;
 
           if (evflag) ev_tally_tip4p(key,vlist,v,ecoul,alpha);
         }
       }
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    global settings
 ------------------------------------------------------------------------- */
 
 void PairLJCutTIP4PLong::settings(int narg, char **arg)
 {
   if (narg < 6 || narg > 7) error->all(FLERR,"Illegal pair_style command");
 
   typeO = force->inumeric(arg[0]);
   typeH = force->inumeric(arg[1]);
   typeB = force->inumeric(arg[2]);
   typeA = force->inumeric(arg[3]);
   qdist = force->numeric(arg[4]);
 
   cut_lj_global = force->numeric(arg[5]);
   if (narg == 6) cut_coul = cut_lj_global;
   else cut_coul = force->numeric(arg[6]);
 
   // reset cutoffs that have been explicitly set
 
   if (allocated) {
     int i,j;
     for (i = 1; i <= atom->ntypes; i++)
       for (j = i+1; j <= atom->ntypes; j++)
         if (setflag[i][j]) cut_lj[i][j] = cut_lj_global;
   }
 }
 
 /* ----------------------------------------------------------------------
    init specific to this pair style
 ------------------------------------------------------------------------- */
 
 void PairLJCutTIP4PLong::init_style()
 {
   if (atom->tag_enable == 0)
     error->all(FLERR,"Pair style lj/cut/coul/long/tip4p requires atom IDs");
   if (!force->newton_pair)
     error->all(FLERR,
                "Pair style lj/cut/coul/long/tip4p requires newton pair on");
   if (!atom->q_flag)
     error->all(FLERR,
                "Pair style lj/cut/coul/long/tip4p requires atom attribute q");
   if (force->bond == NULL)
     error->all(FLERR,"Must use a bond style with TIP4P potential");
   if (force->angle == NULL)
     error->all(FLERR,"Must use an angle style with TIP4P potential");
 
   PairLJCutCoulLong::init_style();
 
   // set alpha parameter
 
   double theta = force->angle->equilibrium_angle(typeA);
   double blen = force->bond->equilibrium_distance(typeB);
   alpha = qdist / (cos(0.5*theta) * blen);
 }
 
 /* ----------------------------------------------------------------------
    init for one type pair i,j and corresponding j,i
 ------------------------------------------------------------------------- */
 
 double PairLJCutTIP4PLong::init_one(int i, int j)
 {
   double cut = PairLJCutCoulLong::init_one(i,j);
 
   // check that LJ epsilon = 0.0 for water H
   // set LJ cutoff to 0.0 for any interaction involving water H
   // so LJ term isn't calculated in compute()
 
   if ((i == typeH && epsilon[i][i] != 0.0) ||
       (j == typeH && epsilon[j][j] != 0.0))
     error->all(FLERR,"Water H epsilon must be 0.0 for "
                "pair style lj/cut/coul/long/tip4p");
 
   if (i == typeH || j == typeH)
     cut_ljsq[j][i] = cut_ljsq[i][j] = 0.0;
 
   return cut;
 }
 
 /* ----------------------------------------------------------------------
   proc 0 writes to restart file
 ------------------------------------------------------------------------- */
 
 void PairLJCutTIP4PLong::write_restart_settings(FILE *fp)
 {
   fwrite(&typeO,sizeof(int),1,fp);
   fwrite(&typeH,sizeof(int),1,fp);
   fwrite(&typeB,sizeof(int),1,fp);
   fwrite(&typeA,sizeof(int),1,fp);
   fwrite(&qdist,sizeof(double),1,fp);
 
   fwrite(&cut_lj_global,sizeof(double),1,fp);
   fwrite(&cut_coul,sizeof(double),1,fp);
   fwrite(&offset_flag,sizeof(int),1,fp);
   fwrite(&mix_flag,sizeof(int),1,fp);
   fwrite(&tail_flag,sizeof(int),1,fp);
   fwrite(&ncoultablebits,sizeof(int),1,fp);
   fwrite(&tabinner,sizeof(double),1,fp);
 }
 
 /* ----------------------------------------------------------------------
   proc 0 reads from restart file, bcasts
 ------------------------------------------------------------------------- */
 
 void PairLJCutTIP4PLong::read_restart_settings(FILE *fp)
 {
   if (comm->me == 0) {
     fread(&typeO,sizeof(int),1,fp);
     fread(&typeH,sizeof(int),1,fp);
     fread(&typeB,sizeof(int),1,fp);
     fread(&typeA,sizeof(int),1,fp);
     fread(&qdist,sizeof(double),1,fp);
 
     fread(&cut_lj_global,sizeof(double),1,fp);
     fread(&cut_coul,sizeof(double),1,fp);
     fread(&offset_flag,sizeof(int),1,fp);
     fread(&mix_flag,sizeof(int),1,fp);
     fread(&tail_flag,sizeof(int),1,fp);
     fread(&ncoultablebits,sizeof(int),1,fp);
     fread(&tabinner,sizeof(double),1,fp);
   }
 
   MPI_Bcast(&typeO,1,MPI_INT,0,world);
   MPI_Bcast(&typeH,1,MPI_INT,0,world);
   MPI_Bcast(&typeB,1,MPI_INT,0,world);
   MPI_Bcast(&typeA,1,MPI_INT,0,world);
   MPI_Bcast(&qdist,1,MPI_DOUBLE,0,world);
 
   MPI_Bcast(&cut_lj_global,1,MPI_DOUBLE,0,world);
   MPI_Bcast(&cut_coul,1,MPI_DOUBLE,0,world);
   MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
   MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
   MPI_Bcast(&tail_flag,1,MPI_INT,0,world);
   MPI_Bcast(&ncoultablebits,1,MPI_INT,0,world);
   MPI_Bcast(&tabinner,1,MPI_DOUBLE,0,world);
 }
 
 /* ----------------------------------------------------------------------
   compute position xM of fictitious charge site for O atom and 2 H atoms
   return it as xM
 ------------------------------------------------------------------------- */
 
 void PairLJCutTIP4PLong::compute_newsite(double *xO, double *xH1,
-                                             double *xH2, double *xM)
+                                         double *xH2, double *xM)
 {
   double delx1 = xH1[0] - xO[0];
   double dely1 = xH1[1] - xO[1];
   double delz1 = xH1[2] - xO[2];
   domain->minimum_image(delx1,dely1,delz1);
 
   double delx2 = xH2[0] - xO[0];
   double dely2 = xH2[1] - xO[1];
   double delz2 = xH2[2] - xO[2];
   domain->minimum_image(delx2,dely2,delz2);
 
   xM[0] = xO[0] + alpha * 0.5 * (delx1 + delx2);
   xM[1] = xO[1] + alpha * 0.5 * (dely1 + dely2);
   xM[2] = xO[2] + alpha * 0.5 * (delz1 + delz2);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void *PairLJCutTIP4PLong::extract(const char *str, int &dim)
 {
   dim = 0;
   if (strcmp(str,"qdist") == 0) return (void *) &qdist;
   if (strcmp(str,"typeO") == 0) return (void *) &typeO;
   if (strcmp(str,"typeH") == 0) return (void *) &typeH;
   if (strcmp(str,"typeA") == 0) return (void *) &typeA;
   if (strcmp(str,"typeB") == 0) return (void *) &typeB;
   if (strcmp(str,"cut_coul") == 0) return (void *) &cut_coul;
   return NULL;
 }
 
 /* ----------------------------------------------------------------------
    memory usage of hneigh
 ------------------------------------------------------------------------- */
 
 double PairLJCutTIP4PLong::memory_usage()
 {
   double bytes = maxeatom * sizeof(double);
   bytes += maxvatom*6 * sizeof(double);
   bytes += 2 * nmax * sizeof(double);
   return bytes;
 }
-
diff --git a/src/input.cpp b/src/input.cpp
index edea3342f..51772ffec 100644
--- a/src/input.cpp
+++ b/src/input.cpp
@@ -1,1511 +1,1506 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "string.h"
 #include "ctype.h"
 #include "unistd.h"
 #include "sys/stat.h"
 #include "input.h"
 #include "style_command.h"
 #include "universe.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "comm.h"
 #include "group.h"
 #include "domain.h"
 #include "output.h"
 #include "thermo.h"
 #include "force.h"
 #include "pair.h"
 #include "min.h"
 #include "modify.h"
 #include "compute.h"
 #include "bond.h"
 #include "angle.h"
 #include "dihedral.h"
 #include "improper.h"
 #include "kspace.h"
 #include "update.h"
 #include "neighbor.h"
 #include "special.h"
 #include "variable.h"
 #include "accelerator_cuda.h"
 #include "error.h"
 #include "memory.h"
 
 #ifdef _OPENMP
 #include "omp.h"
 #endif
 
 using namespace LAMMPS_NS;
 
 #define DELTALINE 256
 #define DELTA 4
 
 /* ---------------------------------------------------------------------- */
 
 Input::Input(LAMMPS *lmp, int argc, char **argv) : Pointers(lmp)
 {
   MPI_Comm_rank(world,&me);
 
   maxline = maxcopy = maxwork = 0;
   line = copy = work = NULL;
   narg = maxarg = 0;
   arg = NULL;
 
   echo_screen = 0;
   echo_log = 1;
 
   label_active = 0;
   labelstr = NULL;
   jump_skip = 0;
 
   if (me == 0) {
     nfile = maxfile = 1;
     infiles = (FILE **) memory->smalloc(sizeof(FILE *),"input:infiles");
     infiles[0] = infile;
   } else infiles = NULL;
 
   variable = new Variable(lmp);
 
   // process command-line args
   // check for args "-var" and "-echo"
   // caller has already checked that sufficient arguments exist
 
   int iarg = 0;
   while (iarg < argc) {
     if (strcmp(argv[iarg],"-var") == 0 || strcmp(argv[iarg],"-v") == 0) {
       int jarg = iarg+3;
       while (jarg < argc && argv[jarg][0] != '-') jarg++;
       variable->set(argv[iarg+1],jarg-iarg-2,&argv[iarg+2]);
       iarg = jarg;
     } else if (strcmp(argv[iarg],"-echo") == 0 ||
                strcmp(argv[iarg],"-e") == 0) {
       narg = 1;
       char **tmp = arg;        // trick echo() into using argv instead of arg
       arg = &argv[iarg+1];
       echo();
       arg = tmp;
       iarg += 2;
     } else iarg++;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 Input::~Input()
 {
   // don't free command and arg strings
   // they just point to other allocated memory
 
   memory->sfree(line);
   memory->sfree(copy);
   memory->sfree(work);
   if (labelstr) delete [] labelstr;
   memory->sfree(arg);
   memory->sfree(infiles);
   delete variable;
 }
 
 /* ----------------------------------------------------------------------
    process all input from infile
    infile = stdin or file if command-line arg "-in" was used
 ------------------------------------------------------------------------- */
 
 void Input::file()
 {
   int m,n;
 
   while (1) {
 
     // read a line from input script
     // n = length of line including str terminator, 0 if end of file
     // if line ends in continuation char '&', concatenate next line
 
     if (me == 0) {
       m = 0;
       while (1) {
         if (maxline-m < 2) reallocate(line,maxline,0);
         if (fgets(&line[m],maxline-m,infile) == NULL) {
           if (m) n = strlen(line) + 1;
           else n = 0;
           break;
         }
         m = strlen(line);
         if (line[m-1] != '\n') continue;
 
         m--;
         while (m >= 0 && isspace(line[m])) m--;
         if (m < 0 || line[m] != '&') {
           line[m+1] = '\0';
           n = m+2;
           break;
         }
       }
     }
 
     // bcast the line
     // if n = 0, end-of-file
     // error if label_active is set, since label wasn't encountered
     // if original input file, code is done
     // else go back to previous input file
 
     MPI_Bcast(&n,1,MPI_INT,0,world);
     if (n == 0) {
       if (label_active) error->all(FLERR,"Label wasn't found in input script");
       if (me == 0) {
         if (infile != stdin) fclose(infile);
         nfile--;
       }
       MPI_Bcast(&nfile,1,MPI_INT,0,world);
       if (nfile == 0) break;
       if (me == 0) infile = infiles[nfile-1];
       continue;
     }
 
     if (n > maxline) reallocate(line,maxline,n);
     MPI_Bcast(line,n,MPI_CHAR,0,world);
 
     // echo the command unless scanning for label
 
     if (me == 0 && label_active == 0) {
       if (echo_screen && screen) fprintf(screen,"%s\n",line);
       if (echo_log && logfile) fprintf(logfile,"%s\n",line);
     }
 
     // parse the line
     // if no command, skip to next line in input script
 
     parse();
     if (command == NULL) continue;
 
     // if scanning for label, skip command unless it's a label command
 
     if (label_active && strcmp(command,"label") != 0) continue;
 
     // execute the command
 
     if (execute_command()) {
       char str[maxline+32];
       sprintf(str,"Unknown command: %s",line);
       error->all(FLERR,str);
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    process all input from filename
 ------------------------------------------------------------------------- */
 
 void Input::file(const char *filename)
 {
   // error if another nested file still open
   // if single open file is not stdin, close it
   // open new filename and set infile, infiles[0]
 
   if (me == 0) {
     if (nfile > 1)
       error->one(FLERR,"Another input script is already being processed");
     if (infile != stdin) fclose(infile);
     infile = fopen(filename,"r");
     if (infile == NULL) {
       char str[128];
       sprintf(str,"Cannot open input script %s",filename);
       error->one(FLERR,str);
     }
     infiles[0] = infile;
   } else infile = NULL;
 
   file();
 }
 
 /* ----------------------------------------------------------------------
    copy command in single to line, parse and execute it
    return command name to caller
 ------------------------------------------------------------------------- */
 
 char *Input::one(const char *single)
 {
   int n = strlen(single) + 1;
   if (n > maxline) reallocate(line,maxline,n);
   strcpy(line,single);
 
   // echo the command unless scanning for label
 
   if (me == 0 && label_active == 0) {
     if (echo_screen && screen) fprintf(screen,"%s\n",line);
     if (echo_log && logfile) fprintf(logfile,"%s\n",line);
   }
 
   // parse the line
   // if no command, just return NULL
 
   parse();
   if (command == NULL) return NULL;
 
   // if scanning for label, skip command unless it's a label command
 
   if (label_active && strcmp(command,"label") != 0) return NULL;
 
   // execute the command and return its name
 
   if (execute_command()) {
     char str[maxline+32];
     sprintf(str,"Unknown command: %s",line);
     error->all(FLERR,str);
   }
 
   return command;
 }
 
 /* ----------------------------------------------------------------------
    parse copy of command line by inserting string terminators
    strip comment = all chars from # on
    replace all $ via variable substitution
    command = first word
    narg = # of args
    arg[] = individual args
    treat text between single/double quotes as one arg
 ------------------------------------------------------------------------- */
 
 void Input::parse()
 {
   // duplicate line into copy string to break into words
 
   int n = strlen(line) + 1;
   if (n > maxcopy) reallocate(copy,maxcopy,n);
   strcpy(copy,line);
 
   // strip any # comment by replacing it with 0
   // do not strip # inside single/double quotes
 
   char quote = '\0';
   char *ptr = copy;
   while (*ptr) {
     if (*ptr == '#' && !quote) {
       *ptr = '\0';
       break;
     }
     if (*ptr == quote) quote = '\0';
     else if (*ptr == '"' || *ptr == '\'') quote = *ptr;
     ptr++;
   }
 
   // perform $ variable substitution (print changes)
   // except if searching for a label since earlier variable may not be defined
 
   if (!label_active) substitute(copy,work,maxcopy,maxwork,1);
 
   // command = 1st arg in copy string
 
   char *next;
   command = nextword(copy,&next);
   if (command == NULL) return;
 
   // point arg[] at each subsequent arg in copy string
   // nextword() inserts string terminators into copy string to delimit args
   // nextword() treats text between single/double quotes as one arg
 
   narg = 0;
   ptr = next;
   while (ptr) {
     if (narg == maxarg) {
       maxarg += DELTA;
       arg = (char **) memory->srealloc(arg,maxarg*sizeof(char *),"input:arg");
     }
     arg[narg] = nextword(ptr,&next);
     if (!arg[narg]) break;
     narg++;
     ptr = next;
   }
 }
 
 /* ----------------------------------------------------------------------
    find next word in str
    insert 0 at end of word
    ignore leading whitespace
    treat text between single/double quotes as one arg
      matching quote must be followed by whitespace char if not end of string
      strip quotes from returned word
    return ptr to start of word
    return next = ptr after word or NULL if word ended with 0
    return NULL if no word in string
 ------------------------------------------------------------------------- */
 
 char *Input::nextword(char *str, char **next)
 {
   char *start,*stop;
 
   start = &str[strspn(str," \t\n\v\f\r")];
   if (*start == '\0') return NULL;
 
   if (*start == '"' || *start == '\'') {
     stop = strchr(&start[1],*start);
     if (!stop) error->all(FLERR,"Unbalanced quotes in input line");
     if (stop[1] && !isspace(stop[1]))
       error->all(FLERR,"Input line quote not followed by whitespace");
     start++;
   } else stop = &start[strcspn(start," \t\n\v\f\r")];
 
   if (*stop == '\0') *next = NULL;
   else *next = stop+1;
   *stop = '\0';
   return start;
 }
 
 /* ----------------------------------------------------------------------
    substitute for $ variables in str using work str2 and return it
    reallocate str/str2 to hold expanded version if necessary & reset max/max2
    print updated string if flag is set and not searching for label
    label_active will be 0 if called from external class
 ------------------------------------------------------------------------- */
 
 void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
 {
   // use str2 as scratch space to expand str, then copy back to str
   // reallocate str and str2 as necessary
   // do not replace $ inside single/double quotes
   // var = pts at variable name, ended by NULL
   //   if $ is followed by '{', trailing '}' becomes NULL
   //   else $x becomes x followed by NULL
   // beyond = points to text following variable
 
   int i,n,paren_count;
   char immediate[256];
   char *var,*value,*beyond;
   char quote = '\0';
   char *ptr = str;
 
   n = strlen(str) + 1;
   if (n > max2) reallocate(str2,max2,n);
   *str2 = '\0';
   char *ptr2 = str2;
 
   while (*ptr) {
     // variable substitution
 
     if (*ptr == '$' && !quote) {
 
       // value = ptr to expanded variable
       // variable name between curly braces, e.g. ${a}
 
       if (*(ptr+1) == '{') {
         var = ptr+2;
         i = 0;
 
         while (var[i] != '\0' && var[i] != '}') i++;
 
         if (var[i] == '\0') error->one(FLERR,"Invalid variable name");
         var[i] = '\0';
         beyond = ptr + strlen(var) + 3;
         value = variable->retrieve(var);
 
       // immediate variable between parenthesis, e.g. $(1/2)
 
       } else if (*(ptr+1) == '(') {
         var = ptr+2;
         paren_count = 0;
         i = 0;
 
         while (var[i] != '\0' && !(var[i] == ')' && paren_count == 0)) {
           switch (var[i]) {
             case '(': paren_count++; break;
             case ')': paren_count--; break;
             default: ;
           }
           i++;
         }
 
         if (var[i] == '\0') error->one(FLERR,"Invalid immediate variable");
         var[i] = '\0';
         beyond = ptr + strlen(var) + 3;
         sprintf(immediate,"%.20g",variable->compute_equal(var));
         value = immediate;
 
       // single character variable name, e.g. $a
 
       } else {
         var = ptr;
         var[0] = var[1];
         var[1] = '\0';
         beyond = ptr + 2;
         value = variable->retrieve(var);
       }
 
       if (value == NULL) error->one(FLERR,"Substitution for illegal variable");
 
       // check if storage in str2 needs to be expanded
       // re-initialize ptr and ptr2 to the point beyond the variable.
 
       n = strlen(str2) + strlen(value) + strlen(beyond) + 1;
       if (n > max2) reallocate(str2,max2,n);
       strcat(str2,value);
       ptr2 = str2 + strlen(str2);
       ptr = beyond;
 
       // output substitution progress if requested
 
       if (flag && me == 0 && label_active == 0) {
         if (echo_screen && screen) fprintf(screen,"%s%s\n",str2,beyond);
         if (echo_log && logfile) fprintf(logfile,"%s%s\n",str2,beyond);
       }
 
       continue;
     }
 
     if (*ptr == quote) quote = '\0';
     else if (*ptr == '"' || *ptr == '\'') quote = *ptr;
 
     // copy current character into str2
 
     *ptr2++ = *ptr++;
     *ptr2 = '\0';
   }
 
   // set length of input str to length of work str2
   // copy work string back to input str
 
   if (max2 > max) reallocate(str,max,max2);
   strcpy(str,str2);
 }
 
 /* ----------------------------------------------------------------------
    rellocate a string
    if n > 0: set max >= n in increments of DELTALINE
    if n = 0: just increment max by DELTALINE
 ------------------------------------------------------------------------- */
 
 void Input::reallocate(char *&str, int &max, int n)
 {
   if (n) {
     while (n > max) max += DELTALINE;
   } else max += DELTALINE;
 
   str = (char *) memory->srealloc(str,max*sizeof(char),"input:str");
 }
 
 /* ----------------------------------------------------------------------
    process a single parsed command
    return 0 if successful, -1 if did not recognize command
 ------------------------------------------------------------------------- */
 
 int Input::execute_command()
 {
   int flag = 1;
 
   if (!strcmp(command,"clear")) clear();
   else if (!strcmp(command,"echo")) echo();
   else if (!strcmp(command,"if")) ifthenelse();
   else if (!strcmp(command,"include")) include();
   else if (!strcmp(command,"jump")) jump();
   else if (!strcmp(command,"label")) label();
   else if (!strcmp(command,"log")) log();
   else if (!strcmp(command,"next")) next_command();
   else if (!strcmp(command,"partition")) partition();
   else if (!strcmp(command,"print")) print();
   else if (!strcmp(command,"quit")) quit();
   else if (!strcmp(command,"shell")) shell();
   else if (!strcmp(command,"variable")) variable_command();
 
   else if (!strcmp(command,"angle_coeff")) angle_coeff();
   else if (!strcmp(command,"angle_style")) angle_style();
   else if (!strcmp(command,"atom_modify")) atom_modify();
   else if (!strcmp(command,"atom_style")) atom_style();
   else if (!strcmp(command,"bond_coeff")) bond_coeff();
   else if (!strcmp(command,"bond_style")) bond_style();
   else if (!strcmp(command,"boundary")) boundary();
   else if (!strcmp(command,"box")) box();
   else if (!strcmp(command,"communicate")) communicate();
   else if (!strcmp(command,"compute")) compute();
   else if (!strcmp(command,"compute_modify")) compute_modify();
   else if (!strcmp(command,"dielectric")) dielectric();
   else if (!strcmp(command,"dihedral_coeff")) dihedral_coeff();
   else if (!strcmp(command,"dihedral_style")) dihedral_style();
   else if (!strcmp(command,"dimension")) dimension();
   else if (!strcmp(command,"dump")) dump();
   else if (!strcmp(command,"dump_modify")) dump_modify();
   else if (!strcmp(command,"fix")) fix();
   else if (!strcmp(command,"fix_modify")) fix_modify();
   else if (!strcmp(command,"group")) group_command();
   else if (!strcmp(command,"improper_coeff")) improper_coeff();
   else if (!strcmp(command,"improper_style")) improper_style();
   else if (!strcmp(command,"kspace_modify")) kspace_modify();
   else if (!strcmp(command,"kspace_style")) kspace_style();
   else if (!strcmp(command,"lattice")) lattice();
   else if (!strcmp(command,"mass")) mass();
   else if (!strcmp(command,"min_modify")) min_modify();
   else if (!strcmp(command,"min_style")) min_style();
   else if (!strcmp(command,"neigh_modify")) neigh_modify();
   else if (!strcmp(command,"neighbor")) neighbor_command();
   else if (!strcmp(command,"newton")) newton();
   else if (!strcmp(command,"package")) package();
   else if (!strcmp(command,"pair_coeff")) pair_coeff();
   else if (!strcmp(command,"pair_modify")) pair_modify();
   else if (!strcmp(command,"pair_style")) pair_style();
   else if (!strcmp(command,"pair_write")) pair_write();
   else if (!strcmp(command,"processors")) processors();
   else if (!strcmp(command,"region")) region();
   else if (!strcmp(command,"reset_timestep")) reset_timestep();
   else if (!strcmp(command,"restart")) restart();
   else if (!strcmp(command,"run_style")) run_style();
   else if (!strcmp(command,"special_bonds")) special_bonds();
   else if (!strcmp(command,"suffix")) suffix();
   else if (!strcmp(command,"thermo")) thermo();
   else if (!strcmp(command,"thermo_modify")) thermo_modify();
   else if (!strcmp(command,"thermo_style")) thermo_style();
   else if (!strcmp(command,"timestep")) timestep();
   else if (!strcmp(command,"uncompute")) uncompute();
   else if (!strcmp(command,"undump")) undump();
   else if (!strcmp(command,"unfix")) unfix();
   else if (!strcmp(command,"units")) units();
 
   else flag = 0;
 
   // return if command was listed above
 
   if (flag) return 0;
 
   // check if command is added via style.h
 
   if (0) return 0;      // dummy line to enable else-if macro expansion
 
 #define COMMAND_CLASS
 #define CommandStyle(key,Class)         \
   else if (strcmp(command,#key) == 0) { \
     Class key(lmp);                     \
     key.command(narg,arg);              \
     return 0;                           \
   }
 #include "style_command.h"
 #undef COMMAND_CLASS
 
   // unrecognized command
 
   return -1;
 }
 
 /* ---------------------------------------------------------------------- */
 /* ---------------------------------------------------------------------- */
 /* ---------------------------------------------------------------------- */
 
 /* ---------------------------------------------------------------------- */
 
 void Input::clear()
 {
   if (narg > 0) error->all(FLERR,"Illegal clear command");
   lmp->destroy();
   lmp->create();
   lmp->post_create();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::echo()
 {
   if (narg != 1) error->all(FLERR,"Illegal echo command");
 
   if (strcmp(arg[0],"none") == 0) {
     echo_screen = 0;
     echo_log = 0;
   } else if (strcmp(arg[0],"screen") == 0) {
     echo_screen = 1;
     echo_log = 0;
   } else if (strcmp(arg[0],"log") == 0) {
     echo_screen = 0;
     echo_log = 1;
   } else if (strcmp(arg[0],"both") == 0) {
     echo_screen = 1;
     echo_log = 1;
   } else error->all(FLERR,"Illegal echo command");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::ifthenelse()
 {
   if (narg < 3) error->all(FLERR,"Illegal if command");
 
   // substitute for variables in Boolean expression for "if"
   // in case expression was enclosed in quotes
   // must substitute on copy of arg else will step on subsequent args
 
   int n = strlen(arg[0]) + 1;
   if (n > maxline) reallocate(line,maxline,n);
   strcpy(line,arg[0]);
   substitute(line,work,maxline,maxwork,0);
 
   // evaluate Boolean expression for "if"
 
   double btest = variable->evaluate_boolean(line);
 
   // bound "then" commands
 
   if (strcmp(arg[1],"then") != 0) error->all(FLERR,"Illegal if command");
 
   int first = 2;
   int iarg = first;
   while (iarg < narg &&
          (strcmp(arg[iarg],"elif") != 0 && strcmp(arg[iarg],"else") != 0))
     iarg++;
   int last = iarg-1;
 
   // execute "then" commands
   // make copies of all arg string commands
   // required because re-parsing a command via one() will wipe out args
 
   if (btest != 0.0) {
     int ncommands = last-first + 1;
     if (ncommands <= 0) error->all(FLERR,"Illegal if command");
 
     char **commands = new char*[ncommands];
     ncommands = 0;
     for (int i = first; i <= last; i++) {
       int n = strlen(arg[i]) + 1;
       if (n == 1) error->all(FLERR,"Illegal if command");
       commands[ncommands] = new char[n];
       strcpy(commands[ncommands],arg[i]);
       ncommands++;
     }
 
     for (int i = 0; i < ncommands; i++) one(commands[i]);
 
     for (int i = 0; i < ncommands; i++) delete [] commands[i];
     delete [] commands;
 
     return;
   }
 
   // done if no "elif" or "else"
 
   if (iarg == narg) return;
 
   // check "elif" or "else" until find commands to execute
   // substitute for variables and evaluate Boolean expression for "elif"
   // must substitute on copy of arg else will step on subsequent args
   // bound and execute "elif" or "else" commands
 
   while (1) {
     if (iarg+2 > narg) error->all(FLERR,"Illegal if command");
     if (strcmp(arg[iarg],"elif") == 0) {
       n = strlen(arg[iarg+1]) + 1;
       if (n > maxline) reallocate(line,maxline,n);
       strcpy(line,arg[iarg+1]);
       substitute(line,work,maxline,maxwork,0);
       btest = variable->evaluate_boolean(line);
       first = iarg+2;
     } else {
       btest = 1.0;
       first = iarg+1;
     }
 
     iarg = first;
     while (iarg < narg &&
            (strcmp(arg[iarg],"elif") != 0 && strcmp(arg[iarg],"else") != 0))
       iarg++;
     last = iarg-1;
 
     if (btest == 0.0) continue;
 
     int ncommands = last-first + 1;
     if (ncommands <= 0) error->all(FLERR,"Illegal if command");
 
     char **commands = new char*[ncommands];
     ncommands = 0;
     for (int i = first; i <= last; i++) {
       int n = strlen(arg[i]) + 1;
       if (n == 1) error->all(FLERR,"Illegal if command");
       commands[ncommands] = new char[n];
       strcpy(commands[ncommands],arg[i]);
       ncommands++;
     }
 
     // execute the list of commands
 
     for (int i = 0; i < ncommands; i++) one(commands[i]);
 
     // clean up
 
     for (int i = 0; i < ncommands; i++) delete [] commands[i];
     delete [] commands;
 
     return;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::include()
 {
   if (narg != 1) error->all(FLERR,"Illegal include command");
 
   if (me == 0) {
     if (nfile == maxfile) {
       maxfile++;
       infiles = (FILE **)
         memory->srealloc(infiles,maxfile*sizeof(FILE *),"input:infiles");
     }
     infile = fopen(arg[0],"r");
     if (infile == NULL) {
       char str[128];
       sprintf(str,"Cannot open input script %s",arg[0]);
       error->one(FLERR,str);
     }
     infiles[nfile++] = infile;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::jump()
 {
   if (narg < 1 || narg > 2) error->all(FLERR,"Illegal jump command");
 
   if (jump_skip) {
     jump_skip = 0;
     return;
   }
 
   if (me == 0) {
     if (strcmp(arg[0],"SELF") == 0) rewind(infile);
     else {
       if (infile != stdin) fclose(infile);
       infile = fopen(arg[0],"r");
       if (infile == NULL) {
         char str[128];
         sprintf(str,"Cannot open input script %s",arg[0]);
         error->one(FLERR,str);
       }
       infiles[nfile-1] = infile;
     }
   }
 
   if (narg == 2) {
     label_active = 1;
     if (labelstr) delete [] labelstr;
     int n = strlen(arg[1]) + 1;
     labelstr = new char[n];
     strcpy(labelstr,arg[1]);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::label()
 {
   if (narg != 1) error->all(FLERR,"Illegal label command");
   if (label_active && strcmp(labelstr,arg[0]) == 0) label_active = 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::log()
 {
   if (narg != 1) error->all(FLERR,"Illegal log command");
 
   if (me == 0) {
     if (logfile) fclose(logfile);
     if (strcmp(arg[0],"none") == 0) logfile = NULL;
     else {
       logfile = fopen(arg[0],"w");
       if (logfile == NULL) {
         char str[128];
         sprintf(str,"Cannot open logfile %s",arg[0]);
         error->one(FLERR,str);
       }
     }
     if (universe->nworlds == 1) universe->ulogfile = logfile;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::next_command()
 {
   if (variable->next(narg,arg)) jump_skip = 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::partition()
 {
   if (narg < 3) error->all(FLERR,"Illegal partition command");
 
   int yesflag;
   if (strcmp(arg[0],"yes") == 0) yesflag = 1;
   else if (strcmp(arg[0],"no") == 0) yesflag = 0;
   else error->all(FLERR,"Illegal partition command");
 
   int ilo,ihi;
   force->bounds(arg[1],universe->nworlds,ilo,ihi);
 
   // copy original line to copy, since will use strtok() on it
   // ptr = start of 4th word
 
   strcpy(copy,line);
   char *ptr = strtok(copy," \t\n\r\f");
   ptr = strtok(NULL," \t\n\r\f");
   ptr = strtok(NULL," \t\n\r\f");
   ptr += strlen(ptr) + 1;
   ptr += strspn(ptr," \t\n\r\f");
 
   // execute the remaining command line on requested partitions
 
   if (yesflag) {
     if (universe->iworld+1 >= ilo && universe->iworld+1 <= ihi) one(ptr);
   } else {
     if (universe->iworld+1 < ilo || universe->iworld+1 > ihi) one(ptr);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::print()
 {
   if (narg != 1) error->all(FLERR,"Illegal print command");
 
   // copy 1st arg back into line (copy is being used)
   // check maxline since arg[0] could have been exanded by variables
   // substitute for $ variables (no printing) and print arg
 
   int n = strlen(arg[0]) + 1;
   if (n > maxline) reallocate(line,maxline,n);
   strcpy(line,arg[0]);
   substitute(line,work,maxline,maxwork,0);
 
   if (me == 0) {
     if (screen) fprintf(screen,"%s\n",line);
     if (logfile) fprintf(logfile,"%s\n",line);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::quit()
 {
   if (narg) error->all(FLERR,"Illegal quit command");
   error->done();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::shell()
 {
   if (narg < 1) error->all(FLERR,"Illegal shell command");
 
   if (strcmp(arg[0],"cd") == 0) {
     if (narg != 2) error->all(FLERR,"Illegal shell command");
     chdir(arg[1]);
 
   } else if (strcmp(arg[0],"mkdir") == 0) {
     if (narg < 2) error->all(FLERR,"Illegal shell command");
 #if !defined(WINDOWS) && !defined(__MINGW32_VERSION)
     if (me == 0)
       for (int i = 1; i < narg; i++)
         mkdir(arg[i], S_IRWXU | S_IRGRP | S_IXGRP);
 #endif
 
   } else if (strcmp(arg[0],"mv") == 0) {
     if (narg != 3) error->all(FLERR,"Illegal shell command");
     if (me == 0) rename(arg[1],arg[2]);
 
   } else if (strcmp(arg[0],"rm") == 0) {
     if (narg < 2) error->all(FLERR,"Illegal shell command");
     if (me == 0)
       for (int i = 1; i < narg; i++) unlink(arg[i]);
 
   } else if (strcmp(arg[0],"rmdir") == 0) {
     if (narg < 2) error->all(FLERR,"Illegal shell command");
     if (me == 0)
       for (int i = 1; i < narg; i++) rmdir(arg[i]);
 
   // use work string to concat args back into one string separated by spaces
   // invoke string in shell via system()
 
   } else {
     int n = 0;
     for (int i = 0; i < narg; i++) n += strlen(arg[i]) + 1;
     if (n > maxwork) reallocate(work,maxwork,n);
 
     strcpy(work,arg[0]);
     for (int i = 1; i < narg; i++) {
       strcat(work," ");
       strcat(work,arg[i]);
     }
 
     if (me == 0) system(work);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::variable_command()
 {
   variable->set(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 /* ---------------------------------------------------------------------- */
 /* ---------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    one function for each LAMMPS-specific input script command
 ------------------------------------------------------------------------- */
 
 /* ---------------------------------------------------------------------- */
 
 void Input::angle_coeff()
 {
   if (domain->box_exist == 0)
     error->all(FLERR,"Angle_coeff command before simulation box is defined");
   if (force->angle == NULL)
     error->all(FLERR,"Angle_coeff command before angle_style is defined");
   if (atom->avec->angles_allow == 0)
     error->all(FLERR,"Angle_coeff command when no angles allowed");
   force->angle->coeff(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::angle_style()
 {
   if (narg < 1) error->all(FLERR,"Illegal angle_style command");
   if (atom->avec->angles_allow == 0)
     error->all(FLERR,"Angle_style command when no angles allowed");
   force->create_angle(arg[0],lmp->suffix);
   if (force->angle) force->angle->settings(narg-1,&arg[1]);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::atom_modify()
 {
   atom->modify_params(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::atom_style()
 {
   if (narg < 1) error->all(FLERR,"Illegal atom_style command");
   if (domain->box_exist)
     error->all(FLERR,"Atom_style command after simulation box is defined");
   atom->create_avec(arg[0],narg-1,&arg[1],lmp->suffix);
-
-  // use grow to initialize atom-based arrays to length 1
-  // so that x[0][0] can be referenced even if proc has no atoms
-
-  //atom->avec->grow(1);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::bond_coeff()
 {
   if (domain->box_exist == 0)
     error->all(FLERR,"Bond_coeff command before simulation box is defined");
   if (force->bond == NULL)
     error->all(FLERR,"Bond_coeff command before bond_style is defined");
   if (atom->avec->bonds_allow == 0)
     error->all(FLERR,"Bond_coeff command when no bonds allowed");
   force->bond->coeff(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::bond_style()
 {
   if (narg < 1) error->all(FLERR,"Illegal bond_style command");
   if (atom->avec->bonds_allow == 0)
     error->all(FLERR,"Bond_style command when no bonds allowed");
   force->create_bond(arg[0],lmp->suffix);
   if (force->bond) force->bond->settings(narg-1,&arg[1]);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::boundary()
 {
   if (domain->box_exist)
     error->all(FLERR,"Boundary command after simulation box is defined");
   domain->set_boundary(narg,arg,0);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::box()
 {
   if (domain->box_exist)
     error->all(FLERR,"Box command after simulation box is defined");
   domain->set_box(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::communicate()
 {
   comm->set(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::compute()
 {
   modify->add_compute(narg,arg,lmp->suffix);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::compute_modify()
 {
   modify->modify_compute(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::dielectric()
 {
   if (narg != 1) error->all(FLERR,"Illegal dielectric command");
   force->dielectric = atof(arg[0]);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::dihedral_coeff()
 {
   if (domain->box_exist == 0)
     error->all(FLERR,"Dihedral_coeff command before simulation box is defined");
   if (force->dihedral == NULL)
     error->all(FLERR,"Dihedral_coeff command before dihedral_style is defined");
   if (atom->avec->dihedrals_allow == 0)
     error->all(FLERR,"Dihedral_coeff command when no dihedrals allowed");
   force->dihedral->coeff(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::dihedral_style()
 {
   if (narg < 1) error->all(FLERR,"Illegal dihedral_style command");
   if (atom->avec->dihedrals_allow == 0)
     error->all(FLERR,"Dihedral_style command when no dihedrals allowed");
   force->create_dihedral(arg[0],lmp->suffix);
   if (force->dihedral) force->dihedral->settings(narg-1,&arg[1]);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::dimension()
 {
   if (narg != 1) error->all(FLERR,"Illegal dimension command");
   if (domain->box_exist)
     error->all(FLERR,"Dimension command after simulation box is defined");
   domain->dimension = atoi(arg[0]);
   if (domain->dimension != 2 && domain->dimension != 3)
     error->all(FLERR,"Illegal dimension command");
 
   // must reset default extra_dof of all computes
   // since some were created before dimension command is encountered
 
   for (int i = 0; i < modify->ncompute; i++)
     modify->compute[i]->reset_extra_dof();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::dump()
 {
   output->add_dump(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::dump_modify()
 {
   output->modify_dump(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::fix()
 {
   modify->add_fix(narg,arg,lmp->suffix);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::fix_modify()
 {
   modify->modify_fix(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::group_command()
 {
   group->assign(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::improper_coeff()
 {
   if (domain->box_exist == 0)
     error->all(FLERR,"Improper_coeff command before simulation box is defined");
   if (force->improper == NULL)
     error->all(FLERR,"Improper_coeff command before improper_style is defined");
   if (atom->avec->impropers_allow == 0)
     error->all(FLERR,"Improper_coeff command when no impropers allowed");
   force->improper->coeff(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::improper_style()
 {
   if (narg < 1) error->all(FLERR,"Illegal improper_style command");
   if (atom->avec->impropers_allow == 0)
     error->all(FLERR,"Improper_style command when no impropers allowed");
   force->create_improper(arg[0],lmp->suffix);
   if (force->improper) force->improper->settings(narg-1,&arg[1]);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::kspace_modify()
 {
   if (force->kspace == NULL)
     error->all(FLERR,"KSpace style has not yet been set");
   force->kspace->modify_params(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::kspace_style()
 {
   force->create_kspace(narg,arg,lmp->suffix);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::lattice()
 {
   domain->set_lattice(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::mass()
 {
   if (narg != 2) error->all(FLERR,"Illegal mass command");
   if (domain->box_exist == 0)
     error->all(FLERR,"Mass command before simulation box is defined");
   atom->set_mass(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::min_modify()
 {
   update->minimize->modify_params(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::min_style()
 {
   if (domain->box_exist == 0)
     error->all(FLERR,"Min_style command before simulation box is defined");
   update->create_minimize(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::neigh_modify()
 {
   neighbor->modify_params(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::neighbor_command()
 {
   neighbor->set(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::newton()
 {
   int newton_pair,newton_bond;
 
   if (narg == 1) {
     if (strcmp(arg[0],"off") == 0) newton_pair = newton_bond = 0;
     else if (strcmp(arg[0],"on") == 0) newton_pair = newton_bond = 1;
     else error->all(FLERR,"Illegal newton command");
   } else if (narg == 2) {
     if (strcmp(arg[0],"off") == 0) newton_pair = 0;
     else if (strcmp(arg[0],"on") == 0) newton_pair= 1;
     else error->all(FLERR,"Illegal newton command");
     if (strcmp(arg[1],"off") == 0) newton_bond = 0;
     else if (strcmp(arg[1],"on") == 0) newton_bond = 1;
     else error->all(FLERR,"Illegal newton command");
   } else error->all(FLERR,"Illegal newton command");
 
   force->newton_pair = newton_pair;
 
   if (newton_bond == 0) {
     if (domain->box_exist && force->newton_bond == 1)
       error->all(FLERR,"Newton bond change after simulation box is defined");
     force->newton_bond = 0;
   } else {
     if (domain->box_exist && force->newton_bond == 0)
       error->all(FLERR,"Newton bond change after simulation box is defined");
     force->newton_bond = 1;
   }
 
   if (newton_pair || newton_bond) force->newton = 1;
   else force->newton = 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::package()
 {
   if (domain->box_exist)
     error->all(FLERR,"Package command after simulation box is defined");
   if (narg < 1) error->all(FLERR,"Illegal package command");
 
   if (strcmp(arg[0],"cuda") == 0) {
     if (!lmp->cuda)
       error->all(FLERR,"Package cuda command without USER-CUDA installed");
     lmp->cuda->accelerator(narg-1,&arg[1]);
 
   } else if (strcmp(arg[0],"gpu") == 0) {
     char **fixarg = new char*[2+narg];
     fixarg[0] = (char *) "package_gpu";
     fixarg[1] = (char *) "all";
     fixarg[2] = (char *) "GPU";
     for (int i = 1; i < narg; i++) fixarg[i+2] = arg[i];
     modify->add_fix(2+narg,fixarg,NULL);
     delete [] fixarg;
     force->newton_pair = 0;
 
   } else if (strcmp(arg[0],"omp") == 0) {
     char **fixarg = new char*[2+narg];
     fixarg[0] = (char *) "package_omp";
     fixarg[1] = (char *) "all";
     fixarg[2] = (char *) "OMP";
     for (int i = 1; i < narg; i++) fixarg[i+2] = arg[i];
     modify->add_fix(2+narg,fixarg,NULL);
     delete [] fixarg;
 
   } else error->all(FLERR,"Illegal package command");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::pair_coeff()
 {
   if (domain->box_exist == 0)
     error->all(FLERR,"Pair_coeff command before simulation box is defined");
   if (force->pair == NULL)
     error->all(FLERR,"Pair_coeff command before pair_style is defined");
   force->pair->coeff(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::pair_modify()
 {
   if (force->pair == NULL)
     error->all(FLERR,"Pair_modify command before pair_style is defined");
   force->pair->modify_params(narg,arg);
 }
 
 /* ----------------------------------------------------------------------
    if old pair style exists and new style is same, just change settings
    else create new pair class
 ------------------------------------------------------------------------- */
 
 void Input::pair_style()
 {
   if (narg < 1) error->all(FLERR,"Illegal pair_style command");
   if (force->pair && strcmp(arg[0],force->pair_style) == 0) {
     force->pair->settings(narg-1,&arg[1]);
     return;
   }
   force->create_pair(arg[0],lmp->suffix);
   if (force->pair) force->pair->settings(narg-1,&arg[1]);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::pair_write()
 {
   if (force->pair == NULL)
     error->all(FLERR,"Pair_write command before pair_style is defined");
   force->pair->write_file(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::processors()
 {
   if (domain->box_exist)
     error->all(FLERR,"Processors command after simulation box is defined");
   comm->set_processors(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::region()
 {
   domain->add_region(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::reset_timestep()
 {
   update->reset_timestep(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::restart()
 {
   output->create_restart(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::run_style()
 {
   if (domain->box_exist == 0)
     error->all(FLERR,"Run_style command before simulation box is defined");
   update->create_integrate(narg,arg,lmp->suffix);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::special_bonds()
 {
   // store 1-3,1-4 and dihedral/extra flag values before change
   // change in 1-2 coeffs will not change the special list
 
   double lj2 = force->special_lj[2];
   double lj3 = force->special_lj[3];
   double coul2 = force->special_coul[2];
   double coul3 = force->special_coul[3];
   int angle = force->special_angle;
   int dihedral = force->special_dihedral;
   int extra = force->special_extra;
 
   force->set_special(narg,arg);
 
   // if simulation box defined and saved values changed, redo special list
 
   if (domain->box_exist && atom->molecular) {
     if (lj2 != force->special_lj[2] || lj3 != force->special_lj[3] ||
         coul2 != force->special_coul[2] || coul3 != force->special_coul[3] ||
         angle != force->special_angle ||
         dihedral != force->special_dihedral ||
         extra != force->special_extra) {
       Special special(lmp);
       special.build();
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::suffix()
 {
   if (narg != 1) error->all(FLERR,"Illegal suffix command");
 
   if (strcmp(arg[0],"off") == 0) lmp->suffix_enable = 0;
   else if (strcmp(arg[0],"on") == 0) lmp->suffix_enable = 1;
   else {
     delete [] lmp->suffix;
     int n = strlen(arg[0]) + 1;
     lmp->suffix = new char[n];
     strcpy(lmp->suffix,arg[0]);
     lmp->suffix_enable = 1;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::thermo()
 {
   output->set_thermo(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::thermo_modify()
 {
   output->thermo->modify_params(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::thermo_style()
 {
   output->create_thermo(narg,arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::timestep()
 {
   if (narg != 1) error->all(FLERR,"Illegal timestep command");
   update->dt = atof(arg[0]);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::uncompute()
 {
   if (narg != 1) error->all(FLERR,"Illegal uncompute command");
   modify->delete_compute(arg[0]);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::undump()
 {
   if (narg != 1) error->all(FLERR,"Illegal undump command");
   output->delete_dump(arg[0]);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::unfix()
 {
   if (narg != 1) error->all(FLERR,"Illegal unfix command");
   modify->delete_fix(arg[0]);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Input::units()
 {
   if (narg != 1) error->all(FLERR,"Illegal units command");
   if (domain->box_exist)
     error->all(FLERR,"Units command after simulation box is defined");
   update->set_units(arg[0]);
 }