diff --git a/doc/Section_commands.html b/doc/Section_commands.html
index 5fb8988b4..2f222a14c 100644
--- a/doc/Section_commands.html
+++ b/doc/Section_commands.html
@@ -1,498 +1,498 @@
 <HTML>
 <CENTER><A HREF = "Section_start.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_howto.html">Next Section</A> 
 </CENTER>
 
 
 
 
 
 
 <HR>
 
 <H3>3. Commands 
 </H3>
 <P>This section describes how a LAMMPS input script is formatted and what
 commands are used to define a LAMMPS simulation.
 </P>
 3.1 <A HREF = "#3_1">LAMMPS input script</A><BR>
 3.2 <A HREF = "#3_2">Parsing rules</A><BR>
 3.3 <A HREF = "#3_3">Input script structure</A><BR>
 3.4 <A HREF = "#3_4">Commands listed by category</A><BR>
 3.5 <A HREF = "#3_5">Commands listed alphabetically</A> <BR>
 
 <HR>
 
 <A NAME = "3_1"></A><H4>3.1 LAMMPS input script 
 </H4>
 <P>LAMMPS executes by reading commands from a input script (text file),
 one line at a time.  When the input script ends, LAMMPS exits.  Each
 command causes LAMMPS to take some action.  It may set an internal
 variable, read in a file, or run a simulation.  Most commands have
 default settings, which means you only need to use the command if you
 wish to change the default.
 </P>
 <P>In many cases, the ordering of commands in an input script is not
 important.  However the following rules apply:
 </P>
 <P>(1) LAMMPS does not read your entire input script and then perform a
 simulation with all the settings.  Rather, the input script is read
 one line at a time and each command takes effect when it is read.
 Thus this sequence of commands:
 </P>
 <PRE>timestep 0.5 
 run      100 
 run      100 
 </PRE>
 <P>does something different than this sequence:
 </P>
 <PRE>run      100 
 timestep 0.5 
 run      100 
 </PRE>
 <P>In the first case, the specified timestep (0.5 fmsec) is used for two
 simulations of 100 timesteps each.  In the 2nd case, the default
 timestep (1.0 fmsec) is used for the 1st 100 step simulation and a 0.5
 fmsec timestep is used for the 2nd one.
 </P>
 <P>(2) Some commands are only valid when they follow other commands.  For
 example you cannot set the temperature of a group of atoms until atoms
 have been defined and a group command is used to define which atoms
 belong to the group.
 </P>
 <P>(3) Sometimes command B will use values that can be set by command A.
 This means command A must precede command B in the input script if it
 is to have the desired effect.  For example, the
 <A HREF = "read_data.html">read_data</A> command initializes the system by setting
 up the simulation box and assigning atoms to processors.  If default
 values are not desired, the <A HREF = "processors.html">processors</A> and
 <A HREF = "boundary.html">boundary</A> commands need to be used before read_data to
 tell LAMMPS how to map processors to the simulation box.
 </P>
 <P>Many input script errors are detected by LAMMPS and an ERROR or
 WARNING message is printed.  <A HREF = "Section_errors.html">This section</A> gives
 more information on what errors mean.  The documentation for each
 command lists restrictions on how the command can be used.
 </P>
 <HR>
 
 <A NAME = "3_2"></A><H4>3.2 Parsing rules 
 </H4>
 <P>Each non-blank line in the input script is treated as a command.
 LAMMPS commands are case sensitive.  Command names are lower-case, as
 are specified command arguments.  Upper case letters may be used in
 file names or user-chosen ID strings.
 </P>
 <P>Here is how each line in the input script is parsed by LAMMPS:
 </P>
 <P>(1) If the last printable character on the line is a "&" character
 (with no surrounding quotes), the command is assumed to continue on
 the next line.  The next line is concatenated to the previous line by
 removing the "&" character and newline.  This allows long commands to
 be continued across two or more lines.
 </P>
 <P>(2) All characters from the first "#" character onward are treated as
 comment and discarded.  See an exception in (6).  Note that a
 comment after a trailing "&" character will prevent the command from
 continuing on the next line.  Also note that for multi-line commands a
 single leading "#" will comment out the entire command.
 </P>
 <P>(3) The line is searched repeatedly for $ characters, which indicate
 variables that are replaced with a text string.  See an exception in
 (6).  If the $ is followed by curly brackets, then the variable name
 is the text inside the curly brackets.  If no curly brackets follow
 the $, then the variable name is the single character immediately
 following the $.  Thus ${myTemp} and $x refer to variable names
 "myTemp" and "x".  See the <A HREF = "variable.html">variable</A> command for
 details of how strings are assigned to variables and how they are
 substituted for in input script commands.
 </P>
 <P>(4) The line is broken into "words" separated by whitespace (tabs,
 spaces).  Note that words can thus contain letters, digits,
 underscores, or punctuation characters.
 </P>
 <P>(5) The first word is the command name.  All successive words in the
 line are arguments.
 </P>
 <P>(6) If you want text with spaces to be treated as a single argument,
 it can be enclosed in either double or single quotes.  E.g.
 </P>
 <PRE>print "Volume = $v"
 print 'Volume = $v' 
 </PRE>
 <P>The quotes are removed when the single argument is stored internally.
 See the <A HREF = "dump_modify.html">dump modify format</A> or <A HREF = "if.html">if</A> commands
 for examples.  A "#" or "$" character that is between quotes will not
 be treated as a comment indicator in (2) or substituted for as a
 variable in (3).
 </P>
 <P>IMPORTANT NOTE: If the argument is itself a command that requires a
 quoted argument (e.g. using a <A HREF = "print.html">print</A> command as part of an
 <A HREF = "if.html">if</A> or <A HREF = "run.html">run every</A> command), then the double and
 single quotes can be nested in the usual manner.  See the doc pages
 for those commands for examples.  Only one of level of nesting is
 allowed, but that should be sufficient for most use cases.
 </P>
 <HR>
 
 <H4><A NAME = "3_3"></A>3.3 Input script structure 
 </H4>
 <P>This section describes the structure of a typical LAMMPS input script.
 The "examples" directory in the LAMMPS distribution contains many
 sample input scripts; the corresponding problems are discussed in
 <A HREF = "Section_example.html">this section</A>, and animated on the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW
 Site</A>.
 </P>
 <P>A LAMMPS input script typically has 4 parts:
 </P>
 <OL><LI>Initialization
 <LI>Atom definition
 <LI>Settings
 <LI>Run a simulation 
 </OL>
 <P>The last 2 parts can be repeated as many times as desired.  I.e. run a
 simulation, change some settings, run some more, etc.  Each of the 4
 parts is now described in more detail.  Remember that almost all the
 commands need only be used if a non-default value is desired.
 </P>
 <P>(1) Initialization
 </P>
 <P>Set parameters that need to be defined before atoms are created or
 read-in from a file.
 </P>
 <P>The relevant commands are <A HREF = "units.html">units</A>,
 <A HREF = "dimension.html">dimension</A>, <A HREF = "newton.html">newton</A>,
 <A HREF = "processors.html">processors</A>, <A HREF = "boundary.html">boundary</A>,
 <A HREF = "atom_style.html">atom_style</A>, <A HREF = "atom_modify.html">atom_modify</A>.
 </P>
 <P>If force-field parameters appear in the files that will be read, these
 commands tell LAMMPS what kinds of force fields are being used:
 <A HREF = "pair_style.html">pair_style</A>, <A HREF = "bond_style.html">bond_style</A>,
 <A HREF = "angle_style.html">angle_style</A>, <A HREF = "dihedral_style.html">dihedral_style</A>,
 <A HREF = "improper_style.html">improper_style</A>.
 </P>
 <P>(2) Atom definition
 </P>
 <P>There are 3 ways to define atoms in LAMMPS.  Read them in from a data
 or restart file via the <A HREF = "read_data.html">read_data</A> or
 <A HREF = "read_restart.html">read_restart</A> commands.  These files can contain
 molecular topology information.  Or create atoms on a lattice (with no
 molecular topology), using these commands: <A HREF = "lattice.html">lattice</A>,
 <A HREF = "region.html">region</A>, <A HREF = "create_box.html">create_box</A>,
 <A HREF = "create_atoms.html">create_atoms</A>.  The entire set of atoms can be
 duplicated to make a larger simulation using the
 <A HREF = "replicate.html">replicate</A> command.
 </P>
 <P>(3) Settings
 </P>
 <P>Once atoms and molecular topology are defined, a variety of settings
 can be specified: force field coefficients, simulation parameters,
 output options, etc.
 </P>
 <P>Force field coefficients are set by these commands (they can also be
 set in the read-in files): <A HREF = "pair_coeff.html">pair_coeff</A>,
 <A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "angle_coeff.html">angle_coeff</A>,
 <A HREF = "dihedral_coeff.html">dihedral_coeff</A>,
 <A HREF = "improper_coeff.html">improper_coeff</A>,
 <A HREF = "kspace_style.html">kspace_style</A>, <A HREF = "dielectric.html">dielectric</A>,
 <A HREF = "special_bonds.html">special_bonds</A>.
 </P>
 <P>Various simulation parameters are set by these commands:
 <A HREF = "neighbor.html">neighbor</A>, <A HREF = "neigh_modify.html">neigh_modify</A>,
 <A HREF = "group.html">group</A>, <A HREF = "timestep.html">timestep</A>,
 <A HREF = "reset_timestep.html">reset_timestep</A>, <A HREF = "run_style.html">run_style</A>,
 <A HREF = "min_style.html">min_style</A>, <A HREF = "min_modify.html">min_modify</A>.
 </P>
 <P>Fixes impose a variety of boundary conditions, time integration, and
 diagnostic options.  The <A HREF = "fix.html">fix</A> command comes in many flavors.
 </P>
 <P>Various computations can be specified for execution during a
 simulation using the <A HREF = "compute.html">compute</A>,
 <A HREF = "compute_modify.html">compute_modify</A>, and <A HREF = "variable.html">variable</A>
 commands.
 </P>
 <P>Output options are set by the <A HREF = "thermo.html">thermo</A>, <A HREF = "dump.html">dump</A>,
 and <A HREF = "restart.html">restart</A> commands.
 </P>
 <P>(4) Run a simulation
 </P>
 <P>A molecular dynamics simulation is run using the <A HREF = "run.html">run</A>
 command.  Energy minimization (molecular statics) is performed using
 the <A HREF = "minimize.html">minimize</A> command.  A parallel tempering
 (replica-exchange) simulation can be run using the
 <A HREF = "temper.html">temper</A> command.
 </P>
 <HR>
 
 <A NAME = "3_4"></A><H4>3.4 Commands listed by category 
 </H4>
 <P>This section lists all LAMMPS commands, grouped by category.  The
 <A HREF = "#3_5">next section</A> lists the same commands alphabetically.  Note that
 some style options for some commands are part of specific LAMMPS
 packages, which means they cannot be used unless the package was
 included when LAMMPS was built.  Not all packages are included in a
 default LAMMPS build.  These dependencies are listed as Restrictions
 in the command's documentation.
 </P>
 <P>Initialization:
 </P>
 <P><A HREF = "atom_modify.html">atom_modify</A>, <A HREF = "atom_style.html">atom_style</A>,
 <A HREF = "boundary.html">boundary</A>, <A HREF = "dimension.html">dimension</A>,
 <A HREF = "newton.html">newton</A>, <A HREF = "processors.html">processors</A>, <A HREF = "units.html">units</A>
 </P>
 <P>Atom definition:
 </P>
 <P><A HREF = "create_atoms.html">create_atoms</A>, <A HREF = "create_box.html">create_box</A>,
 <A HREF = "lattice.html">lattice</A>, <A HREF = "read_data.html">read_data</A>,
 <A HREF = "read_restart.html">read_restart</A>, <A HREF = "region.html">region</A>,
 <A HREF = "replicate.html">replicate</A>
 </P>
 <P>Force fields:
 </P>
 <P><A HREF = "angle_coeff.html">angle_coeff</A>, <A HREF = "angle_style.html">angle_style</A>,
 <A HREF = "bond_coeff.html">bond_coeff</A>, <A HREF = "bond_style.html">bond_style</A>,
 <A HREF = "dielectric.html">dielectric</A>, <A HREF = "dihedral_coeff.html">dihedral_coeff</A>,
 <A HREF = "dihedral_style.html">dihedral_style</A>,
 <A HREF = "improper_coeff.html">improper_coeff</A>,
 <A HREF = "improper_style.html">improper_style</A>,
 <A HREF = "kspace_modify.html">kspace_modify</A>, <A HREF = "kspace_style.html">kspace_style</A>,
 <A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "pair_modify.html">pair_modify</A>,
 <A HREF = "pair_style.html">pair_style</A>, <A HREF = "pair_write.html">pair_write</A>,
 <A HREF = "special_bonds.html">special_bonds</A>
 </P>
 <P>Settings:
 </P>
 <P><A HREF = "communicate.html">communicate</A>, <A HREF = "dipole.html">dipole</A>,
 <A HREF = "group.html">group</A>, <A HREF = "mass.html">mass</A>, <A HREF = "min_modify.html">min_modify</A>,
 <A HREF = "min_style.html">min_style</A>, <A HREF = "neigh_modify.html">neigh_modify</A>,
 <A HREF = "neighbor.html">neighbor</A>, <A HREF = "reset_timestep.html">reset_timestep</A>,
 <A HREF = "run_style.html">run_style</A>, <A HREF = "set.html">set</A>, <A HREF = "shape.html">shape</A>,
 <A HREF = "timestep.html">timestep</A>, <A HREF = "velocity.html">velocity</A>
 </P>
 <P>Fixes:
 </P>
 <P><A HREF = "fix.html">fix</A>, <A HREF = "fix_modify.html">fix_modify</A>, <A HREF = "unfix.html">unfix</A>
 </P>
 <P>Computes:
 </P>
 <P><A HREF = "compute.html">compute</A>, <A HREF = "compute_modify.html">compute_modify</A>,
 <A HREF = "uncompute.html">uncompute</A>
 </P>
 <P>Output:
 </P>
 <P><A HREF = "dump.html">dump</A>, <A HREF = "dump_modify.html">dump_modify</A>,
 <A HREF = "restart.html">restart</A>, <A HREF = "thermo.html">thermo</A>,
 <A HREF = "thermo_modify.html">thermo_modify</A>, <A HREF = "thermo_style.html">thermo_style</A>,
 <A HREF = "undump.html">undump</A>, <A HREF = "write_restart.html">write_restart</A>
 </P>
 <P>Actions:
 </P>
 <P><A HREF = "delete_atoms.html">delete_atoms</A>, <A HREF = "delete_bonds.html">delete_bonds</A>,
 <A HREF = "displace_atoms.html">displace_atoms</A>,
 <A HREF = "displace_box.html">displace_box</A>, <A HREF = "minimize.html">minimize</A>,
 <A HREF = "neb.html">neb</A> <A HREF = "prd.html">prd</A>, <A HREF = "run.html">run</A>, <A HREF = "temper.html">temper</A>
 </P>
 <P>Miscellaneous:
 </P>
 <P><A HREF = "clear.html">clear</A>, <A HREF = "echo.html">echo</A>, <A HREF = "if.html">if</A>,
 <A HREF = "include.html">include</A>, <A HREF = "jump.html">jump</A>, <A HREF = "label.html">label</A>,
 <A HREF = "log.html">log</A>, <A HREF = "next.html">next</A>, <A HREF = "print.html">print</A>,
 <A HREF = "shell.html">shell</A>, <A HREF = "variable.html">variable</A>
 </P>
 <HR>
 
 <H4><A NAME = "3_5"></A><A NAME = "comm"></A>3.5 Individual commands 
 </H4>
 <P>This section lists all LAMMPS commands alphabetically, with a separate
 listing below of styles within certain commands.  The <A HREF = "#3_4">previous
 section</A> lists the same commands, grouped by category.  Note that
 some style options for some commands are part of specific LAMMPS
 packages, which means they cannot be used unless the package was
 included when LAMMPS was built.  Not all packages are included in a
 default LAMMPS build.  These dependencies are listed as Restrictions
 in the command's documentation.
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD ><A HREF = "angle_coeff.html">angle_coeff</A></TD><TD ><A HREF = "angle_style.html">angle_style</A></TD><TD ><A HREF = "atom_modify.html">atom_modify</A></TD><TD ><A HREF = "atom_style.html">atom_style</A></TD><TD ><A HREF = "bond_coeff.html">bond_coeff</A></TD><TD ><A HREF = "bond_style.html">bond_style</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "boundary.html">boundary</A></TD><TD ><A HREF = "change_box.html">change_box</A></TD><TD ><A HREF = "clear.html">clear</A></TD><TD ><A HREF = "communicate.html">communicate</A></TD><TD ><A HREF = "compute.html">compute</A></TD><TD ><A HREF = "compute_modify.html">compute_modify</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "create_atoms.html">create_atoms</A></TD><TD ><A HREF = "create_box.html">create_box</A></TD><TD ><A HREF = "delete_atoms.html">delete_atoms</A></TD><TD ><A HREF = "delete_bonds.html">delete_bonds</A></TD><TD ><A HREF = "dielectric.html">dielectric</A></TD><TD ><A HREF = "dihedral_coeff.html">dihedral_coeff</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "dihedral_style.html">dihedral_style</A></TD><TD ><A HREF = "dimension.html">dimension</A></TD><TD ><A HREF = "dipole.html">dipole</A></TD><TD ><A HREF = "displace_atoms.html">displace_atoms</A></TD><TD ><A HREF = "displace_box.html">displace_box</A></TD><TD ><A HREF = "dump.html">dump</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "dump_modify.html">dump_modify</A></TD><TD ><A HREF = "echo.html">echo</A></TD><TD ><A HREF = "fix.html">fix</A></TD><TD ><A HREF = "fix_modify.html">fix_modify</A></TD><TD ><A HREF = "group.html">group</A></TD><TD ><A HREF = "if.html">if</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "improper_coeff.html">improper_coeff</A></TD><TD ><A HREF = "improper_style.html">improper_style</A></TD><TD ><A HREF = "include.html">include</A></TD><TD ><A HREF = "jump.html">jump</A></TD><TD ><A HREF = "kspace_modify.html">kspace_modify</A></TD><TD ><A HREF = "kspace_style.html">kspace_style</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "label.html">label</A></TD><TD ><A HREF = "lattice.html">lattice</A></TD><TD ><A HREF = "log.html">log</A></TD><TD ><A HREF = "mass.html">mass</A></TD><TD ><A HREF = "minimize.html">minimize</A></TD><TD ><A HREF = "min_modify.html">min_modify</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "min_style.html">min_style</A></TD><TD ><A HREF = "neb.html">neb</A></TD><TD ><A HREF = "neigh_modify.html">neigh_modify</A></TD><TD ><A HREF = "neighbor.html">neighbor</A></TD><TD ><A HREF = "newton.html">newton</A></TD><TD ><A HREF = "next.html">next</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_coeff.html">pair_coeff</A></TD><TD ><A HREF = "pair_modify.html">pair_modify</A></TD><TD ><A HREF = "pair_style.html">pair_style</A></TD><TD ><A HREF = "pair_write.html">pair_write</A></TD><TD ><A HREF = "prd.html">prd</A></TD><TD ><A HREF = "print.html">print</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "processors.html">processors</A></TD><TD ><A HREF = "read_data.html">read_data</A></TD><TD ><A HREF = "read_restart.html">read_restart</A></TD><TD ><A HREF = "region.html">region</A></TD><TD ><A HREF = "replicate.html">replicate</A></TD><TD ><A HREF = "reset_timestep.html">reset_timestep</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "restart.html">restart</A></TD><TD ><A HREF = "run.html">run</A></TD><TD ><A HREF = "run_style.html">run_style</A></TD><TD ><A HREF = "set.html">set</A></TD><TD ><A HREF = "shape.html">shape</A></TD><TD ><A HREF = "shell.html">shell</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "special_bonds.html">special_bonds</A></TD><TD ><A HREF = "temper.html">temper</A></TD><TD ><A HREF = "thermo.html">thermo</A></TD><TD ><A HREF = "thermo_modify.html">thermo_modify</A></TD><TD ><A HREF = "thermo_style.html">thermo_style</A></TD><TD ><A HREF = "timestep.html">timestep</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "uncompute.html">uncompute</A></TD><TD ><A HREF = "undump.html">undump</A></TD><TD ><A HREF = "unfix.html">unfix</A></TD><TD ><A HREF = "units.html">units</A></TD><TD ><A HREF = "variable.html">variable</A></TD><TD ><A HREF = "velocity.html">velocity</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "write_restart.html">write_restart</A> 
+<TR ALIGN="center"><TD ><A HREF = "special_bonds.html">special_bonds</A></TD><TD ><A HREF = "tad.html">tad</A></TD><TD ><A HREF = "temper.html">temper</A></TD><TD ><A HREF = "thermo.html">thermo</A></TD><TD ><A HREF = "thermo_modify.html">thermo_modify</A></TD><TD ><A HREF = "thermo_style.html">thermo_style</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "timestep.html">timestep</A></TD><TD ><A HREF = "uncompute.html">uncompute</A></TD><TD ><A HREF = "undump.html">undump</A></TD><TD ><A HREF = "unfix.html">unfix</A></TD><TD ><A HREF = "units.html">units</A></TD><TD ><A HREF = "variable.html">variable</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "velocity.html">velocity</A></TD><TD ><A HREF = "write_restart.html">write_restart</A> 
 </TD></TR></TABLE></DIV>
 
 <HR>
 
 <H4>Fix styles 
 </H4>
 <P>See the <A HREF = "fix.html">fix</A> command for one-line descriptions
 of each style or click on the style itself for a full description:
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD ><A HREF = "fix_adapt.html">adapt</A></TD><TD ><A HREF = "fix_addforce.html">addforce</A></TD><TD ><A HREF = "fix_aveforce.html">aveforce</A></TD><TD ><A HREF = "fix_ave_atom.html">ave/atom</A></TD><TD ><A HREF = "fix_ave_correlate.html">ave/correlate</A></TD><TD ><A HREF = "fix_ave_histo.html">ave/histo</A></TD><TD ><A HREF = "fix_ave_spatial.html">ave/spatial</A></TD><TD ><A HREF = "fix_ave_time.html">ave/time</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "fix_bond_break.html">bond/break</A></TD><TD ><A HREF = "fix_bond_create.html">bond/create</A></TD><TD ><A HREF = "fix_bond_swap.html">bond/swap</A></TD><TD ><A HREF = "fix_box_relax.html">box/relax</A></TD><TD ><A HREF = "fix_deform.html">deform</A></TD><TD ><A HREF = "fix_deposit.html">deposit</A></TD><TD ><A HREF = "fix_drag.html">drag</A></TD><TD ><A HREF = "fix_dt_reset.html">dt/reset</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "fix_efield.html">efield</A></TD><TD ><A HREF = "fix_enforce2d.html">enforce2d</A></TD><TD ><A HREF = "fix_evaporate.html">evaporate</A></TD><TD ><A HREF = "fix_external.html">external</A></TD><TD ><A HREF = "fix_freeze.html">freeze</A></TD><TD ><A HREF = "fix_gravity.html">gravity</A></TD><TD ><A HREF = "fix_heat.html">heat</A></TD><TD ><A HREF = "fix_indent.html">indent</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "fix_langevin.html">langevin</A></TD><TD ><A HREF = "fix_lineforce.html">lineforce</A></TD><TD ><A HREF = "fix_momentum.html">momentum</A></TD><TD ><A HREF = "fix_move.html">move</A></TD><TD ><A HREF = "fix_msst.html">msst</A></TD><TD ><A HREF = "fix_neb.html">neb</A></TD><TD ><A HREF = "fix_nh.html">nph</A></TD><TD ><A HREF = "fix_nph_asphere.html">nph/asphere</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "fix_nph_sphere.html">nph/sphere</A></TD><TD ><A HREF = "fix_nh.html">npt</A></TD><TD ><A HREF = "fix_npt_asphere.html">npt/asphere</A></TD><TD ><A HREF = "fix_npt_sphere.html">npt/sphere</A></TD><TD ><A HREF = "fix_nve.html">nve</A></TD><TD ><A HREF = "fix_nve_asphere.html">nve/asphere</A></TD><TD ><A HREF = "fix_nve_limit.html">nve/limit</A></TD><TD ><A HREF = "fix_nve_noforce.html">nve/noforce</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "fix_nve_sphere.html">nve/sphere</A></TD><TD ><A HREF = "fix_nh.html">nvt</A></TD><TD ><A HREF = "fix_nvt_asphere.html">nvt/asphere</A></TD><TD ><A HREF = "fix_nvt_sllod.html">nvt/sllod</A></TD><TD ><A HREF = "fix_nvt_sphere.html">nvt/sphere</A></TD><TD ><A HREF = "fix_orient_fcc.html">orient/fcc</A></TD><TD ><A HREF = "fix_planeforce.html">planeforce</A></TD><TD ><A HREF = "fix_poems.html">poems</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "fix_pour.html">pour</A></TD><TD ><A HREF = "fix_press_berendsen.html">press/berendsen</A></TD><TD ><A HREF = "fix_print.html">print</A></TD><TD ><A HREF = "fix_qeq_comb.html">qeq/comb</A></TD><TD ><A HREF = "fix_reax_bonds.html">reax/bonds</A></TD><TD ><A HREF = "fix_recenter.html">recenter</A></TD><TD ><A HREF = "fix_rigid.html">rigid</A></TD><TD ><A HREF = "fix_rigid.html">rigid/nve</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "fix_rigid.html">rigid/nvt</A></TD><TD ><A HREF = "fix_setforce.html">setforce</A></TD><TD ><A HREF = "fix_shake.html">shake</A></TD><TD ><A HREF = "fix_spring.html">spring</A></TD><TD ><A HREF = "fix_spring_rg.html">spring/rg</A></TD><TD ><A HREF = "fix_spring_self.html">spring/self</A></TD><TD ><A HREF = "fix_srd.html">srd</A></TD><TD ><A HREF = "fix_store_force.html">store/force</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "fix_store_state.html">store/state</A></TD><TD ><A HREF = "fix_temp_berendsen.html">temp/berendsen</A></TD><TD ><A HREF = "fix_temp_rescale.html">temp/rescale</A></TD><TD ><A HREF = "fix_thermal_conductivity.html">thermal/conductivity</A></TD><TD ><A HREF = "fix_tmd.html">tmd</A></TD><TD ><A HREF = "fix_ttm.html">ttm</A></TD><TD ><A HREF = "fix_viscosity.html">viscosity</A></TD><TD ><A HREF = "fix_viscous.html">viscous</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "fix_wall.html">wall/colloid</A></TD><TD ><A HREF = "fix_wall_gran.html">wall/gran</A></TD><TD ><A HREF = "fix_wall.html">wall/harmonic</A></TD><TD ><A HREF = "fix_wall.html">wall/lj126</A></TD><TD ><A HREF = "fix_wall.html">wall/lj93</A></TD><TD ><A HREF = "fix_wall_reflect.html">wall/reflect</A></TD><TD ><A HREF = "fix_wall_region.html">wall/region</A></TD><TD ><A HREF = "fix_wall_srd.html">wall/srd</A> 
 </TD></TR></TABLE></DIV>
 
 <P>These are fix styles contributed by users, which can be used if
 <A HREF = "Section_start.html#2_3">LAMMPS is built with the appropriate package</A>.
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD ><A HREF = "fix_atc.html">atc</A></TD><TD ><A HREF = "fix_imd.html">imd</A></TD><TD ><A HREF = "fix_langevin_eff.html">langevin/eff</A></TD><TD ><A HREF = "fix_nh_eff.html">nph/eff</A></TD><TD ><A HREF = "fix_nh_eff.html">npt/eff</A></TD><TD ><A HREF = "fix_nve_eff.html">nve/eff</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "fix_nh_eff.html">nvt/eff</A></TD><TD ><A HREF = "fix_nvt_sllod_eff.html">nvt/sllod/eff</A></TD><TD ><A HREF = "fix_qeq_reax.html">qeq/reax</A></TD><TD ><A HREF = "fix_smd.html">smd</A></TD><TD ><A HREF = "fix_temp_rescale_eff.html">temp/rescale/eff</A> 
 </TD></TR></TABLE></DIV>
 
 <HR>
 
 <H4>Compute styles 
 </H4>
 <P>See the <A HREF = "compute.html">compute</A> command for one-line descriptions of
 each style or click on the style itself for a full description:
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD ><A HREF = "compute_angle_local.html">angle/local</A></TD><TD ><A HREF = "compute_atom_molecule.html">atom/molecule</A></TD><TD ><A HREF = "compute_bond_local.html">bond/local</A></TD><TD ><A HREF = "compute_centro_atom.html">centro/atom</A></TD><TD ><A HREF = "compute_cna_atom.html">cna/atom</A></TD><TD ><A HREF = "compute_com.html">com</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "compute_com_molecule.html">com/molecule</A></TD><TD ><A HREF = "compute_coord_atom.html">coord/atom</A></TD><TD ><A HREF = "compute_damage_atom.html">damage/atom</A></TD><TD ><A HREF = "compute_dihedral_local.html">dihedral/local</A></TD><TD ><A HREF = "compute_displace_atom.html">displace/atom</A></TD><TD ><A HREF = "compute_erotate_asphere.html">erotate/asphere</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "compute_erotate_sphere.html">erotate/sphere</A></TD><TD ><A HREF = "compute_event_displace.html">event/displace</A></TD><TD ><A HREF = "compute_group_group.html">group/group</A></TD><TD ><A HREF = "compute_gyration.html">gyration</A></TD><TD ><A HREF = "compute_gyration_molecule.html">gyration/molecule</A></TD><TD ><A HREF = "compute_heat_flux.html">heat/flux</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "compute_improper_local.html">improper/local</A></TD><TD ><A HREF = "compute_ke.html">ke</A></TD><TD ><A HREF = "compute_ke_atom.html">ke/atom</A></TD><TD ><A HREF = "compute_msd.html">msd</A></TD><TD ><A HREF = "compute_msd_molecule.html">msd/molecule</A></TD><TD ><A HREF = "compute_pair.html">pair</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "compute_pair_local.html">pair/local</A></TD><TD ><A HREF = "compute_pe.html">pe</A></TD><TD ><A HREF = "compute_pe_atom.html">pe/atom</A></TD><TD ><A HREF = "compute_pressure.html">pressure</A></TD><TD ><A HREF = "compute_property_atom.html">property/atom</A></TD><TD ><A HREF = "compute_property_local.html">property/local</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "compute_property_molecule.html">property/molecule</A></TD><TD ><A HREF = "compute_rdf.html">rdf</A></TD><TD ><A HREF = "compute_reduce.html">reduce</A></TD><TD ><A HREF = "compute_reduce.html">reduce/region</A></TD><TD ><A HREF = "compute_stress_atom.html">stress/atom</A></TD><TD ><A HREF = "compute_temp.html">temp</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "compute_temp_asphere.html">temp/asphere</A></TD><TD ><A HREF = "compute_temp_com.html">temp/com</A></TD><TD ><A HREF = "compute_temp_deform.html">temp/deform</A></TD><TD ><A HREF = "compute_temp_partial.html">temp/partial</A></TD><TD ><A HREF = "compute_temp_profile.html">temp/profile</A></TD><TD ><A HREF = "compute_temp_ramp.html">temp/ramp</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "compute_temp_region.html">temp/region</A></TD><TD ><A HREF = "compute_temp_sphere.html">temp/sphere</A></TD><TD ><A HREF = "compute_ti.html">ti</A> 
 </TD></TR></TABLE></DIV>
 
 <P>These are compute styles contributed by users, which can be used if
 <A HREF = "Section_start.html#2_3">LAMMPS is built with the appropriate package</A>.
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD ><A HREF = "compute_ackland_atom.html">ackland/atom</A></TD><TD ><A HREF = "compute_ke_eff.html">ke/eff</A></TD><TD ><A HREF = "compute_ke_atom_eff.html">ke/atom/eff</A></TD><TD ><A HREF = "compute_temp_eff.html">temp/eff</A></TD><TD ><A HREF = "compute_temp_deform_eff.html">temp/deform/eff</A></TD><TD ><A HREF = "compute_temp_region_eff.html">temp/region/eff</A> 
 </TD></TR></TABLE></DIV>
 
 <HR>
 
 <H4>Pair_style potentials 
 </H4>
 <P>See the <A HREF = "pair_style.html">pair_style</A> command for an overview of pair
 potentials.  Click on the style itself for a full description:
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD ><A HREF = "pair_none.html">none</A></TD><TD ><A HREF = "pair_hybrid.html">hybrid</A></TD><TD ><A HREF = "pair_hybrid.html">hybrid/overlay</A></TD><TD ><A HREF = "pair_airebo.html">airebo</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_born.html">born</A></TD><TD ><A HREF = "pair_born.html">born/coul/long</A></TD><TD ><A HREF = "pair_buck.html">buck</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/cut</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_buck.html">buck/coul/long</A></TD><TD ><A HREF = "pair_colloid.html">colloid</A></TD><TD ><A HREF = "pair_comb.html">comb</A></TD><TD ><A HREF = "pair_coul.html">coul/cut</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/debye</A></TD><TD ><A HREF = "pair_coul.html">coul/long</A></TD><TD ><A HREF = "pair_dipole.html">dipole/cut</A></TD><TD ><A HREF = "pair_dpd.html">dpd</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_dpd.html">dpd/tstat</A></TD><TD ><A HREF = "pair_dsmc.html">dsmc</A></TD><TD ><A HREF = "pair_eam.html">eam</A></TD><TD ><A HREF = "pair_eam.html">eam/opt</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/alloy</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy/opt</A></TD><TD ><A HREF = "pair_eam.html">eam/fs</A></TD><TD ><A HREF = "pair_eam.html">eam/fs/opt</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_eim.html">eim</A></TD><TD ><A HREF = "pair_gauss.html">gauss</A></TD><TD ><A HREF = "pair_gayberne.html">gayberne</A></TD><TD ><A HREF = "pair_gayberne.html">gayberne/gpu</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_gran.html">gran/hertz/history</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke/history</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/lj</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/morse</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/implicit</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/opt</A></TD><TD ><A HREF = "pair_class2.html">lj/class2</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/long</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/gpu</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/opt</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut/gpu</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/debye</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/gpu</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/tip4p</A></TD><TD ><A HREF = "pair_lj_expand.html">lj/expand</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_lj_smooth.html">lj/smooth</A></TD><TD ><A HREF = "pair_lj96_cut.html">lj96/cut</A></TD><TD ><A HREF = "pair_lj96_cut.html">lj96/cut/gpu</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_meam.html">meam</A></TD><TD ><A HREF = "pair_morse.html">morse</A></TD><TD ><A HREF = "pair_morse.html">morse/opt</A></TD><TD ><A HREF = "pair_peri.html">peri/lps</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_peri.html">peri/pmb</A></TD><TD ><A HREF = "pair_reax.html">reax</A></TD><TD ><A HREF = "pair_resquared.html">resquared</A></TD><TD ><A HREF = "pair_soft.html">soft</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_sw.html">sw</A></TD><TD ><A HREF = "pair_table.html">table</A></TD><TD ><A HREF = "pair_tersoff.html">tersoff</A></TD><TD ><A HREF = "pair_tersoff_zbl.html">tersoff/zbl</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_yukawa.html">yukawa</A></TD><TD ><A HREF = "pair_yukawa_colloid.html">yukawa/colloid</A> 
 </TD></TR></TABLE></DIV>
 
 <P>These are pair styles contributed by users, which can be used if
 <A HREF = "Section_start.html#2_3">LAMMPS is built with the appropriate package</A>.
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD ><A HREF = "pair_buck_coul.html">buck/coul</A></TD><TD ><A HREF = "pair_cmm.html">cg/cmm</A></TD><TD ><A HREF = "pair_cmm.html">cg/cmm/gpu</A></TD><TD ><A HREF = "pair_cmm.html">cg/cmm/coul/cut</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_cmm.html">cg/cmm/coul/long</A></TD><TD ><A HREF = "pair_cmm.html">cg/cmm/coul/long/gpu</A></TD><TD ><A HREF = "pair_eam.html">eam/cd</A></TD><TD ><A HREF = "pair_eff.html">eff/cut</A></TD></TR>
 <TR ALIGN="center"><TD ><A HREF = "pair_lj_coul.html">lj/coul</A></TD><TD ><A HREF = "pair_reax_c.html">reax/c</A> 
 </TD></TR></TABLE></DIV>
 
 <HR>
 
 <H4>Bond_style potentials 
 </H4>
 <P>See the <A HREF = "bond_style.html">bond_style</A> command for an overview of bond
 potentials.  Click on the style itself for a full description:
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_none.html">none</A></TD><TD WIDTH="100"><A HREF = "bond_hybrid.html">hybrid</A></TD><TD WIDTH="100"><A HREF = "bond_class2.html">class2</A></TD><TD WIDTH="100"><A HREF = "bond_fene.html">fene</A></TD></TR>
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_fene_expand.html">fene/expand</A></TD><TD WIDTH="100"><A HREF = "bond_harmonic.html">harmonic</A></TD><TD WIDTH="100"><A HREF = "bond_morse.html">morse</A></TD><TD WIDTH="100"><A HREF = "bond_nonlinear.html">nonlinear</A></TD></TR>
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_quartic.html">quartic</A></TD><TD WIDTH="100"><A HREF = "bond_table.html">table</A> 
 </TD></TR></TABLE></DIV>
 
 <HR>
 
 <H4>Angle_style potentials 
 </H4>
 <P>See the <A HREF = "angle_style.html">angle_style</A> command for an overview of
 angle potentials.  Click on the style itself for a full description:
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_none.html">none</A></TD><TD WIDTH="100"><A HREF = "angle_hybrid.html">hybrid</A></TD><TD WIDTH="100"><A HREF = "angle_charmm.html">charmm</A></TD><TD WIDTH="100"><A HREF = "angle_class2.html">class2</A></TD></TR>
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_cosine.html">cosine</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_delta.html">cosine/delta</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_periodic.html">cosine/periodic</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_squared.html">cosine/squared</A></TD></TR>
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_harmonic.html">harmonic</A></TD><TD WIDTH="100"><A HREF = "angle_table.html">table</A> 
 </TD></TR></TABLE></DIV>
 
 <P>These are angle styles contributed by users, which can be used if
 <A HREF = "Section_start.html#2_3">LAMMPS is built with the appropriate package</A>.
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD ><A HREF = "angle_cmm.html">cg/cmm</A> 
 </TD></TR></TABLE></DIV>
 
 <HR>
 
 <H4>Dihedral_style potentials 
 </H4>
 <P>See the <A HREF = "dihedral_style.html">dihedral_style</A> command for an overview
 of dihedral potentials.  Click on the style itself for a full
 description:
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "dihedral_none.html">none</A></TD><TD WIDTH="100"><A HREF = "dihedral_hybrid.html">hybrid</A></TD><TD WIDTH="100"><A HREF = "dihedral_charmm.html">charmm</A></TD><TD WIDTH="100"><A HREF = "dihedral_class2.html">class2</A></TD></TR>
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "dihedral_harmonic.html">harmonic</A></TD><TD WIDTH="100"><A HREF = "dihedral_helix.html">helix</A></TD><TD WIDTH="100"><A HREF = "dihedral_multi_harmonic.html">multi/harmonic</A></TD><TD WIDTH="100"><A HREF = "dihedral_opls.html">opls</A> 
 </TD></TR></TABLE></DIV>
 
 <HR>
 
 <H4>Improper_style potentials 
 </H4>
 <P>See the <A HREF = "improper_style.html">improper_style</A> command for an overview
 of improper potentials.  Click on the style itself for a full
 description:
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "improper_none.html">none</A></TD><TD WIDTH="100"><A HREF = "improper_hybrid.html">hybrid</A></TD><TD WIDTH="100"><A HREF = "improper_class2.html">class2</A></TD><TD WIDTH="100"><A HREF = "improper_cvff.html">cvff</A></TD></TR>
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "improper_harmonic.html">harmonic</A></TD><TD WIDTH="100"><A HREF = "improper_umbrella.html">umbrella</A> 
 </TD></TR></TABLE></DIV>
 
 <HR>
 
 <H4>Kspace solvers 
 </H4>
 <P>See the <A HREF = "kspace_style.html">kspace_style</A> command for an overview of
 Kspace solvers.  Click on the style itself for a full description:
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "kspace_style.html">ewald</A></TD><TD WIDTH="100"><A HREF = "kspace_style.html">pppm</A></TD><TD WIDTH="100"><A HREF = "kspace_style.html">pppm/tip4p</A> 
 </TD></TR></TABLE></DIV>
 
 <P>These are Kspace solvers contributed by users, which can be used if
 <A HREF = "Section_start.html#2_3">LAMMPS is built with the appropriate package</A>.
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR ALIGN="center"><TD WIDTH="100"><A HREF = "kspace_style.html">ewald/n</A> 
 </TD></TR></TABLE></DIV>
 
 </HTML>
diff --git a/doc/Section_howto.html b/doc/Section_howto.html
index 0b92fc19a..4bc3da2a8 100644
--- a/doc/Section_howto.html
+++ b/doc/Section_howto.html
@@ -1,1940 +1,1940 @@
 <HTML>
 <CENTER><A HREF = "Section_commands.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_example.html">Next Section</A> 
 </CENTER>
 
 
 
 
 
 
 <HR>
 
 <H3>4. How-to discussions 
 </H3>
 <P>The following sections describe how to use various options within
 LAMMPS.
 </P>
 4.1 <A HREF = "#4_1">Restarting a simulation</A><BR>
 4.2 <A HREF = "#4_2">2d simulations</A><BR>
 4.3 <A HREF = "#4_3">CHARMM, AMBER, and DREIDING force fields</A><BR>
 4.4 <A HREF = "#4_4">Running multiple simulations from one input script</A><BR>
 4.5 <A HREF = "#4_5">Multi-replica simulations</A><BR>
 4.6 <A HREF = "#4_6">Granular models</A><BR>
 4.7 <A HREF = "#4_7">TIP3P water model</A><BR>
 4.8 <A HREF = "#4_8">TIP4P water model</A><BR>
 4.9 <A HREF = "#4_9">SPC water model</A><BR>
 4.10 <A HREF = "#4_10">Coupling LAMMPS to other codes</A><BR>
 4.11 <A HREF = "#4_11">Visualizing LAMMPS snapshots</A><BR>
 4.12 <A HREF = "#4_12">Triclinic (non-orthogonal) simulation boxes</A><BR>
 4.13 <A HREF = "#4_13">NEMD simulations</A><BR>
 4.14 <A HREF = "#4_14">Extended spherical and aspherical particles</A><BR>
 4.15 <A HREF = "#4_15">Output from LAMMPS (thermo, dumps, computes, fixes, variables)</A><BR>
 4.16 <A HREF = "#4_16">Thermostatting, barostatting and computing temperature</A><BR>
 4.17 <A HREF = "#4_17">Walls</A><BR>
 4.18 <A HREF = "#4_18">Elastic constants</A><BR>
 4.19 <A HREF = "#4_19">Library interface to LAMMPS</A><BR>
 4.20 <A HREF = "#4_20">Calculating thermal conductivity</A><BR>
 4.21 <A HREF = "#4_21">Calculating viscosity</A> <BR>
 
 <P>The example input scripts included in the LAMMPS distribution and
 highlighted in <A HREF = "Section_example.html">this section</A> also show how to
 setup and run various kinds of simulations.
 </P>
 <HR>
 
 <A NAME = "4_1"></A><H4>4.1 Restarting a simulation 
 </H4>
 <P>There are 3 ways to continue a long LAMMPS simulation.  Multiple
 <A HREF = "run.html">run</A> commands can be used in the same input script.  Each
 run will continue from where the previous run left off.  Or binary
 restart files can be saved to disk using the <A HREF = "restart.html">restart</A>
 command.  At a later time, these binary files can be read via a
 <A HREF = "read_restart.html">read_restart</A> command in a new script.  Or they can
 be converted to text data files and read by a
 <A HREF = "read_data.html">read_data</A> command in a new script.  <A HREF = "Section_tools.html">This
 section</A> discusses the <I>restart2data</I> tool that is
 used to perform the conversion.
 </P>
 <P>Here we give examples of 2 scripts that read either a binary restart
 file or a converted data file and then issue a new run command to
 continue where the previous run left off.  They illustrate what
 settings must be made in the new script.  Details are discussed in the
 documentation for the <A HREF = "read_restart.html">read_restart</A> and
 <A HREF = "read_data.html">read_data</A> commands.
 </P>
 <P>Look at the <I>in.chain</I> input script provided in the <I>bench</I> directory
 of the LAMMPS distribution to see the original script that these 2
 scripts are based on.  If that script had the line
 </P>
 <PRE>restart	        50 tmp.restart 
 </PRE>
 <P>added to it, it would produce 2 binary restart files (tmp.restart.50
 and tmp.restart.100) as it ran.
 </P>
 <P>This script could be used to read the 1st restart file and re-run the
 last 50 timesteps:
 </P>
 <PRE>read_restart	tmp.restart.50 
 </PRE>
 <PRE>neighbor	0.4 bin
 neigh_modify	every 1 delay 1 
 </PRE>
 <PRE>fix		1 all nve
 fix		2 all langevin 1.0 1.0 10.0 904297 
 </PRE>
 <PRE>timestep	0.012 
 </PRE>
 <PRE>run		50 
 </PRE>
 <P>Note that the following commands do not need to be repeated because
 their settings are included in the restart file: <I>units, atom_style,
 special_bonds, pair_style, bond_style</I>.  However these commands do
 need to be used, since their settings are not in the restart file:
 <I>neighbor, fix, timestep</I>.
 </P>
 <P>If you actually use this script to perform a restarted run, you will
 notice that the thermodynamic data match at step 50 (if you also put a
 "thermo 50" command in the original script), but do not match at step
 100.  This is because the <A HREF = "fix_langevin.html">fix langevin</A> command
 uses random numbers in a way that does not allow for perfect restarts.
 </P>
 <P>As an alternate approach, the restart file could be converted to a data
 file using this tool:
 </P>
 <PRE>restart2data tmp.restart.50 tmp.restart.data 
 </PRE>
 <P>Then, this script could be used to re-run the last 50 steps:
 </P>
 <PRE>units		lj
 atom_style	bond
 pair_style	lj/cut 1.12
 pair_modify	shift yes
 bond_style	fene
 special_bonds   0.0 1.0 1.0 
 </PRE>
 <PRE>read_data	tmp.restart.data 
 </PRE>
 <PRE>neighbor	0.4 bin
 neigh_modify	every 1 delay 1 
 </PRE>
 <PRE>fix		1 all nve
 fix		2 all langevin 1.0 1.0 10.0 904297 
 </PRE>
 <PRE>timestep	0.012 
 </PRE>
 <PRE>reset_timestep	50
 run		50 
 </PRE>
 <P>Note that nearly all the settings specified in the original <I>in.chain</I>
 script must be repeated, except the <I>pair_coeff</I> and <I>bond_coeff</I>
 commands since the new data file lists the force field coefficients.
 Also, the <A HREF = "reset_timestep.html">reset_timestep</A> command is used to tell
 LAMMPS the current timestep.  This value is stored in restart files,
 but not in data files.
 </P>
 <HR>
 
 <A NAME = "4_2"></A><H4>4.2 2d simulations 
 </H4>
 <P>Use the <A HREF = "dimension.html">dimension</A> command to specify a 2d simulation.
 </P>
 <P>Make the simulation box periodic in z via the <A HREF = "boundary.html">boundary</A>
 command.  This is the default.
 </P>
 <P>If using the <A HREF = "create_box.html">create box</A> command to define a
 simulation box, set the z dimensions narrow, but finite, so that the
 create_atoms command will tile the 3d simulation box with a single z
 plane of atoms - e.g.
 </P>
 <PRE><A HREF = "create_box.html">create box</A> 1 -10 10 -10 10 -0.25 0.25 
 </PRE>
 <P>If using the <A HREF = "read_data.html">read data</A> command to read in a file of
 atom coordinates, set the "zlo zhi" values to be finite but narrow,
 similar to the create_box command settings just described.  For each
 atom in the file, assign a z coordinate so it falls inside the
 z-boundaries of the box - e.g. 0.0.
 </P>
 <P>Use the <A HREF = "fix_enforce2d.html">fix enforce2d</A> command as the last
 defined fix to insure that the z-components of velocities and forces
 are zeroed out every timestep.  The reason to make it the last fix is
 so that any forces induced by other fixes will be zeroed out.
 </P>
 <P>Many of the example input scripts included in the LAMMPS distribution
 are for 2d models.
 </P>
 <P>IMPORTANT NOTE: Some models in LAMMPS treat particles as extended
 spheres, as opposed to point particles.  In 2d, the particles will
 still be spheres, not disks, meaning their moment of inertia will be
 the same as in 3d.
 </P>
 <HR>
 
 <A NAME = "4_3"></A><H4>4.3 CHARMM, AMBER, and DREIDING force fields 
 </H4>
 <P>A force field has 2 parts: the formulas that define it and the
 coefficients used for a particular system.  Here we only discuss
 formulas implemented in LAMMPS that correspond to formulas commonly
 used in the CHARMM, AMBER, and DREIDING force fields.  Setting
 coefficients is done in the input data file via the
 <A HREF = "read_data.html">read_data</A> command or in the input script with
 commands like <A HREF = "pair_coeff.html">pair_coeff</A> or
 <A HREF = "bond_coeff.html">bond_coeff</A>.  See <A HREF = "Section_tools.html">this section</A>
 for additional tools that can use CHARMM or AMBER to assign force
 field coefficients and convert their output into LAMMPS input.
 </P>
 <P>See <A HREF = "#MacKerell">(MacKerell)</A> for a description of the CHARMM force
 field.  See <A HREF = "#Cornell">(Cornell)</A> for a description of the AMBER force
 field.
 </P>
 
 
 
 
 <P>These style choices compute force field formulas that are consistent
 with common options in CHARMM or AMBER.  See each command's
 documentation for the formula it computes.
 </P>
 <UL><LI><A HREF = "bond_harmonic.html">bond_style</A> harmonic
 <LI><A HREF = "angle_charmm.html">angle_style</A> charmm
 <LI><A HREF = "dihedral_charmm.html">dihedral_style</A> charmm
 <LI><A HREF = "pair_charmm.html">pair_style</A> lj/charmm/coul/charmm
 <LI><A HREF = "pair_charmm.html">pair_style</A> lj/charmm/coul/charmm/implicit
 <LI><A HREF = "pair_charmm.html">pair_style</A> lj/charmm/coul/long 
 </UL>
 <UL><LI><A HREF = "special_bonds.html">special_bonds</A> charmm
 <LI><A HREF = "special_bonds.html">special_bonds</A> amber 
 </UL>
 <P>DREIDING is a generic force field developed by the <A HREF = "http://www.wag.caltech.edu">Goddard
 group</A> at Caltech and is useful for
 predicting structures and dynamics of organic, biological and
 main-group inorganic molecules. The philosophy in DREIDING is to use
 general force constants and geometry parameters based on simple
 hybridization considerations, rather than individual force constants
 and geometric parameters that depend on the particular combinations of
 atoms involved in the bond, angle, or torsion terms. DREIDING has an
 <A HREF = "pair_hbond_dreiding.html">explicit hydrogen bond term</A> to describe
 interactions involving a hydrogen atom on very electronegative atoms
 (N, O, F).
 </P>
 <P>See <A HREF = "#Mayo">(Mayo)</A> for a description of the DREIDING force field
 </P>
 <P>These style choices compute force field formulas that are consistent
 with the DREIDING force field.  See each command's
 documentation for the formula it computes.
 </P>
 <UL><LI><A HREF = "bond_harmonic.html">bond_style</A> harmonic
 <LI><A HREF = "bond_morse.html">bond_style</A> morse 
 </UL>
 <UL><LI><A HREF = "angle_harmonic.html">angle_style</A> harmonic
 <LI><A HREF = "angle_cosine.html">angle_style</A> cosine
 <LI><A HREF = "angle_cosine_periodic.html">angle_style</A> cosine/periodic 
 </UL>
 <UL><LI><A HREF = "dihedral_charmm.html">dihedral_style</A> charmm
 <LI><A HREF = "improper_umbrella.html">improper_style</A> umbrella 
 </UL>
 <UL><LI><A HREF = "pair_buck.html">pair_style</A> buck
 <LI><A HREF = "pair_buck.html">pair_style</A> buck/coul/cut
 <LI><A HREF = "pair_buck.html">pair_style</A> buck/coul/long
 <LI><A HREF = "pair_lj.html">pair_style</A> lj/cut
 <LI><A HREF = "pair_lj.html">pair_style</A> lj/cut/coul/cut
 <LI><A HREF = "pair_lj.html">pair_style</A> lj/cut/coul/long 
 </UL>
 <UL><LI><A HREF = "pair_hbond_dreiding.html">pair_style</A> hbond/dreiding/lj
 <LI><A HREF = "pair_hbond_dreiding.html">pair_style</A> hbond/dreiding/morse 
 </UL>
 <UL><LI><A HREF = "special_bonds.html">special_bonds</A> dreiding 
 </UL>
 <HR>
 
 <A NAME = "4_4"></A><H4>4.4 Running multiple simulations from one input script 
 </H4>
 <P>This can be done in several ways.  See the documentation for
 individual commands for more details on how these examples work.
 </P>
 <P>If "multiple simulations" means continue a previous simulation for
 more timesteps, then you simply use the <A HREF = "run.html">run</A> command
 multiple times.  For example, this script
 </P>
 <PRE>units lj
 atom_style atomic
 read_data data.lj
 run 10000
 run 10000
 run 10000
 run 10000
 run 10000 
 </PRE>
 <P>would run 5 successive simulations of the same system for a total of
 50,000 timesteps.
 </P>
 <P>If you wish to run totally different simulations, one after the other,
 the <A HREF = "clear.html">clear</A> command can be used in between them to
 re-initialize LAMMPS.  For example, this script
 </P>
 <PRE>units lj
 atom_style atomic
 read_data data.lj
 run 10000
 clear
 units lj
 atom_style atomic
 read_data data.lj.new
 run 10000 
 </PRE>
 <P>would run 2 independent simulations, one after the other.
 </P>
 <P>For large numbers of independent simulations, you can use
 <A HREF = "variable.html">variables</A> and the <A HREF = "next.html">next</A> and
 <A HREF = "jump.html">jump</A> commands to loop over the same input script
 multiple times with different settings.  For example, this
 script, named in.polymer
 </P>
 <PRE>variable d index run1 run2 run3 run4 run5 run6 run7 run8
 shell cd $d
 read_data data.polymer
 run 10000
 shell cd ..
 clear
 next d
 jump in.polymer 
 </PRE>
 <P>would run 8 simulations in different directories, using a data.polymer
 file in each directory.  The same concept could be used to run the
 same system at 8 different temperatures, using a temperature variable
 and storing the output in different log and dump files, for example
 </P>
 <PRE>variable a loop 8
 variable t index 0.8 0.85 0.9 0.95 1.0 1.05 1.1 1.15
 log log.$a
 read data.polymer
 velocity all create $t 352839
 fix 1 all nvt $t $t 100.0
 dump 1 all atom 1000 dump.$a
 run 100000
 next t
 next a
 jump in.polymer 
 </PRE>
 <P>All of the above examples work whether you are running on 1 or
 multiple processors, but assumed you are running LAMMPS on a single
 partition of processors.  LAMMPS can be run on multiple partitions via
 the "-partition" command-line switch as described in <A HREF = "Section_start.html#2_6">this
 section</A> of the manual.
 </P>
 <P>In the last 2 examples, if LAMMPS were run on 3 partitions, the same
 scripts could be used if the "index" and "loop" variables were
 replaced with <I>universe</I>-style variables, as described in the
 <A HREF = "variable.html">variable</A> command.  Also, the "next t" and "next a"
 commands would need to be replaced with a single "next a t" command.
 With these modifications, the 8 simulations of each script would run
 on the 3 partitions one after the other until all were finished.
 Initially, 3 simulations would be started simultaneously, one on each
 partition.  When one finished, that partition would then start
 the 4th simulation, and so forth, until all 8 were completed.
 </P>
 <HR>
 
 <A NAME = "4_5"></A><H4>4.5 Multi-replica simulations 
 </H4>
 <P>Several commands in LAMMPS run mutli-replica simulations, meaning
 that multiple instances (replicas) of your simulation are run
 simultaneously, with small amounts of data exchanged between replicas
 periodically.
 </P>
 <P>These are the relevant commands:
 </P>
 <UL><LI><A HREF = "neb.html">neb</A> for nudged elastic band calculations
 <LI><A HREF = "prd.html">prd</A> for parallel replica dynamics
 <LI><A HREF = "tad.html">tad</A> for temperature accelerated dynamics
 <LI><A HREF = "temper.html">temper</A> for parallel tempering 
 </UL>
 <P>NEB is a method for finding transition states and barrier energies.
 PRD and TAD are methods for performing accelerated dynamics to find
 and perform infrequent events.  Parallel tempering or replica exchange
 runs different replicas at a series of temperature to facilitate
 rare-event sampling.
 </P>
 <P>These command can only be used if LAMMPS was built with the "replica"
 package.  See the <A HREF = "Section_start.html#2_3">Making LAMMPS</A> section for
 more info on packages.
 </P>
 <P>In all these cases, you must run with one or more processors per
 replica.  The processors assigned to each replica are determined at
 run-time by using the <A HREF = "Section_start.html#2_6">-partition command-line
 switch</A> to launch LAMMPS on multiple
 partitions, which in this context are the same as replicas.  E.g.
 these commands:
 </P>
 <PRE>mpirun -np 16 lmp_linux -partition 8x2 -in in.temper
 mpirun -np 8 lmp_linux -partition 8x1 -in in.neb 
 </PRE>
 <P>would each run 8 replicas, on either 16 or 8 processors.  Note the use
 of the <A HREF = "Section_start.html#2_6">-in command-line switch</A> to specify the
 input script which is required when running in multi-replica mode.
 </P>
 <P>Also note that with MPI installed on a machine (e.g. your desktop),
 you can run on more (virtual) processors than you have physical
 processors.  Thus the above commands could be run on a
 single-processor (or few-processor) desktop so that you can run
 a multi-replica simulation on more replicas than you have
 physical processors.
 </P>
 <HR>
 
 <A NAME = "4_6"></A><H4>4.6 Granular models 
 </H4>
 <P>Granular system are composed of spherical particles with a diameter,
 as opposed to point particles.  This means they have an angular
 velocity and torque can be imparted to them to cause them to rotate.
 </P>
 <P>To run a simulation of a granular model, you will want to use
 the following commands:
 </P>
 <UL><LI><A HREF = "atom_style.html">atom_style</A> granular
 <LI><A HREF = "fix_nve_sphere.html">fix nve/sphere</A>
 <LI><A HREF = "fix_gravity.html">fix gravity</A> 
 </UL>
 <P>This compute
 </P>
 <UL><LI><A HREF = "compute_erotate_sphere.html">compute erotate/sphere</A> 
 </UL>
 <P>calculates rotational kinetic energy which can be <A HREF = "Section_howto.html#4_15">output with
 thermodynamic info</A>.
 </P>
 <P>Use one of these 3 pair potentials, which compute forces and torques
 between interacting pairs of particles:
 </P>
 <UL><LI><A HREF = "pair_style.html">pair_style</A> gran/history
 <LI><A HREF = "pair_style.html">pair_style</A> gran/no_history
 <LI><A HREF = "pair_style.html">pair_style</A> gran/hertzian 
 </UL>
 <P>These commands implement fix options specific to granular systems:
 </P>
 <UL><LI><A HREF = "fix_freeze.html">fix freeze</A>
 <LI><A HREF = "fix_pour.html">fix pour</A>
 <LI><A HREF = "fix_viscous.html">fix viscous</A>
 <LI><A HREF = "fix_wall_gran.html">fix wall/gran</A> 
 </UL>
 <P>The fix style <I>freeze</I> zeroes both the force and torque of frozen
 atoms, and should be used for granular system instead of the fix style
 <I>setforce</I>.
 </P>
 <P>For computational efficiency, you can eliminate needless pairwise
 computations between frozen atoms by using this command:
 </P>
 <UL><LI><A HREF = "neigh_modify.html">neigh_modify</A> exclude 
 </UL>
 <HR>
 
 <A NAME = "4_7"></A><H4>4.7 TIP3P water model 
 </H4>
 <P>The TIP3P water model as implemented in CHARMM
 <A HREF = "#MacKerell">(MacKerell)</A> specifies a 3-site rigid water molecule with
 charges and Lennard-Jones parameters assigned to each of the 3 atoms.
 In LAMMPS the <A HREF = "fix_shake.html">fix shake</A> command can be used to hold
 the two O-H bonds and the H-O-H angle rigid.  A bond style of
 <I>harmonic</I> and an angle style of <I>harmonic</I> or <I>charmm</I> should also be
 used.
 </P>
 <P>These are the additional parameters (in real units) to set for O and H
 atoms and the water molecule to run a rigid TIP3P-CHARMM model with a
 cutoff.  The K values can be used if a flexible TIP3P model (without
 fix shake) is desired.  If the LJ epsilon and sigma for HH and OH are
 set to 0.0, it corresponds to the original 1983 TIP3P model
 <A HREF = "#Jorgensen">(Jorgensen)</A>.
 </P>
 <P>O mass = 15.9994<BR>
 H mass = 1.008 <BR>
 </P>
 <P>O charge = -0.834<BR>
 H charge = 0.417 <BR>
 </P>
 <P>LJ epsilon of OO = 0.1521<BR>
 LJ sigma of OO = 3.1507<BR>
 LJ epsilon of HH = 0.0460<BR>
 LJ sigma of HH = 0.4000<BR>
 LJ epsilon of OH = 0.0836<BR>
 LJ sigma of OH = 1.7753 <BR>
 </P>
 <P>K of OH bond = 450<BR>
 r0 of OH bond = 0.9572 <BR>
 </P>
 <P>K of HOH angle = 55<BR>
 theta of HOH angle = 104.52 <BR>
 </P>
 <P>These are the parameters to use for TIP3P with a long-range Coulombic
 solver (Ewald or PPPM in LAMMPS), see <A HREF = "#Price">(Price)</A> for details:
 </P>
 <P>O mass = 15.9994<BR>
 H mass = 1.008 <BR>
 </P>
 <P>O charge = -0.830<BR>
 H charge = 0.415 <BR>
 </P>
 <P>LJ epsilon of OO = 0.102<BR>
 LJ sigma of OO = 3.188<BR>
 LJ epsilon, sigma of OH, HH = 0.0 <BR>
 </P>
 <P>K of OH bond = 450<BR>
 r0 of OH bond = 0.9572 <BR>
 </P>
 <P>K of HOH angle = 55<BR>
 theta of HOH angle = 104.52 <BR>
 </P>
 <P>Wikipedia also has a nice article on <A HREF = "http://en.wikipedia.org/wiki/Water_model">water
 models</A>.
 </P>
 <HR>
 
 <A NAME = "4_8"></A><H4>4.8 TIP4P water model 
 </H4>
 <P>The four-point TIP4P rigid water model extends the traditional
 three-point TIP3P model by adding an additional site, usually
 massless, where the charge associated with the oxygen atom is placed.
 This site M is located at a fixed distance away from the oxygen along
 the bisector of the HOH bond angle.  A bond style of <I>harmonic</I> and an
 angle style of <I>harmonic</I> or <I>charmm</I> should also be used.
 </P>
 <P>Currently, only a four-point model for long-range Coulombics is
 implemented via the LAMMPS <A HREF = "pair_lj.html">pair style
 lj/cut/coul/long/tip4p</A>.  A cutoff version may be added
 the future.  For both models, the bond lengths and bond angles should
 be held fixed using the <A HREF = "fix_shake.html">fix shake</A> command.
 </P>
 <P>These are the additional parameters (in real units) to set for O and H
 atoms and the water molecule to run a rigid TIP4P model with a cutoff
 <A HREF = "#Jorgensen">(Jorgensen)</A>.  Note that the OM distance is specified in
 the <A HREF = "pair_style.html">pair_style</A> command, not as part of the pair
 coefficients.
 </P>
 <P>O mass = 15.9994<BR>
 H mass = 1.008 <BR>
 </P>
 <P>O charge = -1.040<BR>
 H charge = 0.520 <BR>
 </P>
 <P>r0 of OH bond = 0.9572<BR>
 theta of HOH angle = 104.52 <BR>
 </P>
 <P>OM distance = 0.15 <BR>
 </P>
 <P>LJ epsilon of O-O = 0.1550<BR>
 LJ sigma of O-O = 3.1536<BR>
 LJ epsilon, sigma of OH, HH = 0.0 <BR>
 </P>
 <P>These are the parameters to use for TIP4P with a long-range Coulombic
 solver (Ewald or PPPM in LAMMPS):
 </P>
 <P>O mass = 15.9994<BR>
 H mass = 1.008 <BR>
 </P>
 <P>O charge = -1.0484<BR>
 H charge = 0.5242 <BR>
 </P>
 <P>r0 of OH bond = 0.9572<BR>
 theta of HOH angle = 104.52 <BR>
 </P>
 <P>OM distance = 0.1250 <BR>
 </P>
 <P>LJ epsilon of O-O = 0.16275<BR>
 LJ sigma of O-O = 3.16435<BR>
 LJ epsilon, sigma of OH, HH = 0.0 <BR>
 </P>
 <P>Wikipedia also has a nice article on <A HREF = "http://en.wikipedia.org/wiki/Water_model">water
 models</A>.
 </P>
 <HR>
 
 <A NAME = "4_9"></A><H4>4.9 SPC water model 
 </H4>
 <P>The SPC water model specifies a 3-site rigid water molecule with
 charges and Lennard-Jones parameters assigned to each of the 3 atoms.
 In LAMMPS the <A HREF = "fix_shake.html">fix shake</A> command can be used to hold
 the two O-H bonds and the H-O-H angle rigid.  A bond style of
 <I>harmonic</I> and an angle style of <I>harmonic</I> or <I>charmm</I> should also be
 used.
 </P>
 <P>These are the additional parameters (in real units) to set for O and H
 atoms and the water molecule to run a rigid SPC model.
 </P>
 <P>O mass = 15.9994<BR>
 H mass = 1.008 <BR>
 </P>
 <P>O charge = -0.820<BR>
 H charge = 0.410 <BR>
 </P>
 <P>LJ epsilon of OO = 0.1553<BR>
 LJ sigma of OO = 3.166<BR>
 LJ epsilon, sigma of OH, HH = 0.0 <BR>
 </P>
 <P>r0 of OH bond = 1.0<BR>
 theta of HOH angle = 109.47 <BR>
 </P>
 <P>Note that as originally proposed, the SPC model was run with a 9
 Angstrom cutoff for both LJ and Coulommbic terms.  It can also be used
 with long-range Coulombics (Ewald or PPPM in LAMMPS), without changing
 any of the parameters above, though it becomes a different model in
 that mode of usage.
 </P>
 <P>The SPC/E (extended) water model is the same, except
 the partial charge assignemnts change:
 </P>
 <P>O charge = -0.8476<BR>
 H charge = 0.4238 <BR>
 </P>
 <P>See the <A HREF = "#Berendsen">(Berendsen)</A> reference for more details on both
 the SPC and SPC/E models.
 </P>
 <P>Wikipedia also has a nice article on <A HREF = "http://en.wikipedia.org/wiki/Water_model">water
 models</A>.
 </P>
 <HR>
 
 <A NAME = "4_10"></A><H4>4.10 Coupling LAMMPS to other codes 
 </H4>
 <P>LAMMPS is designed to allow it to be coupled to other codes.  For
 example, a quantum mechanics code might compute forces on a subset of
 atoms and pass those forces to LAMMPS.  Or a continuum finite element
 (FE) simulation might use atom positions as boundary conditions on FE
 nodal points, compute a FE solution, and return interpolated forces on
 MD atoms.
 </P>
 <P>LAMMPS can be coupled to other codes in at least 3 ways.  Each has
 advantages and disadvantages, which you'll have to think about in the
 context of your application.
 </P>
 <P>(1) Define a new <A HREF = "fix.html">fix</A> command that calls the other code.  In
 this scenario, LAMMPS is the driver code.  During its timestepping,
 the fix is invoked, and can make library calls to the other code,
 which has been linked to LAMMPS as a library.  This is the way the
 <A HREF = "http://www.rpi.edu/~anderk5/lab">POEMS</A> package that performs constrained rigid-body motion on
 groups of atoms is hooked to LAMMPS.  See the
 <A HREF = "fix_poems.html">fix_poems</A> command for more details.  See <A HREF = "Section_modify.html">this
 section</A> of the documentation for info on how to add
 a new fix to LAMMPS.
 </P>
 
 
 <P>(2) Define a new LAMMPS command that calls the other code.  This is
 conceptually similar to method (1), but in this case LAMMPS and the
 other code are on a more equal footing.  Note that now the other code
 is not called during the timestepping of a LAMMPS run, but between
 runs.  The LAMMPS input script can be used to alternate LAMMPS runs
 with calls to the other code, invoked via the new command.  The
 <A HREF = "run.html">run</A> command facilitates this with its <I>every</I> option, which
 makes it easy to run a few steps, invoke the command, run a few steps,
 invoke the command, etc.
 </P>
 <P>In this scenario, the other code can be called as a library, as in
 (1), or it could be a stand-alone code, invoked by a system() call
 made by the command (assuming your parallel machine allows one or more
 processors to start up another program).  In the latter case the
 stand-alone code could communicate with LAMMPS thru files that the
 command writes and reads.
 </P>
 <P>See <A HREF = "Section_modify.html">this section</A> of the documentation for how to
 add a new command to LAMMPS.
 </P>
 <P>(3) Use LAMMPS as a library called by another code.  In this case the
 other code is the driver and calls LAMMPS as needed.  Or a wrapper
 code could link and call both LAMMPS and another code as libraries.
 Again, the <A HREF = "run.html">run</A> command has options that allow it to be
 invoked with minimal overhead (no setup or clean-up) if you wish to do
 multiple short runs, driven by another program.
 </P>
 <P>Examples of driver codes that call LAMMPS as a library are included in
 the "couple" directory of the LAMMPS distribution; see couple/README
 for more details:
 </P>
 <UL><LI>simple: simple driver programs in C++ and C which invoke LAMMPS as a
 library 
 
 <LI>lammps_quest: coupling of LAMMPS and <A HREF = "http://dft.sandia.gov/Quest">Quest</A>, to run classical
 MD with quantum forces calculated by a density functional code 
 
 <LI>lammps_spparks: coupling of LAMMPS and <A HREF = "http://www.sandia.gov/~sjplimp/spparks.html">SPPARKS</A>, to couple
 a kinetic Monte Carlo model for grain growth using MD to calculate
 strain induced across grain boundaries 
 </UL>
 
 
 
 
 <P><A HREF = "Section_start.html#2_4">This section</A> of the documentation describes
 how to build LAMMPS as a library.  Once this is done, you can
 interface with LAMMPS either via C++, C, Fortran, or Python (or any
 other language that supports a vanilla C-like interface).  For
 example, from C++ you could create one (or more) "instances" of
 LAMMPS, pass it an input script to process, or execute individual
 commands, all by invoking the correct class methods in LAMMPS.  From C
 or Fortran you can make function calls to do the same things.  See
 <A HREF = "Section_python.html">this section</A> of the manual for a description of
 the Python wrapper provided with LAMMPS that operates through the
 LAMMPS library interface.
 </P>
 <P>The files src/library.cpp and library.h contain the C-style interface
 to LAMMPS.  See <A HREF = "Section_howto.html#4_19">this section</A> of the manual
 for a description of the interface and how to extend it for your
 needs.
 </P>
 <P>Note that the lammps_open() function that creates an instance of
 LAMMPS takes an MPI communicator as an argument.  This means that
 instance of LAMMPS will run on the set of processors in the
 communicator.  Thus the calling code can run LAMMPS on all or a subset
 of processors.  For example, a wrapper script might decide to
 alternate between LAMMPS and another code, allowing them both to run
 on all the processors.  Or it might allocate half the processors to
 LAMMPS and half to the other code and run both codes simultaneously
 before syncing them up periodically.  Or it might instantiate multiple
 instances of LAMMPS to perform different calculations.
 </P>
 <HR>
 
 <A NAME = "4_11"></A><H4>4.11 Visualizing LAMMPS snapshots 
 </H4>
 <P>LAMMPS itself does not do visualization, but snapshots from LAMMPS
 simulations can be visualized (and analyzed) in a variety of ways.
 </P>
 <P>LAMMPS snapshots are created by the <A HREF = "dump.html">dump</A> command which can
 create files in several formats.  The native LAMMPS dump format is a
 text file (see "dump atom" or "dump custom") which can be visualized
 by the <A HREF = "Section_tools.html#xmovie">xmovie</A> program, included with the
 LAMMPS package.  This produces simple, fast 2d projections of 3d
 systems, and can be useful for rapid debugging of simulation geometry
 and atom trajectories.
 </P>
 <P>Several programs included with LAMMPS as auxiliary tools can convert
 native LAMMPS dump files to other formats.  See the
 <A HREF = "Section_tools.html">Section_tools</A> doc page for details.  The first is
 the <A HREF = "Section_tools.html#charmm">ch2lmp tool</A>, which contains a
 lammps2pdb Perl script which converts LAMMPS dump files into PDB
 files.  The second is the <A HREF = "Section_tools.html#arc">lmp2arc tool</A> which
 converts LAMMPS dump files into Accelrys' Insight MD program files.
 The third is the <A HREF = "Section_tools.html#cfg">lmp2cfg tool</A> which converts
 LAMMPS dump files into CFG files which can be read into the
 <A HREF = "http://mt.seas.upenn.edu/Archive/Graphics/A">AtomEye</A> visualizer.
 </P>
 <P>A Python-based toolkit distributed by our group can read native LAMMPS
 dump files, including custom dump files with additional columns of
 user-specified atom information, and convert them to various formats
 or pipe them into visualization software directly.  See the <A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">Pizza.py
 WWW site</A> for details.  Specifically, Pizza.py can convert
 LAMMPS dump files into PDB, XYZ, <A HREF = "http://www.ensight.com">Ensight</A>, and VTK formats.
 Pizza.py can pipe LAMMPS dump files directly into the Raster3d and
 RasMol visualization programs.  Pizza.py has tools that do interactive
 3d OpenGL visualization and one that creates SVG images of dump file
 snapshots.
 </P>
 <P>LAMMPS can create XYZ files directly (via "dump xyz") which is a
 simple text-based file format used by many visualization programs
 including <A HREF = "http://www.ks.uiuc.edu/Research/vmd">VMD</A>.
 </P>
 <P>LAMMPS can create DCD files directly (via "dump dcd") which can be
 read by <A HREF = "http://www.ks.uiuc.edu/Research/vmd">VMD</A> in conjunction with a CHARMM PSF file.  Using this
 form of output avoids the need to convert LAMMPS snapshots to PDB
 files.  See the <A HREF = "dump.html">dump</A> command for more information on DCD
 files.
 </P>
 <P>LAMMPS can create XTC files directly (via "dump xtc") which is GROMACS
 file format which can also be read by <A HREF = "http://www.ks.uiuc.edu/Research/vmd">VMD</A> for visualization.
 See the <A HREF = "dump.html">dump</A> command for more information on XTC files.
 </P>
 
 
 
 
 
 
 
 
 <HR>
 
 <A NAME = "4_12"></A><H4>4.12 Triclinic (non-orthogonal) simulation boxes 
 </H4>
 <P>By default, LAMMPS uses an orthogonal simulation box to encompass the
 particles.  The <A HREF = "boundary.html">boundary</A> command sets the boundary
 conditions of the box (periodic, non-periodic, etc).  The orthogonal
 box has its "origin" at (xlo,ylo,zlo) and is defined by 3 edge vectors
 starting from the origin given by A = (xhi-xlo,0,0); B =
 (0,yhi-ylo,0); C = (0,0,zhi-zlo).  The 6 parameters
 (xlo,xhi,ylo,yhi,zlo,zhi) are defined at the time the simluation box
 is created, e.g. by the <A HREF = "create_box.html">create_box</A> or
 <A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
 commands.  Additionally, LAMMPS defines box size parameters lx,ly,lz
 where lx = xhi-xlo, and similarly in the y and z dimensions.  The 6
 parameters, as well as lx,ly,lz, can be output via the <A HREF = "thermo_style.html">thermo_style
 custom</A> command.
 </P>
 <P>LAMMPS also allows simulations to be perfored in non-orthogonal
 simulation boxes shaped as a parallelepiped with triclinic symmetry.
 The parallelepiped has its "origin" at (xlo,ylo,zlo) and is defined by
 3 edge vectors starting from the origin given by A = (xhi-xlo,0,0); B
 = (xy,yhi-ylo,0); C = (xz,yz,zhi-zlo).  <I>Xy,xz,yz</I> can be 0.0 or
 positive or negative values and are called "tilt factors" because they
 are the amount of displacement applied to faces of an originally
 orthogonal box to transform it into the parallelepiped.  Note that in
 LAMMPS the triclinic simulation box edge vectors A,B,C cannot be
 arbitrary vectors.  As indicated, A must be aligned with the x axis, B
 must be in the xy plane, and C is arbitrary.  However, this is not a
 restriction since it is possible to rotate any set of 3 crystal basis
 vectors so that they meet this restriction.
 </P>
 <P>The 9 parameters (xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz) are defined at the
 time the simluation box is created.  This happens in one of 3 ways.
 If the <A HREF = "create_box.html">create_box</A> command is used with a region of
 style <I>prism</I>, then a triclinic box is setup.  See the
 <A HREF = "region.html">region</A> command for details.  If the
 <A HREF = "read_data.html">read_data</A> command is used to define the simulation
 box, and the header of the data file contains a line with the "xy xz
 yz" keyword, then a triclinic box is setup.  See the
 <A HREF = "read_data.html">read_data</A> command for details.  Finally, if the
 <A HREF = "read_restart.html">read_restart</A> command reads a restart file which
 was written from a simulation using a triclinic box, then a triclinic
 box will be setup for the restarted simulation.
 </P>
 <P>Note that you can define a triclinic box with all 3 tilt factors =
 0.0, so that it is initially orthogonal.  This is necessary if the box
 will become non-orthogonal, e.g. due to the <A HREF = "fix_nh.html">fix npt</A> or
 <A HREF = "fix_deform.html">fix deform</A> commands.  Alternatively, you can use the
 <A HREF = "change_box.html">change_box</A> command to convert a simulation box from
 orthogonal to triclinic and vice versa.
 </P>
 <P>As with orthogonal boxes, LAMMPS defines triclinic box size parameters
 lx,ly,lz where lx = xhi-xlo, and similarly in the y and z dimensions.
 The 9 parameters, as well as lx,ly,lz, can be output via the
 <A HREF = "thermo_style.html">thermo_style custom</A> command.
 </P>
 <P>To avoid extremely tilted boxes (which would be computationally
 inefficient), no tilt factor can skew the box more than half the
 distance of the parallel box length, which is the 1st dimension in the
 tilt factor (x for xz).  For example, if xlo = 2 and xhi = 12, then
 the x box length is 10 and the xy tilt factor must be between -5 and
 5.  Similarly, both xz and yz must be between -(xhi-xlo)/2 and
 +(yhi-ylo)/2.  Note that this is not a limitation, since if the
 maximum tilt factor is 5 (as in this example), then configurations
 with tilt = ..., -15, -5, 5, 15, 25, ... are geometrically all
 equivalent.
 </P>
 <P>Triclinic crystal structures are often defined using three lattice
 constants <I>a</I>, <I>b</I>, and <I>c</I>, and three angles <I>alpha</I>, <I>beta</I> and
 <I>gamma</I>.  Note that in this nomenclature, the a,b,c lattice constants
 are the scalar lengths of the 3 A,B,C edge vectors defined above.  The
 relationship between these 6 quantities (a,b,c,alpha,beta,gamma) and
 the LAMMPS box sizes (lx,ly,lz) = (xhi-xlo,yhi-ylo,zhi-zlo) and tilt
 factors (xy,xz,yz) is as follows:
 </P>
 <CENTER><IMG SRC = "Eqs/box.jpg">
 </CENTER>
 <P>As discussed on the <A HREF = "dump.html">dump</A> command doc page, when the BOX
 BOUNDS for a snapshot is written to a dump file for a triclinic box,
 an orthogonal bounding box which encloses the triclinic simulation box
 is output, along with the 3 tilt factors (xy, xz, yz) of the triclinic
 box, formatted as follows:
 </P>
 <PRE>ITEM: BOX BOUNDS xy xz yz
 xlo_bound xhi_bound xy
 ylo_bound yhi_bound xz
 zlo_bound zhi_bound yz 
 </PRE>
 <P>This bounding box is convenient for many visualization programs and is
 calculated from the 9 triclinic box parameters
 (xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz) as follows:
 </P>
 <PRE>xlo_bound = xlo + MIN(0.0,xy,xz,xy+xz)
 xhi_bound = xhi + MAX(0.0,xy,xz,xy+xz)
 ylo_bound = ylo + MIN(0.0,yz)
 yhi_bound = yhi + MAX(0.0,yz)
 zlo_bound = zlo
 zhi_bound = zhi 
 </PRE>
 <P>These formulas can be inverted if you need to convert the bounding box
 back into the triclinic box parameters, e.g. xlo = xlo_bound -
 MIN(0.0,xy,xz,xy+xz).
 </P>
 <P>One use of triclinic simulation boxes is to model solid-state crystals
 with triclinic symmetry.  The <A HREF = "lattice.html">lattice</A> command can be
 used with non-orthogonal basis vectors to define a lattice that will
 tile a triclinic simulation box via the
 <A HREF = "create_atoms.html">create_atoms</A> command.
 </P>
 <P>A second use is to run Parinello-Rahman dyanamics via the <A HREF = "fix_nh.html">fix
 npt</A> command, which will adjust the xy, xz, yz tilt
 factors to compensate for off-diagonal components of the pressure
 tensor.  The analalog for an <A HREF = "minimize.html">energy minimization</A> is
 the <A HREF = "fix_box_relax.html">fix box/relax</A> command.
 </P>
 <P>A third use is to shear a bulk solid to study the response of the
 material.  The <A HREF = "fix_deform.html">fix deform</A> command can be used for
 this purpose.  It allows dynamic control of the xy, xz, yz tilt
 factors as a simulation runs.  This is discussed in the next section
 on non-equilibrium MD (NEMD) simulations.
 </P>
 <HR>
 
 <A NAME = "4_13"></A><H4>4.13 NEMD simulations 
 </H4>
 <P>Non-equilibrium molecular dynamics or NEMD simulations are typically
 used to measure a fluid's rheological properties such as viscosity.
 In LAMMPS, such simulations can be performed by first setting up a
 non-orthogonal simulation box (see the preceding Howto section).
 </P>
 <P>A shear strain can be applied to the simulation box at a desired
 strain rate by using the <A HREF = "fix_deform.html">fix deform</A> command.  The
 <A HREF = "fix_nvt_sllod.html">fix nvt/sllod</A> command can be used to thermostat
 the sheared fluid and integrate the SLLOD equations of motion for the
 system.  Fix nvt/sllod uses <A HREF = "compute_temp_deform.html">compute
 temp/deform</A> to compute a thermal temperature
 by subtracting out the streaming velocity of the shearing atoms.  The
 velocity profile or other properties of the fluid can be monitored via
 the <A HREF = "fix_ave_spatial.html">fix ave/spatial</A> command.
 </P>
 <P>As discussed in the previous section on non-orthogonal simulation
 boxes, the amount of tilt or skew that can be applied is limited by
 LAMMPS for computational efficiency to be 1/2 of the parallel box
 length.  However, <A HREF = "fix_deform.html">fix deform</A> can continuously strain
 a box by an arbitrary amount.  As discussed in the <A HREF = "fix_deform.html">fix
 deform</A> command, when the tilt value reaches a limit,
 the box is re-shaped to the opposite limit which is an equivalent
 tiling of periodic space.  The strain rate can then continue to change
 as before.  In a long NEMD simulation these box re-shaping events may
 occur many times.
 </P>
 <P>In a NEMD simulation, the "remap" option of <A HREF = "fix_deform.html">fix
 deform</A> should be set to "remap v", since that is what
 <A HREF = "fix_nvt_sllod.html">fix nvt/sllod</A> assumes to generate a velocity
 profile consistent with the applied shear strain rate.
 </P>
 <P>An alternative method for calculating viscosities is provided via the
 <A HREF = "fix_viscosity.html">fix viscosity</A> command.
 </P>
 <HR>
 
 <A NAME = "4_14"></A><H4>4.14 Extended spherical and aspherical particles 
 </H4>
 <P>Typical MD models treat atoms or particles as point masses.
 Sometimes, however, it is desirable to have a model with finite-size
 particles such as spherioids or aspherical ellipsoids.  The difference
 is that such particles have a moment of inertia, rotational energy,
 and angular momentum.  Rotation is induced by torque from interactions
 with other particles.
 </P>
 <P>LAMMPS has several options for running simulations with these kinds of
 particles.  The following aspects are discussed in turn:
 </P>
 <UL><LI>atom styles
 <LI>pair potentials
 <LI>time integration
 <LI>computes, thermodynamics, and dump output
 <LI>rigid bodies composed of extended particles 
 </UL>
 <H5>Atom styles 
 </H5>
 <P>There are 3 <A HREF = "atom_style.html">atom styles</A> that allow for definition of
 finite-size particles: granular, dipole, ellipsoid.
 </P>
 <P>Granular particles are spheriods and each particle can have a unique
 diameter and mass (or density).  These particles store an angular
 velocity (omega) and can be acted upon by torque.
 </P>
 <P>Dipolar particles are typically spheriods with a point dipole and each
 particle type has a diamater and mass, set by the <A HREF = "shape.html">shape</A>
 and <A HREF = "mass.html">mass</A> commands.  These particles store an angular
 velocity (omega) and can be acted upon by torque.  They also store an
 orientation for the point dipole (mu) which has a length set by the
 <A HREF = "dipole.html">dipole</A> command.  The <A HREF = "set.html">set</A> command can be used
 to initialize the orientation of dipole moments.
 </P>
 <P>Ellipsoid particles are aspherical.  Each particle type has an
 ellipsoidal shape and mass, defined by the <A HREF = "shape.html">shape</A> and
 <A HREF = "mass.html">mass</A> commands.  These particles store an angular momentum
 and their orientation (quaternion), and can be acted upon by torque.
 They do not store an angular velocity (omega), which can be in a
 different direction than angular momentum, rather they compute it as
 needed.  Ellipsoidal particles can also store a dipole moment if an
 <A HREF = "atom_style.html">atom_style hybrid ellipsoid dipole</A> is used.  The
 <A HREF = "set.html">set</A> command can be used to initialize the orientation of
 ellipsoidal particles and has a brief explanation of quaternions.
 </P>
 <P>Note that if one of these atom styles is used (or multiple styles via
 the <A HREF = "atom_style.html">atom_style hybrid</A> command), not all particles in
 the system are required to be finite-size or aspherical.  For example,
 if the 3 shape parameters are set to the same value, the particle will
 be a spheroid rather than an ellipsoid.  If the 3 shape parameters are
 all set to 0.0 or if the diameter is set to 0.0, it will be a point
 particle.  If the dipole moment is set to zero, the particle will not
 have a point dipole associated with it.  The pair styles used to
 compute pairwise interactions will typically compute the correct
 interaction in these simplified (cheaper) cases.  <A HREF = "pair_hybrid.html">Pair_style
 hybrid</A> can be used to insure the correct
 interactions are computed for the appropriate style of interactions.
 Likewise, using groups to partition particles (ellipsoid versus
 spheroid versus point particles) will allow you to use the appropriate
 time integrators and temperature computations for each class of
 particles.  See the doc pages for various commands for details.
 </P>
 <P>Also note that for <A HREF = "dimension.html">2d simulations</A>, finite-size
 spheroids and ellipsoids are still treated as 3d particles, rather
 than as disks or ellipses.  This means they have the same moment of
 inertia for a 3d extended object.  When their temperature is
 coomputed, the correct degrees of freedom are used for rotation in a
 2d versus 3d system.
 </P>
 <H5>Pair potentials 
 </H5>
 <P>When a system with extended particles is defined, the particles will
 only rotate and experience torque if the force field computes such
 interactions.  These are the various <A HREF = "pair_style.html">pair styles</A>
 that generate torque:
 </P>
 <UL><LI><A HREF = "pair_gran.html">pair_style gran/history</A>
 <LI><A HREF = "pair_gran.html">pair_style gran/hertzian</A>
 <LI><A HREF = "pair_gran.html">pair_style gran/no_history</A>
 <LI><A HREF = "pair_dipole.html">pair_style dipole/cut</A>
 <LI><A HREF = "pair_gayberne.html">pair_style gayberne</A>
 <LI><A HREF = "pair_resquared.html">pair_style resquared</A>
 <LI><A HREF = "pair_lubricate.html">pair_style lubricate</A> 
 </UL>
 <P>The <A HREF = "pair_gran.html">granular pair styles</A> are used with <A HREF = "atom_style.html">atom_style
 granular</A>.  The <A HREF = "pair_dipole.html">dipole pair style</A>
 is used with <A HREF = "atom_style.html">atom_style dipole</A>.  The
 <A HREF = "pair_gayberne.html">GayBerne</A> and <A HREF = "pair_resquared.html">REsquared</A>
 potentials require particles have a <A HREF = "shape.html">shape</A> and are
 designed for <A HREF = "atom_style.html">ellipsoidal particles</A>.  The
 <A HREF = "pair_lubricate.html">lubrication potential</A> requires that particles
 have a <A HREF = "shape.html">shape</A>.  It can currently only be used with
 extended spherical particles.
 </P>
 <H5>Time integration 
 </H5>
 <P>There are 3 fixes that perform time integration on extended spherical
 particles, meaning the integrators update the rotational orientation
 and angular velocity or angular momentum of the particles:
 </P>
 <UL><LI><A HREF = "fix_nve_sphere.html">fix nve/sphere</A>
 <LI><A HREF = "fix_nvt_sphere.html">fix nvt/sphere</A>
 <LI><A HREF = "fix_npt_sphere.html">fix npt/sphere</A> 
 </UL>
 <P>Likewise, there are 3 fixes that perform time integration on extended
 aspherical particles:
 </P>
 <UL><LI><A HREF = "fix_nve_asphere.html">fix nve/asphere</A>
 <LI><A HREF = "fix_nvt_asphere.html">fix nvt/asphere</A>
 <LI><A HREF = "fix_npt_asphere.html">fix npt/asphere</A> 
 </UL>
 <P>The advantage of these fixes is that those which thermostat the
 particles include the rotational degrees of freedom in the temperature
 calculation and thermostatting.  Other thermostats can be used with
 fix nve/sphere or fix nve/asphere, such as fix langevin or fix
 temp/berendsen, but those thermostats only operate on the
 translational kinetic energy of the extended particles.
 </P>
 <P>Note that for mixtures of point and extended particles, you should
 only use these integration fixes on <A HREF = "group.html">groups</A> which contain
 extended particles.
 </P>
 <H5>Computes, thermodynamics, and dump output 
 </H5>
 <P>There are 4 computes that calculate the temperature or rotational energy
 of extended spherical or aspherical particles:
 </P>
 <UL><LI><A HREF = "compute_temp_sphere.html">compute temp/sphere</A>
 <LI><A HREF = "compute_temp_asphere.html">compute temp/asphere</A>
 <LI><A HREF = "compute_erotate_sphere.html">compute erotate/sphere</A>
 <LI><A HREF = "compute_erotate_asphere.html">compute erotate/asphere</A> 
 </UL>
 <P>These include rotational degrees of freedom in their computation.  If
 you wish the thermodynamic output of temperature or pressure to use
 one of these computes (e.g. for a system entirely composed of extended
 particles), then the compute can be defined and the
 <A HREF = "thermo_modify.html">thermo_modify</A> command used.  Note that by
 default thermodynamic quantities will be calculated with a temperature
 that only includes translational degrees of freedom.  See the
 <A HREF = "thermo_style.html">thermo_style</A> command for details.
 </P>
 <P>The <A HREF = "dump.html">dump custom</A> command can output various attributes of
 extended particles, including the dipole moment (mu), the angular
 velocity (omega), the angular momentum (angmom), the quaternion
 (quat), and the torque (tq) on the particle.
 </P>
 <H5>Rigid bodies composed of extended particles 
 </H5>
 <P>The <A HREF = "fix_rigid.html">fix rigid</A> command treats a collection of
 particles as a rigid body, computes its inertia tensor, sums the total
 force and torque on the rigid body each timestep due to forces on its
 constituent particles, and integrates the motion of the rigid body.
 </P>
 <P>(NOTE: the feature described in the following paragraph has not yet
 been released.  It will be soon.)
 </P>
 <P>If any of the constituent particles of a rigid body are extended
 particles (spheroids or ellipsoids), then their contribution to the
 inertia tensor of the body is different than if they were point
 particles.  This means the rotational dynamics of the rigid body will
 be different.  Thus a model of a dimer is different if the dimer
 consists of two point masses versus two extended sphereoids, even if
 the two particles have the same mass.  Extended particles that
 experience torque due to their interaction with other particles will
 also impart that torque to a rigid body they are part of.
 </P>
 <P>See the "fix rigid" command for example of complex rigid-body models
 it is possible to define in LAMMPS.
 </P>
 <P>Note that the <A HREF = "fix_shake.html">fix shake</A> command can also be used to
 treat 2, 3, or 4 particles as a rigid body, but it always assumes the
 particles are point masses.
 </P>
 <HR>
 
 <A NAME = "4_15"></A><H4>4.15 Output from LAMMPS (thermo, dumps, computes, fixes, variables) 
 </H4>
 <P>There are four basic kinds of LAMMPS output:
 </P>
 <UL><LI><A HREF = "thermo_style.html">Thermodynamic output</A>, which is a list
 of quantities printed every few timesteps to the screen and logfile. 
 
 <LI><A HREF = "dump.html">Dump files</A>, which contain snapshots of atoms and various
 per-atom values and are written at a specified frequency. 
 
 <LI>Certain fixes can output user-specified quantities to files: <A HREF = "fix_ave_time.html">fix
 ave/time</A> for time averaging, <A HREF = "fix_ave_spatial.html">fix
 ave/spatial</A> for spatial averaging, and <A HREF = "fix_print.html">fix
 print</A> for single-line output of
 <A HREF = "variable.html">variables</A>.  Fix print can also output to the
 screen. 
 
 <LI><A HREF = "restart.html">Restart files</A>. 
 </UL>
 <P>A simulation prints one set of thermodynamic output and (optionally)
 restart files.  It can generate any number of dump files and fix
 output files, depending on what <A HREF = "dump.html">dump</A> and <A HREF = "fix.html">fix</A>
 commands you specify.
 </P>
 <P>As discussed below, LAMMPS gives you a variety of ways to determine
 what quantities are computed and printed when the thermodynamics,
 dump, or fix commands listed above perform output.  Throughout this
 discussion, note that users can also <A HREF = "Section_modify.html">add their own computes and fixes
 to LAMMPS</A> which can then generate values that can
 then be output with these commands.
 </P>
 <P>The following sub-sections discuss different LAMMPS command related
 to output and the kind of data they operate on and produce:
 </P>
 <UL><LI><A HREF = "#global">Global/per-atom/local data</A>
 <LI><A HREF = "#scalar">Scalar/vector/array data</A>
 <LI><A HREF = "#thermo">Thermodynamic output</A>
 <LI><A HREF = "#dump">Dump file output</A>
 <LI><A HREF = "#fixoutput">Fixes that write output files</A>
 <LI><A HREF = "#computeoutput">Computes that process output quantities</A>
 <LI><A HREF = "#fixoutput">Fixes that process output quantities</A>
 <LI><A HREF = "#compute">Computes that generate values to output</A>
 <LI><A HREF = "#fix">Fixes that generate values to output</A>
 <LI><A HREF = "#variable">Variables that generate values to output</A>
 <LI><A HREF = "#table">Summary table of output options and data flow between commands</A> 
 </UL>
 <H5><A NAME = "global"></A>Global/per-atom/local data 
 </H5>
 <P>Various output-related commands work with three different styles of
 data: global, per-atom, or local.  A global datum is one or more
 system-wide values, e.g. the temperature of the system.  A per-atom
 datum is one or more values per atom, e.g. the kinetic energy of each
 atom.  Local datums are calculated by each processor based on the
 atoms it owns, but there may be zero or more per atom, e.g. a list of
 bond distances.
 </P>
 <H5><A NAME = "scalar"></A>Scalar/vector/array data 
 </H5>
 <P>Global, per-atom, and local datums can each come in three kinds: a
 single scalar value, a vector of values, or a 2d array of values.  The
 doc page for a "compute" or "fix" or "variable" that generates data
 will specify both the style and kind of data it produces, e.g. a
 per-atom vector.
 </P>
 <P>When a quantity is accessed, as in many of the output commands
 discussed below, it can be referenced via the following bracket
 notation, where ID in this case is the ID of a compute.  The leading
 "c_" would be replaced by "f_" for a fix, or "v_" for a variable:
 </P>
-<DIV ALIGN=center><TABLE  WIDTH="0%"  BORDER=1 >
+<DIV ALIGN=center><TABLE  BORDER=1 >
 <TR><TD >c_ID </TD><TD > entire scalar, vector, or array</TD></TR>
 <TR><TD >c_ID[I] </TD><TD > one element of vector, one column of array</TD></TR>
 <TR><TD >c_ID[I][J] </TD><TD > one element of array 
 </TD></TR></TABLE></DIV>
 
 <P>In other words, using one bracket reduces the dimension of the data
 once (vector -> scalar, array -> vector).  Using two brackets reduces
 the dimension twice (array -> scalar).  Thus a command that uses
 scalar values as input can typically also process elements of a vector
 or array.
 </P>
 <H5><A NAME = "thermo"></A>Thermodynamic output 
 </H5>
 <P>The frequency and format of thermodynamic output is set by the
 <A HREF = "thermo.html">thermo</A>, <A HREF = "thermo_style.html">thermo_style</A>, and
 <A HREF = "thermo_modify.html">thermo_modify</A> commands.  The
 <A HREF = "thermo_style.html">thermo_style</A> command also specifies what values
 are calculated and written out.  Pre-defined keywords can be specified
 (e.g. press, etotal, etc).  Three additional kinds of keywords can
 also be specified (c_ID, f_ID, v_name), where a <A HREF = "compute.html">compute</A>
 or <A HREF = "fix.html">fix</A> or <A HREF = "variable.html">variable</A> provides the value to be
 output.  In each case, the compute, fix, or variable must generate
 global values for input to the <A HREF = "dump.html">thermo_style custom</A>
 command.
 </P>
 <H5><A NAME = "dump"></A>Dump file output 
 </H5>
 <P>Dump file output is specified by the <A HREF = "dump.html">dump</A> and
 <A HREF = "dump_modify.html">dump_modify</A> commands.  There are several
 pre-defined formats (dump atom, dump xtc, etc).
 </P>
 <P>There is also a <A HREF = "dump.html">dump custom</A> format where the user
 specifies what values are output with each atom.  Pre-defined atom
 attributes can be specified (id, x, fx, etc).  Three additional kinds
 of keywords can also be specified (c_ID, f_ID, v_name), where a
 <A HREF = "compute.html">compute</A> or <A HREF = "fix.html">fix</A> or <A HREF = "variable.html">variable</A>
 provides the values to be output.  In each case, the compute, fix, or
 variable must generate per-atom values for input to the <A HREF = "dump.html">dump
 custom</A> command.
 </P>
 <P>There is also a <A HREF = "dump.html">dump local</A> format where the user specifies
 what local values to output.  A pre-defined index keyword can be
 specified to enumuerate the local values.  Two additional kinds of
 keywords can also be specified (c_ID, f_ID), where a
 <A HREF = "compute.html">compute</A> or <A HREF = "fix.html">fix</A> or <A HREF = "variable.html">variable</A>
 provides the values to be output.  In each case, the compute or fix
 must generate local values for input to the <A HREF = "dump.html">dump local</A>
 command.
 </P>
 <H5><A NAME = "fixoutput"></A>Fixes that write output files 
 </H5>
 <P>Sevarl fixes take various quantities as input and can write output
 files: <A HREF = "fix_ave_time.html">fix ave/time</A>, <A HREF = "fix_ave_spatial.html">fix
 ave/spatial</A>, <A HREF = "fix_ave_histo.html">fix ave/histo</A>,
 <A HREF = "fix_ave_correlate.html">fix ave/correlate</A>, and <A HREF = "fix_print.html">fix
 print</A>.
 </P>
 <P>The <A HREF = "fix_ave_time.html">fix ave/time</A> command enables direct output to
 a file and/or time-averaging of global scalars or vectors.  The user
 specifies one or more quantities as input.  These can be global
 <A HREF = "compute.html">compute</A> values, global <A HREF = "fix.html">fix</A> values, or
 <A HREF = "variable.html">variables</A> of any style except the atom style which
 produces per-atom values.  Since a variable can refer to keywords used
 by the <A HREF = "thermo_style.html">thermo_style custom</A> command (like temp or
 press) and individual per-atom values, a wide variety of quantities
 can be time averaged and/or output in this way.  If the inputs are one
 or more scalar values, then the fix generate a global scalar or vector
 of output.  If the inputs are one or more vector values, then the fix
 generates a global vector or array of output.  The time-averaged
 output of this fix can also be used as input to other output commands.
 </P>
 <P>The <A HREF = "fix_ave_spatial.html">fix ave/spatial</A> command enables direct
 output to a file of spatial-averaged per-atom quantities like those
 output in dump files, within 1d layers of the simulation box.  The
 per-atom quantities can be atom density (mass or number) or atom
 attributes such as position, velocity, force.  They can also be
 per-atom quantities calculated by a <A HREF = "compute.html">compute</A>, by a
 <A HREF = "fix.html">fix</A>, or by an atom-style <A HREF = "variable.html">variable</A>.  The
 spatial-averaged output of this fix can also be used as input to other
 output commands.
 </P>
 <P>The <A HREF = "fix_ave_histo.html">fix ave/histo</A> command enables direct output
 to a file of histogrammed quantities, which can be global or per-atom
 or local quantities.  The histogram output of this fix can also be
 used as input to other output commands.
 </P>
 <P>The <A HREF = "fix_ave_histo.html">fix ave/correlate</A> command enables direct
 output to a file of time-correlated quantities, which can be global
 scalars.  The correlation matrix output of this fix can also be used
 as input to other output commands.
 </P>
 <P>The <A HREF = "fix_print.html">fix print</A> command can generate a line of output
 written to the screen and log file or to a separate file, periodically
 during a running simulation.  The line can contain one or more
 <A HREF = "variable.html">variable</A> values for any style variable except the atom
 style).  As explained above, variables themselves can contain
 references to global values generated by <A HREF = "thermo_style.html">thermodynamic
 keywords</A>, <A HREF = "compute.html">computes</A>,
 <A HREF = "fix.html">fixes</A>, or other <A HREF = "variable.html">variables</A>, or to per-atom
 values for a specific atom.  Thus the <A HREF = "fix_print.html">fix print</A>
 command is a means to output a wide variety of quantities separate
 from normal thermodynamic or dump file output.
 </P>
 <H5><A NAME = "computeoutput"></A>Computes that process output quantities 
 </H5>
 <P>The <A HREF = "compute_reduce.html">compute reduce</A> and <A HREF = "compute_reduce.html">compute
 reduce/region</A> commands take one or more per-atom
 or local vector quantities as inputs and "reduce" them (sum, min, max,
 ave) to scalar quantities.  These are produced as output values which
 can be used as input to other output commands.
 </P>
 <P>The <A HREF = "compute_property_atom.html">compute property/atom</A> command takes a
 list of one or more pre-defined atom attributes (id, x, fx, etc) and
 stores the values in a per-atom vector or array.  These are produced
 as output values which can be used as input to other output commands.
 The list of atom attributes is the same as for the <A HREF = "dump.html">dump
 custom</A> command.
 </P>
 <P>The <A HREF = "compute_property_local.html">compute property/local</A> command takes
 a list of one or more pre-defined local attributes (bond info, angle
 info, etc) and stores the values in a local vector or array.  These
 are produced as output values which can be used as input to other
 output commands.
 </P>
 <P>The <A HREF = "compute_atom_molecule.html">compute atom/molecule</A> command takes a
 list of one or more per-atom quantities (from a compute, fix, per-atom
 variable) and sums the quantities on a per-molecule basis.  It
 produces a global vector or array as output values which can be used
 as input to other output commands.
 </P>
 <H5><A NAME = "fixoutput"></A>Fixes that process output quantities 
 </H5>
 <P>The <A HREF = "fix_ave_atom.html">fix ave/atom</A> command performs time-averaging
 of per-atom vectors.  The per-atom quantities can be atom attributes
 such as position, velocity, force.  They can also be per-atom
 quantities calculated by a <A HREF = "compute.html">compute</A>, by a
 <A HREF = "fix.html">fix</A>, or by an atom-style <A HREF = "variable.html">variable</A>.  The
 time-averaged per-atom output of this fix can be used as input to
 other output commands.
 </P>
 <P>The <A HREF = "fix_store_state.html">fix store/state</A> command can archive one or
 more per-atom attributes at a particular time, so that the old values
 can be used in a future calculation or output.  The list of atom
 attributes is the same as for the <A HREF = "dump.html">dump custom</A> command,
 including per-atom quantities calculated by a <A HREF = "compute.html">compute</A>,
 by a <A HREF = "fix.html">fix</A>, or by an atom-style <A HREF = "variable.html">variable</A>.
 The output of this fix can be used as input to other output commands.
 </P>
 <H5><A NAME = "compute"></A>Computes that generate values to output 
 </H5>
 <P>Every <A HREF = "compute.html">compute</A> in LAMMPS produces either global or
 per-atom or local values.  The values can be scalars or vectors or
 arrays of data.  These values can be output using the other commands
 described in this section.  The doc page for each compute command
 describes what it produces.  Computes that produce per-atom or local
 values have the word "atom" or "local" in their style name.  Computes
 without the word "atom" or "local" produce global values.
 </P>
 <H5><A NAME = "fix"></A>Fixes that generate values to output 
 </H5>
 <P>Some <A HREF = "fix.html">fixes</A> in LAMMPS produces either global or per-atom or
 local values which can be accessed by other commands.  The values can
 be scalars or vectors or arrays of data.  These values can be output
 using the other commands described in this section.  The doc page for
 each fix command tells whether it produces any output quantities and
 describes them.
 </P>
 <H5><A NAME = "variable"></A>Variables that generate values to output 
 </H5>
 <P>Every <A HREF = "variable.html">variables</A> defined in an input script generates
 either a global scalar value or a per-atom vector (only atom-style
 variables) when it is accessed.  The formulas used to define equal-
 and atom-style variables can contain references to the thermodynamic
 keywords and to global and per-atom data generated by computes, fixes,
 and other variables.  The values generated by variables can be output
 using the other commands described in this section.
 </P>
 <H5><A NAME = "table"></A>Summary table of output options and data flow between commands 
 </H5>
 <P>This table summarizes the various commands that can be used for
 generating output from LAMMPS.  Each command produces output data of
 some kind and/or writes data to a file.  Most of the commands can take
 data from other commands as input.  Thus you can link many of these
 commands together in pipeline form, where data produced by one command
 is used as input to another command and eventually written to the
 screen or to a file.  Note that to hook two commands together the
 output and input data types must match, e.g. global/per-atom/local
 data and scalar/vector/array data.
 </P>
 <P>Also note that, as described above, when a command takes a scalar as
 input, that could be an element of a vector or array.  Likewise a
 vector input could be a column of an array.
 </P>
-<DIV ALIGN=center><TABLE  WIDTH="0%"  BORDER=1 >
+<DIV ALIGN=center><TABLE  BORDER=1 >
 <TR><TD >Command</TD><TD > Input</TD><TD > Output</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "thermo_style.html">thermo_style custom</A></TD><TD > global scalars</TD><TD > screen, log file</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "dump.html">dump custom</A></TD><TD > per-atom vectors</TD><TD > dump file</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "dump.html">dump local</A></TD><TD > local vectors</TD><TD > dump file</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "fix_print.html">fix print</A></TD><TD > global scalar from variable</TD><TD > screen, file</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "print.html">print</A></TD><TD > global scalar from variable</TD><TD > screen</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "compute.html">computes</A></TD><TD > N/A</TD><TD > global/per-atom/local scalar/vector/array</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "fix.html">fixes</A></TD><TD > N/A</TD><TD > global/per-atom/local scalar/vector/array</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "variable.html">variables</A></TD><TD > global scalars, per-atom vectors</TD><TD > global scalar, per-atom vector</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "compute_reduce.html">compute reduce</A></TD><TD > per-atom/local vectors</TD><TD > global scalar/vector</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "compute_property_atom.html">compute property/atom</A></TD><TD > per-atom vectors</TD><TD > per-atom vector/array</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "compute_property_local.html">compute property/local</A></TD><TD > local vectors</TD><TD > local vector/array</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "compute_atom_molecule.html">compute atom/molecule</A></TD><TD > per-atom vectors</TD><TD > global vector/array</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "fix_ave_atom.html">fix ave/atom</A></TD><TD > per-atom vectors</TD><TD > per-atom vector/array</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "fix_ave_time.html">fix ave/time</A></TD><TD > global scalars/vectors</TD><TD > global scalar/vector/array, file</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "fix_ave_spatial.html">fix ave/spatial</A></TD><TD > per-atom vectors</TD><TD > global array, file</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "fix_ave_histo.html">fix ave/histo</A></TD><TD > global/per-atom/local scalars and vectors</TD><TD > global array, file</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "fix_ave_correlate.html">fix ave/correlate</A></TD><TD > global scalars</TD><TD > global array, file</TD><TD ></TD></TR>
 <TR><TD ><A HREF = "fix_store_state.html">fix store/state</A></TD><TD > per-atom vectors</TD><TD > per-atom vector/array</TD><TD ></TD></TR>
 <TR><TD >
 </TD></TR></TABLE></DIV>
 
 <HR>
 
 <A NAME = "4_16"></A><H4>4.16 Thermostatting, barostatting, and computing temperature 
 </H4>
 <P>Thermostatting means controlling the temperature of particles in an MD
 simulation.  Barostatting means controlling the pressure.  Since the
 pressure includes a kinetic component due to particle velocities, both
 these operations require calculation of the temperature.  Typically a
 target temperature (T) and/or pressure (P) is specified by the user,
 and the thermostat or barostat attempts to equilibrate the system to
 the requested T and/or P.
 </P>
 <P>Temperature is computed as kinetic energy divided by some number of
 degrees of freedom (and the Boltzmann constant).  Since kinetic energy
 is a function of particle velocity, there is often a need to
 distinguish between a particle's advection velocity (due to some
 aggregate motiion of particles) and its thermal velocity.  The sum of
 the two is the particle's total velocity, but the latter is often what
 is wanted to compute a temperature.
 </P>
 <P>LAMMPS has several options for computing temperatures, any of which
 can be used in thermostatting and barostatting.  These <A HREF = "compute.html">compute
 commands</A> calculate temperature, and the <A HREF = "compute_pressure.html">compute
 pressure</A> command calculates pressure.
 </P>
 <UL><LI><A HREF = "compute_temp.html">compute temp</A>
 <LI><A HREF = "compute_temp_sphere.html">compute temp/sphere</A>
 <LI><A HREF = "compute_temp_asphere.html">compute temp/asphere</A>
 <LI><A HREF = "compute_temp_com.html">compute temp/com</A>
 <LI><A HREF = "compute_temp_deform.html">compute temp/deform</A>
 <LI><A HREF = "compute_temp_partial.html">compute temp/partial</A>
 <LI><A HREF = "compute_temp_profile.html">compute temp/profile</A>
 <LI><A HREF = "compute_temp_ramp.html">compute temp/ramp</A>
 <LI><A HREF = "compute_temp_region.html">compute temp/region</A> 
 </UL>
 <P>All but the first 3 calculate velocity biases (i.e. advection
 velocities) that are removed when computing the thermal temperature.
 <A HREF = "compute_temp_sphere.html">Compute temp/sphere</A> and <A HREF = "compute_temp_asphere.html">compute
 temp/asphere</A> compute kinetic energy for
 extended particles that includes rotational degrees of freedom.  They
 both allow, as an extra argument, which is another temperature compute
 that subtracts a velocity bias.  This allows the translational
 velocity of extended spherical or aspherical particles to be adjusted
 in prescribed ways.
 </P>
 <P>Thermostatting in LAMMPS is performed by <A HREF = "fix.html">fixes</A>, or in one
 case by a pair style.  Four thermostatting fixes are currently
 available: Nose-Hoover (nvt), Berendsen, Langevin, and direct
 rescaling (temp/rescale).  Dissipative particle dynamics (DPD)
 thermostatting can be invoked via the <I>dpd/tstat</I> pair style:
 </P>
 <UL><LI><A HREF = "fix_nh.html">fix nvt</A>
 <LI><A HREF = "fix_nvt_sphere.html">fix nvt/sphere</A>
 <LI><A HREF = "fix_nvt_asphere.html">fix nvt/asphere</A>
 <LI><A HREF = "fix_nvt_sllod.html">fix nvt/sllod</A>
 <LI><A HREF = "fix_temp_berendsen.html">fix temp/berendsen</A>
 <LI><A HREF = "fix_langevin.html">fix langevin</A>
 <LI><A HREF = "fix_temp_rescale.html">fix temp/rescale</A>
 <LI><A HREF = "pair_dpd.html">pair_style dpd/tstat</A> 
 </UL>
 <P><A HREF = "fix_nh.html">Fix nvt</A> only thermostats the translational velocity of
 particles.  <A HREF = "fix_nvt_sllod.html">Fix nvt/sllod</A> also does this, except
 that it subtracts out a velocity bias due to a deforming box and
 integrates the SLLOD equations of motion.  See the <A HREF = "#4_13">NEMD
 simulations</A> section of this page for further details.  <A HREF = "fix_nvt_sphere.html">Fix
 nvt/sphere</A> and <A HREF = "fix_nvt_asphere.html">fix
 nvt/asphere</A> thermostat not only translation
 velocities but also rotational velocities for spherical and aspherical
 particles.
 </P>
 <P>DPD thermostatting alters pairwise interactions in a manner analagous
 to the per-particle thermostatting of <A HREF = "fix_langevin.html">fix
 langevin</A>.
 </P>
 <P>Any of the thermostatting fixes can use temperature computes that
 remove bias for two purposes: (a) computing the current temperature to
 compare to the requested target temperature, and (b) adjusting only
 the thermal temperature component of the particle's velocities.  See
 the doc pages for the individual fixes and for the
 <A HREF = "fix_modify.html">fix_modify</A> command for instructions on how to assign
 a temperature compute to a thermostatting fix.  For example, you can
 apply a thermostat to only the x and z components of velocity by using
 it in conjunction with <A HREF = "compute_temp_partial.html">compute
 temp/partial</A>.
 </P>
 <P>IMPORTANT NOTE: Only the nvt fixes perform time integration, meaning
 they update the velocities and positions of particles due to forces
 and velocities respectively.  The other thermostat fixes only adjust
 velocities; they do NOT perform time integration updates.  Thus they
 should be used in conjunction with a constant NVE integration fix such
 as these:
 </P>
 <UL><LI><A HREF = "fix_nve.html">fix nve</A>
 <LI><A HREF = "fix_nve_sphere.html">fix nve/sphere</A>
 <LI><A HREF = "fix_nve_asphere.html">fix nve/asphere</A> 
 </UL>
 <P>Barostatting in LAMMPS is also performed by <A HREF = "fix.html">fixes</A>.  Two
 barosttating methods are currently available: Nose-Hoover (npt and
 nph) and Berendsen:
 </P>
 <UL><LI><A HREF = "fix_nh.html">fix npt</A>
 <LI><A HREF = "fix_npt_sphere.html">fix npt/sphere</A>
 <LI><A HREF = "fix_npt_asphere.html">fix npt/asphere</A>
 <LI><A HREF = "fix_nh.html">fix nph</A>
 <LI><A HREF = "fix_press_berendsen.html">fix press/berendsen</A> 
 </UL>
 <P>The <A HREF = "fix_nh.html">fix npt</A> commands include a Nose-Hoover thermostat
 and barostat.  <A HREF = "fix_nh.html">Fix nph</A> is just a Nose/Hoover barostat;
 it does no thermostatting.  Both <A HREF = "fix_nh.html">fix nph</A> and <A HREF = "fix_press_berendsen.html">fix
 press/bernendsen</A> can be used in conjunction
 with any of the thermostatting fixes.
 </P>
 <P>As with the thermostats, <A HREF = "fix_nh.html">fix npt</A> and <A HREF = "fix_nh.html">fix
 nph</A> only use translational motion of the particles in
 computing T and P and performing thermo/barostatting.  <A HREF = "fix_npt_sphere.html">Fix
 npt/sphere</A> and <A HREF = "fix_npt_asphere.html">fix
 npt/asphere</A> thermo/barostat using not only
 translation velocities but also rotational velocities for spherical
 and aspherical particles.
 </P>
 <P>All of the barostatting fixes use the <A HREF = "compute_pressure.html">compute
 pressure</A> compute to calculate a current
 pressure.  By default, this compute is created with a simple <A HREF = "compute_temp.html">compute
 temp</A> (see the last argument of the <A HREF = "compute_pressure.html">compute
 pressure</A> command), which is used to calculated
 the kinetic componenet of the pressure.  The barostatting fixes can
 also use temperature computes that remove bias for the purpose of
 computing the kinetic componenet which contributes to the current
 pressure.  See the doc pages for the individual fixes and for the
 <A HREF = "fix_modify.html">fix_modify</A> command for instructions on how to assign
 a temperature or pressure compute to a barostatting fix.
 </P>
 <P>IMPORTANT NOTE: As with the thermostats, the Nose/Hoover methods (<A HREF = "fix_nh.html">fix
 npt</A> and <A HREF = "fix_nh.html">fix nph</A>) perform time
 integration.  <A HREF = "fix_press_berendsen.html">Fix press/berendsen</A> does NOT,
 so it should be used with one of the constant NVE fixes or with one of
 the NVT fixes.
 </P>
 <P>Finally, thermodynamic output, which can be setup via the
 <A HREF = "thermo_style.html">thermo_style</A> command, often includes temperature
 and pressure values.  As explained on the doc page for the
 <A HREF = "thermo_style.html">thermo_style</A> command, the default T and P are
 setup by the thermo command itself.  They are NOT the ones associated
 with any thermostatting or barostatting fix you have defined or with
 any compute that calculates a temperature or pressure.  Thus if you
 want to view these values of T and P, you need to specify them
 explicitly via a <A HREF = "thermo_style.html">thermo_style custom</A> command.  Or
 you can use the <A HREF = "thermo_modify.html">thermo_modify</A> command to
 re-define what temperature or pressure compute is used for default
 thermodynamic output.
 </P>
 <HR>
 
 <A NAME = "4_17"></A><H4>4.17 Walls 
 </H4>
 <P>Walls in an MD simulation are typically used to bound particle motion,
 i.e. to serve as a boundary condition.
 </P>
 <P>Walls in LAMMPS can be of rough (made of particles) or idealized
 surfaces.  Ideal walls can be smooth, generating forces only in the
 normal direction, or frictional, generating forces also in the
 tangential direction.
 </P>
 <P>Rough walls, built of particles, can be created in various ways.  The
 particles themselves can be generated like any other particle, via the
 <A HREF = "lattice.html">lattice</A> and <A HREF = "create_atoms.html">create_atoms</A> commands,
 or read in via the <A HREF = "read_data.html">read_data</A> command.
 </P>
 <P>Their motion can be constrained by many different commands, so that
 they do not move at all, move together as a group at constant velocity
 or in response to a net force acting on them, move in a prescribed
 fashion (e.g. rotate around a point), etc.  Note that if a time
 integration fix like <A HREF = "fix_nve.html">fix nve</A> or <A HREF = "fix_nh.html">fix nvt</A>
 is not used with the group that contains wall particles, their
 positions and velocities will not be updated.
 </P>
 <UL><LI><A HREF = "fix_aveforce.html">fix aveforce</A> - set force on particles to average value, so they move together
 <LI><A HREF = "fix_setforce.html">fix setforce</A> - set force on particles to a value, e.g. 0.0
 <LI><A HREF = "fix_freeze.html">fix freeze</A> - freeze particles for use as granular walls
 <LI><A HREF = "fix_nve_noforce.html">fix nve/noforce</A> - advect particles by their velocity, but without force
 <LI><A HREF = "fix_move.html">fix move</A> - prescribe motion of particles by a linear velocity, oscillation, rotation, variable 
 </UL>
 <P>The <A HREF = "fix_move.html">fix move</A> command offers the most generality, since
 the motion of individual particles can be specified with
 <A HREF = "variable.html">variable</A> formula which depends on time and/or the
 particle position.
 </P>
 <P>For rough walls, it may be useful to turn off pairwise interactions
 between wall particles via the <A HREF = "neigh_modify.html">neigh_modify
 exclude</A> command.
 </P>
 <P>Rough walls can also be created by specifying frozen particles that do
 not move and do not interact with mobile particles, and then tethering
 other particles to the fixed particles, via a <A HREF = "bond_style.html">bond</A>.
 The bonded particles do interact with other mobile particles.
 </P>
 <P>Idealized walls can be specified via several fix commands.  <A HREF = "fix_wall_gran.html">Fix
 wall/gran</A> creates frictional walls for use with
 granular particles; all the other commands create smooth walls.
 </P>
 <UL><LI><A HREF = "fix_wall_reflect.html">fix wall/reflect</A> - reflective flat walls
 <LI><A HREF = "fix_wall.html">fix wall/lj93</A> - flat walls, with Lennard-Jones 9/3 potential
 <LI><A HREF = "fix_wall.html">fix wall/lj126</A> - flat walls, with Lennard-Jones 12/6 potential
 <LI><A HREF = "fix_wall.html">fix wall/colloid</A> - flat walls, with <A HREF = "pair_colloid.html">pair_style colloid</A> potential
 <LI><A HREF = "fix_wall.html">fix wall/harmonic</A> - flat walls, with repulsive harmonic spring potential
 <LI><A HREF = "fix_wall_region.html">fix wall/region</A> - use region surface as wall
 <LI><A HREF = "fix_wall_gran.html">fix wall/gran</A> - flat or curved walls with <A HREF = "pair_gran.html">pair_style granular</A> potential 
 </UL>
 <P>The <I>lj93</I>, <I>lj126</I>, <I>colloid</I>, and <I>harmonic</I> styles all allow the
 flat walls to move with a constant velocity, or oscillate in time.
 The <A HREF = "fix_wall_region.html">fix wall/region</A> command offers the most
 generality, since the region surface is treated as a wall, and the
 geometry of the region can be a simple primitive volume (e.g. a
 sphere, or cube, or plane), or a complex volume made from the union
 and intersection of primitive volumes.  <A HREF = "region.html">Regions</A> can also
 specify a volume "interior" or "exterior" to the specified primitive
 shape or <I>union</I> or <I>intersection</I>.  <A HREF = "region.html">Regions</A> can also be
 "dynamic" meaning they move with constant velocity, oscillate, or
 rotate.
 </P>
 <P>The only frictional idealized walls currently in LAMMPS are flat or
 curved surfaces specified by the <A HREF = "fix_wall_gran.html">fix wall/gran</A>
 command.  At some point we plan to allow regoin surfaces to be used as
 frictional walls, as well as triangulated surfaces.
 </P>
 <HR>
 
 <A NAME = "4_18"></A><H4>4.18 Elastic constants 
 </H4>
 <P>Elastic constants characterize the stiffness of a material. The formal
 definition is provided by the linear relation that holds between the
 stress and strain tensors in the limit of infinitesimal deformation.
 In tensor notation, this is expressed as s_ij = C_ijkl * e_kl, where
 the repeated indices imply summation. s_ij are the elements of the
 symmetric stress tensor. e_kl are the elements of the symmetric strain
 tensor. C_ijkl are the elements of the fourth rank tensor of elastic
 constants. In three dimensions, this tensor has 3^4=81 elements. Using
 Voigt notation, the tensor can be written as a 6x6 matrix, where C_ij
 is now the derivative of s_i w.r.t. e_j. Because s_i is itself a
 derivative w.r.t. e_i, it follows that C_ij is also symmetric, with at
 most 7*6/2 = 21 distinct elements.
 </P>
 <P>At zero temperature, it is easy to estimate these derivatives by
 deforming the cell in one of the six directions using the command
 <A HREF = "displace_box.html">displace_box</A> and measuring the change in the
 stress tensor. A general-purpose script that does this is given in the
 examples/elastic directory described in <A HREF = "Section_example.html">this
 section</A>.
 </P>
 <P>Calculating elastic constants at finite temperature is more
 challenging, because it is necessary to run a simulation that perfoms
 time averages of differential properties. One way to do this is to
 measure the change in average stress tensor in an NVT simulations when
 the cell volume undergoes a finite deformation. In order to balance
 the systematic and statistical errors in this method, the magnitude of
 the deformation must be chosen judiciously, and care must be taken to
 fully equilibrate the deformed cell before sampling the stress
 tensor. Another approach is to sample the triclinic cell fluctuations
 that occur in an NPT simulation. This method can also be slow to
 converge and requires careful post-processing <A HREF = "#Shinoda">(Shinoda)</A>
 </P>
 <HR>
 
 <A NAME = "4_19"></A><H4>4.19 Library interface to LAMMPS 
 </H4>
 <P>As described in <A HREF = "Section_start.html#2_4">this section</A>, LAMMPS can be
 built as a library, so that it can be called by another code, used in
 a <A HREF = "Section_howto.html#4_10">coupled manner</A> with other codes, or driven
 through a <A HREF = "Section_python.html">Python interface</A>.
 </P>
 <P>All of these methodologies use a C-style interface to LAMMPS that is
 provided in the files src/library.cpp and src/library.h.  The
 functions therein have a C-style argument list, but contain C++ code
 you could write yourself in a C++ application that was invoking LAMMPS
 directly.  The C++ code in the functions illustrates how to invoke
 internal LAMMPS operations.  Note that LAMMPS classes are defined
 within a LAMMPS namespace (LAMMPS_NS) if you use them from another C++
 application.
 </P>
 <P>Library.cpp contains these 4 functions:
 </P>
 <PRE>void lammps_open(int, char **, MPI_Comm, void **);
 void lammps_close(void *);
 void lammps_file(void *, char *);
 char *lammps_command(void *, char *); 
 </PRE>
 <P>The lammps_open() function is used to initialize LAMMPS, passing in a
 list of strings as if they were <A HREF = "#2_6">command-line arguments</A> when
 LAMMPS is run in stand-alone mode from the command line, and a MPI
 communicator for LAMMPS to run under.  It returns a ptr to the LAMMPS
 object that is created, and which is used in subsequent library calls.
 The lammps_open() function can be called multiple times, to create
 multiple instances of LAMMPS.
 </P>
 <P>LAMMPS will run on the set of processors in the communicator.  This
 means the calling code can run LAMMPS on all or a subset of
 processors.  For example, a wrapper script might decide to alternate
 between LAMMPS and another code, allowing them both to run on all the
 processors.  Or it might allocate half the processors to LAMMPS and
 half to the other code and run both codes simultaneously before
 syncing them up periodically.  Or it might instantiate multiple
 instances of LAMMPS to perform different calculations.
 </P>
 <P>The lammps_close() function is used to shut down an instance of LAMMPS
 and free all its memory.
 </P>
 <P>The lammps_file() and lammps_command() functions are used to pass a
 file or string to LAMMPS as if it were an input script or single
 command in an input script.  Thus the calling code can read or
 generate a series of LAMMPS commands one line at a time and pass it
 thru the library interface to setup a problem and then run it,
 interleaving the lammps_command() calls with other calls to extract
 information from LAMMPS, perform its own operations, or call another
 code's library.
 </P>
 <P>Other useful functions are also included in library.cpp.  For example:
 </P>
 <PRE>void *lammps_extract_global(void *, char *)
 void *lammps_extract_atom(void *, char *)
 void *lammps_extract_compute(void *, char *, int, int)
 void *lammps_extract_fix(void *, char *, int, int, int, int)
 void *lammps_extract_variable(void *, char *, char *)
 int lammps_get_natoms(void *)
 void lammps_get_coords(void *, double *)
 void lammps_put_coords(void *, double *) 
 </PRE>
 <P>These can extract various global or per-atom quantities from LAMMPS as
 well as values calculated by a compute, fix, or variable.  The "get"
 and "put" operations can retrieve and reset atom coordinates.
 See the library.cpp file and its associated header file library.h for
 details.
 </P>
 <P>The key idea of the library interface is that you can write any
 functions you wish to define how your code talks to LAMMPS and add
 them to src/library.cpp and src/library.h, as well as to the <A HREF = "Section_python.html">Python
 interface</A>.  The routines you add can access
 or change any LAMMPS data you wish.  The couple and python directories
 have example C++ and C and Python codes which show how a driver code
 can link to LAMMPS as a library, run LAMMPS on a subset of processors,
 grab data from LAMMPS, change it, and put it back into LAMMPS.
 </P>
 <HR>
 
 <A NAME = "4_20"></A><H4>4.20 Calculating thermal conductivity 
 </H4>
 <P>The thermal conductivity kappa of a material can be measured in at
 least 3 ways using various options in LAMMPS.  (See <A HREF = "Section_howto.html#4_21">this
 section</A> of the manual for an analogous
 discussion for viscosity).  The thermal conducitivity tensor kappa is
 a measure of the propensity of a material to transmit heat energy in a
 diffusive manner as given by Fourier's law
 </P>
 <P>J = -kappa grad(T)
 </P>
 <P>where J is the heat flux in units of energy per area per time and
 grad(T) is the spatial gradient of temperature.  The thermal
 conductivity thus has units of energy per distance per time per degree
 K and is often approximated as an isotropic quantity, i.e. as a
 scalar.
 </P>
 <P>The first method is to setup two thermostatted regions at opposite
 ends of a simulation box, or one in the middle and one at the end of a
 periodic box.  By holding the two regions at different temperatures
 with a <A HREF = "Section_howto.html#4_13">thermostatting fix</A>, the energy added
 to the hot region should equal the energy subtracted from the cold
 region and be proportional to the heat flux moving between the
 regions.  See the paper by <A HREF = "#Ikeshoji">Ikeshoji and Hafskjold</A> for
 details of this idea.  Note that thermostatting fixes such as <A HREF = "fix_nh.html">fix
 nvt</A>, <A HREF = "fix_langevin.html">fix langevin</A>, and <A HREF = "fix_temp_rescale.html">fix
 temp/rescale</A> store the cumulative energy they
 add/subtract.  Alternatively, the <A HREF = "fix_heat.html">fix heat</A> command can
 used in place of thermostats on each of two regions, and the resulting
 temperatures of the two regions monitored with the "compute
 temp/region" command or the temperature profile of the intermediate
 region monitored with the <A HREF = "fix_ave_spatial.html">fix ave/spatial</A> and
 <A HREF = "compute_ke_atom.html">compute ke/atom</A> commands.
 </P>
 <P>The second method is to perform a reverse non-equilibrium MD
 simulation using the <A HREF = "fix_thermal_conductivity.html">fix
 thermal/conductivity</A> command which
 implements the rNEMD algorithm of Muller-Plathe.  Kinetic energy is
 swapped between atoms in two different layers of the simulation box.
 This induces a temperature gradient between the two layers which can
 be monitored with the <A HREF = "fix_ave_spatial.html">fix ave/spatial</A> and
 <A HREF = "compute_ke_atom.html">compute ke/atom</A> commands.  The fix tallies the
 cumulative energy transfer that it performs.  See the <A HREF = "fix_thermal_conductivity.html">fix
 thermal/conductivity</A> command for
 details.
 </P>
 <P>The third method is based on the Green-Kubo (GK) formula which relates
 the ensemble average of the auto-correlation of the heat flux to
 kappa.  The heat flux can be calculated from the fluctuations of
 per-atom potential and kinetic energies and per-atom stress tensor in
 a steady-state equilibrated simulation.  This is in contrast to the
 two preceding non-equilibrium methods, where energy flows continuously
 between hot and cold regions of the simulation box.
 </P>
 <P>The <A HREF = "compute_heat_flux.html">compute heat/flux</A> command can calculate
 the needed heat flux and describes how to implement the Green_Kubo
 formalism using additional LAMMPS commands, such as the <A HREF = "fix_ave_correlate.html">fix
 ave/correlate</A> command to calculate the needed
 auto-correlation.  See the doc page for the <A HREF = "compute_heat_flux.html">compute
 heat/flux</A> command for an example input script
 that calculates the thermal conductivity of solid Ar via the GK
 formalism.
 </P>
 <HR>
 
 <A NAME = "4_21"></A><H4>4.21 Calculating viscosity 
 </H4>
 <P>The shear viscosity eta of a fluid can be measured in at least 3 ways
 using various options in LAMMPS.  (See <A HREF = "Section_howto.html#4_20">this
 section</A> of the manual for an analogous
 discussion for thermal conductivity).  Eta is a measure of the
 propensity of a fluid to transmit momentum in a direction
 perpendicular to the direction of velocity or momentum flow.
 Alternatively it is the resistance the fluid has to being sheared.  It
 is given by
 </P>
 <P>J = -eta grad(Vstream)
 </P>
 <P>where J is the momentum flux in units of momentum per area per time.
 and grad(Vstream) is the spatial gradient of the velocity of the fluid
 moving in another direction, normal to the area through which the
 momentum flows.  Viscosity thus has units of pressure-time.
 </P>
 <P>The first method is to perform a non-equlibrium MD (NEMD) simulation
 by shearing the simulation box via the <A HREF = "fix_deform.html">fix deform</A>
 command, and using the <A HREF = "fix_nvt_sllod.html">fix nvt/sllod</A> command to
 thermostat the fluid via the SLLOD equations of motion.  The velocity
 profile setup in the fluid by this procedure can be monitored by the
 <A HREF = "fix_ave_spatial.html">fix ave/spatial</A> command, which determines
 grad(Vstream) in the equation above.  E.g. the derivative in the
 y-direction of the Vx component of fluid motion or grad(Vstream) =
 dVx/dy.  In this case, the Pxy off-diagonal component of the pressure
 or stress tensor, as calculated by the <A HREF = "compute_pressure.html">compute
 pressure</A> command, can also be monitored, which
 is the J term in the equation above.  See <A HREF = "Section_howto.html#4_13">this
 section</A> of the manual for details on NEMD
 simulations.
 </P>
 <P>The second method is to perform a reverse non-equilibrium MD
 simulation using the <A HREF = "fix_viscosity.html">fix viscosity</A> command which
 implements the rNEMD algorithm of Muller-Plathe.  Momentum in one
 dimension is swapped between atoms in two different layers of the
 simulation box in a different dimension.  This induces a velocity
 gradient which can be monitored with the <A HREF = "fix_ave_spatial.html">fix
 ave/spatial</A> command.  The fix tallies the
 cummulative momentum transfer that it performs.  See the <A HREF = "fix_viscosity.html">fix
 viscosity</A> command for details.
 </P>
 <P>The third method is based on the Green-Kubo (GK) formula which relates
 the ensemble average of the auto-correlation of the stress/pressure
 tensor to eta.  This can be done in a steady-state equilibrated
 simulation which is in contrast to the two preceding non-equilibrium
 methods, where momentum flows continuously through the simulation box.
 </P>
 <P>Here is an example input script that calculates the viscosity of
 liquid Ar via the GK formalism:
 </P>
 <PRE># Sample LAMMPS input script for viscosity of liquid Ar 
 </PRE>
 <PRE>units       real
 variable    T equal 86.4956
 variable    V equal vol
 variable    dt equal 4.0
 variable    p equal 400     # correlation length
 variable    s equal 5       # sample interval
 variable    d equal $p*$s   # dump interval 
 </PRE>
 <PRE># convert from LAMMPS real units to SI 
 </PRE>
 <PRE>variable    kB equal 1.3806504e-23    # [J/K/</B> Boltzmann
 variable    atm2Pa equal 101325.0
 variable    A2m equal 1.0e-10
 variable    fs2s equal 1.0e-15
 variable    convert equal ${atm2Pa}*${atm2Pa}*${fs2s}*${A2m}*${A2m}*${A2m} 
 </PRE>
 <PRE># setup problem 
 </PRE>
 <PRE>dimension    3
 boundary     p p p
 lattice      fcc 5.376 orient x 1 0 0 orient y 0 1 0 orient z 0 0 1
 region       box block 0 4 0 4 0 4
 create_box   1 box
 create_atoms 1 box
 mass	     1 39.948
 pair_style   lj/cut 13.0
 pair_coeff   * * 0.2381 3.405
 timestep     ${dt}
 thermo	     $d 
 </PRE>
 <PRE># equilibration and thermalization 
 </PRE>
 <PRE>velocity     all create $T 102486 mom yes rot yes dist gaussian
 fix          NVT all nvt temp $T $T 10 drag 0.2
 run          8000 
 </PRE>
 <PRE># viscosity calculation, switch to NVE if desired 
 </PRE>
 <PRE>#unfix       NVT
 #fix         NVE all nve 
 </PRE>
 <PRE>reset_timestep 0
 variable     pxy equal pxy
 variable     pxz equal pxz
 variable     pyz equal pyz
 fix          SS all ave/correlate $s $p $d &
              v_pxy v_pxz v_pyz type auto file S0St.dat ave running
 variable     scale equal ${convert}/(${kB}*$T)*$V*$s*${dt}
 variable     v11 equal trap(f_SS[3/</B>)*${scale}
 variable     v22 equal trap(f_SS[4/</B>)*${scale}
 variable     v33 equal trap(f_SS[5/</B>)*${scale}
 thermo_style custom step temp press v_pxy v_pxz v_pyz v_v11 v_v22 v_v33
 run          100000
 variable     v equal (v_v11+v_v22+v_v33)/3.0
 variable     ndens equal count(all)/vol
 print        "average viscosity: $v [Pa.s/</B> @ $T K, ${ndens} /A^3" 
 </PRE>
 <HR>
 
 <HR>
 
 <A NAME = "Berendsen"></A>
 
 <P><B>(Berendsen)</B> Berendsen, Grigera, Straatsma, J Phys Chem, 91,
 6269-6271 (1987).
 </P>
 <A NAME = "Cornell"></A>
 
 <P><B>(Cornell)</B> Cornell, Cieplak, Bayly, Gould, Merz, Ferguson,
 Spellmeyer, Fox, Caldwell, Kollman, JACS 117, 5179-5197 (1995).
 </P>
 <A NAME = "Horn"></A>
 
 <P><B>(Horn)</B> Horn, Swope, Pitera, Madura, Dick, Hura, and Head-Gordon,
 J Chem Phys, 120, 9665 (2004).
 </P>
 <A NAME = "Ikeshoji"></A>
 
 <P><B>(Ikeshoji)</B> Ikeshoji and Hafskjold, Molecular Physics, 81, 251-261
 (1994).
 </P>
 <A NAME = "MacKerell"></A>
 
 <P><B>(MacKerell)</B> MacKerell, Bashford, Bellott, Dunbrack, Evanseck, Field,
 Fischer, Gao, Guo, Ha, et al, J Phys Chem, 102, 3586 (1998).
 </P>
 <A NAME = "Mayo"></A>
 
 <P><B>(Mayo)</B> Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909
 (1990).
 </P>
 <A NAME = "Jorgensen"></A>
 
 <P><B>(Jorgensen)</B> Jorgensen, Chandrasekhar, Madura, Impey, Klein, J Chem
 Phys, 79, 926 (1983).
 </P>
 <A NAME = "Price"></A>
 
 <P><B>(Price)</B> Price and Brooks, J Chem Phys, 121, 10096 (2004).
 </P>
 <A NAME = "Shinoda"></A>
 
 <P><B>(Shinoda)</B> Shinoda, Shiga, and Mikami, Phys Rev B, 69, 134103 (2004).
 </P>
 </HTML>
diff --git a/doc/Section_intro.html b/doc/Section_intro.html
index 5e7cd6e06..f9b00bb68 100644
--- a/doc/Section_intro.html
+++ b/doc/Section_intro.html
@@ -1,624 +1,625 @@
 <HTML>
 <CENTER><A HREF = "Manual.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_start.html">Next Section</A> 
 </CENTER>
 
 
 
 
 
 
 <HR>
 
 <H3>1. Introduction 
 </H3>
 <P>These sections provide an overview of what LAMMPS can and can't do,
 describe what it means for LAMMPS to be an open-source code, and
 acknowledge the funding and people who have contributed to LAMMPS over
 the years.
 </P>
 1.1 <A HREF = "#1_1">What is LAMMPS</A><BR>
 1.2 <A HREF = "#1_2">LAMMPS features</A><BR>
 1.3 <A HREF = "#1_3">LAMMPS non-features</A><BR>
 1.4 <A HREF = "#1_4">Open source distribution</A><BR>
 1.5 <A HREF = "#1_5">Acknowledgments and citations</A> <BR>
 
 <HR>
 
 <A NAME = "1_1"></A><H4>1.1 What is LAMMPS 
 </H4>
 <P>LAMMPS is a classical molecular dynamics code that models an ensemble
 of particles in a liquid, solid, or gaseous state.  It can model
 atomic, polymeric, biological, metallic, granular, and coarse-grained
 systems using a variety of force fields and boundary conditions.
 </P>
 <P>For examples of LAMMPS simulations, see the Publications page of the
 <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>.
 </P>
 <P>LAMMPS runs efficiently on single-processor desktop or laptop
 machines, but is designed for parallel computers.  It will run on any
 parallel machine that compiles C++ and supports the <A HREF = "http://www-unix.mcs.anl.gov/mpi">MPI</A>
 message-passing library.  This includes distributed- or shared-memory
 parallel machines and Beowulf-style clusters.
 </P>
 
 
 <P>LAMMPS can model systems with only a few particles up to millions or
 billions.  See <A HREF = "Section_perf.html">this section</A> for information on LAMMPS
 performance and scalability, or the Benchmarks section of the <A HREF = "http://lammps.sandia.gov">LAMMPS
 WWW Site</A>.
 </P>
 <P>LAMMPS is a freely-available open-source code, distributed under the
 terms of the <A HREF = "http://www.gnu.org/copyleft/gpl.html">GNU Public License</A>, which means you can use or
 modify the code however you wish.  See <A HREF = "#1_4">this section</A> for a brief
 discussion of the open-source philosophy.
 </P>
 
 
 <P>LAMMPS is designed to be easy to modify or extend with new
 capabilities, such as new force fields, atom types, boundary
 conditions, or diagnostics.  See <A HREF = "Section_modify.html">this section</A> for
 more details.
 </P>
 <P>The current version of LAMMPS is written in C++.  Earlier versions
 were written in F77 and F90.  See <A HREF = "Section_history.html">this section</A>
 for more information on different versions.  All versions can be
 downloaded from the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>.
 </P>
 <P>LAMMPS was originally developed under a US Department of Energy CRADA
 (Cooperative Research and Development Agreement) between two DOE labs
 and 3 companies.  It is distributed by <A HREF = "http://www.sandia.gov">Sandia National Labs</A>.
 See <A HREF = "#1_5">this section</A> for more information on LAMMPS funding and
 individuals who have contributed to LAMMPS.
 </P>
 
 
 <P>In the most general sense, LAMMPS integrates Newton's equations of
 motion for collections of atoms, molecules, or macroscopic particles
 that interact via short- or long-range forces with a variety of
 initial and/or boundary conditions.  For computational efficiency
 LAMMPS uses neighbor lists to keep track of nearby particles.  The
 lists are optimized for systems with particles that are repulsive at
 short distances, so that the local density of particles never becomes
 too large.  On parallel machines, LAMMPS uses spatial-decomposition
 techniques to partition the simulation domain into small 3d
 sub-domains, one of which is assigned to each processor.  Processors
 communicate and store "ghost" atom information for atoms that border
 their sub-domain.  LAMMPS is most efficient (in a parallel sense) for
 systems whose particles fill a 3d rectangular box with roughly uniform
 density.  Papers with technical details of the algorithms used in
 LAMMPS are listed in <A HREF = "#1_5">this section</A>.
 </P>
 <HR>
 
 <A NAME = "1_2"></A><H4>1.2 LAMMPS features 
 </H4>
 <P>This section highlights LAMMPS features, with pointers to specific
 commands which give more details.  If LAMMPS doesn't have your
 favorite interatomic potential, boundary condition, or atom type, see
 <A HREF = "Section_modify.html">this section</A>, which describes how you can add it to
 LAMMPS.
 </P>
 <H4>General features 
 </H4>
 <UL><LI>  runs on a single processor or in parallel
 <LI>  distributed-memory message-passing parallelism (MPI)
 <LI>  spatial-decomposition of simulation domain for parallelism
 <LI>  open-source distribution
 <LI>  highly portable C++
 <LI>  optional libraries used: MPI and single-processor FFT
 <LI>  easy to extend with new features and functionality
 <LI>  runs from an input script
 <LI>  syntax for defining and using variables and formulas
 <LI>  syntax for looping over runs and breaking out of loops
 <LI>  run one or multiple simulations simultaneously (in parallel) from one script
 <LI>  build as library, invoke LAMMPS thru library interface or provided Python wrapper
 <LI>  couple with other codes: LAMMPS calls other code, other code calls LAMMPS, umbrella code calls both 
 </UL>
 <H4>Particle and model types 
 </H4>
 <P>(<A HREF = "atom_style.html">atom style</A> command)
 </P>
 <UL><LI>  atoms
 <LI>  coarse-grained particles (e.g. bead-spring polymers)
 <LI>  united-atom polymers or organic molecules
 <LI>  all-atom polymers, organic molecules, proteins, DNA
 <LI>  metals
 <LI>  granular materials
 <LI>  coarse-grained mesoscale models
 <LI>  extended spherical and ellipsoidal particles
 <LI>  point dipolar particles
 <LI>  rigid collections of particles
 <LI>  hybrid combinations of these 
 </UL>
 <H4>Force fields 
 </H4>
 <P>(<A HREF = "pair_style.html">pair style</A>, <A HREF = "bond_style.html">bond style</A>,
 <A HREF = "angle_style.html">angle style</A>, <A HREF = "dihedral_style.html">dihedral style</A>,
 <A HREF = "improper_style.html">improper style</A>, <A HREF = "kspace_style.html">kspace style</A>
 commands)
 </P>
 <UL><LI>  pairwise potentials: Lennard-Jones, Buckingham, Morse, Born-Mayer-Huggins,     Yukawa, soft, class 2 (COMPASS), hydrogen bond, tabulated
 <LI>  charged pairwise potentials: Coulombic, point-dipole
 <LI>  manybody potentials: EAM, Finnis/Sinclair EAM, modified EAM (MEAM),     embedded ion method (EIM), Stillinger-Weber, Tersoff, AI-REBO, ReaxFF, COMB
 <LI>  electron force field (eFF)
 <LI>  coarse-grained potentials: DPD, GayBerne, REsquared, colloidal, DLVO
 <LI>  mesoscopic potentials: granular, Peridynamics
 <LI>  bond potentials: harmonic, FENE, Morse, nonlinear, class 2,     quartic (breakable)
 <LI>  angle potentials: harmonic, CHARMM, cosine, cosine/squared, cosine/periodic,     class 2 (COMPASS)
 <LI>  dihedral potentials: harmonic, CHARMM, multi-harmonic, helix,     class 2 (COMPASS), OPLS
 <LI>  improper potentials: harmonic, cvff, umbrella, class 2 (COMPASS)
 <LI>  polymer potentials: all-atom, united-atom, bead-spring, breakable
 <LI>  water potentials: TIP3P, TIP4P, SPC
 <LI>  implicit solvent potentials: hydrodynamic lubrication, Debye
 <LI>  long-range Coulombics and dispersion: Ewald,     PPPM (similar to particle-mesh Ewald), Ewald/N for long-range Lennard-Jones
 <LI>  force-field compatibility with common CHARMM, AMBER, DREIDING, OPLS, GROMACS, COMPASS options
 <LI>  handful of GPU-enabled pair styles 
 </UL>
 <P>  hybrid potentials: multiple pair, bond, angle, dihedral, improper     potentials can be used in one simulation
   overlaid potentials: superposition of multiple pair potentials
 </P>
 <H4>Atom creation 
 </H4>
 <P>(<A HREF = "read_data.html">read_data</A>, <A HREF = "lattice.html">lattice</A>,
 <A HREF = "create_atoms.html">create_atoms</A>, <A HREF = "delete_atoms.html">delete_atoms</A>,
 <A HREF = "displace_atoms.html">displace_atoms</A>, <A HREF = "replicate.html">replicate</A> commands)
 </P>
 <UL><LI>  read in atom coords from files
 <LI>  create atoms on one or more lattices (e.g. grain boundaries)
 <LI>  delete geometric or logical groups of atoms (e.g. voids)
 <LI>  replicate existing atoms multiple times
 <LI>  displace atoms 
 </UL>
 <H4>Ensembles, constraints, and boundary conditions 
 </H4>
 <P>(<A HREF = "fix.html">fix</A> command) 
 </P>
 <UL><LI>  2d or 3d systems
 <LI>  orthogonal or non-orthogonal (triclinic symmetry) simulation domains
 <LI>  constant NVE, NVT, NPT, NPH, Parinello/Rahman integrators
 <LI>  thermostatting options for groups and geometric regions of atoms
 <LI>  pressure control via Nose/Hoover or Berendsen barostatting in 1 to 3 dimensions
 <LI>  simulation box deformation (tensile and shear)
 <LI>  harmonic (umbrella) constraint forces
 <LI>  rigid body constraints
 <LI>  SHAKE bond and angle constraints
 <LI>  bond breaking, formation, swapping
 <LI>  walls of various kinds
 <LI>  non-equilibrium molecular dynamics (NEMD)
 <LI>  variety of additional boundary conditions and constraints 
 </UL>
 <H4>Integrators 
 </H4>
 <P>(<A HREF = "run.html">run</A>, <A HREF = "run_style.html">run_style</A>, <A HREF = "minimize.html">minimize</A> commands) 
 </P>
 <UL><LI>  velocity-Verlet integrator
 <LI>  Brownian dynamics
 <LI>  rigid body integration
 <LI>  energy minimization via conjugate gradient or steepest descent relaxation
 <LI>  rRESPA hierarchical timestepping 
 </UL>
 <H4>Diagnostics 
 </H4>
 <UL><LI>  see the various flavors of the <A HREF = "fix.html">fix</A> and <A HREF = "compute.html">compute</A> commands 
 </UL>
 <H4>Output 
 </H4>
 <P>(<A HREF = "dump.html">dump</A>, <A HREF = "restart.html">restart</A> commands) 
 </P>
 <UL><LI>  log file of thermodynamic info
 <LI>  text dump files of atom coords, velocities, other per-atom quantities
 <LI>  binary restart files
 <LI>  parallel I/O of dump and restart files
 <LI>  per-atom quantities (energy, stress, centro-symmetry parameter, CNA, etc)
 <LI>  user-defined system-wide (log file) or per-atom (dump file) calculations
 <LI>  spatial and time averaging of per-atom quantities
 <LI>  time averaging of system-wide quantities
 <LI>  atom snapshots in native, XYZ, XTC, DCD, CFG formats 
 </UL>
 <H4>Multi-replica models 
 </H4>
 <P><A HREF = "neb.html">nudged elastic band</A>
 <A HREF = "prd.html">parallel replica dynamics</A>
+<A HREF = "tad.html">temperature accelerated dynamics</A>
 <A HREF = "temper.html">parallel tempering</A>
 </P>
 <H4>Pre- and post-processing 
 </H4>
 <UL><LI>Various pre- and post-processing serial tools are packaged
 with LAMMPS; see these <A HREF = "Section_tools.html">doc pages</A>. 
 
 <LI>Our group has also written and released a separate toolkit called
 <A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">Pizza.py</A> which provides tools for doing setup, analysis,
 plotting, and visualization for LAMMPS simulations.  Pizza.py is
 written in <A HREF = "http://www.python.org">Python</A> and is available for download from <A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">the
 Pizza.py WWW site</A>. 
 </UL>
 
 
 
 
 <H4>Specialized features 
 </H4>
 <P>These are LAMMPS capabilities which you may not think of as typical
 molecular dynamics options:
 </P>
 <UL><LI><A HREF = "fix_srd.html">stochastic rotation dynamics (SRD)</A>
 <LI><A HREF = "fix_imd.html">real-time visualization and interactive MD</A>
 <LI><A HREF = "fix_atc.html">atom-to-continuum coupling</A> with finite elements
 <LI>coupled rigid body integration via the <A HREF = "fix_poems.html">POEMS</A> library
 <LI><A HREF = "pair_dsmc.html">Direct Simulation Monte Carlo</A> for low-density fluids
 <LI><A HREF = "pair_peri.html">Peridynamics mesoscale modeling</A>
 <LI><A HREF = "fix_tmd.html">targeted</A> and <A HREF = "fix_smd.html">steered</A> molecular dynamics
 <LI><A HREF = "fix_ttm.html">two-temperature electron model</A> 
 </UL>
 <HR>
 
 <A NAME = "1_3"></A><H4>1.3 LAMMPS non-features 
 </H4>
 <P>LAMMPS is designed to efficiently compute Newton's equations of motion
 for a system of interacting particles.  Many of the tools needed to
 pre- and post-process the data for such simulations are not included
 in the LAMMPS kernel for several reasons:
 </P>
 <UL><LI>the desire to keep LAMMPS simple
 <LI>they are not parallel operations
 <LI>other codes already do them
 <LI>limited development resources 
 </UL>
 <P>Specifically, LAMMPS itself does not:
 </P>
 <UL><LI>run thru a GUI
 <LI>build molecular systems
 <LI>assign force-field coefficients automagically
 <LI>perform sophisticated analyses of your MD simulation
 <LI>visualize your MD simulation
 <LI>plot your output data 
 </UL>
 <P>A few tools for pre- and post-processing tasks are provided as part of
 the LAMMPS package; they are described in <A HREF = "Section_tools.html">this
 section</A>.  However, many people use other codes or
 write their own tools for these tasks.
 </P>
 <P>As noted above, our group has also written and released a separate
 toolkit called <A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">Pizza.py</A> which addresses some of the listed
 bullets.  It provides tools for doing setup, analysis, plotting, and
 visualization for LAMMPS simulations.  Pizza.py is written in
 <A HREF = "http://www.python.org">Python</A> and is available for download from <A HREF = "http://www.sandia.gov/~sjplimp/pizza.html">the Pizza.py WWW
 site</A>.
 </P>
 <P>LAMMPS requires as input a list of initial atom coordinates and types,
 molecular topology information, and force-field coefficients assigned
 to all atoms and bonds.  LAMMPS will not build molecular systems and
 assign force-field parameters for you.
 </P>
 <P>For atomic systems LAMMPS provides a <A HREF = "create_atoms.html">create_atoms</A>
 command which places atoms on solid-state lattices (fcc, bcc,
 user-defined, etc).  Assigning small numbers of force field
 coefficients can be done via the <A HREF = "pair_coeff.html">pair coeff</A>, <A HREF = "bond_coeff.html">bond
 coeff</A>, <A HREF = "angle_coeff.html">angle coeff</A>, etc commands.
 For molecular systems or more complicated simulation geometries, users
 typically use another code as a builder and convert its output to
 LAMMPS input format, or write their own code to generate atom
 coordinate and molecular topology for LAMMPS to read in.
 </P>
 <P>For complicated molecular systems (e.g. a protein), a multitude of
 topology information and hundreds of force-field coefficients must
 typically be specified.  We suggest you use a program like
 <A HREF = "http://www.scripps.edu/brooks">CHARMM</A> or <A HREF = "http://amber.scripps.edu">AMBER</A> or other molecular builders to setup
 such problems and dump its information to a file.  You can then
 reformat the file as LAMMPS input.  Some of the tools in <A HREF = "Section_tools.html">this
 section</A> can assist in this process.
 </P>
 <P>Similarly, LAMMPS creates output files in a simple format.  Most users
 post-process these files with their own analysis tools or re-format
 them for input into other programs, including visualization packages.
 If you are convinced you need to compute something on-the-fly as
 LAMMPS runs, see <A HREF = "Section_modify.html">this section</A> for a discussion
 of how you can use the <A HREF = "dump.html">dump</A> and <A HREF = "compute.html">compute</A> and
 <A HREF = "fix.html">fix</A> commands to print out data of your choosing.  Keep in
 mind that complicated computations can slow down the molecular
 dynamics timestepping, particularly if the computations are not
 parallel, so it is often better to leave such analysis to
 post-processing codes.
 </P>
 <P>A very simple (yet fast) visualizer is provided with the LAMMPS
 package - see the <A HREF = "Section_tools.html#xmovie">xmovie</A> tool in <A HREF = "Section_tools.html">this
 section</A>.  It creates xyz projection views of
 atomic coordinates and animates them.  We find it very useful for
 debugging purposes.  For high-quality visualization we recommend the
 following packages:
 </P>
 <UL><LI><A HREF = "http://www.ks.uiuc.edu/Research/vmd">VMD</A>
 <LI><A HREF = "http://mt.seas.upenn.edu/Archive/Graphics/A">AtomEye</A>
 <LI><A HREF = "http://pymol.sourceforge.net">PyMol</A>
 <LI><A HREF = "http://www.bmsc.washington.edu/raster3d/raster3d.html">Raster3d</A>
 <LI><A HREF = "http://www.openrasmol.org">RasMol</A> 
 </UL>
 <P>Other features that LAMMPS does not yet (and may never) support are
 discussed in <A HREF = "Section_history.html">this section</A>.
 </P>
 <P>Finally, these are freely-available molecular dynamics codes, most of
 them parallel, which may be well-suited to the problems you want to
 model.  They can also be used in conjunction with LAMMPS to perform
 complementary modeling tasks.
 </P>
 <UL><LI><A HREF = "http://www.scripps.edu/brooks">CHARMM</A>
 <LI><A HREF = "http://amber.scripps.edu">AMBER</A>
 <LI><A HREF = "http://www.ks.uiuc.edu/Research/namd/">NAMD</A>
 <LI><A HREF = "http://www.emsl.pnl.gov/docs/nwchem/nwchem.html">NWCHEM</A>
 <LI><A HREF = "http://www.cse.clrc.ac.uk/msi/software/DL_POLY">DL_POLY</A>
 <LI><A HREF = "http://dasher.wustl.edu/tinker">Tinker</A> 
 </UL>
 
 
 
 
 
 
 
 
 
 
 
 
 <P>CHARMM, AMBER, NAMD, NWCHEM, and Tinker are designed primarily for
 modeling biological molecules.  CHARMM and AMBER use
 atom-decomposition (replicated-data) strategies for parallelism; NAMD
 and NWCHEM use spatial-decomposition approaches, similar to LAMMPS.
 Tinker is a serial code.  DL_POLY includes potentials for a variety of
 biological and non-biological materials; both a replicated-data and
 spatial-decomposition version exist.
 </P>
 <HR>
 
 <A NAME = "1_4"></A><H4>1.4 Open source distribution 
 </H4>
 <P>LAMMPS comes with no warranty of any kind.  As each source file states
 in its header, it is a copyrighted code that is distributed free-of-
 charge, under the terms of the <A HREF = "http://www.gnu.org/copyleft/gpl.html">GNU Public License</A> (GPL).  This
 is often referred to as open-source distribution - see
 <A HREF = "http://www.gnu.org">www.gnu.org</A> or <A HREF = "http://www.opensource.org">www.opensource.org</A> for more
 details.  The legal text of the GPL is in the LICENSE file that is
 included in the LAMMPS distribution.
 </P>
 
 
 
 
 <P>Here is a summary of what the GPL means for LAMMPS users:
 </P>
 <P>(1) Anyone is free to use, modify, or extend LAMMPS in any way they
 choose, including for commercial purposes.
 </P>
 <P>(2) If you distribute a modified version of LAMMPS, it must remain
 open-source, meaning you distribute it under the terms of the GPL.
 You should clearly annotate such a code as a derivative version of
 LAMMPS.
 </P>
 <P>(3) If you release any code that includes LAMMPS source code, then it
 must also be open-sourced, meaning you distribute it under the terms
 of the GPL.
 </P>
 <P>(4) If you give LAMMPS files to someone else, the GPL LICENSE file and
 source file headers (including the copyright and GPL notices) should
 remain part of the code.
 </P>
 <P>In the spirit of an open-source code, these are various ways you can
 contribute to making LAMMPS better.  You can send email to the
 <A HREF = "http://lammps.sandia.gov/authors.html">developers</A> on any of these
 items.
 </P>
 <UL><LI>Point prospective users to the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>.  Mention it in
 talks or link to it from your WWW site. 
 
 <LI>If you find an error or omission in this manual or on the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW
 Site</A>, or have a suggestion for something to clarify or include,
 send an email to the
 <A HREF = "http://lammps.sandia.gov/authors.html">developers</A>. 
 
 <LI>If you find a bug, <A HREF = "Section_errors.html#10_2">this section</A> describes
 how to report it. 
 
 <LI>If you publish a paper using LAMMPS results, send the citation (and
 any cool pictures or movies if you like) to add to the Publications,
 Pictures, and Movies pages of the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>, with links
 and attributions back to you. 
 
 <LI>Create a new Makefile.machine that can be added to the src/MAKE
 directory. 
 
 <LI>The tools sub-directory of the LAMMPS distribution has various
 stand-alone codes for pre- and post-processing of LAMMPS data.  More
 details are given in <A HREF = "Section_tools.html">this section</A>.  If you write
 a new tool that users will find useful, it can be added to the LAMMPS
 distribution. 
 
 <LI>LAMMPS is designed to be easy to extend with new code for features
 like potentials, boundary conditions, diagnostic computations, etc.
 <A HREF = "Section_modify.html">This section</A> gives details.  If you add a
 feature of general interest, it can be added to the LAMMPS
 distribution. 
 
 <LI>The Benchmark page of the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> lists LAMMPS
 performance on various platforms.  The files needed to run the
 benchmarks are part of the LAMMPS distribution.  If your machine is
 sufficiently different from those listed, your timing data can be
 added to the page. 
 
 <LI>You can send feedback for the User Comments page of the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW
 Site</A>.  It might be added to the page.  No promises. 
 
 <LI>Cash.  Small denominations, unmarked bills preferred.  Paper sack OK.
 Leave on desk.  VISA also accepted.  Chocolate chip cookies
 encouraged. 
 </UL>
 <HR>
 
 <H4><A NAME = "1_5"></A>1.5 Acknowledgments and citations 
 </H4>
 <P>LAMMPS development has been funded by the <A HREF = "http://www.doe.gov">US Department of
 Energy</A> (DOE), through its CRADA, LDRD, ASCI, and Genomes-to-Life
 programs and its <A HREF = "http://www.sc.doe.gov/ascr/home.html">OASCR</A> and <A HREF = "http://www.er.doe.gov/production/ober/ober_top.html">OBER</A> offices.
 </P>
 <P>Specifically, work on the latest version was funded in part by the US
 Department of Energy's Genomics:GTL program
 (<A HREF = "http://www.doegenomestolife.org">www.doegenomestolife.org</A>) under the <A HREF = "http://www.genomes2life.org">project</A>, "Carbon
 Sequestration in Synechococcus Sp.: From Molecular Machines to
 Hierarchical Modeling".
 </P>
 
 
 
 
 
 
 
 
 
 
 <P>The following papers describe the parallel algorithms used in LAMMPS.
 </P>
 <P>S. J. Plimpton, <B>Fast Parallel Algorithms for Short-Range Molecular
 Dynamics</B>, J Comp Phys, 117, 1-19 (1995).
 </P>
 <P>S. J. Plimpton, R. Pollock, M. Stevens, <B>Particle-Mesh Ewald and
 rRESPA for Parallel Molecular Dynamics Simulations</B>, in Proc of the
 Eighth SIAM Conference on Parallel Processing for Scientific
 Computing, Minneapolis, MN (March 1997).
 </P>
 <P>If you use LAMMPS results in your published work, please cite the J
 Comp Phys reference and include a pointer to the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>
 (http://lammps.sandia.gov).
 </P>
 <P>If you send is information about your publication, we'll be pleased to
 add it to the Publications page of the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A>.  Ditto
 for a picture or movie for the Pictures or Movies pages.
 </P>
 <P>The core group of LAMMPS developers is at Sandia National Labs.  They
 include <A HREF = "http://www.sandia.gov/~sjplimp">Steve Plimpton</A>, Paul Crozier, and Aidan Thompson and can
 be contacted via email: sjplimp, pscrozi, athomps at sandia.gov.
 </P>
 <P>Here are various folks who have made significant contributions to
 features in LAMMPS.  The most recent contributions are at the top of
 the list.
 </P>
 
 
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR><TD >ipp Perl script tool </TD><TD > Reese Jones (Sandia)</TD></TR>
 <TR><TD >eam_database and createatoms tools </TD><TD > Xiaowang Zhou (Sandia)</TD></TR>
 <TR><TD >electron force field (eFF) </TD><TD > Andres Jaramillo-Botero and Julius Su (Caltech)</TD></TR>
 <TR><TD >embedded ion method (EIM) potential </TD><TD > Xiaowang Zhou (Sandia)</TD></TR>
 <TR><TD >COMB potential with charge equilibration </TD><TD > Tzu-Ray Shan (U Florida)</TD></TR>
 <TR><TD >fix ave/correlate </TD><TD >  Benoit Leblanc, Dave Rigby, Paul Saxe (Materials Design) and Reese Jones (Sandia)</TD></TR>
 <TR><TD >pair_style peri/lps </TD><TD > Mike Parks (Sandia)</TD></TR>
 <TR><TD >fix msst </TD><TD > Lawrence Fried (LLNL), Evan Reed (LLNL, Stanford)</TD></TR>
 <TR><TD >thermo_style custom tpcpu & spcpu keywords </TD><TD > Axel Kohlmeyer (Temple U) </TD></TR>
 <TR><TD >fix rigid/nve, fix rigid/nvt </TD><TD > Tony Sheh and Trung Dac Nguyen (U Michigan)</TD></TR>
 <TR><TD >public SVN & Git repositories for LAMMPS </TD><TD > Axel Kohlmeyer (Temple U) and Bill Goldman (Sandia)</TD></TR>
 <TR><TD >fix nvt, fix nph, fix npt, Parinello/Rahman dynamics, fix box/relax </TD><TD > Aidan Thompson (Sandia)</TD></TR>
 <TR><TD >compute heat/flux </TD><TD > German Samolyuk (ORNL) and Mario Pinto (Computational Research Lab, Pune, India)</TD></TR>
 <TR><TD >pair yukawa/colloid </TD><TD > Randy Schunk (Sandia)</TD></TR>
 <TR><TD >fix wall/colloid </TD><TD > Jeremy Lechman (Sandia)</TD></TR>
 <TR><TD >pair_style dsmc for Direct Simulation Monte Carlo (DSMC) modeling </TD><TD > Paul Crozier (Sandia)</TD></TR>
 <TR><TD >fix imd for real-time viz and interactive MD </TD><TD > Axel Kohlmeyer (Temple Univ)</TD></TR>
 <TR><TD >concentration-dependent EAM potential </TD><TD > Alexander Stukowski (Technical University of Darmstadt)</TD></TR>
 <TR><TD >parallel replica dymamics (PRD) </TD><TD > Mike Brown (Sandia)</TD></TR>
 <TR><TD >min_style hftn </TD><TD > Todd Plantenga (Sandia)</TD></TR>
 <TR><TD >fix atc </TD><TD > Reese Jones, Jon Zimmerman, Jeremy Templeton (Sandia)</TD></TR>
 <TR><TD >dump cfg </TD><TD > Liang Wan (Chinese Academy of Sciences)</TD></TR>
 <TR><TD >fix nvt with Nose/Hoover chains </TD><TD > Andy Ballard (U Maryland)</TD></TR>
 <TR><TD >pair_style lj/cut/gpu, pair_style gayberne/gpu </TD><TD > Mike Brown (Sandia)</TD></TR>
 <TR><TD >pair_style lj96/cut, bond_style table, angle_style table </TD><TD > Chuanfu Luo</TD></TR>
 <TR><TD >fix langevin tally </TD><TD > Carolyn Phillips (U Michigan)</TD></TR>
 <TR><TD >compute heat/flux for Green-Kubo </TD><TD > Reese Jones (Sandia), Philip Howell (Siemens), Vikas Varsney (AFRL)</TD></TR>
 <TR><TD >region cone </TD><TD > Pim Schravendijk</TD></TR>
 <TR><TD >fix reax/bonds </TD><TD > Aidan Thompson (Sandia)</TD></TR>
 <TR><TD >pair born/coul/long </TD><TD > Ahmed Ismail (Sandia)</TD></TR>
 <TR><TD >fix ttm </TD><TD > Paul Crozier (Sandia) and Carolyn Phillips (U Michigan)</TD></TR>
 <TR><TD >fix box/relax </TD><TD > Aidan Thompson and David Olmsted (Sandia)</TD></TR>
 <TR><TD >ReaxFF potential </TD><TD > Aidan Thompson (Sandia) and Hansohl Cho (MIT)</TD></TR>
 <TR><TD >compute cna/atom </TD><TD > Wan Liang (Chinese Academy of Sciences)</TD></TR>
 <TR><TD >Tersoff/ZBL potential </TD><TD > Dave Farrell (Northwestern U)</TD></TR>
 <TR><TD >peridynamics </TD><TD > Mike Parks (Sandia)</TD></TR>
 <TR><TD >fix smd for steered MD </TD><TD > Axel Kohlmeyer (U Penn)</TD></TR>
 <TR><TD >GROMACS pair potentials </TD><TD > Mark Stevens (Sandia)</TD></TR>
 <TR><TD >lmp2vmd tool </TD><TD > Axel Kohlmeyer (U Penn)</TD></TR>
 <TR><TD >compute group/group </TD><TD > Naveen Michaud-Agrawal (Johns Hopkins U)</TD></TR>
 <TR><TD >CG-CMM user package for coarse-graining </TD><TD > Axel Kohlmeyer (U Penn)</TD></TR>
 <TR><TD >cosine/delta angle potential </TD><TD > Axel Kohlmeyer (U Penn)</TD></TR>
 <TR><TD >VIM editor add-ons for LAMMPS input scripts </TD><TD > Gerolf Ziegenhain</TD></TR>
 <TR><TD >pair lubricate </TD><TD > Randy Schunk (Sandia)</TD></TR>
 <TR><TD >compute ackland/atom </TD><TD > Gerolf Zeigenhain</TD></TR>
 <TR><TD >kspace_style ewald/n, pair_style lj/coul, pair_style buck/coul </TD><TD >   Pieter in 't Veld (Sandia)</TD></TR>
 <TR><TD >AI-REBO bond-order potential </TD><TD > Ase Henry (MIT)</TD></TR>
 <TR><TD >making LAMMPS a true "object" that can be instantiated multiple times,   e.g. as a library </TD><TD > Ben FrantzDale (RPI)</TD></TR>
 <TR><TD >pymol_asphere viz tool </TD><TD > Mike Brown (Sandia)</TD></TR>
 <TR><TD >NEMD SLLOD integration </TD><TD > Pieter in 't Veld (Sandia)</TD></TR>
 <TR><TD >tensile and shear deformations </TD><TD > Pieter in 't Veld (Sandia)</TD></TR>
 <TR><TD >GayBerne potential </TD><TD > Mike Brown (Sandia)</TD></TR>
 <TR><TD >ellipsoidal particles </TD><TD > Mike Brown (Sandia)</TD></TR>
 <TR><TD >colloid potentials </TD><TD > Pieter in 't Veld (Sandia)</TD></TR>
 <TR><TD >fix heat </TD><TD > Paul Crozier and Ed Webb (Sandia)</TD></TR>
 <TR><TD >neighbor multi and communicate multi </TD><TD > Pieter in 't Veld (Sandia)</TD></TR>
 <TR><TD >MATLAB post-processing scripts </TD><TD > Arun Subramaniyan (Purdue)</TD></TR>
 <TR><TD >triclinic (non-orthogonal) simulation domains </TD><TD > Pieter in 't Veld (Sandia)</TD></TR>
 <TR><TD >thermo_extract tool</TD><TD > Vikas Varshney (Wright Patterson AFB)</TD></TR>
 <TR><TD >fix ave/time and fix ave/spatial </TD><TD > Pieter in 't Veld (Sandia)</TD></TR>
 <TR><TD >MEAM potential </TD><TD > Greg Wagner (Sandia)</TD></TR>
 <TR><TD >optimized pair potentials for lj/cut, charmm/long, eam, morse </TD><TD >   James Fischer (High Performance Technologies),   David Richie and Vincent Natoli (Stone Ridge Technologies)</TD></TR>
 <TR><TD >fix wall/lj126 </TD><TD > Mark Stevens (Sandia)</TD></TR>
 <TR><TD >Stillinger-Weber and Tersoff potentials </TD><TD > Aidan Thompson and Xiaowang Zhou (Sandia)</TD></TR>
 <TR><TD >region prism </TD><TD > Pieter in 't Veld (Sandia)</TD></TR>
 <TR><TD >LJ tail corrections for energy/pressure </TD><TD > Paul Crozier (Sandia)</TD></TR>
 <TR><TD >fix momentum and recenter </TD><TD > Naveen Michaud-Agrawal (Johns Hopkins U)</TD></TR>
 <TR><TD >multi-letter variable names </TD><TD > Naveen Michaud-Agrawal (Johns Hopkins U)</TD></TR>
 <TR><TD >OPLS dihedral potential</TD><TD > Mark Stevens (Sandia)</TD></TR>
 <TR><TD >POEMS coupled rigid body integrator</TD><TD > Rudranarayan Mukherjee (RPI)</TD></TR>
 <TR><TD >faster pair hybrid potential</TD><TD > James Fischer   (High Performance Technologies, Inc), Vincent Natoli and   David Richie (Stone Ridge Technology)</TD></TR>
 <TR><TD >breakable bond quartic potential</TD><TD > Chris Lorenz and Mark Stevens (Sandia)</TD></TR>
 <TR><TD >DCD and XTC dump styles</TD><TD > Naveen Michaud-Agrawal (Johns Hopkins U)</TD></TR>
 <TR><TD >grain boundary orientation fix </TD><TD > Koenraad Janssens and David Olmsted (Sandia)</TD></TR>
 <TR><TD >lj/smooth pair potential </TD><TD > Craig Maloney (UCSB) </TD></TR>
 <TR><TD >radius-of-gyration spring fix </TD><TD > Naveen Michaud-Agrawal (Johns Hopkins U) and   Paul Crozier (Sandia)</TD></TR>
 <TR><TD >self spring fix </TD><TD > Naveen Michaud-Agrawal (Johns Hopkins U)</TD></TR>
 <TR><TD >EAM CoAl and AlCu potentials </TD><TD > Kwang-Reoul Lee (KIST, Korea)</TD></TR>
 <TR><TD >cosine/squared angle potential </TD><TD > Naveen Michaud-Agrawal (Johns Hopkins U)</TD></TR>
 <TR><TD >helix dihedral potential </TD><TD > Naveen Michaud-Agrawal (Johns Hopkins U) and   Mark Stevens (Sandia)</TD></TR>
 <TR><TD >Finnis/Sinclair EAM</TD><TD > Tim Lau (MIT)</TD></TR>
 <TR><TD >dissipative particle dynamics (DPD) potentials</TD><TD > Kurt Smith (U Pitt) and   Frank van Swol (Sandia)</TD></TR>
 <TR><TD >TIP4P potential (4-site water)</TD><TD > Ahmed Ismail and Amalie Frischknecht (Sandia)</TD></TR>
 <TR><TD >uniaxial strain fix</TD><TD > Carsten Svaneborg (Max Planck Institute)</TD></TR>
 <TR><TD >thermodynamics enhanced by fix quantities</TD><TD > Aidan Thompson (Sandia)</TD></TR>
 <TR><TD >compressed dump files</TD><TD > Erik Luijten (U Illinois)</TD></TR>
 <TR><TD >cylindrical indenter fix</TD><TD > Ravi Agrawal (Northwestern U)</TD></TR>
 <TR><TD >electric field fix</TD><TD > Christina Payne (Vanderbilt U)</TD></TR>
 <TR><TD >AMBER <-> LAMMPS tool</TD><TD > Keir Novik (Univ College London) and   Vikas Varshney (U Akron)</TD></TR>
 <TR><TD >CHARMM <-> LAMMPS tool</TD><TD > Pieter in 't Veld and Paul Crozier (Sandia)</TD></TR>
 <TR><TD >Morse bond potential</TD><TD > Jeff Greathouse (Sandia)</TD></TR>
 <TR><TD >radial distribution functions</TD><TD > Paul Crozier & Jeff Greathouse (Sandia)</TD></TR>
 <TR><TD >force tables for long-range Coulombics</TD><TD > Paul Crozier (Sandia)</TD></TR>
 <TR><TD >targeted molecular dynamics (TMD)</TD><TD > Paul Crozier (Sandia) and   Christian Burisch (Bochum University, Germany)</TD></TR>
 <TR><TD >FFT support for SGI SCSL (Altix)</TD><TD > Jim Shepherd (Ga Tech)</TD></TR>
 <TR><TD >lmp2cfg and lmp2traj tools</TD><TD > Ara Kooser, Jeff Greathouse,   Andrey Kalinichev (Sandia)</TD></TR>
 <TR><TD >parallel tempering</TD><TD > Mark Sears (Sandia)</TD></TR>
 <TR><TD >embedded atom method (EAM) potential</TD><TD > Stephen Foiles (Sandia)</TD></TR>
 <TR><TD >multi-harmonic dihedral potential</TD><TD > Mathias Puetz (Sandia)</TD></TR>
 <TR><TD >granular force fields and BC</TD><TD > Leo Silbert & Gary Grest (Sandia)</TD></TR>
 <TR><TD >2d Ewald/PPPM</TD><TD > Paul Crozier (Sandia)</TD></TR>
 <TR><TD >CHARMM force fields</TD><TD > Paul Crozier (Sandia)</TD></TR>
 <TR><TD >msi2lmp tool</TD><TD > Steve Lustig (Dupont), Mike Peachey & John Carpenter (Cray)</TD></TR>
 <TR><TD >HTFN energy minimizer</TD><TD > Todd Plantenga (Sandia)</TD></TR>
 <TR><TD >class 2 force fields</TD><TD > Eric Simon (Cray)</TD></TR>
 <TR><TD >NVT/NPT integrators</TD><TD > Mark Stevens (Sandia)</TD></TR>
 <TR><TD >rRESPA</TD><TD > Mark Stevens & Paul Crozier (Sandia)</TD></TR>
 <TR><TD >Ewald and PPPM solvers</TD><TD > Roy Pollock (LLNL) </TD><TD > 
 </TD></TR></TABLE></DIV>
 
 <P>Other CRADA partners involved in the design and testing of LAMMPS were
 </P>
 <UL><LI>John Carpenter (Mayo Clinic, formerly at Cray Research)
 <LI>Terry Stouch (Lexicon Pharmaceuticals, formerly at Bristol Myers Squibb)
 <LI>Steve Lustig (Dupont)
 <LI>Jim Belak (LLNL) 
 </UL>
 </HTML>
diff --git a/doc/Section_start.html b/doc/Section_start.html
index 4be3c8953..419414938 100644
--- a/doc/Section_start.html
+++ b/doc/Section_start.html
@@ -1,1087 +1,1126 @@
 <HTML>
 <CENTER><A HREF = "Section_intro.html">Previous Section</A> - <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> - <A HREF = "Section_commands.html">Next Section</A> 
 </CENTER>
 
 
 
 
 
 
 <HR>
 
 <H3>2. Getting Started 
 </H3>
 <P>This section describes how to build and run LAMMPS, for both new and
 experienced users.
 </P>
 2.1 <A HREF = "#2_1">What's in the LAMMPS distribution</A><BR>
 2.2 <A HREF = "#2_2">Making LAMMPS</A><BR>
 2.3 <A HREF = "#2_3">Making LAMMPS with optional packages</A><BR>
 2.4 <A HREF = "#2_4">Building LAMMPS as a library</A><BR>
 2.5 <A HREF = "#2_5">Running LAMMPS</A><BR>
 2.6 <A HREF = "#2_6">Command-line options</A><BR>
 2.7 <A HREF = "#2_7">Screen output</A><BR>
 2.8 <A HREF = "#2_8">Running on GPUs</A><BR>
 2.9 <A HREF = "#2_9">Tips for users of previous versions</A> <BR>
 
 <HR>
 
 <H4><A NAME = "2_1"></A>2.1 What's in the LAMMPS distribution 
 </H4>
 <P>When you download LAMMPS you will need to unzip and untar the
 downloaded file with the following commands, after placing the file in
 an appropriate directory.
 </P>
 <PRE>gunzip lammps*.tar.gz 
 tar xvf lammps*.tar 
 </PRE>
 <P>This will create a LAMMPS directory containing two files and several
 sub-directories:
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR><TD >README</TD><TD > text file</TD></TR>
 <TR><TD >LICENSE</TD><TD > the GNU General Public License (GPL)</TD></TR>
 <TR><TD >bench</TD><TD > benchmark problems</TD></TR>
 <TR><TD >couple</TD><TD > code coupling examples, using LAMMPS as a library</TD></TR>
 <TR><TD >doc</TD><TD > documentation</TD></TR>
 <TR><TD >examples</TD><TD > simple test problems</TD></TR>
 <TR><TD >potentials</TD><TD > embedded atom method (EAM) potential files</TD></TR>
 <TR><TD >src</TD><TD > source files</TD></TR>
 <TR><TD >tools</TD><TD > pre- and post-processing tools 
 </TD></TR></TABLE></DIV>
 
 <P>If you download the Windows executable from the download page,
 then you just get a single file:
 </P>
 <PRE>lmp_windows.exe 
 </PRE>
 <P>Skip to the <A HREF = "#2_5">Running LAMMPS</A> section, to learn how to launch this
 executable on a Windows box.
 </P>
 <P>The Windows executable also only includes certain packages and
 bug-fixes/upgrades listed on <A HREF = "http://lammps.sandia.gov/bug.html">this
 page</A> up to a certain date, as
 stated on the download page.  If you want something with more packages
 or that is more current, you'll have to download the source tarball
 and build it yourself, as described in the next section.
 </P>
 <HR>
 
 <H4><A NAME = "2_2"></A>2.2 Making LAMMPS 
 </H4>
 <P>This section has the following sub-sections:
 </P>
 <UL><LI><A HREF = "#2_2_1">Read this first</A>
 <LI><A HREF = "#2_2_2">Building a LAMMPS executable</A>
 <LI><A HREF = "#2_2_3">Common errors that can occur when making LAMMPS</A>
 <LI><A HREF = "#2_2_4">Editing a new low-level Makefile</A>
 <LI><A HREF = "#2_2_5">Additional build tips</A> 
 </UL>
 <HR>
 
 <A NAME = "2_2_1"></A><B><I>Read this first:</I></B> 
 
 <P>Building LAMMPS can be non-trivial.  You will likely need to edit a
 makefile, there are compiler options, additional libraries can be used
 (MPI, FFT), etc.  Please read this section carefully.  If you are not
 comfortable with makefiles, or building codes on a Unix platform, or
 running an MPI job on your machine, please find a local expert to help
 you.  Many compiling, linking, and run problems that users are not
 really LAMMPS issues - they are peculiar to the user's system,
 compilers, libraries, etc.  Such questions are better answered by a
 local expert.
 </P>
 <P>If you have a build problem that you are convinced is a LAMMPS issue
 (e.g. the compiler complains about a line of LAMMPS source code), then
 please send an email to the
 <A HREF = "http://lammps.sandia.gov/authors.html">developers</A>.
 </P>
 <P>If you succeed in building LAMMPS on a new kind of machine, for which
 there isn't a similar Makefile for in the src/MAKE directory, send it
 to the developers and we'll include it in future LAMMPS releases.
 </P>
 <HR>
 
 <A NAME = "2_2_2"></A><B><I>Building a LAMMPS executable:</I></B> 
 
 <P>The src directory contains the C++ source and header files for LAMMPS.
 It also contains a top-level Makefile and a MAKE sub-directory with
 low-level Makefile.* files for several machines.  From within the src
 directory, type "make" or "gmake".  You should see a list of available
 choices.  If one of those is the machine and options you want, you can
 type a command like:
 </P>
 <PRE>make linux
 gmake mac 
 </PRE>
 <P>Note that on a multi-processor or multi-core platform you can launch a
 parallel make, by using the "-j" switch with the make command, which
 will build LAMMPS more quickly.
 </P>
 <P>If you get no errors and an executable like lmp_linux or lmp_mac is
 produced, you're done; it's your lucky day.
 </P>
 <HR>
 
 <A NAME = "2_2_3"></A><B><I>Common errors that can occur when making LAMMPS:</I></B> 
 
 <P>(1) If the make command breaks immediately with errors that indicate
 it can't find files with a "*" in their names, this can be because
 your machine's make doesn't support wildcard expansion in a makefile.
 Try gmake instead of make.  If that doesn't work, try using a -f
 switch with your make command to use Makefile.list which explicitly
 lists all the needed files, e.g.
 </P>
 <PRE>make makelist
 make -f Makefile.list linux
 gmake -f Makefile.list mac 
 </PRE>
 <P>The first "make" command will create a current Makefile.list with all
 the file names in your src dir.  The 2nd "make" command (make or
 gmake) will use it to build LAMMPS.
 </P>
 <P>(2) Other errors typically occur because the low-level Makefile isn't
 setup correctly for your machine.  If your platform is named "foo",
 you will need to create a Makefile.foo in the MAKE sub-directory.  Use
 whatever existing file is closest to your platform as a starting
 point.  See the next section for more instructions.
 </P>
 <P>(3) If you get a link-time error about missing libraries or missing
 dependencies, then it can be because:
 </P>
 <UL><LI>you are including a package that needs an extra library, but have not pre-built the necessary <A HREF = "#2_3_3">package library</A>
 <LI>you are linking to a library that doesn't exist on your system
 <LI>you are not linking to the necessary system library 
 </UL>
 <P>The first issue is discussed below.  The other two issue mean you need
 to edit your low-level Makefile.foo, as discussed in the next
 sub-section.
 </P>
 <HR>
 
 <A NAME = "2_2_4"></A><B><I>Editing a new low-level Makefile.foo:</I></B> 
 
 <P>These are the issues you need to address when editing a low-level
 Makefile for your machine.  The portions of the file you typically
 need to edit are the first line, the "compiler/linker settings"
 section, and the "system-specific settings" section.
 </P>
 <P>(1) Change the first line of Makefile.foo to list the word "foo" after
 the "#", and whatever other options you set.  This is the line you
 will see if you just type "make".
 </P>
 <P>(3) The "compiler/linker settings" section lists compiler and linker
 settings for your C++ compiler, including optimization flags.  You can
 use g++, the open-source GNU compiler, which is available on all Unix
 systems.  You can also use mpicc which will typically be available if
 MPI is installed on your system, though you should check which actual
 compiler it wraps.  Vendor compilers often produce faster code.  On
 boxes with Intel CPUs, we suggest using the free Intel icc compiler,
 which you can download from <A HREF = "http://www.intel.com/software/products/noncom">Intel's compiler site</A>.
 </P>
 
 
 <P>If building a C++ code on your machine requires additional libraries,
 then you should list them as part of the LIB variable.
 </P>
 <P>The DEPFLAGS setting is what triggers the C++ compiler to create a
 dependency list for a source file.  This speeds re-compilation when
 source (*.cpp) or header (*.h) files are edited.  Some compilers do
 not support dependency file creation, or may use a different switch
 than -D.  GNU g++ works with -D.  If your compiler can't create
 dependency files (a long list of errors involving *.d files), then
 you'll need to create a Makefile.foo patterned after Makefile.storm,
 which uses different rules that do not involve dependency files.
 </P>
 <P>(3) The "system-specific settings" section has 4 parts.
 </P>
 <P>(3.a) The LMP_INC variable is used to include options that turn on
 system-dependent ifdefs within the LAMMPS code.
 </P>
 <P>The read_data and dump commands will read/write gzipped files if you
 compile with -DLAMMPS_GZIP.  It requires that your Unix support the
 "popen" command.  Using one of the -DPACK_ARRAY, -DPACK_POINTER, and
 -DPACK_MEMCPY options can make for faster parallel FFTs (in the PPPM
 solver) on some platforms.  The -DPACK_ARRAY setting is the default.
 If you use -DLAMMPS_XDR, the build will include XDR compatibility
 files for doing particle dumps in XTC format.  This is only necessary
 if your platform does have its own XDR files available.  See the
 Restrictions section of the <A HREF = "dump.html">dump</A> command for details.
 </P>
 <P>(3.b) The 3 MPI variables are used to specify an MPI library to build
 LAMMPS with.
 </P>
 <P>If you want LAMMPS to run in parallel, you must have an MPI library
 installed on your platform.  If you use an MPI-wrapped compiler, such
 as "mpicc" to build LAMMPS, you can probably leave these 3 variables
 blank.  If you do not use "mpicc" as your compiler/linker, then you
 need to specify where the mpi.h file (MPI_INC) and the MPI library
 (MPI_PATH) is found and its name (MPI_LIB).
 </P>
 <P>If you are installing MPI yourself, we recommend Argonne's MPICH 1.2
 or 2.0 which can be downloaded from the <A HREF = "http://www-unix.mcs.anl.gov/mpi">Argonne MPI
 site</A>.  LAM MPI should also work.  If
 you are running on a big parallel platform, your system people or the
 vendor should have already installed a version of MPI, which will be
 faster than MPICH or LAM, so find out how to build and link with it.
 If you use MPICH or LAM, you will have to configure and build it for
 your platform.  The MPI configure script should have compiler options
 to enable you to use the same compiler you are using for the LAMMPS
 build, which can avoid problems that can arise when linking LAMMPS to
 the MPI library.
 </P>
 <P>If you just want LAMMPS to run on a single processor, you can use the
 STUBS library in place of MPI, since you don't need an MPI library
 installed on your system.  See the Makefile.serial file for how to
 specify the 3 MPI variables.  You will also need to build the STUBS
 library for your platform before making LAMMPS itself.  From the STUBS
 dir, type "make" and it will hopefully create a libmpi.a suitable for
 linking to LAMMPS.  If this build fails, you will need to edit the
 STUBS/Makefile for your platform.
 </P>
 <P>The file STUBS/mpi.cpp has a CPU timer function MPI_Wtime() that calls
 gettimeofday() .  If your system doesn't support gettimeofday() ,
 you'll need to insert code to call another timer.  Note that the
 ANSI-standard function clock() rolls over after an hour or so, and is
 therefore insufficient for timing long LAMMPS simulations.
 </P>
 <P>(3.c) The 3 FFT variables are used to specify an FFT library which
 LAMMPS uses when using the particle-particle particle-mesh (PPPM)
 option in LAMMPS for long-range Coulombics via the
 <A HREF = "kspace_style.html">kspace_style</A> command.
 </P>
 <P>To use this option, you must have a 1d FFT library installed on your
 platform.  This is specified by a switch of the form -DFFT_XXX where
 XXX = INTEL, DEC, SGI, SCSL, or FFTW.  All but the last one are native
 vendor-provided libraries.  FFTW is a fast, portable library that
 should work on any platform.  You can download it from
 <A HREF = "http://www.fftw.org">www.fftw.org</A>.  Use version 2.1.X, not the newer
 3.0.X.  Building FFTW for your box should be as simple as ./configure;
 make.  Whichever FFT library you have on your platform, you'll need to
 set the appropriate FFT_INC, FFT_PATH, and FFT_LIB variables in
 Makefile.foo.
 </P>
 <P>If you examine src/fft3d.c and src.fft3d.h you'll see it's possible to
 add other vendor FFT libraries via #ifdef statements in the
 appropriate places.  If you successfully add a new FFT option, like
 -DFFT_IBM, please send the LAMMPS developers an email; we'd like to
 add it to LAMMPS.
 </P>
 <P>If you don't plan to use PPPM, you don't need an FFT library.  In this
 case you can set FFT_INC to -DFFT_NONE and leave the other 2 FFT
 variables blank.  Or you can exclude the KSPACE package when you build
 LAMMPS (see below).
 </P>
 <P>(3.d) The several SYSLIB and SYSPATH variables can be ignored unless
 you are building LAMMPS with one or more of the LAMMPS packages that
 require these extra system libraries.  The names of these packages are
 the prefixes on the SYSLIB and SYSPATH variables.  See the <A HREF = "#2_3_4">section
 below</A> for more details.  The SYSLIB variables list the system
 libraries.  The SYSPATH variables are where they are located on your
 machine, which is typically only needed if they are in some
 non-standard place, that is not in your library search path.
 </P>
 <P>That's it.  Once you have a correct Makefile.foo and you have
 pre-built any other libraries it will use (e.g. MPI, FFT, package
 libraries), all you need to do from the src directory is type one of
 these 2 commands:
 </P>
 <PRE>make foo
 gmake foo 
 </PRE>
 <P>You should get the executable lmp_foo when the build is complete.
 </P>
 <HR>
 
 <A NAME = "2_2_5"></A><B><I>Additional build tips:</I></B> 
 
 <P>(1) Building LAMMPS for multiple platforms.
 </P>
 <P>You can make LAMMPS for multiple platforms from the same src
 directory.  Each target creates its own object sub-directory called
 Obj_name where it stores the system-specific *.o files.
 </P>
 <P>(2) Cleaning up.
 </P>
 <P>Typing "make clean-all" or "make clean-foo" will delete *.o object
 files created when LAMMPS is built, for either all builds or for a
 particular machine.
 </P>
 <P>(3) Building for a Mac.
 </P>
 <P>OS X is BSD Unix, so it should just work.  See the Makefile.mac file.
 </P>
 <P>(4) Building for MicroSoft Windows.
 </P>
 <P>The LAMMPS download page has an option to download a pre-built Windows
 exeutable.  See below for instructions for running this executable on
 a Windows box.
 </P>
 <P>If the pre-built executable doesn't have the options you want, then
 you should be able to build LAMMPS from source files on a Windows box.
 I've never done this, but LAMMPS is just standard C++ with MPI and FFT
 calls.  You can use cygwin to build LAMMPS with a Unix make; see
 Makefile.cygwin.  Or you should be able to pull all the source files
 into Visual C++ (ugh) or some similar development environment and
 build it.  In the src/MAKE/Windows directory are some notes from users
 on how they built LAMMPS under Windows, so you can look at their
 instructions for tips.  Good luck - we can't help you on this one.
 </P>
+<P>(5) Changing the size limits in src/lmptype.h
+</P>
+<P>If you are running a very large problem (billions of atoms or more)
+and get a run-time error about the system being too big, either on a
+per-processor basis or in total size, then you may need to change one
+or more settings in src/lmptype.h and re-compile LAMMPS.
+</P>
+<P>As the documentation in that file explains, you have basically
+two choices to make:
+</P>
+<UL><LI>set the data type size of integer atom IDs to 4 or 8 bytes
+<LI>set the data type size of integers that store the total system size to 4 or 8 bytes 
+</UL>
+<P>The default for atom IDs is 4-byte integers since there is a memory
+and communication cost for 8-byte integers.  Non-molecular problems do
+not need atom IDs so this does not restrict their size.  Molecular
+problems (which use IDs to define molecular topology), are limited to
+about 2 billion atoms (2^31) with 4-byte IDs.  With 8-byte IDs they
+are effectively unlimited in size (2^63).
+</P>
+<P>The default for total system size quantities (like the number of atoms
+or timesteps) is 8-byte integers by default which is effectively
+unlimited in size (2^63).  If your system does not support 8-byte
+integers, an error will be generated, and you will need to set
+"bigint" to 4-byte integers.  This restricts your total system size to
+about 2 billion atoms or timesteps (2^31).
+</P>
+<P>Note that in src/lmptype.h there are also settings for the MPI data
+types associated with the integers that store atom IDs and total
+system sizes, which need to be set consistent with the associated C
+data types.
+</P>
+<P>In all cases, the size of problem that can be run on a per-processor
+basis is limited by 4-byte integer storage to about 2 billion atoms
+per processor (2^31), which should not normally be a restriction since
+such a problem would have a huge per-processor memory footprint due to
+neighbor lists and would run very slowly in terms of CPU
+secs/timestep.
+</P>
 <HR>
 
 <H4><A NAME = "2_3"></A>2.3 Making LAMMPS with optional packages 
 </H4>
 <P>This section has the following sub-sections:
 </P>
 <UL><LI><A HREF = "#2_3_1">Package basics</A>
 <LI><A HREF = "#2_3_2">Including/excluding packages</A>
 <LI><A HREF = "#2_3_3">Packages that require extra LAMMPS libraries</A>
 <LI><A HREF = "#2_3_4">Additional Makefile settings for extra libraries</A> 
 </UL>
 <HR>
 
 <A NAME = "2_3_1"></A><B><I>Package basics:</I></B> 
 
 <P>The source code for LAMMPS is structured as a large set of core files
 which are always included, plus optional packages.  Packages are
 groups of files that enable a specific set of features.  For example,
 force fields for molecular systems or granular systems are in
 packages.  You can see the list of all packages by typing "make
 package".
 </P>
 <P>The current list of standard packages is as follows:
 </P>
 <DIV ALIGN=center><TABLE  BORDER=1 >
 <TR><TD >asphere </TD><TD > aspherical particles and force fields</TD></TR>
 <TR><TD >class2 </TD><TD > class 2 force fields</TD></TR>
 <TR><TD >colloid </TD><TD > colloidal particle force fields</TD></TR>
 <TR><TD >dipole </TD><TD > point dipole particles and force fields</TD></TR>
 <TR><TD >dsmc </TD><TD > Direct Simulation Monte Carlo (DMSC) pair style</TD></TR>
 <TR><TD >gpu </TD><TD > GPU-enabled force field styles</TD></TR>
 <TR><TD >granular </TD><TD > force fields and boundary conditions for granular systems</TD></TR>
 <TR><TD >kspace </TD><TD > long-range Ewald and particle-mesh (PPPM) solvers</TD></TR>
 <TR><TD >manybody </TD><TD > metal, 3-body, bond-order potentials</TD></TR>
 <TR><TD >meam </TD><TD > modified embedded atom method (MEAM) potential</TD></TR>
 <TR><TD >molecule </TD><TD > force fields for molecular systems</TD></TR>
 <TR><TD >opt </TD><TD > optimized versions of a few pair potentials</TD></TR>
 <TR><TD >peri </TD><TD > Peridynamics model and potential</TD></TR>
 <TR><TD >poems </TD><TD > coupled rigid body motion</TD></TR>
 <TR><TD >reax </TD><TD > ReaxFF potential</TD></TR>
 <TR><TD >replica </TD><TD > multi-replica methods</TD></TR>
 <TR><TD >shock </TD><TD > methods for MD simulations of shock loading</TD></TR>
 <TR><TD >srd </TD><TD > stochastic rotation dynamics (SRD)</TD></TR>
 <TR><TD >xtc </TD><TD > dump atom snapshots in XTC format 
 </TD></TR></TABLE></DIV>
 
 <P>There are also user-contributed packages which may be as simple as a
 single additional file or many files grouped together which add a
 specific functionality to the code.
 </P>
 <P>The difference between a <I>standard</I> package versus a <I>user</I> package is
 as follows.
 </P>
 <P>Standard packages are supported by the LAMMPS developers and are
 written in a syntax and style consistent with the rest of LAMMPS.
 This means we will answer questions about them, debug and fix them if
 necessary, and keep them compatible with future changes to LAMMPS.
 </P>
 <P>User packages don't necessarily meet these requirements.  If you have
 problems using a feature provided in a user package, you will likely
 need to contact the contributor directly to get help.  Information on
 how to submit additions you make to LAMMPS as a user-contributed
 package is given in <A HREF = "Section_modify.html#package">this section</A> of the
 documentation.
 </P>
 <HR>
 
 <A NAME = "2_3_2"></A><B><I>Including/excluding packages:</I></B> 
 
 <P>Any or all packages can be included or excluded independently BEFORE
 LAMMPS is built.
 </P>
 <P>The two exceptions to this are the "gpu" and "opt" packages.  Some of
 the files in these packages require other packages to also be
 included.  If this is not the case, then those subsidiary files in
 "gpu" and "opt" will not be installed either.  To install all the
 files in package "gpu", the "asphere" and "kspace" packages must also be 
 installed. To install all the files in package "opt", the "kspace" and 
 "manybody" packages must also be installed.
 </P>
 <P>You may wish to exclude certain packages if you will never run certain
 kinds of simulations.  This will keep you from having to build
 auxiliary libraries (see below) and will produce a smaller executable
 which may run a bit faster.
 </P>
 <P>By default, LAMMPS includes only the "kspace", "manybody", and
 "molecule" packages.
 </P>
 <P>Packages are included or excluded by typing "make yes-name" or "make
 no-name", where "name" is the name of the package.  You can also type
 "make yes-standard", "make no-standard", "make yes-user", "make
 no-user", "make yes-all" or "make no-all" to include/exclude various
 sets of packages.  Type "make package" to see the various options.
 </P>
 <P>IMPORTANT NOTE: These make commands work by simply moving files back
 and forth between the main src directory and sub-directories with the
 package name, so that the files are seen or not seen when LAMMPS is
 built.  After you have included or excluded a package, you must
 re-build LAMMPS.
 </P>
 <P>Additional make options exist to help manage LAMMPS files that exist
 in both the src directory and in package sub-directories.  You do not
 normally need to use these commands unless you are editing LAMMPS
 files or have downloaded a patch from the LAMMPS WWW site.
 </P>
 <P>Typing "make package-update" will overwrite src files with files from
 the package directories if the package has been included.  It should
 be used after a patch is installed, since patches only update the
 master package version of a file.  Typing "make package-overwrite"
 will overwrite files in the package directories with src files.
 Typing "make package-check" will list differences between src and
 package versions of the same files.  Again, type "make package" to see
 the various options.
 </P>
 <HR>
 
 <A NAME = "2_3_3"></A><B><I>Packages that require extra LAMMPS libraries:</I></B> 
 
 <P>A few packages (standard or user) require that additional libraries be
 compiled first, which LAMMPS will link to when it builds.  The source
 code for these libraries are included in the LAMMPS distribution under
 the "lib" directory.  Look at the README files in the lib directories
 (e.g. lib/reax/README) for instructions on how to build each library.
 </P>
 <P>IMPORTANT NOTE: If you are including a package in your LAMMPS build
 that uses one of these libraries, then you must build the library
 BEFORE building LAMMPS itself, since the LAMMPS build will attempt to
 link with the library file.
 </P>
 <P>Here is a bit of information about each library:
 </P>
 <P>The "atc" library in lib/atc is used by the user-atc package.  It
 provides continuum field estimation and molecular dynamics-finite
 element coupling methods.  It was written primarily by Reese Jones,
 Jeremy Templeton and Jonathan Zimmerman at Sandia.
 </P>
 <P>The "gpu" library in lib/gpu is used by the gpu package.  It
 contains code to enable portions of LAMMPS to run on a GPU chip
 associated with your CPU.  Currently, only NVIDIA GPUs are supported.
 Building this library requires NVIDIA Cuda tools to be installed on
 your system.  See the <A HREF = "#2_8">Running on GPUs</A> section below for more
 info about installing and using Cuda.
 </P>
 <P>The "meam" library in lib/meam is used by the meam package.
 computes the modified embedded atom method potential, which is a
 generalization of EAM potentials that can be used to model a wider
 variety of materials.  This MEAM implementation was written by Greg
 Wagner at Sandia.  It requires a F90 compiler to build.  The C++ to
 FORTRAN function calls in pair_meam.cpp assumes that FORTRAN object
 names are converted to C object names by appending an underscore
 character. This is generally the case, but on machines that do not
 conform to this convention, you will need to modify either the C++
 code or your compiler settings.
 </P>
 <P>The "poems" library in lib/poems is used by the poems package.
 computes the constrained rigid-body motion of articulated (jointed)
 multibody systems.  POEMS was written and is distributed by Prof Kurt
 Anderson's group at Rensselaer Polytechnic Institute (RPI).
 </P>
 <P>The "reax" library in lib/reax is used by the reax package.  It
 computes the Reactive Force Field (ReaxFF) potential, developed by
 Adri van Duin in Bill Goddard's group at CalTech.  This implementation
 in LAMMPS uses many of Adri's files and was developed by Aidan
 Thompson at Sandia and Hansohl Cho at MIT.  It requires a F77 or F90
 compiler to build.  The C++ to FORTRAN function calls in pair_reax.cpp
 assume that FORTRAN object names are converted to C object names by
 appending an underscore character. This is generally the case, but on
 machines that do not conform to this convention, you will need to
 modify either the C++ code or your compiler settings. The name
 conversion is handled by the preprocessor macro called FORTRAN in
 pair_reax_fortran.h.  Different definitions of this macro can be
 obtained by adding a machine-specific macro definition to the CCFLAGS
 variable in your Makefile e.g. -D_IBM. See pair_reax_fortran.h for
 more info.
 </P>
 <P>As described in its README file, each library is built by typing
 something like
 </P>
 <PRE>make -f Makefile.g++ 
 </PRE>
 <P>in the appropriate directory, e.g. in lib/reax.
 </P>
 <P>You must use a Makefile that is a match for your system.  If one of
 the provided Makefiles is not appropriate for your system you will
 need to edit or add one.  For example, in the case of Fotran-based
 libraries, your system must have a Fortran compiler, the settings for
 which will be in the Makefile.
 </P>
 <HR>
 
 <A NAME = "2_3_4"></A><B><I>Additional Makefile settings for extra libraries:</I></B> 
 
 <P>After the desired library or libraries are built, and the package has
 been included, you can build LAMMPS itself.  For example, from the
 lammps/src directory you would type this, to build LAMMPS with ReaxFF.
 Note that as discussed in the preceding section, the package library
 itself, namely lib/reax/libreax.a, must already have been built, for
 the LAMMPS build to be successful.
 </P>
 <PRE>make yes-reax
 make g++ 
 </PRE>
 <P>Also note that simply building the library is not sufficient to use it
 from LAMMPS.  As in this example, you must also include the package
 that uses and wraps the library before you build LAMMPS itself.
 </P>
 <P>As discussed in point (2.4) of <A HREF = "#2_2_4">this section</A> above, there are
 settings in the low-level Makefile that specify additional system
 libraries needed by individual LAMMPS add-on libraries.  These are the
 settings you must specify correctly in your low-level Makefile in
 lammps/src/MAKE, such as Makefile.foo:
 </P>
 <P>To use the gpu package and library, the settings for gpu_SYSLIB and
 gpu_SYSPATH must be correct.  These are specific to the NVIDIA CUDA
 software which must be installed on your system.
 </P>
 <P>To use the meam or reax packages and their libraries which are Fortran
 based, the settings for meam_SYSLIB, reax_SYSLIB, meam_SYSPATH, and
 reax_SYSPATH must be correct.  This is so that the C++ compiler can
 perform a cross-language link using the appropriate system Fortran
 libraries.
 </P>
 <P>To use the user-atc package and library, the settings for
 user-atc_SYSLIB and user-atc_SYSPATH must be correct.  This is so that
 the appropriate BLAS and LAPACK libs, used by the user-atc library,
 can be found.
 </P>
 <HR>
 
 <H4><A NAME = "2_4"></A>2.4 Building LAMMPS as a library 
 </H4>
 <P>LAMMPS can be built as a library, which can then be called from
 another application or a scripting language.  See <A HREF = "Section_howto.html#4_10">this
 section</A> for more info on coupling LAMMPS to
 other codes.  Building LAMMPS as a library is done by typing
 </P>
 <PRE>make makelib
 make -f Makefile.lib foo 
 </PRE>
 <P>where foo is the machine name.  The first "make" command will create a
 current Makefile.lib with all the file names in your src dir.  The 2nd
 "make" command will use it to build LAMMPS as a library.  This
 requires that Makefile.foo have a library target (lib) and
 system-specific settings for ARCHIVE and ARFLAGS.  See Makefile.linux
 for an example.  The build will create the file liblmp_foo.a which
 another application can link to.
 </P>
 <P>When used from a C++ program, the library allows one or more LAMMPS
 objects to be instantiated.  All of LAMMPS is wrapped in a LAMMPS_NS
 namespace; you can safely use any of its classes and methods from
 within your application code, as needed. 
 </P>
 <P>When used from a C or Fortran program or a scripting language, the
 library has a simple function-style interface, provided in
 src/library.cpp and src/library.h.
 </P>
 <P>See the sample codes couple/simple/simple.cpp and simple.c as examples
 of C++ and C codes that invoke LAMMPS thru its library interface.
 There are other examples as well in the couple directory which are
 discussed in <A HREF = "Section_howto.html#4_10">this section</A> of the manual.
 See <A HREF = "Section_python.html">this section</A> of the manual for a description
 of the Python wrapper provided with LAMMPS that operates through the
 LAMMPS library interface.
 </P>
 <P>The files src/library.cpp and library.h contain the C-style interface
 to LAMMPS.  See <A HREF = "Section_howto.html#4_19">this section</A> of the manual
 for a description of the interface and how to extend it for your
 needs.
 </P>
 <HR>
 
 <H4><A NAME = "2_5"></A>2.5 Running LAMMPS 
 </H4>
 <P>By default, LAMMPS runs by reading commands from stdin; e.g. lmp_linux
 < in.file.  This means you first create an input script (e.g. in.file)
 containing the desired commands.  <A HREF = "Section_commands.html">This section</A>
 describes how input scripts are structured and what commands they
 contain.
 </P>
 <P>You can test LAMMPS on any of the sample inputs provided in the
 examples directory.  Input scripts are named in.* and sample outputs
 are named log.*.name.P where name is a machine and P is the number of
 processors it was run on.
 </P>
 <P>Here is how you might run one of the Lennard-Jones tests on a Linux
 box, using mpirun to launch a parallel job:
 </P>
 <PRE>cd src
 make linux
 cp lmp_linux ../examples/lj
 cd ../examples/lj
 mpirun -np 4 lmp_linux < in.lj.nve 
 </PRE>
 <HR>
 
 <P>On a Windows machine, you can skip making LAMMPS and simply download
 an executable. But note that not all packages are available.
 The following packages are available: asphere, class2, colloid, dipole,
 dsmc, granular, kspace, manybody, molecule, peri, poems, replica, shock,
 user-ackland, user-cd-eam, user-cg-cmm, user-ewaldn, user-smd. But these 
 packages are not available: gpu, meam, opt, reax, xtc, user-atc, user-imd.
 </P>
 <P>To run the LAMMPS executable on a Windows machine, first decide whether 
 you want to download the non-MPI (serial) or the MPI (parallel) version 
 of the executable. Download and save the version you have chosen.
 </P>
 <P>For the non-MPI version, follow these steps:
 </P>
 <UL><LI>Get a command prompt by going to Start->Run... , 
 then typing "cmd". 
 
 <LI>Move to the directory where you have saved lmp_win_no-mpi.exe
 (e.g. by typing: cd "Documents"). 
 
 <LI>At the command prompt, type "lmp_win_no-mpi -in in.lj", replacing in.lj
 with the name of your LAMMPS input script. 
 </UL>
 <P>For the MPI version, which allows you to run LAMMPS under Windows on 
 multiple processors, follow these steps:
 </P>
 <UL><LI>Download and install 
 <A HREF = "http://www.mcs.anl.gov/research/projects/mpich2/downloads/index.php?s=downloads">MPICH2</A>
 for Windows. 
 
 <LI>You'll need to use the mpiexec.exe and smpd.exe files from the MPICH2 package. Put them in 
 same directory (or path) as the LAMMPS Windows executable. 
 
 <LI>Get a command prompt by going to Start->Run... , 
 then typing "cmd". 
 
 <LI>Move to the directory where you have saved lmp_win_mpi.exe
 (e.g. by typing: cd "Documents"). 
 
 <LI>Then type something like this: "mpiexec -np 4 -localonly lmp_win_mpi -in in.lj", 
 replacing in.lj with the name of your LAMMPS input script. 
 
 <LI>Note that you may need to provide smpd with a passphrase --- it doesn't matter what you 
 type. 
 
 <LI>In this mode, output may not immediately show up on the screen, so 
 if your input script takes a long time to execute, you may need to be 
 patient before the output shows up. 
 
 <LI>Alternatively, you can still use this executable to run on a single processor by
 typing something like: "lmp_win_mpi -in in.lj". 
 </UL>
 <HR>
 
 <P>The screen output from LAMMPS is described in the next section.  As it
 runs, LAMMPS also writes a log.lammps file with the same information.
 </P>
 <P>Note that this sequence of commands copies the LAMMPS executable
 (lmp_linux) to the directory with the input files.  This may not be
 necessary, but some versions of MPI reset the working directory to
 where the executable is, rather than leave it as the directory where
 you launch mpirun from (if you launch lmp_linux on its own and not
 under mpirun).  If that happens, LAMMPS will look for additional input
 files and write its output files to the executable directory, rather
 than your working directory, which is probably not what you want.
 </P>
 <P>If LAMMPS encounters errors in the input script or while running a
 simulation it will print an ERROR message and stop or a WARNING
 message and continue.  See <A HREF = "Section_errors.html">this section</A> for a
 discussion of the various kinds of errors LAMMPS can or can't detect,
 a list of all ERROR and WARNING messages, and what to do about them.
 </P>
 <P>LAMMPS can run a problem on any number of processors, including a
 single processor.  In theory you should get identical answers on any
 number of processors and on any machine.  In practice, numerical
 round-off can cause slight differences and eventual divergence of
 molecular dynamics phase space trajectories.
 </P>
 <P>LAMMPS can run as large a problem as will fit in the physical memory
 of one or more processors.  If you run out of memory, you must run on
 more processors or setup a smaller problem.
 </P>
 <HR>
 
 <H4><A NAME = "2_6"></A>2.6 Command-line options 
 </H4>
 <P>At run time, LAMMPS recognizes several optional command-line switches
 which may be used in any order.  For example, lmp_ibm might be
 launched as follows:
 </P>
 <PRE>mpirun -np 16 lmp_ibm -var f tmp.out -log my.log -screen none < in.alloy 
 </PRE>
 <P>These are the command-line options:
 </P>
 <PRE>-echo style 
 </PRE>
 <P>Set the style of command echoing.  The style can be <I>none</I> or <I>screen</I>
 or <I>log</I> or <I>both</I>.  Depending on the style, each command read from
 the input script will be echoed to the screen and/or logfile.  This
 can be useful to figure out which line of your script is causing an
 input error.  The default value is <I>log</I>.  The echo style can also be
 set by using the <A HREF = "echo.html">echo</A> command in the input script itself.
 </P>
 <PRE>-partition 8x2 4 5 ... 
 </PRE>
 <P>Invoke LAMMPS in multi-partition mode.  When LAMMPS is run on P
 processors and this switch is not used, LAMMPS runs in one partition,
 i.e. all P processors run a single simulation.  If this switch is
 used, the P processors are split into separate partitions and each
 partition runs its own simulation.  The arguments to the switch
 specify the number of processors in each partition.  Arguments of the
 form MxN mean M partitions, each with N processors.  Arguments of the
 form N mean a single partition with N processors.  The sum of
 processors in all partitions must equal P.  Thus the command
 "-partition 8x2 4 5" has 10 partitions and runs on a total of 25
 processors.
 </P>
 <P>Note that with MPI installed on a machine (e.g. your desktop), you can
 run on more (virtual) processors than you have physical processors.
 This can be useful for running <A HREF = "Section_howto.html#4_5">multi-replica
 simulations</A>, on one or a few processors.
 </P>
 <P>The input script specifies what simulation is run on which partition;
 see the <A HREF = "variable.html">variable</A> and <A HREF = "next.html">next</A> commands.  This
 <A HREF = "Section_howto.html#4_4">howto section</A> gives examples of how to use
 these commands in this way.  Simulations running on different
 partitions can also communicate with each other; see the
 <A HREF = "temper.html">temper</A> command.
 </P>
 <PRE>-in file 
 </PRE>
 <P>Specify a file to use as an input script.  This is an optional switch
 when running LAMMPS in one-partition mode.  If it is not specified,
 LAMMPS reads its input script from stdin - e.g. lmp_linux < in.run.
 This is a required switch when running LAMMPS in multi-partition mode,
 since multiple processors cannot all read from stdin.
 </P>
 <PRE>-log file 
 </PRE>
 <P>Specify a log file for LAMMPS to write status information to.  In
 one-partition mode, if the switch is not used, LAMMPS writes to the
 file log.lammps.  If this switch is used, LAMMPS writes to the
 specified file.  In multi-partition mode, if the switch is not used, a
 log.lammps file is created with hi-level status information.  Each
 partition also writes to a log.lammps.N file where N is the partition
 ID.  If the switch is specified in multi-partition mode, the hi-level
 logfile is named "file" and each partition also logs information to a
 file.N.  For both one-partition and multi-partition mode, if the
 specified file is "none", then no log files are created.  Using a
 <A HREF = "log.html">log</A> command in the input script will override this setting.
 </P>
 <PRE>-screen file 
 </PRE>
 <P>Specify a file for LAMMPS to write its screen information to.  In
 one-partition mode, if the switch is not used, LAMMPS writes to the
 screen.  If this switch is used, LAMMPS writes to the specified file
 instead and you will see no screen output.  In multi-partition mode,
 if the switch is not used, hi-level status information is written to
 the screen.  Each partition also writes to a screen.N file where N is
 the partition ID.  If the switch is specified in multi-partition mode,
 the hi-level screen dump is named "file" and each partition also
 writes screen information to a file.N.  For both one-partition and
 multi-partition mode, if the specified file is "none", then no screen
 output is performed.
 </P>
 <PRE>-var name value 
 </PRE>
 <P>Specify a variable that will be defined for substitution purposes when
 the input script is read.  "Name" is the variable name which can be a
 single character (referenced as $x in the input script) or a full
 string (referenced as ${abc}).  The value can be any string.  Using
 this command-line option is equivalent to putting the line "variable
 name index value" at the beginning of the input script.  Defining an
 index variable as a command-line argument overrides any setting for
 the same index variable in the input script, since index variables
 cannot be re-defined.  See the <A HREF = "variable.html">variable</A> command for
 more info on defining index and other kinds of variables and <A HREF = "Section_commands.html#3_2">this
 section</A> for more info on using variables in
 input scripts.
 </P>
 <HR>
 
 <H4><A NAME = "2_7"></A>2.7 LAMMPS screen output 
 </H4>
 <P>As LAMMPS reads an input script, it prints information to both the
 screen and a log file about significant actions it takes to setup a
 simulation.  When the simulation is ready to begin, LAMMPS performs
 various initializations and prints the amount of memory (in MBytes per
 processor) that the simulation requires.  It also prints details of
 the initial thermodynamic state of the system.  During the run itself,
 thermodynamic information is printed periodically, every few
 timesteps.  When the run concludes, LAMMPS prints the final
 thermodynamic state and a total run time for the simulation.  It then
 appends statistics about the CPU time and storage requirements for the
 simulation.  An example set of statistics is shown here:
 </P>
 <PRE>Loop time of 49.002 on 2 procs for 2004 atoms 
 </PRE>
 <PRE>Pair   time (%) = 35.0495 (71.5267)
 Bond   time (%) = 0.092046 (0.187841)
 Kspce  time (%) = 6.42073 (13.103)
 Neigh  time (%) = 2.73485 (5.5811)
 Comm   time (%) = 1.50291 (3.06703)
 Outpt  time (%) = 0.013799 (0.0281601)
 Other  time (%) = 2.13669 (4.36041) 
 </PRE>
 <PRE>Nlocal:    1002 ave, 1015 max, 989 min
 Histogram: 1 0 0 0 0 0 0 0 0 1 
 Nghost:    8720 ave, 8724 max, 8716 min 
 Histogram: 1 0 0 0 0 0 0 0 0 1
 Neighs:    354141 ave, 361422 max, 346860 min 
 Histogram: 1 0 0 0 0 0 0 0 0 1 
 </PRE>
 <PRE>Total # of neighbors = 708282
 Ave neighs/atom = 353.434
 Ave special neighs/atom = 2.34032
 Number of reneighborings = 42
 Dangerous reneighborings = 2 
 </PRE>
 <P>The first section gives the breakdown of the CPU run time (in seconds)
 into major categories.  The second section lists the number of owned
 atoms (Nlocal), ghost atoms (Nghost), and pair-wise neighbors stored
 per processor.  The max and min values give the spread of these values
 across processors with a 10-bin histogram showing the distribution.
 The total number of histogram counts is equal to the number of
 processors.
 </P>
 <P>The last section gives aggregate statistics for pair-wise neighbors
 and special neighbors that LAMMPS keeps track of (see the
 <A HREF = "special_bonds.html">special_bonds</A> command).  The number of times
 neighbor lists were rebuilt during the run is given as well as the
 number of potentially "dangerous" rebuilds.  If atom movement
 triggered neighbor list rebuilding (see the
 <A HREF = "neigh_modify.html">neigh_modify</A> command), then dangerous
 reneighborings are those that were triggered on the first timestep
 atom movement was checked for.  If this count is non-zero you may wish
 to reduce the delay factor to insure no force interactions are missed
 by atoms moving beyond the neighbor skin distance before a rebuild
 takes place.
 </P>
 <P>If an energy minimization was performed via the
 <A HREF = "minimize.html">minimize</A> command, additional information is printed,
 e.g.
 </P>
 <PRE>Minimization stats:
   E initial, next-to-last, final = -0.895962 -2.94193 -2.94342
   Gradient 2-norm init/final= 1920.78 20.9992
   Gradient inf-norm init/final= 304.283 9.61216
   Iterations = 36
   Force evaluations = 177 
 </PRE>
 <P>The first line lists the initial and final energy, as well as the
 energy on the next-to-last iteration.  The next 2 lines give a measure
 of the gradient of the energy (force on all atoms).  The 2-norm is the
 "length" of this force vector; the inf-norm is the largest component.
 The last 2 lines are statistics on how many iterations and
 force-evaluations the minimizer required.  Multiple force evaluations
 are typically done at each iteration to perform a 1d line minimization
 in the search direction.
 </P>
 <P>If a <A HREF = "kspace_style.html">kspace_style</A> long-range Coulombics solve was
 performed during the run (PPPM, Ewald), then additional information is
 printed, e.g.
 </P>
 <PRE>FFT time (% of Kspce) = 0.200313 (8.34477)
 FFT Gflps 3d 1d-only = 2.31074 9.19989 
 </PRE>
 <P>The first line gives the time spent doing 3d FFTs (4 per timestep) and
 the fraction it represents of the total KSpace time (listed above).
 Each 3d FFT requires computation (3 sets of 1d FFTs) and communication
 (transposes).  The total flops performed is 5Nlog_2(N), where N is the
 number of points in the 3d grid.  The FFTs are timed with and without
 the communication and a Gflop rate is computed.  The 3d rate is with
 communication; the 1d rate is without (just the 1d FFTs).  Thus you
 can estimate what fraction of your FFT time was spent in
 communication, roughly 75% in the example above.
 </P>
 <HR>
 
 <H4><A NAME = "2_8"></A>2.8 Running on GPUs 
 </H4>
 <P>A few LAMMPS <A HREF = "pair_style.html">pair styles</A> can be run on graphical
 processing units (GPUs).  We plan to add more over time.  Currently,
 they only support NVIDIA GPU cards.  To use them you need to install
 certain NVIDIA CUDA software on your system:
 </P>
 <UL><LI>Check if you have an NVIDIA card: cat /proc/driver/nvidia/cards/0
 <LI>Go to http://www.nvidia.com/object/cuda_get.html
 <LI>Install a driver and toolkit appropriate for your system (SDK is not necessary)
 <LI>Follow the instructions in README in lammps/lib/gpu to build the library.
 <LI>Run lammps/lib/gpu/nvc_get_devices to list supported devices and properties 
 </UL>
 <H4>GPU configuration 
 </H4>
 <P>When using GPUs, you are restricted to one physical GPU per LAMMPS
 process. Multiple processes can share a single GPU and in many cases it
 will be more efficient to run with multiple processes per GPU. Any GPU
 accelerated style requires that <A HREF = "fix_gpu.html">fix gpu</A> be used in the
 input script to select and initialize the GPUs. The format for the fix
 is:
 </P>
 <PRE>fix <I>name</I> all gpu <I>mode</I> <I>first</I> <I>last</I> <I>split</I> 
 </PRE>
 <P>where <I>name</I> is the name for the fix. The gpu fix must be the first
 fix specified for a given run, otherwise the program will exit
 with an error. The gpu fix will not have any effect on runs 
 that do not use GPU acceleration; there should be no problem
 with specifying the fix first in any input script.
 </P>
 <P><I>mode</I> can be either "force" or "force/neigh". In the former,
 neighbor list calculation is performed on the CPU using the
 standard LAMMPS routines. In the latter, the neighbor list
 calculation is performed on the GPU. The GPU neighbor list
 can be used for better performance, however, it 
 should not be used with a triclinic box.
 </P>
 <P>There are cases when it might be more efficient to select the CPU for neighbor
 list builds. If a non-GPU enabled style requires a neighbor list, it will also
 be built using CPU routines. Redundant CPU and GPU neighbor list calculations
 will typically be less efficient. For <A HREF = "pair_hybrid.html">hybrid</A> pair
 styles, GPU calculated neighbor lists might be less efficient because
 no particles will be skipped in a given neighbor list.
 </P>
 <P><I>first</I> is the ID (as reported by lammps/lib/gpu/nvc_get_devices)
 of the first GPU that will be used on each node. <I>last</I> is the
 ID of the last GPU that will be used on each node. If you have
 only one GPU per node, <I>first</I> and <I>last</I> will typically both be
 0. Selecting a non-sequential set of GPU IDs (e.g. 0,1,3)
 is not currently supported.
 </P>
 <P><I>split</I> is the fraction of particles whose forces, torques,
 energies, and/or virials will be calculated on the GPU. This
 can be used to perform CPU and GPU force calculations
 simultaneously. If <I>split</I> is negative, the software will
 attempt to calculate the optimal fraction automatically 
 every 25 timesteps based on CPU and GPU timings. Because the GPU speedups
 are dependent on the number of particles, automatic calculation of the
 split can be less efficient, but typically results in loop times
 within 20% of an optimal fixed split.
 </P>
 <P>If you have two GPUs per node, 8 CPU cores per node, and
 would like to run on 4 nodes with dynamic balancing of
 force calculation across CPU and GPU cores, the fix
 might be
 </P>
 <PRE>fix 0 all gpu force/neigh 0 1 -1 
 </PRE>
 <P>with LAMMPS run on 32 processes. In this case, all
 CPU cores and GPU devices on the nodes would be utilized.
 Each GPU device would be shared by 4 CPU cores. The
 CPU cores would perform force calculations for some
 fraction of the particles at the same time the GPUs
 performed force calculation for the other particles.
 </P>
 <P>Because of the large number of cores on each GPU
 device, it might be more efficient to run on fewer
 processes per GPU when the number of particles per process
 is small (100's of particles); this can be necessary
 to keep the GPU cores busy.
 </P>
 <H4>GPU input script 
 </H4>
 <P>In order to use GPU acceleration in LAMMPS, 
 <A HREF = "fix_gpu.html">fix_gpu</A>
 should be used in order to initialize and configure the
 GPUs for use. Additionally, GPU enabled styles must be
 selected in the input script. Currently,
 this is limited to a few <A HREF = "pair_style.html">pair styles</A>.
 Some GPU-enabled styles have additional restrictions
 listed in their documentation.
 </P>
 <H4>GPU asynchronous pair computation 
 </H4>
 <P>The GPU accelerated pair styles can be used to perform
 pair style force calculation on the GPU while other 
 calculations are
 performed on the CPU. One method to do this is to specify
 a <I>split</I> in the gpu fix as described above. In this case,
 force calculation for the pair style will also be performed
 on the CPU. 
 </P>
 <P>When the CPU work in a GPU pair style has finished,
 the next force computation will begin, possibly before the
 GPU has finished. If <I>split</I> is 1.0 in the gpu fix, the next
 force computation will begin almost immediately. This can
 be used to run a <A HREF = "pair_hybrid.html">hybrid</A> GPU pair style at 
 the same time as a hybrid CPU pair style. In this case, the 
 GPU pair style should be first in the hybrid command in order to
 perform simultaneous calculations. This also
 allows <A HREF = "bond_style.html">bond</A>, <A HREF = "angle_style.html">angle</A>, 
 <A HREF = "dihedral_style.html">dihedral</A>, <A HREF = "improper_style.html">improper</A>, 
 and <A HREF = "kspace_style.html">long-range</A> force
 computations to be run simultaneously with the GPU pair style.
 Once all CPU force computations have completed, the gpu fix
 will block until the GPU has finished all work before continuing
 the run.
 </P>
 <H4>GPU timing 
 </H4>
 <P>GPU accelerated pair styles can perform computations asynchronously
 with CPU computations. The "Pair" time reported by LAMMPS
 will be the maximum of the time required to complete the CPU
 pair style computations and the time required to complete the GPU
 pair style computations. Any time spent for GPU-enabled pair styles
 for computations that run simultaneously with <A HREF = "bond_style.html">bond</A>, 
 <A HREF = "angle_style.html">angle</A>, <A HREF = "dihedral_style.html">dihedral</A>, 
 <A HREF = "improper_style.html">improper</A>, and <A HREF = "kspace_style.html">long-range</A> calculations
 will not be included in the "Pair" time.
 </P>
 <P>When <I>mode</I> for the gpu fix is force/neigh,
 the time for neighbor list calculations on the GPU will be added
 into the "Pair" time, not the "Neigh" time. A breakdown of the
 times required for various tasks on the GPU (data copy, neighbor
 calculations, force computations, etc.) are output only
 with the LAMMPS screen output at the end of each run. These timings represent
 total time spent on the GPU for each routine, regardless of asynchronous
 CPU calculations.
 </P>
 <H4>GPU single vs double precision 
 </H4>
 <P>See the lammps/lib/gpu/README file for instructions on how to build 
 the LAMMPS gpu library for single, mixed, and double precision.  The latter
 requires that your GPU card supports double precision. 
 </P>
 <HR>
 
 <H4><A NAME = "2_9"></A>2.9 Tips for users of previous LAMMPS versions 
 </H4>
 <P>The current C++ began with a complete rewrite of LAMMPS 2001, which
 was written in F90.  Features of earlier versions of LAMMPS are listed
 in <A HREF = "Section_history.html">this section</A>.  The F90 and F77 versions
 (2001 and 99) are also freely distributed as open-source codes; check
 the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> for distribution information if you prefer
 those versions.  The 99 and 2001 versions are no longer under active
 development; they do not have all the features of C++ LAMMPS.
 </P>
 <P>If you are a previous user of LAMMPS 2001, these are the most
 significant changes you will notice in C++ LAMMPS:
 </P>
 <P>(1) The names and arguments of many input script commands have
 changed.  All commands are now a single word (e.g. read_data instead
 of read data).
 </P>
 <P>(2) All the functionality of LAMMPS 2001 is included in C++ LAMMPS,
 but you may need to specify the relevant commands in different ways.
 </P>
 <P>(3) The format of the data file can be streamlined for some problems.
 See the <A HREF = "read_data.html">read_data</A> command for details.  The data file
 section "Nonbond Coeff" has been renamed to "Pair Coeff" in C++ LAMMPS.
 </P>
 <P>(4) Binary restart files written by LAMMPS 2001 cannot be read by C++
 LAMMPS with a <A HREF = "read_restart.html">read_restart</A> command.  This is
 because they were output by F90 which writes in a different binary
 format than C or C++ writes or reads.  Use the <I>restart2data</I> tool
 provided with LAMMPS 2001 to convert the 2001 restart file to a text
 data file.  Then edit the data file as necessary before using the C++
 LAMMPS <A HREF = "read_data.html">read_data</A> command to read it in.
 </P>
 <P>(5) There are numerous small numerical changes in C++ LAMMPS that mean
 you will not get identical answers when comparing to a 2001 run.
 However, your initial thermodynamic energy and MD trajectory should be
 close if you have setup the problem for both codes the same.
 </P>
 </HTML>
diff --git a/doc/Section_start.txt b/doc/Section_start.txt
index ae747ded6..4faa06931 100644
--- a/doc/Section_start.txt
+++ b/doc/Section_start.txt
@@ -1,1075 +1,1114 @@
 "Previous Section"_Section_intro.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_commands.html :c
 
 :link(lws,http://lammps.sandia.gov)
 :link(ld,Manual.html)
 :link(lc,Section_commands.html#comm)
 
 :line
 
 2. Getting Started :h3
 
 This section describes how to build and run LAMMPS, for both new and
 experienced users.
 
 2.1 "What's in the LAMMPS distribution"_#2_1
 2.2 "Making LAMMPS"_#2_2
 2.3 "Making LAMMPS with optional packages"_#2_3
 2.4 "Building LAMMPS as a library"_#2_4
 2.5 "Running LAMMPS"_#2_5
 2.6 "Command-line options"_#2_6
 2.7 "Screen output"_#2_7
 2.8 "Running on GPUs"_#2_8
 2.9 "Tips for users of previous versions"_#2_9 :all(b)
 
 :line
 
 2.1 What's in the LAMMPS distribution :h4,link(2_1)
 
 When you download LAMMPS you will need to unzip and untar the
 downloaded file with the following commands, after placing the file in
 an appropriate directory.
 
 gunzip lammps*.tar.gz 
 tar xvf lammps*.tar :pre
 
 This will create a LAMMPS directory containing two files and several
 sub-directories:
     
 README: text file
 LICENSE: the GNU General Public License (GPL)
 bench: benchmark problems
 couple: code coupling examples, using LAMMPS as a library
 doc: documentation
 examples: simple test problems
 potentials: embedded atom method (EAM) potential files
 src: source files
 tools: pre- and post-processing tools :tb(s=:)
 
 If you download the Windows executable from the download page,
 then you just get a single file:
 
 lmp_windows.exe :pre
 
 Skip to the "Running LAMMPS"_#2_5 section, to learn how to launch this
 executable on a Windows box.
 
 The Windows executable also only includes certain packages and
 bug-fixes/upgrades listed on "this
 page"_http://lammps.sandia.gov/bug.html up to a certain date, as
 stated on the download page.  If you want something with more packages
 or that is more current, you'll have to download the source tarball
 and build it yourself, as described in the next section.
 
 :line
 
 2.2 Making LAMMPS :h4,link(2_2)
 
 This section has the following sub-sections:
 
 "Read this first"_#2_2_1
 "Building a LAMMPS executable"_#2_2_2
 "Common errors that can occur when making LAMMPS"_#2_2_3
 "Editing a new low-level Makefile"_#2_2_4
 "Additional build tips"_#2_2_5 :ul
 
 :line
 
 [{Read this first:}] :link(2_2_1)
 
 Building LAMMPS can be non-trivial.  You will likely need to edit a
 makefile, there are compiler options, additional libraries can be used
 (MPI, FFT), etc.  Please read this section carefully.  If you are not
 comfortable with makefiles, or building codes on a Unix platform, or
 running an MPI job on your machine, please find a local expert to help
 you.  Many compiling, linking, and run problems that users are not
 really LAMMPS issues - they are peculiar to the user's system,
 compilers, libraries, etc.  Such questions are better answered by a
 local expert.
 
 If you have a build problem that you are convinced is a LAMMPS issue
 (e.g. the compiler complains about a line of LAMMPS source code), then
 please send an email to the
 "developers"_http://lammps.sandia.gov/authors.html.
 
 If you succeed in building LAMMPS on a new kind of machine, for which
 there isn't a similar Makefile for in the src/MAKE directory, send it
 to the developers and we'll include it in future LAMMPS releases.
 
 :line
 
 [{Building a LAMMPS executable:}] :link(2_2_2)
 
 The src directory contains the C++ source and header files for LAMMPS.
 It also contains a top-level Makefile and a MAKE sub-directory with
 low-level Makefile.* files for several machines.  From within the src
 directory, type "make" or "gmake".  You should see a list of available
 choices.  If one of those is the machine and options you want, you can
 type a command like:
 
 make linux
 gmake mac :pre
 
 Note that on a multi-processor or multi-core platform you can launch a
 parallel make, by using the "-j" switch with the make command, which
 will build LAMMPS more quickly.
 
 If you get no errors and an executable like lmp_linux or lmp_mac is
 produced, you're done; it's your lucky day.
 
 :line
 
 [{Common errors that can occur when making LAMMPS:}] :link(2_2_3)
 
 (1) If the make command breaks immediately with errors that indicate
 it can't find files with a "*" in their names, this can be because
 your machine's make doesn't support wildcard expansion in a makefile.
 Try gmake instead of make.  If that doesn't work, try using a -f
 switch with your make command to use Makefile.list which explicitly
 lists all the needed files, e.g.
 
 make makelist
 make -f Makefile.list linux
 gmake -f Makefile.list mac :pre
 
 The first "make" command will create a current Makefile.list with all
 the file names in your src dir.  The 2nd "make" command (make or
 gmake) will use it to build LAMMPS.
 
 (2) Other errors typically occur because the low-level Makefile isn't
 setup correctly for your machine.  If your platform is named "foo",
 you will need to create a Makefile.foo in the MAKE sub-directory.  Use
 whatever existing file is closest to your platform as a starting
 point.  See the next section for more instructions.
 
 (3) If you get a link-time error about missing libraries or missing
 dependencies, then it can be because:
 
 you are including a package that needs an extra library, but have not pre-built the necessary "package library"_#2_3_3
 you are linking to a library that doesn't exist on your system
 you are not linking to the necessary system library :ul
 
 The first issue is discussed below.  The other two issue mean you need
 to edit your low-level Makefile.foo, as discussed in the next
 sub-section.
 
 :line
 
 [{Editing a new low-level Makefile.foo:}] :link(2_2_4)
 
 These are the issues you need to address when editing a low-level
 Makefile for your machine.  The portions of the file you typically
 need to edit are the first line, the "compiler/linker settings"
 section, and the "system-specific settings" section.
 
 (1) Change the first line of Makefile.foo to list the word "foo" after
 the "#", and whatever other options you set.  This is the line you
 will see if you just type "make".
 
 (3) The "compiler/linker settings" section lists compiler and linker
 settings for your C++ compiler, including optimization flags.  You can
 use g++, the open-source GNU compiler, which is available on all Unix
 systems.  You can also use mpicc which will typically be available if
 MPI is installed on your system, though you should check which actual
 compiler it wraps.  Vendor compilers often produce faster code.  On
 boxes with Intel CPUs, we suggest using the free Intel icc compiler,
 which you can download from "Intel's compiler site"_intel.
 
 :link(intel,http://www.intel.com/software/products/noncom)
 
 If building a C++ code on your machine requires additional libraries,
 then you should list them as part of the LIB variable.
 
 The DEPFLAGS setting is what triggers the C++ compiler to create a
 dependency list for a source file.  This speeds re-compilation when
 source (*.cpp) or header (*.h) files are edited.  Some compilers do
 not support dependency file creation, or may use a different switch
 than -D.  GNU g++ works with -D.  If your compiler can't create
 dependency files (a long list of errors involving *.d files), then
 you'll need to create a Makefile.foo patterned after Makefile.storm,
 which uses different rules that do not involve dependency files.
 
 (3) The "system-specific settings" section has 4 parts.
 
 (3.a) The LMP_INC variable is used to include options that turn on
 system-dependent ifdefs within the LAMMPS code.
 
 The read_data and dump commands will read/write gzipped files if you
 compile with -DLAMMPS_GZIP.  It requires that your Unix support the
 "popen" command.  Using one of the -DPACK_ARRAY, -DPACK_POINTER, and
 -DPACK_MEMCPY options can make for faster parallel FFTs (in the PPPM
 solver) on some platforms.  The -DPACK_ARRAY setting is the default.
 If you use -DLAMMPS_XDR, the build will include XDR compatibility
 files for doing particle dumps in XTC format.  This is only necessary
 if your platform does have its own XDR files available.  See the
 Restrictions section of the "dump"_dump.html command for details.
 
 (3.b) The 3 MPI variables are used to specify an MPI library to build
 LAMMPS with.
 
 If you want LAMMPS to run in parallel, you must have an MPI library
 installed on your platform.  If you use an MPI-wrapped compiler, such
 as "mpicc" to build LAMMPS, you can probably leave these 3 variables
 blank.  If you do not use "mpicc" as your compiler/linker, then you
 need to specify where the mpi.h file (MPI_INC) and the MPI library
 (MPI_PATH) is found and its name (MPI_LIB).
 
 If you are installing MPI yourself, we recommend Argonne's MPICH 1.2
 or 2.0 which can be downloaded from the "Argonne MPI
 site"_http://www-unix.mcs.anl.gov/mpi.  LAM MPI should also work.  If
 you are running on a big parallel platform, your system people or the
 vendor should have already installed a version of MPI, which will be
 faster than MPICH or LAM, so find out how to build and link with it.
 If you use MPICH or LAM, you will have to configure and build it for
 your platform.  The MPI configure script should have compiler options
 to enable you to use the same compiler you are using for the LAMMPS
 build, which can avoid problems that can arise when linking LAMMPS to
 the MPI library.
 
 If you just want LAMMPS to run on a single processor, you can use the
 STUBS library in place of MPI, since you don't need an MPI library
 installed on your system.  See the Makefile.serial file for how to
 specify the 3 MPI variables.  You will also need to build the STUBS
 library for your platform before making LAMMPS itself.  From the STUBS
 dir, type "make" and it will hopefully create a libmpi.a suitable for
 linking to LAMMPS.  If this build fails, you will need to edit the
 STUBS/Makefile for your platform.
 
 The file STUBS/mpi.cpp has a CPU timer function MPI_Wtime() that calls
 gettimeofday() .  If your system doesn't support gettimeofday() ,
 you'll need to insert code to call another timer.  Note that the
 ANSI-standard function clock() rolls over after an hour or so, and is
 therefore insufficient for timing long LAMMPS simulations.
 
 (3.c) The 3 FFT variables are used to specify an FFT library which
 LAMMPS uses when using the particle-particle particle-mesh (PPPM)
 option in LAMMPS for long-range Coulombics via the
 "kspace_style"_kspace_style.html command.
 
 To use this option, you must have a 1d FFT library installed on your
 platform.  This is specified by a switch of the form -DFFT_XXX where
 XXX = INTEL, DEC, SGI, SCSL, or FFTW.  All but the last one are native
 vendor-provided libraries.  FFTW is a fast, portable library that
 should work on any platform.  You can download it from
 "www.fftw.org"_http://www.fftw.org.  Use version 2.1.X, not the newer
 3.0.X.  Building FFTW for your box should be as simple as ./configure;
 make.  Whichever FFT library you have on your platform, you'll need to
 set the appropriate FFT_INC, FFT_PATH, and FFT_LIB variables in
 Makefile.foo.
 
 If you examine src/fft3d.c and src.fft3d.h you'll see it's possible to
 add other vendor FFT libraries via #ifdef statements in the
 appropriate places.  If you successfully add a new FFT option, like
 -DFFT_IBM, please send the LAMMPS developers an email; we'd like to
 add it to LAMMPS.
 
 If you don't plan to use PPPM, you don't need an FFT library.  In this
 case you can set FFT_INC to -DFFT_NONE and leave the other 2 FFT
 variables blank.  Or you can exclude the KSPACE package when you build
 LAMMPS (see below).
 
 (3.d) The several SYSLIB and SYSPATH variables can be ignored unless
 you are building LAMMPS with one or more of the LAMMPS packages that
 require these extra system libraries.  The names of these packages are
 the prefixes on the SYSLIB and SYSPATH variables.  See the "section
 below"_#2_3_4 for more details.  The SYSLIB variables list the system
 libraries.  The SYSPATH variables are where they are located on your
 machine, which is typically only needed if they are in some
 non-standard place, that is not in your library search path.
 
 That's it.  Once you have a correct Makefile.foo and you have
 pre-built any other libraries it will use (e.g. MPI, FFT, package
 libraries), all you need to do from the src directory is type one of
 these 2 commands:
 
 make foo
 gmake foo :pre
 
 You should get the executable lmp_foo when the build is complete.
 
 :line
 
 [{Additional build tips:}] :link(2_2_5)
 
 (1) Building LAMMPS for multiple platforms.
 
 You can make LAMMPS for multiple platforms from the same src
 directory.  Each target creates its own object sub-directory called
 Obj_name where it stores the system-specific *.o files.
 
 (2) Cleaning up.
 
 Typing "make clean-all" or "make clean-foo" will delete *.o object
 files created when LAMMPS is built, for either all builds or for a
 particular machine.
 
 (3) Building for a Mac.
 
 OS X is BSD Unix, so it should just work.  See the Makefile.mac file.
 
 (4) Building for MicroSoft Windows.
 
 The LAMMPS download page has an option to download a pre-built Windows
 exeutable.  See below for instructions for running this executable on
 a Windows box.
 
 If the pre-built executable doesn't have the options you want, then
 you should be able to build LAMMPS from source files on a Windows box.
 I've never done this, but LAMMPS is just standard C++ with MPI and FFT
 calls.  You can use cygwin to build LAMMPS with a Unix make; see
 Makefile.cygwin.  Or you should be able to pull all the source files
 into Visual C++ (ugh) or some similar development environment and
 build it.  In the src/MAKE/Windows directory are some notes from users
 on how they built LAMMPS under Windows, so you can look at their
 instructions for tips.  Good luck - we can't help you on this one.
 
+(5) Changing the size limits in src/lmptype.h
+
+If you are running a very large problem (billions of atoms or more)
+and get a run-time error about the system being too big, either on a
+per-processor basis or in total size, then you may need to change one
+or more settings in src/lmptype.h and re-compile LAMMPS.
+
+As the documentation in that file explains, you have basically
+two choices to make:
+
+set the data type size of integer atom IDs to 4 or 8 bytes
+set the data type size of integers that store the total system size to 4 or 8 bytes :ul
+
+The default for atom IDs is 4-byte integers since there is a memory
+and communication cost for 8-byte integers.  Non-molecular problems do
+not need atom IDs so this does not restrict their size.  Molecular
+problems (which use IDs to define molecular topology), are limited to
+about 2 billion atoms (2^31) with 4-byte IDs.  With 8-byte IDs they
+are effectively unlimited in size (2^63).
+
+The default for total system size quantities (like the number of atoms
+or timesteps) is 8-byte integers by default which is effectively
+unlimited in size (2^63).  If your system does not support 8-byte
+integers, an error will be generated, and you will need to set
+"bigint" to 4-byte integers.  This restricts your total system size to
+about 2 billion atoms or timesteps (2^31).
+
+Note that in src/lmptype.h there are also settings for the MPI data
+types associated with the integers that store atom IDs and total
+system sizes, which need to be set consistent with the associated C
+data types.
+
+In all cases, the size of problem that can be run on a per-processor
+basis is limited by 4-byte integer storage to about 2 billion atoms
+per processor (2^31), which should not normally be a restriction since
+such a problem would have a huge per-processor memory footprint due to
+neighbor lists and would run very slowly in terms of CPU
+secs/timestep.
+
 :line
 
 2.3 Making LAMMPS with optional packages :h4,link(2_3)
 
 This section has the following sub-sections:
 
 "Package basics"_#2_3_1
 "Including/excluding packages"_#2_3_2
 "Packages that require extra LAMMPS libraries"_#2_3_3
 "Additional Makefile settings for extra libraries"_#2_3_4 :ul
 
 :line
 
 [{Package basics:}] :link(2_3_1)
 
 The source code for LAMMPS is structured as a large set of core files
 which are always included, plus optional packages.  Packages are
 groups of files that enable a specific set of features.  For example,
 force fields for molecular systems or granular systems are in
 packages.  You can see the list of all packages by typing "make
 package".
 
 The current list of standard packages is as follows:
 
 asphere : aspherical particles and force fields
 class2 : class 2 force fields
 colloid : colloidal particle force fields
 dipole : point dipole particles and force fields
 dsmc : Direct Simulation Monte Carlo (DMSC) pair style
 gpu : GPU-enabled force field styles
 granular : force fields and boundary conditions for granular systems
 kspace : long-range Ewald and particle-mesh (PPPM) solvers
 manybody : metal, 3-body, bond-order potentials
 meam : modified embedded atom method (MEAM) potential
 molecule : force fields for molecular systems
 opt : optimized versions of a few pair potentials
 peri : Peridynamics model and potential
 poems : coupled rigid body motion
 reax : ReaxFF potential
 replica : multi-replica methods
 shock : methods for MD simulations of shock loading
 srd : stochastic rotation dynamics (SRD)
 xtc : dump atom snapshots in XTC format :tb(s=:)
 
 There are also user-contributed packages which may be as simple as a
 single additional file or many files grouped together which add a
 specific functionality to the code.
 
 The difference between a {standard} package versus a {user} package is
 as follows.
 
 Standard packages are supported by the LAMMPS developers and are
 written in a syntax and style consistent with the rest of LAMMPS.
 This means we will answer questions about them, debug and fix them if
 necessary, and keep them compatible with future changes to LAMMPS.
 
 User packages don't necessarily meet these requirements.  If you have
 problems using a feature provided in a user package, you will likely
 need to contact the contributor directly to get help.  Information on
 how to submit additions you make to LAMMPS as a user-contributed
 package is given in "this section"_Section_modify.html#package of the
 documentation.
 
 :line
 
 [{Including/excluding packages:}] :link(2_3_2)
 
 Any or all packages can be included or excluded independently BEFORE
 LAMMPS is built.
 
 The two exceptions to this are the "gpu" and "opt" packages.  Some of
 the files in these packages require other packages to also be
 included.  If this is not the case, then those subsidiary files in
 "gpu" and "opt" will not be installed either.  To install all the
 files in package "gpu", the "asphere" and "kspace" packages must also be 
 installed. To install all the files in package "opt", the "kspace" and 
 "manybody" packages must also be installed.
 
 You may wish to exclude certain packages if you will never run certain
 kinds of simulations.  This will keep you from having to build
 auxiliary libraries (see below) and will produce a smaller executable
 which may run a bit faster.
 
 By default, LAMMPS includes only the "kspace", "manybody", and
 "molecule" packages.
 
 Packages are included or excluded by typing "make yes-name" or "make
 no-name", where "name" is the name of the package.  You can also type
 "make yes-standard", "make no-standard", "make yes-user", "make
 no-user", "make yes-all" or "make no-all" to include/exclude various
 sets of packages.  Type "make package" to see the various options.
 
 IMPORTANT NOTE: These make commands work by simply moving files back
 and forth between the main src directory and sub-directories with the
 package name, so that the files are seen or not seen when LAMMPS is
 built.  After you have included or excluded a package, you must
 re-build LAMMPS.
 
 Additional make options exist to help manage LAMMPS files that exist
 in both the src directory and in package sub-directories.  You do not
 normally need to use these commands unless you are editing LAMMPS
 files or have downloaded a patch from the LAMMPS WWW site.
 
 Typing "make package-update" will overwrite src files with files from
 the package directories if the package has been included.  It should
 be used after a patch is installed, since patches only update the
 master package version of a file.  Typing "make package-overwrite"
 will overwrite files in the package directories with src files.
 Typing "make package-check" will list differences between src and
 package versions of the same files.  Again, type "make package" to see
 the various options.
 
 :line
 
 [{Packages that require extra LAMMPS libraries:}] :link(2_3_3)
 
 A few packages (standard or user) require that additional libraries be
 compiled first, which LAMMPS will link to when it builds.  The source
 code for these libraries are included in the LAMMPS distribution under
 the "lib" directory.  Look at the README files in the lib directories
 (e.g. lib/reax/README) for instructions on how to build each library.
 
 IMPORTANT NOTE: If you are including a package in your LAMMPS build
 that uses one of these libraries, then you must build the library
 BEFORE building LAMMPS itself, since the LAMMPS build will attempt to
 link with the library file.
 
 Here is a bit of information about each library:
 
 The "atc" library in lib/atc is used by the user-atc package.  It
 provides continuum field estimation and molecular dynamics-finite
 element coupling methods.  It was written primarily by Reese Jones,
 Jeremy Templeton and Jonathan Zimmerman at Sandia.
 
 The "gpu" library in lib/gpu is used by the gpu package.  It
 contains code to enable portions of LAMMPS to run on a GPU chip
 associated with your CPU.  Currently, only NVIDIA GPUs are supported.
 Building this library requires NVIDIA Cuda tools to be installed on
 your system.  See the "Running on GPUs"_#2_8 section below for more
 info about installing and using Cuda.
 
 The "meam" library in lib/meam is used by the meam package.
 computes the modified embedded atom method potential, which is a
 generalization of EAM potentials that can be used to model a wider
 variety of materials.  This MEAM implementation was written by Greg
 Wagner at Sandia.  It requires a F90 compiler to build.  The C++ to
 FORTRAN function calls in pair_meam.cpp assumes that FORTRAN object
 names are converted to C object names by appending an underscore
 character. This is generally the case, but on machines that do not
 conform to this convention, you will need to modify either the C++
 code or your compiler settings.
 
 The "poems" library in lib/poems is used by the poems package.
 computes the constrained rigid-body motion of articulated (jointed)
 multibody systems.  POEMS was written and is distributed by Prof Kurt
 Anderson's group at Rensselaer Polytechnic Institute (RPI).
 
 The "reax" library in lib/reax is used by the reax package.  It
 computes the Reactive Force Field (ReaxFF) potential, developed by
 Adri van Duin in Bill Goddard's group at CalTech.  This implementation
 in LAMMPS uses many of Adri's files and was developed by Aidan
 Thompson at Sandia and Hansohl Cho at MIT.  It requires a F77 or F90
 compiler to build.  The C++ to FORTRAN function calls in pair_reax.cpp
 assume that FORTRAN object names are converted to C object names by
 appending an underscore character. This is generally the case, but on
 machines that do not conform to this convention, you will need to
 modify either the C++ code or your compiler settings. The name
 conversion is handled by the preprocessor macro called FORTRAN in
 pair_reax_fortran.h.  Different definitions of this macro can be
 obtained by adding a machine-specific macro definition to the CCFLAGS
 variable in your Makefile e.g. -D_IBM. See pair_reax_fortran.h for
 more info.
 
 As described in its README file, each library is built by typing
 something like
 
 make -f Makefile.g++ :pre
 
 in the appropriate directory, e.g. in lib/reax.
 
 You must use a Makefile that is a match for your system.  If one of
 the provided Makefiles is not appropriate for your system you will
 need to edit or add one.  For example, in the case of Fotran-based
 libraries, your system must have a Fortran compiler, the settings for
 which will be in the Makefile.
 
 :line
 
 [{Additional Makefile settings for extra libraries:}] :link(2_3_4)
 
 After the desired library or libraries are built, and the package has
 been included, you can build LAMMPS itself.  For example, from the
 lammps/src directory you would type this, to build LAMMPS with ReaxFF.
 Note that as discussed in the preceding section, the package library
 itself, namely lib/reax/libreax.a, must already have been built, for
 the LAMMPS build to be successful.
 
 make yes-reax
 make g++ :pre
 
 Also note that simply building the library is not sufficient to use it
 from LAMMPS.  As in this example, you must also include the package
 that uses and wraps the library before you build LAMMPS itself.
 
 As discussed in point (2.4) of "this section"_#2_2_4 above, there are
 settings in the low-level Makefile that specify additional system
 libraries needed by individual LAMMPS add-on libraries.  These are the
 settings you must specify correctly in your low-level Makefile in
 lammps/src/MAKE, such as Makefile.foo:
 
 To use the gpu package and library, the settings for gpu_SYSLIB and
 gpu_SYSPATH must be correct.  These are specific to the NVIDIA CUDA
 software which must be installed on your system.
 
 To use the meam or reax packages and their libraries which are Fortran
 based, the settings for meam_SYSLIB, reax_SYSLIB, meam_SYSPATH, and
 reax_SYSPATH must be correct.  This is so that the C++ compiler can
 perform a cross-language link using the appropriate system Fortran
 libraries.
 
 To use the user-atc package and library, the settings for
 user-atc_SYSLIB and user-atc_SYSPATH must be correct.  This is so that
 the appropriate BLAS and LAPACK libs, used by the user-atc library,
 can be found.
 
 :line
 
 2.4 Building LAMMPS as a library :h4,link(2_4)
 
 LAMMPS can be built as a library, which can then be called from
 another application or a scripting language.  See "this
 section"_Section_howto.html#4_10 for more info on coupling LAMMPS to
 other codes.  Building LAMMPS as a library is done by typing
 
 make makelib
 make -f Makefile.lib foo :pre
 
 where foo is the machine name.  The first "make" command will create a
 current Makefile.lib with all the file names in your src dir.  The 2nd
 "make" command will use it to build LAMMPS as a library.  This
 requires that Makefile.foo have a library target (lib) and
 system-specific settings for ARCHIVE and ARFLAGS.  See Makefile.linux
 for an example.  The build will create the file liblmp_foo.a which
 another application can link to.
 
 When used from a C++ program, the library allows one or more LAMMPS
 objects to be instantiated.  All of LAMMPS is wrapped in a LAMMPS_NS
 namespace; you can safely use any of its classes and methods from
 within your application code, as needed. 
 
 When used from a C or Fortran program or a scripting language, the
 library has a simple function-style interface, provided in
 src/library.cpp and src/library.h.
 
 See the sample codes couple/simple/simple.cpp and simple.c as examples
 of C++ and C codes that invoke LAMMPS thru its library interface.
 There are other examples as well in the couple directory which are
 discussed in "this section"_Section_howto.html#4_10 of the manual.
 See "this section"_Section_python.html of the manual for a description
 of the Python wrapper provided with LAMMPS that operates through the
 LAMMPS library interface.
 
 The files src/library.cpp and library.h contain the C-style interface
 to LAMMPS.  See "this section"_Section_howto.html#4_19 of the manual
 for a description of the interface and how to extend it for your
 needs.
 
 :line
 
 2.5 Running LAMMPS :h4,link(2_5)
 
 By default, LAMMPS runs by reading commands from stdin; e.g. lmp_linux
 < in.file.  This means you first create an input script (e.g. in.file)
 containing the desired commands.  "This section"_Section_commands.html
 describes how input scripts are structured and what commands they
 contain.
 
 You can test LAMMPS on any of the sample inputs provided in the
 examples directory.  Input scripts are named in.* and sample outputs
 are named log.*.name.P where name is a machine and P is the number of
 processors it was run on.
 
 Here is how you might run one of the Lennard-Jones tests on a Linux
 box, using mpirun to launch a parallel job:
 
 cd src
 make linux
 cp lmp_linux ../examples/lj
 cd ../examples/lj
 mpirun -np 4 lmp_linux < in.lj.nve :pre
 
 :line
 
 On a Windows machine, you can skip making LAMMPS and simply download
 an executable. But note that not all packages are available.
 The following packages are available: asphere, class2, colloid, dipole,
 dsmc, granular, kspace, manybody, molecule, peri, poems, replica, shock,
 user-ackland, user-cd-eam, user-cg-cmm, user-ewaldn, user-smd. But these 
 packages are not available: gpu, meam, opt, reax, xtc, user-atc, user-imd.
 
 To run the LAMMPS executable on a Windows machine, first decide whether 
 you want to download the non-MPI (serial) or the MPI (parallel) version 
 of the executable. Download and save the version you have chosen.
 
 For the non-MPI version, follow these steps:
 
 Get a command prompt by going to Start->Run... , 
 then typing "cmd". :ulb,l
 
 Move to the directory where you have saved lmp_win_no-mpi.exe
 (e.g. by typing: cd "Documents"). :l
 
 At the command prompt, type "lmp_win_no-mpi -in in.lj", replacing in.lj
 with the name of your LAMMPS input script. :l,ule
 
 For the MPI version, which allows you to run LAMMPS under Windows on 
 multiple processors, follow these steps:
 
 Download and install 
 "MPICH2"_http://www.mcs.anl.gov/research/projects/mpich2/downloads/index.php?s=downloads
 for Windows. :ulb,l
 
 You'll need to use the mpiexec.exe and smpd.exe files from the MPICH2 package. Put them in 
 same directory (or path) as the LAMMPS Windows executable. :l
 
 Get a command prompt by going to Start->Run... , 
 then typing "cmd". :l
 
 Move to the directory where you have saved lmp_win_mpi.exe
 (e.g. by typing: cd "Documents"). :l
 
 Then type something like this: "mpiexec -np 4 -localonly lmp_win_mpi -in in.lj", 
 replacing in.lj with the name of your LAMMPS input script. :l
 Note that you may need to provide smpd with a passphrase --- it doesn't matter what you 
 type. :l
 In this mode, output may not immediately show up on the screen, so 
 if your input script takes a long time to execute, you may need to be 
 patient before the output shows up. :l
 Alternatively, you can still use this executable to run on a single processor by
 typing something like: "lmp_win_mpi -in in.lj". :l,ule
 
 :line
 
 The screen output from LAMMPS is described in the next section.  As it
 runs, LAMMPS also writes a log.lammps file with the same information.
 
 Note that this sequence of commands copies the LAMMPS executable
 (lmp_linux) to the directory with the input files.  This may not be
 necessary, but some versions of MPI reset the working directory to
 where the executable is, rather than leave it as the directory where
 you launch mpirun from (if you launch lmp_linux on its own and not
 under mpirun).  If that happens, LAMMPS will look for additional input
 files and write its output files to the executable directory, rather
 than your working directory, which is probably not what you want.
 
 If LAMMPS encounters errors in the input script or while running a
 simulation it will print an ERROR message and stop or a WARNING
 message and continue.  See "this section"_Section_errors.html for a
 discussion of the various kinds of errors LAMMPS can or can't detect,
 a list of all ERROR and WARNING messages, and what to do about them.
 
 LAMMPS can run a problem on any number of processors, including a
 single processor.  In theory you should get identical answers on any
 number of processors and on any machine.  In practice, numerical
 round-off can cause slight differences and eventual divergence of
 molecular dynamics phase space trajectories.
 
 LAMMPS can run as large a problem as will fit in the physical memory
 of one or more processors.  If you run out of memory, you must run on
 more processors or setup a smaller problem.
 
 :line
 
 2.6 Command-line options :h4,link(2_6)
 
 At run time, LAMMPS recognizes several optional command-line switches
 which may be used in any order.  For example, lmp_ibm might be
 launched as follows:
 
 mpirun -np 16 lmp_ibm -var f tmp.out -log my.log -screen none < in.alloy :pre
 
 These are the command-line options:
 
 -echo style :pre
 
 Set the style of command echoing.  The style can be {none} or {screen}
 or {log} or {both}.  Depending on the style, each command read from
 the input script will be echoed to the screen and/or logfile.  This
 can be useful to figure out which line of your script is causing an
 input error.  The default value is {log}.  The echo style can also be
 set by using the "echo"_echo.html command in the input script itself.
 
 -partition 8x2 4 5 ... :pre
 
 Invoke LAMMPS in multi-partition mode.  When LAMMPS is run on P
 processors and this switch is not used, LAMMPS runs in one partition,
 i.e. all P processors run a single simulation.  If this switch is
 used, the P processors are split into separate partitions and each
 partition runs its own simulation.  The arguments to the switch
 specify the number of processors in each partition.  Arguments of the
 form MxN mean M partitions, each with N processors.  Arguments of the
 form N mean a single partition with N processors.  The sum of
 processors in all partitions must equal P.  Thus the command
 "-partition 8x2 4 5" has 10 partitions and runs on a total of 25
 processors.
 
 Note that with MPI installed on a machine (e.g. your desktop), you can
 run on more (virtual) processors than you have physical processors.
 This can be useful for running "multi-replica
 simulations"_Section_howto.html#4_5, on one or a few processors.
 
 The input script specifies what simulation is run on which partition;
 see the "variable"_variable.html and "next"_next.html commands.  This
 "howto section"_Section_howto.html#4_4 gives examples of how to use
 these commands in this way.  Simulations running on different
 partitions can also communicate with each other; see the
 "temper"_temper.html command.
 
 -in file :pre
 
 Specify a file to use as an input script.  This is an optional switch
 when running LAMMPS in one-partition mode.  If it is not specified,
 LAMMPS reads its input script from stdin - e.g. lmp_linux < in.run.
 This is a required switch when running LAMMPS in multi-partition mode,
 since multiple processors cannot all read from stdin.
 
 -log file :pre
 
 Specify a log file for LAMMPS to write status information to.  In
 one-partition mode, if the switch is not used, LAMMPS writes to the
 file log.lammps.  If this switch is used, LAMMPS writes to the
 specified file.  In multi-partition mode, if the switch is not used, a
 log.lammps file is created with hi-level status information.  Each
 partition also writes to a log.lammps.N file where N is the partition
 ID.  If the switch is specified in multi-partition mode, the hi-level
 logfile is named "file" and each partition also logs information to a
 file.N.  For both one-partition and multi-partition mode, if the
 specified file is "none", then no log files are created.  Using a
 "log"_log.html command in the input script will override this setting.
 
 -screen file :pre
 
 Specify a file for LAMMPS to write its screen information to.  In
 one-partition mode, if the switch is not used, LAMMPS writes to the
 screen.  If this switch is used, LAMMPS writes to the specified file
 instead and you will see no screen output.  In multi-partition mode,
 if the switch is not used, hi-level status information is written to
 the screen.  Each partition also writes to a screen.N file where N is
 the partition ID.  If the switch is specified in multi-partition mode,
 the hi-level screen dump is named "file" and each partition also
 writes screen information to a file.N.  For both one-partition and
 multi-partition mode, if the specified file is "none", then no screen
 output is performed.
 
 -var name value :pre
 
 Specify a variable that will be defined for substitution purposes when
 the input script is read.  "Name" is the variable name which can be a
 single character (referenced as $x in the input script) or a full
 string (referenced as $\{abc\}).  The value can be any string.  Using
 this command-line option is equivalent to putting the line "variable
 name index value" at the beginning of the input script.  Defining an
 index variable as a command-line argument overrides any setting for
 the same index variable in the input script, since index variables
 cannot be re-defined.  See the "variable"_variable.html command for
 more info on defining index and other kinds of variables and "this
 section"_Section_commands.html#3_2 for more info on using variables in
 input scripts.
 
 :line
 
 2.7 LAMMPS screen output :h4,link(2_7)
 
 As LAMMPS reads an input script, it prints information to both the
 screen and a log file about significant actions it takes to setup a
 simulation.  When the simulation is ready to begin, LAMMPS performs
 various initializations and prints the amount of memory (in MBytes per
 processor) that the simulation requires.  It also prints details of
 the initial thermodynamic state of the system.  During the run itself,
 thermodynamic information is printed periodically, every few
 timesteps.  When the run concludes, LAMMPS prints the final
 thermodynamic state and a total run time for the simulation.  It then
 appends statistics about the CPU time and storage requirements for the
 simulation.  An example set of statistics is shown here:
 
 Loop time of 49.002 on 2 procs for 2004 atoms :pre
 
 Pair   time (%) = 35.0495 (71.5267)
 Bond   time (%) = 0.092046 (0.187841)
 Kspce  time (%) = 6.42073 (13.103)
 Neigh  time (%) = 2.73485 (5.5811)
 Comm   time (%) = 1.50291 (3.06703)
 Outpt  time (%) = 0.013799 (0.0281601)
 Other  time (%) = 2.13669 (4.36041) :pre
 
 Nlocal:    1002 ave, 1015 max, 989 min
 Histogram: 1 0 0 0 0 0 0 0 0 1 
 Nghost:    8720 ave, 8724 max, 8716 min 
 Histogram: 1 0 0 0 0 0 0 0 0 1
 Neighs:    354141 ave, 361422 max, 346860 min 
 Histogram: 1 0 0 0 0 0 0 0 0 1 :pre
 
 Total # of neighbors = 708282
 Ave neighs/atom = 353.434
 Ave special neighs/atom = 2.34032
 Number of reneighborings = 42
 Dangerous reneighborings = 2 :pre
 
 The first section gives the breakdown of the CPU run time (in seconds)
 into major categories.  The second section lists the number of owned
 atoms (Nlocal), ghost atoms (Nghost), and pair-wise neighbors stored
 per processor.  The max and min values give the spread of these values
 across processors with a 10-bin histogram showing the distribution.
 The total number of histogram counts is equal to the number of
 processors.
 
 The last section gives aggregate statistics for pair-wise neighbors
 and special neighbors that LAMMPS keeps track of (see the
 "special_bonds"_special_bonds.html command).  The number of times
 neighbor lists were rebuilt during the run is given as well as the
 number of potentially "dangerous" rebuilds.  If atom movement
 triggered neighbor list rebuilding (see the
 "neigh_modify"_neigh_modify.html command), then dangerous
 reneighborings are those that were triggered on the first timestep
 atom movement was checked for.  If this count is non-zero you may wish
 to reduce the delay factor to insure no force interactions are missed
 by atoms moving beyond the neighbor skin distance before a rebuild
 takes place.
 
 If an energy minimization was performed via the
 "minimize"_minimize.html command, additional information is printed,
 e.g.
 
 Minimization stats:
   E initial, next-to-last, final = -0.895962 -2.94193 -2.94342
   Gradient 2-norm init/final= 1920.78 20.9992
   Gradient inf-norm init/final= 304.283 9.61216
   Iterations = 36
   Force evaluations = 177 :pre
 
 The first line lists the initial and final energy, as well as the
 energy on the next-to-last iteration.  The next 2 lines give a measure
 of the gradient of the energy (force on all atoms).  The 2-norm is the
 "length" of this force vector; the inf-norm is the largest component.
 The last 2 lines are statistics on how many iterations and
 force-evaluations the minimizer required.  Multiple force evaluations
 are typically done at each iteration to perform a 1d line minimization
 in the search direction.
 
 If a "kspace_style"_kspace_style.html long-range Coulombics solve was
 performed during the run (PPPM, Ewald), then additional information is
 printed, e.g.
 
 FFT time (% of Kspce) = 0.200313 (8.34477)
 FFT Gflps 3d 1d-only = 2.31074 9.19989 :pre
 
 The first line gives the time spent doing 3d FFTs (4 per timestep) and
 the fraction it represents of the total KSpace time (listed above).
 Each 3d FFT requires computation (3 sets of 1d FFTs) and communication
 (transposes).  The total flops performed is 5Nlog_2(N), where N is the
 number of points in the 3d grid.  The FFTs are timed with and without
 the communication and a Gflop rate is computed.  The 3d rate is with
 communication; the 1d rate is without (just the 1d FFTs).  Thus you
 can estimate what fraction of your FFT time was spent in
 communication, roughly 75% in the example above.
 
 :line
 
 2.8 Running on GPUs :h4,link(2_8)
 
 A few LAMMPS "pair styles"_pair_style.html can be run on graphical
 processing units (GPUs).  We plan to add more over time.  Currently,
 they only support NVIDIA GPU cards.  To use them you need to install
 certain NVIDIA CUDA software on your system:
 
 Check if you have an NVIDIA card: cat /proc/driver/nvidia/cards/0
 Go to http://www.nvidia.com/object/cuda_get.html
 Install a driver and toolkit appropriate for your system (SDK is not necessary)
 Follow the instructions in README in lammps/lib/gpu to build the library.
 Run lammps/lib/gpu/nvc_get_devices to list supported devices and properties :ul
 
 GPU configuration :h4
 
 When using GPUs, you are restricted to one physical GPU per LAMMPS
 process. Multiple processes can share a single GPU and in many cases it
 will be more efficient to run with multiple processes per GPU. Any GPU
 accelerated style requires that "fix gpu"_fix_gpu.html be used in the
 input script to select and initialize the GPUs. The format for the fix
 is:
 
 fix {name} all gpu {mode} {first} {last} {split} :pre
 
 where {name} is the name for the fix. The gpu fix must be the first
 fix specified for a given run, otherwise the program will exit
 with an error. The gpu fix will not have any effect on runs 
 that do not use GPU acceleration; there should be no problem
 with specifying the fix first in any input script.
 
 {mode} can be either "force" or "force/neigh". In the former,
 neighbor list calculation is performed on the CPU using the
 standard LAMMPS routines. In the latter, the neighbor list
 calculation is performed on the GPU. The GPU neighbor list
 can be used for better performance, however, it 
 should not be used with a triclinic box.
 
 There are cases when it might be more efficient to select the CPU for neighbor
 list builds. If a non-GPU enabled style requires a neighbor list, it will also
 be built using CPU routines. Redundant CPU and GPU neighbor list calculations
 will typically be less efficient. For "hybrid"_pair_hybrid.html pair
 styles, GPU calculated neighbor lists might be less efficient because
 no particles will be skipped in a given neighbor list.
 
 {first} is the ID (as reported by lammps/lib/gpu/nvc_get_devices)
 of the first GPU that will be used on each node. {last} is the
 ID of the last GPU that will be used on each node. If you have
 only one GPU per node, {first} and {last} will typically both be
 0. Selecting a non-sequential set of GPU IDs (e.g. 0,1,3)
 is not currently supported.
 
 {split} is the fraction of particles whose forces, torques,
 energies, and/or virials will be calculated on the GPU. This
 can be used to perform CPU and GPU force calculations
 simultaneously. If {split} is negative, the software will
 attempt to calculate the optimal fraction automatically 
 every 25 timesteps based on CPU and GPU timings. Because the GPU speedups
 are dependent on the number of particles, automatic calculation of the
 split can be less efficient, but typically results in loop times
 within 20% of an optimal fixed split.
 
 If you have two GPUs per node, 8 CPU cores per node, and
 would like to run on 4 nodes with dynamic balancing of
 force calculation across CPU and GPU cores, the fix
 might be
 
 fix 0 all gpu force/neigh 0 1 -1 :pre
 
 with LAMMPS run on 32 processes. In this case, all
 CPU cores and GPU devices on the nodes would be utilized.
 Each GPU device would be shared by 4 CPU cores. The
 CPU cores would perform force calculations for some
 fraction of the particles at the same time the GPUs
 performed force calculation for the other particles.
 
 Because of the large number of cores on each GPU
 device, it might be more efficient to run on fewer
 processes per GPU when the number of particles per process
 is small (100's of particles); this can be necessary
 to keep the GPU cores busy.
 
 GPU input script :h4
 
 In order to use GPU acceleration in LAMMPS, 
 "fix_gpu"_fix_gpu.html
 should be used in order to initialize and configure the
 GPUs for use. Additionally, GPU enabled styles must be
 selected in the input script. Currently,
 this is limited to a few "pair styles"_pair_style.html.
 Some GPU-enabled styles have additional restrictions
 listed in their documentation.
 
 GPU asynchronous pair computation :h4
 
 The GPU accelerated pair styles can be used to perform
 pair style force calculation on the GPU while other 
 calculations are
 performed on the CPU. One method to do this is to specify
 a {split} in the gpu fix as described above. In this case,
 force calculation for the pair style will also be performed
 on the CPU. 
 
 When the CPU work in a GPU pair style has finished,
 the next force computation will begin, possibly before the
 GPU has finished. If {split} is 1.0 in the gpu fix, the next
 force computation will begin almost immediately. This can
 be used to run a "hybrid"_pair_hybrid.html GPU pair style at 
 the same time as a hybrid CPU pair style. In this case, the 
 GPU pair style should be first in the hybrid command in order to
 perform simultaneous calculations. This also
 allows "bond"_bond_style.html, "angle"_angle_style.html, 
 "dihedral"_dihedral_style.html, "improper"_improper_style.html, 
 and "long-range"_kspace_style.html force
 computations to be run simultaneously with the GPU pair style.
 Once all CPU force computations have completed, the gpu fix
 will block until the GPU has finished all work before continuing
 the run.
 
 GPU timing :h4
 
 GPU accelerated pair styles can perform computations asynchronously
 with CPU computations. The "Pair" time reported by LAMMPS
 will be the maximum of the time required to complete the CPU
 pair style computations and the time required to complete the GPU
 pair style computations. Any time spent for GPU-enabled pair styles
 for computations that run simultaneously with "bond"_bond_style.html, 
 "angle"_angle_style.html, "dihedral"_dihedral_style.html, 
 "improper"_improper_style.html, and "long-range"_kspace_style.html calculations
 will not be included in the "Pair" time.
 
 When {mode} for the gpu fix is force/neigh,
 the time for neighbor list calculations on the GPU will be added
 into the "Pair" time, not the "Neigh" time. A breakdown of the
 times required for various tasks on the GPU (data copy, neighbor
 calculations, force computations, etc.) are output only
 with the LAMMPS screen output at the end of each run. These timings represent
 total time spent on the GPU for each routine, regardless of asynchronous
 CPU calculations.
 
 GPU single vs double precision :h4
 
 See the lammps/lib/gpu/README file for instructions on how to build 
 the LAMMPS gpu library for single, mixed, and double precision.  The latter
 requires that your GPU card supports double precision. 
 
 :line
 
 2.9 Tips for users of previous LAMMPS versions :h4,link(2_9)
 
 The current C++ began with a complete rewrite of LAMMPS 2001, which
 was written in F90.  Features of earlier versions of LAMMPS are listed
 in "this section"_Section_history.html.  The F90 and F77 versions
 (2001 and 99) are also freely distributed as open-source codes; check
 the "LAMMPS WWW Site"_lws for distribution information if you prefer
 those versions.  The 99 and 2001 versions are no longer under active
 development; they do not have all the features of C++ LAMMPS.
 
 If you are a previous user of LAMMPS 2001, these are the most
 significant changes you will notice in C++ LAMMPS:
 
 (1) The names and arguments of many input script commands have
 changed.  All commands are now a single word (e.g. read_data instead
 of read data).
 
 (2) All the functionality of LAMMPS 2001 is included in C++ LAMMPS,
 but you may need to specify the relevant commands in different ways.
 
 (3) The format of the data file can be streamlined for some problems.
 See the "read_data"_read_data.html command for details.  The data file
 section "Nonbond Coeff" has been renamed to "Pair Coeff" in C++ LAMMPS.
 
 (4) Binary restart files written by LAMMPS 2001 cannot be read by C++
 LAMMPS with a "read_restart"_read_restart.html command.  This is
 because they were output by F90 which writes in a different binary
 format than C or C++ writes or reads.  Use the {restart2data} tool
 provided with LAMMPS 2001 to convert the 2001 restart file to a text
 data file.  Then edit the data file as necessary before using the C++
 LAMMPS "read_data"_read_data.html command to read it in.
 
 (5) There are numerous small numerical changes in C++ LAMMPS that mean
 you will not get identical answers when comparing to a 2001 run.
 However, your initial thermodynamic energy and MD trajectory should be
 close if you have setup the problem for both codes the same.
diff --git a/doc/run.html b/doc/run.html
index d3ac108fb..da99cd1fb 100644
--- a/doc/run.html
+++ b/doc/run.html
@@ -1,189 +1,194 @@
 <HTML>
 <CENTER><A HREF = "http://lammps.sandia.gov">LAMMPS WWW Site</A> - <A HREF = "Manual.html">LAMMPS Documentation</A> - <A HREF = "Section_commands.html#comm">LAMMPS Commands</A> 
 </CENTER>
 
 
 
 
 
 
 <HR>
 
 <H3>run command 
 </H3>
 <P><B>Syntax:</B>
 </P>
 <PRE>run N keyword values ... 
 </PRE>
 <UL><LI>N = # of timesteps 
 
 <LI>zero or more keyword/value pairs may be appended 
 
 <LI>keyword = <I>upto</I> or <I>start</I> or <I>stop</I> or <I>pre</I> or <I>post</I> or <I>every</I> 
 
 <PRE>  <I>upto</I> value = none
   <I>start</I> value = N1
     N1 = timestep at which 1st run started
   <I>stop</I> value = N2
     N2 = timestep at which last run will end
   <I>pre</I> value = <I>no</I> or <I>yes</I>
   <I>post</I> value = <I>no</I> or <I>yes</I> 
   <I>every</I> values = M c1 c2 ...
     M = break the run into M-timestep segments and invoke one or more commands between each segment
     c1,c2,...,cN = one or more LAMMPS commands, each enclosed in quotes
     c1 = NULL means no command will be invoked 
 </PRE>
 
 </UL>
 <P><B>Examples:</B>
 </P>
 <PRE>run 10000
 run 1000000 upto
 run 100 start 0 stop 1000
 run 1000 pre no post yes
 run 100000 start 0 stop 1000000 every 1000 "print 'Protein Rg = $r'"
 run 100000 every 1000 NULL 
 </PRE>
 <P><B>Description:</B>
 </P>
 <P>Run or continue dynamics for a specified number of timesteps.
 </P>
 <P>When the <A HREF = "run_style.html">run style</A> is <I>respa</I>, N refers to outer
 loop (largest) timesteps.
 </P>
 <P>A value of N = 0 is acceptable; only the thermodynamics of the system
 are computed and printed without taking a timestep.
 </P>
 <P>The <I>upto</I> keyword means to perform a run starting at the current
 timestep up to the specified timestep.  E.g. if the current timestep
 is 10,000 and "run 100000 upto" is used, then an additional 90,000
 timesteps will be run.  This can be useful for very long runs on a
 machine that allocates chunks of time and terminate your job when time
 is exceeded.  If you need to restart your script multiple times
 (reading in the last restart file), you can keep restarting your
 script with the same run command until the simulation finally
 completes.
 </P>
 <P>The <I>start</I> or <I>stop</I> keywords can be used if multiple runs are being
 performed and you want a <A HREF = "fix.html">fix</A> command that changes some
 value over time (e.g. temperature) to make the change across the
 entire set of runs and not just a single run.  See the doc page for
 individual fixes to see which ones can be used with the <I>start/stop</I>
 keywords.
 </P>
 <P>For example, consider this fix followed by 10 run commands:
 </P>
 <PRE>fix	     1 all nvt 200.0 300.0 1.0
 run	     1000 start 0 stop 10000
 run	     1000 start 0 stop 10000
 ...
 run	     1000 start 0 stop 10000 
 </PRE>
 <P>The NVT fix ramps the target temperature from 200.0 to 300.0 during a
 run.  If the run commands did not have the start/stop keywords (just
 "run 1000"), then the temperature would ramp from 200.0 to 300.0
 during the 1000 steps of each run.  With the start/stop keywords, the
 ramping takes place over the 10000 steps of all runs together.
 </P>
 <P>The <I>pre</I> and <I>post</I> keywords can be used to streamline the setup,
 clean-up, and associated output to the screen that happens before and
 after a run.  This can be useful if you wish to do many short runs in
 succession (e.g. LAMMPS is being called as a library which is doing
 other computations between successive short LAMMPS runs).
 </P>
 <P>By default (pre and post = yes), LAMMPS creates neighbor lists,
 computes forces, and imposes fix constraints before every run.  And
 after every run it gathers and prints timings statistics.  If a run is
 just a continuation of a previous run (i.e. no settings are changed),
 the initial computation is not necessary; the old neighbor list is
 still valid as are the forces.  So if <I>pre</I> is specified as "no" then
 the initial setup is skipped, except for printing thermodynamic info.
 Note that if <I>pre</I> is set to "no" for the very 1st run LAMMPS
 performs, then it is overridden, since the initial setup computations
 must be done.
 </P>
 <P>IMPORTANT NOTE: If your input script changes settings between 2 runs
 (e.g. adds a <A HREF = "fix.html">fix</A> or <A HREF = "dump.html">dump</A> or
 <A HREF = "compute.html">compute</A> or changes a <A HREF = "neigh_modify.html">neighbor</A> list
 parameter), then the initial setup must be performed.  LAMMPS does not
 check for this, but it would be an error to use the <I>pre no</I> option in
 this case.
 </P>
 <P>If <I>post</I> is specified as "no", the full timing summary is skipped;
 only a one-line summary timing is printed.
 </P>
 <P>The <I>every</I> keyword provides a means of breaking a LAMMPS run into a
 series of shorter runs.  Optionally, one or more LAMMPS commands (c1,
 c2, ..., cN) will be executed in between the short runs.  If used, the
 <I>every</I> keyword must be the last keyword, since it has a variable
 number of arguments.  Each of the trailing arguments is a single
 LAMMPS command, and each command should be enclosed in quotes, so that
 the entire command will be treated as a single argument.  This will
 also prevent any variables in the command from being evaluated until
 it is executed multiple times during the run.  Note that if a command
 itself needs one of its arguments quoted (e.g. the <A HREF = "print.html">print</A>
 command), then you can use a combination of single and double quotes,
 as in the example above or below.
 </P>
 <P>The <I>every</I> keyword is a means to avoid listing a long series of runs
 and interleaving commands in your input script.  For example, a
 <A HREF = "print.html">print</A> command could be invoked or a <A HREF = "fix.html">fix</A> could
 be redefined, e.g. to reset a thermostat temperature.  Or this could
 be useful for invoking a command you have added to LAMMPS that wraps
 some other code (e.g. as a library) to perform a computation
 periodically during a long LAMMPS run.  See <A HREF = "Section_modify.html">this
 section</A> of the documentation for info about how
 to add new commands to LAMMPS.  See <A HREF = "Section_howto.html#4_10">this
 section</A> of the documentation for ideas about
 how to couple LAMMPS to other codes.
 </P>
 <P>With the <I>every</I> option, N total steps are simulated, in shorter runs
 of M steps each.  After each M-length run, the specified commands are
 invoked.  If only a single command is specified as NULL, then no
 command is invoked.  Thus these lines:
 </P>
 <PRE>variable q equal x[100]
 run 6000 every 2000 "print Coord = $q" 
 </PRE>
 <P>are the equivalent of:
 </P>
 <PRE>variable q equal x[100]
 run 2000
 print Coord = $q
 run 2000
 print Coord = $q
 run 2000
 print Coord = $q 
 </PRE>
 <P>which does 3 runs of 2000 steps and prints the x-coordinate of a
 particular atom between runs.  Note that the variable "$q" will
 be evaluated afresh each time the print command is executed.
 </P>
 <P>Note that by using the line continuation character "&", the run every
 command can be spread across many lines, though it is still a single
 command:
 </P>
 <PRE>run 100000 every 1000 &
   "print 'Minimum value = $a'" &
   "print 'Maximum value = $b'" &
   "print 'Temp = $c'" &
   "print 'Press = $d'" 
 </PRE>
 <P>If the <I>pre</I> and <I>post</I> options are set to "no" when used with the
 <I>every</I> keyword, then the 1st run will do the full setup and the last
 run will print the full timing summary, but these operations will be
 skipped for intermediate runs.
 </P>
-<P><B>Restrictions:</B> none
+<P><B>Restrictions:</B>
+</P>
+<P>The number of specified timesteps N must fit in a signed 32-bit
+integer, so you are limited to slightly more than 2 billion steps
+(2^31) in a single run.  However, you can perform successive runs to
+run a simulation for any number of steps (ok, up to 2^63 steps).
 </P>
 <P><B>Related commands:</B>
 </P>
 <P><A HREF = "minimize.html">minimize</A>, <A HREF = "run_style.html">run_style</A>,
 <A HREF = "temper.html">temper</A>
 </P>
 <P><B>Default:</B>
 </P>
 <P>The option defaults are start = the current timestep, stop = current
 timestep + N, pre = yes, and post = yes.
 </P>
 </HTML>
diff --git a/doc/run.txt b/doc/run.txt
index 7561559c2..febf22777 100644
--- a/doc/run.txt
+++ b/doc/run.txt
@@ -1,180 +1,185 @@
 "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc :c
 
 :link(lws,http://lammps.sandia.gov)
 :link(ld,Manual.html)
 :link(lc,Section_commands.html#comm)
 
 :line
 
 run command :h3
 
 [Syntax:]
 
 run N keyword values ... :pre
 
 N = # of timesteps :ulb,l
 zero or more keyword/value pairs may be appended :l
 keyword = {upto} or {start} or {stop} or {pre} or {post} or {every} :l
   {upto} value = none
   {start} value = N1
     N1 = timestep at which 1st run started
   {stop} value = N2
     N2 = timestep at which last run will end
   {pre} value = {no} or {yes}
   {post} value = {no} or {yes} 
   {every} values = M c1 c2 ...
     M = break the run into M-timestep segments and invoke one or more commands between each segment
     c1,c2,...,cN = one or more LAMMPS commands, each enclosed in quotes
     c1 = NULL means no command will be invoked :pre
 :ule
 
 [Examples:]
 
 run 10000
 run 1000000 upto
 run 100 start 0 stop 1000
 run 1000 pre no post yes
 run 100000 start 0 stop 1000000 every 1000 "print 'Protein Rg = $r'"
 run 100000 every 1000 NULL :pre
 
 [Description:]
 
 Run or continue dynamics for a specified number of timesteps.
 
 When the "run style"_run_style.html is {respa}, N refers to outer
 loop (largest) timesteps.
 
 A value of N = 0 is acceptable; only the thermodynamics of the system
 are computed and printed without taking a timestep.
 
 The {upto} keyword means to perform a run starting at the current
 timestep up to the specified timestep.  E.g. if the current timestep
 is 10,000 and "run 100000 upto" is used, then an additional 90,000
 timesteps will be run.  This can be useful for very long runs on a
 machine that allocates chunks of time and terminate your job when time
 is exceeded.  If you need to restart your script multiple times
 (reading in the last restart file), you can keep restarting your
 script with the same run command until the simulation finally
 completes.
 
 The {start} or {stop} keywords can be used if multiple runs are being
 performed and you want a "fix"_fix.html command that changes some
 value over time (e.g. temperature) to make the change across the
 entire set of runs and not just a single run.  See the doc page for
 individual fixes to see which ones can be used with the {start/stop}
 keywords.
 
 For example, consider this fix followed by 10 run commands:
 
 fix	     1 all nvt 200.0 300.0 1.0
 run	     1000 start 0 stop 10000
 run	     1000 start 0 stop 10000
 ...
 run	     1000 start 0 stop 10000 :pre
 
 The NVT fix ramps the target temperature from 200.0 to 300.0 during a
 run.  If the run commands did not have the start/stop keywords (just
 "run 1000"), then the temperature would ramp from 200.0 to 300.0
 during the 1000 steps of each run.  With the start/stop keywords, the
 ramping takes place over the 10000 steps of all runs together.
 
 The {pre} and {post} keywords can be used to streamline the setup,
 clean-up, and associated output to the screen that happens before and
 after a run.  This can be useful if you wish to do many short runs in
 succession (e.g. LAMMPS is being called as a library which is doing
 other computations between successive short LAMMPS runs).
 
 By default (pre and post = yes), LAMMPS creates neighbor lists,
 computes forces, and imposes fix constraints before every run.  And
 after every run it gathers and prints timings statistics.  If a run is
 just a continuation of a previous run (i.e. no settings are changed),
 the initial computation is not necessary; the old neighbor list is
 still valid as are the forces.  So if {pre} is specified as "no" then
 the initial setup is skipped, except for printing thermodynamic info.
 Note that if {pre} is set to "no" for the very 1st run LAMMPS
 performs, then it is overridden, since the initial setup computations
 must be done.
 
 IMPORTANT NOTE: If your input script changes settings between 2 runs
 (e.g. adds a "fix"_fix.html or "dump"_dump.html or
 "compute"_compute.html or changes a "neighbor"_neigh_modify.html list
 parameter), then the initial setup must be performed.  LAMMPS does not
 check for this, but it would be an error to use the {pre no} option in
 this case.
 
 If {post} is specified as "no", the full timing summary is skipped;
 only a one-line summary timing is printed.
 
 The {every} keyword provides a means of breaking a LAMMPS run into a
 series of shorter runs.  Optionally, one or more LAMMPS commands (c1,
 c2, ..., cN) will be executed in between the short runs.  If used, the
 {every} keyword must be the last keyword, since it has a variable
 number of arguments.  Each of the trailing arguments is a single
 LAMMPS command, and each command should be enclosed in quotes, so that
 the entire command will be treated as a single argument.  This will
 also prevent any variables in the command from being evaluated until
 it is executed multiple times during the run.  Note that if a command
 itself needs one of its arguments quoted (e.g. the "print"_print.html
 command), then you can use a combination of single and double quotes,
 as in the example above or below.
 
 The {every} keyword is a means to avoid listing a long series of runs
 and interleaving commands in your input script.  For example, a
 "print"_print.html command could be invoked or a "fix"_fix.html could
 be redefined, e.g. to reset a thermostat temperature.  Or this could
 be useful for invoking a command you have added to LAMMPS that wraps
 some other code (e.g. as a library) to perform a computation
 periodically during a long LAMMPS run.  See "this
 section"_Section_modify.html of the documentation for info about how
 to add new commands to LAMMPS.  See "this
 section"_Section_howto.html#4_10 of the documentation for ideas about
 how to couple LAMMPS to other codes.
 
 With the {every} option, N total steps are simulated, in shorter runs
 of M steps each.  After each M-length run, the specified commands are
 invoked.  If only a single command is specified as NULL, then no
 command is invoked.  Thus these lines:
 
 variable q equal x\[100\]
 run 6000 every 2000 "print Coord = $q" :pre
 
 are the equivalent of:
 
 variable q equal x\[100\]
 run 2000
 print Coord = $q
 run 2000
 print Coord = $q
 run 2000
 print Coord = $q :pre
 
 which does 3 runs of 2000 steps and prints the x-coordinate of a
 particular atom between runs.  Note that the variable "$q" will
 be evaluated afresh each time the print command is executed.
 
 Note that by using the line continuation character "&", the run every
 command can be spread across many lines, though it is still a single
 command:
 
 run 100000 every 1000 &
   "print 'Minimum value = $a'" &
   "print 'Maximum value = $b'" &
   "print 'Temp = $c'" &
   "print 'Press = $d'" :pre
 
 If the {pre} and {post} options are set to "no" when used with the
 {every} keyword, then the 1st run will do the full setup and the last
 run will print the full timing summary, but these operations will be
 skipped for intermediate runs.
 
-[Restrictions:] none
+[Restrictions:]
+
+The number of specified timesteps N must fit in a signed 32-bit
+integer, so you are limited to slightly more than 2 billion steps
+(2^31) in a single run.  However, you can perform successive runs to
+run a simulation for any number of steps (ok, up to 2^63 steps).
 
 [Related commands:]
 
 "minimize"_minimize.html, "run_style"_run_style.html,
 "temper"_temper.html
 
 [Default:]
 
 The option defaults are start = the current timestep, stop = current
 timestep + N, pre = yes, and post = yes.
diff --git a/src/ASPHERE/atom_vec_ellipsoid.cpp b/src/ASPHERE/atom_vec_ellipsoid.cpp
index ddf95831a..e48e7ae30 100755
--- a/src/ASPHERE/atom_vec_ellipsoid.cpp
+++ b/src/ASPHERE/atom_vec_ellipsoid.cpp
@@ -1,847 +1,850 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "stdlib.h"
 #include "atom_vec_ellipsoid.h"
+#include "lmptype.h"
 #include "math_extra.h"
 #include "atom.h"
 #include "force.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecEllipsoid::AtomVecEllipsoid(LAMMPS *lmp, int narg, char **arg) :
   AtomVec(lmp, narg, arg)
 {
   molecular = 0;
   mass_type = 1;
   shape_type = 1;
 
   comm_x_only = comm_f_only = 0;
   size_forward = 7;
   size_reverse = 6;
   size_border = 10;
   size_velocity = 6;
   size_data_atom = 9;
   size_data_vel = 7;
   xcol_data = 3;
 
   atom->angmom_flag = atom->torque_flag = atom->quat_flag = 1;
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n
 ------------------------------------------------------------------------- */
 
 void AtomVecEllipsoid::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
 
   tag = atom->tag = (int *)
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *)
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *)
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
 
   quat = atom->quat = 
     memory->grow_2d_double_array(atom->quat,nmax,4,"atom:quat");
   angmom = atom->angmom = 
     memory->grow_2d_double_array(atom->angmom,nmax,3,"atom:angmom");
   torque = atom->torque = 
     memory->grow_2d_double_array(atom->torque,nmax,3,"atom:torque");
   
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecEllipsoid::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
   quat = atom->quat; angmom = atom->angmom; torque = atom->torque;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecEllipsoid::copy(int i, int j)
 {
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
 
   quat[j][0] = quat[i][0];
   quat[j][1] = quat[i][1];
   quat[j][2] = quat[i][2];
   quat[j][3] = quat[i][3];
   angmom[j][0] = angmom[i][0];
   angmom[j][1] = angmom[i][1];
   angmom[j][2] = angmom[i][2];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::pack_comm(int n, int *list, double *buf,
 			     int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = quat[j][0];
       buf[m++] = quat[j][1];
       buf[m++] = quat[j][2];
       buf[m++] = quat[j][3];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = quat[j][0];
       buf[m++] = quat[j][1];
       buf[m++] = quat[j][2];
       buf[m++] = quat[j][3];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::pack_comm_vel(int n, int *list, double *buf,
 				    int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = quat[j][0];
       buf[m++] = quat[j][1];
       buf[m++] = quat[j][2];
       buf[m++] = quat[j][3];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = angmom[j][0];
       buf[m++] = angmom[j][1];
       buf[m++] = angmom[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = quat[j][0];
       buf[m++] = quat[j][1];
       buf[m++] = quat[j][2];
       buf[m++] = quat[j][3];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = angmom[j][0];
       buf[m++] = angmom[j][1];
       buf[m++] = angmom[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::pack_comm_one(int i, double *buf)
 {
   buf[0] = quat[i][0];
   buf[1] = quat[i][1];
   buf[2] = quat[i][2];
   buf[3] = quat[i][3];
   return 4;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecEllipsoid::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     quat[i][0] = buf[m++];
     quat[i][1] = buf[m++];
     quat[i][2] = buf[m++];
     quat[i][3] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecEllipsoid::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     quat[i][0] = buf[m++];
     quat[i][1] = buf[m++];
     quat[i][2] = buf[m++];
     quat[i][3] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
     angmom[i][0] = buf[m++];
     angmom[i][1] = buf[m++];
     angmom[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::unpack_comm_one(int i, double *buf)
 {
   quat[i][0] = buf[0];
   quat[i][1] = buf[1];
   quat[i][2] = buf[2];
   quat[i][3] = buf[3];
   return 4;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
     buf[m++] = torque[i][0];
     buf[m++] = torque[i][1];
     buf[m++] = torque[i][2];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::pack_reverse_one(int i, double *buf)
 {
   buf[0] = torque[i][0];
   buf[1] = torque[i][1];
   buf[2] = torque[i][2];
   return 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecEllipsoid::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
     torque[j][0] += buf[m++];
     torque[j][1] += buf[m++];
     torque[j][2] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::unpack_reverse_one(int i, double *buf)
 {
   torque[i][0] += buf[0];
   torque[i][1] += buf[1];
   torque[i][2] += buf[2];
   return 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::pack_border(int n, int *list, double *buf,
 				  int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = quat[j][0];
       buf[m++] = quat[j][1];
       buf[m++] = quat[j][2];
       buf[m++] = quat[j][3];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = quat[j][0];
       buf[m++] = quat[j][1];
       buf[m++] = quat[j][2];
       buf[m++] = quat[j][3];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::pack_border_vel(int n, int *list, double *buf,
 				      int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = quat[j][0];
       buf[m++] = quat[j][1];
       buf[m++] = quat[j][2];
       buf[m++] = quat[j][3];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = angmom[j][0];
       buf[m++] = angmom[j][1];
       buf[m++] = angmom[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = quat[j][0];
       buf[m++] = quat[j][1];
       buf[m++] = quat[j][2];
       buf[m++] = quat[j][3];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = angmom[j][0];
       buf[m++] = angmom[j][1];
       buf[m++] = angmom[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::pack_border_one(int i, double *buf)
 {
   buf[0] = quat[i][0];
   buf[1] = quat[i][1];
   buf[2] = quat[i][2];
   buf[3] = quat[i][3];
   return 4;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecEllipsoid::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     quat[i][0] = buf[m++];
     quat[i][1] = buf[m++];
     quat[i][2] = buf[m++];
     quat[i][3] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecEllipsoid::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     quat[i][0] = buf[m++];
     quat[i][1] = buf[m++];
     quat[i][2] = buf[m++];
     quat[i][3] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
     angmom[i][0] = buf[m++];
     angmom[i][1] = buf[m++];
     angmom[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::unpack_border_one(int i, double *buf)
 {
   quat[i][0] = buf[0];
   quat[i][1] = buf[1];
   quat[i][2] = buf[2];
   quat[i][3] = buf[3];
   return 4;
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    xyz must be 1st 3 values, so comm::exchange() can test on them
 ------------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::pack_exchange(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
 
   buf[m++] = quat[i][0];
   buf[m++] = quat[i][1];
   buf[m++] = quat[i][2];
   buf[m++] = quat[i][3];
   buf[m++] = angmom[i][0];
   buf[m++] = angmom[i][1];
   buf[m++] = angmom[i][2];
   
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::unpack_exchange(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
 
   quat[nlocal][0] = buf[m++];
   quat[nlocal][1] = buf[m++];
   quat[nlocal][2] = buf[m++];
   quat[nlocal][3] = buf[m++];
   angmom[nlocal][0] = buf[m++];
   angmom[nlocal][1] = buf[m++];
   angmom[nlocal][2] = buf[m++];
   
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::size_restart()
 {
   int i;
 
   int nlocal = atom->nlocal;
   int n = 18 * nlocal;
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
       for (i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive
 ------------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::pack_restart(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
 
   buf[m++] = quat[i][0];
   buf[m++] = quat[i][1];
   buf[m++] = quat[i][2];
   buf[m++] = quat[i][3];
   buf[m++] = angmom[i][0];
   buf[m++] = angmom[i][1];
   buf[m++] = angmom[i][2];
   
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::unpack_restart(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store) 
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
 
   quat[nlocal][0] = buf[m++];
   quat[nlocal][1] = buf[m++];
   quat[nlocal][2] = buf[m++];
   quat[nlocal][3] = buf[m++];
   angmom[nlocal][0] = buf[m++];
   angmom[nlocal][1] = buf[m++];
   angmom[nlocal][2] = buf[m++];
   
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
 
 void AtomVecEllipsoid::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   quat[nlocal][0] = 1.0;
   quat[nlocal][1] = 0.0;
   quat[nlocal][2] = 0.0;
   quat[nlocal][3] = 0.0;
   angmom[nlocal][0] = 0.0;
   angmom[nlocal][1] = 0.0;
   angmom[nlocal][2] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
 void AtomVecEllipsoid::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
 
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   quat[nlocal][0] = atof(values[5]);
   quat[nlocal][1] = atof(values[6]);
   quat[nlocal][2] = atof(values[7]);
   quat[nlocal][3] = atof(values[8]);
   MathExtra::normalize4(quat[nlocal]);
 
   image[nlocal] = imagetmp;
 
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   angmom[nlocal][0] = 0.0;
   angmom[nlocal][1] = 0.0;
   angmom[nlocal][2] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Atoms section of data file
    initialize other atom quantities for this sub-style
 ------------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::data_atom_hybrid(int nlocal, char **values)
 {
   quat[nlocal][0] = atof(values[0]);
   quat[nlocal][1] = atof(values[1]);
   quat[nlocal][2] = atof(values[2]);
   quat[nlocal][3] = atof(values[3]);
   MathExtra::normalize4(quat[nlocal]);
 
   return 4;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Velocities section of data file
 ------------------------------------------------------------------------- */
 
 void AtomVecEllipsoid::data_vel(int m, char **values)
 {
   v[m][0] = atof(values[0]);
   v[m][1] = atof(values[1]);
   v[m][2] = atof(values[2]);
   angmom[m][0] = atof(values[3]);
   angmom[m][1] = atof(values[4]);
   angmom[m][2] = atof(values[5]);
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Velocities section of data file
 ------------------------------------------------------------------------- */
 
 int AtomVecEllipsoid::data_vel_hybrid(int m, char **values)
 {
   angmom[m][0] = atof(values[0]);
   angmom[m][1] = atof(values[1]);
   angmom[m][2] = atof(values[2]);
   return 3;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory
 ------------------------------------------------------------------------- */
 
 double AtomVecEllipsoid::memory_usage()
 {
   double bytes = 0.0;
 
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
 
   if (atom->memcheck("quat")) bytes += nmax*4 * sizeof(double);
   if (atom->memcheck("angmom")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("torque")) bytes += nmax*3 * sizeof(double);
 
   return bytes;
 }
diff --git a/src/CLASS2/dihedral_class2.cpp b/src/CLASS2/dihedral_class2.cpp
index e4a42b18f..bf29f6457 100644
--- a/src/CLASS2/dihedral_class2.cpp
+++ b/src/CLASS2/dihedral_class2.cpp
@@ -1,937 +1,938 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Eric Simon (Cray)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "string.h"
 #include "stdlib.h"
 #include "dihedral_class2.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "neighbor.h"
 #include "update.h"
 #include "domain.h"
 #include "comm.h"
 #include "force.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define TOLERANCE 0.05
 #define SMALL     0.0000001
 
 /* ---------------------------------------------------------------------- */
 
 DihedralClass2::DihedralClass2(LAMMPS *lmp) : Dihedral(lmp)
 {
   PI = 4.0*atan(1.0);
 }
 
 /* ---------------------------------------------------------------------- */
 
 DihedralClass2::~DihedralClass2()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(setflag_d);
     memory->sfree(setflag_mbt);
     memory->sfree(setflag_ebt);
     memory->sfree(setflag_at);
     memory->sfree(setflag_aat);
     memory->sfree(setflag_bb13t);
 
     memory->sfree(k1);
     memory->sfree(k2);
     memory->sfree(k3);
     memory->sfree(phi1);
     memory->sfree(phi2);
     memory->sfree(phi3);
 
     memory->sfree(mbt_f1);
     memory->sfree(mbt_f2);
     memory->sfree(mbt_f3);
     memory->sfree(mbt_r0);
 
     memory->sfree(ebt_f1_1);
     memory->sfree(ebt_f2_1);
     memory->sfree(ebt_f3_1);
     memory->sfree(ebt_r0_1);
 
     memory->sfree(ebt_f1_2);
     memory->sfree(ebt_f2_2);
     memory->sfree(ebt_f3_2);
     memory->sfree(ebt_r0_2);
 
     memory->sfree(at_f1_1);
     memory->sfree(at_f2_1);
     memory->sfree(at_f3_1);
     memory->sfree(at_theta0_1);
 
     memory->sfree(at_f1_2);
     memory->sfree(at_f2_2);
     memory->sfree(at_f3_2);
     memory->sfree(at_theta0_2);
 
     memory->sfree(aat_k);
     memory->sfree(aat_theta0_1);
     memory->sfree(aat_theta0_2);
 
     memory->sfree(bb13t_k);
     memory->sfree(bb13t_r10);
     memory->sfree(bb13t_r30);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralClass2::compute(int eflag, int vflag)
 {
   int i1,i2,i3,i4,i,j,k,n,type;
   double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
   double edihedral;
   double r1mag2,r1,r2mag2,r2,r3mag2,r3;
   double sb1,rb1,sb2,rb2,sb3,rb3,c0,r12c1;
   double r12c2,costh12,costh13,costh23,sc1,sc2,s1,s2,c;
   double cosphi,phi,sinphi,a11,a22,a33,a12,a13,a23,sx1,sx2;
   double sx12,sy1,sy2,sy12,sz1,sz2,sz12,dphi1,dphi2,dphi3;
   double de_dihedral,t1,t2,t3,t4,cos2phi,cos3phi,bt1,bt2;
   double bt3,sumbte,db,sumbtf,at1,at2,at3,da,da1,da2,r1_0;
   double r3_0,dr1,dr2,tk1,tk2,s12,sin2;
   double dcosphidr[4][3],dphidr[4][3],dbonddr[3][4][3],dthetadr[2][4][3];
   double fabcd[4][3];
 
   edihedral = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   double **x = atom->x;
   double **f = atom->f;
   int **dihedrallist = neighbor->dihedrallist;
   int ndihedrallist = neighbor->ndihedrallist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < ndihedrallist; n++) {
     i1 = dihedrallist[n][0];
     i2 = dihedrallist[n][1];
     i3 = dihedrallist[n][2];
     i4 = dihedrallist[n][3];
     type = dihedrallist[n][4];
 
     // 1st bond
 
     vb1x = x[i1][0] - x[i2][0];
     vb1y = x[i1][1] - x[i2][1];
     vb1z = x[i1][2] - x[i2][2];
     domain->minimum_image(vb1x,vb1y,vb1z);
 
     // 2nd bond
 
     vb2x = x[i3][0] - x[i2][0];
     vb2y = x[i3][1] - x[i2][1];
     vb2z = x[i3][2] - x[i2][2];
     domain->minimum_image(vb2x,vb2y,vb2z);
 
     vb2xm = -vb2x;
     vb2ym = -vb2y;
     vb2zm = -vb2z;
     domain->minimum_image(vb2xm,vb2ym,vb2zm);
 
     // 3rd bond
 
     vb3x = x[i4][0] - x[i3][0];
     vb3y = x[i4][1] - x[i3][1];
     vb3z = x[i4][2] - x[i3][2];
     domain->minimum_image(vb3x,vb3y,vb3z);
 
     // distances
 
     r1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
     r1 = sqrt(r1mag2);
     r2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
     r2 = sqrt(r2mag2);
     r3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
     r3 = sqrt(r3mag2);
 
     sb1 = 1.0/r1mag2;
     rb1 = 1.0/r1;
     sb2 = 1.0/r2mag2;
     rb2 = 1.0/r2;
     sb3 = 1.0/r3mag2;
     rb3 = 1.0/r3;
 
     c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
 
     // angles
 
     r12c1 = rb1*rb2;
     r12c2 = rb2*rb3;
     costh12 = (vb1x*vb2x + vb1y*vb2y + vb1z*vb2z) * r12c1;
     costh13 = c0;
     costh23 = (vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z) * r12c2;
           
     // cos and sin of 2 angles and final c
 
     sin2 = MAX(1.0 - costh12*costh12,0.0);
     sc1 = sqrt(sin2);
     if (sc1 < SMALL) sc1 = SMALL;
     sc1 = 1.0/sc1;
           
     sin2 = MAX(1.0 - costh23*costh23,0.0);
     sc2 = sqrt(sin2);
     if (sc2 < SMALL) sc2 = SMALL;
     sc2 = 1.0/sc2;
           
     s1 = sc1 * sc1;
     s2 = sc2 * sc2;
     s12 = sc1 * sc2;
     c = (c0 + costh12*costh23) * s12;
 
     // error check
 
     if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
       int me;
       MPI_Comm_rank(world,&me);
       if (screen) {
-	char str[128];
-	sprintf(str,"Dihedral problem: %d %d %d %d %d %d",
-		me,update->ntimestep,
+	char str[128],fstr[64];
+	sprintf(fstr,"Dihedral problem: %%d %s %%d %%d %%d %%d",BIGINT_FORMAT);
+	sprintf(str,fstr,me,update->ntimestep,
 		atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
 	error->warning(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]);
 	fprintf(screen,"  3rd atom: %d %g %g %g\n",
 		me,x[i3][0],x[i3][1],x[i3][2]);
 	fprintf(screen,"  4th atom: %d %g %g %g\n",
 		me,x[i4][0],x[i4][1],x[i4][2]);
       }
     }
 
     if (c > 1.0) c = 1.0;
     if (c < -1.0) c = -1.0;
     cosphi = c;
     phi = acos(c);
 
     sinphi = sqrt(1.0 - c*c);
     sinphi = MAX(sinphi,SMALL);
 
     a11 = -c*sb1*s1;
     a22 = sb2 * (2.0*costh13*s12 - c*(s1+s2));
     a33 = -c*sb3*s2;
     a12 = r12c1 * (costh12*c*s1 + costh23*s12);
     a13 = rb1*rb3*s12;
     a23 = r12c2 * (-costh23*c*s2 - costh12*s12);
           
     sx1  = a11*vb1x + a12*vb2x + a13*vb3x;
     sx2  = a12*vb1x + a22*vb2x + a23*vb3x;
     sx12 = a13*vb1x + a23*vb2x + a33*vb3x;
     sy1  = a11*vb1y + a12*vb2y + a13*vb3y;
     sy2  = a12*vb1y + a22*vb2y + a23*vb3y;
     sy12 = a13*vb1y + a23*vb2y + a33*vb3y;
     sz1  = a11*vb1z + a12*vb2z + a13*vb3z;
     sz2  = a12*vb1z + a22*vb2z + a23*vb3z;
     sz12 = a13*vb1z + a23*vb2z + a33*vb3z;
 
     // set up d(cos(phi))/d(r) and dphi/dr arrays
 
     dcosphidr[0][0] = -sx1;
     dcosphidr[0][1] = -sy1;
     dcosphidr[0][2] = -sz1;
     dcosphidr[1][0] = sx2 + sx1;
     dcosphidr[1][1] = sy2 + sy1;
     dcosphidr[1][2] = sz2 + sz1;
     dcosphidr[2][0] = sx12 - sx2;
     dcosphidr[2][1] = sy12 - sy2;
     dcosphidr[2][2] = sz12 - sz2;
     dcosphidr[3][0] = -sx12;
     dcosphidr[3][1] = -sy12;
     dcosphidr[3][2] = -sz12;
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++)
 	dphidr[i][j] = -dcosphidr[i][j] / sinphi;
 
     // energy
 
     dphi1 = phi - phi1[type];
     dphi2 = 2.0*phi - phi2[type];
     dphi3 = 3.0*phi - phi3[type];
     
     if (eflag) edihedral = k1[type]*(1.0 - cos(dphi1)) +
 		 k2[type]*(1.0 - cos(dphi2)) +
 		 k3[type]*(1.0 - cos(dphi3));
     
     de_dihedral = k1[type]*sin(dphi1) + 2.0*k2[type]*sin(dphi2) +
       3.0*k3[type]*sin(dphi3);
 
     // torsion forces on all 4 atoms
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++)
 	fabcd[i][j] = de_dihedral*dphidr[i][j];
 
     // set up d(bond)/d(r) array
     // dbonddr(i,j,k) = bond i, atom j, coordinate k
 
     for (i = 0; i < 3; i++)
       for (j = 0; j < 4; j++)
 	for (k = 0; k < 3; k++)
 	  dbonddr[i][j][k] = 0.0;
     
     // bond1
     
     dbonddr[0][0][0] = vb1x / r1;
     dbonddr[0][0][1] = vb1y / r1;
     dbonddr[0][0][2] = vb1z / r1;
     dbonddr[0][1][0] = -vb1x / r1;
     dbonddr[0][1][1] = -vb1y / r1;
     dbonddr[0][1][2] = -vb1z / r1;
 
     // bond2
 
     dbonddr[1][1][0] = vb2x / r2;
     dbonddr[1][1][1] = vb2y / r2;
     dbonddr[1][1][2] = vb2z / r2;
     dbonddr[1][2][0] = -vb2x / r2;
     dbonddr[1][2][1] = -vb2y / r2;
     dbonddr[1][2][2] = -vb2z / r2;
 
     // bond3
     
     dbonddr[2][2][0] = vb3x / r3;
     dbonddr[2][2][1] = vb3y / r3;
     dbonddr[2][2][2] = vb3z / r3;
     dbonddr[2][3][0] = -vb3x / r3;
     dbonddr[2][3][1] = -vb3y / r3;
     dbonddr[2][3][2] = -vb3z / r3;
 
     // set up d(theta)/d(r) array
     // dthetadr(i,j,k) = angle i, atom j, coordinate k
 
     for (i = 0; i < 2; i++)
       for (j = 0; j < 4; j++)
 	for (k = 0; k < 3; k++)
 	  dthetadr[i][j][k] = 0.0;
     
     t1 = costh12 / r1mag2;
     t2 = costh23 / r2mag2;
     t3 = costh12 / r2mag2;
     t4 = costh23 / r3mag2;
     
     // angle12
     
     dthetadr[0][0][0] = sc1 * ((t1 * vb1x) - (vb2x * r12c1));
     dthetadr[0][0][1] = sc1 * ((t1 * vb1y) - (vb2y * r12c1));
     dthetadr[0][0][2] = sc1 * ((t1 * vb1z) - (vb2z * r12c1));
     
     dthetadr[0][1][0] = sc1 * ((-t1 * vb1x) + (vb2x * r12c1) +
 			       (-t3 * vb2x) + (vb1x * r12c1));
     dthetadr[0][1][1] = sc1 * ((-t1 * vb1y) + (vb2y * r12c1) +
 			       (-t3 * vb2y) + (vb1y * r12c1));
     dthetadr[0][1][2] = sc1 * ((-t1 * vb1z) + (vb2z * r12c1) +
 			       (-t3 * vb2z) + (vb1z * r12c1));
     
     dthetadr[0][2][0] = sc1 * ((t3 * vb2x) - (vb1x * r12c1)); 
     dthetadr[0][2][1] = sc1 * ((t3 * vb2y) - (vb1y * r12c1));
     dthetadr[0][2][2] = sc1 * ((t3 * vb2z) - (vb1z * r12c1));
     
     // angle23
     
     dthetadr[1][1][0] = sc2 * ((t2 * vb2x) + (vb3x * r12c2));
     dthetadr[1][1][1] = sc2 * ((t2 * vb2y) + (vb3y * r12c2));
     dthetadr[1][1][2] = sc2 * ((t2 * vb2z) + (vb3z * r12c2));
     
     dthetadr[1][2][0] = sc2 * ((-t2 * vb2x) - (vb3x * r12c2) +
 			       (t4 * vb3x) + (vb2x * r12c2));
     dthetadr[1][2][1] = sc2 * ((-t2 * vb2y) - (vb3y * r12c2) +
 			       (t4 * vb3y) + (vb2y * r12c2));
     dthetadr[1][2][2] = sc2 * ((-t2 * vb2z) - (vb3z * r12c2) +
 			       (t4 * vb3z) + (vb2z * r12c2));
     
     dthetadr[1][3][0] = -sc2 * ((t4 * vb3x) + (vb2x * r12c2));
     dthetadr[1][3][1] = -sc2 * ((t4 * vb3y) + (vb2y * r12c2));
     dthetadr[1][3][2] = -sc2 * ((t4 * vb3z) + (vb2z * r12c2));
     
     // mid-bond/torsion coupling
     // energy on bond2 (middle bond)
     
     cos2phi = cos(2.0*phi);
     cos3phi = cos(3.0*phi);
     
     bt1 = mbt_f1[type] * cosphi;
     bt2 = mbt_f2[type] * cos2phi;
     bt3 = mbt_f3[type] * cos3phi;
     sumbte = bt1 + bt2 + bt3;
     db = r2 - mbt_r0[type];
     if (eflag) edihedral += db * sumbte;
     
     // force on bond2
     
     bt1 = -mbt_f1[type] * sinphi;
     bt2 = -2.0 * mbt_f2[type] * sin(2.0*phi);
     bt3 = -3.0 * mbt_f3[type] * sin(3.0*phi);
     sumbtf = bt1 + bt2 + bt3;
     
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++)
 	fabcd[i][j] += db*sumbtf*dphidr[i][j] + sumbte*dbonddr[1][i][j];
 
     // end-bond/torsion coupling
     // energy on bond1 (first bond)
 
     bt1 = ebt_f1_1[type] * cosphi;
     bt2 = ebt_f2_1[type] * cos2phi;
     bt3 = ebt_f3_1[type] * cos3phi;
     sumbte = bt1 + bt2 + bt3;
 
     db = r1 - ebt_r0_1[type];
     if (eflag) edihedral += db * (bt1+bt2+bt3);
 
     // force on bond1
 
     bt1 = ebt_f1_1[type] * sinphi;
     bt2 = 2.0 * ebt_f2_1[type] * sin(2.0*phi);
     bt3 = 3.0 * ebt_f3_1[type] * sin(3.0*phi);
     sumbtf = bt1 + bt2 + bt3;
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++)
 	fabcd[i][j] -= db*sumbtf*dphidr[i][j] + sumbte*dbonddr[0][i][j];
 
     // end-bond/torsion coupling
     // energy on bond3 (last bond)
 
     bt1 = ebt_f1_2[type] * cosphi;
     bt2 = ebt_f2_2[type] * cos2phi;
     bt3 = ebt_f3_2[type] * cos3phi;
     sumbte = bt1 + bt2 + bt3;
 
     db = r3 - ebt_r0_2[type];
     if (eflag) edihedral += db * (bt1+bt2+bt3);
 
     // force on bond3
 
     bt1 = -ebt_f1_2[type] * sinphi;
     bt2 = -2.0 * ebt_f2_2[type] * sin(2.0*phi);
     bt3 = -3.0 * ebt_f3_2[type] * sin(3.0*phi);
     sumbtf = bt1 + bt2 + bt3;
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++)
 	fabcd[i][j] += db*sumbtf*dphidr[i][j] + sumbte*dbonddr[2][i][j];
 
     // angle/torsion coupling
     // energy on angle1
 
     at1 = at_f1_1[type] * cosphi;
     at2 = at_f2_1[type] * cos2phi;
     at3 = at_f3_1[type] * cos3phi;
     sumbte = at1 + at2 + at3;
 
     da = acos(costh12) - at_theta0_1[type];
     if (eflag) edihedral += da * (at1+at2+at3);
 
     // force on angle1
 
     bt1 = at_f1_1[type] * sinphi;
     bt2 = 2.0 * at_f2_1[type] * sin(2.0*phi);
     bt3 = 3.0 * at_f3_1[type] * sin(3.0*phi);
     sumbtf = bt1 + bt2 + bt3;
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++)
 	fabcd[i][j] -= da*sumbtf*dphidr[i][j] + sumbte*dthetadr[0][i][j];
 
     // energy on angle2
 
     at1 = at_f1_2[type] * cosphi;
     at2 = at_f2_2[type] * cos2phi;
     at3 = at_f3_2[type] * cos3phi;
     sumbte = at1 + at2 + at3;
 
     da = acos(costh23) - at_theta0_2[type];
     if (eflag) edihedral += da * (at1+at2+at3);
 
     // force on angle2
 
     bt1 = -at_f1_2[type] * sinphi;
     bt2 = -2.0 * at_f2_2[type] * sin(2.0*phi);
     bt3 = -3.0 * at_f3_2[type] * sin(3.0*phi);
     sumbtf = bt1 + bt2 + bt3;
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++)
 	fabcd[i][j] += da*sumbtf*dphidr[i][j] + sumbte*dthetadr[1][i][j];
 
     // angle/angle/torsion coupling
 
     da1 = acos(costh12) - aat_theta0_1[type];
     da2 = acos(costh23) - aat_theta0_2[type];
           
     if (eflag) edihedral += aat_k[type]*da1*da2*cosphi;
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++)
 	fabcd[i][j] -= aat_k[type] * 
 	  (cosphi * (da2*dthetadr[0][i][j] - da1*dthetadr[1][i][j]) +
 	   sinphi * da1*da2*dphidr[i][j]);
 
     // bond1/bond3 coupling
 
     if (fabs(bb13t_k[type]) > SMALL) {
 
       r1_0 = bb13t_r10[type];
       r3_0 = bb13t_r30[type];
       dr1 = r1 - r1_0;
       dr2 = r3 - r3_0;
       tk1 = -bb13t_k[type] * dr1 / r3;
       tk2 = -bb13t_k[type] * dr2 / r1;
 
       if (eflag) edihedral += bb13t_k[type]*dr1*dr2;
         
       fabcd[0][0] += tk2 * vb1x;
       fabcd[0][1] += tk2 * vb1y;
       fabcd[0][2] += tk2 * vb1z;
 
       fabcd[1][0] -= tk2 * vb1x;
       fabcd[1][1] -= tk2 * vb1y;
       fabcd[1][2] -= tk2 * vb1z;
         
       fabcd[2][0] -= tk1 * vb3x;
       fabcd[2][1] -= tk1 * vb3y;
       fabcd[2][2] -= tk1 * vb3z;
 
       fabcd[3][0] += tk1 * vb3x;
       fabcd[3][1] += tk1 * vb3y;
       fabcd[3][2] += tk1 * vb3z;
     }
 
     // apply force to each of 4 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += fabcd[0][0];
       f[i1][1] += fabcd[0][1];
       f[i1][2] += fabcd[0][2];
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] += fabcd[1][0];
       f[i2][1] += fabcd[1][1];
       f[i2][2] += fabcd[1][2];
     }
 
     if (newton_bond || i3 < nlocal) {
       f[i3][0] += fabcd[2][0];
       f[i3][1] += fabcd[2][1];
       f[i3][2] += fabcd[2][2];
     }
 
     if (newton_bond || i4 < nlocal) {
       f[i4][0] += fabcd[3][0];
       f[i4][1] += fabcd[3][1];
       f[i4][2] += fabcd[3][2];
     }
 
     if (evflag)
       ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,
 	       fabcd[0],fabcd[2],fabcd[3],
 	       vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralClass2::allocate()
 {
   allocated = 1;
   int n = atom->ndihedraltypes;
 
   k1 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k1");
   k2 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k2");
   k3 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k3");
   phi1 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:phi1");
   phi2 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:phi2");
   phi3 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:phi3");
 
   mbt_f1 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:mbt_f1");
   mbt_f2 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:mbt_f2");
   mbt_f3 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:mbt_f3");
   mbt_r0 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:mbt_r0");
 
   ebt_f1_1 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:ebt_f1_1");
   ebt_f2_1 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:ebt_f2_1");
   ebt_f3_1 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:ebt_f3_1");
   ebt_r0_1 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:ebt_r0_1");
 
   ebt_f1_2 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:ebt_f1_2");
   ebt_f2_2 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:ebt_f2_2");
   ebt_f3_2 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:ebt_f3_2");
   ebt_r0_2 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:ebt_r0_2");
 
   at_f1_1 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:at_f1_1");
   at_f2_1 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:at_f2_1");
   at_f3_1 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:at_f3_1");
   at_theta0_1 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:at_theta0_1");
 
   at_f1_2 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:at_f1_2");
   at_f2_2 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:at_f2_2");
   at_f3_2 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:at_f3_2");
   at_theta0_2 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:at_theta0_2");
 
   aat_k = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:aat_k");
   aat_theta0_1 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:aat_theta0_1");
   aat_theta0_2 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:aat_theta0_2");
 
   bb13t_k = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:bb13t_k");
   bb13t_r10 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:bb13t_r10");
   bb13t_r30 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:bb13t_r30");
 
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag");
   setflag_d = (int *) 
     memory->smalloc((n+1)*sizeof(int),"dihedral:setflag_d");
   setflag_mbt = (int *) 
     memory->smalloc((n+1)*sizeof(int),"dihedral:setflag_mbt");
   setflag_ebt = (int *) 
     memory->smalloc((n+1)*sizeof(int),"dihedral:setflag_ebt");
   setflag_at = (int *) 
     memory->smalloc((n+1)*sizeof(int),"dihedral:setflag_at");
   setflag_aat = (int *) 
     memory->smalloc((n+1)*sizeof(int),"dihedral:setflag_aat");
   setflag_bb13t = (int *) 
     memory->smalloc((n+1)*sizeof(int),"dihedral:setflag_bb13t");
   for (int i = 1; i <= n; i++)
     setflag[i] = setflag_d[i] = setflag_mbt[i] = setflag_ebt[i] = 
       setflag_at[i] = setflag_aat[i] = setflag_bb13t[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one or more types
    arg1 = "mbt" -> MiddleBondTorsion coeffs
    arg1 = "ebt" -> EndBondTorsion coeffs
    arg1 = "at" -> AngleTorsion coeffs
    arg1 = "aat" -> AngleAngleTorsion coeffs
    arg1 = "bb13" -> BondBond13Torsion coeffs
    arg1 -> Dihedral coeffs
 ------------------------------------------------------------------------- */
 
 void DihedralClass2::coeff(int narg, char **arg)
 {
   if (narg < 2) error->all("Invalid coeffs for this dihedral style");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi);
 
   int count = 0;
 
   if (strcmp(arg[1],"mbt") == 0) {
     if (narg != 6) error->all("Incorrect args for dihedral coefficients");
 
     double f1_one = force->numeric(arg[2]);
     double f2_one = force->numeric(arg[3]);
     double f3_one = force->numeric(arg[4]);
     double r0_one = force->numeric(arg[5]);
     
     for (int i = ilo; i <= ihi; i++) {
       mbt_f1[i] = f1_one;
       mbt_f2[i] = f2_one;
       mbt_f3[i] = f3_one;
       mbt_r0[i] = r0_one;
       setflag_mbt[i] = 1;
       count++;
     }
 
   } else if (strcmp(arg[1],"ebt") == 0) {
     if (narg != 10) error->all("Incorrect args for dihedral coefficients");
 
     double f1_1_one = force->numeric(arg[2]);
     double f2_1_one = force->numeric(arg[3]);
     double f3_1_one = force->numeric(arg[4]);
     double f1_2_one = force->numeric(arg[5]);
     double f2_2_one = force->numeric(arg[6]);
     double f3_2_one = force->numeric(arg[7]);
     double r0_1_one = force->numeric(arg[8]);
     double r0_2_one = force->numeric(arg[9]);
     
     for (int i = ilo; i <= ihi; i++) {
       ebt_f1_1[i] = f1_1_one;
       ebt_f2_1[i] = f2_1_one;
       ebt_f3_1[i] = f3_1_one;
       ebt_f1_2[i] = f1_2_one;
       ebt_f2_2[i] = f2_2_one;
       ebt_f3_2[i] = f3_2_one;
       ebt_r0_1[i] = r0_1_one;
       ebt_r0_2[i] = r0_2_one;
       setflag_ebt[i] = 1;
       count++;
     }
 
   } else if (strcmp(arg[1],"at") == 0) {
     if (narg != 10) error->all("Incorrect args for dihedral coefficients");
 
     double f1_1_one = force->numeric(arg[2]);
     double f2_1_one = force->numeric(arg[3]);
     double f3_1_one = force->numeric(arg[4]);
     double f1_2_one = force->numeric(arg[5]);
     double f2_2_one = force->numeric(arg[6]);
     double f3_2_one = force->numeric(arg[7]);
     double theta0_1_one = force->numeric(arg[8]);
     double theta0_2_one = force->numeric(arg[9]);
 
     // convert theta0's from degrees to radians
     
     for (int i = ilo; i <= ihi; i++) {
       at_f1_1[i] = f1_1_one;
       at_f2_1[i] = f2_1_one;
       at_f3_1[i] = f3_1_one;
       at_f1_2[i] = f1_2_one;
       at_f2_2[i] = f2_2_one;
       at_f3_2[i] = f3_2_one;
       at_theta0_1[i] = theta0_1_one/180.0 * PI;
       at_theta0_2[i] = theta0_2_one/180.0 * PI;
       setflag_at[i] = 1;
       count++;
     }
 
   } else if (strcmp(arg[1],"aat") == 0) {
     if (narg != 5) error->all("Incorrect args for dihedral coefficients");
 
     double k_one = force->numeric(arg[2]);
     double theta0_1_one = force->numeric(arg[3]);
     double theta0_2_one = force->numeric(arg[4]);
 
     // convert theta0's from degrees to radians
     
     for (int i = ilo; i <= ihi; i++) {
       aat_k[i] = k_one;
       aat_theta0_1[i] = theta0_1_one/180.0 * PI;
       aat_theta0_2[i] = theta0_2_one/180.0 * PI;
       setflag_aat[i] = 1;
       count++;
     }
 
   } else if (strcmp(arg[1],"bb13") == 0) {
     if (narg != 5) error->all("Incorrect args for dihedral coefficients");
 
     double k_one = force->numeric(arg[2]);
     double r10_one = force->numeric(arg[3]);
     double r30_one = force->numeric(arg[4]);
     
     for (int i = ilo; i <= ihi; i++) {
       bb13t_k[i] = k_one;
       bb13t_r10[i] = r10_one;
       bb13t_r30[i] = r30_one;
       setflag_bb13t[i] = 1;
       count++;
     }
 
   } else {
     if (narg != 7) error->all("Incorrect args for dihedral coefficients");
 
     double k1_one = force->numeric(arg[1]);
     double phi1_one = force->numeric(arg[2]);
     double k2_one = force->numeric(arg[3]);
     double phi2_one = force->numeric(arg[4]);
     double k3_one = force->numeric(arg[5]);
     double phi3_one = force->numeric(arg[6]);
     
     // convert phi's from degrees to radians
 
     for (int i = ilo; i <= ihi; i++) {
       k1[i] = k1_one;
       phi1[i] = phi1_one/180.0 * PI;
       k2[i] = k2_one;
       phi2[i] = phi2_one/180.0 * PI;
       k3[i] = k3_one;
       phi3[i] = phi3_one/180.0 * PI;
       setflag_d[i] = 1;
       count++;
     }
   }
 
   if (count == 0) error->all("Incorrect args for dihedral coefficients");
 
   for (int i = ilo; i <= ihi; i++)
     if (setflag_d[i] == 1 && setflag_mbt[i] == 1 && setflag_ebt[i] == 1 &&
 	setflag_at[i] == 1 && setflag_aat[i] == 1 && setflag_bb13t[i] == 1)
       setflag[i] = 1;
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out coeffs to restart file 
 ------------------------------------------------------------------------- */
 
 void DihedralClass2::write_restart(FILE *fp)
 {
   fwrite(&k1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&k2[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&k3[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&phi1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&phi2[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&phi3[1],sizeof(double),atom->ndihedraltypes,fp);
 
   fwrite(&mbt_f1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&mbt_f2[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&mbt_f3[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&mbt_r0[1],sizeof(double),atom->ndihedraltypes,fp);
 
   fwrite(&ebt_f1_1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&ebt_f2_1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&ebt_f3_1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&ebt_r0_1[1],sizeof(double),atom->ndihedraltypes,fp);
 
   fwrite(&ebt_f1_2[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&ebt_f2_2[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&ebt_f3_2[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&ebt_r0_2[1],sizeof(double),atom->ndihedraltypes,fp);
 
   fwrite(&at_f1_1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&at_f2_1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&at_f3_1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&at_theta0_1[1],sizeof(double),atom->ndihedraltypes,fp);
 
   fwrite(&at_f1_2[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&at_f2_2[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&at_f3_2[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&at_theta0_2[1],sizeof(double),atom->ndihedraltypes,fp);
 
   fwrite(&aat_k[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&aat_theta0_1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&aat_theta0_2[1],sizeof(double),atom->ndihedraltypes,fp);
 
   fwrite(&bb13t_k[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&bb13t_r10[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&bb13t_r30[1],sizeof(double),atom->ndihedraltypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads coeffs from restart file, bcasts them 
 ------------------------------------------------------------------------- */
 
 void DihedralClass2::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&k1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&k2[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&k3[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&phi1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&phi2[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&phi3[1],sizeof(double),atom->ndihedraltypes,fp);
 
     fread(&mbt_f1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&mbt_f2[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&mbt_f3[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&mbt_r0[1],sizeof(double),atom->ndihedraltypes,fp);
 
     fread(&ebt_f1_1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&ebt_f2_1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&ebt_f3_1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&ebt_r0_1[1],sizeof(double),atom->ndihedraltypes,fp);
 
     fread(&ebt_f1_2[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&ebt_f2_2[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&ebt_f3_2[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&ebt_r0_2[1],sizeof(double),atom->ndihedraltypes,fp);
 
     fread(&at_f1_1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&at_f2_1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&at_f3_1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&at_theta0_1[1],sizeof(double),atom->ndihedraltypes,fp);
 
     fread(&at_f1_2[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&at_f2_2[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&at_f3_2[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&at_theta0_2[1],sizeof(double),atom->ndihedraltypes,fp);
 
     fread(&aat_k[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&aat_theta0_1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&aat_theta0_2[1],sizeof(double),atom->ndihedraltypes,fp);
 
     fread(&bb13t_k[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&bb13t_r10[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&bb13t_r30[1],sizeof(double),atom->ndihedraltypes,fp);
   }
 
   MPI_Bcast(&k1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&k2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&k3[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&phi1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&phi2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&phi3[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
 
   MPI_Bcast(&mbt_f1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&mbt_f2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&mbt_f3[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&mbt_r0[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
 
   MPI_Bcast(&ebt_f1_1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&ebt_f2_1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&ebt_f3_1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&ebt_r0_1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
 
   MPI_Bcast(&ebt_f1_2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&ebt_f2_2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&ebt_f3_2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&ebt_r0_2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
 
   MPI_Bcast(&at_f1_1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&at_f2_1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&at_f3_1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&at_theta0_1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
 
   MPI_Bcast(&at_f1_2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&at_f2_2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&at_f3_2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&at_theta0_2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
 
   MPI_Bcast(&aat_k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&aat_theta0_1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&aat_theta0_2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
 
   MPI_Bcast(&bb13t_k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&bb13t_r10[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&bb13t_r30[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
 
   for (int i = 1; i <= atom->ndihedraltypes; i++) setflag[i] = 1;
 }
diff --git a/src/CLASS2/improper_class2.cpp b/src/CLASS2/improper_class2.cpp
index ff24cb55f..716ced12f 100644
--- a/src/CLASS2/improper_class2.cpp
+++ b/src/CLASS2/improper_class2.cpp
@@ -1,848 +1,851 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Eric Simon (Cray)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "string.h"
 #include "stdlib.h"
 #include "improper_class2.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "neighbor.h"
 #include "update.h"
 #include "domain.h"
 #include "comm.h"
 #include "force.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define SMALL 0.001
 
 /* ---------------------------------------------------------------------- */
 
 ImproperClass2::ImproperClass2(LAMMPS *lmp) : Improper(lmp)
 {
   PI = 4.0*atan(1.0);
 }
 
 /* ---------------------------------------------------------------------- */
 
 ImproperClass2::~ImproperClass2()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(setflag_i);
     memory->sfree(setflag_aa);
 
     memory->sfree(k0);
     memory->sfree(chi0);
 
     memory->sfree(aa_k1);
     memory->sfree(aa_k2);
     memory->sfree(aa_k3);
     memory->sfree(aa_theta0_1);
     memory->sfree(aa_theta0_2);
     memory->sfree(aa_theta0_3);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ImproperClass2::compute(int eflag, int vflag)
 {
   int i1,i2,i3,i4,i,j,k,n,type;
   double eimproper;
   double delr[3][3],rmag[3],rinvmag[3],rmag2[3];
   double theta[3],costheta[3],sintheta[3];
   double cossqtheta[3],sinsqtheta[3],invstheta[3];
   double rABxrCB[3],rDBxrAB[3],rCBxrDB[3];
   double ddelr[3][4],dr[3][4][3],dinvr[3][4][3];
   double dthetadr[3][4][3],dinvsth[3][4][3];
   double dinv3r[4][3],dinvs3r[3][4][3];
   double drCBxrDB[3],rCBxdrDB[3],drDBxrAB[3],rDBxdrAB[3];
   double drABxrCB[3],rABxdrCB[3];
   double dot1,dot2,dd[3];
   double fdot[3][4][3],ftmp,invs3r[3],inv3r;
   double t,tt1,tt3,sc1;
   double dotCBDBAB,dotDBABCB,dotABCBDB;
   double chi,deltachi,d2chi,cossin2;
   double drAB[3][4][3],drCB[3][4][3],drDB[3][4][3];
   double dchi[3][4][3],dtotalchi[4][3];
   double schiABCD,chiABCD,schiCBDA,chiCBDA,schiDBAC,chiDBAC;
   double fabcd[4][3];
 
   eimproper = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   for (i = 0; i < 3; i++)
     for (j = 0; j < 4; j++)
       for (k = 0; k < 3; k++) {
 	dthetadr[i][j][k] = 0.0;
 	drAB[i][j][k] = 0.0;
 	drCB[i][j][k] = 0.0;
 	drDB[i][j][k] = 0.0;
       }
 
   double **x = atom->x;
   double **f = atom->f;
   int **improperlist = neighbor->improperlist;
   int nimproperlist = neighbor->nimproperlist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < nimproperlist; n++) {
     i1 = improperlist[n][0];
     i2 = improperlist[n][1];
     i3 = improperlist[n][2];
     i4 = improperlist[n][3];
     type = improperlist[n][4];
 
     if (k0[type] == 0.0) continue;
 
     // difference vectors
 
     delr[0][0] = x[i1][0] - x[i2][0];
     delr[0][1] = x[i1][1] - x[i2][1];
     delr[0][2] = x[i1][2] - x[i2][2];
     domain->minimum_image(delr[0]);
 
     delr[1][0] = x[i3][0] - x[i2][0];
     delr[1][1] = x[i3][1] - x[i2][1];
     delr[1][2] = x[i3][2] - x[i2][2];
     domain->minimum_image(delr[1]);
 
     delr[2][0] = x[i4][0] - x[i2][0];
     delr[2][1] = x[i4][1] - x[i2][1];
     delr[2][2] = x[i4][2] - x[i2][2];
     domain->minimum_image(delr[2]);
 
     // bond lengths and associated values
 
     for (i = 0; i < 3; i++) {
       rmag2[i] = delr[i][0]*delr[i][0] + delr[i][1]*delr[i][1] + 
 	delr[i][2]*delr[i][2];
       rmag[i] = sqrt(rmag2[i]);
       rinvmag[i] = 1.0/rmag[i];
     }
 
     // angle ABC, CBD, ABD
 
     costheta[0] = (delr[0][0]*delr[1][0] + delr[0][1]*delr[1][1] +  
 		   delr[0][2]*delr[1][2]) / (rmag[0]*rmag[1]);
     costheta[1] = (delr[1][0]*delr[2][0] + delr[1][1]*delr[2][1] + 
 		   delr[1][2]*delr[2][2]) / (rmag[1]*rmag[2]);
     costheta[2] = (delr[0][0]*delr[2][0] + delr[0][1]*delr[2][1] + 
 		   delr[0][2]*delr[2][2]) / (rmag[0]*rmag[2]);
 
     // angle error check
 
     for (i = 0; i < 3; i++) {
       if (costheta[i] == -1.0) {
 	int me;
 	MPI_Comm_rank(world,&me);
 	if (screen) {
-	  char str[128];
-	  sprintf(str,"Improper problem: %d %d %d %d %d %d",
-		  me,update->ntimestep,
+	  char str[128],fstr[64];
+	  sprintf(fstr,"Improper problem: %%d %s %%d %%d %%d %%d",
+		  BIGINT_FORMAT);
+	  sprintf(str,fstr,me,update->ntimestep,
 		  atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
 	  error->warning(str,0);
+	  error->warning(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]);
 	  fprintf(screen,"  3rd atom: %d %g %g %g\n",
 		  me,x[i3][0],x[i3][1],x[i3][2]);
 	  fprintf(screen,"  4th atom: %d %g %g %g\n",
 		  me,x[i4][0],x[i4][1],x[i4][2]);
 	}
       }
     }
 
     for (i = 0; i < 3; i++) {
       if (costheta[i] > 1.0)  costheta[i] = 1.0;
       if (costheta[i] < -1.0) costheta[i] = -1.0;
       theta[i] = acos(costheta[i]);
       cossqtheta[i] = costheta[i]*costheta[i];
       sintheta[i] = sin(theta[i]);
       invstheta[i] = 1.0/sintheta[i];
       sinsqtheta[i] = sintheta[i]*sintheta[i];
     }
 
     // cross & dot products
 
     cross(delr[0],delr[1],rABxrCB);
     cross(delr[2],delr[0],rDBxrAB);
     cross(delr[1],delr[2],rCBxrDB);
 
     dotCBDBAB = dot(rCBxrDB,delr[0]);
     dotDBABCB = dot(rDBxrAB,delr[1]);
     dotABCBDB = dot(rABxrCB,delr[2]);
 
     t = rmag[0] * rmag[1] * rmag[2];
     inv3r = 1.0/t;
     invs3r[0] = invstheta[1] * inv3r;
     invs3r[1] = invstheta[2] * inv3r;
     invs3r[2] = invstheta[0] * inv3r;
 
     // chi ABCD, CBDA, DBAC
     // final chi is average of three
 
     schiABCD = dotCBDBAB * invs3r[0];
     chiABCD = asin(schiABCD);
     schiCBDA = dotDBABCB * invs3r[1];
     chiCBDA = asin(schiCBDA);
     schiDBAC = dotABCBDB * invs3r[2];
     chiDBAC = asin(schiDBAC);
 
     chi = (chiABCD + chiCBDA + chiDBAC) / 3.0;
     deltachi = chi - chi0[type];
     d2chi = deltachi * deltachi;
 
     // energy
 
     if (eflag) eimproper = k0[type]*d2chi;
 
     // forces
     // define d(delr)
     // i = bond AB/CB/DB, j = atom A/B/C/D
 
     for (i = 0; i < 3; i++)
       for (j = 0; j < 4; j++)
 	ddelr[i][j] = 0.0;
 
     ddelr[0][0] = 1.0;
     ddelr[0][1] = -1.0;
     ddelr[1][1] = -1.0;
     ddelr[1][2] = 1.0;
     ddelr[2][1] = -1.0;
     ddelr[2][3] = 1.0;
 
     // compute d(|r|)/dr and d(1/|r|)/dr for each direction, bond and atom
     // define d(r) for each r
     // i = bond AB/CB/DB, j = atom A/B/C/D, k = X/Y/Z
 
     for (i = 0; i < 3; i++)
       for (j = 0; j < 4; j++)
 	for (k = 0; k < 3; k++) {
 	  dr[i][j][k] = delr[i][k] * ddelr[i][j] / rmag[i];
 	  dinvr[i][j][k] = -dr[i][j][k] / rmag2[i];
 	}
 
     // compute d(1 / (|r_AB| * |r_CB| * |r_DB|) / dr
     // i = atom A/B/C/D, j = X/Y/Z
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++)
 	dinv3r[i][j] = rinvmag[1] * (rinvmag[2] * dinvr[0][i][j] +
 				     rinvmag[0] * dinvr[2][i][j]) +
 	  rinvmag[2] * rinvmag[0] * dinvr[1][i][j];
 
     // compute d(theta)/d(r) for 3 angles
     // angleABC
 
     tt1 = costheta[0] / rmag2[0];
     tt3 = costheta[0] / rmag2[1];
     sc1 = 1.0 / sqrt(1.0 - cossqtheta[0]);
 
     dthetadr[0][0][0] = sc1 * ((tt1 * delr[0][0]) - 
 			       (delr[1][0] * rinvmag[0] * rinvmag[1]));
     dthetadr[0][0][1] = sc1 * ((tt1 * delr[0][1]) - 
 			       (delr[1][1] * rinvmag[0] * rinvmag[1]));
     dthetadr[0][0][2] = sc1 * ((tt1 * delr[0][2]) - 
 			       (delr[1][2] * rinvmag[0] * rinvmag[1]));
     dthetadr[0][1][0] = -sc1 * ((tt1 * delr[0][0]) - 
 				(delr[1][0] * rinvmag[0] * rinvmag[1]) +
 				(tt3 * delr[1][0]) - 
 				(delr[0][0] * rinvmag[0] * rinvmag[1]));
     dthetadr[0][1][1] = -sc1 * ((tt1 * delr[0][1]) - 
 				(delr[1][1] * rinvmag[0] * rinvmag[1]) +
 				(tt3 * delr[1][1]) - 
 				(delr[0][1] * rinvmag[0] * rinvmag[1]));
     dthetadr[0][1][2] = -sc1 * ((tt1 * delr[0][2]) - 
 				(delr[1][2] * rinvmag[0] * rinvmag[1]) +
 				(tt3 * delr[1][2]) - 
 				(delr[0][2] * rinvmag[0] * rinvmag[1]));
     dthetadr[0][2][0] = sc1 * ((tt3 * delr[1][0]) - 
 			       (delr[0][0] * rinvmag[0] * rinvmag[1]));
     dthetadr[0][2][1] = sc1 * ((tt3 * delr[1][1]) - 
 			       (delr[0][1] * rinvmag[0] * rinvmag[1]));
     dthetadr[0][2][2] = sc1 * ((tt3 * delr[1][2]) - 
 			       (delr[0][2] * rinvmag[0] * rinvmag[1]));
 
     // angleCBD
 
     tt1 = costheta[1] / rmag2[1];
     tt3 = costheta[1] / rmag2[2];
     sc1 = 1.0 / sqrt(1.0 - cossqtheta[1]);
 
     dthetadr[1][2][0] = sc1 * ((tt1 * delr[1][0]) - 
 			       (delr[2][0] * rinvmag[1] * rinvmag[2]));
     dthetadr[1][2][1] = sc1 * ((tt1 * delr[1][1]) - 
 			       (delr[2][1] * rinvmag[1] * rinvmag[2]));
     dthetadr[1][2][2] = sc1 * ((tt1 * delr[1][2]) - 
 			       (delr[2][2] * rinvmag[1] * rinvmag[2]));
     dthetadr[1][1][0] = -sc1 * ((tt1 * delr[1][0]) - 
 				(delr[2][0] * rinvmag[1] * rinvmag[2]) +
 				(tt3 * delr[2][0]) - 
 				(delr[1][0] * rinvmag[2] * rinvmag[1]));
     dthetadr[1][1][1] = -sc1 * ((tt1 * delr[1][1]) - 
 				(delr[2][1] * rinvmag[1] * rinvmag[2]) +
 				(tt3 * delr[2][1]) - 
 				(delr[1][1] * rinvmag[2] * rinvmag[1]));
     dthetadr[1][1][2] = -sc1 * ((tt1 * delr[1][2]) - 
 				(delr[2][2] * rinvmag[1] * rinvmag[2]) +
 				(tt3 * delr[2][2]) - 
 				(delr[1][2] * rinvmag[2] * rinvmag[1]));
     dthetadr[1][3][0] = sc1 * ((tt3 * delr[2][0]) - 
 			       (delr[1][0] * rinvmag[2] * rinvmag[1]));
     dthetadr[1][3][1] = sc1 * ((tt3 * delr[2][1]) - 
 			       (delr[1][1] * rinvmag[2] * rinvmag[1]));
     dthetadr[1][3][2] = sc1 * ((tt3 * delr[2][2]) - 
 			       (delr[1][2] * rinvmag[2] * rinvmag[1]));
 
     // angleABD
 
     tt1 = costheta[2] / rmag2[0];
     tt3 = costheta[2] / rmag2[2];
     sc1 = 1.0 / sqrt(1.0 - cossqtheta[2]);
 
     dthetadr[2][0][0] = sc1 * ((tt1 * delr[0][0]) - 
 			       (delr[2][0] * rinvmag[0] * rinvmag[2]));
     dthetadr[2][0][1] = sc1 * ((tt1 * delr[0][1]) - 
 			       (delr[2][1] * rinvmag[0] * rinvmag[2]));
     dthetadr[2][0][2] = sc1 * ((tt1 * delr[0][2]) - 
 			       (delr[2][2] * rinvmag[0] * rinvmag[2]));
     dthetadr[2][1][0] = -sc1 * ((tt1 * delr[0][0]) - 
 				(delr[2][0] * rinvmag[0] * rinvmag[2]) +
 				(tt3 * delr[2][0]) - 
 				(delr[0][0] * rinvmag[2] * rinvmag[0]));
     dthetadr[2][1][1] = -sc1 * ((tt1 * delr[0][1]) - 
 				(delr[2][1] * rinvmag[0] * rinvmag[2]) +
 				(tt3 * delr[2][1]) - 
 				(delr[0][1] * rinvmag[2] * rinvmag[0]));
     dthetadr[2][1][2] = -sc1 * ((tt1 * delr[0][2]) - 
 				(delr[2][2] * rinvmag[0] * rinvmag[2]) +
 				(tt3 * delr[2][2]) - 
 				(delr[0][2] * rinvmag[2] * rinvmag[0]));
     dthetadr[2][3][0] = sc1 * ((tt3 * delr[2][0]) - 
 			       (delr[0][0] * rinvmag[2] * rinvmag[0]));
     dthetadr[2][3][1] = sc1 * ((tt3 * delr[2][1]) - 
 			       (delr[0][1] * rinvmag[2] * rinvmag[0]));
     dthetadr[2][3][2] = sc1 * ((tt3 * delr[2][2]) - 
 			       (delr[0][2] * rinvmag[2] * rinvmag[0]));
 
     // compute d( 1 / sin(theta))/dr
     // i = angle, j = atom, k = direction
 
     for (i = 0; i < 3; i++) {
       cossin2 = -costheta[i] / sinsqtheta[i];
       for (j = 0; j < 4; j++)
 	for (k = 0; k < 3; k++)
 	  dinvsth[i][j][k] = cossin2 * dthetadr[i][j][k];
     }
 
     // compute d(1 / sin(theta) * |r_AB| * |r_CB| * |r_DB|)/dr
     // i = angle, j = atom
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++) {
 	dinvs3r[0][i][j] = (invstheta[1] * dinv3r[i][j]) +
 	  (inv3r * dinvsth[1][i][j]);
 	dinvs3r[1][i][j] = (invstheta[2] * dinv3r[i][j]) +
 	  (inv3r * dinvsth[2][i][j]);
 	dinvs3r[2][i][j] = (invstheta[0] * dinv3r[i][j]) +
 	  (inv3r * dinvsth[0][i][j]);
       }
 
     // drCB(i,j,k), etc
     // i = vector X'/Y'/Z', j = atom A/B/C/D, k = direction X/Y/Z
 
     for (i = 0; i < 3; i++) {
       drCB[i][1][i] = -1.0;
       drAB[i][1][i] = -1.0;
       drDB[i][1][i] = -1.0;
       drDB[i][3][i] = 1.0;
       drCB[i][2][i] = 1.0;
       drAB[i][0][i] = 1.0;
     }
 
     // d((r_CB x r_DB) dot r_AB)
     // r_CB x d(r_DB)
     // d(r_CB) x r_DB
     // (r_CB x d(r_DB)) + (d(r_CB) x r_DB)
     // (r_CB x d(r_DB)) + (d(r_CB) x r_DB) dot r_AB
     // d(r_AB) dot (r_CB x r_DB)
 
     for (i = 0; i < 3; i++)
       for (j = 0; j < 4; j++) {
 	cross(delr[1],drDB[i][j],rCBxdrDB);
 	cross(drCB[i][j],delr[2],drCBxrDB);
 	for (k = 0; k < 3; k++) dd[k] = rCBxdrDB[k] + drCBxrDB[k];
 	dot1 = dot(dd,delr[0]);
 	dot2 = dot(rCBxrDB,drAB[i][j]);
 	fdot[0][j][i] = dot1 + dot2;
       }
 
     // d((r_DB x r_AB) dot r_CB)
     // r_DB x d(r_AB)
     // d(r_DB) x r_AB
     // (r_DB x d(r_AB)) + (d(r_DB) x r_AB)
     // (r_DB x d(r_AB)) + (d(r_DB) x r_AB) dot r_CB
     // d(r_CB) dot (r_DB x r_AB)
 
     for (i = 0; i < 3; i++)
       for (j = 0; j < 4; j++) {
 	cross(delr[2],drAB[i][j],rDBxdrAB);
 	cross(drDB[i][j],delr[0],drDBxrAB);
 	for (k = 0; k < 3; k++) dd[k] = rDBxdrAB[k] + drDBxrAB[k];
 	dot1 = dot(dd,delr[1]);
 	dot2 = dot(rDBxrAB,drCB[i][j]);
 	fdot[1][j][i] = dot1 + dot2;
       }
 
     // d((r_AB x r_CB) dot r_DB)
     // r_AB x d(r_CB)
     // d(r_AB) x r_CB
     // (r_AB x d(r_CB)) + (d(r_AB) x r_CB)
     // (r_AB x d(r_CB)) + (d(r_AB) x r_CB) dot r_DB
     // d(r_DB) dot (r_AB x r_CB)
 
     for (i = 0; i < 3; i++)
       for (j = 0; j < 4; j++) {
 	cross(delr[0],drCB[i][j],rABxdrCB);
 	cross(drAB[i][j],delr[1],drABxrCB);
 	for (k = 0; k < 3; k++) dd[k] = rABxdrCB[k] + drABxrCB[k];
 	dot1 = dot(dd,delr[2]);
 	dot2 = dot(rABxrCB,drDB[i][j]);
 	fdot[2][j][i] = dot1 + dot2;
       }
 
     // force on each atom
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++) {
 	ftmp = (fdot[0][i][j] * invs3r[0]) + 
 	  (dinvs3r[0][i][j] * dotCBDBAB);
 	dchi[0][i][j] = ftmp / cos(chiABCD);
 	ftmp = (fdot[1][i][j] * invs3r[1]) + 
 	  (dinvs3r[1][i][j] * dotDBABCB);
 	dchi[1][i][j] = ftmp / cos(chiCBDA);
 	ftmp = (fdot[2][i][j] * invs3r[2]) + 
 	  (dinvs3r[2][i][j] * dotABCBDB);
 	dchi[2][i][j] = ftmp / cos(chiDBAC);
 	dtotalchi[i][j] = (dchi[0][i][j]+dchi[1][i][j]+dchi[2][i][j]) / 3.0;
       }
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++)
 	fabcd[i][j] = -2.0*k0[type] * deltachi*dtotalchi[i][j];
 
     // apply force to each of 4 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += fabcd[0][0];
       f[i1][1] += fabcd[0][1];
       f[i1][2] += fabcd[0][2];
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] += fabcd[1][0];
       f[i2][1] += fabcd[1][1];
       f[i2][2] += fabcd[1][2];
     }
 
     if (newton_bond || i3 < nlocal) {
       f[i3][0] += fabcd[2][0];
       f[i3][1] += fabcd[2][1];
       f[i3][2] += fabcd[2][2];
     }
 
     if (newton_bond || i4 < nlocal) {
       f[i4][0] += fabcd[3][0];
       f[i4][1] += fabcd[3][1];
       f[i4][2] += fabcd[3][2];
     }
 
     if (evflag)
       ev_tally(i1,i2,i3,i4,nlocal,newton_bond,eimproper,
 	       fabcd[0],fabcd[2],fabcd[3],
 	       delr[0][0],delr[0][1],delr[0][2],
 	       delr[1][0],delr[1][1],delr[1][2],
 	       delr[2][0]-delr[1][0],delr[2][1]-delr[1][1],
 	       delr[2][2]-delr[1][2]);
   }
 
   // compute angle-angle interactions
 
   angleangle(eflag,vflag);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ImproperClass2::allocate()
 {
   allocated = 1;
   int n = atom->nimpropertypes;
 
   k0 = (double *) memory->smalloc((n+1)*sizeof(double),"improper:k0");
   chi0 = (double *) memory->smalloc((n+1)*sizeof(double),"improper:chi0");
 
   aa_k1 = (double *) memory->smalloc((n+1)*sizeof(double),"improper:aa_k1");
   aa_k2 = (double *) memory->smalloc((n+1)*sizeof(double),"improper:aa_k2");
   aa_k3 = (double *) memory->smalloc((n+1)*sizeof(double),"improper:aa_k3");
   aa_theta0_1 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"improper:aa_theta0_1");
   aa_theta0_2 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"improper:aa_theta0_2");
   aa_theta0_3 = (double *) 
     memory->smalloc((n+1)*sizeof(double),"improper:aa_theta0_3");
 
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"improper:setflag");
   setflag_i = (int *) 
     memory->smalloc((n+1)*sizeof(int),"improper:setflag_i");
   setflag_aa = (int *) 
     memory->smalloc((n+1)*sizeof(int),"improper:setflag_aa");
   for (int i = 1; i <= n; i++)
     setflag[i] = setflag_i[i] = setflag_aa[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one or more types
    arg1 = "aa" -> AngleAngle coeffs
    else arg1 -> improper coeffs
 ------------------------------------------------------------------------- */
 
 void ImproperClass2::coeff(int narg, char **arg)
 {
   if (narg < 2) error->all("Incorrect args for improper coefficients");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->nimpropertypes,ilo,ihi);
 
   int count = 0;
 
   if (strcmp(arg[1],"aa") == 0) {
     if (narg != 8) error->all("Incorrect args for improper coefficients");
 
     double k1_one = force->numeric(arg[2]);
     double k2_one = force->numeric(arg[3]);
     double k3_one = force->numeric(arg[4]);
     double theta0_1_one = force->numeric(arg[5]);
     double theta0_2_one = force->numeric(arg[6]);
     double theta0_3_one = force->numeric(arg[7]);
     
     // convert theta0's from degrees to radians
 
     for (int i = ilo; i <= ihi; i++) {
       aa_k1[i] = k1_one;
       aa_k2[i] = k2_one;
       aa_k3[i] = k3_one;
       aa_theta0_1[i] = theta0_1_one/180.0 * PI;
       aa_theta0_2[i] = theta0_2_one/180.0 * PI;
       aa_theta0_3[i] = theta0_3_one/180.0 * PI;
       setflag_aa[i] = 1;
       count++;
     }
 
   } else {
     if (narg != 3) error->all("Incorrect args for improper coefficients");
 
     double k0_one = force->numeric(arg[1]);
     double chi0_one = force->numeric(arg[2]);
 
     // convert chi0 from degrees to radians
 
     for (int i = ilo; i <= ihi; i++) {
       k0[i] = k0_one;
       chi0[i] = chi0_one/180.0 * PI;
       setflag_i[i] = 1;
       count++;
     }
   }
 
   if (count == 0) error->all("Incorrect args for improper coefficients");
 
   for (int i = ilo; i <= ihi; i++)
     if (setflag_i[i] == 1 && setflag_aa[i] == 1) setflag[i] = 1;
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out coeffs to restart file 
 ------------------------------------------------------------------------- */
 
 void ImproperClass2::write_restart(FILE *fp)
 {
   fwrite(&k0[1],sizeof(double),atom->nimpropertypes,fp);
   fwrite(&chi0[1],sizeof(double),atom->nimpropertypes,fp);
 
   fwrite(&aa_k1[1],sizeof(double),atom->nimpropertypes,fp);
   fwrite(&aa_k2[1],sizeof(double),atom->nimpropertypes,fp);
   fwrite(&aa_k3[1],sizeof(double),atom->nimpropertypes,fp);
   fwrite(&aa_theta0_1[1],sizeof(double),atom->nimpropertypes,fp);
   fwrite(&aa_theta0_2[1],sizeof(double),atom->nimpropertypes,fp);
   fwrite(&aa_theta0_3[1],sizeof(double),atom->nimpropertypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads coeffs from restart file, bcasts them 
 ------------------------------------------------------------------------- */
 
 void ImproperClass2::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&k0[1],sizeof(double),atom->nimpropertypes,fp);
     fread(&chi0[1],sizeof(double),atom->nimpropertypes,fp);
 
     fread(&aa_k1[1],sizeof(double),atom->nimpropertypes,fp);
     fread(&aa_k2[1],sizeof(double),atom->nimpropertypes,fp);
     fread(&aa_k3[1],sizeof(double),atom->nimpropertypes,fp);
     fread(&aa_theta0_1[1],sizeof(double),atom->nimpropertypes,fp);
     fread(&aa_theta0_2[1],sizeof(double),atom->nimpropertypes,fp);
     fread(&aa_theta0_3[1],sizeof(double),atom->nimpropertypes,fp);
   }
   MPI_Bcast(&k0[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&chi0[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
 
   MPI_Bcast(&aa_k1[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&aa_k2[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&aa_k3[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&aa_theta0_1[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&aa_theta0_2[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&aa_theta0_3[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
 
   for (int i = 1; i <= atom->nimpropertypes; i++) setflag[i] = 1;
 }
 
 /* ----------------------------------------------------------------------
    angle-angle interactions within improper
 ------------------------------------------------------------------------- */
 
 void ImproperClass2::angleangle(int eflag, int vflag)
 {
   int i1,i2,i3,i4,i,j,k,n,type;
   double eimproper;
   double delxAB,delyAB,delzAB,rABmag2,rAB;
   double delxBC,delyBC,delzBC,rBCmag2,rBC;
   double delxBD,delyBD,delzBD,rBDmag2,rBD;
   double costhABC,thetaABC,costhABD;
   double thetaABD,costhCBD,thetaCBD,dthABC,dthCBD,dthABD;
   double sc1,t1,t3,r12;
   double dthetadr[3][4][3],fabcd[4][3];
 
   double **x = atom->x;
   double **f = atom->f;
   int **improperlist = neighbor->improperlist;
   int nimproperlist = neighbor->nimproperlist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < nimproperlist; n++) {
     i1 = improperlist[n][0];
     i2 = improperlist[n][1];
     i3 = improperlist[n][2];
     i4 = improperlist[n][3];
     type = improperlist[n][4];
 
     // difference vectors
 
     delxAB = x[i1][0] - x[i2][0];
     delyAB = x[i1][1] - x[i2][1];
     delzAB = x[i1][2] - x[i2][2];
     domain->minimum_image(delxAB,delyAB,delzAB);
 
     delxBC = x[i3][0] - x[i2][0];
     delyBC = x[i3][1] - x[i2][1];
     delzBC = x[i3][2] - x[i2][2];
     domain->minimum_image(delxBC,delyBC,delzBC);
 
     delxBD = x[i4][0] - x[i2][0];
     delyBD = x[i4][1] - x[i2][1];
     delzBD = x[i4][2] - x[i2][2];
     domain->minimum_image(delxBD,delyBD,delzBD);
 
     // bond lengths
 
     rABmag2 = delxAB*delxAB + delyAB*delyAB + delzAB*delzAB;
     rAB = sqrt(rABmag2);
     rBCmag2 = delxBC*delxBC + delyBC*delyBC + delzBC*delzBC;
     rBC = sqrt(rBCmag2);
     rBDmag2 = delxBD*delxBD + delyBD*delyBD + delzBD*delzBD;
     rBD = sqrt(rBDmag2);
         
     // angle ABC, ABD, CBD
 
     costhABC = (delxAB*delxBC + delyAB*delyBC + delzAB*delzBC) / (rAB * rBC);
     if (costhABC > 1.0)  costhABC = 1.0;
     if (costhABC < -1.0) costhABC = -1.0;
     thetaABC = acos(costhABC);
 
     costhABD = (delxAB*delxBD + delyAB*delyBD + delzAB*delzBD) / (rAB * rBD);
     if (costhABD > 1.0)  costhABD = 1.0;
     if (costhABD < -1.0) costhABD = -1.0;
     thetaABD = acos(costhABD);
 
     costhCBD = (delxBC*delxBD + delyBC*delyBD + delzBC*delzBD) /(rBC * rBD);
     if (costhCBD > 1.0)  costhCBD = 1.0;
     if (costhCBD < -1.0) costhCBD = -1.0;
     thetaCBD = acos(costhCBD);
 
     dthABC = thetaABC - aa_theta0_1[type];
     dthCBD = thetaCBD - aa_theta0_2[type];
     dthABD = thetaABD - aa_theta0_3[type];
 
     // energy
 
     if (eflag) eimproper = aa_k2[type] * dthABC * dthABD + 
 		 aa_k1[type] * dthABC * dthCBD +
 		 aa_k3[type] * dthABD * dthCBD;
 
     // d(theta)/d(r) array
     // angle i, atom j, coordinate k
 
     for (i = 0; i < 3; i++)
       for (j = 0; j < 4; j++)
 	for (k = 0; k < 3; k++)
 	  dthetadr[i][j][k] = 0.0;
 
     // angle ABC
 
     sc1 = sqrt(1.0/(1.0 - costhABC*costhABC));
     t1 = costhABC / rABmag2;
     t3 = costhABC / rBCmag2;
     r12 = 1.0 / (rAB * rBC);
 
     dthetadr[0][0][0] = sc1 * ((t1 * delxAB) - (delxBC * r12));
     dthetadr[0][0][1] = sc1 * ((t1 * delyAB) - (delyBC * r12));
     dthetadr[0][0][2] = sc1 * ((t1 * delzAB) - (delzBC * r12));
     dthetadr[0][1][0] = sc1 * ((-t1 * delxAB) + (delxBC * r12) +
 			       (-t3 * delxBC) + (delxAB * r12));
     dthetadr[0][1][1] = sc1 * ((-t1 * delyAB) + (delyBC * r12) +
 			       (-t3 * delyBC) + (delyAB * r12));
     dthetadr[0][1][2] = sc1 * ((-t1 * delzAB) + (delzBC * r12) +
 			       (-t3 * delzBC) + (delzAB * r12));
     dthetadr[0][2][0] = sc1 * ((t3 * delxBC) - (delxAB * r12));
     dthetadr[0][2][1] = sc1 * ((t3 * delyBC) - (delyAB * r12));
     dthetadr[0][2][2] = sc1 * ((t3 * delzBC) - (delzAB * r12));
 
     // angle CBD
 
     sc1 = sqrt(1.0/(1.0 - costhCBD*costhCBD));
     t1 = costhCBD / rBCmag2;
     t3 = costhCBD / rBDmag2;
     r12 = 1.0 / (rBC * rBD);
 
     dthetadr[1][2][0] = sc1 * ((t1 * delxBC) - (delxBD * r12));
     dthetadr[1][2][1] = sc1 * ((t1 * delyBC) - (delyBD * r12));
     dthetadr[1][2][2] = sc1 * ((t1 * delzBC) - (delzBD * r12));
     dthetadr[1][1][0] = sc1 * ((-t1 * delxBC) + (delxBD * r12) +
 			       (-t3 * delxBD) + (delxBC * r12));
     dthetadr[1][1][1] = sc1 * ((-t1 * delyBC) + (delyBD * r12) +
 			       (-t3 * delyBD) + (delyBC * r12));
     dthetadr[1][1][2] = sc1 * ((-t1 * delzBC) + (delzBD * r12) +
 			       (-t3 * delzBD) + (delzBC * r12));
     dthetadr[1][3][0] = sc1 * ((t3 * delxBD) - (delxBC * r12));
     dthetadr[1][3][1] = sc1 * ((t3 * delyBD) - (delyBC * r12));
     dthetadr[1][3][2] = sc1 * ((t3 * delzBD) - (delzBC * r12));
 
     // angle ABD
 
     sc1 = sqrt(1.0/(1.0 - costhABD*costhABD));
     t1 = costhABD / rABmag2;
     t3 = costhABD / rBDmag2;
     r12 = 1.0 / (rAB * rBD);
 
     dthetadr[2][0][0] = sc1 * ((t1 * delxAB) - (delxBD * r12));
     dthetadr[2][0][1] = sc1 * ((t1 * delyAB) - (delyBD * r12));
     dthetadr[2][0][2] = sc1 * ((t1 * delzAB) - (delzBD * r12));
     dthetadr[2][1][0] = sc1 * ((-t1 * delxAB) + (delxBD * r12) +
 			       (-t3 * delxBD) + (delxAB * r12));
     dthetadr[2][1][1] = sc1 * ((-t1 * delyAB) + (delyBD * r12) +
 			       (-t3 * delyBD) + (delyAB * r12));
     dthetadr[2][1][2] = sc1 * ((-t1 * delzAB) + (delzBD * r12) +
 			       (-t3 * delzBD) + (delzAB * r12));
     dthetadr[2][3][0] = sc1 * ((t3 * delxBD) - (delxAB * r12));
     dthetadr[2][3][1] = sc1 * ((t3 * delyBD) - (delyAB * r12));
     dthetadr[2][3][2] = sc1 * ((t3 * delzBD) - (delzAB * r12));
 
     // angleangle forces
 
     for (i = 0; i < 4; i++)
       for (j = 0; j < 3; j++)
 	fabcd[i][j] = - 
 	  ((aa_k1[type] * 
 	    (dthABC*dthetadr[1][i][j] + dthCBD*dthetadr[0][i][j])) +
 	   (aa_k2[type] * 
 	    (dthABC*dthetadr[2][i][j] + dthABD*dthetadr[0][i][j])) +
 	   (aa_k3[type] *
 	    (dthABD*dthetadr[1][i][j] + dthCBD*dthetadr[2][i][j])));
 
     // apply force to each of 4 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += fabcd[0][0];
       f[i1][1] += fabcd[0][1];
       f[i1][2] += fabcd[0][2];
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] += fabcd[1][0];
       f[i2][1] += fabcd[1][1];
       f[i2][2] += fabcd[1][2];
     }
 
     if (newton_bond || i3 < nlocal) {
       f[i3][0] += fabcd[2][0];
       f[i3][1] += fabcd[2][1];
       f[i3][2] += fabcd[2][2];
     }
 
     if (newton_bond || i4 < nlocal) {
       f[i4][0] += fabcd[3][0];
       f[i4][1] += fabcd[3][1];
       f[i4][2] += fabcd[3][2];
     }
 
     if (evflag)
       ev_tally(i1,i2,i3,i4,nlocal,newton_bond,eimproper,
 	       fabcd[0],fabcd[2],fabcd[3],
 	       delxAB,delyAB,delzAB,delxBC,delyBC,delzBC,delxBD,delyBD,delzBD);
   }
 }
 
 /* ----------------------------------------------------------------------
    cross product: c = a x b
 ------------------------------------------------------------------------- */
 
 void ImproperClass2::cross(double *a, double *b, double *c)
 {
   c[0] = a[1]*b[2] - a[2]*b[1];
   c[1] = a[2]*b[0] - a[0]*b[2];
   c[2] = a[0]*b[1] - a[1]*b[0];
 }
 
 /* ----------------------------------------------------------------------
    dot product of a dot b
 ------------------------------------------------------------------------- */
 
 double ImproperClass2::dot(double *a, double *b)
 {
   return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
 }
diff --git a/src/COLLOID/atom_vec_colloid.cpp b/src/COLLOID/atom_vec_colloid.cpp
index 3c13ecde0..0ba21a735 100644
--- a/src/COLLOID/atom_vec_colloid.cpp
+++ b/src/COLLOID/atom_vec_colloid.cpp
@@ -1,703 +1,706 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "atom_vec_colloid.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "force.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecColloid::AtomVecColloid(LAMMPS *lmp, int narg, char **arg) :
   AtomVec(lmp, narg, arg)
 {
   molecular = 0;
   mass_type = 1;
   shape_type = 1;
 
   comm_x_only = 1;
   comm_f_only = 0;
   size_forward = 3;
   size_reverse = 6;
   size_border = 6;
   size_velocity = 6;
   size_data_atom = 5;
   size_data_vel = 7;
   xcol_data = 3;
 
   atom->omega_flag = atom->torque_flag = 1;
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n
 ------------------------------------------------------------------------- */
 
 void AtomVecColloid::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
 
   tag = atom->tag = (int *)
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *)
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *)
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
 
   omega = atom->omega = 
     memory->grow_2d_double_array(atom->omega,nmax,3,"atom:omega");
   torque = atom->torque = 
     memory->grow_2d_double_array(atom->torque,nmax,3,"atom:torque");
   
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecColloid::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
   omega = atom->omega; torque = atom->torque;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecColloid::copy(int i, int j)
 {
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
 
   omega[j][0] = omega[i][0];
   omega[j][1] = omega[i][1];
   omega[j][2] = omega[i][2];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecColloid::pack_comm(int n, int *list, double *buf,
 			     int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecColloid::pack_comm_vel(int n, int *list, double *buf,
 				  int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = omega[j][0];
       buf[m++] = omega[j][1];
       buf[m++] = omega[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = omega[j][0];
       buf[m++] = omega[j][1];
       buf[m++] = omega[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecColloid::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
   }
 }
 
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecColloid::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
     omega[i][0] = buf[m++];
     omega[i][1] = buf[m++];
     omega[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecColloid::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
     buf[m++] = torque[i][0];
     buf[m++] = torque[i][1];
     buf[m++] = torque[i][2];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecColloid::pack_reverse_one(int i, double *buf)
 {
   buf[0] = torque[i][0];
   buf[1] = torque[i][1];
   buf[2] = torque[i][2];
   return 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecColloid::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
     torque[j][0] += buf[m++];
     torque[j][1] += buf[m++];
     torque[j][2] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecColloid::unpack_reverse_one(int i, double *buf)
 {
   torque[i][0] += buf[0];
   torque[i][1] += buf[1];
   torque[i][2] += buf[2];
   return 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecColloid::pack_border(int n, int *list, double *buf,
 				  int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecColloid::pack_border_vel(int n, int *list, double *buf,
 				    int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = omega[j][0];
       buf[m++] = omega[j][1];
       buf[m++] = omega[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = omega[j][0];
       buf[m++] = omega[j][1];
       buf[m++] = omega[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecColloid::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecColloid::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
     omega[i][0] = buf[m++];
     omega[i][1] = buf[m++];
     omega[i][2] = buf[m++];
   }
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    xyz must be 1st 3 values, so comm::exchange() can test on them
 ------------------------------------------------------------------------- */
 
 int AtomVecColloid::pack_exchange(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
 
   buf[m++] = omega[i][0];
   buf[m++] = omega[i][1];
   buf[m++] = omega[i][2];
   
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecColloid::unpack_exchange(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
 
   omega[nlocal][0] = buf[m++];
   omega[nlocal][1] = buf[m++];
   omega[nlocal][2] = buf[m++];
   
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecColloid::size_restart()
 {
   int i;
 
   int nlocal = atom->nlocal;
   int n = 14 * nlocal;
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
       for (i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive
 ------------------------------------------------------------------------- */
 
 int AtomVecColloid::pack_restart(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
 
   buf[m++] = omega[i][0];
   buf[m++] = omega[i][1];
   buf[m++] = omega[i][2];
   
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
 
 int AtomVecColloid::unpack_restart(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store) 
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
 
   omega[nlocal][0] = buf[m++];
   omega[nlocal][1] = buf[m++];
   omega[nlocal][2] = buf[m++];
   
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
 
 void AtomVecColloid::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   omega[nlocal][0] = 0.0;
   omega[nlocal][1] = 0.0;
   omega[nlocal][2] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
 void AtomVecColloid::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
 
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   image[nlocal] = imagetmp;
 
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   omega[nlocal][0] = 0.0;
   omega[nlocal][1] = 0.0;
   omega[nlocal][2] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Velocities section of data file
 ------------------------------------------------------------------------- */
 
 void AtomVecColloid::data_vel(int m, char **values)
 {
   v[m][0] = atof(values[0]);
   v[m][1] = atof(values[1]);
   v[m][2] = atof(values[2]);
   omega[m][0] = atof(values[3]);
   omega[m][1] = atof(values[4]);
   omega[m][2] = atof(values[5]);
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Velocities section of data file
 ------------------------------------------------------------------------- */
 
 int AtomVecColloid::data_vel_hybrid(int m, char **values)
 {
   omega[m][0] = atof(values[0]);
   omega[m][1] = atof(values[1]);
   omega[m][2] = atof(values[2]);
   return 3;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory
 ------------------------------------------------------------------------- */
 
 double AtomVecColloid::memory_usage()
 {
   double bytes = 0.0;
 
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
 
   if (atom->memcheck("omega")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("torque")) bytes += nmax*3 * sizeof(double);
 
   return bytes;
 }
diff --git a/src/DIPOLE/atom_vec_dipole.cpp b/src/DIPOLE/atom_vec_dipole.cpp
index f3935ccce..cc81711b4 100644
--- a/src/DIPOLE/atom_vec_dipole.cpp
+++ b/src/DIPOLE/atom_vec_dipole.cpp
@@ -1,837 +1,840 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "atom_vec_dipole.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecDipole::AtomVecDipole(LAMMPS *lmp, int narg, char **arg) :
   AtomVec(lmp, narg, arg)
 {
   molecular = 0;
   mass_type = 1;
   shape_type = 1;
   dipole_type = 1;
 
   comm_x_only = comm_f_only = 0;
   size_forward = 6;
   size_reverse = 6;
   size_border = 10;
   size_velocity = 6;
   size_data_atom = 9;
   size_data_vel = 7;
   xcol_data = 4;
 
   atom->q_flag = atom->mu_flag = atom->omega_flag = atom->torque_flag = 1;
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n 
 ------------------------------------------------------------------------- */
 
 void AtomVecDipole::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
 
   tag = atom->tag = (int *) 
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *) 
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *) 
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
 
   q = atom->q = (double *) 
     memory->srealloc(atom->q,nmax*sizeof(double),"atom:q");
   mu = atom->mu = 
     memory->grow_2d_double_array(atom->mu,nmax,3,"atom:mu");
   omega = atom->omega = 
     memory->grow_2d_double_array(atom->omega,nmax,3,"atom:omega");
   torque = atom->torque =
     memory->grow_2d_double_array(atom->torque,nmax,3,"atom:torque");
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecDipole::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
   q = atom->q; mu = atom->mu;
   omega = atom->omega; torque = atom->torque;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecDipole::copy(int i, int j)
 {
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
 
   q[j] = q[i];
   mu[j][0] = mu[i][0];
   mu[j][1] = mu[i][1];
   mu[j][2] = mu[i][2];
   omega[j][0] = omega[i][0];
   omega[j][1] = omega[i][1];
   omega[j][2] = omega[i][2];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::pack_comm(int n, int *list, double *buf,
 			     int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = mu[j][0];
       buf[m++] = mu[j][1];
       buf[m++] = mu[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = mu[j][0];
       buf[m++] = mu[j][1];
       buf[m++] = mu[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::pack_comm_vel(int n, int *list, double *buf,
 				 int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = mu[j][0];
       buf[m++] = mu[j][1];
       buf[m++] = mu[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = omega[j][0];
       buf[m++] = omega[j][1];
       buf[m++] = omega[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = mu[j][0];
       buf[m++] = mu[j][1];
       buf[m++] = mu[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = omega[j][0];
       buf[m++] = omega[j][1];
       buf[m++] = omega[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::pack_comm_one(int i, double *buf)
 {
   buf[0] = mu[i][0];
   buf[1] = mu[i][1];
   buf[2] = mu[i][2];
   return 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecDipole::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     mu[i][0] = buf[m++];
     mu[i][1] = buf[m++];
     mu[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecDipole::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     mu[i][0] = buf[m++];
     mu[i][1] = buf[m++];
     mu[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
     omega[i][0] = buf[m++];
     omega[i][1] = buf[m++];
     omega[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::unpack_comm_one(int i, double *buf)
 {
   mu[i][0] = buf[0];
   mu[i][1] = buf[1];
   mu[i][2] = buf[2];
   return 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
     buf[m++] = torque[i][0];
     buf[m++] = torque[i][1];
     buf[m++] = torque[i][2];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::pack_reverse_one(int i, double *buf)
 {
   buf[0] = torque[i][0];
   buf[1] = torque[i][1];
   buf[2] = torque[i][2];
   return 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecDipole::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
     torque[j][0] += buf[m++];
     torque[j][1] += buf[m++];
     torque[j][2] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::unpack_reverse_one(int i, double *buf)
 {
   torque[i][0] += buf[0];
   torque[i][1] += buf[1];
   torque[i][2] += buf[2];
   return 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::pack_border(int n, int *list, double *buf,
 			       int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = mu[j][0];
       buf[m++] = mu[j][1];
       buf[m++] = mu[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = mu[j][0];
       buf[m++] = mu[j][1];
       buf[m++] = mu[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::pack_border_vel(int n, int *list, double *buf,
 				   int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = mu[j][0];
       buf[m++] = mu[j][1];
       buf[m++] = mu[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = omega[j][0];
       buf[m++] = omega[j][1];
       buf[m++] = omega[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = mu[j][0];
       buf[m++] = mu[j][1];
       buf[m++] = mu[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = omega[j][0];
       buf[m++] = omega[j][1];
       buf[m++] = omega[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::pack_border_one(int i, double *buf)
 {
   buf[0] = q[i];
   buf[1] = mu[i][0];
   buf[2] = mu[i][1];
   buf[3] = mu[i][2];
   return 4;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecDipole::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     q[i] = buf[m++];
     mu[i][0] = buf[m++];
     mu[i][1] = buf[m++];
     mu[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecDipole::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     q[i] = buf[m++];
     mu[i][0] = buf[m++];
     mu[i][1] = buf[m++];
     mu[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
     omega[i][0] = buf[m++];
     omega[i][1] = buf[m++];
     omega[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::unpack_border_one(int i, double *buf)
 {
   q[i] = buf[0];
   mu[i][0] = buf[1];
   mu[i][1] = buf[2];
   mu[i][2] = buf[3];
   return 4;
 }
 
 /* ----------------------------------------------------------------------
    pack all atom quantities for shipping to another proc
    xyz must be 1st 3 values, so that comm::exchange can test on them
 ------------------------------------------------------------------------- */
 
 int AtomVecDipole::pack_exchange(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
 
   buf[m++] = q[i];
   buf[m++] = mu[i][0];
   buf[m++] = mu[i][1];
   buf[m++] = mu[i][2];
   buf[m++] = omega[i][0];
   buf[m++] = omega[i][1];
   buf[m++] = omega[i][2];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecDipole::unpack_exchange(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
 
   q[nlocal] = buf[m++];
   mu[nlocal][0] = buf[m++];
   mu[nlocal][1] = buf[m++];
   mu[nlocal][2] = buf[m++];
   omega[nlocal][0] = buf[m++];
   omega[nlocal][1] = buf[m++];
   omega[nlocal][2] = buf[m++];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecDipole::size_restart()
 {
   int i;
 
   int nlocal = atom->nlocal;
   int n = 18 * nlocal;
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       for (i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive   
 ------------------------------------------------------------------------- */
 
 int AtomVecDipole::pack_restart(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
 
   buf[m++] = q[i];
   buf[m++] = mu[i][0];
   buf[m++] = mu[i][1];
   buf[m++] = mu[i][2];
   buf[m++] = omega[i][0];
   buf[m++] = omega[i][1];
   buf[m++] = omega[i][2];
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
 
 int AtomVecDipole::unpack_restart(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store)
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
 
   q[nlocal] = buf[m++];
   mu[nlocal][0] = buf[m++];
   mu[nlocal][1] = buf[m++];
   mu[nlocal][2] = buf[m++];
   omega[nlocal][0] = buf[m++];
   omega[nlocal][1] = buf[m++];
   omega[nlocal][2] = buf[m++];
 
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
 
 void AtomVecDipole::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   q[nlocal] = 0.0;
   mu[nlocal][0] = 0.0;
   mu[nlocal][1] = 0.0;
   mu[nlocal][2] = 0.0;
   omega[nlocal][0] = 0.0;
   omega[nlocal][1] = 0.0;
   omega[nlocal][2] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
 void AtomVecDipole::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
 
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   q[nlocal] = atof(values[2]);
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   mu[nlocal][0] = atof(values[6]);
   mu[nlocal][1] = atof(values[7]);
   mu[nlocal][2] = atof(values[8]);
 
   image[nlocal] = imagetmp;
 
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   omega[nlocal][0] = 0.0;
   omega[nlocal][1] = 0.0;
   omega[nlocal][2] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Atoms section of data file
    initialize other atom quantities for this sub-style
 ------------------------------------------------------------------------- */
 
 int AtomVecDipole::data_atom_hybrid(int nlocal, char **values)
 {
   q[nlocal] = atof(values[0]);
   mu[nlocal][0] = atof(values[1]);
   mu[nlocal][1] = atof(values[2]);
   mu[nlocal][2] = atof(values[3]);
 
   return 4;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Velocities section of data file
 ------------------------------------------------------------------------- */
 
 void AtomVecDipole::data_vel(int m, char **values)
 {
   v[m][0] = atof(values[0]);
   v[m][1] = atof(values[1]);
   v[m][2] = atof(values[2]);
   omega[m][0] = atof(values[3]);
   omega[m][1] = atof(values[4]);
   omega[m][2] = atof(values[5]);
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Velocities section of data file
 ------------------------------------------------------------------------- */
 
 int AtomVecDipole::data_vel_hybrid(int m, char **values)
 {
   omega[m][0] = atof(values[0]);
   omega[m][1] = atof(values[1]);
   omega[m][2] = atof(values[2]);
   return 3;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
 
 double AtomVecDipole::memory_usage()
 {
   double bytes = 0.0;
 
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
 
   if (atom->memcheck("q")) bytes += nmax * sizeof(double);
   if (atom->memcheck("mu")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("omega")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("torque")) bytes += nmax*3 * sizeof(double);
 
   return bytes;
 }
diff --git a/src/GPU/pair_cg_cmm_coul_long_gpu.cpp b/src/GPU/pair_cg_cmm_coul_long_gpu.cpp
index 8c7825f31..6d7477577 100644
--- a/src/GPU/pair_cg_cmm_coul_long_gpu.cpp
+++ b/src/GPU/pair_cg_cmm_coul_long_gpu.cpp
@@ -1,499 +1,504 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
    
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
    
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "pair_cg_cmm_coul_long_gpu.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "comm.h"
 #include "force.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "integrate.h"
 #include "memory.h"
 #include "error.h"
 #include "neigh_request.h"
 #include "universe.h"
 #include "update.h"
 #include "domain.h"
 #include "string.h"
 #include "kspace.h"
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 #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
 
 // External functions from cuda library for atom decomposition
 
 bool cmml_gpu_init(const int ntypes, double **cutsq, int **cg_type,
                    double **host_lj1, double **host_lj2, double **host_lj3,
                    double **host_lj4, double **offset, double *special_lj,
                    const int nlocal, const int nall, const int max_nbors,
                    const int maxspecial, const double cell_size, int &gpu_mode,
                    FILE *screen, double **host_cut_ljsq, double host_cut_coulsq,
                    double *host_special_coul, const double qqrd2e,
                    const double g_ewald);
 void cmml_gpu_clear();
 int * cmml_gpu_compute_n(const int timestep, const int ago, const int inum,
 	 	         const int nall, double **host_x, int *host_type, 
                          double *boxlo, double *boxhi, int *tag, int **nspecial,
                          int **special, const bool eflag, const bool vflag,
                          const bool eatom, const bool vatom, int &host_start,
                          const double cpu_time, bool &success, double *host_q);
 void cmml_gpu_compute(const int timestep, const int ago, const int inum,
 	 	      const int nall, double **host_x, int *host_type,
                       int *ilist, int *numj, int **firstneigh,
 		      const bool eflag, const bool vflag, const bool eatom,
                       const bool vatom, int &host_start, const double cpu_time,
                       bool &success, double *host_q);
 double cmml_gpu_bytes();
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 PairCGCMMCoulLongGPU::PairCGCMMCoulLongGPU(LAMMPS *lmp) : PairCGCMMCoulLong(lmp), gpu_mode(GPU_PAIR)
 {
   respa_enable = 0;
   cpu_time = 0.0;
 }
 
 /* ----------------------------------------------------------------------
    free all arrays
 ------------------------------------------------------------------------- */
 
 PairCGCMMCoulLongGPU::~PairCGCMMCoulLongGPU()
 {
   cmml_gpu_clear();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairCGCMMCoulLongGPU::compute(int eflag, int vflag)
 {
+  if (update->ntimestep > MAXSMALLINT)
+    error->all("Timestep too big for GPU pair style");
+  int ntimestep = update->ntimestep;
+
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = vflag_fdotr = 0;
   
   int nall = atom->nlocal + atom->nghost;
   int inum, host_start;
   
   bool success = true;
   
   if (gpu_mode == GPU_NEIGH) {
     inum = atom->nlocal;
-    gpulist = cmml_gpu_compute_n(update->ntimestep, neighbor->ago, inum, nall,
+    gpulist = cmml_gpu_compute_n(ntimestep, neighbor->ago, inum, nall,
 			         atom->x, atom->type, domain->sublo,
 				 domain->subhi, atom->tag, atom->nspecial,
                                  atom->special, eflag, vflag, eflag_atom,
                                  vflag_atom, host_start, cpu_time, success,
                                  atom->q);
   } else {
     inum = list->inum;
-    cmml_gpu_compute(update->ntimestep, neighbor->ago, inum, nall, atom->x,
+    cmml_gpu_compute(ntimestep, neighbor->ago, inum, nall, atom->x,
 		     atom->type, list->ilist, list->numneigh, list->firstneigh,
 		     eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time,
                      success, atom->q);
   }
   if (!success)
     error->one("Out of memory on GPGPU");
 
   if (host_start<inum) {
     cpu_time = MPI_Wtime();
     if (gpu_mode == GPU_NEIGH)
       cpu_compute(gpulist, host_start, eflag, vflag);
     else
       cpu_compute(host_start, eflag, vflag);
     cpu_time = MPI_Wtime() - cpu_time;
   }
 }
 
 /* ----------------------------------------------------------------------
    init specific to this pair style
 ------------------------------------------------------------------------- */
 
 void PairCGCMMCoulLongGPU::init_style()
 {
   cut_respa = NULL;
 
   if (!atom->q_flag)
     error->all("Pair style cg/cmm/coul/long requires atom attribute q");
   if (force->pair_match("gpu",0) == NULL)
     error->all("Cannot use pair hybrid with multiple GPU pair styles");
 
   // Repeat cutsq calculation because done after call to init_style
   double maxcut = -1.0;
   double cut;
   for (int i = 1; i <= atom->ntypes; i++) {
     for (int j = i; j <= atom->ntypes; j++) {
       if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
         cut = init_one(i,j);
         cut *= cut;
         if (cut > maxcut)
           maxcut = cut;
         cutsq[i][j] = cutsq[j][i] = cut;
       } else
         cutsq[i][j] = cutsq[j][i] = 0.0;
     }
   }
   double cell_size = sqrt(maxcut) + neighbor->skin;
 
   // insure use of KSpace long-range solver, set g_ewald
 
   if (force->kspace == NULL)
     error->all("Pair style is incompatible with KSpace style");
   g_ewald = force->kspace->g_ewald;
 
   // setup force tables
 
   if (ncoultablebits) init_tables();
 
   int maxspecial=0;
   if (atom->molecular)
     maxspecial=atom->maxspecial;
   bool init_ok = cmml_gpu_init(atom->ntypes+1, cutsq, cg_type, lj1, lj2, lj3,
                                lj4, offset, force->special_lj, atom->nlocal,
                                atom->nlocal+atom->nghost, 300, maxspecial,
                                cell_size, gpu_mode, screen, cut_ljsq,
                                cut_coulsq_global, force->special_coul,
                                force->qqrd2e, g_ewald);
   if (!init_ok)
     error->one("Insufficient memory on accelerator (or no fix gpu).\n"); 
 
   if (force->newton_pair) 
     error->all("Cannot use newton pair with GPU cg/cmm pair style");
 
   if (gpu_mode != GPU_NEIGH) {
     int irequest = neighbor->request(this);
     neighbor->requests[irequest]->half = 0;
     neighbor->requests[irequest]->full = 1;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double PairCGCMMCoulLongGPU::memory_usage()
 {
   double bytes = Pair::memory_usage();
   return bytes + cmml_gpu_bytes();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairCGCMMCoulLongGPU::cpu_compute(int start, int eflag, int vflag)
 {
   int i,j,ii,jj,inum,jnum,itype,jtype,itable;
   double qtmp,xtmp,ytmp,ztmp,delx,dely,delz;
   double fraction,table;
   double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
   double grij,expm2,prefactor,t,erfc;
   int *ilist,*jlist,*numneigh,**firstneigh;
   double rsq;
 
   double **x = atom->x;
   double **f = atom->f;
   double *q = atom->q;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
   double qqrd2e = force->qqrd2e;
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
   
   // loop over neighbors of my atoms
 
   for (ii = start; ii < inum; ii++) {
     i = ilist[ii];
     qtmp = q[i];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
 
       if (j < nall) factor_coul = factor_lj = 1.0;
       else {
 	factor_coul = special_coul[j/nall];
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       const double delx = xtmp - x[j][0];
       const double dely = ytmp - x[j][1];
       const double delz = ztmp - x[j][2];
       const double rsq = delx*delx + dely*dely + delz*delz;
       const int jtype = type[j];
 
       double evdwl = 0.0;
       double ecoul = 0.0;
       double fpair = 0.0;
 
       if (rsq < cutsq[itype][jtype]) {
         const double r2inv = 1.0/rsq;
         const int cgt=cg_type[itype][jtype];
 
         double forcelj  = 0.0;
         double forcecoul = 0.0;
 
         if (rsq < cut_ljsq[itype][jtype]) {
           forcelj=factor_lj;
           if (eflag) evdwl=factor_lj;
 
           if (cgt == CG_LJ12_4) {
             const double r4inv=r2inv*r2inv;
             forcelj *= r4inv*(lj1[itype][jtype]*r4inv*r4inv
                        - lj2[itype][jtype]);
             if (eflag) {
               evdwl *= r4inv*(lj3[itype][jtype]*r4inv*r4inv
                        - lj4[itype][jtype]) - offset[itype][jtype];
             }
           } else if (cgt == CG_LJ9_6) {
             const double r3inv = r2inv*sqrt(r2inv);
             const double r6inv = r3inv*r3inv;
             forcelj *= r6inv*(lj1[itype][jtype]*r3inv
                        - lj2[itype][jtype]);
             if (eflag) {
               evdwl *= r6inv*(lj3[itype][jtype]*r3inv
                         - lj4[itype][jtype]) - offset[itype][jtype];
             }
           } else {
             const double r6inv = r2inv*r2inv*r2inv;
             forcelj *= r6inv*(lj1[itype][jtype]*r6inv
                        - lj2[itype][jtype]);
             if (eflag) {
               evdwl *= r6inv*(lj3[itype][jtype]*r6inv
                        - lj4[itype][jtype]) - offset[itype][jtype];
             }
           }
         }
 
         if (rsq < cut_coulsq_global) {
           if (!ncoultablebits || rsq <= tabinnersq) {
             const double r = sqrt(rsq);
             const double grij = g_ewald * r;
             const double expm2 = exp(-grij*grij);
             const double t = 1.0 / (1.0 + EWALD_P*grij);
             const double erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
             const double prefactor = qqrd2e * qtmp*q[j]/r;
             forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
             if (eflag) ecoul = prefactor*erfc;
             if (factor_coul < 1.0) {
               forcecoul -= (1.0-factor_coul)*prefactor;
               if (eflag) ecoul -= (1.0-factor_coul)*prefactor;
             }
           } else {
             union_int_float_t rsq_lookup;
             rsq_lookup.f = rsq;
             int itable = rsq_lookup.i & ncoulmask;
             itable >>= ncoulshiftbits;
             const double fraction = (rsq_lookup.f - rtable[itable]) *
                                      drtable[itable];
             const double table = ftable[itable] + fraction*dftable[itable];
             forcecoul = qtmp*q[j] * table;
             if (eflag) {
               const double table2 = etable[itable] + fraction*detable[itable];
               ecoul = qtmp*q[j] * table2;
             }
             if (factor_coul < 1.0) {
               const double table2 = ctable[itable] + fraction*dctable[itable];
               const double prefactor = qtmp*q[j] * table2;
               forcecoul -= (1.0-factor_coul)*prefactor;
               if (eflag) ecoul -= (1.0-factor_coul)*prefactor;
             }
           }
         }
         fpair = (forcecoul + forcelj) * r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
 	if (evflag) ev_tally_full(i,evdwl,ecoul,fpair,delx,dely,delz);
       }
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairCGCMMCoulLongGPU::cpu_compute(int *nbors, int start, int eflag,
                                       int vflag)
 {
   int i,j,jnum,itype,jtype,itable;
   double qtmp,xtmp,ytmp,ztmp,delx,dely,delz;
   double fraction,table;
   double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
   double grij,expm2,prefactor,t,erfc;
   double rsq;
 
   double **x = atom->x;
   double **f = atom->f;
   double *q = atom->q;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   int stride = nlocal-start;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
   double qqrd2e = force->qqrd2e;
 
   // loop over neighbors of my atoms
 
   for (i = start; i < nlocal; i++) {
     qtmp = q[i];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     int *nbor = nbors + i - start;
     jnum = *nbor;
     nbor += stride;
     int *nbor_end = nbor + stride * jnum;
 
     for (; nbor<nbor_end; nbor+=stride) {
       j = *nbor;
 
       if (j < nall) factor_coul = factor_lj = 1.0;
       else {
 	factor_coul = special_coul[j/nall];
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       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];
 
       double evdwl = 0.0;
       double ecoul = 0.0;
       double fpair = 0.0;
 
       if (rsq < cutsq[itype][jtype]) {
         const double r2inv = 1.0/rsq;
         const int cgt=cg_type[itype][jtype];
 
         double forcelj  = 0.0;
         double forcecoul = 0.0;
 
         if (rsq < cut_ljsq[itype][jtype]) {
           forcelj=factor_lj;
           if (eflag) evdwl=factor_lj;
 
           if (cgt == CG_LJ12_4) {
             const double r4inv=r2inv*r2inv;
             forcelj *= r4inv*(lj1[itype][jtype]*r4inv*r4inv
                        - lj2[itype][jtype]);
             if (eflag) {
               evdwl *= r4inv*(lj3[itype][jtype]*r4inv*r4inv
                        - lj4[itype][jtype]) - offset[itype][jtype];
             }
           } else if (cgt == CG_LJ9_6) {
             const double r3inv = r2inv*sqrt(r2inv);
             const double r6inv = r3inv*r3inv;
             forcelj *= r6inv*(lj1[itype][jtype]*r3inv
                        - lj2[itype][jtype]);
             if (eflag) {
               evdwl *= r6inv*(lj3[itype][jtype]*r3inv
                         - lj4[itype][jtype]) - offset[itype][jtype];
             }
           } else {
             const double r6inv = r2inv*r2inv*r2inv;
             forcelj *= r6inv*(lj1[itype][jtype]*r6inv
                        - lj2[itype][jtype]);
             if (eflag) {
               evdwl *= r6inv*(lj3[itype][jtype]*r6inv
                        - lj4[itype][jtype]) - offset[itype][jtype];
             }
           }
         }
 
         if (rsq < cut_coulsq_global) {
           if (!ncoultablebits || rsq <= tabinnersq) {
             const double r = sqrt(rsq);
             const double grij = g_ewald * r;
             const double expm2 = exp(-grij*grij);
             const double t = 1.0 / (1.0 + EWALD_P*grij);
             const double erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
             const double prefactor = qqrd2e * qtmp*q[j]/r;
             forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
             if (eflag) ecoul = prefactor*erfc;
             if (factor_coul < 1.0) {
               forcecoul -= (1.0-factor_coul)*prefactor;
               if (eflag) ecoul -= (1.0-factor_coul)*prefactor;
             }
           } else {
             union_int_float_t rsq_lookup;
             rsq_lookup.f = rsq;
             int itable = rsq_lookup.i & ncoulmask;
             itable >>= ncoulshiftbits;
             const double fraction = (rsq_lookup.f - rtable[itable]) *
                                      drtable[itable];
             const double table = ftable[itable] + fraction*dftable[itable];
             forcecoul = qtmp*q[j] * table;
             if (eflag) {
               const double table2 = etable[itable] + fraction*detable[itable];
               ecoul = qtmp*q[j] * table2;
             }
             if (factor_coul < 1.0) {
               const double table2 = ctable[itable] + fraction*dctable[itable];
               const double prefactor = qtmp*q[j] * table2;
               forcecoul -= (1.0-factor_coul)*prefactor;
               if (eflag) ecoul -= (1.0-factor_coul)*prefactor;
             }
           }
         }
         fpair = (forcecoul + forcelj) * r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
         if (j<start) {
   	  if (evflag) ev_tally_full(i,evdwl,ecoul,fpair,delx,dely,delz);
         } else {
           if (j<nlocal) {
 	    f[j][0] -= delx*fpair;
 	    f[j][1] -= dely*fpair;
 	    f[j][2] -= delz*fpair;
   	  }
 	  if (evflag) ev_tally(i,j,nlocal,0,
 			       evdwl,ecoul,fpair,delx,dely,delz);
         }
       }
     }
   }
 }
 
diff --git a/src/GPU/pair_cg_cmm_gpu.cpp b/src/GPU/pair_cg_cmm_gpu.cpp
index 345fbfbf3..19ba73aeb 100644
--- a/src/GPU/pair_cg_cmm_gpu.cpp
+++ b/src/GPU/pair_cg_cmm_gpu.cpp
@@ -1,362 +1,367 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
    
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
    
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "pair_cg_cmm_gpu.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "comm.h"
 #include "force.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "integrate.h"
 #include "memory.h"
 #include "error.h"
 #include "neigh_request.h"
 #include "universe.h"
 #include "update.h"
 #include "domain.h"
 #include "string.h"
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 // External functions from cuda library for atom decomposition
 
 bool cmm_gpu_init(const int ntypes, double **cutsq, int **cg_types, 
                   double **host_lj1, double **host_lj2, double **host_lj3,
                   double **host_lj4, double **offset, double *special_lj,
                   const int nlocal, const int nall, const int max_nbors,
                   const int maxspecial, const double cell_size, int &gpu_mode,
                   FILE *screen);
 void cmm_gpu_clear();
 int * cmm_gpu_compute_n(const int timestep, const int ago, const int inum,
 	 	        const int nall, double **host_x, int *host_type, 
                         double *boxlo, double *boxhi, int *tag, int **nspecial,
                         int **special, const bool eflag, const bool vflag,
                         const bool eatom, const bool vatom, int &host_start,
                         const double cpu_time, bool &success);
 void cmm_gpu_compute(const int timestep, const int ago, const int inum,
 	 	     const int nall, double **host_x, int *host_type,
                      int *ilist, int *numj, int **firstneigh,
 		     const bool eflag, const bool vflag, const bool eatom,
                      const bool vatom, int &host_start, const double cpu_time,
                      bool &success);
 double cmm_gpu_bytes();
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 PairCGCMMGPU::PairCGCMMGPU(LAMMPS *lmp) : PairCGCMM(lmp), gpu_mode(GPU_PAIR)
 {
   respa_enable = 0;
   cpu_time = 0.0;
 }
 
 /* ----------------------------------------------------------------------
    free all arrays
 ------------------------------------------------------------------------- */
 
 PairCGCMMGPU::~PairCGCMMGPU()
 {
   cmm_gpu_clear();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairCGCMMGPU::compute(int eflag, int vflag)
 {
+  if (update->ntimestep > MAXSMALLINT)
+    error->all("Timestep too big for GPU pair style");
+  int ntimestep = update->ntimestep;
+
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = vflag_fdotr = 0;
   
   int nall = atom->nlocal + atom->nghost;
   int inum, host_start;
   
   bool success = true;
   
   if (gpu_mode == GPU_NEIGH) {
     inum = atom->nlocal;
-    gpulist = cmm_gpu_compute_n(update->ntimestep, neighbor->ago, inum, nall,
+    gpulist = cmm_gpu_compute_n(ntimestep, neighbor->ago, inum, nall,
 			        atom->x, atom->type, domain->sublo,
 				domain->subhi, atom->tag, atom->nspecial,
                                 atom->special, eflag, vflag, eflag_atom,
                                 vflag_atom, host_start, cpu_time, success);
   } else {
     inum = list->inum;
-    cmm_gpu_compute(update->ntimestep, neighbor->ago, inum, nall, atom->x,
+    cmm_gpu_compute(ntimestep, neighbor->ago, inum, nall, atom->x,
 		    atom->type, list->ilist, list->numneigh, list->firstneigh,
 		    eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time,
                     success);
   }
   if (!success)
     error->one("Out of memory on GPGPU");
 
   if (host_start<inum) {
     cpu_time = MPI_Wtime();
     if (gpu_mode == GPU_NEIGH)
       cpu_compute(gpulist, host_start, eflag, vflag);
     else
       cpu_compute(host_start, eflag, vflag);
     cpu_time = MPI_Wtime() - cpu_time;
   }
 }
 
 /* ----------------------------------------------------------------------
    init specific to this pair style
 ------------------------------------------------------------------------- */
 
 void PairCGCMMGPU::init_style()
 {
   cut_respa = NULL;
 
   if (force->pair_match("gpu",0) == NULL)
     error->all("Cannot use pair hybrid with multiple GPU pair styles");
 
   // Repeat cutsq calculation because done after call to init_style
   double maxcut = -1.0;
   double cut;
   for (int i = 1; i <= atom->ntypes; i++) {
     for (int j = i; j <= atom->ntypes; j++) {
       if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
         cut = init_one(i,j);
         cut *= cut;
         if (cut > maxcut)
           maxcut = cut;
         cutsq[i][j] = cutsq[j][i] = cut;
       } else
         cutsq[i][j] = cutsq[j][i] = 0.0;
     }
   }
   double cell_size = sqrt(maxcut) + neighbor->skin;
 
   int maxspecial=0;
   if (atom->molecular)
     maxspecial=atom->maxspecial;
   bool init_ok = cmm_gpu_init(atom->ntypes+1,cutsq,cg_type,lj1,lj2,lj3,lj4,
                               offset, force->special_lj, atom->nlocal,
                               atom->nlocal+atom->nghost, 300, maxspecial,
                               cell_size, gpu_mode, screen);
   if (!init_ok)
     error->one("Insufficient memory on accelerator (or no fix gpu).\n"); 
 
   if (force->newton_pair) 
     error->all("Cannot use newton pair with GPU CGCMM pair style");
 
   if (gpu_mode != GPU_NEIGH) {
     int irequest = neighbor->request(this);
     neighbor->requests[irequest]->half = 0;
     neighbor->requests[irequest]->full = 1;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double PairCGCMMGPU::memory_usage()
 {
   double bytes = Pair::memory_usage();
   return bytes + cmm_gpu_bytes();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairCGCMMGPU::cpu_compute(int start, int eflag, int vflag) {
   int i,j,ii,jj,inum,jnum,itype,jtype;
   double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
   double rsq,r2inv,r6inv,forcelj,factor_lj;
   int *ilist,*jlist,*numneigh,**firstneigh;
 
   double **x = atom->x;
   double **f = atom->f;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   double *special_lj = force->special_lj;
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
 
   // loop over neighbors of my atoms
 
   for (ii = start; ii < inum; ii++) {
     i = ilist[ii];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
 
       if (j < nall) factor_lj = 1.0;
       else {
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       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];
 
       if (rsq < cutsq[itype][jtype]) {
         const int cgt=cg_type[itype][jtype];
         r2inv = 1.0/rsq;
 
 	fpair = factor_lj;
 	if (eflag) evdwl = factor_lj;
 	if (cgt == CG_LJ12_4) {
 	  const double r4inv = r2inv*r2inv;
 	  fpair *= r4inv*(lj1[itype][jtype]*r4inv*r4inv
 			  - lj2[itype][jtype]);
 	  if (eflag) {
 	    evdwl *= r4inv*(lj3[itype][jtype]*r4inv*r4inv
 			    - lj4[itype][jtype]) - offset[itype][jtype];
 	  }
 	} else if (cgt == CG_LJ9_6) {
 	  const double r3inv = r2inv*sqrt(r2inv);
 	  const double r6inv = r3inv*r3inv;
 	  fpair *= r6inv*(lj1[itype][jtype]*r3inv
 			  - lj2[itype][jtype]);
 	  if (eflag) {
 	    evdwl *= r6inv*(lj3[itype][jtype]*r3inv
 			    - lj4[itype][jtype]) - offset[itype][jtype];
 	  }
 	} else {
 	  const double r6inv = r2inv*r2inv*r2inv;
 	  fpair *= r6inv*(lj1[itype][jtype]*r6inv
 			  - lj2[itype][jtype]);
 	  if (eflag) {
 	    evdwl *= r6inv*(lj3[itype][jtype]*r6inv
 			    - lj4[itype][jtype]) - offset[itype][jtype];
 	  }
 	}
         fpair *= r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
 	if (evflag) ev_tally_full(i,evdwl,0.0,fpair,delx,dely,delz);
       }
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairCGCMMGPU::cpu_compute(int *nbors, int start, int eflag, int vflag) {
   int i,j,itype,jtype;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   int stride = nlocal-start;
   double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
   double rsq,r2inv,r6inv,forcelj,factor_lj;
   double *special_lj = force->special_lj;
 
   double **x = atom->x;
   double **f = atom->f;
   int *type = atom->type;
 
   // loop over neighbors of my atoms
 
   for (i = start; i < nlocal; i++) {
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     int *nbor = nbors + i - start;
     int jnum = *nbor;
     nbor += stride;
     int *nbor_end = nbor + stride * jnum;
 
     for (; nbor<nbor_end; nbor+=stride) {
       j = *nbor;
       
       if (j < nall) factor_lj = 1.0;
       else {
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       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];
 
       if (rsq < cutsq[itype][jtype]) {
         const int cgt=cg_type[itype][jtype];
         r2inv = 1.0/rsq;
 
 	fpair = factor_lj;
 	if (eflag) evdwl = factor_lj;
 	if (cgt == CG_LJ12_4) {
 	  const double r4inv = r2inv*r2inv;
 	  fpair *= r4inv*(lj1[itype][jtype]*r4inv*r4inv
 			  - lj2[itype][jtype]);
 	  if (eflag) {
 	    evdwl *= r4inv*(lj3[itype][jtype]*r4inv*r4inv
 			    - lj4[itype][jtype]) - offset[itype][jtype];
 	  }
 	} else if (cgt == CG_LJ9_6) {
 	  const double r3inv = r2inv*sqrt(r2inv);
 	  const double r6inv = r3inv*r3inv;
 	  fpair *= r6inv*(lj1[itype][jtype]*r3inv
 			  - lj2[itype][jtype]);
 	  if (eflag) {
 	    evdwl *= r6inv*(lj3[itype][jtype]*r3inv
 			    - lj4[itype][jtype]) - offset[itype][jtype];
 	  }
 	} else {
 	  const double r6inv = r2inv*r2inv*r2inv;
 	  fpair *= r6inv*(lj1[itype][jtype]*r6inv
 			  - lj2[itype][jtype]);
 	  if (eflag) {
 	    evdwl *= r6inv*(lj3[itype][jtype]*r6inv
 			    - lj4[itype][jtype]) - offset[itype][jtype];
 	  }
 	}
         fpair *= r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
         if (j<start) {
   	  if (evflag) ev_tally_full(i,evdwl,0.0,fpair,delx,dely,delz);
         } else {
           if (j<nlocal) {
 	    f[j][0] -= delx*fpair;
 	    f[j][1] -= dely*fpair;
 	    f[j][2] -= delz*fpair;
   	  }
 	  if (evflag) ev_tally(i,j,nlocal,0,
 			       evdwl,0.0,fpair,delx,dely,delz);
 	}
       }
     }
   }
 }
 
diff --git a/src/GPU/pair_gayberne_gpu.cpp b/src/GPU/pair_gayberne_gpu.cpp
index 76079f73e..968350769 100644
--- a/src/GPU/pair_gayberne_gpu.cpp
+++ b/src/GPU/pair_gayberne_gpu.cpp
@@ -1,461 +1,466 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "pair_gayberne_gpu.h"
+#include "lmptype.h"
 #include "math_extra.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "comm.h"
 #include "force.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "integrate.h"
 #include "memory.h"
 #include "error.h"
 #include "neigh_request.h"
 #include "universe.h"
 #include "domain.h"
 #include "update.h"
 #include "string.h"
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 // External functions from cuda library for atom decomposition
 
 bool gb_gpu_init(const int ntypes, const double gamma, const double upsilon,
                  const double mu, double **shape, double **well, double **cutsq,
                  double **sigma, double **epsilon, double *host_lshape,
                  int **form, double **host_lj1, double **host_lj2,
                  double **host_lj3, double **host_lj4, double **offset,
                  double *special_lj, const int nlocal, const int nall,
                  const int max_nbors, const double cell_size,
                  int &gpu_mode, FILE *screen);
 void gb_gpu_clear();
 int * gb_gpu_compute_n(const int timestep, const int ago, const int inum,
 	 	       const int nall, double **host_x, int *host_type,
                        double *boxlo, double *boxhi, const bool eflag,
 		       const bool vflag, const bool eatom, const bool vatom,
                        int &host_start, const double cpu_time, bool &success,
 		       double **host_quat);
 int * gb_gpu_compute(const int timestep, const int ago, const int inum,
 	 	     const int nall, double **host_x, int *host_type,
                      int *ilist, int *numj, int **firstneigh,
 		     const bool eflag, const bool vflag, const bool eatom,
                      const bool vatom, int &host_start, const double cpu_time,
                      bool &success, double **host_quat);
 double gb_gpu_bytes();
 
 using namespace LAMMPS_NS;
 
 enum{SPHERE_SPHERE,SPHERE_ELLIPSE,ELLIPSE_SPHERE,ELLIPSE_ELLIPSE};
 
 /* ---------------------------------------------------------------------- */
 
 PairGayBerneGPU::PairGayBerneGPU(LAMMPS *lmp) : PairGayBerne(lmp),
                                                 gpu_mode(GPU_PAIR)
 {
 }
 
 /* ----------------------------------------------------------------------
    free all arrays
 ------------------------------------------------------------------------- */
 
 PairGayBerneGPU::~PairGayBerneGPU()
 {
   gb_gpu_clear();
   cpu_time = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairGayBerneGPU::compute(int eflag, int vflag)
 {
+  if (update->ntimestep > MAXSMALLINT)
+    error->all("Timestep too big for GPU pair style");
+  int ntimestep = update->ntimestep;
+
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = vflag_fdotr = 0;
 
   int nall = atom->nlocal + atom->nghost;
   int inum, host_start;
 
   bool success = true;
 
   if (gpu_mode == GPU_NEIGH) {
     inum = atom->nlocal;
-    gpulist = gb_gpu_compute_n(update->ntimestep, neighbor->ago, inum, nall,
+    gpulist = gb_gpu_compute_n(ntimestep, neighbor->ago, inum, nall,
 			       atom->x, atom->type, domain->sublo, domain->subhi,
 			       eflag, vflag, eflag_atom, vflag_atom, host_start,
                                cpu_time, success, atom->quat);
   } else {
     inum = list->inum;
-    olist = gb_gpu_compute(update->ntimestep, neighbor->ago, inum, nall, atom->x,
+    olist = gb_gpu_compute(ntimestep, neighbor->ago, inum, nall, atom->x,
 			   atom->type, list->ilist, list->numneigh,
 			   list->firstneigh, eflag, vflag, eflag_atom,
                            vflag_atom, host_start, cpu_time, success,
                            atom->quat);
   }
   if (!success)
     error->one("Out of memory on GPGPU");
 
   if (host_start < inum) {
     cpu_time = MPI_Wtime();
     if (gpu_mode == GPU_NEIGH)
       cpu_compute(gpulist,host_start,eflag,vflag);
     else
       cpu_compute(host_start,eflag,vflag);
     cpu_time = MPI_Wtime() - cpu_time;
   }
 }
 
 /* ----------------------------------------------------------------------
    init specific to this pair style
 ------------------------------------------------------------------------- */
 
 void PairGayBerneGPU::init_style()
 {
   if (force->pair_match("gpu",0) == NULL)
     error->all("Cannot use pair hybrid with multiple GPU pair styles");
   if (!atom->quat_flag || !atom->torque_flag || !atom->avec->shape_type)
     error->all("Pair gayberne requires atom attributes quat, torque, shape");
   if (atom->radius_flag)
     error->all("Pair gayberne cannot be used with atom attribute diameter");
 
   // per-type shape precalculations
   for (int i = 1; i <= atom->ntypes; i++) {
     if (setwell[i]) {
       double *one = atom->shape[i];
       shape[i][0] = one[0]*one[0];
       shape[i][1] = one[1]*one[1];
       shape[i][2] = one[2]*one[2];
       lshape[i] = (one[0]*one[1]+one[2]*one[2])*sqrt(one[0]*one[1]);
     }
   }
 
   // Repeat cutsq calculation because done after call to init_style
   double maxcut = -1.0;
   double cut;
   for (int i = 1; i <= atom->ntypes; i++) {
     for (int j = i; j <= atom->ntypes; j++) {
       if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
         cut = init_one(i,j);
         cut *= cut;
         if (cut > maxcut)
           maxcut = cut;
         cutsq[i][j] = cutsq[j][i] = cut;
       } else
         cutsq[i][j] = cutsq[j][i] = 0.0;
     }
   }
 
   double cell_size = sqrt(maxcut) + neighbor->skin;
 
   bool init_ok = gb_gpu_init(atom->ntypes+1, gamma, upsilon, mu, 
                              shape, well, cutsq, sigma, epsilon, lshape, form,
                              lj1, lj2, lj3, lj4, offset, force->special_lj, 
                              atom->nlocal, atom->nlocal+atom->nghost, 300, 
                              cell_size, gpu_mode, screen);
   if (!init_ok)
     error->one("Insufficient memory on accelerator (or no fix gpu).");
 
   if (force->newton_pair) 
     error->all("Cannot use newton pair with GPU Gay-Berne pair style");
 
   if (gpu_mode != GPU_NEIGH) {
     int irequest = neighbor->request(this);
     neighbor->requests[irequest]->half = 0;
     neighbor->requests[irequest]->full = 1;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double PairGayBerneGPU::memory_usage()
 {
   double bytes = Pair::memory_usage();
   return bytes + gb_gpu_bytes();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairGayBerneGPU::cpu_compute(int start, int eflag, int vflag)
 {
   int i,j,ii,jj,inum,jnum,itype,jtype;
   double evdwl,one_eng,rsq,r2inv,r6inv,forcelj,factor_lj;
   double fforce[3],ttor[3],rtor[3],r12[3];
   double a1[3][3],b1[3][3],g1[3][3],a2[3][3],b2[3][3],g2[3][3],temp[3][3];
   int *ilist,*jlist,*numneigh,**firstneigh;
 
   double **x = atom->x;
   double **f = atom->f;
   double **quat = atom->quat;
   double **tor = atom->torque;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   double *special_lj = force->special_lj;
 
   inum = list->inum;
   ilist = olist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
   
   // loop over neighbors of my atoms
 
   for (ii = start; ii < inum; ii++) {
     i = ilist[ii];
     itype = type[i];
 
     if (form[itype][itype] == ELLIPSE_ELLIPSE) {
       MathExtra::quat_to_mat_trans(quat[i],a1);
       MathExtra::diag_times3(well[itype],a1,temp);
       MathExtra::transpose_times3(a1,temp,b1);
       MathExtra::diag_times3(shape[itype],a1,temp);
       MathExtra::transpose_times3(a1,temp,g1);
     }
 
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
 
       if (j < nall) factor_lj = 1.0;
       else {
         factor_lj = special_lj[j/nall];
         j %= nall;
       }
 
       // r12 = center to center vector
 
       r12[0] = x[j][0]-x[i][0];
       r12[1] = x[j][1]-x[i][1];
       r12[2] = x[j][2]-x[i][2];
       rsq = MathExtra::dot3(r12,r12);
       jtype = type[j];
 
       // compute if less than cutoff
 
       if (rsq < cutsq[itype][jtype]) {
 
 	switch (form[itype][jtype]) {
 	case SPHERE_SPHERE:
 	  r2inv = 1.0/rsq;
 	  r6inv = r2inv*r2inv*r2inv;
 	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
 	  forcelj *= -r2inv;
 	  if (eflag) one_eng = 
 	    r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) -
 	    offset[itype][jtype];
 	  fforce[0] = r12[0]*forcelj;
 	  fforce[1] = r12[1]*forcelj;
 	  fforce[2] = r12[2]*forcelj;
 	  ttor[0] = ttor[1] = ttor[2] = 0.0;
 	  rtor[0] = rtor[1] = rtor[2] = 0.0;
 	  break;
 
         case SPHERE_ELLIPSE:
 	  MathExtra::quat_to_mat_trans(quat[j],a2);
 	  MathExtra::diag_times3(well[jtype],a2,temp);
 	  MathExtra::transpose_times3(a2,temp,b2);
 	  MathExtra::diag_times3(shape[jtype],a2,temp);
 	  MathExtra::transpose_times3(a2,temp,g2);
 	  one_eng = gayberne_lj(j,i,a2,b2,g2,r12,rsq,fforce,rtor);
 	  ttor[0] = ttor[1] = ttor[2] = 0.0;
 	  break;
 
         case ELLIPSE_SPHERE:
 	  one_eng = gayberne_lj(i,j,a1,b1,g1,r12,rsq,fforce,ttor);
 	  rtor[0] = rtor[1] = rtor[2] = 0.0;
 	  break;
 
 	default:
 	  MathExtra::quat_to_mat_trans(quat[j],a2);
 	  MathExtra::diag_times3(well[jtype],a2,temp);
 	  MathExtra::transpose_times3(a2,temp,b2);
 	  MathExtra::diag_times3(shape[jtype],a2,temp);
 	  MathExtra::transpose_times3(a2,temp,g2);
 	  one_eng = gayberne_analytic(i,j,a1,a2,b1,b2,g1,g2,r12,rsq,
 				      fforce,ttor,rtor);
 	  break;
 	}
 
         fforce[0] *= factor_lj;
 	fforce[1] *= factor_lj;
 	fforce[2] *= factor_lj;
         ttor[0] *= factor_lj;
 	ttor[1] *= factor_lj;
 	ttor[2] *= factor_lj;
 
         f[i][0] += fforce[0];
 	f[i][1] += fforce[1];
 	f[i][2] += fforce[2];
         tor[i][0] += ttor[0];
 	tor[i][1] += ttor[1];
 	tor[i][2] += ttor[2];
 
         if (eflag) evdwl = factor_lj*one_eng;
 
 	if (evflag) ev_tally_xyz_full(i,evdwl,0.0,fforce[0],fforce[1],fforce[2],
 				      -r12[0],-r12[1],-r12[2]);
       }
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairGayBerneGPU::cpu_compute(int *nbors, int start, int eflag, int vflag)
 {
   int i,j,itype,jtype;
   double evdwl,one_eng,rsq,r2inv,r6inv,forcelj,factor_lj;
   double fforce[3],ttor[3],rtor[3],r12[3];
   double a1[3][3],b1[3][3],g1[3][3],a2[3][3],b2[3][3],g2[3][3],temp[3][3];
 
   double **x = atom->x;
   double **f = atom->f;
   double **quat = atom->quat;
   double **tor = atom->torque;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   int stride = nlocal-start;
   double *special_lj = force->special_lj;
 
   // loop over neighbors of my atoms
 
   for (i = start; i < nlocal; i++) {
     itype = type[i];
 
     if (form[itype][itype] == ELLIPSE_ELLIPSE) {
       MathExtra::quat_to_mat_trans(quat[i],a1);
       MathExtra::diag_times3(well[itype],a1,temp);
       MathExtra::transpose_times3(a1,temp,b1);
       MathExtra::diag_times3(shape[itype],a1,temp);
       MathExtra::transpose_times3(a1,temp,g1);
     }
 
     int *nbor = nbors+i-start;
     int jnum =* nbor;
     nbor += stride;
     int *nbor_end = nbor + stride * jnum;
 
     for ( ; nbor < nbor_end; nbor += stride) {
       j = *nbor;
 
       if (j < nall) factor_lj = 1.0;
       else {
         factor_lj = special_lj[j/nall];
         j %= nall;
       }
 
       // r12 = center to center vector
 
       r12[0] = x[j][0]-x[i][0];
       r12[1] = x[j][1]-x[i][1];
       r12[2] = x[j][2]-x[i][2];
       rsq = MathExtra::dot3(r12,r12);
       jtype = type[j];
 
       // compute if less than cutoff
 
       if (rsq < cutsq[itype][jtype]) {
 
 	switch (form[itype][jtype]) {
 	case SPHERE_SPHERE:
 	  r2inv = 1.0/rsq;
 	  r6inv = r2inv*r2inv*r2inv;
 	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
 	  forcelj *= -r2inv;
 	  if (eflag) one_eng = 
 	    r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) -
 	    offset[itype][jtype];
 	  fforce[0] = r12[0]*forcelj;
 	  fforce[1] = r12[1]*forcelj;
 	  fforce[2] = r12[2]*forcelj;
 	  ttor[0] = ttor[1] = ttor[2] = 0.0;
 	  rtor[0] = rtor[1] = rtor[2] = 0.0;
 	  break;
 
         case SPHERE_ELLIPSE:
 	  MathExtra::quat_to_mat_trans(quat[j],a2);
 	  MathExtra::diag_times3(well[jtype],a2,temp);
 	  MathExtra::transpose_times3(a2,temp,b2);
 	  MathExtra::diag_times3(shape[jtype],a2,temp);
 	  MathExtra::transpose_times3(a2,temp,g2);
 	  one_eng = gayberne_lj(j,i,a2,b2,g2,r12,rsq,fforce,rtor);
 	  ttor[0] = ttor[1] = ttor[2] = 0.0;
 	  break;
 
         case ELLIPSE_SPHERE:
 	  one_eng = gayberne_lj(i,j,a1,b1,g1,r12,rsq,fforce,ttor);
 	  rtor[0] = rtor[1] = rtor[2] = 0.0;
 	  break;
 
 	default:
 	  MathExtra::quat_to_mat_trans(quat[j],a2);
 	  MathExtra::diag_times3(well[jtype],a2,temp);
 	  MathExtra::transpose_times3(a2,temp,b2);
 	  MathExtra::diag_times3(shape[jtype],a2,temp);
 	  MathExtra::transpose_times3(a2,temp,g2);
 	  one_eng = gayberne_analytic(i,j,a1,a2,b1,b2,g1,g2,r12,rsq,
 				      fforce,ttor,rtor);
 	  break;
 	}
 
         fforce[0] *= factor_lj;
 	fforce[1] *= factor_lj;
 	fforce[2] *= factor_lj;
         ttor[0] *= factor_lj;
 	ttor[1] *= factor_lj;
 	ttor[2] *= factor_lj;
 
         f[i][0] += fforce[0];
 	f[i][1] += fforce[1];
 	f[i][2] += fforce[2];
         tor[i][0] += ttor[0];
 	tor[i][1] += ttor[1];
 	tor[i][2] += ttor[2];
 
         if (eflag) evdwl = factor_lj*one_eng;
 
         if (j<start) { 
   	  if (evflag) ev_tally_xyz_full(i,evdwl,0.0,fforce[0],fforce[1],
 				        fforce[2],-r12[0],-r12[1],-r12[2]);
         } else {
           if (j < nlocal) {
             rtor[0] *= factor_lj;
 	    rtor[1] *= factor_lj;
 	    rtor[2] *= factor_lj;
             f[j][0] -= fforce[0];
 	    f[j][1] -= fforce[1];
 	    f[j][2] -= fforce[2];
             tor[j][0] += rtor[0];
 	    tor[j][1] += rtor[1];
 	    tor[j][2] += rtor[2];
           }
   	  if (evflag) ev_tally_xyz(i,j,nlocal,0,
 	  			   evdwl,0.0,fforce[0],fforce[1],fforce[2],
 				   -r12[0],-r12[1],-r12[2]);
         }
       }
     }
   }
 }
 
 
diff --git a/src/GPU/pair_lj96_cut_gpu.cpp b/src/GPU/pair_lj96_cut_gpu.cpp
index 583c2f27b..095e9d9c0 100644
--- a/src/GPU/pair_lj96_cut_gpu.cpp
+++ b/src/GPU/pair_lj96_cut_gpu.cpp
@@ -1,318 +1,323 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
    
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
    
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "pair_lj96_cut_gpu.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "comm.h"
 #include "force.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "integrate.h"
 #include "memory.h"
 #include "error.h"
 #include "neigh_request.h"
 #include "universe.h"
 #include "update.h"
 #include "domain.h"
 #include "string.h"
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 // External functions from cuda library for atom decomposition
 
 bool lj96_gpu_init(const int ntypes, double **cutsq, double **host_lj1,
                    double **host_lj2, double **host_lj3, double **host_lj4, 
                    double **offset, double *special_lj, const int nlocal, 
                    const int nall, const int max_nbors, const int maxspecial,
                    const double cell_size, int &gpu_mode, FILE *screen);
 void lj96_gpu_clear();
 int * lj96_gpu_compute_n(const int timestep, const int ago, const int inum,
 	 	         const int nall, double **host_x, int *host_type, 
                          double *boxlo, double *boxhi, int *tag, int **nspecial,
                          int **special, const bool eflag, const bool vflag,
                          const bool eatom, const bool vatom, int &host_start,
                          const double cpu_time, bool &success);
 void lj96_gpu_compute(const int timestep, const int ago, const int inum,
 	 	      const int nall, double **host_x, int *host_type,
                       int *ilist, int *numj, int **firstneigh,
 		      const bool eflag, const bool vflag, const bool eatom,
                       const bool vatom, int &host_start, const double cpu_time,
                       bool &success);
 double lj96_gpu_bytes();
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 PairLJ96CutGPU::PairLJ96CutGPU(LAMMPS *lmp) : PairLJ96Cut(lmp), gpu_mode(GPU_PAIR)
 {
   respa_enable = 0;
   cpu_time = 0.0;
 }
 
 /* ----------------------------------------------------------------------
    free all arrays
 ------------------------------------------------------------------------- */
 
 PairLJ96CutGPU::~PairLJ96CutGPU()
 {
   lj96_gpu_clear();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJ96CutGPU::compute(int eflag, int vflag)
 {
+  if (update->ntimestep > MAXSMALLINT)
+    error->all("Timestep too big for GPU pair style");
+  int ntimestep = update->ntimestep;
+
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = vflag_fdotr = 0;
   
   int nall = atom->nlocal + atom->nghost;
   int inum, host_start;
   
   bool success = true;
   
   if (gpu_mode == GPU_NEIGH) {
     inum = atom->nlocal;
-    gpulist = lj96_gpu_compute_n(update->ntimestep, neighbor->ago, inum, nall,
+    gpulist = lj96_gpu_compute_n(ntimestep, neighbor->ago, inum, nall,
 			         atom->x, atom->type, domain->sublo,
 				 domain->subhi, atom->tag, atom->nspecial,
                                  atom->special, eflag, vflag, eflag_atom,
                                  vflag_atom, host_start, cpu_time, success);
   } else {
     inum = list->inum;
-    lj96_gpu_compute(update->ntimestep, neighbor->ago, inum, nall, atom->x,
+    lj96_gpu_compute(ntimestep, neighbor->ago, inum, nall, atom->x,
 		     atom->type, list->ilist, list->numneigh, list->firstneigh,
 		     eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time,
                      success);
   }
   if (!success)
     error->one("Out of memory on GPGPU");
 
   if (host_start<inum) {
     cpu_time = MPI_Wtime();
     if (gpu_mode == GPU_NEIGH)
       cpu_compute(gpulist, host_start, eflag, vflag);
     else
       cpu_compute(host_start, eflag, vflag);
     cpu_time = MPI_Wtime() - cpu_time;
   }
 }
 
 /* ----------------------------------------------------------------------
    init specific to this pair style
 ------------------------------------------------------------------------- */
 
 void PairLJ96CutGPU::init_style()
 {
   cut_respa = NULL;
 
   if (force->pair_match("gpu",0) == NULL)
     error->all("Cannot use pair hybrid with multiple GPU pair styles");
 
   // Repeat cutsq calculation because done after call to init_style
   double maxcut = -1.0;
   double cut;
   for (int i = 1; i <= atom->ntypes; i++) {
     for (int j = i; j <= atom->ntypes; j++) {
       if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
         cut = init_one(i,j);
         cut *= cut;
         if (cut > maxcut)
           maxcut = cut;
         cutsq[i][j] = cutsq[j][i] = cut;
       } else
         cutsq[i][j] = cutsq[j][i] = 0.0;
     }
   }
   double cell_size = sqrt(maxcut) + neighbor->skin;
 
   int maxspecial=0;
   if (atom->molecular)
     maxspecial=atom->maxspecial;
   bool init_ok = lj96_gpu_init(atom->ntypes+1, cutsq, lj1, lj2, lj3, lj4,
                                offset, force->special_lj, atom->nlocal,
                                atom->nlocal+atom->nghost, 300, maxspecial,
                                cell_size, gpu_mode, screen);
   if (!init_ok)
     error->one("Insufficient memory on accelerator (or no fix gpu).\n"); 
 
   if (force->newton_pair) 
     error->all("Cannot use newton pair with GPU LJ96 pair style");
 
   if (gpu_mode != GPU_NEIGH) {
     int irequest = neighbor->request(this);
     neighbor->requests[irequest]->half = 0;
     neighbor->requests[irequest]->full = 1;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double PairLJ96CutGPU::memory_usage()
 {
   double bytes = Pair::memory_usage();
   return bytes + lj96_gpu_bytes();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJ96CutGPU::cpu_compute(int start, int eflag, int vflag) {
   int i,j,ii,jj,inum,jnum,itype,jtype;
   double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
   double rsq,r2inv,r3inv,r6inv,forcelj,factor_lj;
   int *ilist,*jlist,*numneigh,**firstneigh;
 
   double **x = atom->x;
   double **f = atom->f;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   double *special_lj = force->special_lj;
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
 
   // loop over neighbors of my atoms
 
   for (ii = start; ii < inum; ii++) {
     i = ilist[ii];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
 
       if (j < nall) factor_lj = 1.0;
       else {
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       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];
 
       if (rsq < cutsq[itype][jtype]) {
 	r2inv = 1.0/rsq;
 	r6inv = r2inv*r2inv*r2inv;
 	r3inv = sqrt(r6inv);
 	forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
 	fpair = factor_lj*forcelj*r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
 	if (eflag) {
 	  evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) -
 	    offset[itype][jtype];
 	  evdwl *= factor_lj;
 	}
 
 	if (evflag) ev_tally_full(i,evdwl,0.0,fpair,delx,dely,delz);
       }
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJ96CutGPU::cpu_compute(int *nbors, int start, int eflag, int vflag) {
   int i,j,itype,jtype;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   int stride = nlocal-start;
   double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
   double rsq,r2inv,r3inv,r6inv,forcelj,factor_lj;
   double *special_lj = force->special_lj;
 
   double **x = atom->x;
   double **f = atom->f;
   int *type = atom->type;
 
   // loop over neighbors of my atoms
 
   for (i = start; i < nlocal; i++) {
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     int *nbor = nbors + i - start;
     int jnum = *nbor;
     nbor += stride;
     int *nbor_end = nbor + stride * jnum;
 
     for (; nbor<nbor_end; nbor+=stride) {
       j = *nbor;
       
       if (j < nall) factor_lj = 1.0;
       else {
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       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];
 
       if (rsq < cutsq[itype][jtype]) {
 	r2inv = 1.0/rsq;
 	r6inv = r2inv*r2inv*r2inv;
 	r3inv = sqrt(r6inv);
 	forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
 	fpair = factor_lj*forcelj*r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
 	if (eflag) {
 	  evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) -
 	    offset[itype][jtype];
 	  evdwl *= factor_lj;
 	}
 
         if (j<start) {
   	  if (evflag) ev_tally_full(i,evdwl,0.0,fpair,delx,dely,delz);
         } else {
           if (j<nlocal) {
 	    f[j][0] -= delx*fpair;
 	    f[j][1] -= dely*fpair;
 	    f[j][2] -= delz*fpair;
   	  }
 	  if (evflag) ev_tally(i,j,nlocal,0,
 			       evdwl,0.0,fpair,delx,dely,delz);
 	}
       }
     }
   }
 }
diff --git a/src/GPU/pair_lj_cut_coul_cut_gpu.cpp b/src/GPU/pair_lj_cut_coul_cut_gpu.cpp
index 54430cbc3..1c8632c3a 100644
--- a/src/GPU/pair_lj_cut_coul_cut_gpu.cpp
+++ b/src/GPU/pair_lj_cut_coul_cut_gpu.cpp
@@ -1,364 +1,369 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
    
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
    
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "pair_lj_cut_coul_cut_gpu.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "comm.h"
 #include "force.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "integrate.h"
 #include "memory.h"
 #include "error.h"
 #include "neigh_request.h"
 #include "universe.h"
 #include "update.h"
 #include "domain.h"
 #include "string.h"
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 // External functions from cuda library for atom decomposition
 
 bool ljc_gpu_init(const int ntypes, double **cutsq, double **host_lj1,
                   double **host_lj2, double **host_lj3, double **host_lj4, 
                   double **offset, double *special_lj, const int nlocal, 
                   const int nall, const int max_nbors, const int maxspecial,
                   const double cell_size, int &gpu_mode, FILE *screen,
                   double **host_cut_ljsq, double **host_cut_coulsq,
                   double *host_special_coul, const double qqrd2e);
 void ljc_gpu_clear();
 int * ljc_gpu_compute_n(const int timestep, const int ago, const int inum,
 	 	        const int nall, double **host_x, int *host_type, 
                         double *boxlo, double *boxhi, int *tag, int **nspecial,
                         int **special, const bool eflag, const bool vflag,
                         const bool eatom, const bool vatom, int &host_start,
                         const double cpu_time, bool &success, double *host_q);
 void ljc_gpu_compute(const int timestep, const int ago, const int inum,
 	 	     const int nall, double **host_x, int *host_type,
                      int *ilist, int *numj, int **firstneigh,
 		     const bool eflag, const bool vflag, const bool eatom,
                      const bool vatom, int &host_start, const double cpu_time,
                      bool &success, double *host_q);
 double ljc_gpu_bytes();
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 PairLJCutCoulCutGPU::PairLJCutCoulCutGPU(LAMMPS *lmp) : PairLJCutCoulCut(lmp), gpu_mode(GPU_PAIR)
 {
   respa_enable = 0;
   cpu_time = 0.0;
 }
 
 /* ----------------------------------------------------------------------
    free all arrays
 ------------------------------------------------------------------------- */
 
 PairLJCutCoulCutGPU::~PairLJCutCoulCutGPU()
 {
   ljc_gpu_clear();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJCutCoulCutGPU::compute(int eflag, int vflag)
 {
+  if (update->ntimestep > MAXSMALLINT)
+    error->all("Timestep too big for GPU pair style");
+  int ntimestep = update->ntimestep;
+
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = vflag_fdotr = 0;
   
   int nall = atom->nlocal + atom->nghost;
   int inum, host_start;
   
   bool success = true;
   
   if (gpu_mode == GPU_NEIGH) {
     inum = atom->nlocal;
-    gpulist = ljc_gpu_compute_n(update->ntimestep, neighbor->ago, inum, nall,
+    gpulist = ljc_gpu_compute_n(ntimestep, neighbor->ago, inum, nall,
 			        atom->x, atom->type, domain->sublo,
 				domain->subhi, atom->tag, atom->nspecial,
                                 atom->special, eflag, vflag, eflag_atom,
                                 vflag_atom, host_start, cpu_time, success,
                                 atom->q);
   } else {
     inum = list->inum;
-    ljc_gpu_compute(update->ntimestep, neighbor->ago, inum, nall, atom->x,
+    ljc_gpu_compute(ntimestep, neighbor->ago, inum, nall, atom->x,
 		    atom->type, list->ilist, list->numneigh, list->firstneigh,
 		    eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time,
                     success, atom->q);
   }
   if (!success)
     error->one("Out of memory on GPGPU");
 
   if (host_start<inum) {
     cpu_time = MPI_Wtime();
     if (gpu_mode == GPU_NEIGH)
       cpu_compute(gpulist, host_start, eflag, vflag);
     else
       cpu_compute(host_start, eflag, vflag);
     cpu_time = MPI_Wtime() - cpu_time;
   }
 }
 
 /* ----------------------------------------------------------------------
    init specific to this pair style
 ------------------------------------------------------------------------- */
 
 void PairLJCutCoulCutGPU::init_style()
 {
   if (!atom->q_flag)
     error->all("Pair style lj/cut/coul/cut requires atom attribute q");
   if (force->pair_match("gpu",0) == NULL)
     error->all("Cannot use pair hybrid with multiple GPU pair styles");
 
   // Repeat cutsq calculation because done after call to init_style
   double maxcut = -1.0;
   double cut;
   for (int i = 1; i <= atom->ntypes; i++) {
     for (int j = i; j <= atom->ntypes; j++) {
       if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
         cut = init_one(i,j);
         cut *= cut;
         if (cut > maxcut)
           maxcut = cut;
         cutsq[i][j] = cutsq[j][i] = cut;
       } else
         cutsq[i][j] = cutsq[j][i] = 0.0;
     }
   }
   double cell_size = sqrt(maxcut) + neighbor->skin;
 
   int maxspecial=0;
   if (atom->molecular)
     maxspecial=atom->maxspecial;
   bool init_ok = ljc_gpu_init(atom->ntypes+1, cutsq, lj1, lj2, lj3, lj4,
                               offset, force->special_lj, atom->nlocal,
                               atom->nlocal+atom->nghost, 300, maxspecial,
                               cell_size, gpu_mode, screen, cut_ljsq, cut_coulsq,
                               force->special_coul, force->qqrd2e);
   if (!init_ok)
     error->one("Insufficient memory on accelerator (or no fix gpu).\n"); 
 
   if (force->newton_pair) 
     error->all("Cannot use newton pair with GPU LJ pair style");
 
   if (gpu_mode != GPU_NEIGH) {
     int irequest = neighbor->request(this);
     neighbor->requests[irequest]->half = 0;
     neighbor->requests[irequest]->full = 1;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double PairLJCutCoulCutGPU::memory_usage()
 {
   double bytes = Pair::memory_usage();
   return bytes + ljc_gpu_bytes();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJCutCoulCutGPU::cpu_compute(int start, int eflag, int vflag)
 {
   int i,j,ii,jj,inum,jnum,itype,jtype;
   double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
   double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
   int *ilist,*jlist,*numneigh,**firstneigh;
 
   evdwl = ecoul = 0.0;
 
   double **x = atom->x;
   double **f = atom->f;
   double *q = atom->q;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
   int newton_pair = force->newton_pair;
   double qqrd2e = force->qqrd2e;
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
 
   // loop over neighbors of my atoms
 
   for (ii = start; ii < inum; ii++) {
     i = ilist[ii];
     qtmp = q[i];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
 
       if (j < nall) factor_coul = factor_lj = 1.0;
       else {
 	factor_coul = special_coul[j/nall];
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       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];
 
       if (rsq < cutsq[itype][jtype]) {
 	r2inv = 1.0/rsq;
 
 	if (rsq < cut_coulsq[itype][jtype])
 	  forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv);
 	else forcecoul = 0.0;
 
 	if (rsq < cut_ljsq[itype][jtype]) {
 	  r6inv = r2inv*r2inv*r2inv;
 	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
 	} else forcelj = 0.0;
 
 	fpair = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
 	if (eflag) {
 	  if (rsq < cut_coulsq[itype][jtype])
 	    ecoul = factor_coul * qqrd2e * qtmp*q[j]*sqrt(r2inv);
 	  else ecoul = 0.0;
 	  if (rsq < cut_ljsq[itype][jtype]) {
 	    evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
 	      offset[itype][jtype];
 	    evdwl *= factor_lj;
 	  } else evdwl = 0.0;
 	}
 
 	if (evflag) ev_tally_full(i,evdwl,ecoul,fpair,delx,dely,delz);
       }
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJCutCoulCutGPU::cpu_compute(int *nbors, int start, int eflag,
                                       int vflag)
 {
   int i,j,jnum,itype,jtype;
   double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
   double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
 
   evdwl = ecoul = 0.0;
 
   double **x = atom->x;
   double **f = atom->f;
   double *q = atom->q;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   int stride = nlocal-start;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
   double qqrd2e = force->qqrd2e;
 
   // loop over neighbors of my atoms
 
   for (i = start; i < nlocal; i++) {
     qtmp = q[i];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     int *nbor = nbors + i - start;
     jnum = *nbor;
     nbor += stride;
     int *nbor_end = nbor + stride * jnum;
 
     for (; nbor<nbor_end; nbor+=stride) {
       j = *nbor;
 
       if (j < nall) factor_coul = factor_lj = 1.0;
       else {
 	factor_coul = special_coul[j/nall];
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       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];
 
       if (rsq < cutsq[itype][jtype]) {
 	r2inv = 1.0/rsq;
 
 	if (rsq < cut_coulsq[itype][jtype])
 	  forcecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv);
 	else forcecoul = 0.0;
 
 	if (rsq < cut_ljsq[itype][jtype]) {
 	  r6inv = r2inv*r2inv*r2inv;
 	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
 	} else forcelj = 0.0;
 
 	fpair = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
 	if (eflag) {
 	  if (rsq < cut_coulsq[itype][jtype])
 	    ecoul = factor_coul * qqrd2e * qtmp*q[j]*sqrt(r2inv);
 	  else ecoul = 0.0;
 	  if (rsq < cut_ljsq[itype][jtype]) {
 	    evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
 	      offset[itype][jtype];
 	    evdwl *= factor_lj;
 	  } else evdwl = 0.0;
 	}
 
         if (j<start) {
   	  if (evflag) ev_tally_full(i,evdwl,ecoul,fpair,delx,dely,delz);
         } else {
           if (j<nlocal) {
 	    f[j][0] -= delx*fpair;
 	    f[j][1] -= dely*fpair;
 	    f[j][2] -= delz*fpair;
   	  }
 	  if (evflag) ev_tally(i,j,nlocal,0,
 			       evdwl,ecoul,fpair,delx,dely,delz);
         }
       }
     }
   }
 }
diff --git a/src/GPU/pair_lj_cut_coul_long_gpu.cpp b/src/GPU/pair_lj_cut_coul_long_gpu.cpp
index 2ae806439..632f151dc 100644
--- a/src/GPU/pair_lj_cut_coul_long_gpu.cpp
+++ b/src/GPU/pair_lj_cut_coul_long_gpu.cpp
@@ -1,452 +1,457 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
    
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
    
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "pair_lj_cut_coul_long_gpu.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "comm.h"
 #include "force.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "integrate.h"
 #include "memory.h"
 #include "error.h"
 #include "neigh_request.h"
 #include "universe.h"
 #include "update.h"
 #include "domain.h"
 #include "string.h"
 #include "kspace.h"
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 #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
 
 // External functions from cuda library for atom decomposition
 
 bool ljcl_gpu_init(const int ntypes, double **cutsq, double **host_lj1,
                   double **host_lj2, double **host_lj3, double **host_lj4, 
                   double **offset, double *special_lj, const int nlocal, 
                   const int nall, const int max_nbors, const int maxspecial,
                   const double cell_size, int &gpu_mode, FILE *screen,
                   double **host_cut_ljsq, double host_cut_coulsq,
                   double *host_special_coul, const double qqrd2e,
                   const double g_ewald);
 void ljcl_gpu_clear();
 int * ljcl_gpu_compute_n(const int timestep, const int ago, const int inum,
 	 	        const int nall, double **host_x, int *host_type, 
                         double *boxlo, double *boxhi, int *tag, int **nspecial,
                         int **special, const bool eflag, const bool vflag,
                         const bool eatom, const bool vatom, int &host_start,
                         const double cpu_time, bool &success, double *host_q);
 void ljcl_gpu_compute(const int timestep, const int ago, const int inum,
 	 	     const int nall, double **host_x, int *host_type,
                      int *ilist, int *numj, int **firstneigh,
 		     const bool eflag, const bool vflag, const bool eatom,
                      const bool vatom, int &host_start, const double cpu_time,
                      bool &success, double *host_q);
 double ljcl_gpu_bytes();
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 PairLJCutCoulLongGPU::PairLJCutCoulLongGPU(LAMMPS *lmp) : PairLJCutCoulLong(lmp), gpu_mode(GPU_PAIR)
 {
   respa_enable = 0;
   cpu_time = 0.0;
 }
 
 /* ----------------------------------------------------------------------
    free all arrays
 ------------------------------------------------------------------------- */
 
 PairLJCutCoulLongGPU::~PairLJCutCoulLongGPU()
 {
   ljcl_gpu_clear();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJCutCoulLongGPU::compute(int eflag, int vflag)
 {
+  if (update->ntimestep > MAXSMALLINT)
+    error->all("Timestep too big for GPU pair style");
+  int ntimestep = update->ntimestep;
+
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = vflag_fdotr = 0;
   
   int nall = atom->nlocal + atom->nghost;
   int inum, host_start;
   
   bool success = true;
   
   if (gpu_mode == GPU_NEIGH) {
     inum = atom->nlocal;
-    gpulist = ljcl_gpu_compute_n(update->ntimestep, neighbor->ago, inum, nall,
+    gpulist = ljcl_gpu_compute_n(ntimestep, neighbor->ago, inum, nall,
 			         atom->x, atom->type, domain->sublo,
 				 domain->subhi, atom->tag, atom->nspecial,
                                  atom->special, eflag, vflag, eflag_atom,
                                  vflag_atom, host_start, cpu_time, success,
                                  atom->q);
   } else {
     inum = list->inum;
-    ljcl_gpu_compute(update->ntimestep, neighbor->ago, inum, nall, atom->x,
+    ljcl_gpu_compute(ntimestep, neighbor->ago, inum, nall, atom->x,
 		    atom->type, list->ilist, list->numneigh, list->firstneigh,
 		    eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time,
                     success, atom->q);
   }
   if (!success)
     error->one("Out of memory on GPGPU");
 
   if (host_start<inum) {
     cpu_time = MPI_Wtime();
     if (gpu_mode == GPU_NEIGH)
       cpu_compute(gpulist, host_start, eflag, vflag);
     else
       cpu_compute(host_start, eflag, vflag);
     cpu_time = MPI_Wtime() - cpu_time;
   }
 }
 
 /* ----------------------------------------------------------------------
    init specific to this pair style
 ------------------------------------------------------------------------- */
 
 void PairLJCutCoulLongGPU::init_style()
 {
   cut_respa = NULL;
 
   if (!atom->q_flag)
     error->all("Pair style lj/cut/coul/cut requires atom attribute q");
   if (force->pair_match("gpu",0) == NULL)
     error->all("Cannot use pair hybrid with multiple GPU pair styles");
 
   // Repeat cutsq calculation because done after call to init_style
   double maxcut = -1.0;
   double cut;
   for (int i = 1; i <= atom->ntypes; i++) {
     for (int j = i; j <= atom->ntypes; j++) {
       if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
         cut = init_one(i,j);
         cut *= cut;
         if (cut > maxcut)
           maxcut = cut;
         cutsq[i][j] = cutsq[j][i] = cut;
       } else
         cutsq[i][j] = cutsq[j][i] = 0.0;
     }
   }
   double cell_size = sqrt(maxcut) + neighbor->skin;
 
   cut_coulsq = cut_coul * cut_coul;
 
   // insure use of KSpace long-range solver, set g_ewald
 
   if (force->kspace == NULL)
     error->all("Pair style is incompatible with KSpace style");
   g_ewald = force->kspace->g_ewald;
 
   // setup force tables
 
   if (ncoultablebits) init_tables();
 
   int maxspecial=0;
   if (atom->molecular)
     maxspecial=atom->maxspecial;
   bool init_ok = ljcl_gpu_init(atom->ntypes+1, cutsq, lj1, lj2, lj3, lj4,
                               offset, force->special_lj, atom->nlocal,
                               atom->nlocal+atom->nghost, 300, maxspecial,
                               cell_size, gpu_mode, screen, cut_ljsq, cut_coulsq,
                               force->special_coul, force->qqrd2e, g_ewald);
   if (!init_ok)
     error->one("Insufficient memory on accelerator (or no fix gpu).\n"); 
 
   if (force->newton_pair) 
     error->all("Cannot use newton pair with GPU LJ pair style");
 
   if (gpu_mode != GPU_NEIGH) {
     int irequest = neighbor->request(this);
     neighbor->requests[irequest]->half = 0;
     neighbor->requests[irequest]->full = 1;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double PairLJCutCoulLongGPU::memory_usage()
 {
   double bytes = Pair::memory_usage();
   return bytes + ljcl_gpu_bytes();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJCutCoulLongGPU::cpu_compute(int start, int eflag, int vflag)
 {
   int i,j,ii,jj,inum,jnum,itype,jtype,itable;
   double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
   double fraction,table;
   double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
   double grij,expm2,prefactor,t,erfc;
   int *ilist,*jlist,*numneigh,**firstneigh;
   double rsq;
 
   evdwl = ecoul = 0.0;
 
   double **x = atom->x;
   double **f = atom->f;
   double *q = atom->q;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
   double qqrd2e = force->qqrd2e;
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
   
   // loop over neighbors of my atoms
 
   for (ii = start; ii < inum; ii++) {
     i = ilist[ii];
     qtmp = q[i];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
 
       if (j < nall) factor_coul = factor_lj = 1.0;
       else {
 	factor_coul = special_coul[j/nall];
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       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];
 
       if (rsq < cutsq[itype][jtype]) {
 	r2inv = 1.0/rsq;
 
 	if (rsq < cut_coulsq) {
 	  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;
 	    }
 	  }
 	} else forcecoul = 0.0;
 
 	if (rsq < cut_ljsq[itype][jtype]) {
 	  r6inv = r2inv*r2inv*r2inv;
 	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
 	} else forcelj = 0.0;
 
 	fpair = (forcecoul + factor_lj*forcelj) * r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
 	if (eflag) {
 	  if (rsq < cut_coulsq) {
 	    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 (rsq < cut_ljsq[itype][jtype]) {
 	    evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
 	      offset[itype][jtype];
 	    evdwl *= factor_lj;
 	  } else evdwl = 0.0;
 	}
 
 	if (evflag) ev_tally_full(i,evdwl,ecoul,fpair,delx,dely,delz);
       }
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJCutCoulLongGPU::cpu_compute(int *nbors, int start, int eflag,
                                       int vflag)
 {
   int i,j,jnum,itype,jtype,itable;
   double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
   double fraction,table;
   double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
   double grij,expm2,prefactor,t,erfc;
   double rsq;
 
   evdwl = ecoul = 0.0;
 
   double **x = atom->x;
   double **f = atom->f;
   double *q = atom->q;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   int stride = nlocal-start;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
   double qqrd2e = force->qqrd2e;
 
   // loop over neighbors of my atoms
 
   for (i = start; i < nlocal; i++) {
     qtmp = q[i];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     int *nbor = nbors + i - start;
     jnum = *nbor;
     nbor += stride;
     int *nbor_end = nbor + stride * jnum;
 
     for (; nbor<nbor_end; nbor+=stride) {
       j = *nbor;
 
       if (j < nall) factor_coul = factor_lj = 1.0;
       else {
 	factor_coul = special_coul[j/nall];
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       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];
 
       if (rsq < cutsq[itype][jtype]) {
 	r2inv = 1.0/rsq;
 
 	if (rsq < cut_coulsq) {
 	  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;
 	    }
 	  }
 	} else forcecoul = 0.0;
 
 	if (rsq < cut_ljsq[itype][jtype]) {
 	  r6inv = r2inv*r2inv*r2inv;
 	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
 	} else forcelj = 0.0;
 
 	fpair = (forcecoul + factor_lj*forcelj) * r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
 	if (eflag) {
 	  if (rsq < cut_coulsq) {
 	    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 (rsq < cut_ljsq[itype][jtype]) {
 	    evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
 	      offset[itype][jtype];
 	    evdwl *= factor_lj;
 	  } else evdwl = 0.0;
 	}
 
         if (j<start) {
   	  if (evflag) ev_tally_full(i,evdwl,ecoul,fpair,delx,dely,delz);
         } else {
           if (j<nlocal) {
 	    f[j][0] -= delx*fpair;
 	    f[j][1] -= dely*fpair;
 	    f[j][2] -= delz*fpair;
   	  }
 	  if (evflag) ev_tally(i,j,nlocal,0,
 			       evdwl,ecoul,fpair,delx,dely,delz);
         }
       }
     }
   }
 }
 
diff --git a/src/GPU/pair_lj_cut_gpu.cpp b/src/GPU/pair_lj_cut_gpu.cpp
index 1e7d952e1..ba2269d24 100644
--- a/src/GPU/pair_lj_cut_gpu.cpp
+++ b/src/GPU/pair_lj_cut_gpu.cpp
@@ -1,317 +1,322 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
    
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
    
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "pair_lj_cut_gpu.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "comm.h"
 #include "force.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "integrate.h"
 #include "memory.h"
 #include "error.h"
 #include "neigh_request.h"
 #include "universe.h"
 #include "update.h"
 #include "domain.h"
 #include "string.h"
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 // External functions from cuda library for atom decomposition
 
 bool ljl_gpu_init(const int ntypes, double **cutsq, double **host_lj1,
                   double **host_lj2, double **host_lj3, double **host_lj4, 
                   double **offset, double *special_lj, const int nlocal, 
                   const int nall, const int max_nbors, const int maxspecial,
                   const double cell_size, int &gpu_mode, FILE *screen);
 void ljl_gpu_clear();
 int * ljl_gpu_compute_n(const int timestep, const int ago, const int inum,
 	 	        const int nall, double **host_x, int *host_type, 
                         double *boxlo, double *boxhi, int *tag, int **nspecial,
                         int **special, const bool eflag, const bool vflag,
                         const bool eatom, const bool vatom, int &host_start,
                         const double cpu_time, bool &success);
 void ljl_gpu_compute(const int timestep, const int ago, const int inum,
 	 	     const int nall, double **host_x, int *host_type,
                      int *ilist, int *numj, int **firstneigh,
 		     const bool eflag, const bool vflag, const bool eatom,
                      const bool vatom, int &host_start, const double cpu_time,
                      bool &success);
 double ljl_gpu_bytes();
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 PairLJCutGPU::PairLJCutGPU(LAMMPS *lmp) : PairLJCut(lmp), gpu_mode(GPU_PAIR)
 {
   respa_enable = 0;
   cpu_time = 0.0;
 }
 
 /* ----------------------------------------------------------------------
    free all arrays
 ------------------------------------------------------------------------- */
 
 PairLJCutGPU::~PairLJCutGPU()
 {
   ljl_gpu_clear();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJCutGPU::compute(int eflag, int vflag)
 {
+  if (update->ntimestep > MAXSMALLINT)
+    error->all("Timestep too big for GPU pair style");
+  int ntimestep = update->ntimestep;
+
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = vflag_fdotr = 0;
   
   int nall = atom->nlocal + atom->nghost;
   int inum, host_start;
   
   bool success = true;
   
   if (gpu_mode == GPU_NEIGH) {
     inum = atom->nlocal;
-    gpulist = ljl_gpu_compute_n(update->ntimestep, neighbor->ago, inum, nall,
+    gpulist = ljl_gpu_compute_n(ntimestep, neighbor->ago, inum, nall,
 			        atom->x, atom->type, domain->sublo,
 				domain->subhi, atom->tag, atom->nspecial,
                                 atom->special, eflag, vflag, eflag_atom,
                                 vflag_atom, host_start, cpu_time, success);
   } else {
     inum = list->inum;
-    ljl_gpu_compute(update->ntimestep, neighbor->ago, inum, nall, atom->x,
+    ljl_gpu_compute(ntimestep, neighbor->ago, inum, nall, atom->x,
 		    atom->type, list->ilist, list->numneigh, list->firstneigh,
 		    eflag, vflag, eflag_atom, vflag_atom, host_start, cpu_time,
                     success);
   }
   if (!success)
     error->one("Out of memory on GPGPU");
 
   if (host_start<inum) {
     cpu_time = MPI_Wtime();
     if (gpu_mode == GPU_NEIGH)
       cpu_compute(gpulist, host_start, eflag, vflag);
     else
       cpu_compute(host_start, eflag, vflag);
     cpu_time = MPI_Wtime() - cpu_time;
   }
 }
 
 /* ----------------------------------------------------------------------
    init specific to this pair style
 ------------------------------------------------------------------------- */
 
 void PairLJCutGPU::init_style()
 {
   cut_respa = NULL;
 
   if (force->pair_match("gpu",0) == NULL)
     error->all("Cannot use pair hybrid with multiple GPU pair styles");
 
   // Repeat cutsq calculation because done after call to init_style
   double maxcut = -1.0;
   double cut;
   for (int i = 1; i <= atom->ntypes; i++) {
     for (int j = i; j <= atom->ntypes; j++) {
       if (setflag[i][j] != 0 || (setflag[i][i] != 0 && setflag[j][j] != 0)) {
         cut = init_one(i,j);
         cut *= cut;
         if (cut > maxcut)
           maxcut = cut;
         cutsq[i][j] = cutsq[j][i] = cut;
       } else
         cutsq[i][j] = cutsq[j][i] = 0.0;
     }
   }
   double cell_size = sqrt(maxcut) + neighbor->skin;
 
   int maxspecial=0;
   if (atom->molecular)
     maxspecial=atom->maxspecial;
   bool init_ok = ljl_gpu_init(atom->ntypes+1, cutsq, lj1, lj2, lj3, lj4,
                               offset, force->special_lj, atom->nlocal,
                               atom->nlocal+atom->nghost, 300, maxspecial,
                               cell_size, gpu_mode, screen);
   if (!init_ok)
     error->one("Insufficient memory on accelerator (or no fix gpu).\n"); 
 
   if (force->newton_pair) 
     error->all("Cannot use newton pair with GPU LJ pair style");
 
   if (gpu_mode != GPU_NEIGH) {
     int irequest = neighbor->request(this);
     neighbor->requests[irequest]->half = 0;
     neighbor->requests[irequest]->full = 1;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double PairLJCutGPU::memory_usage()
 {
   double bytes = Pair::memory_usage();
   return bytes + ljl_gpu_bytes();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJCutGPU::cpu_compute(int start, int eflag, int vflag) {
   int i,j,ii,jj,inum,jnum,itype,jtype;
   double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
   double rsq,r2inv,r6inv,forcelj,factor_lj;
   int *ilist,*jlist,*numneigh,**firstneigh;
 
   double **x = atom->x;
   double **f = atom->f;
   int *type = atom->type;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   double *special_lj = force->special_lj;
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
 
   // loop over neighbors of my atoms
 
   for (ii = start; ii < inum; ii++) {
     i = ilist[ii];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
 
       if (j < nall) factor_lj = 1.0;
       else {
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       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];
 
       if (rsq < cutsq[itype][jtype]) {
 	r2inv = 1.0/rsq;
 	r6inv = r2inv*r2inv*r2inv;
 	forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
 	fpair = factor_lj*forcelj*r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
 	if (eflag) {
 	  evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
 	    offset[itype][jtype];
 	  evdwl *= factor_lj;
 	}
 
 	if (evflag) ev_tally_full(i,evdwl,0.0,fpair,delx,dely,delz);
       }
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairLJCutGPU::cpu_compute(int *nbors, int start, int eflag, int vflag) {
   int i,j,itype,jtype;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   int stride = nlocal-start;
   double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
   double rsq,r2inv,r6inv,forcelj,factor_lj;
   double *special_lj = force->special_lj;
 
   double **x = atom->x;
   double **f = atom->f;
   int *type = atom->type;
 
   // loop over neighbors of my atoms
 
   for (i = start; i < nlocal; i++) {
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     int *nbor = nbors + i - start;
     int jnum = *nbor;
     nbor += stride;
     int *nbor_end = nbor + stride * jnum;
 
     for (; nbor<nbor_end; nbor+=stride) {
       j = *nbor;
       
       if (j < nall) factor_lj = 1.0;
       else {
 	factor_lj = special_lj[j/nall];
 	j %= nall;
       }
 
       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];
 
       if (rsq < cutsq[itype][jtype]) {
 	r2inv = 1.0/rsq;
 	r6inv = r2inv*r2inv*r2inv;
 	forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
 	fpair = factor_lj*forcelj*r2inv;
 
 	f[i][0] += delx*fpair;
 	f[i][1] += dely*fpair;
 	f[i][2] += delz*fpair;
 
 	if (eflag) {
 	  evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
 	    offset[itype][jtype];
 	  evdwl *= factor_lj;
 	}
 
         if (j<start) {
   	  if (evflag) ev_tally_full(i,evdwl,0.0,fpair,delx,dely,delz);
         } else {
           if (j<nlocal) {
 	    f[j][0] -= delx*fpair;
 	    f[j][1] -= dely*fpair;
 	    f[j][2] -= delz*fpair;
   	  }
 	  if (evflag) ev_tally(i,j,nlocal,0,
 			       evdwl,0.0,fpair,delx,dely,delz);
 	}
       }
     }
   }
 }
 
diff --git a/src/GRANULAR/atom_vec_granular.cpp b/src/GRANULAR/atom_vec_granular.cpp
index 0a37ae8e9..0ebb38d8f 100644
--- a/src/GRANULAR/atom_vec_granular.cpp
+++ b/src/GRANULAR/atom_vec_granular.cpp
@@ -1,957 +1,960 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "atom_vec_granular.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "modify.h"
 #include "force.h"
 #include "fix.h"
 #include "fix_adapt.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecGranular::AtomVecGranular(LAMMPS *lmp, int narg, char **arg) :
   AtomVec(lmp, narg, arg)
 {
   molecular = 0;
 
   comm_x_only = 1;
   comm_f_only = 0;
   size_forward = 3;
   size_reverse = 6;
   size_border = 8;
   size_velocity = 6;
   size_data_atom = 7;
   size_data_vel = 7;
   xcol_data = 5;
 
   atom->radius_flag = atom->density_flag = atom->rmass_flag = 1;
   atom->omega_flag = atom->torque_flag = 1;
 
   radvary = 0;
 
   PI = 4.0*atan(1.0);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecGranular::init()
 {
   // set radvary if particle diameters are time-varying due to fix adapt
 
   for (int i = 0; i < modify->nfix; i++)
     if (strcmp(modify->fix[i]->style,"adapt") == 0) {
       FixAdapt *fix = (FixAdapt *) modify->fix[i];
       if (fix->diamflag) {
         radvary = 1;
         size_forward = 5;
       }
     }
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n
 ------------------------------------------------------------------------- */
 
 void AtomVecGranular::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
 
   tag = atom->tag = (int *)
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *)
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *)
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
 
   radius = atom->radius = (double *)
     memory->srealloc(atom->radius,nmax*sizeof(double),"atom:radius");
   density = atom->density = (double *)
     memory->srealloc(atom->density,nmax*sizeof(double),"atom:density");
   rmass = atom->rmass = (double *)
     memory->srealloc(atom->rmass,nmax*sizeof(double),"atom:rmass");
 
   omega = atom->omega =
     memory->grow_2d_double_array(atom->omega,nmax,3,"atom:omega");
   torque = atom->torque =
     memory->grow_2d_double_array(atom->torque,nmax,3,"atom:torque");
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecGranular::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
   radius = atom->radius; density = atom->density; rmass = atom->rmass;
   omega = atom->omega; torque = atom->torque;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecGranular::copy(int i, int j)
 {
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
 
   radius[j] = radius[i];
   density[j] = density[i];
   rmass[j] = rmass[i];
   omega[j][0] = omega[i][0];
   omega[j][1] = omega[i][1];
   omega[j][2] = omega[i][2];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::pack_comm(int n, int *list, double *buf,
 			       int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   if (radvary == 0) {
     m = 0;
     if (pbc_flag == 0) {
       for (i = 0; i < n; i++) {
 	j = list[i];
 	buf[m++] = x[j][0];
 	buf[m++] = x[j][1];
 	buf[m++] = x[j][2];
       }
     } else {
       if (domain->triclinic == 0) {
 	dx = pbc[0]*domain->xprd;
 	dy = pbc[1]*domain->yprd;
 	dz = pbc[2]*domain->zprd;
       } else {
 	dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
 	dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
 	dz = pbc[2]*domain->zprd;
       }
       for (i = 0; i < n; i++) {
 	j = list[i];
 	buf[m++] = x[j][0] + dx;
 	buf[m++] = x[j][1] + dy;
 	buf[m++] = x[j][2] + dz;
       }
     }
 
   } else {
     m = 0;
     if (pbc_flag == 0) {
       for (i = 0; i < n; i++) {
 	j = list[i];
 	buf[m++] = x[j][0];
 	buf[m++] = x[j][1];
 	buf[m++] = x[j][2];
 	buf[m++] = radius[j];
 	buf[m++] = rmass[j];
       }
     } else {
       if (domain->triclinic == 0) {
 	dx = pbc[0]*domain->xprd;
 	dy = pbc[1]*domain->yprd;
 	dz = pbc[2]*domain->zprd;
       } else {
 	dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
 	dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
 	dz = pbc[2]*domain->zprd;
       }
       for (i = 0; i < n; i++) {
 	j = list[i];
 	buf[m++] = x[j][0] + dx;
 	buf[m++] = x[j][1] + dy;
 	buf[m++] = x[j][2] + dz;
 	buf[m++] = radius[j];
 	buf[m++] = rmass[j];
       }
     }
   }
 
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::pack_comm_vel(int n, int *list, double *buf,
 				   int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   if (radvary == 0) {
     m = 0;
     if (pbc_flag == 0) {
       for (i = 0; i < n; i++) {
 	j = list[i];
 	buf[m++] = x[j][0];
 	buf[m++] = x[j][1];
 	buf[m++] = x[j][2];
 	buf[m++] = v[j][0];
 	buf[m++] = v[j][1];
 	buf[m++] = v[j][2];
 	buf[m++] = omega[j][0];
 	buf[m++] = omega[j][1];
 	buf[m++] = omega[j][2];
       }
     } else {
       if (domain->triclinic == 0) {
 	dx = pbc[0]*domain->xprd;
 	dy = pbc[1]*domain->yprd;
 	dz = pbc[2]*domain->zprd;
       } else {
 	dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
 	dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
 	dz = pbc[2]*domain->zprd;
       }
       for (i = 0; i < n; i++) {
 	j = list[i];
 	buf[m++] = x[j][0] + dx;
 	buf[m++] = x[j][1] + dy;
 	buf[m++] = x[j][2] + dz;
 	buf[m++] = v[j][0];
 	buf[m++] = v[j][1];
 	buf[m++] = v[j][2];
 	buf[m++] = omega[j][0];
 	buf[m++] = omega[j][1];
 	buf[m++] = omega[j][2];
       }
     }
 
   } else {
     m = 0;
     if (pbc_flag == 0) {
       for (i = 0; i < n; i++) {
 	j = list[i];
 	buf[m++] = x[j][0];
 	buf[m++] = x[j][1];
 	buf[m++] = x[j][2];
 	buf[m++] = radius[j];
 	buf[m++] = rmass[j];
 	buf[m++] = v[j][0];
 	buf[m++] = v[j][1];
 	buf[m++] = v[j][2];
 	buf[m++] = omega[j][0];
 	buf[m++] = omega[j][1];
 	buf[m++] = omega[j][2];
       }
     } else {
       if (domain->triclinic == 0) {
 	dx = pbc[0]*domain->xprd;
 	dy = pbc[1]*domain->yprd;
 	dz = pbc[2]*domain->zprd;
       } else {
 	dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
 	dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
 	dz = pbc[2]*domain->zprd;
       }
       for (i = 0; i < n; i++) {
 	j = list[i];
 	buf[m++] = x[j][0] + dx;
 	buf[m++] = x[j][1] + dy;
 	buf[m++] = x[j][2] + dz;
 	buf[m++] = radius[j];
 	buf[m++] = rmass[j];
 	buf[m++] = v[j][0];
 	buf[m++] = v[j][1];
 	buf[m++] = v[j][2];
 	buf[m++] = omega[j][0];
 	buf[m++] = omega[j][1];
 	buf[m++] = omega[j][2];
       }
     }
   }
 
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::pack_comm_one(int i, double *buf)
 {
   if (radvary == 0) return 0;
 
   buf[0] = radius[i];
   buf[1] = rmass[i];
   return 2;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecGranular::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   if (radvary == 0) {
     m = 0;
     last = first + n;
     for (i = first; i < last; i++) {
       x[i][0] = buf[m++];
       x[i][1] = buf[m++];
       x[i][2] = buf[m++];
     }
   } else {
     m = 0;
     last = first + n;
     for (i = first; i < last; i++) {
       x[i][0] = buf[m++];
       x[i][1] = buf[m++];
       x[i][2] = buf[m++];
       radius[i] = buf[m++];
       rmass[i] = buf[m++];
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecGranular::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   if (radvary == 0) {
     m = 0;
     last = first + n;
     for (i = first; i < last; i++) {
       x[i][0] = buf[m++];
       x[i][1] = buf[m++];
       x[i][2] = buf[m++];
       v[i][0] = buf[m++];
       v[i][1] = buf[m++];
       v[i][2] = buf[m++];
       omega[i][0] = buf[m++];
       omega[i][1] = buf[m++];
       omega[i][2] = buf[m++];
     }
   } else {
     m = 0;
     last = first + n;
     for (i = first; i < last; i++) {
       x[i][0] = buf[m++];
       x[i][1] = buf[m++];
       x[i][2] = buf[m++];
       radius[i] = buf[m++];
       rmass[i] = buf[m++];
       v[i][0] = buf[m++];
       v[i][1] = buf[m++];
       v[i][2] = buf[m++];
       omega[i][0] = buf[m++];
       omega[i][1] = buf[m++];
       omega[i][2] = buf[m++];
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::unpack_comm_one(int i, double *buf)
 {
   if (radvary == 0) return 0;
 
   radius[i] = buf[0];
   rmass[i] = buf[1];
   return 2;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
     buf[m++] = torque[i][0];
     buf[m++] = torque[i][1];
     buf[m++] = torque[i][2];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::pack_reverse_one(int i, double *buf)
 {
   buf[0] = torque[i][0];
   buf[1] = torque[i][1];
   buf[2] = torque[i][2];
   return 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecGranular::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
     torque[j][0] += buf[m++];
     torque[j][1] += buf[m++];
     torque[j][2] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::unpack_reverse_one(int i, double *buf)
 {
   torque[i][0] += buf[0];
   torque[i][1] += buf[1];
   torque[i][2] += buf[2];
   return 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::pack_border(int n, int *list, double *buf,
 				 int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = radius[j];
       buf[m++] = rmass[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = radius[j];
       buf[m++] = rmass[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::pack_border_vel(int n, int *list, double *buf,
 				     int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = radius[j];
       buf[m++] = rmass[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = omega[j][0];
       buf[m++] = omega[j][1];
       buf[m++] = omega[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = radius[j];
       buf[m++] = rmass[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = omega[j][0];
       buf[m++] = omega[j][1];
       buf[m++] = omega[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::pack_border_one(int i, double *buf)
 {
   buf[0] = radius[i];
   buf[1] = rmass[i];
   return 2;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecGranular::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     radius[i] = buf[m++];
     rmass[i] = buf[m++];
   }
 }
 
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecGranular::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     radius[i] = buf[m++];
     rmass[i] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
     omega[i][0] = buf[m++];
     omega[i][1] = buf[m++];
     omega[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::unpack_border_one(int i, double *buf)
 {
   radius[i] = buf[0];
   rmass[i] = buf[1];
   return 2;
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    xyz must be 1st 3 values, so comm::exchange() can test on them 
 ------------------------------------------------------------------------- */
 
 int AtomVecGranular::pack_exchange(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
 
   buf[m++] = radius[i];
   buf[m++] = density[i];
   buf[m++] = rmass[i];
   buf[m++] = omega[i][0];
   buf[m++] = omega[i][1];
   buf[m++] = omega[i][2];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecGranular::unpack_exchange(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
 
   radius[nlocal] = buf[m++];
   density[nlocal] = buf[m++];
   rmass[nlocal] = buf[m++];
   omega[nlocal][0] = buf[m++];
   omega[nlocal][1] = buf[m++];
   omega[nlocal][2] = buf[m++];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecGranular::size_restart()
 {
   int i;
 
   int nlocal = atom->nlocal;
   int n = 16 * nlocal;
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       for (i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive   
 ------------------------------------------------------------------------- */
 
 int AtomVecGranular::pack_restart(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
 
   buf[m++] = radius[i];
   buf[m++] = density[i];
   buf[m++] = omega[i][0];
   buf[m++] = omega[i][1];
   buf[m++] = omega[i][2];
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
 
 int AtomVecGranular::unpack_restart(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store)
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
 
   radius[nlocal] = buf[m++];
   density[nlocal] = buf[m++];
 
   if (radius[nlocal] == 0.0) rmass[nlocal] = density[nlocal];
   else 
     rmass[nlocal] = 4.0*PI/3.0 * 
       radius[nlocal]*radius[nlocal]*radius[nlocal] * density[nlocal];
 
   omega[nlocal][0] = buf[m++];
   omega[nlocal][1] = buf[m++];
   omega[nlocal][2] = buf[m++];
 
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
 
 void AtomVecGranular::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   radius[nlocal] = 0.5;
   density[nlocal] = 1.0;
   rmass[nlocal] = 4.0*PI/3.0 *
     radius[nlocal]*radius[nlocal]*radius[nlocal] * density[nlocal];
   omega[nlocal][0] = 0.0;
   omega[nlocal][1] = 0.0;
   omega[nlocal][2] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
 void AtomVecGranular::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
 
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   radius[nlocal] = 0.5 * atof(values[2]);
   if (radius[nlocal] < 0.0)
     error->one("Invalid radius in Atoms section of data file");
 
   density[nlocal] = atof(values[3]);
   if (density[nlocal] <= 0.0)
     error->one("Invalid density in Atoms section of data file");
 
   if (radius[nlocal] == 0.0) rmass[nlocal] = density[nlocal];
   else 
     rmass[nlocal] = 4.0*PI/3.0 *
       radius[nlocal]*radius[nlocal]*radius[nlocal] * density[nlocal];
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   image[nlocal] = imagetmp;
 
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   omega[nlocal][0] = 0.0;
   omega[nlocal][1] = 0.0;
   omega[nlocal][2] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Atoms section of data file
    initialize other atom quantities for this sub-style
 ------------------------------------------------------------------------- */
 
 int AtomVecGranular::data_atom_hybrid(int nlocal, char **values)
 {
   radius[nlocal] = 0.5 * atof(values[0]);
   if (radius[nlocal] < 0.0)
     error->one("Invalid radius in Atoms section of data file");
 
   density[nlocal] = atof(values[1]);
   if (density[nlocal] <= 0.0)
     error->one("Invalid density in Atoms section of data file");
 
   if (radius[nlocal] == 0.0) rmass[nlocal] = density[nlocal];
   else 
     rmass[nlocal] = 4.0*PI/3.0 *
       radius[nlocal]*radius[nlocal]*radius[nlocal] * density[nlocal];
 
   return 2;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Velocities section of data file
 ------------------------------------------------------------------------- */
 
 void AtomVecGranular::data_vel(int m, char **values)
 {
   v[m][0] = atof(values[0]);
   v[m][1] = atof(values[1]);
   v[m][2] = atof(values[2]);
   omega[m][0] = atof(values[3]);
   omega[m][1] = atof(values[4]);
   omega[m][2] = atof(values[5]);
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Velocities section of data file
 ------------------------------------------------------------------------- */
 
 int AtomVecGranular::data_vel_hybrid(int m, char **values)
 {
   omega[m][0] = atof(values[0]);
   omega[m][1] = atof(values[1]);
   omega[m][2] = atof(values[2]);
   return 3;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
 
 double AtomVecGranular::memory_usage()
 {
   double bytes = 0.0;
 
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
 
   if (atom->memcheck("radius")) bytes += nmax * sizeof(double);
   if (atom->memcheck("density")) bytes += nmax * sizeof(double);
   if (atom->memcheck("rmass")) bytes += nmax * sizeof(double);
   if (atom->memcheck("omega")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("torque")) bytes += nmax*3 * sizeof(double);
 
   return bytes;
 }
diff --git a/src/GRANULAR/fix_pour.cpp b/src/GRANULAR/fix_pour.cpp
index 8b00fde01..0f54bbf79 100644
--- a/src/GRANULAR/fix_pour.cpp
+++ b/src/GRANULAR/fix_pour.cpp
@@ -1,577 +1,579 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "fix_pour.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "force.h"
 #include "update.h"
 #include "comm.h"
 #include "modify.h"
 #include "fix_gravity.h"
 #include "domain.h"
 #include "region.h"
 #include "region_block.h"
 #include "region_cylinder.h"
 #include "random_park.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define EPSILON 0.001
 
 /* ---------------------------------------------------------------------- */
 
 FixPour::FixPour(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 6) error->all("Illegal fix pour command");
 
   time_depend = 1;
 
   if (!atom->radius_flag || !atom->rmass_flag)
     error->all("Fix pour requires atom attributes radius, rmass");
 
   // required args
 
   ninsert = atoi(arg[3]);
   ntype = atoi(arg[4]);
   seed = atoi(arg[5]);
 
   if (seed <= 0) error->all("Illegal fix pour command");
 
   PI = 4.0*atan(1.0);
 
   // option defaults
 
   int iregion = -1;
   radius_lo = radius_hi = 0.5;
   density_lo = density_hi = 1.0;
   volfrac = 0.25;
   maxattempt = 50;
   rate = 0.0;
   vxlo = vxhi = vylo = vyhi = vy = vz = 0.0;
 
   // optional args
 
   int iarg = 6;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"region") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix pour command");
       iregion = domain->find_region(arg[iarg+1]);
       if (iregion == -1) error->all("Fix pour region ID does not exist");
       iarg += 2;
     } else if (strcmp(arg[iarg],"diam") == 0) {
       if (iarg+3 > narg) error->all("Illegal fix pour command");
       radius_lo = 0.5 * atof(arg[iarg+1]);
       radius_hi = 0.5 * atof(arg[iarg+2]);
       iarg += 3;
     } else if (strcmp(arg[iarg],"dens") == 0) {
       if (iarg+3 > narg) error->all("Illegal fix pour command");
       density_lo = atof(arg[iarg+1]);
       density_hi = atof(arg[iarg+2]);
       iarg += 3;
     } else if (strcmp(arg[iarg],"vol") == 0) {
       if (iarg+3 > narg) error->all("Illegal fix pour command");
       volfrac = atof(arg[iarg+1]);
       maxattempt = atoi(arg[iarg+2]);
       iarg += 3;
     } else if (strcmp(arg[iarg],"rate") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix pour command");
       rate = atof(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"vel") == 0) {
       if (domain->dimension == 3) {
 	if (iarg+6 > narg) error->all("Illegal fix pour command");
 	vxlo = atof(arg[iarg+1]);
 	vxhi = atof(arg[iarg+2]);
 	vylo = atof(arg[iarg+3]);
 	vyhi = atof(arg[iarg+4]);
 	vz = atof(arg[iarg+5]);
 	iarg += 6;
       } else {
 	if (iarg+4 > narg) error->all("Illegal fix pour command");
 	vxlo = atof(arg[iarg+1]);
 	vxhi = atof(arg[iarg+2]);
 	vy = atof(arg[iarg+3]);
 	vz = 0.0;
 	iarg += 4;
       }
     } else error->all("Illegal fix pour command");
   }
 
   // error checks on region and its extent being inside simulation box
 
   if (iregion == -1) error->all("Must specify a region in fix pour");
   if (domain->regions[iregion]->bboxflag == 0)
     error->all("Fix pour region does not support a bounding box");
   if (domain->regions[iregion]->dynamic_check())
     error->all("Fix pour region cannot be dynamic");
 
   if (strcmp(domain->regions[iregion]->style,"block") == 0) {
     region_style = 1;
     xlo = ((RegBlock *) domain->regions[iregion])->xlo;
     xhi = ((RegBlock *) domain->regions[iregion])->xhi;
     ylo = ((RegBlock *) domain->regions[iregion])->ylo;
     yhi = ((RegBlock *) domain->regions[iregion])->yhi;
     zlo = ((RegBlock *) domain->regions[iregion])->zlo;
     zhi = ((RegBlock *) domain->regions[iregion])->zhi;
     if (xlo < domain->boxlo[0] || xhi > domain->boxhi[0] || 
 	ylo < domain->boxlo[1] || yhi > domain->boxhi[1] || 
 	zlo < domain->boxlo[2] || zhi > domain->boxhi[2])
       error->all("Insertion region extends outside simulation box");
   } else if (strcmp(domain->regions[iregion]->style,"cylinder") == 0) {
     region_style = 2;
     char axis = ((RegCylinder *) domain->regions[iregion])->axis;
     xc = ((RegCylinder *) domain->regions[iregion])->c1;
     yc = ((RegCylinder *) domain->regions[iregion])->c2;
     rc = ((RegCylinder *) domain->regions[iregion])->radius;
     zlo = ((RegCylinder *) domain->regions[iregion])->lo;
     zhi = ((RegCylinder *) domain->regions[iregion])->hi;
     if (axis != 'z')
       error->all("Must use a z-axis cylinder with fix pour");
     if (xc-rc < domain->boxlo[0] || xc+rc > domain->boxhi[0] || 
 	yc-rc < domain->boxlo[1] || yc+rc > domain->boxhi[1] || 
 	zlo < domain->boxlo[2] || zhi > domain->boxhi[2])
       error->all("Insertion region extends outside simulation box");
   } else error->all("Must use a block or cylinder region with fix pour");
 
   if (region_style == 2 && domain->dimension == 2)
     error->all("Must use a block region with fix pour for 2d simulations");
 
   // random number generator, same for all procs
 
   random = new RanPark(lmp,seed);
 
   // allgather arrays
 
   MPI_Comm_rank(world,&me);
   MPI_Comm_size(world,&nprocs);
   recvcounts = new int[nprocs];
   displs = new int[nprocs];
 
   // grav = gravity in distance/time^2 units
   // assume grav = -magnitude at this point, enforce in init()
 
   int ifix;
   for (ifix = 0; ifix < modify->nfix; ifix++)
     if (strcmp(modify->fix[ifix]->style,"gravity") == 0) break;
   if (ifix == modify->nfix) 
     error->all("No fix gravity defined for fix pour");
   grav = - ((FixGravity *) modify->fix[ifix])->magnitude * force->ftm2v;
 
   // nfreq = timesteps between insertions
   // should be time for a particle to fall from top of insertion region
   //   to bottom, taking into account that the region may be moving
   // set these 2 eqs equal to each other, solve for smallest positive t
   //   x = zhi + vz*t + 1/2 grav t^2
   //   x = zlo + rate*t
   //   gives t = [-(vz-rate) - sqrt((vz-rate)^2 - 2*grav*(zhi-zlo))] / grav
   //   where zhi-zlo > 0, grav < 0, and vz & rate can be either > 0 or < 0
 
   double v_relative,delta;
   if (domain->dimension == 3) {
     v_relative = vz - rate;
     delta = zhi - zlo;
   } else {
     v_relative = vy - rate;
     delta = yhi - ylo;
   }
   double t = 
     (-v_relative - sqrt(v_relative*v_relative - 2.0*grav*delta)) / grav;
   nfreq = static_cast<int> (t/update->dt + 0.5);
 
   // 1st insertion on next timestep
 
   force_reneighbor = 1;
   next_reneighbor = update->ntimestep + 1;
   nfirst = next_reneighbor;
   ninserted = 0;
 
   // nper = # to insert each time
   // depends on specified volume fraction
   // volume = volume of insertion region
   // volume_one = volume of inserted particle (with max possible radius)
   // in 3d, insure dy >= 1, for quasi-2d simulations
 
   double volume,volume_one;
   if (domain->dimension == 3) {
     if (region_style == 1) {
       double dy = yhi - ylo;
       if (dy < 1.0) dy = 1.0;
       volume = (xhi-xlo) * dy * (zhi-zlo);
     } else volume = PI*rc*rc * (zhi-zlo);
     volume_one = 4.0/3.0 * PI * radius_hi*radius_hi*radius_hi;
   } else {
     volume = (xhi-xlo) * (yhi-ylo);
     volume_one = PI * radius_hi*radius_hi;
   }
 
   nper = static_cast<int> (volfrac*volume/volume_one);
   int nfinal = update->ntimestep + 1 + (ninsert-1)/nper * nfreq;
 
   // print stats
 
   if (me == 0) {
     if (screen)
       fprintf(screen,
 	      "Particle insertion: %d every %d steps, %d by step %d\n",
 	      nper,nfreq,ninsert,nfinal);
     if (logfile)
       fprintf(logfile,
 	      "Particle insertion: %d every %d steps, %d by step %d\n",
 	      nper,nfreq,ninsert,nfinal);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixPour::~FixPour()
 {
   delete random;
   delete [] recvcounts;
   delete [] displs;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixPour::setmask()
 {
   int mask = 0;
   mask |= PRE_EXCHANGE;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixPour::init()
 {
   if (domain->triclinic) error->all("Cannot use fix pour with triclinic box");
 
   // insure gravity fix exists
   // for 3d must point in -z, for 2d must point in -y
   // else insertion cannot work
 
   int ifix;
   for (ifix = 0; ifix < modify->nfix; ifix++)
     if (strcmp(modify->fix[ifix]->style,"gravity") == 0) break;
   if (ifix == modify->nfix) 
     error->all("No fix gravity defined for fix pour");
 
   double xgrav = ((FixGravity *) modify->fix[ifix])->xgrav;
   double ygrav = ((FixGravity *) modify->fix[ifix])->ygrav;
   double zgrav = ((FixGravity *) modify->fix[ifix])->zgrav;
 
   if (domain->dimension == 3) {
     if (fabs(xgrav) > EPSILON || fabs(ygrav) > EPSILON ||
 	fabs(zgrav+1.0) > EPSILON)
       error->all("Gravity must point in -z to use with fix pour in 3d");
   } else {
     if (fabs(xgrav) > EPSILON || fabs(ygrav+1.0) > EPSILON ||
 	fabs(zgrav) > EPSILON)
       error->all("Gravity must point in -y to use with fix pour in 2d");
   }
 
   double gnew = - ((FixGravity *) modify->fix[ifix])->magnitude * force->ftm2v;
   if (gnew != grav)
     error->all("Gravity changed since fix pour was created");
 }
 
 /* ----------------------------------------------------------------------
    perform particle insertion
 ------------------------------------------------------------------------- */
 
 void FixPour::pre_exchange()
 {
   int i;
 
   // just return if should not be called on this timestep
 
   if (next_reneighbor != update->ntimestep) return;
 
   // nnew = # to insert this timestep
 
   int nnew = nper;
   if (ninserted + nnew > ninsert) nnew = ninsert - ninserted;
 
   // lo/hi current = z (or y) bounds of insertion region this timestep
 
   if (domain->dimension == 3) {
     lo_current = zlo + (update->ntimestep - nfirst) * update->dt * rate;
     hi_current = zhi + (update->ntimestep - nfirst) * update->dt * rate;
   } else {
     lo_current = ylo + (update->ntimestep - nfirst) * update->dt * rate;
     hi_current = yhi + (update->ntimestep - nfirst) * update->dt * rate;
   }
 
   // ncount = # of my atoms that overlap the insertion region
   // nprevious = total of ncount across all procs
   
   int ncount = 0;
   for (i = 0; i < atom->nlocal; i++)
     if (overlap(i)) ncount++;
 
   int nprevious;
   MPI_Allreduce(&ncount,&nprevious,1,MPI_INT,MPI_SUM,world);
 
   // xmine is for my atoms
   // xnear is for atoms from all procs + atoms to be inserted
 
   double **xmine = 
     memory->create_2d_double_array(ncount,4,"fix_pour:xmine");
   double **xnear = 
     memory->create_2d_double_array(nprevious+nnew,4,"fix_pour:xnear");
   int nnear = nprevious;
 
   // setup for allgatherv
 
   int n = 4*ncount;
   MPI_Allgather(&n,1,MPI_INT,recvcounts,1,MPI_INT,world);
 
   displs[0] = 0;
   for (int iproc = 1; iproc < nprocs; iproc++)
     displs[iproc] = displs[iproc-1] + recvcounts[iproc-1];
 
   // load up xmine array
   
   double **x = atom->x;
   double *radius = atom->radius;
 
   ncount = 0;
   for (i = 0; i < atom->nlocal; i++)
     if (overlap(i)) {
       xmine[ncount][0] = x[i][0];
       xmine[ncount][1] = x[i][1];
       xmine[ncount][2] = x[i][2];
       xmine[ncount][3] = radius[i];
       ncount++;
     }
 
   // perform allgatherv to acquire list of nearby particles on all procs
 
   double *ptr = NULL;
   if (ncount) ptr = xmine[0];
   MPI_Allgatherv(ptr,4*ncount,MPI_DOUBLE,
 		 xnear[0],recvcounts,displs,MPI_DOUBLE,world);
 
   // insert new atoms into xnear list, one by one
   // check against all nearby atoms and previously inserted ones
   // if there is an overlap then try again at same z (3d) or y (2d) coord
   // else insert by adding to xnear list
   // max = maximum # of insertion attempts for all particles
   // h = height, biased to give uniform distribution in time of insertion
 
   int success;
   double coord[3],radtmp,delx,dely,delz,rsq,radsum,rn,h;
 
   int attempt = 0;
   int max = nnew * maxattempt;
   int ntotal = nprevious+nnew;
 
   while (nnear < ntotal) {
     rn = random->uniform();
     h = hi_current - rn*rn * (hi_current-lo_current);
     radtmp = radius_lo + random->uniform() * (radius_hi-radius_lo);
     success = 0;
     while (attempt < max) {
       attempt++;
       xyz_random(h,coord);
       for (i = 0; i < nnear; i++) {
 	delx = coord[0] - xnear[i][0];
 	dely = coord[1] - xnear[i][1];
 	delz = coord[2] - xnear[i][2];
 	rsq = delx*delx + dely*dely + delz*delz;
 	radsum = radtmp + xnear[i][3];
 	if (rsq <= radsum*radsum) break;
       }
       if (i == nnear) {
 	success = 1;
 	break;
       }
     }
     if (success) {
       xnear[nnear][0] = coord[0];
       xnear[nnear][1] = coord[1];
       xnear[nnear][2] = coord[2];
       xnear[nnear][3] = radtmp;
       nnear++;
     } else break;
   }
 
   // warn if not all insertions were performed
 
   ninserted += nnear-nprevious;
   if (nnear - nprevious < nnew && me == 0)
     error->warning("Less insertions than requested",0);
 
   // check if new atom is in my sub-box or above it if I'm highest proc
   // if so, add to my list via create_atom()
   // initialize info about the atom
   // type, diameter, density set from fix parameters
   // group mask set to "all" plus fix group
   // z velocity set to what velocity would be if particle
   //   had fallen from top of insertion region
   //   this gives continuous stream of atoms
   //   solution for v from these 2 eqs, after eliminate t:
   //     v = vz + grav*t
   //     coord[2] = hi_current + vz*t + 1/2 grav t^2
   // set npartner for new atom to 0 (assume not touching any others)
 
   AtomVec *avec = atom->avec;
   int j,m,flag;
   double denstmp,vxtmp,vytmp,vztmp;
   double *sublo = domain->sublo;
   double *subhi = domain->subhi;
 
   int nfix = modify->nfix;
   Fix **fix = modify->fix;
 
   for (i = nprevious; i < nnear; i++) {
     coord[0] = xnear[i][0];
     coord[1] = xnear[i][1];
     coord[2] = xnear[i][2];
     radtmp = xnear[i][3];
     denstmp = density_lo + random->uniform() * (density_hi-density_lo);
     if (domain->dimension == 3) {
       vxtmp = vxlo + random->uniform() * (vxhi-vxlo);
       vytmp = vylo + random->uniform() * (vyhi-vylo);
       vztmp = -sqrt(vz*vz + 2.0*grav*(coord[2]-hi_current));
     } else {
       vxtmp = vxlo + random->uniform() * (vxhi-vxlo);
       vytmp = -sqrt(vy*vy + 2.0*grav*(coord[1]-hi_current));
       vztmp = 0.0;
     }
 
     flag = 0;
     if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
 	coord[1] >= sublo[1] && coord[1] < subhi[1] &&
 	coord[2] >= sublo[2] && coord[2] < subhi[2]) flag = 1;
     else if (domain->dimension == 3 && coord[2] >= domain->boxhi[2] &&
 	     comm->myloc[2] == comm->procgrid[2]-1 &&
 	     coord[0] >= sublo[0] && coord[0] < subhi[0] &&
 	     coord[1] >= sublo[1] && coord[1] < subhi[1]) flag = 1;
     else if (domain->dimension == 2 && coord[1] >= domain->boxhi[1] &&
 	     comm->myloc[1] == comm->procgrid[1]-1 &&
 	     coord[0] >= sublo[0] && coord[0] < subhi[0]) flag = 1;
 
     if (flag) {
       avec->create_atom(ntype,coord);
       m = atom->nlocal - 1;
       atom->type[m] = ntype;
       atom->radius[m] = radtmp;
       atom->density[m] = denstmp;
       atom->rmass[m] = 4.0*PI/3.0 * radtmp*radtmp*radtmp * denstmp;
       atom->mask[m] = 1 | groupbit;
       atom->v[m][0] = vxtmp;
       atom->v[m][1] = vytmp;
       atom->v[m][2] = vztmp;
       for (j = 0; j < nfix; j++)
 	if (fix[j]->create_attribute) fix[j]->set_arrays(m);
     }
   }
 
-  // set tag # of new particles beyond all previous atoms
   // reset global natoms
+  // set tag # of new particles beyond all previous atoms
   // if global map exists, reset it now instead of waiting for comm
   // since deleting atoms messes up ghosts
 
-  if (atom->tag_enable) {
-    atom->tag_extend();
+  if (nnear - nprevious > 0) {
     atom->natoms += nnear - nprevious;
-    if (atom->map_style) {
-      atom->nghost = 0;
-      atom->map_init();
-      atom->map_set();
+    if (atom->tag_enable) {
+      atom->tag_extend();
+      if (atom->map_style) {
+	atom->nghost = 0;
+	atom->map_init();
+	atom->map_set();
+      }
     }
   }
 
   // free local memory
 
   memory->destroy_2d_double_array(xmine);
   memory->destroy_2d_double_array(xnear);
 
   // next timestep to insert
 
   if (ninserted < ninsert) next_reneighbor += nfreq;
   else next_reneighbor = 0;
 }
 
 /* ----------------------------------------------------------------------
    check if particle i could overlap with a particle inserted into region
    return 1 if yes, 0 if no
    use maximum diameter for inserted particle
 ------------------------------------------------------------------------- */
 
 int FixPour::overlap(int i)
 {
   double delta = radius_hi + atom->radius[i];
   double **x = atom->x;
 
   if (domain->dimension == 3) {
     if (region_style == 1) {
       if (x[i][0] < xlo-delta || x[i][0] > xhi+delta ||
 	  x[i][1] < ylo-delta || x[i][1] > yhi+delta ||
 	  x[i][2] < lo_current-delta || x[i][2] > hi_current+delta) return 0;
     } else {
       if (x[i][2] < lo_current-delta || x[i][2] > hi_current+delta) return 0;
       double delx = x[i][0] - xc;
       double dely = x[i][1] - yc;
       double rsq = delx*delx + dely*dely;
       double r = rc + delta;
       if (rsq > r*r) return 0;
     }
   } else {
       if (x[i][0] < xlo-delta || x[i][0] > xhi+delta ||
 	  x[i][1] < lo_current-delta || x[i][1] > hi_current+delta) return 0;
   }
 
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixPour::xyz_random(double h, double *coord)
 {
   if (domain->dimension == 3) {
     if (region_style == 1) {
       coord[0] = xlo + random->uniform() * (xhi-xlo);
       coord[1] = ylo + random->uniform() * (yhi-ylo);
       coord[2] = h;
     } else {
       double r1,r2;
       while (1) {
 	r1 = random->uniform() - 0.5;
 	r2 = random->uniform() - 0.5;
 	if (r1*r1 + r2*r2 < 0.25) break;
       }
       coord[0] = xc + 2.0*r1*rc;
       coord[1] = yc + 2.0*r2*rc;
       coord[2] = h;
     }
   } else {
     coord[0] = xlo + random->uniform() * (xhi-xlo);
     coord[1] = h;
     coord[2] = 0.0;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixPour::reset_dt()
 {
   error->all("Cannot change timestep with fix pour");
 }
diff --git a/src/MANYBODY/fix_qeq_comb.cpp b/src/MANYBODY/fix_qeq_comb.cpp
index b8f13964f..7c91cd51c 100644
--- a/src/MANYBODY/fix_qeq_comb.cpp
+++ b/src/MANYBODY/fix_qeq_comb.cpp
@@ -1,253 +1,257 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Tzu-Ray Shan (U Florida, rayshan@ufl.edu)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "fix_qeq_comb.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "force.h"
 #include "group.h"
 #include "respa.h"
 #include "pair_comb.h"
 #include "update.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 /* ---------------------------------------------------------------------- */
 
 FixQEQComb::FixQEQComb(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
 {
   if (narg < 5) error->all("Illegal fix qeq/comb command");
 
   peratom_flag = 1;
   size_peratom_cols = 0;
   peratom_freq = 1;
 
   nevery = force->inumeric(arg[3]);
   precision = force->numeric(arg[4]);
 
   if (nevery <= 0 || precision <= 0.0)
     error->all("Illegal fix qeq/comb command");
 
   MPI_Comm_rank(world,&me);
 
   // optional args
 
   fp = NULL;
 
   int iarg = 5;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"file") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix qeq/comb command");
       if (me == 0) {
 	fp = fopen(arg[iarg+1],"w");
 	if (fp == NULL) {
 	  char str[128];
 	  sprintf(str,"Cannot open fix qeq/comb file %s",arg[iarg+1]);
 	  error->one(str);
 	}
       }
       iarg += 2;
     } else error->all("Illegal fix qeq/comb command");
   }
   
   nmax = atom->nmax;
   qf = (double *) memory->smalloc(nmax*sizeof(double),"qeq:qf");
   q1 = (double *) memory->smalloc(nmax*sizeof(double),"qeq:q1");
   q2 = (double *) memory->smalloc(nmax*sizeof(double),"qeq:q2");
   vector_atom = qf;
 
   // zero the vector since dump may access it on timestep 0
   // zero the vector since a variable may access it before first run
 
   int nlocal = atom->nlocal;
   for (int i = 0; i < nlocal; i++) qf[i] = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixQEQComb::~FixQEQComb()
 {
   if (me == 0 && fp) fclose(fp);
   memory->sfree(qf);
   memory->sfree(q1);
   memory->sfree(q2);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixQEQComb::setmask()
 {
   int mask = 0;
   mask |= POST_FORCE;
   mask |= POST_FORCE_RESPA;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixQEQComb::init()
 {
   if (!atom->q_flag)
     error->all("Fix qeq/comb requires atom attribute q");
 
   comb = (PairComb *) force->pair_match("comb",1);
   if (comb == NULL) error->all("Must use pair_style comb with fix qeq/comb");
 
   if (strcmp(update->integrate_style,"respa") == 0)
     nlevels_respa = ((Respa *) update->integrate)->nlevels;
 
   ngroup = group->count(igroup);
   if (ngroup == 0) error->all("Fix qeq/comb group has no atoms");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixQEQComb::setup(int vflag)
 {
   firstflag = 1;
   if (strcmp(update->integrate_style,"verlet") == 0)
     post_force(vflag);
   else {
     ((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1);
     post_force_respa(vflag,nlevels_respa-1,0);
     ((Respa *) update->integrate)->copy_f_flevel(nlevels_respa-1);
   }
   firstflag = 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixQEQComb::post_force(int vflag)
 {
   int i,iloop,loopmax;
   double heatpq,qmass,dtq,dtq2;
   double enegchkall,enegmaxall;
 
   if (update->ntimestep % nevery) return;
 
   // reallocate work arrays if necessary
   // qf = charge force
   // q1 = charge displacement
   // q2 = tmp storage of charge force for next iteration
 
   if (atom->nmax > nmax) {
     memory->sfree(qf);
     memory->sfree(q1);
     memory->sfree(q2);
     nmax = atom->nmax;
     qf = (double *) memory->smalloc(nmax*sizeof(double),"qeq:qf");
     q1 = (double *) memory->smalloc(nmax*sizeof(double),"qeq:q1");
     q2 = (double *) memory->smalloc(nmax*sizeof(double),"qeq:q2");
     vector_atom = qf;
   }
   
   // more loops for first-time charge equilibrium
 
   iloop = 0; 
   if (firstflag) loopmax = 1000;
   else loopmax = 500;
 
   // charge-equilibration loop
 
-  if (me == 0 && fp)
-    fprintf(fp,"Charge equilibration on step %d\n",update->ntimestep);
+  if (me == 0 && fp) {
+    char fstr[64];
+    sprintf(fstr,"Charge equilibration on step %s\n",BIGINT_FORMAT);
+    fprintf(fp,fstr,update->ntimestep);
+  }
   
   heatpq = 0.01;
   qmass = 0.06;
   dtq = 0.040;
   dtq2 = 0.5*dtq*dtq/qmass;
 
   double enegchk = 0.0;
   double enegtot = 0.0; 
   double enegmax = 0.0;
 
   double *q = atom->q;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (i = 0; i < nlocal; i++)
     q1[i] = q2[i] = qf[i] = 0.0;
 
   for (iloop = 0; iloop < loopmax; iloop ++ ) {
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	q1[i] = qf[i]*dtq2 - heatpq*q1[i];
 	q[i] += q1[i]; 
       }
 
     enegtot = comb->yasu_char(qf,igroup);
     enegtot /= ngroup;
     enegchk = enegmax = 0.0;
 
     for (i = 0; i < nlocal ; i++)
       if (mask[i] & groupbit) {
 	q2[i] = enegtot-qf[i];
 	enegmax = MAX(enegmax,fabs(q2[i]));
 	enegchk += fabs(q2[i]);
 	qf[i] = q2[i];
       }
 
     MPI_Allreduce(&enegchk,&enegchkall,1,MPI_DOUBLE,MPI_SUM,world);
     enegchk = enegchkall/ngroup;
     MPI_Allreduce(&enegmax,&enegmaxall,1,MPI_DOUBLE,MPI_MAX,world);
     enegmax = enegmaxall;
     
     if (enegchk <= precision && enegmax <= 10.0*precision) break;
 
     if (me == 0 && fp)
       fprintf(fp,"  iteration: %d, enegtot %.6g, "
 	      "enegmax %.6g, fq deviation: %.6g\n",
 	      iloop,enegtot,enegmax,enegchk); 
     
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit)
 	q1[i] += qf[i]*dtq2 - heatpq*q1[i]; 
   } 
 
   if (me == 0 && fp) {
     if (iloop == loopmax)
       fprintf(fp,"Charges did not converge in %d iterations\n",iloop);
     else
       fprintf(fp,"Charges converged in %d iterations to %.10f tolerance\n",
 	      iloop,enegchk);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixQEQComb::post_force_respa(int vflag, int ilevel, int iloop)
 {
   if (ilevel == nlevels_respa-1) post_force(vflag);
 }
 
 /* ----------------------------------------------------------------------
    memory usage of local atom-based arrays
 ------------------------------------------------------------------------- */
 
 double FixQEQComb::memory_usage()
 {
   double bytes = atom->nmax*3 * sizeof(double);
   return bytes;
 }
diff --git a/src/MOLECULE/atom_vec_angle.cpp b/src/MOLECULE/atom_vec_angle.cpp
index 6789db500..33390ee34 100644
--- a/src/MOLECULE/atom_vec_angle.cpp
+++ b/src/MOLECULE/atom_vec_angle.cpp
@@ -1,811 +1,814 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "atom_vec_angle.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecAngle::AtomVecAngle(LAMMPS *lmp, int narg, char **arg) :
   AtomVec(lmp, narg, arg)
 {
   molecular = 1;
   bonds_allow = angles_allow = 1;
   mass_type = 1;
 
   comm_x_only = comm_f_only = 1;
   size_forward = 3;
   size_reverse = 3;
   size_border = 7;
   size_velocity = 3;
   size_data_atom = 6;
   size_data_vel = 4;
   xcol_data = 4;
 
   atom->molecule_flag = 1;
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n 
 ------------------------------------------------------------------------- */
 
 void AtomVecAngle::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
 
   tag = atom->tag = (int *) 
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *) 
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *) 
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
 
   molecule = atom->molecule = (int *) 
     memory->srealloc(atom->molecule,nmax*sizeof(int),"atom:molecule");
 
   nspecial = atom->nspecial =
     memory->grow_2d_int_array(atom->nspecial,nmax,3,"atom:nspecial");
   special = atom->special =
     memory->grow_2d_int_array(atom->special,nmax,atom->maxspecial,
 			      "atom:special");
 
   num_bond = atom->num_bond = (int *) 
     memory->srealloc(atom->num_bond,nmax*sizeof(int),"atom:num_bond");
   bond_type = atom->bond_type = 
     memory->grow_2d_int_array(atom->bond_type,nmax,atom->bond_per_atom,
 			      "atom:bond_type");
   bond_atom = atom->bond_atom = 
     memory->grow_2d_int_array(atom->bond_atom,nmax,atom->bond_per_atom,
 			      "atom:bond_atom");
 
   num_angle = atom->num_angle = (int *) 
     memory->srealloc(atom->num_angle,nmax*sizeof(int),"atom:num_angle");
   angle_type = atom->angle_type = 
     memory->grow_2d_int_array(atom->angle_type,nmax,atom->angle_per_atom,
 			      "atom:angle_type");
   angle_atom1 = atom->angle_atom1 = 
     memory->grow_2d_int_array(atom->angle_atom1,nmax,atom->angle_per_atom,
 			      "atom:angle_atom1");
   angle_atom2 = atom->angle_atom2 = 
     memory->grow_2d_int_array(atom->angle_atom2,nmax,atom->angle_per_atom,
 			      "atom:angle_atom2");
   angle_atom3 = atom->angle_atom3 = 
     memory->grow_2d_int_array(atom->angle_atom3,nmax,atom->angle_per_atom,
 			      "atom:angle_atom3");
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecAngle::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
   molecule = atom->molecule;
   nspecial = atom->nspecial; special = atom->special;
   num_bond = atom->num_bond; bond_type = atom->bond_type;
   bond_atom = atom->bond_atom;
   num_angle = atom->num_angle; angle_type = atom->angle_type;
   angle_atom1 = atom->angle_atom1; angle_atom2 = atom->angle_atom2;
   angle_atom3 = atom->angle_atom3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAngle::copy(int i, int j)
 {
   int k;
 
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
 
   molecule[j] = molecule[i];
 
   num_bond[j] = num_bond[i];
   for (k = 0; k < num_bond[j]; k++) {
     bond_type[j][k] = bond_type[i][k];
     bond_atom[j][k] = bond_atom[i][k];
   }
 
   num_angle[j] = num_angle[i];
   for (k = 0; k < num_angle[j]; k++) {
     angle_type[j][k] = angle_type[i][k];
     angle_atom1[j][k] = angle_atom1[i][k];
     angle_atom2[j][k] = angle_atom2[i][k];
     angle_atom3[j][k] = angle_atom3[i][k];
   }
 
   nspecial[j][0] = nspecial[i][0];
   nspecial[j][1] = nspecial[i][1];
   nspecial[j][2] = nspecial[i][2];
   for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAngle::pack_comm(int n, int *list, double *buf,
 			    int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAngle::pack_comm_vel(int n, int *list, double *buf,
 				int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAngle::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAngle::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAngle::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAngle::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAngle::pack_border(int n, int *list, double *buf,
 			      int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAngle::pack_border_vel(int n, int *list, double *buf,
 				  int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAngle::pack_border_one(int i, double *buf)
 {
   buf[0] = molecule[i];
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAngle::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     molecule[i] = static_cast<int> (buf[m++]);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAngle::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     molecule[i] = static_cast<int> (buf[m++]);
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAngle::unpack_border_one(int i, double *buf)
 {
   molecule[i] = static_cast<int> (buf[0]);
   return 1;
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    xyz must be 1st 3 values, so comm::exchange() can test on them 
 ------------------------------------------------------------------------- */
 
 int AtomVecAngle::pack_exchange(int i, double *buf)
 {
   int k;
 
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
 
   buf[m++] = molecule[i];
 
   buf[m++] = num_bond[i];
   for (k = 0; k < num_bond[i]; k++) {
     buf[m++] = bond_type[i][k];
     buf[m++] = bond_atom[i][k];
   }
 
   buf[m++] = num_angle[i];
   for (k = 0; k < num_angle[i]; k++) {
     buf[m++] = angle_type[i][k];
     buf[m++] = angle_atom1[i][k];
     buf[m++] = angle_atom2[i][k];
     buf[m++] = angle_atom3[i][k];
   }
 
   buf[m++] = nspecial[i][0];
   buf[m++] = nspecial[i][1];
   buf[m++] = nspecial[i][2];
   for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAngle::unpack_exchange(double *buf)
 {
   int k;
 
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
 
   molecule[nlocal] = static_cast<int> (buf[m++]);
 
   num_bond[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = static_cast<int> (buf[m++]);
     bond_atom[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_angle[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_angle[nlocal]; k++) {
     angle_type[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom3[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   nspecial[nlocal][0] = static_cast<int> (buf[m++]);
   nspecial[nlocal][1] = static_cast<int> (buf[m++]);
   nspecial[nlocal][2] = static_cast<int> (buf[m++]);
   for (k = 0; k < nspecial[nlocal][2]; k++)
     special[nlocal][k] = static_cast<int> (buf[m++]);
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecAngle::size_restart()
 {
   int i;
 
   int nlocal = atom->nlocal;
   int n = 0;
   for (i = 0; i < nlocal; i++)
     n += 14 + 2*num_bond[i] + 4*num_angle[i];
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       for (i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive   
 ------------------------------------------------------------------------- */
 
 int AtomVecAngle::pack_restart(int i, double *buf)
 {
   int k;
 
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
 
   buf[m++] = molecule[i];
  
   buf[m++] = num_bond[i];
   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++] = num_angle[i];
   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];
   }
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
 
 int AtomVecAngle::unpack_restart(double *buf)
 {
   int k;
 
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store)
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
 
   molecule[nlocal] = static_cast<int> (buf[m++]);
     
   num_bond[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = static_cast<int> (buf[m++]);
     bond_atom[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_angle[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_angle[nlocal]; k++) {
     angle_type[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom3[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
 
 void AtomVecAngle::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   molecule[nlocal] = 0;
   num_bond[nlocal] = 0;
   num_angle[nlocal] = 0;
   nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
 void AtomVecAngle::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
 
   molecule[nlocal] = atoi(values[1]);
 
   type[nlocal] = atoi(values[2]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   image[nlocal] = imagetmp;
 
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   num_bond[nlocal] = 0;
   num_angle[nlocal] = 0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Atoms section of data file
    initialize other atom quantities for this sub-style
 ------------------------------------------------------------------------- */
 
 int AtomVecAngle::data_atom_hybrid(int nlocal, char **values)
 {
   molecule[nlocal] = atoi(values[0]);
 
   num_bond[nlocal] = 0;
   num_angle[nlocal] = 0;
 
   return 1;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
 
 double AtomVecAngle::memory_usage()
 {
   double bytes = 0.0;
 
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
 
   if (atom->memcheck("molecule")) bytes += nmax * sizeof(int);
   if (atom->memcheck("nspecial")) bytes += nmax*3 * sizeof(int);
   if (atom->memcheck("special")) bytes += nmax*atom->maxspecial * sizeof(int);
 
   if (atom->memcheck("num_bond")) bytes += nmax * sizeof(int);
   if (atom->memcheck("bond_type"))
     bytes += nmax*atom->bond_per_atom * sizeof(int);
   if (atom->memcheck("bond_atom"))
     bytes += nmax*atom->bond_per_atom * sizeof(int);
 
   if (atom->memcheck("num_angle")) bytes += nmax * sizeof(int);
   if (atom->memcheck("angle_type"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
   if (atom->memcheck("angle_atom1"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
   if (atom->memcheck("angle_atom2"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
   if (atom->memcheck("angle_atom3"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
 
   return bytes;
 }
diff --git a/src/MOLECULE/atom_vec_bond.cpp b/src/MOLECULE/atom_vec_bond.cpp
index 1e8f91323..13ea1e5e2 100644
--- a/src/MOLECULE/atom_vec_bond.cpp
+++ b/src/MOLECULE/atom_vec_bond.cpp
@@ -1,740 +1,743 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "atom_vec_bond.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecBond::AtomVecBond(LAMMPS *lmp, int narg, char **arg) :
   AtomVec(lmp, narg, arg)
 {
   molecular = 1;
   bonds_allow = 1;
   mass_type = 1;
 
   comm_x_only = comm_f_only = 1;
   size_forward = 3;
   size_reverse = 3;
   size_border = 7;
   size_velocity = 3;
   size_data_atom = 6;
   size_data_vel = 4;
   xcol_data = 4;
 
   atom->molecule_flag = 1;
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n 
 ------------------------------------------------------------------------- */
 
 void AtomVecBond::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
 
   tag = atom->tag = (int *) 
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *) 
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *) 
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
 
   molecule = atom->molecule = (int *) 
     memory->srealloc(atom->molecule,nmax*sizeof(int),"atom:molecule");
 
   nspecial = atom->nspecial =
     memory->grow_2d_int_array(atom->nspecial,nmax,3,"atom:nspecial");
   special = atom->special =
     memory->grow_2d_int_array(atom->special,nmax,atom->maxspecial,
 			      "atom:special");
 
   num_bond = atom->num_bond = (int *) 
     memory->srealloc(atom->num_bond,nmax*sizeof(int),"atom:num_bond");
   bond_type = atom->bond_type = 
     memory->grow_2d_int_array(atom->bond_type,nmax,atom->bond_per_atom,
 			      "atom:bond_type");
   bond_atom = atom->bond_atom = 
     memory->grow_2d_int_array(atom->bond_atom,nmax,atom->bond_per_atom,
 			      "atom:bond_atom");
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecBond::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
   molecule = atom->molecule;
   nspecial = atom->nspecial; special = atom->special;
   num_bond = atom->num_bond; bond_type = atom->bond_type;
   bond_atom = atom->bond_atom;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecBond::copy(int i, int j)
 {
   int k;
 
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
 
   molecule[j] = molecule[i];
 
   num_bond[j] = num_bond[i];
   for (k = 0; k < num_bond[j]; k++) {
     bond_type[j][k] = bond_type[i][k];
     bond_atom[j][k] = bond_atom[i][k];
   }
 
   nspecial[j][0] = nspecial[i][0];
   nspecial[j][1] = nspecial[i][1];
   nspecial[j][2] = nspecial[i][2];
   for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecBond::pack_comm(int n, int *list, double *buf,
 			   int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecBond::pack_comm_vel(int n, int *list, double *buf,
 			       int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecBond::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecBond::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecBond::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecBond::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecBond::pack_border(int n, int *list, double *buf,
 			     int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecBond::pack_border_vel(int n, int *list, double *buf,
 				 int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecBond::pack_border_one(int i, double *buf)
 {
   buf[0] = molecule[i];
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecBond::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     molecule[i] = static_cast<int> (buf[m++]);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecBond::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     molecule[i] = static_cast<int> (buf[m++]);
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecBond::unpack_border_one(int i, double *buf)
 {
   molecule[i] = static_cast<int> (buf[0]);
   return 1;
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    xyz must be 1st 3 values, so comm::exchange() can test on them 
 ------------------------------------------------------------------------- */
 
 int AtomVecBond::pack_exchange(int i, double *buf)
 {
   int k;
 
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
 
   buf[m++] = molecule[i];
 
   buf[m++] = num_bond[i];
   for (k = 0; k < num_bond[i]; k++) {
     buf[m++] = bond_type[i][k];
     buf[m++] = bond_atom[i][k];
   }
 
   buf[m++] = nspecial[i][0];
   buf[m++] = nspecial[i][1];
   buf[m++] = nspecial[i][2];
   for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecBond::unpack_exchange(double *buf)
 {
   int k;
 
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
 
   molecule[nlocal] = static_cast<int> (buf[m++]);
 
   num_bond[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = static_cast<int> (buf[m++]);
     bond_atom[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   nspecial[nlocal][0] = static_cast<int> (buf[m++]);
   nspecial[nlocal][1] = static_cast<int> (buf[m++]);
   nspecial[nlocal][2] = static_cast<int> (buf[m++]);
   for (k = 0; k < nspecial[nlocal][2]; k++)
     special[nlocal][k] = static_cast<int> (buf[m++]);
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecBond::size_restart()
 {
   int i;
 
   int nlocal = atom->nlocal;
   int n = 0;
   for (i = 0; i < nlocal; i++)
     n += 13 + 2*num_bond[i];
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       for (i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive   
 ------------------------------------------------------------------------- */
 
 int AtomVecBond::pack_restart(int i, double *buf)
 {
   int k;
 
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
 
   buf[m++] = molecule[i];
 
   buf[m++] = num_bond[i];
   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];
   }
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
 
 int AtomVecBond::unpack_restart(double *buf)
 {
   int k;
 
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store)
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
 
   molecule[nlocal] = static_cast<int> (buf[m++]);
     
   num_bond[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = static_cast<int> (buf[m++]);
     bond_atom[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
 
 void AtomVecBond::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   molecule[nlocal] = 0;
   num_bond[nlocal] = 0;
   nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
 void AtomVecBond::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
 
   molecule[nlocal] = atoi(values[1]);
 
   type[nlocal] = atoi(values[2]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   image[nlocal] = imagetmp;
 
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   num_bond[nlocal] = 0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Atoms section of data file
    initialize other atom quantities for this sub-style
 ------------------------------------------------------------------------- */
 
 int AtomVecBond::data_atom_hybrid(int nlocal, char **values)
 {
   molecule[nlocal] = atoi(values[0]);
 
   num_bond[nlocal] = 0;
 
   return 1;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
 
 double AtomVecBond::memory_usage()
 {
   double bytes = 0.0;
 
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
 
   if (atom->memcheck("molecule")) bytes += nmax * sizeof(int);
   if (atom->memcheck("nspecial")) bytes += nmax*3 * sizeof(int);
   if (atom->memcheck("special")) bytes += nmax*atom->maxspecial * sizeof(int);
 
   if (atom->memcheck("num_bond")) bytes += nmax * sizeof(int);
   if (atom->memcheck("bond_type"))
     bytes += nmax*atom->bond_per_atom * sizeof(int);
   if (atom->memcheck("bond_atom"))
     bytes += nmax*atom->bond_per_atom * sizeof(int);
 
   return bytes;
 }
diff --git a/src/MOLECULE/atom_vec_full.cpp b/src/MOLECULE/atom_vec_full.cpp
index 5815256fc..2d733ebf4 100644
--- a/src/MOLECULE/atom_vec_full.cpp
+++ b/src/MOLECULE/atom_vec_full.cpp
@@ -1,994 +1,997 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "atom_vec_full.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecFull::AtomVecFull(LAMMPS *lmp, int narg, char **arg) : 
   AtomVec(lmp, narg, arg)
 {
   molecular = 1;
   bonds_allow = angles_allow = dihedrals_allow = impropers_allow = 1;
   mass_type = 1;
 
   comm_x_only = comm_f_only = 1;
   size_forward = 3;
   size_reverse = 3;
   size_border = 8;
   size_velocity = 3;
   size_data_atom = 7;
   size_data_vel = 4;
   xcol_data = 5;
 
   atom->molecule_flag = atom->q_flag = 1;
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n 
 ------------------------------------------------------------------------- */
 
 void AtomVecFull::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
 
   tag = atom->tag = (int *) 
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *) 
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *) 
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
 
   q = atom->q = (double *) 
     memory->srealloc(atom->q,nmax*sizeof(double),"atom:q");
   molecule = atom->molecule = (int *) 
     memory->srealloc(atom->molecule,nmax*sizeof(int),"atom:molecule");
 
   nspecial = atom->nspecial =
     memory->grow_2d_int_array(atom->nspecial,nmax,3,"atom:nspecial");
   special = atom->special =
     memory->grow_2d_int_array(atom->special,nmax,atom->maxspecial,
 			      "atom:special");
 
   num_bond = atom->num_bond = (int *) 
     memory->srealloc(atom->num_bond,nmax*sizeof(int),"atom:num_bond");
   bond_type = atom->bond_type = 
     memory->grow_2d_int_array(atom->bond_type,nmax,atom->bond_per_atom,
 			      "atom:bond_type");
   bond_atom = atom->bond_atom = 
     memory->grow_2d_int_array(atom->bond_atom,nmax,atom->bond_per_atom,
 			      "atom:bond_atom");
 
   num_angle = atom->num_angle = (int *) 
     memory->srealloc(atom->num_angle,nmax*sizeof(int),"atom:num_angle");
   angle_type = atom->angle_type = 
     memory->grow_2d_int_array(atom->angle_type,nmax,atom->angle_per_atom,
 			      "atom:angle_type");
   angle_atom1 = atom->angle_atom1 = 
     memory->grow_2d_int_array(atom->angle_atom1,nmax,atom->angle_per_atom,
 			      "atom:angle_atom1");
   angle_atom2 = atom->angle_atom2 = 
     memory->grow_2d_int_array(atom->angle_atom2,nmax,atom->angle_per_atom,
 			      "atom:angle_atom2");
   angle_atom3 = atom->angle_atom3 = 
     memory->grow_2d_int_array(atom->angle_atom3,nmax,atom->angle_per_atom,
 			      "atom:angle_atom3");
 
   num_dihedral = atom->num_dihedral = (int *) 
     memory->srealloc(atom->num_dihedral,nmax*sizeof(int),"atom:num_dihedral");
   dihedral_type = atom->dihedral_type = 
     memory->grow_2d_int_array(atom->dihedral_type,nmax,atom->dihedral_per_atom,
 			      "atom:dihedral_type");
   dihedral_atom1 = atom->dihedral_atom1 = 
     memory->grow_2d_int_array(atom->dihedral_atom1,nmax,
 			      atom->dihedral_per_atom,"atom:dihedral_atom1");
   dihedral_atom2 = atom->dihedral_atom2 = 
     memory->grow_2d_int_array(atom->dihedral_atom2,nmax,
 			      atom->dihedral_per_atom,"atom:dihedral_atom2");
   dihedral_atom3 = atom->dihedral_atom3 = 
     memory->grow_2d_int_array(atom->dihedral_atom3,nmax,
 			      atom->dihedral_per_atom,"atom:dihedral_atom3");
   dihedral_atom4 = atom->dihedral_atom4 = 
     memory->grow_2d_int_array(atom->dihedral_atom4,nmax,
 			      atom->dihedral_per_atom,"atom:dihedral_atom4");
 
   num_improper = atom->num_improper = (int *) 
     memory->srealloc(atom->num_improper,nmax*sizeof(int),"atom:num_improper");
   improper_type = atom->improper_type = 
     memory->grow_2d_int_array(atom->improper_type,nmax,atom->improper_per_atom,
 			      "atom:improper_type");
   improper_atom1 = atom->improper_atom1 = 
     memory->grow_2d_int_array(atom->improper_atom1,nmax,
 			      atom->improper_per_atom,"atom:improper_atom1");
   improper_atom2 = atom->improper_atom2 = 
     memory->grow_2d_int_array(atom->improper_atom2,nmax,
 			      atom->improper_per_atom,"atom:improper_atom2");
   improper_atom3 = atom->improper_atom3 = 
     memory->grow_2d_int_array(atom->improper_atom3,nmax,
 			      atom->improper_per_atom,"atom:improper_atom3");
   improper_atom4 = atom->improper_atom4 = 
     memory->grow_2d_int_array(atom->improper_atom4,nmax,
 			      atom->improper_per_atom,"atom:improper_atom4");
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecFull::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
   q = atom->q; molecule = atom->molecule;
   nspecial = atom->nspecial; special = atom->special;
   num_bond = atom->num_bond; bond_type = atom->bond_type;
   bond_atom = atom->bond_atom;
   num_angle = atom->num_angle; angle_type = atom->angle_type;
   angle_atom1 = atom->angle_atom1; angle_atom2 = atom->angle_atom2;
   angle_atom3 = atom->angle_atom3;
   num_dihedral = atom->num_dihedral; dihedral_type = atom->dihedral_type;
   dihedral_atom1 = atom->dihedral_atom1; dihedral_atom2 = atom->dihedral_atom2;
   dihedral_atom3 = atom->dihedral_atom3; dihedral_atom4 = atom->dihedral_atom4;
   num_improper = atom->num_improper; improper_type = atom->improper_type;
   improper_atom1 = atom->improper_atom1; improper_atom2 = atom->improper_atom2;
   improper_atom3 = atom->improper_atom3; improper_atom4 = atom->improper_atom4;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecFull::copy(int i, int j)
 {
   int k;
 
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
 
   q[j] = q[i];
   molecule[j] = molecule[i];
 
   num_bond[j] = num_bond[i];
   for (k = 0; k < num_bond[j]; k++) {
     bond_type[j][k] = bond_type[i][k];
     bond_atom[j][k] = bond_atom[i][k];
   }
 
   num_angle[j] = num_angle[i];
   for (k = 0; k < num_angle[j]; k++) {
     angle_type[j][k] = angle_type[i][k];
     angle_atom1[j][k] = angle_atom1[i][k];
     angle_atom2[j][k] = angle_atom2[i][k];
     angle_atom3[j][k] = angle_atom3[i][k];
   }
 
   num_dihedral[j] = num_dihedral[i];
   for (k = 0; k < num_dihedral[j]; k++) {
     dihedral_type[j][k] = dihedral_type[i][k];
     dihedral_atom1[j][k] = dihedral_atom1[i][k];
     dihedral_atom2[j][k] = dihedral_atom2[i][k];
     dihedral_atom3[j][k] = dihedral_atom3[i][k];
     dihedral_atom4[j][k] = dihedral_atom4[i][k];
   }
 
   num_improper[j] = num_improper[i];
   for (k = 0; k < num_improper[j]; k++) {
     improper_type[j][k] = improper_type[i][k];
     improper_atom1[j][k] = improper_atom1[i][k];
     improper_atom2[j][k] = improper_atom2[i][k];
     improper_atom3[j][k] = improper_atom3[i][k];
     improper_atom4[j][k] = improper_atom4[i][k];
   }
 
   nspecial[j][0] = nspecial[i][0];
   nspecial[j][1] = nspecial[i][1];
   nspecial[j][2] = nspecial[i][2];
   for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecFull::pack_comm(int n, int *list, double *buf,
 			   int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecFull::pack_comm_vel(int n, int *list, double *buf,
 			       int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecFull::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecFull::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecFull::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecFull::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecFull::pack_border(int n, int *list, double *buf,
 			     int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = molecule[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = molecule[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecFull::pack_border_vel(int n, int *list, double *buf,
 				 int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = molecule[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = molecule[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecFull::pack_border_one(int i, double *buf)
 {
   buf[0] = q[i];
   buf[1] = molecule[i];
   return 2;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecFull::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     q[i] = buf[m++];
     molecule[i] = static_cast<int> (buf[m++]);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecFull::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     q[i] = buf[m++];
     molecule[i] = static_cast<int> (buf[m++]);
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecFull::unpack_border_one(int i, double *buf)
 {
   q[i] = buf[0];
   molecule[i] = static_cast<int> (buf[1]);
   return 2;
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    xyz must be 1st 3 values, so comm::exchange() can test on them 
 ------------------------------------------------------------------------- */
 
 int AtomVecFull::pack_exchange(int i, double *buf)
 {
   int k;
 
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
 
   buf[m++] = q[i];
   buf[m++] = molecule[i];
 
   buf[m++] = num_bond[i];
   for (k = 0; k < num_bond[i]; k++) {
     buf[m++] = bond_type[i][k];
     buf[m++] = bond_atom[i][k];
   }
 
   buf[m++] = num_angle[i];
   for (k = 0; k < num_angle[i]; k++) {
     buf[m++] = angle_type[i][k];
     buf[m++] = angle_atom1[i][k];
     buf[m++] = angle_atom2[i][k];
     buf[m++] = angle_atom3[i][k];
   }
 
   buf[m++] = num_dihedral[i];
   for (k = 0; k < num_dihedral[i]; k++) {
     buf[m++] = dihedral_type[i][k];
     buf[m++] = dihedral_atom1[i][k];
     buf[m++] = dihedral_atom2[i][k];
     buf[m++] = dihedral_atom3[i][k];
     buf[m++] = dihedral_atom4[i][k];
   }
 
   buf[m++] = num_improper[i];
   for (k = 0; k < num_improper[i]; k++) {
     buf[m++] = improper_type[i][k];
     buf[m++] = improper_atom1[i][k];
     buf[m++] = improper_atom2[i][k];
     buf[m++] = improper_atom3[i][k];
     buf[m++] = improper_atom4[i][k];
   }
 
   buf[m++] = nspecial[i][0];
   buf[m++] = nspecial[i][1];
   buf[m++] = nspecial[i][2];
   for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecFull::unpack_exchange(double *buf)
 {
   int k;
 
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
 
   q[nlocal] = buf[m++];
   molecule[nlocal] = static_cast<int> (buf[m++]);
 
   num_bond[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = static_cast<int> (buf[m++]);
     bond_atom[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_angle[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_angle[nlocal]; k++) {
     angle_type[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom3[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_dihedral[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_dihedral[nlocal]; k++) {
     dihedral_type[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom3[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom4[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_improper[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_improper[nlocal]; k++) {
     improper_type[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom3[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom4[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   nspecial[nlocal][0] = static_cast<int> (buf[m++]);
   nspecial[nlocal][1] = static_cast<int> (buf[m++]);
   nspecial[nlocal][2] = static_cast<int> (buf[m++]);
   for (k = 0; k < nspecial[nlocal][2]; k++)
     special[nlocal][k] = static_cast<int> (buf[m++]);
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecFull::size_restart()
 {
   int i;
 
   int nlocal = atom->nlocal;
   int n = 0;
   for (i = 0; i < nlocal; i++)
     n += 17 + 2*num_bond[i] + 4*num_angle[i] +
       5*num_dihedral[i] + 5*num_improper[i];
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       for (i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive   
 ------------------------------------------------------------------------- */
 
 int AtomVecFull::pack_restart(int i, double *buf)
 {
   int k;
 
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
 
   buf[m++] = q[i];
   buf[m++] = molecule[i];
  
   buf[m++] = num_bond[i];
   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++] = num_angle[i];
   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++] = num_dihedral[i];
   for (k = 0; k < num_dihedral[i]; k++) {
     buf[m++] = MAX(dihedral_type[i][k],-dihedral_type[i][k]);
     buf[m++] = dihedral_atom1[i][k];
     buf[m++] = dihedral_atom2[i][k];
     buf[m++] = dihedral_atom3[i][k];
     buf[m++] = dihedral_atom4[i][k];
   }
 
   buf[m++] = num_improper[i];
   for (k = 0; k < num_improper[i]; k++) {
     buf[m++] = MAX(improper_type[i][k],-improper_type[i][k]);
     buf[m++] = improper_atom1[i][k];
     buf[m++] = improper_atom2[i][k];
     buf[m++] = improper_atom3[i][k];
     buf[m++] = improper_atom4[i][k];
   }
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
 
 int AtomVecFull::unpack_restart(double *buf)
 {
   int k;
 
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store)
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
 
   q[nlocal] = buf[m++];
   molecule[nlocal] = static_cast<int> (buf[m++]);
     
   num_bond[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = static_cast<int> (buf[m++]);
     bond_atom[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_angle[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_angle[nlocal]; k++) {
     angle_type[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom3[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_dihedral[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_dihedral[nlocal]; k++) {
     dihedral_type[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom3[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom4[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_improper[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_improper[nlocal]; k++) {
     improper_type[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom3[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom4[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
 
 void AtomVecFull::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   q[nlocal] = 0.0;
   molecule[nlocal] = 0;
   num_bond[nlocal] = 0;
   num_angle[nlocal] = 0;
   num_dihedral[nlocal] = 0;
   num_improper[nlocal] = 0;
   nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
 void AtomVecFull::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
 
   molecule[nlocal] = atoi(values[1]);
 
   type[nlocal] = atoi(values[2]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   q[nlocal] = atof(values[3]);
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   image[nlocal] = imagetmp;
 
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   num_bond[nlocal] = 0;
   num_angle[nlocal] = 0;
   num_dihedral[nlocal] = 0;
   num_improper[nlocal] = 0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Atoms section of data file
    initialize other atom quantities for this sub-style
 ------------------------------------------------------------------------- */
 
 int AtomVecFull::data_atom_hybrid(int nlocal, char **values)
 {
   molecule[nlocal] = atoi(values[1]);
   q[nlocal] = atof(values[3]);
 
   num_bond[nlocal] = 0;
   num_angle[nlocal] = 0;
   num_dihedral[nlocal] = 0;
   num_improper[nlocal] = 0;
 
   return 2;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
 
 double AtomVecFull::memory_usage()
 {
   double bytes = 0.0;
 
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
 
   if (atom->memcheck("q")) bytes += nmax * sizeof(double);
   if (atom->memcheck("molecule")) bytes += nmax * sizeof(int);
   if (atom->memcheck("nspecial")) bytes += nmax*3 * sizeof(int);
   if (atom->memcheck("special")) bytes += nmax*atom->maxspecial * sizeof(int);
 
   if (atom->memcheck("num_bond")) bytes += nmax * sizeof(int);
   if (atom->memcheck("bond_type"))
     bytes += nmax*atom->bond_per_atom * sizeof(int);
   if (atom->memcheck("bond_atom"))
     bytes += nmax*atom->bond_per_atom * sizeof(int);
 
   if (atom->memcheck("num_angle")) bytes += nmax * sizeof(int);
   if (atom->memcheck("angle_type"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
   if (atom->memcheck("angle_atom1"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
   if (atom->memcheck("angle_atom2"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
   if (atom->memcheck("angle_atom3"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
 
   if (atom->memcheck("num_dihedral")) bytes += nmax * sizeof(int);
   if (atom->memcheck("dihedral_type"))
     bytes += nmax*atom->dihedral_per_atom * sizeof(int);
   if (atom->memcheck("dihedral_atom1"))
     bytes += nmax*atom->dihedral_per_atom * sizeof(int);
   if (atom->memcheck("dihedral_atom2"))
     bytes += nmax*atom->dihedral_per_atom * sizeof(int);
   if (atom->memcheck("dihedral_atom3"))
     bytes += nmax*atom->dihedral_per_atom * sizeof(int);
   if (atom->memcheck("dihedral_atom4"))
     bytes += nmax*atom->dihedral_per_atom * sizeof(int);
 
   if (atom->memcheck("num_improper")) bytes += nmax * sizeof(int);
   if (atom->memcheck("improper_type"))
     bytes += nmax*atom->improper_per_atom * sizeof(int);
   if (atom->memcheck("improper_atom1"))
     bytes += nmax*atom->improper_per_atom * sizeof(int);
   if (atom->memcheck("improper_atom2"))
     bytes += nmax*atom->improper_per_atom * sizeof(int);
   if (atom->memcheck("improper_atom3"))
     bytes += nmax*atom->improper_per_atom * sizeof(int);
   if (atom->memcheck("improper_atom4"))
     bytes += nmax*atom->improper_per_atom * sizeof(int);
 
   return bytes;
 }
diff --git a/src/MOLECULE/atom_vec_molecular.cpp b/src/MOLECULE/atom_vec_molecular.cpp
index 131e80c59..07c46724a 100644
--- a/src/MOLECULE/atom_vec_molecular.cpp
+++ b/src/MOLECULE/atom_vec_molecular.cpp
@@ -1,974 +1,977 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "atom_vec_molecular.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecMolecular::AtomVecMolecular(LAMMPS *lmp, int narg, char **arg) : 
   AtomVec(lmp, narg, arg)
 {
   molecular = 1;
   bonds_allow = angles_allow = dihedrals_allow = impropers_allow = 1;
   mass_type = 1;
 
   comm_x_only = comm_f_only = 1;
   size_forward = 3;
   size_reverse = 3;
   size_border = 7;
   size_velocity = 3;
   size_data_atom = 6;
   size_data_vel = 4;
   xcol_data = 4;
 
   atom->molecule_flag = 1;
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n 
 ------------------------------------------------------------------------- */
 
 void AtomVecMolecular::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
 
   tag = atom->tag = (int *) 
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *) 
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *) 
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
 
   molecule = atom->molecule = (int *) 
     memory->srealloc(atom->molecule,nmax*sizeof(int),"atom:molecule");
 
   nspecial = atom->nspecial =
     memory->grow_2d_int_array(atom->nspecial,nmax,3,"atom:nspecial");
   special = atom->special =
     memory->grow_2d_int_array(atom->special,nmax,atom->maxspecial,
 			      "atom:special");
 
   num_bond = atom->num_bond = (int *) 
     memory->srealloc(atom->num_bond,nmax*sizeof(int),"atom:num_bond");
   bond_type = atom->bond_type = 
     memory->grow_2d_int_array(atom->bond_type,nmax,atom->bond_per_atom,
 			      "atom:bond_type");
   bond_atom = atom->bond_atom = 
     memory->grow_2d_int_array(atom->bond_atom,nmax,atom->bond_per_atom,
 			      "atom:bond_atom");
 
   num_angle = atom->num_angle = (int *) 
     memory->srealloc(atom->num_angle,nmax*sizeof(int),"atom:num_angle");
   angle_type = atom->angle_type = 
     memory->grow_2d_int_array(atom->angle_type,nmax,atom->angle_per_atom,
 			      "atom:angle_type");
   angle_atom1 = atom->angle_atom1 = 
     memory->grow_2d_int_array(atom->angle_atom1,nmax,atom->angle_per_atom,
 			      "atom:angle_atom1");
   angle_atom2 = atom->angle_atom2 = 
     memory->grow_2d_int_array(atom->angle_atom2,nmax,atom->angle_per_atom,
 			      "atom:angle_atom2");
   angle_atom3 = atom->angle_atom3 = 
     memory->grow_2d_int_array(atom->angle_atom3,nmax,atom->angle_per_atom,
 			      "atom:angle_atom3");
 
   num_dihedral = atom->num_dihedral = (int *) 
     memory->srealloc(atom->num_dihedral,nmax*sizeof(int),"atom:num_dihedral");
   dihedral_type = atom->dihedral_type = 
     memory->grow_2d_int_array(atom->dihedral_type,nmax,atom->dihedral_per_atom,
 			      "atom:dihedral_type");
   dihedral_atom1 = atom->dihedral_atom1 = 
     memory->grow_2d_int_array(atom->dihedral_atom1,nmax,
 			      atom->dihedral_per_atom,"atom:dihedral_atom1");
   dihedral_atom2 = atom->dihedral_atom2 = 
     memory->grow_2d_int_array(atom->dihedral_atom2,nmax,
 			      atom->dihedral_per_atom,"atom:dihedral_atom2");
   dihedral_atom3 = atom->dihedral_atom3 = 
     memory->grow_2d_int_array(atom->dihedral_atom3,nmax,
 			      atom->dihedral_per_atom,"atom:dihedral_atom3");
   dihedral_atom4 = atom->dihedral_atom4 = 
     memory->grow_2d_int_array(atom->dihedral_atom4,nmax,
 			      atom->dihedral_per_atom,"atom:dihedral_atom4");
 
   num_improper = atom->num_improper = (int *) 
     memory->srealloc(atom->num_improper,nmax*sizeof(int),"atom:num_improper");
   improper_type = atom->improper_type = 
     memory->grow_2d_int_array(atom->improper_type,nmax,atom->improper_per_atom,
 			      "atom:improper_type");
   improper_atom1 = atom->improper_atom1 = 
     memory->grow_2d_int_array(atom->improper_atom1,nmax,
 			      atom->improper_per_atom,"atom:improper_atom1");
   improper_atom2 = atom->improper_atom2 = 
     memory->grow_2d_int_array(atom->improper_atom2,nmax,
 			      atom->improper_per_atom,"atom:improper_atom2");
   improper_atom3 = atom->improper_atom3 = 
     memory->grow_2d_int_array(atom->improper_atom3,nmax,
 			      atom->improper_per_atom,"atom:improper_atom3");
   improper_atom4 = atom->improper_atom4 = 
     memory->grow_2d_int_array(atom->improper_atom4,nmax,
 			      atom->improper_per_atom,"atom:improper_atom4");
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecMolecular::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
   molecule = atom->molecule;
   nspecial = atom->nspecial; special = atom->special;
   num_bond = atom->num_bond; bond_type = atom->bond_type;
   bond_atom = atom->bond_atom;
   num_angle = atom->num_angle; angle_type = atom->angle_type;
   angle_atom1 = atom->angle_atom1; angle_atom2 = atom->angle_atom2;
   angle_atom3 = atom->angle_atom3;
   num_dihedral = atom->num_dihedral; dihedral_type = atom->dihedral_type;
   dihedral_atom1 = atom->dihedral_atom1; dihedral_atom2 = atom->dihedral_atom2;
   dihedral_atom3 = atom->dihedral_atom3; dihedral_atom4 = atom->dihedral_atom4;
   num_improper = atom->num_improper; improper_type = atom->improper_type;
   improper_atom1 = atom->improper_atom1; improper_atom2 = atom->improper_atom2;
   improper_atom3 = atom->improper_atom3; improper_atom4 = atom->improper_atom4;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecMolecular::copy(int i, int j)
 {
   int k;
 
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
 
   molecule[j] = molecule[i];
 
   num_bond[j] = num_bond[i];
   for (k = 0; k < num_bond[j]; k++) {
     bond_type[j][k] = bond_type[i][k];
     bond_atom[j][k] = bond_atom[i][k];
   }
 
   num_angle[j] = num_angle[i];
   for (k = 0; k < num_angle[j]; k++) {
     angle_type[j][k] = angle_type[i][k];
     angle_atom1[j][k] = angle_atom1[i][k];
     angle_atom2[j][k] = angle_atom2[i][k];
     angle_atom3[j][k] = angle_atom3[i][k];
   }
 
   num_dihedral[j] = num_dihedral[i];
   for (k = 0; k < num_dihedral[j]; k++) {
     dihedral_type[j][k] = dihedral_type[i][k];
     dihedral_atom1[j][k] = dihedral_atom1[i][k];
     dihedral_atom2[j][k] = dihedral_atom2[i][k];
     dihedral_atom3[j][k] = dihedral_atom3[i][k];
     dihedral_atom4[j][k] = dihedral_atom4[i][k];
   }
 
   num_improper[j] = num_improper[i];
   for (k = 0; k < num_improper[j]; k++) {
     improper_type[j][k] = improper_type[i][k];
     improper_atom1[j][k] = improper_atom1[i][k];
     improper_atom2[j][k] = improper_atom2[i][k];
     improper_atom3[j][k] = improper_atom3[i][k];
     improper_atom4[j][k] = improper_atom4[i][k];
   }
 
   nspecial[j][0] = nspecial[i][0];
   nspecial[j][1] = nspecial[i][1];
   nspecial[j][2] = nspecial[i][2];
   for (k = 0; k < nspecial[j][2]; k++) special[j][k] = special[i][k];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecMolecular::pack_comm(int n, int *list, double *buf, 
 				int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecMolecular::pack_comm_vel(int n, int *list, double *buf, 
 				    int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecMolecular::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecMolecular::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecMolecular::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecMolecular::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecMolecular::pack_border(int n, int *list, double *buf,
 				  int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecMolecular::pack_border_vel(int n, int *list, double *buf,
 				      int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = molecule[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecMolecular::pack_border_one(int i, double *buf)
 {
   buf[0] = molecule[i];
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecMolecular::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     molecule[i] = static_cast<int> (buf[m++]);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecMolecular::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     molecule[i] = static_cast<int> (buf[m++]);
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecMolecular::unpack_border_one(int i, double *buf)
 {
   molecule[i] = static_cast<int> (buf[0]);
   return 1;
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    xyz must be 1st 3 values, so comm::exchange() can test on them 
 ------------------------------------------------------------------------- */
 
 int AtomVecMolecular::pack_exchange(int i, double *buf)
 {
   int k;
 
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
 
   buf[m++] = molecule[i];
 
   buf[m++] = num_bond[i];
   for (k = 0; k < num_bond[i]; k++) {
     buf[m++] = bond_type[i][k];
     buf[m++] = bond_atom[i][k];
   }
 
   buf[m++] = num_angle[i];
   for (k = 0; k < num_angle[i]; k++) {
     buf[m++] = angle_type[i][k];
     buf[m++] = angle_atom1[i][k];
     buf[m++] = angle_atom2[i][k];
     buf[m++] = angle_atom3[i][k];
   }
 
   buf[m++] = num_dihedral[i];
   for (k = 0; k < num_dihedral[i]; k++) {
     buf[m++] = dihedral_type[i][k];
     buf[m++] = dihedral_atom1[i][k];
     buf[m++] = dihedral_atom2[i][k];
     buf[m++] = dihedral_atom3[i][k];
     buf[m++] = dihedral_atom4[i][k];
   }
 
   buf[m++] = num_improper[i];
   for (k = 0; k < num_improper[i]; k++) {
     buf[m++] = improper_type[i][k];
     buf[m++] = improper_atom1[i][k];
     buf[m++] = improper_atom2[i][k];
     buf[m++] = improper_atom3[i][k];
     buf[m++] = improper_atom4[i][k];
   }
 
   buf[m++] = nspecial[i][0];
   buf[m++] = nspecial[i][1];
   buf[m++] = nspecial[i][2];
   for (k = 0; k < nspecial[i][2]; k++) buf[m++] = special[i][k];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecMolecular::unpack_exchange(double *buf)
 {
   int k;
 
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
 
   molecule[nlocal] = static_cast<int> (buf[m++]);
 
   num_bond[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = static_cast<int> (buf[m++]);
     bond_atom[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_angle[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_angle[nlocal]; k++) {
     angle_type[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom3[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_dihedral[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_dihedral[nlocal]; k++) {
     dihedral_type[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom3[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom4[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_improper[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_improper[nlocal]; k++) {
     improper_type[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom3[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom4[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   nspecial[nlocal][0] = static_cast<int> (buf[m++]);
   nspecial[nlocal][1] = static_cast<int> (buf[m++]);
   nspecial[nlocal][2] = static_cast<int> (buf[m++]);
   for (k = 0; k < nspecial[nlocal][2]; k++)
     special[nlocal][k] = static_cast<int> (buf[m++]);
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecMolecular::size_restart()
 {
   int i;
 
   int nlocal = atom->nlocal;
   int n = 0;
   for (i = 0; i < nlocal; i++)
     n += 16 + 2*num_bond[i] + 4*num_angle[i] +
       5*num_dihedral[i] + 5*num_improper[i];
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       for (i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive   
 ------------------------------------------------------------------------- */
 
 int AtomVecMolecular::pack_restart(int i, double *buf)
 {
   int k;
 
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
 
   buf[m++] = molecule[i];
  
   buf[m++] = num_bond[i];
   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++] = num_angle[i];
   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++] = num_dihedral[i];
   for (k = 0; k < num_dihedral[i]; k++) {
     buf[m++] = MAX(dihedral_type[i][k],-dihedral_type[i][k]);
     buf[m++] = dihedral_atom1[i][k];
     buf[m++] = dihedral_atom2[i][k];
     buf[m++] = dihedral_atom3[i][k];
     buf[m++] = dihedral_atom4[i][k];
   }
 
   buf[m++] = num_improper[i];
   for (k = 0; k < num_improper[i]; k++) {
     buf[m++] = MAX(improper_type[i][k],-improper_type[i][k]);
     buf[m++] = improper_atom1[i][k];
     buf[m++] = improper_atom2[i][k];
     buf[m++] = improper_atom3[i][k];
     buf[m++] = improper_atom4[i][k];
   }
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
 
 int AtomVecMolecular::unpack_restart(double *buf)
 {
   int k;
 
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store)
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
 
   molecule[nlocal] = static_cast<int> (buf[m++]);
     
   num_bond[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_bond[nlocal]; k++) {
     bond_type[nlocal][k] = static_cast<int> (buf[m++]);
     bond_atom[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_angle[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_angle[nlocal]; k++) {
     angle_type[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     angle_atom3[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_dihedral[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_dihedral[nlocal]; k++) {
     dihedral_type[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom3[nlocal][k] = static_cast<int> (buf[m++]);
     dihedral_atom4[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   num_improper[nlocal] = static_cast<int> (buf[m++]);
   for (k = 0; k < num_improper[nlocal]; k++) {
     improper_type[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom1[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom2[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom3[nlocal][k] = static_cast<int> (buf[m++]);
     improper_atom4[nlocal][k] = static_cast<int> (buf[m++]);
   }
 
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
 
 void AtomVecMolecular::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   molecule[nlocal] = 0;
   num_bond[nlocal] = 0;
   num_angle[nlocal] = 0;
   num_dihedral[nlocal] = 0;
   num_improper[nlocal] = 0;
   nspecial[nlocal][0] = nspecial[nlocal][1] = nspecial[nlocal][2] = 0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
 void AtomVecMolecular::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
 
   molecule[nlocal] = atoi(values[1]);
 
   type[nlocal] = atoi(values[2]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   image[nlocal] = imagetmp;
 
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   num_bond[nlocal] = 0;
   num_angle[nlocal] = 0;
   num_dihedral[nlocal] = 0;
   num_improper[nlocal] = 0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Atoms section of data file
    initialize other atom quantities for this sub-style
 ------------------------------------------------------------------------- */
 
 int AtomVecMolecular::data_atom_hybrid(int nlocal, char **values)
 {
   molecule[nlocal] = atoi(values[0]);
 
   num_bond[nlocal] = 0;
   num_angle[nlocal] = 0;
   num_dihedral[nlocal] = 0;
   num_improper[nlocal] = 0;
 
   return 1;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
 
 double AtomVecMolecular::memory_usage()
 {
   double bytes = 0.0;
 
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
 
   if (atom->memcheck("molecule")) bytes += nmax * sizeof(int);
   if (atom->memcheck("nspecial")) bytes += nmax*3 * sizeof(int);
   if (atom->memcheck("special")) bytes += nmax*atom->maxspecial * sizeof(int);
 
   if (atom->memcheck("num_bond")) bytes += nmax * sizeof(int);
   if (atom->memcheck("bond_type"))
     bytes += nmax*atom->bond_per_atom * sizeof(int);
   if (atom->memcheck("bond_atom"))
     bytes += nmax*atom->bond_per_atom * sizeof(int);
 
   if (atom->memcheck("num_angle")) bytes += nmax * sizeof(int);
   if (atom->memcheck("angle_type"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
   if (atom->memcheck("angle_atom1"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
   if (atom->memcheck("angle_atom2"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
   if (atom->memcheck("angle_atom3"))
     bytes += nmax*atom->angle_per_atom * sizeof(int);
 
   if (atom->memcheck("num_dihedral")) bytes += nmax * sizeof(int);
   if (atom->memcheck("dihedral_type"))
     bytes += nmax*atom->dihedral_per_atom * sizeof(int);
   if (atom->memcheck("dihedral_atom1"))
     bytes += nmax*atom->dihedral_per_atom * sizeof(int);
   if (atom->memcheck("dihedral_atom2"))
     bytes += nmax*atom->dihedral_per_atom * sizeof(int);
   if (atom->memcheck("dihedral_atom3"))
     bytes += nmax*atom->dihedral_per_atom * sizeof(int);
   if (atom->memcheck("dihedral_atom4"))
     bytes += nmax*atom->dihedral_per_atom * sizeof(int);
 
   if (atom->memcheck("num_improper")) bytes += nmax * sizeof(int);
   if (atom->memcheck("improper_type"))
     bytes += nmax*atom->improper_per_atom * sizeof(int);
   if (atom->memcheck("improper_atom1"))
     bytes += nmax*atom->improper_per_atom * sizeof(int);
   if (atom->memcheck("improper_atom2"))
     bytes += nmax*atom->improper_per_atom * sizeof(int);
   if (atom->memcheck("improper_atom3"))
     bytes += nmax*atom->improper_per_atom * sizeof(int);
   if (atom->memcheck("improper_atom4"))
     bytes += nmax*atom->improper_per_atom * sizeof(int);
 
   return bytes;
 }
diff --git a/src/MOLECULE/bond_fene.cpp b/src/MOLECULE/bond_fene.cpp
index babb22689..f1c7b7782 100644
--- a/src/MOLECULE/bond_fene.cpp
+++ b/src/MOLECULE/bond_fene.cpp
@@ -1,261 +1,263 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "bond_fene.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "neighbor.h"
 #include "domain.h"
 #include "comm.h"
 #include "update.h"
 #include "force.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 BondFENE::BondFENE(LAMMPS *lmp) : Bond(lmp)
 {
   TWO_1_3 = pow(2.0,(1.0/3.0));
 }
 
 /* ---------------------------------------------------------------------- */
 
 BondFENE::~BondFENE()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(k);
     memory->sfree(r0);
     memory->sfree(epsilon);
     memory->sfree(sigma);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void BondFENE::compute(int eflag, int vflag)
 {
   int i1,i2,n,type;
   double delx,dely,delz,ebond,fbond;
   double rsq,r0sq,rlogarg,sr2,sr6;
 
   ebond = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   double **x = atom->x;
   double **f = atom->f;
   int **bondlist = neighbor->bondlist;
   int nbondlist = neighbor->nbondlist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < nbondlist; n++) {
     i1 = bondlist[n][0];
     i2 = bondlist[n][1];
     type = bondlist[n][2];
 
     delx = x[i1][0] - x[i2][0];
     dely = x[i1][1] - x[i2][1];
     delz = x[i1][2] - x[i2][2];
     domain->minimum_image(delx,dely,delz);
 
     // force from log term
 
     rsq = delx*delx + dely*dely + delz*delz;
     r0sq = r0[type] * r0[type];
     rlogarg = 1.0 - rsq/r0sq;
 
     // if r -> r0, then rlogarg < 0.0 which is an error
     // issue a warning and reset rlogarg = epsilon
     // if r > 2*r0 something serious is wrong, abort
 
     if (rlogarg < 0.1) {
-      char str[128];
-      sprintf(str,"FENE bond too long: %d %d %d %g",
-              update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
+      char str[128],fstr[64];
+      sprintf(fstr,"FENE bond too long: %s %%d %%d %%g",BIGINT_FORMAT);
+      sprintf(str,fstr,update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
       error->warning(str,0);
       if (rlogarg <= -3.0) error->one("Bad FENE bond");
       rlogarg = 0.1;
     }
 
     fbond = -k[type]/rlogarg;
 
     // force from LJ term
 
     if (rsq < TWO_1_3*sigma[type]*sigma[type]) {
       sr2 = sigma[type]*sigma[type]/rsq;
       sr6 = sr2*sr2*sr2;
       fbond += 48.0*epsilon[type]*sr6*(sr6-0.5)/rsq;
     }
 
     // energy
 
     if (eflag) {
       ebond = -0.5 * k[type]*r0sq*log(rlogarg);
       if (rsq < TWO_1_3*sigma[type]*sigma[type])
 	ebond += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
     }
 
     // apply force to each of 2 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += delx*fbond;
       f[i1][1] += dely*fbond;
       f[i1][2] += delz*fbond;
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] -= delx*fbond;
       f[i2][1] -= dely*fbond;
       f[i2][2] -= delz*fbond;
     }
 
     if (evflag) ev_tally(i1,i2,nlocal,newton_bond,ebond,fbond,delx,dely,delz);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void BondFENE::allocate()
 {
   allocated = 1;
   int n = atom->nbondtypes;
 
   k = (double *) memory->smalloc((n+1)*sizeof(double),"bond:k");
   r0 = (double *) memory->smalloc((n+1)*sizeof(double),"bond:r0");
   epsilon = (double *) memory->smalloc((n+1)*sizeof(double),"bond:epsilon");
   sigma = (double *) memory->smalloc((n+1)*sizeof(double),"bond:sigma");
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"bond:setflag");
   for (int i = 1; i <= n; i++) setflag[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one type
 ------------------------------------------------------------------------- */
 
 void BondFENE::coeff(int narg, char **arg)
 {
   if (narg != 5) error->all("Incorrect args for bond coefficients");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->nbondtypes,ilo,ihi);
 
   double k_one = force->numeric(arg[1]);
   double r0_one = force->numeric(arg[2]);
   double epsilon_one = force->numeric(arg[3]);
   double sigma_one = force->numeric(arg[4]);
 
   int count = 0;
   for (int i = ilo; i <= ihi; i++) {
     k[i] = k_one;
     r0[i] = r0_one;
     epsilon[i] = epsilon_one;
     sigma[i] = sigma_one;
     setflag[i] = 1;
     count++;
   }
 
   if (count == 0) error->all("Incorrect args for bond coefficients");
 }
 
 /* ----------------------------------------------------------------------
    check if special_bond settings are valid
 ------------------------------------------------------------------------- */
 
 void BondFENE::init_style()
 {
   // special bonds should be 0 1 1
 
   if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 ||
       force->special_lj[3] != 1.0) {
     if (comm->me == 0)
       error->warning("Use special bonds = 0,1,1 with bond style fene");
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double BondFENE::equilibrium_distance(int i)
 {
   return 0.97*sigma[i];
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes to restart file
 ------------------------------------------------------------------------- */
 
 void BondFENE::write_restart(FILE *fp)
 {
   fwrite(&k[1],sizeof(double),atom->nbondtypes,fp);
   fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp);
   fwrite(&epsilon[1],sizeof(double),atom->nbondtypes,fp);
   fwrite(&sigma[1],sizeof(double),atom->nbondtypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads from restart file, bcasts
 ------------------------------------------------------------------------- */
 
 void BondFENE::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&k[1],sizeof(double),atom->nbondtypes,fp);
     fread(&r0[1],sizeof(double),atom->nbondtypes,fp);
     fread(&epsilon[1],sizeof(double),atom->nbondtypes,fp);
     fread(&sigma[1],sizeof(double),atom->nbondtypes,fp);
   }
   MPI_Bcast(&k[1],atom->nbondtypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&r0[1],atom->nbondtypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&epsilon[1],atom->nbondtypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&sigma[1],atom->nbondtypes,MPI_DOUBLE,0,world);
 
   for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 double BondFENE::single(int type, double rsq, int i, int j)
 {
   double r0sq = r0[type] * r0[type];
   double rlogarg = 1.0 - rsq/r0sq;
 
   // if r -> r0, then rlogarg < 0.0 which is an error
   // issue a warning and reset rlogarg = epsilon
   // if r > 2*r0 something serious is wrong, abort
 
   if (rlogarg < 0.1) {
-    char str[128];
-    sprintf(str,"FENE bond too long: %d %g",update->ntimestep,sqrt(rsq));
+    char str[128],fstr[64];
+    sprintf(fstr,"FENE bond too long: %s %%g",BIGINT_FORMAT);
+    sprintf(str,fstr,update->ntimestep,sqrt(rsq));
     error->warning(str,0);
     if (rlogarg <= -3.0) error->one("Bad FENE bond");
     rlogarg = 0.1;
   }
 
   double eng = -0.5 * k[type]*r0sq*log(rlogarg);
   if (rsq < TWO_1_3*sigma[type]*sigma[type]) {
     double sr2,sr6;
     sr2 = sigma[type]*sigma[type]/rsq;
     sr6 = sr2*sr2*sr2;
     eng += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
   }
 
   return eng;
 }
diff --git a/src/MOLECULE/bond_fene_expand.cpp b/src/MOLECULE/bond_fene_expand.cpp
index 960786156..588bc3f30 100644
--- a/src/MOLECULE/bond_fene_expand.cpp
+++ b/src/MOLECULE/bond_fene_expand.cpp
@@ -1,275 +1,277 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "bond_fene_expand.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "neighbor.h"
 #include "domain.h"
 #include "comm.h"
 #include "update.h"
 #include "force.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 BondFENEExpand::BondFENEExpand(LAMMPS *lmp) : Bond(lmp)
 {
   TWO_1_3 = pow(2.0,(1.0/3.0));
 }
 
 /* ---------------------------------------------------------------------- */
 
 BondFENEExpand::~BondFENEExpand()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(k);
     memory->sfree(r0);
     memory->sfree(epsilon);
     memory->sfree(sigma);
     memory->sfree(shift);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void BondFENEExpand::compute(int eflag, int vflag)
 {
   int i1,i2,n,type;
   double delx,dely,delz,ebond,fbond;
   double rsq,r0sq,rlogarg,sr2,sr6;
   double r,rshift,rshiftsq;
 
   ebond = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   double **x = atom->x;
   double **f = atom->f;
   int **bondlist = neighbor->bondlist;
   int nbondlist = neighbor->nbondlist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < nbondlist; n++) {
     i1 = bondlist[n][0];
     i2 = bondlist[n][1];
     type = bondlist[n][2];
 
     delx = x[i1][0] - x[i2][0];
     dely = x[i1][1] - x[i2][1];
     delz = x[i1][2] - x[i2][2];
     domain->minimum_image(delx,dely,delz);
 
     // force from log term
 
     rsq = delx*delx + dely*dely + delz*delz;
     r = sqrt(rsq);
     rshift = r - shift[type];
     rshiftsq = rshift*rshift;
     r0sq = r0[type] * r0[type];
     rlogarg = 1.0 - rshiftsq/r0sq;
 
     // if r -> r0, then rlogarg < 0.0 which is an error
     // issue a warning and reset rlogarg = epsilon
     // if r > 2*r0 something serious is wrong, abort
 
     if (rlogarg < 0.1) {
-      char str[128];
-      sprintf(str,"FENE bond too long: %d %d %d %g",
-              update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
+      char str[128],fstr[64];
+      sprintf(fstr,"FENE bond too long: %s %%d %%d %%g",BIGINT_FORMAT);
+      sprintf(str,fstr,update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
       error->warning(str,0);
       if (rlogarg <= -3.0) error->one("Bad FENE bond");
       rlogarg = 0.1;
     }
 
     fbond = -k[type]*rshift/rlogarg/r;
 
     // force from LJ term
 
     if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) {
       sr2 = sigma[type]*sigma[type]/rshiftsq;
       sr6 = sr2*sr2*sr2;
       fbond += 48.0*epsilon[type]*sr6*(sr6-0.5)/rshift/r;
     }
 
     // energy
 
     if (eflag) {
       ebond = -0.5 * k[type]*r0sq*log(rlogarg);
       if (rshiftsq < TWO_1_3*sigma[type]*sigma[type])
 	ebond += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
     }
 
     // apply force to each of 2 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += delx*fbond;
       f[i1][1] += dely*fbond;
       f[i1][2] += delz*fbond;
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] -= delx*fbond;
       f[i2][1] -= dely*fbond;
       f[i2][2] -= delz*fbond;
     }
 
     if (evflag) ev_tally(i1,i2,nlocal,newton_bond,ebond,fbond,delx,dely,delz);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void BondFENEExpand::allocate()
 {
   allocated = 1;
   int n = atom->nbondtypes;
 
   k = (double *) memory->smalloc((n+1)*sizeof(double),"bond:k");
   r0 = (double *) memory->smalloc((n+1)*sizeof(double),"bond:r0");
   epsilon = (double *) memory->smalloc((n+1)*sizeof(double),"bond:epsilon");
   sigma = (double *) memory->smalloc((n+1)*sizeof(double),"bond:sigma");
   shift = (double *) memory->smalloc((n+1)*sizeof(double),"bond:shift");
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"bond:setflag");
   for (int i = 1; i <= n; i++) setflag[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one type
 ------------------------------------------------------------------------- */
 
 void BondFENEExpand::coeff(int narg, char **arg)
 {
   if (narg != 6) error->all("Incorrect args for bond coefficients");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->nbondtypes,ilo,ihi);
 
   double k_one = force->numeric(arg[1]);
   double r0_one = force->numeric(arg[2]);
   double epsilon_one = force->numeric(arg[3]);
   double sigma_one = force->numeric(arg[4]);
   double shift_one = force->numeric(arg[5]);
 
   int count = 0;
   for (int i = ilo; i <= ihi; i++) {
     k[i] = k_one;
     r0[i] = r0_one;
     epsilon[i] = epsilon_one;
     sigma[i] = sigma_one;
     shift[i] = shift_one;
     setflag[i] = 1;
     count++;
   }
 
   if (count == 0) error->all("Incorrect args for bond coefficients");
 }
 
 /* ----------------------------------------------------------------------
    check if special_bond settings are valid
 ------------------------------------------------------------------------- */
 
 void BondFENEExpand::init_style()
 {
   // special bonds should be 0 1 1
 
   if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 ||
       force->special_lj[3] != 1.0) {
     if (comm->me == 0)
       error->warning("Use special bonds = 0,1,1 with bond style fene/expand");
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double BondFENEExpand::equilibrium_distance(int i)
 {
   return 0.97*sigma[i] + shift[i];
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes to restart file
 ------------------------------------------------------------------------- */
 
 void BondFENEExpand::write_restart(FILE *fp)
 {
   fwrite(&k[1],sizeof(double),atom->nbondtypes,fp);
   fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp);
   fwrite(&epsilon[1],sizeof(double),atom->nbondtypes,fp);
   fwrite(&sigma[1],sizeof(double),atom->nbondtypes,fp);
   fwrite(&shift[1],sizeof(double),atom->nbondtypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads from restart file, bcasts
 ------------------------------------------------------------------------- */
 
 void BondFENEExpand::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&k[1],sizeof(double),atom->nbondtypes,fp);
     fread(&r0[1],sizeof(double),atom->nbondtypes,fp);
     fread(&epsilon[1],sizeof(double),atom->nbondtypes,fp);
     fread(&sigma[1],sizeof(double),atom->nbondtypes,fp);
     fread(&shift[1],sizeof(double),atom->nbondtypes,fp);
   }
   MPI_Bcast(&k[1],atom->nbondtypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&r0[1],atom->nbondtypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&epsilon[1],atom->nbondtypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&sigma[1],atom->nbondtypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&shift[1],atom->nbondtypes,MPI_DOUBLE,0,world);
 
   for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 double BondFENEExpand::single(int type, double rsq, int i, int j)
 {
   double r = sqrt(rsq);
   double rshift = r - shift[type];
   double rshiftsq = rshift*rshift;
   double r0sq = r0[type] * r0[type];
   double rlogarg = 1.0 - rshiftsq/r0sq;
 
   // if r -> r0, then rlogarg < 0.0 which is an error
   // issue a warning and reset rlogarg = epsilon
   // if r > 2*r0 something serious is wrong, abort
 
   if (rlogarg < 0.1) {
-    char str[128];
-    sprintf(str,"FENE bond too long: %d %g",update->ntimestep,sqrt(rsq));
+    char str[128],fstr[64];
+    sprintf(fstr,"FENE bond too long: %s %%g",BIGINT_FORMAT);
+    sprintf(str,fstr,update->ntimestep,sqrt(rsq));
     error->warning(str,0);
     if (rlogarg <= -3.0) error->one("Bad FENE bond");
     rlogarg = 0.1;
   }
 
   double eng = -0.5 * k[type]*r0sq*log(rlogarg);
   if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) {
     double sr2,sr6;
     sr2 = sigma[type]*sigma[type]/rshiftsq;
     sr6 = sr2*sr2*sr2;
     eng += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
   }
 
   return eng;
 }
diff --git a/src/MOLECULE/dihedral_charmm.cpp b/src/MOLECULE/dihedral_charmm.cpp
index f2b7d4945..2aae7fd3e 100644
--- a/src/MOLECULE/dihedral_charmm.cpp
+++ b/src/MOLECULE/dihedral_charmm.cpp
@@ -1,432 +1,433 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Paul Crozier (SNL)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "stdlib.h"
 #include "dihedral_charmm.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "comm.h"
 #include "neighbor.h"
 #include "domain.h"
 #include "force.h"
 #include "pair.h"
 #include "update.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define TOLERANCE 0.05
 
 /* ---------------------------------------------------------------------- */
 
 DihedralCharmm::DihedralCharmm(LAMMPS *lmp) : Dihedral(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 DihedralCharmm::~DihedralCharmm()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(k);
     memory->sfree(multiplicity);
     memory->sfree(shift);
     memory->sfree(cos_shift);
     memory->sfree(sin_shift);
     memory->sfree(weight);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralCharmm::compute(int eflag, int vflag)
 {
   int i1,i2,i3,i4,i,m,n,type;
   double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
   double edihedral,f1[3],f2[3],f3[3],f4[3];
   double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv;
   double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb;
   double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz;  
   double c,s,p,sx2,sy2,sz2;
   int itype,jtype;
   double delx,dely,delz,rsq,r2inv,r6inv;
   double forcecoul,forcelj,fpair,ecoul,evdwl;
 
   edihedral = evdwl = ecoul = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   // insure pair->ev_tally() will use 1-4 virial contribution
 
   if (weightflag && vflag_global == 2)
     force->pair->vflag_either = force->pair->vflag_global = 1;
 
   double **x = atom->x;
   double **f = atom->f;
   double *q = atom->q;
   int *atomtype = atom->type;
   int **dihedrallist = neighbor->dihedrallist;
   int ndihedrallist = neighbor->ndihedrallist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
   double qqrd2e = force->qqrd2e;
 
   for (n = 0; n < ndihedrallist; n++) {
     i1 = dihedrallist[n][0];
     i2 = dihedrallist[n][1];
     i3 = dihedrallist[n][2];
     i4 = dihedrallist[n][3];
     type = dihedrallist[n][4];
 
     // 1st bond
 
     vb1x = x[i1][0] - x[i2][0];
     vb1y = x[i1][1] - x[i2][1];
     vb1z = x[i1][2] - x[i2][2];
     domain->minimum_image(vb1x,vb1y,vb1z);
 
     // 2nd bond
 
     vb2x = x[i3][0] - x[i2][0];
     vb2y = x[i3][1] - x[i2][1];
     vb2z = x[i3][2] - x[i2][2];
     domain->minimum_image(vb2x,vb2y,vb2z);
 
     vb2xm = -vb2x;
     vb2ym = -vb2y;
     vb2zm = -vb2z;
     domain->minimum_image(vb2xm,vb2ym,vb2zm);
 
     // 3rd bond
 
     vb3x = x[i4][0] - x[i3][0];
     vb3y = x[i4][1] - x[i3][1];
     vb3z = x[i4][2] - x[i3][2];
     domain->minimum_image(vb3x,vb3y,vb3z);
     
     ax = vb1y*vb2zm - vb1z*vb2ym;
     ay = vb1z*vb2xm - vb1x*vb2zm;
     az = vb1x*vb2ym - vb1y*vb2xm;
     bx = vb3y*vb2zm - vb3z*vb2ym;
     by = vb3z*vb2xm - vb3x*vb2zm;
     bz = vb3x*vb2ym - vb3y*vb2xm;
 
     rasq = ax*ax + ay*ay + az*az;
     rbsq = bx*bx + by*by + bz*bz;
     rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm;
     rg = sqrt(rgsq);
     
     rginv = ra2inv = rb2inv = 0.0;
     if (rg > 0) rginv = 1.0/rg;
     if (rasq > 0) ra2inv = 1.0/rasq;
     if (rbsq > 0) rb2inv = 1.0/rbsq;
     rabinv = sqrt(ra2inv*rb2inv);
 
     c = (ax*bx + ay*by + az*bz)*rabinv;
     s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z);
 
     // error check
 
     if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
       int me;
       MPI_Comm_rank(world,&me);
       if (screen) {
-	char str[128];
-	sprintf(str,"Dihedral problem: %d %d %d %d %d %d",
-		me,update->ntimestep,
+	char str[128],fstr[64];
+	sprintf(fstr,"Dihedral problem: %%d %s %%d %%d %%d %%d",BIGINT_FORMAT);
+	sprintf(str,fstr,me,update->ntimestep,
 		atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
 	error->warning(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]);
 	fprintf(screen,"  3rd atom: %d %g %g %g\n",
 		me,x[i3][0],x[i3][1],x[i3][2]);
 	fprintf(screen,"  4th atom: %d %g %g %g\n",
 		me,x[i4][0],x[i4][1],x[i4][2]);
       }
     }
     
     if (c > 1.0) c = 1.0;
     if (c < -1.0) c = -1.0;
          
     m = multiplicity[type];
     p = 1.0;
     df1 = 0.0;
     
     for (i = 0; i < m; i++) {
       ddf1 = p*c - df1*s;
       df1 = p*s + df1*c;
       p = ddf1;
     }
 
     p = p*cos_shift[type] + df1*sin_shift[type];
     df1 = df1*cos_shift[type] - ddf1*sin_shift[type];
     df1 *= -m;
     p += 1.0;
  
     if (m == 0) {
       p = 1.0 + cos_shift[type];
       df1 = 0.0;
     }
 
     if (eflag) edihedral = k[type] * p; 
        
     fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm;
     hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm;
     fga = fg*ra2inv*rginv;
     hgb = hg*rb2inv*rginv;
     gaa = -ra2inv*rg;
     gbb = rb2inv*rg;
     
     dtfx = gaa*ax;
     dtfy = gaa*ay;
     dtfz = gaa*az;
     dtgx = fga*ax - hgb*bx;
     dtgy = fga*ay - hgb*by;
     dtgz = fga*az - hgb*bz;
     dthx = gbb*bx;
     dthy = gbb*by;
     dthz = gbb*bz;
     
     df = -k[type] * df1;
  
     sx2 = df*dtgx;
     sy2 = df*dtgy;
     sz2 = df*dtgz;
 
     f1[0] = df*dtfx;
     f1[1] = df*dtfy;
     f1[2] = df*dtfz;
 
     f2[0] = sx2 - f1[0];
     f2[1] = sy2 - f1[1];
     f2[2] = sz2 - f1[2];
 
     f4[0] = df*dthx;
     f4[1] = df*dthy;
     f4[2] = df*dthz;
 
     f3[0] = -sx2 - f4[0];
     f3[1] = -sy2 - f4[1];
     f3[2] = -sz2 - f4[2];
 
     // apply force to each of 4 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += f1[0];
       f[i1][1] += f1[1];
       f[i1][2] += f1[2];
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] += f2[0];
       f[i2][1] += f2[1];
       f[i2][2] += f2[2];
     }
 
     if (newton_bond || i3 < nlocal) {
       f[i3][0] += f3[0];
       f[i3][1] += f3[1];
       f[i3][2] += f3[2];
     }
 
     if (newton_bond || i4 < nlocal) {
       f[i4][0] += f4[0];
       f[i4][1] += f4[1];
       f[i4][2] += f4[2];
     }
 
     if (evflag)
       ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4,
 	       vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
 
     // 1-4 LJ and Coulomb interactions
     // tally energy/virial in pair, using newton_bond as newton flag
 
     if (weight[type] > 0.0) {
       itype = atomtype[i1];
       jtype = atomtype[i4];
 
       delx = x[i1][0] - x[i4][0];
       dely = x[i1][1] - x[i4][1];
       delz = x[i1][2] - x[i4][2];
       domain->minimum_image(delx,dely,delz);
       rsq = delx*delx + dely*dely + delz*delz;
       r2inv = 1.0/rsq;
       r6inv = r2inv*r2inv*r2inv;
 
       if (implicit) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv;
       else forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv);
       forcelj = r6inv * (lj14_1[itype][jtype]*r6inv - lj14_2[itype][jtype]);
       fpair = weight[type] * (forcelj+forcecoul)*r2inv;
 
       if (eflag) {
 	ecoul = weight[type] * forcecoul;
 	evdwl = r6inv * (lj14_3[itype][jtype]*r6inv - lj14_4[itype][jtype]);
 	evdwl *= weight[type];
       }
 
       if (newton_bond || i1 < nlocal) {
 	f[i1][0] += delx*fpair;
 	f[i1][1] += dely*fpair;
 	f[i1][2] += delz*fpair;
       }
       if (newton_bond || i4 < nlocal) {
 	f[i4][0] -= delx*fpair;
 	f[i4][1] -= dely*fpair;
 	f[i4][2] -= delz*fpair;
       }
 
       if (evflag) force->pair->ev_tally(i1,i4,nlocal,newton_bond,
 					evdwl,ecoul,fpair,delx,dely,delz);
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralCharmm::allocate()
 {
   allocated = 1;
   int n = atom->ndihedraltypes;
 
   k = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k");
   multiplicity = (int *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:multiplicity");
   shift = (int *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:shift");
   cos_shift = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:cos_shift");
   sin_shift = (double *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:sin_shift");
   weight = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:weight");
 
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag");
   for (int i = 1; i <= n; i++) setflag[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one type
 ------------------------------------------------------------------------- */
 
 void DihedralCharmm::coeff(int narg, char **arg)
 {
   if (narg != 5) error->all("Incorrect args for dihedral coefficients");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi);
   
   // require integer values of shift for backwards compatibility
   // arbitrary phase angle shift could be allowed, but would break
   //   backwards compatibility and is probably not needed
   
   double k_one = force->numeric(arg[1]);
   int multiplicity_one = force->inumeric(arg[2]);
   int shift_one = force->inumeric(arg[3]);
   double weight_one = force->numeric(arg[4]);
 
   if (multiplicity_one < 0)
     error->all("Incorrect multiplicity arg for dihedral coefficients");
   if (weight_one < 0.0 || weight_one > 1.0) 
     error->all("Incorrect weight arg for dihedral coefficients");
 
   double PI = 4.0*atan(1.0);
                        
   int count = 0;
   for (int i = ilo; i <= ihi; i++) {
     k[i] = k_one;
     shift[i] = shift_one;
     cos_shift[i] = cos(PI*shift_one/180.0);
     sin_shift[i] = sin(PI*shift_one/180.0);
     multiplicity[i] = multiplicity_one;
     weight[i] = weight_one;
     setflag[i] = 1;
     count++;
   }
 
   if (count == 0) error->all("Incorrect args for dihedral coefficients");
 }
 
 /* ----------------------------------------------------------------------
    error check and initialize all values needed for force computation 
 ------------------------------------------------------------------------- */
 
 void DihedralCharmm::init_style()
 {
   // insure use of CHARMM pair_style if any weight factors are non-zero
   // set local ptrs to LJ 14 arrays setup by Pair
 
   weightflag = 0;
   for (int i = 1; i <= atom->ndihedraltypes; i++)
     if (weight[i] > 0.0) weightflag = 1;
 
   if (weightflag) {
     int itmp;
     if (force->pair == NULL)
       error->all("Dihedral charmm is incompatible with Pair style");
     lj14_1 = (double **) force->pair->extract("lj14_1",itmp);
     lj14_2 = (double **) force->pair->extract("lj14_2",itmp);
     lj14_3 = (double **) force->pair->extract("lj14_3",itmp);
     lj14_4 = (double **) force->pair->extract("lj14_4",itmp);
     int *ptr = (int *) force->pair->extract("implicit",itmp);
     if (!lj14_1 || !lj14_2 || !lj14_3 || !lj14_4 || !ptr)
       error->all("Dihedral charmm is incompatible with Pair style");
     implicit = *ptr;
   }
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out coeffs to restart file 
 ------------------------------------------------------------------------- */
 
 void DihedralCharmm::write_restart(FILE *fp)
 {
   fwrite(&k[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp);
   fwrite(&shift[1],sizeof(int),atom->ndihedraltypes,fp);
   fwrite(&weight[1],sizeof(double),atom->ndihedraltypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads coeffs from restart file, bcasts them 
 ------------------------------------------------------------------------- */
 
 void DihedralCharmm::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&k[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp);
     fread(&shift[1],sizeof(int),atom->ndihedraltypes,fp);
     fread(&weight[1],sizeof(double),atom->ndihedraltypes,fp);
   }
   MPI_Bcast(&k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&multiplicity[1],atom->ndihedraltypes,MPI_INT,0,world);
   MPI_Bcast(&shift[1],atom->ndihedraltypes,MPI_INT,0,world);
   MPI_Bcast(&weight[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
 
   double PI = 4.0*atan(1.0);
   for (int i = 1; i <= atom->ndihedraltypes; i++) {
     setflag[i] = 1;
     cos_shift[i] = cos(PI*shift[i]/180.0);
     sin_shift[i] = sin(PI*shift[i]/180.0);
   }
 }
diff --git a/src/MOLECULE/dihedral_harmonic.cpp b/src/MOLECULE/dihedral_harmonic.cpp
index 6e76a66dd..a2f62f5b4 100644
--- a/src/MOLECULE/dihedral_harmonic.cpp
+++ b/src/MOLECULE/dihedral_harmonic.cpp
@@ -1,353 +1,354 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Paul Crozier (SNL)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "stdlib.h"
 #include "dihedral_harmonic.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "comm.h"
 #include "neighbor.h"
 #include "domain.h"
 #include "force.h"
 #include "update.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define TOLERANCE 0.05
 #define SMALL     0.001
 
 /* ---------------------------------------------------------------------- */
 
 DihedralHarmonic::DihedralHarmonic(LAMMPS *lmp) : Dihedral(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 DihedralHarmonic::~DihedralHarmonic()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(k);
     memory->sfree(sign);
     memory->sfree(multiplicity);
     memory->sfree(cos_shift);
     memory->sfree(sin_shift);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralHarmonic::compute(int eflag, int vflag)
 {
   int i1,i2,i3,i4,i,m,n,type;
   double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
   double edihedral,f1[3],f2[3],f3[3],f4[3];
   double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv;
   double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb;
   double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz;  
   double c,s,p,sx2,sy2,sz2;
 
   edihedral = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   double **x = atom->x;
   double **f = atom->f;
   int **dihedrallist = neighbor->dihedrallist;
   int ndihedrallist = neighbor->ndihedrallist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < ndihedrallist; n++) {
     i1 = dihedrallist[n][0];
     i2 = dihedrallist[n][1];
     i3 = dihedrallist[n][2];
     i4 = dihedrallist[n][3];
     type = dihedrallist[n][4];
 
     // 1st bond
 
     vb1x = x[i1][0] - x[i2][0];
     vb1y = x[i1][1] - x[i2][1];
     vb1z = x[i1][2] - x[i2][2];
     domain->minimum_image(vb1x,vb1y,vb1z);
 
     // 2nd bond
 
     vb2x = x[i3][0] - x[i2][0];
     vb2y = x[i3][1] - x[i2][1];
     vb2z = x[i3][2] - x[i2][2];
     domain->minimum_image(vb2x,vb2y,vb2z);
 
     vb2xm = -vb2x;
     vb2ym = -vb2y;
     vb2zm = -vb2z;
     domain->minimum_image(vb2xm,vb2ym,vb2zm);
 
     // 3rd bond
 
     vb3x = x[i4][0] - x[i3][0];
     vb3y = x[i4][1] - x[i3][1];
     vb3z = x[i4][2] - x[i3][2];
     domain->minimum_image(vb3x,vb3y,vb3z);
     
     // c,s calculation
 
     ax = vb1y*vb2zm - vb1z*vb2ym;
     ay = vb1z*vb2xm - vb1x*vb2zm;
     az = vb1x*vb2ym - vb1y*vb2xm;
     bx = vb3y*vb2zm - vb3z*vb2ym;
     by = vb3z*vb2xm - vb3x*vb2zm;
     bz = vb3x*vb2ym - vb3y*vb2xm;
 
     rasq = ax*ax + ay*ay + az*az;
     rbsq = bx*bx + by*by + bz*bz;
     rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm;
     rg = sqrt(rgsq);
     
     rginv = ra2inv = rb2inv = 0.0;
     if (rg > 0) rginv = 1.0/rg;
     if (rasq > 0) ra2inv = 1.0/rasq;
     if (rbsq > 0) rb2inv = 1.0/rbsq;
     rabinv = sqrt(ra2inv*rb2inv);
 
     c = (ax*bx + ay*by + az*bz)*rabinv;
     s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z);
 
     // error check
 
     if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
       int me;
       MPI_Comm_rank(world,&me);
       if (screen) {
-	char str[128];
-	sprintf(str,"Dihedral problem: %d %d %d %d %d %d",
-		me,update->ntimestep,
+	char str[128],fstr[64];
+	sprintf(fstr,"Dihedral problem: %%d %s %%d %%d %%d %%d",BIGINT_FORMAT);
+	sprintf(str,fstr,me,update->ntimestep,
 		atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
 	error->warning(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]);
 	fprintf(screen,"  3rd atom: %d %g %g %g\n",
 		me,x[i3][0],x[i3][1],x[i3][2]);
 	fprintf(screen,"  4th atom: %d %g %g %g\n",
 		me,x[i4][0],x[i4][1],x[i4][2]);
       }
     }
     
     if (c > 1.0) c = 1.0;
     if (c < -1.0) c = -1.0;
          
     m = multiplicity[type];
     p = 1.0;
     df1 = 0.0;
     
     for (i = 0; i < m; i++) {
       ddf1 = p*c - df1*s;
       df1 = p*s + df1*c;
       p = ddf1;
     }
 
     p = p*cos_shift[type] + df1*sin_shift[type];
     df1 = df1*cos_shift[type] - ddf1*sin_shift[type];
     df1 *= -m;
     p += 1.0;
  
     if (m == 0) {
       p = 1.0 + cos_shift[type];
       df1 = 0.0;
     }
 
     if (eflag) edihedral = k[type] * p; 
        
     fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm;
     hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm;
     fga = fg*ra2inv*rginv;
     hgb = hg*rb2inv*rginv;
     gaa = -ra2inv*rg;
     gbb = rb2inv*rg;
     
     dtfx = gaa*ax;
     dtfy = gaa*ay;
     dtfz = gaa*az;
     dtgx = fga*ax - hgb*bx;
     dtgy = fga*ay - hgb*by;
     dtgz = fga*az - hgb*bz;
     dthx = gbb*bx;
     dthy = gbb*by;
     dthz = gbb*bz;
     
     df = -k[type] * df1;
     
     sx2 = df*dtgx;
     sy2 = df*dtgy;
     sz2 = df*dtgz;
 
     f1[0] = df*dtfx;
     f1[1] = df*dtfy;
     f1[2] = df*dtfz;
 
     f2[0] = sx2 - f1[0];
     f2[1] = sy2 - f1[1];
     f2[2] = sz2 - f1[2];
 
     f4[0] = df*dthx;
     f4[1] = df*dthy;
     f4[2] = df*dthz;
 
     f3[0] = -sx2 - f4[0];
     f3[1] = -sy2 - f4[1];
     f3[2] = -sz2 - f4[2];
     
     // apply force to each of 4 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += f1[0];
       f[i1][1] += f1[1];
       f[i1][2] += f1[2];
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] += f2[0];
       f[i2][1] += f2[1];
       f[i2][2] += f2[2];
     }
 
     if (newton_bond || i3 < nlocal) {
       f[i3][0] += f3[0];
       f[i3][1] += f3[1];
       f[i3][2] += f3[2];
     }
 
     if (newton_bond || i4 < nlocal) {
       f[i4][0] += f4[0];
       f[i4][1] += f4[1];
       f[i4][2] += f4[2];
     }
 
     if (evflag)
       ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4,
 	       vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralHarmonic::allocate()
 {
   allocated = 1;
   int n = atom->ndihedraltypes;
 
   k = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k");
   sign = (int *) memory->smalloc((n+1)*sizeof(double),"dihedral:sign");
   multiplicity = (int *) 
     memory->smalloc((n+1)*sizeof(double),"dihedral:multiplicity");
   cos_shift = (double *)
     memory->smalloc((n+1)*sizeof(double),"dihedral:cos_shift");
   sin_shift = (double *)
     memory->smalloc((n+1)*sizeof(double),"dihedral:sin_shift");
 
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag");
   for (int i = 1; i <= n; i++) setflag[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one type
 ------------------------------------------------------------------------- */
 
 void DihedralHarmonic::coeff(int narg, char **arg)
 {
   if (narg != 4) error->all("Incorrect args for dihedral coefficients");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi);
 
   double k_one = force->numeric(arg[1]);
   int sign_one = force->inumeric(arg[2]);
   int multiplicity_one = force->inumeric(arg[3]);
 
   // require sign = +/- 1 for backwards compatibility
   // arbitrary phase angle shift could be allowed, but would break
   //   backwards compatibility and is probably not needed
   
   if (sign_one != -1 && sign_one != 1)
     error->all("Incorrect sign arg for dihedral coefficients");
   if (multiplicity_one < 0)
     error->all("Incorrect multiplicity arg for dihedral coefficients");
                        
   int count = 0;
   for (int i = ilo; i <= ihi; i++) {
     k[i] = k_one;
     sign[i] = sign_one;
     if (sign[i] == 1) {
       cos_shift[i] = 1;
       sin_shift[i] = 0;
     } else {
       cos_shift[i] = -1;
       sin_shift[i] = 0;
     }
     multiplicity[i] = multiplicity_one;
     setflag[i] = 1;
     count++;
   }
 
   if (count == 0) error->all("Incorrect args for dihedral coefficients");
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out coeffs to restart file 
 ------------------------------------------------------------------------- */
 
 void DihedralHarmonic::write_restart(FILE *fp)
 {
   fwrite(&k[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&sign[1],sizeof(int),atom->ndihedraltypes,fp);
   fwrite(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads coeffs from restart file, bcasts them 
 ------------------------------------------------------------------------- */
 
 void DihedralHarmonic::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&k[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&sign[1],sizeof(int),atom->ndihedraltypes,fp);
     fread(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp);
   }
   MPI_Bcast(&k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&sign[1],atom->ndihedraltypes,MPI_INT,0,world);
   MPI_Bcast(&multiplicity[1],atom->ndihedraltypes,MPI_INT,0,world);
  
   for (int i = 1; i <= atom->ndihedraltypes; i++) {
     setflag[i] = 1;
     if (sign[i] == 1) {
       cos_shift[i] = 1;
       sin_shift[i] = 0;
     } else {
       cos_shift[i] = -1;
       sin_shift[i] = 0;	    
     }
   }
 }
diff --git a/src/MOLECULE/dihedral_helix.cpp b/src/MOLECULE/dihedral_helix.cpp
index f5b56b3e4..6b9520339 100644
--- a/src/MOLECULE/dihedral_helix.cpp
+++ b/src/MOLECULE/dihedral_helix.cpp
@@ -1,337 +1,338 @@
 /* ----------------------------------------------------------------------
    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: Naveen Michaud-Agrawal (Johns Hopkins U) and
                          Mark Stevens (Sandia)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdlib.h"
 #include "mpi.h"
 #include "dihedral_helix.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "neighbor.h"
 #include "domain.h"
 #include "comm.h"
 #include "force.h"
 #include "update.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define TOLERANCE 0.05
 #define SMALL     0.001
 #define SMALLER   0.00001
 
 /* ---------------------------------------------------------------------- */
 
 DihedralHelix::DihedralHelix(LAMMPS *lmp) : Dihedral(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 DihedralHelix::~DihedralHelix()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(aphi);
     memory->sfree(bphi);
     memory->sfree(cphi);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralHelix::compute(int eflag, int vflag)
 {
   int i1,i2,i3,i4,n,type;
   double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
   double edihedral,f1[3],f2[3],f3[3],f4[3];
   double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
   double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
   double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22;
   double a33,a12,a13,a23,sx2,sy2,sz2;
   double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
 
   edihedral = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   double **x = atom->x;
   double **f = atom->f;
   int **dihedrallist = neighbor->dihedrallist;
   int ndihedrallist = neighbor->ndihedrallist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < ndihedrallist; n++) {
     i1 = dihedrallist[n][0];
     i2 = dihedrallist[n][1];
     i3 = dihedrallist[n][2];
     i4 = dihedrallist[n][3];
     type = dihedrallist[n][4];
 
     // 1st bond
 
     vb1x = x[i1][0] - x[i2][0];
     vb1y = x[i1][1] - x[i2][1];
     vb1z = x[i1][2] - x[i2][2];
     domain->minimum_image(vb1x,vb1y,vb1z);
 
     // 2nd bond
 
     vb2x = x[i3][0] - x[i2][0];
     vb2y = x[i3][1] - x[i2][1];
     vb2z = x[i3][2] - x[i2][2];
     domain->minimum_image(vb2x,vb2y,vb2z);
 
     vb2xm = -vb2x;
     vb2ym = -vb2y;
     vb2zm = -vb2z;
     domain->minimum_image(vb2xm,vb2ym,vb2zm);
 
     // 3rd bond
 
     vb3x = x[i4][0] - x[i3][0];
     vb3y = x[i4][1] - x[i3][1];
     vb3z = x[i4][2] - x[i3][2];
     domain->minimum_image(vb3x,vb3y,vb3z);
 
     // c0 calculation
         
     sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
     sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
     sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
         
     rb1 = sqrt(sb1);
     rb3 = sqrt(sb3);
         
     c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
 
     // 1st and 2nd angle
         
     b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
     b1mag = sqrt(b1mag2);
     b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
     b2mag = sqrt(b2mag2);
     b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
     b3mag = sqrt(b3mag2);
 
     ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
     r12c1 = 1.0 / (b1mag*b2mag);
     c1mag = ctmp * r12c1;
 
     ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
     r12c2 = 1.0 / (b2mag*b3mag);
     c2mag = ctmp * r12c2;
 
     // cos and sin of 2 angles and final c
 
     sin2 = MAX(1.0 - c1mag*c1mag,0.0);
     sc1 = sqrt(sin2);
     if (sc1 < SMALL) sc1 = SMALL;
     sc1 = 1.0/sc1;
 
     sin2 = MAX(1.0 - c2mag*c2mag,0.0);
     sc2 = sqrt(sin2);
     if (sc2 < SMALL) sc2 = SMALL;
     sc2 = 1.0/sc2;
 
     s1 = sc1 * sc1;
     s2 = sc2 * sc2;
     s12 = sc1 * sc2;
     c = (c0 + c1mag*c2mag) * s12;
 
     cx = vb1y*vb2z - vb1z*vb2y;
     cy = vb1z*vb2x - vb1x*vb2z;
     cz = vb1x*vb2y - vb1y*vb2x;
     cmag = sqrt(cx*cx + cy*cy + cz*cz);
     dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag;
     
     // error check
 
     if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
       int me;
       MPI_Comm_rank(world,&me);
       if (screen) {
-	char str[128];
-	sprintf(str,"Dihedral problem: %d %d %d %d %d %d",
-		me,update->ntimestep,
+	char str[128],fstr[64];
+	sprintf(fstr,"Dihedral problem: %%d %s %%d %%d %%d %%d",BIGINT_FORMAT);
+	sprintf(str,fstr,me,update->ntimestep,
 		atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
 	error->warning(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]);
 	fprintf(screen,"  3rd atom: %d %g %g %g\n",
 		me,x[i3][0],x[i3][1],x[i3][2]);
 	fprintf(screen,"  4th atom: %d %g %g %g\n",
 		me,x[i4][0],x[i4][1],x[i4][2]);
       }
     }
     
     if (c > 1.0) c = 1.0;
     if (c < -1.0) c = -1.0;
 
     phi = acos(c);
     if (dx < 0.0) phi *= -1.0;
     si = sin(phi);
     if (fabs(si) < SMALLER) si = SMALLER;
     siinv = 1.0/si;
 
     p = aphi[type]*(1.0 - c) + bphi[type]*(1.0 + cos(3.0*phi)) +
       cphi[type]*(1.0 + cos(phi + 0.25*PI));
     pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv +
       cphi[type]*sin(phi + 0.25*PI)*siinv;
 
     if (eflag) edihedral = p;
 
     a = pd;
     c = c * a;
     s12 = s12 * a;
     a11 = c*sb1*s1;
     a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
     a33 = c*sb3*s2;
     a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12);
     a13 = -rb1*rb3*s12;
     a23 = r12c2 * (c2mag*c*s2 + c1mag*s12);
 
     sx2  = a12*vb1x + a22*vb2x + a23*vb3x;
     sy2  = a12*vb1y + a22*vb2y + a23*vb3y;
     sz2  = a12*vb1z + a22*vb2z + a23*vb3z;
 
     f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
     f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
     f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
 
     f2[0] = -sx2 - f1[0];
     f2[1] = -sy2 - f1[1];
     f2[2] = -sz2 - f1[2];
 
     f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
     f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
     f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
 
     f3[0] = sx2 - f4[0];
     f3[1] = sy2 - f4[1];
     f3[2] = sz2 - f4[2];
 
     // apply force to each of 4 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += f1[0];
       f[i1][1] += f1[1];
       f[i1][2] += f1[2];
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] += f2[0];
       f[i2][1] += f2[1];
       f[i2][2] += f2[2];
     }
 
     if (newton_bond || i3 < nlocal) {
       f[i3][0] += f3[0];
       f[i3][1] += f3[1];
       f[i3][2] += f3[2];
     }
 
     if (newton_bond || i4 < nlocal) {
       f[i4][0] += f4[0];
       f[i4][1] += f4[1];
       f[i4][2] += f4[2];
     }
 
     if (evflag)
       ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4,
 	       vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralHelix::allocate()
 {
   allocated = 1;
   int n = atom->ndihedraltypes;
 
   aphi = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:aphi");
   bphi = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:bphi");
   cphi = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:cphi");
 
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag");
   for (int i = 1; i <= n; i++) setflag[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs from one line in input script
 ------------------------------------------------------------------------- */
 
 void DihedralHelix::coeff(int narg, char **arg)
 {
   if (narg != 4) error->all("Incorrect args for dihedral coefficients");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi);
 
   double aphi_one = force->numeric(arg[1]);
   double bphi_one = force->numeric(arg[2]);
   double cphi_one = force->numeric(arg[3]);
 
   int count = 0;
   for (int i = ilo; i <= ihi; i++) {
     aphi[i] = aphi_one;
     bphi[i] = bphi_one;
     cphi[i] = cphi_one;
     setflag[i] = 1;
     count++;
   }
 
   if (count == 0) error->all("Incorrect args for dihedral coefficients");
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out coeffs to restart file 
 ------------------------------------------------------------------------- */
 
 void DihedralHelix::write_restart(FILE *fp)
 {
   fwrite(&aphi[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&bphi[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&cphi[1],sizeof(double),atom->ndihedraltypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads coeffs from restart file, bcasts them 
 ------------------------------------------------------------------------- */
 
 void DihedralHelix::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&aphi[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&bphi[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&cphi[1],sizeof(double),atom->ndihedraltypes,fp);
   }
   MPI_Bcast(&aphi[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&bphi[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&cphi[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
 
   for (int i = 1; i <= atom->ndihedraltypes; i++) setflag[i] = 1;
 }
diff --git a/src/MOLECULE/dihedral_multi_harmonic.cpp b/src/MOLECULE/dihedral_multi_harmonic.cpp
index e9758cf47..d369db203 100644
--- a/src/MOLECULE/dihedral_multi_harmonic.cpp
+++ b/src/MOLECULE/dihedral_multi_harmonic.cpp
@@ -1,336 +1,339 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mathias Puetz (SNL) and friends
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdlib.h"
 #include "dihedral_multi_harmonic.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "neighbor.h"
 #include "domain.h"
 #include "comm.h"
 #include "force.h"
 #include "update.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define TOLERANCE 0.05
 #define SMALL     0.001
 
 /* ---------------------------------------------------------------------- */
 
 DihedralMultiHarmonic::DihedralMultiHarmonic(LAMMPS *lmp) : Dihedral(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 DihedralMultiHarmonic::~DihedralMultiHarmonic()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(a1);
     memory->sfree(a2);
     memory->sfree(a3);
     memory->sfree(a4);
     memory->sfree(a5);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralMultiHarmonic::compute(int eflag, int vflag)
 {
   int i1,i2,i3,i4,n,type;
   double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
   double edihedral,f1[3],f2[3],f3[3],f4[3];
   double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
   double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
   double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22;
   double a33,a12,a13,a23,sx2,sy2,sz2;
   double s2,sin2;
 
   edihedral = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   double **x = atom->x;
   double **f = atom->f;
   int **dihedrallist = neighbor->dihedrallist;
   int ndihedrallist = neighbor->ndihedrallist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < ndihedrallist; n++) {
     i1 = dihedrallist[n][0];
     i2 = dihedrallist[n][1];
     i3 = dihedrallist[n][2];
     i4 = dihedrallist[n][3];
     type = dihedrallist[n][4];
 
     // 1st bond
 
     vb1x = x[i1][0] - x[i2][0];
     vb1y = x[i1][1] - x[i2][1];
     vb1z = x[i1][2] - x[i2][2];
     domain->minimum_image(vb1x,vb1y,vb1z);
 
     // 2nd bond
 
     vb2x = x[i3][0] - x[i2][0];
     vb2y = x[i3][1] - x[i2][1];
     vb2z = x[i3][2] - x[i2][2];
     domain->minimum_image(vb2x,vb2y,vb2z);
 
     vb2xm = -vb2x;
     vb2ym = -vb2y;
     vb2zm = -vb2z;
     domain->minimum_image(vb2xm,vb2ym,vb2zm);
 
     // 3rd bond
 
     vb3x = x[i4][0] - x[i3][0];
     vb3y = x[i4][1] - x[i3][1];
     vb3z = x[i4][2] - x[i3][2];
     domain->minimum_image(vb3x,vb3y,vb3z);
 
     // c0 calculation
         
     sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
     sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
     sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
         
     rb1 = sqrt(sb1);
     rb3 = sqrt(sb3);
         
     c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
 
     // 1st and 2nd angle
         
     b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
     b1mag = sqrt(b1mag2);
     b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
     b2mag = sqrt(b2mag2);
     b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
     b3mag = sqrt(b3mag2);
 
     ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
     r12c1 = 1.0 / (b1mag*b2mag);
     c1mag = ctmp * r12c1;
 
     ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
     r12c2 = 1.0 / (b2mag*b3mag);
     c2mag = ctmp * r12c2;
 
     // cos and sin of 2 angles and final c
 
     sin2 = MAX(1.0 - c1mag*c1mag,0.0);
     sc1 = sqrt(sin2);
     if (sc1 < SMALL) sc1 = SMALL;
     sc1 = 1.0/sc1;
 
     sin2 = MAX(1.0 - c2mag*c2mag,0.0);
     sc2 = sqrt(sin2);
     if (sc2 < SMALL) sc2 = SMALL;
     sc2 = 1.0/sc2;
 
     s1 = sc1 * sc1;
     s2 = sc2 * sc2;
     s12 = sc1 * sc2;
     c = (c0 + c1mag*c2mag) * s12;
 
     // error check
 
     if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
+      int me;
+      MPI_Comm_rank(world,&me);
       if (screen) {
-	char str[128];
-	sprintf(str,"Dihedral problem: %d %d %d %d %d %d",
-		comm->me,update->ntimestep,
+	char str[128],fstr[64];
+	sprintf(fstr,"Dihedral problem: %%d %s %%d %%d %%d %%d",BIGINT_FORMAT);
+	sprintf(str,fstr,me,update->ntimestep,
 		atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
 	error->warning(str,0);
 	fprintf(screen,"  1st atom: %d %g %g %g\n",
-		comm->me,x[i1][0],x[i1][1],x[i1][2]);
+		me,x[i1][0],x[i1][1],x[i1][2]);
 	fprintf(screen,"  2nd atom: %d %g %g %g\n",
-		comm->me,x[i2][0],x[i2][1],x[i2][2]);
+		me,x[i2][0],x[i2][1],x[i2][2]);
 	fprintf(screen,"  3rd atom: %d %g %g %g\n",
-		comm->me,x[i3][0],x[i3][1],x[i3][2]);
+		me,x[i3][0],x[i3][1],x[i3][2]);
 	fprintf(screen,"  4th atom: %d %g %g %g\n",
-		comm->me,x[i4][0],x[i4][1],x[i4][2]);
+		me,x[i4][0],x[i4][1],x[i4][2]);
       }
     }
     
     if (c > 1.0) c = 1.0;
     if (c < -1.0) c = -1.0;
 
     // force & energy
     // p = sum (i=1,5) a_i * c**(i-1)
     // pd = dp/dc
 
     p = a1[type] + c*(a2[type] + c*(a3[type] + c*(a4[type] + c*a5[type])));
     pd = a2[type] + c*(2.0*a3[type] + c*(3.0*a4[type] + c*4.0*a5[type]));
 
     if (eflag) edihedral = p;
 
     a = pd;
     c = c * a;
     s12 = s12 * a;
     a11 = c*sb1*s1;
     a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
     a33 = c*sb3*s2;
     a12 = -r12c1*(c1mag*c*s1 + c2mag*s12);
     a13 = -rb1*rb3*s12;
     a23 = r12c2*(c2mag*c*s2 + c1mag*s12);
 
     sx2  = a12*vb1x + a22*vb2x + a23*vb3x;
     sy2  = a12*vb1y + a22*vb2y + a23*vb3y;
     sz2  = a12*vb1z + a22*vb2z + a23*vb3z;
 
     f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
     f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
     f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
 
     f2[0] = -sx2 - f1[0];
     f2[1] = -sy2 - f1[1];
     f2[2] = -sz2 - f1[2];
 
     f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
     f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
     f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
 
     f3[0] = sx2 - f4[0];
     f3[1] = sy2 - f4[1];
     f3[2] = sz2 - f4[2];
 
     // apply force to each of 4 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += f1[0];
       f[i1][1] += f1[1];
       f[i1][2] += f1[2];
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] += f2[0];
       f[i2][1] += f2[1];
       f[i2][2] += f2[2];
     }
 
     if (newton_bond || i3 < nlocal) {
       f[i3][0] += f3[0];
       f[i3][1] += f3[1];
       f[i3][2] += f3[2];
     }
 
     if (newton_bond || i4 < nlocal) {
       f[i4][0] += f4[0];
       f[i4][1] += f4[1];
       f[i4][2] += f4[2];
     }
 
     if (evflag)
       ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4,
 	       vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralMultiHarmonic::allocate()
 {
   allocated = 1;
   int n = atom->ndihedraltypes;
 
   a1 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:a1");
   a2 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:a2");
   a3 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:a3");
   a4 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:a4");
   a5 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:a5");
 
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag");
   for (int i = 1; i <= n; i++) setflag[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one type
 ------------------------------------------------------------------------- */
 
 void DihedralMultiHarmonic::coeff(int narg, char **arg)
 {
   if (narg != 6) error->all("Incorrect args for dihedral coefficients");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi);
 
   double a1_one = force->numeric(arg[1]);
   double a2_one = force->numeric(arg[2]);
   double a3_one = force->numeric(arg[3]);
   double a4_one = force->numeric(arg[4]);
   double a5_one = force->numeric(arg[5]);
 
   int count = 0;
   for (int i = ilo; i <= ihi; i++) {
     a1[i] = a1_one;
     a2[i] = a2_one;
     a3[i] = a3_one;
     a4[i] = a4_one;
     a5[i] = a5_one;
     setflag[i] = 1;
     count++;
   }
 
   if (count == 0) error->all("Incorrect args for dihedral coefficients");
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out coeffs to restart file 
 ------------------------------------------------------------------------- */
 
 void DihedralMultiHarmonic::write_restart(FILE *fp)
 {
   fwrite(&a1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&a2[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&a3[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&a4[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&a5[1],sizeof(double),atom->ndihedraltypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads coeffs from restart file, bcasts them 
 ------------------------------------------------------------------------- */
 
 void DihedralMultiHarmonic::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&a1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&a2[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&a3[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&a4[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&a5[1],sizeof(double),atom->ndihedraltypes,fp);
   }
   MPI_Bcast(&a1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&a2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&a3[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&a4[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&a5[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
 
   for (int i = 1; i <= atom->ndihedraltypes; i++) setflag[i] = 1;
 }
diff --git a/src/MOLECULE/dihedral_opls.cpp b/src/MOLECULE/dihedral_opls.cpp
index bb3579e1c..576f6ca4e 100644
--- a/src/MOLECULE/dihedral_opls.cpp
+++ b/src/MOLECULE/dihedral_opls.cpp
@@ -1,346 +1,349 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mark Stevens (SNL)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdlib.h"
 #include "dihedral_opls.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "comm.h"
 #include "neighbor.h"
 #include "domain.h"
 #include "force.h"
 #include "update.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define TOLERANCE 0.05
 #define SMALL     0.001
 #define SMALLER   0.00001
 
 /* ---------------------------------------------------------------------- */
 
 DihedralOPLS::DihedralOPLS(LAMMPS *lmp) : Dihedral(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 DihedralOPLS::~DihedralOPLS()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(k1);
     memory->sfree(k2);
     memory->sfree(k3);
     memory->sfree(k4);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralOPLS::compute(int eflag, int vflag)
 {
   int i1,i2,i3,i4,n,type;
   double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
   double edihedral,f1[3],f2[3],f3[3],f4[3];
   double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
   double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
   double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22;
   double a33,a12,a13,a23,sx2,sy2,sz2;
   double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
 
   edihedral = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   double **x = atom->x;
   double **f = atom->f;
   int **dihedrallist = neighbor->dihedrallist;
   int ndihedrallist = neighbor->ndihedrallist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < ndihedrallist; n++) {
     i1 = dihedrallist[n][0];
     i2 = dihedrallist[n][1];
     i3 = dihedrallist[n][2];
     i4 = dihedrallist[n][3];
     type = dihedrallist[n][4];
 
     // 1st bond
 
     vb1x = x[i1][0] - x[i2][0];
     vb1y = x[i1][1] - x[i2][1];
     vb1z = x[i1][2] - x[i2][2];
     domain->minimum_image(vb1x,vb1y,vb1z);
 
     // 2nd bond
 
     vb2x = x[i3][0] - x[i2][0];
     vb2y = x[i3][1] - x[i2][1];
     vb2z = x[i3][2] - x[i2][2];
     domain->minimum_image(vb2x,vb2y,vb2z);
 
     vb2xm = -vb2x;
     vb2ym = -vb2y;
     vb2zm = -vb2z;
     domain->minimum_image(vb2xm,vb2ym,vb2zm);
 
     // 3rd bond
 
     vb3x = x[i4][0] - x[i3][0];
     vb3y = x[i4][1] - x[i3][1];
     vb3z = x[i4][2] - x[i3][2];
     domain->minimum_image(vb3x,vb3y,vb3z);
 
     // c0 calculation
 
     sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
     sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
     sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
 
     rb1 = sqrt(sb1);
     rb3 = sqrt(sb3);
 
     c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
 
     // 1st and 2nd angle
 
     b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
     b1mag = sqrt(b1mag2);
     b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
     b2mag = sqrt(b2mag2);
     b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
     b3mag = sqrt(b3mag2);
 
     ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
     r12c1 = 1.0 / (b1mag*b2mag);
     c1mag = ctmp * r12c1;
 
     ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
     r12c2 = 1.0 / (b2mag*b3mag);
     c2mag = ctmp * r12c2;
 
     // cos and sin of 2 angles and final c
 
     sin2 = MAX(1.0 - c1mag*c1mag,0.0);
     sc1 = sqrt(sin2);
     if (sc1 < SMALL) sc1 = SMALL;
     sc1 = 1.0/sc1;
 
     sin2 = MAX(1.0 - c2mag*c2mag,0.0);
     sc2 = sqrt(sin2);
     if (sc2 < SMALL) sc2 = SMALL;
     sc2 = 1.0/sc2;
 
     s1 = sc1 * sc1;
     s2 = sc2 * sc2;
     s12 = sc1 * sc2;
     c = (c0 + c1mag*c2mag) * s12;
 
     cx = vb1y*vb2z - vb1z*vb2y;
     cy = vb1z*vb2x - vb1x*vb2z;
     cz = vb1x*vb2y - vb1y*vb2x;
     cmag = sqrt(cx*cx + cy*cy + cz*cz);
     dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag;
 
     // error check
 
     if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
+      int me;
+      MPI_Comm_rank(world,&me);
       if (screen) {
-	char str[128];
-	sprintf(str,"Dihedral problem: %d %d %d %d %d %d",
-		comm->me,update->ntimestep,
+	char str[128],fstr[64];
+	sprintf(fstr,"Dihedral problem: %%d %s %%d %%d %%d %%d",BIGINT_FORMAT);
+	sprintf(str,fstr,me,update->ntimestep,
 		atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
 	error->warning(str,0);
 	fprintf(screen,"  1st atom: %d %g %g %g\n",
-		comm->me,x[i1][0],x[i1][1],x[i1][2]);
+		me,x[i1][0],x[i1][1],x[i1][2]);
 	fprintf(screen,"  2nd atom: %d %g %g %g\n",
-		comm->me,x[i2][0],x[i2][1],x[i2][2]);
+		me,x[i2][0],x[i2][1],x[i2][2]);
 	fprintf(screen,"  3rd atom: %d %g %g %g\n",
-		comm->me,x[i3][0],x[i3][1],x[i3][2]);
+		me,x[i3][0],x[i3][1],x[i3][2]);
 	fprintf(screen,"  4th atom: %d %g %g %g\n",
-		comm->me,x[i4][0],x[i4][1],x[i4][2]);
+		me,x[i4][0],x[i4][1],x[i4][2]);
       }
     }
     
     if (c > 1.0) c = 1.0;
     if (c < -1.0) c = -1.0;
 
     // force & energy
     // p = sum (i=1,4) k_i * (1 + (-1)**(i+1)*cos(i*phi) )
     // pd = dp/dc
 
     phi = acos(c);
     if (dx < 0.0) phi *= -1.0;
     si = sin(phi);
     if (fabs(si) < SMALLER) si = SMALLER;
     siinv = 1.0/si;
 
     p = k1[type]*(1.0 + c) + k2[type]*(1.0 - cos(2.0*phi)) +
       k3[type]*(1.0 + cos(3.0*phi)) + k4[type]*(1.0 - cos(4.0*phi)) ;
     pd = k1[type] - 2.0*k2[type]*sin(2.0*phi)*siinv + 
       3.0*k3[type]*sin(3.0*phi)*siinv - 4.0*k4[type]*sin(4.0*phi)*siinv;
 
     if (eflag) edihedral = p; 
 
     a = pd;
     c = c * a;
     s12 = s12 * a;
     a11 = c*sb1*s1;
     a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
     a33 = c*sb3*s2;
     a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12);
     a13 = -rb1*rb3*s12;
     a23 = r12c2 * (c2mag*c*s2 + c1mag*s12);
 
     sx2  = a12*vb1x + a22*vb2x + a23*vb3x;
     sy2  = a12*vb1y + a22*vb2y + a23*vb3y;
     sz2  = a12*vb1z + a22*vb2z + a23*vb3z;
 
     f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
     f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
     f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
 
     f2[0] = -sx2 - f1[0];
     f2[1] = -sy2 - f1[1];
     f2[2] = -sz2 - f1[2];
 
     f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
     f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
     f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
 
     f3[0] = sx2 - f4[0];
     f3[1] = sy2 - f4[1];
     f3[2] = sz2 - f4[2];
 
     // apply force to each of 4 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += f1[0];
       f[i1][1] += f1[1];
       f[i1][2] += f1[2];
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] += f2[0];
       f[i2][1] += f2[1];
       f[i2][2] += f2[2];
     }
 
     if (newton_bond || i3 < nlocal) {
       f[i3][0] += f3[0];
       f[i3][1] += f3[1];
       f[i3][2] += f3[2];
     }
 
     if (newton_bond || i4 < nlocal) {
       f[i4][0] += f4[0];
       f[i4][1] += f4[1];
       f[i4][2] += f4[2];
     }
 
     if (evflag)
       ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4,
 	       vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DihedralOPLS::allocate()
 {
   allocated = 1;
   int n = atom->ndihedraltypes;
 
   k1 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k1");
   k2 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k2");
   k3 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k3");
   k4 = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k4");
 
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag");
   for (int i = 1; i <= n; i++) setflag[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one type
 ------------------------------------------------------------------------- */
 
 void DihedralOPLS::coeff(int narg, char **arg)
 {
   if (narg != 5) error->all("Incorrect args for dihedral coefficients");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi);
 
   double k1_one = force->numeric(arg[1]);
   double k2_one = force->numeric(arg[2]);
   double k3_one = force->numeric(arg[3]);
   double k4_one = force->numeric(arg[4]);
 
   // store 1/2 factor with prefactor
 
   int count = 0;
   for (int i = ilo; i <= ihi; i++) {
     k1[i] = 0.5*k1_one;
     k2[i] = 0.5*k2_one;
     k3[i] = 0.5*k3_one;
     k4[i] = 0.5*k4_one;
     setflag[i] = 1;
     count++;
   }
 
   if (count == 0) error->all("Incorrect args for dihedral coefficients");
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out coeffs to restart file 
 ------------------------------------------------------------------------- */
 
 void DihedralOPLS::write_restart(FILE *fp)
 {
   fwrite(&k1[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&k2[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&k3[1],sizeof(double),atom->ndihedraltypes,fp);
   fwrite(&k4[1],sizeof(double),atom->ndihedraltypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads coeffs from restart file, bcasts them 
 ------------------------------------------------------------------------- */
 
 void DihedralOPLS::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&k1[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&k2[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&k3[1],sizeof(double),atom->ndihedraltypes,fp);
     fread(&k4[1],sizeof(double),atom->ndihedraltypes,fp);
   }
   MPI_Bcast(&k1[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&k2[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&k3[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&k4[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
  
   for (int i = 1; i <= atom->ndihedraltypes; i++) setflag[i] = 1;
 }
diff --git a/src/MOLECULE/improper_cvff.cpp b/src/MOLECULE/improper_cvff.cpp
index 6ce9e7fd5..a4a662449 100644
--- a/src/MOLECULE/improper_cvff.cpp
+++ b/src/MOLECULE/improper_cvff.cpp
@@ -1,348 +1,349 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "improper_cvff.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "comm.h"
 #include "neighbor.h"
 #include "domain.h"
 #include "force.h"
 #include "update.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define TOLERANCE 0.05
 #define SMALL     0.001
 
 /* ---------------------------------------------------------------------- */
 
 ImproperCvff::ImproperCvff(LAMMPS *lmp) : Improper(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 ImproperCvff::~ImproperCvff()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(k);
     memory->sfree(sign);
     memory->sfree(multiplicity);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ImproperCvff::compute(int eflag, int vflag)
 {
   int i1,i2,i3,i4,m,n,type;
   double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
   double eimproper,f1[3],f2[3],f3[3],f4[3];
   double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
   double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
   double c2mag,sc1,sc2,s1,s2,s12,c,p,pd,rc2,a,a11,a22;
   double a33,a12,a13,a23,sx2,sy2,sz2;
 
   eimproper = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   double **x = atom->x;
   double **f = atom->f;
   int **improperlist = neighbor->improperlist;
   int nimproperlist = neighbor->nimproperlist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < nimproperlist; n++) {
     i1 = improperlist[n][0];
     i2 = improperlist[n][1];
     i3 = improperlist[n][2];
     i4 = improperlist[n][3];
     type = improperlist[n][4];
 
     // 1st bond
 
     vb1x = x[i1][0] - x[i2][0];
     vb1y = x[i1][1] - x[i2][1];
     vb1z = x[i1][2] - x[i2][2];
     domain->minimum_image(vb1x,vb1y,vb1z);
 
     // 2nd bond
 
     vb2x = x[i3][0] - x[i2][0];
     vb2y = x[i3][1] - x[i2][1];
     vb2z = x[i3][2] - x[i2][2];
     domain->minimum_image(vb2x,vb2y,vb2z);
 
     vb2xm = -vb2x;
     vb2ym = -vb2y;
     vb2zm = -vb2z;
     domain->minimum_image(vb2xm,vb2ym,vb2zm);
 
     // 3rd bond
 
     vb3x = x[i4][0] - x[i3][0];
     vb3y = x[i4][1] - x[i3][1];
     vb3z = x[i4][2] - x[i3][2];
     domain->minimum_image(vb3x,vb3y,vb3z);
 
     // c0 calculation
         
     sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
     sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
     sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
         
     rb1 = sqrt(sb1);
     rb3 = sqrt(sb3);
         
     c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
 
     // 1st and 2nd angle
         
     b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
     b1mag = sqrt(b1mag2);
     b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
     b2mag = sqrt(b2mag2);
     b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
     b3mag = sqrt(b3mag2);
 
     ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
     r12c1 = 1.0 / (b1mag*b2mag);
     c1mag = ctmp * r12c1;
 
     ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
     r12c2 = 1.0 / (b2mag*b3mag);
     c2mag = ctmp * r12c2;
 
     // cos and sin of 2 angles and final c
 
     sc1 = sqrt(1.0 - c1mag*c1mag);
     if (sc1 < SMALL) sc1 = SMALL;
     sc1 = 1.0/sc1;
 
     sc2 = sqrt(1.0 - c2mag*c2mag);
     if (sc2 < SMALL) sc2 = SMALL;
     sc2 = 1.0/sc2;
 
     s1 = sc1 * sc1;
     s2 = sc2 * sc2;
     s12 = sc1 * sc2;
     c = (c0 + c1mag*c2mag) * s12;
 
     // error check
 
     if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
       int me;
       MPI_Comm_rank(world,&me);
       if (screen) {
-	char str[128];
-	sprintf(str,"Improper problem: %d %d %d %d %d %d",
-		me,update->ntimestep,
+	char str[128],fstr[64];
+	sprintf(fstr,"Improper problem: %%d %s %%d %%d %%d %%d",BIGINT_FORMAT);
+	sprintf(str,fstr,me,update->ntimestep,
 		atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
 	error->warning(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]);
 	fprintf(screen,"  3rd atom: %d %g %g %g\n",
 		me,x[i3][0],x[i3][1],x[i3][2]);
 	fprintf(screen,"  4th atom: %d %g %g %g\n",
 		me,x[i4][0],x[i4][1],x[i4][2]);
       }
     }
     
     if (c > 1.0) c = 1.0;
     if (c < -1.0) c = -1.0;
 
     // force & energy
     // p = 1 + cos(n*phi) for d = 1
     // p = 1 - cos(n*phi) for d = -1
     // pd = dp/dc / 2
         
     m = multiplicity[type];
 
     if (m == 2) {
       p = 2.0*c*c;
       pd = 2.0*c;
     } else if (m == 3) {
       rc2 = c*c;
       p = (4.0*rc2-3.0)*c + 1.0;
       pd = 6.0*rc2 - 1.5;
     } else if (m == 4) {
       rc2 = c*c;
       p = 8.0*(rc2-1)*rc2 + 2.0;
       pd = (16.0*rc2-8.0)*c;
     } else if (m == 6) {
       rc2 = c*c;
       p = ((32.0*rc2-48.0)*rc2 + 18.0)*rc2;
       pd = (96.0*(rc2-1.0)*rc2 + 18.0)*c;
     } else if (m == 1) {
       p = c + 1.0;
       pd = 0.5;
     } else if (m == 5) {
       rc2 = c*c;
       p = ((16.0*rc2-20.0)*rc2 + 5.0)*c + 1.0;
       pd = (40.0*rc2-30.0)*rc2 + 2.5;
     } else if (m == 0) {
       p = 2.0;
       pd = 0.0;
     }
     
     if (sign[type] == -1) {
       p = 2.0 - p;
       pd = -pd;
     }
 
     if (eflag) eimproper = k[type]*p;
 
     a = 2.0 * k[type] * pd;
     c = c * a;
     s12 = s12 * a;
     a11 = c*sb1*s1;
     a22 = -sb2*(2.0*c0*s12 - c*(s1+s2));
     a33 = c*sb3*s2;
     a12 = -r12c1*(c1mag*c*s1 + c2mag*s12);
     a13 = -rb1*rb3*s12;
     a23 = r12c2*(c2mag*c*s2 + c1mag*s12);
 
     sx2  = a12*vb1x + a22*vb2x + a23*vb3x;
     sy2  = a12*vb1y + a22*vb2y + a23*vb3y;
     sz2  = a12*vb1z + a22*vb2z + a23*vb3z;
 
     f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
     f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
     f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
 
     f2[0] = -sx2 - f1[0];
     f2[1] = -sy2 - f1[1];
     f2[2] = -sz2 - f1[2];
 
     f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
     f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
     f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
 
     f3[0] = sx2 - f4[0];
     f3[1] = sy2 - f4[1];
     f3[2] = sz2 - f4[2];
 
     // apply force to each of 4 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += f1[0];
       f[i1][1] += f1[1];
       f[i1][2] += f1[2];
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] += f2[0];
       f[i2][1] += f2[1];
       f[i2][2] += f2[2];
     }
 
     if (newton_bond || i3 < nlocal) {
       f[i3][0] += f3[0];
       f[i3][1] += f3[1];
       f[i3][2] += f3[2];
     }
 
     if (newton_bond || i4 < nlocal) {
       f[i4][0] += f4[0];
       f[i4][1] += f4[1];
       f[i4][2] += f4[2];
     }
 
     if (evflag)
       ev_tally(i1,i2,i3,i4,nlocal,newton_bond,eimproper,f1,f3,f4,
 	       vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ImproperCvff::allocate()
 {
   allocated = 1;
   int n = atom->nimpropertypes;
 
   k = (double *) memory->smalloc((n+1)*sizeof(double),"improper:k");
   sign = (int *) memory->smalloc((n+1)*sizeof(int),"improper:sign");
   multiplicity = (int *) 
     memory->smalloc((n+1)*sizeof(int),"improper:multiplicity");
 
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"improper:setflag");
   for (int i = 1; i <= n; i++) setflag[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one type
 ------------------------------------------------------------------------- */
 
 void ImproperCvff::coeff(int narg, char **arg)
 {
   if (narg != 4) error->all("Incorrect args for improper coefficients");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->nimpropertypes,ilo,ihi);
 
   double k_one = force->numeric(arg[1]);
   int sign_one = force->inumeric(arg[2]);
   int multiplicity_one = force->inumeric(arg[3]);
 
   int count = 0;
   for (int i = ilo; i <= ihi; i++) {
     k[i] = k_one;
     sign[i] = sign_one;
     multiplicity[i] = multiplicity_one;
     setflag[i] = 1;
     count++;
   }
 
   if (count == 0) error->all("Incorrect args for improper coefficients");
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out coeffs to restart file 
 ------------------------------------------------------------------------- */
 
 void ImproperCvff::write_restart(FILE *fp)
 {
   fwrite(&k[1],sizeof(double),atom->nimpropertypes,fp);
   fwrite(&sign[1],sizeof(int),atom->nimpropertypes,fp);
   fwrite(&multiplicity[1],sizeof(int),atom->nimpropertypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads coeffs from restart file, bcasts them 
 ------------------------------------------------------------------------- */
 
 void ImproperCvff::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&k[1],sizeof(double),atom->nimpropertypes,fp);
     fread(&sign[1],sizeof(int),atom->nimpropertypes,fp);
     fread(&multiplicity[1],sizeof(int),atom->nimpropertypes,fp);
   }
   MPI_Bcast(&k[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&sign[1],atom->nimpropertypes,MPI_INT,0,world);
   MPI_Bcast(&multiplicity[1],atom->nimpropertypes,MPI_INT,0,world);
 
   for (int i = 1; i <= atom->nimpropertypes; i++) setflag[i] = 1;
 }
diff --git a/src/MOLECULE/improper_harmonic.cpp b/src/MOLECULE/improper_harmonic.cpp
index 4487b9e7a..0174ce3c9 100644
--- a/src/MOLECULE/improper_harmonic.cpp
+++ b/src/MOLECULE/improper_harmonic.cpp
@@ -1,283 +1,284 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "improper_harmonic.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "comm.h"
 #include "neighbor.h"
 #include "domain.h"
 #include "force.h"
 #include "update.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define TOLERANCE 0.05
 #define SMALL     0.001
 
 /* ---------------------------------------------------------------------- */
 
 ImproperHarmonic::ImproperHarmonic(LAMMPS *lmp) : Improper(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 ImproperHarmonic::~ImproperHarmonic()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(k);
     memory->sfree(chi);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ImproperHarmonic::compute(int eflag, int vflag)
 {
   int i1,i2,i3,i4,n,type;
   double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z;
   double eimproper,f1[3],f2[3],f3[3],f4[3];
   double ss1,ss2,ss3,r1,r2,r3,c0,c1,c2,s1,s2;
   double s12,c,s,domega,a,a11,a22,a33,a12,a13,a23;
   double sx2,sy2,sz2;
 
   eimproper = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   double **x = atom->x;
   double **f = atom->f;
   int **improperlist = neighbor->improperlist;
   int nimproperlist = neighbor->nimproperlist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < nimproperlist; n++) {
     i1 = improperlist[n][0];
     i2 = improperlist[n][1];
     i3 = improperlist[n][2];
     i4 = improperlist[n][3];
     type = improperlist[n][4];
 
     // geometry of 4-body
 
     vb1x = x[i1][0] - x[i2][0];
     vb1y = x[i1][1] - x[i2][1];
     vb1z = x[i1][2] - x[i2][2];
     domain->minimum_image(vb1x,vb1y,vb1z);
 
     vb2x = x[i3][0] - x[i2][0];
     vb2y = x[i3][1] - x[i2][1];
     vb2z = x[i3][2] - x[i2][2];
     domain->minimum_image(vb2x,vb2y,vb2z);
 
     vb3x = x[i4][0] - x[i3][0];
     vb3y = x[i4][1] - x[i3][1];
     vb3z = x[i4][2] - x[i3][2];
     domain->minimum_image(vb3x,vb3y,vb3z);
 
     ss1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
     ss2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
     ss3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
         
     r1 = sqrt(ss1);
     r2 = sqrt(ss2);
     r3 = sqrt(ss3);
         
     // sin and cos of angle
         
     c0 = (vb1x * vb3x + vb1y * vb3y + vb1z * vb3z) * r1 * r3;
     c1 = (vb1x * vb2x + vb1y * vb2y + vb1z * vb2z) * r1 * r2;
     c2 = -(vb3x * vb2x + vb3y * vb2y + vb3z * vb2z) * r3 * r2;
 
     s1 = 1.0 - c1*c1;
     if (s1 < SMALL) s1 = SMALL;
     s1 = 1.0 / s1;
 
     s2 = 1.0 - c2*c2;
     if (s2 < SMALL) s2 = SMALL;
     s2 = 1.0 / s2;
 
     s12 = sqrt(s1*s2);
     c = (c1*c2 + c0) * s12;
 
     // error check
 
     if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
       int me;
       MPI_Comm_rank(world,&me);
       if (screen) {
-	char str[128];
-	sprintf(str,"Improper problem: %d %d %d %d %d %d",
-		me,update->ntimestep,
+	char str[128],fstr[64];
+	sprintf(fstr,"Improper problem: %%d %s %%d %%d %%d %%d",BIGINT_FORMAT);
+	sprintf(str,fstr,me,update->ntimestep,
 		atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
 	error->warning(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]);
 	fprintf(screen,"  3rd atom: %d %g %g %g\n",
 		me,x[i3][0],x[i3][1],x[i3][2]);
 	fprintf(screen,"  4th atom: %d %g %g %g\n",
 		me,x[i4][0],x[i4][1],x[i4][2]);
       }
     }
     
     if (c > 1.0) c = 1.0;
     if (c < -1.0) c = -1.0;
 
     s = sqrt(1.0 - c*c);
     if (s < SMALL) s = SMALL;
 
     // force & energy
 
     domega = acos(c) - chi[type];
     a = k[type] * domega;
 
     if (eflag) eimproper = a*domega;
 
     a = -a * 2.0/s;
     c = c * a;
     s12 = s12 * a;
     a11 = c*ss1*s1;
     a22 = -ss2 * (2.0*c0*s12 - c*(s1+s2));
     a33 = c*ss3*s2;
     a12 = -r1*r2*(c1*c*s1 + c2*s12);
     a13 = -r1*r3*s12;
     a23 = r2*r3*(c2*c*s2 + c1*s12);
 
     sx2  = a22*vb2x + a23*vb3x + a12*vb1x;
     sy2  = a22*vb2y + a23*vb3y + a12*vb1y;
     sz2  = a22*vb2z + a23*vb3z + a12*vb1z;
 
     f1[0] = a12*vb2x + a13*vb3x + a11*vb1x;
     f1[1] = a12*vb2y + a13*vb3y + a11*vb1y;
     f1[2] = a12*vb2z + a13*vb3z + a11*vb1z;
 
     f2[0] = -sx2 - f1[0];
     f2[1] = -sy2 - f1[1];
     f2[2] = -sz2 - f1[2];
 
     f4[0] = a23*vb2x + a33*vb3x + a13*vb1x;
     f4[1] = a23*vb2y + a33*vb3y + a13*vb1y;
     f4[2] = a23*vb2z + a33*vb3z + a13*vb1z;
 
     f3[0] = sx2 - f4[0];
     f3[1] = sy2 - f4[1];
     f3[2] = sz2 - f4[2];
 
     // apply force to each of 4 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += f1[0];
       f[i1][1] += f1[1];
       f[i1][2] += f1[2];
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] += f2[0];
       f[i2][1] += f2[1];
       f[i2][2] += f2[2];
     }
 
     if (newton_bond || i3 < nlocal) {
       f[i3][0] += f3[0];
       f[i3][1] += f3[1];
       f[i3][2] += f3[2];
     }
 
     if (newton_bond || i4 < nlocal) {
       f[i4][0] += f4[0];
       f[i4][1] += f4[1];
       f[i4][2] += f4[2];
     }
 
     if (evflag)
       ev_tally(i1,i2,i3,i4,nlocal,newton_bond,eimproper,f1,f3,f4,
 	       vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ImproperHarmonic::allocate()
 {
   allocated = 1;
   int n = atom->nimpropertypes;
 
   k = (double *) memory->smalloc((n+1)*sizeof(double),"improper:k");
   chi = (double *) memory->smalloc((n+1)*sizeof(double),"improper:chi");
 
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"improper:setflag");
   for (int i = 1; i <= n; i++) setflag[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one type
 ------------------------------------------------------------------------- */
 
 void ImproperHarmonic::coeff(int narg, char **arg)
 {
   if (narg != 3) error->all("Incorrect args for improper coefficients");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->nimpropertypes,ilo,ihi);
 
   double k_one = force->numeric(arg[1]);
   double chi_one = force->numeric(arg[2]);
 
   // convert chi from degrees to radians
 
   int count = 0;
   for (int i = ilo; i <= ihi; i++) {
     k[i] = k_one;
     chi[i] = chi_one/180.0 * PI;
     setflag[i] = 1;
     count++;
   }
 
   if (count == 0) error->all("Incorrect args for improper coefficients");
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out coeffs to restart file 
 ------------------------------------------------------------------------- */
 
 void ImproperHarmonic::write_restart(FILE *fp)
 {
   fwrite(&k[1],sizeof(double),atom->nimpropertypes,fp);
   fwrite(&chi[1],sizeof(double),atom->nimpropertypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads coeffs from restart file, bcasts them 
 ------------------------------------------------------------------------- */
 
 void ImproperHarmonic::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&k[1],sizeof(double),atom->nimpropertypes,fp);
     fread(&chi[1],sizeof(double),atom->nimpropertypes,fp);
   }
   MPI_Bcast(&k[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&chi[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
 
   for (int i = 1; i <= atom->nimpropertypes; i++) setflag[i] = 1;
 }
diff --git a/src/MOLECULE/improper_umbrella.cpp b/src/MOLECULE/improper_umbrella.cpp
index 9d2cc9cba..3fc2aad60 100644
--- a/src/MOLECULE/improper_umbrella.cpp
+++ b/src/MOLECULE/improper_umbrella.cpp
@@ -1,308 +1,310 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Tod A Pascal (Caltech)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "stdlib.h"
 #include "improper_umbrella.h"
 #include "atom.h"
 #include "comm.h"
 #include "neighbor.h"
 #include "domain.h"
 #include "force.h"
 #include "update.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define TOLERANCE 0.05
 #define SMALL     0.001
 
 /* ---------------------------------------------------------------------- */
 
 ImproperUmbrella::ImproperUmbrella(LAMMPS *lmp) : Improper(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 ImproperUmbrella::~ImproperUmbrella()
 {
   if (allocated) {
     memory->sfree(setflag);
     memory->sfree(kw);
     memory->sfree(w0);
     memory->sfree(C);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ImproperUmbrella::compute(int eflag, int vflag)
 {
   int i1,i2,i3,i4,n,type;
   double eimproper,f1[3],f2[3],f3[3],f4[3];
   double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z;
   double domega,c,a,s,projhfg,dhax,dhay,dhaz,dahx,dahy,dahz,cotphi;
   double ax,ay,az,ra2,rh2,ra,rh,rar,rhr,arx,ary,arz,hrx,hry,hrz;
 
   eimproper = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = 0;
 
   double **x = atom->x;
   double **f = atom->f;
   int **improperlist = neighbor->improperlist;
   int nimproperlist = neighbor->nimproperlist;
   int nlocal = atom->nlocal;
   int newton_bond = force->newton_bond;
 
   for (n = 0; n < nimproperlist; n++) {
     i1 = improperlist[n][0];
     i2 = improperlist[n][1];
     i3 = improperlist[n][2];
     i4 = improperlist[n][3];
     type = improperlist[n][4];
 
     // 1st bond
 
     vb1x = x[i2][0] - x[i1][0];
     vb1y = x[i2][1] - x[i1][1];
     vb1z = x[i2][2] - x[i1][2];
     domain->minimum_image(vb1x,vb1y,vb1z);
 
     // 2nd bond
 
     vb2x = x[i3][0] - x[i1][0];
     vb2y = x[i3][1] - x[i1][1];
     vb2z = x[i3][2] - x[i1][2];
     domain->minimum_image(vb2x,vb2y,vb2z);
 
     // 3rd bond
 
     vb3x = x[i4][0] - x[i1][0];
     vb3y = x[i4][1] - x[i1][1];
     vb3z = x[i4][2] - x[i1][2];
     domain->minimum_image(vb3x,vb3y,vb3z);
 
     // c0 calculation
     // A = vb1 X vb2 is perpendicular to IJK plane
 
     ax = vb1y*vb2z-vb1z*vb2y;
     ay = vb1z*vb2x-vb1x*vb2z;
     az = vb1x*vb2y-vb1y*vb2x;
     ra2 = ax*ax+ay*ay+az*az;
     rh2 = vb3x*vb3x+vb3y*vb3y+vb3z*vb3z;
     ra = sqrt(ra2);
     rh = sqrt(rh2);
     if (ra < SMALL) ra = SMALL;
     if (rh < SMALL) rh = SMALL;
 
     rar = 1/ra;
     rhr = 1/rh;
     arx = ax*rar;
     ary = ay*rar;
     arz = az*rar;
     hrx = vb3x*rhr;
     hry = vb3y*rhr;
     hrz = vb3z*rhr;
 
     c = arx*hrx+ary*hry+arz*hrz;
 
     // error check
 
     if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) {
       int me;
       MPI_Comm_rank(world,&me);
       if (screen) {
-	fprintf(screen,"Improper problem: %d %d %d %d %d %d\n",
-		me,update->ntimestep,
+	char str[128],fstr[64];
+	sprintf(fstr,"Improper problem: %%d %s %%d %%d %%d %%d",BIGINT_FORMAT);
+	sprintf(str,fstr,me,update->ntimestep,
 		atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
+	error->warning(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]);
 	fprintf(screen,"  3rd atom: %d %g %g %g\n",
 		me,x[i3][0],x[i3][1],x[i3][2]);
 	fprintf(screen,"  4th atom: %d %g %g %g\n",
 		me,x[i4][0],x[i4][1],x[i4][2]);
       }
     }
     
     if (c > 1.0) s = 1.0;
     if (c < -1.0) s = -1.0;
 
     s = sqrt(1.0 - c*c);
     if (s < SMALL) s = SMALL;
     cotphi = c/s;
 
     projhfg = (vb3x*vb1x+vb3y*vb1y+vb3z*vb1z) / 
       sqrt(vb1x*vb1x+vb1y*vb1y+vb1z*vb1z); 
     projhfg += (vb3x*vb2x+vb3y*vb2y+vb3z*vb2z) / 
       sqrt(vb2x*vb2x+vb2y*vb2y+vb2z*vb2z);
     if (projhfg > 0.0) {
       s *= -1.0;
       cotphi *= -1.0;
     }
 	
     //  force and energy
     // if w0 = 0: E = k * (1 - cos w)
     // if w0 != 0: E = 0.5 * C (cos w - cos w0)^2, C = k/(sin(w0)^2
 
     if (w0[type] == 0.0) {
       if (eflag) eimproper = kw[type] * (1.0-s);
       a = -kw[type];
     } else {
       domega = s - cos(w0[type]);
       a = 0.5 * C[type] * domega;
       if (eflag) eimproper = a * domega;
       a *= 2.0;
     }
 
     // dhax = diffrence between H and A in X direction, etc
 
     a = a*cotphi;
     dhax = hrx-c*arx;
     dhay = hry-c*ary;
     dhaz = hrz-c*arz;
 
     dahx = arx-c*hrx;
     dahy = ary-c*hry;
     dahz = arz-c*hrz;
 
     f2[0] = (dhay*vb1z - dhaz*vb1y)*rar;
     f2[1] = (dhaz*vb1x - dhax*vb1z)*rar;
     f2[2] = (dhax*vb1y - dhay*vb1x)*rar;
 
     f3[0] = (-dhay*vb2z + dhaz*vb2y)*rar;
     f3[1] = (-dhaz*vb2x + dhax*vb2z)*rar;
     f3[2] = (-dhax*vb2y + dhay*vb2x)*rar;
 
     f4[0] = dahx*rhr;
     f4[1] = dahy*rhr;
     f4[2] = dahz*rhr;
 
     f1[0] = -(f2[0] + f3[0] + f4[0]);
     f1[1] = -(f2[1] + f3[1] + f4[1]);
     f1[2] = -(f2[2] + f3[2] + f4[2]);
 
     // apply force to each of 4 atoms
 
     if (newton_bond || i1 < nlocal) {
       f[i1][0] += f1[0]*a;
       f[i1][1] += f1[1]*a;
       f[i1][2] += f1[2]*a;
     }
 
     if (newton_bond || i2 < nlocal) {
       f[i2][0] += f3[0]*a;
       f[i2][1] += f3[1]*a;
       f[i2][2] += f3[2]*a;
     }
 
     if (newton_bond || i3 < nlocal) {
       f[i3][0] += f2[0]*a;
       f[i3][1] += f2[1]*a;
       f[i3][2] += f2[2]*a;
     }
 
     if (newton_bond || i4 < nlocal) {
       f[i4][0] += f4[0]*a;
       f[i4][1] += f4[1]*a;
       f[i4][2] += f4[2]*a;
     }
 
     if (evflag)
       ev_tally(i1,i2,i3,i4,nlocal,newton_bond,eimproper,f1,f3,f4,
 	       vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ImproperUmbrella::allocate()
 {
   allocated = 1;
   int n = atom->nimpropertypes;
 
   kw = (double *) memory->smalloc((n+1)*sizeof(double),"improper:kw");
   w0 = (double *) memory->smalloc((n+1)*sizeof(double),"improper:w0");
   C = (double *) memory->smalloc((n+1)*sizeof(double),"improper:C");
 
   setflag = (int *) memory->smalloc((n+1)*sizeof(int),"improper:setflag");
   for (int i = 1; i <= n; i++) setflag[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one type
 ------------------------------------------------------------------------- */
 
 void ImproperUmbrella::coeff(int narg, char **arg)
 {
   if (narg != 3) error->all("Incorrect args for improper coefficients");
   if (!allocated) allocate();
 
   int ilo,ihi;
   force->bounds(arg[0],atom->nimpropertypes,ilo,ihi);
 
   double k_one = atof(arg[1]);
   double w_one = atof(arg[2]);
 
   // convert w0 from degrees to radians
 
   int count = 0;
   for (int i = ilo; i <= ihi; i++) {
     kw[i] = k_one;
     w0[i] = w_one/180.0 * PI;
     if (w_one == 0) C[i] = 1.0;
     else C[i] = kw[i]/(pow(sin(w0[i]),2));
     setflag[i] = 1;
     count++;
   }
 
   if (count == 0) error->all("Incorrect args for improper coefficients");
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out coeffs to restart file 
 ------------------------------------------------------------------------- */
 
 void ImproperUmbrella::write_restart(FILE *fp)
 {
   fwrite(&kw[1],sizeof(double),atom->nimpropertypes,fp);
   fwrite(&w0[1],sizeof(double),atom->nimpropertypes,fp);
   fwrite(&C[1],sizeof(double),atom->nimpropertypes,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads coeffs from restart file, bcasts them 
 ------------------------------------------------------------------------- */
 
 void ImproperUmbrella::read_restart(FILE *fp)
 {
   allocate();
 
   if (comm->me == 0) {
     fread(&kw[1],sizeof(double),atom->nimpropertypes,fp);
     fread(&w0[1],sizeof(double),atom->nimpropertypes,fp);
     fread(&C[1],sizeof(double),atom->nimpropertypes,fp);
   }
   MPI_Bcast(&kw[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&w0[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
   MPI_Bcast(&C[1],atom->nimpropertypes,MPI_DOUBLE,0,world);
 
   for (int i = 1; i <= atom->nimpropertypes; i++) setflag[i] = 1;
 }
diff --git a/src/PERI/atom_vec_peri.cpp b/src/PERI/atom_vec_peri.cpp
index 4e43d7a6b..d20809e6b 100644
--- a/src/PERI/atom_vec_peri.cpp
+++ b/src/PERI/atom_vec_peri.cpp
@@ -1,774 +1,777 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Parks (SNL)
 ------------------------------------------------------------------------- */
 
 #include "float.h"
 #include "stdlib.h"
 #include "atom_vec_peri.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecPeri::AtomVecPeri(LAMMPS *lmp, int narg, char **arg) : 
   AtomVec(lmp, narg, arg) 
 {
   molecular = 0;
 
   comm_x_only = 0;
   comm_f_only = 1;
   size_forward = 4;
   size_reverse = 3;
   size_border = 11;
   size_velocity = 3;
   size_data_atom = 7;
   size_data_vel = 4;
   xcol_data = 5;
 
   atom->vfrac_flag = atom->density_flag = atom->rmass_flag = 1;
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n
 ------------------------------------------------------------------------- */
  
 void AtomVecPeri::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
- 
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
+
   tag = atom->tag = (int *)
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *)
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *)
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
 
   vfrac = atom->vfrac = (double *) 
     memory->srealloc(atom->vfrac,nmax*sizeof(double),"atom:vfrac");
   density = atom->density = (double *)
     memory->srealloc(atom->density,nmax*sizeof(double),"atom:density");
   rmass = atom->rmass = (double *) 
     memory->srealloc(atom->rmass,nmax*sizeof(double),"atom:rmass");
   s0 = atom->s0 = (double *) 
     memory->srealloc(atom->s0,nmax*sizeof(double),"atom:s0");
   x0 = atom->x0 = memory->grow_2d_double_array(atom->x0,nmax,3,"atom:x0");
  
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecPeri::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
   vfrac = atom->vfrac; density = atom->density; rmass = atom->rmass;
   s0 = atom->s0; x0 = atom->x0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecPeri::copy(int i, int j)
 {
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
 
   vfrac[j] = vfrac[i];
   density[j] = density[i];
   rmass[j] = rmass[i];
   s0[j] = s0[i];
   x0[j][0] = x0[i][0];
   x0[j][1] = x0[i][1];
   x0[j][2] = x0[i][2];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecPeri::pack_comm(int n, int *list, double *buf,
                            int pbc_flag, int *pbc)
 
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = s0[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = s0[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecPeri::pack_comm_vel(int n, int *list, double *buf,
 			       int pbc_flag, int *pbc)
 
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = s0[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = s0[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecPeri::pack_comm_one(int i, double *buf)
 {
   buf[0] = s0[i];
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecPeri::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     s0[i] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecPeri::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     s0[i] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecPeri::unpack_comm_one(int i, double *buf)
 {
   s0[i] = buf[0];
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecPeri::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecPeri::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecPeri::pack_border(int n, int *list, double *buf,
                                int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = vfrac[j];
       buf[m++] = s0[j];
       buf[m++] = x0[j][0];
       buf[m++] = x0[j][1];
       buf[m++] = x0[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = vfrac[j];
       buf[m++] = s0[j];
       buf[m++] = x0[j][0];
       buf[m++] = x0[j][1];
       buf[m++] = x0[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecPeri::pack_border_vel(int n, int *list, double *buf,
 				 int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = vfrac[j];
       buf[m++] = s0[j];
       buf[m++] = x0[j][0];
       buf[m++] = x0[j][1];
       buf[m++] = x0[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = vfrac[j];
       buf[m++] = s0[j];
       buf[m++] = x0[j][0];
       buf[m++] = x0[j][1];
       buf[m++] = x0[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecPeri::pack_border_one(int i, double *buf)
 {
   buf[0] = vfrac[i];
   buf[1] = s0[i];
   buf[2] = x0[i][0];
   buf[3] = x0[i][1];
   buf[4] = x0[i][2];
   return 5;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecPeri::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     vfrac[i] = buf[m++];
     s0[i] = buf[m++];
     x0[i][0] = buf[m++];
     x0[i][1] = buf[m++];
     x0[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecPeri::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     vfrac[i] = buf[m++];
     s0[i] = buf[m++];
     x0[i][0] = buf[m++];
     x0[i][1] = buf[m++];
     x0[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
  
 int AtomVecPeri::unpack_border_one(int i, double *buf)
 {
   vfrac[i] = buf[0];
   s0[i] = buf[1];
   x0[i][0] = buf[2];
   x0[i][1] = buf[3];
   x0[i][2] = buf[4];
   return 5;
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    xyz must be 1st 3 values, so comm::exchange() can test on them
 ------------------------------------------------------------------------- */
 
 int AtomVecPeri::pack_exchange(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
 
   buf[m++] = vfrac[i];
   buf[m++] = density[i];
   buf[m++] = rmass[i];
   buf[m++] = s0[i];
   buf[m++] = x0[i][0];
   buf[m++] = x0[i][1];
   buf[m++] = x0[i][2];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecPeri::unpack_exchange(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
 
   vfrac[nlocal] = buf[m++];
   density[nlocal] = buf[m++];
   rmass[nlocal] = buf[m++];
   s0[nlocal] = buf[m++];
   x0[nlocal][0] = buf[m++];
   x0[nlocal][1] = buf[m++];
   x0[nlocal][2] = buf[m++];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
  
 int AtomVecPeri::size_restart()
 {
   int i;
  
   int nlocal = atom->nlocal;
   int n = 18 * nlocal;
  
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
       for (i = 0; i < nlocal; i++)
         n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
  
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive
 ------------------------------------------------------------------------- */
  
 int AtomVecPeri::pack_restart(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
  
   buf[m++] = vfrac[i];
   buf[m++] = density[i];
   buf[m++] = rmass[i];
   buf[m++] = s0[i];
   buf[m++] = x0[i][0];
   buf[m++] = x0[i][1];
   buf[m++] = x0[i][2];
  
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
  
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
  
 int AtomVecPeri::unpack_restart(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store)
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
                                                  atom->nextra_store,
                                                  "atom:extra");
   }
  
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
  
   vfrac[nlocal] = buf[m++];
   density[nlocal] = buf[m++];
   rmass[nlocal] = buf[m++];
   s0[nlocal] = buf[m++];
   x0[nlocal][0] = buf[m++];
   x0[nlocal][1] = buf[m++];
   x0[nlocal][2] = buf[m++];
  
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
  
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
  
 void AtomVecPeri::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
  
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
  
   vfrac[nlocal] = 1.0;
   density[nlocal] = 1.0;
   rmass[nlocal] = density[nlocal];
   s0[nlocal] = DBL_MAX;
   x0[nlocal][0] = coord[0];
   x0[nlocal][1] = coord[1];
   x0[nlocal][2] = coord[2];
  
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
  
 void AtomVecPeri::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
  
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   vfrac[nlocal] = atof(values[2]);
   density[nlocal] = atof(values[3]);
   rmass[nlocal] = density[nlocal];
   if (rmass[nlocal] <= 0.0) error->one("Invalid mass value");
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   image[nlocal] = imagetmp;
  
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   s0[nlocal] = DBL_MAX;
   x0[nlocal][0] = coord[0];
   x0[nlocal][1] = coord[1];
   x0[nlocal][2] = coord[2];
  
   atom->nlocal++;
 }
  
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Atoms section of data file
    initialize other atom quantities for this sub-style
 ------------------------------------------------------------------------- */
  
 int AtomVecPeri::data_atom_hybrid(int nlocal, char **values)
 {
   vfrac[nlocal] = atof(values[0]);
   density[nlocal] = atof(values[1]);
   rmass[nlocal] = density[nlocal];
   if (rmass[nlocal] <= 0.0) error->one("Invalid mass value");
 
   s0[nlocal] = DBL_MAX;
   x0[nlocal][0] = x[nlocal][0];
   x0[nlocal][1] = x[nlocal][1];
   x0[nlocal][2] = x[nlocal][2];
  
   return 2;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory
 ------------------------------------------------------------------------- */
  
 double AtomVecPeri::memory_usage()
 {
   double bytes = 0.0;
  
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
  
   if (atom->memcheck("vfrac")) bytes += nmax * sizeof(double);
   if (atom->memcheck("density")) bytes += nmax * sizeof(double);
   if (atom->memcheck("rmass")) bytes += nmax * sizeof(double);
   if (atom->memcheck("s0")) bytes += nmax * sizeof(double);
   if (atom->memcheck("x0")) bytes += nmax*3 * sizeof(double);
  
   return bytes;
 }
diff --git a/src/PERI/fix_peri_neigh.cpp b/src/PERI/fix_peri_neigh.cpp
index 14dbf8cbb..d56946caa 100644
--- a/src/PERI/fix_peri_neigh.cpp
+++ b/src/PERI/fix_peri_neigh.cpp
@@ -1,518 +1,518 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Parks (SNL)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "fix_peri_neigh.h"
 #include "pair_peri_pmb.h"
 #include "pair_peri_lps.h"
 #include "atom.h"
 #include "domain.h"
 #include "force.h"
 #include "comm.h"
 #include "update.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "neigh_request.h"
 #include "pair.h"
 #include "lattice.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 /* ---------------------------------------------------------------------- */
 
 FixPeriNeigh::FixPeriNeigh(LAMMPS *lmp,int narg, char **arg) : 
   Fix(lmp, narg, arg)
 {
   restart_global = 1;
   restart_peratom = 1;
   first = 1;
 
   // perform initial allocation of atom-based arrays
   // register with atom class
   // set maxpartner = 1 as placeholder
 
   maxpartner = 1;
   npartner = NULL;
   partner = NULL;
   r0 = NULL;
   vinter = NULL;
   wvolume = NULL;
 
   grow_arrays(atom->nmax);
   atom->add_callback(0);
   atom->add_callback(1);
 
   // initialize npartner to 0 so atom migration is OK the 1st time
 
   int nlocal = atom->nlocal;
   for (int i = 0; i < nlocal; i++) npartner[i] = 0;
 
   // set comm sizes needed by this fix
 
   comm_forward = 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixPeriNeigh::~FixPeriNeigh()
 {
   // unregister this fix so atom class doesn't invoke it any more
 
   atom->delete_callback(id,0);
   atom->delete_callback(id,1);
 
   // delete locally stored arrays
 
   memory->sfree(npartner);
   memory->destroy_2d_int_array(partner);
   memory->destroy_2d_double_array(r0);
   memory->sfree(vinter);
   memory->sfree(wvolume);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixPeriNeigh::setmask()
 {
   int mask = 0;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixPeriNeigh::init()
 {
   if (!first) return;
 
   // need a full neighbor list once
 
   int irequest = neighbor->request((void *) this);
   neighbor->requests[irequest]->pair = 0;
   neighbor->requests[irequest]->fix  = 1;
   neighbor->requests[irequest]->half = 0; 
   neighbor->requests[irequest]->full = 1;
   neighbor->requests[irequest]->occasional = 1;
 }
 
 /* ---------------------------------------------------------------------- */
  
 void FixPeriNeigh::init_list(int id, NeighList *ptr)
 {
   list = ptr;
 }
 
 /* ----------------------------------------------------------------------
    create initial list of neighbor partners via call to neighbor->build()
    must be done in setup (not init) since fix init comes before neigh init
 ------------------------------------------------------------------------- */
 
 void FixPeriNeigh::setup(int vflag)
 {
   int i,j,ii,jj,itype,jtype,inum,jnum;
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   int *ilist,*jlist,*numneigh;
   int **firstneigh;
 
   double **x = atom->x;
   double *vfrac = atom->vfrac;
   int *type = atom->type;
   int *tag = atom->tag;
   int nlocal = atom->nlocal;
 
  // only build list of bonds on very first run
 
   if (!first) return;
   first = 0;
 
   // invoke full neighbor list (will copy or build if necessary)
 
   neighbor->build_one(list->index);
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
 
   // scan neighbor list to set maxpartner
 
   Pair *anypair = force->pair_match("peri",0);
   double **cutsq = anypair->cutsq;
 
   for (ii = 0; ii < inum; ii++) {
     i = ilist[ii];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
 
       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];
       if (rsq <= cutsq[itype][jtype]) npartner[i]++;
     }
   }
 
   maxpartner = 0;
   for (i = 0; i < nlocal; i++) maxpartner = MAX(maxpartner,npartner[i]);
   int maxall;
   MPI_Allreduce(&maxpartner,&maxall,1,MPI_INT,MPI_MAX,world);
   maxpartner = maxall;
 
   // realloc arrays with correct value for maxpartner
 
   memory->destroy_2d_int_array(partner);
   memory->destroy_2d_double_array(r0);
   memory->sfree(npartner);
 
   npartner = NULL;
   partner = NULL;
   r0 = NULL;
   grow_arrays(atom->nmax);
 
   // create partner list and r0 values from neighbor list
   // compute vinter for each atom
 
   for (i = 0; i < nlocal; i++) {
     npartner[i] = 0;
     vinter[i] = 0.0;
     wvolume[i] = 0.0;
   }
 
   for (ii = 0; ii < inum; ii++) {
     i = ilist[ii];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     itype = type[i];
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
 
       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];
 
       if (rsq <= cutsq[itype][jtype]) {
         partner[i][npartner[i]] = tag[j];
         r0[i][npartner[i]] = sqrt(rsq);
         npartner[i]++;
         vinter[i] += vfrac[j];
       }
     }
   }
 
   // compute wvolume for each atom
 
   double **x0 = atom->x0;
   double half_lc = 0.5*(domain->lattice->xlattice);
   double vfrac_scale;
   PairPeriLPS *pairlps = dynamic_cast<PairPeriLPS*>(anypair);
   PairPeriPMB *pairpmb = dynamic_cast<PairPeriPMB*>(anypair);
   for (i = 0; i < nlocal; i++) {
     double xtmp0 = x0[i][0];
     double ytmp0 = x0[i][1];
     double ztmp0 = x0[i][2];
     jnum = npartner[i];
     itype = type[i];
 
     // loop over partners of particle i
 
     for (jj = 0; jj < jnum; jj++) {
 
       // if bond already broken, skip this partner
 
       if (partner[i][jj] == 0) continue;
 
       // lookup local index of partner particle
 
       j = atom->map(partner[i][jj]);
 
       // skip if particle is "lost"
 
       if (j < 0) continue;
 
       double delx0 = xtmp0 - x0[j][0];
       double dely0 = ytmp0 - x0[j][1];
       double delz0 = ztmp0 - x0[j][2];
       double rsq0 = delx0*delx0 + dely0*dely0 + delz0*delz0;
 
       jtype = type[j];
       double delta = sqrt(cutsq[itype][jtype]);
 
       // scale vfrac[j] if particle j near the horizon
 
       if ((fabs(r0[i][jj] - delta)) <= half_lc)
         vfrac_scale = (-1.0/(2*half_lc))*(r0[i][jj]) +
           (1.0 + ((delta - half_lc)/(2*half_lc) ) );
       else vfrac_scale = 1.0;
 
       if (pairpmb != NULL) // define influence function to be 1.0
         wvolume[i] += 1.0 * rsq0 * vfrac[j] * vfrac_scale;
       else if (pairlps != NULL) // call the PairPeriLPS influence function
         wvolume[i] += pairlps->influence_function(delx0,dely0,delz0) * 
 	  rsq0 * vfrac[j] * vfrac_scale;
 
     }
   }
 
   // communicate wvolume to ghosts
 
   comm->forward_comm_fix(this);
 
   // bond statistics
 
   int n = 0;
   for (i = 0; i < nlocal; i++) n += npartner[i];
   int nall;
   MPI_Allreduce(&n,&nall,1,MPI_INT,MPI_SUM,world);
 
   if (comm->me == 0) {
     if (screen) {
       fprintf(screen,"Peridynamic bonds:\n");
       fprintf(screen,"  total # of bonds = %d\n",nall);
-      fprintf(screen,"  bonds/atom = %g\n",nall/atom->natoms);
+      fprintf(screen,"  bonds/atom = %g\n",(double)nall/atom->natoms);
     }
     if (logfile) {
       fprintf(logfile,"Peridynamic bonds:\n");
       fprintf(logfile,"  total # of bonds = %d\n",nall);
-      fprintf(logfile,"  bonds/atom = %g\n",nall/atom->natoms);
+      fprintf(logfile,"  bonds/atom = %g\n",(double)nall/atom->natoms);
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    memory usage of local atom-based arrays
 ------------------------------------------------------------------------- */
 
 double FixPeriNeigh::memory_usage()
 {
   int nmax = atom->nmax;
   int bytes = nmax * sizeof(int);
   bytes += nmax*maxpartner * sizeof(int);
   bytes += nmax*maxpartner * sizeof(double);
   bytes += nmax * sizeof(double);
   bytes += nmax * sizeof(double);
   return bytes;
 }
 
 /* ----------------------------------------------------------------------
    allocate local atom-based arrays
 ------------------------------------------------------------------------- */
 
 void FixPeriNeigh::grow_arrays(int nmax)
 {
   npartner = (int *) memory->srealloc(npartner,nmax*sizeof(int),
 				      "peri_neigh:npartner");
   partner = memory->grow_2d_int_array(partner,nmax,maxpartner,
 				      "peri_neigh:partner");
   r0 = memory->grow_2d_double_array(r0,nmax,maxpartner,"peri_neigh:r0");
   vinter = (double *) memory->srealloc(vinter,nmax*sizeof(double),
 				       "peri_neigh:vinter");
   wvolume = (double *) memory->srealloc(wvolume,nmax*sizeof(double),
                                        "peri_neigh:wvolume");
 }
 
 /* ----------------------------------------------------------------------
    copy values within local atom-based arrays
 ------------------------------------------------------------------------- */
 
 void FixPeriNeigh::copy_arrays(int i, int j)
 {
   npartner[j] = npartner[i];
   for (int m = 0; m < npartner[j]; m++) {
     partner[j][m] = partner[i][m];
     r0[j][m] = r0[i][m];
   }
   vinter[j] = vinter[i];
   wvolume[j] = wvolume[i];
 }
 
 /* ----------------------------------------------------------------------
    pack values in local atom-based arrays for exchange with another proc
 ------------------------------------------------------------------------- */
 
 int FixPeriNeigh::pack_exchange(int i, double *buf)
 {
   // compact list by eliminating partner = 0 entries
   // set buf[0] after compaction
 
   int m = 1;
   for (int n = 0; n < npartner[i]; n++) {
     if (partner[i][n] == 0) continue;
     buf[m++] = partner[i][n];
     buf[m++] = r0[i][n];
   }
 
   buf[0] = m/2;
   buf[m++] = vinter[i];
   buf[m++] = wvolume[i];
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack values in local atom-based arrays from exchange with another proc
 ------------------------------------------------------------------------- */
 
 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++]);
     r0[nlocal][n] = buf[m++];
   }
   vinter[nlocal] = buf[m++];
   wvolume[nlocal] = buf[m++];
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixPeriNeigh::pack_comm(int n, int *list, double *buf,
                              int pbc_flag, int *pbc)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     buf[m++] = wvolume[j];
   }
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixPeriNeigh::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++)
     wvolume[i] = buf[m++];
 }
 
 /* ----------------------------------------------------------------------
    pack entire state of Fix into one write
 ------------------------------------------------------------------------- */
 
 void FixPeriNeigh::write_restart(FILE *fp)
 {
   int n = 0;
   double list[2];
   list[n++] = first;
   list[n++] = maxpartner;
 
   if (comm->me == 0) {
     int size = n * sizeof(double);
     fwrite(&size,sizeof(int),1,fp);
     fwrite(list,sizeof(double),n,fp);
   }
 }
 
 /* ----------------------------------------------------------------------
    use state info from restart file to restart the Fix
 ------------------------------------------------------------------------- */
 
 void FixPeriNeigh::restart(char *buf)
 {
   int n = 0;
   double *list = (double *) buf;
 
   first = static_cast<int> (list[n++]);
   maxpartner = static_cast<int> (list[n++]);
 
   // grow 2D arrays now, cannot change size of 2nd array index later
 
   grow_arrays(atom->nmax);
 }
 
 /* ----------------------------------------------------------------------
    pack values in local atom-based arrays for restart file
 ------------------------------------------------------------------------- */
 
 int FixPeriNeigh::pack_restart(int i, double *buf)
 {
   int m = 0;
   buf[m++] = 2*npartner[i] + 4;
   buf[m++] = npartner[i];
   for (int n = 0; n < npartner[i]; n++) {
     buf[m++] = partner[i][n];
     buf[m++] = r0[i][n];
   }
   buf[m++] = vinter[i];
   buf[m++] = wvolume[i];
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack values from atom->extra array to restart the fix
 ------------------------------------------------------------------------- */
 
 void FixPeriNeigh::unpack_restart(int nlocal, int nth)
 {
   double **extra = atom->extra;
 
   // skip to Nth set of extra values
 
   int m = 0;
   for (int i = 0; i < nth; i++) m += static_cast<int> (extra[nlocal][m]);
   m++;
 
   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++]);
     r0[nlocal][n] = extra[nlocal][m++];
   }
   vinter[nlocal] = extra[nlocal][m++];
   wvolume[nlocal] = extra[nlocal][m++];
 }
 
 /* ----------------------------------------------------------------------
    maxsize of any atom's restart data
 ------------------------------------------------------------------------- */
 
 int FixPeriNeigh::maxsize_restart()
 {
   return 2*maxpartner + 4;
 }
 
 /* ----------------------------------------------------------------------
    size of atom nlocal's restart data
 ------------------------------------------------------------------------- */
 
 int FixPeriNeigh::size_restart(int nlocal)
 {
   return 2*npartner[nlocal] + 4;
 }
diff --git a/src/REAX/fix_reax_bonds.cpp b/src/REAX/fix_reax_bonds.cpp
index 5961b8ed0..1798ffc32 100644
--- a/src/REAX/fix_reax_bonds.cpp
+++ b/src/REAX/fix_reax_bonds.cpp
@@ -1,237 +1,240 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Aidan Thompson (Sandia)
 ------------------------------------------------------------------------- */
 
 #include "stdlib.h"
 #include "string.h"
 #include "fix_reax_bonds.h"
+#include "lmptype.h"
 #include "pair_reax_fortran.h"
 #include "atom.h"
 #include "update.h"
 #include "force.h"
 #include "modify.h"
 #include "compute.h"
 #include "input.h"
 #include "variable.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 FixReaxBonds::FixReaxBonds(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 5) error->all("Illegal fix reax/bonds command");
 
   MPI_Comm_rank(world,&me);
 
   nevery = atoi(arg[3]);
   if (nevery < 1) error->all("Illegal fix reax/bonds command");
 
   if (me == 0) {
     fp = fopen(arg[4],"w");
     if (fp == NULL) {
       char str[128];
       sprintf(str,"Cannot open fix reax/bonds file %s",arg[4]);
       error->one(str);
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixReaxBonds::~FixReaxBonds()
 {
   if (me == 0) fclose(fp);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixReaxBonds::setmask()
 {
   int mask = 0;
   mask |= END_OF_STEP;
   return mask;
 }
 
 /* ----------------------------------------------------------------------
    perform initial write
 ------------------------------------------------------------------------- */
 
 void FixReaxBonds::setup(int vflag)
 {
   end_of_step();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixReaxBonds::init()
 {
   // insure ReaxFF is defined
 
   if (force->pair_match("reax",1) == NULL)
     error->all("Cannot use fix reax/bonds without pair_style reax");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixReaxBonds::end_of_step()
 {
   OutputReaxBonds(update->ntimestep,fp);
   if (me == 0) fflush(fp);
 }
 
 /* ---------------------------------------------------------------------- */
 
-void FixReaxBonds::OutputReaxBonds(int timestep, FILE *fp) 
+void FixReaxBonds::OutputReaxBonds(bigint ntimestep, FILE *fp) 
 {
   int nparticles,nparticles_tot,nbuf,nbuf_local,most,j;
   int ii,jn,mbond,numbonds,nsbmax,nsbmax_most;
   int nprocs,nlocal_tmp,itmp;
   double cutof3;
   double *buf;
   MPI_Request irequest;
   MPI_Status istatus;
 
   MPI_Comm_size(world,&nprocs);
  
   nparticles = atom->nlocal;
   nparticles_tot = static_cast<int> (atom->natoms);
  
   mbond = ReaxParams::mbond;
   FORTRAN(getnsbmax,GETNSBMAX)(&nsbmax);
   FORTRAN(getcutof3,GETCUTOF3)(&cutof3);
   MPI_Allreduce(&nparticles,&most,1,MPI_INT,MPI_MAX,world);
   MPI_Allreduce(&nsbmax,&nsbmax_most,1,MPI_INT,MPI_MAX,world);
  
   if (me == 0) {
-    fprintf(fp,"# Timestep %d \n",timestep);
+    char fstr[32];
+    sprintf(fstr,"# Timestep %d \n",BIGINT_FORMAT);
+    fprintf(fp,fstr,ntimestep);
     fprintf(fp,"# \n");
     fprintf(fp,"# Number of particles %d \n",nparticles_tot);
     fprintf(fp,"# \n");
     fprintf(fp,"# Max.number of bonds per atom %d with "
 	    "coarse bond order cutoff %5.3f \n",
 	    nsbmax_most,cutof3);
     fprintf(fp,"# Particle connection table and bond orders \n");
     fprintf(fp,"# id type nb id_1...id_nb mol bo_1...bo_nb abo nlp q \n");
   }
  
   // allocate a temporary buffer for the snapshot info
   // big enough for largest number of atoms on any one proc
   // nbuf_local = size of local buffer for table of atom bonds
  
   nbuf = 1+(2*nsbmax_most+7)*most;
   buf = (double *) memory->smalloc(nbuf*sizeof(double),"reax/bonds:buf");
  
   j = 2;
   jn = ReaxParams::nat;
   buf[0] = nparticles;
   for (int iparticle=0;iparticle<nparticles;iparticle++) {
     buf[j-1] = atom->tag[iparticle];                   //atom tag
     buf[j+0] = FORTRAN(cbkia,CBKIA).iag[iparticle];    //atom type
     buf[j+1] = FORTRAN(cbkia,CBKIA).iag[iparticle+jn]; //no.bonds
     int k;
     numbonds = nint(buf[j+1]);
 
     // connection table based on coarse bond order cutoff (> cutof3)
     for (k=2;k<2+numbonds;k++) {
       ii = FORTRAN(cbkia,CBKIA).iag[iparticle+jn*k];
       buf[j+k] = FORTRAN(cbkc,CBKC).itag[ii-1];
     }
     buf[j+k]=FORTRAN(cbkia,CBKIA).iag[iparticle+jn*(mbond+2)]; //molec.id
     j+=(3+numbonds);
 
     // bond orders (> cutof3)
     for (k=0;k<numbonds;k++) {
       ii = FORTRAN(cbknubon2,CBKNUBON2).nubon1[iparticle+jn*k];
       buf[j+k] = FORTRAN(cbkbo,CBKBO).bo[ii-1];
     }
     // sum of bond orders (abo), no. of lone pairs (vlp), charge (ch)
     buf[j+k] = FORTRAN(cbkabo,CBKABO).abo[iparticle];
     buf[j+k+1] = FORTRAN(cbklonpar,CBKLONPAR).vlp[iparticle];
     //    buf[j+k+2] = FORTRAN(cbkch,CBKCH).ch[iparticle];
     buf[j+k+2] = atom->q[iparticle];
     j+=(4+numbonds);
   }
   nbuf_local = j-1;
  
   // node 0 pings each node, receives their buffer, writes to file
   // all other nodes wait for ping, send buffer to node 0
  
   if (me == 0) {
     for (int inode = 0; inode<nprocs; inode++) {
       if (inode == 0) {
 	nlocal_tmp = nparticles;
       } else {
 	MPI_Irecv(&buf[0],nbuf,MPI_DOUBLE,inode,0,world,&irequest);
         MPI_Send(&itmp,0,MPI_INT,inode,0,world);
         MPI_Wait(&irequest,&istatus);
 	nlocal_tmp = nint(buf[0]);
       }
  
       j = 2;
       for (int iparticle=0;iparticle<nlocal_tmp;iparticle++) {
 	// print atom tag, atom type, no.bonds
 
 	fprintf(fp," %d %d %d",nint(buf[j-1]),nint(buf[j+0]),nint(buf[j+1]));
 	int k;
 	numbonds = nint(buf[j+1]);
 	if (numbonds > nsbmax_most) {
 	  char str[128];
 	  sprintf(str,"Fix reax/bonds numbonds > nsbmax_most");
 	  error->one(str);
 	}
 
 	// print connection table
 
 	for (k=2;k<2+numbonds;k++)
 	  fprintf(fp," %d",nint(buf[j+k]));
 	fprintf(fp," %d",nint(buf[j+k]));
 	j+=(3+numbonds);
 
 	// print bond orders
 
 	for (k=0;k<numbonds;k++)
 	  fprintf(fp,"%14.3f",buf[j+k]);
 
 	// print sum of bond orders, no. of lone pairs, charge
 
 	fprintf(fp,"%14.3f%14.3f%14.3f\n",buf[j+k],buf[j+k+1],buf[j+k+2]);
 	j+=(4+numbonds);
       }
     }
 
   } else {
     MPI_Recv(&itmp,0,MPI_INT,0,0,world,&istatus);
     MPI_Rsend(&buf[0],nbuf_local,MPI_DOUBLE,0,0,world);
   }
 
   if (me == 0) fprintf(fp,"# \n");
 
   memory->sfree(buf);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixReaxBonds::nint(const double &r)
 {
   int i = 0;
   if (r>0.0) i = static_cast<int>(r+0.5);
   else if (r<0.0) i = static_cast<int>(r-0.5);
   return i;
 }
diff --git a/src/REAX/pair_reax.cpp b/src/REAX/pair_reax.cpp
index 218c4e427..a51737589 100644
--- a/src/REAX/pair_reax.cpp
+++ b/src/REAX/pair_reax.cpp
@@ -1,1069 +1,1069 @@
 /* ----------------------------------------------------------------------
    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: Aidan Thompson (Sandia, athomps@sandia.gov)
                          Hansohl Cho (MIT, hansohl@mit.edu)
    LAMMPS implementation of the Reactive Force Field (ReaxFF) is based on
      Aidan Thompson's GRASP code
        (General Reactive Atomistic Simulation Program)
      and Ardi Van Duin's original ReaxFF code
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "string.h"
 #include "pair_reax.h"
 #include "pair_reax_fortran.h"
 #include "atom.h"
 #include "update.h"
 #include "force.h"
 #include "comm.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "neigh_request.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 #define SMALL 0.0001
 
 /* ---------------------------------------------------------------------- */
 
 PairREAX::PairREAX(LAMMPS *lmp) : Pair(lmp)
 {
   single_enable = 0;
   one_coeff = 1;
   no_virial_compute = 1;
   
   nextra = 14;
   pvector = new double[nextra];
 
   cutmax = 0.0;
   hbcut = 6.0;
   ihbnew = 1;
   itripstaball = 1;
   iprune = 4;
   ihb = 1;
   chpot = 0;
 
   nmax = 0;
   arow_ptr = NULL;
   ch = NULL;
   elcvec = NULL;
   rcg = NULL;
   wcg = NULL;
   pcg = NULL;
   poldcg = NULL;
   qcg = NULL;
 
   matmax = 0;
   aval = NULL;
   acol_ind = NULL;
 
   comm_forward = 1;
   comm_reverse = 1;
 
   precision = 1.0e-6;
 }
 
 /* ----------------------------------------------------------------------
    free all arrays
    check if allocated, since class can be destructed when incomplete
 ------------------------------------------------------------------------- */
 
 PairREAX::~PairREAX()
 {
   delete [] pvector;
 
   if (allocated) {
     memory->destroy_2d_int_array(setflag);
     memory->destroy_2d_double_array(cutsq);
 
     for (int i = 1; i <= atom->ntypes; i++)
       delete [] param_list[i].params;
     delete [] param_list;
 
     delete [] map;
   }
 
   memory->sfree(arow_ptr);
   memory->sfree(ch);
   memory->sfree(elcvec);
   memory->sfree(rcg);
   memory->sfree(wcg);
   memory->sfree(pcg);
   memory->sfree(poldcg);
   memory->sfree(qcg);
 
   memory->sfree(aval);
   memory->sfree(acol_ind);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairREAX::compute(int eflag, int vflag)
 {
   int i,j;
   double evdwl,ecoul;
   double energy_charge_equilibration;
 
   evdwl = ecoul = 0.0;
   if (eflag || vflag) ev_setup(eflag,vflag);
   else evflag = vflag_fdotr = eflag_global = vflag_global = 0;
 
   if (vflag_global) FORTRAN(cbkvirial, CBKVIRIAL).Lvirial = 1;
   else FORTRAN(cbkvirial, CBKVIRIAL).Lvirial = 0;
 
   if (vflag_atom) FORTRAN(cbkvirial, CBKVIRIAL).Latomvirial = 1;
   else FORTRAN(cbkvirial, CBKVIRIAL).Latomvirial = 0;
 
   // reallocate charge equilibration and CG arrays if necessary
 
   if (atom->nmax > nmax) {
     memory->sfree(rcg);
     memory->sfree(wcg);
     memory->sfree(pcg);
     memory->sfree(poldcg);
     memory->sfree(qcg);
 
     nmax = atom->nmax;
     int n = nmax+1;
 
     arow_ptr = (int *) memory->smalloc(n*sizeof(int),"reax:arow_ptr");
     ch = (double *) memory->smalloc(n*sizeof(double),"reax:ch");
     elcvec = (double *) memory->smalloc(n*sizeof(double),"reax:elcvec");
     rcg = (double *) memory->smalloc(n*sizeof(double),"reax:rcg");
     wcg = (double *) memory->smalloc(n*sizeof(double),"reax:wcg");
     pcg = (double *) memory->smalloc(n*sizeof(double),"reax:pcg");
     poldcg = (double *) memory->smalloc(n*sizeof(double),"reax:poldcg");
     qcg = (double *) memory->smalloc(n*sizeof(double),"reax:qcg");
   }
 
   // calculate the atomic charge distribution
  
   compute_charge(energy_charge_equilibration);
 
   // transfer LAMMPS positions and neighbor lists to REAX
 
   write_reax_positions();
   write_reax_vlist();
 
   // determine whether this bond is owned by the processor or not
 
   FORTRAN(srtbon1, SRTBON1)(&iprune, &ihb, &hbcut, &ihbnew, &itripstaball);
 
   // communicate with other processors for the atomic bond order calculations
 
   FORTRAN(cbkabo, CBKABO).abo;
 
   // communicate local atomic bond order to ghost atomic bond order
 
   packflag = 0;
   comm->forward_comm_pair(this);
 
   FORTRAN(molec, MOLEC)();
   FORTRAN(encalc, ENCALC)();
   FORTRAN(mdsav, MDSAV)(&comm->me);
 
   // read forces from ReaxFF Fortran
 
   read_reax_forces();
 
   // extract global and per-atom energy from ReaxFF Fortran
   // compute_charge already contributed to eatom
 
   if (eflag_global) {
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).eb;
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).ea;
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).elp;
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).emol;
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).ev;
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).epen;
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).ecoa;
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).ehb;
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).et;
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).eco;
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).ew;
     evdwl += FORTRAN(cbkenergies, CBKENERGIES).efi;
 
     ecoul += FORTRAN(cbkenergies, CBKENERGIES).ep;
     ecoul += energy_charge_equilibration;
     
     eng_vdwl += evdwl;
     eng_coul += ecoul;
 
     // Store the different parts of the energy
     // in a list for output by compute pair command
 
     pvector[0] = FORTRAN(cbkenergies, CBKENERGIES).eb;   
     pvector[1] = FORTRAN(cbkenergies, CBKENERGIES).ea;
     pvector[2] = FORTRAN(cbkenergies, CBKENERGIES).elp;
     pvector[3] = FORTRAN(cbkenergies, CBKENERGIES).emol;
     pvector[4] = FORTRAN(cbkenergies, CBKENERGIES).ev;
     pvector[5] = FORTRAN(cbkenergies, CBKENERGIES).epen;
     pvector[6] = FORTRAN(cbkenergies, CBKENERGIES).ecoa;
     pvector[7] = FORTRAN(cbkenergies, CBKENERGIES).ehb;
     pvector[8] = FORTRAN(cbkenergies, CBKENERGIES).et;
     pvector[9] = FORTRAN(cbkenergies, CBKENERGIES).eco;
     pvector[10] = FORTRAN(cbkenergies, CBKENERGIES).ew;
     pvector[11] = FORTRAN(cbkenergies, CBKENERGIES).ep;
     pvector[12] = FORTRAN(cbkenergies, CBKENERGIES).efi;
     pvector[13] = energy_charge_equilibration;    
   
   }
 
   if (eflag_atom) {
     int ntotal = atom->nlocal + atom->nghost;
     for (i = 0; i < ntotal; i++)
       eatom[i] += FORTRAN(cbkd,CBKD).estrain[i];
   }
 
   // extract global and per-atom virial from ReaxFF Fortran
 
   if (vflag_global) {
     virial[0] = -FORTRAN(cbkvirial, CBKVIRIAL).virial[0];
     virial[1] = -FORTRAN(cbkvirial, CBKVIRIAL).virial[1];
     virial[2] = -FORTRAN(cbkvirial, CBKVIRIAL).virial[2];
     virial[3] = -FORTRAN(cbkvirial, CBKVIRIAL).virial[3];
     virial[4] = -FORTRAN(cbkvirial, CBKVIRIAL).virial[4];
     virial[5] = -FORTRAN(cbkvirial, CBKVIRIAL).virial[5];
   }
 
   if (vflag_atom) {
     int ntotal = atom->nlocal + atom->nghost;
     j = 0;
     for (i = 0; i < ntotal; i++) {
       vatom[i][0] = -FORTRAN(cbkvirial, CBKVIRIAL).atomvirial[j+0];
       vatom[i][1] = -FORTRAN(cbkvirial, CBKVIRIAL).atomvirial[j+1];
       vatom[i][2] = -FORTRAN(cbkvirial, CBKVIRIAL).atomvirial[j+2];
       vatom[i][3] = -FORTRAN(cbkvirial, CBKVIRIAL).atomvirial[j+3];
       vatom[i][4] = -FORTRAN(cbkvirial, CBKVIRIAL).atomvirial[j+4];
       vatom[i][5] = -FORTRAN(cbkvirial, CBKVIRIAL).atomvirial[j+5];
       j += 6;
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairREAX::write_reax_positions()
 {
   double xtmp, ytmp, ztmp;
   int j, jx, jy, jz, jia;
 
   double **x = atom->x;
   double *q = atom->q;
   int *type = atom->type;
   int *tag = atom->tag;
   int nlocal = atom->nlocal;
   int nghost = atom->nghost;
 
   FORTRAN(rsmall, RSMALL).na = nlocal+nghost;
   FORTRAN(rsmall, RSMALL).na_local = nlocal;
 
   if (nlocal+nghost > ReaxParams::nat)
     error->one("Reax_defs.h setting for NATDEF is too small");
 
   jx = 0;
   jy = ReaxParams::nat;
   jz = 2*ReaxParams::nat;
   jia = 0;
 
   j = 0;
   for (int i = 0; i < nlocal+nghost; i++, j++) {
     FORTRAN(cbkc, CBKC).c[j+jx] = x[i][0];
     FORTRAN(cbkc, CBKC).c[j+jy] = x[i][1];
     FORTRAN(cbkc, CBKC).c[j+jz] = x[i][2];
     FORTRAN(cbkch, CBKCH).ch[j] = q[i];
     FORTRAN(cbkia, CBKIA).ia[j+jia] = map[type[i]];
     FORTRAN(cbkia, CBKIA).iag[j+jia] = map[type[i]];
     FORTRAN(cbkc, CBKC).itag[j] = tag[i];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairREAX::write_reax_vlist()
 {
   int ii, jj, i, j, iii, jjj;
   double xitmp, yitmp, zitmp;
   double xjtmp, yjtmp, zjtmp;
   int itag,jtag;
   int nvpair, nvlself, nvpairmax;
   int nbond;
   int inum,jnum;
   int *ilist;
   int *jlist;
   int *numneigh,**firstneigh;
   double delr2;
   double delx, dely, delz;
   double rtmp[3];
 
   double **x = atom->x;
   int *tag = atom->tag;
   int nlocal = atom->nlocal;
   int nghost = atom->nghost;
 
   nvpairmax = ReaxParams::nneighmax * ReaxParams::nat;
 
   nvpair = 0;
   nvlself =0;
   nbond = 0;
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
 
   for (ii = 0; ii < inum; ii++) {
     i = ilist[ii];
     xitmp = x[i][0];
     yitmp = x[i][1];
     zitmp = x[i][2];
     itag = tag[i];
     jlist = firstneigh[i];
     jnum = numneigh[i];
     
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
       xjtmp = x[j][0];
       yjtmp = x[j][1];
       zjtmp = x[j][2];
       jtag = tag[j];
       
       delx = xitmp - xjtmp;
       dely = yitmp - yjtmp;
       delz = zitmp - zjtmp;
       
       delr2 = delx*delx+dely*dely+delz*delz;
       
       if (delr2 <= rcutvsq) {
 	if (i < j) {
 	  iii = i+1;
 	  jjj = j+1;
 	} else {
 	  iii = j+1;
 	  jjj = i+1;
 	}
 	if (nvpair >= nvpairmax) 
 	  error->one("Reax_defs.h setting for NNEIGHMAXDEF is too small");
 	
 	FORTRAN(cbkpairs, CBKPAIRS).nvl1[nvpair] = iii;
 	FORTRAN(cbkpairs, CBKPAIRS).nvl2[nvpair] = jjj;
 	FORTRAN(cbknvlbo, CBKNVLBO).nvlbo[nvpair] = 0;
 	
 	if (delr2 <= rcutbsq) {
 	  FORTRAN(cbknvlbo, CBKNVLBO).nvlbo[nvpair] = 1;
 	  nbond++;
 	}
 	
 	FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 0;
 	
 	if (j < nlocal)
 	  FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
 	else if (itag < jtag)
 	  FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
 	else if (itag == jtag) {
 	  if (delz > SMALL)
 	    FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
 	  else if (fabs(delz) < SMALL) {
 	    if (dely > SMALL)
 	      FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
 	    else if (fabs(dely) < SMALL && delx > SMALL)
 	      FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
 	  }
 	}
 	nvpair++;
       }
     }
   }
 
   int ntotal = nlocal + nghost;
 
   for (int i = nlocal; i < ntotal; i++) {
     xitmp = x[i][0];
     yitmp = x[i][1];
     zitmp = x[i][2];
     itag = tag[i];
 
     for (int j = i+1; j < ntotal; j++) {
       xjtmp = x[j][0];
       yjtmp = x[j][1];
       zjtmp = x[j][2];
       jtag = tag[j];
       
       delx = xitmp - xjtmp;
       dely = yitmp - yjtmp;
       delz = zitmp - zjtmp;
       
       delr2 = delx*delx+dely*dely+delz*delz;
       
       // don't need to check the double count since i < j in the ghost region
 
       if (delr2 <= rcutvsq) {
 	iii = i+1;
 	jjj = j+1;
 	      
 	if (nvpair >= nvpairmax) 
 	  error->one("Reax_defs.h setting for NNEIGHMAXDEF is too small");
 	
 	FORTRAN(cbkpairs, CBKPAIRS).nvl1[nvpair] = iii;
 	FORTRAN(cbkpairs, CBKPAIRS).nvl2[nvpair] = jjj;
 	FORTRAN(cbknvlbo, CBKNVLBO).nvlbo[nvpair] = 0;
 
 	if (delr2 <= rcutbsq) {
 	  FORTRAN(cbknvlbo, CBKNVLBO).nvlbo[nvpair] = 1;
 	  nbond++;
 	}
 	
 	FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 0;
 	nvpair++;
       }
     }
   }
 
   FORTRAN(cbkpairs, CBKPAIRS).nvpair = nvpair;
   FORTRAN(cbkpairs, CBKPAIRS).nvlself = nvlself;
 }
 					      
 /* ---------------------------------------------------------------------- */
 
 void PairREAX::read_reax_forces()
 {
   double ftmp[3];
 
   double **f = atom->f;
   int ntotal = atom->nlocal + atom->nghost;
 
   int j = 0;
   for (int i = 0; i < ntotal; i++) {
     ftmp[0] = -FORTRAN(cbkd, CBKD).d[j];
     ftmp[1] = -FORTRAN(cbkd, CBKD).d[j+1];
     ftmp[2] = -FORTRAN(cbkd, CBKD).d[j+2];
     f[i][0] = ftmp[0];
     f[i][1] = ftmp[1];
     f[i][2] = ftmp[2];
     j += 3;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairREAX::allocate()
 {
   allocated = 1;
   int n = atom->ntypes;
 
   setflag = memory->create_2d_int_array(n+1,n+1,"pair:setflag");
   cutsq = memory->create_2d_double_array(n+1,n+1,"pair:cutsq");
 
   param_list = new ff_params[n+1];
   for (int i = 1; i <= n; i++)
     param_list[i].params = new double[5];
 
   map = new int[n+1];
 }
 
 /* ----------------------------------------------------------------------
    global settings 
 ------------------------------------------------------------------------- */
 
 void PairREAX::settings(int narg, char **arg)
 {
   if (narg != 0 && narg !=4) error->all("Illegal pair_style command");
   
   if (narg == 4) {
     hbcut = force->numeric(arg[0]);
-    ihbnew = force->numeric(arg[1]);
-    itripstaball = force->numeric(arg[2]);
+    ihbnew = static_cast<int> (force->numeric(arg[1]));
+    itripstaball = static_cast<int> (force->numeric(arg[2]));
     precision = force->numeric(arg[3]);
 
     if (hbcut <= 0.0 || 
 	(ihbnew != 0 && ihbnew != 1) || 
 	(itripstaball != 0 && itripstaball != 1) || 
 	precision <= 0.0)
       error->all("Illegal pair_style command");
   }
 }
 
 /* ----------------------------------------------------------------------
    set coeffs for one or more type pairs
 ------------------------------------------------------------------------- */
 
 void PairREAX::coeff(int narg, char **arg)
 {
   if (!allocated) allocate();
 
   if (narg != 3 + atom->ntypes)
     error->all("Incorrect args for pair coefficients");
 
   // insure I,J args are * *
 
   if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
     error->all("Incorrect args for pair coefficients");
 
   // insure filename is ffield.reax
 
   if (strcmp(arg[2],"ffield.reax") != 0) 
     error->all("Incorrect args for pair coefficients");
 
   // read args that map atom types to elements in potential file
   // map[i] = which element the Ith atom type is, -1 if NULL
 
   for (int i = 3; i < narg; i++) {
     if (strcmp(arg[i],"NULL") == 0) {
       map[i-2] = -1;
       continue;
     }
     map[i-2] = force->inumeric(arg[i]);
   }
 
   int n = atom->ntypes;
 
   int count = 0;
   for (int i = 1; i <= n; i++)
     for (int j = i; j <= n; j++) {
       setflag[i][j] = 1;
       count++;
     }
 
   if (count == 0) error->all("Incorrect args for pair coefficients");
 }
 
 /* ----------------------------------------------------------------------
    init specific to this pair style
 ------------------------------------------------------------------------- */
 
 void PairREAX::init_style()
 {
   if (atom->tag_enable == 0)
     error->all("Pair style reax requires atom IDs");
   if (force->newton_pair == 0)
     error->all("Pair style reax requires newton pair on");
   if (strcmp(update->unit_style,"real") != 0 && comm->me == 0)
     error->warning("Not using real units with pair reax");
 
   int irequest = neighbor->request(this);
   neighbor->requests[irequest]->newton = 2;
 
   FORTRAN(readc, READC)();
   FORTRAN(reaxinit, REAXINIT)();
   FORTRAN(ffinpt, FFINPT)();
   FORTRAN(tap7th, TAP7TH)();
 
   // turn off read_in by fort.3 in REAX Fortran
 
   int ngeofor_tmp = -1;
   FORTRAN(setngeofor, SETNGEOFOR)(&ngeofor_tmp);
   if (comm->me == 0) FORTRAN(readgeo, READGEO)();
 
   // initial setup for cutoff radius of VLIST and BLIST in ReaxFF
 
   double vlbora;
   
   FORTRAN(getswb, GETSWB)(&swb);
   cutmax=MAX(swb, hbcut);
   rcutvsq=cutmax*cutmax;
   FORTRAN(getvlbora, GETVLBORA)(&vlbora);
   rcutbsq=vlbora*vlbora;
 
   // parameters for charge equilibration from ReaxFF input, fort.4
   // verify that no LAMMPS type to REAX type mapping was invalid
 
   int nelements;
   FORTRAN(getnso, GETNSO)(&nelements);
 
   FORTRAN(getswa, GETSWA)(&swa);
   double chi, eta, gamma;
   for (int itype = 1; itype <= atom->ntypes; itype++) {
     if (map[itype] < 1 || map[itype] > nelements)
       error->all("Invalid REAX atom type");
     chi = FORTRAN(cbkchb, CBKCHB).chi[map[itype]-1];
     eta = FORTRAN(cbkchb, CBKCHB).eta[map[itype]-1];
     gamma = FORTRAN(cbkchb, CBKCHB).gam[map[itype]-1];
     param_list[itype].np = 5;
     param_list[itype].rcutsq = cutmax;
     param_list[itype].params[0] = chi;
     param_list[itype].params[1] = eta;
     param_list[itype].params[2] = gamma;
     param_list[itype].params[3] = swa;
     param_list[itype].params[4] = swb;
   }
 
   taper_setup();
 
 }
 
 /* ----------------------------------------------------------------------
    init for one type pair i,j and corresponding j,i
 ------------------------------------------------------------------------- */
 
 double PairREAX::init_one(int i, int j)
 {
   return cutmax;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int PairREAX::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc)
 {
   int i,j,m;
 
   m = 0;
 
   if (packflag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = FORTRAN(cbkabo, CBKABO).abo[j];
     }
 
   } else {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = wcg[j];
     }
   }
 
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairREAX::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
 
   if (packflag == 0) {
     for (i = first; i < last; i++)
       FORTRAN(cbkabo, CBKABO).abo[i] = buf[m++];
 
   } else {
     for (i = first; i < last; i++)
       wcg[i] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int PairREAX::pack_reverse_comm(int n, int first, double *buf)
 {
   int i,k,m,last,size;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) 
     buf[m++] = wcg[i];
 
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairREAX::unpack_reverse_comm(int n, int *list, double *buf)
 {
   int i,j,k,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     wcg[j] += buf[m++];
   }
 }
 
 /* ----------------------------------------------------------------------
    charge equilibration routines
 ------------------------------------------------------------------------- */
 
 /* ---------------------------------------------------------------------- */
 
 void PairREAX::taper_setup()
 {
   double swb2,swa2,swb3,swa3,d1,d7;
 
   d1=swb-swa;
   d7=pow(d1,7);
   swa2=swa*swa;
   swa3=swa2*swa;
   swb2=swb*swb;
   swb3=swb2*swb;
  
   swc7=  20.0e0/d7;
   swc6= -70.0e0*(swa+swb)/d7;
   swc5=  84.0e0*(swa2+3.0e0*swa*swb+swb2)/d7;
   swc4= -35.0e0*(swa3+9.0e0*swa2*swb+9.0e0*swa*swb2+swb3)/d7;
   swc3= 140.0e0*(swa3*swb+3.0e0*swa2*swb2+swa*swb3)/d7;
   swc2=-210.0e0*(swa3*swb2+swa2*swb3)/d7;
   swc1= 140.0e0*swa3*swb3/d7;
   swc0=(-35.0e0*swa3*swb2*swb2+21.0e0*swa2*swb3*swb2+
 	7.0e0*swa*swb3*swb3+swb3*swb3*swb)/d7;
 }
 
 /* ---------------------------------------------------------------------- */
 
 double PairREAX::taper_E(const double &r, const double &r2)
 {
   double r3=r2*r;
   return swc7*r3*r3*r+swc6*r3*r3+swc5*r3*r2+swc4*r2*r2+swc3*r3+swc2*r2+
      swc1*r+swc0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 double PairREAX::taper_F(const double &r, const double &r2)
 {
   double r3=r2*r;
   return 7.0e0*swc7*r3*r3+6.0e0*swc6*r3*r2+5.0e0*swc5*r2*r2+
     4.0e0*swc4*r3+3.0e0*swc3*r2+2.0e0*swc2*r+swc1;
 }
 
 /* ----------------------------------------------------------------------
    compute current charge distributions based on the charge equilibration
 ------------------------------------------------------------------------- */
 
 void PairREAX::compute_charge(double &energy_charge_equilibration)
 {
   double xitmp, yitmp, zitmp;
   double xjtmp, yjtmp, zjtmp;
   int itype, jtype, itag, jtag;
   int ii, jj, i, j;
   double delr2, delr_norm, gamt, hulp1, hulp2;
   double delx, dely, delz;
   double qsum,qi;
   int nmatentries;
   double sw;
   double rtmp[3];
   int inum,jnum;
   int *ilist;
   int *jlist;
   int *numneigh,**firstneigh;
 
   double **x = atom->x;
   double *q = atom->q;
   int *type = atom->type;
   int *tag = atom->tag;
 
   int nlocal = atom->nlocal;
   int nghost = atom->nghost;
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
 
   // realloc neighbor based arrays if necessary
 
   int numneigh_total = 0;
   for (ii = 0; ii < inum; ii++)
     numneigh_total += numneigh[ilist[ii]];
 
   if (numneigh_total + 2*nlocal > matmax) {
     memory->sfree(aval);
     memory->sfree(acol_ind);
     matmax = numneigh_total + 2*nlocal;
     aval = (double *) memory->smalloc(matmax*sizeof(double),"reax:aval");
     acol_ind = (int *) memory->smalloc(matmax*sizeof(int),"reax:acol_ind");
   }
 
   // build linear system
 
   nmatentries = 0;
 
   for (ii = 0; ii < inum; ii++) {
     i = ilist[ii];
     xitmp = x[i][0];
     yitmp = x[i][1];
     zitmp = x[i][2];
     itype = type[i];
     itag = tag[i];
     jlist = firstneigh[i];
     jnum = numneigh[i];
     
     arow_ptr[i] = nmatentries;
     aval[nmatentries] = 2.0*param_list[itype].params[1];
     acol_ind[nmatentries] = i;
     nmatentries++;
     
     aval[nmatentries] = 1.0;
     acol_ind[nmatentries] = nlocal + nghost;
     nmatentries++;   
     
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
       xjtmp = x[j][0];
       yjtmp = x[j][1];
       zjtmp = x[j][2];
       jtype = type[j];
       jtag = tag[j];
       
       delx = xitmp - xjtmp;
       dely = yitmp - yjtmp;
       delz = zitmp - zjtmp;
       
       delr2 = delx*delx+dely*dely+delz*delz;
       
       // avoid counting local-ghost pair twice since
       // ReaxFF uses half neigh list with newton off
 
       if (j >= nlocal) {
 	if (itag > jtag) {
 	  if ((itag+jtag) % 2 == 0) continue;
 	} else if (itag < jtag) {
 	  if ((itag+jtag) % 2 == 1) continue;
 	} else {
 	  if (zjtmp < zitmp) continue;
 	  if (zjtmp == zitmp && yjtmp < yitmp) continue;
 	  if (zjtmp == zitmp && yjtmp == yitmp && xjtmp < xitmp) continue;
 	}
       }
 
       // rcutvsq = cutmax*cutmax, in ReaxFF
 
       if (delr2 <= rcutvsq) {
 	gamt = sqrt(param_list[itype].params[2]*param_list[jtype].params[2]);
 	delr_norm = sqrt(delr2);
 	sw = taper_E(delr_norm, delr2);	
 	hulp1=(delr_norm*delr2+(1.0/(gamt*gamt*gamt)));
 	hulp2=sw*14.40/cbrt(hulp1);
 	aval[nmatentries] = hulp2;
 	acol_ind[nmatentries] = j;
 	nmatentries++;
       }
     }
   }
 
   // in this case, we don't use Midpoint method
   // so, we don't need to consider ghost-ghost interactions
   // but, need to fill the arow_ptr[] arrays for the ghost atoms
 
   for (i = nlocal; i < nlocal+nghost; i++)
     arow_ptr[i] = nmatentries;
   arow_ptr[nlocal+nghost] = nmatentries;
 
   // add rhs matentries to linear system
  
   for (ii =0; ii<inum; ii++) {
     i = ilist[ii];
     itype = type[i];
     elcvec[i] = -param_list[itype].params[0];
   }
 
   for (i = nlocal; i < nlocal+nghost; i++) elcvec[i] = 0.0;
 
   // assign current charges to charge vector
 
   qsum = 0.0;
   for (ii = 0; ii < inum; ii++) {
     i = ilist[ii];
     qi = q[i];
     ch[i] = qi;
     if (i < nlocal) qsum += qi;
   }
 
   for (i = nlocal; i < nlocal+nghost; i++) {
     qi = q[i];
     ch[i] = qi;
   }
 
   double qtot;
   MPI_Allreduce(&qsum,&qtot,1,MPI_DOUBLE,MPI_SUM,world);
   elcvec[nlocal+nghost] = 0.0;
   ch[nlocal+nghost] = chpot;
 
   // solve the linear system using CG sover
 
   charge_reax(nlocal,nghost,ch,aval,acol_ind,arow_ptr,elcvec);
 
   // calculate the charge equilibration energy
 
   energy_charge_equilibration = 0;
 
   // have already updated charge distributions for the current structure
 
   for (ii = 0; ii < inum; ii++) {
     i = ilist[ii];
     itype = type[i];
 
     // 23.02 is the ReaxFF conversion from eV to kcal/mol
     // should really use constants.evfactor ~23.06
     // but that would break consistency with serial ReaxFF code
     // NOTE: this hard-wired real units
     //       if want other units would have to change params[] in file
 
     qi = 23.02 * (param_list[itype].params[0]*ch[i]+
 		  param_list[itype].params[1]*ch[i]*ch[i]);
     energy_charge_equilibration += qi;
     if (eflag_atom) eatom[i] += qi;
   }
 
   // copy charge vector back to particles from the calculated values
 
   for (i = 0; i < nlocal+nghost; i++) q[i] = ch[i];
   chpot = ch[nlocal+nghost];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void PairREAX::charge_reax(const int & nlocal, const int & nghost,
 			   double ch[], double aval[], int acol_ind[],
 			   int arow_ptr[], double elcvec[])
 {
   double chpottmp, suma;
   double sumtmp;
 
   cg_solve(nlocal,nghost,aval,acol_ind,arow_ptr,ch,elcvec);
 }
 
 /* ----------------------------------------------------------------------
    CG solver for linear systems
 ------------------------------------------------------------------------- */
 
 void PairREAX::cg_solve(const int & nlocal, const int & nghost, 
 			double aval[], int acol_ind[], int arow_ptr[],
 			double x[], double b[])
 {
   double one, zero, rho, rho_old, alpha, beta, gamma;
   int iter, maxiter;
   int n;
   double sumtmp;
 
   // parallel CG method by A. P. Thompson
   // distributed (partial) vectors: b, r, q, A
   // accumulated (full) vectors: x, w, p
   // r = b-A.x
   // w = r            (ReverseComm + Comm)
   
   double *r = rcg;
   double *w = wcg;
   double *p = pcg;
   double *p_old = poldcg;
   double *q = qcg;
 
   n = nlocal+nghost+1;
 
   one = 1.0;
   zero = 0.0;
   maxiter = 100;
 
   for (int i = 0; i < n; i++) w[i] = 0;
   
   // construct r = b-Ax
 
   sparse_product(n, nlocal, nghost, aval, acol_ind, arow_ptr, x, r);
   
   // not using BLAS library
 
   for (int i=0; i<n; i++) {
     r[i] = b[i] - r[i];
     w[i] = r[i];
   }
   
   packflag = 1;
   comm->reverse_comm_pair(this);
   comm->forward_comm_pair(this);
   
   MPI_Allreduce(&w[n-1], &sumtmp, 1, MPI_DOUBLE, MPI_SUM, world);
   w[n-1] = sumtmp;
   rho_old = one;
 
   for (iter = 1; iter < maxiter; iter++) {
     rho = 0.0;
     for (int i=0; i<nlocal; i++) rho += w[i]*w[i];
 
     MPI_Allreduce(&rho, &sumtmp, 1, MPI_DOUBLE, MPI_SUM, world);
     rho = sumtmp + w[n-1]*w[n-1];
     if (rho < precision) break;
 
     for (int i = 0; i<n; i++) p[i] = w[i];
 
     if (iter > 1) {
       beta = rho/rho_old;
       for (int i = 0; i<n; i++) p[i] += beta*p_old[i];
     }
 
     sparse_product(n, nlocal, nghost, aval, acol_ind, arow_ptr, p, q);
     
     gamma = 0.0;
     for (int i=0; i<n; i++) gamma += p[i]*q[i];
     MPI_Allreduce(&gamma, &sumtmp, 1, MPI_DOUBLE, MPI_SUM, world);
 
     gamma = sumtmp;
     alpha = rho/gamma;
 
     for (int i=0; i<n; i++) {
       x[i] += alpha*p[i];
       r[i] -= alpha*q[i];
       w[i] = r[i];
     }
       
     comm->reverse_comm_pair(this);
     comm->forward_comm_pair(this);
 
     MPI_Allreduce(&w[n-1], &sumtmp, 1, MPI_DOUBLE, MPI_SUM, world);
     w[n-1] = sumtmp;
 
     for (int i=0; i<n; i++) p_old[i] = p[i];
     rho_old = rho;
   }
 }
 
 /* ----------------------------------------------------------------------
    sparse maxtrix operations
 ------------------------------------------------------------------------- */
 
 void PairREAX::sparse_product(const int &n, const int &nlocal,
 			      const int &nghost,
 			      double aval[], int acol_ind[], int arow_ptr[],
 			      double *x, double *r)
 {
   int i,j,jj;
 
   for (i=0; i<n; i++) r[i] = 0.0;
 
   for (i=0; i<nlocal; i++) {
     r[i] += aval[arow_ptr[i]]*x[i];
     for (j=arow_ptr[i]+1; j<arow_ptr[i+1]; j++) {
       jj = acol_ind[j];
       r[i] += aval[j]*x[jj];
       r[jj] += aval[j]*x[i];
     }
   }
   
   for (i=nlocal; i<nlocal+nghost; i++)
     for (j=arow_ptr[i]; j<arow_ptr[i+1]; j++) {
       jj = acol_ind[j];
       r[i] += aval[j]*x[jj];
       r[jj] += aval[j]*x[i];
     }
 }
 
 /* ----------------------------------------------------------------------
    memory usage of local atom-based arrays 
 ------------------------------------------------------------------------- */
 
 double PairREAX::memory_usage()
 {
   double bytes = nmax * sizeof(int);
   bytes += 7 * nmax * sizeof(double);
   bytes += matmax * sizeof(int);
   bytes += matmax * sizeof(double);
   return bytes;
 }
diff --git a/src/REAX/pair_reax_fortran.h b/src/REAX/pair_reax_fortran.h
index d672c45c5..1900613c6 100644
--- a/src/REAX/pair_reax_fortran.h
+++ b/src/REAX/pair_reax_fortran.h
@@ -1,209 +1,209 @@
 /* ----------------------------------------------------------------------
    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.
 ------------------------------------------------------------------------- */
 
 // machine-specific C++ -> Fortran calling syntax
 // It defines the FORTRAN macro for converting variable and function
 // names from FORTRAN to C. Different compilers do this in different
 // ways. The default is add an underscore to the lower case string.
 // Other definitions of the macro can be invoked by defining the
 // corresponding macro at compile time using -D e.g. -D_IBM
 
 // CONS(a,b) should return ab, the concatenation of its arguments.
 // If compiler is using strict ISO C standards, the ## works. 
 // Otherwise try the old /**/ trick and test.
 // If that fails, you will need to figure out 
 // a definition for the FORTRAN macro that works on your machine.
 
 #if  __STDC__ 
 #define CONS(a,b) a##b
 #else
 #define CONS(a,b) a/**/b
 #warning "The following declaration is a test of the CONS macro."
 #warning "If it fails with an error, pair_reax_fortran.h must be modified by hand."
 static int my_apples_my_oranges = 1;
 static int my_applesoroanges = CONS(my_apples,_my_oranges);
 #endif
 
 
 #ifdef _IBM
 #define FORTRAN(lcname,ucname)  lcname
 #endif
 
 #ifdef _F2C_LINUX
 #define FORTRAN(lcname,ucname)  CONS(lcname,__)
 #endif
 
 #ifndef FORTRAN
 #define FORTRAN(lcname,ucname)  CONS(lcname,_)
 #endif
 
 // hard-wired array sizes set in Fortran library
 // accesses include file from Fortran library
 
 #include "reax_defs.h"
 
 class ReaxParams {
  public:
   enum {nneighmax=NNEIGHMAXDEF, 
 	nat=NATDEF, 
 	nattot=NATTOTDEF, 
         nsort=NSORTDEF,
 	mbond=MBONDDEF, 
         nbomax=NBOMAXDEF,
   };
 };
 
 // data structures corresponding to values in Fortran library
 
-extern struct {
+extern "C" struct {
   double abo[ReaxParams::nat];
 } FORTRAN(cbkabo,CBKABO);
 
-extern struct {
+extern "C" struct {
   double bo[ReaxParams::nbomax];
 } FORTRAN(cbkbo,CBKBO);
 
-extern struct {
+extern "C" struct {
   double c[3*ReaxParams::nat]; double cglobal[3*ReaxParams::nattot];
   int itag[ReaxParams::nat];
 } FORTRAN(cbkc,CBKC);
 
-extern struct {
+extern "C" struct {
 double ch[ReaxParams::nat];
 } FORTRAN(cbkch,CBKCH);
 
-extern struct {
+extern "C" struct {
   double chi[ReaxParams::nsort];
   double eta[ReaxParams::nsort];
   double gam[ReaxParams::nsort];
 } FORTRAN(cbkchb,CBKCHB);
 
-extern struct {
+extern "C" struct {
   double d[3*ReaxParams::nat]; double estrain[ReaxParams::nat];
 } FORTRAN(cbkd,CBKD);
 
-extern struct {
+extern "C" struct {
   double atomvirial[6*ReaxParams::nat];
   double virial[6]; 
   int Lvirial;
   int Latomvirial;
 } FORTRAN(cbkvirial,CBKVIRIAL);
 
-extern struct {
+extern "C" struct {
   int ia[ReaxParams::nat*(ReaxParams::mbond+3)];
   int iag[ReaxParams::nat*(ReaxParams::mbond+3)];
 } FORTRAN(cbkia,CBKIA);
 
-extern struct {
+extern "C" struct {
   double vlp[ReaxParams::nat];
   double dvlpdsbo[ReaxParams::nat];
 } FORTRAN(cbklonpar,CBKLONPAR);
 
-extern struct {
+extern "C" struct {
   int nubon1[ReaxParams::nat*(ReaxParams::mbond)];
   int nubon2[ReaxParams::nat*(ReaxParams::mbond)];
 } FORTRAN(cbknubon2,CBKNUBON2);
 
-extern struct {
+extern "C" struct {
   int nvl1[ReaxParams::nneighmax * ReaxParams::nat];
   int nvl2[ReaxParams::nneighmax * ReaxParams::nat];
   int nvpair;
   int nvlself;
 } FORTRAN(cbkpairs,CBKPAIRS);
 
-extern struct {
+extern "C" struct {
   int nvlbo[ReaxParams::nneighmax * ReaxParams::nat];
 } FORTRAN(cbknvlbo,CBKNVLBO);
 
-extern struct {
+extern "C" struct {
   int nvlown[ReaxParams::nneighmax * ReaxParams::nat];
 } FORTRAN(cbknvlown,CBKNVLOWN);
 
-extern struct {
+extern "C" struct {
   char qa[20*ReaxParams::nattot+10];
 } FORTRAN(cbkqa,CBKQA);
 
-extern struct {
+extern "C" struct {
   double eb;
   double eoop;
   double epen;
   double estrc;
   double deda[3];
   double pressu;
   double efi;
   double elp;
   double emol;
   double ea;
   double eres;
   double et;
   double eradbo;
   double ev;
   double eco;
   double ecoa;
   double ehb;
   double sw;
   double ew;
   double ep;
   double ekin;
 } FORTRAN(cbkenergies,CBKENERGIES);
 
-extern struct {
+extern "C" struct {
   double tset; 
   double dseed; 
   double tempmd; 
   double ts2; 
   double ts22; 
   int nmolo; 
   int nmolo5; 
   int nbon; 
   int na; 
   int namov;
   int na_local;
 } FORTRAN(rsmall,RSMALL);
 
 // external routines provided by Fortran library
 
 extern "C" void FORTRAN(readc,READC)();
 extern "C" void FORTRAN(reaxinit,REAXINIT)();
 extern "C" void FORTRAN(ffinpt,FFINPT)();
 extern "C" void FORTRAN(tap7th,TAP7TH)();
 extern "C" void FORTRAN(taper,TAPER)(double*,double*);
 extern "C" void FORTRAN(readgeo,READGEO)();
 extern "C" void FORTRAN(srtatom,SRTATOM)();
 extern "C" void FORTRAN(vlist,VLIST) ();
 extern "C" void FORTRAN(srtbon1,SRTBON1)(int*,int*,double*,int*,int*);
 extern "C" void FORTRAN(molec,MOLEC)();
 extern "C" void FORTRAN(encalc,ENCALC)();
 extern "C" void FORTRAN(getswb,GETSWB)(double*);
 extern "C" void FORTRAN(getswa,GETSWA)(double*);
 extern "C" void FORTRAN(getvrange,GET_VRANGE)(double*);
 extern "C" void FORTRAN(getnvlist,GET_NVLIST)(int*);
 extern "C" void FORTRAN(getvlbora,GETVLBORA)(double*);
 extern "C" void FORTRAN(cgsolve,CGSOLVE)
   (int*,double*,int*,double*,double*,int*);
 extern "C" void FORTRAN(getnval,GETNVAL)(int*);
 extern "C" void FORTRAN(getntor,GETNTOR)(int*);
 extern "C" void FORTRAN(getnhb,GETNHB)(int*);
 extern "C" void FORTRAN(getnbonall,GETNBONALL)(int*);
 extern "C" void FORTRAN(getnneighmax,GETNNEIGHMAX)(int*);
 extern "C" void FORTRAN(getnat,GETNAT)(int*);
 extern "C" void FORTRAN(getnattot,GETNATTOT)(int*);
 extern "C" void FORTRAN(getnsort,GETNSORT)(int*);
 extern "C" void FORTRAN(getmbond,GETMBOND)(int*);
 extern "C" void FORTRAN(getnso,GETNSO)(int*);
 extern "C" void FORTRAN(setngeofor,SETNGEOFOR)(int*);
 extern "C" void FORTRAN(mdsav,MDSAV)(int*);
 extern "C" void FORTRAN(getnsbmax,GETNSBMAX)(int*);
 extern "C" void FORTRAN(getnsbma2,GETNSBMA2)(int*);
 extern "C" void FORTRAN(getcutof3,GETCUTOF3)(double*);
 
diff --git a/src/REPLICA/fix_event.h b/src/REPLICA/fix_event.h
index 73df5d157..41ce7f261 100644
--- a/src/REPLICA/fix_event.h
+++ b/src/REPLICA/fix_event.h
@@ -1,52 +1,51 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_FIX_EVENT_H
 #define LMP_FIX_EVENT_H
 
 #include "fix.h"
 
 namespace LAMMPS_NS {
 
 class FixEvent : public Fix {
  public:
-
   FixEvent(class LAMMPS *, int, char **);
   virtual ~FixEvent()=0;    // Use destructor to make base class virtual
   int setmask();
 
   double memory_usage();
   void grow_arrays(int);
   void copy_arrays(int, int);
   int pack_exchange(int, double *);
   int unpack_exchange(int, double *);
   virtual void write_restart(FILE *);
   virtual void restart(char *);
 
   // methods specific to FixEvent
 
   void store_event();         // store quenched atoms
   void restore_event();       // restore quenched atoms
   void store_state();         // store hot atoms
   void restore_state();       // restore hot atoms
 
  private:
   double **xevent;       // atom coords at last event
   double **xold;         // atom coords for reset/restore
   double **vold;         // atom vels for reset/restore
   int *imageold;         // image flags for reset/restore
 };
 
 }
 
 #endif
diff --git a/src/REPLICA/fix_event_prd.cpp b/src/REPLICA/fix_event_prd.cpp
index ad606d9ab..3fba4da90 100644
--- a/src/REPLICA/fix_event_prd.cpp
+++ b/src/REPLICA/fix_event_prd.cpp
@@ -1,100 +1,101 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "stdlib.h"
 #include "string.h"
 #include "fix_event_prd.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "update.h"
 #include "domain.h"
 #include "neighbor.h"
 #include "comm.h"
 #include "universe.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 FixEventPRD::FixEventPRD(LAMMPS *lmp, int narg, char **arg) :
   FixEvent(lmp, narg, arg)
 {
   if (narg != 3) error->all("Illegal fix event command");
 
   restart_global = 1;
 
   event_number = 0;
   event_timestep = update->ntimestep;
   clock = 0;
 }
 
 /* ----------------------------------------------------------------------
    save current atom coords as an event (via call to base class)
    called when an event occurs in some replica
    set event_timestep = when event occurred in a particular replica
    update clock = elapsed time since last event, across all replicas
 ------------------------------------------------------------------------- */
 
-void FixEventPRD::store_event_prd(int timestep, int delta_clock)
+void FixEventPRD::store_event_prd(bigint ntimestep, int delta_clock)
 {
   store_event();
-  event_timestep = timestep;
+  event_timestep = ntimestep;
   clock += delta_clock;
   event_number++;
 }
 
 /* ----------------------------------------------------------------------
    pack entire state of Fix into one write 
 ------------------------------------------------------------------------- */
 
 void FixEventPRD::write_restart(FILE *fp)
 {
   int n = 0;
   double list[6];
   list[n++] = event_number;
   list[n++] = event_timestep;
   list[n++] = clock;
   list[n++] = replica_number;
   list[n++] = correlated_event;
   list[n++] = ncoincident;
 
   if (comm->me == 0) {
     int size = n * sizeof(double);
     fwrite(&size,sizeof(int),1,fp);
     fwrite(list,sizeof(double),n,fp);
   }
 }
 
 /* ----------------------------------------------------------------------
    use state info from restart file to restart the Fix 
 ------------------------------------------------------------------------- */
 
 void FixEventPRD::restart(char *buf)
 {
   int n = 0;
   double *list = (double *) buf;
 
   event_number = static_cast<int> (list[n++]);
   event_timestep = static_cast<int> (list[n++]);
   clock = static_cast<int> (list[n++]);
   replica_number = static_cast<int> (list[n++]);
   correlated_event = static_cast<int> (list[n++]);
   ncoincident = static_cast<int> (list[n++]);
 }
 
 
diff --git a/src/REPLICA/fix_event_prd.h b/src/REPLICA/fix_event_prd.h
index fa97ead78..18f77b324 100644
--- a/src/REPLICA/fix_event_prd.h
+++ b/src/REPLICA/fix_event_prd.h
@@ -1,53 +1,54 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef FIX_CLASS
 
 FixStyle(EVENT/PRD,FixEventPRD)
 
 #else
 
 #ifndef LMP_FIX_EVENT_PRD_H
 #define LMP_FIX_EVENT_PRD_H
 
 #include "fix_event.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class FixEventPRD : public FixEvent {
  public:
   int event_number;      // event counter
-  int event_timestep;    // timestep of last event on any replica
+  bigint event_timestep; // timestep of last event on any replica
   int clock;             // total elapsed timesteps across all replicas
   int replica_number;    // replica where last event occured
   int correlated_event;  // 1 if last event was correlated, 0 otherwise
   int ncoincident;       // # of simultaneous events on different replicas
 
   FixEventPRD(class LAMMPS *, int, char **);
   ~FixEventPRD() {}
 
   void write_restart(FILE *);
   void restart(char *);
 
   // methods specific to FixEventPRD, invoked by PRD
 
-  void store_event_prd(int, int);
+  void store_event_prd(bigint, int);
 
  private:
 
 };
 
 }
 
 #endif
 #endif
diff --git a/src/REPLICA/fix_event_tad.cpp b/src/REPLICA/fix_event_tad.cpp
index 5f0dcd069..108668b63 100644
--- a/src/REPLICA/fix_event_tad.cpp
+++ b/src/REPLICA/fix_event_tad.cpp
@@ -1,94 +1,95 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "stdlib.h"
 #include "string.h"
 #include "fix_event_tad.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "update.h"
 #include "domain.h"
 #include "neighbor.h"
 #include "comm.h"
 #include "universe.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 FixEventTAD::FixEventTAD(LAMMPS *lmp, int narg, char **arg) :
   FixEvent(lmp, narg, arg)
 {
   if (narg != 3) error->all("Illegal fix event command");
 
   restart_global = 1;
 
   event_number = 0;
   event_timestep = update->ntimestep;
   tlo = 0.0;
   ebarrier = 0.0;
 }
 
 /* ----------------------------------------------------------------------
    save current atom coords as an event (via call to base class)
    called when an event occurs in some replica
    set event_timestep = when event occurred
 ------------------------------------------------------------------------- */
 
-void FixEventTAD::store_event_tad(int timestep)
+void FixEventTAD::store_event_tad(bigint ntimestep)
 {
   store_event();
-  event_timestep = timestep;
+  event_timestep = ntimestep;
 }
 
 /* ----------------------------------------------------------------------
    pack entire state of Fix into one write 
 ------------------------------------------------------------------------- */
 
 void FixEventTAD::write_restart(FILE *fp)
 {
   int n = 0;
   double list[4];
   list[n++] = event_number;
   list[n++] = event_timestep;
   list[n++] = tlo;
   list[n++] = ebarrier;
 
   if (comm->me == 0) {
     int size = n * sizeof(double);
     fwrite(&size,sizeof(int),1,fp);
     fwrite(list,sizeof(double),n,fp);
   }
 }
 
 /* ----------------------------------------------------------------------
    use state info from restart file to restart the Fix 
 ------------------------------------------------------------------------- */
 
 void FixEventTAD::restart(char *buf)
 {
   int n = 0;
   double *list = (double *) buf;
 
   event_number = static_cast<int> (list[n++]);
   event_timestep = static_cast<int> (list[n++]);
   tlo = static_cast<double> (list[n++]);
   ebarrier = list[n++];
 }
 
 
diff --git a/src/REPLICA/fix_event_tad.h b/src/REPLICA/fix_event_tad.h
index 5bf937e22..2b6067e9e 100644
--- a/src/REPLICA/fix_event_tad.h
+++ b/src/REPLICA/fix_event_tad.h
@@ -1,51 +1,52 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef FIX_CLASS
 
 FixStyle(EVENT/TAD,FixEventTAD)
 
 #else
 
 #ifndef LMP_FIX_EVENT_TAD_H
 #define LMP_FIX_EVENT_TAD_H
 
 #include "fix_event.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class FixEventTAD : public FixEvent {
  public:
   int event_number;      // event counter
-  int event_timestep;    // timestep of last event
+  bigint event_timestep; // timestep of last event
   double tlo;            // event time at low temperature 
   double ebarrier;       // energy barrier for this event
 
   FixEventTAD(class LAMMPS *, int, char **);
   ~FixEventTAD() {}
 
   void write_restart(FILE *);
   void restart(char *);
 
   // methods specific to FixEventTAD, invoked by TAD
 
-  void store_event_tad(int);
+  void store_event_tad(bigint);
 
  private:
 
 };
 
 }
 
 #endif
 #endif
diff --git a/src/REPLICA/neb.cpp b/src/REPLICA/neb.cpp
index e44c95f7f..f021a1f7f 100644
--- a/src/REPLICA/neb.cpp
+++ b/src/REPLICA/neb.cpp
@@ -1,507 +1,510 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "neb.h"
+#include "lmptype.h"
 #include "universe.h"
 #include "atom.h"
 #include "update.h"
 #include "domain.h"
 #include "min.h"
 #include "modify.h"
 #include "fix.h"
 #include "fix_neb.h"
 #include "output.h"
 #include "thermo.h"
 #include "finish.h"
 #include "timer.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define CHUNK 1000
 #define MAXLINE 256
 
 /* ---------------------------------------------------------------------- */
 
 NEB::NEB(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ----------------------------------------------------------------------
    internal NEB constructor 
 ------------------------------------------------------------------------- */
 
 NEB::NEB(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in,
 	 int n2steps_in, int nevery_in, double *buf_init, double *buf_final) 
   : Pointers(lmp) 
 {
   double delx,dely,delz;
 
   etol = etol_in;
   ftol = ftol_in;
   n1steps = n1steps_in;
   n2steps = n2steps_in;
   nevery = nevery_in;
 
   // replica info
 
   nreplica = universe->nworlds;
   ireplica = universe->iworld;
   me_universe = universe->me;
   uworld = universe->uworld;
   MPI_Comm_rank(world,&me);
 
   // generate linear interpolate replica
 
   double fraction = ireplica/(nreplica-1.0);
 
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   int ii = 0;
   for (int i = 0; i < nlocal; i++) {
     delx = buf_final[ii] - buf_init[ii];
     dely = buf_final[ii+1] - buf_init[ii+1];
     delz = buf_final[ii+2] - buf_init[ii+2];
     domain->minimum_image(delx,dely,delz);
     x[i][0] = buf_init[ii] + fraction*delx;
     x[i][1] = buf_init[ii+1] + fraction*dely;
     x[i][2] = buf_init[ii+2] + fraction*delz;
     ii += 3;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 NEB::~NEB()
 {
   MPI_Comm_free(&roots);
   memory->destroy_2d_double_array(all);
   delete [] rdist;
 }
 
 /* ----------------------------------------------------------------------
    perform NEB on multiple replicas
 ------------------------------------------------------------------------- */
 
 void NEB::command(int narg, char **arg)
 {
   if (domain->box_exist == 0) 
     error->all("NEB command before simulation box is defined");
 
   if (narg != 6) error->universe_all("Illegal NEB command");
   
   etol = atof(arg[0]);
   ftol = atof(arg[1]);
   n1steps = atoi(arg[2]);
   n2steps = atoi(arg[3]);
   nevery = atoi(arg[4]);
   infile = arg[5];
 
   // error checks
 
   if (etol < 0.0) error->all("Illegal NEB command");
   if (ftol < 0.0) error->all("Illegal NEB command");
   if (nevery == 0) error->universe_all("Illegal NEB command");
   if (n1steps % nevery || n2steps % nevery)
     error->universe_all("Illegal NEB command");
 
   // replica info
 
   nreplica = universe->nworlds;
   ireplica = universe->iworld;
   me_universe = universe->me;
   uworld = universe->uworld;
   MPI_Comm_rank(world,&me);
 
   // read in file of final state atom coords and reset my coords
 
   readfile(infile);
 
   // run the NEB calculation
 
   run();
 
 }
 
 /* ----------------------------------------------------------------------
    run NEB on multiple replicas
 ------------------------------------------------------------------------- */
 
 void NEB::run()
 {
   // create MPI communicator for root proc from each world
 
   int color;
   if (me == 0) color = 0;
   else color = 1;
   MPI_Comm_split(uworld,color,0,&roots);
 
   // error checks
 
   if (nreplica == 1) error->all("Cannot use NEB with a single replica");
   if (nreplica != universe->nprocs)
     error->all("Can only use NEB with 1-processor replicas");
   if (atom->sortfreq > 0)
     error->all("Cannot use NEB with atom_modify sort enabled");
   if (atom->map_style == 0) 
     error->all("Cannot use NEB unless atom map exists");
 
   int ineb,idamp;
   for (ineb = 0; ineb < modify->nfix; ineb++)
     if (strcmp(modify->fix[ineb]->style,"neb") == 0) break;
   if (ineb == modify->nfix) error->all("NEB requires use of fix neb");
 
   fneb = (FixNEB *) modify->fix[ineb];
   nall = 4;
   all = memory->create_2d_double_array(nreplica,nall,"neb:all");
   rdist = new double[nreplica];
 
   // initialize LAMMPS
 
   update->whichflag = 2;
   update->etol = etol;
   update->ftol = ftol;
   update->multireplica = 1;
 
   lmp->init();
 
   if (update->minimize->searchflag)
     error->all("NEB requires damped dynamics minimizer");
 
   // setup regular NEB minimization
 
   if (me_universe == 0 && universe->uscreen)
     fprintf(universe->uscreen,"Setting up regular NEB ...\n");
   
   update->beginstep = update->firststep = update->ntimestep;
   update->endstep = update->laststep = update->firststep + n1steps;
   update->nsteps = n1steps;
   update->max_eval = n1steps;
 
   update->minimize->setup();
   
   if (me_universe == 0) {
     if (universe->uscreen)
       fprintf(universe->uscreen,"Step MaxReplicaForce MaxAtomForce "
 	      "GradV0 GradV1 GradVc "
 	      "EBF EBR RDT "
 	      "RD1 PE1 RD2 PE2 ... RDN PEN\n");
     if (universe->ulogfile)
       fprintf(universe->ulogfile,"Step MaxReplicaForce MaxAtomForce "
 	      "GradV0 GradV1 GradVc "
 	      "EBF EBR RDT "
 	      "RD1 PE1 RD2 PE2 ... RDN PEN\n");
   }
   print_status();
   
   // perform regular NEB for n1steps or until replicas converge
   // retrieve PE values from fix NEB and print every nevery iterations
   // break induced if converged
   // damped dynamic min styles insure all replicas converge together
 
   int flag,flagall;
 
   timer->barrier_start(TIME_LOOP);
   
   while (update->minimize->niter < n1steps) {
     update->minimize->run(nevery);
     print_status();
     if (update->minimize->stop_condition) break;
   }
 	
   timer->barrier_stop(TIME_LOOP);
 
   update->minimize->cleanup();
 
   Finish finish(lmp);
   finish.end(1);
 
   // switch fix NEB to climbing mode
   // top = replica that becomes hill climber
 
   double vmax = all[0][0];
   int top = 0;
   for (int m = 1; m < nreplica; m++)
     if (vmax < all[m][0]) {
       vmax = all[m][0];
       top = m;
     }
 
   // setup climbing NEB minimization
   // must reinitialize minimizer so it re-creates its fix MINIMIZE
 
   if (me_universe == 0 && universe->uscreen)
     fprintf(universe->uscreen,"Setting up climbing ...\n");
 
   if (me_universe == 0) {
     if (universe->uscreen)
       fprintf(universe->uscreen,"Climbing replica = %d\n",top+1);
     if (universe->ulogfile)
       fprintf(universe->ulogfile,"Climbing replica = %d\n",top+1);
   }
   
   update->beginstep = update->firststep = update->ntimestep;
   update->endstep = update->laststep = update->firststep + n2steps;
   update->nsteps = n2steps;
   update->max_eval = n2steps;
 
   update->minimize->init();
   fneb->rclimber = top;
   update->minimize->setup();
 
   if (me_universe == 0) {
     if (universe->uscreen)
       fprintf(universe->uscreen,"Step MaxReplicaForce MaxAtomForce "
 	      "GradV0 GradV1 GradVc "
 	      "EBF EBR RDT "
 	      "RD1 PE1 RD2 PE2 ... RDN PEN\n");
     if (universe->ulogfile)
       fprintf(universe->ulogfile,"Step MaxReplicaForce MaxAtomForce "
 	      "GradV0 GradV1 GradVc "
 	      "EBF EBR RDT "
 	      "RD1 PE1 RD2 PE2 ... RDN PEN\n");
   }
   print_status();
   
   // perform climbing NEB for n2steps or until replicas converge
   // retrieve PE values from fix NEB and print every nevery iterations
   // break induced if converged
   // damped dynamic min styles insure all replicas converge together
   
   timer->barrier_start(TIME_LOOP);
   while (update->minimize->niter < n2steps) {
     update->minimize->run(nevery);
     print_status();
     if (update->minimize->stop_condition) break;
   }
 	
   timer->barrier_stop(TIME_LOOP);
 
   update->minimize->cleanup();
 
   finish.end(1);
 
   update->whichflag = 0;
   update->multireplica = 0;
   update->firststep = update->laststep = 0;
   update->beginstep = update->endstep = 0;
 }
 
 /* ----------------------------------------------------------------------
    read target coordinates from file, store with appropriate atom
    adjust coords of each atom based on ireplica
    new coord = replica fraction between current and final state
 ------------------------------------------------------------------------- */
 
 void NEB::readfile(char *file)
 {
   if (me_universe == 0) {
     if (screen) fprintf(screen,"Reading NEB coordinate file %s ...\n",file);
     open(file);
   }
 
   double fraction = ireplica/(nreplica-1.0);
 
   double **x = atom->x;
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   char *buffer = new char[CHUNK*MAXLINE];
   char *ptr,*next,*bufptr;
   int i,m,nlines,tag;
   double xx,yy,zz,delx,dely,delz;
 
   int firstline = 1;
   int ncount = 0;
   int eof = 0;
 
   while (!eof) {
     if (me_universe == 0) {
       m = 0;
       for (nlines = 0; nlines < CHUNK; nlines++) {
 	ptr = fgets(&buffer[m],MAXLINE,fp);
 	if (ptr == NULL) break;
 	m += strlen(&buffer[m]);
       }
       if (ptr == NULL) eof = 1;
       buffer[m++] = '\n';
     }
 
     MPI_Bcast(&eof,1,MPI_INT,0,uworld);
     MPI_Bcast(&nlines,1,MPI_INT,0,uworld);
     MPI_Bcast(&m,1,MPI_INT,0,uworld);
     MPI_Bcast(buffer,m,MPI_CHAR,0,uworld);
 
     bufptr = buffer;
     for (i = 0; i < nlines; i++) {
       next = strchr(bufptr,'\n');
       *next = '\0';
 
       if (firstline) {
 	if (atom->count_words(bufptr) == 4) firstline = 0;
 	else error->all("Incorrect format in NEB coordinate file");
       }
 
       sscanf(bufptr,"%d %lg %lg %lg",&tag,&xx,&yy,&zz);
 
       // adjust atom coord based on replica fraction
       // ignore image flags of final x
       // new x is displacement from old x
       // if final x is across periodic boundary:
       //   new x may be outside box
       //   will be remapped back into box when simulation starts
       //   its image flags will be adjusted appropriately
 
       m = atom->map(tag);
       if (m >= 0 && m < nlocal) {
 	delx = xx - x[m][0];
 	dely = yy - x[m][1];
 	delz = zz - x[m][2];
 	domain->minimum_image(delx,dely,delz);
 	x[m][0] += fraction*delx;
 	x[m][1] += fraction*dely;
 	x[m][2] += fraction*delz;
 	ncount++;
       }
 
       bufptr = next + 1;
     }
   }
 
   // clean up
 
   delete [] buffer;
 
   if (me_universe == 0) {
     if (compressed) pclose(fp);
     else fclose(fp);
   }
 }
 
 /* ----------------------------------------------------------------------
    universe proc 0 opens NEB data file
    test if gzipped
 ------------------------------------------------------------------------- */
 
 void NEB::open(char *file)
 {
   compressed = 0;
   char *suffix = file + strlen(file) - 3;
   if (suffix > file && strcmp(suffix,".gz") == 0) compressed = 1;
   if (!compressed) fp = fopen(file,"r");
   else {
 #ifdef LAMMPS_GZIP
     char gunzip[128];
     sprintf(gunzip,"gunzip -c %s",file);
     fp = popen(gunzip,"r");
 #else
     error->one("Cannot open gzipped file");
 #endif
   }
 
   if (fp == NULL) {
     char str[128];
     sprintf(str,"Cannot open file %s",file);
     error->one(str);
   }
 }
 
 /* ----------------------------------------------------------------------
    query fix NEB for PE of each replica
    proc 0 prints current NEB status
 ------------------------------------------------------------------------- */
 
 void NEB::print_status()
 {
   double fnorm2 = sqrt(update->minimize->fnorm_sqr());
   double fmaxreplica;
   MPI_Allreduce(&fnorm2,&fmaxreplica,1,MPI_DOUBLE,MPI_MAX,roots);
   double fnorminf = update->minimize->fnorm_inf();
   double fmaxatom;
   MPI_Allreduce(&fnorminf,&fmaxatom,1,MPI_DOUBLE,MPI_MAX,roots);
 
   double one[4];
   one[0] = fneb->veng;
   one[1] = fneb->plen;
   one[2] = fneb->nlen;
   one[nall-1] = fneb->gradvnorm;
 
   if (output->thermo->normflag) one[0] /= atom->natoms;
   if (me == 0)
     MPI_Allgather(one,nall,MPI_DOUBLE,&all[0][0],nall,MPI_DOUBLE,roots);
 
   rdist[0] = 0.0;
   for (int i = 1; i < nreplica; i++)
     rdist[i] = rdist[i-1] + all[i][1];
   double endpt = rdist[nreplica-1] = rdist[nreplica-2] + all[nreplica-2][2];
   for (int i = 1; i < nreplica; i++)
     rdist[i] /= endpt;
 
   // look up GradV for the initial, final, and climbing replicas
   // these are identical to fnorm2, but to be safe we
   // take them straight from fix_neb
 
   double gradvnorm0, gradvnorm1, gradvnormc;
 
   int irep;
   irep = 0;
   gradvnorm0 = all[irep][3];
   irep = nreplica-1;
   gradvnorm1 = all[irep][3];
   irep = fneb->rclimber;
   if (irep > -1) {
     gradvnormc = all[irep][3];
     ebf = all[irep][0]-all[0][0];
     ebr = all[irep][0]-all[nreplica-1][0];
   } else {
     double vmax = all[0][0];
     int top = 0;
     for (int m = 1; m < nreplica; m++)
       if (vmax < all[m][0]) {
 	vmax = all[m][0];
 	top = m;
       }
     irep = top;
     gradvnormc = all[irep][3];
     ebf = all[irep][0]-all[0][0];
     ebr = all[irep][0]-all[nreplica-1][0];
   }
 
   if (me_universe == 0) {
+    char fstr[32];
+    sprintf(fstr,"%s %%g %%g ",BIGINT_FORMAT);
     if (universe->uscreen) {
-      fprintf(universe->uscreen,"%d %g %g ",update->ntimestep,
+      fprintf(universe->uscreen,fstr,update->ntimestep,
 	      fmaxreplica,fmaxatom);
       fprintf(universe->uscreen,"%g %g %g ",
 	      gradvnorm0,gradvnorm1,gradvnormc);
       fprintf(universe->uscreen,"%g %g %g ",ebf,ebr,endpt);
       for (int i = 0; i < nreplica; i++) 
 	fprintf(universe->uscreen,"%g %g ",rdist[i],all[i][0]);
       fprintf(universe->uscreen,"\n");
     }
     if (universe->ulogfile) {
-      fprintf(universe->ulogfile,"%d %g %g ",update->ntimestep,
+      fprintf(universe->ulogfile,fstr,update->ntimestep,
 	      fmaxreplica,fmaxatom);
       fprintf(universe->ulogfile,"%g %g %g ",
 	      gradvnorm0,gradvnorm1,gradvnormc);
       fprintf(universe->ulogfile,"%g %g %g ",ebf,ebr,endpt);
       for (int i = 0; i < nreplica; i++)
 	fprintf(universe->ulogfile,"%g %g ",rdist[i],all[i][0]);
       fprintf(universe->ulogfile,"\n");
       fflush(universe->ulogfile);
     }
   }
 }
diff --git a/src/REPLICA/prd.cpp b/src/REPLICA/prd.cpp
index e11dae149..07ca60580 100644
--- a/src/REPLICA/prd.cpp
+++ b/src/REPLICA/prd.cpp
@@ -1,809 +1,812 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mike Brown (SNL)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "prd.h"
 #include "lmptype.h"
 #include "universe.h"
 #include "update.h"
 #include "atom.h"
 #include "domain.h"
 #include "region.h"
 #include "comm.h"
 #include "velocity.h"
 #include "integrate.h"
 #include "min.h"
 #include "neighbor.h"
 #include "modify.h"
 #include "compute.h"
 #include "fix.h"
 #include "fix_event_prd.h"
 #include "force.h"  
 #include "pair.h"
 #include "random_park.h"
 #include "random_mars.h"
 #include "output.h"
 #include "dump.h"
 #include "finish.h"
 #include "timer.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 PRD::PRD(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ----------------------------------------------------------------------
    perform PRD simulation on one or more replicas
 ------------------------------------------------------------------------- */
 
 void PRD::command(int narg, char **arg)
 {
   int flag,ireplica;
 
   // error checks
 
   if (domain->box_exist == 0) 
     error->all("PRD command before simulation box is defined");
   if (universe->nworlds != universe->nprocs && 
       atom->map_style == 0) 
     error->all("Cannot use PRD with multi-processor replicas "
 	       "unless atom map exists");
   if (universe->nworlds == 1 && comm->me == 0) 
     error->warning("Running PRD with only one replica");
 
   if (narg < 7) error->universe_all("Illegal prd command");
 
   nsteps = atoi(arg[0]);
   t_event = atoi(arg[1]);
   n_dephase = atoi(arg[2]);
   t_dephase = atoi(arg[3]);
   t_corr = atoi(arg[4]);
 
   char id_compute[strlen(arg[5])+1];
   strcpy(id_compute,arg[5]);
   int seed = atoi(arg[6]);
   
   options(narg-7,&arg[7]);
 
   // total # of timesteps must be multiple of t_event
 
   if (t_event <= 0) error->universe_all("Invalid t_event in prd command");
   if (nsteps % t_event) 
     error->universe_all("PRD nsteps must be multiple of t_event");
   if (t_corr % t_event)
     error->universe_all("PRD t_corr must be multiple of t_event");
 
   // local storage
 
   int me_universe = universe->me;
   int nprocs_universe = universe->nprocs;
   int nreplica = universe->nworlds;
   int iworld = universe->iworld;
 
   MPI_Comm_rank(world,&me);
   MPI_Comm_size(world,&nprocs);
 
   // comm_replica = communicator between same proc across replicas
   // not used if replicas have unequal number of procs
   // equal_size_replicas = 1 if all replicas have same # of procs
 
   int color = me;
   MPI_Comm_split(universe->uworld,color,0,&comm_replica);
 
   flag = 0;
   if (nreplica*nprocs == nprocs_universe) flag = 1;
   MPI_Allreduce(&flag,&equal_size_replicas,1,MPI_INT,MPI_MIN,universe->uworld);
 
   // workspace for inter-replica communication via gathers
 
   natoms = atom->natoms;
 
   displacements = NULL;
   tagall = NULL;
   xall = NULL;
   imageall = NULL;
 
   if (nreplica != nprocs_universe) {
     displacements = new int[nprocs];
     tagall = (int *) memory->smalloc(natoms*sizeof(int),"prd:tagall");
     xall = memory->create_2d_double_array(natoms,3,"prd:xall");
     imageall = (int *) memory->smalloc(natoms*sizeof(int),"prd:imageall");
   }
 
   // random_select = same RNG for each replica for multiple event selection
   // random_dephase = unique RNG for each replica for dephasing
 
   random_select = new RanPark(lmp,seed);
   random_dephase = new RanMars(lmp,seed+iworld);
 
   // create ComputeTemp class to monitor temperature
   
   char **args = new char*[3];
   args[0] = (char *) "prd_temp";
   args[1] = (char *) "all";
   args[2] = (char *) "temp";
   modify->add_compute(3,args);
   temperature = modify->compute[modify->ncompute-1];
 
   // create Velocity class for velocity creation in dephasing
   // pass it temperature compute, loop_setting, dist_setting settings
 
   atom->check_mass();
   velocity = new Velocity(lmp);
   velocity->init_external("all");
 
   args[0] = (char *) "temp";
   args[1] = (char *) "prd_temp";
   velocity->options(2,args);
   args[0] = (char *) "loop";
   args[1] = (char *) loop_setting;
   if (loop_setting) velocity->options(2,args);
   args[0] = (char *) "dist";
   args[1] = (char *) dist_setting;
   if (dist_setting) velocity->options(2,args);
 
   // create FixEventPRD class to store event and pre-quench states
 
   args[0] = (char *) "prd_event";
   args[1] = (char *) "all";
   args[2] = (char *) "EVENT/PRD";
   modify->add_fix(3,args);
   fix_event = (FixEventPRD *) modify->fix[modify->nfix-1];
 
   // create Finish for timing output
 
   finish = new Finish(lmp);
 
   // string clean-up
 
   delete [] args;
   delete [] loop_setting;
   delete [] dist_setting;
 
   // assign FixEventPRD to event-detection compute
   // necessary so it will know atom coords at last event
 
   int icompute = modify->find_compute(id_compute);
   if (icompute < 0) error->all("Could not find compute ID for PRD");
   compute_event = modify->compute[icompute];
   compute_event->reset_extra_compute_fix("prd_event");
 
   // reset reneighboring criteria since will perform minimizations
 
   neigh_every = neighbor->every;
   neigh_delay = neighbor->delay;
   neigh_dist_check = neighbor->dist_check;
 
   if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) {
     if (me == 0) 
       error->warning("Resetting reneighboring criteria during PRD");
   }
 
   neighbor->every = 1;
   neighbor->delay = 0;
   neighbor->dist_check = 1;
 
   // initialize PRD as if one long dynamics run
 
   update->whichflag = 1;
   update->nsteps = nsteps;
   update->beginstep = update->firststep = update->ntimestep;
   update->endstep = update->laststep = update->firststep + nsteps;
   update->restrict_output = 1;
 
   lmp->init();
 
   // init minimizer settings and minimizer itself
 
   update->etol = etol;
   update->ftol = ftol;
   update->max_eval = maxeval;
 
   update->minimize->init();
 
   // cannot use PRD with time-dependent fixes or regions or atom sorting
 
   for (int i = 0; i < modify->nfix; i++)
     if (modify->fix[i]->time_depend)
       error->all("Cannot use PRD with a time-dependent fix defined");
 
   for (int i = 0; i < domain->nregion; i++)
     if (domain->regions[i]->dynamic_check())
       error->all("Cannot use PRD with a time-dependent region defined");
 
   if (atom->sortfreq > 0)
     error->all("Cannot use PRD with atom_modify sort enabled");
 
   // perform PRD simulation
 
   if (me_universe == 0 && universe->uscreen) 
     fprintf(universe->uscreen,"Setting up PRD ...\n");
 
   if (me_universe == 0) {
     if (universe->uscreen) 
       fprintf(universe->uscreen,"Step CPU Clock Event "
 	      "Correlated Coincident Replica\n");
     if (universe->ulogfile) 
       fprintf(universe->ulogfile,"Step CPU Clock Event "
 	      "Correlated Coincident Replica\n");
   }
 
   // store hot state and quenched event for replica 0
   // use share_event() to copy that info to all replicas
   // this insures all start from same place
 
   // need this line if quench() does only setup_minimal()
   // update->minimize->setup();
 
   fix_event->store_state();
   quench();
   ncoincident = 0;
   share_event(0,0);
   timer->barrier_start(TIME_LOOP);
   time_start = timer->array[TIME_LOOP];
   log_event();
 
   // do full init/setup since are starting all replicas after event
   // replica 0 bcasts temp to all replicas if temp_dephase is not set
 
   update->whichflag = 1;
   lmp->init();
   update->integrate->setup();
 
   if (temp_flag == 0) {
     if (universe->iworld == 0) temp_dephase = temperature->compute_scalar();
     MPI_Bcast(&temp_dephase,1,MPI_DOUBLE,universe->root_proc[0],
               universe->uworld);
   }
 
   // main loop: look for events until out of time
   // (1) dephase independently on each proc after event
   // (2) loop: dynamics, store state, quench, check event, restore state
   // (3) share and record event
 
   nbuild = ndanger = 0;
   time_dephase = time_dynamics = time_quench = time_comm = time_output = 0.0;
 
   timer->barrier_start(TIME_LOOP);
   time_start = timer->array[TIME_LOOP];
 
   while (update->ntimestep < update->endstep) {
     dephase();
 
     ireplica = -1;
     while (update->ntimestep < update->endstep) {
       dynamics();
       fix_event->store_state();
       quench();
       ireplica = check_event();
       if (ireplica >= 0) break;
       fix_event->restore_state();
     }
     if (ireplica < 0) break;
 
     // potentially more efficient for correlated events if don't
     // share until correlated check has completed
     // this will complicate the dump (always on replica 0)
 
     share_event(ireplica,1);
     log_event();
     
     int restart_flag = 0;
     if (output->restart_every && universe->iworld == 0)
       if (fix_event->event_number % output->restart_every == 0)
         restart_flag = 1;
 
     // correlated event loop
     // other procs could be dephasing during this time
 
     int corr_endstep = update->ntimestep + t_corr;
     while (update->ntimestep < corr_endstep) {
       if (update->ntimestep == update->endstep) {
         restart_flag = 0;
         break;
       }
       dynamics();
       fix_event->store_state();
       quench();
       int corr_event_check = check_event(ireplica);
       if (corr_event_check >= 0) {
         share_event(ireplica,2);
         log_event();
         corr_endstep = update->ntimestep + t_corr;
       } else fix_event->restore_state();
     }
     
     // full init/setup since are starting all replicas after event
     // event replica bcasts temp to all replicas if temp_dephase is not set
 
     update->whichflag = 1;
     lmp->init();
     update->integrate->setup();
 
     timer->barrier_start(TIME_LOOP);
     if (t_corr > 0) replicate(ireplica);
     if (temp_flag == 0) {
       if (ireplica == universe->iworld)
 	temp_dephase = temperature->compute_scalar();
       MPI_Bcast(&temp_dephase,1,MPI_DOUBLE,universe->root_proc[ireplica],
         	      universe->uworld);
     }
     timer->barrier_stop(TIME_LOOP);
     time_comm += timer->array[TIME_LOOP];
     
     // write restart file of hot coords
 
     if (restart_flag) {
       timer->barrier_start(TIME_LOOP);
       output->write_restart(update->ntimestep);
       timer->barrier_stop(TIME_LOOP);
       time_output += timer->array[TIME_LOOP];
     }
   }
 
   // set total timers and counters so Finish() will process them
 
   timer->array[TIME_LOOP] = time_start;
   timer->barrier_stop(TIME_LOOP);
 
   timer->array[TIME_PAIR] = time_dephase;
   timer->array[TIME_BOND] = time_dynamics;
   timer->array[TIME_KSPACE] = time_quench;
   timer->array[TIME_COMM] = time_comm;
   timer->array[TIME_OUTPUT] = time_output;
 
   neighbor->ncalls = nbuild;
   neighbor->ndanger = ndanger;
 
   if (me_universe == 0) {
+    char str[128];
+    sprintf(str,"Loop time of %%g on %%d procs for %%d steps with %s atoms\n",
+	    BIGINT_FORMAT);
     if (universe->uscreen) 
-      fprintf(universe->uscreen,
-              "Loop time of %g on %d procs for %d steps with %lu atoms\n",
+      fprintf(universe->uscreen,str,
 	      timer->array[TIME_LOOP],nprocs_universe,nsteps,atom->natoms);
     if (universe->ulogfile) 
-      fprintf(universe->ulogfile,
-              "Loop time of %g on %d procs for %d steps with %lu atoms\n",
+      fprintf(universe->ulogfile,str,
               timer->array[TIME_LOOP],nprocs_universe,nsteps,atom->natoms);
   }
   
   finish->end(2);
   
   update->whichflag = 0;
   update->firststep = update->laststep = 0;
   update->beginstep = update->endstep = 0;
   update->restrict_output = 0;
 
   // reset reneighboring criteria
 
   neighbor->every = neigh_every;
   neighbor->delay = neigh_delay;
   neighbor->dist_check = neigh_dist_check;
 
   // clean up
 
   delete [] displacements;
   memory->sfree(tagall);
   memory->destroy_2d_double_array(xall);
   memory->sfree(imageall);
   
   MPI_Comm_free(&comm_replica);
   delete random_select;
   delete random_dephase;
   delete velocity;
   delete finish;
   modify->delete_compute("prd_temp");
   modify->delete_fix("prd_event");
 
   compute_event->reset_extra_compute_fix(NULL);
 }
 
 /* ----------------------------------------------------------------------
    dephasing = one or more short runs with new random velocities
 ------------------------------------------------------------------------- */
 
 void PRD::dephase()
 {
-  int ntimestep_hold = update->ntimestep;
+  bigint ntimestep_hold = update->ntimestep;
 
   update->whichflag = 1;
   update->nsteps = n_dephase*t_dephase;
 
   timer->barrier_start(TIME_LOOP);
 
   for (int i = 0; i < n_dephase; i++) {
-    int seed = static_cast<int> (random_dephase->uniform() * MAXINT32);
+    int seed = static_cast<int> (random_dephase->uniform() * MAXSMALLINT);
     if (seed == 0) seed = 1;
     velocity->create(temp_dephase,seed);
     update->integrate->run(t_dephase);
     if (temp_flag == 0) temp_dephase = temperature->compute_scalar();
   }
 
   timer->barrier_stop(TIME_LOOP);
   time_dephase += timer->array[TIME_LOOP];
 
   update->integrate->cleanup();
   finish->end(0);
 
   // reset timestep as if dephase did not occur
   // clear timestep storage from computes, since now invalid
 
   update->ntimestep = ntimestep_hold;
   for (int i = 0; i < modify->ncompute; i++)
     if (modify->compute[i]->timeflag) modify->compute[i]->clearstep();
 }
 
 /* ----------------------------------------------------------------------
    single short dynamics run
 ------------------------------------------------------------------------- */
 
 void PRD::dynamics()
 {
   update->whichflag = 1;
   update->nsteps = t_event;
 
   lmp->init();
   update->integrate->setup();
   // this may be needed if don't do full init
   //modify->addstep_compute_all(update->ntimestep);
   int ncalls = neighbor->ncalls;
 
   timer->barrier_start(TIME_LOOP);
   update->integrate->run(t_event);
   timer->barrier_stop(TIME_LOOP);
   time_dynamics += timer->array[TIME_LOOP];
 
   nbuild += neighbor->ncalls - ncalls;
   ndanger += neighbor->ndanger;
 
   update->integrate->cleanup();
   finish->end(0);
 }
 
 /* ----------------------------------------------------------------------
    quench minimization
 ------------------------------------------------------------------------- */
 
 void PRD::quench()
 {
-  int ntimestep_hold = update->ntimestep;
-  int endstep_hold = update->endstep;
+  bigint ntimestep_hold = update->ntimestep;
+  bigint endstep_hold = update->endstep;
 
   // need to change whichflag so that minimize->setup() calling 
   // modify->setup() will call fix->min_setup()
 
   update->whichflag = 2;
   update->nsteps = maxiter;
   update->endstep = update->laststep = update->firststep + maxiter;
 
   // full init works
 
   lmp->init();
   update->minimize->setup();
 
   // partial init does not work
 
   //modify->addstep_compute_all(update->ntimestep);
   //update->minimize->setup_minimal(1);
 
   int ncalls = neighbor->ncalls;
 
   timer->barrier_start(TIME_LOOP);
   update->minimize->run(maxiter);
   timer->barrier_stop(TIME_LOOP);
   time_quench += timer->array[TIME_LOOP];
 
   if (neighbor->ncalls == ncalls) quench_reneighbor = 0;
   else quench_reneighbor = 1;
 
   update->minimize->cleanup();
   finish->end(0);
 
   // reset timestep as if dephase did not occur
   // clear timestep storage from computes, since now invalid
 
   update->ntimestep = ntimestep_hold;
   update->endstep = update->laststep = endstep_hold;
   for (int i = 0; i < modify->ncompute; i++)
     if (modify->compute[i]->timeflag) modify->compute[i]->clearstep();
 }
 
 /* ----------------------------------------------------------------------
    check for an event in any replica
    if replica_num is non-negative only check for event on replica_num 
    if multiple events, choose one at random
    return -1 if no event
    else return ireplica = world in which event occured
 ------------------------------------------------------------------------- */
 
 int PRD::check_event(int replica_num)
 {
   int worldflag,universeflag,scanflag,replicaflag,ireplica;
 
   worldflag = 0;
   if (compute_event->compute_scalar() > 0.0) worldflag = 1;
   if (replica_num >= 0 && replica_num != universe->iworld) worldflag = 0;
   
   timer->barrier_start(TIME_LOOP);
   if (me == 0) MPI_Allreduce(&worldflag,&universeflag,1,
 		             MPI_INT,MPI_SUM,comm_replica);
   MPI_Bcast(&universeflag,1,MPI_INT,0,world);
   ncoincident = universeflag;  
   if (!universeflag) ireplica = -1;
   else {
     if (universeflag > 1) {
       int iwhich = static_cast<int> 
 	(universeflag*random_select->uniform()) + 1;
       if (me == 0) MPI_Scan(&worldflag,&scanflag,1,
 			    MPI_INT,MPI_SUM,comm_replica);
       MPI_Bcast(&scanflag,1,MPI_INT,0,world);
       if (scanflag != iwhich) worldflag = 0;
     }
 
     if (worldflag) replicaflag = universe->iworld;
     else replicaflag = 0;
     if (me == 0) MPI_Allreduce(&replicaflag,&ireplica,1,
   			     MPI_INT,MPI_SUM,comm_replica);
     MPI_Bcast(&ireplica,1,MPI_INT,0,world);
   }
   timer->barrier_stop(TIME_LOOP);
   time_comm += timer->array[TIME_LOOP];
   return ireplica;
 }
 
 /* ----------------------------------------------------------------------
    share quenched and hot coords owned by ireplica with all replicas
    all replicas store event in fix_event
    replica 0 dumps event snapshot
    flag = 0 = called before PRD run
    flag = 1 = called during PRD run = not correlated event
    flag = 2 = called during PRD run = correlated event
 ------------------------------------------------------------------------- */
 
 void PRD::share_event(int ireplica, int flag)
 {
   timer->barrier_start(TIME_LOOP);
 
   // communicate quenched coords to all replicas and store as event
   // decrement event counter if flag = 0 since not really an event
 
   replicate(ireplica);
   timer->barrier_stop(TIME_LOOP);
   time_comm += timer->array[TIME_LOOP];
   
   // adjust time for last correlated event check (not on first event)
 
   int corr_adjust = t_corr;
   if (fix_event->event_number < 1 || flag == 2) corr_adjust = 0;
 
   // delta = time since last correlated event check
 
   int delta = update->ntimestep - fix_event->event_timestep - corr_adjust;
 
   // if this is a correlated event, time elapsed only on one partition
 
   if (flag != 2) delta *= universe->nworlds;
   delta += corr_adjust;
 
   // don't change the clock or timestep if this is a restart
 
   if (flag == 0 && fix_event->event_number != 0) 
     fix_event->store_event_prd(fix_event->event_timestep,0);
   else {
     fix_event->store_event_prd(update->ntimestep,delta);
     fix_event->replica_number = ireplica;
     fix_event->correlated_event = 0;
     if (flag == 2) fix_event->correlated_event = 1;
     fix_event->ncoincident = ncoincident;
   } 
   if (flag == 0) fix_event->event_number--;
 
   // dump snapshot of quenched coords
   // must reneighbor and compute forces before dumping
   // since replica 0 possibly has new state from another replica
   // addstep_compute_all insures eng/virial are calculated if needed
 
   if (output->ndump && universe->iworld == 0) {
     timer->barrier_start(TIME_LOOP);
     modify->addstep_compute_all(update->ntimestep);
     update->integrate->setup_minimal(1);
     output->write_dump(update->ntimestep);
     timer->barrier_stop(TIME_LOOP);
     time_output += timer->array[TIME_LOOP];
   }
 
   // restore and communicate hot coords to all replicas
 
   fix_event->restore_state();
   timer->barrier_start(TIME_LOOP);
   replicate(ireplica);
   timer->barrier_stop(TIME_LOOP);
   time_comm += timer->array[TIME_LOOP];
 }
 
 /* ----------------------------------------------------------------------
    universe proc 0 prints event info
 ------------------------------------------------------------------------- */
 
 void PRD::log_event()
 {
   timer->array[TIME_LOOP] = time_start;
   if (universe->me == 0) {
+    char fstr[32];
+    sprintf(fstr,"%s %%.3f %%d %%d %%d %%d %%d\n",BIGINT_FORMAT);
     if (universe->uscreen)
-      fprintf(universe->uscreen,"%d %.3f %d %d %d %d %d\n",
+      fprintf(universe->uscreen,fstr,
               fix_event->event_timestep,
 	      timer->elapsed(TIME_LOOP),
 	      fix_event->clock,
               fix_event->event_number,fix_event->correlated_event,
 	      fix_event->ncoincident,
               fix_event->replica_number);
     if (universe->ulogfile)
-      fprintf(universe->ulogfile,"%d %.3f %d %d %d %d %d\n",
+      fprintf(universe->ulogfile,fstr,
               fix_event->event_timestep,
 	      timer->elapsed(TIME_LOOP),
 	      fix_event->clock,
               fix_event->event_number,fix_event->correlated_event,
 	      fix_event->ncoincident,
               fix_event->replica_number);
   }
 }
 
 /* ----------------------------------------------------------------------
   communicate atom coords and image flags in ireplica to all other replicas
   one proc per replica:
     direct overwrite via bcast
   equal procs per replica and no replica reneighbored:
     direct overwrite via bcast
   unequal procs per replica or reneighboring occurred:
     collect to root proc of event replica
     bcast to roots of other replicas
     bcast within each replica
     each proc extracts info for atoms it owns using atom IDs
 ------------------------------------------------------------------------- */
 
 void PRD::replicate(int ireplica)
 {
   int nreplica = universe->nworlds;
   int nprocs_universe = universe->nprocs;
   int i,m,flag,commflag;
   int counts[nprocs];
 
   if (nreplica == nprocs_universe) commflag = 0;
   else if (equal_size_replicas) {
     flag = 0;
     if (quench_reneighbor) flag = 1;
     MPI_Allreduce(&flag,&commflag,1,MPI_INT,MPI_MAX,universe->uworld);
   } else commflag = 1;
 
   if (commflag == 0) {
     MPI_Bcast(atom->image,atom->nlocal,MPI_INT,ireplica,comm_replica);
     MPI_Bcast(atom->x[0],3*atom->nlocal,MPI_DOUBLE,ireplica,comm_replica);
   } else {
     if (universe->iworld == ireplica) {
       MPI_Gather(&atom->nlocal,1,MPI_INT,counts,1,MPI_INT,0,world);
       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->image,atom->nlocal,MPI_INT,
       	          imageall,counts,displacements,MPI_INT,0,world);
       for (i = 0; i < nprocs; i++) counts[i] *= 3;
       for (i = 0; i < nprocs-1; i++)
         displacements[i+1] = displacements[i] + counts[i];
       MPI_Gatherv(atom->x[0],3*atom->nlocal,MPI_DOUBLE,
       	          xall[0],counts,displacements,MPI_DOUBLE,0,world);
     }
 
     if (me == 0) {
       MPI_Bcast(tagall,natoms,MPI_INT,ireplica,comm_replica);
       MPI_Bcast(imageall,natoms,MPI_INT,ireplica,comm_replica);
       MPI_Bcast(xall[0],3*natoms,MPI_DOUBLE,ireplica,comm_replica);
     }
 
     MPI_Bcast(tagall,natoms,MPI_INT,0,world);
     MPI_Bcast(imageall,natoms,MPI_INT,0,world);
     MPI_Bcast(xall[0],3*natoms,MPI_DOUBLE,0,world);
 
     double **x = atom->x;
     int nlocal = atom->nlocal;
 
     for (i = 0; i < natoms; i++) {
       m = atom->map(tagall[i]);
       if (m >= 0 && m < nlocal) {
         x[m][0] = xall[i][0];
         x[m][1] = xall[i][1];
         x[m][2] = xall[i][2];
         atom->image[m] = imageall[i];
       }
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    parse optional parameters at end of PRD input line 
 ------------------------------------------------------------------------- */
 
 void PRD::options(int narg, char **arg)
 {
   if (narg < 0) error->all("Illegal prd command");
 
   // set defaults
   
   etol = 0.1;
   ftol = 0.1;
   maxiter = 40;
   maxeval = 50;
   temp_flag = 0;
 
   char *str = "geom";
   int n = strlen(str) + 1;
   loop_setting = new char[n];
   strcpy(loop_setting,str);
 
   str = "gaussian";
   n = strlen(str) + 1;
   dist_setting = new char[n];
   strcpy(dist_setting,str);
 
   int iarg = 0;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"min") == 0) {
       if (iarg+5 > narg) error->all("Illegal prd command");
       etol = atof(arg[iarg+1]);
       ftol = atof(arg[iarg+2]);
       maxiter = atoi(arg[iarg+3]);
       maxeval = atoi(arg[iarg+4]);
       if (maxiter < 0) error->all("Illegal prd command");
       iarg += 5;
 
     } else if (strcmp(arg[iarg],"temp") == 0) {
       if (iarg+2 > narg) error->all("Illegal prd command");
       temp_flag = 1;
       temp_dephase = atof(arg[iarg+1]);
       if (temp_dephase <= 0.0) error->all("Illegal prd command");
       iarg += 2;
 
     } else if (strcmp(arg[iarg],"vel") == 0) {
       if (iarg+3 > narg) error->all("Illegal prd command");
       delete [] loop_setting;
       delete [] dist_setting;
 
       if (strcmp(arg[iarg+1],"all") == 0) loop_setting = NULL;
       else if (strcmp(arg[iarg+1],"local") == 0) loop_setting = NULL;
       else if (strcmp(arg[iarg+1],"geom") == 0) loop_setting = NULL;
       else error->all("Illegal prd command");
       int n = strlen(arg[iarg+1]) + 1;
       loop_setting = new char[n];
       strcpy(loop_setting,arg[iarg+1]);
 
       if (strcmp(arg[iarg+2],"uniform") == 0) dist_setting = NULL;
       else if (strcmp(arg[iarg+2],"gaussian") == 0) dist_setting = NULL;
       else error->all("Illegal prd command");
       n = strlen(arg[iarg+2]) + 1;
       dist_setting = new char[n];
       strcpy(dist_setting,arg[iarg+2]);
 
       iarg += 3;
     } else error->all("Illegal prd command");
   }
 }
diff --git a/src/REPLICA/tad.cpp b/src/REPLICA/tad.cpp
index c1d487ed1..0cbb93707 100644
--- a/src/REPLICA/tad.cpp
+++ b/src/REPLICA/tad.cpp
@@ -1,987 +1,985 @@
-// To do:
-// Mysterious problem with   //  if (universe->iworld == 0) 
-
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Aidan Thompson (SNL)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "tad.h"
 #include "universe.h"
 #include "update.h"
 #include "atom.h"
 #include "domain.h"
 #include "region.h"
 #include "comm.h"
 #include "velocity.h"
 #include "integrate.h"
 #include "min.h"
 #include "neighbor.h"
 #include "modify.h"
 #include "neb.h"
 #include "compute.h"
 #include "fix.h"
 #include "fix_event_tad.h"
 #include "fix_store_state.h"
 #include "force.h"  
 #include "pair.h"
 #include "random_park.h"
 #include "random_mars.h"
 #include "output.h"
 #include "dump.h"
 #include "finish.h"
 #include "timer.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 TAD::TAD(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 TAD::~TAD() {
   memory->sfree(fix_event_list);
   if (neb_logfilename != NULL) delete [] neb_logfilename;
   delete [] min_style;
   delete [] min_style_neb;
 }
 
 /* ----------------------------------------------------------------------
    perform TAD simulation on root proc
    other procs only used for NEB calcs
 ------------------------------------------------------------------------- */
 
 void TAD::command(int narg, char **arg)
 {
 
   fix_event_list = NULL;
   n_event_list = 0;
   nmax_event_list = 0;
   nmin_event_list = 10;
 
   // error checks
 
   if (domain->box_exist == 0) 
     error->all("tad command before simulation box is defined");
-  if (universe->nworlds == 1) error->all("Cannot use TAD with a single replica for NEB");
+  if (universe->nworlds == 1) 
+    error->all("Cannot use TAD with a single replica for NEB");
   if (universe->nworlds != universe->nprocs)
     error->all("Can only use TAD with 1-processor replicas for NEB");
   if (atom->sortfreq > 0)
     error->all("Cannot use TAD with atom_modify sort enabled for NEB");
   if (atom->map_style == 0) 
     error->all("Cannot use TAD unless atom map exists for NEB");
 
   if (narg < 7) error->universe_all("Illegal tad command");
 
   nsteps = atoi(arg[0]);
   t_event = atoi(arg[1]);
   templo = atof(arg[2]);
   temphi = atof(arg[3]);
   delta_conf = atof(arg[4]);
   tmax = atof(arg[5]);
   
   char id_compute[strlen(arg[6])+1];
   strcpy(id_compute,arg[6]);
   
   options(narg-7,&arg[7]);
 
   // total # of timesteps must be multiple of t_event
 
   if (t_event <= 0) error->universe_all("Invalid t_event in tad command");
   if (nsteps % t_event) 
     error->universe_all("TAD nsteps must be multiple of t_event");
 
   if (delta_conf <= 0.0 || delta_conf >= 1.0) 
     error->universe_all("Invalid delta_conf in tad command");
 
   if (tmax <= 0.0) 
     error->universe_all("Invalid tmax in tad command");
 
   // deltconf = (ln(1/delta))/freq_min (timestep units)
 
   deltconf = -log(delta_conf)*tmax/update->dt;
 
   // local storage
 
   int me_universe = universe->me;
   int nprocs_universe = universe->nprocs;
 
   MPI_Comm_rank(world,&me);
   MPI_Comm_size(world,&nprocs);
 
   delta_beta = (1.0/templo - 1.0/temphi) / force->boltz;
   ratio_beta = templo/temphi; 
 
   // create FixEventTAD object to store last event
 
   int narg2 = 3;
   char **args = new char*[narg2];
   args[0] = (char *) "tad_event";
   args[1] = (char *) "all";
   args[2] = (char *) "EVENT/TAD";
   modify->add_fix(narg2,args);
   fix_event = (FixEventTAD *) modify->fix[modify->nfix-1];
   delete [] args;
 
   // create FixStoreState object to store revert state
 
   narg2 = 13;
   args = new char*[narg2];
   args[0] = (char *) "tad_revert";
   args[1] = (char *) "all";
   args[2] = (char *) "store/state";
   args[3] = (char *) "0";
   args[4] = (char *) "x";
   args[5] = (char *) "y";
   args[6] = (char *) "z";
   args[7] = (char *) "ix";
   args[8] = (char *) "iy";
   args[9] = (char *) "iz";
   args[10] = (char *) "vx";
   args[11] = (char *) "vy";
   args[12] = (char *) "vz";
   modify->add_fix(narg2,args);
   fix_revert = (FixStoreState *) modify->fix[modify->nfix-1];
   delete [] args;
 
   // create Finish for timing output
 
   finish = new Finish(lmp);
 
   // assign FixEventTAD to event-detection compute
   // necessary so it will know atom coords at last event
 
   int icompute = modify->find_compute(id_compute);
   if (icompute < 0) error->all("Could not find compute ID for TAD");
   compute_event = modify->compute[icompute];
   compute_event->reset_extra_compute_fix("tad_event");
 
   // reset reneighboring criteria since will perform minimizations
 
   neigh_every = neighbor->every;
   neigh_delay = neighbor->delay;
   neigh_dist_check = neighbor->dist_check;
 
   if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) {
     if (me_universe == 0) 
       error->warning("Resetting reneighboring criteria during TAD");
   }
 
   neighbor->every = 1;
   neighbor->delay = 0;
   neighbor->dist_check = 1;
 
   // initialize TAD as if one long dynamics run
 
   update->whichflag = 1;
   update->nsteps = nsteps;
   update->beginstep = update->firststep = update->ntimestep;
   update->endstep = update->laststep = update->firststep + nsteps;
   update->restrict_output = 1;
 
   lmp->init();
 
   // set minimize style for quench
 
   narg2 = 1;
   args = new char*[narg2];
   args[0] = min_style;
 
   update->create_minimize(narg2,args);
 
   delete [] args;
 
   // init minimizer settings and minimizer itself
 
   update->etol = etol;
   update->ftol = ftol;
   update->max_eval = maxeval;
 
   update->minimize->init();
 
   // perform TAD simulation
 
   if (me_universe == 0 && universe->uscreen) 
     fprintf(universe->uscreen,"Setting up TAD ...\n");
 
   if (me_universe == 0) {
     if (universe->uscreen) 
-      fprintf(universe->uscreen,"Step CPU Clock Event "
-	      "\n");
+      fprintf(universe->uscreen,"Step CPU Clock Event\n");
     if (universe->ulogfile) 
-      fprintf(universe->ulogfile,"Step CPU Clock Event "
-	      "\n");
+      fprintf(universe->ulogfile,"Step CPU Clock Event\n");
   }
 
   ulogfile_lammps = universe->ulogfile;
   uscreen_lammps = universe->uscreen;
   ulogfile_neb = NULL;
   uscreen_neb = NULL;
   if (me_universe == 0 && neb_logfilename) 
     ulogfile_neb = fopen(neb_logfilename,"w");
 
   // store hot state and quenched event, only on replica 0
 
   // need this line if quench() does only setup_minimal()
   // update->minimize->setup();
 
   // This should work with if uncommented, but does not
   // if (universe->iworld == 0) {
   fix_event->store_state();
   quench();
   timer->barrier_start(TIME_LOOP);
   time_start = timer->array[TIME_LOOP];
   fix_event->store_event_tad(update->ntimestep);
   log_event();
   fix_event->restore_state();
 
   // do full init/setup
   
   update->whichflag = 1;
   lmp->init();
   update->integrate->setup();
   //   }
     
   // main loop: look for events until out of time
   // (1) dynamics, store state, quench, check event, restore state
   // (2) if event, perform NEB, record in fix_event_list
   // (3) if confident, pick earliest event 
 
   nbuild = ndanger = 0;
   time_neb = time_dynamics = time_quench = time_comm = time_output = 0.0;
 
   timer->barrier_start(TIME_LOOP);
   time_start = timer->array[TIME_LOOP];
   
   int confident_flag, event_flag;
 
   if (universe->iworld == 0) {
     while (update->ntimestep < update->endstep) {
 
       // initialize list of possible events
       
       initialize_event_list();
       confident_flag = 0;
 
       while (update->ntimestep < update->endstep) {
 	event_flag = 0;
 	while (update->ntimestep < update->endstep) {
 
 	  dynamics();
 
 
 	  fix_event->store_state();
 
 
 	  quench();
 
 
 	  event_flag = check_event();
 	  MPI_Bcast(&event_flag,1,MPI_INT,0,universe->uworld);
 
 	  if (event_flag) break;
 
 	  // restore hot state
 
 	  fix_event->restore_state();
 
 	  // store hot state in revert
 
 	  fix_revert->end_of_step();
 	}
 	if (!event_flag) break;
 
 	add_event();
 
 	perform_neb(n_event_list-1);
 	compute_tlo(n_event_list-1);
 	confident_flag = check_confidence();
 	MPI_Bcast(&confident_flag,1,MPI_INT,0,universe->uworld);
 	if (confident_flag) break;
 	if (universe->iworld == 0) revert();
       }
       if (!confident_flag) break;
     
       perform_event(event_first);
 
       // need to sync timestep with TAD 
 
       MPI_Bcast(&(update->ntimestep),1,MPI_INT,0,universe->uworld);
     
       int restart_flag = 0;
       if (output->restart_every && universe->iworld == 0)
 	if (fix_event->event_number % output->restart_every == 0)
 	  restart_flag = 1;
 
       // full init/setup since are starting after event
 
       update->whichflag = 1;
       lmp->init();
       update->integrate->setup();
 
     // write restart file of hot coords
 
       if (restart_flag) {
 	timer->barrier_start(TIME_LOOP);
 	output->write_restart(update->ntimestep);
 	timer->barrier_stop(TIME_LOOP);
 	time_output += timer->array[TIME_LOOP];
       }
     }
 
   } else {
 
     while (update->ntimestep < update->endstep) {
       confident_flag = 0;
       while (update->ntimestep < update->endstep) {
 	event_flag = 0;
 	while (update->ntimestep < update->endstep) {
 	  update->ntimestep += t_event;
 	  MPI_Bcast(&event_flag,1,MPI_INT,0,universe->uworld);
 
 	  if (event_flag) break;
 	}
 	if (!event_flag) break;
 	perform_neb(-1);
 	MPI_Bcast(&confident_flag,1,MPI_INT,0,universe->uworld);
 	if (confident_flag) break;
       }
       if (!confident_flag) break;
     
       // need to sync timestep with TAD 
 
       MPI_Bcast(&(update->ntimestep),1,MPI_INT,0,universe->uworld);
     }
   }
 
   // set total timers and counters so Finish() will process them
 
   timer->array[TIME_LOOP] = time_start;
   timer->barrier_stop(TIME_LOOP);
 
   timer->array[TIME_PAIR] = time_neb;
   timer->array[TIME_BOND] = time_dynamics;
   timer->array[TIME_KSPACE] = time_quench;
   timer->array[TIME_COMM] = time_comm;
   timer->array[TIME_OUTPUT] = time_output;
 
   neighbor->ncalls = nbuild;
   neighbor->ndanger = ndanger;
 
   if (me_universe == 0) {
+    char str[128];
+    sprintf(str,"Loop time of %%g on %%d procs for %%d steps with %s atoms\n",
+	    BIGINT_FORMAT);
     if (universe->uscreen) 
-      fprintf(universe->uscreen,
-              "Loop time of %g on %d procs for %d steps with %lu atoms\n",
+      fprintf(universe->uscreen,str,
 	      timer->array[TIME_LOOP],nprocs_universe,nsteps,atom->natoms);
     if (universe->ulogfile) 
-      fprintf(universe->ulogfile,
-              "Loop time of %g on %d procs for %d steps with %lu atoms\n",
+      fprintf(universe->ulogfile,str,
               timer->array[TIME_LOOP],nprocs_universe,nsteps,atom->natoms);
   }
 
   if (me_universe == 0) fclose(ulogfile_neb);
   
   finish->end(3);
   
   update->whichflag = 0;
   update->firststep = update->laststep = 0;
   update->beginstep = update->endstep = 0;
   update->restrict_output = 0;
 
   // reset reneighboring criteria
 
   neighbor->every = neigh_every;
   neighbor->delay = neigh_delay;
   neighbor->dist_check = neigh_dist_check;
 
   delete finish;
   modify->delete_fix("tad_event");
   modify->delete_fix("tad_revert");
   delete_event_list();
 
   compute_event->reset_extra_compute_fix(NULL);
 }
 
 /* ----------------------------------------------------------------------
    single short dynamics run
 ------------------------------------------------------------------------- */
 
 void TAD::dynamics()
 {
   update->whichflag = 1;
   update->nsteps = t_event;
 
   lmp->init();
   update->integrate->setup();
   // this may be needed if don't do full init
   //modify->addstep_compute_all(update->ntimestep);
   int ncalls = neighbor->ncalls;
 
   timer->barrier_start(TIME_LOOP);
   update->integrate->run(t_event);
   timer->barrier_stop(TIME_LOOP);
   time_dynamics += timer->array[TIME_LOOP];
 
   nbuild += neighbor->ncalls - ncalls;
   ndanger += neighbor->ndanger;
 
   update->integrate->cleanup();
   finish->end(0);
 }
 
 /* ----------------------------------------------------------------------
    quench minimization
 ------------------------------------------------------------------------- */
 
 void TAD::quench()
 {
-  int ntimestep_hold = update->ntimestep;
-  int endstep_hold = update->endstep;
+  bigint ntimestep_hold = update->ntimestep;
+  bigint endstep_hold = update->endstep;
 
   // need to change whichflag so that minimize->setup() calling 
   // modify->setup() will call fix->min_setup()
 
   update->whichflag = 2;
   update->nsteps = maxiter;
   update->endstep = update->laststep = update->firststep + maxiter;
 
   // full init works
 
   lmp->init();
   update->minimize->setup();
 
   // partial init does not work
 
   //modify->addstep_compute_all(update->ntimestep);
   //update->minimize->setup_minimal(1);
 
   int ncalls = neighbor->ncalls;
 
   timer->barrier_start(TIME_LOOP);
   update->minimize->run(maxiter);
   timer->barrier_stop(TIME_LOOP);
   time_quench += timer->array[TIME_LOOP];
 
   if (neighbor->ncalls == ncalls) quench_reneighbor = 0;
   else quench_reneighbor = 1;
 
   update->minimize->cleanup();
   finish->end(1);
 
   // reset timestep as if quench did not occur
   // clear timestep storage from computes, since now invalid
 
   update->ntimestep = ntimestep_hold;
   update->endstep = update->laststep = endstep_hold;
   for (int i = 0; i < modify->ncompute; i++)
     if (modify->compute[i]->timeflag) modify->compute[i]->clearstep();
 }
 
 /* ----------------------------------------------------------------------
    check for an event
    return 0 if no event
    return 1 if event
 ------------------------------------------------------------------------- */
 
 int TAD::check_event()
 {
   int flag;
 
   flag = 0;
   if (compute_event->compute_scalar() > 0.0) flag = 1;
 
   return flag;
 }
 
 /* ----------------------------------------------------------------------
    universe proc 0 prints event info
 ------------------------------------------------------------------------- */
 
 void TAD::log_event()
 {
   timer->array[TIME_LOOP] = time_start;
   if (universe->me == 0) {
+    char fstr[32];
+    sprintf(fstr,"%s %%.3f %%.3f %%d\n",BIGINT_FORMAT);
     if (universe->uscreen)
-      fprintf(universe->uscreen,"%d %.3f %.3f %d\n",
+      fprintf(universe->uscreen,fstr,
               fix_event->event_timestep,
 	      timer->elapsed(TIME_LOOP),
 	      fix_event->tlo,
               fix_event->event_number);
     if (universe->ulogfile)
-      fprintf(universe->ulogfile,"%d %.3f %.3f %d\n",
+      fprintf(universe->ulogfile,fstr,
               fix_event->event_timestep,
 	      timer->elapsed(TIME_LOOP),
 	      fix_event->tlo,
               fix_event->event_number);
   }
 
   // dump snapshot of quenched coords
   // must reneighbor and compute forces before dumping
   // addstep_compute_all insures eng/virial are calculated if needed
   
   if (output->ndump && universe->iworld == 0) {
     timer->barrier_start(TIME_LOOP);
     modify->addstep_compute_all(update->ntimestep);
     update->integrate->setup_minimal(1);
     output->write_dump(update->ntimestep);
     timer->barrier_stop(TIME_LOOP);
     time_output += timer->array[TIME_LOOP];
   }
 
 }
 
 /* ----------------------------------------------------------------------
    parse optional parameters at end of TAD input line 
 ------------------------------------------------------------------------- */
 
 void TAD::options(int narg, char **arg)
 {
   if (narg < 0) error->all("Illegal tad command");
 
   // set defaults
   
   etol = 0.1;
   ftol = 0.1;
   maxiter = 40;
   maxeval = 50;
 
   etol_neb = 0.01;
   ftol_neb = 0.01;
   n1steps_neb = 100;
   n2steps_neb = 100;
   nevery_neb = 10;
 
   min_style = new char[3];
   strcpy(min_style,"cg");
   min_style_neb = new char[9];
   strcpy(min_style_neb,"quickmin");
   neb_logfilename = NULL;
 
   int iarg = 0;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"min") == 0) {
       if (iarg+5 > narg) error->all("Illegal tad command");
       etol = atof(arg[iarg+1]);
       ftol = atof(arg[iarg+2]);
       maxiter = atoi(arg[iarg+3]);
       maxeval = atoi(arg[iarg+4]);
       if (maxiter < 0 || maxeval < 0 || 
 	  etol < 0.0 || ftol < 0.0 ) 
 	error->all("Illegal tad command");
       iarg += 5;
 
     } else if (strcmp(arg[iarg],"neb") == 0) {
       if (iarg+6 > narg) error->all("Illegal tad command");
       etol_neb = atof(arg[iarg+1]);
       ftol_neb = atof(arg[iarg+2]);
       n1steps_neb = atoi(arg[iarg+3]);
       n2steps_neb = atoi(arg[iarg+4]);
       nevery_neb = atoi(arg[iarg+5]);
       if (etol_neb < 0.0 || ftol_neb < 0.0 || 
 	  n1steps_neb < 0 || n2steps_neb < 0 ||
 	  nevery_neb < 0) error->all("Illegal tad command");
       iarg += 6;
       
     } else if (strcmp(arg[iarg],"min_style") == 0) {
       if (iarg+2 > narg) error->all("Illegal tad command");
       int n = strlen(arg[iarg+1]) + 1;
       delete [] min_style;
       min_style = new char[n];
       strcpy(min_style,arg[iarg+1]);
       iarg += 2;
 
     } else if (strcmp(arg[iarg],"neb_style") == 0) {
       if (iarg+2 > narg) error->all("Illegal tad command");
       int n = strlen(arg[iarg+1]) + 1;
       delete [] min_style_neb;
       min_style_neb = new char[n];
       strcpy(min_style_neb,arg[iarg+1]);
       iarg += 2;
 
     } else if (strcmp(arg[iarg],"neb_log") == 0) {
       delete [] neb_logfilename;
       if (iarg+2 > narg) error->all("Illegal tad command");
       if (strcmp(arg[iarg+1],"none") == 0) neb_logfilename = NULL;
       else {
 	int n = strlen(arg[iarg+1]) + 1;
 	neb_logfilename = new char[n];
 	strcpy(neb_logfilename,arg[iarg+1]);
       }
       iarg += 2;
     } else error->all("Illegal tad command");
   }
 }
 
 /* ----------------------------------------------------------------------
    perform NEB calculation
 ------------------------------------------------------------------------- */
 
 void TAD::perform_neb(int ievent)
 {
 
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   double *buf_final = (double *) 
     memory->smalloc(3*nlocal*sizeof(double),"tad:buffinal");
 
   // set system to quenched state of event ievent
 
   if (universe->iworld == 0) {
 
     fix_event_list[ievent]->restore_event();
 
     int ii = 0;
     for (int i = 0; i < nlocal; i++) {
       buf_final[ii++] = x[i][0]; 
       buf_final[ii++] = x[i][1]; 
       buf_final[ii++] = x[i][2]; 
     }
   }
 
   MPI_Bcast(buf_final,3*nlocal,MPI_DOUBLE,universe->root_proc[0],
 	    universe->uworld);
 
   double *buf_init = (double *)
     memory->smalloc(3*nlocal*sizeof(double),"tad:bufinit");
     
   // set system to quenched state of fix_event
 
   if (universe->iworld == 0) {
 
     fix_event->restore_event();
 
     int ii = 0;
     for (int i = 0; i < nlocal; i++) {
       buf_init[ii++] = x[i][0]; 
       buf_init[ii++] = x[i][1]; 
       buf_init[ii++] = x[i][2]; 
     }
   }
 
   MPI_Bcast(buf_init,3*nlocal,MPI_DOUBLE,universe->root_proc[0],
 	    universe->uworld);
 
   // create FixNEB object to support NEB
 
   int narg2 = 4;
   char **args = new char*[narg2];
   args[0] = (char *) "neb";
   args[1] = (char *) "all";
   args[2] = (char *) "neb";
   char str[128];
   args[3] = str; 
   double kspring = 1.0;
   sprintf(args[3],"%f",kspring);
   modify->add_fix(narg2,args);
   fix_neb = (Fix *) modify->fix[modify->nfix-1];
   delete [] args;
 
   // switch minimize style to quickmin for NEB
 
   narg2 = 1;
   args = new char*[narg2];
   args[0] = min_style_neb;
 
   update->create_minimize(narg2,args);
 
   delete [] args;
 
   // create NEB object
 
   neb = new NEB(lmp,etol_neb,ftol_neb,n1steps_neb, 
 		n2steps_neb,nevery_neb,buf_init,buf_final);
 
   // free up temporary arrays
 
   memory->sfree(buf_init);
   memory->sfree(buf_final);
 
   // Run NEB
 
-  double beginstep_hold = update->beginstep;
-  double endstep_hold = update->endstep;
-  double ntimestep_hold = update->ntimestep;
-  double nsteps_hold = update->nsteps;
+  int beginstep_hold = update->beginstep;
+  int endstep_hold = update->endstep;
+  int ntimestep_hold = update->ntimestep;
+  int nsteps_hold = update->nsteps;
 
   if (universe->me == 0) {
     universe->ulogfile = ulogfile_neb;
     universe->uscreen = uscreen_neb;
   }
 
   // Had to bypass timer interface
   // because timer->array is reset
   // inside neb->run()
 
 //    timer->barrier_start(TIME_LOOP);
 //    neb->run();
 //    timer->barrier_stop(TIME_LOOP);
 //    time_neb += timer->array[TIME_LOOP];
 
   MPI_Barrier(world);
   double time_tmp = MPI_Wtime();
   neb->run();
   MPI_Barrier(world);
   time_neb += MPI_Wtime() - time_tmp;
 
   if (universe->me == 0) {
     universe->ulogfile = ulogfile_lammps;
     universe->uscreen = uscreen_lammps;
   }
 
   // Extract barrier energy from NEB
 
   if (universe->iworld == 0)
     fix_event_list[ievent]->ebarrier = neb->ebf;
 
   update->beginstep = update->firststep = beginstep_hold;
   update->endstep = update->laststep = endstep_hold;
   update->ntimestep = ntimestep_hold;
   update->nsteps = nsteps_hold;
 
   // switch minimize style back for quench
 
   narg2 = 1;
   args = new char*[narg2];
   args[0] = min_style;
 
   update->create_minimize(narg2,args);
 
   update->etol = etol;
   update->ftol = ftol;
 
   delete [] args;
 
   // Clean up 
 
   modify->delete_fix("neb");
   delete neb;
 }
 
 /* ----------------------------------------------------------------------
    check if confidence criterion for tstop is satisfied
    return 0 if not satisfied
    return 1 if satisfied
 ------------------------------------------------------------------------- */
 
 int TAD::check_confidence()
 {
   int flag;
 
   // update stopping time
 
   deltstop = deltconf*pow(deltfirst/deltconf, ratio_beta);
 
   flag = 0;
   if (deltstop < update->ntimestep - fix_event->event_timestep) flag = 1;
 
   return flag;
 }
 
 /* ----------------------------------------------------------------------
    reflect back in to starting state
 ------------------------------------------------------------------------- */
 
 void TAD::revert()
 {
   double **x = atom->x;
   double **v = atom->v;
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   double **array_atom = fix_revert->array_atom;
 
   for (int i = 0; i < nlocal; i++) {
     x[i][0] = array_atom[i][0];
     x[i][1] = array_atom[i][1];
     x[i][2] = array_atom[i][2];
     image[i] = ((int(array_atom[i][5]) + 512 & 1023) << 20) |
       ((int(array_atom[i][4]) + 512 & 1023) << 10) |
       (int(array_atom[i][3]) + 512 & 1023);
     v[i][0] = -array_atom[i][6];
     v[i][1] = -array_atom[i][7];
     v[i][2] = -array_atom[i][8];
   }
 }
 
 /* ----------------------------------------------------------------------
    Initialize list of possible events
 ------------------------------------------------------------------------- */
 
 void TAD::initialize_event_list() {
 
   // First delete old events, if any
 
   delete_event_list();
 
   // Create new list
 
   n_event_list = 0;
   grow_event_list(nmin_event_list);
 }
 
 /* ----------------------------------------------------------------------
    Delete list of possible events
 ------------------------------------------------------------------------- */
 
 void TAD::delete_event_list() {
 
   for (int i = 0; i < n_event_list; i++) {
     char str[128];
     sprintf(str,"tad_event_%d",i);
     modify->delete_fix(str);
   }
   memory->sfree(fix_event_list);
   fix_event_list = NULL;
   n_event_list = 0;
   nmax_event_list = 0;
 
 }
 
 /* ----------------------------------------------------------------------
    add event
 ------------------------------------------------------------------------- */
 
 void TAD::add_event()
 {
 
   // create FixEventTAD object to store possible event
 
   int narg = 3;
   char **args = new char*[narg];
 
   char str[128];
   sprintf(str,"tad_event_%d",n_event_list);
 
   args[0] = str;
   args[1] = (char *) "all";
   args[2] = (char *) "EVENT/TAD";
   modify->add_fix(narg,args);
 
   if (n_event_list == nmax_event_list) 
     grow_event_list(nmax_event_list+nmin_event_list);
   n_event_list += 1;
   int ievent = n_event_list-1;
   fix_event_list[ievent] = (FixEventTAD *) modify->fix[modify->nfix-1];
 
   // store quenched state for new event
 
   fix_event_list[ievent]->store_event_tad(update->ntimestep);
 
   // store hot state for new event
 
   fix_event->restore_state();
   fix_event_list[ievent]->store_state();
 
   // string clean-up
 
   delete [] args;
 
 }
 
 /* ----------------------------------------------------------------------
    compute cold time for event ievent
 ------------------------------------------------------------------------- */
 
 void TAD::compute_tlo(int ievent)
 {
   double deltlo,delthi,ebarrier;
 
   ebarrier = fix_event_list[ievent]->ebarrier;
   delthi = fix_event_list[ievent]->event_timestep 
     - fix_event->event_timestep;
   deltlo = delthi*exp(ebarrier*delta_beta);
   fix_event_list[ievent]->tlo = fix_event->tlo + deltlo;
 
   // first-replica output about each event
 
   if (universe->me == 0) {
-    char str[128];
+    char str[128],fstr[128];
     double tfrac = 0.0;
     if (ievent > 0) tfrac = delthi/deltstop;
 //     sprintf(str,
 // 	    "New event: ievent = %d eb = %g t_lo = %g t_hi = %g t_hi/t_stop = %g \n",
 // 	    ievent,ebarrier,deltlo,delthi,tfrac);
 //     error->warning(str);
 
+    sprintf(fstr,"New event: t_hi = %s ievent = %%d eb = %%g "
+	    "dt_lo = %%g dt_hi/t_stop = %%g \n",BIGINT_FORMAT);
+
     if (screen) 
-      fprintf(screen,
-	     "New event: t_hi = %d ievent = %d eb = %g dt_lo = %g dt_hi/t_stop = %g \n",
-	      fix_event_list[ievent]->event_timestep,
+      fprintf(screen,fstr,fix_event_list[ievent]->event_timestep,
 	      ievent,ebarrier,deltlo,tfrac);
     if (logfile) 
-      fprintf(logfile,
-	     "New event: t_hi = %d ievent = %d eb = %g dt_lo = %g dt_hi/t_stop = %g \n",
-	      fix_event_list[ievent]->event_timestep,
+      fprintf(logfile,fstr,fix_event_list[ievent]->event_timestep,
 	      ievent,ebarrier,deltlo,tfrac);
   }
 
   // update first event
 
   if (ievent == 0) {
     deltfirst = deltlo;
     event_first = ievent;
   } else if (deltlo < deltfirst) {
     deltfirst = deltlo;
     event_first = ievent;
   }
 
 }
 
 /* ----------------------------------------------------------------------
    perform event
 ------------------------------------------------------------------------- */
 
 void TAD::perform_event(int ievent)
 {
   // reset timestep to that of event
 
   update->ntimestep = fix_event_list[ievent]->event_timestep;
 
   // Copy event to current event
 
   fix_event->tlo = fix_event_list[ievent]->tlo;
   fix_event->event_number++;
   fix_event->event_timestep = update->ntimestep;
   fix_event_list[ievent]->restore_event();
   fix_event->store_event_tad(fix_event_list[ievent]->event_timestep);
 
   // output stats and dump for quenched state
 
   log_event();
 
   // load and store hot state
 
   fix_event_list[ievent]->restore_state();
   fix_event->store_state();
 }
 
 /* ----------------------------------------------------------------------
    Allocate list of pointers to events
 ------------------------------------------------------------------------- */
 
 void TAD::grow_event_list(int nmax) {
   if (nmax_event_list > nmax) return;
   fix_event_list = (FixEventTAD **) memory->srealloc(fix_event_list,nmax*sizeof(FixEventTAD *),"tad:eventlist");
   nmax_event_list = nmax;
 }
 
diff --git a/src/REPLICA/temper.cpp b/src/REPLICA/temper.cpp
index 592e012f3..17fcc41c7 100644
--- a/src/REPLICA/temper.cpp
+++ b/src/REPLICA/temper.cpp
@@ -1,357 +1,358 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Mark Sears (SNL)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "temper.h"
+#include "lmptype.h"
 #include "universe.h"
 #include "domain.h"
 #include "atom.h"
 #include "update.h"
 #include "integrate.h"
 #include "modify.h"
 #include "compute.h"
 #include "force.h"
 #include "output.h"
 #include "thermo.h"
 #include "fix.h"
 #include "random_park.h"
 #include "finish.h"
 #include "timer.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 // #define TEMPER_DEBUG 1
 
 /* ---------------------------------------------------------------------- */
 
 Temper::Temper(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 Temper::~Temper()
 {
   MPI_Comm_free(&roots);
   if (ranswap) delete ranswap;
   delete ranboltz;
   delete [] set_temp;
   delete [] temp2world;
   delete [] world2temp;
   delete [] world2root;
 }
 
 /* ----------------------------------------------------------------------
    perform tempering with inter-world swaps
 ------------------------------------------------------------------------- */
 
 void Temper::command(int narg, char **arg)
 {
   if (universe->nworlds == 1) 
     error->all("Must have more than one processor partition to temper");
   if (domain->box_exist == 0) 
     error->all("Temper command before simulation box is defined");
   if (narg != 6 && narg != 7) error->universe_all("Illegal temper command");
 
   int nsteps = atoi(arg[0]);
   nevery = atoi(arg[1]);
   double temp = atof(arg[2]);
 
   for (whichfix = 0; whichfix < modify->nfix; whichfix++)
     if (strcmp(arg[3],modify->fix[whichfix]->id) == 0) break;
   if (whichfix == modify->nfix) 
     error->universe_all("Tempering fix ID is not defined");
 
   seed_swap = atoi(arg[4]);
   seed_boltz = atoi(arg[5]);
 
   my_set_temp = universe->iworld;
   if (narg == 7) my_set_temp = atoi(arg[6]);
 
   // swap frequency must evenly divide total # of timesteps
 
   if (nevery == 0) error->universe_all("Invalid frequency in temper command");
   nswaps = nsteps/nevery;
   if (nswaps*nevery != nsteps) 
     error->universe_all("Non integer # of swaps in temper command");
 
   // fix style must be appropriate for temperature control
 
   if ((strcmp(modify->fix[whichfix]->style,"nvt") != 0) &&
       (strcmp(modify->fix[whichfix]->style,"langevin") != 0) &&
       (strcmp(modify->fix[whichfix]->style,"temp/berendsen") != 0) &&
       (strcmp(modify->fix[whichfix]->style,"temp/rescale") != 0))
     error->universe_all("Tempering temperature fix is not valid");
 
   // setup for long tempering run
 
   update->whichflag = 1;
   update->nsteps = nsteps;
   update->beginstep = update->firststep = update->ntimestep;
   update->endstep = update->laststep = update->firststep + nsteps;
 
   lmp->init();
 
   // local storage
 
   me_universe = universe->me;
   MPI_Comm_rank(world,&me);
   nworlds = universe->nworlds;
   iworld = universe->iworld;
   boltz = force->boltz;
 
   // pe_compute = ptr to thermo_pe compute
   // notify compute it will be called at first swap
 
   int id = modify->find_compute("thermo_pe");
   if (id < 0) error->all("Tempering could not find thermo_pe compute");
   Compute *pe_compute = modify->compute[id];
   pe_compute->addstep(update->ntimestep + nevery);
 
   // create MPI communicator for root proc from each world
 
   int color;
   if (me == 0) color = 0;
   else color = 1;
   MPI_Comm_split(universe->uworld,color,0,&roots);
 
   // RNGs for swaps and Boltzmann test
   // warm up Boltzmann RNG
 
   if (seed_swap) ranswap = new RanPark(lmp,seed_swap);
   else ranswap = NULL;
   ranboltz = new RanPark(lmp,seed_boltz + me_universe);
   for (int i = 0; i < 100; i++) ranboltz->uniform();
 
   // world2root[i] = global proc that is root proc of world i
 
   world2root = new int[nworlds];
   if (me == 0) 
     MPI_Allgather(&me_universe,1,MPI_INT,world2root,1,MPI_INT,roots);
   MPI_Bcast(world2root,nworlds,MPI_INT,0,world);
 
   // create static list of set temperatures
   // allgather tempering arg "temp" across root procs
   // bcast from each root to other procs in world
 
   set_temp = new double[nworlds];
   if (me == 0) MPI_Allgather(&temp,1,MPI_DOUBLE,set_temp,1,MPI_DOUBLE,roots);
   MPI_Bcast(set_temp,nworlds,MPI_DOUBLE,0,world);
 
   // create world2temp only on root procs from my_set_temp
   // create temp2world on root procs from world2temp,
   //   then bcast to all procs within world
 
   world2temp = new int[nworlds];
   temp2world = new int[nworlds];
   if (me == 0) {
     MPI_Allgather(&my_set_temp,1,MPI_INT,world2temp,1,MPI_INT,roots);
     for (int i = 0; i < nworlds; i++) temp2world[world2temp[i]] = i;
   }
   MPI_Bcast(temp2world,nworlds,MPI_INT,0,world);
 
   // if restarting tempering, reset temp target of Fix to current my_set_temp
 
   if (narg == 7) {
     double new_temp = set_temp[my_set_temp];
     modify->fix[whichfix]->reset_target(new_temp);
   }
 
   // setup tempering runs
 
   int i,which,partner,swap,partner_set_temp,partner_world;
   double pe,pe_partner,boltz_factor,new_temp;
   MPI_Status status;
 
   if (me_universe == 0 && universe->uscreen) 
     fprintf(universe->uscreen,"Setting up tempering ...\n");
 
   update->integrate->setup();
 
   if (me_universe == 0) {
     if (universe->uscreen) {
       fprintf(universe->uscreen,"Step");
       for (int i = 0; i < nworlds; i++)
 	fprintf(universe->uscreen," T%d",i);
       fprintf(universe->uscreen,"\n");
     }
     if (universe->ulogfile) {
       fprintf(universe->ulogfile,"Step");
       for (int i = 0; i < nworlds; i++)
 	fprintf(universe->ulogfile," T%d",i);
       fprintf(universe->ulogfile,"\n");
     }
     print_status();
   }
 
   timer->barrier_start(TIME_LOOP);
 
   for (int iswap = 0; iswap < nswaps; iswap++) {
 	
     // run for nevery timesteps
 
     update->integrate->run(nevery);
 	
     // compute PE
     // notify compute it will be called at next swap
 
     pe = pe_compute->compute_scalar();
     pe_compute->addstep(update->ntimestep + nevery);
 
     // which = which of 2 kinds of swaps to do (0,1)
 
     if (!ranswap) which = iswap % 2;
     else if (ranswap->uniform() < 0.5) which = 0;
     else which = 1;
 
     // partner_set_temp = which set temp I am partnering with for this swap
 
     if (which == 0) {
       if (my_set_temp % 2 == 0) partner_set_temp = my_set_temp + 1;
       else partner_set_temp = my_set_temp - 1;
     } else {
       if (my_set_temp % 2 == 1) partner_set_temp = my_set_temp + 1;
       else partner_set_temp = my_set_temp - 1;
     }
 
     // partner = proc ID to swap with
     // if partner = -1, then I am not a proc that swaps
 
     partner = -1;
     if (me == 0 && partner_set_temp >= 0 && partner_set_temp < nworlds) {
       partner_world = temp2world[partner_set_temp];
       partner = world2root[partner_world];
     }
 
     // swap with a partner, only root procs in each world participate
     // hi proc sends PE to low proc
     // lo proc make Boltzmann decision on whether to swap
     // lo proc communicates decision back to hi proc
 
     swap = 0;
     if (partner != -1) {
       if (me_universe > partner) 
 	MPI_Send(&pe,1,MPI_DOUBLE,partner,0,universe->uworld);
       else
 	MPI_Recv(&pe_partner,1,MPI_DOUBLE,partner,0,universe->uworld,&status);
 
       if (me_universe < partner) {
 	boltz_factor = (pe - pe_partner) * 
 	  (1.0/(boltz*set_temp[my_set_temp]) - 
 	   1.0/(boltz*set_temp[partner_set_temp]));
 	if (boltz_factor >= 0.0) swap = 1;
 	else if (ranboltz->uniform() < exp(boltz_factor)) swap = 1;
       }
 
       if (me_universe < partner) 
 	MPI_Send(&swap,1,MPI_INT,partner,0,universe->uworld);
       else
 	MPI_Recv(&swap,1,MPI_INT,partner,0,universe->uworld,&status);
 
 #ifdef TEMPER_DEBUG
       if (me_universe < partner)
 	printf("SWAP %d & %d: yes = %d,Ts = %d %d, PEs = %g %g, Bz = %g %g\n",
 	       me_universe,partner,swap,my_set_temp,partner_set_temp,
 	       pe,pe_partner,boltz_factor,exp(boltz_factor));
 #endif
 
     }
 
     // bcast swap result to other procs in my world
 
     MPI_Bcast(&swap,1,MPI_INT,0,world);
 
     // rescale kinetic energy via velocities if move is accepted
 
     if (swap) scale_velocities(partner_set_temp,my_set_temp);
 	
     // if my world swapped, all procs in world reset temp target of Fix
 
     if (swap) {
       new_temp = set_temp[partner_set_temp];
       modify->fix[whichfix]->reset_target(new_temp);
     }
 
     // update my_set_temp and temp2world on every proc
     // root procs update their value if swap took place
     // allgather across root procs
     // bcast within my world
 
     if (swap) my_set_temp = partner_set_temp;
     if (me == 0) {
       MPI_Allgather(&my_set_temp,1,MPI_INT,world2temp,1,MPI_INT,roots);
       for (i = 0; i < nworlds; i++) temp2world[world2temp[i]] = i;
     }
     MPI_Bcast(temp2world,nworlds,MPI_INT,0,world);
 
     // print out current swap status
 
     if (me_universe == 0) print_status();
   }
 
   timer->barrier_stop(TIME_LOOP);
 
   update->integrate->cleanup();
 
   Finish finish(lmp);
   finish.end(1);
 
   update->whichflag = 0;
   update->firststep = update->laststep = 0;
   update->beginstep = update->endstep = 0;
 }
 
 /* ----------------------------------------------------------------------
    scale kinetic energy via velocities a la Sugita
 ------------------------------------------------------------------------- */
 
 void Temper::scale_velocities(int t_partner, int t_me)
 {
   double sfactor = sqrt(set_temp[t_partner]/set_temp[t_me]);
 
   double **v = atom->v;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
     v[i][0] = v[i][0]*sfactor;
     v[i][1] = v[i][1]*sfactor;
     v[i][2] = v[i][2]*sfactor;
   }
 }
 
 /* ----------------------------------------------------------------------
    proc 0 prints current tempering status
 ------------------------------------------------------------------------- */
 
 void Temper::print_status()
 {
   if (universe->uscreen) {
-    fprintf(universe->uscreen,"%d ",update->ntimestep);
+    fprintf(universe->uscreen,BIGINT_FORMAT,update->ntimestep);
     for (int i = 0; i < nworlds; i++) 
-      fprintf(universe->uscreen,"%d ",world2temp[i]);
+      fprintf(universe->uscreen," %d",world2temp[i]);
     fprintf(universe->uscreen,"\n");
   }
   if (universe->ulogfile) {
-    fprintf(universe->ulogfile,"%d ",update->ntimestep);
+    fprintf(universe->ulogfile,BIGINT_FORMAT,update->ntimestep);
     for (int i = 0; i < nworlds; i++)
-      fprintf(universe->ulogfile,"%d ",world2temp[i]);
+      fprintf(universe->ulogfile," %d",world2temp[i]);
     fprintf(universe->ulogfile,"\n");
     fflush(universe->ulogfile);
   }
 }
diff --git a/src/SRD/fix_srd.cpp b/src/SRD/fix_srd.cpp
index a59d10599..71ce7698e 100644
--- a/src/SRD/fix_srd.cpp
+++ b/src/SRD/fix_srd.cpp
@@ -1,3534 +1,3528 @@
 /* ----------------------------------------------------------------------
    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: Jeremy Lechman (SNL), Pieter in 't Veld (BASF)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "string.h"
 #include "stdlib.h"
 #include "fix_srd.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "group.h"
 #include "update.h"
 #include "force.h"
 #include "pair.h"
 #include "domain.h"
 #include "neighbor.h"
 #include "comm.h"
 #include "modify.h"
 #include "fix_deform.h"
 #include "fix_wall_srd.h"
 #include "random_mars.h"
 #include "random_park.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{SLIP,NOSLIP};
 enum{SPHERE,ELLIPSOID,WALL};
 enum{SPHERE_SHAPE,SPHERE_RADIUS};
 enum{ANGULAR_OMEGA,ANGULAR_ANGMOM};
 enum{INSIDE_ERROR,INSIDE_WARN,INSIDE_IGNORE};
 enum{BIG_MOVE,SRD_MOVE,SRD_ROTATE};
 enum{CUBIC_ERROR,CUBIC_WARN};
 enum{SHIFT_NO,SHIFT_YES,SHIFT_POSSIBLE};
 
 enum{NO_REMAP,X_REMAP,V_REMAP};                   // same as fix_deform.cpp
 
 #define INERTIA 0.4
 #define ATOMPERBIN 10
 #define BIG 1.0e20
 #define VBINSIZE 5
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 //#define SRD_DEBUG 1
 //#define SRD_DEBUG_ATOMID 58
 //#define SRD_DEBUG_TIMESTEP 449
 
 /* ---------------------------------------------------------------------- */
 
 FixSRD::FixSRD(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
 {
   if (narg < 8) error->all("Illegal fix srd command");
 
   restart_pbc = 1;
   vector_flag = 1;
   size_vector = 12;
   global_freq = 1;
   extvector = 0;
 
   nevery = atoi(arg[3]);
 
   bigexist = 1;
   if (strcmp(arg[4],"NULL") == 0) bigexist = 0;
   else biggroup = group->find(arg[4]);
 
   temperature_srd = atof(arg[5]);
   gridsrd = atof(arg[6]);
   int seed = atoi(arg[7]);
 
   // parse options
 
   lamdaflag = 0;
   collidestyle = NOSLIP;
   overlap = 0;
   insideflag = INSIDE_ERROR;
   exactflag = 1;
   radfactor = 1.0;
   maxbounceallow = 0;
   gridsearch = gridsrd;
   cubicflag = CUBIC_ERROR;
   cubictol = 0.01;
   shiftuser = SHIFT_NO;
   shiftseed = 0;
   streamflag = 1;
 
   int iarg = 8;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"lamda") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix srd command");
       lamda = atof(arg[iarg+1]);
       lamdaflag = 1;
       iarg += 2;
     } else if (strcmp(arg[iarg],"collision") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix srd command");
       if (strcmp(arg[iarg+1],"slip") == 0) collidestyle = SLIP;
       else if (strcmp(arg[iarg+1],"noslip") == 0) collidestyle = NOSLIP;
       else error->all("Illegal fix srd command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"overlap") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix srd command");
       if (strcmp(arg[iarg+1],"yes") == 0) overlap = 1;
       else if (strcmp(arg[iarg+1],"no") == 0) overlap = 0;
       else error->all("Illegal fix srd command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"inside") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix srd command");
       if (strcmp(arg[iarg+1],"error") == 0) insideflag = INSIDE_ERROR;
       else if (strcmp(arg[iarg+1],"warn") == 0) insideflag = INSIDE_WARN;
       else if (strcmp(arg[iarg+1],"ignore") == 0) insideflag = INSIDE_IGNORE;
       else error->all("Illegal fix srd command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"exact") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix srd command");
       if (strcmp(arg[iarg+1],"yes") == 0) exactflag = 1;
       else if (strcmp(arg[iarg+1],"no") == 0) exactflag = 0;
       else error->all("Illegal fix srd command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"radius") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix srd command");
       radfactor = atof(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"bounce") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix srd command");
       maxbounceallow = atoi(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"search") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix srd command");
       gridsearch = atof(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"cubic") == 0) {
       if (iarg+3 > narg) error->all("Illegal fix srd command");
       if (strcmp(arg[iarg+1],"error") == 0) cubicflag = CUBIC_ERROR;
       else if (strcmp(arg[iarg+1],"warn") == 0) cubicflag = CUBIC_WARN;
       else error->all("Illegal fix srd command");
       cubictol = atof(arg[iarg+2]);
       iarg += 3;
     } else if (strcmp(arg[iarg],"shift") == 0) {
       if (iarg+3 > narg) error->all("Illegal fix srd command");
       else if (strcmp(arg[iarg+1],"no") == 0) shiftuser = SHIFT_NO;
       else if (strcmp(arg[iarg+1],"yes") == 0) shiftuser = SHIFT_YES;
       else if (strcmp(arg[iarg+1],"possible") == 0) shiftuser = SHIFT_POSSIBLE;
       else error->all("Illegal fix srd command");
       shiftseed = atoi(arg[iarg+2]);
       iarg += 3;
     } else if (strcmp(arg[iarg],"stream") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix srd command");
       if (strcmp(arg[iarg+1],"yes") == 0) streamflag = 1;
       else if (strcmp(arg[iarg+1],"no") == 0) streamflag = 0;
       else error->all("Illegal fix srd command");
       iarg += 2;
     } else error->all("Illegal fix srd command");
   }
 
   // error check
 
   if (nevery <= 0) error->all("Illegal fix srd command");
   if (bigexist && biggroup < 0) error->all("Could not find fix srd group ID");
   if (gridsrd <= 0.0) error->all("Illegal fix srd command");
   if (temperature_srd <= 0.0) error->all("Illegal fix srd command");
   if (seed <= 0) error->all("Illegal fix srd command");
   if (radfactor <= 0.0) error->all("Illegal fix srd command");
   if (maxbounceallow < 0) error->all("Illegal fix srd command");
   if (lamdaflag && lamda <= 0.0) error->all("Illegal fix srd command");
   if (gridsearch <= 0.0) error->all("Illegal fix srd command");
   if (cubictol < 0.0 || cubictol > 1.0) error->all("Illegal fix srd command");
   if ((shiftuser == SHIFT_YES || shiftuser == SHIFT_POSSIBLE) && 
       shiftseed <= 0) error->all("Illegal fix srd command");
 
   // initialize Marsaglia RNG with processor-unique seed
 
   me = comm->me;
   nprocs = comm->nprocs;
 
   random = new RanMars(lmp,seed + me);
 
   // if requested, initialize shift RNG, same on every proc
 
   if (shiftuser == SHIFT_YES || shiftuser == SHIFT_POSSIBLE)
     randomshift = new RanPark(lmp,shiftseed);
   else randomshift = NULL;
 
   // initialize data structs and flags
 
   if (bigexist) biggroupbit = group->bitmask[biggroup];
   else biggroupbit = 0;
 
   nmax = 0;
   binhead = NULL;
   maxbin1 = 0;
   binnext = NULL;
   maxbuf = 0;
   sbuf1 = sbuf2 = rbuf1 = rbuf2 = NULL;
 
   shifts[0].maxvbin = shifts[1].maxvbin = 0;
   shifts[0].vbin = shifts[1].vbin = NULL;
 
   shifts[0].maxbinsq = shifts[1].maxbinsq = 0;
   for (int ishift = 0; ishift < 2; ishift++)
     for (int iswap = 0; iswap < 6; iswap++)
       shifts[ishift].bcomm[iswap].sendlist = 
 	shifts[ishift].bcomm[iswap].recvlist = NULL;
 
   maxbin2 = 0;
   nbinbig = NULL;
   binbig = NULL;
   binsrd = NULL;
 
   nstencil = maxstencil = 0;
   stencil = NULL;
 
   maxbig = 0;
   biglist = NULL;
 
   stats_flag = 1;
   for (int i = 0; i < size_vector; i++) stats_all[i] = 0.0;
 
   initflag = 0;
 
   srd_bin_temp = 0.0;
   srd_bin_count = 0;
 
   // fix parameters
 
   if (collidestyle == SLIP) comm_reverse = 3;
   else comm_reverse = 6;
   force_reneighbor = 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixSRD::~FixSRD()
 {
   delete random;
   delete randomshift;
 
   memory->sfree(binhead);
   memory->sfree(binnext);
   memory->sfree(sbuf1);
   memory->sfree(sbuf2);
   memory->sfree(rbuf1);
   memory->sfree(rbuf2);
 
   memory->sfree(shifts[0].vbin);
   memory->sfree(shifts[1].vbin);
   for (int ishift = 0; ishift < 2; ishift++)
     for (int iswap = 0; iswap < 6; iswap++) {
       memory->sfree(shifts[ishift].bcomm[iswap].sendlist);
       memory->sfree(shifts[ishift].bcomm[iswap].recvlist);
     }
 
   memory->sfree(nbinbig);
   memory->destroy_2d_int_array(binbig);
   memory->sfree(binsrd);
   memory->destroy_2d_int_array(stencil);
   memory->sfree(biglist);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixSRD::setmask()
 {
   int mask = 0;
   mask |= PRE_NEIGHBOR;
   mask |= POST_FORCE;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixSRD::init()
 {
   // error checks
 
   if (force->newton_pair == 0) error->all("Fix srd requires newton pair on");
   if (bigexist && comm->ghost_velocity == 0)
     error->all("Fix srd requires ghost atoms store velocity");
 
   if (bigexist && !atom->radius_flag && !atom->avec->shape_type)
     error->all("Fix SRD requires atom attribute radius or shape");
   if (bigexist && !atom->angmom_flag && !atom->omega_flag)
     error->all("Fix SRD requires atom attribute angmom or omega");
   if (bigexist && atom->angmom_flag && atom->omega_flag)
     error->all("Fix SRD cannot have both atom attributes angmom and omega");
   if (bigexist && collidestyle == NOSLIP && !atom->torque_flag)
     error->all("Fix SRD no-slip requires atom attribute torque");
 
   if (initflag && update->dt != dt_big)
     error->all("Cannot change timestep once fix srd is setup");
 
   // orthogonal vs triclinic simulation box
   // could be static or shearing box
 
   triclinic = domain->triclinic;
 
   // wallexist = 1 if SRD wall(s) are defined
 
   wallexist = 0;
   for (int m = 0; m < modify->nfix; m++) {
     if (strcmp(modify->fix[m]->style,"wall/srd") == 0) {
       if (wallexist) error->all("Cannot use fix wall/srd more than once");
       wallexist = 1;
       wallfix = (FixWallSRD *) modify->fix[m];
       nwall = wallfix->nwall;
       wallvarflag = wallfix->varflag;
       wallwhich = wallfix->wallwhich;
       xwall = wallfix->xwall;
       xwallhold = wallfix->xwallhold;
       vwall = wallfix->vwall;
       fwall = wallfix->fwall;
       walltrigger = 0.5 * neighbor->skin;
       if (wallfix->overlap && overlap == 0 && me == 0)
 	error->warning("Fix SRD walls overlap but fix srd overlap not set");
     }
   }
 
   // set change_flags if box size or shape changes
 
   change_size = change_shape = 0;
   if (domain->nonperiodic == 2) change_size = 1;
   for (int i = 0; i < modify->nfix; i++)
     if (modify->fix[i]->box_change) {
       if (modify->fix[i]->box_change_size) change_size = 1;
       if (modify->fix[i]->box_change_shape) change_shape = 1;
       if (strcmp(modify->fix[i]->style,"deform") == 0) {
 	FixDeform *deform = (FixDeform *) modify->fix[i];
 	if (deform->box_change_shape && deform->remapflag != V_REMAP)
 	  error->all("Using fix srd with inconsistent "
 		     "fix deform remap option");
       }
     }
 
   // parameterize based on current box volume
 
   dimension = domain->dimension;
   parameterize();
 
   // limit initial SRD velocities if necessary
 
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   double vsq;
   nrescale = 0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       vsq = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2];
       if (vsq > vmaxsq) nrescale++;
     }
 
   int all;
   MPI_Allreduce(&nrescale,&all,1,MPI_INT,MPI_SUM,world);
   if (me == 0) {
     if (screen)
       fprintf(screen,"  # of rescaled SRD velocities = %d\n",all);
     if (logfile)
       fprintf(logfile,"  # of rescaled SRD velocities = %d\n",all);
   }
 
   velocity_stats(igroup);
   if (bigexist) velocity_stats(biggroup);
 
   // zero per-run stats
 
   bouncemaxnum = 0;
   bouncemax = 0;
   reneighcount = 0;
   initflag = 1;
 
   next_reneighbor = -1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixSRD::setup(int vflag)
 {
   setup_bounds();
 
   if (dist_srd_reneigh < nevery*dt_big*vmax && me == 0)
     error->warning("Fix srd SRD moves may trigger frequent reneighboring");
 
   // setup search bins and search stencil based on these distances
 
   if (bigexist || wallexist) {
     setup_search_bins();
     setup_search_stencil();
   } else nbins2 = 0;
 
   // perform first bining of SRD and big particles and walls
   // set reneighflag to turn off SRD rotation
   // don't do SRD rotation in setup, only during timestepping
 
   reneighflag = BIG_MOVE;
   pre_neighbor();
 }
 /* ----------------------------------------------------------------------
    assign SRD particles to bins
    assign big particles to all bins they overlap
 ------------------------------------------------------------------------- */
 
 void FixSRD::pre_neighbor()
 {
   int i,j,m,ix,iy,iz,jx,jy,jz,ibin,jbin,lo,hi;
   double rsq,cutbinsq;
   double xlamda[3];
 
   // grow SRD per-atom bin arrays if necessary
 
   if (atom->nlocal > nmax) {
     nmax = atom->nmax;
     memory->sfree(binsrd);
     memory->sfree(binnext);
     binsrd = (int *) memory->smalloc(nmax*sizeof(int),"fix/srd:binsrd");
     binnext = (int *) memory->smalloc(nmax*sizeof(int),"fix/srd:binnext");
   }
 
   // setup and grow BIG info list if necessary
   // set index ptrs to BIG particles and to WALLS
   // big_static() adds static properties to info list
 
   if (bigexist || wallexist) {
     if (bigexist) {
       if (biggroup == atom->firstgroup) nbig = atom->nfirst + atom->nghost;
       else {
 	int *mask = atom->mask;
 	int nlocal = atom->nlocal;
 	nbig = atom->nghost;
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & biggroupbit) nbig++;
       }
     } else nbig = 0;
 
     int ninfo = nbig;
     if (wallexist) ninfo += nwall;
 
     if (ninfo > maxbig) {
       maxbig = ninfo;
       memory->sfree(biglist);
       biglist = (Big *) memory->smalloc(maxbig*sizeof(Big),"fix/srd:biglist");
     }
 
     if (bigexist) {
       int *mask = atom->mask;
       int nlocal = atom->nlocal;
       if (biggroup == atom->firstgroup) nlocal = atom->nfirst;
       nbig = 0;
       for (i = 0; i < nlocal; i++)
 	if (mask[i] & biggroupbit) biglist[nbig++].index = i;
       int nall = atom->nlocal + atom->nghost;
       for (i = atom->nlocal; i < nall; i++)
 	if (mask[i] & biggroupbit) biglist[nbig++].index = i;
       big_static();
     }
 
     if (wallexist) {
       for (m = 0; m < nwall; m++) {
 	biglist[nbig+m].index = m;
 	biglist[nbig+m].type = WALL;
       }
       wallfix->wall_params(1);
     }
   }
 
   // if simulation box size changes, reset velocity bins
   // if big particles exist, reset search bins if box size or shape changes,
   //   b/c finite-size particles will overlap different bins as the box tilts
 
   if (change_size) setup_bounds();
   if (change_size) setup_velocity_bins();
   if ((change_size || change_shape) && (bigexist || wallexist)) {
     setup_search_bins();
     setup_search_stencil();
   }
 
   // map each owned & ghost big particle to search bins it overlaps
   // zero out bin counters for big particles
   // if firstgroup is defined, only loop over first and ghost particles
   // for each big particle: loop over stencil to find overlap bins
 
   int *mask = atom->mask;
   double **x = atom->x;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   int nfirst = nlocal;
   if (bigexist && biggroup == atom->firstgroup) nfirst = atom->nfirst;
 
   if (bigexist || wallexist)
     for (i = 0; i < nbins2; i++)
       nbinbig[i] = 0;
 
   if (bigexist) {
     i = nbig = 0;
     while (i < nall) {
       if (mask[i] & biggroupbit) {
 	ix = static_cast<int> ((x[i][0]-xblo2)*bininv2x);
 	iy = static_cast<int> ((x[i][1]-yblo2)*bininv2y);
 	iz = static_cast<int> ((x[i][2]-zblo2)*bininv2z);
 	ibin = iz*nbin2y*nbin2x + iy*nbin2x + ix;
 
 	if (ix < 0 || ix >= nbin2x || iy < 0 || iy >= nbin2y || 
 	    iz < 0 || iz >= nbin2z)
 	  error->one("Fix SRD: bad search bin assignment");
       
 	cutbinsq = biglist[nbig].cutbinsq;
 	for (j = 0; j < nstencil; j++) {
 	  jx = ix + stencil[j][0];
 	  jy = iy + stencil[j][1];
 	  jz = iz + stencil[j][2];
 	  
 	  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);
 	    error->one("Fix SRD: bad stencil bin for big particle");
 	  }
 	  rsq = point_bin_distance(x[i],jx,jy,jz);
 	  if (rsq < cutbinsq) {
 	    jbin = ibin + stencil[j][3];
 	    if (nbinbig[jbin] == ATOMPERBIN)
 	      error->one("Fix SRD: too many big particles in bin");
 	    binbig[jbin][nbinbig[jbin]++] = nbig;
 	  }
 	}
 	nbig++;
       }
 
       i++;
       if (i == nfirst) i = nlocal;
     }
   }
 
   // map each wall to search bins it covers, up to non-periodic boundary
   // if wall moves, add walltrigger to its position
   // this insures it is added to all search bins it may move into
   // may not overlap any of my search bins
 
   if (wallexist) {
     double delta = 0.0;
     if (wallvarflag) delta = walltrigger;
 
     for (m = 0; m < nwall; m++) {
       int dim = wallwhich[m] / 2;
       int side = wallwhich[m] % 2;
 
       if (dim == 0) {
 	if (side == 0) {
 	  hi = static_cast<int> ((xwall[m]+delta-xblo2)*bininv2x);
 	  if (hi < 0) continue;
 	  if (hi >= nbin2x) error->all("Fix SRD: bad search bin assignment");
 	  lo = 0;
 	} else {
 	  lo = static_cast<int> ((xwall[m]-delta-xblo2)*bininv2x);
 	  if (lo >= nbin2x) continue;
 	  if (lo < 0) error->all("Fix SRD: bad search bin assignment");
 	  hi = nbin2x-1;
 	}
 
 	for (ix = lo; ix <= hi; ix++)
 	  for (iy = 0; iy < nbin2y; iy++)
 	    for (iz = 0; iz < nbin2z; iz++) {
 	      ibin = iz*nbin2y*nbin2x + iy*nbin2x + ix;
 	      if (nbinbig[ibin] == ATOMPERBIN)
 		error->all("Fix SRD: too many walls in bin");
 	      binbig[ibin][nbinbig[ibin]++] = nbig+m;
 	    }
 
       } else if (dim == 1) {
 	if (side == 0) {
 	  hi = static_cast<int> ((xwall[m]+delta-yblo2)*bininv2y);
 	  if (hi < 0) continue;
 	  if (hi >= nbin2y) error->all("Fix SRD: bad search bin assignment");
 	  lo = 0;
 	} else {
 	  lo = static_cast<int> ((xwall[m]-delta-yblo2)*bininv2y);
 	  if (lo >= nbin2y) continue;
 	  if (lo < 0) error->all("Fix SRD: bad search bin assignment");
 	  hi = nbin2y-1;
 	}
 
 	for (iy = lo; iy <= hi; iy++)
 	  for (ix = 0; ix < nbin2x; ix++)
 	    for (iz = 0; iz < nbin2z; iz++) {
 	      ibin = iz*nbin2y*nbin2x + iy*nbin2x + ix;
 	      if (nbinbig[ibin] == ATOMPERBIN)
 		error->all("Fix SRD: too many walls in bin");
 	      binbig[ibin][nbinbig[ibin]++] = nbig+m;
 	    }
 
       } else if (dim == 2) {
 	if (side == 0) {
 	  hi = static_cast<int> ((xwall[m]+delta-zblo2)*bininv2z);
 	  if (hi < 0) continue;
 	  if (hi >= nbin2z) error->all("Fix SRD: bad search bin assignment");
 	  lo = 0;
 	} else {
 	  lo = static_cast<int> ((xwall[m]-delta-zblo2)*bininv2z);
 	  if (lo >= nbin2z) continue;
 	  if (lo < 0) error->all("Fix SRD: bad search bin assignment");
 	  hi = nbin2z-1;
 	}
 
 	for (iz = lo; iz < hi; iz++)
 	  for (ix = 0; ix < nbin2x; ix++)
 	    for (iy = 0; iy < nbin2y; iy++) {
 	      ibin = iz*nbin2y*nbin2x + iy*nbin2x + ix;
 	      if (nbinbig[ibin] == ATOMPERBIN)
 		error->all("Fix SRD: too many walls in bin");
 	      binbig[ibin][nbinbig[ibin]++] = nbig+m;
 	    }
       }
     }
   }
 
   // rotate SRD velocities on SRD timestep
   // done now since all SRDs are currently inside my sub-domain
 
   if (reneighflag == SRD_ROTATE) reset_velocities();
 
   // log stats if reneighboring occurred b/c SRDs moved too far
 
   if (reneighflag == SRD_MOVE) reneighcount++;
   reneighflag = BIG_MOVE;
 }
 
 /* ----------------------------------------------------------------------
    advect SRD particles and detect collisions between SRD and BIG particles
    when collision occurs, change x,v of SRD, force,torque of BIG particle
 ------------------------------------------------------------------------- */
 
 void FixSRD::post_force(int vflag)
 {
   int i,m,ix,iy,iz;
   double xlamda[3];
 
   // zero per-timestep stats
 
   stats_flag = 0;
   ncheck = ncollide = nbounce = ninside = nrescale = 0;
 
   // zero ghost forces & torques on BIG particles
 
   double **f = atom->f;
   double **torque = atom->torque;
   int nlocal = atom->nlocal;
   int nall = nlocal + atom->nghost;
   if (bigexist == 0) nall = 0;
 
   for (i = nlocal; i < nall; i++)
     f[i][0] = f[i][1] = f[i][2] = 0.0;
 
   if (collidestyle == NOSLIP)
     for (i = nlocal; i < nall; i++)
       torque[i][0] = torque[i][1] = torque[i][2] = 0.0;
 
   // advect SRD particles
   // assign to search bins if big particles or walls exist
 
   int *mask = atom->mask;
   double **x = atom->x;
   double **v = atom->v;
 
   if (bigexist || wallexist) {
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	x[i][0] += dt_big*v[i][0];
 	x[i][1] += dt_big*v[i][1];
 	x[i][2] += dt_big*v[i][2];
 	
 	ix = static_cast<int> ((x[i][0]-xblo2)*bininv2x);
 	iy = static_cast<int> ((x[i][1]-yblo2)*bininv2y);
 	iz = static_cast<int> ((x[i][2]-zblo2)*bininv2z);
 	binsrd[i] = iz*nbin2y*nbin2x + iy*nbin2x + ix;
 	
 	if (ix < 0 || ix >= nbin2x || iy < 0 || iy >= nbin2y || 
 	    iz < 0 || iz >= nbin2z) {
-	  printf("SRD particle %d on step %d\n",
-		 atom->tag[i],update->ntimestep);
+	  char fstr[64];
+	  sprintf(fstr,"SRD particle %%d on step %s\n",BIGINT_FORMAT);
+	  printf(fstr,atom->tag[i],update->ntimestep);
 	  printf("v = %g %g %g\n",v[i][0],v[i][1],v[i][2]);
 	  printf("x = %g %g %g\n",x[i][0],x[i][1],x[i][2]);
 	  printf("ix,iy,iz nx,ny,nz = %d %d %d %d %d %d\n",
 		 ix,iy,iz,nbin2x,nbin2y,nbin2z);
 	  error->one("Fix SRD: bad bin assignment for SRD advection");
 	}
       }
 
   } else {
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	x[i][0] += dt_big*v[i][0];
 	x[i][1] += dt_big*v[i][1];
 	x[i][2] += dt_big*v[i][2];
       }
   }
 
   // detect collision of SRDs with BIG particles or walls
 
   if (bigexist || wallexist) {
     if (bigexist && (collidestyle == NOSLIP || any_ellipsoids)) big_dynamic();
     if (wallexist) wallfix->wall_params(0);
     if (overlap) collisions_multi();
     else collisions_single();
   }
 
   // reverse communicate forces & torques on BIG particles
 
   if (bigexist) {
     flocal = f;
     tlocal = torque;
     comm->reverse_comm_fix(this);
   }
 
   // if any SRD particle has moved too far, trigger reneigh on next step
   // for triclinic, perform check in lamda units
 
   int flag = 0;
 
   if (triclinic) domain->x2lamda(nlocal);
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       if (x[i][0] < srdlo_reneigh[0] || x[i][0] > srdhi_reneigh[0] ||
 	  x[i][1] < srdlo_reneigh[1] || x[i][1] > srdhi_reneigh[1] ||
 	  x[i][2] < srdlo_reneigh[2] || x[i][2] > srdhi_reneigh[2]) flag = 1;
     }
   if (triclinic) domain->lamda2x(nlocal);
 
   int flagall;
   MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
   if (flagall) {
     next_reneighbor = update->ntimestep + 1;
     reneighflag = SRD_MOVE;
   }
 
   // if wall has moved too far, trigger reneigh on next step
   // analagous to neighbor check for big particle moving 1/2 of skin distance
 
   if (wallexist) {
     for (m = 0; m < nwall; m++)
       if (fabs(xwall[m]-xwallhold[m]) > walltrigger)
 	next_reneighbor = update->ntimestep + 1;
   }
 
   // if next timestep is SRD timestep, trigger reneigh
 
   if ((update->ntimestep+1) % nevery == 0) {
     next_reneighbor = update->ntimestep + 1;
     reneighflag = SRD_ROTATE;
   }
 }
 
 /* ----------------------------------------------------------------------
    reset SRD velocities
    may perform random shifting by 1/2 bin in each dimension
    called at pre-neighbor stage when all SRDs are now inside my sub-domain
    for triclinic, will set mean velocity to box deformation velocity
 ------------------------------------------------------------------------- */
 
 void FixSRD::reset_velocities()
 {
   int i,j,n,ix,iy,iz,ibin,axis,sign,irandom;
   double u[3],vave[3];
   double vx,vy,vz,vsq;
   double *vold,*vnew,*xlamda;
   double vstream[3];
 
   // if requested, perform a dynamic shift
 
   if (shiftflag) {
     double *boxlo;
     if (triclinic == 0) boxlo = domain->boxlo;
     else boxlo = domain->boxlo_lamda;
     shifts[1].corner[0] = boxlo[0] - binsize1x*randomshift->uniform();
     shifts[1].corner[1] = boxlo[1] - binsize1y*randomshift->uniform();
     if (dimension == 3)
       shifts[1].corner[2] = boxlo[2] - binsize1z*randomshift->uniform();
     else shifts[1].corner[2] = boxlo[2];
     setup_velocity_shift(1,1);
   }
 
   double *corner = shifts[shiftflag].corner;
   int *binlo = shifts[shiftflag].binlo;
   int *binhi = shifts[shiftflag].binhi;
   int nbins = shifts[shiftflag].nbins;
   int nbinx = shifts[shiftflag].nbinx;
   int nbiny = shifts[shiftflag].nbiny;
   BinAve *vbin = shifts[shiftflag].vbin;
 
   // binhead = 1st SRD particle in each bin
   // binnext = index of next particle in bin
   // bin assignment is done in lamda units for triclinic
 
   int *mask = atom->mask;
   double **x = atom->x;
   double **v = atom->v;
   int nlocal = atom->nlocal;
 
   if (triclinic) domain->x2lamda(nlocal);
 
   for (i = 0; i < nbins; i++) binhead[i] = -1;
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       ix = static_cast<int> ((x[i][0]-corner[0])*bininv1x);
       ix = MAX(ix,binlo[0]);
       ix = MIN(ix,binhi[0]);
       iy = static_cast<int> ((x[i][1]-corner[1])*bininv1y);
       iy = MAX(iy,binlo[1]);
       iy = MIN(iy,binhi[1]);
       iz = static_cast<int> ((x[i][2]-corner[2])*bininv1z);
       iz = MAX(iz,binlo[2]);
       iz = MIN(iz,binhi[2]);
 
       ibin = (iz-binlo[2])*nbiny*nbinx + (iy-binlo[1])*nbinx + (ix-binlo[0]);
       binnext[i] = binhead[ibin];
       binhead[ibin] = i;
     }
 
   if (triclinic) domain->lamda2x(nlocal);
 
   if (triclinic && streamflag) {
     double *h_rate = domain->h_rate;
     double *h_ratelo = domain->h_ratelo;
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	xlamda = x[i];
 	v[i][0] -= h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] + 
 	  h_rate[4]*xlamda[2] + h_ratelo[0];
 	v[i][1] -= h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1];
 	v[i][2] -= h_rate[2]*xlamda[2] + h_ratelo[2];
       }
   }
 
   // for each bin I have particles contributing to:
   // compute ave v and v^2 of particles in that bin
   // if I own the bin, set its random value, else set to 0.0
 
   for (i = 0; i < nbins; i++) {
     n = 0;
     vave[0] = vave[1] = vave[2] = 0.0;
     for (j = binhead[i]; j >= 0; j = binnext[j]) {
       vx = v[j][0];
       vy = v[j][1];
       vz = v[j][2];
       vave[0] += vx;
       vave[1] += vy;
       vave[2] += vz;
       n++;
     }
 
     vbin[i].vave[0] = vave[0];
     vbin[i].vave[1] = vave[1];
     vbin[i].vave[2] = vave[2];
     vbin[i].n = n;
     if (vbin[i].owner) vbin[i].random = random->uniform();
     else vbin[i].random = 0.0;
   }
 
   // communicate bin info for bins which more than 1 proc contribute to
 
   if (shifts[shiftflag].commflag) vbin_comm(shiftflag);
 
   // for each bin I have particles contributing to:
   // reassign particle velocity by rotation around a random axis
   // accumulate T_srd for each bin I own
   // for triclinic, replace mean velocity with stream velocity
 
   srd_bin_temp = 0.0;
   srd_bin_count = 0;
 
   if (dimension == 2) axis = 2;
 
   for (i = 0; i < nbins; i++) {
     n = vbin[i].n;
     if (n == 0) continue;
     vold = vbin[i].vave;
     vold[0] /= n;
     vold[1] /= n;
     vold[2] /= n;
 
     // if (triclinic && streamflag) {
     // xlamda = vbin[i].xctr;
     // vstream[0] = h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] + 
     //	h_rate[4]*xlamda[2] + h_ratelo[0];
     // vstream[1] = h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1];
     //  vstream[2] = h_rate[2]*xlamda[2] + h_ratelo[2];
     // vnew = vstream;
     //} else vnew = vold;
 
     vnew = vold;
 
     irandom = static_cast<int> (6.0*vbin[i].random);
     sign = irandom % 2;
     if (dimension == 3) axis = irandom / 2;
 
     vsq = 0.0;
     for (j = binhead[i]; j >= 0; j = binnext[j]) {
       if (axis == 0) {
 	u[0] = v[j][0]-vold[0];
 	u[1] = sign ? v[j][2]-vold[2] : vold[2]-v[j][2];
 	u[2] = sign ? vold[1]-v[j][1] : v[j][1]-vold[1];
       } else if (axis == 1) {
 	u[1] = v[j][1]-vold[1];
 	u[0] = sign ? v[j][2]-vold[2] : vold[2]-v[j][2];
 	u[2] = sign ? vold[0]-v[j][0] : v[j][0]-vold[0];
       } else {
 	u[2] = v[j][2]-vold[2];
 	u[1] = sign ? v[j][0]-vold[0] : vold[0]-v[j][0];
 	u[0] = sign ? vold[1]-v[j][1] : v[j][1]-vold[1];
       }
       vsq += u[0]*u[0] + u[1]*u[1] + u[2]*u[2];
       v[j][0] = u[0] + vnew[0];
       v[j][1] = u[1] + vnew[1];
       v[j][2] = u[2] + vnew[2];
     }
 
     // sum partial contribution of my particles to T even if I don't own bin
     // but only count bin if I own it, so that bin is counted exactly once
 
     if (n > 1) {
       srd_bin_temp += vsq / (n-1);
       if (vbin[i].owner) srd_bin_count++;
     }
   }
 
   srd_bin_temp *= force->mvv2e * mass_srd / (dimension * force->boltz);
 
   if (triclinic && streamflag) {
     double *h_rate = domain->h_rate;
     double *h_ratelo = domain->h_ratelo;
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	xlamda = x[i];
 	v[i][0] += h_rate[0]*xlamda[0] + h_rate[5]*xlamda[1] + 
 	  h_rate[4]*xlamda[2] + h_ratelo[0];
 	v[i][1] += h_rate[1]*xlamda[1] + h_rate[3]*xlamda[2] + h_ratelo[1];
 	v[i][2] += h_rate[2]*xlamda[2] + h_ratelo[2];
       }
   }
 
   // rescale any too-large velocities 
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       vsq = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2];
       if (vsq > vmaxsq) nrescale++;
     }
 }
 
 /* ----------------------------------------------------------------------
    communicate summed particle info for bins that overlap 1 or more procs
 ------------------------------------------------------------------------- */
 
 void FixSRD::vbin_comm(int ishift)
 {
   BinComm *bcomm1,*bcomm2;
   MPI_Request request1,request2;
   MPI_Status status;
   
   // send/recv bins in both directions in each dimension
   // don't send if nsend = 0
   //   due to static bins aliging with proc boundary
   //   due to dynamic bins across non-periodic global boundary
   // copy to self if sendproc = me
   // MPI send to another proc if sendproc != me
   // don't recv if nrecv = 0
   // copy from self if recvproc = me
   // MPI recv from another proc if recvproc != me
   
   BinAve *vbin = shifts[ishift].vbin;
   int *procgrid = comm->procgrid;
 
   int iswap = 0;
   for (int idim = 0; idim < dimension; idim++) {
     bcomm1 = &shifts[ishift].bcomm[iswap++];
     bcomm2 = &shifts[ishift].bcomm[iswap++];
     
     if (procgrid[idim] == 1) {
       if (bcomm1->nsend)
 	vbin_pack(vbin,bcomm1->nsend,bcomm1->sendlist,sbuf1);
       if (bcomm2->nsend)
 	vbin_pack(vbin,bcomm2->nsend,bcomm2->sendlist,sbuf2);
       if (bcomm1->nrecv)
 	vbin_unpack(sbuf1,vbin,bcomm1->nrecv,bcomm1->recvlist);
       if (bcomm2->nrecv)
 	vbin_unpack(sbuf2,vbin,bcomm2->nrecv,bcomm2->recvlist);
 
     } else {
       if (bcomm1->nrecv)
 	MPI_Irecv(rbuf1,bcomm1->nrecv*VBINSIZE,MPI_DOUBLE,bcomm1->recvproc,0,
 		  world,&request1);
       if (bcomm2->nrecv)
 	MPI_Irecv(rbuf2,bcomm2->nrecv*VBINSIZE,MPI_DOUBLE,bcomm2->recvproc,0,
 		  world,&request2);
       if (bcomm1->nsend) {
 	vbin_pack(vbin,bcomm1->nsend,bcomm1->sendlist,sbuf1);
 	MPI_Send(sbuf1,bcomm1->nsend*VBINSIZE,MPI_DOUBLE,
 		 bcomm1->sendproc,0,world);
       }
       if (bcomm2->nsend) {
 	vbin_pack(vbin,bcomm2->nsend,bcomm2->sendlist,sbuf2);
 	MPI_Send(sbuf2,bcomm2->nsend*VBINSIZE,MPI_DOUBLE,
 		 bcomm2->sendproc,0,world);
       }
       if (bcomm1->nrecv) {
 	MPI_Wait(&request1,&status);
 	vbin_unpack(rbuf1,vbin,bcomm1->nrecv,bcomm1->recvlist);
       }
       if (bcomm2->nrecv) {
 	MPI_Wait(&request2,&status);
 	vbin_unpack(rbuf2,vbin,bcomm2->nrecv,bcomm2->recvlist);
       }
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    pack velocity bin data into a message buffer for sending
 ------------------------------------------------------------------------- */
 
 void FixSRD::vbin_pack(BinAve *vbin, int n, int *list, double *buf)
 {
   int j;
   int m = 0;
   for (int i = 0; i < n; i++) {
     j = list[i];
     buf[m++] = vbin[j].n;
     buf[m++] = vbin[j].vave[0];
     buf[m++] = vbin[j].vave[1];
     buf[m++] = vbin[j].vave[2];
     buf[m++] = vbin[j].random;
   }
 }
 
 /* ----------------------------------------------------------------------
    unpack velocity bin data from a message buffer and sum values to my bins
 ------------------------------------------------------------------------- */
 
 void FixSRD::vbin_unpack(double *buf, BinAve *vbin, int n, int *list)
 {
   int j;
   int m = 0;
   for (int i = 0; i < n; i++) {
     j = list[i];
     vbin[j].n += static_cast<int> (buf[m++]);
     vbin[j].vave[0] += buf[m++];
     vbin[j].vave[1] += buf[m++];
     vbin[j].vave[2] += buf[m++];
     vbin[j].random += buf[m++];
   }
 }
 
 /* ----------------------------------------------------------------------
    detect all collisions between SRD and BIG particles or WALLS
    assume SRD can be inside at most one BIG particle or WALL at a time
    unoverlap SRDs for each collision
 ------------------------------------------------------------------------- */
 
 void FixSRD::collisions_single()
 {
   int i,j,k,m,type,mbig,ibin,ibounce,inside,collide_flag;
   double dt,t_remain;
   double norm[3],xscoll[3],xbcoll[3],vsnew[3];
   Big *big;
 
   // outer loop over SRD particles
   // inner loop over BIG particles or WALLS that overlap SRD particle bin
   // if overlap between SRD and BIG particle or wall:
   //   for exact, compute collision pt in time
   //   for inexact, push SRD to surf of BIG particle or WALL
   // update x,v of SRD and f,torque on BIG particle
   // re-bin SRD particle after collision
   // iterate until the SRD particle has no overlaps with BIG particles or WALLS
 
   double **x = atom->x;
   double **v = atom->v;
   double **f = atom->f;
   double **torque = atom->torque;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (i = 0; i < nlocal; i++) {
     if (!(mask[i] & groupbit)) continue;
 
     ibin = binsrd[i];
     if (nbinbig[ibin] == 0) continue;
 
     ibounce = 0;
     collide_flag = 1;
     dt = dt_big;
 
     while (collide_flag) {
       mbig = nbinbig[ibin];
       if (ibounce == 0) ncheck += mbig;
 
       collide_flag = 0;
       for (m = 0; m < mbig; m++) {
 	k = binbig[ibin][m];
 	big = &biglist[k];
 	j = big->index;
 	type = big->type;
 
 	if (type == SPHERE) inside = inside_sphere(x[i],x[j],big);
 	else if (type == ELLIPSOID) inside = inside_ellipsoid(x[i],x[j],big);
 	else inside = inside_wall(x[i],j);
 
 	if (inside) {
 	  if (exactflag) {
 	    if (type == SPHERE)
 	      t_remain = collision_sphere_exact(x[i],x[j],v[i],v[j],big,
 						xscoll,xbcoll,norm);
 	    else if (type == ELLIPSOID)
 	      t_remain = collision_ellipsoid_exact(x[i],x[j],v[i],v[j],big,
 						   xscoll,xbcoll,norm);
 	    else 
 	      t_remain = collision_wall_exact(x[i],j,v[i],xscoll,xbcoll,norm);
 
 	  } else {
 	    t_remain = 0.5*dt;
 	    if (type == SPHERE)
 	      collision_sphere_inexact(x[i],x[j],big,xscoll,xbcoll,norm);
 	    else if (type == ELLIPSOID)
 	      collision_ellipsoid_inexact(x[i],x[j],big,xscoll,xbcoll,norm);
 	    else
 	      collision_wall_inexact(x[i],j,xscoll,xbcoll,norm);
 	  }
 
 #ifdef SRD_DEBUG
 	  if (update->ntimestep == SRD_DEBUG_TIMESTEP &&
 	      atom->tag[i] == SRD_DEBUG_ATOMID)
 	    print_collision(i,j,ibounce,t_remain,dt,xscoll,xbcoll,norm,type);
 #endif
 
 	  if (t_remain > dt) {
 	    ninside++;
-	    if (insideflag == INSIDE_ERROR) {
-	      char str[128];
-	      if (type != WALL)
-		sprintf(str,"SRD particle %d started "
-			"inside big particle %d on step %d bounce %d\n",
+	    if (insideflag == INSIDE_ERROR || insideflag == INSIDE_WARN) {
+	      char str[128],fstr[128];
+	      if (type != WALL) {
+		sprintf(fstr,"SRD particle %%d started "
+			"inside big particle %%d on step %s bounce %%d\n",
+			BIGINT_FORMAT);
+		sprintf(str,fstr,
 			atom->tag[i],atom->tag[j],update->ntimestep,ibounce+1);
-	      else
-		sprintf(str,"SRD particle %d started "
-			"inside wall %d on step %d bounce %d\n",
-			atom->tag[i],j,update->ntimestep,ibounce+1);
-	      error->one(str);
-	    }
-	    if (insideflag == INSIDE_WARN) {
-	      char str[128];
-	      if (type != WALL)
-		sprintf(str,"SRD particle %d started "
-			"inside big particle %d on step %d bounce %d\n",
-			atom->tag[i],atom->tag[j],update->ntimestep,ibounce+1);
-	      else
-		sprintf(str,"SRD particle %d started "
-			"inside wall %d on step %d bounce %d\n",
+	      } else {
+		sprintf(fstr,"SRD particle %%d started "
+			"inside wall %%d on step %s bounce %%d\n",
+			BIGINT_FORMAT);
+		sprintf(str,fstr,
 			atom->tag[i],j,update->ntimestep,ibounce+1);
+	      }
+	      if (insideflag == INSIDE_ERROR) error->one(str);
 	      error->warning(str);
 	    }
 	    break;
 	  }
 
 	  if (collidestyle == SLIP) {
 	    if (type == SPHERE)
 	      slip_sphere(v[i],v[j],norm,vsnew);
 	    else if (type == ELLIPSOID)
 	      slip_ellipsoid(v[i],v[j],x[j],big,xscoll,norm,vsnew);
 	    else
 	      slip_wall(v[i],j,norm,vsnew);
 	  } else {
 	    if (type != WALL)
 	      noslip(v[i],v[j],x[j],big,xscoll,norm,vsnew);
 	    else
 	      noslip_wall(v[i],j,xscoll,norm,vsnew);
 	  }
 
 	  if (dimension == 2) vsnew[2] = 0.0;
 
 	  // check on rescaling of vsnew
 
 	  double vsq = vsnew[0]*vsnew[0] + vsnew[1]*vsnew[1] + 
 	    vsnew[2]*vsnew[2];
 	  if (vsq > vmaxsq) nrescale++;
 
 	  // update BIG particle and WALL and SRD
 	  // BIG particle is not torqued if sphere and SLIP collision
 
 	  if (collidestyle == SLIP && type == SPHERE)
 	    force_torque(v[i],vsnew,xscoll,xbcoll,f[j],NULL);
 	  else if (type != WALL)
 	    force_torque(v[i],vsnew,xscoll,xbcoll,f[j],torque[j]);
 	  else if (type == WALL)
 	    force_wall(v[i],vsnew,j);
 
 	  ibin = binsrd[i] = update_srd(i,t_remain,xscoll,vsnew,x[i],v[i]);
 
 	  if (ibounce == 0) ncollide++;
 	  ibounce++;
 	  if (ibounce < maxbounceallow || maxbounceallow == 0)
 	    collide_flag = 1;
 	  dt = t_remain;
 	  break;
 	}
       }
     }
 
     nbounce += ibounce;
     if (maxbounceallow && ibounce >= maxbounceallow) bouncemaxnum++;
     if (ibounce > bouncemax) bouncemax = ibounce;
   }
 }
 
 /* ----------------------------------------------------------------------
    detect all collisions between SRD and big particles
    an SRD can be inside more than one big particle at a time
    requires finding which big particle SRD collided with first
    unoverlap SRDs for each collision
 ------------------------------------------------------------------------- */
 
 void FixSRD::collisions_multi()
 {
   int i,j,k,m,type,mbig,ibin,ibounce,inside,jfirst,typefirst;
   double dt,t_remain,t_first;
   double norm[3],xscoll[3],xbcoll[3],vsnew[3];
   double normfirst[3],xscollfirst[3],xbcollfirst[3];
   Big *big;
 
   // outer loop over SRD particles
   // inner loop over BIG particles or WALLS that overlap SRD particle bin
   // loop over all BIG and WALLS to find which one SRD collided with first
   // if overlap between SRD and BIG particle or wall:
   //   compute collision pt in time
   // update x,v of SRD and f,torque on BIG particle
   // re-bin SRD particle after collision
   // iterate until the SRD particle has no overlaps with BIG particles or WALLS
 
   double **x = atom->x;
   double **v = atom->v;
   double **f = atom->f;
   double **torque = atom->torque;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (i = 0; i < nlocal; i++) {
     if (!(mask[i] & groupbit)) continue;
 
     ibin = binsrd[i];
     if (nbinbig[ibin] == 0) continue;
 
     ibounce = 0;
     dt = dt_big;
 
     while (1) {
       mbig = nbinbig[ibin];
       if (ibounce == 0) ncheck += mbig;
 
       t_first = 0.0;
       for (m = 0; m < mbig; m++) {
 	k = binbig[ibin][m];
 	big = &biglist[k];
 	j = big->index;
 	type = big->type;
 
 	if (type == SPHERE) inside = inside_sphere(x[i],x[j],big);
 	else if (type == ELLIPSOID) inside = inside_ellipsoid(x[i],x[j],big);
 	else inside = inside_wall(x[i],j);
 
 	if (inside) {
 	  if (type == SPHERE)
 	    t_remain = collision_sphere_exact(x[i],x[j],v[i],v[j],big,
 					      xscoll,xbcoll,norm);
 	  else if (type == ELLIPSOID)
 	    t_remain = collision_ellipsoid_exact(x[i],x[j],v[i],v[j],big,
 						 xscoll,xbcoll,norm);
 	  else 
 	    t_remain = collision_wall_exact(x[i],j,v[i],xscoll,xbcoll,norm);
 
 #ifdef SRD_DEBUG
 	  if (update->ntimestep == SRD_DEBUG_TIMESTEP &&
 	      atom->tag[i] == SRD_DEBUG_ATOMID)
 	    print_collision(i,j,ibounce,t_remain,dt,xscoll,xbcoll,norm,type);
 #endif
 
 	  if (t_remain > dt || t_remain < 0.0) {
 	    ninside++;
-	    if (insideflag == INSIDE_ERROR) {
-	      char str[128];
-	      sprintf(str,"SRD particle %d started "
-		      "inside big particle %d on step %d bounce %d\n",
-		      atom->tag[i],atom->tag[j],update->ntimestep,ibounce+1);
-	      error->one(str);
-	    }
-	    if (insideflag == INSIDE_WARN) {
-	      char str[128];
-	      sprintf(str,"SRD particle %d started "
-		      "inside big particle %d on step %d bounce %d\n",
+	    if (insideflag == INSIDE_ERROR || insideflag == INSIDE_WARN) {
+	      char str[128],fstr[128];
+	      sprintf(fstr,"SRD particle %%d started "
+		      "inside big particle %%d on step %s bounce %%d\n",
+		      BIGINT_FORMAT);
+	      sprintf(str,fstr,
 		      atom->tag[i],atom->tag[j],update->ntimestep,ibounce+1);
+	      if (insideflag == INSIDE_ERROR) error->one(str);
 	      error->warning(str);
 	    }
 	    t_first = 0.0;
 	    break;
 	  }
 
 	  if (t_remain > t_first) {
 	    t_first = t_remain;
 	    jfirst = j;
 	    typefirst = type;
 	    xscollfirst[0] = xscoll[0];
 	    xscollfirst[1] = xscoll[1];
 	    xscollfirst[2] = xscoll[2];
 	    xbcollfirst[0] = xbcoll[0];
 	    xbcollfirst[1] = xbcoll[1];
 	    xbcollfirst[2] = xbcoll[2];
 	    normfirst[0] = norm[0];
 	    normfirst[1] = norm[1];
 	    normfirst[2] = norm[2];
 	  }
 	}
       }
 
       if (t_first == 0.0) break;
       j = jfirst;
       type = typefirst;
       xscoll[0] = xscollfirst[0];
       xscoll[1] = xscollfirst[1];
       xscoll[2] = xscollfirst[2];
       xbcoll[0] = xbcollfirst[0];
       xbcoll[1] = xbcollfirst[1];
       xbcoll[2] = xbcollfirst[2];
       norm[0] = normfirst[0];
       norm[1] = normfirst[1];
       norm[2] = normfirst[2];
 
       if (collidestyle == SLIP) {
 	if (type == SPHERE)
 	  slip_sphere(v[i],v[j],norm,vsnew);
 	else if (type == ELLIPSOID)
 	  slip_ellipsoid(v[i],v[j],x[j],big,xscoll,norm,vsnew);
 	else
 	  slip_wall(v[i],j,norm,vsnew);
       } else {
 	if (type != WALL)
 	  noslip(v[i],v[j],x[j],big,xscoll,norm,vsnew);
 	else
 	  noslip_wall(v[i],j,xscoll,norm,vsnew);
       }
 
       if (dimension == 2) vsnew[2] = 0.0;
 
       // check on rescaling of vsnew
 
       double vsq = vsnew[0]*vsnew[0] + vsnew[1]*vsnew[1] + vsnew[2]*vsnew[2];
       if (vsq > vmaxsq) nrescale++;
 
       // update BIG particle and WALL and SRD
       // BIG particle is not torqued if sphere and SLIP collision
 
       if (collidestyle == SLIP && type == SPHERE)
 	force_torque(v[i],vsnew,xscoll,xbcoll,f[j],NULL);
       else if (type != WALL)
 	force_torque(v[i],vsnew,xscoll,xbcoll,f[j],torque[j]);
       else if (type == WALL)
 	force_wall(v[i],vsnew,j);
 
       ibin = binsrd[i] = update_srd(i,t_first,xscoll,vsnew,x[i],v[i]);
 
       if (ibounce == 0) ncollide++;
       ibounce++;
       if (ibounce == maxbounceallow) break;
       dt = t_first;
     }
 
     nbounce += ibounce;
     if (maxbounceallow && ibounce >= maxbounceallow) bouncemaxnum++;
     if (ibounce > bouncemax) bouncemax = ibounce;
   }
 }
 
 /* ----------------------------------------------------------------------
    check if SRD particle S is inside spherical big particle B
 ------------------------------------------------------------------------- */
 
 int FixSRD::inside_sphere(double *xs, double *xb, Big *big)
 {
   double dx,dy,dz;
 
   dx = xs[0] - xb[0];
   dy = xs[1] - xb[1];
   dz = xs[2] - xb[2];
 
   if (dx*dx + dy*dy + dz*dz <= big->radsq) return 1;
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    check if SRD particle S is inside ellipsoidal big particle B
 ------------------------------------------------------------------------- */
 
 int FixSRD::inside_ellipsoid(double *xs, double *xb, Big *big)
 {
   double x,y,z;
 
   double *ex = big->ex;
   double *ey = big->ey;
   double *ez = big->ez;
 
   double xs_xb[3];
   xs_xb[0] = xs[0] - xb[0];
   xs_xb[1] = xs[1] - xb[1];
   xs_xb[2] = xs[2] - xb[2];
 
   x = xs_xb[0]*ex[0] + xs_xb[1]*ex[1] + xs_xb[2]*ex[2];
   y = xs_xb[0]*ey[0] + xs_xb[1]*ey[1] + xs_xb[2]*ey[2];
   z = xs_xb[0]*ez[0] + xs_xb[1]*ez[1] + xs_xb[2]*ez[2];
 
   if (x*x*big->aradsqinv + y*y*big->bradsqinv + z*z*big->cradsqinv <= 1.0)
     return 1;
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    check if SRD particle S is inside wall IWALL
 ------------------------------------------------------------------------- */
 
 int FixSRD::inside_wall(double *xs, int iwall)
 {
   int dim = wallwhich[iwall] / 2;
   int side = wallwhich[iwall] % 2;
 
   if (side == 0 && xs[dim] < xwall[iwall]) return 1;
   if (side && xs[dim] > xwall[iwall]) return 1;
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    collision of SRD particle S with surface of spherical big particle B
    exact because compute time of collision
    dt = time previous to now at which collision occurs
    xscoll = collision pt = position of SRD at time of collision
    xbcoll = position of big particle at time of collision
    norm = surface normal of collision pt at time of collision
 ------------------------------------------------------------------------- */
 
 double FixSRD::collision_sphere_exact(double *xs, double *xb,
 				      double *vs, double *vb, Big *big,
 				      double *xscoll, double *xbcoll,
 				      double *norm)
 {
   double vs_dot_vs,vb_dot_vb,vs_dot_vb;
   double vs_dot_xb,vb_dot_xs,vs_dot_xs,vb_dot_xb;
   double xs_dot_xs,xb_dot_xb,xs_dot_xb;
   double a,b,c,scale,dt;
 
   vs_dot_vs = vs[0]*vs[0] + vs[1]*vs[1] + vs[2]*vs[2];
   vb_dot_vb = vb[0]*vb[0] + vb[1]*vb[1] + vb[2]*vb[2];
   vs_dot_vb = vs[0]*vb[0] + vs[1]*vb[1] + vs[2]*vb[2];
 
   vs_dot_xb = vs[0]*xb[0] + vs[1]*xb[1] + vs[2]*xb[2];
   vb_dot_xs = vb[0]*xs[0] + vb[1]*xs[1] + vb[2]*xs[2];
   vs_dot_xs = vs[0]*xs[0] + vs[1]*xs[1] + vs[2]*xs[2];
   vb_dot_xb = vb[0]*xb[0] + vb[1]*xb[1] + vb[2]*xb[2];
 
   xs_dot_xs = xs[0]*xs[0] + xs[1]*xs[1] + xs[2]*xs[2];
   xb_dot_xb = xb[0]*xb[0] + xb[1]*xb[1] + xb[2]*xb[2];
   xs_dot_xb = xs[0]*xb[0] + xs[1]*xb[1] + xs[2]*xb[2];
 
   a = vs_dot_vs + vb_dot_vb - 2.0*vs_dot_vb;
   b = 2.0 * (vs_dot_xb + vb_dot_xs - vs_dot_xs - vb_dot_xb);
   c = xs_dot_xs + xb_dot_xb - 2.0*xs_dot_xb - big->radsq;
 
   dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a);
 
   xscoll[0] = xs[0] - dt*vs[0];
   xscoll[1] = xs[1] - dt*vs[1];
   xscoll[2] = xs[2] - dt*vs[2];
 
   xbcoll[0] = xb[0] - dt*vb[0];
   xbcoll[1] = xb[1] - dt*vb[1];
   xbcoll[2] = xb[2] - dt*vb[2];
 
   norm[0] = xscoll[0] - xbcoll[0];
   norm[1] = xscoll[1] - xbcoll[1];
   norm[2] = xscoll[2] - xbcoll[2];
   scale = 1.0/sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
   norm[0] *= scale;
   norm[1] *= scale;
   norm[2] *= scale;
 
   return dt;
 }
 
 /* ----------------------------------------------------------------------
    collision of SRD particle S with surface of spherical big particle B
    inexact because just push SRD to surface of big particle at end of step
    time of collision = end of step
    xscoll = collision pt = position of SRD at time of collision
    xbcoll = xb = position of big particle at time of collision
    norm = surface normal of collision pt at time of collision
 ------------------------------------------------------------------------- */
 
 void FixSRD::collision_sphere_inexact(double *xs, double *xb,
 				      Big *big,
 				      double *xscoll, double *xbcoll,
 				      double *norm)
 {
   double scale;
 
   norm[0] = xs[0] - xb[0];
   norm[1] = xs[1] - xb[1];
   norm[2] = xs[2] - xb[2];
   scale = 1.0/sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
   norm[0] *= scale;
   norm[1] *= scale;
   norm[2] *= scale;
 
   xscoll[0] = xb[0] + big->radius*norm[0];
   xscoll[1] = xb[1] + big->radius*norm[1];
   xscoll[2] = xb[2] + big->radius*norm[2];
 
   xbcoll[0] = xb[0];
   xbcoll[1] = xb[1];
   xbcoll[2] = xb[2];
 }
 
 /* ----------------------------------------------------------------------
    collision of SRD particle S with surface of ellipsoidal big particle B
    exact because compute time of collision
    dt = time previous to now at which collision occurs
    xscoll = collision pt = position of SRD at time of collision
    xbcoll = position of big particle at time of collision
    norm = surface normal of collision pt at time of collision
 ------------------------------------------------------------------------- */
 
 double FixSRD::collision_ellipsoid_exact(double *xs, double *xb,
 					 double *vs, double *vb, Big *big,
 					 double *xscoll, double *xbcoll,
 					 double *norm)
 {
   double vs_vb[3],xs_xb[3],omega_ex[3],omega_ey[3],omega_ez[3];
   double excoll[3],eycoll[3],ezcoll[3],delta[3],xbody[3],nbody[3];
   double ax,bx,cx,ay,by,cy,az,bz,cz;
   double a,b,c,dt,scale;
 
   double *omega = big->omega;
   double *ex = big->ex;
   double *ey = big->ey;
   double *ez = big->ez;
 
   vs_vb[0] = vs[0]-vb[0]; vs_vb[1] = vs[1]-vb[1]; vs_vb[2] = vs[2]-vb[2];
   xs_xb[0] = xs[0]-xb[0]; xs_xb[1] = xs[1]-xb[1]; xs_xb[2] = xs[2]-xb[2];
 
   omega_ex[0] = omega[1]*ex[2] - omega[2]*ex[1];
   omega_ex[1] = omega[2]*ex[0] - omega[0]*ex[2];
   omega_ex[2] = omega[0]*ex[1] - omega[1]*ex[0];
 
   omega_ey[0] = omega[1]*ey[2] - omega[2]*ey[1];
   omega_ey[1] = omega[2]*ey[0] - omega[0]*ey[2];
   omega_ey[2] = omega[0]*ey[1] - omega[1]*ey[0];
 
   omega_ez[0] = omega[1]*ez[2] - omega[2]*ez[1];
   omega_ez[1] = omega[2]*ez[0] - omega[0]*ez[2];
   omega_ez[2] = omega[0]*ez[1] - omega[1]*ez[0];
 
   ax = vs_vb[0]*omega_ex[0] + vs_vb[1]*omega_ex[1] + vs_vb[2]*omega_ex[2];
   bx = -(vs_vb[0]*ex[0] + vs_vb[1]*ex[1] + vs_vb[2]*ex[2]);
   bx -= xs_xb[0]*omega_ex[0] + xs_xb[1]*omega_ex[1] + xs_xb[2]*omega_ex[2];
   cx = xs_xb[0]*ex[0] + xs_xb[1]*ex[1] + xs_xb[2]*ex[2];
 
   ay = vs_vb[0]*omega_ey[0] + vs_vb[1]*omega_ey[1] + vs_vb[2]*omega_ey[2];
   by = -(vs_vb[0]*ey[0] + vs_vb[1]*ey[1] + vs_vb[2]*ey[2]);
   by -= xs_xb[0]*omega_ey[0] + xs_xb[1]*omega_ey[1] + xs_xb[2]*omega_ey[2];
   cy = xs_xb[0]*ey[0] + xs_xb[1]*ey[1] + xs_xb[2]*ey[2];
 
   az = vs_vb[0]*omega_ez[0] + vs_vb[1]*omega_ez[1] + vs_vb[2]*omega_ez[2];
   bz = -(vs_vb[0]*ez[0] + vs_vb[1]*ez[1] + vs_vb[2]*ez[2]);
   bz -= xs_xb[0]*omega_ez[0] + xs_xb[1]*omega_ez[1] + xs_xb[2]*omega_ez[2];
   cz = xs_xb[0]*ez[0] + xs_xb[1]*ez[1] + xs_xb[2]*ez[2];
 
   a = (bx*bx + 2.0*ax*cx)*big->aradsqinv +
     (by*by + 2.0*ay*cy)*big->bradsqinv + 
     (bz*bz + 2.0*az*cz)*big->cradsqinv;
   b = 2.0 * (bx*cx*big->aradsqinv + by*cy*big->bradsqinv +
 	     bz*cz*big->cradsqinv);
   c = cx*cx*big->aradsqinv + cy*cy*big->bradsqinv +
     cz*cz*big->cradsqinv - 1.0;
 
   dt = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a);
 
   xscoll[0] = xs[0] - dt*vs[0];
   xscoll[1] = xs[1] - dt*vs[1];
   xscoll[2] = xs[2] - dt*vs[2];
 
   xbcoll[0] = xb[0] - dt*vb[0];
   xbcoll[1] = xb[1] - dt*vb[1];
   xbcoll[2] = xb[2] - dt*vb[2];
 
   // calculate normal to ellipsoid at collision pt
   // Excoll,Eycoll,Ezcoll = orientation of ellipsoid at collision time
   // nbody = normal in body frame of ellipsoid (Excoll,Eycoll,Ezcoll)
   // norm = normal in space frame
   // only worry about normalizing final norm vector
 
   excoll[0] = ex[0] - dt * (omega[1]*ex[2] - omega[2]*ex[1]);
   excoll[1] = ex[1] - dt * (omega[2]*ex[0] - omega[0]*ex[2]);
   excoll[2] = ex[2] - dt * (omega[0]*ex[1] - omega[1]*ex[0]);
 
   eycoll[0] = ey[0] - dt * (omega[1]*ey[2] - omega[2]*ey[1]);
   eycoll[1] = ey[1] - dt * (omega[2]*ey[0] - omega[0]*ey[2]);
   eycoll[2] = ey[2] - dt * (omega[0]*ey[1] - omega[1]*ey[0]);
 
   ezcoll[0] = ez[0] - dt * (omega[1]*ez[2] - omega[2]*ez[1]);
   ezcoll[1] = ez[1] - dt * (omega[2]*ez[0] - omega[0]*ez[2]);
   ezcoll[2] = ez[2] - dt * (omega[0]*ez[1] - omega[1]*ez[0]);
 
   delta[0] = xscoll[0] - xbcoll[0];
   delta[1] = xscoll[1] - xbcoll[1];
   delta[2] = xscoll[2] - xbcoll[2];
 
   xbody[0] = delta[0]*excoll[0] + delta[1]*excoll[1] + delta[2]*excoll[2];
   xbody[1] = delta[0]*eycoll[0] + delta[1]*eycoll[1] + delta[2]*eycoll[2];
   xbody[2] = delta[0]*ezcoll[0] + delta[1]*ezcoll[1] + delta[2]*ezcoll[2];
 
   nbody[0] = xbody[0]*big->aradsqinv;
   nbody[1] = xbody[1]*big->bradsqinv;
   nbody[2] = xbody[2]*big->cradsqinv;
 
   norm[0] = excoll[0]*nbody[0] + eycoll[0]*nbody[1] + ezcoll[0]*nbody[2];
   norm[1] = excoll[1]*nbody[0] + eycoll[1]*nbody[1] + ezcoll[1]*nbody[2];
   norm[2] = excoll[2]*nbody[0] + eycoll[2]*nbody[1] + ezcoll[2]*nbody[2];
   scale = 1.0/sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
   norm[0] *= scale;
   norm[1] *= scale;
   norm[2] *= scale;
 
   return dt;
 }
 
 /* ----------------------------------------------------------------------
    collision of SRD particle S with surface of ellipsoidal big particle B
    inexact because just push SRD to surface of big particle at end of step
 ------------------------------------------------------------------------- */
 
 void FixSRD::collision_ellipsoid_inexact(double *xs, double *xb,
 					 Big *big,
 					 double *xscoll, double *xbcoll,
 					 double *norm)
 {
   double xs_xb[3],delta[3],xbody[3],nbody[3];
   double x,y,z,scale;
 
   double *ex = big->ex;
   double *ey = big->ey;
   double *ez = big->ez;
 
   xs_xb[0] = xs[0] - xb[0];
   xs_xb[1] = xs[1] - xb[1];
   xs_xb[2] = xs[2] - xb[2];
 
   x = xs_xb[0]*ex[0] + xs_xb[1]*ex[1] + xs_xb[2]*ex[2];
   y = xs_xb[0]*ey[0] + xs_xb[1]*ey[1] + xs_xb[2]*ey[2];
   z = xs_xb[0]*ez[0] + xs_xb[1]*ez[1] + xs_xb[2]*ez[2];
 
   scale = 1.0/sqrt(x*x*big->aradsqinv + y*y*big->bradsqinv +
 		   z*z*big->cradsqinv);
   x *= scale;
   y *= scale;
   z *= scale;
 
   xscoll[0] = x*ex[0] + y*ey[0] + z*ez[0] + xb[0];
   xscoll[1] = x*ex[1] + y*ey[1] + z*ez[1] + xb[1];
   xscoll[2] = x*ex[2] + y*ey[2] + z*ez[2] + xb[2];
 
   xbcoll[0] = xb[0];
   xbcoll[1] = xb[1];
   xbcoll[2] = xb[2];
 
   // calculate normal to ellipsoid at collision pt
   // nbody = normal in body frame of ellipsoid
   // norm = normal in space frame
   // only worry about normalizing final norm vector
 
   delta[0] = xscoll[0] - xbcoll[0];
   delta[1] = xscoll[1] - xbcoll[1];
   delta[2] = xscoll[2] - xbcoll[2];
 
   xbody[0] = delta[0]*ex[0] + delta[1]*ex[1] + delta[2]*ex[2];
   xbody[1] = delta[0]*ey[0] + delta[1]*ey[1] + delta[2]*ey[2];
   xbody[2] = delta[0]*ez[0] + delta[1]*ez[1] + delta[2]*ez[2];
 
   nbody[0] = xbody[0]*big->aradsqinv;
   nbody[1] = xbody[1]*big->bradsqinv;
   nbody[2] = xbody[2]*big->cradsqinv;
 
   norm[0] = ex[0]*nbody[0] + ey[0]*nbody[1] + ez[0]*nbody[2];
   norm[1] = ex[1]*nbody[0] + ey[1]*nbody[1] + ez[1]*nbody[2];
   norm[2] = ex[2]*nbody[0] + ey[2]*nbody[1] + ez[2]*nbody[2];
   scale = 1.0/sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
   norm[0] *= scale;
   norm[1] *= scale;
   norm[2] *= scale;
 }
 
 /* ----------------------------------------------------------------------
    collision of SRD particle S with wall IWALL
    exact because compute time of collision
    dt = time previous to now at which collision occurs
    xscoll = collision pt = position of SRD at time of collision
    norm = surface normal of collision pt at time of collision
 ------------------------------------------------------------------------- */
 
 double FixSRD::collision_wall_exact(double *xs, int iwall, double *vs,
 				     double *xscoll, double *xbcoll,
 				     double *norm)
 {
   int dim = wallwhich[iwall] / 2;
 
   double dt = (xs[dim] - xwall[iwall]) / (vs[dim] - vwall[iwall]);
   xscoll[0] = xs[0] - dt*vs[0];
   xscoll[1] = xs[1] - dt*vs[1];
   xscoll[2] = xs[2] - dt*vs[2];
 
   xbcoll[0] = xbcoll[1] = xbcoll[2] = 0.0;
   xbcoll[dim] = xwall[iwall] - dt*vwall[iwall];
 
   int side = wallwhich[iwall] % 2;
   norm[0] = norm[1] = norm[2] = 0.0;
   if (side == 0) norm[dim] = 1.0;
   else norm[dim] = -1.0;
 
   return dt;
 }
 
 /* ----------------------------------------------------------------------
    collision of SRD particle S with wall IWALL
    inexact because just push SRD to surface of wall at end of step
    time of collision = end of step
    xscoll = collision pt = position of SRD at time of collision
    norm = surface normal of collision pt at time of collision
 ------------------------------------------------------------------------- */
 
 void FixSRD::collision_wall_inexact(double *xs, int iwall, double *xscoll, 
 				     double *xbcoll, double *norm)
 {
   int dim = wallwhich[iwall] / 2;
 
   xscoll[0] = xs[0];
   xscoll[1] = xs[1];
   xscoll[2] = xs[2];
   xscoll[dim] = xwall[iwall];
 
   xbcoll[0] = xbcoll[1] = xbcoll[2] = 0.0;
   xbcoll[dim] = xwall[iwall];
 
   int side = wallwhich[iwall] % 2;
   norm[0] = norm[1] = norm[2] = 0.0;
   if (side == 0) norm[dim] = 1.0;
   else norm[dim] = -1.0;
 }
 
 /* ----------------------------------------------------------------------
    SLIP collision with sphere
    vs = velocity of SRD, vb = velocity of BIG
    norm = unit normal from surface of BIG at collision pt
    v of BIG particle in direction of surf normal is added to v of SRD
    return vsnew of SRD
 ------------------------------------------------------------------------- */
 
 void FixSRD::slip_sphere(double *vs, double *vb, double *norm, double *vsnew)
 {
   double r1,r2,vnmag,vs_dot_n,vsurf_dot_n;
   double tangent[3];
 
   while (1) {
     r1 = sigma * random->gaussian();
     r2 = sigma * random->gaussian();
     vnmag = sqrt(r1*r1 + r2*r2);
     if (vnmag*vnmag <= vmaxsq) break;
   }
 
   vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2];
 
   tangent[0] = vs[0] - vs_dot_n*norm[0];
   tangent[1] = vs[1] - vs_dot_n*norm[1];
   tangent[2] = vs[2] - vs_dot_n*norm[2];
 
   // vsurf = velocity of collision pt = translation/rotation of BIG particle
   // for sphere, only vb (translation) can contribute in normal direction
 
   vsurf_dot_n = vb[0]*norm[0] + vb[1]*norm[1] + vb[2]*norm[2];
 
   vsnew[0] = (vnmag+vsurf_dot_n)*norm[0] + tangent[0];
   vsnew[1] = (vnmag+vsurf_dot_n)*norm[1] + tangent[1];
   vsnew[2] = (vnmag+vsurf_dot_n)*norm[2] + tangent[2];
 }
 
 /* ----------------------------------------------------------------------
    SLIP collision with ellipsoid
    vs = velocity of SRD, vb = velocity of BIG
    xb = position of BIG, omega = rotation of BIG
    xsurf = collision pt on surf of BIG
    norm = unit normal from surface of BIG at collision pt
    v of BIG particle in direction of surf normal is added to v of SRD
    includes component due to rotation of ellipsoid
    return vsnew of SRD
 ------------------------------------------------------------------------- */
 
 void FixSRD::slip_ellipsoid(double *vs, double *vb, double *xb, Big *big,
 			    double *xsurf, double *norm, double *vsnew)
 {
   double r1,r2,vnmag,vs_dot_n,vsurf_dot_n;
   double tangent[3],vsurf[3];
   double *omega = big->omega;
 
   while (1) {
     r1 = sigma * random->gaussian();
     r2 = sigma * random->gaussian();
     vnmag = sqrt(r1*r1 + r2*r2);
     if (vnmag*vnmag <= vmaxsq) break;
   }
 
   vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2];
 
   tangent[0] = vs[0] - vs_dot_n*norm[0];
   tangent[1] = vs[1] - vs_dot_n*norm[1];
   tangent[2] = vs[2] - vs_dot_n*norm[2];
 
   // vsurf = velocity of collision pt = translation/rotation of BIG particle
 
   vsurf[0] = vb[0] + omega[1]*(xsurf[2]-xb[2]) - omega[2]*(xsurf[1]-xb[1]);
   vsurf[1] = vb[1] + omega[2]*(xsurf[0]-xb[0]) - omega[0]*(xsurf[2]-xb[2]);
   vsurf[2] = vb[2] + omega[0]*(xsurf[1]-xb[1]) - omega[1]*(xsurf[0]-xb[0]);
 
   vsurf_dot_n = vsurf[0]*norm[0] + vsurf[1]*norm[1] + vsurf[2]*norm[2];
 
   vsnew[0] = (vnmag+vsurf_dot_n)*norm[0] + tangent[0];
   vsnew[1] = (vnmag+vsurf_dot_n)*norm[1] + tangent[1];
   vsnew[2] = (vnmag+vsurf_dot_n)*norm[2] + tangent[2];
 }
 
 /* ----------------------------------------------------------------------
    SLIP collision with wall IWALL
    vs = velocity of SRD
    norm = unit normal from WALL at collision pt
    v of WALL in direction of surf normal is added to v of SRD
    return vsnew of SRD
 ------------------------------------------------------------------------- */
 
 void FixSRD::slip_wall(double *vs, int iwall, double *norm, double *vsnew)
 {
   double vs_dot_n,scale,r1,r2,vnmag,vtmag1,vtmag2;
   double tangent1[3],tangent2[3];
 
   vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2];
 
   tangent1[0] = vs[0] - vs_dot_n*norm[0];
   tangent1[1] = vs[1] - vs_dot_n*norm[1];
   tangent1[2] = vs[2] - vs_dot_n*norm[2];
   scale = 1.0/sqrt(tangent1[0]*tangent1[0] + tangent1[1]*tangent1[1] +
 		   tangent1[2]*tangent1[2]);
   tangent1[0] *= scale;
   tangent1[1] *= scale;
   tangent1[2] *= scale;
 
   tangent2[0] = norm[1]*tangent1[2] - norm[2]*tangent1[1];
   tangent2[1] = norm[2]*tangent1[0] - norm[0]*tangent1[2];
   tangent2[2] = norm[0]*tangent1[1] - norm[1]*tangent1[0];
 
   while (1) {
     r1 = sigma * random->gaussian();
     r2 = sigma * random->gaussian();
     vnmag = sqrt(r1*r1 + r2*r2);
     vtmag1 = sigma * random->gaussian();
     vtmag2 = sigma * random->gaussian();
     if (vnmag*vnmag + vtmag1*vtmag1 + vtmag2*vtmag2 <= vmaxsq) break;
   }
 
   vsnew[0] = vnmag*norm[0] + vtmag1*tangent1[0] + vtmag2*tangent2[0];
   vsnew[1] = vnmag*norm[1] + vtmag1*tangent1[1] + vtmag2*tangent2[1];
   vsnew[2] = vnmag*norm[2] + vtmag1*tangent1[2] + vtmag2*tangent2[2];
 
   // add in velocity of collision pt = velocity of wall
 
   int dim = wallwhich[iwall] / 2;
   vsnew[dim] += vwall[iwall];
 }
 
 /* ----------------------------------------------------------------------
    NO-SLIP collision with sphere or ellipsoid
    vs = velocity of SRD, vb = velocity of BIG
    xb = position of BIG, omega = rotation of BIG
    xsurf = collision pt on surf of BIG
    norm = unit normal from surface of BIG at collision pt
    v of collision pt is added to v of SRD
    includes component due to rotation of BIG
    return vsnew of SRD
 ------------------------------------------------------------------------- */
 
 void FixSRD::noslip(double *vs, double *vb, double *xb, Big *big,
 		    double *xsurf, double *norm, double *vsnew)
 {
   double vs_dot_n,scale,r1,r2,vnmag,vtmag1,vtmag2;
   double tangent1[3],tangent2[3];
   double *omega = big->omega;
 
   vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2];
 
   tangent1[0] = vs[0] - vs_dot_n*norm[0];
   tangent1[1] = vs[1] - vs_dot_n*norm[1];
   tangent1[2] = vs[2] - vs_dot_n*norm[2];
   scale = 1.0/sqrt(tangent1[0]*tangent1[0] + tangent1[1]*tangent1[1] +
 		   tangent1[2]*tangent1[2]);
   tangent1[0] *= scale;
   tangent1[1] *= scale;
   tangent1[2] *= scale;
 
   tangent2[0] = norm[1]*tangent1[2] - norm[2]*tangent1[1];
   tangent2[1] = norm[2]*tangent1[0] - norm[0]*tangent1[2];
   tangent2[2] = norm[0]*tangent1[1] - norm[1]*tangent1[0];
 
   while (1) {
     r1 = sigma * random->gaussian();
     r2 = sigma * random->gaussian();
     vnmag = sqrt(r1*r1 + r2*r2);
     vtmag1 = sigma * random->gaussian();
     vtmag2 = sigma * random->gaussian();
     if (vnmag*vnmag + vtmag1*vtmag1 + vtmag2*vtmag2 <= vmaxsq) break;
   }
 
   vsnew[0] = vnmag*norm[0] + vtmag1*tangent1[0] + vtmag2*tangent2[0];
   vsnew[1] = vnmag*norm[1] + vtmag1*tangent1[1] + vtmag2*tangent2[1];
   vsnew[2] = vnmag*norm[2] + vtmag1*tangent1[2] + vtmag2*tangent2[2];
 
   // add in velocity of collision pt = translation/rotation of BIG particle
 
   vsnew[0] += vb[0] + omega[1]*(xsurf[2]-xb[2]) - omega[2]*(xsurf[1]-xb[1]);
   vsnew[1] += vb[1] + omega[2]*(xsurf[0]-xb[0]) - omega[0]*(xsurf[2]-xb[2]);
   vsnew[2] += vb[2] + omega[0]*(xsurf[1]-xb[1]) - omega[1]*(xsurf[0]-xb[0]);
 }
 
 /* ----------------------------------------------------------------------
    NO-SLIP collision with wall IWALL
    vs = velocity of SRD
    xsurf = collision pt on surf of WALL
    norm = unit normal from WALL at collision pt
    v of collision pt is added to v of SRD
    return vsnew of SRD
 ------------------------------------------------------------------------- */
 
 void FixSRD::noslip_wall(double *vs, int iwall,
 			 double *xsurf, double *norm, double *vsnew)
 {
   double vs_dot_n,scale,r1,r2,vnmag,vtmag1,vtmag2;
   double tangent1[3],tangent2[3];
 
   vs_dot_n = vs[0]*norm[0] + vs[1]*norm[1] + vs[2]*norm[2];
 
   tangent1[0] = vs[0] - vs_dot_n*norm[0];
   tangent1[1] = vs[1] - vs_dot_n*norm[1];
   tangent1[2] = vs[2] - vs_dot_n*norm[2];
   scale = 1.0/sqrt(tangent1[0]*tangent1[0] + tangent1[1]*tangent1[1] +
 		   tangent1[2]*tangent1[2]);
   tangent1[0] *= scale;
   tangent1[1] *= scale;
   tangent1[2] *= scale;
 
   tangent2[0] = norm[1]*tangent1[2] - norm[2]*tangent1[1];
   tangent2[1] = norm[2]*tangent1[0] - norm[0]*tangent1[2];
   tangent2[2] = norm[0]*tangent1[1] - norm[1]*tangent1[0];
 
   while (1) {
     r1 = sigma * random->gaussian();
     r2 = sigma * random->gaussian();
     vnmag = sqrt(r1*r1 + r2*r2);
     vtmag1 = sigma * random->gaussian();
     vtmag2 = sigma * random->gaussian();
     if (vnmag*vnmag + vtmag1*vtmag1 + vtmag2*vtmag2 <= vmaxsq) break;
   }
 
   vsnew[0] = vnmag*norm[0] + vtmag1*tangent1[0] + vtmag2*tangent2[0];
   vsnew[1] = vnmag*norm[1] + vtmag1*tangent1[1] + vtmag2*tangent2[1];
   vsnew[2] = vnmag*norm[2] + vtmag1*tangent1[2] + vtmag2*tangent2[2];
 
   // add in velocity of collision pt = velocity of wall
 
   int dim = wallwhich[iwall] / 2;
   vsnew[dim] += vwall[iwall];
 }
 
 /* ----------------------------------------------------------------------
    impart force and torque to BIG particle
    force on BIG particle = -dp/dt of SRD particle
    torque on BIG particle = r cross (-dp/dt)
 ------------------------------------------------------------------------- */
 
 void FixSRD::force_torque(double *vsold, double *vsnew,
 			  double *xs, double *xb,
 			  double *fb, double *tb)
 {
   double dpdt[3],xs_xb[3];
 
   double factor = mass_srd / dt_big / force->ftm2v;
   dpdt[0] = factor * (vsnew[0] - vsold[0]);
   dpdt[1] = factor * (vsnew[1] - vsold[1]);
   dpdt[2] = factor * (vsnew[2] - vsold[2]);
 
   fb[0] -= dpdt[0];
   fb[1] -= dpdt[1];
   fb[2] -= dpdt[2];
 
   // no torque if SLIP collision and BIG is a sphere
 
   if (tb) {
     xs_xb[0] = xs[0]-xb[0];
     xs_xb[1] = xs[1]-xb[1];
     xs_xb[2] = xs[2]-xb[2];
     tb[0] -= xs_xb[1]*dpdt[2] - xs_xb[2]*dpdt[1];
     tb[1] -= xs_xb[2]*dpdt[0] - xs_xb[0]*dpdt[2];
     tb[2] -= xs_xb[0]*dpdt[1] - xs_xb[1]*dpdt[0];
   }
 }
 
 /* ----------------------------------------------------------------------
    impart force to WALL
    force on WALL = -dp/dt of SRD particle
 ------------------------------------------------------------------------- */
 
 void FixSRD::force_wall(double *vsold, double *vsnew, int iwall)
 
 {
   double dpdt[3],xs_xb[3];
 
   double factor = mass_srd / dt_big / force->ftm2v;
   dpdt[0] = factor * (vsnew[0] - vsold[0]);
   dpdt[1] = factor * (vsnew[1] - vsold[1]);
   dpdt[2] = factor * (vsnew[2] - vsold[2]);
 
   fwall[iwall][0] -= dpdt[0];
   fwall[iwall][1] -= dpdt[1];
   fwall[iwall][2] -= dpdt[2];
 }
 
 /* ----------------------------------------------------------------------
    update SRD particle position & velocity & search bin assignment
    check if SRD moved outside of valid region
    if so, may overlap off-processor BIG particle
 ------------------------------------------------------------------------- */
 
 int FixSRD::update_srd(int i, double dt, double *xscoll, double *vsnew,
 		       double *xs, double *vs)
 {
   int ix,iy,iz;
 
   vs[0] = vsnew[0];
   vs[1] = vsnew[1];
   vs[2] = vsnew[2];
 
   xs[0] = xscoll[0] + dt*vsnew[0];
   xs[1] = xscoll[1] + dt*vsnew[1];
   xs[2] = xscoll[2] + dt*vsnew[2];
 
   if (triclinic) domain->x2lamda(xs,xs);
 
   if (xs[0] < srdlo[0] || xs[0] > srdhi[0] || 
       xs[1] < srdlo[1] || xs[1] > srdhi[1] || 
       xs[2] < srdlo[2] || xs[2] > srdhi[2]) {
     printf("Bad SRD particle move\n");
-    printf("  particle %d on proc %d at timestep %d\n",
-	   atom->tag[i],me,update->ntimestep);
+    char fstr[64];
+    sprintf(fstr,"  particle %%d on proc %%d at timestep %s\n",BIGINT_FORMAT);
+    printf(fstr,atom->tag[i],me,update->ntimestep);
     printf("  xnew %g %g %g\n",xs[0],xs[1],xs[2]);
     printf("  srdlo/hi x %g %g\n",srdlo[0],srdhi[0]);
     printf("  srdlo/hi y %g %g\n",srdlo[1],srdhi[1]);
     printf("  srdlo/hi z %g %g\n",srdlo[2],srdhi[2]);
     error->warning("Fix srd particle moved outside valid domain");
   }
 
   if (triclinic) domain->lamda2x(xs,xs);
 
   ix = static_cast<int> ((xs[0]-xblo2)*bininv2x);
   iy = static_cast<int> ((xs[1]-yblo2)*bininv2y);
   iz = static_cast<int> ((xs[2]-zblo2)*bininv2z);
   return iz*nbin2y*nbin2x + iy*nbin2x + ix;
 }
 
 /* ----------------------------------------------------------------------
    setup all SRD parameters with big particles
 ------------------------------------------------------------------------- */
 
 void FixSRD::parameterize()
 {
   double PI = 4.0*atan(1.0);
 
   // timesteps
 
   dt_big = update->dt;
   dt_srd = nevery * update->dt;
 
   // maxbigdiam,minbigdiam = max/min diameter of any big particle
   // big particle must either have radius > 0 or shape > 0 defined
   // apply radfactor at end
 
   double *radius = atom->radius;
   double **shape = atom->shape;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   any_ellipsoids = 0;
   maxbigdiam = 0.0;
   minbigdiam = BIG;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & biggroupbit) {
       if (radius) {
 	if (radius[i] == 0.0)
 	  error->one("Big particle in fix srd cannot be point particle");
 	maxbigdiam = MAX(maxbigdiam,2.0*radius[i]);
 	minbigdiam = MIN(minbigdiam,2.0*radius[i]);
       } else {
 	if (shape[type[i]][0] == 0.0)
 	  error->one("Big particle in fix srd cannot be point particle");
 	maxbigdiam = MAX(maxbigdiam,2.0*shape[type[i]][0]);
 	maxbigdiam = MAX(maxbigdiam,2.0*shape[type[i]][1]);
 	maxbigdiam = MAX(maxbigdiam,2.0*shape[type[i]][2]);
 	minbigdiam = MIN(minbigdiam,2.0*shape[type[i]][0]);
 	minbigdiam = MIN(minbigdiam,2.0*shape[type[i]][1]);
 	minbigdiam = MIN(minbigdiam,2.0*shape[type[i]][2]);
 	if (shape[type[i]][0] != shape[type[i]][1] ||
 	    shape[type[i]][0] != shape[type[i]][2])
 	  any_ellipsoids = 1;
       }
     }
 
   double tmp = maxbigdiam;
   MPI_Allreduce(&tmp,&maxbigdiam,1,MPI_DOUBLE,MPI_MAX,world);
   tmp = minbigdiam;
   MPI_Allreduce(&tmp,&minbigdiam,1,MPI_DOUBLE,MPI_MIN,world);
 
   maxbigdiam *= radfactor;
   minbigdiam *= radfactor;
 
   int itmp = any_ellipsoids;
   MPI_Allreduce(&itmp,&any_ellipsoids,1,MPI_INT,MPI_MAX,world);
 
   // big particles are only torqued if are ellipsoids or NOSLIP collisions
 
   if (any_ellipsoids == 0 && collidestyle == SLIP) torqueflag = 0;
   else torqueflag = 1;
 
   // mass of SRD particles, require monodispersity
 
   double *rmass = atom->rmass;
   double *mass = atom->mass;
 
   int flag = 0;
   mass_srd = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       if (rmass) {
 	if (mass_srd == 0.0) mass_srd = rmass[i];
 	else if (rmass[i] != mass_srd) flag = 1;
       } else {
 	if (mass_srd == 0.0) mass_srd = mass[type[i]];
 	else if (mass[type[i]] != mass_srd) flag = 1;
       }
     }
 
   int flagall;
   MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_MAX,world);
   if (flagall) 
     error->all("Fix srd requires SRD particles all have same mass");
 
   // set temperature and lamda of SRD particles from each other
   // lamda = dt_srd * sqrt(boltz * temperature_srd / mass_srd);
 
   if (lamdaflag == 0)
     lamda = dt_srd * sqrt(force->boltz*temperature_srd/mass_srd/force->mvv2e);
   else
     temperature_srd = force->mvv2e * 
       (lamda/dt_srd)*(lamda/dt_srd) * mass_srd/force->boltz;
 
   // vmax = maximum velocity of an SRD particle
   // dmax = maximum distance an SRD can move = 4*lamda = vmax * dt_srd
 
   sigma = lamda/dt_srd;
   dmax = 4.0*lamda;
   vmax = dmax/dt_srd;
   vmaxsq = vmax*vmax;
 
   // volbig = total volume of all big particles
   // apply radfactor to reduce final volume
 
   double volbig = 0.0;
 
   if (dimension == 3) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & biggroupbit) {
 	if (radius)
 	  volbig += 4.0/3.0*PI*radius[i]*radius[i]*radius[i];
 	else
 	  volbig += 4.0/3.0*PI *
 	    shape[type[i]][0]*shape[type[i]][1]*shape[type[i]][2];
       }
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & biggroupbit) {
 	if (radius)
 	  volbig += PI*radius[i]*radius[i];
 	else
 	  volbig += PI*shape[type[i]][0]*shape[type[i]][1];
       }
   }
 
   tmp = volbig;
   MPI_Allreduce(&tmp,&volbig,1,MPI_DOUBLE,MPI_SUM,world);
 
   if (dimension == 3) volbig *= radfactor*radfactor*radfactor;
   else volbig *= radfactor*radfactor;
 
   // particle counts
 
   bigint mbig = 0;
   if (bigexist) mbig = group->count(biggroup);
   bigint nsrd = group->count(igroup);
 
   // mass_big = total mass of all big particles
 
   mass_big = 0.0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & biggroupbit) {
       if (rmass) mass_big += rmass[i];
       else mass_big += mass[type[i]];
     }
 
   tmp = mass_big;
   MPI_Allreduce(&tmp,&mass_big,1,MPI_DOUBLE,MPI_SUM,world);
 
   // mass density ratio = big / SRD
 
   double density_big = 0.0;
   if (bigexist) density_big = mass_big / volbig;
 
   double volsrd,density_srd;
   if (dimension == 3) {
     volsrd = (domain->xprd * domain->yprd * domain->zprd) - volbig;
     density_srd = nsrd * mass_srd / 
       (domain->xprd*domain->yprd*domain->zprd - volbig);
   } else {
     volsrd = (domain->xprd * domain->yprd) - volbig;
     density_srd = nsrd * mass_srd /
       (domain->xprd*domain->yprd - volbig);
   }
 
   double mdratio = density_big/density_srd;
 
   // create grid for binning/rotating SRD particles from gridsrd
 
   setup_velocity_bins();
 
   // binsize3 = binsize1 in box units (not lamda units for triclinic)
 
   double binsize3x = binsize1x;
   double binsize3y = binsize1y;
   double binsize3z = binsize1z;
   if (triclinic) {
     binsize3x = binsize1x * domain->xprd;
     binsize3y = binsize1y * domain->yprd;
     binsize3z = binsize1z * domain->zprd;
   }
 
   // srd_per_grid = # of SRD particles per SRD grid cell
 
   double ncell;
   if (dimension == 3)
     ncell = volsrd / (binsize3x*binsize3y*binsize3z);
   else
     ncell = volsrd / (binsize3x*binsize3y);
 
   srd_per_cell = (double) nsrd / ncell;
 
   // kinematic viscosity of SRD fluid
   // output in cm^2/sec units, converted by xxt2kmu
 
   double viscosity;
   if (dimension == 3)
     viscosity = gridsrd*gridsrd/(18.0*dt_srd) * 
       (1.0-(1.0-exp(-srd_per_cell))/srd_per_cell) + 
       (force->boltz*temperature_srd*dt_srd/(4.0*mass_srd*force->mvv2e)) *
       ((srd_per_cell+2.0)/(srd_per_cell-1.0));
   else
     viscosity = 
       (force->boltz*temperature_srd*dt_srd/(2.0*mass_srd*force->mvv2e)) *
       (srd_per_cell/(srd_per_cell-1.0 + exp(-srd_per_cell)) - 1.0) +
       (gridsrd*gridsrd)/(12.0*dt_srd) * 
       ((srd_per_cell-1.0 + exp(-srd_per_cell))/srd_per_cell);
   viscosity *= force->xxt2kmu;
 
   // print SRD parameters
 
   if (me == 0) {
+    char str[64];
+    sprintf(str,"  SRD/big particles = %s %s\n",BIGINT_FORMAT,BIGINT_FORMAT);
     if (screen) {
       fprintf(screen,"SRD info:\n");
-      fprintf(screen,"  SRD/big particles = %lu %lu\n",nsrd,mbig);
+      fprintf(screen,str,nsrd,mbig);
       fprintf(screen,"  big particle diameter max/min = %g %g\n",
 	      maxbigdiam,minbigdiam);
       fprintf(screen,"  SRD temperature & lamda = %g %g\n",
 	      temperature_srd,lamda);
       fprintf(screen,"  SRD max distance & max velocity = %g %g\n",dmax,vmax);
       fprintf(screen,"  SRD grid counts: %d %d %d\n",nbin1x,nbin1y,nbin1z);
       fprintf(screen,"  SRD grid size: request, actual (xyz) = %g, %g %g %g\n",
 	      gridsrd,binsize3x,binsize3y,binsize3z);
       fprintf(screen,"  SRD per actual grid cell = %g\n",srd_per_cell);
       fprintf(screen,"  SRD viscosity = %g\n",viscosity);
       fprintf(screen,"  big/SRD mass density ratio = %g\n",mdratio);
     }
     if (logfile) {
       fprintf(logfile,"SRD info:\n");
-      fprintf(logfile,"  SRD/big particles = %lu %lu\n",nsrd,mbig);
+      fprintf(logfile,str,nsrd,mbig);
       fprintf(logfile,"  big particle diameter max/min = %g %g\n",
 	      maxbigdiam,minbigdiam);
       fprintf(logfile,"  SRD temperature & lamda = %g %g\n",
 	      temperature_srd,lamda);
       fprintf(logfile,"  SRD max distance & max velocity = %g %g\n",dmax,vmax);
       fprintf(logfile,"  SRD grid counts: %d %d %d\n",nbin1x,nbin1y,nbin1z);
       fprintf(logfile,"  SRD grid size: request, actual (xyz) = %g, %g %g %g\n",
 	      gridsrd,binsize3x,binsize3y,binsize3z);
       fprintf(logfile,"  SRD per actual grid cell = %g\n",srd_per_cell);
       fprintf(logfile,"  SRD viscosity = %g\n",viscosity);
       fprintf(logfile,"  big/SRD mass density ratio = %g\n",mdratio);
     }
   }
 
   // error if less than 1 SRD bin per processor in some dim
 
   if (nbin1x < comm->procgrid[0] || nbin1y < comm->procgrid[1] || 
       nbin1z < comm->procgrid[2]) 
     error->all("Fewer SRD bins than processors in some dimension");
 
   // check if SRD bins are within tolerance for shape and size
 
   int tolflag = 0;
   if (binsize3y/binsize3x > 1.0+cubictol ||
       binsize3x/binsize3y > 1.0+cubictol) tolflag = 1;
   if (dimension == 3) {
     if (binsize3z/binsize3x > 1.0+cubictol ||
 	binsize3x/binsize3z > 1.0+cubictol) tolflag = 1;
   }
 
   if (tolflag) {
     if (cubicflag == CUBIC_ERROR)
       error->all("SRD bins for fix srd are not cubic enough");
     if (me == 0)
       error->warning("SRD bins for fix srd are not cubic enough");
   }
 
   tolflag = 0;
   if (binsize3x/gridsrd > 1.0+cubictol || gridsrd/binsize3x > 1.0+cubictol)
     tolflag = 1;
   if (binsize3y/gridsrd > 1.0+cubictol || gridsrd/binsize3y > 1.0+cubictol)
     tolflag = 1;
   if (dimension == 3) {
     if (binsize3z/gridsrd > 1.0+cubictol || gridsrd/binsize3z > 1.0+cubictol)
       tolflag = 1;
   }
 
   if (tolflag) {
     if (cubicflag == CUBIC_ERROR)
       error->all("SRD bin size for fix srd differs from user request");
     if (me == 0)
       error->warning("SRD bin size for fix srd differs from user request");
   }
 
   // error if lamda < 0.6 of SRD grid size and no shifting allowed
   // turn on shifting in this case if allowed
 
   double maxgridsrd = MAX(binsize3x,binsize3y);
   if (dimension == 3) maxgridsrd = MAX(maxgridsrd,binsize3z);
 
   shiftflag = 0;
   if (lamda < 0.6*maxgridsrd && shiftuser == SHIFT_NO)
     error->all("Fix srd lamda must be >= 0.6 of SRD grid size");
   else if (lamda < 0.6*maxgridsrd && shiftuser == SHIFT_POSSIBLE) {
     shiftflag = 1;
     if (me == 0) 
       error->warning("SRD bin shifting turned on due to small lamda");
   } else if (shiftuser == SHIFT_YES) shiftflag = 1;
 
   // warnings
 
   if (bigexist && maxgridsrd > 0.25 * minbigdiam && me == 0)
     error->warning("Fix srd grid size > 1/4 of big particle diameter");
   if (viscosity < 0.0 && me == 0)
     error->warning("Fix srd viscosity < 0.0 due to low SRD density");
   if (bigexist && dt_big*vmax > minbigdiam && me == 0)
     error->warning("Fix srd particles may move > big particle diameter");
   if (wallexist && collidestyle == NOSLIP && shiftflag == 1)
     error->warning("Fix srd no-slip wall collisions with bin shifting");
 }
 
 /* ----------------------------------------------------------------------
    set static parameters of each big particle, owned and ghost
    called each reneighboring
    use radfactor in distance parameters
 ------------------------------------------------------------------------- */
 
 void FixSRD::big_static()
 {
   int i;
   double rad,arad,brad,crad;
 
   double *radius = atom->radius;
   double **shape = atom->shape;
   int *type = atom->type;
 
   int omega_flag = atom->omega_flag;
 
   double skinhalf = 0.5 * neighbor->skin;
 
   for (int k = 0; k < nbig; k++) {
     i = biglist[k].index;
     if (radius) {
       biglist[k].type = SPHERE;
       biglist[k].typesphere = SPHERE_RADIUS;
       biglist[k].typeangular = ANGULAR_OMEGA;
       rad = radfactor*radius[i];
       biglist[k].radius = rad;
       biglist[k].radsq = rad*rad;
       biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf);
     } else if (shape[type[i]][0] == shape[type[i]][1] && 
 	       shape[type[i]][0] == shape[type[i]][2]) {
       biglist[k].type = SPHERE;
       biglist[k].typesphere = SPHERE_SHAPE;
 
       // either atom->omega is defined or atom->angmom, cannot both be defined
 
       if (omega_flag) biglist[k].typeangular = ANGULAR_OMEGA;
       else biglist[k].typeangular = ANGULAR_ANGMOM;
 
       rad = radfactor*shape[type[i]][0];
       biglist[k].radius = rad;
       biglist[k].radsq = rad*rad;
       biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf);
     } else {
       biglist[k].type = ELLIPSOID;
       biglist[k].typeangular = ANGULAR_ANGMOM;
       arad = radfactor*shape[type[i]][0];
       brad = radfactor*shape[type[i]][1];
       crad = radfactor*shape[type[i]][2];
       biglist[k].aradsqinv = 1.0/(arad*arad);
       biglist[k].bradsqinv = 1.0/(brad*brad);
       biglist[k].cradsqinv = 1.0/(crad*crad);
       rad = MAX(arad,brad);
       rad = MAX(rad,crad);
       biglist[k].cutbinsq = (rad+skinhalf) * (rad+skinhalf);
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    set dynamics parameters of each big particle, owned and ghost
    for ELLIPSOID, need current omega and ex,ey,ez
    for SPHERE, need current omega from atom->omega or atom->angmom
    called each timestep
 ------------------------------------------------------------------------- */
 
 void FixSRD::big_dynamic()
 {
   int i,itype;
   double inertia;
 
   double **omega = atom->omega;
   double **angmom = atom->angmom;
   double **quat = atom->quat;
   double **shape = atom->shape;
   double *mass = atom->mass;
   int *type = atom->type;
 
   for (int k = 0; k < nbig; k++) {
     i = biglist[k].index;
 
     // ellipsoid with angmom
     // calculate ex,ey,ez and omega from quaternion and angmom
 
     if (biglist[k].type == ELLIPSOID) {
       exyz_from_q(quat[i],biglist[k].ex,biglist[k].ey,biglist[k].ez);
       omega_from_mq(angmom[i],biglist[k].ex,biglist[k].ey,biglist[k].ez,
 		    mass[type[i]],shape[type[i]],biglist[k].omega);
 
     // sphere with omega and shape or radius
     // set omega from atom->omega directly
 
     } else if (biglist[k].typeangular == ANGULAR_OMEGA) {
       biglist[k].omega[0] = omega[i][0];
       biglist[k].omega[1] = omega[i][1];
       biglist[k].omega[2] = omega[i][2];
 
     // sphere with angmom and shape
     // calculate omega from angmom
 
     } else if (biglist[k].typeangular == ANGULAR_ANGMOM) {
       itype = type[i];
       inertia = INERTIA * mass[itype]*shape[itype][0]*shape[itype][0];
       biglist[k].omega[0] = angmom[i][0] / inertia;
       biglist[k].omega[1] = angmom[i][1] / inertia;
       biglist[k].omega[2] = angmom[i][2] / inertia;
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    set bounds for big and SRD particle movement
    called at setup() and when box size changes (but not shape)
 ------------------------------------------------------------------------- */
 
 void FixSRD::setup_bounds()
 {
   // triclinic scale factors
   // convert a real distance (perpendicular to box face) to a lamda distance
 
   double length0,length1,length2;
   if (triclinic) {
     double *h_inv = domain->h_inv;
     length0 = sqrt(h_inv[0]*h_inv[0] + h_inv[5]*h_inv[5] + h_inv[4]*h_inv[4]);
     length1 = sqrt(h_inv[1]*h_inv[1] + h_inv[3]*h_inv[3]);
     length2 = h_inv[2];
   }
 
   // collision object = CO = big particle or wall
   // big particles can be owned or ghost or unknown, walls are all owned
   // dist_ghost = distance from sub-domain (SD) that
   //   owned/ghost CO may move to before reneigh,
   //   used to bound search bins in setup_search_bins()
   // dist_srd = distance from SD at which SRD could collide with unknown CO,
   //   used to error check bounds of SRD movement after collisions via srdlo/hi
   // dist_srd_reneigh = distance from SD at which an SRD should trigger
   //   a reneigh, b/c next SRD move might overlap with unknown CO,
   //   used for SRD triggering of reneighboring via srdlo/hi_reneigh
   // onemove = max distance an SRD can move in one step
   // if big_particles (and possibly walls):
   //   dist_ghost = cut + 1/2 skin due to moving away before reneigh
   //   dist_srd = cut - 1/2 skin - 1/2 diam due to ghost CO moving towards
   //   dist_reneigh = dist_srd - onemove
   // if walls and no big particles:
   //   dist_ghost = 0.0, since not used
   // if no big particles or walls:
   //   dist_ghost and dist_srd = 0.0, since not used since no search bins
   //   dist_srd_reneigh = subsize - onemove = 
   //     max distance to move without being lost during comm->exchange()
   //   subsize = perp distance between sub-domain faces (orthog or triclinic)
 
   double cut = MAX(neighbor->cutneighmax,comm->cutghostuser);
   double onemove = dt_big*vmax;
 
   if (bigexist) {
     dist_ghost = cut + 0.5*neighbor->skin;
     dist_srd = cut - 0.5*neighbor->skin - 0.5*maxbigdiam;
     dist_srd_reneigh = dist_srd - onemove;
   } else if (wallexist) {
     dist_ghost = 4*onemove;
     dist_srd = 4*onemove;
     dist_srd_reneigh = 4*onemove - onemove;
   } else {
     dist_ghost = dist_srd = 0.0;
     double subsize;
     if (triclinic == 0) {
       subsize = domain->prd[0]/comm->procgrid[0];
       subsize = MIN(subsize,domain->prd[1]/comm->procgrid[1]);
       if (dimension == 3) 
 	subsize = MIN(subsize,domain->prd[2]/comm->procgrid[2]);
     } else {
       subsize = 1.0/comm->procgrid[0]/length0;
       subsize = MIN(subsize,1.0/comm->procgrid[1]/length1);
       if (dimension == 3) 
 	subsize = MIN(subsize,1.0/comm->procgrid[2]/length2);
     }
     dist_srd_reneigh = subsize - onemove;
   }
 
   // lo/hi = bbox on this proc which SRD particles must stay inside
   // lo/hi reneigh = bbox on this proc outside of which SRDs trigger a reneigh
   // for triclinic, these bbox are in lamda units
 
   if (triclinic == 0) {
     srdlo[0] = domain->sublo[0] - dist_srd;
     srdhi[0] = domain->subhi[0] + dist_srd;
     srdlo[1] = domain->sublo[1] - dist_srd;
     srdhi[1] = domain->subhi[1] + dist_srd;
     srdlo[2] = domain->sublo[2] - dist_srd;
     srdhi[2] = domain->subhi[2] + dist_srd;
 
     srdlo_reneigh[0] = domain->sublo[0] - dist_srd_reneigh;
     srdhi_reneigh[0] = domain->subhi[0] + dist_srd_reneigh;
     srdlo_reneigh[1] = domain->sublo[1] - dist_srd_reneigh;
     srdhi_reneigh[1] = domain->subhi[1] + dist_srd_reneigh;
     srdlo_reneigh[2] = domain->sublo[2] - dist_srd_reneigh;
     srdhi_reneigh[2] = domain->subhi[2] + dist_srd_reneigh;
 
   } else {
     srdlo[0] = domain->sublo_lamda[0] - dist_srd*length0;
     srdhi[0] = domain->subhi_lamda[0] + dist_srd*length0;
     srdlo[1] = domain->sublo_lamda[1] - dist_srd*length1;
     srdhi[1] = domain->subhi_lamda[1] + dist_srd*length1;
     srdlo[2] = domain->sublo_lamda[2] - dist_srd*length2;
     srdhi[2] = domain->subhi_lamda[2] + dist_srd*length2;
 
     srdlo_reneigh[0] = domain->sublo_lamda[0] - dist_srd_reneigh*length0;
     srdhi_reneigh[0] = domain->subhi_lamda[0] + dist_srd_reneigh*length0;
     srdlo_reneigh[1] = domain->sublo_lamda[1] - dist_srd_reneigh*length1;
     srdhi_reneigh[1] = domain->subhi_lamda[1] + dist_srd_reneigh*length1;
     srdlo_reneigh[2] = domain->sublo_lamda[2] - dist_srd_reneigh*length2;
     srdhi_reneigh[2] = domain->subhi_lamda[2] + dist_srd_reneigh*length2;
   }
 }
 
 /* ----------------------------------------------------------------------
    setup bins used for binning SRD particles for velocity reset
    gridsrd = desired bin size
    also setup bin shifting parameters
    also setup comm of bins that straddle processor boundaries
    called at beginning of each run
    called every reneighbor if box size changes, but not if box shape changes
 ------------------------------------------------------------------------- */
 
 void FixSRD::setup_velocity_bins()
 {
   // require integer # of bins across global domain
 
   nbin1x = static_cast<int> (domain->xprd/gridsrd + 0.5);
   nbin1y = static_cast<int> (domain->yprd/gridsrd + 0.5);
   nbin1z = static_cast<int> (domain->zprd/gridsrd + 0.5);
   if (dimension == 2) nbin1z = 1;
 
   if (nbin1x == 0) nbin1x = 1;
   if (nbin1y == 0) nbin1y = 1;
   if (nbin1z == 0) nbin1z = 1;
 
   if (triclinic == 0) {
     binsize1x = domain->xprd / nbin1x;
     binsize1y = domain->yprd / nbin1y;
     binsize1z = domain->zprd / nbin1z;
     bininv1x = 1.0/binsize1x;
     bininv1y = 1.0/binsize1y;
     bininv1z = 1.0/binsize1z;
   } else {
     binsize1x = 1.0 / nbin1x;
     binsize1y = 1.0 / nbin1y;
     binsize1z = 1.0 / nbin1z;
     bininv1x = nbin1x;
     bininv1y = nbin1y;
     bininv1z = nbin1z;
   }
 
   nbins1 = nbin1x*nbin1y*nbin1z;
 
   // setup two shifts, 0 = no shift, 1 = shift
   // initialize no shift case since static
   // shift case is dynamic, has to be initialized each time shift occurs
   // setup_velocity_shift allocates memory for vbin and sendlist/recvlist
 
   double *boxlo;
   if (triclinic == 0) boxlo = domain->boxlo;
   else boxlo = domain->boxlo_lamda;
 
   shifts[0].corner[0] = boxlo[0];
   shifts[0].corner[1] = boxlo[1];
   shifts[0].corner[2] = boxlo[2];
   setup_velocity_shift(0,0);
 
   shifts[1].corner[0] = boxlo[0];
   shifts[1].corner[1] = boxlo[1];
   shifts[1].corner[2] = boxlo[2];
   setup_velocity_shift(1,0);
 
   // allocate binhead based on max # of bins in either shift
 
   int max = shifts[0].nbins;
   max = MAX(max,shifts[1].nbins);
 
   if (max > maxbin1) {
     memory->sfree(binhead);
     maxbin1 = max;
     binhead = (int *) memory->smalloc(max*sizeof(int),"fix/srd:binhead");
   }
 
   // allocate sbuf,rbuf based on biggest bin message
 
   max = 0;
   for (int ishift = 0; ishift < 2; ishift++)
     for (int iswap = 0; iswap < 2*dimension; iswap++) {
       max = MAX(max,shifts[ishift].bcomm[iswap].nsend);
       max = MAX(max,shifts[ishift].bcomm[iswap].nrecv);
     }
 
   if (max > maxbuf) {
     memory->sfree(sbuf1);
     memory->sfree(sbuf2);
     memory->sfree(rbuf1);
     memory->sfree(rbuf2);
     maxbuf = max;
     sbuf1 = (double *) 
       memory->smalloc(max*VBINSIZE*sizeof(double),"fix/srd:sbuf");
     sbuf2 = (double *) 
       memory->smalloc(max*VBINSIZE*sizeof(double),"fix/srd:sbuf");
     rbuf1 = (double *) 
       memory->smalloc(max*VBINSIZE*sizeof(double),"fix/srd:rbuf");
     rbuf2 = (double *) 
       memory->smalloc(max*VBINSIZE*sizeof(double),"fix/srd:rbuf");
   }
 
   // commflag = 1 if any comm required due to bins overlapping proc boundaries
 
   shifts[0].commflag = 0;
   if (nbin1x % comm->procgrid[0]) shifts[0].commflag = 1;
   if (nbin1y % comm->procgrid[1]) shifts[0].commflag = 1;
   if (nbin1z % comm->procgrid[2]) shifts[0].commflag = 1;
   shifts[1].commflag = 1;
 }
 
 /* ----------------------------------------------------------------------
    setup velocity shift parameters
    set binlo[]/binhi[] and nbins,nbinx,nbiny,nbinz for this proc
    set bcomm[6] params based on bin overlaps with proc boundaries
    no comm of bins across non-periodic global boundaries
    set vbin owner flags for bins I am owner of
    ishift = 0, dynamic = 0:
      set all settings since are static
      allocate and set bcomm params and vbins
      do not comm bins that align with proc boundaries
    ishift = 1, dynamic = 0:
      set max bounds on bin counts and message sizes
      allocate and set bcomm params and vbins based on max bounds
      other settings will later change dynamically
    ishift = 1, dynamic = 1:
      set actual bin bounds and counts for specific shift
      set bcomm params and vbins (already allocated)
    called by setup_velocity_bins() and reset_velocities()
 ------------------------------------------------------------------------- */
 
 void FixSRD::setup_velocity_shift(int ishift, int dynamic)
 {
   int i,j,k,m,id,nsend;
   int *sendlist;
   BinComm *first,*second;
   BinAve *vbin;
 
   double *sublo,*subhi;
   if (triclinic == 0) {
     sublo = domain->sublo;
     subhi = domain->subhi;
   } else {
     sublo = domain->sublo_lamda;
     subhi = domain->subhi_lamda;
   }
 
   int *binlo = shifts[ishift].binlo;
   int *binhi = shifts[ishift].binhi;
   double *corner = shifts[ishift].corner;
   int *procgrid = comm->procgrid;
   int *myloc = comm->myloc;
   
   binlo[0] = static_cast<int> ((sublo[0]-corner[0])*bininv1x);
   binlo[1] = static_cast<int> ((sublo[1]-corner[1])*bininv1y);
   binlo[2] = static_cast<int> ((sublo[2]-corner[2])*bininv1z);
   if (dimension == 2) shifts[ishift].binlo[2] = 0;
   
   binhi[0] = static_cast<int> ((subhi[0]-corner[0])*bininv1x);
   binhi[1] = static_cast<int> ((subhi[1]-corner[1])*bininv1y);
   binhi[2] = static_cast<int> ((subhi[2]-corner[2])*bininv1z);
   if (dimension == 2) shifts[ishift].binhi[2] = 0;
 
   if (ishift == 0) {
     if (myloc[0]*nbin1x % procgrid[0] == 0)
       binlo[0] = myloc[0]*nbin1x/procgrid[0];
     if (myloc[1]*nbin1y % procgrid[1] == 0)
       binlo[1] = myloc[1]*nbin1y/procgrid[1];
     if (myloc[2]*nbin1z % procgrid[2] == 0)
       binlo[2] = myloc[2]*nbin1z/procgrid[2];
     
     if ((myloc[0]+1)*nbin1x % procgrid[0] == 0)
       binhi[0] = (myloc[0]+1)*nbin1x/procgrid[0] - 1;
     if ((myloc[1]+1)*nbin1y % procgrid[1] == 0)
       binhi[1] = (myloc[1]+1)*nbin1y/procgrid[1] - 1;
     if ((myloc[2]+1)*nbin1z % procgrid[2] == 0)
       binhi[2] = (myloc[2]+1)*nbin1z/procgrid[2] - 1;
   }
   
   int nbinx = binhi[0] - binlo[0] + 1;
   int nbiny = binhi[1] - binlo[1] + 1;
   int nbinz = binhi[2] - binlo[2] + 1;
 
   // allow for one extra bin if shifting will occur
   
   if (ishift == 1 && dynamic == 0) {
     nbinx++;
     nbiny++;
     if (dimension == 3) nbinz++;
   }
   
   int nbins = nbinx*nbiny*nbinz;
   int nbinxy = nbinx*nbiny;
   int nbinsq = nbinx*nbiny;
   nbinsq = MAX(nbiny*nbinz,nbinsq);
   nbinsq = MAX(nbinx*nbinz,nbinsq);
   
   shifts[ishift].nbins = nbins;
   shifts[ishift].nbinx = nbinx;
   shifts[ishift].nbiny = nbiny;
   shifts[ishift].nbinz = nbinz;
 
   int reallocflag = 0;
   if (dynamic == 0 && nbinsq > shifts[ishift].maxbinsq) {
     shifts[ishift].maxbinsq = nbinsq;
     reallocflag = 1;
   }
 
   // bcomm neighbors
   // first = send in lo direction, recv from hi direction
   // second = send in hi direction, recv from lo direction
   
   if (dynamic == 0) {
     shifts[ishift].bcomm[0].sendproc = comm->procneigh[0][0];
     shifts[ishift].bcomm[0].recvproc = comm->procneigh[0][1];
     shifts[ishift].bcomm[1].sendproc = comm->procneigh[0][1];
     shifts[ishift].bcomm[1].recvproc = comm->procneigh[0][0];
     shifts[ishift].bcomm[2].sendproc = comm->procneigh[1][0];
     shifts[ishift].bcomm[2].recvproc = comm->procneigh[1][1];
     shifts[ishift].bcomm[3].sendproc = comm->procneigh[1][1];
     shifts[ishift].bcomm[3].recvproc = comm->procneigh[1][0];
     shifts[ishift].bcomm[4].sendproc = comm->procneigh[2][0];
     shifts[ishift].bcomm[4].recvproc = comm->procneigh[2][1];
     shifts[ishift].bcomm[5].sendproc = comm->procneigh[2][1];
     shifts[ishift].bcomm[5].recvproc = comm->procneigh[2][0];
   }
   
   // set nsend,nrecv and sendlist,recvlist for each swap in x,y,z
   // set nsend,nrecv = 0 if static bins align with proc boundary
   //   or to prevent dynamic bin swapping across non-periodic global boundary
   // allocate sendlist,recvlist only for dynamic = 0
   
   first = &shifts[ishift].bcomm[0];
   second = &shifts[ishift].bcomm[1];
   
   first->nsend = first->nrecv = second->nsend = second->nrecv = nbiny*nbinz;
   if (ishift == 0) {
     if (myloc[0]*nbin1x % procgrid[0] == 0)
       first->nsend = second->nrecv = 0;
     if ((myloc[0]+1)*nbin1x % procgrid[0] == 0)
       second->nsend = first->nrecv = 0;
   } else if (dynamic == 0 && domain->xperiodic == 0) {
     if (myloc[0] == 0) first->nsend = second->nrecv = 0;
     if (myloc[0] == procgrid[0]-1) second->nsend = first->nrecv = 0;
   }
 
   if (reallocflag) {
     memory->sfree(first->sendlist);
     memory->sfree(first->recvlist);
     memory->sfree(second->sendlist);
     memory->sfree(second->recvlist);
     first->sendlist = (int *) 
       memory->smalloc(nbinsq*sizeof(int),"fix/srd:sendlist");
     first->recvlist = (int *) 
       memory->smalloc(nbinsq*sizeof(int),"fix/srd:sendlist");
     second->sendlist = (int *) 
       memory->smalloc(nbinsq*sizeof(int),"fix/srd:sendlist");
     second->recvlist = (int *) 
       memory->smalloc(nbinsq*sizeof(int),"fix/srd:sendlist");
   }
 
   m = 0;
   i = 0;
   for (j = 0; j < nbiny; j++) 
     for (k = 0; k < nbinz; k++) {
       id = k*nbinxy + j*nbinx + i;
       first->sendlist[m] = second->recvlist[m] = id;
       m++;
     }
   m = 0;
   i = nbinx-1;
   for (j = 0; j < nbiny; j++) 
     for (k = 0; k < nbinz; k++) {
       id = k*nbinxy + j*nbinx + i;
       second->sendlist[m] = first->recvlist[m] = id;
       m++;
     }
   
   first = &shifts[ishift].bcomm[2];
   second = &shifts[ishift].bcomm[3];
   
   first->nsend = first->nrecv = second->nsend = second->nrecv = nbinx*nbinz;
   if (ishift == 0) {
     if (myloc[1]*nbin1y % procgrid[1] == 0)
       first->nsend = second->nrecv = 0;
     if ((myloc[1]+1)*nbin1y % procgrid[1] == 0)
       second->nsend = first->nrecv = 0;
   } else if (dynamic == 0 && domain->yperiodic == 0) {
     if (myloc[1] == 0) first->nsend = second->nrecv = 0;
     if (myloc[1] == procgrid[1]-1) second->nsend = first->nrecv = 0;
   }
   
   if (reallocflag) {
     memory->sfree(first->sendlist);
     memory->sfree(first->recvlist);
     memory->sfree(second->sendlist);
     memory->sfree(second->recvlist);
     first->sendlist = (int *) 
       memory->smalloc(nbinsq*sizeof(int),"fix/srd:sendlist");
     first->recvlist = (int *) 
       memory->smalloc(nbinsq*sizeof(int),"fix/srd:sendlist");
     second->sendlist = (int *) 
       memory->smalloc(nbinsq*sizeof(int),"fix/srd:sendlist");
     second->recvlist = (int *) 
       memory->smalloc(nbinsq*sizeof(int),"fix/srd:sendlist");
   }
   
   m = 0;
   j = 0;
   for (i = 0; i < nbinx; i++) 
     for (k = 0; k < nbinz; k++) {
       id = k*nbinxy + j*nbinx + i;
       first->sendlist[m] = second->recvlist[m] = id;
       m++;
     }
   m = 0;
   j = nbiny-1;
   for (i = 0; i < nbinx; i++) 
     for (k = 0; k < nbinz; k++) {
       id = k*nbinxy + j*nbinx + i;
       second->sendlist[m] = first->recvlist[m] = id;
       m++;
     }
   
   if (dimension == 3) {
     first = &shifts[ishift].bcomm[4];
     second = &shifts[ishift].bcomm[5];
     
     first->nsend = first->nrecv = second->nsend = second->nrecv = nbinx*nbiny;
     if (ishift == 0) {
       if (myloc[2]*nbin1z % procgrid[2] == 0)
 	first->nsend = second->nrecv = 0;
       if ((myloc[2]+1)*nbin1z % procgrid[2] == 0)
 	second->nsend = first->nrecv = 0;
     } else if (dynamic == 0 && domain->zperiodic == 0) {
       if (myloc[2] == 0) first->nsend = second->nrecv = 0;
       if (myloc[2] == procgrid[2]-1) second->nsend = first->nrecv = 0;
     }
     
     if (reallocflag) {
       memory->sfree(first->sendlist);
       memory->sfree(first->recvlist);
       memory->sfree(second->sendlist);
       memory->sfree(second->recvlist);
       first->sendlist = (int *) 
 	memory->smalloc(nbinx*nbiny*sizeof(int),"fix/srd:sendlist");
       first->recvlist = (int *) 
 	memory->smalloc(nbinx*nbiny*sizeof(int),"fix/srd:sendlist");
       second->sendlist = (int *) 
 	memory->smalloc(nbinx*nbiny*sizeof(int),"fix/srd:sendlist");
       second->recvlist = (int *) 
 	memory->smalloc(nbinx*nbiny*sizeof(int),"fix/srd:sendlist");
     }
     
     m = 0;
     k = 0;
     for (i = 0; i < nbinx; i++) 
       for (j = 0; j < nbiny; j++) {
 	id = k*nbinxy + j*nbinx + i;
 	first->sendlist[m] = second->recvlist[m] = id;
 	m++;
       }
     m = 0;
     k = nbinz-1;
     for (i = 0; i < nbinx; i++) 
       for (j = 0; j < nbiny; j++) {
 	id = k*nbinxy + j*nbinx + i;
 	second->sendlist[m] = first->recvlist[m] = id;
 	m++;
       }
   }
   
   // allocate vbins, only for dynamic = 0
   
   if (dynamic == 0 && nbins > shifts[ishift].maxvbin) {
     memory->sfree(shifts[ishift].vbin);
     shifts[ishift].maxvbin = nbins;
     shifts[ishift].vbin = (BinAve *) 
       memory->smalloc(nbins*sizeof(BinAve),"fix/srd:vbin");
   }
   
   // for vbins I own, set owner = 1
   // if bin never sent to anyone, I own it
   // if bin sent to lower numbered proc, I do not own it
   // if bin sent to self, I do not own it on even swap (avoids double counting)
   
   vbin = shifts[ishift].vbin;
   for (i = 0; i < nbins; i++) vbin[i].owner = 1;
   for (int iswap = 0; iswap < 2*dimension; iswap++) {
     if (shifts[ishift].bcomm[iswap].sendproc > me) continue;
     if (shifts[ishift].bcomm[iswap].sendproc == me && iswap % 2 == 0) continue;
     nsend = shifts[ishift].bcomm[iswap].nsend;
     sendlist = shifts[ishift].bcomm[iswap].sendlist;
     for (m = 0; m < nsend; m++) vbin[sendlist[m]].owner = 0;
   }
 
   // if triclinic and streamflag:
   // set xctr (in lamda units) for all nbins so can compute bin vstream
 
   if (triclinic && streamflag) {
     m = 0;
     for (k = 0; k < nbinz; k++)
       for (j = 0; j < nbiny; j++)
 	for (i = 0; i < nbinx; i++) {
 	  vbin[m].xctr[0] = corner[0] + (i+binlo[0]+0.5)/nbin1x;
 	  vbin[m].xctr[1] = corner[1] + (j+binlo[1]+0.5)/nbin1y;
 	  vbin[m].xctr[2] = corner[2] + (k+binlo[2]+0.5)/nbin1z;
 	  m++;
 	}
   }
 }
 
 /* ----------------------------------------------------------------------
    setup bins used for big and SRD particle searching
    gridsearch = desired bin size
    bins are orthogonal whether simulation box is orthogonal or triclinic
    for orthogonal boxes, called at each setup since cutghost may change
    for triclinic boxes, called at every reneigh, since tilt may change
    sets the following:
      nbin2 xyz = # of bins in each dim
      binsize2 and bininv2 xyz = size of bins in each dim
      xyz blo2 = origin of bins
 ------------------------------------------------------------------------- */
 
 void FixSRD::setup_search_bins()
 {
   // subboxlo/hi = real space bbox which 
   //   owned/ghost big particles or walls can be in
   // start with bounding box for my sub-domain, add dist_ghost
   // for triclinic, need to:
   //   a) convert dist_ghost to lamda space via length012
   //   b) lo/hi = sub-domain big particle bbox in lamda space
   //   c) convert lo/hi to real space bounding box via domain->bbox()
   //   similar to neighbor::setup_bins() and comm::cutghost[] calculation
 
   double subboxlo[3],subboxhi[3];
 
   if (triclinic == 0) {
     subboxlo[0] = domain->sublo[0] - dist_ghost;
     subboxlo[1] = domain->sublo[1] - dist_ghost;
     subboxlo[2] = domain->sublo[2] - dist_ghost;
     subboxhi[0] = domain->subhi[0] + dist_ghost;
     subboxhi[1] = domain->subhi[1] + dist_ghost;
     subboxhi[2] = domain->subhi[2] + dist_ghost;
   } else {
     double *h_inv = domain->h_inv;
     double length0,length1,length2;
     length0 = sqrt(h_inv[0]*h_inv[0] + h_inv[5]*h_inv[5] + h_inv[4]*h_inv[4]);
     length1 = sqrt(h_inv[1]*h_inv[1] + h_inv[3]*h_inv[3]);
     length2 = h_inv[2];
     double lo[3],hi[3];
     lo[0] = domain->sublo_lamda[0] - dist_ghost*length0;
     lo[1] = domain->sublo_lamda[1] - dist_ghost*length1;
     lo[2] = domain->sublo_lamda[2] - dist_ghost*length2;
     hi[0] = domain->subhi_lamda[0] + dist_ghost*length0;
     hi[1] = domain->subhi_lamda[1] + dist_ghost*length1;
     hi[2] = domain->subhi_lamda[2] + dist_ghost*length2;
     domain->bbox(lo,hi,subboxlo,subboxhi);
   }
 
   // require integer # of bins for that volume
 
   nbin2x = static_cast<int> ((subboxhi[0] - subboxlo[0]) / gridsearch);
   nbin2y = static_cast<int> ((subboxhi[1] - subboxlo[1]) / gridsearch);
   nbin2z = static_cast<int> ((subboxhi[2] - subboxlo[2]) / gridsearch);
   if (dimension == 2) nbin2z = 1;
 
   if (nbin2x == 0) nbin2x = 1;
   if (nbin2y == 0) nbin2y = 1;
   if (nbin2z == 0) nbin2z = 1;
 
   binsize2x = (subboxhi[0] - subboxlo[0]) / nbin2x;
   binsize2y = (subboxhi[1] - subboxlo[1]) / nbin2y;
   binsize2z = (subboxhi[2] - subboxlo[2]) / nbin2z;
   bininv2x = 1.0/binsize2x;
   bininv2y = 1.0/binsize2y;
   bininv2z = 1.0/binsize2z;
 
   // add bins on either end due to extent of big particles
   // radmax = max distance from central bin that biggest particle overlaps
   // includes skin movement
   // nx,ny,nz = max # of bins to search away from central bin
 
   double radmax = 0.5*maxbigdiam + 0.5*neighbor->skin;
 
   int nx = static_cast<int> (radmax/binsize2x) + 1;
   int ny = static_cast<int> (radmax/binsize2y) + 1;
   int nz = static_cast<int> (radmax/binsize2z) + 1;
   if (dimension == 2) nz = 0;
 
   nbin2x += 2*nx;
   nbin2y += 2*ny;
   nbin2z += 2*nz;
 
   xblo2 = subboxlo[0] - nx*binsize2x;
   yblo2 = subboxlo[1] - ny*binsize2y;
   zblo2 = subboxlo[2] - nz*binsize2z;
   if (dimension == 2) zblo2 = domain->boxlo[2];
 
   // allocate bins
   // first deallocate previous bins if necessary
 
   nbins2 = nbin2x*nbin2y*nbin2z;
   if (nbins2 > maxbin2) {
     memory->sfree(nbinbig);
     memory->destroy_2d_int_array(binbig);
     maxbin2 = nbins2;
     nbinbig = (int *) memory->smalloc(nbins2*sizeof(int),"fix/srd:nbinbig");
     binbig = memory->create_2d_int_array(nbins2,ATOMPERBIN,"fix/srd:binbig");
   }
 }
 
 /* ----------------------------------------------------------------------
    compute stencil of bin offsets for a big particle overlapping search bins
 ------------------------------------------------------------------------- */
 
 void FixSRD::setup_search_stencil()
 {
   // radmax = max distance from central bin that any big particle overlaps
   // includes skin movement
   // nx,ny,nz = max # of bins to search away from central bin
 
   double radmax = 0.5*maxbigdiam + 0.5*neighbor->skin;
   double radsq = radmax*radmax;
 
   int nx = static_cast<int> (radmax/binsize2x) + 1;
   int ny = static_cast<int> (radmax/binsize2y) + 1;
   int nz = static_cast<int> (radmax/binsize2z) + 1;
   if (dimension == 2) nz = 0;
 
   // allocate stencil array
   // deallocate previous stencil if necessary
 
   int max = (2*nx+1) * (2*ny+1) * (2*nz+1);
   if (max > maxstencil) {
     memory->destroy_2d_int_array(stencil);
     maxstencil = max;
     stencil = memory->create_2d_int_array(max,4,"fix/srd:stencil");
   }
 
   // loop over all bins
   // add bin to stencil:
   // if distance of closest corners of bin and central bin is within cutoff
 
   nstencil = 0;
   for (int k = -nz; k <= nz; k++)
     for (int j = -ny; j <= ny; j++)
       for (int i = -nx; i <= nx; i++)
 	if (bin_bin_distance(i,j,k) < radsq) {
 	  stencil[nstencil][0] = i;
 	  stencil[nstencil][1] = j;
 	  stencil[nstencil][2] = k;
 	  stencil[nstencil][3] = k*nbin2y*nbin2x + j*nbin2x + i;
 	  nstencil++;
 	}
 }
 
 /* ----------------------------------------------------------------------
    compute closest squared distance between point x and bin ibin
 ------------------------------------------------------------------------- */
 
 double FixSRD::point_bin_distance(double *x, int i, int j, int k)
 {
   double delx,dely,delz;
 
   double xlo = xblo2 + i*binsize2x;
   double xhi = xlo + binsize2x;
   double ylo = yblo2 + j*binsize2y;
   double yhi = ylo + binsize2y;
   double zlo = zblo2 + k*binsize2z;
   double zhi = zlo + binsize2z;
 
   if (x[0] < xlo) delx = xlo - x[0];
   else if (x[0] > xhi) delx = x[0] - xhi;
   else delx = 0.0;
 
   if (x[1] < ylo) dely = ylo - x[1];
   else if (x[1] > yhi) dely = x[1] - yhi;
   else dely = 0.0;
 
   if (x[2] < zlo) delz = zlo - x[2];
   else if (x[2] > zhi) delz = x[2] - zhi;
   else delz = 0.0;
 
   return (delx*delx + dely*dely + delz*delz);
 }
 
 /* ----------------------------------------------------------------------
    compute closest squared distance between 2 bins
    central bin (0,0,0) and bin (i,j,k)
 ------------------------------------------------------------------------- */
 
 double FixSRD::bin_bin_distance(int i, int j, int k)
 {
   double delx,dely,delz;
 
   if (i > 0) delx = (i-1)*binsize2x;
   else if (i == 0) delx = 0.0;
   else delx = (i+1)*binsize2x;
 
   if (j > 0) dely = (j-1)*binsize2y;
   else if (j == 0) dely = 0.0;
   else dely = (j+1)*binsize2y;
 
   if (k > 0) delz = (k-1)*binsize2z;
   else if (k == 0) delz = 0.0;
   else delz = (k+1)*binsize2z;
 
   return (delx*delx + dely*dely + delz*delz);
 }
 
 /* ----------------------------------------------------------------------
    compute space-frame ex,ey,ez from current quaternion q
    ex,ey,ez = space-frame coords of 1st,2nd,3rd principal axis
    operation is ex = q' d q = Q d, where d is (1,0,0) = 1st axis in body frame
 ------------------------------------------------------------------------- */
 
 void FixSRD::exyz_from_q(double *q, double *ex, double *ey, double *ez)
 {
   ex[0] = q[0]*q[0] + q[1]*q[1] - q[2]*q[2] - q[3]*q[3];
   ex[1] = 2.0 * (q[1]*q[2] + q[0]*q[3]);
   ex[2] = 2.0 * (q[1]*q[3] - q[0]*q[2]);
 
   ey[0] = 2.0 * (q[1]*q[2] - q[0]*q[3]);
   ey[1] = q[0]*q[0] - q[1]*q[1] + q[2]*q[2] - q[3]*q[3];
   ey[2] = 2.0 * (q[2]*q[3] + q[0]*q[1]);
 
   ez[0] = 2.0 * (q[1]*q[3] + q[0]*q[2]);
   ez[1] = 2.0 * (q[2]*q[3] - q[0]*q[1]);
   ez[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
 }
 
 /* ----------------------------------------------------------------------
    compute omega from angular momentum
    w = omega = angular velocity in space frame
    wbody = angular velocity in body frame
    set wbody component to 0.0 if inertia component is 0.0
    otherwise body can spin easily around that axis
    project space-frame angular momentum onto body axes
    and divide by principal moments
 ------------------------------------------------------------------------- */
 
 void FixSRD::omega_from_mq(double *m, double *ex, double *ey, double *ez,
 			   double mass, double *shape, double *w)
 {
   double inertia[3],wbody[3];
 
   inertia[0] = 0.2*mass * (shape[1]*shape[1]+shape[2]*shape[2]);
   inertia[1] = 0.2*mass * (shape[0]*shape[0]+shape[2]*shape[2]);
   inertia[2] = 0.2*mass * (shape[0]*shape[0]+shape[1]*shape[1]);
 
   wbody[0] = (m[0]*ex[0] + m[1]*ex[1] + m[2]*ex[2]) / inertia[0];
   wbody[1] = (m[0]*ey[0] + m[1]*ey[1] + m[2]*ey[2]) / inertia[1];
   wbody[2] = (m[0]*ez[0] + m[1]*ez[1] + m[2]*ez[2]) / inertia[2];
 
   w[0] = wbody[0]*ex[0] + wbody[1]*ey[0] + wbody[2]*ez[0];
   w[1] = wbody[0]*ex[1] + wbody[1]*ey[1] + wbody[2]*ez[1];
   w[2] = wbody[0]*ex[2] + wbody[1]*ey[2] + wbody[2]*ez[2];
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixSRD::pack_reverse_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
 
   if (torqueflag) {
     for (i = first; i < last; i++) {
       buf[m++] = flocal[i][0];
       buf[m++] = flocal[i][1];
       buf[m++] = flocal[i][2];
       buf[m++] = tlocal[i][0];
       buf[m++] = tlocal[i][1];
       buf[m++] = tlocal[i][2];
     }
 
   } else {
     for (i = first; i < last; i++) {
       buf[m++] = flocal[i][0];
       buf[m++] = flocal[i][1];
       buf[m++] = flocal[i][2];
     }
   }
 
   return comm_reverse;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixSRD::unpack_reverse_comm(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
 
   if (torqueflag) {
     for (i = 0; i < n; i++) {
       j = list[i];
       flocal[j][0] += buf[m++];
       flocal[j][1] += buf[m++];
       flocal[j][2] += buf[m++];
       tlocal[j][0] += buf[m++];
       tlocal[j][1] += buf[m++];
       tlocal[j][2] += buf[m++];
     }
 
   } else {
     for (i = 0; i < n; i++) {
       j = list[i];
       flocal[j][0] += buf[m++];
       flocal[j][1] += buf[m++];
       flocal[j][2] += buf[m++];
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    SRD stats
 ------------------------------------------------------------------------- */
 
 double FixSRD::compute_vector(int n)
 {
   // only sum across procs one time
 
   if (stats_flag == 0) {
     stats[0] = ncheck;
     stats[1] = ncollide;
     stats[2] = nbounce;
     stats[3] = ninside;
     stats[4] = nrescale;
     stats[5] = nbins2;
     stats[6] = nbins1;
     stats[7] = srd_bin_count;
     stats[8] = srd_bin_temp;
     stats[9] = bouncemaxnum;
     stats[10] = bouncemax;
     stats[11] = reneighcount;
 
     MPI_Allreduce(stats,stats_all,10,MPI_DOUBLE,MPI_SUM,world);
     MPI_Allreduce(&stats[10],&stats_all[10],1,MPI_DOUBLE,MPI_MAX,world);
     if (stats_all[7] != 0.0) stats_all[8] /= stats_all[7];
     stats_all[6] /= nprocs;
 
     stats_flag = 1;
   }
 
   return stats_all[n];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixSRD::velocity_stats(int groupnum)
 {
   int bitmask = group->bitmask[groupnum];
 
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   double vone;
   double vave = 0.0;
   double vmax = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & bitmask) {
       vone = sqrt(v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]);
       vave += vone;
       if (vone > vmax) vmax = vone;
     }
 
   double all;
   MPI_Allreduce(&vave,&all,1,MPI_DOUBLE,MPI_SUM,world);
   double count = group->count(groupnum);
   if (count != 0.0) vave = all/count;
   else vave = 0.0;
 
   MPI_Allreduce(&vmax,&all,1,MPI_DOUBLE,MPI_MAX,world);
   vmax = all;
 
   if (me == 0) {
     if (screen)
       fprintf(screen,"  ave/max %s velocity = %g %g\n",
 	      group->names[groupnum],vave,vmax);
     if (logfile)
       fprintf(logfile,"  ave/max %s velocity = %g %g\n",
 	      group->names[groupnum],vave,vmax);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double FixSRD::memory_usage()
 {
   double bytes = 0.0;
   bytes += (shifts[0].nbins + shifts[1].nbins) * sizeof(BinAve);
   bytes += nmax * sizeof(int);
   if (bigexist) {
     bytes += nbins2 * sizeof(int);
     bytes += nbins2*ATOMPERBIN * sizeof(int);
   }
   bytes += nmax * sizeof(int);
   return bytes;
 }
 
 /* ----------------------------------------------------------------------
    useful debugging functions
 ------------------------------------------------------------------------- */
 
 double FixSRD::distance(int i, int j)
 {
   double dx = atom->x[i][0] - atom->x[j][0];
   double dy = atom->x[i][1] - atom->x[j][1];
   double dz = atom->x[i][2] - atom->x[j][2];
   return sqrt(dx*dx + dy*dy + dz*dz);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixSRD::print_collision(int i, int j, int ibounce,
 			      double t_remain, double dt,
 			      double *xscoll, double *xbcoll, double *norm,
 			      int type)
 {
   double xsstart[3],xbstart[3];
   double **x = atom->x;
   double **v = atom->v;
 
   if (type != WALL) {
     printf("COLLISION between SRD %d and BIG %d\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);
     printf("  time remaining post-collision = %g\n",t_remain);
     
     xsstart[0] = x[i][0] - dt*v[i][0];
     xsstart[1] = x[i][1] - dt*v[i][1];
     xsstart[2] = x[i][2] - dt*v[i][2];
     xbstart[0] = x[j][0] - dt*v[j][0];
     xbstart[1] = x[j][1] - dt*v[j][1];
     xbstart[2] = x[j][2] - dt*v[j][2];
 
     printf("  SRD start position = %g %g %g\n",
 	   xsstart[0],xsstart[1],xsstart[2]);
     printf("  BIG start position = %g %g %g\n",
 	   xbstart[0],xbstart[1],xbstart[2]);
     printf("  SRD coll  position = %g %g %g\n",
 	   xscoll[0],xscoll[1],xscoll[2]);
     printf("  BIG coll  position = %g %g %g\n",
 	   xbcoll[0],xbcoll[1],xbcoll[2]);
     printf("  SRD end   position = %g %g %g\n",x[i][0],x[i][1],x[i][2]);
     printf("  BIG end   position = %g %g %g\n",x[j][0],x[j][1],x[j][2]);
 
     printf("  SRD vel = %g %g %g\n",v[i][0],v[i][1],v[i][2]);
     printf("  BIG vel = %g %g %g\n",v[j][0],v[j][1],v[j][2]);
     printf("  surf norm = %g %g %g\n",norm[0],norm[1],norm[2]);
     
     double rstart = sqrt((xsstart[0]-xbstart[0])*(xsstart[0]-xbstart[0]) +
 			 (xsstart[1]-xbstart[1])*(xsstart[1]-xbstart[1]) +
 			 (xsstart[2]-xbstart[2])*(xsstart[2]-xbstart[2]));
     double rcoll = sqrt((xscoll[0]-xbcoll[0])*(xscoll[0]-xbcoll[0]) +
 			(xscoll[1]-xbcoll[1])*(xscoll[1]-xbcoll[1]) +
 			(xscoll[2]-xbcoll[2])*(xscoll[2]-xbcoll[2]));
     double rend = sqrt((x[i][0]-x[j][0])*(x[i][0]-x[j][0]) +
 		       (x[i][1]-x[j][1])*(x[i][1]-x[j][1]) +
 		       (x[i][2]-x[j][2])*(x[i][2]-x[j][2]));
     
     printf("  separation at start = %g\n",rstart);
     printf("  separation at coll  = %g\n",rcoll);
     printf("  separation at end   = %g\n",rend);
 
   } else {
     int dim = wallwhich[j] / 2;
 
     printf("COLLISION between SRD %d 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);
     printf("  time remaining post-collision = %g\n",t_remain);
     
     xsstart[0] = x[i][0] - dt*v[i][0];
     xsstart[1] = x[i][1] - dt*v[i][1];
     xsstart[2] = x[i][2] - dt*v[i][2];
     xbstart[0] = xbstart[1] = xbstart[2] = 0.0;
     xbstart[dim] = xwall[j] - dt*vwall[j];
 
     printf("  SRD start position = %g %g %g\n",
 	   xsstart[0],xsstart[1],xsstart[2]);
     printf("  WALL start position = %g\n",xbstart[dim]);
     printf("  SRD coll  position = %g %g %g\n",
 	   xscoll[0],xscoll[1],xscoll[2]);
     printf("  WALL coll position = %g\n",xbcoll[dim]);
     printf("  SRD end   position = %g %g %g\n",x[i][0],x[i][1],x[i][2]);
     printf("  WALL end  position = %g\n",xwall[j]);
 
     printf("  SRD vel = %g %g %g\n",v[i][0],v[i][1],v[i][2]);
     printf("  WALL vel = %g\n",vwall[j]);
     printf("  surf norm = %g %g %g\n",norm[0],norm[1],norm[2]);
     
     double rstart = xsstart[dim]-xbstart[dim];
     double rcoll = xscoll[dim]-xbcoll[dim];
     double rend = x[dim][0]-xwall[j];
     
     printf("  separation at start = %g\n",rstart);
     printf("  separation at coll  = %g\n",rcoll);
     printf("  separation at end   = %g\n",rend);
   }
 }
diff --git a/src/SRD/fix_wall_srd.cpp b/src/SRD/fix_wall_srd.cpp
index 359ad63d6..9c8eb4ce5 100644
--- a/src/SRD/fix_wall_srd.cpp
+++ b/src/SRD/fix_wall_srd.cpp
@@ -1,261 +1,261 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "string.h"
 #include "fix_wall_srd.h"
 #include "atom.h"
 #include "modify.h"
 #include "fix.h"
 #include "domain.h"
 #include "lattice.h"
 #include "input.h"
 #include "modify.h"
 #include "update.h"
 #include "variable.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{XLO,XHI,YLO,YHI,ZLO,ZHI};
 enum{NONE,EDGE,CONSTANT,VARIABLE};
 
 /* ---------------------------------------------------------------------- */
 
 FixWallSRD::FixWallSRD(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 4) error->all("Illegal fix wall/srd command");
 
   // parse args
 
   nwall = 0;
   int scaleflag = 1;
 
   int iarg = 3;
   while (iarg < narg) {
     if ((strcmp(arg[iarg],"xlo") == 0) || (strcmp(arg[iarg],"xhi") == 0) ||
 	(strcmp(arg[iarg],"ylo") == 0) || (strcmp(arg[iarg],"yhi") == 0) ||
 	(strcmp(arg[iarg],"zlo") == 0) || (strcmp(arg[iarg],"zhi") == 0)) {
       if (iarg+2 > narg) error->all("Illegal fix wall/srd command");
 
       int newwall;
       if (strcmp(arg[iarg],"xlo") == 0) newwall = XLO;
       else if (strcmp(arg[iarg],"xhi") == 0) newwall = XHI;
       else if (strcmp(arg[iarg],"ylo") == 0) newwall = YLO;
       else if (strcmp(arg[iarg],"yhi") == 0) newwall = YHI;
       else if (strcmp(arg[iarg],"zlo") == 0) newwall = ZLO;
       else if (strcmp(arg[iarg],"zhi") == 0) newwall = ZHI;
 
       for (int m = 0; m < nwall; m++)
 	if (newwall == wallwhich[m])
 	  error->all("Wall defined twice in fix wall/srd command");
 
       wallwhich[nwall] = newwall;
       if (strcmp(arg[iarg+1],"EDGE") == 0) {
 	wallstyle[nwall] = EDGE;
 	int dim = wallwhich[nwall] / 2;
 	int side = wallwhich[nwall] % 2;
 	if (side == 0) coord0[nwall] = domain->boxlo[dim];
 	else coord0[nwall] = domain->boxhi[dim];
       } else if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) {
 	wallstyle[nwall] = VARIABLE;
 	int n = strlen(&arg[iarg+1][2]) + 1;
 	varstr[nwall] = new char[n];
 	strcpy(varstr[nwall],&arg[iarg+1][2]);
       } else {
 	wallstyle[nwall] = CONSTANT;
 	coord0[nwall] = atof(arg[iarg+1]);
       }
 
       nwall++;
       iarg += 2;
 
     } else if (strcmp(arg[iarg],"units") == 0) {
       if (iarg+2 > narg) error->all("Illegal wall/srd command");
       if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
       else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
       else error->all("Illegal fix wall/srd command");
       iarg += 2;
     } else error->all("Illegal fix wall/srd command");
   }
 
   // error check
 
   if (nwall == 0) error->all("Illegal fix wall command");
 
   for (int m = 0; m < nwall; m++) {
     if ((wallwhich[m] == XLO || wallwhich[m] == XHI) && domain->xperiodic)
       error->all("Cannot use fix wall/srd in periodic dimension");
     if ((wallwhich[m] == YLO || wallwhich[m] == YHI) && domain->yperiodic)
       error->all("Cannot use fix wall/srd in periodic dimension");
     if ((wallwhich[m] == ZLO || wallwhich[m] == ZHI) && domain->zperiodic)
       error->all("Cannot use fix wall/srd in periodic dimension");
   }
 
   for (int m = 0; m < nwall; m++)
     if ((wallwhich[m] == ZLO || wallwhich[m] == ZHI) && domain->dimension == 2)
       error->all("Cannot use fix wall/srd zlo/zhi for a 2d simulation");
 
   // setup wall force array
 
   array_flag = 1;
   size_array_rows = nwall;
   size_array_cols = 3;
   global_freq = 1;
   extarray = 1;
 
   fwall = memory->create_2d_double_array(nwall,3,"wall/srd:fwall");
   fwall_all = memory->create_2d_double_array(nwall,3,"wall/srd:fwall_all");
 
   // scale coord for CONSTANT walls
 
   int flag = 0;
   for (int m = 0; m < nwall; m++)
     if (wallstyle[m] == CONSTANT) flag = 1;
 
   if (flag) {
     if (scaleflag && domain->lattice == NULL)
       error->all("Use of fix wall with undefined lattice");
 
     double xscale,yscale,zscale;
     if (scaleflag) {
       xscale = domain->lattice->xlattice;
       yscale = domain->lattice->ylattice;
       zscale = domain->lattice->zlattice;
     }
     else xscale = yscale = zscale = 1.0;
 
     double scale;
     for (int m = 0; m < nwall; m++) {
       if (wallwhich[m] < YLO) scale = xscale;
       else if (wallwhich[m] < ZLO) scale = yscale;
       else scale = zscale;
       if (wallstyle[m] == CONSTANT) coord0[m] *= scale;
     }
   }
 
   // set overlap if walls exist in multiple dimensions
 
   int dimflag[3];
   dimflag[0] = dimflag[1] = dimflag[2] = 0;
   for (int m = 0; m < nwall; m++)
     dimflag[wallwhich[m]/2] = 1;
   if (dimflag[0] + dimflag[1] + dimflag[2] > 1) overlap = 1;
   else overlap = 0;
 
   // set time_depend and varflag if any wall positions are variable
 
   varflag = 0;
   for (int m = 0; m < nwall; m++)
     if (wallstyle[m] == VARIABLE) time_depend = varflag = 1;
   laststep = -1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixWallSRD::~FixWallSRD()
 {
   for (int m = 0; m < nwall; m++)
     if (wallstyle[m] == VARIABLE) delete [] varstr[m];
   memory->destroy_2d_double_array(fwall);
   memory->destroy_2d_double_array(fwall_all);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixWallSRD::setmask()
 {
   int mask = 0;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixWallSRD::init()
 {
   int flag = 0;
   for (int m = 0; m < modify->nfix; m++)
     if (strcmp(modify->fix[m]->style,"srd") == 0) flag = 1;
   if (!flag) error->all("Cannot use fix wall/srd without fix srd");
 
   for (int m = 0; m < nwall; m++) {
     if (wallstyle[m] != VARIABLE) continue;
     varindex[m] = input->variable->find(varstr[m]);
     if (varindex[m] < 0)
       error->all("Variable name for fix wall/srd does not exist");
     if (!input->variable->equalstyle(varindex[m]))
       error->all("Variable for fix wall/srd is invalid style");
   }
 
   dt = update->dt;
 }
 
 /* ----------------------------------------------------------------------
    return force component on a wall
 ------------------------------------------------------------------------- */
 
 double FixWallSRD::compute_array(int i, int j)
 {
   // only sum across procs one time
 
   if (force_flag == 0) {
     MPI_Allreduce(&fwall[0][0],&fwall_all[0][0],3*nwall,
 		  MPI_DOUBLE,MPI_SUM,world);
     force_flag = 1;
   }
   return fwall_all[i][j];
 }
 
 /* ----------------------------------------------------------------------
    set wall position and velocity, zero forces on walls
    evaluate variable if necessary, wrap with clear/add
    if flag, then being called on reneighbor, so archive wall positions
 ------------------------------------------------------------------------- */
 
 void FixWallSRD::wall_params(int flag)
 {
   double xnew;
 
   if (varflag) modify->clearstep_compute();
 
-  int ntimestep = update->ntimestep;
+  bigint ntimestep = update->ntimestep;
 
   for (int m = 0; m < nwall; m++) {
     if (wallstyle[m] == VARIABLE)
       xnew = input->variable->compute_equal(varindex[m]);
     else xnew = coord0[m];
 
     if (laststep < 0) {
       xwall[m] = xwalllast[m] = xnew;
       vwall[m] = 0.0;
     } else if (laststep < ntimestep) {
       xwalllast[m] = xwall[m];
       xwall[m] = xnew;
       vwall[m] = (xwall[m] - xwalllast[m]) / dt;
     } 
 
     fwall[m][0] = fwall[m][1] = fwall[m][2] = 0.0;
   }
 
   laststep = ntimestep;
 
   if (varflag) modify->addstep_compute(update->ntimestep + 1);
 
   if (flag)
     for (int m = 0; m < nwall; m++)
       xwallhold[m] = xwall[m];
 
   force_flag = 0;
 }
diff --git a/src/SRD/fix_wall_srd.h b/src/SRD/fix_wall_srd.h
index c10ec1253..ed5afcde3 100644
--- a/src/SRD/fix_wall_srd.h
+++ b/src/SRD/fix_wall_srd.h
@@ -1,59 +1,60 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef FIX_CLASS
 
 FixStyle(wall/srd,FixWallSRD)
 
 #else
 
 #ifndef LMP_FIX_WALL_SRD_H
 #define LMP_FIX_WALL_SRD_H
 
 #include "fix.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class FixWallSRD : public Fix {
  public:
   int nwall,varflag,overlap;
   int wallwhich[6];
   double xwall[6],xwallhold[6],vwall[6];
   double **fwall;
 
   FixWallSRD(class LAMMPS *, int, char **);
   ~FixWallSRD();
   int setmask();
   void init();
   double compute_array(int, int);
 
   void wall_params(int);
 
  private:
   int wallstyle[6];
   double coord0[6];
   char *varstr[6];
   int varindex[6];
 
   double dt;
   double xwalllast[6];
-  int laststep;
+  bigint laststep;
   
   double **fwall_all;
   int force_flag;
 };
 
 }
 
 #endif
 #endif
diff --git a/src/STUBS/mpi.cpp b/src/STUBS/mpi.cpp
index 5087707d5..a0333a9c8 100644
--- a/src/STUBS/mpi.cpp
+++ b/src/STUBS/mpi.cpp
@@ -1,413 +1,413 @@
 /* -----------------------------------------------------------------------
    LAMMPS 2003 (July 31) - Molecular Dynamics Simulator
    Sandia National Laboratories, www.cs.sandia.gov/~sjplimp/lammps.html
    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.
 ------------------------------------------------------------------------ */
 
 /* Single-processor "stub" versions of MPI routines */
 
 #include "stdlib.h"
 #include "string.h"
 #include "stdio.h"
 #include "stdint.h"
 #include <sys/time.h>
 #include "mpi.h"
 
 /* lo-level function prototypes */
 
 void mpi_copy_int(void *, void *, int);
 void mpi_copy_float(void *, void *, int);
 void mpi_copy_double(void *, void *, int);
 void mpi_copy_char(void *, void *, int);
 void mpi_copy_byte(void *, void *, int);
 
 /* lo-level data structure */
 
 struct {
   double value;
   int proc;
 } double_int;
 
 /* ---------------------------------------------------------------------- */
 /* MPI Functions */
 /* ---------------------------------------------------------------------- */
 
 int MPI_Init(int *argc, char ***argv) {return 0;}
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Initialized(int *flag)
 {
   *flag = 1;
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Comm_rank(MPI_Comm comm, int *me)
 {
   *me = 0;
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Comm_size(MPI_Comm comm, int *nprocs)
 {
   *nprocs = 1;
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Abort(MPI_Comm comm, int errorcode)
 {
   exit(1);
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Finalize() {return 0;}
 
 /* ---------------------------------------------------------------------- */
 
 double MPI_Wtime()
 {
   double time;
   struct timeval tv;
 
   gettimeofday(&tv,NULL);
   time = 1.0 * tv.tv_sec + 1.0e-6 * tv.tv_usec;
   return time;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Type_size(MPI_Datatype datatype, int *size)
 {
   if (datatype == MPI_INT) *size = sizeof(int);
   else if (datatype == MPI_FLOAT) *size = sizeof(float);
   else if (datatype == MPI_DOUBLE) *size = sizeof(double);
   else if (datatype == MPI_CHAR) *size = sizeof(char);
   else if (datatype == MPI_BYTE) *size = sizeof(char);
-  else if (datatype == MPI_UNSIGNED_LONG_LONG) *size = sizeof(uint64_t);
+  else if (datatype == MPI_LONG_LONG) *size = sizeof(uint64_t);
   else if (datatype == MPI_DOUBLE_INT) *size = sizeof(double_int);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Send(void *buf, int count, MPI_Datatype datatype,
              int dest, int tag, MPI_Comm comm)
 {
   printf("MPI Stub WARNING: Should not send message to self\n");
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Rsend(void *buf, int count, MPI_Datatype datatype,
               int dest, int tag, MPI_Comm comm)
 {
   printf("MPI Stub WARNING: Should not rsend message to self\n");
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Recv(void *buf, int count, MPI_Datatype datatype,
              int source, int tag, MPI_Comm comm, MPI_Status *status)
 {
   printf("MPI Stub WARNING: Should not recv message from self\n");
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Irecv(void *buf, int count, MPI_Datatype datatype,
               int source, int tag, MPI_Comm comm, MPI_Request *request)
 {
   printf("MPI Stub WARNING: Should not recv message from self\n");
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Wait(MPI_Request *request, MPI_Status *status)
 {
   printf("MPI Stub WARNING: Should not wait on message from self\n");
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Waitall(int n, MPI_Request *request, MPI_Status *status)
 {
   printf("MPI Stub WARNING: Should not wait on message from self\n");
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Waitany(int count, MPI_Request *request, int *index, 
                 MPI_Status *status)
 {
   printf("MPI Stub WARNING: Should not wait on message from self\n");
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Sendrecv(void *sbuf, int scount, MPI_Datatype sdatatype,
                  int dest, int stag, void *rbuf, int rcount,
                  MPI_Datatype rdatatype, int source, int rtag,
                  MPI_Comm comm, MPI_Status *status)
 {
   printf("MPI Stub WARNING: Should not send message to self\n");
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count)
 {
   printf("MPI Stub WARNING: Should not get count of message to self\n");
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *comm_out)
 {
   *comm_out = comm;
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *comm_out)
 {
   *comm_out = comm;
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Comm_free(MPI_Comm *comm) {return 0;}
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Cart_create(MPI_Comm comm_old, int ndims, int *dims, int *periods,
                     int reorder, MPI_Comm *comm_cart)
 {
   *comm_cart = comm_old;
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Cart_get(MPI_Comm comm, int maxdims, int *dims, int *periods,
                  int *coords)
 {
   dims[0] = dims[1] = dims[2] = 1;
   periods[0] = periods[1] = periods[2] = 1;
   coords[0] = coords[1] = coords[2] = 0;
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Cart_shift(MPI_Comm comm, int direction, int displ,
                    int *source, int *dest)
 {
   *source = *dest = 0;
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Cart_rank(MPI_Comm comm, int *coords, int *rank)
 {
   *rank = 0;
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Barrier(MPI_Comm comm) {return 0;}
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Bcast(void *buf, int count, MPI_Datatype datatype,
               int root, MPI_Comm comm) {return 0;}
 
 /* ---------------------------------------------------------------------- */
 
 /* copy values from data1 to data2 */
 
 int MPI_Allreduce(void *sendbuf, void *recvbuf, int count,
                   MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
 {
   int n;
   if (datatype == MPI_INT) n = count*sizeof(int);
   else if (datatype == MPI_FLOAT) n = count*sizeof(float);
   else if (datatype == MPI_DOUBLE) n = count*sizeof(double);
   else if (datatype == MPI_CHAR) n = count*sizeof(char);
   else if (datatype == MPI_BYTE) n = count*sizeof(char);
-  else if (datatype == MPI_UNSIGNED_LONG_LONG) n = count*sizeof(uint64_t);
+  else if (datatype == MPI_LONG_LONG) n = count*sizeof(uint64_t);
   else if (datatype == MPI_DOUBLE_INT) n = count*sizeof(double_int);
 
   memcpy(recvbuf,sendbuf,n);
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 /* copy values from data1 to data2 */
 
 int MPI_Reduce(void *sendbuf, void *recvbuf, int count,
 		   MPI_Datatype datatype, MPI_Op op,
 		   int root, MPI_Comm comm)
 {
   int n;
   if (datatype == MPI_INT) n = count*sizeof(int);
   else if (datatype == MPI_FLOAT) n = count*sizeof(float);
   else if (datatype == MPI_DOUBLE) n = count*sizeof(double);
   else if (datatype == MPI_CHAR) n = count*sizeof(char);
   else if (datatype == MPI_BYTE) n = count*sizeof(char);
-  else if (datatype == MPI_UNSIGNED_LONG_LONG) n = count*sizeof(uint64_t);
+  else if (datatype == MPI_LONG_LONG) n = count*sizeof(uint64_t);
   else if (datatype == MPI_DOUBLE_INT) n = count*sizeof(double_int);
 
   memcpy(recvbuf,sendbuf,n);
   return 0;
 }
 
 
 /* ---------------------------------------------------------------------- */
 
 int MPI_Scan(void *sendbuf, void *recvbuf, int count,
              MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
 {
   int n;
   if (datatype == MPI_INT) n = count*sizeof(int);
   else if (datatype == MPI_FLOAT) n = count*sizeof(float);
   else if (datatype == MPI_DOUBLE) n = count*sizeof(double);
   else if (datatype == MPI_CHAR) n = count*sizeof(char);
   else if (datatype == MPI_BYTE) n = count*sizeof(char);
-  else if (datatype == MPI_UNSIGNED_LONG_LONG) n = count*sizeof(uint64_t);
+  else if (datatype == MPI_LONG_LONG) n = count*sizeof(uint64_t);
   else if (datatype == MPI_DOUBLE_INT) n = count*sizeof(double_int);
 
   memcpy(recvbuf,sendbuf,n);
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 /* copy values from data1 to data2 */
 
 int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                   void *recvbuf, int recvcount, MPI_Datatype recvtype,
                   MPI_Comm comm)
 {
   int n;
   if (sendtype == MPI_INT) n = sendcount*sizeof(int);
   else if (sendtype == MPI_FLOAT) n = sendcount*sizeof(float);
   else if (sendtype == MPI_DOUBLE) n = sendcount*sizeof(double);
   else if (sendtype == MPI_CHAR) n = sendcount*sizeof(char);
   else if (sendtype == MPI_BYTE) n = sendcount*sizeof(char);
-  else if (sendtype == MPI_UNSIGNED_LONG_LONG) n = sendcount*sizeof(uint64_t);
+  else if (sendtype == MPI_LONG_LONG) n = sendcount*sizeof(uint64_t);
   else if (sendtype == MPI_DOUBLE_INT) n = sendcount*sizeof(double_int);
 
   memcpy(recvbuf,sendbuf,n);
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 /* copy values from data1 to data2 */
 
 int MPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                    void *recvbuf, int *recvcounts, int *displs,
                    MPI_Datatype recvtype, MPI_Comm comm)
 {
   int n;
   if (sendtype == MPI_INT) n = sendcount*sizeof(int);
   else if (sendtype == MPI_FLOAT) n = sendcount*sizeof(float);
   else if (sendtype == MPI_DOUBLE) n = sendcount*sizeof(double);
   else if (sendtype == MPI_CHAR) n = sendcount*sizeof(char);
   else if (sendtype == MPI_BYTE) n = sendcount*sizeof(char);
-  else if (sendtype == MPI_UNSIGNED_LONG_LONG) n = sendcount*sizeof(uint64_t);
+  else if (sendtype == MPI_LONG_LONG) n = sendcount*sizeof(uint64_t);
   else if (sendtype == MPI_DOUBLE_INT) n = sendcount*sizeof(double_int);
 
   memcpy(recvbuf,sendbuf,n);
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 /* copy values from data1 to data2 */
 
 int MPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
 {
   int n;
   if (datatype == MPI_INT) n = *recvcounts*sizeof(int);
   else if (datatype == MPI_FLOAT) n = *recvcounts*sizeof(float);
   else if (datatype == MPI_DOUBLE) n = *recvcounts*sizeof(double);
   else if (datatype == MPI_CHAR) n = *recvcounts*sizeof(char);
   else if (datatype == MPI_BYTE) n = *recvcounts*sizeof(char);
-  else if (datatype == MPI_UNSIGNED_LONG_LONG) n = *recvcounts*sizeof(uint64_t);
+  else if (datatype == MPI_LONG_LONG) n = *recvcounts*sizeof(uint64_t);
   else if (datatype == MPI_DOUBLE_INT) n = *recvcounts*sizeof(double_int);
 
   memcpy(recvbuf,sendbuf,n);
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 /* copy values from data1 to data2 */
 
 int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                void *recvbuf, int recvcount, MPI_Datatype recvtype,
                int root, MPI_Comm comm)
 {
   int n;
   if (sendtype == MPI_INT) n = sendcount*sizeof(int);
   else if (sendtype == MPI_FLOAT) n = sendcount*sizeof(float);
   else if (sendtype == MPI_DOUBLE) n = sendcount*sizeof(double);
   else if (sendtype == MPI_CHAR) n = sendcount*sizeof(char);
   else if (sendtype == MPI_BYTE) n = sendcount*sizeof(char);
-  else if (sendtype == MPI_UNSIGNED_LONG_LONG) n = sendcount*sizeof(uint64_t);
+  else if (sendtype == MPI_LONG_LONG) n = sendcount*sizeof(uint64_t);
   else if (sendtype == MPI_DOUBLE_INT) n = sendcount*sizeof(double_int);
 
   memcpy(recvbuf,sendbuf,n);
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 /* copy values from data1 to data2 */
 
 int MPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
 		    void *recvbuf, int *recvcounts, int *displs,
 		    MPI_Datatype recvtype, int root, MPI_Comm comm)
 {
   int n;
   if (sendtype == MPI_INT) n = sendcount*sizeof(int);
   else if (sendtype == MPI_FLOAT) n = sendcount*sizeof(float);
   else if (sendtype == MPI_DOUBLE) n = sendcount*sizeof(double);
   else if (sendtype == MPI_CHAR) n = sendcount*sizeof(char);
   else if (sendtype == MPI_BYTE) n = sendcount*sizeof(char);
-  else if (sendtype == MPI_UNSIGNED_LONG_LONG) n = sendcount*sizeof(uint64_t);
+  else if (sendtype == MPI_LONG_LONG) n = sendcount*sizeof(uint64_t);
   else if (sendtype == MPI_DOUBLE_INT) n = sendcount*sizeof(double_int);
 
   memcpy(recvbuf,sendbuf,n);
   return 0;
 }
diff --git a/src/STUBS/mpi.h b/src/STUBS/mpi.h
index 8c70c9f0f..7104993f5 100644
--- a/src/STUBS/mpi.h
+++ b/src/STUBS/mpi.h
@@ -1,117 +1,117 @@
 /* -----------------------------------------------------------------------
    LAMMPS 2003 (July 31) - Molecular Dynamics Simulator
    Sandia National Laboratories, www.cs.sandia.gov/~sjplimp/lammps.html
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------ */
 
 #ifndef MPI_STUBS
 #define MPI_STUBS
 
 /* Dummy defs for MPI stubs */
 
 #define MPI_COMM_WORLD 0
 
 #define MPI_SUCCESS 0
 
 #define MPI_INT 1
 #define MPI_FLOAT 2
 #define MPI_DOUBLE 3
 #define MPI_CHAR 4
 #define MPI_BYTE 5
-#define MPI_UNSIGNED_LONG_LONG 6
+#define MPI_LONG_LONG 6
 #define MPI_DOUBLE_INT 7
 
 #define MPI_SUM 1
 #define MPI_MAX 2
 #define MPI_MIN 3
 #define MPI_MAXLOC 4
 #define MPI_MINLOC 5
 #define MPI_LOR 6
 
 #define MPI_ANY_SOURCE -1
 
 #define MPI_Comm int
 #define MPI_Request int
 #define MPI_Datatype int
 #define MPI_Op int
 
 /* MPI data structs */
 
 struct MPI_Status {
   int MPI_SOURCE;
 };
 
 /* Function prototypes for MPI stubs */
 
 int MPI_Init(int *argc, char ***argv);
 int MPI_Initialized(int *flag);
 int MPI_Comm_rank(MPI_Comm comm, int *me);
 int MPI_Comm_size(MPI_Comm comm, int *nprocs);
 int MPI_Abort(MPI_Comm comm, int errorcode);
 int MPI_Finalize();
 double MPI_Wtime();
 
 int MPI_Type_size(int, int *);
 
 int MPI_Send(void *buf, int count, MPI_Datatype datatype,
              int dest, int tag, MPI_Comm comm);
 int MPI_Rsend(void *buf, int count, MPI_Datatype datatype,
               int dest, int tag, MPI_Comm comm);
 int MPI_Recv(void *buf, int count, MPI_Datatype datatype,
              int source, int tag, MPI_Comm comm, MPI_Status *status);
 int MPI_Irecv(void *buf, int count, MPI_Datatype datatype,
               int source, int tag, MPI_Comm comm, MPI_Request *request);
 int MPI_Wait(MPI_Request *request, MPI_Status *status);
 int MPI_Waitall(int n, MPI_Request *request, MPI_Status *status);
 int MPI_Waitany(int count, MPI_Request *request, int *index, 
                 MPI_Status *status);
 int MPI_Sendrecv(void *sbuf, int scount, MPI_Datatype sdatatype,
 		  int dest, int stag, void *rbuf, int rcount,
 		  MPI_Datatype rdatatype, int source, int rtag,
 		  MPI_Comm comm, MPI_Status *status);
 int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count);
 
 int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *comm_out);
 int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *comm_out);
 int MPI_Comm_free(MPI_Comm *comm);
 
 int MPI_Cart_create(MPI_Comm comm_old, int ndims, int *dims, int *periods,
                     int reorder, MPI_Comm *comm_cart);
 int MPI_Cart_get(MPI_Comm comm, int maxdims, int *dims, int *periods,
                  int *coords);
 int MPI_Cart_shift(MPI_Comm comm, int direction, int displ,
                    int *source, int *dest);
 int MPI_Cart_rank(MPI_Comm comm, int *coords, int *rank);
 
 int MPI_Barrier(MPI_Comm comm);
 int MPI_Bcast(void *buf, int count, MPI_Datatype datatype,
               int root, MPI_Comm comm);
 int MPI_Allreduce(void *sendbuf, void *recvbuf, int count,
                   MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
 int MPI_Reduce(void *sendbuf, void *recvbuf, int count,
 		   MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);
 int MPI_Scan(void *sendbuf, void *recvbuf, int count,
              MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
 int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                   void *recvbuf, int recvcount, MPI_Datatype recvtype,
                   MPI_Comm comm);
 int MPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                    void *recvbuf, int *recvcounts, int *displs,
                    MPI_Datatype recvtype, MPI_Comm comm);
 int MPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
 int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                void *recvbuf, int recvcount, MPI_Datatype recvtype,
                int root, MPI_Comm comm);
 int MPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
 		    void *recvbuf, int *recvcounts, int *displs,
 		    MPI_Datatype recvtype, int root, MPI_Comm comm);
 
 #endif
diff --git a/src/USER-EFF/Install.sh b/src/USER-EFF/Install.sh
index 407168c56..64a7b71c0 100644
--- a/src/USER-EFF/Install.sh
+++ b/src/USER-EFF/Install.sh
@@ -1,73 +1,73 @@
 # Install/unInstall package files in LAMMPS
 
 if (test $1 = 1) then
 
   cp -p atom_vec_electron.cpp ..
   cp -p pair_eff_cut.cpp ..
   cp -p compute_ke_eff.cpp ..
   cp -p compute_ke_atom_eff.cpp ..
   cp -p compute_temp_deform_eff.cpp ..
   cp -p compute_temp_eff.cpp ..
   cp -p compute_temp_region_eff.cpp ..
   cp -p fix_langevin_eff.cpp ..
   cp -p fix_nh_eff.cpp ..
   cp -p fix_nve_eff.cpp ..
   cp -p fix_nvt_eff.cpp ..
   cp -p fix_nvt_sllod_eff.cpp ..
   cp -p fix_npt_eff.cpp ..
   cp -p fix_nph_eff.cpp ..
   cp -p fix_temp_rescale_eff.cpp ..
 
   cp -p atom_vec_electron.h ..
   cp -p pair_eff_cut.h ..
   cp -p pair_eff_inline.h ..
   cp -p compute_ke_eff.h ..
   cp -p compute_ke_atom_eff.h ..
   cp -p compute_temp_deform_eff.h ..
   cp -p compute_temp_eff.h ..
   cp -p compute_temp_region_eff.h ..
   cp -p fix_langevin_eff.h ..
   cp -p fix_nh_eff.h ..
   cp -p fix_nve_eff.h ..
   cp -p fix_nvt_eff.h ..
   cp -p fix_nvt_sllod_eff.h ..
   cp -p fix_npt_eff.h ..
   cp -p fix_nph_eff.h ..
   cp -p fix_temp_rescale_eff.h ..
 
 elif (test $1 = 0) then
 
   rm ../atom_vec_electron.cpp
   rm ../pair_eff_cut.cpp
   rm ../compute_ke_eff.cpp
   rm ../compute_ke_atom_eff.cpp
   rm ../compute_temp_deform_eff.cpp
   rm ../compute_temp_eff.cpp
   rm ../compute_temp_region_eff.cpp
-  rm ../fix_langevin_eff.cpp ..
+  rm ../fix_langevin_eff.cpp
   rm ../fix_nh_eff.cpp
   rm ../fix_nve_eff.cpp
   rm ../fix_nvt_eff.cpp
   rm ../fix_nvt_sllod_eff.cpp
   rm ../fix_npt_eff.cpp
   rm ../fix_nph_eff.cpp
   rm ../fix_temp_rescale_eff.cpp
 
   rm ../atom_vec_electron.h
   rm ../pair_eff_cut.h
   rm ../pair_eff_inline.h
   rm ../compute_ke_eff.h
   rm ../compute_ke_atom_eff.h
   rm ../compute_temp_deform_eff.h
   rm ../compute_temp_eff.h
   rm ../compute_temp_region_eff.h
-  rm ../fix_langevin_eff.h ..
+  rm ../fix_langevin_eff.h
   rm ../fix_nh_eff.h
   rm ../fix_nve_eff.h
   rm ../fix_nvt_eff.h
   rm ../fix_nvt_sllod_eff.h
   rm ../fix_npt_eff.h
   rm ../fix_nph_eff.h
   rm ../fix_temp_rescale_eff.h
 
 fi
diff --git a/src/USER-EFF/atom_vec_electron.cpp b/src/USER-EFF/atom_vec_electron.cpp
index f3a399768..ceba59846 100644
--- a/src/USER-EFF/atom_vec_electron.cpp
+++ b/src/USER-EFF/atom_vec_electron.cpp
@@ -1,798 +1,801 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
    
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
    
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Andres Jaramillo-Botero (Caltech)
 ------------------------------------------------------------------------- */
 
-#include "math.h"
 #include "stdlib.h"
 #include "atom_vec_electron.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "modify.h"
 #include "force.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecElectron::AtomVecElectron(LAMMPS *lmp, int narg, char **arg) :
   AtomVec(lmp, narg, arg)
 {
   comm_x_only = comm_f_only = 0;
   
   mass_type = 1;
   molecular = 0;
   
   size_forward = 5;
   size_reverse = 4;	
   size_border = 10;	
   size_velocity = 4;
   size_data_atom = 8;
   size_data_vel = 5;
   xcol_data = 6;
   
   atom->q_flag = atom->spin_flag = atom->eradius_flag = 
     atom->ervel_flag = atom->erforce_flag = 1;
 }
 
 /* ----------------------------------------------------------------------
    grow atom-electron arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n 
 ------------------------------------------------------------------------- */
 
 void AtomVecElectron::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
-  
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
+
   tag = atom->tag = (int *) 
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *) 
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *) 
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
   
   q = atom->q = (double *)
     memory->srealloc(atom->q,nmax*sizeof(double),"atom:q");
   spin = atom->spin = (int *)
     memory->srealloc(atom->spin,nmax*sizeof(int),"atom:spin");
   eradius = atom->eradius = (double *)
     memory->srealloc(atom->eradius,nmax*sizeof(double),"atom:eradius");
   ervel = atom->ervel = (double *)
     memory->srealloc(atom->ervel,nmax*sizeof(double),"atom:ervel");
   erforce = atom->erforce = (double *)
     memory->srealloc(atom->erforce,nmax*sizeof(double),"atom:erforce");
   
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecElectron::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
-  q = atom->q; eradius = atom->eradius; ervel = atom->ervel; erforce = atom->erforce;
+  q = atom->q;
+  eradius = atom->eradius; ervel = atom->ervel; erforce = atom->erforce;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecElectron::copy(int i, int j)
 {
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
   
   q[j] = q[i];
   spin[j] = spin[i];
   eradius[j] = eradius[i];
   ervel[j] = ervel[i];
   
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::pack_comm(int n, int *list, double *buf,
 			       int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = eradius[j];
       buf[m++] = ervel[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = eradius[j];
       buf[m++] = ervel[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::pack_comm_vel(int n, int *list, double *buf,
 				   int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = eradius[j];
       buf[m++] = ervel[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = eradius[j];
       buf[m++] = ervel[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecElectron::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
   
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     eradius[i] = buf[m++];
     ervel[i] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecElectron::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
   
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
     eradius[i] = buf[m++];
     ervel[i] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::pack_comm_one(int i, double *buf)
 {
   buf[0] = eradius[i];
   buf[1] = ervel[i];
   
   return 2;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::unpack_comm_one(int i, double *buf)
 {
   eradius[i] = buf[0];
   ervel[i] = buf[1];
   
   return 2;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
   
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
     buf[m++] = erforce[i];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::pack_reverse_one(int i, double *buf)
 {
   buf[0] = erforce[i];
 
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecElectron::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
   
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
     erforce[j] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::unpack_reverse_one(int i, double *buf)
 {
   erforce[i] += buf[0];
   
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::pack_border_vel(int n, int *list, double *buf,
 				     int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = q[j];
       buf[m++] = spin[j];
       buf[m++] = eradius[j];
       buf[m++] = ervel[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       buf[m++] = q[j];
       buf[m++] = spin[j];
       buf[m++] = eradius[j];
       buf[m++] = ervel[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecElectron::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
   
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
     q[i] = buf[m++];
     spin[i] = static_cast<int> (buf[m++]);
     eradius[i] = buf[m++];
     ervel[i] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::pack_border(int n, int *list, double *buf,
 				 int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = spin[j];
       buf[m++] = eradius[j];
       buf[m++] = ervel[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = spin[j];
       buf[m++] = eradius[j];
       buf[m++] = ervel[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::pack_border_one(int i, double *buf)
 {
   buf[0] = q[i];
   buf[1] = spin[i];
   buf[2] = eradius[i];
   buf[3] = ervel[i];
   
   return 4;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecElectron::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
   
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);		
     q[i] = buf[m++];
     spin[i] = static_cast<int> (buf[m++]);
     eradius[i] = buf[m++];
     ervel[i] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::unpack_border_one(int i, double *buf)
 {
   q[i] = buf[0];
   spin[i] = static_cast<int> (buf[1]);
   eradius[i] = buf[2];
   ervel[i] = buf[3];
   
   return 4;
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    xyz must be 1st 3 values, so comm::exchange() can test on them 
 ------------------------------------------------------------------------- */
 
 int AtomVecElectron::pack_exchange(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];	
   buf[m++] = q[i];
   buf[m++] = spin[i];
   buf[m++] = eradius[i];
   buf[m++] = ervel[i];
   
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
   
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecElectron::unpack_exchange(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
   
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);	
   q[nlocal] = buf[m++];
   spin[nlocal] = static_cast<int> (buf[m++]);
   eradius[nlocal] = buf[m++];
   ervel[nlocal] = buf[m++];
   
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
   
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecElectron::size_restart()
 {
   int i;
   
   int nlocal = atom->nlocal;
   int n = 15 * nlocal;	// Associated with pack_restart
   
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       for (i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
   
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive   
 ------------------------------------------------------------------------- */
 
 int AtomVecElectron::pack_restart(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   
   buf[m++] = q[i];
   buf[m++] = spin[i];
   buf[m++] = eradius[i];
   buf[m++] = ervel[i];
   
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
   
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
 
 int AtomVecElectron::unpack_restart(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store)
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
   
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   
   q[nlocal] = buf[m++];
   spin[nlocal] = static_cast<int> (buf[m++]);
   eradius[nlocal] = buf[m++];
   ervel[nlocal] = buf[m++];
   
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
   
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
 
 void AtomVecElectron::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
   
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   
   q[nlocal] = 0.0;
   spin[nlocal] = 1;
   eradius[nlocal] = 1.0;	
   ervel[nlocal] = 0.0; 
   
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
 void AtomVecElectron::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   
   if (nlocal == nmax) grow(0);
   
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
   
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
   
   q[nlocal] = atof(values[2]);
   spin[nlocal] = atoi(values[3]);
   eradius[nlocal] = atof(values[4]);
   
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   
   image[nlocal] = imagetmp;
   
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   ervel[nlocal] = 0.0;
   
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Atoms section of data file
    initialize other atom quantities for this sub-style
 ------------------------------------------------------------------------- */
 
 int AtomVecElectron::data_atom_hybrid(int nlocal, char **values)
 {
   q[nlocal] = atof(values[0]);
   spin[nlocal] = atoi(values[1]);
   eradius[nlocal] = atof(values[2]);
   if (eradius[nlocal] < 0.0)
     error->one("Invalid eradius in Atoms section of data file");
   
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   ervel[nlocal] = 0.0;
   
   return 2;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Velocities section of data file
 ------------------------------------------------------------------------- */
 
 void AtomVecElectron::data_vel(int m, char **values)
 {
   v[m][0] = atof(values[0]);
   v[m][1] = atof(values[1]);
   v[m][2] = atof(values[2]);
   ervel[m] = atof(values[3]);
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Velocities section of data file
 ------------------------------------------------------------------------- */
 
 int AtomVecElectron::data_vel_hybrid(int m, char **values)
 {
   ervel[m] = atof(values[0]);
   
   return 1;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
 
 double AtomVecElectron::memory_usage()
 {
   double bytes = 0.0;
   
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
   
   if (atom->memcheck("q")) bytes += nmax * sizeof(double);
   if (atom->memcheck("spin")) bytes += nmax * sizeof(int);
   if (atom->memcheck("eradius")) bytes += nmax * sizeof(double);
   if (atom->memcheck("ervel")) bytes += nmax * sizeof(double);
   if (atom->memcheck("erforce")) bytes += nmax * sizeof(double);
   
   return bytes;
 }
diff --git a/src/USER-IMD/fix_imd.cpp b/src/USER-IMD/fix_imd.cpp
index 427d6ed49..380f67cc2 100644
--- a/src/USER-IMD/fix_imd.cpp
+++ b/src/USER-IMD/fix_imd.cpp
@@ -1,1357 +1,1355 @@
 /* ----------------------------------------------------------------------
    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.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    The FixIMD class contains code from VMD and NAMD which is copyrighted
    by the Board of Trustees of the University of Illinois and is free to 
    use with LAMMPS according to point 2 of the UIUC license (10% clause):
 
 " Licensee may, at its own expense, create and freely distribute 
 complimentary works that interoperate with the Software, directing others to 
 the TCBG server to license and obtain the Software itself. Licensee may, at 
 its own expense, modify the Software to make derivative works.  Except as 
 explicitly provided below, this License shall apply to any derivative work 
 as it does to the original Software distributed by Illinois.  Any derivative 
 work should be clearly marked and renamed to notify users that it is a 
 modified version and not the original Software distributed by Illinois.  
 Licensee agrees to reproduce the copyright notice and other proprietary 
 markings on any derivative work and to include in the documentation of such 
 work the acknowledgement:
 
  "This software includes code developed by the Theoretical and Computational 
   Biophysics Group in the Beckman Institute for Advanced Science and 
   Technology at the University of Illinois at Urbana-Champaign."
 
 Licensee may redistribute without restriction works with up to 1/2 of their 
 non-comment source code derived from at most 1/10 of the non-comment source 
 code developed by Illinois and contained in the Software, provided that the 
 above directions for notice and acknowledgement are observed.  Any other 
 distribution of the Software or any derivative work requires a separate 
 license with Illinois.  Licensee may contact Illinois (vmd@ks.uiuc.edu) to 
 negotiate an appropriate license for such distribution."
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author:  Axel Kohlmeyer (TempleU)
    IMD API, hash, and socket code written by: John E. Stone, 
    Justin Gullingsrud, and James Phillips, (TCBG, Beckman Institute, UIUC)
 ------------------------------------------------------------------------- */
 
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #if defined(_MSC_VER) 
 #include <winsock2.h>
 #else
 #include <arpa/inet.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <netinet/in.h>
 #include <netdb.h>
 #include <sys/file.h>
 #endif
 
 #include <errno.h>
 
 #include "fix_imd.h"
 #include "atom.h"
 #include "comm.h"
 #include "update.h"
 #include "respa.h"
 #include "domain.h"
 #include "error.h"
 #include "group.h"
 #include "memory.h"
 
 /********** API definitions of the VMD/NAMD code ************************
  * This code was taken and adapted from VMD-1.8.7/NAMD-2.7 in Sep 2009. *
  * If there are any bugs or problems, please contact akohlmey@gmail.com *
  ************************************************************************/
 
 /***************************************************************************
  *cr
  *cr            (C) Copyright 1995-2009 The Board of Trustees of the
  *cr                        University of Illinois
  *cr                         All Rights Reserved
  *cr
  ***************************************************************************/
 
 /* part 1: integer hash table */
 
 /** hash table top level data structure */
 typedef struct inthash_t {
   struct inthash_node_t **bucket;        /* array of hash nodes */
   int size;                           /* size of the array */
   int entries;                        /* number of entries in table */
   int downshift;                      /* shift cound, used in hash function */
   int mask;                           /* used to select bits for hashing */
 } inthash_t;
 
 /** hash table node data structure */
 typedef struct inthash_node_t {
   int data;                           /* data in hash node */
   int key;                            /* key for hash lookup */
   struct inthash_node_t *next;        /* next node in hash chain */
 } inthash_node_t;
 
 #define HASH_FAIL  -1
 #define HASH_LIMIT  0.5
 
 /* initialize new hash table  */
 static void inthash_init(inthash_t *tptr, int buckets);
 /* lookup entry in hash table */
 static int inthash_lookup(const inthash_t *tptr, int key);
 /* generate list of keys for reverse lookups. */
 static int *inthash_keys(inthash_t *tptr);
 /* insert an entry into hash table. */
 static int inthash_insert(inthash_t *tptr, int key, int data);
 /* delete the hash table */
 static void inthash_destroy(inthash_t *tptr);
 
 /* part 2: Interactive MD (IMD) API */
 
 #include <limits.h>
 
 #if ( INT_MAX == 2147483647 )
 typedef int     int32;
 #else
 typedef short   int32;
 #endif
 
 typedef struct {
   int32 type;
   int32 length;
 } IMDheader;
 
 #define IMDHEADERSIZE 8
 #define IMDVERSION 2
 
 typedef enum IMDType_t {
   IMD_DISCONNECT,   /**< close IMD connection, leaving sim running */
   IMD_ENERGIES,     /**< energy data block                         */
   IMD_FCOORDS,      /**< atom coordinates                          */
   IMD_GO,           /**< start the simulation                      */
   IMD_HANDSHAKE,    /**< endianism and version check message       */
   IMD_KILL,         /**< kill the simulation job, shutdown IMD     */
   IMD_MDCOMM,       /**< MDComm style force data                   */
   IMD_PAUSE,        /**< pause the running simulation              */
   IMD_TRATE,        /**< set IMD update transmission rate          */
   IMD_IOERROR       /**< indicate an I/O error                     */
 } IMDType;          /**< IMD command message type enumerations */
 
 typedef struct {
   int32 tstep;      /**< integer timestep index                    */
   float T;          /**< Temperature in degrees Kelvin             */
   float Etot;       /**< Total energy, in Kcal/mol                 */
   float Epot;       /**< Potential energy, in Kcal/mol             */
   float Evdw;       /**< Van der Waals energy, in Kcal/mol         */
   float Eelec;      /**< Electrostatic energy, in Kcal/mol         */
   float Ebond;      /**< Bond energy, Kcal/mol                     */
   float Eangle;     /**< Angle energy, Kcal/mol                    */
   float Edihe;      /**< Dihedral energy, Kcal/mol                 */
   float Eimpr;      /**< Improper energy, Kcal/mol                 */
 } IMDEnergies;      /**< IMD simulation energy report structure    */
 
 /** Send control messages - these consist of a header with no subsequent data */
 static int imd_handshake(void *);    /**< check endianness, version compat */
 /** Receive header and data */
 static IMDType imd_recv_header(void *, int32 *);
 /** Receive MDComm-style forces, units are Kcal/mol/angstrom */
 static int imd_recv_mdcomm(void *, int32, int32 *, float *);
 /** Receive energies */
 static int imd_recv_energies(void *, IMDEnergies *);
 /** Receive atom coordinates. */
 static int imd_recv_fcoords(void *, int32, float *);
 /** Prepare IMD data packet header */
 static void imd_fill_header(IMDheader *header, IMDType type, int32 length);
 /** Write data to socket */
 static int32 imd_writen(void *s, const char *ptr, int32 n);
 
 /* part 3: abstracts platform-dependent routines/APIs for using sockets */
 
 typedef struct {
   struct sockaddr_in addr; /* address of socket provided by bind() */
   int addrlen;             /* size of the addr struct */
   int sd;                  /* socket file descriptor */
 } imdsocket;
 
 static int   imdsock_init(void);
 static void *imdsock_create(void);
 static int   imdsock_bind(void *, int);
 static int   imdsock_listen(void *);
 static void *imdsock_accept(void *);  /* return new socket */
 static int   imdsock_write(void *, const void *, int);
 static int   imdsock_read(void *, void *, int);
 static int   imdsock_selread(void *, int);
 static int   imdsock_selwrite(void *, int);
 static void  imdsock_shutdown(void *);
 static void  imdsock_destroy(void *);
 
 /***************************************************************
  * End of API definitions of the VMD/NAMD code.                *
  * The implementation follows at the end of the file.          *
  ***************************************************************/
 
 using namespace LAMMPS_NS;
 
 /* adapted sort for in-place sorting of map indices. */
 static void id_sort(int *idmap, int left, int right);
 
 /* struct for packed data communication of coordinates and forces. */
 struct commdata { 
   int tag; 
   float x,y,z; 
 };
 
 /***************************************************************
  * create class and parse arguments in LAMMPS script. Syntax: 
  * fix ID group-ID imd <imd_trate> <imd_port> [unwrap (on|off)] [fscale <imd_fscale>] 
  ***************************************************************/
 FixIMD::FixIMD(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 4) 
     error->all("Illegal fix imd command");
 
   imd_port = atoi(arg[3]); 
   if (imd_port < 1024)
     error->all("Illegal fix imd parameter: port < 1024");
 
   /* default values for optional flags */
   unwrap_flag = 0;
   nowait_flag = 0;
   connect_msg = 1;
   imd_fscale = 1.0;
   imd_trate = 1;
   
   /* parse optional arguments */
   int argsdone = 4;
   while (argsdone+1 < narg) {
     if (0 == strcmp(arg[argsdone], "unwrap")) {
       if (0 == strcmp(arg[argsdone+1], "on")) {  
         unwrap_flag = 1;
       } else {
         unwrap_flag = 0;
       }
     } else if (0 == strcmp(arg[argsdone], "nowait")) {
       if (0 == strcmp(arg[argsdone+1], "on")) {  
         nowait_flag = 1;
       } else {
         nowait_flag = 0;
       }
     } else if (0 == strcmp(arg[argsdone], "fscale")) {
       imd_fscale = atof(arg[argsdone+1]);
     } else if (0 == strcmp(arg[argsdone], "trate")) {
       imd_trate = atoi(arg[argsdone+1]);
     } else {
       error->all("Unknown fix imd parameter");
     }
     ++argsdone; ++argsdone;
   }
 
   /* sanity check on parameters */
   if (imd_trate < 1)
     error->all("Illegal fix imd parameter. trate < 1.");
 
-  bigint n;
-  if (igroup == group->find("all"))  n = atom->natoms;
-  else n = group->count(igroup);
-  if (n > MAXINT32) error->all("Too many atoms for fix imd");
+  bigint n = group->count(igroup);
+  if (n > MAXSMALLINT) error->all("Too many atoms for fix imd");
   num_coords = static_cast<int> (n);
 
   MPI_Comm_rank(world,&me);
 
   /* initialize various imd state variables. */
   clientsock = NULL;
   localsock  = NULL;
   nlevels_respa = 0;
   imd_inactive = 0;
   imd_terminate = 0;
   imd_forces = 0;
   force_buf = NULL;
   maxbuf = 0;
   comm_buf = NULL;
   idmap = NULL;
   rev_idmap = NULL;
   
   if (me == 0) {
     /* set up incoming socket on MPI rank 0. */
     imdsock_init();
     localsock = imdsock_create();
     clientsock = NULL;
     if (imdsock_bind(localsock,imd_port)) {
       perror("bind to socket failed");
       imdsock_destroy(localsock);
       imd_terminate = 1;
     } else {
       imdsock_listen(localsock);
     }
   }
   MPI_Bcast(&imd_terminate, 1, MPI_INT, 0, world);
   if (imd_terminate)
     error->all("LAMMPS Terminated on error in IMD.");
     
   /* storage required to communicate a single coordinate or force. */
   size_one = sizeof(struct commdata);
 }
 
 /*********************************
  * Clean up on deleting the fix. *
  *********************************/
 FixIMD::~FixIMD()
 {
 
   inthash_t *hashtable = (inthash_t *)idmap;
   memory->sfree(comm_buf);
   memory->sfree(force_buf);
   inthash_destroy(hashtable);
   delete hashtable;
   free(rev_idmap);
   // close sockets
   imdsock_shutdown(clientsock);
   imdsock_destroy(clientsock);
   imdsock_shutdown(localsock);
   imdsock_destroy(localsock);
   clientsock=NULL;
   localsock=NULL;
   return;
 }
 
 /* ---------------------------------------------------------------------- */
 int FixIMD::setmask()
 {
   int mask = 0;
   mask |= POST_FORCE;
   mask |= POST_FORCE_RESPA;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 void FixIMD::init()
 {
   if (strcmp(update->integrate_style,"respa") == 0)
     nlevels_respa = ((Respa *) update->integrate)->nlevels;
 
   return;
 }
 
 /* ---------------------------------------------------------------------- */
 
 /* (re-)connect to an IMD client (e.g. VMD). return 1 if
    new connection was made, 0 if not. */
 int FixIMD::reconnect()
 {
   /* set up IMD communication, but only if needed. */
   imd_inactive = 0;
   imd_terminate = 0;
   
   if (me == 0) {
     if (clientsock) return 1;
     if (screen && connect_msg)
       if (nowait_flag)
         fprintf(screen,"Listening for IMD connection on port %d.\n",imd_port);
       else
         fprintf(screen,"Waiting for IMD connection on port %d.\n",imd_port);
     
     connect_msg = 0;
     clientsock = NULL;
     if (nowait_flag) {
       int retval = imdsock_selread(localsock,0);
       if (retval > 0) {
         clientsock = imdsock_accept(localsock);
       } else {
         imd_inactive = 1;
         return 0;
       }
     } else {
       int retval=0;
       do {
         retval = imdsock_selread(localsock, 60);
       } while (retval <= 0);
       clientsock = imdsock_accept(localsock);
     }
     
     if (!imd_inactive && !clientsock) {
       if (screen)
         fprintf(screen, "IMD socket accept error. Dropping connection.\n");
       imd_terminate = 1;
       return 0;
     } else {
       /* check endianness and IMD protocol version. */
       if (imd_handshake(clientsock)) {
         if (screen)
           fprintf(screen, "IMD handshake error. Dropping connection.\n");
         imdsock_destroy(clientsock);
         imd_terminate = 1;
         return 0;
       } else {
         int32 length;
         if (imdsock_selread(clientsock, 1) != 1 ||
             imd_recv_header(clientsock, &length) != IMD_GO) {
           if (screen)
             fprintf(screen, "Incompatible IMD client version? Dropping connection.\n");
           imdsock_destroy(clientsock);
           imd_terminate = 1;
           return 0;
         } else {
           return 1;
         }
       }
     }
   }
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 /* wait for IMD client (e.g. VMD) to respond, initialize communication 
  * buffers and collect tag/id maps. */
 void FixIMD::setup(int)
 {
   /* nme:    number of atoms in group on this MPI task
    * nmax:   max number of atoms in group across all MPI tasks
    * nlocal: all local atoms
    */
   int i,j;
   int nmax,nme,nlocal;
   int *mask  = atom->mask;
   int *tag  = atom->tag;
   nlocal = atom->nlocal;
   nme=0;
   for (i=0; i < nlocal; ++i)
     if (mask[i] & groupbit) ++nme;
 
   MPI_Allreduce(&nme,&nmax,1,MPI_INT,MPI_MAX,world);
   maxbuf = nmax*size_one;
   comm_buf = memory->smalloc(maxbuf,"imd:comm_buf");
 
   connect_msg = 1;
   reconnect();
   MPI_Bcast(&imd_inactive, 1, MPI_INT, 0, world);
   MPI_Bcast(&imd_terminate, 1, MPI_INT, 0, world);
   if (imd_terminate)
     error->all("LAMMPS terminated on error in setting up IMD connection.");
 
   /* initialize and build hashtable. */
   inthash_t *hashtable=new inthash_t;
   inthash_init(hashtable, num_coords);
   idmap = (void *)hashtable;
   
   MPI_Status status;
   MPI_Request request;
   int tmp, ndata;
   struct commdata *buf = static_cast<struct commdata *>(comm_buf);
 
   if (me == 0) {
     int *taglist = new int[num_coords];
     int numtag=0; /* counter to map atom tags to a 0-based consecutive index list */
     
     for (i=0; i < nlocal; ++i) {
       if (mask[i] & groupbit) {
         taglist[numtag] = tag[i];
         ++numtag;
       }
     }
     
     /* loop over procs to receive remote data */
     for (i=1; i < comm->nprocs; ++i) {
       MPI_Irecv(comm_buf, maxbuf, MPI_BYTE, i, 0, world, &request);
       MPI_Send(&tmp, 0, MPI_INT, i, 0, world);
       MPI_Wait(&request, &status);
       MPI_Get_count(&status, MPI_BYTE, &ndata);
       ndata /= size_one;
 
       for (j=0; j < ndata; ++j) {
         taglist[numtag] = buf[j].tag;
         ++numtag;
       }
     }
 
     /* sort list of tags by value to have consistently the 
      * same list when running in parallel and build hash table. */
     id_sort(taglist, 0, num_coords-1);
     for (i=0; i < num_coords; ++i) {
       inthash_insert(hashtable, taglist[i], i);
     }
     delete[] taglist;
 
     /* generate reverse index-to-tag map for communicating 
      * IMD forces back to the proper atoms */
     rev_idmap=inthash_keys(hashtable);
   } else {
     nme=0;
     for (i=0; i < nlocal; ++i) {
       if (mask[i] & groupbit) {
         buf[nme].tag = tag[i];
         ++nme;
       }
     }
     /* blocking receive to wait until it is our turn to send data. */
     MPI_Recv(&tmp, 0, MPI_INT, 0, 0, world, &status);
     MPI_Rsend(comm_buf, nme*size_one, MPI_BYTE, 0, 0, world);
   }
   
   return;
 }
 
 /* ---------------------------------------------------------------------- */
 /* Main IMD protocol handler:
  * Send coodinates, energies, and add IMD forces to atoms. */
 void FixIMD::post_force(int vflag)
 {
   /* check for reconnect */
   if (imd_inactive) {
     reconnect();
     MPI_Bcast(&imd_inactive, 1, MPI_INT, 0, world);
     MPI_Bcast(&imd_terminate, 1, MPI_INT, 0, world);
     if (imd_terminate)
       error->all("LAMMPS terminated on error in setting up IMD connection.");
     if (imd_inactive)
       return;     /* IMD client has detached and not yet come back. do nothing. */
   }
 
   int *tag = atom->tag;
   double **x = atom->x;
   int *image = atom->image;
   int nlocal = atom->nlocal;
   int *mask  = atom->mask;
   struct commdata *buf;
 
   /* Check if we need to communicate coordinates to the client.
    * Tuning imd_trate allows to keep the overhead for IMD low
    * at the expense of a more jumpy display. Rather than using
    * end_of_step() we do everything here in one go.
    *
    * If we don't communicate, only check if we have forces 
    * stored away and apply them. */
   if (update->ntimestep % imd_trate) {
     if (imd_forces > 0) {
       double **f = atom->f;
       buf = static_cast<struct commdata *>(force_buf);
 
       /* XXX. this is in principle O(N**2) = not good. 
        * however we assume for now that the number of atoms 
        * that we manipulate via IMD will be small compared 
        * to the total system size, so we don't hurt too much. */
       for (int j=0; j < imd_forces; ++j) {
         for (int i=0; i < nlocal; ++i) {
           if (mask[i] & groupbit) {
             if (buf[j].tag == tag[i]) {
               f[i][0] += buf[j].x;
               f[i][1] += buf[j].y;
               f[i][2] += buf[j].z;
             }
           }
         }
       }
     }
     return;
   }
   
   /* check and potentially grow local communication buffers. */
   int i, k, nmax, nme=0;
   for (i=0; i < nlocal; ++i)
     if (mask[i] & groupbit) ++nme;
 
   MPI_Allreduce(&nme,&nmax,1,MPI_INT,MPI_MAX,world);
   if (nmax*size_one > maxbuf) {
     memory->sfree(comm_buf);
     maxbuf = nmax*size_one;
     comm_buf = memory->smalloc(maxbuf,"imd:comm_buf");
   }
 
   MPI_Status status;
   MPI_Request request;
   int tmp, ndata;
   buf = static_cast<struct commdata *>(comm_buf);
   
   if (me == 0) {
     /* collect data into new array. we bypass the IMD API to save
      * us one extra copy of the data. */
     int   msglen = 3*sizeof(float)*num_coords+IMDHEADERSIZE;
     char *msgdata = new char[msglen];
     imd_fill_header((IMDheader *)msgdata, IMD_FCOORDS, num_coords);
     /* array pointer, to the offset where we receive the coordinates. */
     float *recvcoord = (float *) (msgdata+IMDHEADERSIZE);
 
     /* add local data */
     if (unwrap_flag) {
       double xprd = domain->xprd;
       double yprd = domain->yprd;
       double zprd = domain->zprd;
 
       for (i=0; i<nlocal; ++i) {
         if (mask[i] & groupbit) {
           const int j = 3*inthash_lookup((inthash_t *)idmap, tag[i]);
           if (j != HASH_FAIL) {
             recvcoord[j]   = x[i][0] + ((image[i] & 1023) - 512) * xprd;
             recvcoord[j+1] = x[i][1] + ((image[i] >> 10 & 1023) - 512) * yprd;
             recvcoord[j+2] = x[i][2] + ((image[i] >> 20) - 512) * zprd;
           }
         }
       }
     } else {
       for (i=0; i<nlocal; ++i) {
         if (mask[i] & groupbit) {
           const int j = 3*inthash_lookup((inthash_t *)idmap, tag[i]);
           if (j != HASH_FAIL) {
             recvcoord[j]   = x[i][0];
             recvcoord[j+1] = x[i][1];
             recvcoord[j+2] = x[i][2];
           }
         }
       }
     }
 
     /* loop over procs to receive remote data */
     for (i=1; i < comm->nprocs; ++i) {
       MPI_Irecv(comm_buf, maxbuf, MPI_BYTE, i, 0, world, &request);
       MPI_Send(&tmp, 0, MPI_INT, i, 0, world);
       MPI_Wait(&request, &status);
       MPI_Get_count(&status, MPI_BYTE, &ndata);
       ndata /= size_one;
       
       for (k=0; k<ndata; ++k) {
         const int j = 3*inthash_lookup((inthash_t *)idmap, buf[k].tag);
         if (j != HASH_FAIL) {
           recvcoord[j]   = buf[k].x;
           recvcoord[j+1] = buf[k].y;
           recvcoord[j+2] = buf[k].z;
         }
       }
     }
 
     /* done collecting frame data now communicate with IMD client. */
     
     /* send coordinate data, if client is able to accept */
     if (clientsock && imdsock_selwrite(clientsock,0)) {
       imd_writen(clientsock, msgdata, msglen);
     }
     delete[] msgdata;
     
     /* process all pending incoming data. */
     int imd_paused=0;
     while ((imdsock_selread(clientsock, 0) > 0) || imd_paused) {
       /* if something requested to turn off IMD while paused get out */
       if (imd_inactive) break;
       
       int32 length;
       int msg = imd_recv_header(clientsock, &length);
 
       switch(msg) {
 
         case IMD_GO:
           if (screen)
             fprintf(screen, "Ignoring unexpected IMD_GO message.\n");
           break;
 
         case IMD_IOERROR:
           if (screen)
             fprintf(screen, "IMD connection lost.\n");
           /* fallthrough */
 
         case IMD_DISCONNECT: {
           /* disconnect from client. wait for new connection. */
           imd_paused = 0;
           imd_forces = 0;
           memory->sfree(force_buf);
           force_buf = NULL;
           imdsock_destroy(clientsock);
           clientsock = NULL;
           if (screen)
             fprintf(screen, "IMD client detached. LAMMPS run continues.\n");
 
           connect_msg = 1;
           reconnect();
           if (imd_terminate) imd_inactive = 1;
           break;
         }
 
         case IMD_KILL:
           /* stop the simulation job and shutdown IMD */
           if (screen)
             fprintf(screen, "IMD client requested termination of run.\n");
           imd_inactive = 1;
           imd_terminate = 1;
           imd_paused = 0;
           imdsock_destroy(clientsock);
           clientsock = NULL;
           break;
 
         case IMD_PAUSE:
           /* pause the running simulation. wait for second IMD_PAUSE to continue. */
           if (imd_paused) {
             if (screen) 
               fprintf(screen, "Continuing run on IMD client request.\n");
             imd_paused = 0;
           } else {
             if (screen)
               fprintf(screen, "Pausing run on IMD client request.\n");
             imd_paused = 1;
           }
           break;
 
         case IMD_TRATE:
           /* change the IMD transmission data rate */
           if (length > 0) 
             imd_trate = length;
           if (screen) 
             fprintf(screen, "IMD client requested change of transfer rate. Now it is %d.\n", imd_trate);
           break;
 
         case IMD_ENERGIES: {
           IMDEnergies dummy_energies;
           imd_recv_energies(clientsock, &dummy_energies);
           break;
         }
             
         case IMD_FCOORDS: {
           float *dummy_coords = new float[3*length];
           imd_recv_fcoords(clientsock, length, dummy_coords);
           delete[] dummy_coords;
           break;
         }
 
         case IMD_MDCOMM: {
           int32 *imd_tags = new int32[length];
           float *imd_fdat = new float[3*length];
           imd_recv_mdcomm(clientsock, length, imd_tags, imd_fdat);
 
           if (imd_forces < length) { /* grow holding space for forces, if needed. */
             if (force_buf != NULL) 
               memory->sfree(force_buf);
             force_buf = memory->smalloc(length*size_one, "imd:force_buf");
           }
           imd_forces = length;
           buf = static_cast<struct commdata *>(force_buf);
           
           /* compare data to hash table */
           for (int ii=0; ii < length; ++ii) {
             buf[ii].tag = rev_idmap[imd_tags[ii]];
             buf[ii].x   = imd_fdat[3*ii];
             buf[ii].y   = imd_fdat[3*ii+1];
             buf[ii].z   = imd_fdat[3*ii+2];
           }
           delete[] imd_tags;
           delete[] imd_fdat;
           break;
         }
             
         default:
           if (screen)
             fprintf(screen, "Unhandled incoming IMD message #%d. length=%d\n", msg, length);
           break;
       }
     }
   } else {
     /* copy coordinate data into communication buffer */
     nme = 0;
     if (unwrap_flag) {
       double xprd = domain->xprd;
       double yprd = domain->yprd;
       double zprd = domain->zprd;
 
       for (i=0; i<nlocal; ++i) {
         if (mask[i] & groupbit) {
           buf[nme].tag = tag[i];
           buf[nme].x   = x[i][0] + ((image[i] & 1023) - 512) * xprd;
           buf[nme].y   = x[i][1] + ((image[i] >> 10 & 1023) - 512) * yprd;
           buf[nme].z   = x[i][2] + ((image[i] >> 20) - 512) * zprd;
           ++nme;
         }
       }
     } else {
       for (i=0; i<nlocal; ++i) {
         if (mask[i] & groupbit) {
           buf[nme].tag = tag[i];
           buf[nme].x   = x[i][0];
           buf[nme].y   = x[i][1];
           buf[nme].z   = x[i][2];
           ++nme;
         }
       }
     }
     /* blocking receive to wait until it is our turn to send data. */
     MPI_Recv(&tmp, 0, MPI_INT, 0, 0, world, &status);
     MPI_Rsend(comm_buf, nme*size_one, MPI_BYTE, 0, 0, world);
   }
 
   /* update all tasks with current settings. */
   int old_imd_forces = imd_forces;
   MPI_Bcast(&imd_trate, 1, MPI_INT, 0, world);
   MPI_Bcast(&imd_inactive, 1, MPI_INT, 0, world);  
   MPI_Bcast(&imd_forces, 1, MPI_INT, 0, world);
   MPI_Bcast(&imd_terminate, 1, MPI_INT, 0, world);
   if (imd_terminate)
     error->all("LAMMPS terminated on IMD request.");
 
   if (imd_forces > 0) {
     /* check if we need to readjust the forces comm buffer on the receiving nodes. */
     if (me != 0) {
       if (old_imd_forces < imd_forces) { /* grow holding space for forces, if needed. */
         if (force_buf != NULL) 
           memory->sfree(force_buf);
         force_buf = memory->smalloc(imd_forces*size_one, "imd:force_buf");
       }
     }
     MPI_Bcast(force_buf, imd_forces*size_one, MPI_BYTE, 0, world);
   }
   return;
 }
 
 /* ---------------------------------------------------------------------- */
 void FixIMD::post_force_respa(int vflag, int ilevel, int iloop)
 {
   /* only process IMD on the outmost RESPA level. */
   if (ilevel == nlevels_respa-1) post_force(vflag);
   return;
 }
 
 /* ---------------------------------------------------------------------- */
 /* local memory usage. approximately. */
 double FixIMD::memory_usage(void)
 {
   return static_cast<double>(num_coords+maxbuf+imd_forces)*size_one;
 }
 
 /* End of FixIMD class implementation. */
 
 /************************************************************************
  * integer list sort code: 
  ************************************************************************/
 
 /* sort for integer map. initial call  id_sort(idmap, 0, natoms - 1); */
 void id_sort(int *idmap, int left, int right)
 {
   int pivot, l_hold, r_hold;
 
   l_hold = left;
   r_hold = right;
   pivot = idmap[left];
   
   while (left < right) {
     while ((idmap[right] >= pivot) && (left < right))
       right--;
     if (left != right) {
       idmap[left] = idmap[right];
       left++;
     }
     while ((idmap[left] <= pivot) && (left < right))
       left++;
     if (left != right) {
       idmap[right] = idmap[left];
       right--;
     }
   }
   idmap[left] = pivot;
   pivot = left;
   left = l_hold;
   right = r_hold;
 
   if (left < pivot)
     id_sort(idmap, left, pivot-1);
   if (right > pivot)
     id_sort(idmap, pivot+1, right);
 }
 
 /***************************************************************************/
 
 /* NOTE: the following code is the based on the example implementation
  * of the IMD protocol API from VMD and NAMD. The UIUC license allows 
  * to re-use up to 10% of a project's code to be used in other software */
 
 /***************************************************************************
  * DESCRIPTION:
  *   Socket interface, abstracts machine dependent APIs/routines. 
  ***************************************************************************/
 
 int imdsock_init(void) {
 #if defined(_MSC_VER)
   int rc = 0;
   static int initialized=0;
 
   if (!initialized) {
     WSADATA wsdata;
     rc = WSAStartup(MAKEWORD(1,1), &wsdata);
     if (rc == 0)
       initialized = 1;
   }
 
   return rc;
 #else   
   return 0;
 #endif
 }
 
 
 void * imdsock_create(void) {
   imdsocket * s;
 
   s = (imdsocket *) malloc(sizeof(imdsocket));
   if (s != NULL)
     memset(s, 0, sizeof(imdsocket)); 
 
   if ((s->sd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
     printf("Failed to open socket.");
     free(s);
     return NULL;
   }
 
   return (void *) s;
 }
 
 int imdsock_bind(void * v, int port) {
   imdsocket *s = (imdsocket *) v;
   memset(&(s->addr), 0, sizeof(s->addr)); 
   s->addr.sin_family = PF_INET;
   s->addr.sin_port = htons(port);
 
   return bind(s->sd, (struct sockaddr *) &s->addr, sizeof(s->addr));
 }
 
 int imdsock_listen(void * v) {
   imdsocket *s = (imdsocket *) v;
   return listen(s->sd, 5);
 }
 
 void *imdsock_accept(void * v) {
   int rc;
   imdsocket *new_s = NULL, *s = (imdsocket *) v;
 #if defined(ARCH_AIX5) || defined(ARCH_AIX5_64) || defined(ARCH_AIX6_64)
   unsigned int len;
 #elif defined(SOCKLEN_T)
   SOCKLEN_T len;
 #elif defined(_POSIX_SOURCE)
   socklen_t len;
 #else
   int len;
 #endif
 
   len = sizeof(s->addr);
   rc = accept(s->sd, (struct sockaddr *) &s->addr, ( socklen_t * ) &len);
   if (rc >= 0) {
     new_s = (imdsocket *) malloc(sizeof(imdsocket));
     if (new_s != NULL) {
       *new_s = *s;
       new_s->sd = rc;
     }
   }
   return (void *)new_s;
 }
 
 int  imdsock_write(void * v, const void *buf, int len) {
   imdsocket *s = (imdsocket *) v;
 #if defined(_MSC_VER)
   return send(s->sd, (const char*) buf, len, 0);  /* windows lacks the write() call */
 #else
   return write(s->sd, buf, len);
 #endif
 }
 
 int  imdsock_read(void * v, void *buf, int len) {
   imdsocket *s = (imdsocket *) v;
 #if defined(_MSC_VER)
   return recv(s->sd, (char*) buf, len, 0); /* windows lacks the read() call */
 #else
   return read(s->sd, buf, len);
 #endif
 
 }
 
 void imdsock_shutdown(void *v) {
   imdsocket * s = (imdsocket *) v;
   if (s == NULL)
     return;
 
 #if defined(_MSC_VER)
   shutdown(s->sd, SD_SEND);
 #else
   shutdown(s->sd, 1);  /* complete sends and send FIN */
 #endif
 }
 
 void imdsock_destroy(void * v) {
   imdsocket * s = (imdsocket *) v;
   if (s == NULL)
     return;
 
 #if defined(_MSC_VER)
   closesocket(s->sd);
 #else
   close(s->sd);
 #endif
   free(s);  
 }
 
 int imdsock_selread(void *v, int sec) {
   imdsocket *s = (imdsocket *)v;
   fd_set rfd;
   struct timeval tv;
   int rc;
  
   if (v == NULL) return 0;
   
   FD_ZERO(&rfd);
   FD_SET(s->sd, &rfd);
   memset((void *)&tv, 0, sizeof(struct timeval));
   tv.tv_sec = sec;
   do {
     rc = select(s->sd+1, &rfd, NULL, NULL, &tv);
   } while (rc < 0 && errno == EINTR);
   return rc;
 
 }
   
 int imdsock_selwrite(void *v, int sec) {
   imdsocket *s = (imdsocket *)v;
   fd_set wfd;
   struct timeval tv;
   int rc;
  
   if (v == NULL) return 0;
 
   FD_ZERO(&wfd);
   FD_SET(s->sd, &wfd);
   memset((void *)&tv, 0, sizeof(struct timeval));
   tv.tv_sec = sec;
   do {
     rc = select(s->sd + 1, NULL, &wfd, NULL, &tv);
   } while (rc < 0 && errno == EINTR);
   return rc;
 }
 
 /* end of socket code. */
 /*************************************************************************/
 
 /*************************************************************************/
 /* start of imd API code. */
 /* Only works with aligned 4-byte quantities, will cause a bus error */
 /* on some platforms if used on unaligned data.                      */
 void swap4_aligned(void *v, long ndata) {
   int *data = (int *) v;
   long i;
   int *N;
   for (i=0; i<ndata; i++) {
     N = data + i;
     *N=(((*N>>24)&0xff) | ((*N&0xff)<<24) |
         ((*N>>8)&0xff00) | ((*N&0xff00)<<8));
   }
 }
 
 
 /** structure used to perform byte swapping operations */
 typedef union {
   int32 i;
   struct {
     unsigned int highest : 8;
     unsigned int high    : 8;
     unsigned int low     : 8;
     unsigned int lowest  : 8;
   } b;
 } netint;
 
 static int32 imd_htonl(int32 h) {
   netint n;
   n.b.highest = h >> 24;
   n.b.high    = h >> 16;
   n.b.low     = h >> 8;
   n.b.lowest  = h;
   return n.i;
 }
 
 static int32 imd_ntohl(int32 n) {
   netint u;
   u.i = n;
   return (u.b.highest << 24 | u.b.high << 16 | u.b.low << 8 | u.b.lowest);
 }
 
 static void imd_fill_header(IMDheader *header, IMDType type, int32 length) {
   header->type = imd_htonl((int32)type);
   header->length = imd_htonl(length);
 }
 
 static void swap_header(IMDheader *header) {
   header->type = imd_ntohl(header->type);
   header->length= imd_ntohl(header->length);
 }
 
 static int32 imd_readn(void *s, char *ptr, int32 n) {
   int32 nleft;
   int32 nread;
  
   nleft = n;
   while (nleft > 0) {
     if ((nread = imdsock_read(s, ptr, nleft)) < 0) {
       if (errno == EINTR)
         nread = 0;         /* and call read() again */
       else
         return -1;
     } else if (nread == 0)
       break;               /* EOF */
     nleft -= nread;
     ptr += nread;
   }
   return n-nleft;
 }
 
 static int32 imd_writen(void *s, const char *ptr, int32 n) {
   int32 nleft;
   int32 nwritten;
 
   nleft = n;
   while (nleft > 0) {
     if ((nwritten = imdsock_write(s, ptr, nleft)) <= 0) {
       if (errno == EINTR)
         nwritten = 0;
       else
         return -1;
     }
     nleft -= nwritten;
     ptr += nwritten;
   }
   return n;
 }
 
 int imd_disconnect(void *s) {
   IMDheader header;
   imd_fill_header(&header, IMD_DISCONNECT, 0);
   return (imd_writen(s, (char *)&header, IMDHEADERSIZE) != IMDHEADERSIZE);
 }
 
 int imd_handshake(void *s) {
   IMDheader header;
   imd_fill_header(&header, IMD_HANDSHAKE, 1);
   header.length = IMDVERSION;   /* Not byteswapped! */
   return (imd_writen(s, (char *)&header, IMDHEADERSIZE) != IMDHEADERSIZE);
 }
 
 /* The IMD receive functions */
 
 IMDType imd_recv_header(void *s, int32 *length) {
   IMDheader header;
   if (imd_readn(s, (char *)&header, IMDHEADERSIZE) != IMDHEADERSIZE)
     return IMD_IOERROR;
   swap_header(&header);
   *length = header.length;
   return IMDType(header.type); 
 }
 
 int imd_recv_mdcomm(void *s, int32 n, int32 *indices, float *forces) {
   if (imd_readn(s, (char *)indices, 4*n) != 4*n) return 1;
   if (imd_readn(s, (char *)forces, 12*n) != 12*n) return 1;
   return 0;
 }
 
 int imd_recv_energies(void *s, IMDEnergies *energies) {
   return (imd_readn(s, (char *)energies, sizeof(IMDEnergies))
           != sizeof(IMDEnergies));
 }
 
 int imd_recv_fcoords(void *s, int32 n, float *coords) {
   return (imd_readn(s, (char *)coords, 12*n) != 12*n);
 }
 
 /************************************************************************
  * integer hash code:
  ************************************************************************/
 
 /* inthash() - Hash function returns a hash number for a given key.
  * tptr: Pointer to a hash table, key: The key to create a hash number for */
 static int inthash(const inthash_t *tptr, int key) {
   int hashvalue;
 
   hashvalue = (((key*1103515249)>>tptr->downshift) & tptr->mask);
   if (hashvalue < 0) {
     hashvalue = 0;
   }    
 
   return hashvalue;
 }
 
 /*
  *  rebuild_table_int() - Create new hash table when old one fills up.
  *
  *  tptr: Pointer to a hash table
  */
 static void rebuild_table_int(inthash_t *tptr) {
   inthash_node_t **old_bucket, *old_hash, *tmp;
   int old_size, h, i;
 
   old_bucket=tptr->bucket;
   old_size=tptr->size;
 
   /* create a new table and rehash old buckets */
   inthash_init(tptr, old_size<<1);
   for (i=0; i<old_size; i++) {
     old_hash=old_bucket[i];
     while(old_hash) {
       tmp=old_hash;
       old_hash=old_hash->next;
       h=inthash(tptr, tmp->key);
       tmp->next=tptr->bucket[h];
       tptr->bucket[h]=tmp;
       tptr->entries++;
     } /* while */
   } /* for */
 
   /* free memory used by old table */
   free(old_bucket);
 
   return;
 }
 
 /*
  *  inthash_init() - Initialize a new hash table.
  *
  *  tptr: Pointer to the hash table to initialize
  *  buckets: The number of initial buckets to create
  */
 void inthash_init(inthash_t *tptr, int buckets) {
 
   /* make sure we allocate something */
   if (buckets==0)
     buckets=16;
 
   /* initialize the table */
   tptr->entries=0;
   tptr->size=2;
   tptr->mask=1;
   tptr->downshift=29;
 
   /* ensure buckets is a power of 2 */
   while (tptr->size<buckets) {
     tptr->size<<=1;
     tptr->mask=(tptr->mask<<1)+1;
     tptr->downshift--;
   } /* while */
 
   /* allocate memory for table */
   tptr->bucket=(inthash_node_t **) calloc(tptr->size, sizeof(inthash_node_t *));
 
   return;
 }
 
 /*
  *  inthash_lookup() - Lookup an entry in the hash table and return a pointer to
  *    it or HASH_FAIL if it wasn't found.
  *
  *  tptr: Pointer to the hash table
  *  key: The key to lookup
  */
 int inthash_lookup(const inthash_t *tptr, int key) {
   int h;
   inthash_node_t *node;
 
 
   /* find the entry in the hash table */
   h=inthash(tptr, key);
   for (node=tptr->bucket[h]; node!=NULL; node=node->next) {
     if (node->key == key)
       break;
   }
 
   /* return the entry if it exists, or HASH_FAIL */
   return(node ? node->data : HASH_FAIL);
 }
 
 
 /*
  *  inthash_keys() - Return a list of keys.
  *  NOTE: the returned list must be freed with free(3).
  */
 int *inthash_keys(inthash_t *tptr) {
 
   int *keys;
   inthash_node_t *node;
   
   keys = (int *)calloc(tptr->entries, sizeof(int));
   
   for (int i=0; i < tptr->size; ++i) {
     for (node=tptr->bucket[i]; node != NULL; node=node->next) {
       keys[node->data] = node->key;
     }
   }
   
   return keys;
 }
 
 /*
  *  inthash_insert() - Insert an entry into the hash table.  If the entry already
  *  exists return a pointer to it, otherwise return HASH_FAIL.
  *
  *  tptr: A pointer to the hash table
  *  key: The key to insert into the hash table
  *  data: A pointer to the data to insert into the hash table
  */
 int inthash_insert(inthash_t *tptr, int key, int data) {
   int tmp;
   inthash_node_t *node;
   int h;
 
   /* check to see if the entry exists */
   if ((tmp=inthash_lookup(tptr, key)) != HASH_FAIL)
     return(tmp);
 
   /* expand the table if needed */
   while (tptr->entries>=HASH_LIMIT*tptr->size)
     rebuild_table_int(tptr);
 
   /* insert the new entry */
   h=inthash(tptr, key);
   node=(struct inthash_node_t *) malloc(sizeof(inthash_node_t));
   node->data=data;
   node->key=key;
   node->next=tptr->bucket[h];
   tptr->bucket[h]=node;
   tptr->entries++;
 
   return HASH_FAIL;
 }
 
 /*
  * inthash_destroy() - Delete the entire table, and all remaining entries.
  * 
  */
 void inthash_destroy(inthash_t *tptr) {
   inthash_node_t *node, *last;
   int i;
 
   for (i=0; i<tptr->size; i++) {
     node = tptr->bucket[i];
     while (node != NULL) { 
       last = node;   
       node = node->next;
       free(last);
     }
   }     
 
   /* free the entire array of buckets */
   if (tptr->bucket != NULL) {
     free(tptr->bucket);
     memset(tptr, 0, sizeof(inthash_t));
   }
 }
 
 
 // Local Variables:
 // mode: c++
 // compile-command: "make -j4 openmpi"
 // c-basic-offset: 2
 // fill-column: 76
 // indent-tabs-mode: nil
 // End:
 
diff --git a/src/XTC/dump_xtc.cpp b/src/XTC/dump_xtc.cpp
index 0aed69ea7..89ea2eb1c 100644
--- a/src/XTC/dump_xtc.cpp
+++ b/src/XTC/dump_xtc.cpp
@@ -1,1201 +1,1208 @@
 /* ----------------------------------------------------------------------
    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: Naveen Michaud-Agrawal (Johns Hopkins U)
                          open-source XDR routines from
 			   Frans van Hoesel (http://md.chem.rug.nl/hoesel)
 			   are included in this file
                          Axel Kohlmeyer (Temple U)
                            port to platforms without XDR support
                            added support for unwrapped trajectories
 			   support for groups
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "string.h"
 #include "limits.h"
 #include "dump_xtc.h"
 #include "domain.h"
 #include "atom.h"
 #include "update.h"
 #include "group.h"
 #include "output.h"
 #include "error.h"
 #include "memory.h"
 
 using namespace LAMMPS_NS;
 
 #define EPS 1e-5
 #define XTC_MAGIC 1995
 
 #define MYMIN(a,b) ((a) < (b) ? (a) : (b))
 #define MYMAX(a,b) ((a) > (b) ? (a) : (b))
 
 int xdropen(XDR *, const char *, const char *);
 int xdrclose(XDR *);
 void xdrfreebuf();
 int xdr3dfcoord(XDR *, float *, int *, float *);
 
 /* ---------------------------------------------------------------------- */
 
 DumpXTC::DumpXTC(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg)
 {
   if (narg != 5) error->all("Illegal dump xtc command");
   if (binary || compressed || multifile || multiproc)
     error->all("Invalid dump xtc filename");
 
   size_one = 3;
   sort_flag = 1;
   sortcol = 0;
   format_default = NULL;
   flush_flag = 0;
   unwrap_flag = 0;
   precision = 1000.0;
 
   // allocate global array for atom coords
 
-  if (igroup == 0) natoms = static_cast<int> (atom->natoms);
-  else natoms = static_cast<int> (group->count(igroup));
-  if (natoms <= 0) error->all("Invalid natoms for dump xtc");
+  bigint n = group->count(igroup);
+  if (n > MAXSMALLINT/3/sizeof(float)) 
+    error->all("Too many atoms for dump xtc");
+  natoms = static_cast<int> (n);
 
   coords = (float *) memory->smalloc(3*natoms*sizeof(float),"dump:coords");
 
   // sfactor = conversion of coords to XTC units
   // GROMACS standard is nanometers, not Angstroms
 
   sfactor = 0.1;
   if (strcmp(update->unit_style,"lj") == 0) sfactor = 1.0;
 
   openfile();
   nevery_save = 0;
   ntotal = 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 DumpXTC::~DumpXTC()
 {
   memory->sfree(coords);
 
   if (me == 0) {
     xdrclose(&xd);
     xdrfreebuf();
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpXTC::init_style()
 {
   if (sort_flag == 0 || sortcol != 0)
     error->all("Dump xtc requires sorting by atom ID");
 
   // check that flush_flag is not set since dump::write() will use it
 
   if (flush_flag) error->all("Cannot set dump_modify flush for dump xtc");
 
   // check that dump frequency has not changed and is not a variable
 
   int idump;
   for (idump = 0; idump < output->ndump; idump++)
     if (strcmp(id,output->dump[idump]->id) == 0) break;
   if (output->every_dump[idump] == 0)
     error->all("Cannot use variable every setting for dump xtc");
 
   if (nevery_save == 0) nevery_save = output->every_dump[idump];
   else if (nevery_save != output->every_dump[idump])
     error->all("Cannot change dump_modify every for dump xtc");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpXTC::openfile()
 {
   // XTC maintains it's own XDR file ptr
   // set fp to NULL so parent dump class will not use it
 
   fp = NULL;
   if (me == 0)
     if (xdropen(&xd,filename,"w") == 0) error->one("Cannot open dump file");
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpXTC::write_header(int n)
+void DumpXTC::write_header(bigint nbig)
 {
+  if (nbig > MAXSMALLINT) error->all("Too many atoms for dump xtc");
+  int n = nbig;
+  if (update->ntimestep > MAXSMALLINT)
+    error->all("Too big a timestep for dump xtc");
+  int ntimestep = update->ntimestep;
+
   // all procs realloc coords if total count grew
 
   if (n != natoms) {
     natoms = n;
     memory->sfree(coords);
     coords = (float *) memory->smalloc(3*natoms*sizeof(float),"dump:coords");
   }
 
   // only proc 0 writes header
 
   if (me != 0) return;
 
   int tmp = XTC_MAGIC;
   xdr_int(&xd,&tmp);
   xdr_int(&xd,&n);
-  xdr_int(&xd,&update->ntimestep);
-  float time_value = update->ntimestep * update->dt;
+  xdr_int(&xd,&ntimestep);
+  float time_value = ntimestep * update->dt;
   xdr_float(&xd,&time_value);
 
   // cell basis vectors
   if (domain->triclinic) {
     float zero = 0.0;
     float xdim = sfactor * (domain->boxhi[0] - domain->boxlo[0]);
     float ydim = sfactor * (domain->boxhi[1] - domain->boxlo[1]);
     float zdim = sfactor * (domain->boxhi[2] - domain->boxlo[2]);
     float xy = sfactor * domain->xy;
     float xz = sfactor * domain->xz;
     float yz = sfactor * domain->yz;
 
     xdr_float(&xd,&xdim); xdr_float(&xd,&zero); xdr_float(&xd,&zero);
     xdr_float(&xd,&xy  ); xdr_float(&xd,&ydim); xdr_float(&xd,&zero);
     xdr_float(&xd,&xz  ); xdr_float(&xd,&yz  ); xdr_float(&xd,&zdim);
   } else {
     float zero = 0.0;
     float xdim = sfactor * (domain->boxhi[0] - domain->boxlo[0]);
     float ydim = sfactor * (domain->boxhi[1] - domain->boxlo[1]);
     float zdim = sfactor * (domain->boxhi[2] - domain->boxlo[2]);
 
     xdr_float(&xd,&xdim); xdr_float(&xd,&zero); xdr_float(&xd,&zero);
     xdr_float(&xd,&zero); xdr_float(&xd,&ydim); xdr_float(&xd,&zero);
     xdr_float(&xd,&zero); xdr_float(&xd,&zero); xdr_float(&xd,&zdim);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpXTC::count()
 {
   if (igroup == 0) return atom->nlocal;
 
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int m = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) m++;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpXTC::pack(int *ids)
 {
   int m,n;
 
   int *tag = atom->tag;
   double **x = atom->x;
   int *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   m = n = 0;
   if (unwrap_flag == 1) {
     double xprd = domain->xprd;
     double yprd = domain->yprd;
     double zprd = domain->zprd;
     double xy = domain->xy;
     double xz = domain->xz;
     double yz = domain->yz;
 
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	int ix = (image[i] & 1023) - 512;
 	int iy = (image[i] >> 10 & 1023) - 512;
 	int iz = (image[i] >> 20) - 512;
 	
 	if (domain->triclinic) {
 	  buf[m++] = sfactor * (x[i][0] + ix * xprd + iy * xy + iz * xz);
 	  buf[m++] = sfactor * (x[i][1] + iy * yprd + iz * yz);
 	  buf[m++] = sfactor * (x[i][2] + iz * zprd);
 	} else {
 	  buf[m++] = sfactor * (x[i][0] + ix * xprd);
 	  buf[m++] = sfactor * (x[i][1] + iy * yprd);
 	  buf[m++] = sfactor * (x[i][2] + iz * zprd);
 	}
 	ids[n++] = tag[i];
       }
 
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	buf[m++] = sfactor*x[i][0];
 	buf[m++] = sfactor*x[i][1];
 	buf[m++] = sfactor*x[i][2];
 	ids[n++] = tag[i];
       }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpXTC::write_data(int n, double *mybuf)
 {
   int j;
 
   // copy buf atom coords into global array
 
   int m = 0;
   int k = 3*ntotal;
   for (int i = 0; i < n; i++) {
     coords[k++] = mybuf[m++];
     coords[k++] = mybuf[m++];
     coords[k++] = mybuf[m++];
     ntotal++;
   }
 
   // if last chunk of atoms in this snapshot, write global arrays to file
 
   if (ntotal == natoms) {
     write_frame();
     ntotal = 0;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpXTC::modify_param(int narg, char **arg)
 {
   if (strcmp(arg[0],"unwrap") == 0) {
     if (narg < 2) error->all("Illegal dump_modify command");
     if (strcmp(arg[1],"yes") == 0) unwrap_flag = 1;
     else if (strcmp(arg[1],"no") == 0) unwrap_flag = 0;
     else error->all("Illegal dump_modify command");
     return 2;
   } else if (strcmp(arg[0],"precision") == 0) {
     if (narg < 2) error->all("Illegal dump_modify command");
     precision = atof(arg[1]);
     if ((fabs(precision-10.0) > EPS) && (fabs(precision-100.0) > EPS) && 
 	(fabs(precision-1000.0) > EPS) && (fabs(precision-10000.0) > EPS) && 
 	(fabs(precision-100000.0) > EPS) && 
 	(fabs(precision-1000000.0) > EPS)) 
       error->all("Illegal dump_modify command");
     return 2;
   }
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory in buf and global coords array
 ------------------------------------------------------------------------- */
 
 double DumpXTC::memory_usage()
 {
   double bytes = Dump::memory_usage();
   bytes += 3*natoms * sizeof(float);
   return bytes;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpXTC::write_frame()
 {
   xdr3dfcoord(&xd,coords,&natoms,&precision);
 }
 
 // ----------------------------------------------------------------------
 // C functions that create GROMOS-compatible XDR files
 // open-source
 // (c) 1995 Frans van Hoesel, hoesel@chem.rug.nl
 // ----------------------------------------------------------------------
 
 /*____________________________________________________________________________
  |
  | Below are the routines to be used by C programmers. Use the 'normal'
  | xdr routines to write integers, floats, etc (see man xdr)	
  |
  | int xdropen(XDR *xdrs, const char *filename, const char *type)
  |	This will open the file with the given filename and the 
  |	given mode. You should pass it an allocated XDR struct
  |	in xdrs, to be used in all other calls to xdr routines.
  |	Mode is 'w' to create, or update an file, and for all 
  |	other values of mode the file is opened for reading. 
  |	You need to call xdrclose to flush the output and close
  |	the file.
  |
  |	Note that you should not use xdrstdio_create, which
  |	comes with the standard xdr library.
  |
  | int xdrclose(XDR *xdrs)
  |	Flush the data to the file, and close the file;
  |	You should not use xdr_destroy (which comes standard
  |	with the xdr libraries).
  |	 
  | int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision)
  |	This is \fInot\fR a standard xdr routine. I named it this 
  |	way, because it invites people to use the other xdr 
  |	routines.
  |
  |	(c) 1995 Frans van Hoesel, hoesel@chem.rug.nl
 */	
 
 #define MAXID 20
 static FILE *xdrfiles[MAXID];
 static XDR *xdridptr[MAXID];
 static char xdrmodes[MAXID];
 static int *ip = NULL;
 static int *buf = NULL;
 
 /*___________________________________________________________________________
  |
  | what follows are the C routines for opening, closing xdr streams
  | and the routine to read/write compressed coordinates together
  | with some routines to assist in this task (those are marked
  | static and cannot be called from user programs)
 */
 #define MAXABS INT_MAX-2
 
 #ifndef SQR
 #define SQR(x) ((x)*(x))
 #endif
 static int magicints[] = {
   0, 0, 0, 0, 0, 0, 0, 0, 0,
   8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
   80, 101, 128, 161, 203, 256, 322, 406, 512, 645,
   812, 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501,
   8192, 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536,
   82570, 104031, 131072, 165140, 208063, 262144, 330280, 416127, 
   524287, 660561,
   832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 
   4194304, 5284491, 6658042,
   8388607, 10568983, 13316085, 16777216 };
 
 #define FIRSTIDX 9
 /* note that magicints[FIRSTIDX-1] == 0 */
 #define LASTIDX (sizeof(magicints) / sizeof(*magicints))
 
 /*__________________________________________________________________________
  |
  | xdropen - open xdr file
  |
  | This versions differs from xdrstdio_create, because I need to know
  | the state of the file (read or write) so I can use xdr3dfcoord
  | in eigther read or write mode, and the file descriptor
  | so I can close the file (something xdr_destroy doesn't do).
  |
 */
 
 int xdropen(XDR *xdrs, const char *filename, const char *type)
 {
   static int init_done = 0;
   enum xdr_op lmode;
   int xdrid;
     
   if (init_done == 0) {
     for (xdrid = 1; xdrid < MAXID; xdrid++) {
       xdridptr[xdrid] = NULL;
     }
     init_done = 1;
   }
   xdrid = 1;
   while (xdrid < MAXID && xdridptr[xdrid] != NULL) {
     xdrid++;
   }
   if (xdrid == MAXID) {
     return 0;
   }
   if (*type == 'w' || *type == 'W') {
     type = (char *) "w+";
     lmode = XDR_ENCODE;
   } else {
     type = (char *) "r";
     lmode = XDR_DECODE;
   }
   xdrfiles[xdrid] = fopen(filename, type);
   if (xdrfiles[xdrid] == NULL) {
     xdrs = NULL;
     return 0;
   }
   xdrmodes[xdrid] = *type;
 
   /* next test isn't usefull in the case of C language
    * but is used for the Fortran interface
    * (C users are expected to pass the address of an already allocated
    * XDR staructure)
    */
   if (xdrs == NULL) {
     xdridptr[xdrid] = (XDR *) malloc(sizeof(XDR));
     xdrstdio_create(xdridptr[xdrid], xdrfiles[xdrid], lmode);
   } else {
     xdridptr[xdrid] = xdrs;
     xdrstdio_create(xdrs, xdrfiles[xdrid], lmode);
   }
   return xdrid;
 }
 
 /*_________________________________________________________________________
  |
  | xdrclose - close a xdr file
  |
  | This will flush the xdr buffers, and destroy the xdr stream.
  | It also closes the associated file descriptor (this is *not*
  | done by xdr_destroy).
  |
 */
  
 int xdrclose(XDR *xdrs)
 {
   int xdrid;
     
   if (xdrs == NULL) {
     fprintf(stderr, "xdrclose: passed a NULL pointer\n");
     exit(1);
   }
   for (xdrid = 1; xdrid < MAXID; xdrid++) {
     if (xdridptr[xdrid] == xdrs) {
       
       xdr_destroy(xdrs);
       fclose(xdrfiles[xdrid]);
       xdridptr[xdrid] = NULL;
       return 1;
     }
   } 
   fprintf(stderr, "xdrclose: no such open xdr file\n");
   exit(1);
   return 1;
 }
 
 /*_________________________________________________________________________
  |
  | xdrfreebuf - free the buffers used by xdr3dfcoord
  |
 */
 void xdrfreebuf()
 {
   if (ip) free(ip);
   if (buf) free(buf);
   ip = NULL;
   buf = NULL;
 }
 
 
 /*____________________________________________________________________________
  |
  | sendbits - encode num into buf using the specified number of bits
  |
  | This routines appends the value of num to the bits already present in
  | the array buf. You need to give it the number of bits to use and you
  | better make sure that this number of bits is enough to hold the value
  | Also num must be positive.
  |
 */
 
 static void sendbits(int buf[], int num_of_bits, int num)
 {
   unsigned int cnt, lastbyte;
   int lastbits;
   unsigned char * cbuf;
     
   cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
   cnt = (unsigned int) buf[0];
   lastbits = buf[1];
   lastbyte =(unsigned int) buf[2];
   while (num_of_bits >= 8) {
     lastbyte = (lastbyte << 8) | ((num >> (num_of_bits -8)) /* & 0xff*/);
     cbuf[cnt++] = lastbyte >> lastbits;
     num_of_bits -= 8;
   }
   if (num_of_bits > 0) {
     lastbyte = (lastbyte << num_of_bits) | num;
     lastbits += num_of_bits;
     if (lastbits >= 8) {
       lastbits -= 8;
       cbuf[cnt++] = lastbyte >> lastbits;
     }
   }
   buf[0] = cnt;
   buf[1] = lastbits;
   buf[2] = lastbyte;
   if (lastbits>0) {
     cbuf[cnt] = lastbyte << (8 - lastbits);
   }
 }
 
 /*_________________________________________________________________________
  |
  | sizeofint - calculate bitsize of an integer
  |
  | return the number of bits needed to store an integer with given max size
  |
 */
 
 static int sizeofint(const int size)
 {
   unsigned int num = 1;
   int num_of_bits = 0;
   
   while (size >= num && num_of_bits < 32) {
     num_of_bits++;
     num <<= 1;
   }
   return num_of_bits;
 }
 
 /*___________________________________________________________________________
  |
  | sizeofints - calculate 'bitsize' of compressed ints
  |
  | given the number of small unsigned integers and the maximum value
  | return the number of bits needed to read or write them with the
  | routines receiveints and sendints. You need this parameter when
  | calling these routines. Note that for many calls I can use
  | the variable 'smallidx' which is exactly the number of bits, and
  | So I don't need to call 'sizeofints for those calls.
 */
 
 static int sizeofints( const int num_of_ints, unsigned int sizes[])
 {
   int i, num;
   unsigned int num_of_bytes, num_of_bits, bytes[32], bytecnt, tmp;
   num_of_bytes = 1;
   bytes[0] = 1;
   num_of_bits = 0;
   for (i=0; i < num_of_ints; i++) {	
     tmp = 0;
     for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++) {
       tmp = bytes[bytecnt] * sizes[i] + tmp;
       bytes[bytecnt] = tmp & 0xff;
       tmp >>= 8;
     }
     while (tmp != 0) {
       bytes[bytecnt++] = tmp & 0xff;
       tmp >>= 8;
     }
     num_of_bytes = bytecnt;
   }
   num = 1;
   num_of_bytes--;
   while (bytes[num_of_bytes] >= num) {
     num_of_bits++;
     num *= 2;
   }
   return num_of_bits + num_of_bytes * 8;
 }
 
 /*____________________________________________________________________________
  |
  | sendints - send a small set of small integers in compressed 
  |
  | this routine is used internally by xdr3dfcoord, to send a set of
  | small integers to the buffer. 
  | Multiplication with fixed (specified maximum ) sizes is used to get
  | to one big, multibyte integer. Allthough the routine could be
  | modified to handle sizes bigger than 16777216, or more than just
  | a few integers, this is not done, because the gain in compression
  | isn't worth the effort. Note that overflowing the multiplication
  | or the byte buffer (32 bytes) is unchecked and causes bad results.
  |
  */
  
 static void sendints(int buf[], const int num_of_ints, const int num_of_bits,
 		     unsigned int sizes[], unsigned int nums[])
 {
   int i;
   unsigned int bytes[32], num_of_bytes, bytecnt, tmp;
   
   tmp = nums[0];
   num_of_bytes = 0;
   do {
     bytes[num_of_bytes++] = tmp & 0xff;
     tmp >>= 8;
   } while (tmp != 0);
   
   for (i = 1; i < num_of_ints; i++) {
     if (nums[i] >= sizes[i]) {
       fprintf(stderr,"major breakdown in sendints num %d doesn't "
 	      "match size %d\n", nums[i], sizes[i]);
       exit(1);
     }
     /* use one step multiply */    
     tmp = nums[i];
     for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++) {
       tmp = bytes[bytecnt] * sizes[i] + tmp;
       bytes[bytecnt] = tmp & 0xff;
       tmp >>= 8;
     }
     while (tmp != 0) {
       bytes[bytecnt++] = tmp & 0xff;
       tmp >>= 8;
     }
     num_of_bytes = bytecnt;
   }
   if (num_of_bits >= num_of_bytes * 8) {
     for (i = 0; i < num_of_bytes; i++) {
       sendbits(buf, 8, bytes[i]);
     }
     sendbits(buf, num_of_bits - num_of_bytes * 8, 0);
   } else {
     for (i = 0; i < num_of_bytes-1; i++) {
       sendbits(buf, 8, bytes[i]);
     }
     sendbits(buf, num_of_bits- (num_of_bytes -1) * 8, bytes[i]);
   }
 }
 
 /*___________________________________________________________________________
  |
  | receivebits - decode number from buf using specified number of bits
  | 
  | extract the number of bits from the array buf and construct an integer
  | from it. Return that value.
  |
 */
 
 static int receivebits(int buf[], int num_of_bits)
 {
   int cnt, num; 
   unsigned int lastbits, lastbyte;
   unsigned char * cbuf;
   int mask = (1 << num_of_bits) -1;
   
   cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
   cnt = buf[0];
   lastbits = (unsigned int) buf[1];
   lastbyte = (unsigned int) buf[2];
   
   num = 0;
   while (num_of_bits >= 8) {
     lastbyte = ( lastbyte << 8 ) | cbuf[cnt++];
     num |=  (lastbyte >> lastbits) << (num_of_bits - 8);
     num_of_bits -=8;
   }
   if (num_of_bits > 0) {
     if (lastbits < num_of_bits) {
       lastbits += 8;
       lastbyte = (lastbyte << 8) | cbuf[cnt++];
     }
     lastbits -= num_of_bits;
     num |= (lastbyte >> lastbits) & ((1 << num_of_bits) -1);
   }
   num &= mask;
   buf[0] = cnt;
   buf[1] = lastbits;
   buf[2] = lastbyte;
   return num; 
 }
 
 /*____________________________________________________________________________
  |
  | receiveints - decode 'small' integers from the buf array
  |
  | this routine is the inverse from sendints() and decodes the small integers
  | written to buf by calculating the remainder and doing divisions with
  | the given sizes[]. You need to specify the total number of bits to be
  | used from buf in num_of_bits.
  |
 */
 
 static void receiveints(int buf[], const int num_of_ints, int num_of_bits,
 			unsigned int sizes[], int nums[])
 {
   int bytes[32];
   int i, j, num_of_bytes, p, num;
   
   bytes[1] = bytes[2] = bytes[3] = 0;
   num_of_bytes = 0;
   while (num_of_bits > 8) {
     bytes[num_of_bytes++] = receivebits(buf, 8);
     num_of_bits -= 8;
   }
   if (num_of_bits > 0) {
     bytes[num_of_bytes++] = receivebits(buf, num_of_bits);
   }
   for (i = num_of_ints-1; i > 0; i--) {
     num = 0;
     for (j = num_of_bytes-1; j >=0; j--) {
       num = (num << 8) | bytes[j];
       p = num / sizes[i];
       bytes[j] = p;
       num = num - p * sizes[i];
     }
     nums[i] = num;
   }
   nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
 }
    
 /*____________________________________________________________________________
  |
  | xdr3dfcoord - read or write compressed 3d coordinates to xdr file.
  |
  | this routine reads or writes (depending on how you opened the file with
  | xdropen() ) a large number of 3d coordinates (stored in *fp).
  | The number of coordinates triplets to write is given by *size. On
  | read this number may be zero, in which case it reads as many as were written
  | or it may specify the number if triplets to read (which should match the
  | number written).
  | Compression is achieved by first converting all floating numbers to integer
  | using multiplication by *precision and rounding to the nearest integer.
  | Then the minimum and maximum value are calculated to determine the range.
  | The limited range of integers so found, is used to compress the coordinates.
  | In addition the differences between succesive coordinates is calculated.
  | If the difference happens to be 'small' then only the difference is saved,
  | compressing the data even more. The notion of 'small' is changed dynamically
  | and is enlarged or reduced whenever needed or possible.
  | Extra compression is achieved in the case of GROMOS and coordinates of
  | water molecules. GROMOS first writes out the Oxygen position, followed by
  | the two hydrogens. In order to make the differences smaller (and thereby
  | compression the data better) the order is changed into first one hydrogen
  | then the oxygen, followed by the other hydrogen. This is rather special, but
  | it shouldn't harm in the general case.
  |
  */
  
 int xdr3dfcoord(XDR *xdrs, float *fp, int *size, float *precision)
 {
   static int oldsize;
   
   int minint[3], maxint[3], mindiff, *lip, diff;
   int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
   int minidx, maxidx;
   unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
   int flag, k;
   int small, smaller, larger, i, is_small, is_smaller, run, prevrun;
   float *lfp, lf;
   int tmp, *thiscoord,  prevcoord[3];
   unsigned int tmpcoord[30];
   
   int bufsize, xdrid, lsize;
   unsigned int bitsize;
   float inv_precision;
   int errval = 1;
   
   /* find out if xdrs is opened for reading or for writing */
   xdrid = 0;
   while (xdridptr[xdrid] != xdrs) {
     xdrid++;
     if (xdrid >= MAXID) {
       fprintf(stderr, "xdr error. no open xdr stream\n");
       exit (1);
     }
   }
   if (xdrmodes[xdrid] == 'w') {
     
     /* xdrs is open for writing */
     
     if (xdr_int(xdrs, size) == 0)
       return 0;
     size3 = *size * 3;
     /* when the number of coordinates is small, don't try to compress; just
      * write them as floats using xdr_vector
      */
     if (*size <= 9 ) {
       return (xdr_vector(xdrs, (char *) fp, size3, sizeof(*fp),
 			 (xdrproc_t)xdr_float));
     }
     
     xdr_float(xdrs, precision);
     if (ip == NULL) {
       ip = (int *) malloc(size3 * sizeof(*ip));
       if (ip == NULL) {
 	fprintf(stderr,"malloc failed\n");
 	exit(1);
       }
       bufsize = (int) (size3 * 1.2);
       buf = (int *) malloc(bufsize * sizeof(*buf));
       if (buf == NULL) {
 	fprintf(stderr,"malloc failed\n");
 	exit(1);
       }
       oldsize = *size;
     } else if (*size > oldsize) {
       ip = (int *) realloc(ip, size3 * sizeof(*ip));
       if (ip == NULL) {
 	fprintf(stderr,"malloc failed\n");
 	exit(1);
       }
       bufsize = (int) (size3 * 1.2);
       buf = (int *) realloc(buf, bufsize * sizeof(*buf));
       if (buf == NULL) {
 	fprintf(stderr,"malloc failed\n");
 	exit(1);
       }
       oldsize = *size;
     }
     /* buf[0-2] are special and do not contain actual data */
     buf[0] = buf[1] = buf[2] = 0;
     minint[0] = minint[1] = minint[2] = INT_MAX;
     maxint[0] = maxint[1] = maxint[2] = INT_MIN;
     prevrun = -1;
     lfp = fp;
     lip = ip;
     mindiff = INT_MAX;
     oldlint1 = oldlint2 = oldlint3 = 0;
     while(lfp < fp + size3 ) {
       /* find nearest integer */
       if (*lfp >= 0.0)
 	lf = *lfp * *precision + 0.5;
       else
 	lf = *lfp * *precision - 0.5;
       if (fabs(lf) > MAXABS) {
 	/* scaling would cause overflow */
 	errval = 0;
       }
       lint1 = (int) lf;
       if (lint1 < minint[0]) minint[0] = lint1;
       if (lint1 > maxint[0]) maxint[0] = lint1;
       *lip++ = lint1;
       lfp++;
       if (*lfp >= 0.0)
 	lf = *lfp * *precision + 0.5;
       else
 	lf = *lfp * *precision - 0.5;
       if (fabs(lf) > MAXABS) {
 	/* scaling would cause overflow */
 	errval = 0;
       }
       lint2 = (int) lf;
       if (lint2 < minint[1]) minint[1] = lint2;
       if (lint2 > maxint[1]) maxint[1] = lint2;
       *lip++ = lint2;
       lfp++;
       if (*lfp >= 0.0)
 	lf = *lfp * *precision + 0.5;
       else
 	lf = *lfp * *precision - 0.5;
       if (fabs(lf) > MAXABS) {
 	/* scaling would cause overflow */
 	errval = 0;
       }
       lint3 = (int) lf;
       if (lint3 < minint[2]) minint[2] = lint3;
       if (lint3 > maxint[2]) maxint[2] = lint3;
       *lip++ = lint3;
       lfp++;
       diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
       if (diff < mindiff && lfp > fp + 3)
 	mindiff = diff;
       oldlint1 = lint1;
       oldlint2 = lint2;
       oldlint3 = lint3;
     }
     xdr_int(xdrs, &(minint[0]));
     xdr_int(xdrs, &(minint[1]));
     xdr_int(xdrs, &(minint[2]));
     
     xdr_int(xdrs, &(maxint[0]));
     xdr_int(xdrs, &(maxint[1]));
     xdr_int(xdrs, &(maxint[2]));
     
     if ((float)maxint[0] - (float)minint[0] >= MAXABS ||
 	(float)maxint[1] - (float)minint[1] >= MAXABS ||
 	(float)maxint[2] - (float)minint[2] >= MAXABS) {
       /* turning value in unsigned by subtracting minint
        * would cause overflow
        */
       errval = 0;
     }
     sizeint[0] = maxint[0] - minint[0]+1;
     sizeint[1] = maxint[1] - minint[1]+1;
     sizeint[2] = maxint[2] - minint[2]+1;
     
     /* check if one of the sizes is to big to be multiplied */
     if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff) {
       bitsizeint[0] = sizeofint(sizeint[0]);
       bitsizeint[1] = sizeofint(sizeint[1]);
       bitsizeint[2] = sizeofint(sizeint[2]);
       bitsize = 0; /* flag the use of large sizes */
     } else {
       bitsize = sizeofints(3, sizeint);
     }
     lip = ip;
     luip = (unsigned int *) ip;
     smallidx = FIRSTIDX;
     while (smallidx < LASTIDX && magicints[smallidx] < mindiff) {
       smallidx++;
     }
     xdr_int(xdrs, &smallidx);
     maxidx = MYMIN(LASTIDX, smallidx + 8) ;
     minidx = maxidx - 8; /* often this equal smallidx */
     smaller = magicints[MYMAX(FIRSTIDX, smallidx-1)] / 2;
     small = magicints[smallidx] / 2;
     sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
     larger = magicints[maxidx] / 2;
     i = 0;
     while (i < *size) {
       is_small = 0;
       thiscoord = (int *)(luip) + i * 3;
       if (smallidx < maxidx && i >= 1 &&
 	  abs(thiscoord[0] - prevcoord[0]) < larger &&
 	  abs(thiscoord[1] - prevcoord[1]) < larger &&
 	  abs(thiscoord[2] - prevcoord[2]) < larger) {
 	is_smaller = 1;
       } else if (smallidx > minidx) {
 	is_smaller = -1;
       } else {
 	is_smaller = 0;
       }
       if (i + 1 < *size) {
 	if (abs(thiscoord[0] - thiscoord[3]) < small &&
 	    abs(thiscoord[1] - thiscoord[4]) < small &&
 	    abs(thiscoord[2] - thiscoord[5]) < small) {
 	  /* interchange first with second atom for better
 	   * compression of water molecules
 	   */
 	  tmp = thiscoord[0]; thiscoord[0] = thiscoord[3];
 	  thiscoord[3] = tmp;
 	  tmp = thiscoord[1]; thiscoord[1] = thiscoord[4];
 	  thiscoord[4] = tmp;
 	  tmp = thiscoord[2]; thiscoord[2] = thiscoord[5];
 	  thiscoord[5] = tmp;
 	  is_small = 1;
 	}
 	
       }
       tmpcoord[0] = thiscoord[0] - minint[0];
       tmpcoord[1] = thiscoord[1] - minint[1];
       tmpcoord[2] = thiscoord[2] - minint[2];
       if (bitsize == 0) {
 	sendbits(buf, bitsizeint[0], tmpcoord[0]);
 	sendbits(buf, bitsizeint[1], tmpcoord[1]);
 	sendbits(buf, bitsizeint[2], tmpcoord[2]);
       } else {
 	sendints(buf, 3, bitsize, sizeint, tmpcoord);
       }
       prevcoord[0] = thiscoord[0];
       prevcoord[1] = thiscoord[1];
       prevcoord[2] = thiscoord[2];
       thiscoord = thiscoord + 3;
       i++;
       
       run = 0;
       if (is_small == 0 && is_smaller == -1)
 	is_smaller = 0;
       while (is_small && run < 8*3) {
 	if (is_smaller == -1 && (SQR(thiscoord[0] - prevcoord[0]) +
 				 SQR(thiscoord[1] - prevcoord[1]) +
 				 SQR(thiscoord[2] - prevcoord[2]) >= 
 				 smaller * smaller)) {
 	  is_smaller = 0;
 	}
 	
 	tmpcoord[run++] = thiscoord[0] - prevcoord[0] + small;
 	tmpcoord[run++] = thiscoord[1] - prevcoord[1] + small;
 	tmpcoord[run++] = thiscoord[2] - prevcoord[2] + small;
 	
 	prevcoord[0] = thiscoord[0];
 	prevcoord[1] = thiscoord[1];
 	prevcoord[2] = thiscoord[2];
 	
 	i++;
 	thiscoord = thiscoord + 3;
 	is_small = 0;
 	if (i < *size &&
 	    abs(thiscoord[0] - prevcoord[0]) < small &&
 	    abs(thiscoord[1] - prevcoord[1]) < small &&
 	    abs(thiscoord[2] - prevcoord[2]) < small) {
 	  is_small = 1;
 	}
       }
       if (run != prevrun || is_smaller != 0) {
 	prevrun = run;
 	sendbits(buf, 1, 1); /* flag the change in run-length */
 	sendbits(buf, 5, run+is_smaller+1);
       } else {
 	sendbits(buf, 1, 0); /* flag the fact that runlength did not change */
       }
       for (k=0; k < run; k+=3) {
 	sendints(buf, 3, smallidx, sizesmall, &tmpcoord[k]);	
       }
       if (is_smaller != 0) {
 	smallidx += is_smaller;
 	if (is_smaller < 0) {
 	  small = smaller;
 	  smaller = magicints[smallidx-1] / 2;
 	} else {
 	  smaller = small;
 	  small = magicints[smallidx] / 2;
 	}
 	sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
       }
     }
     if (buf[1] != 0) buf[0]++;;
     xdr_int(xdrs, &(buf[0])); /* buf[0] holds the length in bytes */
     return errval * (xdr_opaque(xdrs, (caddr_t)&(buf[3]), (u_int)buf[0]));
   } else {
     
     /* xdrs is open for reading */
     
     if (xdr_int(xdrs, &lsize) == 0) 
       return 0;
     if (*size != 0 && lsize != *size) {
       fprintf(stderr, "wrong number of coordinates in xdr3dfcoor; "
 	      "%d arg vs %d in file", *size, lsize);
     }
     *size = lsize;
     size3 = *size * 3;
     if (*size <= 9) {
       return (xdr_vector(xdrs, (char *) fp, size3, sizeof(*fp),
 			 (xdrproc_t)xdr_float));
     }
     xdr_float(xdrs, precision);
     if (ip == NULL) {
       ip = (int *) malloc(size3 * sizeof(*ip));
       if (ip == NULL) {
 	fprintf(stderr,"malloc failed\n");
 	exit(1);
       }
       bufsize = (int) (size3 * 1.2);
       buf = (int *) malloc(bufsize * sizeof(*buf));
       if (buf == NULL) {
 	fprintf(stderr,"malloc failed\n");
 	exit(1);
       }
       oldsize = *size;
     } else if (*size > oldsize) {
       ip = (int *)realloc(ip, size3 * sizeof(*ip));
       if (ip == NULL) {
 	fprintf(stderr,"malloc failed\n");
 	exit(1);
       }
       bufsize = (int) (size3 * 1.2);
       buf = (int *)realloc(buf, bufsize * sizeof(*buf));
       if (buf == NULL) {
 	fprintf(stderr,"malloc failed\n");
 	exit(1);
       }
       oldsize = *size;
     }
     buf[0] = buf[1] = buf[2] = 0;
     
     xdr_int(xdrs, &(minint[0]));
     xdr_int(xdrs, &(minint[1]));
     xdr_int(xdrs, &(minint[2]));
     
     xdr_int(xdrs, &(maxint[0]));
     xdr_int(xdrs, &(maxint[1]));
     xdr_int(xdrs, &(maxint[2]));
     
     sizeint[0] = maxint[0] - minint[0]+1;
     sizeint[1] = maxint[1] - minint[1]+1;
     sizeint[2] = maxint[2] - minint[2]+1;
     
     /* check if one of the sizes is to big to be multiplied */
     if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff) {
       bitsizeint[0] = sizeofint(sizeint[0]);
       bitsizeint[1] = sizeofint(sizeint[1]);
       bitsizeint[2] = sizeofint(sizeint[2]);
       bitsize = 0; /* flag the use of large sizes */
     } else {
       bitsize = sizeofints(3, sizeint);
     }
     
     xdr_int(xdrs, &smallidx);
     maxidx = MYMIN(LASTIDX, smallidx + 8) ;
     minidx = maxidx - 8; /* often this equal smallidx */
     smaller = magicints[MYMAX(FIRSTIDX, smallidx-1)] / 2;
     small = magicints[smallidx] / 2;
     sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
     larger = magicints[maxidx];
     
     /* buf[0] holds the length in bytes */
     
     if (xdr_int(xdrs, &(buf[0])) == 0)
       return 0;
     if (xdr_opaque(xdrs, (caddr_t)&(buf[3]), (u_int)buf[0]) == 0)
       return 0;
     buf[0] = buf[1] = buf[2] = 0;
     
     lfp = fp;
     inv_precision = 1.0 / * precision;
     run = 0;
     i = 0;
     lip = ip;
     while ( i < lsize ) {
       thiscoord = (int *)(lip) + i * 3;
       
       if (bitsize == 0) {
 	thiscoord[0] = receivebits(buf, bitsizeint[0]);
 	thiscoord[1] = receivebits(buf, bitsizeint[1]);
 	thiscoord[2] = receivebits(buf, bitsizeint[2]);
       } else {
 	receiveints(buf, 3, bitsize, sizeint, thiscoord);
       }
       
       i++;
       thiscoord[0] += minint[0];
       thiscoord[1] += minint[1];
       thiscoord[2] += minint[2];
       
       prevcoord[0] = thiscoord[0];
       prevcoord[1] = thiscoord[1];
       prevcoord[2] = thiscoord[2];
       
       
       flag = receivebits(buf, 1);
       is_smaller = 0;
       if (flag == 1) {
 	run = receivebits(buf, 5);
 	is_smaller = run % 3;
 	run -= is_smaller;
 	is_smaller--;
       }
       if (run > 0) {
 	thiscoord += 3;
 	for (k = 0; k < run; k+=3) {
 	  receiveints(buf, 3, smallidx, sizesmall, thiscoord);
 	  i++;
 	  thiscoord[0] += prevcoord[0] - small;
 	  thiscoord[1] += prevcoord[1] - small;
 	  thiscoord[2] += prevcoord[2] - small;
 	  if (k == 0) {
 	    /* interchange first with second atom for better
 	     * compression of water molecules
 	     */
 	    tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
 	    prevcoord[0] = tmp;
 	    tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
 	    prevcoord[1] = tmp;
 	    tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
 	    prevcoord[2] = tmp;
 	    *lfp++ = prevcoord[0] * inv_precision;
 	    *lfp++ = prevcoord[1] * inv_precision;
 	    *lfp++ = prevcoord[2] * inv_precision;
 	  } else {
 	    prevcoord[0] = thiscoord[0];
 	    prevcoord[1] = thiscoord[1];
 	    prevcoord[2] = thiscoord[2];
 	  }
 	  *lfp++ = thiscoord[0] * inv_precision;
 	  *lfp++ = thiscoord[1] * inv_precision;
 	  *lfp++ = thiscoord[2] * inv_precision;
 	}
       } else {
 	*lfp++ = thiscoord[0] * inv_precision;
 	*lfp++ = thiscoord[1] * inv_precision;
 	*lfp++ = thiscoord[2] * inv_precision;		
       }
       smallidx += is_smaller;
       if (is_smaller < 0) {
 	small = smaller;
 	if (smallidx > FIRSTIDX) {
 	  smaller = magicints[smallidx - 1] /2;
 	} else {
 	  smaller = 0;
 	}
       } else if (is_smaller > 0) {
 	smaller = small;
 	small = magicints[smallidx] / 2;
       }
       sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
     }
   }
   return 1;
 }
diff --git a/src/XTC/dump_xtc.h b/src/XTC/dump_xtc.h
index ebc928cc1..e1e2ca025 100644
--- a/src/XTC/dump_xtc.h
+++ b/src/XTC/dump_xtc.h
@@ -1,63 +1,63 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef DUMP_CLASS
 
 DumpStyle(xtc,DumpXTC)
 
 #else
 
 #ifndef LMP_DUMP_XTC_H
 #define LMP_DUMP_XTC_H
 
 #include "dump.h"
 
 #ifdef LAMMPS_XDR
 #include "xdr_compat.h"
 #else
 #include "rpc/rpc.h"
 #include "rpc/xdr.h"
 #endif
 
 namespace LAMMPS_NS {
 
 class DumpXTC : public Dump {
  public:
   DumpXTC(class LAMMPS *, int, char**);
   ~DumpXTC();
 	
  private:
   int natoms,ntotal;
   int nevery_save;
   int unwrap_flag;            // 1 if atom coords are unwrapped, 0 if no
   float precision;            // user-adjustable precision setting
   float *coords;
   double sfactor;
   XDR xd;
 
   void init_style();
   int modify_param(int, char **);
   void openfile();
-  void write_header(int);
+  void write_header(bigint);
   int count();
   void pack(int *);
   void write_data(int, double *);
   double memory_usage();
 
   void write_frame();
 };
 
 }
 
 #endif
 #endif
diff --git a/src/atom.h b/src/atom.h
index 0cb05c7eb..563bc9b1c 100644
--- a/src/atom.h
+++ b/src/atom.h
@@ -1,223 +1,223 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_ATOM_H
 #define LMP_ATOM_H
 
 #include "pointers.h"
 #include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class Atom : protected Pointers {
  public:
   char *atom_style;
   class AtomVec *avec;
 
   // atom counts
 
   bigint natoms;                // total # of atoms in system, could be 0
   int nlocal,nghost;            // # of owned and ghost atoms on this proc
   int nmax;                     // max # of owned+ghost in arrays on this proc
   int tag_enable;               // 0/1 if atom ID tags are defined
   int molecular;                // 0 = atomic, 1 = molecular system
 
   bigint nbonds,nangles,ndihedrals,nimpropers;
   int ntypes,nbondtypes,nangletypes,ndihedraltypes,nimpropertypes;
   int bond_per_atom,angle_per_atom,dihedral_per_atom,improper_per_atom;
   int extra_bond_per_atom;
 
   int firstgroup;               // store atoms in this group first, -1 if unset
   int nfirst;                   // # of atoms in first group on this proc
   char *firstgroupname;         // group-ID to store first, NULL if unset
 
   // per-atom arrays
   // customize by adding new array
 
   int *tag,*type,*mask,*image;
   double **x,**v,**f;
 
   int *molecule;
   double *q,**mu;
   double **quat,**omega,**angmom,**torque;
   double *radius,*density,*rmass,*vfrac,*s0;
   double **x0;
 
   int *spin;
   double *eradius,*ervel,*erforce;
 
   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
   int maxspecial;               // special[nlocal][maxspecial]
 
   int *num_bond;
   int **bond_type;
   int **bond_atom;
 
   int *num_angle;
   int **angle_type;
   int **angle_atom1,**angle_atom2,**angle_atom3;
 
   int *num_dihedral;
   int **dihedral_type;
   int **dihedral_atom1,**dihedral_atom2,**dihedral_atom3,**dihedral_atom4;
 
   int *num_improper;
   int **improper_type;
   int **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4;
 
   // per-atom array existence flags
   // these can be checked before array is allocated
   // customize by adding new flag
 
   int molecule_flag;
   int q_flag,mu_flag;
   int quat_flag,omega_flag,angmom_flag,torque_flag;
   int radius_flag,density_flag,rmass_flag,vfrac_flag;
   int spin_flag,eradius_flag,ervel_flag,erforce_flag;
 
   // extra peratom info in restart file destined for fix & diag 
 
   double **extra;
 
   // per-type arrays
 
   double *mass,**shape,*dipole;
   int *mass_setflag,*shape_setflag,*dipole_setflag;
 
   // callback ptrs for atom arrays managed by fix classes
 
   int nextra_grow,nextra_restart;             // # of callbacks of each type
   int *extra_grow,*extra_restart;             // index of fix to callback to
   int nextra_grow_max,nextra_restart_max;     // size of callback lists
   int nextra_store;
 
   int map_style;                  // default or user-specified style of map
                                   // 0 = none, 1 = array, 2 = hash
 
   // spatial sorting of atoms
 
   int sortfreq;             // sort atoms every this many steps, 0 = off
-  int nextsort;             // next timestep to sort on
+  bigint nextsort;          // next timestep to sort on
 
   // functions
 
   Atom(class LAMMPS *);
   ~Atom();
 
   void settings(class Atom *);
   void create_avec(const char *, int, char **);
   class AtomVec *new_avec(const char *, int, char **);
   void init();
   void setup();
 
   int style_match(const char *);
   void modify_params(int, char **);
   void tag_extend();
   int tag_consecutive();
 
   int parse_data(const char *);
   int count_words(const char *);
 
   void data_atoms(int, char *);
   void data_vels(int, char *);
   void data_bonds(int, char *);
   void data_angles(int, char *);
   void data_dihedrals(int, char *);
   void data_impropers(int, char *);
 
   void allocate_type_arrays();
   void set_mass(const char *);
   void set_mass(int, double);
   void set_mass(int, char **);
   void set_mass(double *);
   void check_mass();
   void set_shape(const char *);
   void set_shape(int, char **);
   void set_shape(double **);
   void check_shape();
   void set_dipole(const char *);
   void set_dipole(int, char **);
   void set_dipole(double *);
   void check_dipole();
 
   void first_reorder();
   void sort();
 
   void add_callback(int);
   void delete_callback(const char *, int);
   void update_callback(int);
 
   void *extract(char *);
 
   double memory_usage();
   int memcheck(const char *);
 
   // functions for global to local ID mapping
   // map lookup function inlined for efficiency
   
   inline int map(int global) {
     if (map_style == 1) return map_array[global];
     else return map_find_hash(global);
   };
 
   void map_init();
   void map_clear();
   void map_set();
   void map_one(int, int);
   void map_delete();
   int map_find_hash(int);
 
  private:
 
   // global to local ID mapping
 
   int map_tag_max;
   int *map_array;
 
   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
   };
   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 *primes;                    // table of prime #s for hashing
   int nprimes;                    // # of primes
 
   // spatial sorting of atoms
 
   int nbins;                      // # of sorting bins
   int nbinx,nbiny,nbinz;          // bins in each dimension
   int maxbin;                     // max # of bins
   int maxnext;                    // max size of next,permute
   int *binhead;                   // 1st atom in each bin
   int *next;                      // next atom in bin
   int *permute;                   // permutation vector
   double userbinsize;             // requested sort bin size
   double bininvx,bininvy,bininvz; // inverse actual bin sizes
   double bboxlo[3],bboxhi[3];     // bounding box of my sub-domain
 
   int memlength;                  // allocated size of memstr
   char *memstr;                   // string of array names already counted
 
   void setup_sort_bins();
 };
 
 }
 
 #endif
diff --git a/src/atom_vec_atomic.cpp b/src/atom_vec_atomic.cpp
index 665f66f04..13dd6b4a9 100644
--- a/src/atom_vec_atomic.cpp
+++ b/src/atom_vec_atomic.cpp
@@ -1,591 +1,594 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "atom_vec_atomic.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecAtomic::AtomVecAtomic(LAMMPS *lmp, int narg, char **arg) :
   AtomVec(lmp, narg, arg)
 {
   molecular = 0;
   mass_type = 1;
 
   comm_x_only = comm_f_only = 1;
   size_forward = 3;
   size_reverse = 3;
   size_border = 6;
   size_velocity = 3;
   size_data_atom = 5;
   size_data_vel = 4;
   xcol_data = 3;
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n 
 ------------------------------------------------------------------------- */
 
 void AtomVecAtomic::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
 
   tag = atom->tag = (int *) 
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *) 
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *) 
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecAtomic::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAtomic::copy(int i, int j)
 {
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_comm(int n, int *list, double *buf,
 			     int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_comm_vel(int n, int *list, double *buf,
 				 int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAtomic::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAtomic::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAtomic::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_border(int n, int *list, double *buf,
 			       int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_border_vel(int n, int *list, double *buf,
 				   int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAtomic::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecAtomic::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    xyz must be 1st 3 values, so comm::exchange() can test on them 
 ------------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_exchange(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAtomic::unpack_exchange(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecAtomic::size_restart()
 {
   int i;
 
   int nlocal = atom->nlocal;
   int n = 11 * nlocal;
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       for (i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive   
 ------------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_restart(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
 
 int AtomVecAtomic::unpack_restart(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store)
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
 
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
 
 void AtomVecAtomic::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
 void AtomVecAtomic::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
 
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   image[nlocal] = imagetmp;
 
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
 
 double AtomVecAtomic::memory_usage()
 {
   double bytes = 0.0;
 
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
 
   return bytes;
 }
diff --git a/src/atom_vec_charge.cpp b/src/atom_vec_charge.cpp
index 76b69b4bd..69a918562 100644
--- a/src/atom_vec_charge.cpp
+++ b/src/atom_vec_charge.cpp
@@ -1,647 +1,650 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "atom_vec_charge.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecCharge::AtomVecCharge(LAMMPS *lmp, int narg, char **arg) : 
   AtomVec(lmp, narg, arg)
 {
   molecular = 0;
   mass_type = 1;
 
   comm_x_only = comm_f_only = 1;
   size_forward = 3;
   size_reverse = 3;
   size_border = 7;
   size_velocity = 3;
   size_data_atom = 6;
   size_data_vel = 4;
   xcol_data = 4;
 
   atom->q_flag = 1;
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n 
 ------------------------------------------------------------------------- */
 
 void AtomVecCharge::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
 
   tag = atom->tag = (int *) 
     memory->srealloc(atom->tag,nmax*sizeof(int),"atom:tag");
   type = atom->type = (int *)
     memory->srealloc(atom->type,nmax*sizeof(int),"atom:type");
   mask = atom->mask = (int *) 
     memory->srealloc(atom->mask,nmax*sizeof(int),"atom:mask");
   image = atom->image = (int *) 
     memory->srealloc(atom->image,nmax*sizeof(int),"atom:image");
   x = atom->x = memory->grow_2d_double_array(atom->x,nmax,3,"atom:x");
   v = atom->v = memory->grow_2d_double_array(atom->v,nmax,3,"atom:v");
   f = atom->f = memory->grow_2d_double_array(atom->f,nmax,3,"atom:f");
 
   q = atom->q = (double *) 
     memory->srealloc(atom->q,nmax*sizeof(double),"atom:q");
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecCharge::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
   q = atom->q;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecCharge::copy(int i, int j)
 {
   tag[j] = tag[i];
   type[j] = type[i];
   mask[j] = mask[i];
   image[j] = image[i];
   x[j][0] = x[i][0];
   x[j][1] = x[i][1];
   x[j][2] = x[i][2];
   v[j][0] = v[i][0];
   v[j][1] = v[i][1];
   v[j][2] = v[i][2];
 
   q[j] = q[i];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecCharge::pack_comm(int n, int *list, double *buf,
 			     int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecCharge::pack_comm_vel(int n, int *list, double *buf,
 				 int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecCharge::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecCharge::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecCharge::pack_reverse(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecCharge::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecCharge::pack_border(int n, int *list, double *buf,
 			       int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecCharge::pack_border_vel(int n, int *list, double *buf,
 				   int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = q[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecCharge::pack_border_one(int i, double *buf)
 {
   buf[0] = q[i];
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecCharge::unpack_border(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     q[i] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecCharge::unpack_border_vel(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     q[i] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecCharge::unpack_border_one(int i, double *buf)
 {
   q[i] = buf[0];
   return 1;
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    xyz must be 1st 3 values, so comm::exchange() can test on them 
 ------------------------------------------------------------------------- */
 
 int AtomVecCharge::pack_exchange(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
 
   buf[m++] = q[i];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecCharge::unpack_exchange(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
 
   q[nlocal] = buf[m++];
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecCharge::size_restart()
 {
   int i;
 
   int nlocal = atom->nlocal;
   int n = 12 * nlocal;
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       for (i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    molecular types may be negative, but write as positive   
 ------------------------------------------------------------------------- */
 
 int AtomVecCharge::pack_restart(int i, double *buf)
 {
   int m = 1;
   buf[m++] = x[i][0];
   buf[m++] = x[i][1];
   buf[m++] = x[i][2];
   buf[m++] = tag[i];
   buf[m++] = type[i];
   buf[m++] = mask[i];
   buf[m++] = image[i];
   buf[m++] = v[i][0];
   buf[m++] = v[i][1];
   buf[m++] = v[i][2];
 
   buf[m++] = q[i];
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
 ------------------------------------------------------------------------- */
 
 int AtomVecCharge::unpack_restart(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store)
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
 
   int m = 1;
   x[nlocal][0] = buf[m++];
   x[nlocal][1] = buf[m++];
   x[nlocal][2] = buf[m++];
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
   image[nlocal] = static_cast<int> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
 
   q[nlocal] = buf[m++];
 
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    set other values to defaults
 ------------------------------------------------------------------------- */
 
 void AtomVecCharge::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = 0;
   type[nlocal] = itype;
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
   image[nlocal] = (512 << 20) | (512 << 10) | 512;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   q[nlocal] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
 void AtomVecCharge::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
 
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   q[nlocal] = atof(values[2]);
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   image[nlocal] = imagetmp;
 
   mask[nlocal] = 1;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack hybrid quantities from one line in Atoms section of data file
    initialize other atom quantities for this sub-style
 ------------------------------------------------------------------------- */
 
 int AtomVecCharge::data_atom_hybrid(int nlocal, char **values)
 {
   q[nlocal] = atof(values[0]);
 
   return 1;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
 
 double AtomVecCharge::memory_usage()
 {
   double bytes = 0.0;
 
   if (atom->memcheck("tag")) bytes += nmax * sizeof(int);
   if (atom->memcheck("type")) bytes += nmax * sizeof(int);
   if (atom->memcheck("mask")) bytes += nmax * sizeof(int);
   if (atom->memcheck("image")) bytes += nmax * sizeof(int);
   if (atom->memcheck("x")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("v")) bytes += nmax*3 * sizeof(double);
   if (atom->memcheck("f")) bytes += nmax*3 * sizeof(double);
 
   if (atom->memcheck("q")) bytes += nmax * sizeof(double);
 
   return bytes;
 }
diff --git a/src/atom_vec_hybrid.cpp b/src/atom_vec_hybrid.cpp
index 02bc5df28..8be54a102 100644
--- a/src/atom_vec_hybrid.cpp
+++ b/src/atom_vec_hybrid.cpp
@@ -1,770 +1,773 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "string.h"
 #include "atom_vec_hybrid.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define DELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecHybrid::AtomVecHybrid(LAMMPS *lmp, int narg, char **arg) :
   AtomVec(lmp, narg, arg)
 {
   int i,k;
 
   if (narg < 1) error->all("Illegal atom_style command");
 
   // create sub-styles
 
   nstyles = narg;
   styles = new AtomVec*[nstyles];
   keywords = new char*[nstyles];
 
   for (i = 0; i < narg; i++) {
     for (k = 0; k < i; k++)
       if (strcmp(arg[i],keywords[k]) == 0) 
 	error->all("Atom style hybrid cannot use same atom style twice");
     if (strcmp(arg[i],"hybrid") == 0) 
       error->all("Atom style hybrid cannot have hybrid as an argument");
     styles[i] = atom->new_avec(arg[i],0,NULL);
     keywords[i] = new char[strlen(arg[i])+1];
     strcpy(keywords[i],arg[i]);
   }
 
   // hybrid settings are MAX or MIN of sub-style settings
   // hybrid sizes are minimial values plus extra values for each sub-style
 
   molecular = 0;
   comm_x_only = comm_f_only = 1;
 
   size_forward = 3;
   size_reverse = 3;
   size_border = 6;
   size_data_atom = 5;
   size_data_vel = 4;
   xcol_data = 3;
 
   for (k = 0; k < nstyles; k++) {
     molecular = MAX(molecular,styles[k]->molecular);
     bonds_allow = MAX(bonds_allow,styles[k]->bonds_allow);
     angles_allow = MAX(angles_allow,styles[k]->angles_allow);
     dihedrals_allow = MAX(dihedrals_allow,styles[k]->dihedrals_allow);
     impropers_allow = MAX(impropers_allow,styles[k]->impropers_allow);
     mass_type = MAX(mass_type,styles[k]->mass_type);
     shape_type = MAX(shape_type,styles[k]->shape_type);
     dipole_type = MAX(dipole_type,styles[k]->dipole_type);
 
     comm_x_only = MIN(comm_x_only,styles[k]->comm_x_only);
     comm_f_only = MIN(comm_f_only,styles[k]->comm_f_only);
     size_forward += styles[k]->size_forward - 3;
     size_reverse += styles[k]->size_reverse - 3;
     size_border += styles[k]->size_border - 6;
     size_data_atom += styles[k]->size_data_atom - 5;
     size_data_vel += styles[k]->size_data_vel - 4;
   }
 
   size_velocity = 3;
   if (atom->omega_flag) size_velocity += 3;
   if (atom->angmom_flag) size_velocity += 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 AtomVecHybrid::~AtomVecHybrid()
 {
   for (int k = 0; k < nstyles; k++) delete styles[k];
   delete [] styles;
   for (int k = 0; k < nstyles; k++) delete [] keywords[k];
   delete [] keywords;
 }
 
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
    n > 0 allocates arrays to size n 
 ------------------------------------------------------------------------- */
 
 void AtomVecHybrid::grow(int n)
 {
   if (n == 0) nmax += DELTA;
   else nmax = n;
   atom->nmax = nmax;
+  if (nmax < 0 || nmax > MAXSMALLINT)
+    error->one("Per-processor system is too big");
 
   // sub-styles perform all reallocation
   // turn off nextra_grow so hybrid can do that once below
 
   int tmp = atom->nextra_grow;
   atom->nextra_grow = 0;
   for (int k = 0; k < nstyles; k++) styles[k]->grow(nmax);
   atom->nextra_grow = tmp;
 
   // insure hybrid local ptrs and sub-style ptrs are up to date
   // for sub-styles, do this in case
   //   multiple sub-style reallocs of same array occurred
 
   grow_reset();
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
 /* ----------------------------------------------------------------------
    reset local array ptrs
 ------------------------------------------------------------------------- */
 
 void AtomVecHybrid::grow_reset()
 {
   tag = atom->tag; type = atom->type;
   mask = atom->mask; image = atom->image;
   x = atom->x; v = atom->v; f = atom->f;
   omega = atom->omega; angmom = atom->angmom;
 
   for (int k = 0; k < nstyles; k++) styles[k]->grow_reset();
 }
 
 /* ----------------------------------------------------------------------
    copy array values for all sub-styles
 ------------------------------------------------------------------------- */
 
 void AtomVecHybrid::copy(int i, int j)
 {
   int tmp = atom->nextra_grow;
   atom->nextra_grow = 0;
   for (int k = 0; k < nstyles; k++) styles[k]->copy(i,j);
   atom->nextra_grow = tmp;
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecHybrid::pack_comm(int n, int *list, double *buf,
 			     int pbc_flag, int *pbc)
 {
   int i,j,k,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       for (k = 0; k < nstyles; k++)
 	m += styles[k]->pack_comm_one(j,&buf[m]);
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       for (k = 0; k < nstyles; k++)
 	m += styles[k]->pack_comm_one(j,&buf[m]);
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecHybrid::pack_comm_vel(int n, int *list, double *buf,
 				 int pbc_flag, int *pbc)
 {
   int i,j,k,m;
   double dx,dy,dz;
   int omega_flag = atom->omega_flag;
   int angmom_flag = atom->angmom_flag;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       if (omega_flag) {
 	buf[m++] = omega[j][0];
 	buf[m++] = omega[j][1];
 	buf[m++] = omega[j][2];
       }
       if (angmom_flag) {
 	buf[m++] = angmom[j][0];
 	buf[m++] = angmom[j][1];
 	buf[m++] = angmom[j][2];
       }
       for (k = 0; k < nstyles; k++)
 	m += styles[k]->pack_comm_one(j,&buf[m]);
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       if (omega_flag) {
 	buf[m++] = omega[j][0];
 	buf[m++] = omega[j][1];
 	buf[m++] = omega[j][2];
       }
       if (angmom_flag) {
 	buf[m++] = angmom[j][0];
 	buf[m++] = angmom[j][1];
 	buf[m++] = angmom[j][2];
       }
       for (k = 0; k < nstyles; k++)
 	m += styles[k]->pack_comm_one(j,&buf[m]);
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecHybrid::unpack_comm(int n, int first, double *buf)
 {
   int i,k,last;
 
   int m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     for (k = 0; k < nstyles; k++)
       m += styles[k]->unpack_comm_one(i,&buf[m]);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecHybrid::unpack_comm_vel(int n, int first, double *buf)
 {
   int i,k,last;
   int omega_flag = atom->omega_flag;
   int angmom_flag = atom->angmom_flag;
 
   int m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
     if (omega_flag) {
       omega[i][0] = buf[m++];
       omega[i][1] = buf[m++];
       omega[i][2] = buf[m++];
     }
     if (angmom_flag) {
       angmom[i][0] = buf[m++];
       angmom[i][1] = buf[m++];
       angmom[i][2] = buf[m++];
     }
     for (k = 0; k < nstyles; k++)
       m += styles[k]->unpack_comm_one(i,&buf[m]);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecHybrid::pack_reverse(int n, int first, double *buf)
 {
   int i,k,last;
 
   int m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     buf[m++] = f[i][0];
     buf[m++] = f[i][1];
     buf[m++] = f[i][2];
     for (k = 0; k < nstyles; k++)
       m += styles[k]->pack_reverse_one(i,&buf[m]);
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecHybrid::unpack_reverse(int n, int *list, double *buf)
 {
   int i,j,k,m;
 
   m = 0;
   for (i = 0; i < n; i++) {
     j = list[i];
     f[j][0] += buf[m++];
     f[j][1] += buf[m++];
     f[j][2] += buf[m++];
     for (k = 0; k < nstyles; k++)
       m += styles[k]->unpack_reverse_one(j,&buf[m]);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecHybrid::pack_border(int n, int *list, double *buf,
 			       int pbc_flag, int *pbc)
 {
   int i,j,k,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       for (k = 0; k < nstyles; k++)
 	m += styles[k]->pack_border_one(j,&buf[m]);
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       for (k = 0; k < nstyles; k++)
 	m += styles[k]->pack_border_one(j,&buf[m]);
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecHybrid::pack_border_vel(int n, int *list, double *buf,
 				   int pbc_flag, int *pbc)
 {
   int i,j,k,m;
   double dx,dy,dz;
   int omega_flag = atom->omega_flag;
   int angmom_flag = atom->angmom_flag;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0];
       buf[m++] = x[j][1];
       buf[m++] = x[j][2];
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       if (omega_flag) {
 	buf[m++] = omega[j][0];
 	buf[m++] = omega[j][1];
 	buf[m++] = omega[j][2];
       }
       if (angmom_flag) {
 	buf[m++] = angmom[j][0];
 	buf[m++] = angmom[j][1];
 	buf[m++] = angmom[j][2];
       }
       for (k = 0; k < nstyles; k++)
 	m += styles[k]->pack_border_one(j,&buf[m]);
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0];
       dy = pbc[1];
       dz = pbc[2];
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = x[j][0] + dx;
       buf[m++] = x[j][1] + dy;
       buf[m++] = x[j][2] + dz;
       buf[m++] = tag[j];
       buf[m++] = type[j];
       buf[m++] = mask[j];
       buf[m++] = v[j][0];
       buf[m++] = v[j][1];
       buf[m++] = v[j][2];
       if (omega_flag) {
 	buf[m++] = omega[j][0];
 	buf[m++] = omega[j][1];
 	buf[m++] = omega[j][2];
       }
       if (angmom_flag) {
 	buf[m++] = angmom[j][0];
 	buf[m++] = angmom[j][1];
 	buf[m++] = angmom[j][2];
       }
       for (k = 0; k < nstyles; k++)
 	m += styles[k]->pack_border_one(j,&buf[m]);
     }
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecHybrid::unpack_border(int n, int first, double *buf)
 {
   int i,k,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     for (k = 0; k < nstyles; k++)
       m += styles[k]->unpack_border_one(i,&buf[m]);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void AtomVecHybrid::unpack_border_vel(int n, int first, double *buf)
 {
   int i,k,m,last;
   int omega_flag = atom->omega_flag;
   int angmom_flag = atom->angmom_flag;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     if (i == nmax) grow(0);
     x[i][0] = buf[m++];
     x[i][1] = buf[m++];
     x[i][2] = buf[m++];
     tag[i] = static_cast<int> (buf[m++]);
     type[i] = static_cast<int> (buf[m++]);
     mask[i] = static_cast<int> (buf[m++]);
     v[i][0] = buf[m++];
     v[i][1] = buf[m++];
     v[i][2] = buf[m++];
     if (omega_flag) {
       omega[i][0] = buf[m++];
       omega[i][1] = buf[m++];
       omega[i][2] = buf[m++];
     }
     if (angmom_flag) {
       angmom[i][0] = buf[m++];
       angmom[i][1] = buf[m++];
       angmom[i][2] = buf[m++];
     }
     for (k = 0; k < nstyles; k++)
       m += styles[k]->unpack_border_one(i,&buf[m]);
   }
 }
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
    pack each sub-style one after the other
 ------------------------------------------------------------------------- */
 
 int AtomVecHybrid::pack_exchange(int i, double *buf)
 {
   int k;
 
   int tmp = atom->nextra_grow;
   atom->nextra_grow = 0;
 
   int m = 0;
   for (k = 0; k < nstyles; k++) 
     m += styles[k]->pack_exchange(i,&buf[m]);
 
   atom->nextra_grow = tmp;
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for single atom received from another proc
    unpack each sub-style one after the other
    grow() occurs here so arrays for all sub-styles are grown
 ------------------------------------------------------------------------- */
 
 int AtomVecHybrid::unpack_exchange(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   int tmp = atom->nextra_grow;
   atom->nextra_grow = 0;
 
   int m = 0;
   for (int k = 0; k < nstyles; k++) {
     m += styles[k]->unpack_exchange(&buf[m]);
     atom->nlocal--;
   }
 
   atom->nextra_grow = tmp;
 
   if (atom->nextra_grow)
     for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
 	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    size of restart data for all atoms owned by this proc
    include extra data stored by fixes
 ------------------------------------------------------------------------- */
 
 int AtomVecHybrid::size_restart()
 {
   int tmp = atom->nextra_restart;
   atom->nextra_restart = 0;
 
   int n = 0;
   for (int k = 0; k < nstyles; k++)
     n += styles[k]->size_restart();
 
   atom->nextra_restart = tmp;
 
   int nlocal = atom->nlocal;
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       for (int i = 0; i < nlocal; i++)
 	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
 
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
    pack each sub-style one after the other
 ------------------------------------------------------------------------- */
 
 int AtomVecHybrid::pack_restart(int i, double *buf)
 {
   int tmp = atom->nextra_restart;
   atom->nextra_restart = 0;
 
   int m = 0;
   for (int k = 0; k < nstyles; k++)
     m += styles[k]->pack_restart(i,&buf[m]);
 
   atom->nextra_restart = tmp;
 
   if (atom->nextra_restart)
     for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack data for one atom from restart file including extra quantities
    unpack each sub-style one after the other
    grow() occurs here so arrays for all sub-styles are grown
 ------------------------------------------------------------------------- */
 
 int AtomVecHybrid::unpack_restart(double *buf)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) {
     grow(0);
     if (atom->nextra_store)
       atom->extra = memory->grow_2d_double_array(atom->extra,nmax,
 						 atom->nextra_store,
 						 "atom:extra");
   }
 
   int tmp = atom->nextra_store;
   atom->nextra_store = 0;
 
   int m = 0;
   for (int k = 0; k < nstyles; k++) {
     m += styles[k]->unpack_restart(&buf[m]);
     atom->nlocal--;
   }
   atom->nextra_store = tmp;
 
   double **extra = atom->extra;
   if (atom->nextra_store) {
     int size = static_cast<int> (buf[0]) - m;
     for (int i = 0; i < size; i++) extra[nlocal][i] = buf[m++];
   }
 
   atom->nlocal++;
   return m;
 }
 
 /* ----------------------------------------------------------------------
    create one atom of itype at coord
    create each sub-style one after the other
    grow() occurs here so arrays for all sub-styles are grown
 ------------------------------------------------------------------------- */
 
 void AtomVecHybrid::create_atom(int itype, double *coord)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   for (int k = 0; k < nstyles; k++) {
     styles[k]->create_atom(itype,coord);
     atom->nlocal--;
   }
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Atoms section of data file
    grow() occurs here so arrays for all sub-styles are grown
 ------------------------------------------------------------------------- */
 
 void AtomVecHybrid::data_atom(double *coord, int imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
 
   tag[nlocal] = atoi(values[0]);
   if (tag[nlocal] <= 0)
     error->one("Invalid atom ID in Atoms section of data file");
 
   type[nlocal] = atoi(values[1]);
   if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
     error->one("Invalid atom type in Atoms section of data file");
 
   x[nlocal][0] = coord[0];
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
 
   image[nlocal] = imagetmp;
   mask[nlocal] = 1;
 
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
   if (atom->omega_flag) {
     omega[nlocal][0] = 0.0;
     omega[nlocal][1] = 0.0;
     omega[nlocal][2] = 0.0;
   }
   if (atom->angmom_flag) {
     angmom[nlocal][0] = 0.0;
     angmom[nlocal][1] = 0.0;
     angmom[nlocal][2] = 0.0;
   }
 
   // each sub-style parses sub-style specific values
 
   int m = 5;
   for (int k = 0; k < nstyles; k++) 
     m += styles[k]->data_atom_hybrid(nlocal,&values[m]);
 
   atom->nlocal++;
 }
 
 /* ----------------------------------------------------------------------
    unpack one line from Velocities section of data file
 ------------------------------------------------------------------------- */
 
 void AtomVecHybrid::data_vel(int m, char **values)
 {
   v[m][0] = atof(values[0]);
   v[m][1] = atof(values[1]);
   v[m][2] = atof(values[2]);
 
   // each sub-style parses sub-style specific values
 
   int n = 3;
   for (int k = 0; k < nstyles; k++) 
     n += styles[k]->data_vel_hybrid(m,&values[n]);
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory
 ------------------------------------------------------------------------- */
 
 double AtomVecHybrid::memory_usage()
 {
   double bytes = 0.0;
   for (int k = 0; k < nstyles; k++) bytes += styles[k]->memory_usage();
   return bytes;
 }
diff --git a/src/compute.cpp b/src/compute.cpp
index 81cedcd17..27e7ff564 100644
--- a/src/compute.cpp
+++ b/src/compute.cpp
@@ -1,295 +1,296 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "string.h"
 #include "ctype.h"
 #include "compute.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "comm.h"
 #include "group.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define DELTA 4
 #define BIG 2000000000
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 /* ---------------------------------------------------------------------- */
 
 Compute::Compute(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
 {
   if (narg < 3) error->all("Illegal compute command");
 
   // compute ID, group, and style
   // ID must be all alphanumeric chars or underscores
 
   int n = strlen(arg[0]) + 1;
   id = new char[n];
   strcpy(id,arg[0]);
 
   for (int i = 0; i < n-1; i++)
     if (!isalnum(id[i]) && id[i] != '_')
       error->all("Compute ID must be alphanumeric or underscore characters");
 
   igroup = group->find(arg[1]);
   if (igroup == -1) error->all("Could not find compute group ID");
   groupbit = group->bitmask[igroup];
 
   n = strlen(arg[2]) + 1;
   style = new char[n];
   strcpy(style,arg[2]);
 
   // set child class defaults
 
   scalar_flag = vector_flag = array_flag = 0;
   peratom_flag = local_flag = 0;
 
   tempflag = pressflag = peflag = 0;
   pressatomflag = peatomflag = 0;
   tempbias = 0;
 
   timeflag = 0;
   comm_forward = comm_reverse = 0;
 
   invoked_scalar = invoked_vector = invoked_array = -1;
   invoked_peratom = invoked_local = -1;
 
   // set modify defaults
 
   extra_dof = domain->dimension;
   dynamic = 0;
 
   // setup list of timesteps
   
   ntime = maxtime = 0;
   tlist = NULL;
 
   // setup map for molecule IDs
 
   molmap = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
 
 Compute::~Compute()
 {
   delete [] id;
   delete [] style;
 
   memory->sfree(tlist);
   memory->sfree(molmap);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Compute::modify_params(int narg, char **arg)
 {
   if (narg == 0) error->all("Illegal compute_modify command");
 
   int iarg = 0;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"extra") == 0) {
       if (iarg+2 > narg) error->all("Illegal compute_modify command");
       extra_dof = atoi(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"dynamic") == 0) {
       if (iarg+2 > narg) error->all("Illegal compute_modify command");
       if (strcmp(arg[iarg+1],"no") == 0) dynamic = 0;
       else if (strcmp(arg[iarg+1],"yes") == 0) dynamic = 1;
       else error->all("Illegal compute_modify command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"thermo") == 0) {
       if (iarg+2 > narg) error->all("Illegal compute_modify command");
       if (strcmp(arg[iarg+1],"no") == 0) thermoflag = 0;
       else if (strcmp(arg[iarg+1],"yes") == 0) thermoflag = 1;
       else error->all("Illegal compute_modify command");
       iarg += 2;
     } else error->all("Illegal compute_modify command");
   }
 }
 
 /* ----------------------------------------------------------------------
    reset extra_dof to its default value
 ------------------------------------------------------------------------- */
 
 void Compute::reset_extra_dof()
 {
   extra_dof = domain->dimension;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Compute::reset_extra_compute_fix(char *)
 {
   error->all("Compute does not allow an extra compute or fix to be reset");
 }
 
 /* ----------------------------------------------------------------------
    add ntimestep to list of timesteps the compute will be called on
    do not add if already in list
    search from top downward, since list of times is in decreasing order
 ------------------------------------------------------------------------- */
 
-void Compute::addstep(int ntimestep)
+void Compute::addstep(bigint ntimestep)
 {
   // i = location in list to insert ntimestep
 
   int i;
   for (i = ntime-1; i >= 0; i--) {
     if (ntimestep == tlist[i]) return;
     if (ntimestep < tlist[i]) break;
   }
   i++;
 
   // extend list as needed
 
   if (ntime == maxtime) {
     maxtime += DELTA;
-    tlist = (int *)
-      memory->srealloc(tlist,maxtime*sizeof(int),"compute:tlist");
+    tlist = (bigint *)
+      memory->srealloc(tlist,maxtime*sizeof(bigint),"compute:tlist");
   }
 
   // move remainder of list upward and insert ntimestep
 
   for (int j = ntime-1; j >= i; j--) tlist[j+1] = tlist[j];
   tlist[i] = ntimestep;
   ntime++;
 }
 
 /* ----------------------------------------------------------------------
    return 1/0 if ntimestep is or is not in list of calling timesteps
    if value(s) on top of list are less than ntimestep, delete them
    search from top downward, since list of times is in decreasing order
 ------------------------------------------------------------------------- */
 
-int Compute::matchstep(int ntimestep)
+int Compute::matchstep(bigint ntimestep)
 {
   for (int i = ntime-1; i >= 0; i--) {
     if (ntimestep < tlist[i]) return 0;
     if (ntimestep == tlist[i]) return 1;
     if (ntimestep > tlist[i]) ntime--;
   }
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    clean out list of timesteps to call the compute on
 ------------------------------------------------------------------------- */
 
 void Compute::clearstep()
 {
   ntime = 0;
 }
 
 /* ----------------------------------------------------------------------
    identify molecule IDs with atoms in group
    warn if any atom in group has molecule ID = 0
    warn if any molecule has only some atoms in group
    return Ncount = # of molecules with atoms in group
    set molmap to NULL if molecule IDs include all in range from 1 to Ncount
    else: molecule IDs range from idlo to idhi
          set molmap to vector of length idhi-idlo+1
 	 molmap[id-idlo] = index from 0 to Ncount-1
          return idlo and idhi
 ------------------------------------------------------------------------- */
 
 int Compute::molecules_in_group(int &idlo, int &idhi)
 {
   int i;
 
   memory->sfree(molmap);
   molmap = NULL;
 
   // find lo/hi molecule ID for any atom in group
   // warn if atom in group has ID = 0
 
   int *molecule = atom->molecule;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int lo = BIG;
   int hi = -BIG;
   int flag = 0;
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       if (molecule[i] == 0) {
 	flag = 1;
 	continue;
       }
       lo = MIN(lo,molecule[i]);
       hi = MAX(hi,molecule[i]);
     }
 
   int flagall;
   MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
   if (flagall && comm->me == 0)
     error->warning("Atom with molecule ID = 0 included in "
 		   "compute molecule group");
 
   MPI_Allreduce(&lo,&idlo,1,MPI_INT,MPI_MIN,world);
   MPI_Allreduce(&hi,&idhi,1,MPI_INT,MPI_MAX,world);
   if (idlo == BIG) return 0;
 
   // molmap = vector of length nlen
   // set to 1 for IDs that appear in group across all procs, else 0
 
   int nlen = idhi-idlo+1;
   molmap = (int *) memory->smalloc(nlen*sizeof(int),"compute:molmap");
   for (i = 0; i < nlen; i++) molmap[i] = 0;
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit)
       molmap[molecule[i]-idlo] = 1;
 
   int *molmapall = 
     (int *) memory->smalloc(nlen*sizeof(int),"compute:molmapall");
   MPI_Allreduce(molmap,molmapall,nlen,MPI_INT,MPI_MAX,world);
 
   // nmolecules = # of non-zero IDs in molmap
   // molmap[i] = index of molecule, skipping molecules not in group with -1
 
   int nmolecules = 0;
   for (i = 0; i < nlen; i++)
     if (molmapall[i]) molmap[i] = nmolecules++;
     else molmap[i] = -1;
   memory->sfree(molmapall);
 
   // warn if any molecule has some atoms in group and some not in group
 
   flag = 0;
   for (i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) continue;
     if (molecule[i] == 0) continue;
     if (molecule[i] < idlo || molecule[i] > idhi) continue;
     if (molmap[molecule[i]-idlo] >= 0) flag = 1;
   }
 
   MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
   if (flagall && comm->me == 0)
     error->warning("One or more compute molecules has atoms not in group");
 
   // if molmap simply stores 1 to Nmolecules, then free it
 
   if (nmolecules < nlen) return nmolecules;
   if (idlo > 1) return nmolecules;
   memory->sfree(molmap);
   molmap = NULL;
   return nmolecules;
 }
diff --git a/src/compute.h b/src/compute.h
index f13f2fa9a..cb7c3152f 100644
--- a/src/compute.h
+++ b/src/compute.h
@@ -1,128 +1,129 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_COMPUTE_H
 #define LMP_COMPUTE_H
 
 #include "pointers.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class Compute : protected Pointers {
  public:
   char *id,*style;
   int igroup,groupbit;
 
   double scalar;            // computed global scalar
   double *vector;           // computed global vector
   double **array;           // computed global array
   double *vector_atom;      // computed per-atom vector
   double **array_atom;      // computed per-atom array
   double *vector_local;     // computed local vector
   double **array_local;     // computed local array
 
   int scalar_flag;          // 0/1 if compute_scalar() function exists
   int vector_flag;          // 0/1 if compute_vector() function exists
   int array_flag;           // 0/1 if compute_array() function exists
   int size_vector;          // length of global vector
   int size_array_rows;      // rows in global array
   int size_array_cols;      // columns in global array
 
   int peratom_flag;         // 0/1 if compute_peratom() function exists
   int size_peratom_cols;    // 0 = vector, N = columns in peratom array
 
   int local_flag;           // 0/1 if compute_local() function exists
   int size_local_rows;      // rows in local vector or array
   int size_local_cols;      // 0 = vector, N = columns in local array
 
   int extscalar;            // 0/1 if global scalar is intensive/extensive
   int extvector;            // 0/1/-1 if global vector is all int/ext/extlist
   int *extlist;             // list of 0/1 int/ext for each vec component
   int extarray;             // 0/1 if global array is all intensive/extensive
 
   int tempflag;       // 1 if Compute can be used as temperature
                       // must have both compute_scalar, compute_vector
   int pressflag;      // 1 if Compute can be used as pressure (uses virial)
                       // must have both compute_scalar, compute_vector
   int pressatomflag;  // 1 if Compute calculates per-atom virial
   int peflag;         // 1 if Compute calculates PE (uses Force energies)
   int peatomflag;     // 1 if Compute calculates per-atom PE
 
   int tempbias;       // 0/1 if Compute temp includes self/extra bias
 
   int timeflag;       // 1 if Compute stores list of timesteps it's called on
   int ntime;          // # of entries in time list
   int maxtime;        // max # of entries time list can hold
-  int *tlist;         // time list of steps the Compute is called on
+  bigint *tlist;      // list of timesteps the Compute is called on
 
-  int invoked_flag;     // non-zero if invoked or accessed this step, 0 if not
-  int invoked_scalar;   // last timestep on which compute_scalar() was invoked
-  int invoked_vector;   // ditto for compute_vector()
-  int invoked_array;    // ditto for compute_array()
-  int invoked_peratom;  // ditto for compute_peratom()
-  int invoked_local;    // ditto for compute_local()
+  int invoked_flag;       // non-zero if invoked or accessed this step, 0 if not
+  bigint invoked_scalar;  // last timestep on which compute_scalar() was invoked
+  bigint invoked_vector;  // ditto for compute_vector()
+  bigint invoked_array;   // ditto for compute_array()
+  bigint invoked_peratom; // ditto for compute_peratom()
+  bigint invoked_local;   // ditto for compute_local()
 
   double dof;         // degrees-of-freedom for temperature
 
   int comm_forward;   // size of forward communication (0 if none)
   int comm_reverse;   // size of reverse communication (0 if none)
 
   Compute(class LAMMPS *, int, char **);
   virtual ~Compute();
   void modify_params(int, char **);
   void reset_extra_dof();
 
   virtual void init() = 0;
   virtual void init_list(int, class NeighList *) {}
   virtual double compute_scalar() {return 0.0;}
   virtual void compute_vector() {}
   virtual void compute_array() {}
   virtual void compute_peratom() {}
   virtual void compute_local() {}
 
   virtual int pack_comm(int, int *, double *, int, int *) {return 0;}
   virtual void unpack_comm(int, int, double *) {}
   virtual int pack_reverse_comm(int, int, double *) {return 0;}
   virtual void unpack_reverse_comm(int, int *, double *) {}
 
   virtual int dof_remove(int) {return 0;}
   virtual void remove_bias(int, double *) {}
   virtual void remove_bias_all() {}
   virtual void restore_bias(int, double *) {}
   virtual void restore_bias_all() {}
 
   virtual void reset_extra_compute_fix(char *);
 
-  void addstep(int);
-  int matchstep(int);
+  void addstep(bigint);
+  int matchstep(bigint);
   void clearstep();
 
   virtual double memory_usage() {return 0.0;}
 
  protected:
   int extra_dof;               // extra DOF for temperature computes
   int dynamic;                 // recount atoms for temperature computes
   int thermoflag;              // 1 if include fix PE for PE computes
 
   double vbias[3];             // stored velocity bias for one atom
   double **vbiasall;           // stored velocity bias for all atoms
   int maxbias;                 // size of vbiasall array
 
   int *molmap;                 // convert molecule ID to local index
 
   int molecules_in_group(int &, int &);
 };
 
 }
 
 #endif
diff --git a/src/compute_reduce.cpp b/src/compute_reduce.cpp
index db9c3b6a6..da1ff6bcb 100644
--- a/src/compute_reduce.cpp
+++ b/src/compute_reduce.cpp
@@ -1,656 +1,656 @@
 /* ----------------------------------------------------------------------
    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 "string.h"
 #include "stdlib.h"
 #include "compute_reduce.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "update.h"
 #include "domain.h"
 #include "modify.h"
 #include "fix.h"
 #include "force.h"
 #include "comm.h"
 #include "group.h"
 #include "input.h"
 #include "variable.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{SUM,MINN,MAXX,AVE};
 enum{X,V,F,COMPUTE,FIX,VARIABLE};
 enum{PERATOM,LOCAL};
 
 #define INVOKED_VECTOR 2
 #define INVOKED_ARRAY 4
 #define INVOKED_PERATOM 8
 #define INVOKED_LOCAL 16
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 #define BIG 1.0e20
 
 /* ---------------------------------------------------------------------- */
 
 ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) :
   Compute(lmp, narg, arg)
 {
   int iarg;
   if (strcmp(style,"reduce") == 0) {
     if (narg < 5) error->all("Illegal compute reduce command");
     idregion = NULL;
     iarg = 3;
   } else if (strcmp(style,"reduce/region") == 0) {
     if (narg < 6) error->all("Illegal compute reduce/region command");
     iregion = domain->find_region(arg[3]);
     if (iregion == -1)
       error->all("Region ID for compute reduce/region does not exist");
     int n = strlen(arg[3]) + 1;
     idregion = new char[n];
     strcpy(idregion,arg[3]);
     iarg = 4;
   }
 
   if (strcmp(arg[iarg],"sum") == 0) mode = SUM;
   else if (strcmp(arg[iarg],"min") == 0) mode = MINN;
   else if (strcmp(arg[iarg],"max") == 0) mode = MAXX;
   else if (strcmp(arg[iarg],"ave") == 0) mode = AVE;
   else error->all("Illegal compute reduce command");
   iarg++;
 
   MPI_Comm_rank(world,&me);
 
   // parse remaining values until one isn't recognized
 
   which = new int[narg-4];
   argindex = new int[narg-4];
   flavor = new int[narg-4];
   ids = new char*[narg-4];
   value2index = new int[narg-4];
   nvalues = 0;
 
   while (iarg < narg) {
     ids[nvalues] = NULL;
 
     if (strcmp(arg[iarg],"x") == 0) {
       which[nvalues] = X;
       argindex[nvalues++] = 0;
     } else if (strcmp(arg[iarg],"y") == 0) {
       which[nvalues] = X;
       argindex[nvalues++] = 1;
     } else if (strcmp(arg[iarg],"z") == 0) {
       which[nvalues] = X;
       argindex[nvalues++] = 2;
 
     } else if (strcmp(arg[iarg],"vx") == 0) {
       which[nvalues] = V;
       argindex[nvalues++] = 0;
     } else if (strcmp(arg[iarg],"vy") == 0) {
       which[nvalues] = V;
       argindex[nvalues++] = 1;
     } else if (strcmp(arg[iarg],"vz") == 0) {
       which[nvalues] = V;
       argindex[nvalues++] = 2;
 
     } else if (strcmp(arg[iarg],"fx") == 0) {
       which[nvalues] = F;
       argindex[nvalues++] = 0;
     } else if (strcmp(arg[iarg],"fy") == 0) {
       which[nvalues] = F;
       argindex[nvalues++] = 1;
     } else if (strcmp(arg[iarg],"fz") == 0) {
       which[nvalues] = F;
       argindex[nvalues++] = 2;
 
     } else if (strncmp(arg[iarg],"c_",2) == 0 || 
 	       strncmp(arg[iarg],"f_",2) == 0 || 
 	       strncmp(arg[iarg],"v_",2) == 0) {
       if (arg[iarg][0] == 'c') which[nvalues] = COMPUTE;
       else if (arg[iarg][0] == 'f') which[nvalues] = FIX;
       else if (arg[iarg][0] == 'v') which[nvalues] = VARIABLE;
 
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Illegal compute reduce command");
 	argindex[nvalues] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[nvalues] = 0;
 
       n = strlen(suffix) + 1;
       ids[nvalues] = new char[n];
       strcpy(ids[nvalues],suffix);
       nvalues++;
       delete [] suffix;
 
     } else break;
 
     iarg++;
   }
 
   // optional args
 
   replace = new int[nvalues];
   for (int i = 0; i < nvalues; i++) replace[i] = -1;
 
   while (iarg < narg) {
     if (strcmp(arg[iarg],"replace") == 0) {
       if (iarg+3 > narg) error->all("Illegal compute reduce command");
       if (mode != MINN && mode != MAXX)
 	error->all("Compute reduce replace requires min or max mode");
       int col1 = atoi(arg[iarg+1]) - 1;
       int col2 = atoi(arg[iarg+2]) - 1;
       if (col1 < 0 || col1 >= nvalues || col2 < 0 || col2 >= nvalues)
 	error->all("Illegal compute reduce command");
       if (col1 == col2)	error->all("Illegal compute reduce command");
       if (replace[col1] >= 0 || replace[col2] >= 0)
 	error->all("Invalid replace values in compute reduce"); 
       replace[col1] = col2;
       iarg += 3;
     } else error->all("Illegal compute reduce command");
   }
 
   // delete replace if not set
 
   int flag = 0;
   for (int i = 0; i < nvalues; i++)
     if (replace[i] >= 0) flag = 1;
   if (!flag) {
     delete [] replace;
     replace = NULL;
   }
 
   // setup and error check
 
   for (int i = 0; i < nvalues; i++) {
     if (which[i] == X || which[i] == V || which[i] == F)
       flavor[i] = PERATOM;
 
     else if (which[i] == COMPUTE) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for compute reduce does not exist");
       if (modify->compute[icompute]->peratom_flag) {
 	flavor[i] = PERATOM;
 	if (argindex[i] == 0 && 
 	    modify->compute[icompute]->size_peratom_cols != 0)
 	  error->all("Compute reduce compute does not "
 		     "calculate a per-atom vector");
 	if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0)
 	  error->all("Compute reduce compute does not "
 		     "calculate a per-atom array");
 	if (argindex[i] && 
 	    argindex[i] > modify->compute[icompute]->size_peratom_cols)
 	  error->all("Compute reduce compute array is accessed out-of-range");
       } else if (modify->compute[icompute]->local_flag) {
 	flavor[i] = LOCAL;
 	if (argindex[i] == 0 && 
 	    modify->compute[icompute]->size_local_cols != 0)
 	  error->all("Compute reduce compute does not "
 		     "calculate a local vector");
 	if (argindex[i] && modify->compute[icompute]->size_local_cols == 0)
 	  error->all("Compute reduce compute does not "
 		     "calculate a local array");
 	if (argindex[i] && 
 	    argindex[i] > modify->compute[icompute]->size_local_cols)
 	  error->all("Compute reduce compute array is accessed out-of-range");
       } else error->all("Compute reduce compute calculates global values");
 
     } else if (which[i] == FIX) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0)
 	error->all("Fix ID for compute reduce does not exist");
       if (modify->fix[ifix]->peratom_flag) {
 	flavor[i] = PERATOM;
 	if (argindex[i] == 0 && 
 	    modify->fix[ifix]->size_peratom_cols != 0)
 	  error->all("Compute reduce fix does not "
 		     "calculate a per-atom vector");
 	if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0)
 	  error->all("Compute reduce fix does not "
 		     "calculate a per-atom array");
 	if (argindex[i] && 
 	    argindex[i] > modify->fix[ifix]->size_peratom_cols)
 	  error->all("Compute reduce fix array is accessed out-of-range");
       } else if (modify->fix[ifix]->local_flag) {
 	flavor[i] = LOCAL;
 	if (argindex[i] == 0 && 
 	    modify->fix[ifix]->size_local_cols != 0)
 	  error->all("Compute reduce fix does not "
 		     "calculate a local vector");
 	if (argindex[i] && modify->fix[ifix]->size_local_cols == 0)
 	  error->all("Compute reduce fix does not "
 		     "calculate a local array");
 	if (argindex[i] && 
 	    argindex[i] > modify->fix[ifix]->size_local_cols)
 	  error->all("Compute reduce fix array is accessed out-of-range");
       } else error->all("Compute reduce fix calculates global values");
 
     } else if (which[i] == VARIABLE) {
       int ivariable = input->variable->find(ids[i]);
       if (ivariable < 0)
 	error->all("Variable name for compute reduce does not exist");
       if (input->variable->atomstyle(ivariable) == 0)
 	error->all("Compute reduce variable is not atom-style variable");
       flavor[i] = PERATOM;
     }
   }
 
   // this compute produces either a scalar or vector
 
   if (nvalues == 1) {
     scalar_flag = 1;
     if (mode == SUM) extscalar = 1;
     else extscalar = 0;
     vector = onevec = NULL;
     indices = owner = NULL;
   } else {
     vector_flag = 1;
     size_vector = nvalues;
     if (mode == SUM) extvector = 1;
     else extvector = 0;
     vector = new double[size_vector];
     onevec = new double[size_vector];
     indices = new int[size_vector];
     owner = new int[size_vector];
   }
 
   maxatom = 0;
   varatom = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
 
 ComputeReduce::~ComputeReduce()
 {
   delete [] which;
   delete [] argindex;
   delete [] flavor;
   for (int m = 0; m < nvalues; m++) delete [] ids[m];
   delete [] ids;
   delete [] value2index;
   delete [] replace;
   delete [] idregion;
 
   delete [] vector;
   delete [] onevec;
   delete [] indices;
   delete [] owner;
 
   memory->sfree(varatom);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeReduce::init()
 {
   // set indices and check validity of all computes,fixes,variables
 
   for (int m = 0; m < nvalues; m++) {
     if (which[m] == COMPUTE) {
       int icompute = modify->find_compute(ids[m]);
       if (icompute < 0)
 	error->all("Compute ID for compute reduce does not exist");
       value2index[m] = icompute;
       
     } else if (which[m] == FIX) {
       int ifix = modify->find_fix(ids[m]);
       if (ifix < 0) 
 	error->all("Fix ID for compute reduce does not exist");
       value2index[m] = ifix;
 
     } else if (which[m] == VARIABLE) {
       int ivariable = input->variable->find(ids[m]);
       if (ivariable < 0) 
 	error->all("Variable name for compute reduce does not exist");
       value2index[m] = ivariable;
 
     } else value2index[m] = -1;
   }
 
   // set index and check validity of region
 
   if (idregion) {
     iregion = domain->find_region(idregion);
     if (iregion == -1)
       error->all("Region ID for compute reduce/region does not exist");
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 double ComputeReduce::compute_scalar()
 {
   invoked_scalar = update->ntimestep;
 
   double one = compute_one(0,-1);
 
   if (mode == SUM) {
     MPI_Allreduce(&one,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
   } else if (mode == MINN) {
     MPI_Allreduce(&one,&scalar,1,MPI_DOUBLE,MPI_MIN,world);
   } else if (mode == MAXX) {
     MPI_Allreduce(&one,&scalar,1,MPI_DOUBLE,MPI_MAX,world);
   } else if (mode == AVE) {
     MPI_Allreduce(&one,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
     scalar /= count(0);
   }
 
   return scalar;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ComputeReduce::compute_vector()
 {
   invoked_vector = update->ntimestep;
 
   for (int m = 0; m < nvalues; m++)
     if (!replace || replace[m] < 0) {
       onevec[m] = compute_one(m,-1);
       indices[m] = index;
     }
 
   if (mode == SUM) {
     for (int m = 0; m < nvalues; m++)
       MPI_Allreduce(&onevec[m],&vector[m],1,MPI_DOUBLE,MPI_SUM,world);
 
   } else if (mode == MINN) {
     if (!replace) {
       for (int m = 0; m < nvalues; m++)
 	MPI_Allreduce(&onevec[m],&vector[m],1,MPI_DOUBLE,MPI_MIN,world);
 
     } else {
       for (int m = 0; m < nvalues; m++)
 	if (replace[m] < 0) {
 	  pairme.value = onevec[m];
 	  pairme.proc = me;
 	  MPI_Allreduce(&pairme,&pairall,1,MPI_DOUBLE_INT,MPI_MINLOC,world);
 	  vector[m] = pairall.value;
 	  owner[m] = pairall.proc;
 	}
       for (int m = 0; m < nvalues; m++)
 	if (replace[m] >= 0) {
 	  if (me == owner[replace[m]])
 	    vector[m] = compute_one(m,indices[replace[m]]);
 	  MPI_Bcast(&vector[m],1,MPI_DOUBLE,owner[replace[m]],world);
 	}
     }
 
   } else if (mode == MAXX) {
     if (!replace) {
       for (int m = 0; m < nvalues; m++)
 	MPI_Allreduce(&onevec[m],&vector[m],1,MPI_DOUBLE,MPI_MAX,world);
 
     } else {
       for (int m = 0; m < nvalues; m++)
 	if (replace[m] < 0) {
 	  pairme.value = onevec[m];
 	  pairme.proc = me;
 	  MPI_Allreduce(&pairme,&pairall,1,MPI_DOUBLE_INT,MPI_MAXLOC,world);
 	  vector[m] = pairall.value;
 	  owner[m] = pairall.proc;
 	}
       for (int m = 0; m < nvalues; m++)
 	if (replace[m] >= 0) {
 	  if (me == owner[replace[m]])
 	    vector[m] = compute_one(m,indices[replace[m]]);
 	  MPI_Bcast(&vector[m],1,MPI_DOUBLE,owner[replace[m]],world);
 	}
     }
 
   } else if (mode == AVE) {
     for (int m = 0; m < nvalues; m++) {
       MPI_Allreduce(&onevec[m],&vector[m],1,MPI_DOUBLE,MPI_SUM,world);
       vector[m] /= count(m);
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    calculate reduced value for one input M and return it
    if flag = -1:
      sum/min/max/ave all values in vector
      for per-atom quantities, limit to atoms in group
      if mode = MIN or MAX, also set index to which vector value wins
    if flag >= 0: simply return vector[flag]
 ------------------------------------------------------------------------- */
 
 double ComputeReduce::compute_one(int m, int flag)
 {
   int i;
 
   // invoke the appropriate attribute,compute,fix,variable
   // for flag = -1, compute scalar quantity by scanning over atom properties
   // only include atoms in group for atom properties and per-atom quantities
 
   index = -1;
   int vidx = value2index[m];
   int aidx = argindex[m];
 
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   double one;
   if (mode == SUM) one = 0.0;
   else if (mode == MINN) one = BIG;
   else if (mode == MAXX) one = -BIG;
   else if (mode == AVE) one = 0.0;
 
   if (which[m] == X) {
     double **x = atom->x;
     if (flag < 0) {
       for (i = 0; i < nlocal; i++)
 	if (mask[i] & groupbit) combine(one,x[i][aidx],i);
     } else one = x[flag][aidx];
   } else if (which[m] == V) {
     double **v = atom->v;
     if (flag < 0) {
       for (i = 0; i < nlocal; i++)
 	if (mask[i] & groupbit) combine(one,v[i][aidx],i);
     } else one = v[flag][aidx];
   } else if (which[m] == F) {
     double **f = atom->f;
     if (flag < 0) {
       for (i = 0; i < nlocal; i++)
 	if (mask[i] & groupbit) combine(one,f[i][aidx],i);
     } else one = f[flag][aidx];
     
   // invoke compute if not previously invoked
 
   } else if (which[m] == COMPUTE) {
     Compute *compute = modify->compute[vidx];
     
     if (flavor[m] == PERATOM) {
       if (!(compute->invoked_flag & INVOKED_PERATOM)) {
 	compute->compute_peratom();
 	compute->invoked_flag |= INVOKED_PERATOM;
       }
 
       if (aidx == 0) {
 	double *comp_vec = compute->vector_atom;
 	int n = nlocal;
 	if (flag < 0) {
 	  for (i = 0; i < n; i++)
 	    if (mask[i] & groupbit) combine(one,comp_vec[i],i);
 	} else one = comp_vec[flag];
       } else {
 	double **carray_atom = compute->array_atom;
 	int n = nlocal;
 	int aidxm1 = aidx - 1;
 	if (flag < 0) {
 	  for (i = 0; i < n; i++)
 	    if (mask[i] & groupbit) combine(one,carray_atom[i][aidxm1],i);
 	} else one = carray_atom[flag][aidxm1];
       }
 
     } else if (flavor[m] == LOCAL) {
       if (!(compute->invoked_flag & INVOKED_LOCAL)) {
 	compute->compute_local();
 	compute->invoked_flag |= INVOKED_LOCAL;
       }
 
       if (aidx == 0) {
 	double *comp_vec = compute->vector_local;
 	int n = compute->size_local_rows;
 	if (flag < 0)
 	  for (i = 0; i < n; i++)
 	    combine(one,comp_vec[i],i);
 	else one = comp_vec[flag];
       } else {
 	double **carray_local = compute->array_local;
 	int n = compute->size_local_rows;
 	int aidxm1 = aidx - 1;
 	if (flag < 0)
 	  for (i = 0; i < n; i++)
 	    combine(one,carray_local[i][aidxm1],i);
 	else one = carray_local[flag][aidxm1];
       }
     }
 
   // access fix fields, check if fix frequency is a match
 
   } else if (which[m] == FIX) {
     if (update->ntimestep % modify->fix[vidx]->peratom_freq)
       error->all("Fix used in compute reduce not computed at compatible time");
     Fix *fix = modify->fix[vidx];
 
     if (flavor[m] == PERATOM) {
       if (aidx == 0) {
 	double *fix_vector = fix->vector_atom;
 	int n = nlocal;
 	if (flag < 0) {
 	  for (i = 0; i < n; i++)
 	    if (mask[i] & groupbit) combine(one,fix_vector[i],i);
 	} else one = fix_vector[flag];
       } else {
 	double **fix_array = fix->array_atom;
 	int aidxm1 = aidx - 1;
 	if (flag < 0) {
 	  for (i = 0; i < nlocal; i++)
 	    if (mask[i] & groupbit) combine(one,fix_array[i][aidxm1],i);
 	} else one = fix_array[flag][aidxm1];
       }
 
     } else if (flavor[m] == LOCAL) {
       if (aidx == 0) {
 	double *fix_vector = fix->vector_local;
 	int n = fix->size_local_rows;
 	if (flag < 0)
 	  for (i = 0; i < n; i++)
 	    combine(one,fix_vector[i],i);
 	else one = fix_vector[flag];
       } else {
 	double **fix_array = fix->array_local;
 	int n = fix->size_local_rows;
 	int aidxm1 = aidx - 1;
 	if (flag < 0)
 	  for (i = 0; i < n; i++)
 	    combine(one,fix_array[i][aidxm1],i);
 	else one = fix_array[flag][aidxm1];
       }
     }
     
   // evaluate atom-style variable
 
   } else if (which[m] == VARIABLE) {
     if (nlocal > maxatom) {
       maxatom = atom->nmax;
       memory->sfree(varatom);
       varatom =	(double *) 
 	memory->smalloc(maxatom*sizeof(double),"reduce:varatom");
     }
 
     input->variable->compute_atom(vidx,igroup,varatom,1,0);
     if (flag < 0) {
       for (i = 0; i < nlocal; i++)
 	if (mask[i] & groupbit) combine(one,varatom[i],i);
     } else one = varatom[flag];
   }
 
   return one;
 }
 
 /* ---------------------------------------------------------------------- */
 
 bigint ComputeReduce::count(int m)
 {
   int vidx = value2index[m];
   int aidx = argindex[m];
 
   if (which[m] == X || which[m] == V || which[m] == F)
     return group->count(igroup);
   else if (which[m] == COMPUTE) {
     Compute *compute = modify->compute[vidx];
     if (flavor[m] == PERATOM) {
       return group->count(igroup);
     } else if (flavor[m] == LOCAL) {
       bigint ncount = compute->size_local_rows;
       bigint ncountall;
-      MPI_Allreduce(&ncount,&ncountall,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+      MPI_Allreduce(&ncount,&ncountall,1,MPI_LMP_BIGINT,MPI_SUM,world);
       return ncountall;
     }
   } else if (which[m] == FIX) {
     Fix *fix = modify->fix[vidx];
     if (flavor[m] == PERATOM) {
       return group->count(igroup);
     } else if (flavor[m] == LOCAL) {
       bigint ncount = fix->size_local_rows;
       bigint ncountall;
-      MPI_Allreduce(&ncount,&ncountall,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+      MPI_Allreduce(&ncount,&ncountall,1,MPI_LMP_BIGINT,MPI_SUM,world);
       return ncountall;
     }
   } else if (which[m] == VARIABLE)
     return group->count(igroup);
 
   bigint dummy = 0;
   return dummy;
 }
 
 /* ----------------------------------------------------------------------
    combine two values according to reduction mode
    for MIN/MAX, also update index with winner
 ------------------------------------------------------------------------- */
 
 void ComputeReduce::combine(double &one, double two, int i)
 {
   if (mode == SUM || mode == AVE) one += two;
   else if (mode == MINN) {
     if (two < one) {
       one = two;
       index = i;
     }
   } else if (mode == MAXX) {
     if (two > one) {
       one = two;
       index = i;
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    memory usage of varatom
 ------------------------------------------------------------------------- */
 
 double ComputeReduce::memory_usage()
 {
   double bytes = maxatom * sizeof(double);
   return bytes;
 }
diff --git a/src/create_atoms.cpp b/src/create_atoms.cpp
index e895c6853..60f823909 100644
--- a/src/create_atoms.cpp
+++ b/src/create_atoms.cpp
@@ -1,483 +1,487 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "create_atoms.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "comm.h"
 #include "modify.h"
 #include "fix.h"
 #include "domain.h"
 #include "lattice.h"
 #include "region.h"
 #include "random_park.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define BIG      1.0e30
 #define EPSILON  1.0e-6
 
 enum{BOX,REGION,SINGLE,RANDOM};
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 /* ---------------------------------------------------------------------- */
 
 CreateAtoms::CreateAtoms(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 void CreateAtoms::command(int narg, char **arg)
 {
   if (domain->box_exist == 0) 
     error->all("Create_atoms command before simulation box is defined");
   if (modify->nfix_restart_peratom) 
     error->all("Cannot create_atoms after "
 	       "reading restart file with per-atom info");
 
   // parse arguments
 
   if (narg < 2) error->all("Illegal create_atoms command");
   itype = atoi(arg[0]);
   if (itype <= 0 || itype > atom->ntypes) 
     error->all("Invalid atom type in create_atoms command");
 
   int iarg;
   if (strcmp(arg[1],"box") == 0) {
     style = BOX;
     iarg = 2;
   } else if (strcmp(arg[1],"region") == 0) {
     style = REGION;
     if (narg < 3) error->all("Illegal create_atoms command");
     nregion = domain->find_region(arg[2]);
     if (nregion == -1) error->all("Create_atoms region ID does not exist");
     iarg = 3;;
   } else if (strcmp(arg[1],"single") == 0) {
     style = SINGLE;
     if (narg < 5) error->all("Illegal create_atoms command");
     xone[0] = atof(arg[2]);
     xone[1] = atof(arg[3]);
     xone[2] = atof(arg[4]);
     iarg = 5;
   } else if (strcmp(arg[1],"random") == 0) {
     style = RANDOM;
     if (narg < 5) error->all("Illegal create_atoms command");
     nrandom = atoi(arg[2]);
     seed = atoi(arg[3]);
     if (strcmp(arg[4],"NULL") == 0) nregion = -1;
     else {
       nregion = domain->find_region(arg[4]);
       if (nregion == -1) error->all("Create_atoms region ID does not exist");
     }
     iarg = 5;
   } else error->all("Illegal create_atoms command");
 
   // process optional keywords
 
   int scaleflag = 1;
 
   if (domain->lattice) {
     nbasis = domain->lattice->nbasis;
     basistype = new int[nbasis];
     for (int i = 0; i < nbasis; i++) basistype[i] = itype;
   }
 
   while (iarg < narg) {
     if (strcmp(arg[iarg],"basis") == 0) {
       if (iarg+3 > narg) error->all("Illegal create_atoms command");
       if (domain->lattice == NULL)
 	error->all("Cannot create atoms with undefined lattice");
       int ibasis = atoi(arg[iarg+1]);
       itype = atoi(arg[iarg+2]);
       if (ibasis <= 0 || ibasis > nbasis || 
 	  itype <= 0 || itype > atom->ntypes) 
 	error->all("Illegal create_atoms command");
       basistype[ibasis-1] = itype;
       iarg += 3;
     } else if (strcmp(arg[iarg],"units") == 0) {
       if (iarg+2 > narg) error->all("Illegal create_atoms command");
       if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
       else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
       else error->all("Illegal create_atoms command");
       iarg += 2;
     } else error->all("Illegal create_atoms command");
   }
 
   // error checks
 
   if (style == RANDOM) {
     if (nrandom < 0) error->all("Illegal create_atoms command");
     if (seed <= 0) error->all("Illegal create_atoms command");
   }
 
   // demand lattice be defined
   // else setup scaling for single atom
   // could use domain->lattice->lattice2box() to do conversion of
   //   lattice to box, but not consistent with other uses of units=lattice
   // triclinic remapping occurs in add_single()
 
   if (style == BOX || style == REGION) {
     if (domain->lattice == NULL)
       error->all("Cannot create atoms with undefined lattice");
   } else if (scaleflag == 1) {
     if (domain->lattice == NULL)
       error->all("Cannot create atoms with undefined lattice");
     xone[0] *= domain->lattice->xlattice;
     xone[1] *= domain->lattice->ylattice;
     xone[2] *= domain->lattice->zlattice;
   }
 
   // add atoms
 
   bigint natoms_previous = atom->natoms;
   int nlocal_previous = atom->nlocal;
 
   if (style == SINGLE) add_single();
   else if (style == RANDOM) add_random();
   else add_lattice();
 
   // invoke set_arrays() for fixes that need initialization of new atoms
 
   int nlocal = atom->nlocal;
   for (int m = 0; m < modify->nfix; m++) {
     Fix *fix = modify->fix[m];
     if (fix->create_attribute)
       for (int i = nlocal_previous; i < nlocal; i++)
 	fix->set_arrays(i);
   }
 
   // clean up
 
   if (domain->lattice) delete [] basistype;
 
   // new total # of atoms
 
   bigint nblocal = atom->nlocal;
-  MPI_Allreduce(&nblocal,&atom->natoms,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&nblocal,&atom->natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
+  if (atom->natoms < 0 || atom->natoms > MAXBIGINT)
+    error->all("Too many total atoms");
 
   // print status
 
   if (comm->me == 0) {
+    char str[32];
+    sprintf(str,"Created %s atoms\n",BIGINT_FORMAT);
     if (screen)
-      fprintf(screen,"Created %lu atoms\n",atom->natoms-natoms_previous);
+      fprintf(screen,str,atom->natoms-natoms_previous);
     if (logfile)
-      fprintf(logfile,"Created %lu atoms\n",atom->natoms-natoms_previous);
+      fprintf(logfile,str,atom->natoms-natoms_previous);
   }
 
   // reset simulation now that more atoms are defined
   // add tags for newly created atoms if possible
   // if global map exists, reset it
   // if a molecular system, set nspecial to 0 for new atoms
 
-  if (atom->natoms > MAXINT32) atom->tag_enable = 0;
-  if (atom->natoms <= MAXINT32) atom->tag_extend();
+  if (atom->natoms > MAXTAGINT) atom->tag_enable = 0;
+  if (atom->natoms <= MAXTAGINT) atom->tag_extend();
 
   if (atom->map_style) {
     atom->nghost = 0;
     atom->map_init();
     atom->map_set();
   }
   if (atom->molecular) {
     int **nspecial = atom->nspecial;
     for (int i = nlocal_previous; i < atom->nlocal; i++) {
       nspecial[i][0] = 0;
       nspecial[i][1] = 0;
       nspecial[i][2] = 0;
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    add single atom with coords at xone if it's in my sub-box
    if triclinic, xone is in lamda coords
 ------------------------------------------------------------------------- */
 
 void CreateAtoms::add_single()
 {
   double *sublo,*subhi;
 
   // sub-domain bounding box, in lamda units if triclinic
 
   if (domain->triclinic == 0) {
     sublo = domain->sublo;
     subhi = domain->subhi;
   } else {
     sublo = domain->sublo_lamda;
     subhi = domain->subhi_lamda;
   }
 
   // if triclinic, convert to lamda coords (0-1)
 
   double lamda[3],*coord;
   if (domain->triclinic) {
     domain->x2lamda(xone,lamda);
     coord = lamda;
   } else coord = xone;
 
   // if atom is in my subbox, create it
 
   if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
       coord[1] >= sublo[1] && coord[1] < subhi[1] &&
       coord[2] >= sublo[2] && coord[2] < subhi[2])
     atom->avec->create_atom(itype,xone);
 }
 
 
 /* ----------------------------------------------------------------------
    add Nrandom atoms at random locations
 ------------------------------------------------------------------------- */
 
 void CreateAtoms::add_random()
 {
   double xlo,ylo,zlo,xhi,yhi,zhi,zmid;
   double lamda[3],*coord;
   double *sublo,*subhi,*boxlo,*boxhi;
 
   // random number generator, same for all procs
 
   RanPark *random = new RanPark(lmp,seed);
 
   // bounding box for atom creation
   // in real units, even if triclinic
   // only limit bbox by region if its bboxflag is set (interior region)
 
   if (domain->triclinic == 0) {
     xlo = domain->boxlo[0]; xhi = domain->boxhi[0];
     ylo = domain->boxlo[1]; yhi = domain->boxhi[1];
     zlo = domain->boxlo[2]; zhi = domain->boxhi[2];
     zmid = zlo + 0.5*(zhi-zlo);
   } else {
     xlo = domain->boxlo_bound[0]; xhi = domain->boxhi_bound[0];
     ylo = domain->boxlo_bound[1]; yhi = domain->boxhi_bound[1];
     zlo = domain->boxlo_bound[2]; zhi = domain->boxhi_bound[2];
     zmid = zlo + 0.5*(zhi-zlo);
   }
 
   if (nregion >= 0 && domain->regions[nregion]->bboxflag) {
     xlo = MAX(xlo,domain->regions[nregion]->extent_xlo);
     xhi = MIN(xhi,domain->regions[nregion]->extent_xhi);
     ylo = MAX(ylo,domain->regions[nregion]->extent_ylo);
     yhi = MIN(yhi,domain->regions[nregion]->extent_yhi);
     zlo = MAX(zlo,domain->regions[nregion]->extent_zlo);
     zhi = MIN(zhi,domain->regions[nregion]->extent_zhi);
   }
 
   // sub-domain bounding box, in lamda units if triclinic
 
   if (domain->triclinic == 0) {
     sublo = domain->sublo;
     subhi = domain->subhi;
   } else {
     sublo = domain->sublo_lamda;
     subhi = domain->subhi_lamda;
     boxlo = domain->boxlo_lamda;
     boxhi = domain->boxhi_lamda;
   }
 
   // generate random positions for each new atom within bounding box
   // iterate until atom is within region and triclinic simulation box
   // if final atom position is in my subbox, create it
 
   int valid;
   for (int i = 0; i < nrandom; i++) {
     while (1) {
       xone[0] = xlo + random->uniform() * (xhi-xlo);
       xone[1] = ylo + random->uniform() * (yhi-ylo);
       xone[2] = zlo + random->uniform() * (zhi-zlo);
       if (domain->dimension == 2) xone[2] = zmid;
 
       valid = 1;
       if (nregion >= 0 && 
 	  domain->regions[nregion]->match(xone[0],xone[1],xone[2]) == 0)
 	valid = 0;
       if (domain->triclinic) {
 	domain->x2lamda(xone,lamda);
 	coord = lamda;
 	if (coord[0] < boxlo[0] || coord[0] >= boxhi[0] ||
 	    coord[1] < boxlo[1] || coord[1] >= boxhi[1] ||
 	    coord[2] < boxlo[2] || coord[2] >= boxhi[2]) valid = 0;
       } else coord = xone;
 
       if (valid) break;
     }
 
     // if triclinic, coord is now in lamda units
 
     if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
 	coord[1] >= sublo[1] && coord[1] < subhi[1] &&
 	coord[2] >= sublo[2] && coord[2] < subhi[2])
       atom->avec->create_atom(itype,xone);
   }
   
   // clean-up
 
   delete random;
 }
 
 /* ----------------------------------------------------------------------
    add many atoms by looping over lattice
 ------------------------------------------------------------------------- */
 
 void CreateAtoms::add_lattice()
 {
   // convert 8 corners of my subdomain from box coords to lattice coords
   // for orthogonal, use corner pts of my subbox
   // for triclinic, use bounding box of my subbox
   // xyz min to max = bounding box around the domain corners in lattice space
 
   int triclinic = domain->triclinic;
   double bboxlo[3],bboxhi[3];
 
   if (triclinic == 0) {
     bboxlo[0] = domain->sublo[0]; bboxhi[0] = domain->subhi[0];
     bboxlo[1] = domain->sublo[1]; bboxhi[1] = domain->subhi[1];
     bboxlo[2] = domain->sublo[2]; bboxhi[2] = domain->subhi[2];
   } else domain->bbox(domain->sublo_lamda,domain->subhi_lamda,bboxlo,bboxhi);
 
   double xmin,ymin,zmin,xmax,ymax,zmax;
   xmin = ymin = zmin = BIG;
   xmax = ymax = zmax = -BIG;
 
   domain->lattice->bbox(1,bboxlo[0],bboxlo[1],bboxlo[2],
 			xmin,ymin,zmin,xmax,ymax,zmax);
   domain->lattice->bbox(1,bboxhi[0],bboxlo[1],bboxlo[2],
 			xmin,ymin,zmin,xmax,ymax,zmax);
   domain->lattice->bbox(1,bboxlo[0],bboxhi[1],bboxlo[2],
 			xmin,ymin,zmin,xmax,ymax,zmax);
   domain->lattice->bbox(1,bboxhi[0],bboxhi[1],bboxlo[2],
 			xmin,ymin,zmin,xmax,ymax,zmax);
   domain->lattice->bbox(1,bboxlo[0],bboxlo[1],bboxhi[2],
 			xmin,ymin,zmin,xmax,ymax,zmax);
   domain->lattice->bbox(1,bboxhi[0],bboxlo[1],bboxhi[2],
 			xmin,ymin,zmin,xmax,ymax,zmax);
   domain->lattice->bbox(1,bboxlo[0],bboxhi[1],bboxhi[2],
 			xmin,ymin,zmin,xmax,ymax,zmax);
   domain->lattice->bbox(1,bboxhi[0],bboxhi[1],bboxhi[2],
 			xmin,ymin,zmin,xmax,ymax,zmax);
 
   // ilo:ihi,jlo:jhi,klo:khi = loop bounds for lattice overlap of my subbox
   // overlap = any part of a unit cell (face,edge,pt) in common with my subbox
   // in lattice space, subbox is a tilted box
   // but bbox of subbox is aligned with lattice axes
   // so ilo:khi unit cells should completely tile bounding box
   // decrement lo, increment hi to avoid round-off issues in lattice->bbox(),
   //   which can lead to missing atoms in rare cases
   // extra decrement of lo if min < 0, since static_cast(-1.5) = -1
 
   int ilo,ihi,jlo,jhi,klo,khi;
   ilo = static_cast<int> (xmin) - 1;
   jlo = static_cast<int> (ymin) - 1;
   klo = static_cast<int> (zmin) - 1;
   ihi = static_cast<int> (xmax) + 1;
   jhi = static_cast<int> (ymax) + 1;
   khi = static_cast<int> (zmax) + 1;
 
   if (xmin < 0.0) ilo--;
   if (ymin < 0.0) jlo--;
   if (zmin < 0.0) klo--;
 
   // set bounds for my proc
   // if periodic:
   //   should create exactly 1 atom when 2 images are both "on" the boundary
   //   either image may be slightly inside/outside true box due to round-off
   //   if I am lo proc, decrement lower bound by EPSILON
   //     this will insure lo image is created
   //   if I am hi proc, decrement upper bound by 2.0*EPSILON
   //     this will insure hi image is not created
   //   thus insertion box is EPSILON smaller than true box
   //     and is shifted away from true boundary
   //     which is where atoms are likely to be generated
 
   double epsilon[3];
   if (triclinic) epsilon[0] = epsilon[1] = epsilon[2] = EPSILON;
   else {
     epsilon[0] = domain->prd[0] * EPSILON;
     epsilon[1] = domain->prd[1] * EPSILON;
     epsilon[2] = domain->prd[2] * EPSILON;
   }
 
   double sublo[3],subhi[3];
 
   if (triclinic == 0) {
     sublo[0] = domain->sublo[0]; subhi[0] = domain->subhi[0];
     sublo[1] = domain->sublo[1]; subhi[1] = domain->subhi[1];
     sublo[2] = domain->sublo[2]; subhi[2] = domain->subhi[2];
   } else {
     sublo[0] = domain->sublo_lamda[0]; subhi[0] = domain->subhi_lamda[0];
     sublo[1] = domain->sublo_lamda[1]; subhi[1] = domain->subhi_lamda[1];
     sublo[2] = domain->sublo_lamda[2]; subhi[2] = domain->subhi_lamda[2];
   }
 
   if (domain->xperiodic) {
     if (comm->myloc[0] == 0) sublo[0] -= epsilon[0];
     if (comm->myloc[0] == comm->procgrid[0]-1) subhi[0] -= 2.0*epsilon[0];
   }
   if (domain->yperiodic) {
     if (comm->myloc[1] == 0) sublo[1] -= epsilon[1];
     if (comm->myloc[1] == comm->procgrid[1]-1) subhi[1] -= 2.0*epsilon[1];
   }
   if (domain->zperiodic) {
     if (comm->myloc[2] == 0) sublo[2] -= epsilon[2];
     if (comm->myloc[2] == comm->procgrid[2]-1) subhi[2] -= 2.0*epsilon[2];
   }
 
   // iterate on 3d periodic lattice of unit cells using loop bounds
   // iterate on nbasis atoms in each unit cell
   // convert lattice coords to box coords
   // add atom if it meets all criteria 
 
   double **basis = domain->lattice->basis;
   double x[3],lamda[3];
   double *coord;
 
   int i,j,k,m;
   for (k = klo; k <= khi; k++)
     for (j = jlo; j <= jhi; j++)
       for (i = ilo; i <= ihi; i++)
 	for (m = 0; m < nbasis; m++) {
 
 	  x[0] = i + basis[m][0];
 	  x[1] = j + basis[m][1];
 	  x[2] = k + basis[m][2];
 
 	  // convert from lattice coords to box coords
 
 	  domain->lattice->lattice2box(x[0],x[1],x[2]);
 
 	  // if a region was specified, test if atom is in it
 
 	  if (style == REGION)
 	    if (!domain->regions[nregion]->match(x[0],x[1],x[2])) continue;
 
 	  // test if atom is in my subbox
 
 	  if (triclinic) {
 	    domain->x2lamda(x,lamda);
 	    coord = lamda;
 	  } else coord = x;
 
 	  if (coord[0] < sublo[0] || coord[0] >= subhi[0] || 
 	      coord[1] < sublo[1] || coord[1] >= subhi[1] || 
 	      coord[2] < sublo[2] || coord[2] >= subhi[2]) continue;
 
 	  // add the atom to my list of atoms
 
 	  atom->avec->create_atom(basistype[m],x);
 	}
 }
diff --git a/src/delete_atoms.cpp b/src/delete_atoms.cpp
index 1fcf224b0..f140c5237 100644
--- a/src/delete_atoms.cpp
+++ b/src/delete_atoms.cpp
@@ -1,362 +1,363 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "string.h"
 #include "delete_atoms.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "comm.h"
 #include "domain.h"
 #include "force.h"
 #include "group.h"
 #include "region.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "neigh_request.h"
 #include "random_mars.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 /* ---------------------------------------------------------------------- */
 
 DeleteAtoms::DeleteAtoms(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 void DeleteAtoms::command(int narg, char **arg)
 {
   if (domain->box_exist == 0) 
     error->all("Delete_atoms command before simulation box is defined");
   if (narg < 1) error->all("Illegal delete_atoms command");
   if (atom->tag_enable == 0)
     error->all("Cannot use delete_atoms unless atoms have IDs");
 
   // store state before delete
 
   bigint natoms_previous = atom->natoms;
 
   // delete the atoms
 
   if (strcmp(arg[0],"group") == 0) delete_group(narg,arg);
   else if (strcmp(arg[0],"region") == 0) delete_region(narg,arg);
   else if (strcmp(arg[0],"overlap") == 0) delete_overlap(narg,arg);
   else if (strcmp(arg[0],"porosity") == 0) delete_porosity(narg,arg);
   else error->all("Illegal delete_atoms command");
 
   // delete local atoms flagged in dlist
   // reset nlocal
 
   AtomVec *avec = atom->avec;
   int nlocal = atom->nlocal;
 
   int i = 0;
   while (i < nlocal) {
     if (dlist[i]) {
       avec->copy(nlocal-1,i);
       dlist[i] = dlist[nlocal-1];
       nlocal--;
     } else i++;
   }
 
   atom->nlocal = nlocal;
   memory->sfree(dlist);
 
   // if non-molecular system and compress flag set,
   // reset atom tags to be contiguous
   // set all atom IDs to 0, call tag_extend()
 
   if (atom->molecular == 0 && compress_flag) {
     int *tag = atom->tag;
     for (i = 0; i < nlocal; i++) tag[i] = 0;
     atom->tag_extend();
   }
 
   // reset atom->natoms
   // reset atom->map if it exists
   // set nghost to 0 so old ghosts of deleted atoms won't be mapped
 
   bigint nblocal = atom->nlocal;
-  MPI_Allreduce(&nblocal,&atom->natoms,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&nblocal,&atom->natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
   if (atom->map_style) {
     atom->nghost = 0;
     atom->map_init();
     atom->map_set();
   }
 
   // print before and after atom count
 
   bigint ndelete = natoms_previous - atom->natoms;
 
   if (comm->me == 0) {
-    if (screen) fprintf(screen,"Deleted %lu atoms, new total = %lu\n",
-			ndelete,atom->natoms);
-    if (logfile) fprintf(logfile,"Deleted %lu atoms, new total = %lu\n",
-			 ndelete,atom->natoms);
+    char str[64];
+    sprintf(str,"Deleted %s atoms, new total = %s\n",
+	    BIGINT_FORMAT,BIGINT_FORMAT);
+    if (screen) fprintf(screen,str,ndelete,atom->natoms);
+    if (logfile) fprintf(logfile,str,ndelete,atom->natoms);
   }
 }
 
 /* ----------------------------------------------------------------------
    delete all atoms in group
    group will still exist
 ------------------------------------------------------------------------- */
 
 void DeleteAtoms::delete_group(int narg, char **arg)
 {
   if (narg < 2) error->all("Illegal delete_atoms command");
 
   int igroup = group->find(arg[1]);
   if (igroup == -1) error->all("Could not find delete_atoms group ID");
   options(narg-2,&arg[2]);
 
   // allocate and initialize deletion list
   
   int nlocal = atom->nlocal;
   dlist = (int *) memory->smalloc(nlocal*sizeof(int),"delete_atoms:dlist");
   for (int i = 0; i < nlocal; i++) dlist[i] = 0;
 
   int *mask = atom->mask;
   int groupbit = group->bitmask[igroup];
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) dlist[i] = 1;
 }
 
 /* ----------------------------------------------------------------------
    delete all atoms in region
 ------------------------------------------------------------------------- */
 
 void DeleteAtoms::delete_region(int narg, char **arg)
 {
   if (narg < 2) error->all("Illegal delete_atoms command");
   
   int iregion = domain->find_region(arg[1]);
   if (iregion == -1) error->all("Could not find delete_atoms region ID");
   options(narg-2,&arg[2]);
 
   // allocate and initialize deletion list
   
   int nlocal = atom->nlocal;
   dlist = (int *) memory->smalloc(nlocal*sizeof(int),"delete_atoms:dlist");
   for (int i = 0; i < nlocal; i++) dlist[i] = 0;
 
   double **x = atom->x;
 
   for (int i = 0; i < nlocal; i++)
     if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2])) dlist[i] = 1;
 }
 
 /* ----------------------------------------------------------------------
    delete atoms so there are no pairs within cutoff
    which atoms are deleted depends on ordering of atoms within proc
    deletions can vary with processor count
    no guarantee that minimium number of atoms will be deleted
 ------------------------------------------------------------------------- */
 
 void DeleteAtoms::delete_overlap(int narg, char **arg)
 {
   if (narg < 4) error->all("Illegal delete_atoms command");
     
   // read args
 
   double cut = atof(arg[1]);
   double cutsq = cut*cut;
 
   int igroup1 = group->find(arg[2]);
   int igroup2 = group->find(arg[3]);
   if (igroup1 < 0 || igroup2 < 0)
     error->all("Could not find delete_atoms group ID");
   options(narg-4,&arg[4]);
 
   int group1bit = group->bitmask[igroup1];
   int group2bit = group->bitmask[igroup2];
 
   if (comm->me == 0 && screen)
     fprintf(screen,"System init for delete_atoms ...\n");
 
   // request a full neighbor list for use by this command
 
   int irequest = neighbor->request((void *) this);
   neighbor->requests[irequest]->pair = 0;
   neighbor->requests[irequest]->command = 1;
   neighbor->requests[irequest]->half = 0;
   neighbor->requests[irequest]->full = 1;
   neighbor->requests[irequest]->occasional = 1;
 
   // init entire system since comm->borders and neighbor->build is done
   // comm::init needs neighbor::init needs pair::init needs kspace::init, etc
   
   lmp->init();
 
   // error check on cutoff
   // if no pair style, neighbor list will be empty
 
   if (force->pair == NULL)
     error->all("Delete_atoms requires a pair style be defined");
   if (cut > neighbor->cutneighmax) 
     error->all("Delete_atoms cutoff > neighbor cutoff");
 
   // setup domain, communication and neighboring
   // acquire ghosts
   // build neighbor list based on earlier request
 
   if (domain->triclinic) domain->x2lamda(atom->nlocal);
   domain->pbc();
   domain->reset_box();
   comm->setup();
   if (neighbor->style) neighbor->setup_bins();
   comm->exchange();
   comm->borders();
   if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
 
   NeighList *list = neighbor->lists[irequest];
   neighbor->build_one(irequest);
 
   // allocate and initialize deletion list
   // must be after exchange potentially changes nlocal
   
   int nlocal = atom->nlocal;
   dlist = (int *) memory->smalloc(nlocal*sizeof(int),"delete_atoms:dlist");
   for (int i = 0; i < nlocal; i++) dlist[i] = 0;
 
   // double loop over owned atoms and their full neighbor list
   // at end of loop, there are no more overlaps
   // only ever delete owned atom I, never J even if owned
 
   int *tag = atom->tag;
   int *mask = atom->mask;
   double **x = atom->x;
   int nall = atom->nlocal + atom->nghost;
   double *special_coul = force->special_coul;
   double *special_lj = force->special_lj;
 
   int i,j,ii,jj,inum,jnum;
   double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
   int *ilist,*jlist,*numneigh,**firstneigh;
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
 
   for (ii = 0; ii < inum; ii++) {
     i = ilist[ii];
     xtmp = x[i][0];
     ytmp = x[i][1];
     ztmp = x[i][2];
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
 
       // if weighting factors are 0, skip this pair
       // could be 0 and still be in neigh list for long-range Coulombics
       // want consistency with non-charged pairs which wouldn't be in list
 
       if (j >= nall) {
 	if (special_coul[j/nall] == 0.0 && special_lj[j/nall] == 0.0) continue;
 	j %= nall;
       }
 
       // only consider deletion if I,J distance < cutoff
 
       delx = xtmp - x[j][0];
       dely = ytmp - x[j][1];
       delz = ztmp - x[j][2];
       rsq = delx*delx + dely*dely + delz*delz;
       if (rsq >= cutsq) continue;
 
       // only consider deletion if I,J are in groups 1,2 respectively
       // true whether J is owned or ghost atom
 
       if (!(mask[i] & group1bit)) continue;
       if (!(mask[j] & group2bit)) continue;
 
       // J is owned atom:
       //   delete atom I if atom J has not already been deleted
       // J is ghost atom:
       //   delete atom I if J,I is not a candidate deletion pair
       //     due to being in groups 1,2 respectively
       //   if they are candidate pair, then either:
       //      another proc owns J and could delete J
       //      J is a ghost of another of my owned atoms, and I could delete J
       //   test on tags of I,J insures that only I or J is deleted
 
       if (j < nlocal) {
 	if (dlist[j]) continue;
       } else if ((mask[i] & group2bit) && (mask[j] & group1bit)) {
 	if (tag[i] > tag[j]) continue;
       }
 
       dlist[i] = 1;
       break;
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    create porosity by deleting atoms in a specified region 
 ------------------------------------------------------------------------- */
 
 void DeleteAtoms::delete_porosity(int narg, char **arg)
 {
   if (narg < 4) error->all("Illegal delete_atoms command");
 
   int iregion = domain->find_region(arg[1]);
   if (iregion == -1) error->all("Could not find delete_atoms region ID");
 
   double porosity_fraction = atof(arg[2]);
   int seed = atoi(arg[3]);
   options(narg-4,&arg[4]);
 
   RanMars *random = new RanMars(lmp,seed + comm->me);
 
   // allocate and initialize deletion list
  
   int nlocal = atom->nlocal;
   dlist = (int *) memory->smalloc(nlocal*sizeof(int),"delete_atoms:dlist");
   for (int i = 0; i < nlocal; i++) dlist[i] = 0;
 
   double **x = atom->x;
 
   for (int i = 0; i < nlocal; i++)
     if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
       if (random->uniform() <= porosity_fraction) dlist[i] = 1;
 }
 
 /* ----------------------------------------------------------------------
    process command options
 ------------------------------------------------------------------------- */
 
 void DeleteAtoms::options(int narg, char **arg)
 {
   compress_flag = 1;
 
   int iarg = 0;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"compress") == 0) {
       if (iarg+2 > narg) error->all("Illegal delete_bonds command");
       if (strcmp(arg[iarg+1],"yes") == 0) compress_flag = 1;
       else if (strcmp(arg[iarg+1],"no") == 0) compress_flag = 0;
       else error->all("Illegal delete_bonds command");
       iarg += 2;
     } else error->all("Illegal delete_bonds command");
   }
 }
diff --git a/src/delete_bonds.cpp b/src/delete_bonds.cpp
index b2c80cd8f..0b1ff6dae 100644
--- a/src/delete_bonds.cpp
+++ b/src/delete_bonds.cpp
@@ -1,486 +1,486 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "string.h"
 #include "delete_bonds.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "domain.h"
 #include "neighbor.h"
 #include "comm.h"
 #include "force.h"
 #include "group.h"
 #include "special.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{MULTI,ATOM,BOND,ANGLE,DIHEDRAL,IMPROPER,STATS};
 
 /* ---------------------------------------------------------------------- */
 
 DeleteBonds::DeleteBonds(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 void DeleteBonds::command(int narg, char **arg)
 {
   if (domain->box_exist == 0) 
     error->all("Delete_bonds command before simulation box is defined");
   if (atom->natoms == 0)
     error->all("Delete_bonds command with no atoms existing");
   if (atom->molecular == 0)
     error->all("Cannot use delete_bonds with non-molecular system");
   if (narg < 2) error->all("Illegal delete_bonds command");
 
   // init entire system since comm->borders is done
   // comm::init needs neighbor::init needs pair::init needs kspace::init, etc
 
   if (comm->me == 0 && screen)
     fprintf(screen,"System init for delete_bonds ...\n");
   lmp->init();
 
   if (comm->me == 0 && screen) fprintf(screen,"Deleting bonds ...\n");
 
   // identify group
 
   int igroup = group->find(arg[0]);
   if (igroup == -1) error->all("Cannot find delete_bonds group ID");
   int groupbit = group->bitmask[igroup];
   
   // set style and which = type value
 
   int style;
   if (strcmp(arg[1],"multi") == 0) style = MULTI;
   else if (strcmp(arg[1],"atom") == 0) style = ATOM;
   else if (strcmp(arg[1],"bond") == 0) style = BOND;
   else if (strcmp(arg[1],"angle") == 0) style = ANGLE;
   else if (strcmp(arg[1],"dihedral") == 0) style = DIHEDRAL;
   else if (strcmp(arg[1],"improper") == 0) style = IMPROPER;
   else if (strcmp(arg[1],"stats") == 0) style = STATS;
   else error->all("Illegal delete_bonds command");
 
   int iarg = 2;
   int which;
   if (style != MULTI && style != STATS) {
     if (narg < 3) error->all("Illegal delete_bonds command");
     which = atoi(arg[2]);
     iarg++;
   }
 
   // grab optional keywords
 
   int undo_flag = 0;
   int remove_flag = 0;
   int special_flag = 0;
 
   while (iarg < narg) {
     if (strcmp(arg[iarg],"undo") == 0) undo_flag = 1;
     else if (strcmp(arg[iarg],"remove") == 0) remove_flag = 1;
     else if (strcmp(arg[iarg],"special") == 0) special_flag = 1;
     else error->all("Illegal delete_bonds command");
     iarg++;
   }
 
   // border swap to insure type and mask is current for off-proc atoms
   // enforce PBC before in case atoms are outside box
 
   if (domain->triclinic) domain->x2lamda(atom->nlocal);
   domain->pbc();
   domain->reset_box();
   comm->setup();
   comm->exchange();
   comm->borders();
   if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
 
   // set topology interactions either off or on
   // criteria for an interaction to potentially be changed (set flag = 1)
   //   all atoms in interaction must be in group
   //   for style = MULTI, no other criteria
   //   for style = ATOM, at least one atom is specified type
   //   for style = BOND/ANGLE/DIHEDRAL/IMPROPER, interaction is specified type
   //   for style = STATS only compute stats, flag is always 0
   // if flag = 1
   //   set interaction type negative if undo_flag = 0
   //   set interaction type positive if undo_flag = 1
 
   int *mask = atom->mask;
   int *type = atom->type;
   int nlocal = atom->nlocal;
 
   int i,m,n,flag;
   int atom1,atom2,atom3,atom4;
 
   if (atom->avec->bonds_allow) {
     int *num_bond = atom->num_bond;
     int **bond_type = atom->bond_type;
 
     for (i = 0; i < nlocal; i++) {
       for (m = 0; m < num_bond[i]; m++) {
 	atom1 = atom->map(atom->bond_atom[i][m]);
 	if (atom1 == -1) error->one("Bond atom missing in delete_bonds");
 	if (mask[i] & groupbit && mask[atom1] & groupbit) {
 	  flag = 0;
 	  if (style == MULTI) flag = 1;
 	  if (style == ATOM && 
 	      (type[i] == which || type[atom1] == which)) flag = 1;
 	  if (style == BOND && (bond_type[i][m] == which)) flag = 1;
 	  if (flag) {
 	    if (undo_flag == 0 && bond_type[i][m] > 0)
 	      bond_type[i][m] = -bond_type[i][m]; 
 	    if (undo_flag == 1 && bond_type[i][m] < 0)
 	      bond_type[i][m] = -bond_type[i][m]; 
 	  }
 	}
       }
     }
   }
 
   if (atom->avec->angles_allow) {
     int *num_angle = atom->num_angle;
     int **angle_type = atom->angle_type;
 
     for (i = 0; i < nlocal; i++) {
       for (m = 0; m < num_angle[i]; m++) {
 	atom1 = atom->map(atom->angle_atom1[i][m]);
 	atom2 = atom->map(atom->angle_atom2[i][m]);
 	atom3 = atom->map(atom->angle_atom3[i][m]);
 	if (atom1 == -1 || atom2 == -1 || atom3 == -1)
 	  error->one("Angle atom missing in delete_bonds");
 	if (mask[atom1] & groupbit && mask[atom2] & groupbit &&
 	    mask[atom3] & groupbit) {
 	  flag = 0;
 	  if (style == MULTI) flag = 1;
 	  if (style == ATOM && 
 	      (type[atom1] == which || type[atom2] == which ||
 	       type[atom3] == which)) flag = 1;
 	  if (style == ANGLE && (angle_type[i][m] == which)) flag = 1;
 	  if (flag) {
 	    if (undo_flag == 0 && angle_type[i][m] > 0)
 	      angle_type[i][m] = -angle_type[i][m]; 
 	    if (undo_flag == 1 && angle_type[i][m] < 0)
 	      angle_type[i][m] = -angle_type[i][m]; 
 	  }
 	}
       }
     }
   }
 
   if (atom->avec->dihedrals_allow) {
     int *num_dihedral = atom->num_dihedral;
     int **dihedral_type = atom->dihedral_type;
 
     for (i = 0; i < nlocal; i++) {
       for (m = 0; m < num_dihedral[i]; m++) {
 	atom1 = atom->map(atom->dihedral_atom1[i][m]);
 	atom2 = atom->map(atom->dihedral_atom2[i][m]);
 	atom3 = atom->map(atom->dihedral_atom3[i][m]);
 	atom4 = atom->map(atom->dihedral_atom4[i][m]);
 	if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1)
 	  error->one("Dihedral atom missing in delete_bonds");
 	if (mask[atom1] & groupbit && mask[atom2] & groupbit &&
 	    mask[atom3] & groupbit && mask[atom4] & groupbit) {
 	  flag = 0;
 	  if (style == MULTI) flag = 1;
 	  if (style == ATOM && 
 	      (type[atom1] == which || type[atom2] == which ||
 	       type[atom3] == which || type[atom4] == which)) flag = 1;
 	  if (style == DIHEDRAL && (dihedral_type[i][m] == which)) flag = 1;
 	  if (flag) {
 	    if (undo_flag == 0 && dihedral_type[i][m] > 0)
 	      dihedral_type[i][m] = -dihedral_type[i][m]; 
 	    if (undo_flag == 1 && dihedral_type[i][m] < 0)
 	      dihedral_type[i][m] = -dihedral_type[i][m]; 
 	  }
 	}
       }
     }
   }
 
   if (atom->avec->impropers_allow) {
     int *num_improper = atom->num_improper;
     int **improper_type = atom->improper_type;
 
     for (i = 0; i < nlocal; i++) {
       for (m = 0; m < num_improper[i]; m++) {
 	atom1 = atom->map(atom->improper_atom1[i][m]);
 	atom2 = atom->map(atom->improper_atom2[i][m]);
 	atom3 = atom->map(atom->improper_atom3[i][m]);
 	atom4 = atom->map(atom->improper_atom4[i][m]);
 	if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1)
 	  error->one("Improper atom missing in delete_bonds");
 	if (mask[atom1] & groupbit && mask[atom2] & groupbit &&
 	    mask[atom3] & groupbit && mask[atom4] & groupbit) {
 	  flag = 0;
 	  if (style == MULTI) flag = 1;
 	  if (style == ATOM && 
 	      (type[atom1] == which || type[atom2] == which ||
 	       type[atom3] == which || type[atom4] == which)) flag = 1;
 	  if (style == IMPROPER && (improper_type[i][m] == which)) flag = 1;
 	  if (flag) {
 	    if (undo_flag == 0 && improper_type[i][m] > 0)
 	      improper_type[i][m] = -improper_type[i][m]; 
 	    if (undo_flag == 1 && improper_type[i][m] < 0)
 	      improper_type[i][m] = -improper_type[i][m]; 
 	  }
 	}
       }
     }
   }
 
   // remove interactions if requested
   // only if all atoms in bond, angle, etc are in the delete_bonds group
 
   if (remove_flag) {
 
     if (atom->avec->bonds_allow) {
       for (i = 0; i < nlocal; i++) {
 	m = 0;
 	while (m < atom->num_bond[i]) {
 	  if (atom->bond_type[i][m] <= 0) {
 	    atom1 = atom->map(atom->bond_atom[i][m]);
 	    if (mask[i] & groupbit && mask[atom1] & groupbit) {
 	      n = atom->num_bond[i];
 	      atom->bond_type[i][m] = atom->bond_type[i][n-1];
 	      atom->bond_atom[i][m] = atom->bond_atom[i][n-1];
 	      atom->num_bond[i]--;
 	    } else m++;
 	  } else m++;
 	}
       }
     }
 
     if (atom->avec->angles_allow) {
       for (i = 0; i < nlocal; i++) {
 	m = 0;
 	while (m < atom->num_angle[i]) {
 	  if (atom->angle_type[i][m] <= 0) {
 	    atom1 = atom->map(atom->angle_atom1[i][m]);
 	    atom2 = atom->map(atom->angle_atom2[i][m]);
 	    atom3 = atom->map(atom->angle_atom3[i][m]);
 	    if (mask[atom1] & groupbit && mask[atom2] & groupbit &&
 		mask[atom3] & groupbit) {
 	      n = atom->num_angle[i];
 	      atom->angle_type[i][m] = atom->angle_type[i][n-1];
 	      atom->angle_atom1[i][m] = atom->angle_atom1[i][n-1];
 	      atom->angle_atom2[i][m] = atom->angle_atom2[i][n-1];
 	      atom->angle_atom3[i][m] = atom->angle_atom3[i][n-1];
 	      atom->num_angle[i]--;
 	    } else m++;
 	  } else m++;
 	}
       }
     }
 
     if (atom->avec->dihedrals_allow) {
       for (i = 0; i < nlocal; i++) {
 	m = 0;
 	while (m < atom->num_dihedral[i]) {
 	  if (atom->dihedral_type[i][m] <= 0) {
 	    atom1 = atom->map(atom->dihedral_atom1[i][m]);
 	    atom2 = atom->map(atom->dihedral_atom2[i][m]);
 	    atom3 = atom->map(atom->dihedral_atom3[i][m]);
 	    atom4 = atom->map(atom->dihedral_atom4[i][m]);
 	    if (mask[atom1] & groupbit && mask[atom2] & groupbit &&
 		mask[atom3] & groupbit && mask[atom4] & groupbit) {
 	      n = atom->num_dihedral[i];
 	      atom->dihedral_type[i][m] = atom->dihedral_type[i][n-1];
 	      atom->dihedral_atom1[i][m] = atom->dihedral_atom1[i][n-1];
 	      atom->dihedral_atom2[i][m] = atom->dihedral_atom2[i][n-1];
 	      atom->dihedral_atom3[i][m] = atom->dihedral_atom3[i][n-1];
 	      atom->dihedral_atom4[i][m] = atom->dihedral_atom4[i][n-1];
 	      atom->num_dihedral[i]--;
 	    } else m++;
 	  } else m++;
 	}
       }
     }
 
     if (atom->avec->impropers_allow) {
       for (i = 0; i < nlocal; i++) {
 	m = 0;
 	while (m < atom->num_improper[i]) {
 	  if (atom->improper_type[i][m] <= 0) {
 	    atom1 = atom->map(atom->improper_atom1[i][m]);
 	    atom2 = atom->map(atom->improper_atom2[i][m]);
 	    atom3 = atom->map(atom->improper_atom3[i][m]);
 	    atom4 = atom->map(atom->improper_atom4[i][m]);
 	    if (mask[atom1] & groupbit && mask[atom2] & groupbit &&
 		mask[atom3] & groupbit && mask[atom4] & groupbit) {
 	      n = atom->num_improper[i];
 	      atom->improper_type[i][m] = atom->improper_type[i][n-1];
 	      atom->improper_atom1[i][m] = atom->improper_atom1[i][n-1];
 	      atom->improper_atom2[i][m] = atom->improper_atom2[i][n-1];
 	      atom->improper_atom3[i][m] = atom->improper_atom3[i][n-1];
 	      atom->improper_atom4[i][m] = atom->improper_atom4[i][n-1];
 	      atom->num_improper[i]--;
 	    } else m++;
 	  } else m++;
 	}
       }
     }
 
   }
 
   // if interactions were removed, recompute global counts
 
   if (remove_flag) {
 
     if (atom->avec->bonds_allow) {
       bigint nbonds = 0;
       for (i = 0; i < nlocal; i++) nbonds += atom->num_bond[i];
-      MPI_Allreduce(&nbonds,&atom->nbonds,1,MPI_UNSIGNED_LONG_LONG,
+      MPI_Allreduce(&nbonds,&atom->nbonds,1,MPI_LMP_BIGINT,
 		    MPI_SUM,world);
       if (force->newton_bond == 0) atom->nbonds /= 2;
     }
 
     if (atom->avec->angles_allow) {
       bigint nangles = 0;
       for (i = 0; i < nlocal; i++) nangles += atom->num_angle[i];
-      MPI_Allreduce(&nangles,&atom->nangles,1,MPI_UNSIGNED_LONG_LONG,
+      MPI_Allreduce(&nangles,&atom->nangles,1,MPI_LMP_BIGINT,
 		    MPI_SUM,world);
       if (force->newton_bond == 0) atom->nangles /= 3;
     }
 
     if (atom->avec->dihedrals_allow) {
       bigint ndihedrals = 0;
       for (i = 0; i < nlocal; i++) ndihedrals += atom->num_dihedral[i];
       MPI_Allreduce(&ndihedrals,&atom->ndihedrals,
-		    1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+		    1,MPI_LMP_BIGINT,MPI_SUM,world);
       if (force->newton_bond == 0) atom->ndihedrals /= 4;
     }
 
     if (atom->avec->impropers_allow) {
       bigint nimpropers = 0;
       for (i = 0; i < nlocal; i++) nimpropers += atom->num_improper[i];
       MPI_Allreduce(&nimpropers,&atom->nimpropers,
-		    1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+		    1,MPI_LMP_BIGINT,MPI_SUM,world);
       if (force->newton_bond == 0) atom->nimpropers /= 4;
     }
 
   }
 
   // compute and print stats
 
   bigint tmp;
   bigint bond_on,bond_off;
   bigint angle_on,angle_off;
   bigint dihedral_on,dihedral_off;
   bigint improper_on,improper_off;
 
   if (atom->avec->bonds_allow) {
     bond_on = bond_off = 0;
     for (i = 0; i < nlocal; i++)
       for (m = 0; m < atom->num_bond[i]; m++)
 	if (atom->bond_type[i][m] > 0) bond_on++;
 	else bond_off++;
-    MPI_Allreduce(&bond_on,&tmp,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+    MPI_Allreduce(&bond_on,&tmp,1,MPI_LMP_BIGINT,MPI_SUM,world);
     bond_on = tmp;
-    MPI_Allreduce(&bond_off,&tmp,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+    MPI_Allreduce(&bond_off,&tmp,1,MPI_LMP_BIGINT,MPI_SUM,world);
     bond_off = tmp;
     if (force->newton_bond == 0) {
       bond_on /= 2;
       bond_off /= 2;
     }
   }
 
   if (atom->avec->angles_allow) {
     angle_on = angle_off = 0;
     for (i = 0; i < nlocal; i++)
       for (m = 0; m < atom->num_angle[i]; m++)
 	if (atom->angle_type[i][m] > 0) angle_on++;
 	else angle_off++;
-    MPI_Allreduce(&angle_on,&tmp,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+    MPI_Allreduce(&angle_on,&tmp,1,MPI_LMP_BIGINT,MPI_SUM,world);
     angle_on = tmp;
-    MPI_Allreduce(&angle_off,&tmp,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+    MPI_Allreduce(&angle_off,&tmp,1,MPI_LMP_BIGINT,MPI_SUM,world);
     angle_off = tmp;
     if (force->newton_bond == 0) {
       angle_on /= 3;
       angle_off /= 3;
     }
   }
 
   if (atom->avec->dihedrals_allow) {
     dihedral_on = dihedral_off = 0;
     for (i = 0; i < nlocal; i++)
       for (m = 0; m < atom->num_dihedral[i]; m++)
 	if (atom->dihedral_type[i][m] > 0) dihedral_on++;
 	else dihedral_off++;
-    MPI_Allreduce(&dihedral_on,&tmp,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+    MPI_Allreduce(&dihedral_on,&tmp,1,MPI_LMP_BIGINT,MPI_SUM,world);
     dihedral_on = tmp;
-    MPI_Allreduce(&dihedral_off,&tmp,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+    MPI_Allreduce(&dihedral_off,&tmp,1,MPI_LMP_BIGINT,MPI_SUM,world);
     dihedral_off = tmp;
     if (force->newton_bond == 0) {
       dihedral_on /= 4;
       dihedral_off /= 4;
     }
   }
 
   if (atom->avec->impropers_allow) {
     improper_on = improper_off = 0;
     for (i = 0; i < nlocal; i++)
       for (m = 0; m < atom->num_improper[i]; m++)
 	if (atom->improper_type[i][m] > 0) improper_on++;
 	else improper_off++;
-    MPI_Allreduce(&improper_on,&tmp,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+    MPI_Allreduce(&improper_on,&tmp,1,MPI_LMP_BIGINT,MPI_SUM,world);
     improper_on = tmp;
-    MPI_Allreduce(&improper_off,&tmp,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+    MPI_Allreduce(&improper_off,&tmp,1,MPI_LMP_BIGINT,MPI_SUM,world);
     improper_off = tmp;
     if (force->newton_bond == 0) {
       improper_on /= 4;
       improper_off /= 4;
     }
   }
 
   if (comm->me == 0) {
-    if (screen) {
-      if (atom->avec->bonds_allow)
-	fprintf(screen,"  %lu total bonds, %lu turned on, %lu turned off\n",
-		atom->nbonds,bond_on,bond_off);
-      if (atom->avec->angles_allow)
-	fprintf(screen,"  %lu total angles, %lu turned on, %lu turned off\n",
-		atom->nangles,angle_on,angle_off);
-      if (atom->avec->dihedrals_allow)
-	fprintf(screen,"  %lu total dihedrals, %lu turned on, %lu turned off\n",
-		atom->ndihedrals,dihedral_on,dihedral_off);
-      if (atom->avec->impropers_allow)
-	fprintf(screen,"  %lu total impropers, %lu turned on, %lu turned off\n",
-		atom->nimpropers,improper_on,improper_off);
+    if (atom->avec->bonds_allow) {
+      char str[128];
+      sprintf(str,"  %s total bonds, %s turned on, %s turned off\n",
+	      BIGINT_FORMAT,BIGINT_FORMAT,BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->nbonds,bond_on,bond_off);
+      if (logfile) fprintf(logfile,str,atom->nbonds,bond_on,bond_off);
+    }
+    if (atom->avec->angles_allow) {
+      char str[128];
+      sprintf(str,"  %s total angles, %s turned on, %s turned off\n",
+	      BIGINT_FORMAT,BIGINT_FORMAT,BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->nangles,angle_on,angle_off);
+      if (logfile) fprintf(logfile,str,atom->nangles,angle_on,angle_off);
     }
-    if (logfile) {
-      if (atom->avec->bonds_allow)
-	fprintf(logfile,"  %lu total bonds, %lu turned on, %lu turned off\n",
-		atom->nbonds,bond_on,bond_off);
-      if (atom->avec->angles_allow)
-	fprintf(logfile,"  %lu total angles, %lu turned on, %lu turned off\n",
-		atom->nangles,angle_on,angle_off);
-      if (atom->avec->dihedrals_allow)
-	fprintf(logfile,"  %lu total dihedrals, %lu turned on, "
-		"%lu turned off\n",
-		atom->ndihedrals,dihedral_on,dihedral_off);
-      if (atom->avec->impropers_allow)
-	fprintf(logfile,"  %lu total impropers, %lu turned on, "
-		"%lu turned off\n",
-		atom->nimpropers,improper_on,improper_off);
+    if (atom->avec->dihedrals_allow) {
+      char str[128];
+      sprintf(str,"  %s total dihedrals, %s turned on, %s turned off\n",
+	      BIGINT_FORMAT,BIGINT_FORMAT,BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->ndihedrals,dihedral_on,dihedral_off);
+      if (logfile) fprintf(logfile,str,
+			   atom->ndihedrals,dihedral_on,dihedral_off);
+    }
+    if (atom->avec->impropers_allow) {
+      char str[128];
+      sprintf(str,"  %s total impropers, %s turned on, %s turned off\n",
+	      BIGINT_FORMAT,BIGINT_FORMAT,BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->nimpropers,improper_on,improper_off);
+      if (logfile) fprintf(logfile,str,
+			   atom->nimpropers,improper_on,improper_off);
     }
   }
 
   // re-compute special list if requested
 
   if (special_flag) {
     Special special(lmp);
     special.build();
   }
 }
diff --git a/src/displace_atoms.cpp b/src/displace_atoms.cpp
index 4a9be6df2..1e93c919b 100644
--- a/src/displace_atoms.cpp
+++ b/src/displace_atoms.cpp
@@ -1,243 +1,244 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "string.h"
 #include "displace_atoms.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "modify.h"
 #include "domain.h"
 #include "lattice.h"
 #include "comm.h"
 #include "irregular.h"
 #include "group.h"
 #include "random_park.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{MOVE,RAMP,RANDOM};
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 /* ---------------------------------------------------------------------- */
 
 DisplaceAtoms::DisplaceAtoms(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 void DisplaceAtoms::command(int narg, char **arg)
 {
   int i;
 
   if (domain->box_exist == 0) 
     error->all("Displace_atoms command before simulation box is defined");
   if (narg < 2) error->all("Illegal displace_atoms command");
   if (modify->nfix_restart_peratom) 
     error->all("Cannot displace_atoms after "
 	       "reading restart file with per-atom info");
 
   if (comm->me == 0 && screen) fprintf(screen,"Displacing atoms ...\n");
 
   // group and style
 
   int igroup = group->find(arg[0]);
   if (igroup == -1) error->all("Could not find displace_atoms group ID");
   int groupbit = group->bitmask[igroup];
 
   int style;
   if (strcmp(arg[1],"move") == 0) style = MOVE;
   else if (strcmp(arg[1],"ramp") == 0) style = RAMP;
   else if (strcmp(arg[1],"random") == 0) style = RANDOM;
   else error->all("Illegal displace_atoms command");
 
   // set option defaults
 
   scaleflag = 1;
 
   // read options from end of input line
 
   if (style == MOVE) options(narg-5,&arg[5]);
   else if (style == RAMP) options(narg-8,&arg[8]);
   else if (style == RANDOM) options(narg-6,&arg[6]);
 
   // setup scaling
 
   if (scaleflag && domain->lattice == NULL)
     error->all("Use of displace_atoms with undefined lattice");
 
   double xscale,yscale,zscale;
   if (scaleflag) {
     xscale = domain->lattice->xlattice;
     yscale = domain->lattice->ylattice;
     zscale = domain->lattice->zlattice;
   }
   else xscale = yscale = zscale = 1.0;
 
   // move atoms by 3-vector
 
   if (style == MOVE) {
 
     double delx = xscale*atof(arg[2]);
     double dely = yscale*atof(arg[3]);
     double delz = zscale*atof(arg[4]);
 
     double **x = atom->x;
     int *mask = atom->mask;
     int nlocal = atom->nlocal;
 
     for (i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
 	x[i][0] += delx;
 	x[i][1] += dely;
 	x[i][2] += delz;
       }
     }
   }
 
   // move atoms in ramped fashion
     
   if (style == RAMP) {
 
     int d_dim;
     if (strcmp(arg[2],"x") == 0) d_dim = 0;
     else if (strcmp(arg[2],"y") == 0) d_dim = 1;
     else if (strcmp(arg[2],"z") == 0) d_dim = 2;
     else error->all("Illegal displace_atoms ramp command");
 
     double d_lo,d_hi;
     if (d_dim == 0) {
       d_lo = xscale*atof(arg[3]);
       d_hi = xscale*atof(arg[4]);
     } else if (d_dim == 1) {
       d_lo = yscale*atof(arg[3]);
       d_hi = yscale*atof(arg[4]);
     } else if (d_dim == 2) {
       d_lo = zscale*atof(arg[3]);
       d_hi = zscale*atof(arg[4]);
     }
 
     int coord_dim;
     if (strcmp(arg[5],"x") == 0) coord_dim = 0;
     else if (strcmp(arg[5],"y") == 0) coord_dim = 1;
     else if (strcmp(arg[5],"z") == 0) coord_dim = 2;
     else error->all("Illegal displace_atoms ramp command");
 
     double coord_lo,coord_hi;
     if (coord_dim == 0) {
       coord_lo = xscale*atof(arg[6]);
       coord_hi = xscale*atof(arg[7]);
     } else if (coord_dim == 1) {
       coord_lo = yscale*atof(arg[6]);
       coord_hi = yscale*atof(arg[7]);
     } else if (coord_dim == 2) {
       coord_lo = zscale*atof(arg[6]);
       coord_hi = zscale*atof(arg[7]);
     }
 
     double **x = atom->x;
     int *mask = atom->mask;
     int nlocal = atom->nlocal;
 
     double fraction,dramp;
 
     for (i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
 	fraction = (x[i][coord_dim] - coord_lo) / (coord_hi - coord_lo);
 	fraction = MAX(fraction,0.0);
 	fraction = MIN(fraction,1.0);
 	dramp = d_lo + fraction*(d_hi - d_lo);
 	x[i][d_dim] += dramp;
       }
     }
   }
 
   // move atoms randomly
   // makes atom result independent of what proc owns it via random->reset()
     
   if (style == RANDOM) {
     RanPark *random = new RanPark(lmp,1);
 
     double dx = xscale*atof(arg[2]);
     double dy = yscale*atof(arg[3]);
     double dz = zscale*atof(arg[4]);
     int seed = atoi(arg[5]);
     if (seed <= 0) error->all("Illegal displace_atoms random command");
 
     double **x = atom->x;
     int *mask = atom->mask;
     int nlocal = atom->nlocal;
 
     for (i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
 	random->reset(seed,x[i]);
 	x[i][0] += dx * 2.0*(random->uniform()-0.5);
 	x[i][1] += dy * 2.0*(random->uniform()-0.5);
 	x[i][2] += dz * 2.0*(random->uniform()-0.5);
       }
     }
 
     delete random;
   }
 
   // move atoms back inside simulation box and to new processors
   // use remap() instead of pbc() in case atoms moved a long distance
   // use irregular() in case atoms moved a long distance
 
   double **x = atom->x;
   int *image = atom->image;
   int nlocal = atom->nlocal;
   for (i = 0; i < nlocal; i++) domain->remap(x[i],image[i]);
 
   if (domain->triclinic) domain->x2lamda(atom->nlocal);
   domain->reset_box();
   Irregular *irregular = new Irregular(lmp);
   irregular->migrate_atoms();
   delete irregular;
   if (domain->triclinic) domain->lamda2x(atom->nlocal);
 
   // check if any atoms were lost
 
   bigint natoms;
   bigint nblocal = atom->nlocal;
-  MPI_Allreduce(&nblocal,&natoms,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&nblocal,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
   if (natoms != atom->natoms) {
-    char str[128];
-    sprintf(str,"Lost atoms via displace_atoms: original %lu current %lu",
-	    atom->natoms,natoms);
+    char fstr[64],str[128];
+    sprintf(fstr,"Lost atoms via displace_atoms: original %s current %s",
+	    BIGINT_FORMAT,BIGINT_FORMAT);
+    sprintf(str,fstr,atom->natoms,natoms);
     error->all(str);
   }
 }
 
 /* ----------------------------------------------------------------------
    parse optional parameters at end of displace_atoms input line 
 ------------------------------------------------------------------------- */
 
 void DisplaceAtoms::options(int narg, char **arg)
 {
   if (narg < 0) error->all("Illegal displace_atoms command");
 
   int iarg = 0;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"units") == 0) {
       if (iarg+2 > narg) error->all("Illegal displace_atoms command");
       if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
       else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
       else error->all("Illegal displace_atoms command");
       iarg += 2;
     } else error->all("Illegal displace_atoms command");
   }
 }
diff --git a/src/displace_box.cpp b/src/displace_box.cpp
index 33d1a3137..e80ddbbd3 100644
--- a/src/displace_box.cpp
+++ b/src/displace_box.cpp
@@ -1,418 +1,419 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "displace_box.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "modify.h"
 #include "domain.h"
 #include "lattice.h"
 #include "comm.h"
 #include "irregular.h"
 #include "group.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{NONE,FINAL,DELTA,SCALE,VOLUME};
 enum{ONE_FROM_ONE,ONE_FROM_TWO,TWO_FROM_ONE};
 enum{NO_REMAP,X_REMAP};
 
 /* ---------------------------------------------------------------------- */
 
 DisplaceBox::DisplaceBox(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 void DisplaceBox::command(int narg, char **arg)
 {
   int i;
 
   if (domain->box_exist == 0) 
     error->all("Displace_box command before simulation box is defined");
   if (narg < 2) error->all("Illegal displace_box command");
   if (modify->nfix_restart_peratom) 
     error->all("Cannot displace_box after "
 	       "reading restart file with per-atom info");
 
   if (comm->me == 0 && screen) fprintf(screen,"Displacing box ...\n");
 
   // group
 
   int igroup = group->find(arg[0]);
   if (igroup == -1) error->all("Could not find displace_box group ID");
   int groupbit = group->bitmask[igroup];
 
   // set defaults
 
   set = new Set[6];
   set[0].style = set[1].style = set[2].style = 
     set[3].style = set[4].style = set[5].style = NONE;
 
   // parse arguments
 
   int triclinic = domain->triclinic;
 
   int index;
   int iarg = 1;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"x") == 0 || strcmp(arg[iarg],"y") == 0 ||
 	strcmp(arg[iarg],"z") == 0) {
       if (strcmp(arg[iarg],"x") == 0) index = 0;
       else if (strcmp(arg[iarg],"y") == 0) index = 1;
       else if (strcmp(arg[iarg],"z") == 0) index = 2;
 
       if (iarg+2 > narg) error->all("Illegal displace_box command");
       if (strcmp(arg[iarg+1],"final") == 0) {
 	if (iarg+4 > narg) error->all("Illegal displace_box command");
 	set[index].style = FINAL;
 	set[index].flo = atof(arg[iarg+2]);
 	set[index].fhi = atof(arg[iarg+3]);
 	iarg += 4;
       } else if (strcmp(arg[iarg+1],"delta") == 0) {
 	if (iarg+4 > narg) error->all("Illegal displace_box command");
 	set[index].style = DELTA;
 	set[index].dlo = atof(arg[iarg+2]);
 	set[index].dhi = atof(arg[iarg+3]);
 	iarg += 4;
       } else if (strcmp(arg[iarg+1],"scale") == 0) {
 	if (iarg+3 > narg) error->all("Illegal displace_box command");
 	set[index].style = SCALE;
 	set[index].scale = atof(arg[iarg+2]);
 	iarg += 3;
       } else if (strcmp(arg[iarg+1],"volume") == 0) {
 	set[index].style = VOLUME;
 	iarg += 2;
       } else error->all("Illegal displace_box command");
 
     } else if (strcmp(arg[iarg],"xy") == 0 || strcmp(arg[iarg],"xz") == 0 ||
 	strcmp(arg[iarg],"yz") == 0) {
       if (triclinic == 0)
 	error->all("Displace_box tilt factors require triclinic box");
       if (strcmp(arg[iarg],"xy") == 0) index = 5;
       else if (strcmp(arg[iarg],"xz") == 0) index = 4;
       else if (strcmp(arg[iarg],"yz") == 0) index = 3;
       if (iarg+2 > narg) error->all("Illegal displace_box command");
       if (strcmp(arg[iarg+1],"final") == 0) {
 	if (iarg+3 > narg) error->all("Illegal displace_box command");
 	set[index].style = FINAL;
 	set[index].ftilt = atof(arg[iarg+2]);
 	iarg += 3;
       } else if (strcmp(arg[iarg+1],"delta") == 0) {
 	if (iarg+3 > narg) error->all("Illegal displace_box command");
 	set[index].style = DELTA;
 	set[index].dtilt = atof(arg[iarg+2]);
 	iarg += 3;
       } else error->all("Illegal displace_box command");
 
     } else break;
   }
 
   // read options from end of input line
 
   options(narg-iarg,&arg[iarg]);
 
   // check periodicity
 
   if ((set[0].style && domain->xperiodic == 0) ||
       (set[1].style && domain->yperiodic == 0) ||
       (set[2].style && domain->zperiodic == 0))
     error->all("Cannot displace_box on a non-periodic boundary");
 
   if (set[3].style && (domain->yperiodic == 0 || domain->zperiodic == 0))
     error->all("Cannot displace_box on a non-periodic boundary");
   if (set[4].style && (domain->xperiodic == 0 || domain->zperiodic == 0))
     error->all("Cannot displace_box on a non-periodic boundary");
   if (set[5].style && (domain->xperiodic == 0 || domain->yperiodic == 0))
     error->all("Cannot displace_box on a non-periodic boundary");
 
   // apply scaling to FINAL,DELTA since they have distance units
 
   int flag = 0;
   for (int i = 0; i < 6; i++)
     if (set[i].style == FINAL || set[i].style == DELTA) flag = 1;
 
   if (flag && scaleflag && domain->lattice == NULL)
     error->all("Use of displace_box with undefined lattice");
 
   double xscale,yscale,zscale;
   if (flag && scaleflag) {
     xscale = domain->lattice->xlattice;
     yscale = domain->lattice->ylattice;
     zscale = domain->lattice->zlattice;
   }
   else xscale = yscale = zscale = 1.0;
 
   // for 3,4,5 scaling is in 1st dimension, e.g. x for xz
 
   double map[6];
   map[0] = xscale; map[1] = yscale; map[2] = zscale;
   map[3] = yscale; map[4] = xscale; map[5] = xscale;
 
   for (int i = 0; i < 3; i++) {
     if (set[i].style == FINAL) {
       set[i].flo *= map[i];
       set[i].fhi *= map[i];
     } else if (set[i].style == DELTA) {
       set[i].dlo *= map[i];
       set[i].dhi *= map[i];
     }
   }
 
   for (int i = 3; i < 6; i++) {
     if (set[i].style == FINAL) set[i].ftilt *= map[i];
     else if (set[i].style == DELTA) set[i].dtilt *= map[i];
   }
 
   // set initial/final values for box size and shape
   // final = initial if no setting
 
   for (int i = 0; i < 3; i++) {
     set[i].lo_stop = set[i].lo_start = domain->boxlo[i];
     set[i].hi_stop = set[i].hi_start = domain->boxhi[i];
 
     if (set[i].style == FINAL) {
       set[i].lo_stop = set[i].flo;
       set[i].hi_stop = set[i].fhi;
     } else if (set[i].style == DELTA) {
       set[i].lo_stop = set[i].lo_start + set[i].dlo;
       set[i].hi_stop = set[i].hi_start + set[i].dhi;
     } else if (set[i].style == SCALE) {
       set[i].lo_stop = 0.5*(set[i].lo_start+set[i].hi_start) - 
 	0.5*set[i].scale*(set[i].hi_start-set[i].lo_start);
       set[i].hi_stop = 0.5*(set[i].lo_start+set[i].hi_start) + 
 	0.5*set[i].scale*(set[i].hi_start-set[i].lo_start);
     }
   }
 
   for (int i = 3; i < 6; i++) {
     if (i == 5) set[i].tilt_start = domain->xy;
     else if (i == 4) set[i].tilt_start = domain->xz;
     else if (i == 3) set[i].tilt_start = domain->yz;
     set[i].tilt_stop = set[i].tilt_start;
 
     if (set[i].style == FINAL) {
       set[i].tilt_stop = set[i].ftilt;
     } else if (set[i].style == DELTA) {
       set[i].tilt_stop = set[i].tilt_start + set[i].dtilt;
     }
   }
 
   // for VOLUME, setup links to other dims
   // fixed, dynamic1,2, vol_start
 
   for (int i = 0; i < 3; i++) {
     set[i].vol_start = domain->xprd * domain->yprd * domain->zprd;
 
     if (set[i].style != VOLUME) continue;
     int other1 = (i+1) % 3;
     int other2 = (i+2) % 3;
 
     if (set[other1].style == NONE) {
       if (set[other2].style == NONE || set[other2].style == VOLUME)
 	error->all("Fix deform volume setting is invalid");
       set[i].substyle = ONE_FROM_ONE;
       set[i].fixed = other1;
       set[i].dynamic1 = other2;
     } else if (set[other2].style == NONE) {
       if (set[other1].style == NONE || set[other1].style == VOLUME)
 	error->all("Fix deform volume setting is invalid");
       set[i].substyle = ONE_FROM_ONE;
       set[i].fixed = other2;
       set[i].dynamic1 = other1;
     } else if (set[other1].style == VOLUME) {
       if (set[other2].style == NONE || set[other2].style == VOLUME)
 	error->all("Fix deform volume setting is invalid");
       set[i].substyle = TWO_FROM_ONE;
       set[i].fixed = other1;
       set[i].dynamic1 = other2;
     } else if (set[other2].style == VOLUME) {
       if (set[other1].style == NONE || set[other1].style == VOLUME)
 	error->all("Fix deform volume setting is invalid");
       set[i].substyle = TWO_FROM_ONE;
       set[i].fixed = other2;
       set[i].dynamic1 = other1;
     } else {
       set[i].substyle = ONE_FROM_TWO;
       set[i].dynamic2 = other1;
       set[i].dynamic2 = other2;
     }
   }
 
   // set new box size for VOLUME dims that are linked to other dims
 
   for (int i = 0; i < 3; i++) {
     if (set[i].style != VOLUME) continue;
 
     if (set[i].substyle == ONE_FROM_ONE) {
       set[i].lo_stop = 0.5*(set[i].lo_start+set[i].hi_start) -
 	0.5*(set[i].vol_start /
 	     (set[set[i].dynamic1].hi_stop -
 	      set[set[i].dynamic1].lo_stop) /
 	     (set[set[i].fixed].hi_start-set[set[i].fixed].lo_start));
       set[i].hi_stop = 0.5*(set[i].lo_start+set[i].hi_start) +
 	0.5*(set[i].vol_start /
 	     (set[set[i].dynamic1].hi_stop -
 	      set[set[i].dynamic1].lo_stop) /
 	     (set[set[i].fixed].hi_start-set[set[i].fixed].lo_start));
 
     } else if (set[i].substyle == ONE_FROM_TWO) {
       set[i].lo_stop = 0.5*(set[i].lo_start+set[i].hi_start) -
 	0.5*(set[i].vol_start /
 	     (set[set[i].dynamic1].hi_stop - 
 	      set[set[i].dynamic1].lo_stop) /
 	     (set[set[i].dynamic2].hi_stop - 
 	      set[set[i].dynamic2].lo_stop));
       set[i].hi_stop = 0.5*(set[i].lo_start+set[i].hi_start) +
 	0.5*(set[i].vol_start /
 	     (set[set[i].dynamic1].hi_stop -
 	      set[set[i].dynamic1].lo_stop) /
 	     (set[set[i].dynamic2].hi_stop - 
 	      set[set[i].dynamic2].lo_stop));
       
     } else if (set[i].substyle == TWO_FROM_ONE) {
       set[i].lo_stop = 0.5*(set[i].lo_start+set[i].hi_start) -
 	0.5*sqrt(set[i].vol_start /
 		 (set[set[i].dynamic1].hi_stop - 
 		  set[set[i].dynamic1].lo_stop) /
 		 (set[set[i].fixed].hi_start - 
 		  set[set[i].fixed].lo_start) *
 		 (set[i].hi_start - set[i].lo_start));
       set[i].hi_stop = 0.5*(set[i].lo_start+set[i].hi_start) +
 	0.5*sqrt(set[i].vol_start /
 		 (set[set[i].dynamic1].hi_stop - 
 		  set[set[i].dynamic1].lo_stop) /
 		 (set[set[i].fixed].hi_start - 
 		  set[set[i].fixed].lo_start) *
 		 (set[i].hi_start - set[i].lo_start));
     }
   }
 
   // check that final tilt is not illegal value
 
   double xprd_stop = set[0].hi_stop - set[0].lo_stop;
   double yprd_stop = set[0].hi_stop - set[0].lo_stop;
 
   if (set[3].tilt_stop < -0.5*yprd_stop || set[3].tilt_stop > 0.5*yprd_stop ||
       set[4].tilt_stop < -0.5*xprd_stop || set[4].tilt_stop > 0.5*xprd_stop ||
       set[5].tilt_stop < -0.5*xprd_stop || set[5].tilt_stop > 0.5*xprd_stop)
     error->all("Induced tilt by displace_box is too large");
 
   // convert atoms to lamda coords
 
   if (remapflag == X_REMAP) {
     double **x = atom->x;
     int *mask = atom->mask;
     int nlocal = atom->nlocal;
 
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit)
 	domain->x2lamda(x[i],x[i]);
  }
 
   // reset global and local box to new size/shape
 
   domain->boxlo[0] = set[0].lo_stop;
   domain->boxlo[1] = set[1].lo_stop;
   domain->boxlo[2] = set[2].lo_stop;
   domain->boxhi[0] = set[0].hi_stop;
   domain->boxhi[1] = set[1].hi_stop;
   domain->boxhi[2] = set[2].hi_stop;
 
   if (triclinic) {
     domain->yz = set[3].tilt_stop;
     domain->xz = set[4].tilt_stop;
     domain->xy = set[5].tilt_stop;
   }
 
   domain->set_global_box();
   domain->set_local_box();
 
   // convert atoms back to box coords
 
   if (remapflag == X_REMAP) {
     double **x = atom->x;
     int *mask = atom->mask;
     int nlocal = atom->nlocal;
 
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit)
 	domain->lamda2x(x[i],x[i]);
   }
 
   // move atoms back inside simulation box and to new processors
   // use remap() instead of pbc()
   //   in case box moved a long distance relative to atoms
   // use irregular() in case box moved a long distance relative to atoms
 
   double **x = atom->x;
   int *image = atom->image;
   int nlocal = atom->nlocal;
   for (i = 0; i < nlocal; i++) domain->remap(x[i],image[i]);
 
   if (domain->triclinic) domain->x2lamda(atom->nlocal);
   domain->reset_box();
   Irregular *irregular = new Irregular(lmp);
   irregular->migrate_atoms();
   delete irregular;
   if (domain->triclinic) domain->lamda2x(atom->nlocal);
 
   // clean up
 
   delete [] set;
 
   // check if any atoms were lost
 
   bigint natoms;
   bigint nblocal = atom->nlocal;
-  MPI_Allreduce(&nblocal,&natoms,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&nblocal,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
   if (natoms != atom->natoms) {
-    char str[128];
-    sprintf(str,"Lost atoms via displace_box: original %lu current %lu",
-	    atom->natoms,natoms);
+    char fstr[64],str[128];
+    sprintf(fstr,"Lost atoms via displace_box: original %s current %s",
+	    BIGINT_FORMAT,BIGINT_FORMAT);
+    sprintf(str,fstr,atom->natoms,natoms);
     error->all(str);
   }
 }
 
 /* ----------------------------------------------------------------------
    parse optional parameters at end of displace_box input line 
 ------------------------------------------------------------------------- */
 
 void DisplaceBox::options(int narg, char **arg)
 {
   if (narg < 0) error->all("Illegal displace_box command");
 
   remapflag = X_REMAP;
   scaleflag = 1;
 
   int iarg = 0;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"remap") == 0) {
       if (iarg+2 > narg) error->all("Illegal displace_box command");
       if (strcmp(arg[iarg+1],"x") == 0) remapflag = X_REMAP;
       else if (strcmp(arg[iarg+1],"none") == 0) remapflag = NO_REMAP;
       else error->all("Illegal displace_box command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"units") == 0) {
       if (iarg+2 > narg) error->all("Illegal displace_box command");
       if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
       else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
       else error->all("Illegal displace_box command");
       iarg += 2;
     } else error->all("Illegal displace_box command");
   }
 }
diff --git a/src/dump.cpp b/src/dump.cpp
index 76708f01e..a382c7fa9 100644
--- a/src/dump.cpp
+++ b/src/dump.cpp
@@ -1,707 +1,713 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "string.h"
 #include "stdio.h"
 #include "dump.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "irregular.h"
 #include "update.h"
 #include "domain.h"
 #include "group.h"
 #include "output.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 // allocate space for static class variable
 
 Dump *Dump::dumpptr;
 
 #define BIG 1.0e20
 #define IBIG 2147483647
 #define EPSILON 1.0e-6
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 enum{ASCEND,DESCEND};
 
 /* ---------------------------------------------------------------------- */
 
 Dump::Dump(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
 {
   MPI_Comm_rank(world,&me);
   MPI_Comm_size(world,&nprocs);
 
   int n = strlen(arg[0]) + 1;
   id = new char[n];
   strcpy(id,arg[0]);
 
   igroup = group->find(arg[1]);
   groupbit = group->bitmask[igroup];
 
   n = strlen(arg[2]) + 1;
   style = new char[n];
   strcpy(style,arg[2]);
 
   n = strlen(arg[4]) + 1;
   filename = new char[n];
   strcpy(filename,arg[4]);
 
   first_flag = 0;
   flush_flag = 1;
   format = NULL;
   format_user = NULL;
   clearstep = 0;
   sort_flag = 0;
   append_flag = 0;
 
   maxbuf = maxids = maxsort = maxproc = 0;
   buf = bufsort = NULL;
   ids = idsort = index = proclist = NULL;
   irregular = NULL;
 
   // parse filename for special syntax
   // if contains '%', write one file per proc and replace % with proc-ID
   // if contains '*', write one file per timestep and replace * with timestep
   // check file suffixes
   //   if ends in .bin = binary file
   //   else if ends in .gz = gzipped text file
   //   else ASCII text file
 
   fp = NULL;
   singlefile_opened = 0;
   compressed = 0;
   binary = 0;
   multifile = 0;
   multiproc = 0;
 
   char *ptr;
   if (ptr = strchr(filename,'%')) {
     multiproc = 1;
     char *extend = new char[strlen(filename) + 16];
     *ptr = '\0';
     sprintf(extend,"%s%d%s",filename,me,ptr+1);
     delete [] filename;
     n = strlen(extend) + 1;
     filename = new char[n];
     strcpy(filename,extend);
     delete [] extend;
   }
 
   if (strchr(filename,'*')) multifile = 1;
 
   char *suffix = filename + strlen(filename) - strlen(".bin");
   if (suffix > filename && strcmp(suffix,".bin") == 0) binary = 1;
   suffix = filename + strlen(filename) - strlen(".gz");
   if (suffix > filename && strcmp(suffix,".gz") == 0) compressed = 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 Dump::~Dump()
 {
   delete [] id;
   delete [] style;
   delete [] filename;
 
   delete [] format;
   delete [] format_default;
   delete [] format_user;
 
   memory->sfree(buf);
   memory->sfree(bufsort);
   memory->sfree(ids);
   memory->sfree(idsort);
   memory->sfree(index);
   memory->sfree(proclist);
   delete irregular;
 
   // XTC style sets fp to NULL since it closes file in its destructor
 
   if (multifile == 0 && fp != NULL) {
     if (compressed) {
       if (multiproc) pclose(fp);
       else if (me == 0) pclose(fp);
     } else {
       if (multiproc) fclose(fp);
       else if (me == 0) fclose(fp);
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Dump::init()
 {
   init_style();
 
   if (!sort_flag) {
     memory->sfree(bufsort);
     memory->sfree(ids);
     memory->sfree(idsort);
     memory->sfree(index);
     memory->sfree(proclist);
     delete irregular;
 
     maxids = maxsort = maxproc = 0;
     bufsort = NULL;
     ids = idsort = index = proclist = NULL;
     irregular = NULL;
   }
 
   if (sort_flag) {
     if (sortcol == 0 && atom->tag_enable == 0)
       error->all("Cannot dump sort on atom IDs with no atom IDs defined");
     if (sortcol && sortcol > size_one)
       error->all("Dump sort column is invalid");
     if (nprocs > 1 && irregular == NULL)
       irregular = new Irregular(lmp);
 
     bigint size = group->count(igroup);
-    if (size > MAXINT32) error->all("Too many atoms to dump sort");
+    if (size > MAXSMALLINT) error->all("Too many atoms to dump sort");
 
     // set reorderflag = 1 if can simply reorder local atoms rather than sort
     // criteria: sorting by ID, atom IDs are consecutive from 1 to Natoms
     //           min/max IDs of group match size of group
     // compute ntotal_reorder, nme_reorder, idlo/idhi to test against later
 
     reorderflag = 0;
     if (sortcol == 0 && atom->tag_consecutive()) {
       int *tag = atom->tag;
       int *mask = atom->mask;
       int nlocal = atom->nlocal;
 
       int min = IBIG;
       int 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);
 
       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);
 
 	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);
 	if (me && me == lom1) idlo--;
 	else if (me && me != lo) idlo++;
 	if (me+1 == him1) idhi--;
 	else if (me+1 != hi) idhi++;
 
 	nme_reorder = idhi-idlo;
 	ntotal_reorder = isize;
       }
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Dump::write()
 {
   // if file per timestep, open new file
 
   if (multifile) openfile();
 
   // simulation box bounds
 
   if (domain->triclinic == 0) {
     boxxlo = domain->boxlo[0];
     boxxhi = domain->boxhi[0];
     boxylo = domain->boxlo[1];
     boxyhi = domain->boxhi[1];
     boxzlo = domain->boxlo[2];
     boxzhi = domain->boxhi[2];
   } else {
     boxxlo = domain->boxlo_bound[0];
     boxxhi = domain->boxhi_bound[0];
     boxylo = domain->boxlo_bound[1];
     boxyhi = domain->boxhi_bound[1];
     boxzlo = domain->boxlo_bound[2];
     boxzhi = domain->boxhi_bound[2];
     boxxy = domain->xy;
     boxxz = domain->xz;
     boxyz = domain->yz;
   }
 
   // nme = # of dump lines this proc will contribute to dump
 
   nme = count();
+  bigint bnme = nme;
 
   // ntotal = total # of dump lines
   // nmax = max # of dump lines on any proc
 
   int nmax;
   if (multiproc) nmax = nme;
   else {
-    MPI_Allreduce(&nme,&ntotal,1,MPI_INT,MPI_SUM,world);
+    MPI_Allreduce(&bnme,&ntotal,1,MPI_LMP_BIGINT,MPI_SUM,world);
     MPI_Allreduce(&nme,&nmax,1,MPI_INT,MPI_MAX,world);
   }
 
   // write timestep header
 
-  if (multiproc) write_header(nme);
+  if (multiproc) write_header(bnme);
   else write_header(ntotal);
 
-  // this insures proc 0 can receive everyone's info
+  // insure proc 0 can receive everyone's info
+  // limit nmax*size_one to int since used as arg in MPI_Rsend() below
   // pack my data into buf
   // if sorting on IDs also request ID list from pack()
   // sort buf as needed
 
   if (nmax > maxbuf) {
+    if ((bigint) nmax * size_one > MAXSMALLINT)
+      error->all("Too much per-proc info for dump");
     maxbuf = nmax;
     memory->sfree(buf);
     buf = (double *) 
       memory->smalloc(maxbuf*size_one*sizeof(double),"dump:buf");
   }
   if (sort_flag && sortcol == 0 && nmax > maxids) {
     maxids = nmax;
     memory->sfree(ids);
     ids = (int *) memory->smalloc(maxids*sizeof(int),"dump:ids");
   }
 
   if (sort_flag && sortcol == 0) pack(ids);
   else pack(NULL);
   if (sort_flag) sort();
 
   // multiproc = 1 = each proc writes own data to own file 
   // multiproc = 0 = all procs write to one file thru proc 0
   //   proc 0 pings each proc, receives it's data, writes to file
   //   all other procs wait for ping, send their data to proc 0
 
   if (multiproc) write_data(nme,buf);
   else {
     int tmp,nlines;
     MPI_Status status;
     MPI_Request request;
 
     if (me == 0) {
       for (int iproc = 0; iproc < nprocs; iproc++) {
 	if (iproc) {
 	  MPI_Irecv(buf,maxbuf*size_one,MPI_DOUBLE,iproc,0,world,&request);
 	  MPI_Send(&tmp,0,MPI_INT,iproc,0,world);
 	  MPI_Wait(&request,&status);
 	  MPI_Get_count(&status,MPI_DOUBLE,&nlines);
 	  nlines /= size_one;
 	} else nlines = nme;
 
 	write_data(nlines,buf);
       }
       if (flush_flag) fflush(fp);
       
     } else {
       MPI_Recv(&tmp,0,MPI_INT,0,0,world,&status);
       MPI_Rsend(buf,nme*size_one,MPI_DOUBLE,0,0,world);
     }
   }
 
   // if file per timestep, close file
 
   if (multifile) {
     if (compressed) {
       if (multiproc) pclose(fp);
       else if (me == 0) pclose(fp);
     } else {
       if (multiproc) fclose(fp);
       else if (me == 0) fclose(fp);
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    generic opening of a dump file
    ASCII or binary or gzipped
    some derived classes override this function
 ------------------------------------------------------------------------- */
 
 void Dump::openfile()
 {
   // single file, already opened, so just return
 
   if (singlefile_opened) return;
   if (multifile == 0) singlefile_opened = 1;
 
   // if one file per timestep, replace '*' with current timestep
 
   char *filecurrent;
   if (multifile == 0) filecurrent = filename;
   else {
     filecurrent = new char[strlen(filename) + 16];
     char *ptr = strchr(filename,'*');
     *ptr = '\0';
-    sprintf(filecurrent,"%s%d%s",filename,update->ntimestep,ptr+1);
+    char fstr[16];
+    sprintf(fstr,"%%s%s%%s",BIGINT_FORMAT);
+    sprintf(filecurrent,fstr,filename,update->ntimestep,ptr+1);
     *ptr = '*';
   }
 
   // open one file on proc 0 or file on every proc
 
   if (me == 0 || multiproc) {
     if (compressed) {
 #ifdef LAMMPS_GZIP
       char gzip[128];
       sprintf(gzip,"gzip -6 > %s",filecurrent);
       fp = popen(gzip,"w");
 #else
       error->one("Cannot open gzipped file");
 #endif
     } else if (binary) {
       fp = fopen(filecurrent,"wb");
     } else if (append_flag) {
       fp = fopen(filecurrent,"a");
     } else {
       fp = fopen(filecurrent,"w");
     }
 
     if (fp == NULL) error->one("Cannot open dump file");
   } else fp = NULL;
 
   // delete string with timestep replaced
 
   if (multifile) delete [] filecurrent;
 }
 
 /* ----------------------------------------------------------------------
    parallel sort of buf across all procs
    changes nme, reorders datums in buf, grows buf if necessary
 ------------------------------------------------------------------------- */
 
 void Dump::sort()
 {
   int i,iproc;
   double value;
 
   // if single proc, swap ptrs to buf,ids <-> bufsort,idsort
 
   if (nprocs == 1) {
     if (nme > maxsort) {
       maxsort = nme;
       memory->sfree(bufsort);
       bufsort = (double *)
 	memory->smalloc(maxsort*size_one*sizeof(double),"dump:bufsort");
       memory->sfree(index);
       index = (int *) memory->smalloc(maxsort*sizeof(int),"dump:index");
       if (sortcol == 0) {
 	memory->sfree(idsort);
 	idsort = (int *) memory->smalloc(maxsort*sizeof(int),"dump:idsort");
       }
     }
 
     double *dptr = buf;
     buf = bufsort;
     bufsort = dptr;
 
     if (sortcol == 0) {
       int *iptr = ids;
       ids = idsort;
       idsort = iptr;
     }
 
   // if multiple procs, exchange datums between procs via irregular
     
   } else {
 
     // grow proclist if necessary
 
     if (nme > maxproc) {
       maxproc = nme;
       memory->sfree(proclist);
       proclist = (int *) memory->smalloc(maxproc*sizeof(int),"dump:proclist");
     }
     
     // proclist[i] = which proc Ith datum will be sent to
 
     if (sortcol == 0) {
       int min = IBIG;
       int 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;
       for (i = 0; i < nme; i++) {
 	iproc = static_cast<int> ((ids[i]-minall)/range * nprocs);
 	proclist[i] = iproc;
       }
 
     } else {
       double min = BIG;
       double max = -BIG;
       for (i = 0; i < nme; i++) {
 	value = buf[i*size_one + sortcolm1];
 	min = MIN(min,value);
 	max = MAX(max,value);
       }
       double minall,maxall;
       MPI_Allreduce(&min,&minall,1,MPI_DOUBLE,MPI_MIN,world);
       MPI_Allreduce(&max,&maxall,1,MPI_DOUBLE,MPI_MAX,world);
       double range = maxall-minall + EPSILON*(maxall-minall);
       if (range == 0.0) range = EPSILON;
       for (i = 0; i < nme; i++) {
 	value = buf[i*size_one + sortcolm1];
 	iproc = static_cast<int> ((value-minall)/range * nprocs);
 	proclist[i] = iproc;
       }
     }
 
     // create comm plan, grow recv bufs if necessary,
     // exchange datums, destroy plan
     // if sorting on atom IDs, exchange IDs also
 
     nme = irregular->create_data(nme,proclist);
 
     if (nme > maxsort) {
       maxsort = nme;
       memory->sfree(bufsort);
       bufsort = (double *) 
 	memory->smalloc(maxsort*size_one*sizeof(double),"dump:bufsort");
       memory->sfree(index);
       index = (int *) memory->smalloc(maxsort*sizeof(int),"dump:index");
       if (sortcol == 0) {
 	memory->sfree(idsort);
 	idsort = (int *) memory->smalloc(maxsort*sizeof(int),"dump:idsort");
       }
     }
     
     irregular->exchange_data((char *) buf,size_one*sizeof(double),
 			     (char *) bufsort);
     if (sortcol == 0) 
       irregular->exchange_data((char *) ids,sizeof(int),(char *) idsort);
     irregular->destroy_data();
   }
 
   // if reorder flag is set & total/per-proc counts match pre-computed values,
   // then create index directly from idsort
   // else quicksort of index using IDs or buf column as comparator
 
   if (reorderflag) {
     if (ntotal != ntotal_reorder) reorderflag = 0;
     int flag = 0;
     if (nme != nme_reorder) flag = 1;
     int flagall;
     MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
     if (flagall) reorderflag = 0;
 
     if (reorderflag)
       for (i = 0; i < nme; i++)
 	index[idsort[i]-idlo] = i;
   }
 
   if (!reorderflag) {
     dumpptr = this;
     for (i = 0; i < nme; i++) index[i] = i;
     if (sortcol == 0) qsort(index,nme,sizeof(int),idcompare);
     else if (sortorder == ASCEND) qsort(index,nme,sizeof(int),bufcompare);
     else qsort(index,nme,sizeof(int),bufcompare_reverse);
   }
 
   // reset buf size and maxbuf to largest of any post-sort nme values
   // this insures proc 0 can receive everyone's info
 
   int nmax;
   if (multiproc) nmax = nme;
   else MPI_Allreduce(&nme,&nmax,1,MPI_INT,MPI_MAX,world);
 
   if (nmax > maxbuf) {
     maxbuf = nmax;
     memory->sfree(buf);
     buf = (double *) 
       memory->smalloc(maxbuf*size_one*sizeof(double),"dump:buf");
   }
 
   // copy data from bufsort to buf using index
     
   int nbytes = size_one*sizeof(double);
   for (i = 0; i < nme; i++)
     memcpy(&buf[i*size_one],&bufsort[index[i]*size_one],nbytes);
 }
 
 /* ----------------------------------------------------------------------
    compare two atom IDs
    called via qsort() in sort() method
    is a static method so access data via dumpptr
 ------------------------------------------------------------------------- */
 
 int Dump::idcompare(const void *pi, const void *pj)
 {
   int *idsort = dumpptr->idsort;
 
   int i = *((int *) pi);
   int j = *((int *) pj);
 
   if (idsort[i] < idsort[j]) return -1;
   if (idsort[i] > idsort[j]) return 1;
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    compare two buffer values with size_one stride
    called via qsort() in sort() method
    is a static method so access data via dumpptr
    sort in ASCENDing order
 ------------------------------------------------------------------------- */
 
 int Dump::bufcompare(const void *pi, const void *pj)
 {
   double *bufsort = dumpptr->bufsort;
   int size_one = dumpptr->size_one;
   int sortcolm1 = dumpptr->sortcolm1;
 
   int i = *((int *) pi)*size_one + sortcolm1;
   int j = *((int *) pj)*size_one + sortcolm1;
 
   if (bufsort[i] < bufsort[j]) return -1;
   if (bufsort[i] > bufsort[j]) return 1;
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    compare two buffer values with size_one stride
    called via qsort() in sort() method
    is a static method so access data via dumpptr
    sort in DESCENDing order
 ------------------------------------------------------------------------- */
 
 int Dump::bufcompare_reverse(const void *pi, const void *pj)
 {
   double *bufsort = dumpptr->bufsort;
   int size_one = dumpptr->size_one;
   int sortcolm1 = dumpptr->sortcolm1;
 
   int i = *((int *) pi)*size_one + sortcolm1;
   int j = *((int *) pj)*size_one + sortcolm1;
 
   if (bufsort[i] > bufsort[j]) return -1;
   if (bufsort[i] < bufsort[j]) return 1;
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    process params common to all dumps here
    if unknown param, call modify_param specific to the dump
 ------------------------------------------------------------------------- */
 
 void Dump::modify_params(int narg, char **arg)
 {
   if (narg == 0) error->all("Illegal dump_modify command");
 
   int iarg = 0;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"append") == 0) {
       if (iarg+2 > narg) error->all("Illegal dump_modify command");
       if (strcmp(arg[iarg+1],"yes") == 0) append_flag = 1;
       else if (strcmp(arg[iarg+1],"no") == 0) append_flag = 0;
       else error->all("Illegal dump_modify command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"every") == 0) {
       if (iarg+2 > narg) error->all("Illegal dump_modify command");
       int idump;
       for (idump = 0; idump < output->ndump; idump++)
 	if (strcmp(id,output->dump[idump]->id) == 0) break;
       int n;
       if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) {
 	delete [] output->var_dump[idump];
 	n = strlen(&arg[iarg+1][2]) + 1;
 	output->var_dump[idump] = new char[n];
 	strcpy(output->var_dump[idump],&arg[iarg+1][2]);
 	n = 0;
       } else {
 	n = atoi(arg[iarg+1]);
 	if (n <= 0) error->all("Illegal dump_modify command");
       }
       output->every_dump[idump] = n;
       iarg += 2;
     } else if (strcmp(arg[iarg],"first") == 0) {
       if (iarg+2 > narg) error->all("Illegal dump_modify command");
       if (strcmp(arg[iarg+1],"yes") == 0) first_flag = 1;
       else if (strcmp(arg[iarg+1],"no") == 0) first_flag = 0;
       else error->all("Illegal dump_modify command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"flush") == 0) {
       if (iarg+2 > narg) error->all("Illegal dump_modify command");
       if (strcmp(arg[iarg+1],"yes") == 0) flush_flag = 1;
       else if (strcmp(arg[iarg+1],"no") == 0) flush_flag = 0;
       else error->all("Illegal dump_modify command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"format") == 0) {
       if (iarg+2 > narg) error->all("Illegal dump_modify command");
       delete [] format_user;
       format_user = NULL;
       if (strcmp(arg[iarg+1],"none")) {
 	int n = strlen(arg[iarg+1]) + 1;
 	format_user = new char[n];
 	strcpy(format_user,arg[iarg+1]);
       }
       iarg += 2;
     } else if (strcmp(arg[iarg],"sort") == 0) {
       if (iarg+2 > narg) error->all("Illegal dump_modify command");
       if (strcmp(arg[iarg+1],"off") == 0) sort_flag = 0;
       else if (strcmp(arg[iarg+1],"id") == 0) {
 	sort_flag = 1;
 	sortcol = 0;
 	sortorder = ASCEND;
       } else {
 	sort_flag = 1;
 	sortcol = atoi(arg[iarg+1]);
 	sortorder = ASCEND;
 	if (sortcol == 0) error->all("Illegal dump_modify command");
 	if (sortcol < 0) {
 	  sortorder = DESCEND;
 	  sortcol = -sortcol;
 	}
 	sortcolm1 = sortcol - 1;
       }
       iarg += 2;
     } else {
       int n = modify_param(narg-iarg,&arg[iarg]);
       if (n == 0) error->all("Illegal dump_modify command");
       iarg += n;
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory
 ------------------------------------------------------------------------- */
 
 double Dump::memory_usage()
 {
   double bytes = maxbuf*size_one * sizeof(double);      // buf
   if (sort_flag) {
     if (sortcol == 0) bytes += maxids * sizeof(int);    // ids
     bytes += maxsort*size_one * sizeof(double);         // bufsort
     if (sortcol == 0) bytes += maxsort * sizeof(int);   // idsort
     bytes += maxsort * sizeof(int);                     // index
     bytes += maxproc * sizeof(int);                     // proclist
     if (irregular) bytes += irregular->memory_usage();
   }
   return bytes;
 }
diff --git a/src/dump.h b/src/dump.h
index 6fea5482b..4b4aeb289 100644
--- a/src/dump.h
+++ b/src/dump.h
@@ -1,107 +1,108 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_DUMP_H
 #define LMP_DUMP_H
 
 #include "stdio.h"
 #include "pointers.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class Dump : protected Pointers {
  public:
   char *id;                  // user-defined name of Dump
   char *style;               // style of Dump
   int igroup,groupbit;       // group that Dump is performed on
 
   int first_flag;            // 0 if no initial dump, 1 if yes initial dump
   int clearstep;             // 1 if dump invokes computes, 0 if not
 
   // static variable across all Dump objects
 
   static Dump *dumpptr;         // holds a ptr to Dump currently being used
 
   Dump(class LAMMPS *, int, char **);
   virtual ~Dump();
   void init();
   void write();
   void modify_params(int, char **);
   virtual double memory_usage();
 
  protected:
   int me,nprocs;             // proc info
 
   char *filename;            // user-specified file
   int compressed;            // 1 if dump file is written compressed, 0 no
   int binary;                // 1 if dump file is written binary, 0 no
   int multifile;             // 0 = one big file, 1 = one file per timestep
   int multiproc;             // 0 = proc 0 writes for all, 1 = one file/proc
 
   int header_flag;           // 0 = item, 2 = xyz
   int flush_flag;            // 0 if no flush, 1 if flush every dump
   int sort_flag;             // 1 if sorted output
   int append_flag;           // 1 if open file in append mode, 0 if not
   int singlefile_opened;     // 1 = one big file, already opened, else 0
   int sortcol;               // 0 to sort on ID, 1-N on columns
   int sortcolm1;             // sortcol - 1
   int sortorder;             // ASCEND or DESCEND
 
   char *format_default;      // default format string
   char *format_user;         // format string set by user
   char *format;              // format string for the file write
   FILE *fp;                  // file to write dump to
   int size_one;              // # of quantities for one atom
   int nme;                   // # of atoms in this dump from me
 
   double boxxlo,boxxhi;      // local copies of domain values
   double boxylo,boxyhi;      // lo/hi are bounding box for triclinic
   double boxzlo,boxzhi;
   double boxxy,boxxz,boxyz;
 
-  int ntotal;                // # of per-atom lines in snapshot
+  bigint ntotal;             // # of per-atom lines in snapshot
   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
 
   int maxbuf;                // size of buf
   double *buf;               // memory for atom quantities
 
   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
   double *bufsort;
   int *idsort,*index,*proclist;
 
 
   class Irregular *irregular;
 
   virtual void init_style() = 0;
   virtual void openfile();
   virtual int modify_param(int, char **) {return 0;}
-  virtual void write_header(int) = 0;
+  virtual void write_header(bigint) = 0;
   virtual int count() = 0;
   virtual void pack(int *) = 0;
   virtual void write_data(int, double *) = 0;
 
   void sort();
   static int idcompare(const void *, const void *);
   static int bufcompare(const void *, const void *);
   static int bufcompare_reverse(const void *, const void *);
 };
 
 }
 
 #endif
diff --git a/src/dump_atom.cpp b/src/dump_atom.cpp
index 930fc6e1d..11152f5b7 100644
--- a/src/dump_atom.cpp
+++ b/src/dump_atom.cpp
@@ -1,438 +1,438 @@
 /* ----------------------------------------------------------------------
    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 "string.h"
 #include "dump_atom.h"
 #include "domain.h"
 #include "atom.h"
 #include "update.h"
 #include "group.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 DumpAtom::DumpAtom(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg)
 {
   if (narg != 5) error->all("Illegal dump atom command");
 
   scale_flag = 1;
   image_flag = 0;
   format_default = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::init_style()
 {
   if (image_flag == 0) size_one = 5;
   else size_one = 8;
 
   // default format depends on image flags
 
   delete [] format;
   if (format_user) {
     int n = strlen(format_user) + 2;
     format = new char[n];
     strcpy(format,format_user);
     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";
     int n = strlen(str) + 2;
     format = new char[n];
     strcpy(format,str);
     strcat(format,"\n");
   }
 
   // setup column string
 
   if (scale_flag == 0 && image_flag == 0)
     columns = "id type x y z";
   else if (scale_flag == 0 && image_flag == 1)
     columns = "id type x y z ix iy iz";
   else if (scale_flag == 1 && image_flag == 0)
     columns = "id type xs ys zs";
   else if (scale_flag == 1 && image_flag == 1)
     columns = "id type xs ys zs ix iy iz";
 
   // setup function ptrs
 
   if (binary && domain->triclinic == 0)
     header_choice = &DumpAtom::header_binary;
   else if (binary && domain->triclinic == 1)
     header_choice = &DumpAtom::header_binary_triclinic;
   else if (!binary && domain->triclinic == 0)
     header_choice = &DumpAtom::header_item;
   else if (!binary && domain->triclinic == 1)
     header_choice = &DumpAtom::header_item_triclinic;
 
   if (scale_flag == 1 && image_flag == 0 && domain->triclinic == 0)
     pack_choice = &DumpAtom::pack_scale_noimage;
   else if (scale_flag == 1 && image_flag == 1 && domain->triclinic == 0)
     pack_choice = &DumpAtom::pack_scale_image;
   else if (scale_flag == 1 && image_flag == 0 && domain->triclinic == 1)
     pack_choice = &DumpAtom::pack_scale_noimage_triclinic;
   else if (scale_flag == 1 && image_flag == 1 && domain->triclinic == 1)
     pack_choice = &DumpAtom::pack_scale_image_triclinic;
   else if (scale_flag == 0 && image_flag == 0)
     pack_choice = &DumpAtom::pack_noscale_noimage;
   else if (scale_flag == 0 && image_flag == 1)
     pack_choice = &DumpAtom::pack_noscale_image;
 
   if (binary) write_choice = &DumpAtom::write_binary;
   else if (image_flag == 0) write_choice = &DumpAtom::write_noimage;
   else if (image_flag == 1) write_choice = &DumpAtom::write_image;
 
   // open single file, one time only
 
   if (multifile == 0) openfile();
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpAtom::modify_param(int narg, char **arg)
 {
   if (strcmp(arg[0],"scale") == 0) {
     if (narg < 2) error->all("Illegal dump_modify command");
     if (strcmp(arg[1],"yes") == 0) scale_flag = 1;
     else if (strcmp(arg[1],"no") == 0) scale_flag = 0;
     else error->all("Illegal dump_modify command");
     return 2;
   } else if (strcmp(arg[0],"image") == 0) {
     if (narg < 2) error->all("Illegal dump_modify command");
     if (strcmp(arg[1],"yes") == 0) image_flag = 1;
     else if (strcmp(arg[1],"no") == 0) image_flag = 0;
     else error->all("Illegal dump_modify command");
     return 2;
   }
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::write_header(int ndump)
+void DumpAtom::write_header(bigint ndump)
 {
   if (multiproc) (this->*header_choice)(ndump);
   else if (me == 0) (this->*header_choice)(ndump);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpAtom::count()
 {
   if (igroup == 0) return atom->nlocal;
 
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int m = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) m++;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::pack(int *ids)
 {
   (this->*pack_choice)(ids);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::write_data(int n, double *mybuf)
 {
   (this->*write_choice)(n,mybuf);
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::header_binary(int ndump)
+void DumpAtom::header_binary(bigint ndump)
 {
-  fwrite(&update->ntimestep,sizeof(int),1,fp);
-  fwrite(&ndump,sizeof(int),1,fp);
+  fwrite(&update->ntimestep,sizeof(bigint),1,fp);
+  fwrite(&ndump,sizeof(bigint),1,fp);
   fwrite(&domain->triclinic,sizeof(int),1,fp);
   fwrite(&boxxlo,sizeof(double),1,fp);
   fwrite(&boxxhi,sizeof(double),1,fp);
   fwrite(&boxylo,sizeof(double),1,fp);
   fwrite(&boxyhi,sizeof(double),1,fp);
   fwrite(&boxzlo,sizeof(double),1,fp);
   fwrite(&boxzhi,sizeof(double),1,fp);
   fwrite(&size_one,sizeof(int),1,fp);
   if (multiproc) {
     int one = 1;
     fwrite(&one,sizeof(int),1,fp);
   } else fwrite(&nprocs,sizeof(int),1,fp);
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::header_binary_triclinic(int ndump)
+void DumpAtom::header_binary_triclinic(bigint ndump)
 {
-  fwrite(&update->ntimestep,sizeof(int),1,fp);
-  fwrite(&ndump,sizeof(int),1,fp);
+  fwrite(&update->ntimestep,sizeof(bigint),1,fp);
+  fwrite(&ndump,sizeof(bigint),1,fp);
   fwrite(&domain->triclinic,sizeof(int),1,fp);
   fwrite(&boxxlo,sizeof(double),1,fp);
   fwrite(&boxxhi,sizeof(double),1,fp);
   fwrite(&boxylo,sizeof(double),1,fp);
   fwrite(&boxyhi,sizeof(double),1,fp);
   fwrite(&boxzlo,sizeof(double),1,fp);
   fwrite(&boxzhi,sizeof(double),1,fp);
   fwrite(&boxxy,sizeof(double),1,fp);
   fwrite(&boxxz,sizeof(double),1,fp);
   fwrite(&boxyz,sizeof(double),1,fp);
   fwrite(&size_one,sizeof(int),1,fp);
   if (multiproc) {
     int one = 1;
     fwrite(&one,sizeof(int),1,fp);
   } else fwrite(&nprocs,sizeof(int),1,fp);
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::header_item(int ndump)
+void DumpAtom::header_item(bigint ndump)
 {
   fprintf(fp,"ITEM: TIMESTEP\n");
-  fprintf(fp,"%d\n",update->ntimestep);
+  fprintf(fp,BIGINT_FORMAT_NL,update->ntimestep);
   fprintf(fp,"ITEM: NUMBER OF ATOMS\n");
-  fprintf(fp,"%d\n",ndump);
+  fprintf(fp,BIGINT_FORMAT_NL,ndump);
   fprintf(fp,"ITEM: BOX BOUNDS\n");
   fprintf(fp,"%g %g\n",boxxlo,boxxhi);
   fprintf(fp,"%g %g\n",boxylo,boxyhi);
   fprintf(fp,"%g %g\n",boxzlo,boxzhi);
   fprintf(fp,"ITEM: ATOMS %s\n",columns);
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpAtom::header_item_triclinic(int ndump)
+void DumpAtom::header_item_triclinic(bigint ndump)
 {
   fprintf(fp,"ITEM: TIMESTEP\n");
-  fprintf(fp,"%d\n",update->ntimestep);
+  fprintf(fp,BIGINT_FORMAT_NL,update->ntimestep);
   fprintf(fp,"ITEM: NUMBER OF ATOMS\n");
-  fprintf(fp,"%d\n",ndump);
+  fprintf(fp,BIGINT_FORMAT_NL,ndump);
   fprintf(fp,"ITEM: BOX BOUNDS xy xz yz\n");
   fprintf(fp,"%g %g %g\n",boxxlo,boxxhi,boxxy);
   fprintf(fp,"%g %g %g\n",boxylo,boxyhi,boxxz);
   fprintf(fp,"%g %g %g\n",boxzlo,boxzhi,boxyz);
   fprintf(fp,"ITEM: ATOMS %s\n",columns);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::pack_scale_image(int *ids)
 {
   int m,n;
 
   int *tag = atom->tag;
   int *type = atom->type;
   int *image = atom->image;
   int *mask = atom->mask;
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   double invxprd = 1.0/domain->xprd;
   double invyprd = 1.0/domain->yprd;
   double invzprd = 1.0/domain->zprd;
 
   m = n = 00;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       buf[m++] = tag[i];
       buf[m++] = type[i];
       buf[m++] = (x[i][0] - boxxlo) * invxprd;
       buf[m++] = (x[i][1] - boxylo) * invyprd;
       buf[m++] = (x[i][2] - boxzlo) * invzprd;
       buf[m++] = (image[i] & 1023) - 512;
       buf[m++] = (image[i] >> 10 & 1023) - 512;
       buf[m++] = (image[i] >> 20) - 512;
       if (ids) ids[n++] = tag[i];
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::pack_scale_noimage(int *ids)
 {
   int m,n;
 
   int *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   double invxprd = 1.0/domain->xprd;
   double invyprd = 1.0/domain->yprd;
   double invzprd = 1.0/domain->zprd;
   
   m = n = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       buf[m++] = tag[i];
       buf[m++] = type[i];
       buf[m++] = (x[i][0] - boxxlo) * invxprd;
       buf[m++] = (x[i][1] - boxylo) * invyprd;
       buf[m++] = (x[i][2] - boxzlo) * invzprd;
       if (ids) ids[n++] = tag[i];
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::pack_scale_image_triclinic(int *ids)
 {
   int m,n;
 
   int *tag = atom->tag;
   int *type = atom->type;
   int *image = atom->image;
   int *mask = atom->mask;
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   double lamda[3];
 
   m = n = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       buf[m++] = tag[i];
       buf[m++] = type[i];
       domain->x2lamda(x[i],lamda);
       buf[m++] = lamda[0];
       buf[m++] = lamda[1];
       buf[m++] = lamda[2];
       buf[m++] = (image[i] & 1023) - 512;
       buf[m++] = (image[i] >> 10 & 1023) - 512;
       buf[m++] = (image[i] >> 20) - 512;
       if (ids) ids[n++] = tag[i];
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::pack_scale_noimage_triclinic(int *ids)
 {
   int m,n;
 
   int *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   double lamda[3];
   
   m = n = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       buf[m++] = tag[i];
       buf[m++] = type[i];
       domain->x2lamda(x[i],lamda);
       buf[m++] = lamda[0];
       buf[m++] = lamda[1];
       buf[m++] = lamda[2];
       if (ids) ids[n++] = tag[i];
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::pack_noscale_image(int *ids)
 {
   int m,n;
 
   int *tag = atom->tag;
   int *type = atom->type;
   int *image = atom->image;
   int *mask = atom->mask;
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   m = n = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       buf[m++] = tag[i];
       buf[m++] = type[i];
       buf[m++] = x[i][0];
       buf[m++] = x[i][1];
       buf[m++] = x[i][2];
       buf[m++] = (image[i] & 1023) - 512;
       buf[m++] = (image[i] >> 10 & 1023) - 512;
       buf[m++] = (image[i] >> 20) - 512;
       if (ids) ids[n++] = tag[i];
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::pack_noscale_noimage(int *ids)
 {
   int m,n;
 
   int *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   m = n = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       buf[m++] = tag[i];
       buf[m++] = type[i];
       buf[m++] = x[i][0];
       buf[m++] = x[i][1];
       buf[m++] = x[i][2];
       if (ids) ids[n++] = tag[i];
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::write_binary(int n, double *mybuf)
 {
   n *= size_one;
   fwrite(&n,sizeof(int),1,fp);
   fwrite(mybuf,sizeof(double),n,fp);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::write_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]),
 	    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;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpAtom::write_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]),
 	    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 14f8e7524..0483a7d64 100644
--- a/src/dump_atom.h
+++ b/src/dump_atom.h
@@ -1,70 +1,70 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef DUMP_CLASS
 
 DumpStyle(atom,DumpAtom)
 
 #else
 
 #ifndef LMP_DUMP_ATOM_H
 #define LMP_DUMP_ATOM_H
 
 #include "dump.h"
 
 namespace LAMMPS_NS {
 
 class DumpAtom : public Dump {
  public:
   DumpAtom(LAMMPS *, int, char**);
 
  private:
   int scale_flag;            // 1 if atom coords are scaled, 0 if no
   int image_flag;            // 1 if append box count to atom coords, 0 if no
 
   char *columns;             // column labels
 
   void init_style();
   int modify_param(int, char **);
-  void write_header(int);
+  void write_header(bigint);
   int count();
   void pack(int *);
   void write_data(int, double *);
 
-  typedef void (DumpAtom::*FnPtrHeader)(int);
+  typedef void (DumpAtom::*FnPtrHeader)(bigint);
   FnPtrHeader header_choice;           // ptr to write header functions
-  void header_binary(int);
-  void header_binary_triclinic(int);
-  void header_item(int);
-  void header_item_triclinic(int);
+  void header_binary(bigint);
+  void header_binary_triclinic(bigint);
+  void header_item(bigint);
+  void header_item_triclinic(bigint);
 
   typedef void (DumpAtom::*FnPtrPack)(int *);
   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 *);
 
   typedef void (DumpAtom::*FnPtrData)(int, double *);
   FnPtrData write_choice;              // ptr to write data functions
   void write_binary(int, double *);
   void write_image(int, double *);
   void write_noimage(int, double *);
 };
 
 }
 
 #endif
 #endif
diff --git a/src/dump_cfg.cpp b/src/dump_cfg.cpp
index b11a5169b..924c09eaf 100755
--- a/src/dump_cfg.cpp
+++ b/src/dump_cfg.cpp
@@ -1,289 +1,291 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Liang Wan (Chinese Academy of Sciences)
 ------------------------------------------------------------------------- */
 
 #include "stdlib.h"
 #include "string.h"
 #include "dump_cfg.h"
 #include "atom.h"
 #include "domain.h"
 #include "comm.h"
 #include "modify.h"
 #include "compute.h"
 #include "input.h"
 #include "fix.h"
 #include "variable.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{INT,DOUBLE};  // same as in dump_custom.cpp
 
 /* ---------------------------------------------------------------------- */
 
 DumpCFG::DumpCFG(LAMMPS *lmp, int narg, char **arg) :
   DumpCustom(lmp, narg, arg)
 {
   if (narg < 10 ||
       strcmp(arg[5],"id") != 0 || strcmp(arg[6],"type") != 0 ||
       strcmp(arg[7],"xs") != 0 || strcmp(arg[8],"ys") != 0 ||
       strcmp(arg[9],"zs") != 0)
     error->all("Dump cfg arguments must start with 'id type xs ys zs'");
 
   ntypes = atom->ntypes;
   typenames = NULL;
 
   // arrays for data rearrangement
 
   rbuf = NULL;
   nchosen = nlines = 0;
 
   // setup auxiliary property name strings
   // convert 'X_ID[m]' (X=c,f,v) to 'ID_m'
 
   if (narg > 10) auxname = new char*[narg-10];
   else auxname = NULL;
 
   int i = 0;
   for (int iarg = 10; iarg < narg; iarg++, i++) {
     if (strncmp(arg[iarg],"c_",2) == 0 ||
 	strncmp(arg[iarg],"f_",2) == 0 ||
 	strncmp(arg[iarg],"v_",2) == 0) {
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Invalid keyword in dump cfg command");
 	*ptr = '\0';
 	*(ptr+2) = '\0';
 	auxname[i] = new char[strlen(suffix) + 3];
 	strcpy(auxname[i],suffix);
 	strcat(auxname[i],"_");
 	strcat(auxname[i],ptr+1);
       } else {
 	auxname[i] = new char[strlen(suffix) + 1];
 	strcpy(auxname[i],suffix);
       }
 
       delete [] suffix;
 
     } else {
       auxname[i] = new char[strlen(arg[iarg]) + 1];
       strcpy(auxname[i],arg[iarg]);
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 DumpCFG::~DumpCFG()
 {
   if (typenames) {
     for (int i = 1; i <= ntypes; i++) delete [] typenames[i];
     delete [] typenames;
   }
 
   if (rbuf) memory->destroy_2d_double_array(rbuf);
 
   if (auxname) {
     for (int i = 0; i < nfield-5; i++) delete [] auxname[i];
     delete [] auxname;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCFG::init_style()
 {
   if (multifile == 0)
     error->all("Dump in CFG format requires one snapshot per file");
 
   if (typenames == NULL) {
     typenames = new char*[ntypes+1];
     for (int itype = 1; itype <= ntypes; itype++) {
       typenames[itype] = new char[3];
       strcpy(typenames[itype],"C");
     }
     if (comm->me == 0)
       error->warning("All element names have been set to 'C' for dump cfg");
   }
 
   // setup format strings
 
   delete [] format;
   char *str;
   if (format_user) str = format_user;
   else str = format_default;
 
   int n = strlen(str) + 1;
   format = new char[n];
   strcpy(format,str);
 
   // tokenize the format string and add space at end of each format element
 
   char *ptr;
   for (int i = 0; i < size_one; i++) {
     if (i == 0) ptr = strtok(format," \0");
     else ptr = strtok(NULL," \0");
     delete [] vformat[i];
     vformat[i] = new char[strlen(ptr) + 2];
     strcpy(vformat[i],ptr);
     vformat[i] = strcat(vformat[i]," ");
   }
 
   // find current ptr for each compute,fix,variable
   // check that fix frequency is acceptable
 
   int icompute;
   for (int i = 0; i < ncompute; i++) {
     icompute = modify->find_compute(id_compute[i]);
     if (icompute < 0) error->all("Could not find dump cfg compute ID");
     compute[i] = modify->compute[icompute];
   }
 
   int ifix;
   for (int i = 0; i < nfix; i++) {
     ifix = modify->find_fix(id_fix[i]);
     if (ifix < 0) error->all("Could not find dump cfg fix ID");
     fix[i] = modify->fix[ifix];
     if (nevery % modify->fix[ifix]->peratom_freq)
       error->all("Dump cfg and fix not computed at compatible times");
   }
 
   int ivariable;
   for (int i = 0; i < nvariable; i++) {
     ivariable = input->variable->find(id_variable[i]);
     if (ivariable < 0) error->all("Could not find dump cfg variable name");
     variable[i] = ivariable;
   }
 
   // set index and check validity of region
 
   if (iregion >= 0) {
     iregion = domain->find_region(idregion);
     if (iregion == -1) error->all("Region ID for dump cfg does not exist");
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpCFG::write_header(int n)
+void DumpCFG::write_header(bigint n)
 {
   if (me == 0 || multiproc) {
-    fprintf(fp,"Number of particles = %d\n", n);
+    char str[64];
+    sprintf(str,"Number of particles = %s\n",BIGINT_FORMAT);
+    fprintf(fp,str,n);
     fprintf(fp,"A = 1.0 Angstrom (basic length-scale)\n");
     fprintf(fp,"H0(1,1) = %g A\n",domain->xprd);
     fprintf(fp,"H0(1,2) = 0 A \n");
     fprintf(fp,"H0(1,3) = 0 A \n");
     fprintf(fp,"H0(2,1) = %g A \n",domain->xy);
     fprintf(fp,"H0(2,2) = %g A\n",domain->yprd);
     fprintf(fp,"H0(2,3) = 0 A \n");
     fprintf(fp,"H0(3,1) = %g A \n",domain->xz);
     fprintf(fp,"H0(3,2) = %g A \n",domain->yz);
     fprintf(fp,"H0(3,3) = %g A\n",domain->zprd);
     fprintf(fp,".NO_VELOCITY.\n");
     fprintf(fp,"entry_count = %d\n",nfield-2);
     for (int i = 0; i < nfield-5; i++)
       fprintf(fp,"auxiliary[%d] = %s\n",i,auxname[i]);
   }
 
   // calculate total # of data lines to be written on a writing proc
 
   if (multiproc) nchosen = nmine;
   else MPI_Reduce(&nmine,&nchosen,1,MPI_INT,MPI_SUM,0,world);
 
   // allocate memory needed for data rearrangement on writing proc(s)
 
   if (multiproc || me == 0) {
     if (rbuf) memory->destroy_2d_double_array(rbuf);
     rbuf = memory->create_2d_double_array(nchosen,size_one,"dump:rbuf");
   }
 }
 
 /* ----------------------------------------------------------------------
    write data lines to file in a block-by-block style
    write head of block (mass & element name) only if has atoms of the type
 ------------------------------------------------------------------------- */
 
 void DumpCFG::write_data(int n, double *mybuf)
 {
   int i,j,m,itype;
   int tag_i,index;
   double *mass = atom->mass;
 
   // transfer data from buf to rbuf
   // if write by proc 0, transfer chunk by chunk
 
   for (i = 0, m = 0; i < n; i++) {
     for (j = 0; j < size_one; j++)
       rbuf[nlines][j] = mybuf[m++];
     nlines++;
   }
 
   //  write data lines in rbuf to file after transfer is done
   
   if (nlines == nchosen) {
     for (itype = 1; itype <= ntypes; itype++) {
       for (i = 0; i < nchosen; i++)
 	if (rbuf[i][1] == itype) break;
       if (i < nchosen) {
 	fprintf(fp,"%g\n",mass[itype]);
 	fprintf(fp,"%s\n",typenames[itype]);
 	for (; i < nchosen; i++) {
 	  if (rbuf[i][1] == itype) {
 	    for (j = 2; j < size_one; j++) {
 	      if (vtype[j] == INT)
 		fprintf(fp,vformat[j],static_cast<int> (rbuf[i][j]));
 	      else fprintf(fp,vformat[j],rbuf[i][j]);
 	    }
 	    fprintf(fp,"\n");
 	  }
 	}
       }
     }
     nlines = 0;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpCFG::modify_param2(int narg, char **arg)
 {
   if (strcmp(arg[0],"element") == 0) {
     if (narg != ntypes+1)
       error->all("Dump modify element names do not match atom types");
 
     if (typenames) {
       for (int i = 1; i <= ntypes; i++) delete [] typenames[i];
       delete [] typenames;
       typenames = NULL;
     }
 
     typenames = new char*[ntypes+1];
     for (int itype = 1; itype <= ntypes; itype++) {
       typenames[itype] = new char[3];
       if (strlen(arg[itype]) >= 3)
 	error->all("Illegal chemical element names");
       strcpy(typenames[itype],arg[itype]);
     }
     return ntypes+1;
 
   } else return 0;
 }
diff --git a/src/dump_cfg.h b/src/dump_cfg.h
index ca3cd4032..0467983f7 100755
--- a/src/dump_cfg.h
+++ b/src/dump_cfg.h
@@ -1,50 +1,50 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef DUMP_CLASS
 
 DumpStyle(cfg,DumpCFG)
 
 #else
 
 #ifndef LMP_DUMP_CFG_H
 #define LMP_DUMP_CFG_H
 
 #include "dump_custom.h"
 
 namespace LAMMPS_NS {
 
 class DumpCFG : public DumpCustom {
  public:
   DumpCFG(class LAMMPS *, int, char **);
   ~DumpCFG();
 
  private:
   int ntypes;                // # of atom types
   char **typenames;	     // array of element names for each type
   char **auxname;            // name strings of auxiliary properties
   int nchosen;               // # of lines to be written on a writing proc
   int nlines;                // # of lines transferred from buf to rbuf
   double **rbuf;             // buf of data lines for data lines rearrangement
 
   void init_style();
-  void write_header(int);
+  void write_header(bigint);
   void write_data(int, double *);
 
   int modify_param2(int, char **);
 };
 
 }
 
 #endif
 #endif
diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp
index c5058d89f..2ee551c1d 100644
--- a/src/dump_custom.cpp
+++ b/src/dump_custom.cpp
@@ -1,2295 +1,2294 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "dump_custom.h"
 #include "atom.h"
 #include "force.h"
 #include "domain.h"
 #include "region.h"
 #include "group.h"
 #include "input.h"
 #include "variable.h"
 #include "update.h"
 #include "modify.h"
 #include "compute.h"
 #include "fix.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 // customize by adding keyword
 // same list as in compute_property.cpp, also customize that command
 
 enum{ID,MOL,TYPE,MASS,
        X,Y,Z,XS,YS,ZS,XSTRI,YSTRI,ZSTRI,XU,YU,ZU,XUTRI,YUTRI,ZUTRI,IX,IY,IZ,
        VX,VY,VZ,FX,FY,FZ,
        Q,MUX,MUY,MUZ,RADIUS,OMEGAX,OMEGAY,OMEGAZ,ANGMOMX,ANGMOMY,ANGMOMZ,
        QUATW,QUATI,QUATJ,QUATK,TQX,TQY,TQZ,SPIN,ERADIUS,ERVEL,ERFORCE,
        COMPUTE,FIX,VARIABLE};
 enum{LT,LE,GT,GE,EQ,NEQ};
 enum{INT,DOUBLE};
 
 #define INVOKED_PERATOM 8
 
 /* ---------------------------------------------------------------------- */
 
 DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) :
   Dump(lmp, narg, arg)
 {
   if (narg == 5) error->all("No dump custom arguments specified");
 
   clearstep = 1;
 
   nevery = atoi(arg[3]);
 
   size_one = nfield = narg-5;
   pack_choice = new FnPtrPack[nfield];
   vtype = new int[nfield];
 
   iregion = -1;
   idregion = NULL;
   nthresh = 0;
   thresh_array = NULL;
   thresh_op = NULL;
   thresh_value = NULL;
 
   // computes, fixes, variables which the dump accesses
 
   field2index = (int *) memory->smalloc(nfield*sizeof(int),"dump:field2index");
   argindex = (int *) memory->smalloc(nfield*sizeof(int),"dump:argindex");
 
   ncompute = 0;
   id_compute = NULL;
   compute = NULL;
 
   nfix = 0;
   id_fix = NULL;
   fix = NULL;
 
   nvariable = 0;
   id_variable = NULL;
   variable = NULL;
   vbuf = NULL;
 
   // process attributes
 
   parse_fields(narg,arg);
 
   // atom selection arrays
 
   maxlocal = 0;
   choose = NULL;
   dchoose = NULL;
 
   // setup format strings
 
   vformat = new char*[size_one];
 
   format_default = new char[3*size_one+1];
   format_default[0] = '\0';
 
   for (int i = 0; i < size_one; i++) {
     if (vtype[i] == INT) format_default = strcat(format_default,"%d ");
     else format_default = strcat(format_default,"%g ");
     vformat[i] = NULL;
   }
 
   // setup column string
 
   int n = 0;
   for (int iarg = 5; iarg < narg; iarg++) n += strlen(arg[iarg]) + 2;
   columns = new char[n];
   columns[0] = '\0';
   for (int iarg = 5; iarg < narg; iarg++) {
     strcat(columns,arg[iarg]);
     strcat(columns," ");
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 DumpCustom::~DumpCustom()
 {
   delete [] pack_choice;
   delete [] vtype;
   memory->sfree(field2index);
   memory->sfree(argindex);
 
   delete [] idregion;
   memory->sfree(thresh_array);
   memory->sfree(thresh_op);
   memory->sfree(thresh_value);
 
   for (int i = 0; i < ncompute; i++) delete [] id_compute[i];
   memory->sfree(id_compute);
   delete [] compute;
 
   for (int i = 0; i < nfix; i++) delete [] id_fix[i];
   memory->sfree(id_fix);
   delete [] fix;
 
   for (int i = 0; i < nvariable; i++) delete [] id_variable[i];
   memory->sfree(id_variable);
   delete [] variable;
   for (int i = 0; i < nvariable; i++) memory->sfree(vbuf[i]);
   delete [] vbuf;
 
   memory->sfree(choose);
   memory->sfree(dchoose);
 
   for (int i = 0; i < size_one; i++) delete [] vformat[i];
   delete [] vformat;
 
   delete [] columns;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::init_style()
 {
   delete [] format;
   char *str;
   if (format_user) str = format_user;
   else str = format_default;
 
   int n = strlen(str) + 1;
   format = new char[n];
   strcpy(format,str);
 
   // tokenize the format string and add space at end of each format element
 
   char *ptr;
   for (int i = 0; i < size_one; i++) {
     if (i == 0) ptr = strtok(format," \0");
     else ptr = strtok(NULL," \0");
     delete [] vformat[i];
     vformat[i] = new char[strlen(ptr) + 2];
     strcpy(vformat[i],ptr);
     vformat[i] = strcat(vformat[i]," ");
   }
 
   // setup function ptrs
 
   if (binary && domain->triclinic == 0)
     header_choice = &DumpCustom::header_binary;
   else if (binary && domain->triclinic == 1)
     header_choice = &DumpCustom::header_binary_triclinic;
   else if (!binary && domain->triclinic == 0)
     header_choice = &DumpCustom::header_item;
   else if (!binary && domain->triclinic == 1)
     header_choice = &DumpCustom::header_item_triclinic;
 
   if (binary) write_choice = &DumpCustom::write_binary;
   else write_choice = &DumpCustom::write_text;
 
   // find current ptr for each compute,fix,variable
   // check that fix frequency is acceptable
 
   int icompute;
   for (int i = 0; i < ncompute; i++) {
     icompute = modify->find_compute(id_compute[i]);
     if (icompute < 0) error->all("Could not find dump custom compute ID");
     compute[i] = modify->compute[icompute];
   }
 
   int ifix;
   for (int i = 0; i < nfix; i++) {
     ifix = modify->find_fix(id_fix[i]);
     if (ifix < 0) error->all("Could not find dump custom fix ID");
     fix[i] = modify->fix[ifix];
     if (nevery % modify->fix[ifix]->peratom_freq)
       error->all("Dump custom and fix not computed at compatible times");
   }
 
   int ivariable;
   for (int i = 0; i < nvariable; i++) {
     ivariable = input->variable->find(id_variable[i]);
     if (ivariable < 0) error->all("Could not find dump custom variable name");
     variable[i] = ivariable;
   }
 
   // set index and check validity of region
 
   if (iregion >= 0) {
     iregion = domain->find_region(idregion);
     if (iregion == -1) error->all("Region ID for dump custom does not exist");
   }
 
   // open single file, one time only
 
   if (multifile == 0) openfile();
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpCustom::write_header(int ndump)
+void DumpCustom::write_header(bigint ndump)
 {
   if (multiproc) (this->*header_choice)(ndump);
   else if (me == 0) (this->*header_choice)(ndump);
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpCustom::header_binary(int ndump)
+void DumpCustom::header_binary(bigint ndump)
 {
-  fwrite(&update->ntimestep,sizeof(int),1,fp);
-  fwrite(&ndump,sizeof(int),1,fp);
+  fwrite(&update->ntimestep,sizeof(bigint),1,fp);
+  fwrite(&ndump,sizeof(bigint),1,fp);
   fwrite(&domain->triclinic,sizeof(int),1,fp);
   fwrite(&boxxlo,sizeof(double),1,fp);
   fwrite(&boxxhi,sizeof(double),1,fp);
   fwrite(&boxylo,sizeof(double),1,fp);
   fwrite(&boxyhi,sizeof(double),1,fp);
   fwrite(&boxzlo,sizeof(double),1,fp);
   fwrite(&boxzhi,sizeof(double),1,fp);
   fwrite(&size_one,sizeof(int),1,fp);
   if (multiproc) {
     int one = 1;
     fwrite(&one,sizeof(int),1,fp);
   } else fwrite(&nprocs,sizeof(int),1,fp);
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpCustom::header_binary_triclinic(int ndump)
+void DumpCustom::header_binary_triclinic(bigint ndump)
 {
-  fwrite(&update->ntimestep,sizeof(int),1,fp);
-  fwrite(&ndump,sizeof(int),1,fp);
+  fwrite(&update->ntimestep,sizeof(bigint),1,fp);
+  fwrite(&ndump,sizeof(bigint),1,fp);
   fwrite(&domain->triclinic,sizeof(int),1,fp);
   fwrite(&boxxlo,sizeof(double),1,fp);
   fwrite(&boxxhi,sizeof(double),1,fp);
   fwrite(&boxylo,sizeof(double),1,fp);
   fwrite(&boxyhi,sizeof(double),1,fp);
   fwrite(&boxzlo,sizeof(double),1,fp);
   fwrite(&boxzhi,sizeof(double),1,fp);
   fwrite(&boxxy,sizeof(double),1,fp);
   fwrite(&boxxz,sizeof(double),1,fp);
   fwrite(&boxyz,sizeof(double),1,fp);
   fwrite(&size_one,sizeof(int),1,fp);
   if (multiproc) {
     int one = 1;
     fwrite(&one,sizeof(int),1,fp);
   } else fwrite(&nprocs,sizeof(int),1,fp);
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpCustom::header_item(int ndump)
+void DumpCustom::header_item(bigint ndump)
 {
   fprintf(fp,"ITEM: TIMESTEP\n");
-  fprintf(fp,"%d\n",update->ntimestep);
+  fprintf(fp,BIGINT_FORMAT_NL,update->ntimestep);
   fprintf(fp,"ITEM: NUMBER OF ATOMS\n");
-  fprintf(fp,"%d\n",ndump);
+  fprintf(fp,BIGINT_FORMAT_NL,ndump);
   fprintf(fp,"ITEM: BOX BOUNDS\n");
   fprintf(fp,"%g %g\n",boxxlo,boxxhi);
   fprintf(fp,"%g %g\n",boxylo,boxyhi);
   fprintf(fp,"%g %g\n",boxzlo,boxzhi);
   fprintf(fp,"ITEM: ATOMS %s\n",columns);
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpCustom::header_item_triclinic(int ndump)
+void DumpCustom::header_item_triclinic(bigint ndump)
 {
   fprintf(fp,"ITEM: TIMESTEP\n");
-  fprintf(fp,"%d\n",update->ntimestep);
+  fprintf(fp,BIGINT_FORMAT_NL,update->ntimestep);
   fprintf(fp,"ITEM: NUMBER OF ATOMS\n");
-  fprintf(fp,"%d\n",ndump);
+  fprintf(fp,BIGINT_FORMAT_NL,ndump);
   fprintf(fp,"ITEM: BOX BOUNDS xy xz yz\n");
   fprintf(fp,"%g %g %g\n",boxxlo,boxxhi,boxxy);
   fprintf(fp,"%g %g %g\n",boxylo,boxyhi,boxxz);
   fprintf(fp,"%g %g %g\n",boxzlo,boxzhi,boxyz);
   fprintf(fp,"ITEM: ATOMS %s\n",columns);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpCustom::count()
 {
   int i;
 
   // grow choose and variable vbuf arrays if needed
 
   int nlocal = atom->nlocal;
   if (nlocal > maxlocal) {
     maxlocal = atom->nmax;
 
     memory->sfree(choose);
     memory->sfree(dchoose);
     choose = (int *) memory->smalloc(maxlocal*sizeof(int),"dump:choose");
     dchoose = (double *) 
       memory->smalloc(maxlocal*sizeof(double),"dump:dchoose");
 
     for (i = 0; i < nvariable; i++) {
       memory->sfree(vbuf[i]);
       vbuf[i] = (double *) 
 	memory->smalloc(maxlocal*sizeof(double),"dump:vbuf");
     }
   }
 
   // invoke Computes for per-atom quantities
 
   if (ncompute) {
-    int ntimestep = update->ntimestep;
     for (i = 0; i < ncompute; i++)
       if (!(compute[i]->invoked_flag & INVOKED_PERATOM)) {
 	compute[i]->compute_peratom();
 	compute[i]->invoked_flag |= INVOKED_PERATOM;
       }
   }
 
   // evaluate atom-style Variables for per-atom quantities
 
   if (nvariable)
     for (i = 0; i < nvariable; i++)
       input->variable->compute_atom(variable[i],igroup,vbuf[i],1,0);
   
   // choose all local atoms for output
 
   for (i = 0; i < nlocal; i++) choose[i] = 1;
   nmine = nlocal;
 
   // un-choose if not in group
 
   if (igroup) {
     int *mask = atom->mask;
     for (i = 0; i < nlocal; i++)
       if (!(mask[i] & groupbit)) {
 	choose[i] = 0;
 	nmine--;
       }
   }
 
   // un-choose if not in region
 
   if (iregion >= 0) {
     Region *region = domain->regions[iregion];
     double **x = atom->x;
     for (i = 0; i < nlocal; i++)
       if (choose[i] && region->match(x[i][0],x[i][1],x[i][2]) == 0) {
 	choose[i] = 0;
 	nmine--;
       }
   }
 
   // un-choose if any threshhold criterion isn't met
 
   if (nthresh) {
     double *ptr;
     double value;
     int nstride;
     int nlocal = atom->nlocal;
     
     for (int ithresh = 0; ithresh < nthresh; ithresh++) {
 
       // customize by adding to if statement
 
       if (thresh_array[ithresh] == ID) {
 	int *tag = atom->tag;
 	for (i = 0; i < nlocal; i++) dchoose[i] = tag[i];
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == MOL) {
 	if (!atom->molecule_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	int *molecule = atom->molecule;
 	for (i = 0; i < nlocal; i++) dchoose[i] = molecule[i];
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == TYPE) {
 	int *type = atom->type;
 	for (i = 0; i < nlocal; i++) dchoose[i] = type[i];
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == MASS) {
 	if (atom->rmass) {
 	  ptr = atom->rmass;
 	  nstride = 1;
 	} else {
 	  double *mass = atom->mass;
 	  int *type = atom->type;
 	  for (i = 0; i < nlocal; i++) dchoose[i] = mass[type[i]];
 	  ptr = dchoose;
 	  nstride = 1;
 	}
 
       } else if (thresh_array[ithresh] == X) {
 	ptr = &atom->x[0][0];
 	nstride = 3;
       } else if (thresh_array[ithresh] == Y) {
 	ptr = &atom->x[0][1];
 	nstride = 3;
       } else if (thresh_array[ithresh] == Z) {
 	ptr = &atom->x[0][2];
 	nstride = 3;
 
       } else if (thresh_array[ithresh] == XS) {
         double **x = atom->x;
 	double boxxlo = domain->boxlo[0];
 	double invxprd = 1.0/domain->xprd;
 	for (i = 0; i < nlocal; i++) 
 	  dchoose[i] = (x[i][0] - boxxlo) * invxprd;
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == YS) {
         double **x = atom->x;
 	double boxylo = domain->boxlo[1];
 	double invyprd = 1.0/domain->yprd;
 	for (i = 0; i < nlocal; i++) 
 	  dchoose[i] = (x[i][1] - boxylo) * invyprd;
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == ZS) {
         double **x = atom->x;
 	double boxzlo = domain->boxlo[2];
 	double invzprd = 1.0/domain->zprd;
 	for (i = 0; i < nlocal; i++) 
 	  dchoose[i] = (x[i][2] - boxzlo) * invzprd;
 	ptr = dchoose;
 	nstride = 1;
 
       } else if (thresh_array[ithresh] == XSTRI) {
         double **x = atom->x;
 	double *boxlo = domain->boxlo;
 	double *h_inv = domain->h_inv;
 	for (i = 0; i < nlocal; i++) 
 	  dchoose[i] = h_inv[0]*(x[i][0]-boxlo[0]) + 
 	    h_inv[5]*(x[i][1]-boxlo[1]) + h_inv[4]*(x[i][2]-boxlo[2]);
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == YSTRI) {
         double **x = atom->x;
 	double *boxlo = domain->boxlo;
 	double *h_inv = domain->h_inv;
 	for (i = 0; i < nlocal; i++) 
 	  dchoose[i] = h_inv[1]*(x[i][1]-boxlo[1]) + 
 	    h_inv[3]*(x[i][2]-boxlo[2]);
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == ZSTRI) {
         double **x = atom->x;
 	double *boxlo = domain->boxlo;
 	double *h_inv = domain->h_inv;
 	for (i = 0; i < nlocal; i++) 
 	  dchoose[i] = h_inv[2]*(x[i][2]-boxlo[2]);
 	ptr = dchoose;
 	nstride = 1;
 
       } else if (thresh_array[ithresh] == XU) {
         double **x = atom->x;
 	int *image = atom->image;
 	double xprd = domain->xprd;
 	for (i = 0; i < nlocal; i++) 
 	  dchoose[i] = x[i][0] + ((image[i] & 1023) - 512) * xprd;
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == YU) {
         double **x = atom->x;
 	int *image = atom->image;
 	double yprd = domain->yprd;
 	for (i = 0; i < nlocal; i++) 
 	  dchoose[i] = x[i][1] + ((image[i] >> 10 & 1023) - 512) * yprd;
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == ZU) {
         double **x = atom->x;
 	int *image = atom->image;
 	double zprd = domain->zprd;
 	for (i = 0; i < nlocal; i++) 
 	  dchoose[i] = x[i][2] + ((image[i] >> 20) - 512) * zprd;
 	ptr = dchoose;
 	nstride = 1;
 
       } else if (thresh_array[ithresh] == XUTRI) {
         double **x = atom->x;
 	int *image = atom->image;
 	double *h = domain->h;
 	int xbox,ybox,zbox;
 	for (i = 0; i < nlocal; i++) {
 	  xbox = (image[i] & 1023) - 512;
 	  ybox = (image[i] >> 10 & 1023) - 512;
 	  zbox = (image[i] >> 20) - 512;
 	  dchoose[i] = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
 	}
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == YUTRI) {
         double **x = atom->x;
 	int *image = atom->image;
 	double *h = domain->h;
 	int ybox,zbox;
 	for (i = 0; i < nlocal; i++) {
 	  ybox = (image[i] >> 10 & 1023) - 512;
 	  zbox = (image[i] >> 20) - 512;
 	  dchoose[i] = x[i][1] + h[1]*ybox + h[3]*zbox;
 	}
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == ZUTRI) {
         double **x = atom->x;
 	int *image = atom->image;
 	double *h = domain->h;
 	int zbox;
 	for (i = 0; i < nlocal; i++) {
 	  zbox = (image[i] >> 20) - 512;
 	  dchoose[i] = x[i][2] + h[2]*zbox;
 	}
 	ptr = dchoose;
 	nstride = 1;
 
       } else if (thresh_array[ithresh] == IX) {
 	int *image = atom->image;
 	for (i = 0; i < nlocal; i++)
 	  dchoose[i] = (image[i] & 1023) - 512;
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == IY) {
 	int *image = atom->image;
 	for (i = 0; i < nlocal; i++)
 	  dchoose[i] = (image[i] >> 10 & 1023) - 512;
 	ptr = dchoose;
 	nstride = 1;
       } else if (thresh_array[ithresh] == IZ) {
 	int *image = atom->image;
 	for (i = 0; i < nlocal; i++)
 	  dchoose[i] = (image[i] >> 20) - 512;
 	ptr = dchoose;
 	nstride = 1;
 
       } else if (thresh_array[ithresh] == VX) {
 	ptr = &atom->v[0][0];
 	nstride = 3;
       } else if (thresh_array[ithresh] == VY) {
 	ptr = &atom->v[0][1];
 	nstride = 3;
       } else if (thresh_array[ithresh] == VZ) {
 	ptr = &atom->v[0][2];
 	nstride = 3;
       } else if (thresh_array[ithresh] == FX) {
 	ptr = &atom->f[0][0];
 	nstride = 3;
       } else if (thresh_array[ithresh] == FY) {
 	ptr = &atom->f[0][1];
 	nstride = 3;
       } else if (thresh_array[ithresh] == FZ) {
 	ptr = &atom->f[0][2];
 	nstride = 3;
 
       } else if (thresh_array[ithresh] == Q) {
 	if (!atom->q_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = atom->q;
 	nstride = 1;
       } else if (thresh_array[ithresh] == MUX) {
 	if (!atom->mu_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->mu[0][0];
 	nstride = 3;
       } else if (thresh_array[ithresh] == MUY) {
 	if (!atom->mu_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->mu[0][1];
 	nstride = 3;
       } else if (thresh_array[ithresh] == MUZ) {
 	if (!atom->mu_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->mu[0][2];
 	nstride = 3;
 
       } else if (thresh_array[ithresh] == RADIUS) {
 	if (!atom->radius_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = atom->radius;
 	nstride = 1;
       } else if (thresh_array[ithresh] == OMEGAX) {
 	if (!atom->omega_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->omega[0][0];
 	nstride = 3;
       } else if (thresh_array[ithresh] == OMEGAY) {
 	if (!atom->omega_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->omega[0][1];
 	nstride = 3;
       } else if (thresh_array[ithresh] == OMEGAZ) {
 	if (!atom->omega_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->omega[0][2];
 	nstride = 3;
       } else if (thresh_array[ithresh] == ANGMOMX) {
 	if (!atom->angmom_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->angmom[0][0];
 	nstride = 3;
       } else if (thresh_array[ithresh] == ANGMOMY) {
 	if (!atom->angmom_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->angmom[0][1];
 	nstride = 3;
       } else if (thresh_array[ithresh] == ANGMOMZ) {
 	if (!atom->angmom_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->angmom[0][2];
 	nstride = 3;
 
       } else if (thresh_array[ithresh] == QUATW) {
 	if (!atom->quat_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->quat[0][0];
 	nstride = 4;
       } else if (thresh_array[ithresh] == QUATI) {
 	if (!atom->quat_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->quat[0][1];
 	nstride = 4;
       } else if (thresh_array[ithresh] == QUATJ) {
 	if (!atom->quat_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->quat[0][2];
 	nstride = 4;
       } else if (thresh_array[ithresh] == QUATK) {
 	if (!atom->quat_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->quat[0][3];
 	nstride = 4;
       } else if (thresh_array[ithresh] == TQX) {
 	if (!atom->torque_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->torque[0][0];
 	nstride = 3;
       } else if (thresh_array[ithresh] == TQY) {
 	if (!atom->torque_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->torque[0][1];
 	nstride = 3;
       } else if (thresh_array[ithresh] == TQZ) {
 	if (!atom->torque_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
 	ptr = &atom->torque[0][2];
 	nstride = 3;
 
       } else if (thresh_array[ithresh] == SPIN) {
 	if (!atom->spin_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
         int *spin = atom->spin;
         for (i = 0; i < nlocal; i++) dchoose[i] = spin[i];
         ptr = dchoose;
         nstride = 1;
       } else if (thresh_array[ithresh] == ERADIUS) {
 	if (!atom->eradius_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
         ptr = atom->eradius;
         nstride = 1;
       } else if (thresh_array[ithresh] == ERVEL) {
 	if (!atom->ervel_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
         ptr = atom->ervel;
         nstride = 1;
       } else if (thresh_array[ithresh] == ERFORCE) {
 	if (!atom->erforce_flag)
 	  error->all("Threshhold for an atom property that isn't allocated");
         ptr = atom->erforce;
         nstride = 1;				
 
       } else if (thresh_array[ithresh] == COMPUTE) {
 	i = nfield + ithresh;
 	if (argindex[i] == 0) {
 	  ptr = compute[field2index[i]]->vector_atom;
 	  nstride = 1;
 	} else {
 	  ptr = &compute[field2index[i]]->array_atom[0][argindex[i]-1];
 	  nstride = compute[field2index[i]]->size_peratom_cols;
 	}
 
       } else if (thresh_array[ithresh] == FIX) {
 	i = nfield + ithresh;
 	if (argindex[i] == 0) {
 	  ptr = fix[field2index[i]]->vector_atom;
 	  nstride = 1;
 	} else {
 	  ptr = &fix[field2index[i]]->array_atom[0][argindex[i]-1];
 	  nstride = fix[field2index[i]]->size_peratom_cols;
 	}
 
       } else if (thresh_array[ithresh] == VARIABLE) {
 	i = nfield + ithresh;
 	ptr = vbuf[field2index[i]];
 	nstride = 1;
       }
 
       // unselect atoms that don't meet threshhold criterion
 
       value = thresh_value[ithresh];
 
       if (thresh_op[ithresh] == LT) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
 	  if (choose[i] && *ptr >= value) {
 	    choose[i] = 0;
 	    nmine--;
 	  }
       } else if (thresh_op[ithresh] == LE) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
 	  if (choose[i] && *ptr > value) {
 	    choose[i] = 0;
 	    nmine--;
 	  }
       } else if (thresh_op[ithresh] == GT) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
 	  if (choose[i] && *ptr <= value) {
 	    choose[i] = 0;
 	    nmine--;
 	  }
       } else if (thresh_op[ithresh] == GE) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
 	  if (choose[i] && *ptr < value) {
 	    choose[i] = 0;
 	    nmine--;
 	  }
       } else if (thresh_op[ithresh] == EQ) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
 	  if (choose[i] && *ptr != value) {
 	    choose[i] = 0;
 	    nmine--;
 	  }
       } else if (thresh_op[ithresh] == NEQ) {
 	for (i = 0; i < nlocal; i++, ptr += nstride)
 	  if (choose[i] && *ptr == value) {
 	    choose[i] = 0;
 	    nmine--;
 	  }
       }
     }
   }
 
   return nmine;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack(int *ids)
 {
   for (int n = 0; n < size_one; n++) (this->*pack_choice[n])(n);
   if (ids) {
     int *tag = atom->tag;
     int nlocal = atom->nlocal;
     int n = 0;
     for (int i = 0; i < nlocal; i++)
       if (choose[i]) ids[n++] = tag[i];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::write_data(int n, double *mybuf)
 {
   (this->*write_choice)(n,mybuf);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::write_binary(int n, double *mybuf)
 {
   n *= size_one;
   fwrite(&n,sizeof(int),1,fp);
   fwrite(mybuf,sizeof(double),n,fp);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::write_text(int n, double *mybuf)
 {
   int i,j;
 
   int m = 0;
   for (i = 0; i < n; i++) {
     for (j = 0; j < size_one; j++) {
       if (vtype[j] == INT) fprintf(fp,vformat[j],static_cast<int> (mybuf[m]));
       else fprintf(fp,vformat[j],mybuf[m]);
       m++;
     }
     fprintf(fp,"\n");
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::parse_fields(int narg, char **arg)
 {
   // customize by adding to if statement
 
   int i;
   for (int iarg = 5; iarg < narg; iarg++) {
     i = iarg-5;
 
     if (strcmp(arg[iarg],"id") == 0) {
       pack_choice[i] = &DumpCustom::pack_id;
       vtype[i] = INT;
     } else if (strcmp(arg[iarg],"mol") == 0) {
       if (!atom->molecule_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_molecule;
       vtype[i] = INT;
     } else if (strcmp(arg[iarg],"type") == 0) {
       pack_choice[i] = &DumpCustom::pack_type;
       vtype[i] = INT;
     } else if (strcmp(arg[iarg],"mass") == 0) {
       pack_choice[i] = &DumpCustom::pack_mass;
       vtype[i] = DOUBLE;
 
     } else if (strcmp(arg[iarg],"x") == 0) {
       pack_choice[i] = &DumpCustom::pack_x;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"y") == 0) {
       pack_choice[i] = &DumpCustom::pack_y;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"z") == 0) {
       pack_choice[i] = &DumpCustom::pack_z;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"xs") == 0) {
       if (domain->triclinic) pack_choice[i] = &DumpCustom::pack_xs_triclinic;
       else pack_choice[i] = &DumpCustom::pack_xs;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"ys") == 0) {
       if (domain->triclinic) pack_choice[i] = &DumpCustom::pack_ys_triclinic;
       else pack_choice[i] = &DumpCustom::pack_ys;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"zs") == 0) {
       if (domain->triclinic) pack_choice[i] = &DumpCustom::pack_zs_triclinic;
       else pack_choice[i] = &DumpCustom::pack_zs;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"xu") == 0) {
       if (domain->triclinic) pack_choice[i] = &DumpCustom::pack_xu_triclinic;
       else pack_choice[i] = &DumpCustom::pack_xu;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"yu") == 0) {
       if (domain->triclinic) pack_choice[i] = &DumpCustom::pack_yu_triclinic;
       else pack_choice[i] = &DumpCustom::pack_yu;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"zu") == 0) {
       if (domain->triclinic) pack_choice[i] = &DumpCustom::pack_zu_triclinic;
       else pack_choice[i] = &DumpCustom::pack_zu;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"ix") == 0) {
       pack_choice[i] = &DumpCustom::pack_ix;
       vtype[i] = INT;
     } else if (strcmp(arg[iarg],"iy") == 0) {
       pack_choice[i] = &DumpCustom::pack_iy;
       vtype[i] = INT;
     } else if (strcmp(arg[iarg],"iz") == 0) {
       pack_choice[i] = &DumpCustom::pack_iz;
       vtype[i] = INT;
 
     } else if (strcmp(arg[iarg],"vx") == 0) {
       pack_choice[i] = &DumpCustom::pack_vx;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"vy") == 0) {
       pack_choice[i] = &DumpCustom::pack_vy;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"vz") == 0) {
       pack_choice[i] = &DumpCustom::pack_vz;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"fx") == 0) {
       pack_choice[i] = &DumpCustom::pack_fx;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"fy") == 0) {
       pack_choice[i] = &DumpCustom::pack_fy;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"fz") == 0) {
       pack_choice[i] = &DumpCustom::pack_fz;
       vtype[i] = DOUBLE;
 
     } else if (strcmp(arg[iarg],"q") == 0) {
       if (!atom->q_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_q;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"mux") == 0) {
       if (!atom->mu_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_mux;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"muy") == 0) {
       if (!atom->mu_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_muy;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"muz") == 0) {
       if (!atom->mu_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_muz;
       vtype[i] = DOUBLE;
 
     } else if (strcmp(arg[iarg],"radius") == 0) {
       if (!atom->radius_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_radius;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"omegax") == 0) {
       if (!atom->omega_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_omegax;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"omegay") == 0) {
       if (!atom->omega_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_omegay;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"omegaz") == 0) {
       if (!atom->omega_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_omegaz;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"angmomx") == 0) {
       if (!atom->angmom_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_angmomx;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"angmomy") == 0) {
       if (!atom->angmom_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_angmomy;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"angmomz") == 0) {
       if (!atom->angmom_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_angmomz;
       vtype[i] = DOUBLE;
 
     } else if (strcmp(arg[iarg],"quatw") == 0) {
       if (!atom->quat_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_quatw;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"quati") == 0) {
       if (!atom->quat_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_quati;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"quatj") == 0) {
       if (!atom->quat_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_quatj;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"quatk") == 0) {
       if (!atom->quat_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_quatk;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"tqx") == 0) {
       if (!atom->torque_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_tqx;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"tqy") == 0) {
       if (!atom->torque_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_tqy;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"tqz") == 0) {
       if (!atom->torque_flag)
 	error->all("Dumping an atom property that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_tqz;
       vtype[i] = DOUBLE;
 
     } else if (strcmp(arg[iarg],"spin") == 0) {
       if (!atom->spin_flag)
         error->all("Dumping an atom quantity that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_spin;
       vtype[i] = INT;
     } else if (strcmp(arg[iarg],"eradius") == 0) {
       if (!atom->eradius_flag)
         error->all("Dumping an atom quantity that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_eradius;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"ervel") == 0) {
       if (!atom->ervel_flag)
         error->all("Dumping an atom quantity that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_ervel;
       vtype[i] = DOUBLE;
     } else if (strcmp(arg[iarg],"erforce") == 0) {
       if (!atom->erforce_flag)
         error->all("Dumping an atom quantity that isn't allocated");
       pack_choice[i] = &DumpCustom::pack_erforce;
       vtype[i] = DOUBLE;
 
     // compute value = c_ID
     // if no trailing [], then arg is set to 0, else arg is int between []
 
     } else if (strncmp(arg[iarg],"c_",2) == 0) {
       pack_choice[i] = &DumpCustom::pack_compute;
       vtype[i] = DOUBLE;
 
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Invalid attribute in dump custom command");
 	argindex[i] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[i] = 0;
 
       n = modify->find_compute(suffix);
       if (n < 0) error->all("Could not find dump custom compute ID");
       if (modify->compute[n]->peratom_flag == 0)
 	error->all("Dump custom compute does not compute per-atom info");
       if (argindex[i] == 0 && modify->compute[n]->size_peratom_cols > 0)
 	error->all("Dump custom compute does not calculate per-atom vector");
       if (argindex[i] > 0 && modify->compute[n]->size_peratom_cols == 0)
 	error->all("Dump custom compute does not calculate per-atom array");
       if (argindex[i] > 0 && 
 	  argindex[i] > modify->compute[n]->size_peratom_cols)
 	error->all("Dump custom compute vector is accessed out-of-range");
 
       field2index[i] = add_compute(suffix);
       delete [] suffix;
       
     // fix value = f_ID
     // if no trailing [], then arg is set to 0, else arg is between []
 
     } else if (strncmp(arg[iarg],"f_",2) == 0) {
       pack_choice[i] = &DumpCustom::pack_fix;
       vtype[i] = DOUBLE;
 
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Invalid attribute in dump custom command");
 	argindex[i] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[i] = 0;
 
       n = modify->find_fix(suffix);
       if (n < 0) error->all("Could not find dump custom fix ID");
       if (modify->fix[n]->peratom_flag == 0)
 	error->all("Dump custom fix does not compute per-atom info");
       if (argindex[i] == 0 && modify->fix[n]->size_peratom_cols > 0)
 	error->all("Dump custom fix does not compute per-atom vector");
       if (argindex[i] > 0 && modify->fix[n]->size_peratom_cols == 0)
 	error->all("Dump custom fix does not compute per-atom array");
       if (argindex[i] > 0 && 
 	  argindex[i] > modify->fix[n]->size_peratom_cols)
 	error->all("Dump custom fix vector is accessed out-of-range");
 
       field2index[i] = add_fix(suffix);
       delete [] suffix;
 
     // variable value = v_name
 
     } else if (strncmp(arg[iarg],"v_",2) == 0) {
       pack_choice[i] = &DumpCustom::pack_variable;
       vtype[i] = DOUBLE;
 
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       argindex[i] = 0;
 
       n = input->variable->find(suffix);
       if (n < 0) error->all("Could not find dump custom variable name");
       if (input->variable->atomstyle(n) == 0)
 	error->all("Dump custom variable is not atom-style variable");
 
       field2index[i] = add_variable(suffix);
       delete [] suffix;
 
     } else error->all("Invalid attribute in dump custom command");
   }
 }
 
 /* ----------------------------------------------------------------------
    add Compute to list of Compute objects used by dump
    return index of where this Compute is in list
    if already in list, do not add, just return index, else add to list
 ------------------------------------------------------------------------- */
 
 int DumpCustom::add_compute(char *id)
 {
   int icompute;
   for (icompute = 0; icompute < ncompute; icompute++)
     if (strcmp(id,id_compute[icompute]) == 0) break;
   if (icompute < ncompute) return icompute;
   
   id_compute = (char **)
     memory->srealloc(id_compute,(ncompute+1)*sizeof(char *),"dump:id_compute");
   delete [] compute;
   compute = new Compute*[ncompute+1];
 
   int n = strlen(id) + 1;
   id_compute[ncompute] = new char[n];
   strcpy(id_compute[ncompute],id);
   ncompute++;
   return ncompute-1;
 }
 
 /* ----------------------------------------------------------------------
    add Fix to list of Fix objects used by dump
    return index of where this Fix is in list
    if already in list, do not add, just return index, else add to list
 ------------------------------------------------------------------------- */
 
 int DumpCustom::add_fix(char *id)
 {
   int ifix;
   for (ifix = 0; ifix < nfix; ifix++)
     if (strcmp(id,id_fix[ifix]) == 0) break;
   if (ifix < nfix) return ifix;
   
   id_fix = (char **)
     memory->srealloc(id_fix,(nfix+1)*sizeof(char *),"dump:id_fix");
   delete [] fix;
   fix = new Fix*[nfix+1];
 
   int n = strlen(id) + 1;
   id_fix[nfix] = new char[n];
   strcpy(id_fix[nfix],id);
   nfix++;
   return nfix-1;
 }
 
 /* ----------------------------------------------------------------------
    add Variable to list of Variables used by dump
    return index of where this Variable is in list
    if already in list, do not add, just return index, else add to list
 ------------------------------------------------------------------------- */
 
 int DumpCustom::add_variable(char *id)
 {
   int ivariable;
   for (ivariable = 0; ivariable < nvariable; ivariable++)
     if (strcmp(id,id_variable[ivariable]) == 0) break;
   if (ivariable < nvariable) return ivariable;
   
   id_variable = (char **)
     memory->srealloc(id_variable,(nvariable+1)*sizeof(char *),
 		     "dump:id_variable");
   delete [] variable;
   variable = new int[nvariable+1];
   delete [] vbuf;
   vbuf = new double*[nvariable+1];
   for (int i = 0; i <= nvariable; i++) vbuf[i] = NULL;
 
   int n = strlen(id) + 1;
   id_variable[nvariable] = new char[n];
   strcpy(id_variable[nvariable],id);
   nvariable++;
   return nvariable-1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpCustom::modify_param(int narg, char **arg)
 {
   if (strcmp(arg[0],"region") == 0) {
     if (narg < 2) error->all("Illegal dump_modify command");
     if (strcmp(arg[1],"none") == 0) iregion = -1;
     else {
       iregion = domain->find_region(arg[1]);
       if (iregion == -1) error->all("Dump_modify region ID does not exist");
       int n = strlen(arg[1]) + 1;
       idregion = new char[n];
       strcpy(idregion,arg[1]);
     }
     return 2;
     
   } else if (strcmp(arg[0],"thresh") == 0) {
     if (narg < 2) error->all("Illegal dump_modify command");
     if (strcmp(arg[1],"none") == 0) {
       if (nthresh) {
 	memory->sfree(thresh_array);
 	memory->sfree(thresh_op);
 	memory->sfree(thresh_value);
 	thresh_array = NULL;
 	thresh_op = NULL;
 	thresh_value = NULL;
       }
       nthresh = 0;
       return 2;
     }
     
     if (narg < 4) error->all("Illegal dump_modify command");
     
     // grow threshhold arrays
     
     thresh_array = (int *)
       memory->srealloc(thresh_array,(nthresh+1)*sizeof(int),
 		       "dump:thresh_array");
     thresh_op = (int *)
       memory->srealloc(thresh_op,(nthresh+1)*sizeof(int),
 		       "dump:thresh_op");
     thresh_value = (double *)
       memory->srealloc(thresh_value,(nthresh+1)*sizeof(double),
 		       "dump:thresh_value");
 
     // set attribute type of threshhold
     // customize by adding to if statement
     
     if (strcmp(arg[1],"id") == 0) thresh_array[nthresh] = ID;
     else if (strcmp(arg[1],"mol") == 0) thresh_array[nthresh] = MOL;
     else if (strcmp(arg[1],"type") == 0) thresh_array[nthresh] = TYPE;
     else if (strcmp(arg[1],"mass") == 0) thresh_array[nthresh] = MASS;
 
     else if (strcmp(arg[1],"x") == 0) thresh_array[nthresh] = X;
     else if (strcmp(arg[1],"y") == 0) thresh_array[nthresh] = Y;
     else if (strcmp(arg[1],"z") == 0) thresh_array[nthresh] = Z;
 
     else if (strcmp(arg[1],"xs") == 0 && domain->triclinic == 0)
       thresh_array[nthresh] = XS;
     else if (strcmp(arg[1],"xs") == 0 && domain->triclinic == 1)
       thresh_array[nthresh] = XSTRI;
     else if (strcmp(arg[1],"ys") == 0 && domain->triclinic == 0)
       thresh_array[nthresh] = YS;
     else if (strcmp(arg[1],"ys") == 0 && domain->triclinic == 1)
       thresh_array[nthresh] = YSTRI;
     else if (strcmp(arg[1],"zs") == 0 && domain->triclinic == 0)
       thresh_array[nthresh] = ZS;
     else if (strcmp(arg[1],"zs") == 0 && domain->triclinic == 1)
       thresh_array[nthresh] = ZSTRI;
 
     else if (strcmp(arg[1],"xu") == 0 && domain->triclinic == 0)
       thresh_array[nthresh] = XU;
     else if (strcmp(arg[1],"xu") == 0 && domain->triclinic == 1)
       thresh_array[nthresh] = XUTRI;
     else if (strcmp(arg[1],"yu") == 0 && domain->triclinic == 0)
       thresh_array[nthresh] = YU;
     else if (strcmp(arg[1],"yu") == 0 && domain->triclinic == 1)
       thresh_array[nthresh] = YUTRI;
     else if (strcmp(arg[1],"zu") == 0 && domain->triclinic == 0)
       thresh_array[nthresh] = ZU;
     else if (strcmp(arg[1],"zu") == 0 && domain->triclinic == 1)
       thresh_array[nthresh] = ZUTRI;
 
     else if (strcmp(arg[1],"ix") == 0) thresh_array[nthresh] = IX;
     else if (strcmp(arg[1],"iy") == 0) thresh_array[nthresh] = IY;
     else if (strcmp(arg[1],"iz") == 0) thresh_array[nthresh] = IZ;
     else if (strcmp(arg[1],"vx") == 0) thresh_array[nthresh] = VX;
     else if (strcmp(arg[1],"vy") == 0) thresh_array[nthresh] = VY;
     else if (strcmp(arg[1],"vz") == 0) thresh_array[nthresh] = VZ;
     else if (strcmp(arg[1],"fx") == 0) thresh_array[nthresh] = FX;
     else if (strcmp(arg[1],"fy") == 0) thresh_array[nthresh] = FY;
     else if (strcmp(arg[1],"fz") == 0) thresh_array[nthresh] = FZ;
 
     else if (strcmp(arg[1],"q") == 0) thresh_array[nthresh] = Q;
     else if (strcmp(arg[1],"mux") == 0) thresh_array[nthresh] = MUX;
     else if (strcmp(arg[1],"muy") == 0) thresh_array[nthresh] = MUY;
     else if (strcmp(arg[1],"muz") == 0) thresh_array[nthresh] = MUZ;
 
     else if (strcmp(arg[1],"radius") == 0) thresh_array[nthresh] = RADIUS;
     else if (strcmp(arg[1],"omegax") == 0) thresh_array[nthresh] = OMEGAX;
     else if (strcmp(arg[1],"omegay") == 0) thresh_array[nthresh] = OMEGAY;
     else if (strcmp(arg[1],"omegaz") == 0) thresh_array[nthresh] = OMEGAZ;
     else if (strcmp(arg[1],"angmomx") == 0) thresh_array[nthresh] = ANGMOMX;
     else if (strcmp(arg[1],"angmomy") == 0) thresh_array[nthresh] = ANGMOMY;
     else if (strcmp(arg[1],"angmomz") == 0) thresh_array[nthresh] = ANGMOMZ;
 
     else if (strcmp(arg[1],"quatw") == 0) thresh_array[nthresh] = QUATW;
     else if (strcmp(arg[1],"quati") == 0) thresh_array[nthresh] = QUATI;
     else if (strcmp(arg[1],"quatj") == 0) thresh_array[nthresh] = QUATJ;
     else if (strcmp(arg[1],"quatk") == 0) thresh_array[nthresh] = QUATK;
     else if (strcmp(arg[1],"tqx") == 0) thresh_array[nthresh] = TQX;
     else if (strcmp(arg[1],"tqy") == 0) thresh_array[nthresh] = TQY;
     else if (strcmp(arg[1],"tqz") == 0) thresh_array[nthresh] = TQZ;
 
     else if (strcmp(arg[1],"spin") == 0) thresh_array[nthresh] = SPIN;
     else if (strcmp(arg[1],"eradius") == 0) thresh_array[nthresh] = ERADIUS;
     else if (strcmp(arg[1],"ervel") == 0) thresh_array[nthresh] = ERVEL;
     else if (strcmp(arg[1],"erforce") == 0) thresh_array[nthresh] = ERFORCE;
 
     // compute value = c_ID
     // if no trailing [], then arg is set to 0, else arg is between []
     // must grow field2index and argindex arrays, since access is beyond nfield
 
     else if (strncmp(arg[1],"c_",2) == 0) {
       thresh_array[nthresh] = COMPUTE;
       field2index = (int *) memory->srealloc(field2index,
 					     (nfield+nthresh+1)*sizeof(int),
 					     "dump:field2index");
       argindex = (int *) memory->srealloc(argindex,
 					  (nfield+nthresh+1)*sizeof(int),
 					  "dump:argindex");
       int n = strlen(arg[1]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[1][2]);
     
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Invalid attribute in dump modify command");
 	argindex[nfield+nthresh] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[nfield+nthresh] = 0;
       
       n = modify->find_compute(suffix);
       if (n < 0) error->all("Could not find dump modify compute ID");
 
       if (modify->compute[n]->peratom_flag == 0)
 	error->all("Dump modify compute ID does not compute per-atom info");
       if (argindex[nfield+nthresh] == 0 && 
 	  modify->compute[n]->size_peratom_cols > 0)
 	error->all("Dump modify compute ID does not compute per-atom vector");
       if (argindex[nfield+nthresh] > 0 && 
 	  modify->compute[n]->size_peratom_cols == 0)
 	error->all("Dump modify compute ID does not compute per-atom array");
       if (argindex[nfield+nthresh] > 0 && 
 	  argindex[nfield+nthresh] > modify->compute[n]->size_peratom_cols)
 	error->all("Dump modify compute ID vector is not large enough");
 
       field2index[nfield+nthresh] = add_compute(suffix);
       delete [] suffix;
 
     // fix value = f_ID
     // if no trailing [], then arg is set to 0, else arg is between []
     // must grow field2index and argindex arrays, since access is beyond nfield
 
     } else if (strncmp(arg[1],"f_",2) == 0) {
       thresh_array[nthresh] = FIX;
       field2index = (int *) memory->srealloc(field2index,
 					     (nfield+nthresh+1)*sizeof(int),
 					     "dump:field2index");
       argindex = (int *) memory->srealloc(argindex,
 					  (nfield+nthresh+1)*sizeof(int),
 					  "dump:argindex");
       int n = strlen(arg[1]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[1][2]);
     
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Invalid attribute in dump modify command");
 	argindex[nfield+nthresh] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[nfield+nthresh] = 0;
       
       n = modify->find_fix(suffix);
       if (n < 0) error->all("Could not find dump modify fix ID");
 
       if (modify->fix[n]->peratom_flag == 0)
 	error->all("Dump modify fix ID does not compute per-atom info");
       if (argindex[nfield+nthresh] == 0 && 
 	  modify->fix[n]->size_peratom_cols > 0)
 	error->all("Dump modify fix ID does not compute per-atom vector");
       if (argindex[nfield+nthresh] > 0 && 
 	  modify->fix[n]->size_peratom_cols == 0)
 	error->all("Dump modify fix ID does not compute per-atom array");
       if (argindex[nfield+nthresh] > 0 && 
 	  argindex[nfield+nthresh] > modify->fix[n]->size_peratom_cols)
 	error->all("Dump modify fix ID vector is not large enough");
 
       field2index[nfield+nthresh] = add_fix(suffix);
       delete [] suffix;
 
     // variable value = v_ID
     // must grow field2index and argindex arrays, since access is beyond nfield
 
     } else if (strncmp(arg[1],"v_",2) == 0) {
       thresh_array[nthresh] = VARIABLE;
       field2index = (int *) memory->srealloc(field2index,
 					     (nfield+nthresh+1)*sizeof(int),
 					     "dump:field2index");
       argindex = (int *) memory->srealloc(argindex,
 					  (nfield+nthresh+1)*sizeof(int),
 					  "dump:argindex");
       int n = strlen(arg[1]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[1][2]);
     
       argindex[nfield+nthresh] = 0;
       
       n = input->variable->find(suffix);
       if (n < 0) error->all("Could not find dump modify variable name");
       if (input->variable->atomstyle(n) == 0)
 	error->all("Dump modify variable is not atom-style variable");
 
       field2index[nfield+nthresh] = add_variable(suffix);
       delete [] suffix;
 
     } else error->all("Invalid dump_modify threshhold operator");
 
     // set operation type of threshhold
 
     if (strcmp(arg[2],"<") == 0) thresh_op[nthresh] = LT;
     else if (strcmp(arg[2],"<=") == 0) thresh_op[nthresh] = LE;
     else if (strcmp(arg[2],">") == 0) thresh_op[nthresh] = GT;
     else if (strcmp(arg[2],">=") == 0) thresh_op[nthresh] = GE;
     else if (strcmp(arg[2],"==") == 0) thresh_op[nthresh] = EQ;
     else if (strcmp(arg[2],"!=") == 0) thresh_op[nthresh] = NEQ;
     else error->all("Invalid dump_modify threshhold operator");
 
     // set threshhold value
 
     thresh_value[nthresh] = atof(arg[3]);
 
     nthresh++;
     return 4;
 
   // pass along unknown params to child class
 
   } else {
     int n = modify_param2(narg,arg);
     return n;
   }
 
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory in buf, choose, variable arrays
 ------------------------------------------------------------------------- */
 
 double DumpCustom::memory_usage()
 {
   double bytes = Dump::memory_usage();
   bytes += maxlocal * sizeof(int);
   bytes += maxlocal * sizeof(double);
   bytes += maxlocal * nvariable * sizeof(double);
   return bytes;
 }
 
 /* ----------------------------------------------------------------------
    extraction of Compute, Fix, Variable results
 ------------------------------------------------------------------------- */
 
 void DumpCustom::pack_compute(int n)
 {
   double *vector = compute[field2index[n]]->vector_atom;
   double **array = compute[field2index[n]]->array_atom;
   int index = argindex[n];
   int nlocal = atom->nlocal;
 
   if (index == 0) {
     for (int i = 0; i < nlocal; i++)
       if (choose[i]) {
 	buf[n] = vector[i];
 	n += size_one;
       }
   } else {
     index--;
     for (int i = 0; i < nlocal; i++)
       if (choose[i]) {
 	buf[n] = array[i][index];
 	n += size_one;
       }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_fix(int n)
 {
   double *vector = fix[field2index[n]]->vector_atom;
   double **array = fix[field2index[n]]->array_atom;
   int index = argindex[n];
   int nlocal = atom->nlocal;
 
   if (index == 0) {
     for (int i = 0; i < nlocal; i++)
       if (choose[i]) {
 	buf[n] = vector[i];
 	n += size_one;
       }
   } else {
     index--;
     for (int i = 0; i < nlocal; i++)
       if (choose[i]) {
 	buf[n] = array[i][index];
 	n += size_one;
       }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_variable(int n)
 {
   double *vector = vbuf[field2index[n]];
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = vector[i];
       n += size_one;
     }
 }
 
 /* ----------------------------------------------------------------------
    one method for every attribute dump custom can output
    the atom property is packed into buf starting at n with stride size_one
    customize a new attribute by adding a method
 ------------------------------------------------------------------------- */
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_id(int n)
 {
   int *tag = atom->tag;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = tag[i];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_molecule(int n)
 {
   int *molecule = atom->molecule;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = molecule[i];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_type(int n)
 {
   int *type = atom->type;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = type[i];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_mass(int n)
 {
   int *type = atom->type;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   if (rmass) {
     for (int i = 0; i < nlocal; i++)
       if (choose[i]) {
 	buf[n] = rmass[i];
 	n += size_one;
       }
   } else {
     for (int i = 0; i < nlocal; i++)
       if (choose[i]) {
 	buf[n] = mass[type[i]];
 	n += size_one;
       }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_x(int n)
 {
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = x[i][0];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_y(int n)
 {
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = x[i][1];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_z(int n)
 {
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = x[i][2];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_xs(int n)
 {
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   double boxxlo = domain->boxlo[0];
   double invxprd = 1.0/domain->xprd;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = (x[i][0] - boxxlo) * invxprd;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_ys(int n)
 {
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   double boxylo = domain->boxlo[1];
   double invyprd = 1.0/domain->yprd;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = (x[i][1] - boxylo) * invyprd;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_zs(int n)
 {
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   double boxzlo = domain->boxlo[2];
   double invzprd = 1.0/domain->zprd;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = (x[i][2] - boxzlo) * invzprd;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_xs_triclinic(int n)
 {
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   double *boxlo = domain->boxlo;
   double *h_inv = domain->h_inv;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = h_inv[0]*(x[i][0]-boxlo[0]) + 
 	h_inv[5]*(x[i][1]-boxlo[1]) + h_inv[4]*(x[i][2]-boxlo[2]);
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_ys_triclinic(int n)
 {
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   double *boxlo = domain->boxlo;
   double *h_inv = domain->h_inv;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = h_inv[1]*(x[i][1]-boxlo[1]) + h_inv[3]*(x[i][2]-boxlo[2]);
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_zs_triclinic(int n)
 {
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   double *boxlo = domain->boxlo;
   double *h_inv = domain->h_inv;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = h_inv[2]*(x[i][2]-boxlo[2]);
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_xu(int n)
 {
   double **x = atom->x;
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   double xprd = domain->xprd;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = x[i][0] + ((image[i] & 1023) - 512) * xprd;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_yu(int n)
 {
   double **x = atom->x;
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   double yprd = domain->yprd;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = x[i][1] + ((image[i] >> 10 & 1023) - 512) * yprd;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_zu(int n)
 {
   double **x = atom->x;
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   double zprd = domain->zprd;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = x[i][2] + ((image[i] >> 20) - 512) * zprd;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_xu_triclinic(int n)
 {
   double **x = atom->x;
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   double *h = domain->h;
   int xbox,ybox,zbox;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       buf[n] = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_yu_triclinic(int n)
 {
   double **x = atom->x;
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   double *h = domain->h;
   int ybox,zbox;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       buf[n] = x[i][1] + h[1]*ybox + h[3]*zbox;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_zu_triclinic(int n)
 {
   double **x = atom->x;
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   double *h = domain->h;
   int zbox;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       zbox = (image[i] >> 20) - 512;
       buf[n] = x[i][2] + h[2]*zbox;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_ix(int n)
 {
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = (image[i] & 1023) - 512;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_iy(int n)
 {
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = (image[i] >> 10 & 1023) - 512;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_iz(int n)
 {
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = (image[i] >> 20) - 512;
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_vx(int n)
 {
   double **v = atom->v;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = v[i][0];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_vy(int n)
 {
   double **v = atom->v;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = v[i][1];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_vz(int n)
 {
   double **v = atom->v;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = v[i][2];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_fx(int n)
 {
   double **f = atom->f;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = f[i][0];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_fy(int n)
 {
   double **f = atom->f;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = f[i][1];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_fz(int n)
 {
   double **f = atom->f;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = f[i][2];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_q(int n)
 {
   double *q = atom->q;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = q[i];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_mux(int n)
 {
   double **mu = atom->mu;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = mu[i][0];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_muy(int n)
 {
   double **mu = atom->mu;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = mu[i][1];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_muz(int n)
 {
   double **mu = atom->mu;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = mu[i][2];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_radius(int n)
 {
   double *radius = atom->radius;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = radius[i];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_omegax(int n)
 {
   double **omega = atom->omega;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = omega[i][0];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_omegay(int n)
 {
   double **omega = atom->omega;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = omega[i][1];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_omegaz(int n)
 {
   double **omega = atom->omega;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = omega[i][2];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_angmomx(int n)
 {
   double **angmom = atom->angmom;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = angmom[i][0];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_angmomy(int n)
 {
   double **angmom = atom->angmom;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = angmom[i][1];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_angmomz(int n)
 {
   double **angmom = atom->angmom;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = angmom[i][2];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_quatw(int n)
 {
   double **quat = atom->quat;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = quat[i][0];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_quati(int n)
 {
   double **quat = atom->quat;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = quat[i][1];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_quatj(int n)
 {
   double **quat = atom->quat;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = quat[i][2];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_quatk(int n)
 {
   double **quat = atom->quat;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = quat[i][3];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_tqx(int n)
 {
   double **torque = atom->torque;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = torque[i][0];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_tqy(int n)
 {
   double **torque = atom->torque;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = torque[i][1];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_tqz(int n)
 {
   double **torque = atom->torque;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = torque[i][2];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_spin(int n)
 {
   int *spin = atom->spin;
   int nlocal = atom->nlocal;
   
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = spin[i];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_eradius(int n)
 {
   double *eradius = atom->eradius;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = eradius[i];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_ervel(int n)
 {
   double *ervel = atom->ervel;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = ervel[i];
       n += size_one;
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpCustom::pack_erforce(int n)
 {
   double *erforce = atom->erforce;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (choose[i]) {
       buf[n] = erforce[i];
       n += size_one;
     }
 }
diff --git a/src/dump_custom.h b/src/dump_custom.h
index 18be848f0..0f7913272 100644
--- a/src/dump_custom.h
+++ b/src/dump_custom.h
@@ -1,164 +1,164 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef DUMP_CLASS
 
 DumpStyle(custom,DumpCustom)
 
 #else
 
 #ifndef LMP_DUMP_CUSTOM_H
 #define LMP_DUMP_CUSTOM_H
 
 #include "dump.h"
 
 namespace LAMMPS_NS {
 
 class DumpCustom : public Dump {
  public:
   DumpCustom(class LAMMPS *, int, char **);
   virtual ~DumpCustom();
 
  protected:
   int nevery;                // dump frequency to check Fix against
   int iregion;               // -1 if no region, else which region
   char *idregion;            // region ID
   int nthresh;               // # of defined threshholds
   int *thresh_array;         // array to threshhhold on for each nthresh
   int *thresh_op;            // threshhold operation for each nthresh
   double *thresh_value;      // threshhold value for each nthresh
 
   int nmine;                 // # of lines I am dumping
   int *vtype;                // type of each vector (INT, DOUBLE)
   char **vformat;            // format string for each vector element
 
   char *columns;             // column labels
 
   int maxlocal;              // size of atom selection and variable arrays
   int *choose;               // 1 if output this atom, 0 if no
   double *dchoose;           // value for each atom to threshhold against
 
   int nfield;                // # of keywords listed by user
 
   int *field2index;          // which compute,fix,variable calcs this field
   int *argindex;             // index into compute,fix scalar_atom,vector_atom
                              // 0 for scalar_atom, 1-N for vector_atom values
 
   int ncompute;              // # of Compute objects used by dump
   char **id_compute;         // their IDs
   class Compute **compute;   // list of ptrs to the Compute objects
 
   int nfix;                  // # of Fix objects used by dump
   char **id_fix;             // their IDs
   class Fix **fix;           // list of ptrs to the Fix objects
 
   int nvariable;             // # of Variables used by dump
   char **id_variable;        // their names
   int *variable;             // list of indices for the Variables
   double **vbuf;             // local storage for variable evaluation
 
   // private methods
 
   virtual void init_style();
-  virtual void write_header(int);
+  virtual void write_header(bigint);
   int count();
   void pack(int *);
   virtual void write_data(int, double *);
   double memory_usage();
 
   void parse_fields(int, char **);
   int add_compute(char *);
   int add_fix(char *);
   int add_variable(char *);
   int modify_param(int, char **);
   virtual int modify_param2(int, char **) {return 0;}
 
-  typedef void (DumpCustom::*FnPtrHeader)(int);
+  typedef void (DumpCustom::*FnPtrHeader)(bigint);
   FnPtrHeader header_choice;           // ptr to write header functions
-  void header_binary(int);
-  void header_binary_triclinic(int);
-  void header_item(int);
-  void header_item_triclinic(int);
+  void header_binary(bigint);
+  void header_binary_triclinic(bigint);
+  void header_item(bigint);
+  void header_item_triclinic(bigint);
 
   typedef void (DumpCustom::*FnPtrData)(int, double *);
   FnPtrData write_choice;              // ptr to write data functions
   void write_binary(int, double *);
   void write_text(int, double *);
 
   // customize by adding a method prototype
 
   typedef void (DumpCustom::*FnPtrPack)(int);
   FnPtrPack *pack_choice;              // ptrs to pack functions
 
   void pack_id(int);
   void pack_molecule(int);
   void pack_type(int);
   void pack_mass(int);
 
   void pack_x(int);
   void pack_y(int);
   void pack_z(int);
   void pack_xs(int);
   void pack_ys(int);
   void pack_zs(int);
   void pack_xs_triclinic(int);
   void pack_ys_triclinic(int);
   void pack_zs_triclinic(int);
   void pack_xu(int);
   void pack_yu(int);
   void pack_zu(int);
   void pack_xu_triclinic(int);
   void pack_yu_triclinic(int);
   void pack_zu_triclinic(int);
   void pack_ix(int);
   void pack_iy(int);
   void pack_iz(int);
 
   void pack_vx(int);
   void pack_vy(int);
   void pack_vz(int);
   void pack_fx(int);
   void pack_fy(int);
   void pack_fz(int);
   void pack_q(int);
   void pack_mux(int);
   void pack_muy(int);
   void pack_muz(int);
   void pack_radius(int);
   void pack_omegax(int);
   void pack_omegay(int);
   void pack_omegaz(int);
   void pack_angmomx(int);
   void pack_angmomy(int);
   void pack_angmomz(int);
   void pack_quatw(int);
   void pack_quati(int);
   void pack_quatj(int);
   void pack_quatk(int);
   void pack_tqx(int);
   void pack_tqy(int);
   void pack_tqz(int);
   void pack_spin(int);
   void pack_eradius(int);
   void pack_ervel(int);
   void pack_erforce(int);
 
   void pack_compute(int);
   void pack_fix(int);
   void pack_variable(int);
 };
 
 }
 
 #endif
 #endif
diff --git a/src/dump_dcd.cpp b/src/dump_dcd.cpp
index 222b8dc4b..5235ccdf8 100644
--- a/src/dump_dcd.cpp
+++ b/src/dump_dcd.cpp
@@ -1,369 +1,371 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Naveen Michaud-Agrawal (Johns Hopkins U)
                         Axel Kohlmeyer (Temple U), support for groups
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "inttypes.h"
 #include "stdio.h"
 #include "time.h"
 #include "string.h"
 #include "dump_dcd.h"
 #include "lmptype.h"
 #include "domain.h"
 #include "atom.h"
 #include "update.h"
 #include "output.h"
 #include "group.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define NFILE_POS 8L
 #define NSTEP_POS 20L
 
 // necessary to set SEEK params b/c MPI-2 messes with these settings
 
 #ifndef SEEK_SET
 #define SEEK_SET        0
 #define SEEK_CUR        1
 #define SEEK_END        2
 #endif
 
 /* ---------------------------------------------------------------------- */
 
 static inline void fwrite_int32(FILE* fd, uint32_t i)
 {
   fwrite(&i,sizeof(uint32_t),1,fd);
 }
 
 /* ---------------------------------------------------------------------- */
 
 DumpDCD::DumpDCD(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg)
 {
   if (narg != 5) error->all("Illegal dump dcd command");
   if (binary || compressed || multifile || multiproc)
     error->all("Invalid dump dcd filename");
 
   size_one = 3;
   sort_flag = 1;
   sortcol = 0;
 
   unwrap_flag = 0;
   format_default = NULL;
     
   // allocate global array for atom coords
 
-  bigint n;
-  if (igroup == 0) n = static_cast<int> (atom->natoms);
-  else n = static_cast<int> (group->count(igroup));
-  if (n > MAXINT32) error->all("Too many atoms for dump dcd");
-  natoms = n;
+  bigint n = group->count(igroup);
+  if (n > MAXSMALLINT/sizeof(float)) error->all("Too many atoms for dump dcd");
+  natoms = static_cast<int> (n);
 
   coords = (float *) memory->smalloc(3*natoms*sizeof(float),"dump:coords");
   xf = &coords[0*natoms];
   yf = &coords[1*natoms];
   zf = &coords[2*natoms];
 
   openfile();
   headerflag = 0;
   nevery_save = 0;
   ntotal = 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 DumpDCD::~DumpDCD()
 {
   memory->sfree(coords);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpDCD::init_style()
 {
   if (sort_flag == 0 || sortcol != 0)
     error->all("Dump dcd requires sorting by atom ID");
 
   // check that dump frequency has not changed and is not a variable
 
   int idump;
   for (idump = 0; idump < output->ndump; idump++)
     if (strcmp(id,output->dump[idump]->id) == 0) break;
   if (output->every_dump[idump] == 0)
     error->all("Cannot use variable every setting for dump dcd");
 
   if (nevery_save == 0) nevery_save = output->every_dump[idump];
   else if (nevery_save != output->every_dump[idump])
     error->all("Cannot change dump_modify every for dump dcd");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpDCD::openfile()
 {
   if (me == 0) {
     fp = fopen(filename,"wb");
     if (fp == NULL) error->one("Cannot open dump file");
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpDCD::write_header(int n)
+void DumpDCD::write_header(bigint n)
 {
   if (n != natoms) error->all("Dump dcd of non-matching # of atoms");
+  if (update->ntimestep > MAXSMALLINT)
+    error->all("Too big a timestep for dump dcd");
 
   // first time, write header for entire file
 
   if (headerflag == 0) {
     if (me == 0) write_dcd_header("Written by LAMMPS");
     headerflag = 1;
     nframes = 0;
   }
 
   // dim[] = size and angle cosines of orthogonal or triclinic box
   // dim[0] = a = length of unit cell vector along x-axis
   // dim[1] = gamma = cosine of angle between a and b
   // dim[2] = b = length of unit cell vector in xy-plane
   // dim[3] = beta = cosine of angle between a and c
   // dim[4] = alpha = cosine of angle between b and c
   // dim[5] = c = length of final unit cell vector
   // 48 = 6 doubles
 
   double dim[6];
   if (domain->triclinic) {
     double *h = domain->h;
     double alen = h[0];
     double blen = sqrt(h[5]*h[5] + h[1]*h[1]);
     double clen = sqrt(h[4]*h[4] + h[3]*h[3] + h[2]*h[2]);
     dim[0] = alen;
     dim[2] = blen;
     dim[5] = clen;
     dim[4] = (h[5]*h[4] + h[1]*h[3]) / blen/clen; // alpha
     dim[3] = (h[0]*h[4]) / alen/clen;             // beta
     dim[1] = (h[0]*h[5]) / alen/blen;             // gamma
   } else {
     dim[0] = domain->xprd;
     dim[2] = domain->yprd;
     dim[5] = domain->zprd;
     dim[1] = dim[3] = dim[4] = 0.0;
   }
   
   if (me == 0) {
     uint32_t out_integer = 48;
     fwrite_int32(fp,out_integer);
     fwrite(dim,out_integer,1,fp); 
     fwrite_int32(fp,out_integer);
     if (flush_flag) fflush(fp);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpDCD::count()
 {
   if (igroup == 0) return atom->nlocal;
 
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int m = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) m++;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpDCD::pack(int *ids)
 {
   int m,n;
 
   int *tag = atom->tag;
   double **x = atom->x;
   int *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   m = n = 0;
   if (unwrap_flag) {
     double xprd = domain->xprd;
     double yprd = domain->yprd;
     double zprd = domain->zprd;
     double xy = domain->xy;
     double xz = domain->xz;
     double yz = domain->yz;
 
     for (int i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
 	int ix = (image[i] & 1023) - 512;
 	int iy = (image[i] >> 10 & 1023) - 512;
 	int iz = (image[i] >> 20) - 512;
 
 	if (domain->triclinic) {
 	  buf[m++] = x[i][0] + ix * xprd + iy * xy + iz * xz;
 	  buf[m++] = x[i][1] + iy * yprd + iz * yz;
 	  buf[m++] = x[i][2] + iz * zprd;
 	} else {
 	  buf[m++] = x[i][0] + ix * xprd;
 	  buf[m++] = x[i][1] + iy * yprd;
 	  buf[m++] = x[i][2] + iz * zprd;
 	}
 	ids[n++] = tag[i];
       }
     }
 
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	buf[m++] = x[i][0];
 	buf[m++] = x[i][1];
 	buf[m++] = x[i][2];
 	ids[n++] = tag[i];
       }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpDCD::write_data(int n, double *mybuf)
 {
   // copy buf atom coords into 3 global arrays
 
   int m = 0;
   for (int i = 0; i < n; i++) {
     xf[ntotal] = mybuf[m++];
     yf[ntotal] = mybuf[m++];
     zf[ntotal] = mybuf[m++];
     ntotal++;
   }
 
   // if last chunk of atoms in this snapshot, write global arrays to file
 
   if (ntotal == natoms) {
     write_frame();
     ntotal = 0;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpDCD::modify_param(int narg, char **arg)
 {
   if (strcmp(arg[0],"unwrap") == 0) {
     if (narg < 2) error->all("Illegal dump_modify command");
     if (strcmp(arg[1],"yes") == 0) unwrap_flag = 1;
     else if (strcmp(arg[1],"no") == 0) unwrap_flag = 0;
     else error->all("Illegal dump_modify command");
     return 2;
   }
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory in buf and global coords array
 ------------------------------------------------------------------------- */
 
 double DumpDCD::memory_usage()
 {
   double bytes = Dump::memory_usage();
   bytes += 3*natoms * sizeof(float);
   return bytes;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpDCD::write_frame()
 {
   // write coords
 
   uint32_t out_integer = natoms*sizeof(float);
   fwrite_int32(fp,out_integer);
   fwrite(xf,out_integer,1,fp);
   fwrite_int32(fp,out_integer);
   fwrite_int32(fp,out_integer);
   fwrite(yf,out_integer,1,fp);
   fwrite_int32(fp,out_integer);
   fwrite_int32(fp,out_integer);
   fwrite(zf,out_integer,1,fp);
   fwrite_int32(fp,out_integer);
   
   // update NFILE and NSTEP fields in DCD header
 
   nframes++;
   out_integer = nframes;
   fseek(fp,NFILE_POS,SEEK_SET);
   fwrite_int32(fp,out_integer);
   out_integer = update->ntimestep;
   fseek(fp,NSTEP_POS,SEEK_SET);
   fwrite_int32(fp,out_integer);
   fseek(fp,0,SEEK_END);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpDCD::write_dcd_header(const char *remarks)
 {
   uint32_t out_integer;
   float out_float;
   char title_string[200];
   time_t cur_time;
   struct tm *tmbuf;
 
+  int ntimestep = update->ntimestep;
+
   out_integer = 84;
   fwrite_int32(fp,out_integer);
   strcpy(title_string,"CORD");
   fwrite(title_string,4,1,fp);
   fwrite_int32(fp,0);                    // NFILE = # of snapshots in file
-  fwrite_int32(fp,update->ntimestep);    // START = timestep of first snapshot
+  fwrite_int32(fp,ntimestep);            // START = timestep of first snapshot
   fwrite_int32(fp,nevery_save);          // SKIP = interval between snapshots
-  fwrite_int32(fp,update->ntimestep);    // NSTEP = timestep of last snapshot
+  fwrite_int32(fp,ntimestep);            // NSTEP = timestep of last snapshot
   fwrite_int32(fp,0);			 // NAMD writes NSTEP or ISTART
   fwrite_int32(fp,0);
   fwrite_int32(fp,0);
   fwrite_int32(fp,0);
   fwrite_int32(fp,0);
   out_float = update->dt;
   fwrite(&out_float,sizeof(float),1,fp);
   fwrite_int32(fp,1);
   fwrite_int32(fp,0);
   fwrite_int32(fp,0);
   fwrite_int32(fp,0);
   fwrite_int32(fp,0);
   fwrite_int32(fp,0);
   fwrite_int32(fp,0);
   fwrite_int32(fp,0);
   fwrite_int32(fp,0);
   fwrite_int32(fp,24);                   // pretend to be Charmm version 24
   fwrite_int32(fp,84);
   fwrite_int32(fp,164);
   fwrite_int32(fp,2);
   strncpy(title_string,remarks,80);
   title_string[79] = '\0';
   fwrite(title_string,80,1,fp);
   cur_time=time(NULL);
   tmbuf=localtime(&cur_time);
   memset(title_string,' ',81);
   strftime(title_string,80,"REMARKS Created %d %B,%Y at %R",tmbuf);
   fwrite(title_string,80,1,fp);
   fwrite_int32(fp,164);
   fwrite_int32(fp,4);
   fwrite_int32(fp,natoms);                // number of atoms in each snapshot
   fwrite_int32(fp,4);
   if (flush_flag) fflush(fp);
 }
diff --git a/src/dump_dcd.h b/src/dump_dcd.h
index fc5e51668..c71f154ac 100644
--- a/src/dump_dcd.h
+++ b/src/dump_dcd.h
@@ -1,57 +1,57 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef DUMP_CLASS
 
 DumpStyle(dcd,DumpDCD)
 
 #else
 
 #ifndef LMP_DUMP_DCD_H
 #define LMP_DUMP_DCD_H
 
 #include "stdio.h"
 #include "dump.h"
 #include "inttypes.h"
 
 namespace LAMMPS_NS {
 
 class DumpDCD : public Dump {
  public:
   DumpDCD(LAMMPS *, int, char**);
   ~DumpDCD();
 
  private:
   int natoms,ntotal;
   int headerflag,nevery_save,nframes;
 
   float *coords,*xf,*yf,*zf;
   int unwrap_flag;            // 1 if atom coords are unwrapped, 0 if no
 
   void init_style();
   void openfile();
-  void write_header(int);
+  void write_header(bigint);
   int count();
   void pack(int *);
   void write_data(int, double *);
   int modify_param(int, char **);
   double memory_usage();
 
   void write_frame();
   void write_dcd_header(const char *);
 };
 
 }
 
 #endif
 #endif
diff --git a/src/dump_local.cpp b/src/dump_local.cpp
index c93beac71..0230a0ac1 100644
--- a/src/dump_local.cpp
+++ b/src/dump_local.cpp
@@ -1,473 +1,472 @@
 /* ----------------------------------------------------------------------
    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 "string.h"
 #include "stdlib.h"
 #include "dump_local.h"
 #include "atom.h"
 #include "modify.h"
 #include "fix.h"
 #include "compute.h"
 #include "domain.h"
 #include "update.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{INT,DOUBLE};
 
 #define INVOKED_LOCAL 16
 
 /* ---------------------------------------------------------------------- */
 
 DumpLocal::DumpLocal(LAMMPS *lmp, int narg, char **arg) : 
   Dump(lmp, narg, arg)
 {
   if (narg == 5) error->all("No dump local arguments specified");
 
   clearstep = 1;
 
   nevery = atoi(arg[3]);
 
   size_one = nfield = narg-5;
   pack_choice = new FnPtrPack[nfield];
   vtype = new int[nfield];
 
   // computes & fixes which the dump accesses
 
   field2index = new int[nfield];
   argindex = new int[nfield];
 
   ncompute = 0;
   id_compute = NULL;
   compute = NULL;
 
   nfix = 0;
   id_fix = NULL;
   fix = NULL;
 
   // process attributes
 
   parse_fields(narg,arg);
 
   // setup format strings
 
   vformat = new char*[size_one];
 
   format_default = new char[3*size_one+1];
   format_default[0] = '\0';
 
   for (int i = 0; i < size_one; i++) {
     if (vtype[i] == INT) format_default = strcat(format_default,"%d ");
     else format_default = strcat(format_default,"%g ");
     vformat[i] = NULL;
   }
 
   // setup column string
 
   int n = 0;
   for (int iarg = 5; iarg < narg; iarg++) n += strlen(arg[iarg]) + 2;
   columns = new char[n];
   columns[0] = '\0';
   for (int iarg = 5; iarg < narg; iarg++) {
     strcat(columns,arg[iarg]);
     strcat(columns," ");
   }
 
   // setup default label string
 
   char *str = "ENTRIES";
   n = strlen(str) + 1;
   label = new char[n];
   strcpy(label,str);
 }
 
 /* ---------------------------------------------------------------------- */
 
 DumpLocal::~DumpLocal()
 {
   delete [] pack_choice;
   delete [] vtype;
   delete [] field2index;
   delete [] argindex;
 
   for (int i = 0; i < ncompute; i++) delete [] id_compute[i];
   memory->sfree(id_compute);
   delete [] compute;
 
   for (int i = 0; i < nfix; i++) delete [] id_fix[i];
   memory->sfree(id_fix);
   delete [] fix;
 
   for (int i = 0; i < size_one; i++) delete [] vformat[i];
   delete [] vformat;
 
   delete [] columns;
   delete [] label;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpLocal::init_style()
 {
   if (sort_flag && sortcol == 0)
     error->all("Dump local cannot sort by atom ID");
 
   delete [] format;
   char *str;
   if (format_user) str = format_user;
   else str = format_default;
 
   int n = strlen(str) + 1;
   format = new char[n];
   strcpy(format,str);
 
   // tokenize the format string and add space at end of each format element
 
   char *ptr;
   for (int i = 0; i < size_one; i++) {
     if (i == 0) ptr = strtok(format," \0");
     else ptr = strtok(NULL," \0");
     delete [] vformat[i];
     vformat[i] = new char[strlen(ptr) + 2];
     strcpy(vformat[i],ptr);
     vformat[i] = strcat(vformat[i]," ");
   }
 
   // find current ptr for each compute,fix,variable
   // check that fix frequency is acceptable
 
   int icompute;
   for (int i = 0; i < ncompute; i++) {
     icompute = modify->find_compute(id_compute[i]);
     if (icompute < 0) error->all("Could not find dump local compute ID");
     compute[i] = modify->compute[icompute];
   }
 
   int ifix;
   for (int i = 0; i < nfix; i++) {
     ifix = modify->find_fix(id_fix[i]);
     if (ifix < 0) error->all("Could not find dump local fix ID");
     fix[i] = modify->fix[ifix];
     if (nevery % modify->fix[ifix]->local_freq)
       error->all("Dump local and fix not computed at compatible times");
   }
 
   // open single file, one time only
 
   if (multifile == 0) openfile();
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpLocal::modify_param(int narg, char **arg)
 {
   if (strcmp(arg[0],"label") == 0) {
     if (narg < 2) error->all("Illegal dump_modify command");
     delete [] label;
     int n = strlen(arg[1]) + 1;
     label = new char[n];
     strcpy(label,arg[1]);
     return 2;
   }
   return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpLocal::write_header(int ndump)
+void DumpLocal::write_header(bigint ndump)
 {
   if (me == 0) {
     fprintf(fp,"ITEM: TIMESTEP\n");
-    fprintf(fp,"%d\n",update->ntimestep);
+    fprintf(fp,BIGINT_FORMAT_NL,update->ntimestep);
     fprintf(fp,"ITEM: NUMBER OF %s\n",label);
-    fprintf(fp,"%d\n",ndump);
+    fprintf(fp,BIGINT_FORMAT_NL,ndump);
     fprintf(fp,"ITEM: %s %s\n",label,columns);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpLocal::count()
 {
   int i;
 
   // invoke Computes for local quantities
 
   if (ncompute) {
-    int ntimestep = update->ntimestep;
     for (i = 0; i < ncompute; i++) {
       if (!(compute[i]->invoked_flag & INVOKED_LOCAL)) {
 	compute[i]->compute_local();
 	compute[i]->invoked_flag |= INVOKED_LOCAL;
       }
     }
   }
 
   // nmine = # of local values I contribute
   // must be consistent for all input fields
 
   nmine = -1;
 
   int icompute;
   for (int i = 0; i < ncompute; i++) {
     if (nmine < 0) nmine = compute[i]->size_local_rows;
     else if (nmine != compute[i]->size_local_rows)
       error->one("Dump local count is not consistent across input fields");
   }
 
   int ifix;
   for (int i = 0; i < nfix; i++) {
     if (nmine < 0) nmine = fix[i]->size_local_rows;
     else if (nmine != fix[i]->size_local_rows)
       error->one("Dump local count is not consistent across input fields");
   }
 
   return nmine;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpLocal::pack(int *dummy)
 {
   for (int n = 0; n < size_one; n++) (this->*pack_choice[n])(n);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpLocal::write_data(int n, double *mybuf)
 {
   int i,j;
 
   int m = 0;
   for (i = 0; i < n; i++) {
     for (j = 0; j < size_one; j++) {
       if (vtype[j] == INT) fprintf(fp,vformat[j],static_cast<int> (mybuf[m]));
       else fprintf(fp,vformat[j],mybuf[m]);
       m++;
     }
     fprintf(fp,"\n");
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpLocal::parse_fields(int narg, char **arg)
 {
   int computefixflag = 0;
 
   // customize by adding to if statement
 
   int i;
   for (int iarg = 5; iarg < narg; iarg++) {
     i = iarg-5;
 
     if (strcmp(arg[iarg],"index") == 0) {
       pack_choice[i] = &DumpLocal::pack_index;
       vtype[i] = INT;
 
     // compute value = c_ID
     // if no trailing [], then arg is set to 0, else arg is int between []
 
     } else if (strncmp(arg[iarg],"c_",2) == 0) {
       computefixflag = 1;
       pack_choice[i] = &DumpLocal::pack_compute;
       vtype[i] = DOUBLE;
 
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Invalid attribute in dump local command");
 	argindex[i] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[i] = 0;
 
       n = modify->find_compute(suffix);
       if (n < 0) error->all("Could not find dump local compute ID");
       if (modify->compute[n]->local_flag == 0)
 	error->all("Dump local compute does not compute local info");
       if (argindex[i] == 0 && modify->compute[n]->size_local_cols > 0)
 	error->all("Dump local compute does not calculate local vector");
       if (argindex[i] > 0 && modify->compute[n]->size_local_cols == 0)
 	error->all("Dump local compute does not calculate local array");
       if (argindex[i] > 0 && 
 	  argindex[i] > modify->compute[n]->size_local_cols)
 	error->all("Dump local compute vector is accessed out-of-range");
 
       field2index[i] = add_compute(suffix);
       delete [] suffix;
       
     // fix value = f_ID
     // if no trailing [], then arg is set to 0, else arg is between []
 
     } else if (strncmp(arg[iarg],"f_",2) == 0) {
       computefixflag = 1;
       pack_choice[i] = &DumpLocal::pack_fix;
       vtype[i] = DOUBLE;
 
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Invalid attribute in dump local command");
 	argindex[i] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[i] = 0;
 
       n = modify->find_fix(suffix);
       if (n < 0) error->all("Could not find dump local fix ID");
       if (modify->fix[n]->local_flag == 0)
 	error->all("Dump local fix does not compute local info");
       if (argindex[i] == 0 && modify->fix[n]->size_local_cols > 0)
 	error->all("Dump local fix does not compute local vector");
       if (argindex[i] > 0 && modify->fix[n]->size_local_cols == 0)
 	error->all("Dump local fix does not compute local array");
       if (argindex[i] > 0 && 
 	  argindex[i] > modify->fix[n]->size_local_cols)
 	error->all("Dump local fix vector is accessed out-of-range");
 
       field2index[i] = add_fix(suffix);
       delete [] suffix;
 
     } else error->all("Invalid attribute in dump local command");
   }
 
   if (computefixflag == 0)
     error->all("Dump local attributes contain no compute or fix");
 }
 
 /* ----------------------------------------------------------------------
    add Compute to list of Compute objects used by dump
    return index of where this Compute is in list
    if already in list, do not add, just return index, else add to list
 ------------------------------------------------------------------------- */
 
 int DumpLocal::add_compute(char *id)
 {
   int icompute;
   for (icompute = 0; icompute < ncompute; icompute++)
     if (strcmp(id,id_compute[icompute]) == 0) break;
   if (icompute < ncompute) return icompute;
   
   id_compute = (char **)
     memory->srealloc(id_compute,(ncompute+1)*sizeof(char *),"dump:id_compute");
   delete [] compute;
   compute = new Compute*[ncompute+1];
 
   int n = strlen(id) + 1;
   id_compute[ncompute] = new char[n];
   strcpy(id_compute[ncompute],id);
   ncompute++;
   return ncompute-1;
 }
 
 /* ----------------------------------------------------------------------
    add Fix to list of Fix objects used by dump
    return index of where this Fix is in list
    if already in list, do not add, just return index, else add to list
 ------------------------------------------------------------------------- */
 
 int DumpLocal::add_fix(char *id)
 {
   int ifix;
   for (ifix = 0; ifix < nfix; ifix++)
     if (strcmp(id,id_fix[ifix]) == 0) break;
   if (ifix < nfix) return ifix;
   
   id_fix = (char **)
     memory->srealloc(id_fix,(nfix+1)*sizeof(char *),"dump:id_fix");
   delete [] fix;
   fix = new Fix*[nfix+1];
 
   int n = strlen(id) + 1;
   id_fix[nfix] = new char[n];
   strcpy(id_fix[nfix],id);
   nfix++;
   return nfix-1;
 }
 
 /* ----------------------------------------------------------------------
    extraction of Compute, Fix results
 ------------------------------------------------------------------------- */
 
 void DumpLocal::pack_compute(int n)
 {
   double *vector = compute[field2index[n]]->vector_local;
   double **array = compute[field2index[n]]->array_local;
   int ncount = compute[field2index[n]]->size_local_rows;
   int index = argindex[n];
 
   if (index == 0) {
     for (int i = 0; i < ncount; i++) {
       buf[n] = vector[i];
       n += size_one;
     }
   } else {
     index--;
     for (int i = 0; i < ncount; i++) {
       buf[n] = array[i][index];
       n += size_one;
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpLocal::pack_fix(int n)
 {
   double *vector = fix[field2index[n]]->vector_local;
   double **array = fix[field2index[n]]->array_local;
   int index = argindex[n];
 
   if (index == 0) {
     for (int i = 0; i < nmine; i++) {
       buf[n] = vector[i];
       n += size_one;
     }
   } else {
     index--;
     for (int i = 0; i < nmine; i++) {
       buf[n] = array[i][index];
       n += size_one;
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    one method for every attribute dump local can output
    the local value is packed into buf starting at n with stride size_one
    customize a new attribute by adding a method
 ------------------------------------------------------------------------- */
 
 /* ---------------------------------------------------------------------- */
 
 void DumpLocal::pack_index(int n)
 {
   int index;
   MPI_Scan(&nmine,&index,1,MPI_INT,MPI_SUM,world);
   index -= nmine;
 
   for (int i = 0; i < nmine; i++) {
     buf[n] = ++index;
     n += size_one;
   }
 }
diff --git a/src/dump_local.h b/src/dump_local.h
index 53173d791..cc2fedf96 100644
--- a/src/dump_local.h
+++ b/src/dump_local.h
@@ -1,80 +1,80 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef DUMP_CLASS
 
 DumpStyle(local,DumpLocal)
 
 #else
 
 #ifndef LMP_DUMP_LOCAL_H
 #define LMP_DUMP_LOCAL_H
 
 #include "dump.h"
 
 namespace LAMMPS_NS {
 
 class DumpLocal : public Dump {
  public:
   DumpLocal(LAMMPS *, int, char **);
   ~DumpLocal();
 
  private:
   int nevery;                // dump frequency to check Fix against
   char *label;               // string for dump file header
 
   int nmine;                 // # of lines I am dumping
   int *vtype;                // type of each vector (INT, DOUBLE)
   char **vformat;            // format string for each vector element
 
   char *columns;             // column labels
 
   int nfield;                // # of keywords listed by user
 
   int *field2index;          // which compute,fix,variable calcs this field
   int *argindex;             // index into compute,fix scalar_atom,vector_atom
                              // 0 for scalar_atom, 1-N for vector_atom values
 
   int ncompute;              // # of Compute objects used by dump
   char **id_compute;         // their IDs
   class Compute **compute;   // list of ptrs to the Compute objects
 
   int nfix;                  // # of Fix objects used by dump
   char **id_fix;             // their IDs
   class Fix **fix;           // list of ptrs to the Fix objects
 
   void init_style();
   int modify_param(int, char **);
-  void write_header(int);
+  void write_header(bigint);
   int count();
   void pack(int *);
   void write_data(int, double *);
 
   void parse_fields(int, char **);
   int add_compute(char *);
   int add_fix(char *);
 
   // customize by adding a method prototype
 
   typedef void (DumpLocal::*FnPtrPack)(int);
   FnPtrPack *pack_choice;              // ptrs to pack functions
 
   void pack_index(int);
   void pack_compute(int);
   void pack_fix(int);
 };
 
 }
 
 #endif
 #endif
diff --git a/src/dump_xyz.cpp b/src/dump_xyz.cpp
index 93d6294aa..06c0686e7 100644
--- a/src/dump_xyz.cpp
+++ b/src/dump_xyz.cpp
@@ -1,118 +1,118 @@
 /* ----------------------------------------------------------------------
    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 "string.h"
 #include "dump_xyz.h"
 #include "atom.h"
 #include "group.h"
 #include "error.h"
 #include "memory.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 DumpXYZ::DumpXYZ(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg)
 {
   if (narg != 5) error->all("Illegal dump xyz command");
   if (binary || multiproc) error->all("Invalid dump xyz filename");
 
   size_one = 5;
   sort_flag = 1;
   sortcol = 0;
 
   char *str = (char *) "%d %g %g %g";
   int n = strlen(str) + 1;
   format_default = new char[n];
   strcpy(format_default,str);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpXYZ::init_style()
 {
   delete [] format;
   char *str;
   if (format_user) str = format_user;
   else str = format_default;
 
   int n = strlen(str) + 2;
   format = new char[n];
   strcpy(format,str);
   strcat(format,"\n");
 
   // open single file, one time only
 
   if (multifile == 0) openfile();
 }
 
 /* ---------------------------------------------------------------------- */
 
-void DumpXYZ::write_header(int n)
+void DumpXYZ::write_header(bigint n)
 {
   if (me == 0) {
-    fprintf(fp,"%d\n",n);
+    fprintf(fp,BIGINT_FORMAT_NL,n);
     fprintf(fp,"Atoms\n");
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 int DumpXYZ::count()
 {
   if (igroup == 0) return atom->nlocal;
 
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int m = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) m++;
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpXYZ::pack(int *ids)
 {
   int m,n;
 
   int *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   m = n = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       buf[m++] = tag[i];
       buf[m++] = type[i];
       buf[m++] = x[i][0];
       buf[m++] = x[i][1];
       buf[m++] = x[i][2];
       if (ids) ids[n++] = tag[i];
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void DumpXYZ::write_data(int n, double *mybuf)
 {
   int m = 0;
   for (int i = 0; i < n; i++) {
     fprintf(fp,format,
 	    static_cast<int> (mybuf[m+1]),mybuf[m+2],mybuf[m+3],mybuf[m+4]);
     m += size_one;
   }
 }
diff --git a/src/dump_xyz.h b/src/dump_xyz.h
index b15580511..39e6d5d19 100644
--- a/src/dump_xyz.h
+++ b/src/dump_xyz.h
@@ -1,43 +1,43 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef DUMP_CLASS
 
 DumpStyle(xyz,DumpXYZ)
 
 #else
 
 #ifndef LMP_DUMP_XYZ_H
 #define LMP_DUMP_XYZ_H
 
 #include "dump.h"
 
 namespace LAMMPS_NS {
 
 class DumpXYZ : public Dump {
  public:
   DumpXYZ(class LAMMPS *, int, char**);
   ~DumpXYZ() {}
 	
  private:
   void init_style();
-  void write_header(int);
+  void write_header(bigint);
   int count();
   void pack(int *);
   void write_data(int, double *);
 };
 
 }
 
 #endif
 #endif
diff --git a/src/finish.cpp b/src/finish.cpp
index d45cf63b2..92496b5b9 100644
--- a/src/finish.cpp
+++ b/src/finish.cpp
@@ -1,657 +1,654 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "string.h"
 #include "stdio.h"
 #include "finish.h"
 #include "timer.h"
 #include "atom.h"
 #include "force.h"
 #include "kspace.h"
 #include "update.h"
 #include "min.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "neigh_request.h"
 #include "output.h"
 #include "memory.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 /* ---------------------------------------------------------------------- */
 
 Finish::Finish(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 void Finish::end(int flag)
 {
   int i,m,nneigh,nneighfull;
   int histo[10];
   int loopflag,minflag,prdflag,tadflag,timeflag,fftflag,histoflag,neighflag;
   double time,tmp,ave,max,min;
   double time_loop,time_other;
   bigint natoms;
 
   int me,nprocs;
   MPI_Comm_rank(world,&me);
   MPI_Comm_size(world,&nprocs);
 
   // choose flavors of statistical output
   // flag determines caller
   // flag = 0 = just loop summary
   // flag = 1 = dynamics or minimization
   // flag = 2 = PRD
   // flag = 3 = TAD
   
   loopflag = 1;
   minflag = prdflag = tadflag = timeflag = fftflag = histoflag = neighflag = 0;
 
   if (flag == 1) {
     if (update->whichflag == 2) minflag = 1;
     timeflag = histoflag = neighflag = 1;
     if (strstr(force->kspace_style,"pppm")) fftflag = 1;
   }
   if (flag == 2) prdflag = histoflag = neighflag = 1;
   if (flag == 3) tadflag = histoflag = neighflag = 1;
 
   // loop stats
 
   if (loopflag) {
     time_other = timer->array[TIME_LOOP] -
       (timer->array[TIME_PAIR] + timer->array[TIME_BOND] + 
        timer->array[TIME_KSPACE] + timer->array[TIME_NEIGHBOR] +
        timer->array[TIME_COMM] + timer->array[TIME_OUTPUT]);
     
     time_loop = timer->array[TIME_LOOP];
     MPI_Allreduce(&time_loop,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time_loop = tmp/nprocs;
 
     // overall loop time
     // use actual natoms, in case atoms were lost
 
     bigint nblocal = atom->nlocal;
-    MPI_Allreduce(&nblocal,&natoms,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+    MPI_Allreduce(&nblocal,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
     
     if (me == 0) {
-      if (screen) 
-	fprintf(screen,
-		"Loop time of %g on %d procs for %d steps with %lu atoms\n",
-		time_loop,nprocs,update->nsteps,natoms);
-      if (logfile)
-	fprintf(logfile,
-		"Loop time of %g on %d procs for %d steps with %lu atoms\n",
-		time_loop,nprocs,update->nsteps,natoms);
+      char str[128];
+      sprintf(str,"Loop time of %%g on %%d procs for %%d steps with %s atoms\n",
+	      BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,time_loop,nprocs,update->nsteps,natoms);
+      if (logfile) fprintf(logfile,str,time_loop,nprocs,update->nsteps,natoms);
     }
 
     if (time_loop == 0.0) time_loop = 1.0;
   }
 
   // minimization stats
 
   if (minflag) {
     if (me == 0) {
       if (screen) fprintf(screen,"\n");
       if (logfile) fprintf(logfile,"\n");
     }
 
     if (me == 0) {
       if (screen) {
 	fprintf(screen,"Minimization stats:\n");
 	fprintf(screen,"  Stopping criterion = %s\n",
 		update->minimize->stopstr);
 	fprintf(screen,"  Energy initial, next-to-last, final = \n"
 		"    %18.12g %18.12g %18.12g\n",
 		update->minimize->einitial,update->minimize->eprevious,
 		update->minimize->efinal);
 	fprintf(screen,"  Force two-norm initial, final = %g %g\n",
 		update->minimize->fnorm2_init,update->minimize->fnorm2_final);
 	fprintf(screen,"  Force max component initial, final = %g %g\n",
 		update->minimize->fnorminf_init,
 		update->minimize->fnorminf_final);
 	fprintf(screen,"  Final line search alpha, max atom move = %g %g\n",
 		update->minimize->alpha_final,
 		update->minimize->alpha_final*
 		update->minimize->fnorminf_final);
 	fprintf(screen,"  Iterations, force evaluations = %d %d\n",
 		update->minimize->niter,update->minimize->neval);
       }
       if (logfile) {
 	fprintf(logfile,"Minimization stats:\n");
 	fprintf(logfile,"  Stopping criterion = %s\n",
 		update->minimize->stopstr);
 	fprintf(logfile,"  Energy initial, next-to-last, final = \n"
 		"    %18.12g %18.12g %18.12g\n",
 		update->minimize->einitial,update->minimize->eprevious,
 		update->minimize->efinal);
 	fprintf(logfile,"  Force two-norm initial, final = %g %g\n",
 		update->minimize->fnorm2_init,update->minimize->fnorm2_final);
 	fprintf(logfile,"  Force max component initial, final = %g %g\n",
 		update->minimize->fnorminf_init,
 		update->minimize->fnorminf_final);
 	fprintf(logfile,"  Final line search alpha, max atom move = %g %g\n",
 		update->minimize->alpha_final,
 		update->minimize->alpha_final*
 		update->minimize->fnorminf_final);
 	fprintf(logfile,"  Iterations, force evaluations = %d %d\n",
 		update->minimize->niter,update->minimize->neval);
       }
     }
   }
 
   // PRD stats using PAIR,BOND,KSPACE for dephase,dynamics,quench
 
   if (prdflag) {
     if (me == 0) {
       if (screen) fprintf(screen,"\n");
       if (logfile) fprintf(logfile,"\n");
     }
 
     if (screen) fprintf(screen,"PRD stats:\n");
     if (logfile) fprintf(logfile,"PRD stats:\n");
 
     time = timer->array[TIME_PAIR];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"  Dephase  time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"  Dephase  time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
 
     time = timer->array[TIME_BOND];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"  Dynamics time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"  Dynamics time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
 
     time = timer->array[TIME_KSPACE];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"  Quench   time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"  Quench   time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
 
     time = time_other;
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"  Other    time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"  Other    time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
   }
 
   // TAD stats using PAIR,BOND,KSPACE for neb,dynamics,quench
 
   if (tadflag) {
     if (me == 0) {
       if (screen) fprintf(screen,"\n");
       if (logfile) fprintf(logfile,"\n");
     }
 
     if (screen) fprintf(screen,"TAD stats:\n");
     if (logfile) fprintf(logfile,"TAD stats:\n");
 
     time = timer->array[TIME_PAIR];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"  NEB      time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"  NEB      time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
 
     time = timer->array[TIME_BOND];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"  Dynamics time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"  Dynamics time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
 
     time = timer->array[TIME_KSPACE];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"  Quench   time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"  Quench   time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
 
 
     time = timer->array[TIME_COMM];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"  Comm     time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"  Comm     time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
 
 
     time = timer->array[TIME_OUTPUT];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"  Output   time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"  Output   time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
 
     time = time_other;
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"  Other    time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"  Other    time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
   }
 
   // timing breakdowns
 
   if (timeflag) {
     if (me == 0) {
       if (screen) fprintf(screen,"\n");
       if (logfile) fprintf(logfile,"\n");
     }
 
     time = timer->array[TIME_PAIR];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"Pair  time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"Pair  time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
 
     if (atom->molecular) {
       time = timer->array[TIME_BOND];
       MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
       time = tmp/nprocs;
       if (me == 0) {
 	if (screen) 
 	  fprintf(screen,"Bond  time (%%) = %g (%g)\n",
 		  time,time/time_loop*100.0);
 	if (logfile)
 	  fprintf(logfile,"Bond  time (%%) = %g (%g)\n",
 		  time,time/time_loop*100.0);
       }
     }
     
     if (force->kspace) {
       time = timer->array[TIME_KSPACE];
       MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
       time = tmp/nprocs;
       if (me == 0) {
 	if (screen) 
 	  fprintf(screen,"Kspce time (%%) = %g (%g)\n",
 		  time,time/time_loop*100.0);
 	if (logfile)
 	  fprintf(logfile,"Kspce time (%%) = %g (%g)\n",
 		  time,time/time_loop*100.0);
       }
     }
     
     time = timer->array[TIME_NEIGHBOR];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"Neigh time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"Neigh time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
     
     time = timer->array[TIME_COMM];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"Comm  time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"Comm  time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
     
     time = timer->array[TIME_OUTPUT];
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"Outpt time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"Outpt time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
     
     time = time_other;
     MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time = tmp/nprocs;
     if (me == 0) {
       if (screen) 
 	fprintf(screen,"Other time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
       if (logfile) 
 	fprintf(logfile,"Other time (%%) = %g (%g)\n",
 		time,time/time_loop*100.0);
     }
   }
   
   // FFT timing statistics
   // time3d,time1d = total time during run for 3d and 1d FFTs
 
   if (fftflag) {
     if (me == 0) {
       if (screen) fprintf(screen,"\n");
       if (logfile) fprintf(logfile,"\n");
     }
 
     int nsteps = update->nsteps;
 
     int nsample = 5;
     double time3d,time1d;
     force->kspace->timing(nsample,time3d,time1d);
     
     time3d = nsteps * time3d / nsample;
     MPI_Allreduce(&time3d,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time3d = tmp/nprocs;
     
     time1d = nsteps * time1d / nsample;
     MPI_Allreduce(&time1d,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time1d = tmp/nprocs;
     
     double time_kspace = timer->array[TIME_KSPACE];
     MPI_Allreduce(&time_kspace,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
     time_kspace = tmp/nprocs;
 
     double ntotal = 1.0 * force->kspace->nx_pppm *
       force->kspace->ny_pppm * force->kspace->nz_pppm;
     double nflops = 5.0 * ntotal * log(ntotal);
 
     double fraction,flop3,flop1;
     if (nsteps) {
       fraction = time3d/time_kspace*100.0;
       flop3 = nflops/1.0e9/(time3d/4.0/nsteps);
       flop1 = nflops/1.0e9/(time1d/4.0/nsteps);
     } else fraction = flop3 = flop1 = 0.0;
 
     if (me == 0) {
       if (screen) {
 	fprintf(screen,"FFT time (%% of Kspce) = %g (%g)\n",time3d,fraction);
 	fprintf(screen,"FFT Gflps 3d (1d only) = %g %g\n",flop3,flop1);
       }
       if (logfile) {
 	fprintf(logfile,"FFT time (%% of Kspce) = %g (%g)\n",time3d,fraction);
 	fprintf(logfile,"FFT Gflps 3d (1d only) = %g %g\n",flop3,flop1);
       }
     }
   }
 
   if (histoflag) {
     if (me == 0) {
       if (screen) fprintf(screen,"\n");
       if (logfile) fprintf(logfile,"\n");
     }
 
     tmp = atom->nlocal;
     stats(1,&tmp,&ave,&max,&min,10,histo);
     if (me == 0) {
       if (screen) {
 	fprintf(screen,"Nlocal:    %g ave %g max %g min\n",ave,max,min);
 	fprintf(screen,"Histogram:");
 	for (i = 0; i < 10; i++) fprintf(screen," %d",histo[i]);
 	fprintf(screen,"\n");
       }
       if (logfile) {
 	fprintf(logfile,"Nlocal:    %g ave %g max %g min\n",ave,max,min);
 	fprintf(logfile,"Histogram:");
 	for (i = 0; i < 10; i++) fprintf(logfile," %d",histo[i]);
 	fprintf(logfile,"\n");
       }
     }
     
     tmp = atom->nghost;
     stats(1,&tmp,&ave,&max,&min,10,histo);
     if (me == 0) {
       if (screen) {
 	fprintf(screen,"Nghost:    %g ave %g max %g min\n",ave,max,min);
 	fprintf(screen,"Histogram:");
 	for (i = 0; i < 10; i++) fprintf(screen," %d",histo[i]);
 	fprintf(screen,"\n");
       }
       if (logfile) {
 	fprintf(logfile,"Nghost:    %g ave %g max %g min\n",ave,max,min);
 	fprintf(logfile,"Histogram:");
 	for (i = 0; i < 10; i++) fprintf(logfile," %d",histo[i]);
 	fprintf(logfile,"\n");
       }
     }
     
     // find a non-skip neighbor list containing half the pairwise interactions
     // count neighbors in that list for stats purposes
     
     for (m = 0; m < neighbor->old_nrequest; m++)
       if ((neighbor->old_requests[m]->half || 
 	   neighbor->old_requests[m]->gran ||
 	   neighbor->old_requests[m]->respaouter ||
 	   neighbor->old_requests[m]->half_from_full) &&
 	  neighbor->old_requests[m]->skip == 0 &&
 	  neighbor->lists[m]->numneigh) break;
 
     nneigh = 0;
     if (m < neighbor->old_nrequest) {
       int inum = neighbor->lists[m]->inum;
       int *ilist = neighbor->lists[m]->ilist;
       int *numneigh = neighbor->lists[m]->numneigh;
       for (i = 0; i < inum; i++)
 	nneigh += numneigh[ilist[i]];
     }
     
     tmp = nneigh;
     stats(1,&tmp,&ave,&max,&min,10,histo);
     if (me == 0) {
       if (screen) {
 	fprintf(screen,"Neighs:    %g ave %g max %g min\n",ave,max,min);
 	fprintf(screen,"Histogram:");
 	for (i = 0; i < 10; i++) fprintf(screen," %d",histo[i]);
 	fprintf(screen,"\n");
       }
       if (logfile) {
 	fprintf(logfile,"Neighs:    %g ave %g max %g min\n",ave,max,min);
 	fprintf(logfile,"Histogram:");
 	for (i = 0; i < 10; i++) fprintf(logfile," %d",histo[i]);
 	fprintf(logfile,"\n");
       }
     }
     
     // find a non-skip neighbor list containing full pairwise interactions
     // count neighbors in that list for stats purposes
 
     for (m = 0; m < neighbor->old_nrequest; m++)
       if (neighbor->old_requests[m]->full &&
 	  neighbor->old_requests[m]->skip == 0) break;
     
     nneighfull = 0;
     if (m < neighbor->old_nrequest) {
       if (neighbor->lists[m]->numneigh > 0) {
 	int inum = neighbor->lists[m]->inum;
 	int *ilist = neighbor->lists[m]->ilist;
 	int *numneigh = neighbor->lists[m]->numneigh;
 	for (i = 0; i < inum; i++)
 	  nneighfull += numneigh[ilist[i]];
       }
 
       tmp = nneighfull;
       stats(1,&tmp,&ave,&max,&min,10,histo);
       if (me == 0) {
 	if (screen) {
 	  fprintf(screen,"FullNghs:  %g ave %g max %g min\n",ave,max,min);
 	  fprintf(screen,"Histogram:");
 	  for (i = 0; i < 10; i++) fprintf(screen," %d",histo[i]);
 	  fprintf(screen,"\n");
 	}
 	if (logfile) {
 	  fprintf(logfile,"FullNghs: %g ave %g max %g min\n",ave,max,min);
 	  fprintf(logfile,"Histogram:");
 	  for (i = 0; i < 10; i++) fprintf(logfile," %d",histo[i]);
 	  fprintf(logfile,"\n");
 	}
       }
     }
   }
 
   if (neighflag) {
     if (me == 0) {
       if (screen) fprintf(screen,"\n");
       if (logfile) fprintf(logfile,"\n");
     }
     
     tmp = MAX(nneigh,nneighfull);
     double nall;
     MPI_Allreduce(&tmp,&nall,1,MPI_DOUBLE,MPI_SUM,world);
     
     int nspec;
     double nspec_all;
     if (atom->molecular) {
       nspec = 0;
       for (i = 0; i < atom->nlocal; i++) nspec += atom->nspecial[i][2];
       tmp = nspec;
       MPI_Allreduce(&tmp,&nspec_all,1,MPI_DOUBLE,MPI_SUM,world);
     }
     
     if (me == 0) {
       if (screen) {
 	if (nall < 2.0e9) 
 	  fprintf(screen,
 		  "Total # of neighbors = %d\n",static_cast<int> (nall));
 	else fprintf(screen,"Total # of neighbors = %g\n",nall);
 	if (natoms > 0) fprintf(screen,"Ave neighs/atom = %g\n",nall/natoms);
 	if (atom->molecular && natoms > 0) 
 	  fprintf(screen,"Ave special neighs/atom = %g\n",nspec_all/natoms);
 	fprintf(screen,"Neighbor list builds = %d\n",neighbor->ncalls);
 	fprintf(screen,"Dangerous builds = %d\n",neighbor->ndanger);
       }
       if (logfile) {
 	if (nall < 2.0e9) 
 	  fprintf(logfile,
 		  "Total # of neighbors = %d\n",static_cast<int> (nall));
 	else fprintf(logfile,"Total # of neighbors = %g\n",nall);
 	if (natoms > 0) fprintf(logfile,"Ave neighs/atom = %g\n",nall/natoms);
 	if (atom->molecular && natoms > 0) 
 	  fprintf(logfile,"Ave special neighs/atom = %g\n",nspec_all/natoms);
 	fprintf(logfile,"Neighbor list builds = %d\n",neighbor->ncalls);
 	fprintf(logfile,"Dangerous builds = %d\n",neighbor->ndanger);
       }
     }
   }
   
   if (logfile) fflush(logfile);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Finish::stats(int n, double *data, 
 		   double *pave, double *pmax, double *pmin,
 		   int nhisto, int *histo)
 {
   int i,m;
   int *histotmp;
 
   double min = 1.0e20;
   double max = -1.0e20;
   double ave = 0.0;
   for (i = 0; i < n; i++) {
     ave += data[i];
     if (data[i] < min) min = data[i];
     if (data[i] > max) max = data[i];
   }
 
   int ntotal;
   MPI_Allreduce(&n,&ntotal,1,MPI_INT,MPI_SUM,world);
   double tmp;
   MPI_Allreduce(&ave,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
   ave = tmp/ntotal;
   MPI_Allreduce(&min,&tmp,1,MPI_DOUBLE,MPI_MIN,world);
   min = tmp;
   MPI_Allreduce(&max,&tmp,1,MPI_DOUBLE,MPI_MAX,world);
   max = tmp;
 
   for (i = 0; i < nhisto; i++) histo[i] = 0;
 
   double del = max - min;
   for (i = 0; i < n; i++) {
     if (del == 0.0) m = 0;
     else m = static_cast<int> ((data[i]-min)/del * nhisto);
     if (m > nhisto-1) m = nhisto-1;
     histo[m]++;
   }
 
   histotmp = (int *) memory->smalloc(nhisto*sizeof(int),"finish:histotmp");
   MPI_Allreduce(histo,histotmp,nhisto,MPI_INT,MPI_SUM,world);
   for (i = 0; i < nhisto; i++) histo[i] = histotmp[i];
   memory->sfree(histotmp);
 
   *pave = ave;
   *pmax = max;
   *pmin = min;
 }
diff --git a/src/fix.h b/src/fix.h
index b35653d64..c44cccfa2 100644
--- a/src/fix.h
+++ b/src/fix.h
@@ -1,170 +1,171 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_FIX_H
 #define LMP_FIX_H
 
 #include "pointers.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class Fix : protected Pointers {
  public:
   char *id,*style;
   int igroup,groupbit;
 
   int restart_global;            // 1 if Fix saves global state, 0 if not
   int restart_peratom;           // 1 if Fix saves peratom state, 0 if not
   int force_reneighbor;          // 1 if Fix forces reneighboring, 0 if not
   int box_change;                // 1 if Fix changes box, 0 if not
   int box_change_size;           // 1 if Fix changes box size, 0 if not
   int box_change_shape;          // 1 if Fix changes box shape, 0 if not
-  int next_reneighbor;           // next timestep to force a reneighboring
+  bigint next_reneighbor;        // next timestep to force a reneighboring
   int thermo_energy;             // 1 if fix_modify enabled ThEng, 0 if not
   int nevery;                    // how often to call an end_of_step fix
   int rigid_flag;                // 1 if Fix integrates rigid bodies, 0 if not
   int virial_flag;               // 1 if Fix contributes to virial, 0 if not
   int no_change_box;             // 1 if cannot swap ortho <-> triclinic
   int time_integrate;            // 1 if fix performs time integration, 0 if no
   int time_depend;               // 1 if fix is timestep dependent, 0 if not
   int create_attribute;          // 1 if fix stores attributes that need
                                  //      setting when a new atom is created
   int restart_pbc;               // 1 if fix moves atoms (except integrate)
                                  //      so write_restart must remap to PBC
 
   int scalar_flag;               // 0/1 if compute_scalar() function exists
   int vector_flag;               // 0/1 if compute_vector() function exists
   int array_flag;                // 0/1 if compute_array() function exists
   int size_vector;               // length of global vector
   int size_array_rows;           // rows in global array
   int size_array_cols;           // columns in global array
   int global_freq;               // frequency s/v data is available at
 
   int peratom_flag;              // 0/1 if per-atom data is stored
   int size_peratom_cols;         // 0 = vector, N = columns in peratom array
   int peratom_freq;              // frequency per-atom data is available at
 
   int local_flag;                // 0/1 if local data is stored
   int size_local_rows;           // rows in local vector or array
   int size_local_cols;           // 0 = vector, N = columns in local array
   int local_freq;                // frequency local data is available at
 
   int extscalar;            // 0/1 if global scalar is intensive/extensive
   int extvector;            // 0/1/-1 if global vector is all int/ext/extlist
   int *extlist;             // list of 0/1 int/ext for each vec component
   int extarray;             // 0/1 if global array is intensive/extensive
 
   double *vector_atom;           // computed per-atom vector
   double **array_atom;           // computed per-atom array
   double *vector_local;          // computed local vector
   double **array_local;          // computed local array
 
   int comm_forward;              // size of forward communication (0 if none)
   int comm_reverse;              // size of reverse communication (0 if none)
 
   double virial[6];              // accumlated virial
   double **vatom;                // accumulated per-atom virial
 
   int INITIAL_INTEGRATE,POST_INTEGRATE;    // mask settings
   int PRE_EXCHANGE,PRE_NEIGHBOR;
   int PRE_FORCE,POST_FORCE,FINAL_INTEGRATE,END_OF_STEP,THERMO_ENERGY;
   int INITIAL_INTEGRATE_RESPA,POST_INTEGRATE_RESPA;
   int PRE_FORCE_RESPA,POST_FORCE_RESPA,FINAL_INTEGRATE_RESPA;
   int MIN_PRE_EXCHANGE,MIN_PRE_FORCE,MIN_POST_FORCE,MIN_ENERGY;
   int POST_RUN;
 
   Fix(class LAMMPS *, int, char **);
   virtual ~Fix();
   void modify_params(int, char **);
 
   virtual int setmask() = 0;
 
   virtual void init() {}
   virtual void init_list(int, class NeighList *) {}
   virtual void setup(int) {}
   virtual void setup_pre_force(int) {}
   virtual void min_setup(int) {}
   virtual void initial_integrate(int) {}
   virtual void post_integrate() {}
   virtual void pre_exchange() {}
   virtual void pre_neighbor() {}
   virtual void pre_force(int) {}
   virtual void post_force(int) {}
   virtual void final_integrate() {}
   virtual void end_of_step() {}
   virtual void post_run() {}
   virtual void write_restart(FILE *) {}
   virtual void restart(char *) {}
 
   virtual void grow_arrays(int) {}
   virtual void copy_arrays(int, int) {}
   virtual void set_arrays(int) {}
   virtual int pack_exchange(int, double *) {return 0;}
   virtual int unpack_exchange(int, double *) {return 0;}
   virtual int pack_restart(int, double *) {return 0;}
   virtual void unpack_restart(int, int) {}
   virtual int size_restart(int) {return 0;}
   virtual int maxsize_restart() {return 0;}
 
   virtual void setup_pre_force_respa(int, int) {}
   virtual void initial_integrate_respa(int, int, int) {}
   virtual void post_integrate_respa(int, int) {}
   virtual void pre_force_respa(int, int, int) {}
   virtual void post_force_respa(int, int, int) {}
   virtual void final_integrate_respa(int, int) {}
 
   virtual void min_setup_pre_force(int) {}
   virtual void min_pre_exchange() {}
   virtual void min_pre_force(int) {}
   virtual void min_post_force(int) {}
 
   virtual double min_energy(double *) {return 0.0;}
   virtual void min_store() {}
   virtual void min_clearstore() {}
   virtual void min_pushstore() {}
   virtual void min_popstore() {}
   virtual int min_reset_ref() {return 0;}
   virtual void min_step(double, double *) {}
   virtual double max_alpha(double *) {return 0.0;}
   virtual int min_dof() {return 0;}
 
   virtual int pack_comm(int, int *, double *, int, int *) {return 0;}
   virtual void unpack_comm(int, int, double *) {}
   virtual int pack_reverse_comm(int, int, double *) {return 0;}
   virtual void unpack_reverse_comm(int, int *, double *) {}
 
   virtual double compute_scalar() {return 0.0;}
   virtual double compute_vector(int) {return 0.0;}
   virtual double compute_array(int,int) {return 0.0;}
 
   virtual int dof(int) {return 0;}
   virtual void deform(int) {}
   virtual void reset_target(double) {}
   virtual void reset_dt() {}
 
   virtual int modify_param(int, char **) {return 0;}
 
   virtual double memory_usage() {return 0.0;}
 
  protected:
   int evflag;
   int vflag_global,vflag_atom;
   int maxvatom;
 
   void v_setup(int);
   void v_tally(int, int *, double, double *);
 };
 
 }
 
 #endif
diff --git a/src/fix_ave_atom.cpp b/src/fix_ave_atom.cpp
index eb8cf19b2..ef7de11d3 100644
--- a/src/fix_ave_atom.cpp
+++ b/src/fix_ave_atom.cpp
@@ -1,447 +1,448 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "string.h"
 #include "fix_ave_atom.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "update.h"
 #include "modify.h"
 #include "compute.h"
 #include "input.h"
 #include "variable.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{X,V,F,COMPUTE,FIX,VARIABLE};
 
 #define INVOKED_PERATOM 8
 
 /* ---------------------------------------------------------------------- */
 
 FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 7) error->all("Illegal fix ave/atom command");
 
   time_depend = 1;
 
   nevery = atoi(arg[3]);
   nrepeat = atoi(arg[4]);
   peratom_freq = atoi(arg[5]);
 
   // parse remaining values
 
   which = new int[narg-6];
   argindex = new int[narg-6];
   ids = new char*[narg-6];
   value2index = new int[narg-6];
   nvalues = 0;
 
   int iarg = 6;
   while (iarg < narg) {
     ids[nvalues] = NULL;
 
     if (strcmp(arg[iarg],"x") == 0) {
       which[nvalues] = X;
       argindex[nvalues++] = 0;
     } else if (strcmp(arg[iarg],"y") == 0) {
       which[nvalues] = X;
       argindex[nvalues++] = 1;
     } else if (strcmp(arg[iarg],"z") == 0) {
       which[nvalues] = X;
       argindex[nvalues++] = 2;
 
     } else if (strcmp(arg[iarg],"vx") == 0) {
       which[nvalues] = V;
       argindex[nvalues++] = 0;
     } else if (strcmp(arg[iarg],"vy") == 0) {
       which[nvalues] = V;
       argindex[nvalues++] = 1;
     } else if (strcmp(arg[iarg],"vz") == 0) {
       which[nvalues] = V;
       argindex[nvalues++] = 2;
 
     } else if (strcmp(arg[iarg],"fx") == 0) {
       which[nvalues] = F;
       argindex[nvalues++] = 0;
     } else if (strcmp(arg[iarg],"fy") == 0) {
       which[nvalues] = F;
       argindex[nvalues++] = 1;
     } else if (strcmp(arg[iarg],"fz") == 0) {
       which[nvalues] = F;
       argindex[nvalues++] = 2;
 
     } else if (strncmp(arg[iarg],"c_",2) == 0 || 
 	       strncmp(arg[iarg],"f_",2) == 0 || 
 	       strncmp(arg[iarg],"v_",2) == 0) {
       if (arg[iarg][0] == 'c') which[nvalues] = COMPUTE;
       else if (arg[iarg][0] == 'f') which[nvalues] = FIX;
       else if (arg[iarg][0] == 'v') which[nvalues] = VARIABLE;
 
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Illegal fix ave/atom command");
 	argindex[nvalues] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[nvalues] = 0;
 
       n = strlen(suffix) + 1;
       ids[nvalues] = new char[n];
       strcpy(ids[nvalues],suffix);
       nvalues++;
       delete [] suffix;
 
     } else error->all("Illegal fix ave/atom command");
 
     iarg++;
   }
 
   // setup and error check
   // for fix inputs, check that fix frequency is acceptable
 
   if (nevery <= 0 || nrepeat <= 0 || peratom_freq <= 0)
     error->all("Illegal fix ave/atom command");
   if (peratom_freq % nevery || (nrepeat-1)*nevery >= peratom_freq)
     error->all("Illegal fix ave/atom command");
 
   for (int i = 0; i < nvalues; i++) {
     if (which[i] == COMPUTE) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/atom does not exist");
       if (modify->compute[icompute]->peratom_flag == 0)
 	error->all("Fix ave/atom compute does not calculate per-atom values");
       if (argindex[i] == 0 && 
 	  modify->compute[icompute]->size_peratom_cols != 0)
 	error->all("Fix ave/atom compute does not "
 		   "calculate a per-atom vector");
       if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0)
 	error->all("Fix ave/atom compute does not "
 		   "calculate a per-atom array");
       if (argindex[i] && 
 	  argindex[i] > modify->compute[icompute]->size_peratom_cols)
 	error->all("Fix ave/atom compute array is accessed out-of-range");
 
     } else if (which[i] == FIX) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0)
 	error->all("Fix ID for fix ave/atom does not exist");
       if (modify->fix[ifix]->peratom_flag == 0)
 	error->all("Fix ave/atom fix does not calculate per-atom values");
       if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0)
 	error->all("Fix ave/atom fix does not calculate a per-atom vector");
       if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0)
 	error->all("Fix ave/atom fix does not calculate a per-atom array");
       if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols)
 	error->all("Fix ave/atom fix array is accessed out-of-range");
       if (nevery % modify->fix[ifix]->peratom_freq)
 	error->all("Fix for fix ave/atom not computed at compatible time");
 
     } else if (which[i] == VARIABLE) {
       int ivariable = input->variable->find(ids[i]);
       if (ivariable < 0)
 	error->all("Variable name for fix ave/atom does not exist");
       if (input->variable->atomstyle(ivariable) == 0)
 	error->all("Fix ave/atom variable is not atom-style variable");
     }
   }
 
   // this fix produces either a per-atom vector or array
 
   peratom_flag = 1;
   if (nvalues == 1) size_peratom_cols = 0;
   else size_peratom_cols = nvalues;
 
   // perform initial allocation of atom-based array
   // register with Atom class
 
   array = NULL;
   grow_arrays(atom->nmax);
   atom->add_callback(0);
 
   // zero the array since dump may access it on timestep 0
   // zero the array since a variable may access it before first run
 
   int nlocal = atom->nlocal;
   for (int i = 0; i < nlocal; i++)
     for (int m = 0; m < nvalues; m++)
       array[i][m] = 0.0;
   
   // nvalid = next step on which end_of_step does something
   // add nvalid to all computes that store invocation times
   // since don't know a priori which are invoked by this fix
   // once in end_of_step() can set timestep for ones actually invoked
 
   irepeat = 0;
   nvalid = nextvalid();
   modify->addstep_compute_all(nvalid);
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixAveAtom::~FixAveAtom()
 {
   // unregister callback to this fix from Atom class
  
   atom->delete_callback(id,0);
 
   delete [] which;
   delete [] argindex;
   for (int m = 0; m < nvalues; m++) delete [] ids[m];
   delete [] ids;
   delete [] value2index;
 
   memory->destroy_2d_double_array(array);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixAveAtom::setmask()
 {
   int mask = 0;
   mask |= END_OF_STEP;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixAveAtom::init()
 {
   // set indices and check validity of all computes,fixes,variables
 
   for (int m = 0; m < nvalues; m++) {
     if (which[m] == COMPUTE) {
       int icompute = modify->find_compute(ids[m]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/atom does not exist");
       value2index[m] = icompute;
       
     } else if (which[m] == FIX) {
       int ifix = modify->find_fix(ids[m]);
       if (ifix < 0) 
 	error->all("Fix ID for fix ave/atom does not exist");
       value2index[m] = ifix;
 
     } else if (which[m] == VARIABLE) {
       int ivariable = input->variable->find(ids[m]);
       if (ivariable < 0) 
 	error->all("Variable name for fix ave/atom does not exist");
       value2index[m] = ivariable;
 
     } else value2index[m] = -1;
   }
 
   // need to reset nvalid if nvalid < ntimestep b/c minimize was performed
 
   if (nvalid < update->ntimestep) {
     irepeat = 0;
     nvalid = nextvalid();
     modify->addstep_compute_all(nvalid);
   }
 }
 
 /* ----------------------------------------------------------------------
    only does something if nvalid = current timestep
 ------------------------------------------------------------------------- */
 
 void FixAveAtom::setup(int vflag)
 {
   end_of_step();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixAveAtom::end_of_step()
 {
   int i,j,m,n;
 
   // skip if not step which requires doing something
 
-  int ntimestep = update->ntimestep;
+  bigint ntimestep = update->ntimestep;
   if (ntimestep != nvalid) return;
 
   // zero if first step
 
   int nlocal = atom->nlocal;
 
   if (irepeat == 0)
     for (i = 0; i < nlocal; i++)
       for (m = 0; m < nvalues; m++)
 	array[i][m] = 0.0;
   
   // accumulate results of attributes,computes,fixes,variables to local copy
   // compute/fix/variable may invoke computes so wrap with clear/add
 
   modify->clearstep_compute();
 
   int *mask = atom->mask;
 
   for (m = 0; m < nvalues; m++) {
     n = value2index[m];
     j = argindex[m];
 
     if (which[m] == X) {
       double **x = atom->x;
       for (i = 0; i < nlocal; i++)
 	if (mask[i] & groupbit) array[i][m] += x[i][j];
 
     } else if (which[m] == V) {
       double **v = atom->v;
       for (i = 0; i < nlocal; i++)
 	if (mask[i] & groupbit) array[i][m] += v[i][j];
 
     } else if (which[m] == F) {
       double **f = atom->f;
       for (i = 0; i < nlocal; i++)
 	if (mask[i] & groupbit) array[i][m] += f[i][j];
 
     // invoke compute if not previously invoked
 
     } else if (which[m] == COMPUTE) {
       Compute *compute = modify->compute[n];
       if (!(compute->invoked_flag & INVOKED_PERATOM)) {
 	compute->compute_peratom();
 	compute->invoked_flag |= INVOKED_PERATOM;
       }
 
       if (j == 0) {
 	double *compute_vector = compute->vector_atom;
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit) array[i][m] += compute_vector[i];
       } else {
 	int jm1 = j - 1;
 	double **compute_array = compute->array_atom;
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit) array[i][m] += compute_array[i][jm1];
       }
 
     // access fix fields, guaranteed to be ready
 
     } else if (which[m] == FIX) {
       if (j == 0) {
 	double *fix_vector = modify->fix[n]->vector_atom;
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit) array[i][m] += fix_vector[i];
       } else {
 	int jm1 = j - 1;
 	double **fix_array = modify->fix[n]->array_atom;
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit) array[i][m] += fix_array[i][jm1];
       }
 
     // evaluate atom-style variable
 
     } else if (which[m] == VARIABLE)
       input->variable->compute_atom(n,igroup,&array[0][m],nvalues,1);
   }
 
   // done if irepeat < nrepeat
   // else reset irepeat and nvalid
 
   irepeat++;
   if (irepeat < nrepeat) {
     nvalid += nevery;
     modify->addstep_compute(nvalid);
     return;
   }
 
   irepeat = 0;
   nvalid = ntimestep+peratom_freq - (nrepeat-1)*nevery;
   modify->addstep_compute(nvalid);
 
   // average the final result for the Nfreq timestep
 
   double repeat = nrepeat;
   for (i = 0; i < nlocal; i++)
     for (m = 0; m < nvalues; m++)
       array[i][m] /= repeat;
 }
 
 /* ----------------------------------------------------------------------
    memory usage of local atom-based array
 ------------------------------------------------------------------------- */
 
 double FixAveAtom::memory_usage()
 {
   double bytes;
   bytes = atom->nmax*nvalues * sizeof(double);
   return bytes;
 }
 
 /* ----------------------------------------------------------------------
    allocate atom-based array
 ------------------------------------------------------------------------- */
 
 void FixAveAtom::grow_arrays(int nmax)
 {
   array = memory->grow_2d_double_array(array,nmax,nvalues,
 				       "fix_ave/atom:array");
   array_atom = array;
   vector_atom = array[0];
 }
 
 /* ----------------------------------------------------------------------
    copy values within local atom-based array
 ------------------------------------------------------------------------- */
 
 void FixAveAtom::copy_arrays(int i, int j)
 {
   for (int m = 0; m < nvalues; m++)
     array[j][m] = array[i][m];
 }
 
 /* ----------------------------------------------------------------------
    pack values in local atom-based array for exchange with another proc
 ------------------------------------------------------------------------- */
 
 int FixAveAtom::pack_exchange(int i, double *buf)
 {
   for (int m = 0; m < nvalues; m++) buf[m] = array[i][m];
   return nvalues;
 }
 
 /* ----------------------------------------------------------------------
    unpack values in local atom-based array from exchange with another proc
 ------------------------------------------------------------------------- */
 
 int FixAveAtom::unpack_exchange(int nlocal, double *buf)
 {
   for (int m = 0; m < nvalues; m++) array[nlocal][m] = buf[m];
   return nvalues;
 }
 
 /* ----------------------------------------------------------------------
    calculate nvalid = next step on which end_of_step does something
    can be this timestep if multiple of nfreq and nrepeat = 1
    else backup from next multiple of nfreq
 ------------------------------------------------------------------------- */
 
-int FixAveAtom::nextvalid()
+bigint FixAveAtom::nextvalid()
 {
-  int nvalid = (update->ntimestep/peratom_freq)*peratom_freq + peratom_freq;
+  bigint nvalid = (update->ntimestep/peratom_freq)*peratom_freq + peratom_freq;
   if (nvalid-peratom_freq == update->ntimestep && nrepeat == 1)
     nvalid = update->ntimestep;
   else
     nvalid -= (nrepeat-1)*nevery;
   if (nvalid < update->ntimestep) nvalid += peratom_freq;
   return nvalid;
 }
diff --git a/src/fix_ave_atom.h b/src/fix_ave_atom.h
index 7ab406b81..409b78cc2 100644
--- a/src/fix_ave_atom.h
+++ b/src/fix_ave_atom.h
@@ -1,57 +1,58 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef FIX_CLASS
 
 FixStyle(ave/atom,FixAveAtom)
 
 #else
 
 #ifndef LMP_FIX_AVE_ATOM_H
 #define LMP_FIX_AVE_ATOM_H
 
 #include "stdio.h"
 #include "fix.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class FixAveAtom : public Fix {
  public:
   FixAveAtom(class LAMMPS *, int, char **);
   ~FixAveAtom();
   int setmask();
   void init();
   void setup(int);
   void end_of_step();
 
   double memory_usage();
   void grow_arrays(int);
   void copy_arrays(int, int);
   int pack_exchange(int, double *);
   int unpack_exchange(int, double *);
 
  private:
   int nvalues;
-  int nrepeat,nvalid,irepeat;
+  int nrepeat,irepeat;
+  bigint nvalid;
   int *which,*argindex,*value2index;
   char **ids;
-
   double **array;
 
-  int nextvalid();
+  bigint nextvalid();
 };
 
 }
 
 #endif
 #endif
diff --git a/src/fix_ave_correlate.cpp b/src/fix_ave_correlate.cpp
index 941970e52..b962a0d59 100644
--- a/src/fix_ave_correlate.cpp
+++ b/src/fix_ave_correlate.cpp
@@ -1,594 +1,597 @@
 /* ----------------------------------------------------------------------
    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:
      Benoit Leblanc, Dave Rigby, Paul Saxe (Materials Design)
      Reese Jones (Sandia)
 ------------------------------------------------------------------------- */
 
 #include "stdlib.h"
 #include "string.h"
 #include "fix_ave_correlate.h"
+#include "lmptype.h"
 #include "update.h"
 #include "modify.h"
 #include "compute.h"
 #include "input.h"
 #include "variable.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{COMPUTE,FIX,VARIABLE};
 enum{ONE,RUNNING};
 enum{AUTO,UPPER,LOWER,AUTOUPPER,AUTOLOWER,FULL};
 
 #define INVOKED_SCALAR 1
 #define INVOKED_VECTOR 2
 #define INVOKED_ARRAY 4
 
 /* ---------------------------------------------------------------------- */
 
 FixAveCorrelate::FixAveCorrelate(LAMMPS * lmp, int narg, char **arg):
   Fix (lmp, narg, arg)
 {
   if (narg < 7) error->all ("Illegal fix ave/correlate command");
 
   MPI_Comm_rank(world,&me);
 
   nevery = atoi(arg[3]);
   nrepeat = atoi(arg[4]);
   nfreq = atoi(arg[5]);
 
   global_freq = nfreq;
   time_depend = 1;
 
   // parse values until one isn't recognized
 
   which = new int[narg-6];
   argindex = new int[narg-6];
   ids = new char*[narg-6];
   value2index = new int[narg-6];
   nvalues = 0;
 
   int iarg = 6;
   while (iarg < narg) {
     if (strncmp(arg[iarg],"c_",2) == 0 || 
 	strncmp(arg[iarg],"f_",2) == 0 || 
 	strncmp(arg[iarg],"v_",2) == 0) {
       if (arg[iarg][0] == 'c') which[nvalues] = COMPUTE;
       else if (arg[iarg][0] == 'f') which[nvalues] = FIX;
       else if (arg[iarg][0] == 'v') which[nvalues] = VARIABLE;
 
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Illegal fix ave/correlate command");
 	argindex[nvalues] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[nvalues] = 0;
 
       n = strlen(suffix) + 1;
       ids[nvalues] = new char[n];
       strcpy(ids[nvalues],suffix);
       delete [] suffix;
 
       nvalues++;
       iarg++;
     } else break;
   }
 
   // optional args
 
   type = AUTO;
   ave = ONE;
   startstep = 0;
   prefactor = 1.0;
   fp = NULL;
   char *title1 = NULL;
   char *title2 = NULL;
   char *title3 = NULL;
 
   while (iarg < narg) {
     if (strcmp(arg[iarg],"type") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/correlate command");
       if (strcmp(arg[iarg+1],"auto") == 0) type = AUTO;
       else if (strcmp(arg[iarg+1],"upper") == 0) type = UPPER;
       else if (strcmp(arg[iarg+1],"lower") == 0) type = LOWER;
       else if (strcmp(arg[iarg+1],"auto/upper") == 0) type = AUTOUPPER;
       else if (strcmp(arg[iarg+1],"auto/lower") == 0) type = AUTOLOWER;
       else if (strcmp(arg[iarg+1],"full") == 0) type = FULL;
       else error->all("Illegal fix ave/correlate command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"ave") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/correlate command");
       if (strcmp(arg[iarg+1],"one") == 0) ave = ONE;
       else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING;
       else error->all("Illegal fix ave/correlate command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"start") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/correlate command");
       startstep = atoi(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"prefactor") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/correlate command");
       prefactor = atof(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"file") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/correlate command");
       if (me == 0) {
 	fp = fopen(arg[iarg+1],"w");
 	if (fp == NULL) {
 	  char str[128];
 	  sprintf(str,"Cannot open fix ave/correlate file %s",arg[iarg+1]);
 	  error->one(str);
 	}
       }
       iarg += 2;
     } else if (strcmp(arg[iarg],"title1") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/correlate command");
       delete [] title1;
       int n = strlen(arg[iarg+1]) + 1;
       title1 = new char[n];
       strcpy(title1,arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"title2") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/correlate command");
       delete [] title2;
       int n = strlen(arg[iarg+1]) + 1;
       title2 = new char[n];
       strcpy(title2,arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"title3") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/correlate command");
       delete [] title3;
       int n = strlen(arg[iarg+1]) + 1;
       title3 = new char[n];
       strcpy(title3,arg[iarg+1]);
       iarg += 2;
     } else error->all("Illegal fix ave/correlate command");
   }
 
   // setup and error check
   // for fix inputs, check that fix frequency is acceptable
 
   if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0)
     error->all("Illegal fix ave/correlate command");
   if (nfreq % nevery)
     error->all("Illegal fix ave/correlate command");
   if (ave == ONE && nfreq < (nrepeat-1)*nevery)
     error->all("Illegal fix ave/correlate command");
 
   for (int i = 0; i < nvalues; i++) {
     if (which[i] == COMPUTE) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all ("Compute ID for fix ave/correlate does not exist");
       if (argindex[i] == 0 && modify->compute[icompute]->scalar_flag == 0)
 	error->all ("Fix ave/correlate compute does not calculate a scalar");
       if (argindex[i] && modify->compute[icompute]->vector_flag == 0)
 	error->all ("Fix ave/correlate compute does not calculate a vector");
       if (argindex[i] && argindex[i] > modify->compute[icompute]->size_vector)
 	error->all ("Fix ave/correlate compute vector "
 		    "is accessed out-of-range");
 
     } else if (which[i] == FIX) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0)
 	error->all ("Fix ID for fix ave/correlate does not exist");
       if (argindex[i] == 0 && modify->fix[ifix]->scalar_flag == 0)
 	error->all ("Fix ave/correlate fix does not calculate a scalar");
       if (argindex[i] && modify->fix[ifix]->vector_flag == 0)
 	error->all ("Fix ave/correlate fix does not calculate a vector");
       if (argindex[i] && argindex[i] > modify->fix[ifix]->size_vector)
 	error->all ("Fix ave/correlate fix vector is accessed out-of-range");
       if (nevery % modify->fix[ifix]->global_freq)
 	error->all("Fix for fix ave/correlate "
 		   "not computed at compatible time");
 
     } else if (which[i] == VARIABLE) {
       int ivariable = input->variable->find(ids[i]);
       if (ivariable < 0)
 	error->all ("Variable name for fix ave/correlate does not exist");
       if (input->variable->equalstyle(ivariable) == 0)
 	error->all ("Fix ave/correlate variable is not equal-style variable");
     }
   }
 
   // npair = # of correlation pairs to calculate
 
   if (type == AUTO) npair = nvalues;
   if (type == UPPER || type == LOWER) npair = nvalues*(nvalues-1)/2;
   if (type == AUTOUPPER || type == AUTOLOWER) npair = nvalues*(nvalues+1)/2;
   if (type == FULL) npair = nvalues*nvalues;
 
   // print file comment lines
 
   if (fp && me == 0) {
     if (title1) fprintf(fp,"%s\n",title1);
     else fprintf(fp,"# Time-correlated data for fix %s\n",id);
     if (title2) fprintf(fp,"%s\n",title2);
     else fprintf(fp,"# Timestep Number-of-time-windows\n");
     if (title3) fprintf(fp,"%s\n",title3);
     else {
       fprintf(fp,"# Index TimeDelta Ncount");
       if (type == AUTO)
 	for (int i = 0; i < nvalues; i++)
 	  fprintf(fp," %s*%s",arg[6+i],arg[6+i]);
       else if (type == UPPER)
 	for (int i = 0; i < nvalues; i++)
 	  for (int j = i+1; j < nvalues; j++)
 	    fprintf(fp," %s*%s",arg[6+i],arg[6+j]);
       else if (type == LOWER) 
 	for (int i = 0; i < nvalues; i++)
 	  for (int j = 0; j < i-1; j++)
 	    fprintf(fp," %s*%s",arg[6+i],arg[6+j]);
       else if (type == AUTOUPPER)
 	for (int i = 0; i < nvalues; i++)
 	  for (int j = i; j < nvalues; j++)
 	    fprintf(fp," %s*%s",arg[6+i],arg[6+j]);
       else if (type == AUTOLOWER) 
 	for (int i = 0; i < nvalues; i++)
 	  for (int j = 0; j < i; j++)
 	    fprintf(fp," %s*%s",arg[6+i],arg[6+j]);
       else if (type == FULL)
 	for (int i = 0; i < nvalues; i++)
 	  for (int j = 0; j < nvalues; j++)
 	    fprintf(fp," %s*%s",arg[6+i],arg[6+j]);
       fprintf(fp,"\n");
     }
   }
 
   delete [] title1;
   delete [] title2;
   delete [] title3;
   
   // allocate and initialize memory for averaging
   // set count and corr to zero since they accumulate
   // also set save versions to zero in case accessed via compute_array()
 
   values = memory->create_2d_double_array(nrepeat,nvalues,
 					  "ave/correlate:values");
   count = (int *) memory->smalloc(nrepeat*sizeof(int),
 				  "ave/correlate:count");
   save_count = (int *) memory->smalloc(nrepeat*sizeof(int),
 				       "ave/correlate:save_count");
   corr = memory->create_2d_double_array(nrepeat,npair,
 					"ave/correlate:corr");
   save_corr = memory->create_2d_double_array(nrepeat,npair,
 					     "ave/correlate:save_corr");
 
   int i,j;
   for (i = 0; i < nrepeat; i++) {
     save_count[i] = count[i] = 0;
     for (j = 0; j < npair; j++)
       save_corr[i][j] = corr[i][j] = 0.0;
   }
 
   // this fix produces a global array
 
   array_flag = 1;
   size_array_rows = nrepeat;
   size_array_cols = npair+2;
   extarray = 0;
 
   // nvalid = next step on which end_of_step does something
   // add nvalid to all computes that store invocation times
   // since don't know a priori which are invoked by this fix
   // once in end_of_step() can set timestep for ones actually invoked
 
   lastindex = -1;
   firstindex = 0;
   nsample = 0;
   nvalid = nextvalid();
   modify->addstep_compute_all(nvalid);
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixAveCorrelate::~FixAveCorrelate()
 {
   delete [] which;
   delete [] argindex;
   delete [] value2index;
   for (int i = 0; i < nvalues; i++) delete [] ids[i];
   delete [] ids;
 
   memory->destroy_2d_double_array(values);
   memory->sfree(count);
   memory->sfree(save_count);
   memory->destroy_2d_double_array(corr);
   memory->destroy_2d_double_array(save_corr);
 
   if (fp && me == 0) fclose(fp);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixAveCorrelate::setmask()
 {
   int mask = 0;
   mask |= END_OF_STEP;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixAveCorrelate::init()
 {
   // set current indices for all computes,fixes,variables
 
   for (int i = 0; i < nvalues; i++) {
     if (which[i] == COMPUTE) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/correlate does not exist");
       value2index[i] = icompute;
 
     } else if (which[i] == FIX) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0) 
 	error->all("Fix ID for fix ave/correlate does not exist");
       value2index[i] = ifix;
 
     } else if (which[i] == VARIABLE) {
       int ivariable = input->variable->find(ids[i]);
       if (ivariable < 0) 
 	error->all("Variable name for fix ave/correlate does not exist");
       value2index[i] = ivariable;
     }
   }
 
   // need to reset nvalid if nvalid < ntimestep b/c minimize was performed
 
   if (nvalid < update->ntimestep) {
     lastindex = -1;
     firstindex = 0;
     nsample = 0;
     nvalid = nextvalid();
     modify->addstep_compute_all(nvalid);
   }
 }
 
 /* ----------------------------------------------------------------------
    only does something if nvalid = current timestep
 ------------------------------------------------------------------------- */
 
 void FixAveCorrelate::setup(int vflag)
 {
   end_of_step();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixAveCorrelate::end_of_step()
 {
   int i,j,k,m;
   double scalar;
 
   // skip if not step which requires doing something
 
-  int ntimestep = update->ntimestep;
+  bigint ntimestep = update->ntimestep;
   if (ntimestep != nvalid) return;
 
   // accumulate results of computes,fixes,variables to origin
   // compute/fix/variable may invoke computes so wrap with clear/add
 
   modify->clearstep_compute();
 
   // lastindex = index in values ring of latest time sample
 
   lastindex++;
   if (lastindex == nrepeat) lastindex = 0;
 
   for (i = 0; i < nvalues; i++) {
     m = value2index[i];
     
     // invoke compute if not previously invoked
     
     if (which[i] == COMPUTE) {
       Compute *compute = modify->compute[m];
       
       if (argindex[i] == 0) {
 	if (!(compute->invoked_flag & INVOKED_SCALAR)) {
 	  compute->compute_scalar();
 	  compute->invoked_flag |= INVOKED_SCALAR;
 	}
 	scalar = compute->scalar;
       } else {
 	if (!(compute->invoked_flag & INVOKED_VECTOR)) {
 	  compute->compute_vector();
 	  compute->invoked_flag |= INVOKED_VECTOR;
 	}
 	scalar = compute->vector[argindex[i]-1];
       }
       
     // access fix fields, guaranteed to be ready
       
     } else if (which[i] == FIX) {
       if (argindex[i] == 0) 
 	scalar = modify->fix[m]->compute_scalar();
       else
 	scalar = modify->fix[m]->compute_vector(argindex[i]-1);
       
     // evaluate equal-style variable
       
     } else if (which[i] == VARIABLE)
       scalar = input->variable->compute_equal(m);
     
     values[lastindex][i] = scalar;
   }
 
   // fistindex = index in values ring of earliest time sample
   // nsample = number of time samples in values ring
 
   if (nsample < nrepeat) nsample++;
   else {
     firstindex++;
     if (firstindex == nrepeat) firstindex = 0;
   }
 
   nvalid += nevery;
   modify->addstep_compute(nvalid);
 
   // calculate all Cij() enabled by latest values
 
   accumulate();
   if (ntimestep % nfreq) return;
 
   // save results in save_count and save_corr
 
   for (i = 0; i < nrepeat; i++) {
     save_count[i] = count[i];
     if (count[i])
       for (j = 0; j < npair; j++)
 	save_corr[i][j] = prefactor*corr[i][j]/count[i];
     else
       for (j = 0; j < npair; j++)
 	save_corr[i][j] = 0.0;
   }
 
   // output to file
 
   if (fp && me == 0) {
-    fprintf(fp,"%d %d\n",ntimestep,nrepeat);
+    char fstr[16];
+    sprintf(fstr,"%s %%d\n",BIGINT_FORMAT);
+    fprintf(fp,fstr,ntimestep,nrepeat);
     for (i = 0; i < nrepeat; i++) {
       fprintf(fp,"%d %d %d",i+1,i*nevery,count[i]);
       if (count[i])
 	for (j = 0; j < npair; j++)
 	  fprintf(fp," %g",prefactor*corr[i][j]/count[i]);
       else
 	for (j = 0; j < npair; j++)
 	  fprintf(fp," 0.0");
       fprintf(fp,"\n");
     }
     fflush(fp);
   }
 
   // zero accumulation if requested
   // recalculate Cij(0)
 
   if (ave == ONE) {
     for (i = 0; i < nrepeat; i++) {
       count[i] = 0;
       for (j = 0; j < npair; j++)
 	corr[i][j] = 0.0;
     }
     nsample = 1;
     accumulate();
   }
 }
 
 /* ----------------------------------------------------------------------
    accumulate correlation data using more recently added values
 ------------------------------------------------------------------------- */
 
 void FixAveCorrelate::accumulate()
 {
   int i,j,k,m,n,ipair;
 
   for (k = 0; k < nsample; k++) count[k]++;
 
   if (type == AUTO) {
     m = n = lastindex;
     for (k = 0; k < nsample; k++) {
       ipair = 0;
       for (i = 0; i < nvalues; i++) {
 	corr[k][ipair++] += values[m][i]*values[n][i];
       }
       m--;
       if (m < 0) m = nrepeat-1;
     }
   } else if (type == UPPER) {
     m = n = lastindex;
     for (k = 0; k < nsample; k++) {
       ipair = 0;
       for (i = 0; i < nvalues; i++)
 	for (j = i+1; j < nvalues; j++)
 	  corr[k][ipair++] += values[m][i]*values[n][j];
       m--;
       if (m < 0) m = nrepeat-1;
     }
   } else if (type == LOWER) {
     m = n = lastindex;
     for (k = 0; k < nsample; k++) {
       ipair = 0;
       for (i = 0; i < nvalues; i++)
 	for (j = 0; j < i-1; j++)
 	  corr[k][ipair++] += values[m][i]*values[n][j];
       m--;
       if (m < 0) m = nrepeat-1;
     }
   } else if (type == AUTOUPPER) {
     m = n = lastindex;
     for (k = 0; k < nsample; k++) {
       ipair = 0;
       for (i = 0; i < nvalues; i++)
 	for (j = i; j < nvalues; j++)
 	  corr[k][ipair++] += values[m][i]*values[n][j];
       m--;
       if (m < 0) m = nrepeat-1;
     }
   } else if (type == AUTOLOWER) {
     m = n = lastindex;
     for (k = 0; k < nsample; k++) {
       ipair = 0;
       for (i = 0; i < nvalues; i++)
 	for (j = 0; j < i; j++)
 	  corr[k][ipair++] += values[m][i]*values[n][j];
       m--;
       if (m < 0) m = nrepeat-1;
     }
   } else if (type == FULL) {
     m = n = lastindex;
     for (k = 0; k < nsample; k++) {
       ipair = 0;
       for (i = 0; i < nvalues; i++)
 	for (j = 0; j < nvalues; j++)
 	  corr[k][ipair++] += values[m][i]*values[n][j];
       m--;
       if (m < 0) m = nrepeat-1;
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    return I,J array value
 ------------------------------------------------------------------------- */
 
 double FixAveCorrelate::compute_array(int i, int j)
 {
   if (j == 0) return 1.0*i*nevery;
   else if (j == 1) return 1.0*save_count[i];
   else if (save_count[i]) return save_corr[i][j-2];
   return 0.0;
 }
 
 /* ----------------------------------------------------------------------
    nvalid = next step on which end_of_step does something
    this step if multiple of nevery, else next multiple
    startstep is lower bound
 ------------------------------------------------------------------------- */
 
-int FixAveCorrelate::nextvalid()
+bigint FixAveCorrelate::nextvalid()
 {
-  int nvalid = update->ntimestep;
+  bigint nvalid = update->ntimestep;
   if (startstep > nvalid) nvalid = startstep;
   if (nvalid % nevery) nvalid = (nvalid/nevery)*nevery + nevery;
   return nvalid;
 }
diff --git a/src/fix_ave_correlate.h b/src/fix_ave_correlate.h
index faacf6eab..e5dc5046c 100644
--- a/src/fix_ave_correlate.h
+++ b/src/fix_ave_correlate.h
@@ -1,67 +1,69 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef FIX_CLASS
 
 FixStyle(ave/correlate,FixAveCorrelate)
 
 #else
 
 #ifndef LMP_FIX_AVE_CORRELATE_H
 #define LMP_FIX_AVE_CORRELATE_H
 
 #include "stdio.h"
 #include "fix.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class FixAveCorrelate : public Fix {
  public:
   FixAveCorrelate(class LAMMPS *, int, char **);
   ~FixAveCorrelate();
   int setmask();
   void init();
   void setup(int);
   void end_of_step();
   double compute_array(int,int);
 
  private:
   int me,nvalues;
-  int nrepeat,nfreq,nvalid;
+  int nrepeat,nfreq;
+  bigint nvalid;
   int *which,*argindex,*value2index;
   char **ids;
   FILE *fp;
 
   int type,ave,startstep;
   double prefactor;
   char *title1,*title2,*title3;
 
   int firstindex;      // index in values ring of earliest time sample
   int lastindex;       // index in values ring of latest time sample
   int nsample;         // number of time samples in values ring
 
   int npair;           // number of correlation pairs to calculate
   int *count;
   double **values,**corr;
 
   int *save_count;     // saved values at Nfreq for output via compute_array()
   double **save_corr;
     
   void accumulate();
-  int nextvalid();
+  bigint nextvalid();
 };
 
 }
 
 #endif
 #endif
diff --git a/src/fix_ave_histo.cpp b/src/fix_ave_histo.cpp
index d04fea1c3..b0c234583 100644
--- a/src/fix_ave_histo.cpp
+++ b/src/fix_ave_histo.cpp
@@ -1,1001 +1,1003 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "string.h"
 #include "fix_ave_histo.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "update.h"
 #include "modify.h"
 #include "compute.h"
 #include "group.h"
 #include "input.h"
 #include "variable.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{X,V,F,COMPUTE,FIX,VARIABLE};
 enum{ONE,RUNNING};
 enum{SCALAR,VECTOR,WINDOW};
 enum{GLOBAL,PERATOM,LOCAL};
 enum{IGNORE,END,EXTRA};
 
 #define INVOKED_SCALAR 1
 #define INVOKED_VECTOR 2
 #define INVOKED_ARRAY 4
 #define INVOKED_PERATOM 8
 #define INVOKED_LOCAL 16
 
 #define BIG 1.0e20
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 /* ---------------------------------------------------------------------- */
 
 FixAveHisto::FixAveHisto(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 10) error->all("Illegal fix ave/histo command");
 
   MPI_Comm_rank(world,&me);
 
   nevery = atoi(arg[3]);
   nrepeat = atoi(arg[4]);
   nfreq = atoi(arg[5]);
 
   global_freq = nfreq;
   vector_flag = 1;
   size_vector = 4;
   extvector = 0;
   array_flag = 1;
   size_local_cols = 3;
   extarray = 0;
   time_depend = 1;
 
   lo = atof(arg[6]);
   hi = atof(arg[7]);
   nbins = atoi(arg[8]);
 
   // scan values to count them
   // then read options so know mode = SCALAR/VECTOR before re-reading values
 
   nvalues = 0;
 
   int iarg = 9;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"x") == 0 ||
 	strcmp(arg[iarg],"y") == 0 ||
 	strcmp(arg[iarg],"z") == 0 || 
 	strcmp(arg[iarg],"vx") == 0 ||
 	strcmp(arg[iarg],"vy") == 0 ||
 	strcmp(arg[iarg],"vz") == 0 ||
 	strcmp(arg[iarg],"fx") == 0 ||
 	strcmp(arg[iarg],"fy") == 0 ||
 	strcmp(arg[iarg],"fz") == 0 ||
 	strncmp(arg[iarg],"c_",2) == 0 || 
 	strncmp(arg[iarg],"f_",2) == 0 || 
 	strncmp(arg[iarg],"v_",2) == 0) {
       nvalues++;
       iarg++;
     } else break;
   }
 
   options(narg,arg);
 
   // parse values until one isn't recognized
   // if mode = VECTOR and value is a global array:
   //   expand it as if columns listed one by one
   //   adjust nvalues accordingly via maxvalues
 
   which = argindex = value2index = NULL;
   ids = NULL;
   int maxvalues = nvalues;
   allocate_values(maxvalues);
   nvalues = 0;
 
   iarg = 9;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"x") == 0) {
       which[nvalues] = X;
       argindex[nvalues] = 0;
       ids[nvalues] = NULL;
       nvalues++;
       iarg++;
     } else if (strcmp(arg[iarg],"y") == 0) {
       which[nvalues] = X;
       argindex[nvalues] = 1;
       ids[nvalues] = NULL;
       nvalues++;
       iarg++;
     } else if (strcmp(arg[iarg],"z") == 0) {
       which[nvalues] = X;
       argindex[nvalues] = 2;
       ids[nvalues] = NULL;
       nvalues++;
       iarg++;
 
     } else if (strcmp(arg[iarg],"vx") == 0) {
       which[nvalues] = V;
       argindex[nvalues] = 0;
       ids[nvalues] = NULL;
       nvalues++;
       iarg++;
     } else if (strcmp(arg[iarg],"vy") == 0) {
       which[nvalues] = V;
       argindex[nvalues] = 1;
       ids[nvalues] = NULL;
       nvalues++;
       iarg++;
     } else if (strcmp(arg[iarg],"vz") == 0) {
       which[nvalues] = V;
       argindex[nvalues] = 2;
       ids[nvalues] = NULL;
       nvalues++;
       iarg++;
 
     } else if (strcmp(arg[iarg],"fx") == 0) {
       which[nvalues] = F;
       argindex[nvalues] = 0;
       ids[nvalues] = NULL;
       nvalues++;
       iarg++;
     } else if (strcmp(arg[iarg],"fy") == 0) {
       which[nvalues] = F;
       argindex[nvalues] = 1;
       ids[nvalues] = NULL;
       nvalues++;
       iarg++;
     } else if (strcmp(arg[iarg],"fz") == 0) {
       which[nvalues] = F;
       argindex[nvalues] = 2;
       ids[nvalues] = NULL;
       nvalues++;
       iarg++;
 
     } else if ((strncmp(arg[iarg],"c_",2) == 0) || 
 	(strncmp(arg[iarg],"f_",2) == 0) || 
 	(strncmp(arg[iarg],"v_",2) == 0)) {
       if (arg[iarg][0] == 'c') which[nvalues] = COMPUTE;
       else if (arg[iarg][0] == 'f') which[nvalues] = FIX;
       else if (arg[iarg][0] == 'v') which[nvalues] = VARIABLE;
 
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Illegal fix ave/histo command");
 	argindex[nvalues] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[nvalues] = 0;
 
       n = strlen(suffix) + 1;
       ids[nvalues] = new char[n];
       strcpy(ids[nvalues],suffix);
       delete [] suffix;
 
       if (mode == VECTOR && which[nvalues] == COMPUTE && 
 	  argindex[nvalues] == 0) {
 	int icompute = modify->find_compute(ids[nvalues]);
 	if (icompute < 0)
 	  error->all("Compute ID for fix ave/histo does not exist");
 	if (modify->compute[icompute]->array_flag) {
 	  int ncols = modify->compute[icompute]->size_array_cols;
 	  maxvalues += ncols-1;
 	  allocate_values(maxvalues);
 	  argindex[nvalues] = 1;
 	  for (int icol = 1; icol < ncols; icol++) {
 	    which[nvalues+icol] = which[nvalues];
 	    argindex[nvalues+icol] = icol+1;
 	    n = strlen(ids[nvalues]) + 1;
 	    ids[nvalues+icol] = new char[n];
 	    strcpy(ids[nvalues+icol],ids[nvalues]);
 	  }
 	  nvalues += ncols-1;
 	}
 
       } else if (mode == VECTOR && which[nvalues] == FIX && 
 		 argindex[nvalues] == 0) {
 	int ifix = modify->find_fix(ids[nvalues]);
 	if (ifix < 0)
 	  error->all("Fix ID for fix ave/histo does not exist");
 	if (modify->fix[ifix]->array_flag) {
 	  int ncols = modify->fix[ifix]->size_array_cols;
 	  maxvalues += ncols-1;
 	  allocate_values(maxvalues);
 	  argindex[nvalues] = 1;
 	  for (int icol = 1; icol < ncols; icol++) {
 	    which[nvalues+icol] = which[nvalues];
 	    argindex[nvalues+icol] = icol+1;
 	    n = strlen(ids[nvalues]) + 1;
 	    ids[nvalues+icol] = new char[n];
 	    strcpy(ids[nvalues+icol],ids[nvalues]);
 	  }
 	  nvalues += ncols-1;
 	}
       }
 
       nvalues++;
       iarg++;
     } else break;
   }
 
   // setup and error check
   // kind = inputs are all global, or all per-atom, or all local
   // for fix inputs, check that fix frequency is acceptable
 
   if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0)
     error->all("Illegal fix ave/histo command");
   if (nfreq % nevery || (nrepeat-1)*nevery >= nfreq)
     error->all("Illegal fix ave/histo command");
   if (lo >= hi) error->all("Illegal fix ave/histo command");
   if (nbins <= 0) error->all("Illegal fix ave/histo command");
 
   int kindflag;
   for (int i = 0; i < nvalues; i++) {
     if (which[i] == X || which[i] == V || which[i] == F) kindflag = PERATOM;
     else if (which[i] == COMPUTE) {
       Compute *compute = modify->compute[modify->find_compute(ids[0])];
       if (compute->scalar_flag || compute->vector_flag || compute->array_flag)
 	kindflag = GLOBAL;
       else if (compute->peratom_flag) kindflag = PERATOM;
       else if (compute->local_flag) kindflag = LOCAL;
       else error->all("Fix ave/histo input is invalid compute");
     } else if (which[i] == FIX) {
       Fix *fix = modify->fix[modify->find_fix(ids[0])];
       if (fix->scalar_flag || fix->vector_flag || fix->array_flag)
 	kindflag = GLOBAL;
       else if (fix->peratom_flag) kindflag = PERATOM;
       else if (fix->local_flag) kindflag = LOCAL;
       else error->all("Fix ave/histo input is invalid fix");
     } else if (which[i] == VARIABLE) {
       int ivariable = input->variable->find(ids[i]);
       if (input->variable->equalstyle(ivariable)) kindflag = GLOBAL;
       else if (input->variable->atomstyle(ivariable)) kindflag = PERATOM;
       else error->all("Fix ave/histo input is invalid variable");
     }
     if (i == 0) kind = kindflag;
     else if (kindflag != kind)
       error->all("Fix ave/histo inputs are not all global, peratom, or local");
   }
 
   if (kind == PERATOM && mode == SCALAR) 
     error->all("Fix ave/histo cannot input per-atom values in scalar mode");
   if (kind == LOCAL && mode == SCALAR)
     error->all("Fix ave/histo cannot input local values in scalar mode");
 
   for (int i = 0; i < nvalues; i++) {
     if (which[i] == COMPUTE && kind == GLOBAL && mode == SCALAR) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/histo does not exist");
       if (argindex[i] == 0 && modify->compute[icompute]->scalar_flag == 0)
 	error->all("Fix ave/histo compute does not calculate a global scalar");
       if (argindex[i] && modify->compute[icompute]->vector_flag == 0)
 	error->all("Fix ave/histo compute does not calculate a global vector");
       if (argindex[i] && argindex[i] > modify->compute[icompute]->size_vector)
 	error->all("Fix ave/histo compute vector is accessed out-of-range");
 
     } else if (which[i] == COMPUTE && kind == GLOBAL && mode == VECTOR) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/histo does not exist");
       if (argindex[i] == 0 && modify->compute[icompute]->vector_flag == 0)
 	error->all("Fix ave/histo compute does not calculate a global vector");
       if (argindex[i] && modify->compute[icompute]->array_flag == 0)
 	error->all("Fix ave/histo compute does not calculate a global array");
       if (argindex[i] && 
 	  argindex[i] > modify->compute[icompute]->size_array_cols)
 	error->all("Fix ave/histo compute array is accessed out-of-range");
 
     } else if (which[i] == COMPUTE && kind == PERATOM) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/histo does not exist");
       if (modify->compute[icompute]->peratom_flag == 0)
 	error->all("Fix ave/histo compute does not calculate per-atom values");
       if (argindex[i] == 0 && 
 	  modify->compute[icompute]->size_peratom_cols != 0)
 	error->all("Fix ave/histo compute does not "
 		   "calculate a per-atom vector");
       if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0)
 	error->all("Fix ave/histo compute does not "
 		   "calculate a per-atom array");
       if (argindex[i] && 
 	  argindex[i] > modify->compute[icompute]->size_peratom_cols)
 	error->all("Fix ave/histo compute array is accessed out-of-range");
 
     } else if (which[i] == COMPUTE && kind == LOCAL) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/histo does not exist");
       if (modify->compute[icompute]->local_flag == 0)
 	error->all("Fix ave/histo compute does not calculate local values");
       if (argindex[i] == 0 && 
 	  modify->compute[icompute]->size_local_cols != 0)
 	error->all("Fix ave/histo compute does not "
 		   "calculate a local vector");
       if (argindex[i] && modify->compute[icompute]->size_local_cols == 0)
 	error->all("Fix ave/histo compute does not "
 		   "calculate a local array");
       if (argindex[i] && 
 	  argindex[i] > modify->compute[icompute]->size_local_cols)
 	error->all("Fix ave/histo compute array is accessed out-of-range");
 
     } else if (which[i] == FIX && kind == GLOBAL && mode == SCALAR) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0)
 	error->all("Fix ID for fix ave/histo does not exist");
       if (argindex[i] == 0 && modify->fix[ifix]->scalar_flag == 0)
 	error->all("Fix ave/histo fix does not calculate a global scalar");
       if (argindex[i] && modify->fix[ifix]->vector_flag == 0)
 	error->all("Fix ave/histo fix does not calculate a global vector");
       if (argindex[i] && argindex[i] > modify->fix[ifix]->size_vector)
 	error->all("Fix ave/histo fix vector is accessed out-of-range");
       if (nevery % modify->fix[ifix]->global_freq)
 	error->all("Fix for fix ave/histo not computed at compatible time");
 
     } else if (which[i] == FIX && kind == GLOBAL && mode == VECTOR) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0)
 	error->all("Fix ID for fix ave/histo does not exist");
       if (argindex[i] == 0 && modify->fix[ifix]->vector_flag == 0)
 	error->all("Fix ave/histo fix does not calculate a global vector");
       if (argindex[i] && modify->fix[ifix]->array_flag == 0)
 	error->all("Fix ave/histo fix does not calculate a global array");
       if (argindex[i] && argindex[i] > modify->fix[ifix]->size_array_cols)
 	error->all("Fix ave/histo fix array is accessed out-of-range");
       if (nevery % modify->fix[ifix]->global_freq)
 	error->all("Fix for fix ave/histo not computed at compatible time");
 
     } else if (which[i] == FIX && kind == PERATOM) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0)
 	error->all("Fix ID for fix ave/histo does not exist");
       if (modify->fix[ifix]->peratom_flag == 0)
 	error->all("Fix ave/histo fix does not calculate per-atom values");
       if (argindex[i] == 0 && 
 	  modify->fix[ifix]->size_peratom_cols != 0)
 	error->all("Fix ave/histo fix does not "
 		   "calculate a per-atom vector");
       if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0)
 	error->all("Fix ave/histo fix does not "
 		   "calculate a per-atom array");
       if (argindex[i] && 
 	  argindex[i] > modify->fix[ifix]->size_peratom_cols)
 	error->all("Fix ave/histo fix array is accessed out-of-range");
       if (nevery % modify->fix[ifix]->global_freq)
 	error->all("Fix for fix ave/histo not computed at compatible time");
 
     } else if (which[i] == FIX && kind == LOCAL) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0)
 	error->all("Fix ID for fix ave/histo does not exist");
       if (modify->fix[ifix]->local_flag == 0)
 	error->all("Fix ave/histo fix does not calculate local values");
       if (argindex[i] == 0 && 
 	  modify->fix[ifix]->size_local_cols != 0)
 	error->all("Fix ave/histo fix does not "
 		   "calculate a local vector");
       if (argindex[i] && modify->fix[ifix]->size_local_cols == 0)
 	error->all("Fix ave/histo fix does not "
 		   "calculate a local array");
       if (argindex[i] && 
 	  argindex[i] > modify->fix[ifix]->size_local_cols)
 	error->all("Fix ave/histo fix array is accessed out-of-range");
       if (nevery % modify->fix[ifix]->global_freq)
 	error->all("Fix for fix ave/histo not computed at compatible time");
 
     } else if (which[i] == VARIABLE && kind == GLOBAL) {
       int ivariable = input->variable->find(ids[i]);
       if (ivariable < 0)
 	error->all("Variable name for fix ave/histo does not exist");
 
     } else if (which[i] == VARIABLE && kind == PERATOM) {
       int ivariable = input->variable->find(ids[i]);
       if (ivariable < 0)
 	error->all("Variable name for fix ave/histo does not exist");
     }
   }
 
   // print file comment lines
 
   if (fp && me == 0) {
     if (title1) fprintf(fp,"%s\n",title1);
     else fprintf(fp,"# Histogrammed data for fix %s\n",id);
     if (title2) fprintf(fp,"%s\n",title2);
     else fprintf(fp,"# TimeStep Number-of-bins "
 		 "Total-counts Missing-counts Min-value Max-value\n");
     if (title3) fprintf(fp,"%s\n",title3);
     else fprintf(fp,"# Bin Coord Count Count/Total\n");
   }
 
   delete [] title1;
   delete [] title2;
   delete [] title3;
 
   // allocate and initialize memory for averaging
 
   if (beyond == EXTRA) nbins += 2;
   size_local_rows = nbins;
 
   bin = new double[nbins];
   bin_total = new double[nbins];
   bin_all = new double[nbins];
   coord = new double[nbins];
 
   stats_list = NULL;
   bin_list = NULL;
   vector = NULL;
   maxatom = 0;
   if (ave == WINDOW) {
     stats_list = memory->create_2d_double_array(nwindow,4,
 						"ave/histo:stats_list");
     bin_list = memory->create_2d_double_array(nwindow,nbins,
 					      "ave/histo:bin_list");
   }
 
   // initializations
   // set coord to bin centers
 
   if (beyond == EXTRA) {
     binsize = (hi-lo)/(nbins-2);
     bininv = 1.0/binsize;
   } else {
     binsize = (hi-lo)/nbins;
     bininv = 1.0/binsize;
   }
 
   if (beyond == EXTRA) {
     coord[0] = lo;
     coord[nbins-1] = hi;
     for (int i = 1; i < nbins-1; i++)
       coord[i] = lo + (i-1+0.5)*binsize;
   } else {
     for (int i = 0; i < nbins; i++)
       coord[i] = lo + (i+0.5)*binsize;
   }
 
   irepeat = 0;
   iwindow = window_limit = 0;
 
   stats_total[0] = stats_total[1] = stats_total[2] = stats_total[3] = 0.0;
   for (int i = 0; i < nbins; i++) bin_total[i] = 0.0;
 
   // nvalid = next step on which end_of_step does something
   // add nvalid to all computes that store invocation times
   // since don't know a priori which are invoked by this fix
   // once in end_of_step() can set timestep for ones actually invoked
 
   nvalid = nextvalid();
   modify->addstep_compute_all(nvalid);
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixAveHisto::~FixAveHisto()
 {
   memory->sfree(which);
   memory->sfree(argindex);
   memory->sfree(value2index);
   for (int i = 0; i < nvalues; i++) delete [] ids[i];
   memory->sfree(ids);
 
   if (fp && me == 0) fclose(fp);
 
   delete [] bin;
   delete [] bin_total;
   delete [] bin_all;
   delete [] coord;
   memory->destroy_2d_double_array(stats_list);
   memory->destroy_2d_double_array(bin_list);
   memory->sfree(vector);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixAveHisto::setmask()
 {
   int mask = 0;
   mask |= END_OF_STEP;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixAveHisto::init()
 {
   // set current indices for all computes,fixes,variables
 
   for (int i = 0; i < nvalues; i++) {
     if (which[i] == COMPUTE) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/histo does not exist");
       value2index[i] = icompute;
 
     } else if (which[i] == FIX) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0) 
 	error->all("Fix ID for fix ave/histo does not exist");
       value2index[i] = ifix;
 
     } else if (which[i] == VARIABLE) {
       int ivariable = input->variable->find(ids[i]);
       if (ivariable < 0) 
 	error->all("Variable name for fix ave/histo does not exist");
       value2index[i] = ivariable;
     }
   }
 
   // need to reset nvalid if nvalid < ntimestep b/c minimize was performed
 
   if (nvalid < update->ntimestep) {
     irepeat = 0;
     nvalid = nextvalid();
     modify->addstep_compute_all(nvalid);
   }
 }
 
 /* ----------------------------------------------------------------------
    only does something if nvalid = current timestep
 ------------------------------------------------------------------------- */
 
 void FixAveHisto::setup(int vflag)
 {
   end_of_step();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixAveHisto::end_of_step()
 {
   int i,j,m;
 
   // skip if not step which requires doing something
 
-  int ntimestep = update->ntimestep;
+  bigint ntimestep = update->ntimestep;
   if (ntimestep != nvalid) return;
 
   // zero if first step
 
   if (irepeat == 0) {
     stats[0] = stats[1] = 0.0;
     stats[2] = BIG;
     stats[3] = -BIG;
     for (i = 0; i < nbins; i++) bin[i] = 0.0;
   }
 
   // accumulate results of computes,fixes,variables to local copy
   // compute/fix/variable may invoke computes so wrap with clear/add
 
   modify->clearstep_compute();
 
   for (i = 0; i < nvalues; i++) {
     m = value2index[i];
     j = argindex[i];
 
     // atom attributes
 
     if (which[i] == X)
       bin_atoms(&atom->x[0][j],3);
     else if (which[i] == V)
       bin_atoms(&atom->v[0][j],3);
     else if (which[i] == F)
       bin_atoms(&atom->f[0][j],3);
 
     // invoke compute if not previously invoked
     
     if (which[i] == COMPUTE) {
       Compute *compute = modify->compute[m];
 
       if (kind == GLOBAL && mode == SCALAR) {
 	if (j == 0) {
 	  if (!(compute->invoked_flag & INVOKED_SCALAR)) {
 	    compute->compute_scalar();
 	    compute->invoked_flag |= INVOKED_SCALAR;
 	  }
 	  bin_one(compute->scalar);
 	} else {
 	  if (!(compute->invoked_flag & INVOKED_VECTOR)) {
 	    compute->compute_vector();
 	    compute->invoked_flag |= INVOKED_VECTOR;
 	  }
 	  bin_one(compute->vector[j-1]);
 	}
       } else if (kind == GLOBAL && mode == VECTOR) {
 	if (j == 0) {
 	  if (!(compute->invoked_flag & INVOKED_VECTOR)) {
 	    compute->compute_vector();
 	    compute->invoked_flag |= INVOKED_VECTOR;
 	  }
 	  bin_vector(compute->size_vector,compute->vector,1);
 	} else {
 	  if (!(compute->invoked_flag & INVOKED_ARRAY)) {
 	    compute->compute_array();
 	    compute->invoked_flag |= INVOKED_ARRAY;
 	  }
 	  bin_vector(compute->size_array_rows,&compute->array[0][j-1],
 		     compute->size_array_cols);
 	}
 
       } else if (kind == PERATOM) {
 	if (!(compute->invoked_flag & INVOKED_PERATOM)) {
 	  compute->compute_peratom();
 	  compute->invoked_flag |= INVOKED_PERATOM;
 	}
 	if (j == 0)
 	  bin_atoms(compute->vector_atom,1);
 	else
 	  bin_atoms(compute->array_atom[j-1],
 		    compute->size_peratom_cols);
 
       } else if (kind == LOCAL) {
 	if (!(compute->invoked_flag & INVOKED_LOCAL)) {
 	  compute->compute_local();
 	  compute->invoked_flag |= INVOKED_LOCAL;
 	}
 	if (j == 0)
 	  bin_vector(compute->size_local_rows,compute->vector_local,1);
 	else
 	  bin_vector(compute->size_local_rows,&compute->array_local[0][j-1],
 		     compute->size_local_cols);
       }
 
       // access fix fields, guaranteed to be ready
       
     } else if (which[i] == FIX) {
 
       Fix *fix = modify->fix[m];
 
       if (kind == GLOBAL && mode == SCALAR) {
 	if (j == 0) bin_one(fix->compute_scalar());
 	else bin_one(fix->compute_vector(j-1));
 
       } else if (kind == GLOBAL && mode == VECTOR) {
 	if (j == 0) {
 	  int n = fix->size_vector;
 	  for (i = 0; i < n; i++) bin_one(fix->compute_vector(i));
 	} else {
 	  int n = fix->size_vector;
 	  for (i = 0; i < n; i++) bin_one(fix->compute_array(i,j-1));
 	}
 
       } else if (kind == PERATOM) {
 	if (j == 0) bin_atoms(fix->vector_atom,1);
 	else bin_atoms(fix->array_atom[j-1],fix->size_peratom_cols);
 
       } else if (kind == LOCAL) {
 	if (j == 0) bin_vector(fix->size_local_rows,fix->vector_local,1);
 	else 
 	  bin_vector(fix->size_local_rows,&fix->array_local[0][j-1],
 		     fix->size_local_cols);
       }
 
       // evaluate equal-style variable
       
     } else if (which[i] == VARIABLE && kind == GLOBAL) {
       bin_one(input->variable->compute_equal(m));
 
     } else if (which[i] == VARIABLE && kind == PERATOM) {
       if (atom->nlocal > maxatom) {
 	memory->sfree(vector);
 	maxatom = atom->nmax;
 	vector = (double *) memory->smalloc(maxatom*sizeof(double),
 					    "ave/histo:vector");
       }
       input->variable->compute_atom(m,igroup,vector,1,0);
       bin_atoms(vector,1);
     }
   }
 
   // done if irepeat < nrepeat
   // else reset irepeat and nvalid
 
   irepeat++;
   if (irepeat < nrepeat) {
     nvalid += nevery;
     modify->addstep_compute(nvalid);
     return;
   }
 
   irepeat = 0;
   nvalid = ntimestep + nfreq - (nrepeat-1)*nevery;
   modify->addstep_compute(nvalid);
 
   // merge histogram stats across procs if necessary
 
   if (kind == PERATOM || kind == LOCAL) {
     MPI_Allreduce(stats,stats_all,2,MPI_DOUBLE,MPI_SUM,world);
     MPI_Allreduce(&stats[2],&stats_all[2],1,MPI_DOUBLE,MPI_MIN,world);
     MPI_Allreduce(&stats[3],&stats_all[3],1,MPI_DOUBLE,MPI_MAX,world);
     MPI_Allreduce(bin,bin_all,nbins,MPI_DOUBLE,MPI_SUM,world);
 
     stats[0] = stats_all[0];
     stats[1] = stats_all[1];
     stats[2] = stats_all[2];
     stats[3] = stats_all[3];
     for (i = 0; i < nbins; i++) bin[i] = bin_all[i];
   }
 
   // if ave = ONE, only single Nfreq timestep value is needed
   // if ave = RUNNING, combine with all previous Nfreq timestep values
   // if ave = WINDOW, combine with nwindow most recent Nfreq timestep values
 
   if (ntimestep >= startstep) {
     if (ave == ONE) {
       stats_total[0] = stats[0];
       stats_total[1] = stats[1];
       stats_total[2] = stats[2];
       stats_total[3] = stats[3];
       for (i = 0; i < nbins; i++) bin_total[i] = bin[i];
 
     } else if (ave == RUNNING) {
       stats_total[0] += stats[0];
       stats_total[1] += stats[1];
       stats_total[2] = MIN(stats_total[2],stats[2]);
       stats_total[3] = MAX(stats_total[3],stats[3]);
       for (i = 0; i < nbins; i++) bin_total[i] += bin[i];
       
     } else if (ave == WINDOW) {
       stats_total[0] += stats[0];
       if (window_limit) stats_total[0] -= stats_list[iwindow][0];
       stats_list[iwindow][0] = stats[0];
       stats_total[1] += stats[1];
       if (window_limit) stats_total[1] -= stats_list[iwindow][1];
       stats_list[iwindow][1] = stats[1];
 
       if (window_limit) m = nwindow;
       else m = iwindow+1;
 
       stats_list[iwindow][2] = stats[2];
       stats_total[2] = stats_list[0][2];
       for (i = 1; i < m; i++) 
 	stats_total[2] = MIN(stats_total[2],stats_list[i][2]);
       stats_list[iwindow][3] = stats[3];
       stats_total[3] = stats_list[0][3];
       for (i = 1; i < m; i++) 
 	stats_total[3] = MAX(stats_total[3],stats_list[i][3]);
 
       for (i = 0; i < nbins; i++) {
 	bin_total[i] += bin[i];
 	if (window_limit) bin_total[i] -= bin_list[iwindow][i];
 	bin_list[iwindow][i] = bin[i];
       }
       
       iwindow++;
       if (iwindow == nwindow) {
 	iwindow = 0;
 	window_limit = 1;
       }
     }
   }
 
   // output result to file
 
   if (fp && me == 0) {
-    fprintf(fp,"%d %d %g %g %g %g\n",
-	    ntimestep,nbins,
+    char fstr[32];
+    sprintf(fstr,"%s %%d %%g %%g %%g %%g\n",BIGINT_FORMAT);
+    fprintf(fp,fstr,ntimestep,nbins,
 	    stats_total[0],stats_total[1],stats_total[2],stats_total[3]);
     if (stats_total[0] != 0.0)
       for (i = 0; i < nbins; i++)
 	fprintf(fp,"%d %g %g %g\n",
 		i+1,coord[i],bin_total[i],bin_total[i]/stats_total[0]);
     else
       for (i = 0; i < nbins; i++)
 	fprintf(fp,"%d %g %g %g\n",i+1,coord[i],0.0,0.0);
     fflush(fp);
   }
 }
 
 /* ----------------------------------------------------------------------
    return Ith vector value
 ------------------------------------------------------------------------- */
 
 double FixAveHisto::compute_vector(int i)
 {
   return stats_total[i];
 }
 
 /* ----------------------------------------------------------------------
    return I,J array value
 ------------------------------------------------------------------------- */
 
 double FixAveHisto::compute_array(int i, int j)
 {
   if (j == 0) return coord[j];
   else if (j == 1) return bin_total[j];
   else if (stats_total[0] != 0.0) return bin_total[j]/stats_total[0];
   return 0.0;
 }
 
 /* ----------------------------------------------------------------------
    bin a single value
 ------------------------------------------------------------------------- */
 
 void FixAveHisto::bin_one(double value)
 {
   stats[2] = MIN(stats[2],value);
   stats[3] = MAX(stats[3],value);
 
   if (value < lo) {
     if (beyond == IGNORE) {
       stats[1] += 1.0;
       return;
     } else bin[0] += 1.0;
   } else if (value > hi) {
     if (beyond == IGNORE) {
       stats[1] += 1.0;
       return;
     } else bin[nbins-1] += 1.0;
   } else {
     int ibin = static_cast<int> ((value-lo)*bininv);
     ibin = MIN(ibin,nbins-1);
     if (beyond == EXTRA) ibin++;
     bin[ibin] += 1.0;
   }
 
   stats[0] += 1.0;
 }
 
 /* ----------------------------------------------------------------------
    bin a vector of values with stride
 ------------------------------------------------------------------------- */
 
 void FixAveHisto::bin_vector(int n, double *values, int stride)
 {
   int m = 0;
   for (int i = 0; i < n; i++) {
     bin_one(values[m]);
     m += stride;
   }
 }
 
 /* ----------------------------------------------------------------------
    bin a per-atom vector of values with stride
    only bin if atom is in group
 ------------------------------------------------------------------------- */
 
 void FixAveHisto::bin_atoms(double *values, int stride)
 {
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int m = 0;
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) bin_one(values[m]);
     m += stride;
   }
 }
 
 /* ----------------------------------------------------------------------
    parse optional args
 ------------------------------------------------------------------------- */
 
 void FixAveHisto::options(int narg, char **arg)
 {
   // option defaults
 
   fp = NULL;
   ave = ONE;
   startstep = 0;
   mode = SCALAR;
   beyond = IGNORE;
   title1 = NULL;
   title2 = NULL;
   title3 = NULL;
 
   // optional args
 
   int iarg = 9 + nvalues;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"file") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/histo command");
       if (me == 0) {
 	fp = fopen(arg[iarg+1],"w");
 	if (fp == NULL) {
 	  char str[128];
 	  sprintf(str,"Cannot open fix ave/histo file %s",arg[iarg+1]);
 	  error->one(str);
 	}
       }
       iarg += 2;
     } else if (strcmp(arg[iarg],"ave") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/histo command");
       if (strcmp(arg[iarg+1],"one") == 0) ave = ONE;
       else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING;
       else if (strcmp(arg[iarg+1],"window") == 0) ave = WINDOW;
       else error->all("Illegal fix ave/histo command");
       if (ave == WINDOW) {
 	if (iarg+3 > narg) error->all("Illegal fix ave/histo command");
 	nwindow = atoi(arg[iarg+2]);
 	if (nwindow <= 0) error->all("Illegal fix ave/histo command");
       }
       iarg += 2;
       if (ave == WINDOW) iarg++;
     } else if (strcmp(arg[iarg],"start") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/histo command");
       startstep = atoi(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"mode") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/histo command");
       if (strcmp(arg[iarg+1],"scalar") == 0) mode = SCALAR;
       else if (strcmp(arg[iarg+1],"vector") == 0) mode = VECTOR;
       else error->all("Illegal fix ave/histo command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"beyond") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/histo command");
       if (strcmp(arg[iarg+1],"ignore") == 0) beyond = IGNORE;
       else if (strcmp(arg[iarg+1],"end") == 0) beyond = END;
       else if (strcmp(arg[iarg+1],"extra") == 0) beyond = EXTRA;
       else error->all("Illegal fix ave/histo command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"title1") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       delete [] title1;
       int n = strlen(arg[iarg+1]) + 1;
       title1 = new char[n];
       strcpy(title1,arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"title2") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       delete [] title2;
       int n = strlen(arg[iarg+1]) + 1;
       title2 = new char[n];
       strcpy(title2,arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"title3") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       delete [] title3;
       int n = strlen(arg[iarg+1]) + 1;
       title3 = new char[n];
       strcpy(title3,arg[iarg+1]);
       iarg += 2;
     } else error->all("Illegal fix ave/histo command");
   }
 }
 
 /* ----------------------------------------------------------------------
    reallocate vectors for each input value, of length N
 ------------------------------------------------------------------------- */
 
 void FixAveHisto::allocate_values(int n)
 {
   which = (int *) memory->srealloc(which,n*sizeof(int),"ave/time:which");
   argindex = (int *) memory->srealloc(argindex,n*sizeof(int),
 				      "ave/time:argindex");
   value2index = (int *) memory->srealloc(value2index,n*sizeof(int),
 					 "ave/time:value2index");
   ids = (char **) memory->srealloc(ids,n*sizeof(char *),"ave/time:ids");
 }
 
 /* ----------------------------------------------------------------------
    calculate nvalid = next step on which end_of_step does something
    can be this timestep if multiple of nfreq and nrepeat = 1
    else backup from next multiple of nfreq
 ------------------------------------------------------------------------- */
 
-int FixAveHisto::nextvalid()
+bigint FixAveHisto::nextvalid()
 {
-  int nvalid = (update->ntimestep/nfreq)*nfreq + nfreq;
+  bigint nvalid = (update->ntimestep/nfreq)*nfreq + nfreq;
   if (nvalid-nfreq == update->ntimestep && nrepeat == 1)
     nvalid = update->ntimestep;
   else
     nvalid -= (nrepeat-1)*nevery;
   if (nvalid < update->ntimestep) nvalid += nfreq;
   return nvalid;
 }
diff --git a/src/fix_ave_histo.h b/src/fix_ave_histo.h
index 64903a973..7dc63220b 100644
--- a/src/fix_ave_histo.h
+++ b/src/fix_ave_histo.h
@@ -1,74 +1,76 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef FIX_CLASS
 
 FixStyle(ave/histo,FixAveHisto)
 
 #else
 
 #ifndef LMP_FIX_AVE_HISTO_H
 #define LMP_FIX_AVE_HISTO_H
 
 #include "stdio.h"
 #include "fix.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class FixAveHisto : public Fix {
  public:
   FixAveHisto(class LAMMPS *, int, char **);
   ~FixAveHisto();
   int setmask();
   void init();
   void setup(int);
   void end_of_step();
   double compute_vector(int);
   double compute_array(int,int);
 
  private:
   int me,nvalues;
-  int nrepeat,nfreq,nvalid,irepeat;
+  int nrepeat,nfreq,irepeat;
+  bigint nvalid;
   int *which,*argindex,*value2index;
   char **ids;
   FILE *fp;
   double lo,hi,binsize,bininv;
   int kind,beyond;
 
   double stats[4],stats_total[4],stats_all[4];
   double **stats_list;
 
   int nbins;
   double *bin,*bin_total,*bin_all;
   double **bin_list;
   double *coord;
 
   double *vector;
   int maxatom;
 
   int ave,nwindow,nsum,startstep,mode;
   char *title1,*title2,*title3;
   int iwindow,window_limit;
 
   void bin_one(double);
   void bin_vector(int, double *, int);
   void bin_atoms(double *, int);
   void options(int, char **);
   void allocate_values(int);
-  int nextvalid();
+  bigint nextvalid();
 };
 
 }
 
 #endif
 #endif
diff --git a/src/fix_ave_spatial.cpp b/src/fix_ave_spatial.cpp
index 7b562052a..760464223 100644
--- a/src/fix_ave_spatial.cpp
+++ b/src/fix_ave_spatial.cpp
@@ -1,1296 +1,1299 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Pieter in 't Veld (SNL)
 ------------------------------------------------------------------------- */
 
 #include "stdlib.h"
 #include "string.h"
 #include "fix_ave_spatial.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "update.h"
 #include "force.h"
 #include "domain.h"
 #include "region.h"
 #include "lattice.h"
 #include "modify.h"
 #include "compute.h"
 #include "input.h"
 #include "variable.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{LOWER,CENTER,UPPER,COORD};
 enum{V,F,DENSITY_NUMBER,DENSITY_MASS,COMPUTE,FIX,VARIABLE};
 enum{SAMPLE,ALL};
 enum{BOX,LATTICE,REDUCED};
 enum{ONE,RUNNING,WINDOW};
 
 #define INVOKED_PERATOM 8
 #define BIG 1000000000
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 /* ---------------------------------------------------------------------- */
 
 FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 6) error->all("Illegal fix ave/spatial command");
 
   MPI_Comm_rank(world,&me);
 
   nevery = atoi(arg[3]);
   nrepeat = atoi(arg[4]);
   nfreq = atoi(arg[5]);
 
   global_freq = nfreq;
   no_change_box = 1;
   time_depend = 1;
 
   ndim = 0;
   int iarg = 6;
   while (iarg < narg && ndim < 3) {
     if (iarg+3 > narg) break;
     if (strcmp(arg[iarg],"x") == 0) dim[ndim] = 0;
     else if (strcmp(arg[iarg],"y") == 0) dim[ndim] = 1;
     else if (strcmp(arg[iarg],"z") == 0) dim[ndim] = 2;
     else break;
 
     if (dim[ndim] == 2 && domain->dimension == 2)
       error->all("Cannot use fix ave/spatial z for 2 dimensional model");
 
     if (strcmp(arg[iarg+1],"lower") == 0) originflag[ndim] = LOWER;
     if (strcmp(arg[iarg+1],"center") == 0) originflag[ndim] = CENTER;
     if (strcmp(arg[iarg+1],"upper") == 0) originflag[ndim] = UPPER;
     else originflag[ndim] = COORD;
     if (originflag[ndim] == COORD) origin[ndim] = atof(arg[iarg+1]);
 
     delta[ndim] = atof(arg[iarg+2]);
     ndim++;
     iarg += 3;
   }
 
   if (!ndim) error->all("Illegal fix ave/spatial command");
   if (ndim == 2 && dim[0] == dim[1])
     error->all("Same dimension twice in fix ave/spatial");
   if (ndim == 3 && (dim[0] == dim[1] || dim[1] == dim[2] || dim[0] == dim[2])) 
     error->all("Same dimension twice in fix ave/spatial");
 
   // parse values until one isn't recognized
 
   which = new int[narg-9];
   argindex = new int[narg-9];
   ids = new char*[narg-9];
   value2index = new int[narg-9];
   nvalues = 0;
 
   while (iarg < narg) {
     ids[nvalues] = NULL;
 
     if (strcmp(arg[iarg],"vx") == 0) {
       which[nvalues] = V;
       argindex[nvalues++] = 0;
     } else if (strcmp(arg[iarg],"vy") == 0) {
       which[nvalues] = V;
       argindex[nvalues++] = 1;
     } else if (strcmp(arg[iarg],"vz") == 0) {
       which[nvalues] = V;
       argindex[nvalues++] = 2;
 
     } else if (strcmp(arg[iarg],"fx") == 0) {
       which[nvalues] = F;
       argindex[nvalues++] = 0;
     } else if (strcmp(arg[iarg],"fy") == 0) {
       which[nvalues] = F;
       argindex[nvalues++] = 1;
     } else if (strcmp(arg[iarg],"fz") == 0) {
       which[nvalues] = F;
       argindex[nvalues++] = 2;
 
     } else if (strcmp(arg[iarg],"density/number") == 0) {
       which[nvalues] = DENSITY_NUMBER;
       argindex[nvalues++] = 0;
     } else if (strcmp(arg[iarg],"density/mass") == 0) {
       which[nvalues] = DENSITY_MASS;
       argindex[nvalues++] = 0;
 
     } else if (strncmp(arg[iarg],"c_",2) == 0 || 
 	       strncmp(arg[iarg],"f_",2) == 0 || 
 	       strncmp(arg[iarg],"v_",2) == 0) {
       if (arg[iarg][0] == 'c') which[nvalues] = COMPUTE;
       else if (arg[iarg][0] == 'f') which[nvalues] = FIX;
       else if (arg[iarg][0] == 'v') which[nvalues] = VARIABLE;
 
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Illegal fix ave/spatial command");
 	argindex[nvalues] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[nvalues] = 0;
 
       n = strlen(suffix) + 1;
       ids[nvalues] = new char[n];
       strcpy(ids[nvalues],suffix);
       nvalues++;
       delete [] suffix;
 
     } else break;
 
     iarg++;
   }
 
   // optional args
 
   normflag = ALL;
   scaleflag = LATTICE;
   regionflag = 0;
   idregion = NULL;
   fp = NULL;
   ave = ONE;
   char *title1 = NULL;
   char *title2 = NULL;
   char *title3 = NULL;
 
   while (iarg < narg) {
     if (strcmp(arg[iarg],"norm") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       if (strcmp(arg[iarg+1],"all") == 0) normflag = ALL;
       else if (strcmp(arg[iarg+1],"sample") == 0) normflag = SAMPLE;
       else error->all("Illegal fix ave/spatial command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"units") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       if (strcmp(arg[iarg+1],"box") == 0) scaleflag = BOX;
       else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = LATTICE;
       else if (strcmp(arg[iarg+1],"reduced") == 0) scaleflag = REDUCED;
       else error->all("Illegal fix ave/spatial command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"region") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       iregion = domain->find_region(arg[iarg+1]);
       if (iregion == -1) 
 	error->all("Region ID for fix ave/spatial does not exist");
       int n = strlen(arg[iarg+1]) + 1;
       idregion = new char[n];
       strcpy(idregion,arg[iarg+1]);
       regionflag = 1;
       iarg += 2;
     } else if (strcmp(arg[iarg],"file") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       if (me == 0) {
 	fp = fopen(arg[iarg+1],"w");
 	if (fp == NULL) {
 	  char str[128];
 	  sprintf(str,"Cannot open fix ave/spatial file %s",arg[iarg+1]);
 	  error->one(str);
 	}
       }
       iarg += 2;
     } else if (strcmp(arg[iarg],"ave") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       if (strcmp(arg[iarg+1],"one") == 0) ave = ONE;
       else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING;
       else if (strcmp(arg[iarg+1],"window") == 0) ave = WINDOW;
       else error->all("Illegal fix ave/spatial command");
       if (ave == WINDOW) {
 	if (iarg+3 > narg) error->all("Illegal fix ave/spatial command");
 	nwindow = atoi(arg[iarg+2]);
 	if (nwindow <= 0) error->all("Illegal fix ave/spatial command");
       }
       iarg += 2;
       if (ave == WINDOW) iarg++;
     } else if (strcmp(arg[iarg],"title1") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       delete [] title1;
       int n = strlen(arg[iarg+1]) + 1;
       title1 = new char[n];
       strcpy(title1,arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"title2") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       delete [] title2;
       int n = strlen(arg[iarg+1]) + 1;
       title2 = new char[n];
       strcpy(title2,arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"title3") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       delete [] title3;
       int n = strlen(arg[iarg+1]) + 1;
       title3 = new char[n];
       strcpy(title3,arg[iarg+1]);
       iarg += 2;
     } else error->all("Illegal fix ave/spatial command");
   }
 
   // setup and error check
 
   if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0)
     error->all("Illegal fix ave/spatial command");
   if (nfreq % nevery || (nrepeat-1)*nevery >= nfreq)
     error->all("Illegal fix ave/spatial command");
   if (delta[0] <= 0.0) error->all("Illegal fix ave/spatial command");
   if (ndim >= 2 && delta[1] <= 0.0) 
     error->all("Illegal fix ave/spatial command");
   if (ndim == 3 && delta[2] <= 0.0) 
     error->all("Illegal fix ave/spatial command");
 
   for (int i = 0; i < nvalues; i++) {
     if (which[i] == COMPUTE) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/spatial does not exist");
       if (modify->compute[icompute]->peratom_flag == 0)
 	error->all("Fix ave/spatial compute does not "
 		   "calculate per-atom values");
       if (argindex[i] == 0 && 
 	  modify->compute[icompute]->size_peratom_cols != 0)
 	error->all("Fix ave/spatial compute does not "
 		   "calculate a per-atom vector");
       if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0)
 	error->all("Fix ave/spatial compute does not "
 		   "calculate a per-atom array");
       if (argindex[i] && 
 	  argindex[i] > modify->compute[icompute]->size_peratom_cols)
 	error->all("Fix ave/spatial compute vector is accessed out-of-range");
 
     } else if (which[i] == FIX) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0)
 	error->all("Fix ID for fix ave/spatial does not exist");
       if (modify->fix[ifix]->peratom_flag == 0)
 	error->all("Fix ave/spatial fix does not calculate per-atom values");
       if (argindex[i] && modify->fix[ifix]->size_peratom_cols != 0)
 	error->all("Fix ave/spatial fix does not calculate a per-atom vector");
       if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0)
 	error->all("Fix ave/spatial fix does not calculate a per-atom array");
       if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols)
 	error->all("Fix ave/spatial fix vector is accessed out-of-range");
     } else if (which[i] == VARIABLE) {
       int ivariable = input->variable->find(ids[i]);
       if (ivariable < 0)
 	error->all("Variable name for fix ave/spatial does not exist");
       if (input->variable->atomstyle(ivariable) == 0)
 	error->all("Fix ave/spatial variable is not atom-style variable");
     }
   }
 
   // print file comment lines
 
   if (fp && me == 0) {
     if (title1) fprintf(fp,"%s\n",title1);
     else fprintf(fp,"# Spatial-averaged data for fix %s and group %s\n",
 		 id,arg[1]);
     if (title2) fprintf(fp,"%s\n",title2);
     else fprintf(fp,"# Timestep Number-of-bins\n");
     if (title3) fprintf(fp,"%s\n",title3);
     else {
       if (ndim == 1) fprintf(fp,"# Bin Coord Ncount");
       else if (ndim == 2) fprintf(fp,"# Bin Coord1 Coord2 Ncount");
       else if (ndim == 3) fprintf(fp,"# Bin Coord1 Coord2 Coord3 Ncount");
       for (int i = 0; i < nvalues; i++) fprintf(fp," %s",arg[9+i]);
       fprintf(fp,"\n");
     }
   }
 
   delete [] title1;
   delete [] title2;
   delete [] title3;
 
   // this fix produces a global array
 
   array_flag = 1;
   size_local_rows = BIG;
   size_local_cols = 1 + ndim + nvalues;
   extarray = 0;
 
   // setup scaling
 
   int triclinic = domain->triclinic;
   if (triclinic == 1 && scaleflag != REDUCED)
     error->all("Fix ave/spatial for triclinic boxes requires units reduced");
 
   if (scaleflag == LATTICE && domain->lattice == NULL)
     error->all("Use of fix ave/spatial with undefined lattice");
 
   if (scaleflag == LATTICE) {
     xscale = domain->lattice->xlattice;
     yscale = domain->lattice->ylattice;
     zscale = domain->lattice->zlattice;
   }
   else xscale = yscale = zscale = 1.0;
 
   // apply scaling factors
 
   double scale;
   for (int idim = 0; idim < ndim; idim++) {
     if (dim[idim] == 0) scale = xscale;
     else if (dim[idim] == 1) scale = yscale;
     else if (dim[idim] == 2) scale = zscale;
     delta[idim] *= scale;
     if (originflag[idim] == COORD) origin[idim] *= scale;
     invdelta[idim] = 1.0/delta[idim];
   }
 
   // initializations
 
   irepeat = 0;
   iwindow = window_limit = 0;
   norm = 0;
 
   maxvar = 0;
   varatom = NULL;
 
   maxatom = 0;
   bin = NULL;
 
   nbins = maxbin = 0;
   count_one = count_many = count_sum = count_total = NULL;
   coord = NULL;
   count_list = NULL;
   values_one = values_many = values_sum = values_total = NULL;
   values_list = NULL;
 
   // nvalid = next step on which end_of_step does something
   // add nvalid to all computes that store invocation times
   // since don't know a priori which are invoked by this fix
   // once in end_of_step() can set timestep for ones actually invoked
 
   nvalid = nextvalid();
   modify->addstep_compute_all(nvalid);
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixAveSpatial::~FixAveSpatial()
 {
   delete [] which;
   delete [] argindex;
   for (int i = 0; i < nvalues; i++) delete [] ids[i];
   delete [] ids;
   delete [] value2index;
   delete [] idregion;
 
   if (fp && me == 0) fclose(fp);
 
   memory->sfree(varatom);
   memory->sfree(bin);
 
   memory->sfree(count_one);
   memory->sfree(count_many);
   memory->sfree(count_sum);
   memory->sfree(count_total);
   memory->destroy_2d_double_array(coord);
   memory->destroy_2d_double_array(count_list);
   memory->destroy_2d_double_array(values_one);
   memory->destroy_2d_double_array(values_many);
   memory->destroy_2d_double_array(values_sum);
   memory->destroy_2d_double_array(values_total);
   memory->destroy_3d_double_array(values_list);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixAveSpatial::setmask()
 {
   int mask = 0;
   mask |= END_OF_STEP;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixAveSpatial::init()
 {
   // set and check validity of region
 
   if (regionflag) {
     iregion = domain->find_region(idregion);
     if (iregion == -1)
       error->all("Region ID for fix ave/spatial does not exist");
     region = domain->regions[iregion];
   }
 
   // # of bins cannot vary for ave = RUNNING or WINDOW
 
   if (ave == RUNNING || ave == WINDOW) {
     if (scaleflag != REDUCED && domain->box_change)
       error->all("Fix ave/spatial settings invalid with changing box");
   }
 
   // set indices and check validity of all computes,fixes,variables
   // check that fix frequency is acceptable
 
   for (int m = 0; m < nvalues; m++) {
     if (which[m] == COMPUTE) {
       int icompute = modify->find_compute(ids[m]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/spatial does not exist");
       value2index[m] = icompute;
       
     } else if (which[m] == FIX) {
       int ifix = modify->find_fix(ids[m]);
       if (ifix < 0) 
 	error->all("Fix ID for fix ave/spatial does not exist");
       value2index[m] = ifix;
 
       if (nevery % modify->fix[ifix]->peratom_freq)
 	error->all("Fix for fix ave/spatial not computed at compatible time");
 
     } else if (which[m] == VARIABLE) {
       int ivariable = input->variable->find(ids[m]);
       if (ivariable < 0) 
 	error->all("Variable name for fix ave/spatial does not exist");
       value2index[m] = ivariable;
 
     } else value2index[m] = -1;
   }
 
   // need to reset nvalid if nvalid < ntimestep b/c minimize was performed
 
   if (nvalid < update->ntimestep) {
     irepeat = 0;
     nvalid = nextvalid();
     modify->addstep_compute_all(nvalid);
   }
 }
 
 /* ----------------------------------------------------------------------
    setup initial bins
    only does averaging if nvalid = current timestep
 ------------------------------------------------------------------------- */
 
 void FixAveSpatial::setup(int vflag)
 {
   setup_bins();
   end_of_step();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixAveSpatial::end_of_step()
 {
   int i,j,m,n;
 
   // skip if not step which requires doing something
 
-  int ntimestep = update->ntimestep;
+  bigint ntimestep = update->ntimestep;
   if (ntimestep != nvalid) return;
 
   // zero out arrays that accumulate over many samples
   // if box changes, first re-setup bins
 
   if (irepeat == 0) {
     if (domain->box_change) setup_bins();
     for (m = 0; m < nbins; m++) {
       count_many[m] = count_sum[m] = 0.0;
       for (i = 0; i < nvalues; i++) values_many[m][i] = 0.0;
     }
   }
 
   // zero out arrays for one sample
 
   for (m = 0; m < nbins; m++) {
     count_one[m] = 0.0;
     for (i = 0; i < nvalues; i++) values_one[m][i] = 0.0;
   }
 
   // assign each atom to a bin
 
   double **x = atom->x;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   if (nlocal > maxatom) {
     maxatom = atom->nmax;
     memory->sfree(bin);
     bin = (int *) 
       memory->smalloc(maxatom*sizeof(int),"ave/spatial:bin");
   }
 
   if (ndim == 1) atom2bin1d();
   else if (ndim == 2) atom2bin2d();
   else atom2bin3d();
 
   // perform the computation for one sample
   // accumulate results of attributes,computes,fixes,variables to local copy
   // sum within each bin, only include atoms in fix group
   // compute/fix/variable may invoke computes so wrap with clear/add
 
   modify->clearstep_compute();
 
   for (m = 0; m < nvalues; m++) {
     n = value2index[m];
     j = argindex[m];
 
     // V,F adds velocities,forces to values
 
     if (which[m] == V || which[m] == F) {
       double **attribute;
       if (which[m] == V) attribute = atom->v;
       else attribute = atom->f;
       
       if (regionflag == 0) {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit)
 	    values_one[bin[i]][m] += attribute[i][j];
       } else {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
 	    values_one[bin[i]][m] += attribute[i][j];
       }
 
     // DENSITY_NUMBER adds 1 to values
 
     } else if (which[m] == DENSITY_NUMBER) {
 
       if (regionflag == 0) {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit)
 	    values_one[bin[i]][m] += 1.0;
       } else {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
 	    values_one[bin[i]][m] += 1.0;
       }
 
     // DENSITY_MASS adds mass to values
 
     } else if (which[m] == DENSITY_MASS) {
       int *type = atom->type;
       double *mass = atom->mass;
       double *rmass = atom->rmass;
 
       if (regionflag == 0) {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit) {
 	    if (rmass) values_one[bin[i]][m] += rmass[i];
 	    else values_one[bin[i]][m] += mass[type[i]];
 	  }
       } else {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
 	    if (rmass) values_one[bin[i]][m] += rmass[i];
 	    else values_one[bin[i]][m] += mass[type[i]];
 	  }
       }
 
     // COMPUTE adds its scalar or vector component to values
     // invoke compute if not previously invoked
 
     } else if (which[m] == COMPUTE) {
       Compute *compute = modify->compute[n];
       if (!(compute->invoked_flag & INVOKED_PERATOM)) {
 	compute->compute_peratom();
 	compute->invoked_flag |= INVOKED_PERATOM;
       }
       double *vector = compute->vector_atom;
       double **array = compute->array_atom;
       int jm1 = j - 1;
 
       if (regionflag == 0) {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit) {
 	    if (j == 0) values_one[bin[i]][m] += vector[i];
 	    else values_one[bin[i]][m] += array[i][jm1];
 	  }
       } else {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
 	    if (j == 0) values_one[bin[i]][m] += vector[i];
 	    else values_one[bin[i]][m] += array[i][jm1];
 	  }
       }
 
     // FIX adds its scalar or vector component to values
     // access fix fields, guaranteed to be ready
 
     } else if (which[m] == FIX) {
       double *vector = modify->fix[n]->vector_atom;
       double **array = modify->fix[n]->array_atom;
       int jm1 = j - 1;
 
       if (regionflag == 0) {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit) {
 	    if (j == 0) values_one[bin[i]][m] += vector[i];
 	    else values_one[bin[i]][m] += array[i][jm1];
 	  }
       } else {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
 	    if (j == 0) values_one[bin[i]][m] += vector[i];
 	    else values_one[bin[i]][m] += array[i][jm1];
 	  }
       }
 
     // VARIABLE adds its per-atom quantities to values
     // evaluate atom-style variable
 
     } else if (which[m] == VARIABLE) {
       if (nlocal > maxvar) {
 	maxvar = atom->nmax;
 	memory->sfree(varatom);
 	varatom = (double *) 
 	  memory->smalloc(maxvar*sizeof(double),"ave/spatial:varatom");
       }
 
       input->variable->compute_atom(n,igroup,varatom,1,0);
 
       if (regionflag == 0) {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit)
 	    values_one[bin[i]][m] += varatom[i];
       } else {
 	for (i = 0; i < nlocal; i++)
 	  if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
 	    values_one[bin[i]][m] += varatom[i];
       }
     }
   }
 
   // process a single sample
   // if normflag = ALL, accumulate values,count separately to many
   // if normflag = SAMPLE, one = value/count, accumulate one to many
   // exception is SAMPLE density: no normalization by atom count
 
   if (normflag == ALL) {
     for (m = 0; m < nbins; m++) {
       count_many[m] += count_one[m];
       for (j = 0; j < nvalues; j++)
 	values_many[m][j] += values_one[m][j];
     }
   } else {
     MPI_Allreduce(count_one,count_many,nbins,MPI_DOUBLE,MPI_SUM,world);
     for (m = 0; m < nbins; m++) {
       if (count_many[m] > 0.0)
 	for (j = 0; j < nvalues; j++) {
 	  if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS)
 	    values_many[m][j] += values_one[m][j];
 	  else values_many[m][j] += values_one[m][j]/count_many[m];
 	}
       count_sum[m] += count_many[m];
     }
   }
 
   // done if irepeat < nrepeat
   // else reset irepeat and nvalid
 
   irepeat++;
   if (irepeat < nrepeat) {
     nvalid += nevery;
     modify->addstep_compute(nvalid);
     return;
   }
 
   irepeat = 0;
   nvalid = ntimestep+nfreq - (nrepeat-1)*nevery;
   modify->addstep_compute(nvalid);
 
   // time average across samples
   // if normflag = ALL, final is total value / total count
   // if normflag = SAMPLE, final is sum of ave / repeat
   // exception is densities: normalized by repeat, not total count
 
   double repeat = nrepeat;
   double mv2d = force->mv2d;
 
   if (normflag == ALL) {
     MPI_Allreduce(count_many,count_sum,nbins,MPI_DOUBLE,MPI_SUM,world);
     MPI_Allreduce(&values_many[0][0],&values_sum[0][0],nbins*nvalues,
 		  MPI_DOUBLE,MPI_SUM,world);
     for (m = 0; m < nbins; m++) {
       if (count_sum[m] > 0.0)
 	for (j = 0; j < nvalues; j++)
 	  if (which[j] == DENSITY_NUMBER) values_sum[m][j] /= repeat;
 	  else if (which[j] == DENSITY_MASS) values_sum[m][j] *= mv2d/repeat;
 	  else values_sum[m][j] /= count_sum[m];
       count_sum[m] /= repeat;
     }
   } else {
     MPI_Allreduce(&values_many[0][0],&values_sum[0][0],nbins*nvalues,
 		  MPI_DOUBLE,MPI_SUM,world);
     for (m = 0; m < nbins; m++) {
       for (j = 0; j < nvalues; j++)
 	values_sum[m][j] /= repeat;
       count_sum[m] /= repeat;
     }
   }
 
   // density is additionally normalized by bin volume
 
   for (j = 0; j < nvalues; j++)
     if (which[j] == DENSITY_NUMBER || which[j] == DENSITY_MASS)
       for (m = 0; m < nbins; m++)
 	values_sum[m][j] /= bin_volume;
 
   // if ave = ONE, only single Nfreq timestep value is needed
   // if ave = RUNNING, combine with all previous Nfreq timestep values
   // if ave = WINDOW, comine with nwindow most recent Nfreq timestep values
 
   if (ave == ONE) {
     for (m = 0; m < nbins; m++) {
       for (i = 0; i < nvalues; i++) 
 	values_total[m][i] = values_sum[m][i];
       count_total[m] = count_sum[m];
     }
     norm = 1;
 
   } else if (ave == RUNNING) {
     for (m = 0; m < nbins; m++) {
       for (i = 0; i < nvalues; i++)
 	values_total[m][i] += values_sum[m][i];
       count_total[m] += count_sum[m];
     }
     norm++;
 
   } else if (ave == WINDOW) {
     for (m = 0; m < nbins; m++) {
       for (i = 0; i < nvalues; i++) {
 	values_total[m][i] += values_sum[m][i];
 	if (window_limit) values_total[m][i] -= values_list[iwindow][m][i];
 	values_list[iwindow][m][i] = values_sum[m][i];
       }
       count_total[m] += count_sum[m];
       if (window_limit) count_total[m] -= count_list[iwindow][m];
       count_list[iwindow][m] = count_sum[m];
     }
 
     iwindow++;
     if (iwindow == nwindow) {
       iwindow = 0;
       window_limit = 1;
     }
     if (window_limit) norm = nwindow;
     else norm = iwindow;
   }
 
   // output result to file
   
   if (fp && me == 0) {
-    fprintf(fp,"%d %d\n",ntimestep,nbins);
+    char fstr[16];
+    sprintf(fstr,"%s %%d\n",BIGINT_FORMAT);
+    fprintf(fp,fstr,ntimestep,nbins);
     if (ndim == 1)
       for (m = 0; m < nbins; m++) {
 	fprintf(fp,"  %d %g %g",m+1,coord[m][0],
 		count_total[m]/norm);
 	for (i = 0; i < nvalues; i++) 
 	  fprintf(fp," %g",values_total[m][i]/norm);
 	fprintf(fp,"\n");
       }
     else if (ndim == 2)
       for (m = 0; m < nbins; m++) {
 	fprintf(fp,"  %d %g %g %g",m+1,coord[m][0],coord[m][1],
 		count_total[m]/norm);
 	for (i = 0; i < nvalues; i++) 
 	  fprintf(fp," %g",values_total[m][i]/norm);
 	fprintf(fp,"\n");
       }
     else
       for (m = 0; m < nbins; m++) {
 	fprintf(fp,"  %d %g %g %g %g",m+1,coord[m][0],coord[m][1],coord[m][2],
 		count_total[m]/norm);
 	for (i = 0; i < nvalues; i++) 
 	  fprintf(fp," %g",values_total[m][i]/norm);
 	fprintf(fp,"\n");
       }
 
     fflush(fp);
   }
 }
 
 /* ----------------------------------------------------------------------
    setup 1d, 2d, or 3d bins and their extent and coordinates
    called at setup() and when averaging occurs if box size changes
 ------------------------------------------------------------------------- */
 
 void FixAveSpatial::setup_bins()
 {
   int i,j,k,m,n;
   double lo,hi,coord1,coord2;
 
   // lo = bin boundary immediately below boxlo
   // hi = bin boundary immediately above boxhi
   // allocate and initialize arrays based on new bin count
 
   double *boxlo,*boxhi,*prd;
   if (scaleflag == REDUCED) {
     boxlo = domain->boxlo_lamda;
     boxhi = domain->boxhi_lamda;
     prd = domain->prd_lamda;
   } else {
     boxlo = domain->boxlo;
     boxhi = domain->boxhi;
     prd = domain->prd;
   }
 
   if (domain->dimension == 3)
     bin_volume = domain->xprd * domain->yprd * domain->zprd;
   else bin_volume = domain->xprd * domain->yprd;
   nbins = 1;
 
   for (m = 0; m < ndim; m++) {
     if (originflag[m] == LOWER) origin[m] = boxlo[dim[m]];
     else if (originflag[m] == UPPER) origin[m] = boxhi[dim[m]];
     else if (originflag[m] == CENTER) 
       origin[m] = 0.5 * (boxlo[dim[m]] + boxhi[dim[m]]);
     
     if (origin[m] < boxlo[dim[m]]) {
       n = static_cast<int> ((boxlo[dim[m]] - origin[m]) * invdelta[m]);
       lo = origin[m] + n*delta[m];
     } else {
       n = static_cast<int> ((origin[m] - boxlo[dim[m]]) * invdelta[m]);
       lo = origin[m] - n*delta[m];
       if (lo > boxlo[dim[m]]) lo -= delta[m];
     }
     if (origin[m] < boxhi[dim[m]]) {
       n = static_cast<int> ((boxhi[dim[m]] - origin[m]) * invdelta[m]);
       hi = origin[m] + n*delta[m];
       if (hi < boxhi[dim[m]]) hi += delta[m];
     } else {
       n = static_cast<int> ((origin[m] - boxhi[dim[m]]) * invdelta[m]);
       hi = origin[m] - n*delta[m];
     }
     
     offset[m] = lo;
     nlayers[m] = static_cast<int> ((hi-lo) * invdelta[m] + 0.5);
     nbins *= nlayers[m];
     bin_volume *= delta[m]/prd[dim[m]];
   }
 
   // reallocate bin arrays if needed
 
   if (nbins > maxbin) {
     maxbin = nbins;
     count_one = (double *) 
       memory->srealloc(count_one,nbins*sizeof(double),
 		       "ave/spatial:count_one");
     count_many = (double *) 
       memory->srealloc(count_many,nbins*sizeof(double),
 		       "ave/spatial:count_many");
     count_sum = (double *) 
       memory->srealloc(count_sum,nbins*sizeof(double),
 		       "ave/spatial:count_sum");
     count_total = (double *) 
       memory->srealloc(count_total,nbins*sizeof(double),
 		       "ave/spatial:count_total");
     
     coord = 
       memory->grow_2d_double_array(coord,nbins,ndim,"ave/spatial:coord");
     values_one = memory->grow_2d_double_array(values_one,nbins,nvalues,
 					      "ave/spatial:values_one");
     values_many = memory->grow_2d_double_array(values_many,nbins,nvalues,
 					       "ave/spatial:values_many");
     values_sum = memory->grow_2d_double_array(values_sum,nbins,nvalues,
 					      "ave/spatial:values_sum");
     values_total = memory->grow_2d_double_array(values_total,nbins,nvalues,
 						"ave/spatial:values_total");
     
     // only allocate count and values list for ave = WINDOW
     
     if (ave == WINDOW) {
       count_list =
 	memory->create_2d_double_array(nwindow,nbins,
 				       "ave/spatial:count_list");
       values_list =
 	memory->create_3d_double_array(nwindow,nbins,nvalues,
 				       "ave/spatial:values_list");
     }
 
     // reinitialize regrown count/values total since they accumulate
 
     for (m = 0; m < nbins; m++) {
       for (i = 0; i < nvalues; i++) values_total[m][i] = 0.0;
       count_total[m] = 0.0;
     }
   }
 
   // set bin coordinates
 
   if (ndim == 1) {
     for (i = 0; i < nlayers[0]; i++)
       coord[i][0] = offset[0] + (i+0.5)*delta[0];
   } else if (ndim == 2) {
     m = 0;
     for (i = 0; i < nlayers[0]; i++) {
       coord1 = offset[0] + (i+0.5)*delta[0];
       for (j = 0; j < nlayers[1]; j++) {
 	coord[m][0] = coord1;
 	coord[m][1] = offset[1] + (j+0.5)*delta[1];
 	m++;
       }
     }
   } else if (ndim == 3) {
     m = 0;
     for (i = 0; i < nlayers[0]; i++) {
       coord1 = offset[0] + (i+0.5)*delta[0];
       for (j = 0; j < nlayers[1]; j++) {
 	coord2 = offset[1] + (j+0.5)*delta[1];
 	for (k = 0; k < nlayers[2]; k++) {
 	  coord[m][0] = coord1;
 	  coord[m][1] = coord2;
 	  coord[m][2] = offset[2] + (k+0.5)*delta[2];
 	  m++;
 	}
       }
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    assign each atom to a 1d bin
 ------------------------------------------------------------------------- */
 
 void FixAveSpatial::atom2bin1d()
 {
   int i,ibin;
   double *boxlo,*boxhi,*prd;
   double xremap;
   double lamda[3];
 
   double **x = atom->x;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int idim = dim[0];
   int nlayerm1 = nlayers[0] - 1;
   int periodicity = domain->periodicity[idim];
 
   if (periodicity) {
     if (scaleflag == REDUCED) {
       boxlo = domain->boxlo_lamda;
       boxhi = domain->boxhi_lamda;
       prd = domain->prd_lamda;
     } else {
       boxlo = domain->boxlo;
       boxhi = domain->boxhi;
       prd = domain->prd;
     }
   }
 
   // remap each atom's relevant coord back into box via PBC if necessary
   // if scaleflag = REDUCED, box coords -> lamda coords
 
   if (regionflag == 0) {
     if (scaleflag == REDUCED) domain->x2lamda(nlocal);
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	xremap = x[i][idim];
 	if (periodicity) {
 	  if (xremap < boxlo[idim]) xremap += prd[idim];
 	  if (xremap >= boxhi[idim]) xremap -= prd[idim];
 	}
 	ibin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
 	ibin = MAX(ibin,0);
 	ibin = MIN(ibin,nlayerm1);
 	bin[i] = ibin;
 	count_one[ibin] += 1.0;
       }
     if (scaleflag == REDUCED) domain->lamda2x(nlocal);
 
   } else {
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
 	if (scaleflag == REDUCED) {
 	  domain->x2lamda(x[i],lamda);
 	  xremap = lamda[idim];
 	} else xremap = x[i][idim];
 	if (periodicity) {
 	  if (xremap < boxlo[idim]) xremap += prd[idim];
 	  if (xremap >= boxhi[idim]) xremap -= prd[idim];
 	}
 	ibin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
 	ibin = MAX(ibin,0);
 	ibin = MIN(ibin,nlayerm1);
 	bin[i] = ibin;
 	count_one[ibin] += 1.0;
       }
   }
 }
 
 /* ----------------------------------------------------------------------
    assign each atom to a 2d bin
 ------------------------------------------------------------------------- */
 
 void FixAveSpatial::atom2bin2d()
 {
   int i,ibin,i1bin,i2bin;
   double *boxlo,*boxhi,*prd;
   double xremap,yremap;
   double lamda[3];
 
   double **x = atom->x;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int idim = dim[0];
   int jdim = dim[1];
   int nlayer1m1 = nlayers[0] - 1;
   int nlayer2m1 = nlayers[1] - 1;
   int* periodicity = domain->periodicity;
 
   if (periodicity[idim] || periodicity[jdim]) {
     if (scaleflag == REDUCED) {
       boxlo = domain->boxlo_lamda;
       boxhi = domain->boxhi_lamda;
       prd = domain->prd_lamda;
     } else {
       boxlo = domain->boxlo;
       boxhi = domain->boxhi;
       prd = domain->prd;
     }
   }
 
   // remap each atom's relevant coord back into box via PBC if necessary
   // if scaleflag = REDUCED, box coords -> lamda coords
 
   if (regionflag == 0) {
     if (scaleflag == REDUCED) domain->x2lamda(nlocal);
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	xremap = x[i][idim];
 	if (periodicity[idim]) {
 	  if (xremap < boxlo[idim]) xremap += prd[idim];
 	  if (xremap >= boxhi[idim]) xremap -= prd[idim];
 	}
 	i1bin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
 	i1bin = MAX(i1bin,0);
 	i1bin = MIN(i1bin,nlayer1m1);
 
 	yremap = x[i][jdim];
 	if (periodicity[jdim]) {
 	  if (yremap < boxlo[jdim]) yremap += prd[jdim];
 	  if (yremap >= boxhi[jdim]) yremap -= prd[jdim];
 	}
 	i2bin = static_cast<int> ((yremap - offset[1]) * invdelta[1]);
 	i2bin = MAX(i2bin,0);
 	i2bin = MIN(i2bin,nlayer2m1);
 
 	ibin = i1bin*nlayers[1] + i2bin;
 	bin[i] = ibin;
 	count_one[ibin] += 1.0;
       }
     if (scaleflag == REDUCED) domain->lamda2x(nlocal);
 
   } else {
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
 	if (scaleflag == REDUCED) {
 	  domain->x2lamda(x[i],lamda);
 	  xremap = lamda[idim];
 	  yremap = lamda[jdim];
 	} else {
 	  xremap = x[i][idim];
 	  yremap = x[i][jdim];
 	}
 
 	if (periodicity[idim]) {
 	  if (xremap < boxlo[idim]) xremap += prd[idim];
 	  if (xremap >= boxhi[idim]) xremap -= prd[idim];
 	}
 	i1bin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
 	i1bin = MAX(i1bin,0);
 	i1bin = MIN(i1bin,nlayer1m1-1);
 
 	if (periodicity[jdim]) {
 	  if (yremap < boxlo[jdim]) yremap += prd[jdim];
 	  if (yremap >= boxhi[jdim]) yremap -= prd[jdim];
 	}
 	i2bin = static_cast<int> ((yremap - offset[1]) * invdelta[1]);
 	i2bin = MAX(i2bin,0);
 	i2bin = MIN(i2bin,nlayer2m1-1);
 
 	ibin = i1bin*nlayers[1] + i2bin;
 	bin[i] = ibin;
 	count_one[ibin] += 1.0;
       }
   }
 }
 
 /* ----------------------------------------------------------------------
    assign each atom to a 3d bin
 ------------------------------------------------------------------------- */
 
 void FixAveSpatial::atom2bin3d()
 {
   int i,ibin,i1bin,i2bin,i3bin;
   double *boxlo,*boxhi,*prd;
   double xremap,yremap,zremap;
   double lamda[3];
 
   double **x = atom->x;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int idim = dim[0];
   int jdim = dim[1];
   int kdim = dim[2];
   int nlayer1m1 = nlayers[0] - 1;
   int nlayer2m1 = nlayers[1] - 1;
   int nlayer3m1 = nlayers[2] - 1;
   int* periodicity = domain->periodicity;
 
   if (periodicity[idim] || periodicity[jdim] || periodicity[kdim]) {
     if (scaleflag == REDUCED) {
       boxlo = domain->boxlo_lamda;
       boxhi = domain->boxhi_lamda;
       prd = domain->prd_lamda;
     } else {
       boxlo = domain->boxlo;
       boxhi = domain->boxhi;
       prd = domain->prd;
     }
   }
 
   // remap each atom's relevant coord back into box via PBC if necessary
   // if scaleflag = REDUCED, box coords -> lamda coords
 
   if (regionflag == 0) {
     if (scaleflag == REDUCED) domain->x2lamda(nlocal);
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	xremap = x[i][idim];
 	if (periodicity[idim]) {
 	  if (xremap < boxlo[idim]) xremap += prd[idim];
 	  if (xremap >= boxhi[idim]) xremap -= prd[idim];
 	}
 	i1bin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
 	i1bin = MAX(i1bin,0);
 	i1bin = MIN(i1bin,nlayer1m1);
 
 	yremap = x[i][jdim];
 	if (periodicity[jdim]) {
 	  if (yremap < boxlo[jdim]) yremap += prd[jdim];
 	  if (yremap >= boxhi[jdim]) yremap -= prd[jdim];
 	}
 	i2bin = static_cast<int> ((yremap - offset[1]) * invdelta[1]);
 	i2bin = MAX(i2bin,0);
 	i2bin = MIN(i2bin,nlayer2m1);
 
 	zremap = x[i][kdim];
 	if (periodicity[kdim]) {
 	  if (zremap < boxlo[kdim]) yremap += prd[kdim];
 	  if (zremap >= boxhi[kdim]) yremap -= prd[kdim];
 	}
 	i3bin = static_cast<int> ((zremap - offset[2]) * invdelta[2]);
 	i3bin = MAX(i3bin,0);
 	i3bin = MIN(i3bin,nlayer3m1);
 
 	ibin = i1bin*nlayers[1]*nlayers[2] + i2bin*nlayers[2] + i3bin;
 	bin[i] = ibin;
 	count_one[ibin] += 1.0;
       }
     if (scaleflag == REDUCED) domain->lamda2x(nlocal);
 
   } else {
     for (i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
 	if (scaleflag == REDUCED) {
 	  domain->x2lamda(x[i],lamda);
 	  xremap = lamda[idim];
 	  yremap = lamda[jdim];
 	  zremap = lamda[kdim];
 	} else {
 	  xremap = x[i][idim];
 	  yremap = x[i][jdim];
 	  zremap = x[i][kdim];
 	}
 
 	if (periodicity[idim]) {
 	  if (xremap < boxlo[idim]) xremap += prd[idim];
 	  if (xremap >= boxhi[idim]) xremap -= prd[idim];
 	}
 	i1bin = static_cast<int> ((xremap - offset[0]) * invdelta[0]);
 	i1bin = MAX(i1bin,0);
 	i1bin = MIN(i1bin,nlayer1m1);
 
 	if (periodicity[jdim]) {
 	  if (yremap < boxlo[jdim]) yremap += prd[jdim];
 	  if (yremap >= boxhi[jdim]) yremap -= prd[jdim];
 	}
 	i2bin = static_cast<int> ((yremap - offset[1]) * invdelta[1]);
 	i2bin = MAX(i2bin,0);
 	i2bin = MIN(i2bin,nlayer2m1);
 
 	if (periodicity[kdim]) {
 	  if (zremap < boxlo[kdim]) yremap += prd[kdim];
 	  if (zremap >= boxhi[kdim]) yremap -= prd[kdim];
 	}
 	i3bin = static_cast<int> ((zremap - offset[2]) * invdelta[2]);
 	i3bin = MAX(i3bin,0);
 	i3bin = MIN(i3bin,nlayer3m1);
 
 	ibin = i1bin*nlayers[1]*nlayers[2] + i2bin*nlayers[2] + i3bin;
 	bin[i] = ibin;
 	count_one[ibin] += 1.0;
       }
   }
 }
 
 /* ----------------------------------------------------------------------
    return I,J array value
    if I exceeds current bins, return 0.0 instead of generating an error
    column 1,2,3 = bin coords, next column = count, remaining columns = Nvalues
 ------------------------------------------------------------------------- */
 
 double FixAveSpatial::compute_array(int i, int j)
 {
   if (values_total == NULL) return 0.0;
   if (i >= nbins) return 0.0;
   if (j < ndim) return coord[i][j];
   j -= ndim+1;
   if (j < 0) return count_total[i]/norm;
   return values_total[i][j]/norm;
 }
 
 /* ----------------------------------------------------------------------
    calculate nvalid = next step on which end_of_step does something
    can be this timestep if multiple of nfreq and nrepeat = 1
    else backup from next multiple of nfreq
 ------------------------------------------------------------------------- */
 
-int FixAveSpatial::nextvalid()
+bigint FixAveSpatial::nextvalid()
 {
-  int nvalid = (update->ntimestep/nfreq)*nfreq + nfreq;
+  bigint nvalid = (update->ntimestep/nfreq)*nfreq + nfreq;
   if (nvalid-nfreq == update->ntimestep && nrepeat == 1)
     nvalid = update->ntimestep;
   else
     nvalid -= (nrepeat-1)*nevery;
   if (nvalid < update->ntimestep) nvalid += nfreq;
   return nvalid;
 }
 
 /* ----------------------------------------------------------------------
    memory usage of varatom and bins
 ------------------------------------------------------------------------- */
 
 double FixAveSpatial::memory_usage()
 {
   double bytes = maxvar * sizeof(double);         // varatom
   bytes += maxatom * sizeof(int);                 // bin
   bytes += 4*nbins * sizeof(double);              // count one,many,sum,total
   bytes += ndim*nbins * sizeof(double);           // coord
   bytes += nvalues*nbins * sizeof(double);        // values one,many,sum,total
   bytes += nwindow*nbins * sizeof(double);          // count_list
   bytes += nwindow*nbins*nvalues * sizeof(double);  // values_list
   return bytes;
 }
diff --git a/src/fix_ave_spatial.h b/src/fix_ave_spatial.h
index 66dec3eaa..eefd20347 100644
--- a/src/fix_ave_spatial.h
+++ b/src/fix_ave_spatial.h
@@ -1,81 +1,83 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef FIX_CLASS
 
 FixStyle(ave/spatial,FixAveSpatial)
 
 #else
 
 #ifndef LMP_FIX_AVE_SPATIAL_H
 #define LMP_FIX_AVE_SPATIAL_H
 
 #include "stdio.h"
 #include "fix.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class FixAveSpatial : public Fix {
  public:
   FixAveSpatial(class LAMMPS *, int, char **);
   ~FixAveSpatial();
   int setmask();
   void init();
   void setup(int);
   void end_of_step();
   double compute_array(int,int);
   double memory_usage();
 
  private:
   int me,nvalues;
-  int nrepeat,nfreq,nvalid,irepeat;
+  int nrepeat,nfreq,irepeat;
+  bigint nvalid;
   int ndim,normflag,regionflag,iregion;
   char *tstring,*sstring,*idregion;
   int *which,*argindex,*value2index;
   char **ids;
   FILE *fp;
   class Region *region;
 
   int ave,nwindow,scaleflag;
   int norm,iwindow,window_limit;
   double xscale,yscale,zscale;
   double bin_volume;
 
   int dim[3],originflag[3],nlayers[3];
   double origin[3],delta[3];
   double offset[3],invdelta[3]; 
 
   int maxvar;
   double *varatom;
 
   int maxatom;
   int *bin;
 
   int nbins,maxbin;
   double **coord;
   double *count_one,*count_many,*count_sum;
   double **values_one,**values_many,**values_sum;
   double *count_total,**count_list;
   double **values_total,***values_list;
 
   void setup_bins();
   void atom2bin1d();
   void atom2bin2d();
   void atom2bin3d();
-  int nextvalid();
+  bigint nextvalid();
 };
 
 }
 
 #endif
 #endif
diff --git a/src/fix_ave_time.cpp b/src/fix_ave_time.cpp
index 2edc58074..a2138243c 100644
--- a/src/fix_ave_time.cpp
+++ b/src/fix_ave_time.cpp
@@ -1,932 +1,935 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Pieter in 't Veld (SNL)
 ------------------------------------------------------------------------- */
 
 #include "stdlib.h"
 #include "string.h"
 #include "fix_ave_time.h"
+#include "lmptype.h"
 #include "update.h"
 #include "modify.h"
 #include "compute.h"
 #include "group.h"
 #include "input.h"
 #include "variable.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{COMPUTE,FIX,VARIABLE};
 enum{ONE,RUNNING,WINDOW};
 enum{SCALAR,VECTOR};
 
 #define INVOKED_SCALAR 1
 #define INVOKED_VECTOR 2
 #define INVOKED_ARRAY 4
 
 /* ---------------------------------------------------------------------- */
 
 FixAveTime::FixAveTime(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 7) error->all("Illegal fix ave/time command");
 
   MPI_Comm_rank(world,&me);
 
   nevery = atoi(arg[3]);
   nrepeat = atoi(arg[4]);
   nfreq = atoi(arg[5]);
 
   global_freq = nfreq;
   time_depend = 1;
 
   // scan values to count them
   // then read options so know mode = SCALAR/VECTOR before re-reading values
 
   nvalues = 0;
 
   int iarg = 6;
   while (iarg < narg) {
     if ((strncmp(arg[iarg],"c_",2) == 0) || 
 	(strncmp(arg[iarg],"f_",2) == 0) || 
 	(strncmp(arg[iarg],"v_",2) == 0)) {
       nvalues++;
       iarg++;
     } else break;
   }
 
   options(narg,arg);
 
   // parse values until one isn't recognized
   // if mode = VECTOR and value is a global array:
   //   expand it as if columns listed one by one
   //   adjust nvalues accordingly via maxvalues
 
   which = argindex = value2index = offcol = NULL;
   ids = NULL;
   int maxvalues = nvalues;
   allocate_values(maxvalues);
   nvalues = 0;
 
   iarg = 6;
   while (iarg < narg) {
     if (strncmp(arg[iarg],"c_",2) == 0 || 
 	strncmp(arg[iarg],"f_",2) == 0 || 
 	strncmp(arg[iarg],"v_",2) == 0) {
       if (arg[iarg][0] == 'c') which[nvalues] = COMPUTE;
       else if (arg[iarg][0] == 'f') which[nvalues] = FIX;
       else if (arg[iarg][0] == 'v') which[nvalues] = VARIABLE;
 
       int n = strlen(arg[iarg]);
       char *suffix = new char[n];
       strcpy(suffix,&arg[iarg][2]);
 
       char *ptr = strchr(suffix,'[');
       if (ptr) {
 	if (suffix[strlen(suffix)-1] != ']')
 	  error->all("Illegal fix ave/time command");
 	argindex[nvalues] = atoi(ptr+1);
 	*ptr = '\0';
       } else argindex[nvalues] = 0;
 
       n = strlen(suffix) + 1;
       ids[nvalues] = new char[n];
       strcpy(ids[nvalues],suffix);
       delete [] suffix;
 
       if (mode == VECTOR && which[nvalues] == COMPUTE && 
 	  argindex[nvalues] == 0) {
 	int icompute = modify->find_compute(ids[nvalues]);
 	if (icompute < 0)
 	  error->all("Compute ID for fix ave/time does not exist");
 	if (modify->compute[icompute]->array_flag) {
 	  int ncols = modify->compute[icompute]->size_array_cols;
 	  maxvalues += ncols-1;
 	  allocate_values(maxvalues);
 	  argindex[nvalues] = 1;
 	  for (int icol = 1; icol < ncols; icol++) {
 	    which[nvalues+icol] = which[nvalues];
 	    argindex[nvalues+icol] = icol+1;
 	    n = strlen(ids[nvalues]) + 1;
 	    ids[nvalues+icol] = new char[n];
 	    strcpy(ids[nvalues+icol],ids[nvalues]);
 	  }
 	  nvalues += ncols-1;
 	}
 
       } else if (mode == VECTOR && which[nvalues] == FIX && 
 		 argindex[nvalues] == 0) {
 	int ifix = modify->find_fix(ids[nvalues]);
 	if (ifix < 0)
 	  error->all("Fix ID for fix ave/time does not exist");
 	if (modify->fix[ifix]->array_flag) {
 	  int ncols = modify->fix[ifix]->size_array_cols;
 	  maxvalues += ncols-1;
 	  allocate_values(maxvalues);
 	  argindex[nvalues] = 1;
 	  for (int icol = 1; icol < ncols; icol++) {
 	    which[nvalues+icol] = which[nvalues];
 	    argindex[nvalues+icol] = icol+1;
 	    n = strlen(ids[nvalues]) + 1;
 	    ids[nvalues+icol] = new char[n];
 	    strcpy(ids[nvalues+icol],ids[nvalues]);
 	  }
 	  nvalues += ncols-1;
 	}
       }
 
       nvalues++;
       iarg++;
     } else break;
   }
 
   // set off columns now that nvalues is finalized
 
   for (int i = 0; i < nvalues; i++) offcol[i] = 0;
   for (int i = 0; i < noff; i++) {
     if (offlist[i] < 1 || offlist[i] > nvalues)
       error->all("Invalid fix ave/time off column");
     offcol[offlist[i]-1] = 1;
   }
 
   // setup and error check
   // for fix inputs, check that fix frequency is acceptable
 
   if (nevery <= 0 || nrepeat <= 0 || nfreq <= 0)
     error->all("Illegal fix ave/time command");
   if (nfreq % nevery || (nrepeat-1)*nevery >= nfreq)
     error->all("Illegal fix ave/time command");
 
   for (int i = 0; i < nvalues; i++) {
     if (which[i] == COMPUTE && mode == SCALAR) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/time does not exist");
       if (argindex[i] == 0 && modify->compute[icompute]->scalar_flag == 0)
 	error->all("Fix ave/time compute does not calculate a scalar");
       if (argindex[i] && modify->compute[icompute]->vector_flag == 0)
 	error->all("Fix ave/time compute does not calculate a vector");
       if (argindex[i] && argindex[i] > modify->compute[icompute]->size_vector)
 	error->all("Fix ave/time compute vector is accessed out-of-range");
 
     } else if (which[i] == COMPUTE && mode == VECTOR) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/time does not exist");
       if (argindex[i] == 0 && modify->compute[icompute]->vector_flag == 0)
 	error->all("Fix ave/time compute does not calculate a vector");
       if (argindex[i] && modify->compute[icompute]->array_flag == 0)
 	error->all("Fix ave/time compute does not calculate an array");
       if (argindex[i] && 
 	  argindex[i] > modify->compute[icompute]->size_array_cols)
 	error->all("Fix ave/time compute array is accessed out-of-range");
 
     } else if (which[i] == FIX && mode == SCALAR) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0)
 	error->all("Fix ID for fix ave/time does not exist");
       if (argindex[i] == 0 && modify->fix[ifix]->scalar_flag == 0)
 	error->all("Fix ave/time fix does not calculate a scalar");
       if (argindex[i] && modify->fix[ifix]->vector_flag == 0)
 	error->all("Fix ave/time fix does not calculate a vector");
       if (argindex[i] && argindex[i] > modify->fix[ifix]->size_vector)
 	error->all("Fix ave/time fix vector is accessed out-of-range");
       if (nevery % modify->fix[ifix]->global_freq)
 	error->all("Fix for fix ave/time not computed at compatible time");
 
     } else if (which[i] == FIX && mode == VECTOR) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0)
 	error->all("Fix ID for fix ave/time does not exist");
       if (argindex[i] == 0 && modify->fix[ifix]->vector_flag == 0)
 	error->all("Fix ave/time fix does not calculate a vector");
       if (argindex[i] && modify->fix[ifix]->array_flag == 0)
 	error->all("Fix ave/time fix does not calculate an array");
       if (argindex[i] && argindex[i] > modify->fix[ifix]->size_array_cols)
 	error->all("Fix ave/time fix array is accessed out-of-range");
       if (nevery % modify->fix[ifix]->global_freq)
 	error->all("Fix for fix ave/time not computed at compatible time");
 
     } else if (which[i] == VARIABLE) {
       int ivariable = input->variable->find(ids[i]);
       if (ivariable < 0)
 	error->all("Variable name for fix ave/time does not exist");
       if (input->variable->equalstyle(ivariable) == 0)
 	error->all("Fix ave/time variable is not equal-style variable");
       if (mode == VECTOR)
 	error->all("Fix ave/time cannot use variable with vector mode");
     }
   }
 
   // if VECTOR mode, check that all columns are same length
   // nrows = # of rows in output array
 
   if (mode == VECTOR) {
     int length;
 
     for (int i = 0; i < nvalues; i++) {
       if (which[i] == COMPUTE) {
 	int icompute = modify->find_compute(ids[i]);
 	if (argindex[i] == 0) length = modify->compute[icompute]->size_vector;
 	else length = modify->compute[icompute]->size_array_rows;
       } else if (which[i] == FIX) {
 	int ifix = modify->find_fix(ids[i]);
 	if (argindex[i] == 0) length = modify->fix[ifix]->size_vector;
 	else length = modify->fix[ifix]->size_array_rows;
       }
       if (i == 0) nrows = length;
       else if (length != nrows)
 	error->all("Fix ave/time columns are inconsistent lengths");
     }
 
     column = new double[nrows];
   } else column = NULL;
 
   // print file comment lines
   // for mode = VECTOR, cannot use arg to print
   // since array args may have been expanded to multiple vectors
 
   if (fp && me == 0) {
     if (title1) fprintf(fp,"%s\n",title1);
     else fprintf(fp,"# Time-averaged data for fix %s\n",id);
     if (title2) fprintf(fp,"%s\n",title2);
     else if (mode == SCALAR) {
       fprintf(fp,"# TimeStep");
       for (int i = 0; i < nvalues; i++) fprintf(fp," %s",arg[6+i]);
       fprintf(fp,"\n");
     } else fprintf(fp,"# TimeStep Number-of-rows\n");
     if (title3 && mode == VECTOR) fprintf(fp,"%s\n",title3);
     else if (mode == VECTOR) {
       fprintf(fp,"# Row");
       for (int i = 0; i < nvalues; i++) {
 	if (which[i] == COMPUTE) fprintf(fp," c_%s",ids[i]);
 	else if (which[i] == FIX) fprintf(fp," f_%s",ids[i]);
 	else if (which[i] == VARIABLE) fprintf(fp," v_%s",ids[i]);
 	if (argindex[i]) fprintf(fp,"[%d]",argindex[i]);
       }
       fprintf(fp,"\n");
     }
   }
 
   delete [] title1;
   delete [] title2;
   delete [] title3;
 
   // allocate memory for averaging
 
   vector = vector_total = NULL;
   vector_list = NULL;
   array = array_total = NULL;
   array_list = NULL;
   
   if (mode == SCALAR) {
     vector = new double[nvalues];
     vector_total = new double[nvalues];
     if (ave == WINDOW)
       vector_list = memory->create_2d_double_array(nwindow,nvalues,
 						   "ave/time:vector_list");
   } else {
     array = memory->create_2d_double_array(nrows,nvalues,"ave/time:array");
     array_total = memory->create_2d_double_array(nrows,nvalues,
 						 "ave/time:array_total");
     if (ave == WINDOW)
       array_list = memory->create_3d_double_array(nwindow,nrows,nvalues,
 						  "ave/time:array_list");
   }
 
   // this fix produces either a global scalar or vector or array
   // SCALAR mode produces either a scalar or vector
   // VECTOR mode produces either a vector or array
   // intensive/extensive flags set by compute,fix,variable that produces value
   
   extlist = NULL;
 
   if (mode == SCALAR) {
     if (nvalues == 1) {
       scalar_flag = 1;
       if (which[0] == COMPUTE) {
 	Compute *compute = modify->compute[modify->find_compute(ids[0])];
 	if (argindex[0] == 0) extscalar = compute->extscalar;
 	else if (compute->extvector >= 0) extscalar = compute->extvector;
 	else extscalar = compute->extlist[argindex[0]-1];
       } else if (which[0] == FIX) {
 	Fix *fix = modify->fix[modify->find_fix(ids[0])];
 	if (argindex[0] == 0) extscalar = fix->extscalar;
 	else if (fix->extvector >= 0) extscalar = fix->extvector;
 	else extscalar = fix->extlist[argindex[0]-1];
       } else if (which[0] == VARIABLE)
 	extscalar = 0;
       
     } else {
       vector_flag = 1;
       size_vector = nvalues;
       extvector = -1;
       extlist = new int[nvalues];
       for (int i = 0; i < nvalues; i++) {
 	if (which[i] == COMPUTE) {
 	  Compute *compute = modify->compute[modify->find_compute(ids[i])];
 	  if (argindex[i] == 0) extlist[i] = compute->extscalar;
 	  else if (compute->extvector >= 0) extlist[i] = compute->extvector;
 	  else extlist[i] = compute->extlist[argindex[i]-1];
 	} else if (which[i] == FIX) {
 	  Fix *fix = modify->fix[modify->find_fix(ids[i])];
 	  if (argindex[i] == 0) extlist[i] = fix->extscalar;
 	  else if (fix->extvector >= 0) extlist[i] = fix->extvector;
 	  else extlist[i] = fix->extlist[argindex[i]-1];
 	} else if (which[i] == VARIABLE)
 	  extlist[i] = 0;
       }
     }
 
   } else {
     if (nvalues == 1) {
       vector_flag = 1;
       size_vector = nrows;
       if (which[0] == COMPUTE) {
 	Compute *compute = modify->compute[modify->find_compute(ids[0])];
 	if (argindex[0] == 0) {
 	  extvector = compute->extvector;
 	  if (extvector == -1) {
 	    extlist = new int[nrows];
 	    for (int i = 0; i < nrows; i++) extlist[i] = compute->extlist[i];
 	  }
 	} else extvector = compute->extarray;
       } else if (which[0] == FIX) {
 	Fix *fix = modify->fix[modify->find_fix(ids[0])];
 	if (argindex[0] == 0) {
 	  extvector = fix->extvector;
 	  if (extvector == -1) {
 	    extlist = new int[nrows];
 	    for (int i = 0; i < nrows; i++) extlist[i] = fix->extlist[i];
 	  }
 	} else extvector = fix->extarray;
       }
 
     } else {
       array_flag = 1;
       size_local_rows = nrows;
       size_local_cols = nvalues;
       int value;
       for (int i = 0; i < nvalues; i++) {
 	if (which[i] == COMPUTE) {
 	  Compute *compute = modify->compute[modify->find_compute(ids[i])];
 	  if (argindex[i] == 0) value = compute->extvector;
 	  else value = compute->extarray;
 	} else if (which[i] == FIX) {
 	  Fix *fix = modify->fix[modify->find_fix(ids[i])];
 	  if (argindex[i] == 0) value = fix->extvector;
 	  else value = fix->extarray;
 	}
 	if (value == -1) 
 	  error->all("Fix ave/time cannot set output array "
 		     "intensive/extensive from these inputs");
 	if (i == 0) extarray = value;
 	else if (value != extarray)
 	  error->all("Fix ave/time cannot set output array "
 		     "intensive/extensive from these inputs");
       }
     }
   }
 
   // initializations
   // set vector_total/array_total to zero since it accumulates
 
   irepeat = 0;
   iwindow = window_limit = 0;
   norm = 0;
 
   if (mode == SCALAR)
     for (int i = 0; i < nvalues; i++) vector_total[i] = 0.0;
   else
     for (int i = 0; i < nrows; i++)
       for (int j = 0; j < nvalues; j++) array_total[i][j] = 0.0;
 
   // nvalid = next step on which end_of_step does something
   // add nvalid to all computes that store invocation times
   // since don't know a priori which are invoked by this fix
   // once in end_of_step() can set timestep for ones actually invoked
 
   nvalid = nextvalid();
   modify->addstep_compute_all(nvalid);
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixAveTime::~FixAveTime()
 {
   memory->sfree(which);
   memory->sfree(argindex);
   memory->sfree(value2index);
   memory->sfree(offcol);
   for (int i = 0; i < nvalues; i++) delete [] ids[i];
   memory->sfree(ids);
 
   delete [] extlist;
 
   if (fp && me == 0) fclose(fp);
 
   delete [] vector;
   delete [] vector_total;
   delete [] column;
   memory->destroy_2d_double_array(array);
   memory->destroy_2d_double_array(array_total);
   memory->destroy_3d_double_array(array_list);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixAveTime::setmask()
 {
   int mask = 0;
   mask |= END_OF_STEP;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixAveTime::init()
 {
   // set current indices for all computes,fixes,variables
 
   for (int i = 0; i < nvalues; i++) {
     if (which[i] == COMPUTE) {
       int icompute = modify->find_compute(ids[i]);
       if (icompute < 0)
 	error->all("Compute ID for fix ave/time does not exist");
       value2index[i] = icompute;
 
     } else if (which[i] == FIX) {
       int ifix = modify->find_fix(ids[i]);
       if (ifix < 0) 
 	error->all("Fix ID for fix ave/time does not exist");
       value2index[i] = ifix;
 
     } else if (which[i] == VARIABLE) {
       int ivariable = input->variable->find(ids[i]);
       if (ivariable < 0) 
 	error->all("Variable name for fix ave/time does not exist");
       value2index[i] = ivariable;
     }
   }
 
   // need to reset nvalid if nvalid < ntimestep b/c minimize was performed
 
   if (nvalid < update->ntimestep) {
     irepeat = 0;
     nvalid = nextvalid();
     modify->addstep_compute_all(nvalid);
   }
 }
 
 /* ----------------------------------------------------------------------
    only does something if nvalid = current timestep
 ------------------------------------------------------------------------- */
 
 void FixAveTime::setup(int vflag)
 {
   end_of_step();
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixAveTime::end_of_step()
 {
   // skip if not step which requires doing something
 
-  int ntimestep = update->ntimestep;
+  bigint ntimestep = update->ntimestep;
   if (ntimestep != nvalid) return;
 
   if (mode == SCALAR) invoke_scalar(ntimestep);
   else invoke_vector(ntimestep);
 }
 
 /* ---------------------------------------------------------------------- */
 
-void FixAveTime::invoke_scalar(int ntimestep)
+void FixAveTime::invoke_scalar(bigint ntimestep)
 {
   int i,m;
   double scalar;
 
   // zero if first step
 
   if (irepeat == 0)
     for (i = 0; i < nvalues; i++) vector[i] = 0.0;
 
   // accumulate results of computes,fixes,variables to local copy
   // compute/fix/variable may invoke computes so wrap with clear/add
 
   modify->clearstep_compute();
 
   for (i = 0; i < nvalues; i++) {
     m = value2index[i];
     
     // invoke compute if not previously invoked
     
     if (which[i] == COMPUTE) {
       Compute *compute = modify->compute[m];
       
       if (argindex[i] == 0) {
 	if (!(compute->invoked_flag & INVOKED_SCALAR)) {
 	  compute->compute_scalar();
 	  compute->invoked_flag |= INVOKED_SCALAR;
 	}
 	scalar = compute->scalar;
       } else {
 	if (!(compute->invoked_flag & INVOKED_VECTOR)) {
 	  compute->compute_vector();
 	  compute->invoked_flag |= INVOKED_VECTOR;
 	}
 	scalar = compute->vector[argindex[i]-1];
       }
       
     // access fix fields, guaranteed to be ready
       
     } else if (which[i] == FIX) {
       if (argindex[i] == 0) 
 	scalar = modify->fix[m]->compute_scalar();
       else
 	scalar = modify->fix[m]->compute_vector(argindex[i]-1);
       
     // evaluate equal-style variable
       
     } else if (which[i] == VARIABLE)
       scalar = input->variable->compute_equal(m);
     
     // add value to vector or just set directly if offcol is set
     
     if (offcol[i]) vector[i] = scalar;
     else vector[i] += scalar;
   }
 
   // done if irepeat < nrepeat
   // else reset irepeat and nvalid
 
   irepeat++;
   if (irepeat < nrepeat) {
     nvalid += nevery;
     modify->addstep_compute(nvalid);
     return;
   }
 
   irepeat = 0;
   nvalid = ntimestep + nfreq - (nrepeat-1)*nevery;
   modify->addstep_compute(nvalid);
 
   // average the final result for the Nfreq timestep
 
   double repeat = nrepeat;
   for (i = 0; i < nvalues; i++)
     if (offcol[i] == 0) vector[i] /= repeat;
 
   // if ave = ONE, only single Nfreq timestep value is needed
   // if ave = RUNNING, combine with all previous Nfreq timestep values
   // if ave = WINDOW, combine with nwindow most recent Nfreq timestep values
 
   if (ntimestep >= startstep) {
     if (ave == ONE) {
       for (i = 0; i < nvalues; i++) vector_total[i] = vector[i];
       norm = 1;
 
     } else if (ave == RUNNING) {
       for (i = 0; i < nvalues; i++) vector_total[i] += vector[i];
       norm++;
       
     } else if (ave == WINDOW) {
       for (i = 0; i < nvalues; i++) {
 	vector_total[i] += vector[i];
 	if (window_limit) vector_total[i] -= vector_list[iwindow][i];
 	vector_list[iwindow][i] = vector[i];
       }
       
       iwindow++;
       if (iwindow == nwindow) {
 	iwindow = 0;
 	window_limit = 1;
       }
       if (window_limit) norm = nwindow;
       else norm = iwindow;
     }
   }
 
   // insure any columns with offcol set are effectively set to last value
 
   for (i = 0; i < nvalues; i++)
     if (offcol[i]) vector_total[i] = norm*vector[i];
 
   // output result to file
 
   if (fp && me == 0) {
-    fprintf(fp,"%d",ntimestep);
+    fprintf(fp,BIGINT_FORMAT,ntimestep);
     for (i = 0; i < nvalues; i++) fprintf(fp," %g",vector_total[i]/norm);
     fprintf(fp,"\n");
     fflush(fp);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
-void FixAveTime::invoke_vector(int ntimestep)
+void FixAveTime::invoke_vector(bigint ntimestep)
 {
   int i,j,m;
   
   // zero if first step
 
   if (irepeat == 0)
     for (i = 0; i < nrows; i++)
       for (j = 0; j < nvalues; j++) array[i][j] = 0.0;
   
   // accumulate results of computes,fixes,variables to local copy
   // compute/fix/variable may invoke computes so wrap with clear/add
   
   modify->clearstep_compute();
   
   for (j = 0; j < nvalues; j++) {
     m = value2index[j];
     
     // invoke compute if not previously invoked
     
     if (which[j] == COMPUTE) {
       Compute *compute = modify->compute[m];
       
       if (argindex[j] == 0) {
 	if (!(compute->invoked_flag & INVOKED_VECTOR)) {
 	  compute->compute_vector();
 	  compute->invoked_flag |= INVOKED_VECTOR;
 	}
 	double *cvector = compute->vector;
 	for (i = 0; i < nrows; i++)
 	  column[i] = cvector[i];
 	
       } else {
 	if (!(compute->invoked_flag & INVOKED_ARRAY)) {
 	  compute->compute_array();
 	  compute->invoked_flag |= INVOKED_ARRAY;
 	}
 	double **carray = compute->array;
 	int icol = argindex[j]-1;
 	for (i = 0; i < nrows; i++)
 	  column[i] = carray[i][icol];
       }
       
     // access fix fields, guaranteed to be ready
       
     } else if (which[j] == FIX) {
       Fix *fix = modify->fix[m];
       if (argindex[j] == 0)
 	for (i = 0; i < nrows; i++)
 	  column[i] = fix->compute_vector(i);
       else {
 	int icol = argindex[j]-1;
 	for (i = 0; i < nrows; i++)
 	  column[i] = fix->compute_array(i,icol);
       }
     }
     
     // add columns of values to array or just set directly if offcol is set
     
     if (offcol[j]) {
       for (i = 0; i < nrows; i++)
 	array[i][j] = column[i];
     } else {
       for (i = 0; i < nrows; i++)
 	array[i][j] += column[i];
     }
   }
   
   // done if irepeat < nrepeat
   // else reset irepeat and nvalid
   
   irepeat++;
   if (irepeat < nrepeat) {
     nvalid += nevery;
     modify->addstep_compute(nvalid);
     return;
   }
   
   irepeat = 0;
   nvalid = ntimestep+nfreq - (nrepeat-1)*nevery;
   modify->addstep_compute(nvalid);
   
   // average the final result for the Nfreq timestep
   
   double repeat = nrepeat;
   for (i = 0; i < nrows; i++)
     for (j = 0; j < nvalues; j++)
       if (offcol[j] == 0) array[i][j] /= repeat;
   
   // if ave = ONE, only single Nfreq timestep value is needed
   // if ave = RUNNING, combine with all previous Nfreq timestep values
   // if ave = WINDOW, combine with nwindow most recent Nfreq timestep values
   
   if (ntimestep >= startstep) {
     if (ave == ONE) {
       for (i = 0; i < nrows; i++)
 	for (j = 0; j < nvalues; j++) array_total[i][j] = array[i][j];
       norm = 1;
       
     } else if (ave == RUNNING) {
       for (i = 0; i < nrows; i++)
 	for (j = 0; j < nvalues; j++) array_total[i][j] += array[i][j];
       norm++;
       
     } else if (ave == WINDOW) {
       for (i = 0; i < nrows; i++)
 	for (j = 0; j < nvalues; j++) {
 	  array_total[i][j] += array[i][j];
 	  if (window_limit) array_total[i][j] -= array_list[iwindow][i][j];
 	  array_list[iwindow][i][j] = array[i][j];
 	}
       
       iwindow++;
       if (iwindow == nwindow) {
 	iwindow = 0;
 	window_limit = 1;
       }
       if (window_limit) norm = nwindow;
       else norm = iwindow;
     }
   }
   
   // insure any columns with offcol set are effectively set to last value
   
   for (i = 0; i < nrows; i++)
     for (j = 0; j < nvalues; j++)
       if (offcol[j]) array_total[i][j] = norm*array[i][j];
   
   // output result to file
       
   if (fp && me == 0) {
-    fprintf(fp,"%d %d\n",ntimestep,nrows);
+    char fstr[16];
+    sprintf(fstr,"%s %%d\n",BIGINT_FORMAT);
+    fprintf(fp,fstr,ntimestep,nrows);
     for (i = 0; i < nrows; i++) {
       fprintf(fp,"%d",i+1);
       for (j = 0; j < nvalues; j++) fprintf(fp," %g",array_total[i][j]/norm);
       fprintf(fp,"\n");
     }
     fflush(fp);
   }
 }
 
 /* ----------------------------------------------------------------------
    return scalar value
 ------------------------------------------------------------------------- */
 
 double FixAveTime::compute_scalar()
 {
   if (norm) return vector_total[0]/norm;
   return 0.0;
 }
 
 /* ----------------------------------------------------------------------
    return Ith vector value
 ------------------------------------------------------------------------- */
 
 double FixAveTime::compute_vector(int i)
 {
   if (norm) {
     if (mode == SCALAR) return vector_total[i]/norm;
     if (mode == VECTOR) return array_total[i][0];
   }
   return 0.0;
 }
 
 /* ----------------------------------------------------------------------
    return I,J array value
 ------------------------------------------------------------------------- */
 
 double FixAveTime::compute_array(int i, int j)
 {
   if (norm) return array_total[i][j]/norm;
   return 0.0;
 }
 
 /* ----------------------------------------------------------------------
    parse optional args
 ------------------------------------------------------------------------- */
 
 void FixAveTime::options(int narg, char **arg)
 {
   // option defaults
 
   fp = NULL;
   ave = ONE;
   startstep = 0;
   mode = SCALAR;
   noff = 0;
   offlist = NULL;
   title1 = NULL;
   title2 = NULL;
   title3 = NULL;
 
   // optional args
 
   int iarg = 6 + nvalues;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"file") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/time command");
       if (me == 0) {
 	fp = fopen(arg[iarg+1],"w");
 	if (fp == NULL) {
 	  char str[128];
 	  sprintf(str,"Cannot open fix ave/time file %s",arg[iarg+1]);
 	  error->one(str);
 	}
       }
       iarg += 2;
     } else if (strcmp(arg[iarg],"ave") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/time command");
       if (strcmp(arg[iarg+1],"one") == 0) ave = ONE;
       else if (strcmp(arg[iarg+1],"running") == 0) ave = RUNNING;
       else if (strcmp(arg[iarg+1],"window") == 0) ave = WINDOW;
       else error->all("Illegal fix ave/time command");
       if (ave == WINDOW) {
 	if (iarg+3 > narg) error->all("Illegal fix ave/time command");
 	nwindow = atoi(arg[iarg+2]);
 	if (nwindow <= 0) error->all("Illegal fix ave/time command");
       }
       iarg += 2;
       if (ave == WINDOW) iarg++;
     } else if (strcmp(arg[iarg],"start") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/time command");
       startstep = atoi(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"mode") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/time command");
       if (strcmp(arg[iarg+1],"scalar") == 0) mode = SCALAR;
       else if (strcmp(arg[iarg+1],"vector") == 0) mode = VECTOR;
       else error->all("Illegal fix ave/time command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"off") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/time command");
       offlist = (int *) 
 	memory->srealloc(offlist,(noff+1)*sizeof(int),"ave/time:offlist");
       offlist[noff++] = atoi(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"title1") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       delete [] title1;
       int n = strlen(arg[iarg+1]) + 1;
       title1 = new char[n];
       strcpy(title1,arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"title2") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       delete [] title2;
       int n = strlen(arg[iarg+1]) + 1;
       title2 = new char[n];
       strcpy(title2,arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"title3") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix ave/spatial command");
       delete [] title3;
       int n = strlen(arg[iarg+1]) + 1;
       title3 = new char[n];
       strcpy(title3,arg[iarg+1]);
       iarg += 2;
     } else error->all("Illegal fix ave/time command");
   }
 }
 
 /* ----------------------------------------------------------------------
    reallocate vectors for each input value, of length N
 ------------------------------------------------------------------------- */
 
 void FixAveTime::allocate_values(int n)
 {
   which = (int *) memory->srealloc(which,n*sizeof(int),"ave/time:which");
   argindex = (int *) memory->srealloc(argindex,n*sizeof(int),
 				      "ave/time:argindex");
   value2index = (int *) memory->srealloc(value2index,n*sizeof(int),
 					 "ave/time:value2index");
   offcol = (int *) memory->srealloc(offcol,n*sizeof(int),"ave/time:offcol");
   ids = (char **) memory->srealloc(ids,n*sizeof(char *),"ave/time:ids");
 }
 
 /* ----------------------------------------------------------------------
    calculate nvalid = next step on which end_of_step does something
    can be this timestep if multiple of nfreq and nrepeat = 1
    else backup from next multiple of nfreq
 ------------------------------------------------------------------------- */
 
-int FixAveTime::nextvalid()
+bigint FixAveTime::nextvalid()
 {
-  int nvalid = (update->ntimestep/nfreq)*nfreq + nfreq;
+  bigint nvalid = (update->ntimestep/nfreq)*nfreq + nfreq;
   if (nvalid-nfreq == update->ntimestep && nrepeat == 1)
     nvalid = update->ntimestep;
   else
     nvalid -= (nrepeat-1)*nevery;
   if (nvalid < update->ntimestep) nvalid += nfreq;
   return nvalid;
 }
diff --git a/src/fix_ave_time.h b/src/fix_ave_time.h
index 286511ea2..a8c118d39 100644
--- a/src/fix_ave_time.h
+++ b/src/fix_ave_time.h
@@ -1,72 +1,74 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef FIX_CLASS
 
 FixStyle(ave/time,FixAveTime)
 
 #else
 
 #ifndef LMP_FIX_AVE_TIME_H
 #define LMP_FIX_AVE_TIME_H
 
 #include "stdio.h"
 #include "fix.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class FixAveTime : public Fix {
  public:
   FixAveTime(class LAMMPS *, int, char **);
   ~FixAveTime();
   int setmask();
   void init();
   void setup(int);
   void end_of_step();
   double compute_scalar();
   double compute_vector(int);
   double compute_array(int,int);
 
  private:
   int me,nvalues;
-  int nrepeat,nfreq,nvalid,irepeat;
+  int nrepeat,nfreq,irepeat;
+  bigint nvalid;
   int *which,*argindex,*value2index,*offcol;
   char **ids;
   FILE *fp;
   int nrows;
 
   int ave,nwindow,nsum,startstep,mode;
   int noff;
   int *offlist;
   char *title1,*title2,*title3;
 
   int norm,iwindow,window_limit;
   double *vector;
   double *vector_total;
   double **vector_list;
   double *column;
   double **array;
   double **array_total;
   double ***array_list;
 
-  void invoke_scalar(int);
-  void invoke_vector(int);
+  void invoke_scalar(bigint);
+  void invoke_vector(bigint);
   void options(int, char **);
   void allocate_values(int);
-  int nextvalid();
+  bigint nextvalid();
 };
 
 }
 
 #endif
 #endif
diff --git a/src/fix_deposit.cpp b/src/fix_deposit.cpp
index 60fc34ed6..357a32594 100644
--- a/src/fix_deposit.cpp
+++ b/src/fix_deposit.cpp
@@ -1,459 +1,460 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "fix_deposit.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "force.h"
 #include "update.h"
 #include "modify.h"
 #include "fix.h"
 #include "comm.h"
 #include "domain.h"
 #include "lattice.h"
 #include "region.h"
 #include "random_park.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 FixDeposit::FixDeposit(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 7) error->all("Illegal fix deposit command");
 
   restart_global = 1;
   time_depend = 1;
 
   // required args
 
   ninsert = atoi(arg[3]);
   ntype = atoi(arg[4]);
   nfreq = atoi(arg[5]);
   seed = atoi(arg[6]);
 
   if (seed <= 0) error->all("Illegal fix deposit command");
 
   // set defaults
 
   iregion = -1;
   idregion = NULL;
   globalflag = localflag = 0;
   lo = hi = deltasq = 0.0;
   nearsq = 0.0;
   maxattempt = 10;
   rateflag = 0;
   vxlo = vxhi = vylo = vyhi = vzlo = vzhi = 0.0;
   scaleflag = 1;
 
   // read options from end of input line
 
   options(narg-7,&arg[7]);
 
   // error checks on region and its extent being inside simulation box
 
   if (iregion == -1) error->all("Must specify a region in fix deposit");
   if (domain->regions[iregion]->bboxflag == 0)
     error->all("Fix deposit region does not support a bounding box");
   if (domain->regions[iregion]->dynamic_check())
     error->all("Fix deposit region cannot be dynamic");
 
   xlo = domain->regions[iregion]->extent_xlo;
   xhi = domain->regions[iregion]->extent_xhi;
   ylo = domain->regions[iregion]->extent_ylo;
   yhi = domain->regions[iregion]->extent_yhi;
   zlo = domain->regions[iregion]->extent_zlo;
   zhi = domain->regions[iregion]->extent_zhi;
 
   if (domain->triclinic == 0) {
     if (xlo < domain->boxlo[0] || xhi > domain->boxhi[0] || 
 	ylo < domain->boxlo[1] || yhi > domain->boxhi[1] || 
 	zlo < domain->boxlo[2] || zhi > domain->boxhi[2])
       error->all("Deposition region extends outside simulation box");
   } else {
     if (xlo < domain->boxlo_bound[0] || xhi > domain->boxhi_bound[0] || 
 	ylo < domain->boxlo_bound[1] || yhi > domain->boxhi_bound[1] || 
 	zlo < domain->boxlo_bound[2] || zhi > domain->boxhi_bound[2])
       error->all("Deposition region extends outside simulation box");
   }
 
   // setup scaling
 
   if (scaleflag && domain->lattice == NULL)
     error->all("Use of fix deposit with undefined lattice");
 
   double xscale,yscale,zscale;
   if (scaleflag) {
     xscale = domain->lattice->xlattice;
     yscale = domain->lattice->ylattice;
     zscale = domain->lattice->zlattice;
   }
   else xscale = yscale = zscale = 1.0;
 
   // apply scaling to all input parameters with dist/vel units
 
   if (domain->dimension == 2) {
     lo *= yscale;
     hi *= yscale;
     rate *= yscale;
   } else {
     lo *= zscale;
     hi *= zscale;
     rate *= zscale;
   }
   deltasq *= xscale*xscale;
   nearsq *= xscale*xscale;
   vxlo *= xscale;
   vxhi *= xscale;
   vylo *= yscale;
   vyhi *= yscale;
   vzlo *= zscale;
   vzhi *= zscale;
 
   // random number generator, same for all procs
 
   random = new RanPark(lmp,seed);
 
   // set up reneighboring
 
   force_reneighbor = 1;
   next_reneighbor = update->ntimestep + 1;
   nfirst = next_reneighbor;
   ninserted = 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixDeposit::~FixDeposit()
 {
   delete random;
   delete [] idregion;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixDeposit::setmask()
 {
   int mask = 0;
   mask |= PRE_EXCHANGE;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixDeposit::init()
 {
   // set index and check validity of region
 
   iregion = domain->find_region(idregion);
   if (iregion == -1) error->all("Region ID for fix deposit does not exist");
 }
 
 /* ----------------------------------------------------------------------
    perform particle insertion
 ------------------------------------------------------------------------- */
 
 void FixDeposit::pre_exchange()
 {
   int i,j;
   int flag,flagall;
   double coord[3],lamda[3],delx,dely,delz,rsq;
   double *newcoord;
 
   // just return if should not be called on this timestep
 
   if (next_reneighbor != update->ntimestep) return;
 
   // compute current offset = bottom of insertion volume
 
   double offset = 0.0;
   if (rateflag) offset = (update->ntimestep - nfirst) * update->dt * rate;
 
   double *sublo,*subhi;
   if (domain->triclinic == 0) {
     sublo = domain->sublo;
     subhi = domain->subhi;
   } else {
     sublo = domain->sublo_lamda;
     subhi = domain->subhi_lamda;
   }
 
   // attempt an insertion until successful
 
   int nfix = modify->nfix;
   Fix **fix = modify->fix;
 
   int success = 0;
   int attempt = 0;
   while (attempt < maxattempt) {
     attempt++;
 
     // choose random position for new atom within region
 
     coord[0] = xlo + random->uniform() * (xhi-xlo);
     coord[1] = ylo + random->uniform() * (yhi-ylo);
     coord[2] = zlo + random->uniform() * (zhi-zlo);
     while (domain->regions[iregion]->match(coord[0],coord[1],coord[2]) == 0) {
       coord[0] = xlo + random->uniform() * (xhi-xlo);
       coord[1] = ylo + random->uniform() * (yhi-ylo);
       coord[2] = zlo + random->uniform() * (zhi-zlo);
     }
 
     // adjust vertical coord by offset
 
     if (domain->dimension == 2) coord[1] += offset;
     else coord[2] += offset;
 
     // if global, reset vertical coord to be lo-hi above highest atom
     // if local, reset vertical coord to be lo-hi above highest "nearby" atom
     // local computation computes lateral distance between 2 particles w/ PBC
 
     if (globalflag || localflag) {
       int dim;
       double max,maxall,delx,dely,delz,rsq;
 
       if (domain->dimension == 2) {
 	dim = 1;
 	max = domain->boxlo[1];
       } else {
 	dim = 2;
 	max = domain->boxlo[2];
       }
 
       double **x = atom->x;
       int nlocal = atom->nlocal;
       for (i = 0; i < nlocal; i++) {
 	if (localflag) {
 	  delx = coord[0] - x[i][0];
 	  dely = coord[1] - x[i][1];
 	  delz = 0.0;
 	  domain->minimum_image(delx,dely,delz);
 	  if (domain->dimension == 2) rsq = delx*delx;
 	  else rsq = delx*delx + dely*dely;
 	  if (rsq > deltasq) continue;
 	}
 	if (x[i][dim] > max) max = x[i][dim];
       }
 
       MPI_Allreduce(&max,&maxall,1,MPI_DOUBLE,MPI_MAX,world);
       if (domain->dimension == 2)
 	coord[1] = maxall + lo + random->uniform()*(hi-lo);
       else
 	coord[2] = maxall + lo + random->uniform()*(hi-lo);
     }      
 
     // now have final coord
     // if distance to any atom is less than near, try again
 
     double **x = atom->x;
     int nlocal = atom->nlocal;
 
     flag = 0;
     for (i = 0; i < nlocal; i++) {
       delx = coord[0] - x[i][0];
       dely = coord[1] - x[i][1];
       delz = coord[2] - x[i][2];
       domain->minimum_image(delx,dely,delz);
       rsq = delx*delx + dely*dely + delz*delz;
       if (rsq < nearsq) flag = 1;
     }
     MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_MAX,world);
     if (flagall) continue;
 
     // insertion will proceed
     // choose random velocity for new atom
 
     double vxtmp = vxlo + random->uniform() * (vxhi-vxlo);
     double vytmp = vylo + random->uniform() * (vyhi-vylo);
     double vztmp = vzlo + random->uniform() * (vzhi-vzlo);
 
     // check if new atom is in my sub-box or above it if I'm highest proc
     // if so, add to my list via create_atom()
     // initialize info about the atoms
     // set group mask to "all" plus fix group
     
     if (domain->triclinic) {
       domain->x2lamda(coord,lamda);
       newcoord = lamda;
     } else newcoord = coord;
 
     flag = 0;
     if (newcoord[0] >= sublo[0] && newcoord[0] < subhi[0] &&
 	newcoord[1] >= sublo[1] && newcoord[1] < subhi[1] &&
 	newcoord[2] >= sublo[2] && newcoord[2] < subhi[2]) flag = 1;
     else if (domain->dimension == 3 && newcoord[2] >= domain->boxhi[2] &&
 	     comm->myloc[2] == comm->procgrid[2]-1 &&
 	     newcoord[0] >= sublo[0] && newcoord[0] < subhi[0] &&
 	     newcoord[1] >= sublo[1] && newcoord[1] < subhi[1]) flag = 1;
     else if (domain->dimension == 2 && newcoord[1] >= domain->boxhi[1] &&
 	     comm->myloc[1] == comm->procgrid[1]-1 &&
 	     newcoord[0] >= sublo[0] && newcoord[0] < subhi[0]) flag = 1;
 
     if (flag) {
       atom->avec->create_atom(ntype,coord);
       int m = atom->nlocal - 1;
       atom->type[m] = ntype;
       atom->mask[m] = 1 | groupbit;
       atom->v[m][0] = vxtmp;
       atom->v[m][1] = vytmp;
       atom->v[m][2] = vztmp;
       for (j = 0; j < nfix; j++)
 	if (fix[j]->create_attribute) fix[j]->set_arrays(m);
     }
     MPI_Allreduce(&flag,&success,1,MPI_INT,MPI_MAX,world);
     break;
   }
 
   // warn if not successful b/c too many attempts or no proc owned particle
 
-  if (comm->me == 0)
-    if (success == 0)
-      error->warning("Particle deposition was unsuccessful",0);
+  if (!success && comm->me == 0)
+    error->warning("Particle deposition was unsuccessful",0);
 
-  // set tag # of new particle beyond all previous atoms
   // reset global natoms
+  // set tag # of new particle beyond all previous atoms
   // if global map exists, reset it now instead of waiting for comm
   // since deleting atoms messes up ghosts
 
-  if (success && atom->tag_enable) {
-    atom->tag_extend();
+  if (success) {
     atom->natoms += 1;
-    if (atom->map_style) {
-      atom->nghost = 0;
-      atom->map_init();
-      atom->map_set();
+    if (atom->tag_enable) {
+      atom->tag_extend();
+      if (atom->map_style) {
+	atom->nghost = 0;
+	atom->map_init();
+	atom->map_set();
+      }
     }
   }
 
   // next timestep to insert
   // next_reneighbor = 0 if done
 
   if (success) ninserted++;
   if (ninserted < ninsert) next_reneighbor += nfreq;
   else next_reneighbor = 0;
 }
 
 /* ----------------------------------------------------------------------
    parse optional parameters at end of input line 
 ------------------------------------------------------------------------- */
 
 void FixDeposit::options(int narg, char **arg)
 {
   if (narg < 0) error->all("Illegal fix indent command");
 
   int iarg = 0;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"region") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix deposit command");
       iregion = domain->find_region(arg[iarg+1]);
       if (iregion == -1)
 	error->all("Region ID for fix deposit does not exist");
       int n = strlen(arg[iarg+1]) + 1;
       idregion = new char[n];
       strcpy(idregion,arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"global") == 0) {
       if (iarg+3 > narg) error->all("Illegal fix deposit command");
       globalflag = 1;
       localflag = 0;
       lo = atof(arg[iarg+1]);
       hi = atof(arg[iarg+2]);
       iarg += 3;
     } else if (strcmp(arg[iarg],"local") == 0) {
       if (iarg+4 > narg) error->all("Illegal fix deposit command");
       localflag = 1;
       globalflag = 0;
       lo = atof(arg[iarg+1]);
       hi = atof(arg[iarg+2]);
       deltasq = atof(arg[iarg+3])*atof(arg[iarg+3]);
       iarg += 4;
     } else if (strcmp(arg[iarg],"near") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix deposit command");
       nearsq = atof(arg[iarg+1])*atof(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"attempt") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix deposit command");
       maxattempt = atoi(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"rate") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix deposit command");
       rateflag = 1;
       rate = atof(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"vx") == 0) {
       if (iarg+3 > narg) error->all("Illegal fix deposit command");
       vxlo = atof(arg[iarg+1]);
       vxhi = atof(arg[iarg+2]);
       iarg += 3;
     } else if (strcmp(arg[iarg],"vy") == 0) {
       if (iarg+3 > narg) error->all("Illegal fix deposit command");
       vylo = atof(arg[iarg+1]);
       vyhi = atof(arg[iarg+2]);
       iarg += 3;
     } else if (strcmp(arg[iarg],"vz") == 0) {
       if (iarg+3 > narg) error->all("Illegal fix deposit command");
       vzlo = atof(arg[iarg+1]);
       vzhi = atof(arg[iarg+2]);
       iarg += 3;
     } else if (strcmp(arg[iarg],"units") == 0) {
       if (iarg+2 > narg) error->all("Illegal fix deposit command");
       if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
       else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
       else error->all("Illegal fix deposit command");
       iarg += 2;
     } else error->all("Illegal fix deposit command");
   }
 }
 
 /* ----------------------------------------------------------------------
    pack entire state of Fix into one write 
 ------------------------------------------------------------------------- */
 
 void FixDeposit::write_restart(FILE *fp)
 {
   int n = 0;
   double list[4];
   list[n++] = random->state();
   list[n++] = ninserted;
   list[n++] = nfirst;
   list[n++] = next_reneighbor;
 
   if (comm->me == 0) {
     int size = n * sizeof(double);
     fwrite(&size,sizeof(int),1,fp);
     fwrite(list,sizeof(double),n,fp);
   }
 }
 
 /* ----------------------------------------------------------------------
    use state info from restart file to restart the Fix 
 ------------------------------------------------------------------------- */
 
 void FixDeposit::restart(char *buf)
 {
   int n = 0;
   double *list = (double *) buf;
 
   seed = static_cast<int> (list[n++]);
   ninserted = static_cast<int> (list[n++]);
   nfirst = static_cast<int> (list[n++]);
   next_reneighbor = static_cast<int> (list[n++]);
 
   random->reset(seed);
 }
diff --git a/src/fix_orient_fcc.cpp b/src/fix_orient_fcc.cpp
index 5a7ea4470..5f7fdc068 100644
--- a/src/fix_orient_fcc.cpp
+++ b/src/fix_orient_fcc.cpp
@@ -1,565 +1,564 @@
 /* ----------------------------------------------------------------------
    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: Koenraad Janssens and David Olmsted (SNL)
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "string.h"
 #include "stdlib.h"
 #include "mpi.h"
 #include "fix_orient_fcc.h"
 #include "atom.h"
 #include "update.h"
 #include "respa.h"
 #include "neighbor.h"
 #include "neigh_list.h"
 #include "neigh_request.h"
 #include "comm.h"
 #include "output.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define BIG 1000000000
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 /* ---------------------------------------------------------------------- */
 
 FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   MPI_Comm_rank(world,&me);
 
   if (narg != 11) error->all("Illegal fix orient/fcc command");
 
   scalar_flag = 1;
   global_freq = 1;
   extscalar = 1;
 
   nstats = atoi(arg[3]);
   direction_of_motion = atoi(arg[4]);
   a = atof(arg[5]);
   Vxi = atof(arg[6]);
   uxif_low = atof(arg[7]);
   uxif_high = atof(arg[8]);
 
   if (direction_of_motion == 0) {
     int n = strlen(arg[9]) + 1;
     chifilename = new char[n];
     strcpy(chifilename,arg[9]);
     n = strlen(arg[10]) + 1;
     xifilename = new char[n];
     strcpy(xifilename,arg[10]);
   } else if (direction_of_motion == 1) {
     int n = strlen(arg[9]) + 1;
     xifilename = new char[n];
     strcpy(xifilename,arg[9]);
     n = strlen(arg[10]) + 1;
     chifilename = new char[n];
     strcpy(chifilename,arg[10]);
   } else error->all("Illegal fix orient/fcc command");
 
   // initializations
 
   PI = 4.0*atan(1.0);
   half_fcc_nn = 6;
   use_xismooth = false;
   double xicutoff = 1.57;
   xicutoffsq = xicutoff * xicutoff;
   cutsq = 0.5 * a*a*xicutoffsq;
   nmax = 0;
 
   // read xi and chi reference orientations from files
 
   if (me == 0) {
     char line[512];
     char *result;
     int count;
 
     FILE *infile = fopen(xifilename,"r");
     if (infile == NULL) error->one("Fix orient/fcc file open failed");
     for (int i = 0; i < 6; i++) {
       result = fgets(line,512,infile);
       if (!result) error->one("Fix orient/fcc file read failed");
       count = sscanf(line,"%lg %lg %lg",&Rxi[i][0],&Rxi[i][1],&Rxi[i][2]);
       if (count != 3) error->one("Fix orient/fcc file read failed");
     }
     fclose(infile);
 
     infile = fopen(chifilename,"r");
     if (infile == NULL) error->one("Fix orient/fcc file open failed");
     for (int i = 0; i < 6; i++) {
       result = fgets(line,512,infile);
       if (!result) error->one("Fix orient/fcc file read failed");
       count = sscanf(line,"%lg %lg %lg",&Rchi[i][0],&Rchi[i][1],&Rchi[i][2]);
       if (count != 3) error->one("Fix orient/fcc file read failed");
     }
     fclose(infile);
   }
 
   MPI_Bcast(&Rxi[0][0],18,MPI_DOUBLE,0,world);
   MPI_Bcast(&Rchi[0][0],18,MPI_DOUBLE,0,world);
 
   // make copy of the reference vectors
 
   for (int i = 0; i < 6; i++)
     for (int j = 0; j < 3; j++) {
       half_xi_chi_vec[0][i][j] = Rxi[i][j];
       half_xi_chi_vec[1][i][j] = Rchi[i][j];
     }
 
   // compute xiid,xi0,xi1 for all 12 neighbors
   // xi is the favored crystal
   // want order parameter when actual is Rchi
 
   double xi_sq,dxi[3],rchi[3];
 
   xiid = 0.0;
   for (int i = 0; i < 6; i++) {
     rchi[0] = Rchi[i][0];
     rchi[1] = Rchi[i][1];
     rchi[2] = Rchi[i][2];
     find_best_ref(rchi,0,xi_sq,dxi);
     xiid += sqrt(xi_sq);
     for (int j = 0; j < 3; j++) rchi[j] = -rchi[j];
     find_best_ref(rchi,0,xi_sq,dxi);
     xiid += sqrt(xi_sq);
   }
 
   xiid /= 12.0;
   xi0 = uxif_low * xiid;
   xi1 = uxif_high * xiid;
 
   // set comm size needed by this Fix
   // NOTE: doesn't seem that use_xismooth is ever true
 
   if (use_xismooth) comm_forward = 62;
   else comm_forward = 50;
 
   added_energy = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixOrientFCC::~FixOrientFCC()
 {
   delete [] xifilename;
   delete [] chifilename;
   if (nmax) delete [] nbr;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixOrientFCC::setmask()
 {
   int mask = 0;
   mask |= POST_FORCE;
   mask |= THERMO_ENERGY;
   mask |= POST_FORCE_RESPA;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixOrientFCC::init()
 {
   if (strcmp(update->integrate_style,"respa") == 0)
     nlevels_respa = ((Respa *) update->integrate)->nlevels;
 
   // need a full neighbor list, built whenever re-neighboring occurs
 
   int irequest = neighbor->request((void *) this);
   neighbor->requests[irequest]->pair = 0;
   neighbor->requests[irequest]->fix = 1;
   neighbor->requests[irequest]->half = 0;
   neighbor->requests[irequest]->full = 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixOrientFCC::init_list(int id, NeighList *ptr)
 {
   list = ptr;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixOrientFCC::setup(int vflag)
 {
   if (strcmp(update->integrate_style,"verlet") == 0)
     post_force(vflag);
   else {
     ((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1);
     post_force_respa(vflag,nlevels_respa-1,0);
     ((Respa *) update->integrate)->copy_f_flevel(nlevels_respa-1);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixOrientFCC::post_force(int vflag)
 {
   int i,j,k,ii,jj,inum,jnum,m,n,nn,nsort,id_self;
   int *ilist,*jlist,*numneigh,**firstneigh;
   double edelta,omega;
   double dx,dy,dz,rsq,xismooth,xi_sq,duxi,duxi_other;
   double dxi[3];
   double *dxiptr;
   bool found_myself;
 
   // set local ptrs
 
   double **x = atom->x;
   double **f = atom->f;
   int *mask = atom->mask;
   int *tag = atom->tag;
   int nlocal = atom->nlocal;
   int nall = atom->nlocal + atom->nghost;
 
   inum = list->inum;
   ilist = list->ilist;
   numneigh = list->numneigh;
   firstneigh = list->firstneigh;
 
   // insure nbr data structure is adequate size
 
   if (nall > nmax) {
     if (nmax) delete [] nbr;
     nbr = new Nbr[nall];
     nmax = nall;
   }
 
   // loop over owned atoms and build Nbr data structure of neighbors
   // use full neighbor list
 
   added_energy = 0.0;
   int count = 0;
   int mincount = BIG;
   int maxcount = 0;
 
   for (ii = 0; ii < inum; ii++) {
     i = ilist[ii];
     jlist = firstneigh[i];
     jnum = numneigh[i];
 
     if (jnum < mincount) mincount = jnum;
     if (jnum > maxcount) {
       if (maxcount) delete [] sort;
       sort = new Sort[jnum];
       maxcount = jnum;
     }
 
     // loop over all neighbors of atom i
     // for those within cutsq, build sort data structure
     // store local id, rsq, delta vector, xismooth (if included)
 
     nsort = 0;
     for (jj = 0; jj < jnum; jj++) {
       j = jlist[jj];
       count++;
 
       dx = x[i][0] - x[j][0];
       dy = x[i][1] - x[j][1];
       dz = x[i][2] - x[j][2];
       rsq = dx*dx + dy*dy + dz*dz;
 
       if (rsq < cutsq) {
 	sort[nsort].id = j;
 	sort[nsort].rsq = rsq;
 	sort[nsort].delta[0] = dx;
 	sort[nsort].delta[1] = dy;
 	sort[nsort].delta[2] = dz;
 	if (use_xismooth) {
 	  xismooth = (xicutoffsq - 2.0*rsq/(a*a)) / (xicutoffsq - 1.0);
 	  sort[nsort].xismooth = 1.0 - fabs(1.0-xismooth);
 	}
 	nsort++;
       }
     }
 
     // sort neighbors by rsq distance
     // no need to sort if nsort <= 12
     
     if (nsort > 12) qsort(sort,nsort,sizeof(Sort),compare);
 
     // copy up to 12 nearest neighbors into nbr data structure
     // operate on delta vector via find_best_ref() to compute dxi
     
     n = MIN(12,nsort);
     nbr[i].n = n;
     if (n == 0) continue;
 
     double xi_total = 0.0;
     for (j = 0; j < n; j++) {
       find_best_ref(sort[j].delta,0,xi_sq,dxi);
       xi_total += sqrt(xi_sq);
       nbr[i].id[j] = sort[j].id;
       nbr[i].dxi[j][0] = dxi[0]/n;
       nbr[i].dxi[j][1] = dxi[1]/n;
       nbr[i].dxi[j][2] = dxi[2]/n;
       if (use_xismooth) nbr[i].xismooth[j] = sort[j].xismooth;
     }
     xi_total /= n;
 
     // compute potential derivative to xi
 
     if (xi_total < xi0) {
       nbr[i].duxi = 0.0;
       edelta = 0.0;
     } else if (xi_total > xi1) {
       nbr[i].duxi = 0.0;
       edelta = Vxi;
     } else {
       omega = (0.5*PI)*(xi_total-xi0) / (xi1-xi0);
       nbr[i].duxi = PI*Vxi*sin(2.0*omega) / (2.0*(xi1-xi0));
       edelta = Vxi*(1 - cos(2.0*omega)) / 2.0;
     }
     added_energy += edelta;
   }
   
   if (maxcount) delete [] sort;
   
   // communicate to acquire nbr data for ghost atoms
 
   comm->forward_comm_fix(this);
 
   // compute grain boundary force on each owned atom
   // skip atoms not in group
 
   for (ii = 0; ii < inum; ii++) {
     i = ilist[ii];
     if (!(mask[i] & groupbit)) continue;
     n = nbr[i].n;
     duxi = nbr[i].duxi;
 
     for (j = 0; j < n; j++) {
       dxiptr = &nbr[i].dxi[j][0];
       if (use_xismooth) {
 	xismooth = nbr[i].xismooth[j];
         f[i][0] += duxi * dxiptr[0] * xismooth;
         f[i][1] += duxi * dxiptr[1] * xismooth;
         f[i][2] += duxi * dxiptr[2] * xismooth;
       } else {
 	f[i][0] += duxi * dxiptr[0];
         f[i][1] += duxi * dxiptr[1];
         f[i][2] += duxi * dxiptr[2];
       }
 
       // m = local index of neighbor
       // id_self = ID for atom I in atom M's neighbor list
       // if M is local atom, id_self will be local ID of atom I
       // if M is ghost atom, id_self will be global ID of atom I
 
       m = nbr[i].id[j]; 
       if (m < nlocal) id_self = i;
       else id_self = tag[i];
       found_myself = false;
       nn = nbr[m].n;
 
       for (k = 0; k < nn; k++) {
 	if (id_self == nbr[m].id[k]) {
 	  if (found_myself) error->one("Fix orient/fcc found self twice");
 	  found_myself = true;
 	  duxi_other = nbr[m].duxi;
 	  dxiptr = &nbr[m].dxi[k][0];
 	  if (use_xismooth) {
 	    xismooth = nbr[m].xismooth[k];
 	    f[i][0] -= duxi_other * dxiptr[0] * xismooth;
 	    f[i][1] -= duxi_other * dxiptr[1] * xismooth;
 	    f[i][2] -= duxi_other * dxiptr[2] * xismooth;
 	  } else {
 	    f[i][0] -= duxi_other * dxiptr[0];
 	    f[i][1] -= duxi_other * dxiptr[1];
 	    f[i][2] -= duxi_other * dxiptr[2];
 	  }
 	}
       }
     }
   }
 
   // print statistics every nstats timesteps
 
   if (nstats && update->ntimestep % nstats == 0) {
     int total;
     MPI_Allreduce(&count,&total,1,MPI_INT,MPI_SUM,world);
     double ave = total/atom->natoms;
 
     int min,max;
     MPI_Allreduce(&mincount,&min,1,MPI_INT,MPI_MIN,world);
     MPI_Allreduce(&maxcount,&max,1,MPI_INT,MPI_MAX,world);
 
     if (me == 0) { 
-      if (screen) {
-	fprintf(screen,"orient step %d: %lu atoms have %d neighbors\n",
-		update->ntimestep,atom->natoms,total);
+      char str[64];
+      sprintf(str,"orient step %%d: %s atoms have %%d neighbors\n",
+	      BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,update->ntimestep,atom->natoms,total);
+      if (logfile) fprintf(logfile,str,update->ntimestep,atom->natoms,total);
+      if (screen)
 	fprintf(screen,"  neighs: min = %d, max = %d, ave = %g\n",
 		min,max,ave);
-      }
-      if (logfile) {
-	fprintf(logfile,"orient step %d: %lu atoms have %d neighbors\n",
-		update->ntimestep,atom->natoms,total);
+      if (logfile)
 	fprintf(logfile,"  neighs: min = %d, max = %d, ave = %g\n",
 		min,max,ave);
-      }
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixOrientFCC::post_force_respa(int vflag, int ilevel, int iloop)
 {
   if (ilevel == nlevels_respa-1) post_force(vflag);
 }
 
 /* ---------------------------------------------------------------------- */
 
 double FixOrientFCC::compute_scalar()
 {
   MPI_Allreduce(&added_energy,&total_added_e,1,MPI_DOUBLE,MPI_SUM,world);
   return total_added_e;
 }
 
 /* ---------------------------------------------------------------------- */
 
 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 nlocal = atom->nlocal;
   int m = 0;
 
   for (i = 0; i < n; i++) {
     k = list[i];
     num = nbr[k].n;
     buf[m++] = static_cast<double> (num);
     buf[m++] = nbr[k].duxi;
 
     for (j = 0; j < num; j++) {
       if (use_xismooth) buf[m++] = nbr[m].xismooth[j];
       buf[m++] = nbr[k].dxi[j][0];
       buf[m++] = nbr[k].dxi[j][1];
       buf[m++] = nbr[k].dxi[j][2];
 
       // id stored in buf needs to be global ID
       // if k is a local atom, it stores local IDs, so convert to global
       // if k is a ghost atom (already comm'd), its IDs are already global
 
       id = nbr[k].id[j];
       if (k < nlocal) id = tag[id];
       buf[m++] = static_cast<double> (id);
     }
 
     m += (12-num) * 3;
     if (use_xismooth) m += 12-num;
   }
 
   if (use_xismooth) return 62;
   return 50;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixOrientFCC::unpack_comm(int n, int first, double *buf)
 {
   int i,j,num;
   int last = first + n;
   int m = 0;
 
   for (i = first; i < last; i++) {
     nbr[i].n = num = static_cast<int> (buf[m++]);
     nbr[i].duxi = buf[m++];
 
     for (j = 0; j < num; j++) {
       if (use_xismooth) nbr[i].xismooth[j] = buf[m++];
       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++]);
     }
 
     m += (12-num) * 3;
     if (use_xismooth) m += 12-num;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixOrientFCC::find_best_ref(double *displs, int which_crystal, 
 				 double &xi_sq, double *dxi)
 {
   int i;
   double dot,tmp;
 
   double  best_dot  = -1.0;         // best is biggest (smallest angle)
   int     best_i    = -1;
   int     best_sign = 0;
 
   for (i = 0; i < half_fcc_nn; i++) {
     dot = displs[0] * half_xi_chi_vec[which_crystal][i][0] +
       displs[1] * half_xi_chi_vec[which_crystal][i][1] +
       displs[2] * half_xi_chi_vec[which_crystal][i][2];
     if (fabs(dot) > best_dot) {
       best_dot = fabs(dot);
       best_i = i;
       if (dot < 0.0) best_sign = -1;
       else best_sign = 1;
     }
   }
 
   xi_sq = 0.0;
   for (i = 0; i < 3; i++) {
     tmp = displs[i] - best_sign * half_xi_chi_vec[which_crystal][best_i][i];
     xi_sq += tmp*tmp;
   }
 
   if (xi_sq > 0.0) {
     double xi = sqrt(xi_sq);
     for (i = 0; i < 3; i++)
       dxi[i] = (best_sign * half_xi_chi_vec[which_crystal][best_i][i] - 
 		displs[i]) / xi;
   } else dxi[0] = dxi[1] = dxi[2] = 0.0;
 }
 
 /* ----------------------------------------------------------------------
    compare two neighbors I and J in sort data structure
    called via qsort in post_force() method
    is a static method so can't access sort data structure directly
    return -1 if I < J, 0 if I = J, 1 if I > J
    do comparison based on rsq distance
 ------------------------------------------------------------------------- */
 
 int FixOrientFCC::compare(const void *pi, const void *pj)
 {
   FixOrientFCC::Sort *ineigh = (FixOrientFCC::Sort *) pi;
   FixOrientFCC::Sort *jneigh = (FixOrientFCC::Sort *) pj;
 
   if (ineigh->rsq < jneigh->rsq) return -1;
   else if (ineigh->rsq > jneigh->rsq) return 1;
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    memory usage of local atom-based arrays 
 ------------------------------------------------------------------------- */
 
 double FixOrientFCC::memory_usage()
 {
   double bytes = atom->nmax * sizeof(Nbr);
   return bytes;
 }
diff --git a/src/fix_shake.cpp b/src/fix_shake.cpp
index 96aecdf77..cf38f11e4 100644
--- a/src/fix_shake.cpp
+++ b/src/fix_shake.cpp
@@ -1,2427 +1,2435 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "stdio.h"
 #include "fix_shake.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "update.h"
 #include "respa.h"
 #include "modify.h"
 #include "domain.h"
 #include "force.h"
 #include "bond.h"
 #include "angle.h"
 #include "comm.h"
 #include "group.h"
 #include "fix_respa.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define BIG 1.0e20
 #define MASSDELTA 0.1
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 /* ---------------------------------------------------------------------- */
 
 FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   MPI_Comm_rank(world,&me);
   MPI_Comm_size(world,&nprocs);
 
   PI = 4.0*atan(1.0);
 
   virial_flag = 1;
   create_attribute = 1;
 
   // error check
 
   if (atom->molecular == 0)
     error->all("Cannot use fix shake with non-molecular system");
 
   // perform initial allocation of atom-based arrays
   // register with Atom class
 
   shake_flag = NULL;
   shake_atom = shake_type = NULL;
   xshake = NULL;
 
   grow_arrays(atom->nmax);
   atom->add_callback(0);
 
   // set comm size needed by this fix
 
   comm_forward = 3;
 
   // parse SHAKE args
 
   if (narg < 8) error->all("Illegal fix shake command");
 
   tolerance = atof(arg[3]);
   max_iter = atoi(arg[4]);
   output_every = atoi(arg[5]);
 
   // parse SHAKE args for bond and angle types
   // will be used by find_clusters
   // store args for "b" "a" "t" as flags in (1:n) list for fast access
   // store args for "m" in list of length nmass for looping over
   // for "m" verify that atom masses have been set
 
   bond_flag = new int[atom->nbondtypes+1];
   for (int i = 1; i <= atom->nbondtypes; i++) bond_flag[i] = 0;
   angle_flag = new int[atom->nangletypes+1];
   for (int i = 1; i <= atom->nangletypes; i++) angle_flag[i] = 0;
   type_flag = new int[atom->ntypes+1];
   for (int i = 1; i <= atom->ntypes; i++) type_flag[i] = 0;
   mass_list = new double[atom->ntypes];
   nmass = 0;
 
   char mode = '\0';
   int next = 6;
   while (next < narg) {
 
     if (strcmp(arg[next],"b") == 0) mode = 'b';
     else if (strcmp(arg[next],"a") == 0) mode = 'a';
     else if (strcmp(arg[next],"t") == 0) mode = 't';
     else if (strcmp(arg[next],"m") == 0) {
       mode = 'm';
       atom->check_mass();
 
     } else if (mode == 'b') {
       int i = atoi(arg[next]);
       if (i < 1 || i > atom->nbondtypes) 
 	error->all("Invalid bond type index for fix shake");
       bond_flag[i] = 1;
 
     } else if (mode == 'a') {
       int i = atoi(arg[next]);
       if (i < 1 || i > atom->nangletypes) 
 	error->all("Invalid angle type index for fix shake");
       angle_flag[i] = 1;
 
     } else if (mode == 't') {
       int i = atoi(arg[next]);
       if (i < 1 || i > atom->ntypes) 
 	error->all("Invalid atom type index for fix shake");
       type_flag[i] = 1;
 
     } else if (mode == 'm') {
       double massone = atof(arg[next]);
       if (massone == 0.0) error->all("Invalid atom mass for fix shake");
       if (nmass == atom->ntypes) error->all("Too many masses for fix shake");
       mass_list[nmass++] = massone;
 
     } else error->all("Illegal fix shake command");
     next++;
   }
 
   // allocate bond and angle distance arrays, indexed from 1 to n
 
   bond_distance = new double[atom->nbondtypes+1];
   angle_distance = new double[atom->nangletypes+1];
 
   // allocate statistics arrays
 
   if (output_every) {
     int nb = atom->nbondtypes + 1;
     b_count = new int[nb];
     b_count_all = new int[nb];
     b_ave = new double[nb];
     b_ave_all = new double[nb];
     b_max = new double[nb];
     b_max_all = new double[nb];
     b_min = new double[nb];
     b_min_all = new double[nb];
 
     int na = atom->nangletypes + 1;
     a_count = new int[na];
     a_count_all = new int[na];
     a_ave = new double[na];
     a_ave_all = new double[na];
     a_max = new double[na];
     a_max_all = new double[na];
     a_min = new double[na];
     a_min_all = new double[na];
   }
 
   // identify all SHAKE clusters
 
   find_clusters();
 
   // initialize list of SHAKE clusters to constrain
 
   maxlist = 0;
   list = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixShake::~FixShake()
 {
   // unregister callbacks to this fix from Atom class
 
   atom->delete_callback(id,0);
 
   // set bond_type and angle_type back to positive for SHAKE clusters
   // must set for all SHAKE bonds and angles stored by each atom
 
   int **bond_type = atom->bond_type;
   int **angle_type = atom->angle_type;
   int nlocal = atom->nlocal;
 
   int n;
   for (int i = 0; i < nlocal; i++) {
     if (shake_flag[i] == 0) continue;
     else if (shake_flag[i] == 1) {
       n = bondfind(i,shake_atom[i][0],shake_atom[i][1]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
       n = bondfind(i,shake_atom[i][0],shake_atom[i][2]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
       n = anglefind(i,shake_atom[i][1],shake_atom[i][2]);
       if (n >= 0) angle_type[i][n] = -angle_type[i][n];
     } else if (shake_flag[i] == 2) {
       n = bondfind(i,shake_atom[i][0],shake_atom[i][1]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
     } else if (shake_flag[i] == 3) {
       n = bondfind(i,shake_atom[i][0],shake_atom[i][1]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
       n = bondfind(i,shake_atom[i][0],shake_atom[i][2]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
     } else if (shake_flag[i] == 4) {
       n = bondfind(i,shake_atom[i][0],shake_atom[i][1]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
       n = bondfind(i,shake_atom[i][0],shake_atom[i][2]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
       n = bondfind(i,shake_atom[i][0],shake_atom[i][3]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
     }
   }
 
   // delete locally stored arrays
 
   memory->sfree(shake_flag);
   memory->destroy_2d_int_array(shake_atom);
   memory->destroy_2d_int_array(shake_type);
   memory->destroy_2d_double_array(xshake);
 
   delete [] bond_flag;
   delete [] angle_flag;
   delete [] type_flag;
   delete [] mass_list;
 
   delete [] bond_distance;
   delete [] angle_distance;
 
   if (output_every) {
     delete [] b_count;
     delete [] b_count_all;
     delete [] b_ave;
     delete [] b_ave_all;
     delete [] b_max;
     delete [] b_max_all;
     delete [] b_min;
     delete [] b_min_all;
 
     delete [] a_count;
     delete [] a_count_all;
     delete [] a_ave;
     delete [] a_ave_all;
     delete [] a_max;
     delete [] a_max_all;
     delete [] a_min;
     delete [] a_min_all;
   }
 
   memory->sfree(list);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixShake::setmask()
 {
   int mask = 0;
   mask |= PRE_NEIGHBOR;
   mask |= POST_FORCE;
   mask |= POST_FORCE_RESPA;
   return mask;
 }
 
 /* ----------------------------------------------------------------------
    set bond and angle distances
    this init must happen after force->bond and force->angle inits 
 ------------------------------------------------------------------------- */
 
 void FixShake::init()
 {
   int i,m,flag,flag_all,type1,type2,bond1_type,bond2_type;
   double rsq,angle;
 
   // error if more than one shake fix
 
   int count = 0;
   for (i = 0; i < modify->nfix; i++)
     if (strcmp(modify->fix[i]->style,"shake") == 0) count++;
   if (count > 1) error->all("More than one fix shake");
 
   // cannot use with minimization since SHAKE turns off bonds
   // that should contribute to potential energy
 
   if (update->whichflag == 2)
     error->all("Fix shake cannot be used with minimization");
 
   // error if npt,nph fix comes before shake fix
 
   for (i = 0; i < modify->nfix; i++) {
     if (strcmp(modify->fix[i]->style,"npt") == 0) break;
     if (strcmp(modify->fix[i]->style,"nph") == 0) break;
   }
   if (i < modify->nfix) {
     for (int j = i; j < modify->nfix; j++)
       if (strcmp(modify->fix[j]->style,"shake") == 0)
 	error->all("Shake fix must come before NPT/NPH fix");
   }
 
   // if rRESPA, find associated fix that must exist
   // could have changed locations in fix list since created
   // set ptrs to rRESPA variables
 
   if (strcmp(update->integrate_style,"respa") == 0) {
     for (i = 0; i < modify->nfix; i++)
       if (strcmp(modify->fix[i]->style,"RESPA") == 0) ifix_respa = i;
     nlevels_respa = ((Respa *) update->integrate)->nlevels;
     loop_respa = ((Respa *) update->integrate)->loop;
     step_respa = ((Respa *) update->integrate)->step;
   }
 
   // set equilibrium bond distances
 
   if (force->bond == NULL)
     error->all("Bond potential must be defined for SHAKE");
   for (i = 1; i <= atom->nbondtypes; i++) 
     bond_distance[i] = force->bond->equilibrium_distance(i);
 
   // set equilibrium angle distances
 
   int nlocal = atom->nlocal;
 
   for (i = 1; i <= atom->nangletypes; i++) {
     if (angle_flag[i] == 0) continue;
     if (force->angle == NULL)
       error->all("Angle potential must be defined for SHAKE");
 
     // scan all atoms for a SHAKE angle cluster
     // extract bond types for the 2 bonds in the cluster
     // bond types must be same in all clusters of this angle type,
     //   else set error flag
     
     flag = 0;
     bond1_type = bond2_type = 0;
     for (m = 0; m < nlocal; m++) {
       if (shake_flag[m] != 1) continue;
       if (shake_type[m][2] != i) continue;
       type1 = MIN(shake_type[m][0],shake_type[m][1]);
       type2 = MAX(shake_type[m][0],shake_type[m][1]);
       if (bond1_type > 0) {
 	if (type1 != bond1_type || type2 != bond2_type) {
 	  flag = 1;
 	  break;
 	}
       }
       bond1_type = type1;
       bond2_type = type2;
     }
 
     // error check for any bond types that are not the same
     
     MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world);
     if (flag_all) error->all("Shake angles have different bond types");
     
     // insure all procs have bond types
     
     MPI_Allreduce(&bond1_type,&flag_all,1,MPI_INT,MPI_MAX,world);
     bond1_type = flag_all;
     MPI_Allreduce(&bond2_type,&flag_all,1,MPI_INT,MPI_MAX,world);
     bond2_type = flag_all;
     
     // if bond types are 0, no SHAKE angles of this type exist
     // just skip this angle
     
     if (bond1_type == 0) {
       angle_distance[i] = 0.0;
       continue;
     }
 
     // compute the angle distance as a function of 2 bond distances
     
     angle = force->angle->equilibrium_angle(i);
     rsq = 2.0*bond_distance[bond1_type]*bond_distance[bond2_type] * 
       (1.0-cos(angle));
     angle_distance[i] = sqrt(rsq);
   }
 }
 
 /* ----------------------------------------------------------------------
    SHAKE as pre-integrator constraint 
 ------------------------------------------------------------------------- */
 
 void FixShake::setup(int vflag)
 {
   pre_neighbor();
 
   if (output_every) stats();
 
   // setup SHAKE output
 
-  int ntimestep = update->ntimestep;
+  bigint ntimestep = update->ntimestep;
   next_output = ntimestep + output_every;
   if (output_every == 0) next_output = update->laststep + 1;
   if (output_every && ntimestep % output_every != 0)
     next_output = (ntimestep/output_every)*output_every + output_every;
 
   // half timestep constraint on pre-step, full timestep thereafter
 
   if (strcmp(update->integrate_style,"verlet") == 0) {
     dtv = update->dt;
     dtfsq = 0.5 * update->dt * update->dt * force->ftm2v;
     post_force(vflag);
     dtfsq = update->dt * update->dt * force->ftm2v;
   } else {
     dtv = step_respa[0];
     dtf_innerhalf = 0.5 * step_respa[0] * force->ftm2v;
     dtf_inner = dtf_innerhalf;
     ((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1);
     post_force_respa(vflag,nlevels_respa-1,0);
     ((Respa *) update->integrate)->copy_f_flevel(nlevels_respa-1);
     dtf_inner = step_respa[0] * force->ftm2v;
   }
 }
 
 /* ----------------------------------------------------------------------
    build list of SHAKE clusters to constrain
    if one or more atoms in cluster are on this proc,
      this proc lists the cluster exactly once 
 ------------------------------------------------------------------------- */
 
 void FixShake::pre_neighbor()
 {
   int atom1,atom2,atom3,atom4;
 
   // local copies of atom quantities
   // used by SHAKE until next re-neighboring
 
   x = atom->x;
   v = atom->v;
   f = atom->f;
   mass = atom->mass;
   rmass = atom->rmass;
   type = atom->type;
   nlocal = atom->nlocal;
 
   // extend size of SHAKE list if necessary
 
   if (nlocal > maxlist) {
     maxlist = nlocal;
     memory->sfree(list);
     list = (int *) memory->smalloc(maxlist*sizeof(int),"shake:list");
   }
 
   // build list of SHAKE clusters I compute
 
   nlist = 0;
 
   for (int i = 0; i < nlocal; i++)
     if (shake_flag[i]) {
       if (shake_flag[i] == 2) {
 	atom1 = atom->map(shake_atom[i][0]);
 	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 %d",
+	  char str[128],fstr[64];
+	  sprintf(fstr,"Shake atoms %%d %%d missing on proc %%d at step %s",
+		  BIGINT_FORMAT);
+	  sprintf(str,fstr,
 		  shake_atom[i][0],shake_atom[i][1],me,update->ntimestep);
 	  error->one(str);
 	}
 	if (i <= atom1 && i <= atom2) list[nlist++] = i;
       } else if (shake_flag[i] % 2 == 1) {
 	atom1 = atom->map(shake_atom[i][0]);
 	atom2 = atom->map(shake_atom[i][1]);
 	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 %d",
+	  char str[128],fstr[64];
+	  sprintf(fstr,"Shake atoms %%d %%d %%d missing on proc %%d at step %s",
+		  BIGINT_FORMAT);
+	  sprintf(str,fstr,
 		  shake_atom[i][0],shake_atom[i][1],shake_atom[i][2],
 		  me,update->ntimestep);
 	  error->one(str);
 	}
 	if (i <= atom1 && i <= atom2 && i <= atom3) list[nlist++] = i;
       } else {
 	atom1 = atom->map(shake_atom[i][0]);
 	atom2 = atom->map(shake_atom[i][1]);
 	atom3 = atom->map(shake_atom[i][2]);
 	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 %d",
+	  char str[128],fstr[64];
+	  sprintf(fstr,
+		  "Shake atoms %%d %%d %%d %%d missing on proc %%d at step %s",
+		  BIGINT_FORMAT);
+	  sprintf(str,fstr,
 		  shake_atom[i][0],shake_atom[i][1],
 		  shake_atom[i][2],shake_atom[i][3],
 		  me,update->ntimestep);
 	  error->one(str);
 	}
 	if (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4) 
 	  list[nlist++] = i;
       }
     }
 }
 
 /* ----------------------------------------------------------------------
    compute the force adjustment for SHAKE constraint 
 ------------------------------------------------------------------------- */
 
 void FixShake::post_force(int vflag)
 {
   if (update->ntimestep == next_output) stats();
 
   // xshake = unconstrained move with current v,f
   // communicate results if necessary
 
   unconstrained_update();
   if (nprocs > 1) comm->forward_comm_fix(this);
 
   // virial setup
 
   if (vflag) v_setup(vflag);
   else evflag = 0;
 
   // loop over clusters to add constraint forces
 
   int m;
   for (int i = 0; i < nlist; i++) {
     m = list[i];
     if (shake_flag[m] == 2) shake2(m);
     else if (shake_flag[m] == 3) shake3(m);
     else if (shake_flag[m] == 4) shake4(m);
     else shake3angle(m);
   }
 }
 
 /* ----------------------------------------------------------------------
    enforce SHAKE constraints from rRESPA
    xshake prediction portion is different than Verlet
 ------------------------------------------------------------------------- */
 
 void FixShake::post_force_respa(int vflag, int ilevel, int iloop)
 {
   // call stats only on outermost level
 
   if (ilevel == nlevels_respa-1 && update->ntimestep == next_output) stats();
 
   // enforce SHAKE constraints on every loop iteration of every rRESPA level
   // except last loop iteration of inner levels
 
   if (ilevel < nlevels_respa-1 && iloop == loop_respa[ilevel]-1) return;
 
   // xshake = unconstrained move with current v,f as function of level
   // communicate results if necessary
 
   unconstrained_update_respa(ilevel);
   if (nprocs > 1) comm->forward_comm_fix(this);
 
   // virial setup, only need to compute on outermost level
 
   if (ilevel == nlevels_respa-1 && vflag) v_setup(vflag);
   else evflag = 0;
 
   // loop over clusters to add constraint forces
 
   int m;
   for (int i = 0; i < nlist; i++) {
     m = list[i];
     if (shake_flag[m] == 2) shake2(m);
     else if (shake_flag[m] == 3) shake3(m);
     else if (shake_flag[m] == 4) shake4(m);
     else shake3angle(m);
   }
 }
 
 /* ----------------------------------------------------------------------
    count # of degrees-of-freedom removed by SHAKE for atoms in igroup 
 ------------------------------------------------------------------------- */
 
 int FixShake::dof(int igroup)
 {
   int groupbit = group->bitmask[igroup];
 
   int *mask = atom->mask;
   int *tag = atom->tag;
   int nlocal = atom->nlocal;
 
   // count dof in a cluster if and only if
   // the central atom is in group and atom i is the central atom
 
   int n = 0;
   for (int i = 0; i < nlocal; i++) {
     if (!(mask[i] & groupbit)) continue;
     if (shake_flag[i] == 0) continue;
     if (shake_atom[i][0] != tag[i]) continue;
     if (shake_flag[i] == 1) n += 3;
     else if (shake_flag[i] == 2) n += 1;
     else if (shake_flag[i] == 3) n += 2;
     else if (shake_flag[i] == 4) n += 3;
   }
 
   int nall;
   MPI_Allreduce(&n,&nall,1,MPI_INT,MPI_SUM,world);
   return nall;
 }
 
 /* ----------------------------------------------------------------------
    identify whether each atom is in a SHAKE cluster
    only include atoms in fix group and those bonds/angles specified in input
    test whether all clusters are valid
    set shake_flag, shake_atom, shake_type values
    set bond,angle types negative so will be ignored in neighbor lists 
 ------------------------------------------------------------------------- */
 
 void FixShake::find_clusters()
 {
   int i,j,m,n;
   int flag,flag_all,messtag,loop,nbuf,nbufmax,size;
   double massone;
   int *buf,*bufcopy;
   MPI_Request request;
   MPI_Status status;
 
   if (me == 0 && screen) fprintf(screen,"Finding SHAKE clusters ...\n");
 
   // local copies of atom ptrs
 
   int *tag = atom->tag;
   int *type = atom->type;
   int *mask = atom->mask;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int **bond_type = atom->bond_type;
   int **angle_type = atom->angle_type;
   int **nspecial = atom->nspecial;
   int **special = atom->special;
   int nlocal = atom->nlocal;
 
   int angles_allow = atom->avec->angles_allow;
 
   // setup ring of procs
 
   int next = me + 1;
   int prev = me -1; 
   if (next == nprocs) next = 0;
   if (prev < 0) prev = nprocs - 1;
 
   // -----------------------------------------------------
   // allocate arrays for self (1d) and bond partners (2d)
   // max = max # of bond partners for owned atoms = 2nd dim of partner arrays
   // npartner[i] = # of bonds attached to atom i
   // nshake[i] = # of SHAKE bonds attached to atom i
   // partner_tag[i][] = global IDs of each partner
   // partner_mask[i][] = mask of each partner
   // partner_type[i][] = type of each partner
   // partner_massflag[i][] = 1 if partner meets mass criterion, 0 if not
   // partner_bondtype[i][] = type of bond attached to each partner
   // partner_shake[i][] = 1 if SHAKE bonded to partner, 0 if not
   // partner_nshake[i][] = nshake value for each partner
   // -----------------------------------------------------
 
   int max = 0;
   for (i = 0; i < nlocal; i++) max = MAX(max,nspecial[i][0]);
 
   int *npartner = (int *) 
     memory->smalloc(nlocal*sizeof(double),"shake:npartner");
   int *nshake = (int *)
     memory->smalloc(nlocal*sizeof(double),"shake:nshake");
   int **partner_tag = 
     memory->create_2d_int_array(nlocal,max,"shake:partner_tag");
   int **partner_mask = 
     memory->create_2d_int_array(nlocal,max,"shake:partner_mask");
   int **partner_type = 
     memory->create_2d_int_array(nlocal,max,"shake:partner_type");
   int **partner_massflag = 
     memory->create_2d_int_array(nlocal,max,"shake:partner_massflag");
   int **partner_bondtype = 
     memory->create_2d_int_array(nlocal,max,"shake:partner_bondtype");
   int **partner_shake = 
     memory->create_2d_int_array(nlocal,max,"shake:partner_shake");
   int **partner_nshake = 
     memory->create_2d_int_array(nlocal,max,"shake:partner_nshake");
 
   // -----------------------------------------------------
   // set npartner and partner_tag from special arrays
   // -----------------------------------------------------
 
   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];
   }
 
   // -----------------------------------------------------
   // set partner_mask, partner_type, partner_massflag, partner_bondtype
   //   for bonded partners
   // requires communication for off-proc partners
   // -----------------------------------------------------
 
   // fill in mask, type, massflag, bondtype if own bond partner
   // info to store in buf for each off-proc bond = nper = 6
   //   2 atoms IDs in bond, space for mask, type, massflag, bondtype
   // nbufmax = largest buffer needed to hold info from any proc
 
   int nper = 6;
 
   nbuf = 0;
   for (i = 0; i < nlocal; i++) {
     for (j = 0; j < npartner[i]; j++) {
       partner_mask[i][j] = 0;
       partner_type[i][j] = 0;
       partner_massflag[i][j] = 0;
       partner_bondtype[i][j] = 0;
 
       m = atom->map(partner_tag[i][j]);
       if (m >= 0 && m < nlocal) {
 	partner_mask[i][j] = mask[m];
 	partner_type[i][j] = type[m];
 	if (nmass) {
 	  if (rmass) massone = rmass[m];
 	  else massone = mass[type[m]];
 	  partner_massflag[i][j] = masscheck(massone);
 	}
 	n = bondfind(i,tag[i],partner_tag[i][j]);
 	if (n >= 0) partner_bondtype[i][j] = bond_type[i][n];
 	else {
 	  n = bondfind(m,tag[i],partner_tag[i][j]);
 	  if (n >= 0) partner_bondtype[i][j] = bond_type[m][n];
 	}
       } else nbuf += nper;
     }
   }
 
   MPI_Allreduce(&nbuf,&nbufmax,1,MPI_INT,MPI_MAX,world);
 
   buf = new int[nbufmax];
   bufcopy = new int[nbufmax];
 
   // fill buffer with info
 
   size = 0;
   for (i = 0; i < nlocal; i++) {
     for (j = 0; j < npartner[i]; j++) {
       m = atom->map(partner_tag[i][j]);
       if (m < 0 || m >= nlocal) {
 	buf[size] = tag[i];
 	buf[size+1] = partner_tag[i][j];
 	buf[size+2] = 0;
 	buf[size+3] = 0;
 	buf[size+4] = 0;
 	n = bondfind(i,tag[i],partner_tag[i][j]);
 	if (n >= 0) buf[size+5] = bond_type[i][n];
 	else buf[size+5] = 0;
 	size += nper;
       }
     }
   }
 
   // cycle buffer around ring of procs back to self
   // when receive buffer, scan bond partner IDs for atoms I own
   // if I own partner:
   //   fill in mask and type and massflag
   //   search for bond with 1st atom and fill in bondtype
 
   messtag = 1;
   for (loop = 0; loop < nprocs; loop++) {
     i = 0;
     while (i < size) {
       m = atom->map(buf[i+1]);
       if (m >= 0 && m < nlocal) {
 	buf[i+2] = mask[m];
 	buf[i+3] = type[m];
 	if (nmass) {
 	  if (rmass) massone = rmass[m];
 	  else massone = mass[type[m]];
 	  buf[i+4] = masscheck(massone);
 	}
 	if (buf[i+5] == 0) {
 	  n = bondfind(m,buf[i],buf[i+1]);
 	  if (n >= 0) buf[i+5] = bond_type[m][n];
 	}
       }
       i += nper;
     }
     if (me != next) {
       MPI_Irecv(bufcopy,nbufmax,MPI_INT,prev,messtag,world,&request);
       MPI_Send(buf,size,MPI_INT,next,messtag,world);
       MPI_Wait(&request,&status);
       MPI_Get_count(&status,MPI_INT,&size);
       for (j = 0; j < size; j++) buf[j] = bufcopy[j];
     }
   }
 
   // store partner info returned to me
 
   m = 0;
   while (m < size) {
     i = atom->map(buf[m]);
     for (j = 0; j < npartner[i]; j++)
       if (buf[m+1] == partner_tag[i][j]) break;
     partner_mask[i][j] = buf[m+2];
     partner_type[i][j] = buf[m+3];
     partner_massflag[i][j] = buf[m+4];
     partner_bondtype[i][j] = buf[m+5];
     m += nper;
   }
 
   delete [] buf;
   delete [] bufcopy;
 
   // error check for unfilled partner info
   // if partner_type not set, is an error
   // partner_bondtype may not be set if special list is not consistent
   //   with bondatom (e.g. due to delete_bonds command)
   // this is OK if one or both atoms are not in fix group, since
   //   bond won't be SHAKEn anyway
   // else it's an error
 
   flag = 0;
   for (i = 0; i < nlocal; i++)
     for (j = 0; j < npartner[i]; j++) {
       if (partner_type[i][j] == 0) flag = 1;
       if (!(mask[i] & groupbit)) continue;
       if (!(partner_mask[i][j] & groupbit)) continue;
       if (partner_bondtype[i][j] == 0) flag = 1;
     }
 
   MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
   if (flag_all) error->all("Did not find fix shake partner info");
 
   // -----------------------------------------------------
   // identify SHAKEable bonds
   // set nshake[i] = # of SHAKE bonds attached to atom i
   // set partner_shake[i][] = 1 if SHAKE bonded to partner, 0 if not
   // both atoms must be in group, bondtype must be > 0
   // check if bondtype is in input bond_flag
   // check if type of either atom is in input type_flag
   // check if mass of either atom is in input mass_list
   // -----------------------------------------------------
 
   int np;
 
   for (i = 0; i < nlocal; i++) {
     nshake[i] = 0;
     np = npartner[i];
     for (j = 0; j < np; j++) {
       partner_shake[i][j] = 0;
 
       if (!(mask[i] & groupbit)) continue;
       if (!(partner_mask[i][j] & groupbit)) continue;
       if (partner_bondtype[i][j] <= 0) continue;
 
       if (bond_flag[partner_bondtype[i][j]]) {
 	partner_shake[i][j] = 1;
 	nshake[i]++;
 	continue;
       }
       if (type_flag[type[i]] || type_flag[partner_type[i][j]]) {
 	partner_shake[i][j] = 1;
 	nshake[i]++;
 	continue;
       }
       if (nmass) {
 	if (partner_massflag[i][j]) {
 	  partner_shake[i][j] = 1;
 	  nshake[i]++;
 	  continue;
 	} else {
 	  if (rmass) massone = rmass[i];
 	  else massone = mass[type[i]];
 	  if (masscheck(massone)) {
 	    partner_shake[i][j] = 1;
 	    nshake[i]++;
 	    continue;
 	  }
 	}
       }
     }
   }
 
   // -----------------------------------------------------
   // set partner_nshake for bonded partners
   // requires communication for off-proc partners
   // -----------------------------------------------------
 
   // fill in partner_nshake if own bond partner
   // info to store in buf for each off-proc bond =
   //   2 atoms IDs in bond, space for nshake value
   // nbufmax = largest buffer needed to hold info from any proc
 
   nbuf = 0;
   for (i = 0; i < nlocal; i++) {
     for (j = 0; j < npartner[i]; j++) {
       m = atom->map(partner_tag[i][j]);
       if (m >= 0 && m < nlocal) partner_nshake[i][j] = nshake[m];
       else nbuf += 3;
     }
   }
   
   MPI_Allreduce(&nbuf,&nbufmax,1,MPI_INT,MPI_MAX,world);
 
   buf = new int[nbufmax];
   bufcopy = new int[nbufmax];
 
   // fill buffer with info
 
   size = 0;
   for (i = 0; i < nlocal; i++) {
     for (j = 0; j < npartner[i]; j++) {
       m = atom->map(partner_tag[i][j]);
       if (m < 0 || m >= nlocal) {
 	buf[size] = tag[i];
 	buf[size+1] = partner_tag[i][j];
 	size += 3;
       }
     }
   }
 
   // cycle buffer around ring of procs back to self
   // when receive buffer, scan bond partner IDs for atoms I own
   // if I own partner, fill in nshake value
 
   messtag = 2;
   for (loop = 0; loop < nprocs; loop++) {
     i = 0;
     while (i < size) {
       m = atom->map(buf[i+1]);
       if (m >= 0 && m < nlocal) buf[i+2] = nshake[m];
       i += 3;
     }
     if (me != next) {
       MPI_Irecv(bufcopy,nbufmax,MPI_INT,prev,messtag,world,&request);
       MPI_Send(buf,size,MPI_INT,next,messtag,world);
       MPI_Wait(&request,&status);
       MPI_Get_count(&status,MPI_INT,&size);
       for (j = 0; j < size; j++) buf[j] = bufcopy[j];
     }
   }
 
   // store partner info returned to me
 
   m = 0;
   while (m < size) {
     i = atom->map(buf[m]);
     for (j = 0; j < npartner[i]; j++)
       if (buf[m+1] == partner_tag[i][j]) break;
     partner_nshake[i][j] = buf[m+2];
     m += 3;
   }
 
   delete [] buf;
   delete [] bufcopy;
 
   // -----------------------------------------------------
   // error checks
   // no atom with nshake > 3
   // no connected atoms which both have nshake > 1
   // -----------------------------------------------------
 
   flag = 0;
   for (i = 0; i < nlocal; i++) if (nshake[i] > 3) flag = 1;
   MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
   if (flag_all) error->all("Shake cluster of more than 4 atoms");
 
   flag = 0;
   for (i = 0; i < nlocal; i++) {
     if (nshake[i] <= 1) continue;
     for (j = 0; j < npartner[i]; j++)
       if (partner_shake[i][j] && partner_nshake[i][j] > 1) flag = 1;
   }
   MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
   if (flag_all) error->all("Shake clusters are connected");
 
   // -----------------------------------------------------
   // set SHAKE arrays that are stored with atoms & add angle constraints
   // zero shake arrays for all owned atoms
   // if I am central atom set shake_flag & shake_atom & shake_type 
   // for 2-atom clusters, I am central atom if my atom ID < partner ID
   // for 3-atom clusters, test for angle constraint
   //   angle will be stored by this atom if it exists
   //   if angle type matches angle_flag, then it is angle-constrained
   // shake_flag[] = 0 if atom not in SHAKE cluster
   //                2,3,4 = size of bond-only cluster
   //                1 = 3-atom angle cluster
   // shake_atom[][] = global IDs of 2,3,4 atoms in cluster
   //                  central atom is 1st
   //                  for 2-atom cluster, lowest ID is 1st
   // shake_type[][] = bondtype of each bond in cluster
   //                  for 3-atom angle cluster, 3rd value is angletype
   // -----------------------------------------------------
 
   for (i = 0; i < nlocal; i++) {
     shake_flag[i] = 0;
     shake_atom[i][0] = 0;
     shake_atom[i][1] = 0;
     shake_atom[i][2] = 0;
     shake_atom[i][3] = 0;
     shake_type[i][0] = 0;
     shake_type[i][1] = 0;
     shake_type[i][2] = 0;
 
     if (nshake[i] == 1) {
       for (j = 0; j < npartner[i]; j++)
 	if (partner_shake[i][j]) break;
       if (partner_nshake[i][j] == 1 && tag[i] < partner_tag[i][j]) {
 	shake_flag[i] = 2;
 	shake_atom[i][0] = tag[i];
 	shake_atom[i][1] = partner_tag[i][j];
 	shake_type[i][0] = partner_bondtype[i][j];
       }
     }
 
     if (nshake[i] > 1) {
       shake_flag[i] = 1;
       shake_atom[i][0] = tag[i];
       for (j = 0; j < npartner[i]; j++)
 	if (partner_shake[i][j]) {
 	  m = shake_flag[i];
 	  shake_atom[i][m] = partner_tag[i][j];
 	  shake_type[i][m-1] = partner_bondtype[i][j];
 	  shake_flag[i]++;
 	}
     }
 
     if (nshake[i] == 2 && angles_allow) {
       n = anglefind(i,shake_atom[i][1],shake_atom[i][2]);
       if (n < 0) continue;
       if (angle_type[i][n] < 0) continue;
       if (angle_flag[angle_type[i][n]]) {
 	shake_flag[i] = 1;
 	shake_type[i][2] = angle_type[i][n];
       }
     }
   }
 
   // -----------------------------------------------------
   // set shake_flag,shake_atom,shake_type for non-central atoms
   // requires communication for off-proc atoms
   // -----------------------------------------------------
 
   // fill in shake arrays for each bond partner I own
   // info to store in buf for each off-proc bond =
   //   all values from shake_flag, shake_atom, shake_type
   // nbufmax = largest buffer needed to hold info from any proc
 
   nbuf = 0;
   for (i = 0; i < nlocal; i++) {
     if (shake_flag[i] == 0) continue;
     for (j = 0; j < npartner[i]; j++) {
       if (partner_shake[i][j] == 0) continue;
       m = atom->map(partner_tag[i][j]);
       if (m >= 0 && m < nlocal) {
 	shake_flag[m] = shake_flag[i];
 	shake_atom[m][0] = shake_atom[i][0];
 	shake_atom[m][1] = shake_atom[i][1];
 	shake_atom[m][2] = shake_atom[i][2];
 	shake_atom[m][3] = shake_atom[i][3];
 	shake_type[m][0] = shake_type[i][0];
 	shake_type[m][1] = shake_type[i][1];
 	shake_type[m][2] = shake_type[i][2];
       } else nbuf += 9;
     }
   }
 
   MPI_Allreduce(&nbuf,&nbufmax,1,MPI_INT,MPI_MAX,world);
 
   buf = new int[nbufmax];
   bufcopy = new int[nbufmax];
 
   // fill buffer with info
 
   size = 0;
   for (i = 0; i < nlocal; i++) {
     if (shake_flag[i] == 0) continue;
     for (j = 0; j < npartner[i]; j++) {
       if (partner_shake[i][j] == 0) continue;
       m = atom->map(partner_tag[i][j]);
       if (m < 0 || m >= nlocal) {
 	buf[size] = partner_tag[i][j];
 	buf[size+1] = shake_flag[i];
 	buf[size+2] = shake_atom[i][0];
 	buf[size+3] = shake_atom[i][1];
 	buf[size+4] = shake_atom[i][2];
 	buf[size+5] = shake_atom[i][3];
 	buf[size+6] = shake_type[i][0];
 	buf[size+7] = shake_type[i][1];
 	buf[size+8] = shake_type[i][2];
 	size += 9;
       }
     }
   }
 
   // cycle buffer around ring of procs back to self
   // when receive buffer, scan for ID that I own
   // if I own ID, fill in shake array values
 
   messtag = 3;
   for (loop = 0; loop < nprocs; loop++) {
     i = 0;
     while (i < size) {
       m = atom->map(buf[i]);
       if (m >= 0 && m < nlocal) {
 	shake_flag[m] = buf[i+1];
 	shake_atom[m][0] = buf[i+2];
 	shake_atom[m][1] = buf[i+3];
 	shake_atom[m][2] = buf[i+4];
 	shake_atom[m][3] = buf[i+5];
 	shake_type[m][0] = buf[i+6];
 	shake_type[m][1] = buf[i+7];
 	shake_type[m][2] = buf[i+8];
       }
       i += 9;
     }
     if (me != next) {
       MPI_Irecv(bufcopy,nbufmax,MPI_INT,prev,messtag,world,&request);
       MPI_Send(buf,size,MPI_INT,next,messtag,world);
       MPI_Wait(&request,&status);
       MPI_Get_count(&status,MPI_INT,&size);
       for (j = 0; j < size; j++) buf[j] = bufcopy[j];
     }
   }
 
   delete [] buf;
   delete [] bufcopy;
 
   // -----------------------------------------------------
   // free local memory
   // -----------------------------------------------------
 
   memory->sfree(npartner);
   memory->sfree(nshake);
   memory->destroy_2d_int_array(partner_tag);
   memory->destroy_2d_int_array(partner_mask);
   memory->destroy_2d_int_array(partner_type);
   memory->destroy_2d_int_array(partner_massflag);
   memory->destroy_2d_int_array(partner_bondtype);
   memory->destroy_2d_int_array(partner_shake);
   memory->destroy_2d_int_array(partner_nshake);
 
   // -----------------------------------------------------
   // set bond_type and angle_type negative for SHAKE clusters
   // must set for all SHAKE bonds and angles stored by each atom
   // -----------------------------------------------------
 
   for (i = 0; i < nlocal; i++) {
     if (shake_flag[i] == 0) continue;
     else if (shake_flag[i] == 1) {
       n = bondfind(i,shake_atom[i][0],shake_atom[i][1]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
       n = bondfind(i,shake_atom[i][0],shake_atom[i][2]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
       n = anglefind(i,shake_atom[i][1],shake_atom[i][2]);
       if (n >= 0) angle_type[i][n] = -angle_type[i][n];
     } else if (shake_flag[i] == 2) {
       n = bondfind(i,shake_atom[i][0],shake_atom[i][1]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
     } else if (shake_flag[i] == 3) {
       n = bondfind(i,shake_atom[i][0],shake_atom[i][1]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
       n = bondfind(i,shake_atom[i][0],shake_atom[i][2]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
     } else if (shake_flag[i] == 4) {
       n = bondfind(i,shake_atom[i][0],shake_atom[i][1]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
       n = bondfind(i,shake_atom[i][0],shake_atom[i][2]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
       n = bondfind(i,shake_atom[i][0],shake_atom[i][3]);
       if (n >= 0) bond_type[i][n] = -bond_type[i][n];
     }
   }
 
   // -----------------------------------------------------
   // print info on SHAKE clusters
   // -----------------------------------------------------
 
   int count1,count2,count3,count4;
   count1 = count2 = count3 = count4 = 0;
   for (i = 0; i < nlocal; i++) {
     if (shake_flag[i] == 1) count1++;
     else if (shake_flag[i] == 2) count2++;
     else if (shake_flag[i] == 3) count3++;
     else if (shake_flag[i] == 4) count4++;
   }
 
   int tmp;
   tmp = count1;
   MPI_Allreduce(&tmp,&count1,1,MPI_INT,MPI_SUM,world);
   tmp = count2;
   MPI_Allreduce(&tmp,&count2,1,MPI_INT,MPI_SUM,world);
   tmp = count3;
   MPI_Allreduce(&tmp,&count3,1,MPI_INT,MPI_SUM,world);
   tmp = count4;
   MPI_Allreduce(&tmp,&count4,1,MPI_INT,MPI_SUM,world);
 
   if (me == 0) {
     if (screen) {
       fprintf(screen,"  %d = # of size 2 clusters\n",count2/2);
       fprintf(screen,"  %d = # of size 3 clusters\n",count3/3);
       fprintf(screen,"  %d = # of size 4 clusters\n",count4/4);
       fprintf(screen,"  %d = # of frozen angles\n",count1/3);
     }
     if (logfile) {
       fprintf(logfile,"  %d = # of size 2 clusters\n",count2/2);
       fprintf(logfile,"  %d = # of size 3 clusters\n",count3/3);
       fprintf(logfile,"  %d = # of size 4 clusters\n",count4/4);
       fprintf(logfile,"  %d = # of frozen angles\n",count1/3);
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    check if massone is within MASSDELTA of any mass in mass_list
    return 1 if yes, 0 if not
 ------------------------------------------------------------------------- */
 
 int FixShake::masscheck(double massone)
 {
   for (int i = 0; i < nmass; i++)
     if (fabs(mass_list[i]-massone) <= MASSDELTA) return 1;
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    update the unconstrained position of each atom
    only for SHAKE clusters, else set to 0.0
    assumes NVE update, seems to be accurate enough for NVT,NPT,NPH as well 
 ------------------------------------------------------------------------- */
 
 void FixShake::unconstrained_update()
 {
   double dtfmsq;
   
   if (rmass) {
     for (int i = 0; i < nlocal; i++) {
       if (shake_flag[i]) {
 	dtfmsq = dtfsq / rmass[i];
 	xshake[i][0] = x[i][0] + dtv*v[i][0] + dtfmsq*f[i][0];
 	xshake[i][1] = x[i][1] + dtv*v[i][1] + dtfmsq*f[i][1];
 	xshake[i][2] = x[i][2] + dtv*v[i][2] + dtfmsq*f[i][2];
       } else xshake[i][2] = xshake[i][1] = xshake[i][0] = 0.0;
     }
   } else {
     for (int i = 0; i < nlocal; i++) {
       if (shake_flag[i]) {
 	dtfmsq = dtfsq / mass[type[i]];
 	xshake[i][0] = x[i][0] + dtv*v[i][0] + dtfmsq*f[i][0];
 	xshake[i][1] = x[i][1] + dtv*v[i][1] + dtfmsq*f[i][1];
 	xshake[i][2] = x[i][2] + dtv*v[i][2] + dtfmsq*f[i][2];
       } else xshake[i][2] = xshake[i][1] = xshake[i][0] = 0.0;
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    update the unconstrained position of each atom in a rRESPA step
    only for SHAKE clusters, else set to 0.0
    assumes NVE update, seems to be accurate enough for NVT,NPT,NPH as well 
 ------------------------------------------------------------------------- */
 
 void FixShake::unconstrained_update_respa(int ilevel)
 {
   // xshake = atom coords after next x update in innermost loop
   // depends on rRESPA level
   // for levels > 0 this includes more than one velocity update
   // xshake = predicted position from call to this routine at level N =
   // x + dt0 (v + dtN/m fN + 1/2 dt(N-1)/m f(N-1) + ... + 1/2 dt0/m f0)
   // also set dtfsq = dt0*dtN so that shake2,shake3,etc can use it
 
   double ***f_level = ((FixRespa *) modify->fix[ifix_respa])->f_level;
   dtfsq = dtf_inner * step_respa[ilevel];
 
   double invmass,dtfmsq;
   int jlevel;
 
   if (rmass) {
     for (int i = 0; i < nlocal; i++) {
       if (shake_flag[i]) {
 	invmass = 1.0 / rmass[i];
 	dtfmsq = dtfsq * invmass;
 	xshake[i][0] = x[i][0] + dtv*v[i][0] + dtfmsq*f[i][0];
 	xshake[i][1] = x[i][1] + dtv*v[i][1] + dtfmsq*f[i][1];
 	xshake[i][2] = x[i][2] + dtv*v[i][2] + dtfmsq*f[i][2];
 	for (jlevel = 0; jlevel < ilevel; jlevel++) {
 	  dtfmsq = dtf_innerhalf * step_respa[jlevel] * invmass;
 	  xshake[i][0] += dtfmsq*f_level[i][jlevel][0];
 	  xshake[i][1] += dtfmsq*f_level[i][jlevel][1];
 	  xshake[i][2] += dtfmsq*f_level[i][jlevel][2];
 	}
       } else xshake[i][2] = xshake[i][1] = xshake[i][0] = 0.0;
     }
 
   } else {
     for (int i = 0; i < nlocal; i++) {
       if (shake_flag[i]) {
 	invmass = 1.0 / mass[type[i]];
 	dtfmsq = dtfsq * invmass;
 	xshake[i][0] = x[i][0] + dtv*v[i][0] + dtfmsq*f[i][0];
 	xshake[i][1] = x[i][1] + dtv*v[i][1] + dtfmsq*f[i][1];
 	xshake[i][2] = x[i][2] + dtv*v[i][2] + dtfmsq*f[i][2];
 	for (jlevel = 0; jlevel < ilevel; jlevel++) {
 	  dtfmsq = dtf_innerhalf * step_respa[jlevel] * invmass;
 	  xshake[i][0] += dtfmsq*f_level[i][jlevel][0];
 	  xshake[i][1] += dtfmsq*f_level[i][jlevel][1];
 	  xshake[i][2] += dtfmsq*f_level[i][jlevel][2];
 	}
       } else xshake[i][2] = xshake[i][1] = xshake[i][0] = 0.0;
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixShake::shake2(int m)
 {
   int nlist,list[2];
   double v[6];
   double invmass0,invmass1;
 
   // local atom IDs and constraint distances
 
   int i0 = atom->map(shake_atom[m][0]);
   int i1 = atom->map(shake_atom[m][1]);
   double bond1 = bond_distance[shake_type[m][0]];
 
   // r01 = distance vec between atoms, with PBC
 
   double r01[3];
   r01[0] = x[i0][0] - x[i1][0];
   r01[1] = x[i0][1] - x[i1][1];
   r01[2] = x[i0][2] - x[i1][2];
   domain->minimum_image(r01);
 
   // s01 = distance vec after unconstrained update, with PBC
 
   double s01[3];
   s01[0] = xshake[i0][0] - xshake[i1][0];
   s01[1] = xshake[i0][1] - xshake[i1][1];
   s01[2] = xshake[i0][2] - xshake[i1][2];
   domain->minimum_image(s01);
 
   // scalar distances between atoms
 
   double r01sq = r01[0]*r01[0] + r01[1]*r01[1] + r01[2]*r01[2];
   double s01sq = s01[0]*s01[0] + s01[1]*s01[1] + s01[2]*s01[2];
 
   // a,b,c = coeffs in quadratic equation for lamda
   
   if (rmass) {
     invmass0 = 1.0/rmass[i0];
     invmass1 = 1.0/rmass[i1];
   } else {
     invmass0 = 1.0/mass[type[i0]];
     invmass1 = 1.0/mass[type[i1]];
   }
 
   double a = (invmass0+invmass1)*(invmass0+invmass1) * r01sq;
   double b = 2.0 * (invmass0+invmass1) *
     (s01[0]*r01[0] + s01[1]*r01[1] + s01[2]*r01[2]);
   double c = s01sq - bond1*bond1;
 
   // error check
 
   double determ = b*b - 4.0*a*c;
   if (determ < 0.0) {
     error->warning("Shake determinant < 0.0",0);
     determ = 0.0;
   }
 
   // exact quadratic solution for lamda
 
   double lamda,lamda1,lamda2;
   lamda1 = (-b+sqrt(determ)) / (2.0*a);
   lamda2 = (-b-sqrt(determ)) / (2.0*a);
 
   if (fabs(lamda1) <= fabs(lamda2)) lamda = lamda1;
   else lamda = lamda2;
 
   // update forces if atom is owned by this processor
 
   lamda /= dtfsq;
 
   if (i0 < nlocal) {
     f[i0][0] += lamda*r01[0];
     f[i0][1] += lamda*r01[1];
     f[i0][2] += lamda*r01[2];
   }
 
   if (i1 < nlocal) {
     f[i1][0] -= lamda*r01[0];
     f[i1][1] -= lamda*r01[1];
     f[i1][2] -= lamda*r01[2];
   }
 
   if (evflag) {
     nlist = 0;
     if (i0 < nlocal) list[nlist++] = i0;
     if (i1 < nlocal) list[nlist++] = i1;
 
     v[0] = lamda*r01[0]*r01[0];
     v[1] = lamda*r01[1]*r01[1];
     v[2] = lamda*r01[2]*r01[2];
     v[3] = lamda*r01[0]*r01[1];
     v[4] = lamda*r01[0]*r01[2];
     v[5] = lamda*r01[1]*r01[2];
 
     v_tally(nlist,list,2.0,v);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixShake::shake3(int m)
 {
   int nlist,list[3];
   double v[6];
   double invmass0,invmass1,invmass2;
 
   // local atom IDs and constraint distances
 
   int i0 = atom->map(shake_atom[m][0]);
   int i1 = atom->map(shake_atom[m][1]);
   int i2 = atom->map(shake_atom[m][2]);
   double bond1 = bond_distance[shake_type[m][0]];
   double bond2 = bond_distance[shake_type[m][1]];
 
   // r01,r02 = distance vec between atoms, with PBC
 
   double r01[3];
   r01[0] = x[i0][0] - x[i1][0];
   r01[1] = x[i0][1] - x[i1][1];
   r01[2] = x[i0][2] - x[i1][2];
   domain->minimum_image(r01);
 
   double r02[3];
   r02[0] = x[i0][0] - x[i2][0];
   r02[1] = x[i0][1] - x[i2][1];
   r02[2] = x[i0][2] - x[i2][2];
   domain->minimum_image(r02);
 
   // s01,s02 = distance vec after unconstrained update, with PBC
 
   double s01[3];
   s01[0] = xshake[i0][0] - xshake[i1][0];
   s01[1] = xshake[i0][1] - xshake[i1][1];
   s01[2] = xshake[i0][2] - xshake[i1][2];
   domain->minimum_image(s01);
 
   double s02[3];
   s02[0] = xshake[i0][0] - xshake[i2][0];
   s02[1] = xshake[i0][1] - xshake[i2][1];
   s02[2] = xshake[i0][2] - xshake[i2][2];
   domain->minimum_image(s02);
 
   // scalar distances between atoms
 
   double r01sq = r01[0]*r01[0] + r01[1]*r01[1] + r01[2]*r01[2];
   double r02sq = r02[0]*r02[0] + r02[1]*r02[1] + r02[2]*r02[2];
   double s01sq = s01[0]*s01[0] + s01[1]*s01[1] + s01[2]*s01[2];
   double s02sq = s02[0]*s02[0] + s02[1]*s02[1] + s02[2]*s02[2];
 
   // matrix coeffs and rhs for lamda equations
 
   if (rmass) {
     invmass0 = 1.0/rmass[i0];
     invmass1 = 1.0/rmass[i1];
     invmass2 = 1.0/rmass[i2];
   } else {
     invmass0 = 1.0/mass[type[i0]];
     invmass1 = 1.0/mass[type[i1]];
     invmass2 = 1.0/mass[type[i2]];
   }
 
   double a11 = 2.0 * (invmass0+invmass1) *
     (s01[0]*r01[0] + s01[1]*r01[1] + s01[2]*r01[2]);
   double a12 = 2.0 * invmass0 *
     (s01[0]*r02[0] + s01[1]*r02[1] + s01[2]*r02[2]);
   double a21 = 2.0 * invmass0 *
     (s02[0]*r01[0] + s02[1]*r01[1] + s02[2]*r01[2]);
   double a22 = 2.0 * (invmass0+invmass2) *
     (s02[0]*r02[0] + s02[1]*r02[1] + s02[2]*r02[2]);
 
   // inverse of matrix
 
   double determ = a11*a22 - a12*a21;
   if (determ == 0.0) error->one("Shake determinant = 0.0");
   double determinv = 1.0/determ;
   
   double a11inv = a22*determinv;
   double a12inv = -a12*determinv;
   double a21inv = -a21*determinv;
   double a22inv = a11*determinv;
 
   // quadratic correction coeffs
 
   double r0102 = (r01[0]*r02[0] + r01[1]*r02[1] + r01[2]*r02[2]);
 
   double quad1_0101 = (invmass0+invmass1)*(invmass0+invmass1) * r01sq;
   double quad1_0202 = invmass0*invmass0 * r02sq;
   double quad1_0102 = 2.0 * (invmass0+invmass1)*invmass0 * r0102;
 
   double quad2_0202 = (invmass0+invmass2)*(invmass0+invmass2) * r02sq;
   double quad2_0101 = invmass0*invmass0 * r01sq;
   double quad2_0102 = 2.0 * (invmass0+invmass2)*invmass0 * r0102;
 
   // iterate until converged
 
   double lamda01 = 0.0;
   double lamda02 = 0.0;
   int niter = 0;
   int done = 0;
 
   double quad1,quad2,b1,b2,lamda01_new,lamda02_new;
 
   while (!done && niter < max_iter) {
     quad1 = quad1_0101 * lamda01*lamda01 + quad1_0202 * lamda02*lamda02 + 
       quad1_0102 * lamda01*lamda02;
     quad2 = quad2_0101 * lamda01*lamda01 + quad2_0202 * lamda02*lamda02 + 
       quad2_0102 * lamda01*lamda02;
         
     b1 = bond1*bond1 - s01sq - quad1;
     b2 = bond2*bond2 - s02sq - quad2;
         
     lamda01_new = a11inv*b1 + a12inv*b2;
     lamda02_new = a21inv*b1 + a22inv*b2;
 
     done = 1;
     if (fabs(lamda01_new-lamda01) > tolerance) done = 0;
     if (fabs(lamda02_new-lamda02) > tolerance) done = 0;
 
     lamda01 = lamda01_new;
     lamda02 = lamda02_new;
     niter++;
   }
 
   // update forces if atom is owned by this processor
 
   lamda01 = lamda01/dtfsq;
   lamda02 = lamda02/dtfsq;
 
   if (i0 < nlocal) {
     f[i0][0] += lamda01*r01[0] + lamda02*r02[0];
     f[i0][1] += lamda01*r01[1] + lamda02*r02[1];
     f[i0][2] += lamda01*r01[2] + lamda02*r02[2];
   }
 
   if (i1 < nlocal) {
     f[i1][0] -= lamda01*r01[0];
     f[i1][1] -= lamda01*r01[1];
     f[i1][2] -= lamda01*r01[2];
   }
 
   if (i2 < nlocal) {
     f[i2][0] -= lamda02*r02[0];
     f[i2][1] -= lamda02*r02[1];
     f[i2][2] -= lamda02*r02[2];
   }
 
   if (evflag) {
     nlist = 0;
     if (i0 < nlocal) list[nlist++] = i0;
     if (i1 < nlocal) list[nlist++] = i1;
     if (i2 < nlocal) list[nlist++] = i2;
 
     v[0] = lamda01*r01[0]*r01[0] + lamda02*r02[0]*r02[0];
     v[1] = lamda01*r01[1]*r01[1] + lamda02*r02[1]*r02[1];
     v[2] = lamda01*r01[2]*r01[2] + lamda02*r02[2]*r02[2];
     v[3] = lamda01*r01[0]*r01[1] + lamda02*r02[0]*r02[1];
     v[4] = lamda01*r01[0]*r01[2] + lamda02*r02[0]*r02[2];
     v[5] = lamda01*r01[1]*r01[2] + lamda02*r02[1]*r02[2];
 
     v_tally(nlist,list,3.0,v);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixShake::shake4(int m)
 {
   int nlist,list[4];
   double v[6];
   double invmass0,invmass1,invmass2,invmass3;
 
   // local atom IDs and constraint distances
 
   int i0 = atom->map(shake_atom[m][0]);
   int i1 = atom->map(shake_atom[m][1]);
   int i2 = atom->map(shake_atom[m][2]);
   int i3 = atom->map(shake_atom[m][3]);
   double bond1 = bond_distance[shake_type[m][0]];
   double bond2 = bond_distance[shake_type[m][1]];
   double bond3 = bond_distance[shake_type[m][2]];
 
   // r01,r02,r03 = distance vec between atoms, with PBC
 
   double r01[3];
   r01[0] = x[i0][0] - x[i1][0];
   r01[1] = x[i0][1] - x[i1][1];
   r01[2] = x[i0][2] - x[i1][2];
   domain->minimum_image(r01);
 
   double r02[3];
   r02[0] = x[i0][0] - x[i2][0];
   r02[1] = x[i0][1] - x[i2][1];
   r02[2] = x[i0][2] - x[i2][2];
   domain->minimum_image(r02);
 
   double r03[3];
   r03[0] = x[i0][0] - x[i3][0];
   r03[1] = x[i0][1] - x[i3][1];
   r03[2] = x[i0][2] - x[i3][2];
   domain->minimum_image(r03);
 
   // s01,s02,s03 = distance vec after unconstrained update, with PBC
 
   double s01[3];
   s01[0] = xshake[i0][0] - xshake[i1][0];
   s01[1] = xshake[i0][1] - xshake[i1][1];
   s01[2] = xshake[i0][2] - xshake[i1][2];
   domain->minimum_image(s01);
 
   double s02[3];
   s02[0] = xshake[i0][0] - xshake[i2][0];
   s02[1] = xshake[i0][1] - xshake[i2][1];
   s02[2] = xshake[i0][2] - xshake[i2][2];
   domain->minimum_image(s02);
 
   double s03[3];
   s03[0] = xshake[i0][0] - xshake[i3][0];
   s03[1] = xshake[i0][1] - xshake[i3][1];
   s03[2] = xshake[i0][2] - xshake[i3][2];
   domain->minimum_image(s03);
 
   // scalar distances between atoms
 
   double r01sq = r01[0]*r01[0] + r01[1]*r01[1] + r01[2]*r01[2];
   double r02sq = r02[0]*r02[0] + r02[1]*r02[1] + r02[2]*r02[2];
   double r03sq = r03[0]*r03[0] + r03[1]*r03[1] + r03[2]*r03[2];
   double s01sq = s01[0]*s01[0] + s01[1]*s01[1] + s01[2]*s01[2];
   double s02sq = s02[0]*s02[0] + s02[1]*s02[1] + s02[2]*s02[2];
   double s03sq = s03[0]*s03[0] + s03[1]*s03[1] + s03[2]*s03[2];
 
   // matrix coeffs and rhs for lamda equations
 
   if (rmass) {
     invmass0 = 1.0/rmass[i0];
     invmass1 = 1.0/rmass[i1];
     invmass2 = 1.0/rmass[i2];
     invmass3 = 1.0/rmass[i3];
   } else {
     invmass0 = 1.0/mass[type[i0]];
     invmass1 = 1.0/mass[type[i1]];
     invmass2 = 1.0/mass[type[i2]];
     invmass3 = 1.0/mass[type[i3]];
   }
 
   double a11 = 2.0 * (invmass0+invmass1) *
     (s01[0]*r01[0] + s01[1]*r01[1] + s01[2]*r01[2]);
   double a12 = 2.0 * invmass0 *
     (s01[0]*r02[0] + s01[1]*r02[1] + s01[2]*r02[2]);
   double a13 = 2.0 * invmass0 *
     (s01[0]*r03[0] + s01[1]*r03[1] + s01[2]*r03[2]);
   double a21 = 2.0 * invmass0 *
     (s02[0]*r01[0] + s02[1]*r01[1] + s02[2]*r01[2]);
   double a22 = 2.0 * (invmass0+invmass2) *
     (s02[0]*r02[0] + s02[1]*r02[1] + s02[2]*r02[2]);
   double a23 = 2.0 * invmass0 *
     (s02[0]*r03[0] + s02[1]*r03[1] + s02[2]*r03[2]);
   double a31 = 2.0 * invmass0 *
     (s03[0]*r01[0] + s03[1]*r01[1] + s03[2]*r01[2]);
   double a32 = 2.0 * invmass0 *
     (s03[0]*r02[0] + s03[1]*r02[1] + s03[2]*r02[2]);
   double a33 = 2.0 * (invmass0+invmass3) *
     (s03[0]*r03[0] + s03[1]*r03[1] + s03[2]*r03[2]);
   
   // inverse of matrix;
 
   double determ = a11*a22*a33 + a12*a23*a31 + a13*a21*a32 -
     a11*a23*a32 - a12*a21*a33 - a13*a22*a31;
   if (determ == 0.0) error->one("Shake determinant = 0.0");
   double determinv = 1.0/determ;
   
   double a11inv = determinv * (a22*a33 - a23*a32);
   double a12inv = -determinv * (a12*a33 - a13*a32);
   double a13inv = determinv * (a12*a23 - a13*a22);
   double a21inv = -determinv * (a21*a33 - a23*a31);
   double a22inv = determinv * (a11*a33 - a13*a31);
   double a23inv = -determinv * (a11*a23 - a13*a21);
   double a31inv = determinv * (a21*a32 - a22*a31);
   double a32inv = -determinv * (a11*a32 - a12*a31);
   double a33inv = determinv * (a11*a22 - a12*a21);
 
   // quadratic correction coeffs
 
   double r0102 = (r01[0]*r02[0] + r01[1]*r02[1] + r01[2]*r02[2]);
   double r0103 = (r01[0]*r03[0] + r01[1]*r03[1] + r01[2]*r03[2]);
   double r0203 = (r02[0]*r03[0] + r02[1]*r03[1] + r02[2]*r03[2]);
 
   double quad1_0101 = (invmass0+invmass1)*(invmass0+invmass1) * r01sq;
   double quad1_0202 = invmass0*invmass0 * r02sq;
   double quad1_0303 = invmass0*invmass0 * r03sq;
   double quad1_0102 = 2.0 * (invmass0+invmass1)*invmass0 * r0102;
   double quad1_0103 = 2.0 * (invmass0+invmass1)*invmass0 * r0103;
   double quad1_0203 = 2.0 * invmass0*invmass0 * r0203;
 
   double quad2_0101 = invmass0*invmass0 * r01sq;
   double quad2_0202 = (invmass0+invmass2)*(invmass0+invmass2) * r02sq;
   double quad2_0303 = invmass0*invmass0 * r03sq;
   double quad2_0102 = 2.0 * (invmass0+invmass2)*invmass0 * r0102;
   double quad2_0103 = 2.0 * invmass0*invmass0 * r0103;
   double quad2_0203 = 2.0 * (invmass0+invmass2)*invmass0 * r0203;
 
   double quad3_0101 = invmass0*invmass0 * r01sq;
   double quad3_0202 = invmass0*invmass0 * r02sq;
   double quad3_0303 = (invmass0+invmass3)*(invmass0+invmass3) * r03sq;
   double quad3_0102 = 2.0 * invmass0*invmass0 * r0102;
   double quad3_0103 = 2.0 * (invmass0+invmass3)*invmass0 * r0103;
   double quad3_0203 = 2.0 * (invmass0+invmass3)*invmass0 * r0203;
 
   // iterate until converged
 
   double lamda01 = 0.0;
   double lamda02 = 0.0;
   double lamda03 = 0.0;
   int niter = 0;
   int done = 0;
 
   double quad1,quad2,quad3,b1,b2,b3,lamda01_new,lamda02_new,lamda03_new;
 
   while (!done && niter < max_iter) {
     quad1 = quad1_0101 * lamda01*lamda01 + 
       quad1_0202 * lamda02*lamda02 +
       quad1_0303 * lamda03*lamda03 + 
       quad1_0102 * lamda01*lamda02 +
       quad1_0103 * lamda01*lamda03 +
       quad1_0203 * lamda02*lamda03;
 
     quad2 = quad2_0101 * lamda01*lamda01 + 
       quad2_0202 * lamda02*lamda02 +
       quad2_0303 * lamda03*lamda03 + 
       quad2_0102 * lamda01*lamda02 +
       quad2_0103 * lamda01*lamda03 +
       quad2_0203 * lamda02*lamda03;
 
     quad3 = quad3_0101 * lamda01*lamda01 + 
       quad3_0202 * lamda02*lamda02 +
       quad3_0303 * lamda03*lamda03 + 
       quad3_0102 * lamda01*lamda02 +
       quad3_0103 * lamda01*lamda03 +
       quad3_0203 * lamda02*lamda03;
 
     b1 = bond1*bond1 - s01sq - quad1;
     b2 = bond2*bond2 - s02sq - quad2;
     b3 = bond3*bond3 - s03sq - quad3;
         
     lamda01_new = a11inv*b1 + a12inv*b2 + a13inv*b3;
     lamda02_new = a21inv*b1 + a22inv*b2 + a23inv*b3;
     lamda03_new = a31inv*b1 + a32inv*b2 + a33inv*b3;
 
     done = 1;
     if (fabs(lamda01_new-lamda01) > tolerance) done = 0;
     if (fabs(lamda02_new-lamda02) > tolerance) done = 0;
     if (fabs(lamda03_new-lamda03) > tolerance) done = 0;
 
     lamda01 = lamda01_new;
     lamda02 = lamda02_new;
     lamda03 = lamda03_new;
     niter++;
   }
 
   // update forces if atom is owned by this processor
 
   lamda01 = lamda01/dtfsq;
   lamda02 = lamda02/dtfsq;
   lamda03 = lamda03/dtfsq;
 
   if (i0 < nlocal) {
     f[i0][0] += lamda01*r01[0] + lamda02*r02[0] + lamda03*r03[0];
     f[i0][1] += lamda01*r01[1] + lamda02*r02[1] + lamda03*r03[1];
     f[i0][2] += lamda01*r01[2] + lamda02*r02[2] + lamda03*r03[2];
   }
 
   if (i1 < nlocal) {
     f[i1][0] -= lamda01*r01[0];
     f[i1][1] -= lamda01*r01[1];
     f[i1][2] -= lamda01*r01[2];
   }
 
   if (i2 < nlocal) {
     f[i2][0] -= lamda02*r02[0];
     f[i2][1] -= lamda02*r02[1];
     f[i2][2] -= lamda02*r02[2];
   }
 
   if (i3 < nlocal) {
     f[i3][0] -= lamda03*r03[0];
     f[i3][1] -= lamda03*r03[1];
     f[i3][2] -= lamda03*r03[2];
   }
 
   if (evflag) {
     nlist = 0;
     if (i0 < nlocal) list[nlist++] = i0;
     if (i1 < nlocal) list[nlist++] = i1;
     if (i2 < nlocal) list[nlist++] = i2;
     if (i3 < nlocal) list[nlist++] = i3;
 
     v[0] = lamda01*r01[0]*r01[0]+lamda02*r02[0]*r02[0]+lamda03*r03[0]*r03[0];
     v[1] = lamda01*r01[1]*r01[1]+lamda02*r02[1]*r02[1]+lamda03*r03[1]*r03[1];
     v[2] = lamda01*r01[2]*r01[2]+lamda02*r02[2]*r02[2]+lamda03*r03[2]*r03[2];
     v[3] = lamda01*r01[0]*r01[1]+lamda02*r02[0]*r02[1]+lamda03*r03[0]*r03[1];
     v[4] = lamda01*r01[0]*r01[2]+lamda02*r02[0]*r02[2]+lamda03*r03[0]*r03[2];
     v[5] = lamda01*r01[1]*r01[2]+lamda02*r02[1]*r02[2]+lamda03*r03[1]*r03[2];
 
     v_tally(nlist,list,4.0,v);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixShake::shake3angle(int m)
 {
   int nlist,list[3];
   double v[6];
   double invmass0,invmass1,invmass2;
 
   // local atom IDs and constraint distances
 
   int i0 = atom->map(shake_atom[m][0]);
   int i1 = atom->map(shake_atom[m][1]);
   int i2 = atom->map(shake_atom[m][2]);
   double bond1 = bond_distance[shake_type[m][0]];
   double bond2 = bond_distance[shake_type[m][1]];
   double bond12 = angle_distance[shake_type[m][2]];
 
   // r01,r02,r12 = distance vec between atoms, with PBC
 
   double r01[3];
   r01[0] = x[i0][0] - x[i1][0];
   r01[1] = x[i0][1] - x[i1][1];
   r01[2] = x[i0][2] - x[i1][2];
   domain->minimum_image(r01);
 
   double r02[3];
   r02[0] = x[i0][0] - x[i2][0];
   r02[1] = x[i0][1] - x[i2][1];
   r02[2] = x[i0][2] - x[i2][2];
   domain->minimum_image(r02);
 
   double r12[3];
   r12[0] = x[i1][0] - x[i2][0];
   r12[1] = x[i1][1] - x[i2][1];
   r12[2] = x[i1][2] - x[i2][2];
   domain->minimum_image(r12);
 
   // s01,s02,s12 = distance vec after unconstrained update, with PBC
 
   double s01[3];
   s01[0] = xshake[i0][0] - xshake[i1][0];
   s01[1] = xshake[i0][1] - xshake[i1][1];
   s01[2] = xshake[i0][2] - xshake[i1][2];
   domain->minimum_image(s01);
 
   double s02[3];
   s02[0] = xshake[i0][0] - xshake[i2][0];
   s02[1] = xshake[i0][1] - xshake[i2][1];
   s02[2] = xshake[i0][2] - xshake[i2][2];
   domain->minimum_image(s02);
 
   double s12[3];
   s12[0] = xshake[i1][0] - xshake[i2][0];
   s12[1] = xshake[i1][1] - xshake[i2][1];
   s12[2] = xshake[i1][2] - xshake[i2][2];
   domain->minimum_image(s12);
 
   // scalar distances between atoms
 
   double r01sq = r01[0]*r01[0] + r01[1]*r01[1] + r01[2]*r01[2];
   double r02sq = r02[0]*r02[0] + r02[1]*r02[1] + r02[2]*r02[2];
   double r12sq = r12[0]*r12[0] + r12[1]*r12[1] + r12[2]*r12[2];
   double s01sq = s01[0]*s01[0] + s01[1]*s01[1] + s01[2]*s01[2];
   double s02sq = s02[0]*s02[0] + s02[1]*s02[1] + s02[2]*s02[2];
   double s12sq = s12[0]*s12[0] + s12[1]*s12[1] + s12[2]*s12[2];
 
   // matrix coeffs and rhs for lamda equations
 
   if (rmass) {
     invmass0 = 1.0/rmass[i0];
     invmass1 = 1.0/rmass[i1];
     invmass2 = 1.0/rmass[i2];
   } else {
     invmass0 = 1.0/mass[type[i0]];
     invmass1 = 1.0/mass[type[i1]];
     invmass2 = 1.0/mass[type[i2]];
   }
 
   double a11 = 2.0 * (invmass0+invmass1) *
     (s01[0]*r01[0] + s01[1]*r01[1] + s01[2]*r01[2]);
   double a12 = 2.0 * invmass0 *
     (s01[0]*r02[0] + s01[1]*r02[1] + s01[2]*r02[2]);
   double a13 = - 2.0 * invmass1 *
     (s01[0]*r12[0] + s01[1]*r12[1] + s01[2]*r12[2]);
   double a21 = 2.0 * invmass0 *
     (s02[0]*r01[0] + s02[1]*r01[1] + s02[2]*r01[2]);
   double a22 = 2.0 * (invmass0+invmass2) *
     (s02[0]*r02[0] + s02[1]*r02[1] + s02[2]*r02[2]);
   double a23 = 2.0 * invmass2 *
     (s02[0]*r12[0] + s02[1]*r12[1] + s02[2]*r12[2]);
   double a31 = - 2.0 * invmass1 *
     (s12[0]*r01[0] + s12[1]*r01[1] + s12[2]*r01[2]);
   double a32 = 2.0 * invmass2 *
     (s12[0]*r02[0] + s12[1]*r02[1] + s12[2]*r02[2]);
   double a33 = 2.0 * (invmass1+invmass2) *
     (s12[0]*r12[0] + s12[1]*r12[1] + s12[2]*r12[2]);
 
   // inverse of matrix
 
   double determ = a11*a22*a33 + a12*a23*a31 + a13*a21*a32 -
     a11*a23*a32 - a12*a21*a33 - a13*a22*a31;
   if (determ == 0.0) error->one("Shake determinant = 0.0");
   double determinv = 1.0/determ;
   
   double a11inv = determinv * (a22*a33 - a23*a32);
   double a12inv = -determinv * (a12*a33 - a13*a32);
   double a13inv = determinv * (a12*a23 - a13*a22);
   double a21inv = -determinv * (a21*a33 - a23*a31);
   double a22inv = determinv * (a11*a33 - a13*a31);
   double a23inv = -determinv * (a11*a23 - a13*a21);
   double a31inv = determinv * (a21*a32 - a22*a31);
   double a32inv = -determinv * (a11*a32 - a12*a31);
   double a33inv = determinv * (a11*a22 - a12*a21);
 
   // quadratic correction coeffs
 
   double r0102 = (r01[0]*r02[0] + r01[1]*r02[1] + r01[2]*r02[2]);
   double r0112 = (r01[0]*r12[0] + r01[1]*r12[1] + r01[2]*r12[2]);
   double r0212 = (r02[0]*r12[0] + r02[1]*r12[1] + r02[2]*r12[2]);
 
   double quad1_0101 = (invmass0+invmass1)*(invmass0+invmass1) * r01sq;
   double quad1_0202 = invmass0*invmass0 * r02sq;
   double quad1_1212 = invmass1*invmass1 * r12sq;
   double quad1_0102 = 2.0 * (invmass0+invmass1)*invmass0 * r0102;
   double quad1_0112 = - 2.0 * (invmass0+invmass1)*invmass1 * r0112;
   double quad1_0212 = - 2.0 * invmass0*invmass1 * r0212;
 
   double quad2_0101 = invmass0*invmass0 * r01sq;
   double quad2_0202 = (invmass0+invmass2)*(invmass0+invmass2) * r02sq;
   double quad2_1212 = invmass2*invmass2 * r12sq;
   double quad2_0102 = 2.0 * (invmass0+invmass2)*invmass0 * r0102;
   double quad2_0112 = 2.0 * invmass0*invmass2 * r0112;
   double quad2_0212 = 2.0 * (invmass0+invmass2)*invmass2 * r0212;
 
   double quad3_0101 = invmass1*invmass1 * r01sq;
   double quad3_0202 = invmass2*invmass2 * r02sq;
   double quad3_1212 = (invmass1+invmass2)*(invmass1+invmass2) * r12sq;
   double quad3_0102 = - 2.0 * invmass1*invmass2 * r0102;
   double quad3_0112 = - 2.0 * (invmass1+invmass2)*invmass1 * r0112;
   double quad3_0212 = 2.0 * (invmass1+invmass2)*invmass2 * r0212;
 
   // iterate until converged
 
   double lamda01 = 0.0;
   double lamda02 = 0.0;
   double lamda12 = 0.0;
   int niter = 0;
   int done = 0;
 
   double quad1,quad2,quad3,b1,b2,b3,lamda01_new,lamda02_new,lamda12_new;
 
   while (!done && niter < max_iter) {
     quad1 = quad1_0101 * lamda01*lamda01 + 
       quad1_0202 * lamda02*lamda02 +
       quad1_1212 * lamda12*lamda12 + 
       quad1_0102 * lamda01*lamda02 +
       quad1_0112 * lamda01*lamda12 +
       quad1_0212 * lamda02*lamda12;
 
     quad2 = quad2_0101 * lamda01*lamda01 + 
       quad2_0202 * lamda02*lamda02 +
       quad2_1212 * lamda12*lamda12 + 
       quad2_0102 * lamda01*lamda02 +
       quad2_0112 * lamda01*lamda12 +
       quad2_0212 * lamda02*lamda12;
       
     quad3 = quad3_0101 * lamda01*lamda01 + 
       quad3_0202 * lamda02*lamda02 +
       quad3_1212 * lamda12*lamda12 + 
       quad3_0102 * lamda01*lamda02 +
       quad3_0112 * lamda01*lamda12 +
       quad3_0212 * lamda02*lamda12;
 
     b1 = bond1*bond1 - s01sq - quad1;
     b2 = bond2*bond2 - s02sq - quad2;
     b3 = bond12*bond12 - s12sq - quad3;
         
     lamda01_new = a11inv*b1 + a12inv*b2 + a13inv*b3;
     lamda02_new = a21inv*b1 + a22inv*b2 + a23inv*b3;
     lamda12_new = a31inv*b1 + a32inv*b2 + a33inv*b3;
 
     done = 1;
     if (fabs(lamda01_new-lamda01) > tolerance) done = 0;
     if (fabs(lamda02_new-lamda02) > tolerance) done = 0;
     if (fabs(lamda12_new-lamda12) > tolerance) done = 0;
 
     lamda01 = lamda01_new;
     lamda02 = lamda02_new;
     lamda12 = lamda12_new;
     niter++;
   }
 
   // update forces if atom is owned by this processor
 
   lamda01 = lamda01/dtfsq;
   lamda02 = lamda02/dtfsq;
   lamda12 = lamda12/dtfsq;
 
   if (i0 < nlocal) {
     f[i0][0] += lamda01*r01[0] + lamda02*r02[0];
     f[i0][1] += lamda01*r01[1] + lamda02*r02[1];
     f[i0][2] += lamda01*r01[2] + lamda02*r02[2];
   }
 
   if (i1 < nlocal) {
     f[i1][0] -= lamda01*r01[0] - lamda12*r12[0];
     f[i1][1] -= lamda01*r01[1] - lamda12*r12[1];
     f[i1][2] -= lamda01*r01[2] - lamda12*r12[2];
   }
 
   if (i2 < nlocal) {
     f[i2][0] -= lamda02*r02[0] + lamda12*r12[0];
     f[i2][1] -= lamda02*r02[1] + lamda12*r12[1];
     f[i2][2] -= lamda02*r02[2] + lamda12*r12[2];
   }
 
   if (evflag) {
     nlist = 0;
     if (i0 < nlocal) list[nlist++] = i0;
     if (i1 < nlocal) list[nlist++] = i1;
     if (i2 < nlocal) list[nlist++] = i2;
 
     v[0] = lamda01*r01[0]*r01[0]+lamda02*r02[0]*r02[0]+lamda12*r12[0]*r12[0];
     v[1] = lamda01*r01[1]*r01[1]+lamda02*r02[1]*r02[1]+lamda12*r12[1]*r12[1];
     v[2] = lamda01*r01[2]*r01[2]+lamda02*r02[2]*r02[2]+lamda12*r12[2]*r12[2];
     v[3] = lamda01*r01[0]*r01[1]+lamda02*r02[0]*r02[1]+lamda12*r12[0]*r12[1];
     v[4] = lamda01*r01[0]*r01[2]+lamda02*r02[0]*r02[2]+lamda12*r12[0]*r12[2];
     v[5] = lamda01*r01[1]*r01[2]+lamda02*r02[1]*r02[2]+lamda12*r12[1]*r12[2];
 
     v_tally(nlist,list,3.0,v);
   }
 }
 
 /* ----------------------------------------------------------------------
    print-out bond & angle statistics 
 ------------------------------------------------------------------------- */
 
 void FixShake::stats()
 {
   int i,j,m,n,iatom,jatom,katom;
   double delx,dely,delz;
   double r,r1,r2,r3,angle;
 
   // zero out accumulators
 
   int nb = atom->nbondtypes + 1;
   int na = atom->nangletypes + 1;
 
   for (i = 0; i < nb; i++) {
     b_count[i] = 0;
     b_ave[i] = b_max[i] = 0.0;
     b_min[i] = BIG;
   }
   for (i = 0; i < na; i++) {
     a_count[i] = 0;
     a_ave[i] = a_max[i] = 0.0;
     a_min[i] = BIG;
   }
 
   // log stats for each bond & angle
   // OK to double count since are just averaging
 
   double **x = atom->x;
   int nlocal = atom->nlocal;
 
   for (i = 0; i < nlocal; i++) {
     if (shake_flag[i] == 0) continue;
 
     // bond stats
 
     n = shake_flag[i];
     if (n == 1) n = 3;
     iatom = atom->map(shake_atom[i][0]);
     for (j = 1; j < n; j++) {
       jatom = atom->map(shake_atom[i][j]);
       delx = x[iatom][0] - x[jatom][0];
       dely = x[iatom][1] - x[jatom][1];
       delz = x[iatom][2] - x[jatom][2];
       domain->minimum_image(delx,dely,delz);
       r = sqrt(delx*delx + dely*dely + delz*delz);
       
       m = shake_type[i][j-1];
       b_count[m]++;
       b_ave[m] += r;
       b_max[m] = MAX(b_max[m],r);
       b_min[m] = MIN(b_min[m],r);
     }
 
     // angle stats
 
     if (shake_flag[i] == 1) {
       iatom = atom->map(shake_atom[i][0]);
       jatom = atom->map(shake_atom[i][1]);
       katom = atom->map(shake_atom[i][2]);
 
       delx = x[iatom][0] - x[jatom][0];
       dely = x[iatom][1] - x[jatom][1];
       delz = x[iatom][2] - x[jatom][2];
       domain->minimum_image(delx,dely,delz);
       r1 = sqrt(delx*delx + dely*dely + delz*delz);
 
       delx = x[iatom][0] - x[katom][0];
       dely = x[iatom][1] - x[katom][1];
       delz = x[iatom][2] - x[katom][2];
       domain->minimum_image(delx,dely,delz);
       r2 = sqrt(delx*delx + dely*dely + delz*delz);
 
       delx = x[jatom][0] - x[katom][0];
       dely = x[jatom][1] - x[katom][1];
       delz = x[jatom][2] - x[katom][2];
       domain->minimum_image(delx,dely,delz);
       r3 = sqrt(delx*delx + dely*dely + delz*delz);
 
       angle = acos((r1*r1 + r2*r2 - r3*r3) / (2.0*r1*r2));
       angle *= 180.0/PI;
       m = shake_type[i][2];
       a_count[m]++;
       a_ave[m] += angle;
       a_max[m] = MAX(a_max[m],angle);
       a_min[m] = MIN(a_min[m],angle);
     }
   }
 
   // sum across all procs
 
   MPI_Allreduce(b_count,b_count_all,nb,MPI_INT,MPI_SUM,world);
   MPI_Allreduce(b_ave,b_ave_all,nb,MPI_DOUBLE,MPI_SUM,world);
   MPI_Allreduce(b_max,b_max_all,nb,MPI_DOUBLE,MPI_MAX,world);
   MPI_Allreduce(b_min,b_min_all,nb,MPI_DOUBLE,MPI_MIN,world);
 
   MPI_Allreduce(a_count,a_count_all,na,MPI_INT,MPI_SUM,world);
   MPI_Allreduce(a_ave,a_ave_all,na,MPI_DOUBLE,MPI_SUM,world);
   MPI_Allreduce(a_max,a_max_all,na,MPI_DOUBLE,MPI_MAX,world);
   MPI_Allreduce(a_min,a_min_all,na,MPI_DOUBLE,MPI_MIN,world);
 
   // print stats only for non-zero counts
 
   if (me == 0) {
+    char fstr[64];
+    sprintf(fstr,"SHAKE stats (type/ave/delta) on step %s\n",BIGINT_FORMAT);
     if (screen) {
-      fprintf(screen,"SHAKE stats (type/ave/delta) on step %d\n",
-	      update->ntimestep);
+      fprintf(screen,fstr,update->ntimestep);
       for (i = 1; i < nb; i++) 
 	if (b_count_all[i])
 	  fprintf(screen,"  %d %g %g\n",i,
 		  b_ave_all[i]/b_count_all[i],b_max_all[i]-b_min_all[i]);
       for (i = 1; i < na; i++) 
 	if (a_count_all[i])
 	  fprintf(screen,"  %d %g %g\n",i,
 		  a_ave_all[i]/a_count_all[i],a_max_all[i]-a_min_all[i]);
     }
     if (logfile) {
-      fprintf(logfile,"SHAKE stats (type/ave/delta) on step %d\n",
-	      update->ntimestep);
+      fprintf(logfile,fstr,update->ntimestep);
       for (i = 0; i < nb; i++) 
 	if (b_count_all[i])
 	  fprintf(logfile,"  %d %g %g\n",i,
 		  b_ave_all[i]/b_count_all[i],b_max_all[i]-b_min_all[i]);
       for (i = 0; i < na; i++) 
 	if (a_count_all[i])
 	  fprintf(logfile,"  %d %g %g\n",i,
 		  a_ave_all[i]/a_count_all[i],a_max_all[i]-a_min_all[i]);
     }
   }
 
   // next timestep for stats
 
   next_output += output_every;
 }
 
 /* ----------------------------------------------------------------------
    find a bond between global tags n1 and n2 stored with local atom i
    return -1 if don't find it
    return bond index if do find it
 ------------------------------------------------------------------------- */
 
 int FixShake::bondfind(int i, int n1, int n2)
 {
   int *tag = atom->tag;
   int **bond_atom = atom->bond_atom;
   int nbonds = atom->num_bond[i];
 
   int m;
   for (m = 0; m < nbonds; m++) {
     if (n1 == tag[i] && n2 == bond_atom[i][m]) break;
     if (n1 == bond_atom[i][m] && n2 == tag[i]) break;
   }
   if (m < nbonds) return m;
   return -1;
 }
 
 /* ----------------------------------------------------------------------
    find an angle with global end atoms n1 and n2 stored with local atom i
    return -1 if don't find it
    return angle index if do find it
 ------------------------------------------------------------------------- */
 
 int FixShake::anglefind(int i, int n1, int n2)
 {
   int **angle_atom1 = atom->angle_atom1;
   int **angle_atom3 = atom->angle_atom3;
   int nangles = atom->num_angle[i];
 
   int m;
   for (m = 0; m < nangles; m++) {
     if (n1 == angle_atom1[i][m] && n2 == angle_atom3[i][m]) break;
     if (n1 == angle_atom3[i][m] && n2 == angle_atom1[i][m]) break;
   }
   if (m < nangles) return m;
   return -1;
 }
 
 /* ----------------------------------------------------------------------
    memory usage of local atom-based arrays 
 ------------------------------------------------------------------------- */
 
 double FixShake::memory_usage()
 {
   int nmax = atom->nmax;
   double bytes = nmax * sizeof(int);
   bytes += nmax*4 * sizeof(int);
   bytes += nmax*3 * sizeof(int);
   bytes += nmax*3 * sizeof(double);
   bytes += maxvatom*6 * sizeof(double);
   return bytes;
 }
 
 /* ----------------------------------------------------------------------
    allocate local atom-based arrays 
 ------------------------------------------------------------------------- */
 
 void FixShake::grow_arrays(int nmax)
 {
   shake_flag = (int *)
     memory->srealloc(shake_flag,nmax*sizeof(int),"shake:shake_flag");
   shake_atom =
     memory->grow_2d_int_array(shake_atom,nmax,4,"shake:shake_atom");
   shake_type =
     memory->grow_2d_int_array(shake_type,nmax,3,"shake:shake_type");
   memory->destroy_2d_double_array(xshake);
   xshake = memory->create_2d_double_array(nmax,3,"shake:xshake");
 }
 
 /* ----------------------------------------------------------------------
    copy values within local atom-based arrays 
 ------------------------------------------------------------------------- */
 
 void FixShake::copy_arrays(int i, int j)
 {
   int flag = shake_flag[j] = shake_flag[i];
   if (flag == 1) {
     shake_atom[j][0] = shake_atom[i][0];
     shake_atom[j][1] = shake_atom[i][1];
     shake_atom[j][2] = shake_atom[i][2];
     shake_type[j][0] = shake_type[i][0];
     shake_type[j][1] = shake_type[i][1];
     shake_type[j][2] = shake_type[i][2];
   } else if (flag == 2) {
     shake_atom[j][0] = shake_atom[i][0];
     shake_atom[j][1] = shake_atom[i][1];
     shake_type[j][0] = shake_type[i][0];
   } else if (flag == 3) {
     shake_atom[j][0] = shake_atom[i][0];
     shake_atom[j][1] = shake_atom[i][1];
     shake_atom[j][2] = shake_atom[i][2];
     shake_type[j][0] = shake_type[i][0];
     shake_type[j][1] = shake_type[i][1];
   } else if (flag == 4) {
     shake_atom[j][0] = shake_atom[i][0];
     shake_atom[j][1] = shake_atom[i][1];
     shake_atom[j][2] = shake_atom[i][2];
     shake_atom[j][3] = shake_atom[i][3];
     shake_type[j][0] = shake_type[i][0];
     shake_type[j][1] = shake_type[i][1];
     shake_type[j][2] = shake_type[i][2];
   }
 }
 
 /* ----------------------------------------------------------------------
    initialize one atom's array values, called when atom is created
 ------------------------------------------------------------------------- */
 
 void FixShake::set_arrays(int i)
 {
   shake_flag[i] = 0;
 }
 
 /* ----------------------------------------------------------------------
    pack values in local atom-based arrays for exchange with another proc 
 ------------------------------------------------------------------------- */
 
 int FixShake::pack_exchange(int i, double *buf)
 {
   int m = 0;
   buf[m++] = shake_flag[i];
   int flag = shake_flag[i];
   if (flag == 1) {
     buf[m++] = shake_atom[i][0];
     buf[m++] = shake_atom[i][1];
     buf[m++] = shake_atom[i][2];
     buf[m++] = shake_type[i][0];
     buf[m++] = shake_type[i][1];
     buf[m++] = shake_type[i][2];
   } else if (flag == 2) {
     buf[m++] = shake_atom[i][0];
     buf[m++] = shake_atom[i][1];
     buf[m++] = shake_type[i][0];
   } else if (flag == 3) {
     buf[m++] = shake_atom[i][0];
     buf[m++] = shake_atom[i][1];
     buf[m++] = shake_atom[i][2];
     buf[m++] = shake_type[i][0];
     buf[m++] = shake_type[i][1];
   } else if (flag == 4) {
     buf[m++] = shake_atom[i][0];
     buf[m++] = shake_atom[i][1];
     buf[m++] = shake_atom[i][2];
     buf[m++] = shake_atom[i][3];
     buf[m++] = shake_type[i][0];
     buf[m++] = shake_type[i][1];
     buf[m++] = shake_type[i][2];
   }
   return m;
 }
 
 /* ----------------------------------------------------------------------
    unpack values in local atom-based arrays from exchange with another proc 
 ------------------------------------------------------------------------- */
 
 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_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_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_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_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++]);
   }
   return m;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixShake::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
 
   m = 0;
   if (pbc_flag == 0) {
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = xshake[j][0];
       buf[m++] = xshake[j][1];
       buf[m++] = xshake[j][2];
     }
   } else {
     if (domain->triclinic == 0) {
       dx = pbc[0]*domain->xprd;
       dy = pbc[1]*domain->yprd;
       dz = pbc[2]*domain->zprd;
     } else {
       dx = pbc[0]*domain->xprd + pbc[5]*domain->xy + pbc[4]*domain->xz;
       dy = pbc[1]*domain->yprd + pbc[3]*domain->yz;
       dz = pbc[2]*domain->zprd;
     }
     for (i = 0; i < n; i++) {
       j = list[i];
       buf[m++] = xshake[j][0] + dx;
       buf[m++] = xshake[j][1] + dy;
       buf[m++] = xshake[j][2] + dz;
     }
   }
   return 3;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixShake::unpack_comm(int n, int first, double *buf)
 {
   int i,m,last;
 
   m = 0;
   last = first + n;
   for (i = first; i < last; i++) {
     xshake[i][0] = buf[m++];
     xshake[i][1] = buf[m++];
     xshake[i][2] = buf[m++];
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixShake::reset_dt()
 {
   if (strcmp(update->integrate_style,"verlet") == 0) {
     dtv = update->dt;
     dtfsq = update->dt * update->dt * force->ftm2v;
   } else {
     dtv = step_respa[0];
     dtf_innerhalf = 0.5 * step_respa[0] * force->ftm2v;
     dtf_inner = step_respa[0] * force->ftm2v;
   }
 }
diff --git a/src/fix_shake.h b/src/fix_shake.h
index ebef049db..fc919aaa1 100644
--- a/src/fix_shake.h
+++ b/src/fix_shake.h
@@ -1,118 +1,119 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef FIX_CLASS
 
 FixStyle(shake,FixShake)
 
 #else
 
 #ifndef LMP_FIX_SHAKE_H
 #define LMP_FIX_SHAKE_H
 
 #include "fix.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class FixShake : public Fix {
  public:
   FixShake(class LAMMPS *, int, char **);
   ~FixShake();
   int setmask();
   void init();
   void setup(int);
   void pre_neighbor();
   void post_force(int);
   void post_force_respa(int, int, int);
 
   double memory_usage();
   void grow_arrays(int);
   void copy_arrays(int, int);
   void set_arrays(int);
   int pack_exchange(int, double *);
   int unpack_exchange(int, double *);
   int pack_comm(int, int *, double *, int, int *);
   void unpack_comm(int, int, double *);
 
   int dof(int);
   void reset_dt();
 
  private:
   int me,nprocs;
   double PI;
   double tolerance;                      // SHAKE tolerance
   int max_iter;                          // max # of SHAKE iterations
   int output_every;                      // SHAKE stat output every so often
-  int next_output;                       // timestep for next output
+  bigint next_output;                    // timestep for next output
 
                                          // settings from input command
   int *bond_flag,*angle_flag;            // bond/angle types to constrain
   int *type_flag;                        // constrain bonds to these types
   double *mass_list;                     // constrain bonds to these masses
   int nmass;                             // # of masses in mass_list
 
   double *bond_distance,*angle_distance; // constraint distances
 
   int ifix_respa;                        // rRESPA fix needed by SHAKE
   int nlevels_respa;                     // copies of needed rRESPA variables
   int *loop_respa;
   double *step_respa;
 
   double **x,**v,**f;                    // local ptrs to atom class quantities
   double *mass,*rmass;
   int *type;
   int nlocal;
                                          // atom-based arrays
   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
                                          // central atom is 1st
                                          // lowest global ID is 1st for size 2
   int **shake_type;                      // bondtype of each bond in cluster
                                          // for angle cluster, 3rd value
                                          //   is angletype
   double **xshake;                       // unconstrained atom coords
 
   int vflag;                            // virial flag
   double dtv,dtfsq;                     // timesteps for trial move
   double dtf_inner,dtf_innerhalf;       // timesteps for rRESPA trial move
 
   int *list;                            // list of clusters to SHAKE
   int nlist,maxlist;                    // size and max-size of list
 
                                         // stat quantities
   int *b_count,*b_count_all;            // counts for each bond type
   double *b_ave,*b_max,*b_min;          // ave/max/min dist for each bond type
   double *b_ave_all,*b_max_all,*b_min_all;   // MPI summing arrays
   int *a_count,*a_count_all;            // ditto for angle types
   double *a_ave,*a_max,*a_min;
   double *a_ave_all,*a_max_all,*a_min_all;
 
   void find_clusters();
   int masscheck(double);
   void unconstrained_update();
   void unconstrained_update_respa(int);
   void shake2(int);
   void shake3(int);
   void shake4(int);
   void shake3angle(int);
   void stats();
   int bondfind(int, int, int);
   int anglefind(int, int, int);
 };
 
 }
 
 #endif
 #endif
diff --git a/src/fix_tmd.cpp b/src/fix_tmd.cpp
index 1dd6bb383..f976fd18e 100644
--- a/src/fix_tmd.cpp
+++ b/src/fix_tmd.cpp
@@ -1,559 +1,561 @@
 /* ----------------------------------------------------------------------
    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: Paul Crozier (SNL)
                          Christian Burisch (Bochum Univeristy, Germany)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "fix_tmd.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "update.h"
 #include "modify.h"
 #include "domain.h"
 #include "group.h"
 #include "respa.h"
 #include "force.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define CHUNK 1000
 #define MAXLINE 256
 
 /* ---------------------------------------------------------------------- */
 
 FixTMD::FixTMD(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 6) error->all("Illegal fix tmd command");
 
   rho_stop = atof(arg[3]);
   nfileevery = atoi(arg[5]);
   if (rho_stop < 0 || nfileevery < 0) error->all("Illegal fix tmd command");
   if (nfileevery && narg != 7) error->all("Illegal fix tmd command");
 
   MPI_Comm_rank(world,&me);
 
   // perform initial allocation of atom-based arrays
   // register with Atom class
 
   xf = NULL;
   xold = NULL;
   grow_arrays(atom->nmax);
   atom->add_callback(0);
 
   // make sure an atom map exists before reading in target coordinates
 
   if (atom->map_style == 0) 
     error->all("Cannot use fix TMD unless atom map exists");
 
   // read from arg[4] and store coordinates of final target in xf
 
   readfile(arg[4]);
 
   // open arg[6] statistics file and write header
 
   if (nfileevery) {
     if (narg != 7) error->all("Illegal fix tmd command");
     if (me == 0) {
       fp = fopen(arg[6],"w");
       if (fp == NULL) {
 	char str[128];
 	sprintf(str,"Cannot open fix tmd file %s",arg[6]);
 	error->one(str);
       }
       fprintf(fp,"%s %s\n","# Step rho_target rho_old gamma_back",
 	      "gamma_forward lambda work_lambda work_analytical");
     }
   }
 
   masstotal = group->mass(igroup);
 
   // rho_start = initial rho
   // xold = initial x or 0.0 if not in group
 
   int *mask = atom->mask;
   int *type = atom->type;
   int *image = atom->image;
   double **x = atom->x;
   double *mass = atom->mass;
   int nlocal = atom->nlocal;
 
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
 
   double dx,dy,dz;
   int xbox,ybox,zbox;
   rho_start = 0.0;
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       dx = x[i][0] + xbox*xprd - xf[i][0];
       dy = x[i][1] + ybox*yprd - xf[i][1];
       dz = x[i][2] + zbox*zprd - xf[i][2];
       rho_start += mass[type[i]]*(dx*dx + dy*dy + dz*dz);
       xold[i][0] = x[i][0] + xbox*xprd;
       xold[i][1] = x[i][1] + ybox*yprd;
       xold[i][2] = x[i][2] + zbox*zprd;
     } else xold[i][0] = xold[i][1] = xold[i][2] = 0.0;
   }
 
   double rho_start_total;
   MPI_Allreduce(&rho_start,&rho_start_total,1,MPI_DOUBLE,MPI_SUM,world);
   rho_start = sqrt(rho_start_total/masstotal);
   rho_old = rho_start;
 
   work_lambda = 0.0;
   work_analytical = 0.0;
   previous_stat = 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixTMD::~FixTMD()
 {
   if (nfileevery && me == 0) fclose(fp);
 
   // unregister callbacks to this fix from Atom class
 
   atom->delete_callback(id,0);
 
   // delete locally stored arrays
 
   memory->destroy_2d_double_array(xf);
   memory->destroy_2d_double_array(xold);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixTMD::setmask()
 {
   int mask = 0;
   mask |= INITIAL_INTEGRATE;
   mask |= INITIAL_INTEGRATE_RESPA;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTMD::init()
 {
   // check that no integrator fix comes after a TMD fix
 
   int flag = 0;
   for (int i = 0; i < modify->nfix; i++) {
     if (strcmp(modify->fix[i]->style,"tmd") == 0) flag = 1;
     if (flag && strcmp(modify->fix[i]->style,"nve") == 0) flag = 2;
     if (flag && strcmp(modify->fix[i]->style,"nvt") == 0) flag = 2;
     if (flag && strcmp(modify->fix[i]->style,"npt") == 0) flag = 2;
     if (flag && strcmp(modify->fix[i]->style,"nph") == 0) flag = 2;
   }
   if (flag == 2) error->all("Fix tmd must come after integration fixes");
 
   // timesteps
 
   dtv = update->dt;
   dtf = update->dt * force->ftm2v;
   if (strcmp(update->integrate_style,"respa") == 0)
     step_respa = ((Respa *) update->integrate)->step;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTMD::initial_integrate(int vflag)
 {
   double a,b,c,d,e;
   double dx,dy,dz,dxkt,dykt,dzkt;
   double dxold,dyold,dzold,xback,yback,zback;
   double gamma_forward,gamma_back,gamma_max,lambda;
   double kt,fr,kttotal,frtotal,dtfm;
 
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
   double **x = atom->x;
   double **v = atom->v;
   double **f = atom->f;
   double *mass = atom->mass;
   int *image = atom->image;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   int xbox,ybox,zbox;
 
   double delta = update->ntimestep - update->beginstep;
   delta /= update->endstep - update->beginstep;
   double rho_target = rho_start + delta * (rho_stop - rho_start);
 
   // compute the Lagrange multiplier
 
   a = b = e = 0.0;
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
       dxold = xold[i][0] - xf[i][0];
       dyold = xold[i][1] - xf[i][1];
       dzold = xold[i][2] - xf[i][2];
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       dx = x[i][0] + xbox*xprd - xf[i][0];
       dy = x[i][1] + ybox*yprd - xf[i][1];
       dz = x[i][2] + zbox*zprd - xf[i][2];
       a += mass[type[i]]*(dxold*dxold + dyold*dyold + dzold*dzold);
       b += mass[type[i]]*(dx   *dxold + dy   *dyold + dz   *dzold);
       e += mass[type[i]]*(dx   *dx    + dy   *dy    + dz   *dz);
     }
   }
 
   double abe[3],abetotal[3];
   abe[0] = a;  abe[1] = b;  abe[2] = e;
   MPI_Allreduce(abe,abetotal,3,MPI_DOUBLE,MPI_SUM,world);
 
   a = abetotal[0]/masstotal;
   b = 2.0*abetotal[1]/masstotal;
   e = abetotal[2]/masstotal;
   c = e - rho_old*rho_old;
   d = b*b - 4*a*c;  
 
   if (d < 0) d = 0;
   if (b >= 0) gamma_max = (-b - sqrt(d))/(2*a);
   else        gamma_max = (-b + sqrt(d))/(2*a);
   gamma_back = c/(a*gamma_max);
   if (a == 0.0) gamma_back = 0;
 
   c = e - rho_target*rho_target;
   d = b*b - 4*a*c;  
   if (d < 0) d = 0;
   if (b >= 0) gamma_max = (-b - sqrt(d))/(2*a);
   else        gamma_max = (-b + sqrt(d))/(2*a);
   gamma_forward = c/(a*gamma_max);
   if (a == 0.0) gamma_forward = 0;
 
   fr = kt = 0.0;
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
       dxold = xold[i][0] - xf[i][0];
       dyold = xold[i][1] - xf[i][1];
       dzold = xold[i][2] - xf[i][2];
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       xback = x[i][0] + xbox*xprd + gamma_back*dxold;
       yback = x[i][1] + ybox*yprd + gamma_back*dyold;
       zback = x[i][2] + zbox*zprd + gamma_back*dzold;
       dxkt = xback - xold[i][0];
       dykt = yback - xold[i][1];
       dzkt = zback - xold[i][2];
       kt += mass[type[i]]*(dxkt*dxkt + dykt*dykt + dzkt*dzkt);
       fr += f[i][0]*dxold + f[i][1]*dyold + f[i][2]*dzold;
     }
   }
 
   double r[2],rtotal[2];
   r[0] = fr;  r[1] = kt;
   MPI_Allreduce(r,rtotal,2,MPI_DOUBLE,MPI_SUM,world);
   frtotal = rtotal[0];
   kttotal = rtotal[1];
 
   // stat write of mean constraint force based on previous time step constraint
 
   if (nfileevery && me == 0) {   
     work_analytical += 
       (-frtotal - kttotal/dtv/dtf)*(rho_target - rho_old)/rho_old;
     lambda = gamma_back*rho_old*masstotal/dtv/dtf;
     work_lambda += lambda*(rho_target - rho_old);
     if (!(update->ntimestep % nfileevery) && 
 	(previous_stat != update->ntimestep)) {
-      fprintf(fp,"%d %g %g %g %g %g %g %g\n",
-	      update->ntimestep,rho_target,rho_old,
+      char fstr[64];
+      sprintf(fstr,"%s %%g %%g %%g %%g %%g %%g %%g\n",BIGINT_FORMAT);
+      fprintf(fp,fstr,update->ntimestep,rho_target,rho_old,
               gamma_back,gamma_forward,lambda,work_lambda,work_analytical);
       fflush(fp);
       previous_stat = update->ntimestep;
     }
   }
   rho_old = rho_target;
 
   // apply the constraint and save constrained positions for next step
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
       dtfm = dtf / mass[type[i]];
       dxold = xold[i][0] - xf[i][0];
       x[i][0] += gamma_forward*dxold;
       v[i][0] += gamma_forward*dxold/dtv;
       f[i][0] += gamma_forward*dxold/dtv/dtfm;
       dyold = xold[i][1] - xf[i][1];
       x[i][1] += gamma_forward*dyold;
       v[i][1] += gamma_forward*dyold/dtv;
       f[i][1] += gamma_forward*dyold/dtv/dtfm;
       dzold = xold[i][2] - xf[i][2];
       x[i][2] += gamma_forward*dzold;
       v[i][2] += gamma_forward*dzold/dtv;
       f[i][2] += gamma_forward*dzold/dtv/dtfm;
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       xold[i][0] = x[i][0] + xbox*xprd;
       xold[i][1] = x[i][1] + ybox*yprd;
       xold[i][2] = x[i][2] + zbox*zprd;
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTMD::initial_integrate_respa(int vflag, int ilevel, int flag)
 {
   if (flag) return;             // only used by NPT,NPH
 
   dtv = step_respa[ilevel];
   dtf = step_respa[ilevel] * force->ftm2v;
 
   if (ilevel == 0) initial_integrate(vflag);
 }
 
 /* ----------------------------------------------------------------------
    memory usage of local atom-based arrays
 ------------------------------------------------------------------------- */
 
 double FixTMD::memory_usage()
 {
   double bytes = 2*atom->nmax*3 * sizeof(double);
   return bytes;
 }
 
 /* ----------------------------------------------------------------------
    allocate atom-based arrays
 ------------------------------------------------------------------------- */
 
 void FixTMD::grow_arrays(int nmax)
 {
   xf = memory->grow_2d_double_array(xf,nmax,3,"fix_tmd:xf");
   xold = memory->grow_2d_double_array(xold,nmax,3,"fix_tmd:xold");
 }
 
 /* ----------------------------------------------------------------------
    copy values within local atom-based arrays
 ------------------------------------------------------------------------- */
 
 void FixTMD::copy_arrays(int i, int j)
 {
   xf[j][0] = xf[i][0];
   xf[j][1] = xf[i][1];
   xf[j][2] = xf[i][2];
   xold[j][0] = xold[i][0];
   xold[j][1] = xold[i][1];
   xold[j][2] = xold[i][2];
 }
 
 /* ----------------------------------------------------------------------
    pack values in local atom-based arrays for exchange with another proc
 ------------------------------------------------------------------------- */
 
 int FixTMD::pack_exchange(int i, double *buf)
 {
   buf[0] = xf[i][0];
   buf[1] = xf[i][1];
   buf[2] = xf[i][2];
   buf[3] = xold[i][0];
   buf[4] = xold[i][1];
   buf[5] = xold[i][2];
   return 6;
 }
 
 /* ----------------------------------------------------------------------
    unpack values in local atom-based arrays from exchange with another proc
 ------------------------------------------------------------------------- */
 
 int FixTMD::unpack_exchange(int nlocal, double *buf)
 {
   xf[nlocal][0] = buf[0];
   xf[nlocal][1] = buf[1];
   xf[nlocal][2] = buf[2];
   xold[nlocal][0] = buf[3];
   xold[nlocal][1] = buf[4];
   xold[nlocal][2] = buf[5];
   return 6;
 }
 
 /* ----------------------------------------------------------------------
    read target coordinates from file, store with appropriate atom
 ------------------------------------------------------------------------- */
 
 void FixTMD::readfile(char *file)
 {
   if (me == 0) {
     if (screen) fprintf(screen,"Reading TMD target file %s ...\n",file);
     open(file);
   }
 
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   char *buffer = new char[CHUNK*MAXLINE];
   char *ptr,*next,*bufptr;
   int i,m,nlines,tag,imageflag,ix,iy,iz;
   double x,y,z,xprd,yprd,zprd;
 
   int firstline = 1;
   int ncount = 0;
   int eof = 0;
   xprd = yprd = zprd = -1.0;
 
   while (!eof) {
     if (me == 0) {
       m = 0;
       for (nlines = 0; nlines < CHUNK; nlines++) {
 	ptr = fgets(&buffer[m],MAXLINE,fp);
 	if (ptr == NULL) break;
 	m += strlen(&buffer[m]);
       }
       if (ptr == NULL) eof = 1;
       buffer[m++] = '\n';
     }
 
     MPI_Bcast(&eof,1,MPI_INT,0,world);
     MPI_Bcast(&nlines,1,MPI_INT,0,world);
     MPI_Bcast(&m,1,MPI_INT,0,world);
     MPI_Bcast(buffer,m,MPI_CHAR,0,world);
 
     bufptr = buffer;
     for (i = 0; i < nlines; i++) {
       next = strchr(bufptr,'\n');
       *next = '\0';
 
       if (firstline) {
 	if (strstr(bufptr,"xlo xhi")) {
 	  double lo,hi;
 	  sscanf(bufptr,"%lg %lg",&lo,&hi);
 	  xprd = hi - lo;
 	  bufptr = next + 1;
 	  continue;
 	} else if (strstr(bufptr,"ylo yhi")) {
 	  double lo,hi;
 	  sscanf(bufptr,"%lg %lg",&lo,&hi);
 	  yprd = hi - lo;
 	  bufptr = next + 1;
 	  continue;
 	} else if (strstr(bufptr,"zlo zhi")) {
 	  double lo,hi;
 	  sscanf(bufptr,"%lg %lg",&lo,&hi);
 	  zprd = hi - lo;
 	  bufptr = next + 1;
 	  continue;
 	} else if (atom->count_words(bufptr) == 4) {
 	  if (xprd >= 0.0 || yprd >= 0.0 || zprd >= 0.0) 
 	    error->all("Incorrect format in TMD target file");
 	  imageflag = 0;
 	  firstline = 0;
 	} else if (atom->count_words(bufptr) == 7) {
 	  if (xprd < 0.0 || yprd < 0.0 || zprd < 0.0) 
 	    error->all("Incorrect format in TMD target file");
 	  imageflag = 1;
 	  firstline = 0;
 	} else error->all("Incorrect format in TMD target file");
       }
 
       if (imageflag)
 	sscanf(bufptr,"%d %lg %lg %lg %d %d %d",&tag,&x,&y,&z,&ix,&iy,&iz);
       else
 	sscanf(bufptr,"%d %lg %lg %lg",&tag,&x,&y,&z);
 
       m = atom->map(tag);
       if (m >= 0 && m < nlocal && mask[m] & groupbit) {
 	if (imageflag) {
 	  xf[m][0] = x + ix*xprd;
 	  xf[m][1] = y + iy*yprd;
 	  xf[m][2] = z + iz*zprd;
 	} else {
 	  xf[m][0] = x;
 	  xf[m][1] = y;
 	  xf[m][2] = z;
 	}
 	ncount++;
       }
 
       bufptr = next + 1;
     }
   }
 
   // clean up
 
   delete [] buffer;
 
   if (me == 0) {
     if (compressed) pclose(fp);
     else fclose(fp);
   }
 
   // check that all atoms in group were listed in target file
   // set xf = 0.0 for atoms not in group
 
   int gcount = 0;
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) gcount++;
     else xf[i][0] = xf[i][1] = xf[i][2] = 0.0;
 
   int flag = 0;
   if (gcount != ncount) flag = 1;
 
   int flagall;
   MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
   if (flagall) error->all("TMD target file did not list all group atoms");
 }
 
 /* ----------------------------------------------------------------------
    proc 0 opens TMD data file
    test if gzipped
 ------------------------------------------------------------------------- */
 
 void FixTMD::open(char *file)
 {
   compressed = 0;
   char *suffix = file + strlen(file) - 3;
   if (suffix > file && strcmp(suffix,".gz") == 0) compressed = 1;
   if (!compressed) fp = fopen(file,"r");
   else {
 #ifdef LAMMPS_GZIP
     char gunzip[128];
     sprintf(gunzip,"gunzip -c %s",file);
     fp = popen(gunzip,"r");
 #else
     error->one("Cannot open gzipped file");
 #endif
   }
 
   if (fp == NULL) {
     char str[128];
     sprintf(str,"Cannot open file %s",file);
     error->one(str);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTMD::reset_dt()
 {
   dtv = update->dt;
   dtf = update->dt * force->ftm2v;
 }
diff --git a/src/fix_tmd.h b/src/fix_tmd.h
index 785bae60c..ee4a723d8 100644
--- a/src/fix_tmd.h
+++ b/src/fix_tmd.h
@@ -1,61 +1,62 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifdef FIX_CLASS
 
 FixStyle(tmd,FixTMD)
 
 #else
 
 #ifndef LMP_FIX_TMD_H
 #define LMP_FIX_TMD_H
 
 #include "stdio.h"
 #include "fix.h"
 
 namespace LAMMPS_NS {
 
 class FixTMD : public Fix {
  public:
   FixTMD(class LAMMPS *, int, char **);
   ~FixTMD();
   int setmask();
   void init();
   void initial_integrate(int);
   void initial_integrate_respa(int, int, int);
 
   double memory_usage();
   void grow_arrays(int);
   void copy_arrays(int, int);
   int pack_exchange(int, double *);
   int unpack_exchange(int, double *);
   void reset_dt();
 
  private:
   int me;
-  int nfileevery,previous_stat,compressed;
+  int nfileevery,compressed;
+  bigint previous_stat;
   FILE *fp;
   double rho_start,rho_stop,rho_old,masstotal;
   double dtv,dtf;
   double *step_respa;
   double work_lambda,work_analytical;
   double **xf,**xold;
 
   void readfile(char *);
   void open(char *);
 };
 
 }
 
 #endif
 #endif
diff --git a/src/fix_ttm.cpp b/src/fix_ttm.cpp
index 0cc1a191f..4edfba1bb 100644
--- a/src/fix_ttm.cpp
+++ b/src/fix_ttm.cpp
@@ -1,698 +1,699 @@
 /* ----------------------------------------------------------------------
    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: Paul Crozier (SNL)
                          Carolyn Phillips (University of Michigan)
 ------------------------------------------------------------------------- */
 
 #include "mpi.h"
 #include "math.h"
 #include "string.h"
 #include "stdlib.h"
 #include "fix_ttm.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "force.h"
 #include "update.h"
 #include "domain.h"
 #include "region.h"
 #include "respa.h"
 #include "comm.h"
 #include "random_mars.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define MAXLINE 1024
 
 /* ---------------------------------------------------------------------- */
 
 FixTTM::FixTTM(LAMMPS *lmp, int narg, char **arg) :
   Fix(lmp, narg, arg)
 {
   if (narg < 15) error->all("Illegal fix ttm command");
 
   vector_flag = 1;
   size_vector = 2;
   global_freq = 1;
   extvector = 1;
   nevery = 1;
   restart_peratom = 1;
   restart_global = 1;
 
   seed = atoi(arg[3]);
   electronic_specific_heat = atof(arg[4]);
   electronic_density = atof(arg[5]);
   electronic_thermal_conductivity = atof(arg[6]);
   gamma_p = atof(arg[7]);
   gamma_s = atof(arg[8]);
   v_0 = atof(arg[9]);
   nxnodes = atoi(arg[10]);
   nynodes = atoi(arg[11]);
   nznodes = atoi(arg[12]);
 
   fpr = fopen(arg[13],"r");
   if (fpr == NULL) {
     char str[128];
     sprintf(str,"Cannot open file %s",arg[13]);
     error->one(str);
   }
 
   nfileevery = atoi(arg[14]);
 
   if (nfileevery) {
     if (narg != 16) error->all("Illegal fix ttm command");
     MPI_Comm_rank(world,&me);
     if (me == 0) {
       fp = fopen(arg[15],"w");
       if (fp == NULL) {
         char str[128];
         sprintf(str,"Cannot open fix ttm file %s",arg[15]);
         error->one(str);
       }
     }
   }
 
   // error check
 
   if (seed <= 0) error->all("Invalid random number seed in fix ttm command");
   if (electronic_specific_heat <= 0.0) 
     error->all("Fix ttm electronic_specific_heat must be > 0.0");
   if (electronic_density <= 0.0) 
     error->all("Fix ttm electronic_density must be > 0.0");
   if (electronic_thermal_conductivity < 0.0)
     error->all("Fix ttm electronic_thermal_conductivity must be >= 0.0");
   if (gamma_p <= 0.0) error->all("Fix ttm gamma_p must be > 0.0");
   if (gamma_s < 0.0) error->all("Fix ttm gamma_s must be >= 0.0");
   if (v_0 < 0.0) error->all("Fix ttm v_0 must be >= 0.0");
   if (nxnodes <= 0 || nynodes <= 0 || nznodes <= 0)
     error->all("Fix ttm number of nodes must be > 0");
 
   v_0_sq = v_0*v_0;
 
   // initialize Marsaglia RNG with processor-unique seed
 
   random = new RanMars(lmp,seed + comm->me);
 
   // allocate per-type arrays for force prefactors
 
   gfactor1 = new double[atom->ntypes+1];
   gfactor2 = new double[atom->ntypes+1];
 
   // allocate 3d grid variables
 
   total_nnodes = nxnodes*nynodes*nznodes;
 
   nsum = memory->create_3d_int_array(nxnodes,nynodes,nznodes,"ttm:nsum");
   nsum_all = memory->create_3d_int_array(nxnodes,nynodes,nznodes,
                                          "ttm:nsum_all");
   T_initial_set = memory->create_3d_int_array(nxnodes,nynodes,nznodes,
                                               "ttm:T_initial_set");
   sum_vsq = memory->create_3d_double_array(nxnodes,nynodes,nznodes,
                                            "ttm:sum_vsq");
   sum_mass_vsq = 
     memory->create_3d_double_array(nxnodes,nynodes,nznodes,
                                    "ttm:sum_mass_vsq");
   sum_vsq_all = memory->create_3d_double_array(nxnodes,nynodes,nznodes,
                                                "ttm:sum_vsq_all");
   sum_mass_vsq_all = 
     memory->create_3d_double_array(nxnodes,nynodes,nznodes,
                                    "ttm:sum_mass_vsq_all");
   T_electron_old = 
     memory->create_3d_double_array(nxnodes,nynodes,nznodes,
                                    "ttm:T_electron_old");
   T_electron = 
     memory->create_3d_double_array(nxnodes,nynodes,nznodes,"ttm:T_electron");
   net_energy_transfer = 
     memory->create_3d_double_array(nxnodes,nynodes,nznodes,
                                         "TTM:net_energy_transfer");
   net_energy_transfer_all = 
     memory->create_3d_double_array(nxnodes,nynodes,nznodes,
                                         "TTM:net_energy_transfer_all");
  
   flangevin = NULL;
   grow_arrays(atom->nmax);
 
   // zero out the flangevin array
 
   for (int i = 0; i < atom->nmax; i++) {
     flangevin[i][0] = 0;
     flangevin[i][1] = 0;
     flangevin[i][2] = 0;
   }
 
   atom->add_callback(0);
   atom->add_callback(1);
 
   // set initial electron temperatures from user input file
 
   if (me == 0) read_initial_electron_temperatures();
   MPI_Bcast(&T_electron[0][0][0],total_nnodes,MPI_DOUBLE,0,world);
 }
 
 /* ---------------------------------------------------------------------- */
 
 FixTTM::~FixTTM()
 {
   if (nfileevery && me == 0) fclose(fp);
 
   delete random;
 
   delete [] gfactor1;
   delete [] gfactor2;
 
   memory->destroy_3d_int_array(nsum);
   memory->destroy_3d_int_array(nsum_all);
   memory->destroy_3d_int_array(T_initial_set);
   memory->destroy_3d_double_array(sum_vsq);
   memory->destroy_3d_double_array(sum_mass_vsq);
   memory->destroy_3d_double_array(sum_vsq_all);
   memory->destroy_3d_double_array(sum_mass_vsq_all);
   memory->destroy_3d_double_array(T_electron_old);
   memory->destroy_3d_double_array(T_electron);
   memory->destroy_2d_double_array(flangevin);
   memory->destroy_3d_double_array(net_energy_transfer);
   memory->destroy_3d_double_array(net_energy_transfer_all); 
 }
 
 /* ---------------------------------------------------------------------- */
 
 int FixTTM::setmask()
 {
   int mask = 0;
   mask |= POST_FORCE;
   mask |= POST_FORCE_RESPA;
   mask |= END_OF_STEP;
   return mask;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTTM::init()
 {
   if (domain->dimension == 2)
     error->all("Cannot use fix ttm with 2d simulation");
   if (domain->nonperiodic != 0)
     error->all("Cannot use nonperiodic boundares with fix ttm");
   if (domain->triclinic)
     error->all("Cannot use fix ttm with triclinic box");
 
   // set force prefactors
 
   for (int i = 1; i <= atom->ntypes; i++) {
     gfactor1[i] = - gamma_p / force->ftm2v;
     gfactor2[i] = 
       sqrt(24.0*force->boltz*gamma_p/update->dt/force->mvv2e) / force->ftm2v;
   }
 
   for (int ixnode = 0; ixnode < nxnodes; ixnode++)
     for (int iynode = 0; iynode < nynodes; iynode++)
       for (int iznode = 0; iznode < nznodes; iznode++)
         net_energy_transfer_all[ixnode][iynode][iznode] = 0;
 
   if (strcmp(update->integrate_style,"respa") == 0)
     nlevels_respa = ((Respa *) update->integrate)->nlevels;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTTM::setup(int vflag)
 {
   if (strcmp(update->integrate_style,"verlet") == 0)
     post_force_setup(vflag);
   else {
     ((Respa *) update->integrate)->copy_flevel_f(nlevels_respa-1);
     post_force_respa_setup(vflag,nlevels_respa-1,0);
     ((Respa *) update->integrate)->copy_f_flevel(nlevels_respa-1);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTTM::post_force(int vflag)
 {
   double **x = atom->x;
   double **v = atom->v;
   double **f = atom->f;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   double gamma1,gamma2;
 
   // apply damping and thermostat to all atoms in fix group
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
 
       double xscale = (x[i][0] - domain->boxlo[0])/domain->xprd;
       double yscale = (x[i][1] - domain->boxlo[1])/domain->yprd;
       double zscale = (x[i][2] - domain->boxlo[2])/domain->zprd;
       int ixnode = static_cast<int>(xscale*nxnodes);
       int iynode = static_cast<int>(yscale*nynodes);
       int iznode = static_cast<int>(zscale*nznodes);
       while (ixnode > nxnodes-1) ixnode -= nxnodes;
       while (iynode > nynodes-1) iynode -= nynodes;
       while (iznode > nznodes-1) iznode -= nznodes;
       while (ixnode < 0) ixnode += nxnodes;
       while (iynode < 0) iynode += nynodes;
       while (iznode < 0) iznode += nznodes;
 
       if (T_electron[ixnode][iynode][iznode] < 0) 
         error->all("Electronic temperature dropped below zero");
 
       double tsqrt = sqrt(T_electron[ixnode][iynode][iznode]);
 
       gamma1 = gfactor1[type[i]];
       double vsq = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2];
       if (vsq > v_0_sq) gamma1 *= (gamma_p + gamma_s)/gamma_p;
       gamma2 = gfactor2[type[i]] * tsqrt;
 
       flangevin[i][0] = gamma1*v[i][0] + gamma2*(random->uniform()-0.5);
       flangevin[i][1] = gamma1*v[i][1] + gamma2*(random->uniform()-0.5);
       flangevin[i][2] = gamma1*v[i][2] + gamma2*(random->uniform()-0.5);
 
       f[i][0] += flangevin[i][0];
       f[i][1] += flangevin[i][1];
       f[i][2] += flangevin[i][2];
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTTM::post_force_setup(int vflag)
 {
   double **f = atom->f;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   // apply langevin forces that have been stored from previous run
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
       f[i][0] += flangevin[i][0];
       f[i][1] += flangevin[i][1];
       f[i][2] += flangevin[i][2];
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTTM::post_force_respa(int vflag, int ilevel, int iloop)
 {
   if (ilevel == nlevels_respa-1) post_force(vflag);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTTM::post_force_respa_setup(int vflag, int ilevel, int iloop)
 {
   if (ilevel == nlevels_respa-1) post_force_setup(vflag);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTTM::reset_dt()
 {
   for (int i = 1; i <= atom->ntypes; i++)
     gfactor2[i] = 
       sqrt(24.0*force->boltz*gamma_p/update->dt/force->mvv2e) / force->ftm2v;
 }
 
 /* ----------------------------------------------------------------------
    read in initial electron temperatures from a user-specified file
    only called by proc 0
 ------------------------------------------------------------------------- */
 
 void FixTTM::read_initial_electron_temperatures()
 {
   char line[MAXLINE];
 
   for (int ixnode = 0; ixnode < nxnodes; ixnode++)
     for (int iynode = 0; iynode < nynodes; iynode++)
       for (int iznode = 0; iznode < nznodes; iznode++)
         T_initial_set[ixnode][iynode][iznode] = 0;
 
   // read initial electron temperature values from file
 
   int ixnode,iynode,iznode;
   double T_tmp;
   while (1) {
     if (fgets(line,MAXLINE,fpr) == NULL) break;
     sscanf(line,"%d %d %d %lg",&ixnode,&iynode,&iznode,&T_tmp);
     if (T_tmp < 0.0) error->one("Fix ttm electron temperatures must be > 0.0");
     T_electron[ixnode][iynode][iznode] = T_tmp;
     T_initial_set[ixnode][iynode][iznode] = 1;
   }
 
   for (int ixnode = 0; ixnode < nxnodes; ixnode++)
     for (int iynode = 0; iynode < nynodes; iynode++)
       for (int iznode = 0; iznode < nznodes; iznode++)
         if (T_initial_set[ixnode][iynode][iznode] == 0)
           error->one("Initial temperatures not all set in fix ttm");
 
   // close file
 
   fclose(fpr);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTTM::end_of_step()
 {
   double **x = atom->x;
   double **v = atom->v;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
  
   for (int ixnode = 0; ixnode < nxnodes; ixnode++)
     for (int iynode = 0; iynode < nynodes; iynode++)
       for (int iznode = 0; iznode < nznodes; iznode++)
         net_energy_transfer[ixnode][iynode][iznode] = 0;
       
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       double xscale = (x[i][0] - domain->boxlo[0])/domain->xprd;
       double yscale = (x[i][1] - domain->boxlo[1])/domain->yprd;
       double zscale = (x[i][2] - domain->boxlo[2])/domain->zprd;
       int ixnode = static_cast<int>(xscale*nxnodes);
       int iynode = static_cast<int>(yscale*nynodes);
       int iznode = static_cast<int>(zscale*nznodes);
       while (ixnode > nxnodes-1) ixnode -= nxnodes;
       while (iynode > nynodes-1) iynode -= nynodes;
       while (iznode > nznodes-1) iznode -= nznodes;
       while (ixnode < 0) ixnode += nxnodes;
       while (iynode < 0) iynode += nynodes;
       while (iznode < 0) iznode += nznodes;
       net_energy_transfer[ixnode][iynode][iznode] += 
 	(flangevin[i][0]*v[i][0] + flangevin[i][1]*v[i][1] + 
 	 flangevin[i][2]*v[i][2]);
     }
   
   MPI_Allreduce(&net_energy_transfer[0][0][0],
 		&net_energy_transfer_all[0][0][0],
 		total_nnodes,MPI_DOUBLE,MPI_SUM,world);
 
   double dx = domain->xprd/nxnodes;
   double dy = domain->yprd/nynodes;
   double dz = domain->zprd/nznodes;
   double del_vol = dx*dy*dz;
 
   // num_inner_timesteps = # of inner steps (thermal solves)
   // required this MD step to maintain a stable explicit solve
 
   int num_inner_timesteps = 1;
   double inner_dt = update->dt;
   double stability_criterion = 1.0 - 
     2.0*inner_dt/(electronic_specific_heat*electronic_density) * 
     (electronic_thermal_conductivity*(1.0/dx/dx + 1.0/dy/dy + 1.0/dz/dz));
   if (stability_criterion < 0.0) {
     inner_dt = 0.5*(electronic_specific_heat*electronic_density) / 
       (electronic_thermal_conductivity*(1.0/dx/dx + 1.0/dy/dy + 1.0/dz/dz));
     num_inner_timesteps = static_cast<int>(update->dt/inner_dt) + 1;
     inner_dt = update->dt/double(num_inner_timesteps);
     if (num_inner_timesteps > 1000000) 
       error->warning("Too many inner timesteps in fix ttm",0);
   }
 
   for (int ith_inner_timestep = 0; ith_inner_timestep < num_inner_timesteps; 
        ith_inner_timestep++) {
 
     for (int ixnode = 0; ixnode < nxnodes; ixnode++)
       for (int iynode = 0; iynode < nynodes; iynode++)
         for (int iznode = 0; iznode < nznodes; iznode++)
           T_electron_old[ixnode][iynode][iznode] =
             T_electron[ixnode][iynode][iznode];
     
     // compute new electron T profile
 
     for (int ixnode = 0; ixnode < nxnodes; ixnode++)
       for (int iynode = 0; iynode < nynodes; iynode++)
         for (int iznode = 0; iznode < nznodes; iznode++) {
           int right_xnode = ixnode + 1;
           int right_ynode = iynode + 1;
           int right_znode = iznode + 1;
           if (right_xnode == nxnodes) right_xnode = 0;
           if (right_ynode == nynodes) right_ynode = 0;
           if (right_znode == nznodes) right_znode = 0;
           int left_xnode = ixnode - 1;
           int left_ynode = iynode - 1;
           int left_znode = iznode - 1;
           if (left_xnode == -1) left_xnode = nxnodes - 1;
           if (left_ynode == -1) left_ynode = nynodes - 1;
           if (left_znode == -1) left_znode = nznodes - 1;
           T_electron[ixnode][iynode][iznode] = 
             T_electron_old[ixnode][iynode][iznode] + 
             inner_dt/(electronic_specific_heat*electronic_density) * 
             (electronic_thermal_conductivity *
              ((T_electron_old[right_xnode][iynode][iznode] + 
                T_electron_old[left_xnode][iynode][iznode] - 
                2*T_electron_old[ixnode][iynode][iznode])/dx/dx +
               (T_electron_old[ixnode][right_ynode][iznode] + 
                T_electron_old[ixnode][left_ynode][iznode] - 
                2*T_electron_old[ixnode][iynode][iznode])/dy/dy +
               (T_electron_old[ixnode][iynode][right_znode] + 
                T_electron_old[ixnode][iynode][left_znode] - 
                2*T_electron_old[ixnode][iynode][iznode])/dz/dz) -
               (net_energy_transfer_all[ixnode][iynode][iznode])/del_vol);   
         }
   }
 
   // output nodal temperatures for current timestep
 
   if ((nfileevery) && !(update->ntimestep % nfileevery)) { 
 
     // compute atomic Ta for each grid point
   
     for (int ixnode = 0; ixnode < nxnodes; ixnode++)
       for (int iynode = 0; iynode < nynodes; iynode++)
         for (int iznode = 0; iznode < nznodes; iznode++) {
           nsum[ixnode][iynode][iznode] = 0;
           nsum_all[ixnode][iynode][iznode] = 0;
           sum_vsq[ixnode][iynode][iznode] = 0.0; 
           sum_mass_vsq[ixnode][iynode][iznode] = 0.0;
           sum_vsq_all[ixnode][iynode][iznode] = 0.0;
           sum_mass_vsq_all[ixnode][iynode][iznode] = 0.0;
         } 
 
     double massone;  
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
         if (rmass) massone = rmass[i];
         else massone = mass[type[i]];
         double xscale = (x[i][0] - domain->boxlo[0])/domain->xprd;
         double yscale = (x[i][1] - domain->boxlo[1])/domain->yprd;
         double zscale = (x[i][2] - domain->boxlo[2])/domain->zprd;
         int ixnode = static_cast<int>(xscale*nxnodes);
         int iynode = static_cast<int>(yscale*nynodes);
         int iznode = static_cast<int>(zscale*nznodes);
         while (ixnode > nxnodes-1) ixnode -= nxnodes;
         while (iynode > nynodes-1) iynode -= nynodes;
         while (iznode > nznodes-1) iznode -= nznodes;
         while (ixnode < 0) ixnode += nxnodes;
         while (iynode < 0) iynode += nynodes;
         while (iznode < 0) iznode += nznodes;
         double vsq = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2];
         nsum[ixnode][iynode][iznode] += 1;
         sum_vsq[ixnode][iynode][iznode] += vsq;
         sum_mass_vsq[ixnode][iynode][iznode] += massone*vsq;
       }
   
     MPI_Allreduce(&nsum[0][0][0],&nsum_all[0][0][0],total_nnodes,
                   MPI_INT,MPI_SUM,world);
     MPI_Allreduce(&sum_vsq[0][0][0],&sum_vsq_all[0][0][0],total_nnodes,
                   MPI_DOUBLE,MPI_SUM,world);
     MPI_Allreduce(&sum_mass_vsq[0][0][0],&sum_mass_vsq_all[0][0][0],
                   total_nnodes,MPI_DOUBLE,MPI_SUM,world);
   
     if (me == 0) {
-      fprintf(fp,"%d ",update->ntimestep);
+      fprintf(fp,BIGINT_FORMAT,update->ntimestep);
 
       double T_a;
       for (int ixnode = 0; ixnode < nxnodes; ixnode++)
         for (int iynode = 0; iynode < nynodes; iynode++)
           for (int iznode = 0; iznode < nznodes; iznode++) {
             T_a = 0;
             if (nsum_all[ixnode][iynode][iznode] > 0)
               T_a = sum_mass_vsq_all[ixnode][iynode][iznode]/
                 (3.0*force->boltz*nsum_all[ixnode][iynode][iznode]/force->mvv2e);
-            fprintf(fp,"%f ",T_a);
+            fprintf(fp," %f",T_a);
           }
             
       fprintf(fp,"\t");
       for (int ixnode = 0; ixnode < nxnodes; ixnode++)
         for (int iynode = 0; iynode < nynodes; iynode++)
           for (int iznode = 0; iznode < nznodes; iznode++)
             fprintf(fp,"%f ",T_electron[ixnode][iynode][iznode]);
       fprintf(fp,"\n");
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    memory usage of 3d grid
 ------------------------------------------------------------------------- */
 
 double FixTTM::memory_usage()
 {
   double bytes = 0.0;
   bytes += 5*total_nnodes * sizeof(int);
   bytes += 14*total_nnodes * sizeof(double);
   return bytes;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void FixTTM::grow_arrays(int ngrow) 
 {
 
  flangevin = memory->grow_2d_double_array(flangevin,ngrow,3,"TTM:flangevin");  
 
 }
 
 /* ----------------------------------------------------------------------
   return the energy of the electronic subsystem or the net_energy transfer
    between the subsystems
 ------------------------------------------------------------------------- */
 
 double FixTTM::compute_vector(int n)
 {
   double e_energy = 0.0;
   double transfer_energy = 0.0;
 
   double dx = domain->xprd/nxnodes;
   double dy = domain->yprd/nynodes;
   double dz = domain->zprd/nznodes;
   double del_vol = dx*dy*dz;
 
   for (int ixnode = 0; ixnode < nxnodes; ixnode++)
     for (int iynode = 0; iynode < nynodes; iynode++)
       for (int iznode = 0; iznode < nznodes; iznode++) {
         e_energy += 
 	  T_electron[ixnode][iynode][iznode]*electronic_specific_heat* 
 	  electronic_density*del_vol;
         transfer_energy += 
 	  net_energy_transfer_all[ixnode][iynode][iznode]*update->dt;
   }
 
   if (n == 0) return e_energy;
   if (n == 1) return transfer_energy;
   return 0.0;
 }
 
 /* ----------------------------------------------------------------------
    pack entire state of Fix into one write 
 ------------------------------------------------------------------------- */
 
 void FixTTM::write_restart(FILE *fp)
 {
   double *rlist = (double *) 
     memory->smalloc((1+nxnodes*nynodes*nznodes)*sizeof(double),"TTM:rlist");
 
   int n = 0;
   rlist[n++] = seed;
  
   for (int ixnode = 0; ixnode < nxnodes; ixnode++)
     for (int iynode = 0; iynode < nynodes; iynode++)
       for (int iznode = 0; iznode < nznodes; iznode++)
         rlist[n++] =  T_electron[ixnode][iynode][iznode];
   
   if (comm->me == 0) {
     int size = n * sizeof(double);
     fwrite(&size,sizeof(int),1,fp);
     fwrite(rlist,sizeof(double),n,fp);
   }
 
   memory->sfree(rlist);
 }
 
 /* ----------------------------------------------------------------------
    use state info from restart file to restart the Fix 
 ------------------------------------------------------------------------- */
 
 void FixTTM::restart(char *buf)
 {
   int n = 0;
   double *rlist = (double *) buf;
   
   // the seed must be changed from the initial seed
 
   seed = static_cast<int> (0.5*rlist[n++]);
   
   for (int ixnode = 0; ixnode < nxnodes; ixnode++)
     for (int iynode = 0; iynode < nynodes; iynode++)
       for (int iznode = 0; iznode < nznodes; iznode++)
         T_electron[ixnode][iynode][iznode] = rlist[n++];
   
   delete random;
   random = new RanMars(lmp,seed+comm->me);
 }
 
 /* ----------------------------------------------------------------------
    pack values in local atom-based arrays for restart file
 ------------------------------------------------------------------------- */
 
 int FixTTM::pack_restart(int i, double *buf)
 {
   buf[0] = 4;
   buf[1] = flangevin[i][0];
   buf[2] = flangevin[i][1];
   buf[3] = flangevin[i][2];
   return 4;
 }
 
 /* ----------------------------------------------------------------------
    unpack values from atom->extra array to restart the fix
 ------------------------------------------------------------------------- */
 
 void FixTTM::unpack_restart(int nlocal, int nth)
 {
   double **extra = atom->extra;
 
   // skip to Nth set of extra values
 
   int m = 0;
   for (int i = 0; i < nth; i++) m += static_cast<int> (extra[nlocal][m]);
   m++;
 
   flangevin[nlocal][0] = extra[nlocal][m++];
   flangevin[nlocal][1] = extra[nlocal][m++];
   flangevin[nlocal][2] = extra[nlocal][m++];
 }
 
 /* ----------------------------------------------------------------------
    maxsize of any atom's restart data
 ------------------------------------------------------------------------- */
 
 int FixTTM::maxsize_restart()
 {
   return 4;
 }
 
 /* ----------------------------------------------------------------------
    size of atom nlocal's restart data
 ------------------------------------------------------------------------- */
 
 int FixTTM::size_restart(int nlocal)
 {
   return 4;
 }
diff --git a/src/group.cpp b/src/group.cpp
index b2ee3c4af..79a526b5b 100644
--- a/src/group.cpp
+++ b/src/group.cpp
@@ -1,1469 +1,1469 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "mpi.h"
 #include "stdio.h"
 #include "string.h"
 #include "stdlib.h"
 #include "group.h"
 #include "lmptype.h"
 #include "domain.h"
 #include "atom.h"
 #include "force.h"
 #include "region.h"
 #include "modify.h"
 #include "fix.h"
 #include "compute.h"
 #include "output.h"
 #include "dump.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MAX_GROUP 32
 
 enum{TYPE,MOLECULE,ID};
 enum{LT,LE,GT,GE,EQ,NEQ,BETWEEN};
 
 #define BIG 1.0e20
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 /* ----------------------------------------------------------------------
    initialize group memory
 ------------------------------------------------------------------------- */
 
 Group::Group(LAMMPS *lmp) : Pointers(lmp)
 {
   MPI_Comm_rank(world,&me);
 
   names = new char*[MAX_GROUP];
   bitmask = new int[MAX_GROUP];
   inversemask = new int[MAX_GROUP];
 
   for (int i = 0; i < MAX_GROUP; i++) names[i] = NULL;
   for (int i = 0; i < MAX_GROUP; i++) bitmask[i] = 1 << i;
   for (int i = 0; i < MAX_GROUP; i++) inversemask[i] = bitmask[i] ^ ~0;
 
   // create "all" group
 
   char *str = (char *) "all";
   int n = strlen(str) + 1;
   names[0] = new char[n];
   strcpy(names[0],str);
   ngroup = 1;
 }
 
 /* ----------------------------------------------------------------------
    free all memory
 ------------------------------------------------------------------------- */
 
 Group::~Group()
 {
   for (int i = 0; i < MAX_GROUP; i++) delete [] names[i];
   delete [] names;
   delete [] bitmask;
   delete [] inversemask;
 }
 
 /* ----------------------------------------------------------------------
    assign atoms to a new or existing group
 ------------------------------------------------------------------------- */
 
 void Group::assign(int narg, char **arg)
 {
   int i;
 
   if (domain->box_exist == 0) 
     error->all("Group command before simulation box is defined");
   if (narg < 2) error->all("Illegal group command");
 
   // delete the group if not being used elsewhere
   // clear mask of each atom assigned to this group
 
   if (strcmp(arg[1],"delete") == 0) {
     int igroup = find(arg[0]);
     if (igroup == -1) error->all("Could not find group delete group ID");
     if (igroup == 0) error->all("Cannot delete group all");
     for (i = 0; i < modify->nfix; i++)
       if (modify->fix[i]->igroup == igroup)
 	error->all("Cannot delete group currently used by a fix");
     for (i = 0; i < modify->ncompute; i++)
       if (modify->compute[i]->igroup == igroup)
 	error->all("Cannot delete group currently used by a compute");
     for (i = 0; i < output->ndump; i++)
       if (output->dump[i]->igroup == igroup)
 	error->all("Cannot delete group currently used by a dump");
     if (atom->firstgroupname && strcmp(arg[0],atom->firstgroupname) == 0)
       error->all("Cannot delete group currently used by atom_modify first");
 
     int *mask = atom->mask;
     int nlocal = atom->nlocal;
     int bits = inversemask[igroup];
     for (i = 0; i < nlocal; i++) mask[i] &= bits;
 
     delete [] names[igroup];
     names[igroup] = NULL;
     ngroup--;
 
     return;
   }
 
   // find group in existing list
   // add a new group if igroup = -1
 
   int igroup = find(arg[0]);
 
   if (igroup == -1) {
     if (ngroup == MAX_GROUP) error->all("Too many groups");
     igroup = find_unused();
     int n = strlen(arg[0]) + 1;
     names[igroup] = new char[n];
     strcpy(names[igroup],arg[0]);
     ngroup++;
   }
 
   double **x = atom->x;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   int bit = bitmask[igroup];
     
   // style = region
   // add to group if atom is in region
 
   if (strcmp(arg[1],"region") == 0) {
 
     if (narg != 3) error->all("Illegal group command");
     
     int iregion = domain->find_region(arg[2]);
     if (iregion == -1) error->all("Group region ID does not exist");
 
     for (i = 0; i < nlocal; i++)
       if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
 	mask[i] |= bit;
 
   // style = logical condition
 
   } else if (narg >= 3 && 
 	     (strcmp(arg[2],"<") == 0 || strcmp(arg[2],">") == 0 || 
 	      strcmp(arg[2],"<=") == 0 || strcmp(arg[2],">=") == 0 || 
 	      strcmp(arg[2],"<>") == 0)) {
 
     if (narg < 4 || narg > 5) error->all("Illegal group command");
     int category,condition,bound1,bound2;
 
     if (strcmp(arg[1],"type") == 0) category = TYPE;
     else if (strcmp(arg[1],"molecule") == 0) category = MOLECULE;
     else if (strcmp(arg[1],"id") == 0) category = ID;
     else error->all("Illegal group command");
     
     if (strcmp(arg[2],"<") == 0) condition = LT;
     else if (strcmp(arg[2],"<=") == 0) condition = LE;
     else if (strcmp(arg[2],">") == 0) condition = GT;
     else if (strcmp(arg[2],">=") == 0) condition = GE;
     else if (strcmp(arg[2],"==") == 0) condition = EQ;
     else if (strcmp(arg[2],"!=") == 0) condition = NEQ;
     else if (strcmp(arg[2],"<>") == 0) condition = BETWEEN;
     else error->all("Illegal group command");
 
     bound1 = atoi(arg[3]);
     bound2 = -1;
 
     if (condition == BETWEEN) {
       if (narg != 5) error->all("Illegal group command");
       bound2 = atoi(arg[4]);
     }
 
     int *attribute;
     if (category == TYPE) attribute = atom->type;
     else if (category == MOLECULE) attribute = atom->molecule;
     else if (category == ID) attribute = atom->tag;
 
     // 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;
     }
 
   // style = list of values
 
   } else if (strcmp(arg[1],"type") == 0 || strcmp(arg[1],"molecule") == 0 ||
 	     strcmp(arg[1],"id") == 0) {
 
     if (narg < 3) error->all("Illegal group command");
 
     int length = narg-2;
     int *list = new int[length];
 
     int category;
     if (strcmp(arg[1],"type") == 0) category = TYPE;
     else if (strcmp(arg[1],"molecule") == 0) category = MOLECULE;
     else if (strcmp(arg[1],"id") == 0) category = ID;
     else error->all("Illegal group command");
     
     length = narg - 2;
     for (int iarg = 2; iarg < narg; iarg++) list[iarg-2] = atoi(arg[iarg]);
 
     int *attribute;
     if (category == TYPE) attribute = atom->type;
     else if (category == MOLECULE) attribute = atom->molecule;
     else if (category == ID) attribute = atom->tag;
 
     // add to group if attribute is any in list
 
     for (int ilist = 0; ilist < length; ilist++)
       for (i = 0; i < nlocal; i++)
 	if (attribute[i] == list[ilist]) mask[i] |= bit;
 
     delete [] list;
     
   // style = subtract
 
   } else if (strcmp(arg[1],"subtract") == 0) {
 
     if (narg < 4) error->all("Illegal group command");
     
     int length = narg-2;
     int *list = new int[length];
 
     int jgroup;
     for (int iarg = 2; iarg < narg; iarg++) {
       jgroup = find(arg[iarg]);
       if (jgroup == -1) error->all("Group ID does not exist");
       list[iarg-2] = jgroup;
     }
 
     // add to group if in 1st group in list
 
     int otherbit = bitmask[list[0]];
 
     for (i = 0; i < nlocal; i++) 
       if (mask[i] & otherbit) mask[i] |= bit;
 
     // remove atoms if they are in any of the other groups
     // AND with inverse mask removes the atom from group
 
     int inverse = inversemask[igroup];
 
     for (int ilist = 1; ilist < length; ilist++) {
       otherbit = bitmask[list[ilist]];
       for (i = 0; i < nlocal; i++) 
 	if (mask[i] & otherbit) mask[i] &= inverse;
     }
 
     delete [] list;
 
   // style = union
 
   } else if (strcmp(arg[1],"union") == 0) {
 
     if (narg < 3) error->all("Illegal group command");
     
     int length = narg-2;
     int *list = new int[length];
 
     int jgroup;
     for (int iarg = 2; iarg < narg; iarg++) {
       jgroup = find(arg[iarg]);
       if (jgroup == -1) error->all("Group ID does not exist");
       list[iarg-2] = jgroup;
     }
 
     // add to group if in any other group in list
 
     int otherbit;
 
     for (int ilist = 0; ilist < length; ilist++) {
       otherbit = bitmask[list[ilist]];
       for (i = 0; i < nlocal; i++) 
 	if (mask[i] & otherbit) mask[i] |= bit;
     }
 
     delete [] list;
 
   // style = intersect
 
   } else if (strcmp(arg[1],"intersect") == 0) {
 
     if (narg < 4) error->all("Illegal group command");
     
     int length = narg-2;
     int *list = new int[length];
 
     int jgroup;
     for (int iarg = 2; iarg < narg; iarg++) {
       jgroup = find(arg[iarg]);
       if (jgroup == -1) error->all("Group ID does not exist");
       list[iarg-2] = jgroup;
     }
 
     // add to group if in all groups in list
 
     int otherbit,ok,ilist;
 
     for (i = 0; i < nlocal; i++) {
       ok = 1;
       for (ilist = 0; ilist < length; ilist++) {
 	otherbit = bitmask[list[ilist]];
 	if ((mask[i] & otherbit) == 0) ok = 0;
       }
       if (ok) mask[i] |= bit;
     }
 
     delete [] list;
 
   // not a valid group style
 
   } else error->all("Illegal group command");
 
   // print stats for changed group
 
   int n;
   n = 0;
   for (i = 0; i < nlocal; i++) if (mask[i] & bit) n++;
 
   double rlocal = n;
   double all;
   MPI_Allreduce(&rlocal,&all,1,MPI_DOUBLE,MPI_SUM,world);
 
   if (me == 0) {
     if (screen) fprintf(screen,"%.15g atoms in group %s\n",all,names[igroup]);
     if (logfile)
       fprintf(logfile,"%.15g atoms in group %s\n",all,names[igroup]);
   }
 }
  
 /* ----------------------------------------------------------------------
    add flagged atoms to a new or existing group
 ------------------------------------------------------------------------- */
 
 void Group::create(char *name, int *flag)
 {
   int i;
 
   // find group in existing list
   // add a new group if igroup = -1
 
   int igroup = find(name);
 
   if (igroup == -1) {
     if (ngroup == MAX_GROUP) error->all("Too many groups");
     igroup = find_unused();
     int n = strlen(name) + 1;
     names[igroup] = new char[n];
     strcpy(names[igroup],name);
     ngroup++;
   }
 
   // add atoms to group whose flags are set
 
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   int bit = bitmask[igroup];
 
   for (i = 0; i < nlocal; i++) 
     if (flag[i]) mask[i] |= bit;
 }
 
 /* ----------------------------------------------------------------------
    return group index if name matches existing group, -1 if no such group
 ------------------------------------------------------------------------- */
 
 int Group::find(const char *name)
 {
   for (int igroup = 0; igroup < MAX_GROUP; igroup++)
     if (names[igroup] && strcmp(name,names[igroup]) == 0) return igroup;
   return -1;
 }
 
 /* ----------------------------------------------------------------------
    return index of first available group
    should never be called when group limit has been reached
 ------------------------------------------------------------------------- */
 
 int Group::find_unused()
 {
   for (int igroup = 0; igroup < MAX_GROUP; igroup++)
     if (names[igroup] == NULL) return igroup;
   return -1;
 }
 
 /* ----------------------------------------------------------------------
    write group info to a restart file
    only called by proc 0
 ------------------------------------------------------------------------- */
 
 void Group::write_restart(FILE *fp)
 {
   fwrite(&ngroup,sizeof(int),1,fp);
 
   // use count to not change restart format with deleted groups
   // remove this on next major release
 
   int n;
   int count = 0;
   for (int i = 0; i < MAX_GROUP; i++) {
     if (names[i]) n = strlen(names[i]) + 1;
     else n = 0;
     fwrite(&n,sizeof(int),1,fp);
     if (n) {
       fwrite(names[i],sizeof(char),n,fp);
       count++;
     }
     if (count == ngroup) break;
   }
 }
 
 /* ----------------------------------------------------------------------
    read group info from a restart file
    proc 0 reads, bcast to all procs
 ------------------------------------------------------------------------- */
 
 void Group::read_restart(FILE *fp)
 {
   int i,n;
 
   // delete existing group names
   // atom masks will be overwritten by reading of restart file
 
   for (i = 0; i < MAX_GROUP; i++) delete [] names[i];
 
   if (me == 0) fread(&ngroup,sizeof(int),1,fp);
   MPI_Bcast(&ngroup,1,MPI_INT,0,world);
 
   // use count to not change restart format with deleted groups
   // remove this on next major release
 
   int count = 0;
   for (i = 0; i < MAX_GROUP; i++) {
     if (count == ngroup) {
       names[i] = NULL;
       continue;
     }
     if (me == 0) fread(&n,sizeof(int),1,fp);
     MPI_Bcast(&n,1,MPI_INT,0,world);
     if (n) {
       names[i] = new char[n];
       if (me == 0) fread(names[i],sizeof(char),n,fp);
       MPI_Bcast(names[i],n,MPI_CHAR,0,world);
       count++;
     } else names[i] = NULL;
   }
 }
 
 // ----------------------------------------------------------------------
 // computations on a group of atoms
 // ----------------------------------------------------------------------
 
 /* ----------------------------------------------------------------------
    count atoms in group
 ------------------------------------------------------------------------- */
 
 bigint Group::count(int igroup)
 {
   int groupbit = bitmask[igroup];
 
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int n = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) n++;
 
   bigint nsingle = n;
   bigint nall;
-  MPI_Allreduce(&nsingle,&nall,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&nsingle,&nall,1,MPI_LMP_BIGINT,MPI_SUM,world);
   return nall;
 }
 
 /* ----------------------------------------------------------------------
    count atoms in group and region
 ------------------------------------------------------------------------- */
 
 bigint Group::count(int igroup, int iregion)
 {
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double **x = atom->x;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   int n = 0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) n++;
 
   bigint nsingle = n;
   bigint nall;
-  MPI_Allreduce(&nsingle,&nall,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&nsingle,&nall,1,MPI_LMP_BIGINT,MPI_SUM,world);
   return nall;
 }
 
 /* ----------------------------------------------------------------------
    compute the total mass of group of atoms
    use either per-type mass or per-atom rmass
 ------------------------------------------------------------------------- */
 
 double Group::mass(int igroup)
 {
   int groupbit = bitmask[igroup];
 
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int *mask = atom->mask;
   int *type = atom->type;
   int nlocal = atom->nlocal;
 
   double one = 0.0;
 
   if (rmass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) one += rmass[i];
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) one += mass[type[i]];
   }
 
   double all;
   MPI_Allreduce(&one,&all,1,MPI_DOUBLE,MPI_SUM,world);
   return all;
 }
 
 /* ----------------------------------------------------------------------
    compute the total mass of group of atoms in region
    use either per-type mass or per-atom rmass
 ------------------------------------------------------------------------- */
 
 double Group::mass(int igroup, int iregion)
 {
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double **x = atom->x;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int *mask = atom->mask;
   int *type = atom->type;
   int nlocal = atom->nlocal;
 
   double one = 0.0;
 
   if (rmass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
 	one += rmass[i];
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
 	one += mass[type[i]];
   }
 
   double all;
   MPI_Allreduce(&one,&all,1,MPI_DOUBLE,MPI_SUM,world);
   return all;
 }
 
 /* ----------------------------------------------------------------------
    compute the total charge of group of atoms
 ------------------------------------------------------------------------- */
 
 double Group::charge(int igroup)
 {
   int groupbit = bitmask[igroup];
 
   double *q = atom->q;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   double qone = 0.0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) qone += q[i];
 
   double qall;
   MPI_Allreduce(&qone,&qall,1,MPI_DOUBLE,MPI_SUM,world);
   return qall;
 }
 
 /* ----------------------------------------------------------------------
    compute the total charge of group of atoms in region
 ------------------------------------------------------------------------- */
 
 double Group::charge(int igroup, int iregion)
 {
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double **x = atom->x;
   double *q = atom->q;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   double qone = 0.0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
       qone += q[i];
 
   double qall;
   MPI_Allreduce(&qone,&qall,1,MPI_DOUBLE,MPI_SUM,world);
   return qall;
 }
 
 /* ----------------------------------------------------------------------
    compute the coordinate bounds of the group of atoms
    periodic images are not considered, so atoms are NOT unwrapped
 ------------------------------------------------------------------------- */
 
 void Group::bounds(int igroup, double *minmax)
 {
   int groupbit = bitmask[igroup];
 
   double extent[6];
   extent[0] = extent[2] = extent[4] = BIG;
   extent[1] = extent[3] = extent[5] = -BIG;
   
   double **x = atom->x;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
       extent[0] = MIN(extent[0],x[i][0]);
       extent[1] = MAX(extent[1],x[i][0]);
       extent[2] = MIN(extent[2],x[i][1]);
       extent[3] = MAX(extent[3],x[i][1]);
       extent[4] = MIN(extent[4],x[i][2]);
       extent[5] = MAX(extent[5],x[i][2]);
     }
   }
   
   // compute extent across all procs
   // flip sign of MIN to do it in one Allreduce MAX
   // set box by extent in shrink-wrapped dims
   
   extent[0] = -extent[0];
   extent[2] = -extent[2];
   extent[4] = -extent[4];
   
   MPI_Allreduce(extent,minmax,6,MPI_DOUBLE,MPI_MAX,world);
 
   minmax[0] = -minmax[0];
   minmax[2] = -minmax[2];
   minmax[4] = -minmax[4];
 }
 
 /* ----------------------------------------------------------------------
    compute the coordinate bounds of the group of atoms in region
    periodic images are not considered, so atoms are NOT unwrapped
 ------------------------------------------------------------------------- */
 
 void Group::bounds(int igroup, double *minmax, int iregion)
 {
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double extent[6];
   extent[0] = extent[2] = extent[4] = BIG;
   extent[1] = extent[3] = extent[5] = -BIG;
   
   double **x = atom->x;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
       extent[0] = MIN(extent[0],x[i][0]);
       extent[1] = MAX(extent[1],x[i][0]);
       extent[2] = MIN(extent[2],x[i][1]);
       extent[3] = MAX(extent[3],x[i][1]);
       extent[4] = MIN(extent[4],x[i][2]);
       extent[5] = MAX(extent[5],x[i][2]);
     }
   }
   
   // compute extent across all procs
   // flip sign of MIN to do it in one Allreduce MAX
   // set box by extent in shrink-wrapped dims
   
   extent[0] = -extent[0];
   extent[2] = -extent[2];
   extent[4] = -extent[4];
   
   MPI_Allreduce(extent,minmax,6,MPI_DOUBLE,MPI_MAX,world);
 
   minmax[0] = -minmax[0];
   minmax[2] = -minmax[2];
   minmax[4] = -minmax[4];
 }
 
 /* ----------------------------------------------------------------------
    compute the center-of-mass coords of group of atoms
    masstotal = total mass
    return center-of-mass coords in cm[]
    must unwrap atoms to compute center-of-mass correctly
 ------------------------------------------------------------------------- */
 
 void Group::xcm(int igroup, double masstotal, double *cm)
 {
   int groupbit = bitmask[igroup];
 
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
   int *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   double cmone[3];
   cmone[0] = cmone[1] = cmone[2] = 0.0;
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
 
   int xbox,ybox,zbox;
   double massone;
 
   if (rmass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	xbox = (image[i] & 1023) - 512;
 	ybox = (image[i] >> 10 & 1023) - 512;
 	zbox = (image[i] >> 20) - 512;
 	massone = rmass[i];
 	cmone[0] += (x[i][0] + xbox*xprd) * massone;
 	cmone[1] += (x[i][1] + ybox*yprd) * massone;
 	cmone[2] += (x[i][2] + zbox*zprd) * massone;
       }
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	xbox = (image[i] & 1023) - 512;
 	ybox = (image[i] >> 10 & 1023) - 512;
 	zbox = (image[i] >> 20) - 512;
 	massone = mass[type[i]];
 	cmone[0] += (x[i][0] + xbox*xprd) * massone;
 	cmone[1] += (x[i][1] + ybox*yprd) * massone;
 	cmone[2] += (x[i][2] + zbox*zprd) * massone;
       }
   }
 
   MPI_Allreduce(cmone,cm,3,MPI_DOUBLE,MPI_SUM,world);
   if (masstotal > 0.0) {
     cm[0] /= masstotal;
     cm[1] /= masstotal;
     cm[2] /= masstotal;
   }
 }
 
 /* ----------------------------------------------------------------------
    compute the center-of-mass coords of group of atoms in region
    mastotal = total mass
    return center-of-mass coords in cm[]
    must unwrap atoms to compute center-of-mass correctly
 ------------------------------------------------------------------------- */
 
 void Group::xcm(int igroup, double masstotal, double *cm, int iregion)
 {
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
   int *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   double cmone[3];
   cmone[0] = cmone[1] = cmone[2] = 0.0;
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
 
   int xbox,ybox,zbox;
   double massone;
 
   if (rmass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
 	xbox = (image[i] & 1023) - 512;
 	ybox = (image[i] >> 10 & 1023) - 512;
 	zbox = (image[i] >> 20) - 512;
 	massone = rmass[i];
 	cmone[0] += (x[i][0] + xbox*xprd) * massone;
 	cmone[1] += (x[i][1] + ybox*yprd) * massone;
 	cmone[2] += (x[i][2] + zbox*zprd) * massone;
       }
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
 	xbox = (image[i] & 1023) - 512;
 	ybox = (image[i] >> 10 & 1023) - 512;
 	zbox = (image[i] >> 20) - 512;
 	massone = mass[type[i]];
 	cmone[0] += (x[i][0] + xbox*xprd) * massone;
 	cmone[1] += (x[i][1] + ybox*yprd) * massone;
 	cmone[2] += (x[i][2] + zbox*zprd) * massone;
       }
   }
 
   MPI_Allreduce(cmone,cm,3,MPI_DOUBLE,MPI_SUM,world);
   if (masstotal > 0.0) {
     cm[0] /= masstotal;
     cm[1] /= masstotal;
     cm[2] /= masstotal;
   }
 }
 
 /* ----------------------------------------------------------------------
    compute the center-of-mass velocity of group of atoms
    masstotal = total mass
    return center-of-mass velocity in cm[]
 ------------------------------------------------------------------------- */
 
 void Group::vcm(int igroup, double masstotal, double *cm)
 {
   int groupbit = bitmask[igroup];
 
   double **v = atom->v;
   int *mask = atom->mask;
   int *type = atom->type;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   double p[3],massone;
   p[0] = p[1] = p[2] = 0.0;
 
   if (rmass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	massone = rmass[i];
 	p[0] += v[i][0]*massone;
 	p[1] += v[i][1]*massone;
 	p[2] += v[i][2]*massone;
       }
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
 	massone = mass[type[i]];
 	p[0] += v[i][0]*massone;
 	p[1] += v[i][1]*massone;
 	p[2] += v[i][2]*massone;
       }
   }
 
   MPI_Allreduce(p,cm,3,MPI_DOUBLE,MPI_SUM,world);
   if (masstotal > 0.0) {
     cm[0] /= masstotal;
     cm[1] /= masstotal;
     cm[2] /= masstotal;
   }
 }
 
 /* ----------------------------------------------------------------------
    compute the center-of-mass velocity of group of atoms in region
    masstotal = total mass
    return center-of-mass velocity in cm[]
 ------------------------------------------------------------------------- */
 
 void Group::vcm(int igroup, double masstotal, double *cm, int iregion)
 {
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double **x = atom->x;
   double **v = atom->v;
   int *mask = atom->mask;
   int *type = atom->type;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   double p[3],massone;
   p[0] = p[1] = p[2] = 0.0;
 
   if (rmass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
 	massone = rmass[i];
 	p[0] += v[i][0]*massone;
 	p[1] += v[i][1]*massone;
 	p[2] += v[i][2]*massone;
       }
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
 	massone = mass[type[i]];
 	p[0] += v[i][0]*massone;
 	p[1] += v[i][1]*massone;
 	p[2] += v[i][2]*massone;
       }
   }
 
   MPI_Allreduce(p,cm,3,MPI_DOUBLE,MPI_SUM,world);
   if (masstotal > 0.0) {
     cm[0] /= masstotal;
     cm[1] /= masstotal;
     cm[2] /= masstotal;
   }
 }
 
 /* ----------------------------------------------------------------------
    compute the total force on group of atoms
 ------------------------------------------------------------------------- */
 
 void Group::fcm(int igroup, double *cm)
 {
   int groupbit = bitmask[igroup];
 
   double **f = atom->f;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   double flocal[3];
   flocal[0] = flocal[1] = flocal[2] = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       flocal[0] += f[i][0];
       flocal[1] += f[i][1];
       flocal[2] += f[i][2];
     }
 
   MPI_Allreduce(flocal,cm,3,MPI_DOUBLE,MPI_SUM,world);
 }
 
 /* ----------------------------------------------------------------------
    compute the total force on group of atoms in region
 ------------------------------------------------------------------------- */
 
 void Group::fcm(int igroup, double *cm, int iregion)
 {
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double **x = atom->x;
   double **f = atom->f;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   double flocal[3];
   flocal[0] = flocal[1] = flocal[2] = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
       flocal[0] += f[i][0];
       flocal[1] += f[i][1];
       flocal[2] += f[i][2];
     }
 
   MPI_Allreduce(flocal,cm,3,MPI_DOUBLE,MPI_SUM,world);
 }
 
 /* ----------------------------------------------------------------------
    compute the total kinetic energy of group of atoms and return it
 ------------------------------------------------------------------------- */
 
 double Group::ke(int igroup)
 {
   int groupbit = bitmask[igroup];
 
   double **v = atom->v;
   int *mask = atom->mask;
   int *type = atom->type;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   double one = 0.0;
 
   if (rmass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit)
 	one += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) *
 	  rmass[i];
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit)
 	one += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) *
 	  mass[type[i]];
   }
   
   double all;
   MPI_Allreduce(&one,&all,1,MPI_DOUBLE,MPI_SUM,world);
   all *= 0.5 * force->mvv2e;
   return all;
 }
 
 /* ----------------------------------------------------------------------
    compute the total kinetic energy of group of atoms in region and return it
 ------------------------------------------------------------------------- */
 
 double Group::ke(int igroup, int iregion)
 {
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double **x = atom->x;
   double **v = atom->v;
   int *mask = atom->mask;
   int *type = atom->type;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   double one = 0.0;
 
   if (rmass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
 	one += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) *
 	  rmass[i];
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
 	one += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) *
 	  mass[type[i]];
   }
   
   double all;
   MPI_Allreduce(&one,&all,1,MPI_DOUBLE,MPI_SUM,world);
   all *= 0.5 * force->mvv2e;
   return all;
 }
 
 /* ----------------------------------------------------------------------
    compute the radius-of-gyration of group of atoms
    around center-of-mass cm
    must unwrap atoms to compute Rg correctly
 ------------------------------------------------------------------------- */
 
 double Group::gyration(int igroup, double masstotal, double *cm)
 {
   int groupbit = bitmask[igroup];
 
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
   int *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   int xbox,ybox,zbox;
   double dx,dy,dz,massone;
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
   double rg = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
       if (rmass) massone = rmass[i];
       else massone = mass[type[i]];
       rg += (dx*dx + dy*dy + dz*dz) * massone;
     }
   double rg_all;
   MPI_Allreduce(&rg,&rg_all,1,MPI_DOUBLE,MPI_SUM,world);
   
   if (masstotal > 0.0) return sqrt(rg_all/masstotal);
   return 0.0;
 }
 
 /* ----------------------------------------------------------------------
    compute the radius-of-gyration of group of atoms in region
    around center-of-mass cm
    must unwrap atoms to compute Rg correctly
 ------------------------------------------------------------------------- */
 
 double Group::gyration(int igroup, double masstotal, double *cm, int iregion)
 {
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
   int *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   int xbox,ybox,zbox;
   double dx,dy,dz,massone;
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
   double rg = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
       if (rmass) massone = rmass[i];
       else massone = mass[type[i]];
       rg += (dx*dx + dy*dy + dz*dz) * massone;
     }
   double rg_all;
   MPI_Allreduce(&rg,&rg_all,1,MPI_DOUBLE,MPI_SUM,world);
   
   if (masstotal > 0.0) return sqrt(rg_all/masstotal);
   return 0.0;
 }
 
 /* ----------------------------------------------------------------------
    compute the angular momentum L (lmom) of group
    around center-of-mass cm
    must unwrap atoms to compute L correctly
 ------------------------------------------------------------------------- */
 
 void Group::angmom(int igroup, double *cm, double *lmom)
 {
   int groupbit = bitmask[igroup];
 
   double **x = atom->x;
   double **v = atom->v;
   int *mask = atom->mask;
   int *type = atom->type;
   int *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   int xbox,ybox,zbox;
   double dx,dy,dz,massone;
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
   double p[3];
   p[0] = p[1] = p[2] = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
       if (rmass) massone = rmass[i];
       else massone = mass[type[i]];
       p[0] += massone * (dy*v[i][2] - dz*v[i][1]);
       p[1] += massone * (dz*v[i][0] - dx*v[i][2]);
       p[2] += massone * (dx*v[i][1] - dy*v[i][0]);
     }
 
   MPI_Allreduce(p,lmom,3,MPI_DOUBLE,MPI_SUM,world);
 }
 
 /* ----------------------------------------------------------------------
    compute the angular momentum L (lmom) of group of atoms in region
    around center-of-mass cm
    must unwrap atoms to compute L correctly
 ------------------------------------------------------------------------- */
 
 void Group::angmom(int igroup, double *cm, double *lmom, int iregion)
 {
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double **x = atom->x;
   double **v = atom->v;
   int *mask = atom->mask;
   int *type = atom->type;
   int *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   int xbox,ybox,zbox;
   double dx,dy,dz,massone;
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
   double p[3];
   p[0] = p[1] = p[2] = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
       if (rmass) massone = rmass[i];
       else massone = mass[type[i]];
       p[0] += massone * (dy*v[i][2] - dz*v[i][1]);
       p[1] += massone * (dz*v[i][0] - dx*v[i][2]);
       p[2] += massone * (dx*v[i][1] - dy*v[i][0]);
     }
 
   MPI_Allreduce(p,lmom,3,MPI_DOUBLE,MPI_SUM,world);
 }
 
 /* ----------------------------------------------------------------------
    compute the torque T (tq) on group
    around center-of-mass cm
    must unwrap atoms to compute T correctly
 ------------------------------------------------------------------------- */
 
 void Group::torque(int igroup, double *cm, double *tq)
 {
   int groupbit = bitmask[igroup];
 
   double **x = atom->x;
   double **f = atom->f;
   int *mask = atom->mask;
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   int xbox,ybox,zbox;
   double dx,dy,dz;
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
   double tlocal[3];
   tlocal[0] = tlocal[1] = tlocal[2] = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
       tlocal[0] += dy*f[i][2] - dz*f[i][1];
       tlocal[1] += dz*f[i][0] - dx*f[i][2];
       tlocal[2] += dx*f[i][1] - dy*f[i][0];
     }
 
   MPI_Allreduce(tlocal,tq,3,MPI_DOUBLE,MPI_SUM,world);
 }
 
 /* ----------------------------------------------------------------------
    compute the torque T (tq) on group of atoms in region
    around center-of-mass cm
    must unwrap atoms to compute T correctly
 ------------------------------------------------------------------------- */
 
 void Group::torque(int igroup, double *cm, double *tq, int iregion)
 {
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double **x = atom->x;
   double **f = atom->f;
   int *mask = atom->mask;
   int *image = atom->image;
   int nlocal = atom->nlocal;
 
   int xbox,ybox,zbox;
   double dx,dy,dz;
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
   double tlocal[3];
   tlocal[0] = tlocal[1] = tlocal[2] = 0.0;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
       tlocal[0] += dy*f[i][2] - dz*f[i][1];
       tlocal[1] += dz*f[i][0] - dx*f[i][2];
       tlocal[2] += dx*f[i][1] - dy*f[i][0];
     }
 
   MPI_Allreduce(tlocal,tq,3,MPI_DOUBLE,MPI_SUM,world);
 }
 
 /* ----------------------------------------------------------------------
    compute moment of inertia tensor around center-of-mass cm of group
    must unwrap atoms to compute itensor correctly
 ------------------------------------------------------------------------- */
 
 void Group::inertia(int igroup, double *cm, double itensor[3][3])
 {
   int i,j;
 
   int groupbit = bitmask[igroup];
 
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
   int *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   int xbox,ybox,zbox;
   double dx,dy,dz,massone;
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
   double ione[3][3];
   for (i = 0; i < 3; i++)
     for (j = 0; j < 3; j++)
       ione[i][j] = 0.0;
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
       if (rmass) massone = rmass[i];
       else massone = mass[type[i]];
       ione[0][0] += massone * (dy*dy + dz*dz);
       ione[1][1] += massone * (dx*dx + dz*dz);
       ione[2][2] += massone * (dx*dx + dy*dy);
       ione[0][1] -= massone * dx*dy;
       ione[1][2] -= massone * dy*dz;
       ione[0][2] -= massone * dx*dz;
     }
   ione[1][0] = ione[0][1];
   ione[2][1] = ione[1][2];
   ione[2][0] = ione[0][2];
 
   MPI_Allreduce(&ione[0][0],&itensor[0][0],9,MPI_DOUBLE,MPI_SUM,world);
 }
 
 /* ----------------------------------------------------------------------
    compute moment of inertia tensor around cm of group of atoms in region
    must unwrap atoms to compute itensor correctly
 ------------------------------------------------------------------------- */
 
 void Group::inertia(int igroup, double *cm, double itensor[3][3], int iregion)
 {
   int i,j;
 
   int groupbit = bitmask[igroup];
   Region *region = domain->regions[iregion];
 
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
   int *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
 
   int xbox,ybox,zbox;
   double dx,dy,dz,massone;
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
   double ione[3][3];
   for (i = 0; i < 3; i++)
     for (j = 0; j < 3; j++)
       ione[i][j] = 0.0;
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
       if (rmass) massone = rmass[i];
       else massone = mass[type[i]];
       ione[0][0] += massone * (dy*dy + dz*dz);
       ione[1][1] += massone * (dx*dx + dz*dz);
       ione[2][2] += massone * (dx*dx + dy*dy);
       ione[0][1] -= massone * dx*dy;
       ione[1][2] -= massone * dy*dz;
       ione[0][2] -= massone * dx*dz;
     }
   ione[1][0] = ione[0][1];
   ione[2][1] = ione[1][2];
   ione[2][0] = ione[0][2];
 
   MPI_Allreduce(&ione[0][0],&itensor[0][0],9,MPI_DOUBLE,MPI_SUM,world);
 }
 
 /* ----------------------------------------------------------------------
    compute angular velocity omega from L = Iw, inverting I to solve for w
    really not a group operation, but L and I were computed for a group
 ------------------------------------------------------------------------- */
 
 void Group::omega(double *angmom, double inertia[3][3], double *w)
 {
   double inverse[3][3];
 
   inverse[0][0] = inertia[1][1]*inertia[2][2] - inertia[1][2]*inertia[2][1];
   inverse[0][1] = -(inertia[0][1]*inertia[2][2] - inertia[0][2]*inertia[2][1]);
   inverse[0][2] = inertia[0][1]*inertia[1][2] - inertia[0][2]*inertia[1][1];
 
   inverse[1][0] = -(inertia[1][0]*inertia[2][2] - inertia[1][2]*inertia[2][0]);
   inverse[1][1] = inertia[0][0]*inertia[2][2] - inertia[0][2]*inertia[2][0];
   inverse[1][2] = -(inertia[0][0]*inertia[1][2] - inertia[0][2]*inertia[1][0]);
 
   inverse[2][0] = inertia[1][0]*inertia[2][1] - inertia[1][1]*inertia[2][0];
   inverse[2][1] = -(inertia[0][0]*inertia[2][1] - inertia[0][1]*inertia[2][0]);
   inverse[2][2] = inertia[0][0]*inertia[1][1] - inertia[0][1]*inertia[1][0];
 
   double determinant = inertia[0][0]*inertia[1][1]*inertia[2][2] + 
     inertia[0][1]*inertia[1][2]*inertia[2][0] + 
     inertia[0][2]*inertia[1][0]*inertia[2][1] - 
     inertia[0][0]*inertia[1][2]*inertia[2][1] -
     inertia[0][1]*inertia[1][0]*inertia[2][2] - 
     inertia[2][0]*inertia[1][1]*inertia[0][2]; 
 
   if (determinant > 0.0)
     for (int i = 0; i < 3; i++)
       for (int j = 0; j < 3; j++)
 	inverse[i][j] /= determinant;
 
   w[0] = inverse[0][0]*angmom[0] + inverse[0][1]*angmom[1] + 
     inverse[0][2]*angmom[2];
   w[1] = inverse[1][0]*angmom[0] + inverse[1][1]*angmom[1] + 
     inverse[1][2]*angmom[2];
   w[2] = inverse[2][0]*angmom[0] + inverse[2][1]*angmom[1] + 
     inverse[2][2]*angmom[2];
 }
diff --git a/src/integrate.cpp b/src/integrate.cpp
index ca5297b59..5b7d8df19 100644
--- a/src/integrate.cpp
+++ b/src/integrate.cpp
@@ -1,131 +1,132 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "integrate.h"
+#include "lmptype.h"
 #include "update.h"
 #include "modify.h"
 #include "compute.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 Integrate::Integrate(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
 {
   elist_global = elist_atom = NULL;
   vlist_global = vlist_atom = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
 
 Integrate::~Integrate()
 {
   delete [] elist_global;
   delete [] elist_atom;
   delete [] vlist_global;
   delete [] vlist_atom;
 }
 
 /* ----------------------------------------------------------------------
    setup lists of computes for global and per-atom PE and pressure
 ------------------------------------------------------------------------- */
 
 void Integrate::ev_setup()
 {
   delete [] elist_global;
   delete [] elist_atom;
   delete [] vlist_global;
   delete [] vlist_atom;
   elist_global = elist_atom = NULL;
   vlist_global = vlist_atom = NULL;
 
   nelist_global = nelist_atom = 0;
   nvlist_global = nvlist_atom = 0;
   for (int i = 0; i < modify->ncompute; i++) {
     if (modify->compute[i]->peflag) nelist_global++;
     if (modify->compute[i]->peatomflag) nelist_atom++;
     if (modify->compute[i]->pressflag) nvlist_global++;
     if (modify->compute[i]->pressatomflag) nvlist_atom++;
   }
 
   if (nelist_global) elist_global = new Compute*[nelist_global];
   if (nelist_atom) elist_atom = new Compute*[nelist_atom];
   if (nvlist_global) vlist_global = new Compute*[nvlist_global];
   if (nvlist_atom) vlist_atom = new Compute*[nvlist_atom];
 
   nelist_global = nelist_atom = 0;
   nvlist_global = nvlist_atom = 0;
   for (int i = 0; i < modify->ncompute; i++) {
     if (modify->compute[i]->peflag)
       elist_global[nelist_global++] = modify->compute[i];
     if (modify->compute[i]->peatomflag)
       elist_atom[nelist_atom++] = modify->compute[i];
     if (modify->compute[i]->pressflag)
       vlist_global[nvlist_global++] = modify->compute[i];
     if (modify->compute[i]->pressatomflag)
       vlist_atom[nvlist_atom++] = modify->compute[i];
   }
 }
 
 /* ----------------------------------------------------------------------
    set eflag,vflag for current iteration
    invoke matchstep() on all timestep-dependent computes to clear their arrays
    eflag/vflag based on computes that need info on this ntimestep
    eflag = 0 = no energy computation
    eflag = 1 = global energy only
    eflag = 2 = per-atom energy only
    eflag = 3 = both global and per-atom energy
    vflag = 0 = no virial computation (pressure)
    vflag = 1 = global virial with pair portion via sum of pairwise interactions
    vflag = 2 = global virial with pair portion via F dot r including ghosts
    vflag = 4 = per-atom virial only
    vflag = 5 or 6 = both global and per-atom virial
 ------------------------------------------------------------------------- */
 
-void Integrate::ev_set(int ntimestep)
+void Integrate::ev_set(bigint ntimestep)
 {
   int i,flag;
 
   flag = 0;
   int eflag_global = 0;
   for (i = 0; i < nelist_global; i++)
     if (elist_global[i]->matchstep(ntimestep)) flag = 1;
   if (flag) eflag_global = 1;
 
   flag = 0;
   int eflag_atom = 0;
   for (i = 0; i < nelist_atom; i++)
     if (elist_atom[i]->matchstep(ntimestep)) flag = 1;
   if (flag) eflag_atom = 2;
 
   if (eflag_global) update->eflag_global = ntimestep;
   if (eflag_atom) update->eflag_atom = ntimestep;
   eflag = eflag_global + eflag_atom;
 
   flag = 0;
   int vflag_global = 0;
   for (i = 0; i < nvlist_global; i++)
     if (vlist_global[i]->matchstep(ntimestep)) flag = 1;
   if (flag) vflag_global = virial_style;
 
   flag = 0;
   int vflag_atom = 0;
   for (i = 0; i < nvlist_atom; i++)
     if (vlist_atom[i]->matchstep(ntimestep)) flag = 1;
   if (flag) vflag_atom = 4;
 
   if (vflag_global) update->vflag_global = ntimestep;
   if (vflag_atom) update->vflag_atom = ntimestep;
   vflag = vflag_global + vflag_atom;
 }
diff --git a/src/integrate.h b/src/integrate.h
index 8c7d948b3..bcbc71192 100644
--- a/src/integrate.h
+++ b/src/integrate.h
@@ -1,50 +1,51 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_INTEGRATE_H
 #define LMP_INTEGRATE_H
 
 #include "pointers.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class Integrate : protected Pointers {
  public:
   Integrate(class LAMMPS *, int, char **);
   virtual ~Integrate();
   virtual void init() = 0;
   virtual void setup() = 0;
   virtual void setup_minimal(int) = 0;
   virtual void run(int) = 0;
   virtual void cleanup() {}
   virtual void reset_dt() {}
   virtual double memory_usage() {return 0.0;}
 
  protected:
   int eflag,vflag;                  // flags for energy/virial computation
   int virial_style;                 // compute virial explicitly or implicitly
 
   int nelist_global,nelist_atom;    // # of PE,virial computes to check
   int nvlist_global,nvlist_atom;
   class Compute **elist_global;     // lists of PE,virial Computes
   class Compute **elist_atom;
   class Compute **vlist_global;
   class Compute **vlist_atom;
 
   void ev_setup();
-  void ev_set(int);
+  void ev_set(bigint);
 };
 
 }
 
 #endif
diff --git a/src/lammps.cpp b/src/lammps.cpp
index 6b87c0a33..97b07922a 100644
--- a/src/lammps.cpp
+++ b/src/lammps.cpp
@@ -1,351 +1,358 @@
 /* ----------------------------------------------------------------------
    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 "string.h"
 #include "lammps.h"
 #include "memory.h"
 #include "error.h"
 #include "universe.h"
 #include "input.h"
 #include "atom.h"
 #include "update.h"
 #include "neighbor.h"
 #include "comm.h"
 #include "domain.h"
 #include "force.h"
 #include "modify.h"
 #include "group.h"
 #include "output.h"
 #include "timer.h"
 
 using namespace LAMMPS_NS;
 
 /* ----------------------------------------------------------------------
    start up LAMMPS
    allocate fundamental classes (memory, error, universe, input)
    parse input switches
    initialize communicators, screen & logfile output
    input is allocated at end after MPI info is setup
 ------------------------------------------------------------------------- */
 
 LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator)
 {
   memory = new Memory(this);
   error = new Error(this);
   universe = new Universe(this,communicator);
   output = NULL;
 
   screen = NULL;
   logfile = NULL;
 
   // parse input switches
 
   int inflag = 0;
   int screenflag = 0;
   int logflag = 0;
   int iarg = 1;
 
   while (iarg < narg) {
     if (strcmp(arg[iarg],"-partition") == 0) {
       universe->existflag = 1;
       if (iarg+2 > narg) 
 	error->universe_all("Invalid command-line argument");
       iarg++;
       while (iarg < narg && arg[iarg][0] != '-') {
 	universe->add_world(arg[iarg]);
 	iarg++;
       }
     } else if (strcmp(arg[iarg],"-in") == 0) {
       if (iarg+2 > narg) 
 	error->universe_all("Invalid command-line argument");
       inflag = iarg + 1;
       iarg += 2;
     } else if (strcmp(arg[iarg],"-screen") == 0) {
       if (iarg+2 > narg) 
 	error->universe_all("Invalid command-line argument");
       screenflag = iarg + 1;
       iarg += 2;
     } else if (strcmp(arg[iarg],"-log") == 0) {
       if (iarg+2 > narg) 
 	error->universe_all("Invalid command-line argument");
       logflag = iarg + 1;
       iarg += 2;
     } else if (strcmp(arg[iarg],"-var") == 0) {
       if (iarg+3 > narg) 
 	error->universe_all("Invalid command-line argument");
       iarg += 3;
     } else if (strcmp(arg[iarg],"-echo") == 0) {
       if (iarg+2 > narg) 
 	error->universe_all("Invalid command-line argument");
       iarg += 2;
     } else error->universe_all("Invalid command-line argument");
   }
 
   // if no partition command-line switch, universe is one world w/ all procs
 
   if (universe->existflag == 0) universe->add_world(NULL);
 
   // sum of procs in all worlds must equal total # of procs
 
   if (!universe->consistent())
     error->universe_all("Processor partitions are inconsistent");
 
   // universe cannot use stdin for input file
 
   if (universe->existflag && inflag == 0)
     error->universe_all("Must use -in switch with multiple partitions");
 
   // set universe screen and logfile
 
   if (universe->me == 0) {
     if (screenflag == 0)
       universe->uscreen = stdout;
     else if (strcmp(arg[screenflag],"none") == 0)
       universe->uscreen = NULL;
     else {
       universe->uscreen = fopen(arg[screenflag],"w");
       if (universe->uscreen == NULL) 
 	error->universe_one("Cannot open universe screen file");
     }
     if (logflag == 0) {
       universe->ulogfile = fopen("log.lammps","w");
       if (universe->ulogfile == NULL) 
 	error->universe_one("Cannot open log.lammps");
     } else if (strcmp(arg[logflag],"none") == 0)
       universe->ulogfile = NULL;
     else {
       universe->ulogfile = fopen(arg[logflag],"w");
       if (universe->ulogfile == NULL) 
 	error->universe_one("Cannot open universe log file");
     }
   }
 
   if (universe->me > 0) {
     if (screenflag == 0) universe->uscreen = stdout;
     else universe->uscreen = NULL;
     universe->ulogfile = NULL;
   }
 
   // universe does not exist on its own, only a single world
   // inherit settings from universe
   // set world screen, logfile, communicator, infile
   // open input script if from file
 
   if (universe->existflag == 0) {
     screen = universe->uscreen;
     logfile = universe->ulogfile;
     world = universe->uworld;
     infile = NULL;
 
     if (universe->me == 0) {
       if (inflag == 0) infile = stdin;
       else infile = fopen(arg[inflag],"r");
       if (infile == NULL) {
 	char str[128];
 	sprintf(str,"Cannot open input script %s",arg[inflag]);
 	error->one(str);
       }
     }
 
     if (universe->me == 0) {
       if (screen) fprintf(screen,"LAMMPS (%s)\n",universe->version);
       if (logfile) fprintf(logfile,"LAMMPS (%s)\n",universe->version);
     }
 
   // universe is one or more worlds
   // split into separate communicators
   // set world screen, logfile, communicator, infile
   // open input script
 
   } else {
     int me;
     MPI_Comm_split(universe->uworld,universe->iworld,0,&world);
     MPI_Comm_rank(world,&me);
 
     if (me == 0) {
       if (screenflag == 0) {
 	char str[32];
 	sprintf(str,"screen.%d",universe->iworld);
 	screen = fopen(str,"w");
 	if (screen == NULL) error->one("Cannot open screen file");
       } else if (strcmp(arg[screenflag],"none") == 0)
 	screen = NULL;
       else {
 	char str[128];
 	sprintf(str,"%s.%d",arg[screenflag],universe->iworld);
 	screen = fopen(str,"w");
 	if (screen == NULL) error->one("Cannot open screen file");
       }
     } else screen = NULL;
     
     if (me == 0) {
       if (logflag == 0) {
 	char str[32];
 	sprintf(str,"log.lammps.%d",universe->iworld);
 	logfile = fopen(str,"w");
 	if (logfile == NULL) error->one("Cannot open logfile");
       } else if (strcmp(arg[logflag],"none") == 0)
 	logfile = NULL;
       else {
 	char str[128];
 	sprintf(str,"%s.%d",arg[logflag],universe->iworld);
 	logfile = fopen(str,"w");
 	if (logfile == NULL) error->one("Cannot open logfile");
       }
     } else logfile = NULL;
     
     if (me == 0) {
       infile = fopen(arg[inflag],"r");
       if (infile == NULL) {
 	char str[128];
 	sprintf(str,"Cannot open input script %s",arg[inflag]);
 	error->one(str);
       }
     } else infile = NULL;
     
     // screen and logfile messages for universe and world
     
     if (universe->me == 0) {
       if (universe->uscreen) {
 	fprintf(universe->uscreen,"LAMMPS (%s)\n",universe->version);
 	fprintf(universe->uscreen,"Running on %d partitions of processors\n",
 		universe->nworlds);
       }
       if (universe->ulogfile) {
 	fprintf(universe->ulogfile,"LAMMPS (%s)\n",universe->version);
 	fprintf(universe->ulogfile,"Running on %d partitions of processors\n",
 		universe->nworlds);
       }
     }
     
     if (me == 0) {
       if (screen) {
 	fprintf(screen,"LAMMPS (%s)\n",universe->version);
 	fprintf(screen,"Processor partition = %d\n",universe->iworld);
       }
       if (logfile) {
 	fprintf(logfile,"LAMMPS (%s)\n",universe->version);
 	fprintf(logfile,"Processor partition = %d\n",universe->iworld);
       }
     }
   }
 
-  // check datatype sizes
+  // check datatype settings in lmptype.h
 
-  if (sizeof(bigint) != 8)
-    error->all("No support for 8-byte unsigned integers");
+  if (sizeof(smallint) != sizeof(int))
+    error->all("Smallint setting in lmptype.h is invalid");
+  if (sizeof(tagint) < sizeof(smallint))
+    error->all("Tagint setting in lmptype.h is invalid");
+  if (sizeof(bigint) < sizeof(tagint))
+    error->all("Bigint setting in lmptype.h is invalid");
 
   int mpisize;
-  MPI_Type_size(MPI_UNSIGNED_LONG_LONG,&mpisize);
-  if (mpisize != 8)
-    error->all("MPI_UNSIGNED_LONG_LONG is not 8-byte data type");
+  MPI_Type_size(MPI_LMP_TAGINT,&mpisize);
+  if (mpisize != sizeof(tagint))
+      error->all("MPI_LMP_TAGINT and tagint in lmptype.h are not compatible");
+  MPI_Type_size(MPI_LMP_BIGINT,&mpisize);
+  if (mpisize != sizeof(bigint))
+      error->all("MPI_LMP_BIGINT and bigint in lmptype.h are not compatible");
 
   // allocate input class now that MPI is fully setup
 
   input = new Input(this,narg,arg);
 
   // allocate top-level classes
 
   create();
 }
 
 /* ----------------------------------------------------------------------
    shutdown LAMMPS
    delete top-level classes
    close screen and log files in world and universe
    output files were already closed in destroy()
    delete fundamental classes
 ------------------------------------------------------------------------- */
 
 LAMMPS::~LAMMPS()
 {
   destroy();
 
   if (universe->nworlds == 1) {
     if (logfile) fclose(logfile);
   } else {
     if (screen && screen != stdout) fclose(screen);
     if (logfile) fclose(logfile);
     if (universe->ulogfile) fclose(universe->ulogfile);
   }
 
   if (world != universe->uworld) MPI_Comm_free(&world);
 
   delete input;
   delete universe;
   delete error;
   delete memory;
 }
 
 /* ----------------------------------------------------------------------
    allocate single instance of top-level classes
    fundamental classes are allocated in constructor
 ------------------------------------------------------------------------- */
 
 void LAMMPS::create()
 {
   atom = new Atom(this);
   neighbor = new Neighbor(this);
   comm = new Comm(this);
   domain = new Domain(this);
   group = new Group(this);
   force = new Force(this);    // must be after group, to create temperature
   modify = new Modify(this);
   output = new Output(this);  // must be after group, so "all" exists
                               // must be after modify so can create Computes
   update = new Update(this);  // must be after output, force, neighbor
   timer = new Timer(this);
 }
 
 /* ----------------------------------------------------------------------
    initialize top-level classes
 ------------------------------------------------------------------------- */
 
 void LAMMPS::init()
 {
   update->init();
   force->init();         // pair must come after update due to minimizer
   domain->init();
   atom->init();          // atom must come after force:
                          //   atom deletes extra array
                          //   used by fix shear_history::unpack_restart()
                          //   when force->pair->gran_history creates fix ??
   modify->init();        // modify must come after update, force, atom, domain
   neighbor->init();      // neighbor must come after force, modify
   comm->init();          // comm must come after force, modify, neighbor
   output->init();        // output must come after domain, force, modify
   timer->init();
 }
 
 /* ----------------------------------------------------------------------
    delete single instance of top-level classes
    fundamental classes are deleted in destructor
 ------------------------------------------------------------------------- */
 
 void LAMMPS::destroy()
 {
   delete update;
   delete neighbor;
   delete comm;
   delete force;
   delete group;
   delete output;
   delete modify;          // modify must come after output, force, update
                           //   since they delete fixes
   delete domain;          // domain must come after modify
                           //   since fix destructors access domain
   delete atom;            // atom must come after modify, neighbor
                           //   since fixes delete callbacks in atom
   delete timer;
 }
diff --git a/src/library.cpp b/src/library.cpp
index 546ad4f3f..2b2cc3977 100644
--- a/src/library.cpp
+++ b/src/library.cpp
@@ -1,411 +1,411 @@
 /* ----------------------------------------------------------------------
    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.
 ------------------------------------------------------------------------- */
 
 // C or Fortran style library interface to LAMMPS
 // customize by adding new LAMMPS-specific functions
 
 #include "mpi.h"
 #include "string.h"
 #include "stdlib.h"
 #include "library.h"
 #include "lmptype.h"
 #include "lammps.h"
 #include "input.h"
 #include "atom.h"
 #include "domain.h"
 #include "update.h"
 #include "group.h"
 #include "input.h"
 #include "variable.h"
 #include "modify.h"
 #include "compute.h"
 #include "fix.h"
 
 using namespace LAMMPS_NS;
 
 /* ----------------------------------------------------------------------
    create an instance of LAMMPS and return pointer to it
    pass in command-line args and MPI communicator to run on
 ------------------------------------------------------------------------- */
 
 void lammps_open(int argc, char **argv, MPI_Comm communicator, void **ptr)
 {
   LAMMPS *lmp = new LAMMPS(argc,argv,communicator);
   *ptr = (void *) lmp;
 }
 
 /* ----------------------------------------------------------------------
    create an instance of LAMMPS and return pointer to it
    caller doesn't know MPI communicator, so use MPI_COMM_WORLD
    intialize MPI if needed
 ------------------------------------------------------------------------- */
 
 void lammps_open_no_mpi(int argc, char **argv, void **ptr)
 {
   int flag;
   MPI_Initialized(&flag);
 
   if (!flag) {
     int argc = 0;
     char **argv = NULL;
     MPI_Init(&argc,&argv);
   }
 
   MPI_Comm communicator = MPI_COMM_WORLD;
 
   LAMMPS *lmp = new LAMMPS(argc,argv,communicator);
   *ptr = (void *) lmp;
 }
 
 /* ----------------------------------------------------------------------
    destruct an instance of LAMMPS
 ------------------------------------------------------------------------- */
 
 void lammps_close(void *ptr)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
   delete lmp;
 }
 
 /* ----------------------------------------------------------------------
    process an input script in filename str
 ------------------------------------------------------------------------- */
 
 void lammps_file(void *ptr, char *str)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
   lmp->input->file(str);
 }
 
 /* ----------------------------------------------------------------------
    process a single input command in str
 ------------------------------------------------------------------------- */
 
 char *lammps_command(void *ptr, char *str)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
   return lmp->input->one(str);
 }
 
 /* ----------------------------------------------------------------------
    clean-up function to free memory allocated by lib and returned to caller
 ------------------------------------------------------------------------- */
 
 void lammps_free(void *ptr)
 {
   free(ptr);
 }
 
 /* ----------------------------------------------------------------------
    add LAMMPS-specific library functions
    all must receive LAMMPS pointer as argument
    customize by adding a function here and in library.h header file
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    extract a pointer to an internal LAMMPS global entity
    name = desired quantity, e.g. dt or boxyhi or natoms
    returns a void pointer to the entity
      which the caller can cast to the proper data type
    returns a NULL if name not listed below
    customize by adding names
 ------------------------------------------------------------------------- */
 
 void *lammps_extract_global(void *ptr, char *name)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
 
   if (strcmp(name,"dt") == 0) return (void *) &lmp->update->dt;
   if (strcmp(name,"boxxlo") == 0) return (void *) &lmp->domain->boxlo[0];
   if (strcmp(name,"boxxhi") == 0) return (void *) &lmp->domain->boxhi[0];
   if (strcmp(name,"boxylo") == 0) return (void *) &lmp->domain->boxlo[1];
   if (strcmp(name,"boxyhi") == 0) return (void *) &lmp->domain->boxhi[1];
   if (strcmp(name,"boxzlo") == 0) return (void *) &lmp->domain->boxlo[2];
   if (strcmp(name,"boxzhi") == 0) return (void *) &lmp->domain->boxhi[2];
   if (strcmp(name,"natoms") == 0) return (void *) &lmp->atom->natoms;
   if (strcmp(name,"nlocal") == 0) return (void *) &lmp->atom->nlocal;
   return NULL;
 }
 
 /* ----------------------------------------------------------------------
    extract a pointer to an internal LAMMPS atom-based entity
    name = desired quantity, e.g. x or mass
    returns a void pointer to the entity
      which the caller can cast to the proper data type
    returns a NULL if Atom::extract() does not recognize the name
    customize by adding names to Atom::extract()
 ------------------------------------------------------------------------- */
 
 void *lammps_extract_atom(void *ptr, char *name)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
   return lmp->atom->extract(name);
 }
 
 /* ----------------------------------------------------------------------
    extract a pointer to an internal LAMMPS compute-based entity
    id = compute ID
    style = 0 for global data, 1 for per-atom data, 2 for local data
    type = 0 for scalar, 1 for vector, 2 for array
    returns a void pointer to the compute's internal data structure
      for the entity which the caller can cast to the proper data type
    returns a NULL if id is not recognized or style/type not supported
    IMPORTANT: if the compute is not current it will be invoked
      LAMMPS cannot easily check if it is valid to invoke the compute,
      so caller must insure that it is OK
 ------------------------------------------------------------------------- */
 
 void *lammps_extract_compute(void *ptr, char *id, int style, int type)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
 
   int icompute = lmp->modify->find_compute(id);
   if (icompute < 0) return NULL;
   Compute *compute = lmp->modify->compute[icompute];
 
   if (style == 0) {
     if (type == 0) {
       if (!compute->scalar_flag) return NULL;
       if (compute->invoked_scalar != lmp->update->ntimestep)
 	compute->compute_scalar();
       return (void *) &compute->scalar;
     }
     if (type == 1) {
       if (!compute->vector_flag) return NULL;
       if (compute->invoked_vector != lmp->update->ntimestep)
 	compute->compute_vector();
       return (void *) compute->vector;
     }
     if (type == 2) {
       if (!compute->array_flag) return NULL;
       if (compute->invoked_array != lmp->update->ntimestep)
 	compute->compute_array();
       return (void *) compute->array;
     }
   }
 
   if (style == 1) {
     if (!compute->peratom_flag) return NULL;
     if (type == 1) {
       if (compute->invoked_peratom != lmp->update->ntimestep)
 	compute->compute_peratom();
       return (void *) compute->vector_atom;
     }
     if (type == 2) {
       if (compute->invoked_peratom != lmp->update->ntimestep)
 	compute->compute_peratom();
       return (void *) compute->array_atom;
     }
   }
 
   if (style == 2) {
     if (!compute->local_flag) return NULL;
     if (type == 1) {
       if (compute->invoked_local != lmp->update->ntimestep)
 	compute->compute_local();
       return (void *) compute->vector_local;
     }
     if (type == 2) {
       if (compute->invoked_local != lmp->update->ntimestep)
 	compute->compute_local();
       return (void *) compute->array_local;
     }
   }
 
   return NULL;
 }
 
 /* ----------------------------------------------------------------------
    extract a pointer to an internal LAMMPS fix-based entity
    id = fix ID
    style = 0 for global data, 1 for per-atom data, 2 for local data
    type = 0 for scalar, 1 for vector, 2 for array
    i,j = indices needed only to specify which global vector or array value
    for global data, returns a pointer to a memory location
      which is allocated by this function
      which the caller can cast to a (double *) which points to the value
    for per-atom or local data, returns a pointer to the 
      fix's internal data structure for the entity
      which the caller can cast to the proper data type
    returns a NULL if id is not recognized or style/type not supported
    IMPORTANT: for global data,
      this function allocates a double to store the value in,
      so the caller must free this memory to avoid a leak, e.g.
        double *dptr = (double *) lammps_extract_fix();
        double value = *dptr;
        free(dptr);
    IMPORTANT: LAMMPS cannot easily check when info extracted from
      the fix is valid, so caller must insure that it is OK
 ------------------------------------------------------------------------- */
 
 void *lammps_extract_fix(void *ptr, char *id, int style, int type,
 			 int i, int j)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
 
   int ifix = lmp->modify->find_fix(id);
   if (ifix < 0) return NULL;
   Fix *fix = lmp->modify->fix[ifix];
 
   if (style == 0) {
     double *dptr = (double *) malloc(sizeof(double));
     if (type == 0) {
       if (!fix->scalar_flag) return NULL;
       *dptr = fix->compute_scalar();
       return (void *) dptr;
     }
     if (type == 1) {
       if (!fix->vector_flag) return NULL;
       *dptr = fix->compute_vector(i);
       return (void *) dptr;
     }
     if (type == 2) {
       if (!fix->array_flag) return NULL;
       *dptr = fix->compute_array(i,j);
       return (void *) dptr;
     }
   }
 
   if (style == 1) {
     if (!fix->peratom_flag) return NULL;
     if (type == 1) return (void *) fix->vector_atom;
     if (type == 2) return (void *) fix->array_atom;
   }
 
   if (style == 2) {
     if (!fix->local_flag) return NULL;
     if (type == 1) return (void *) fix->vector_local;
     if (type == 2) return (void *) fix->array_local;
   }
 
   return NULL;
 }
 
 /* ----------------------------------------------------------------------
    extract a pointer to an internal LAMMPS evaluated variable
    name = variable name, must be equal-style or atom-style variable
    group = group ID for evaluating an atom-style variable, else NULL
    for equal-style variable, returns a pointer to a memory location
      which is allocated by this function
      which the caller can cast to a (double *) which points to the value
    for atom-style variable, returns a pointer to the 
      vector of per-atom values on each processor,
      which the caller can cast to the proper data type
    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 in
      so the caller must free this memory to avoid a leak
      e.g. for equal-style variables
        double *dptr = (double *) lammps_extract_variable();
        double value = *dptr;
        free(dptr);
      e.g. for atom-style variables
        double *vector = (double *) lammps_extract_variable();
        use the vector values
        free(vector);
    IMPORTANT: LAMMPS cannot easily check when it is valid to evaluate
      the variable or any fixes or computes or thermodynamic info it references,
      so caller must insure that it is OK
 ------------------------------------------------------------------------- */
 
 void *lammps_extract_variable(void *ptr, char *name, char *group)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
 
   int ivar = lmp->input->variable->find(name);
   if (ivar < 0) return NULL;
 
   if (lmp->input->variable->equalstyle(ivar)) {
     double *dptr = (double *) malloc(sizeof(double));
     *dptr = lmp->input->variable->compute_equal(ivar);
     return (void *) dptr;
   }
 
   if (lmp->input->variable->atomstyle(ivar)) {
     int igroup = lmp->group->find(group);
     if (igroup < 0) return NULL;
     int nlocal = lmp->atom->nlocal;
     double *vector = (double *) malloc(nlocal*sizeof(double));
     lmp->input->variable->compute_atom(ivar,igroup,vector,1,0);
     return (void *) vector;
   }
 
   return NULL;
 }
 
 /* ---------------------------------------------------------------------- */
 
 int lammps_get_natoms(void *ptr)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
-  if (lmp->atom->natoms > MAXINT32) return 0;
+  if (lmp->atom->natoms > MAXSMALLINT) return 0;
   int natoms = static_cast<int> (lmp->atom->natoms);
   return natoms;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void lammps_get_coords(void *ptr, double *coords)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
 
   // error if tags are not defined or not consecutive
 
   if (lmp->atom->tag_enable == 0 || lmp->atom->tag_consecutive() == 0) return;
-  if (lmp->atom->natoms > MAXINT32) return;
+  if (lmp->atom->natoms > MAXSMALLINT) return;
 
   int natoms = static_cast<int> (lmp->atom->natoms);
   double *copy = new double[3*natoms];
   for (int i = 0; i < 3*natoms; i++) copy[i] = 0.0;
 
   double **x = lmp->atom->x;
   int *tag = lmp->atom->tag;
   int nlocal = lmp->atom->nlocal;
 
   int id,offset;
   for (int i = 0; i < nlocal; i++) {
     id = tag[i];
     offset = 3*(id-1);
     copy[offset+0] = x[i][0];
     copy[offset+1] = x[i][1];
     copy[offset+2] = x[i][2];
   }
 
   MPI_Allreduce(copy,coords,3*natoms,MPI_DOUBLE,MPI_SUM,lmp->world);
   delete [] copy;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void lammps_put_coords(void *ptr, double *coords)
 {
   LAMMPS *lmp = (LAMMPS *) ptr;
 
   // error if no map defined by LAMMPS
 
   if (lmp->atom->map_style == 0) return;
-  if (lmp->atom->natoms > MAXINT32) return;
+  if (lmp->atom->natoms > MAXSMALLINT) return;
 
   int natoms = static_cast<int> (lmp->atom->natoms);
   double **x = lmp->atom->x;
 
   int m,offset;
   for (int i = 0; i < natoms; i++) {
     if ((m = lmp->atom->map(i+1)) >= 0) {
       offset = 3*i;
       x[m][0] = coords[offset+0];
       x[m][1] = coords[offset+1];
       x[m][2] = coords[offset+2];
     }
   }
 }
diff --git a/src/lmptype.h b/src/lmptype.h
index 1ab30c82c..84c135e24 100644
--- a/src/lmptype.h
+++ b/src/lmptype.h
@@ -1,26 +1,118 @@
 /* ----------------------------------------------------------------------
    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.
 ------------------------------------------------------------------------- */
 
+// define integer data types used by LAMMPS and associated size limits
+
+// smallint = variables for system on 1 processor (nlocal, etc)
+// tagint = variables for atom IDs (tag)
+// bigint = variables for total system (natoms, ntimestep, etc)
+
+// smallint must be an int, as defined by C compiler
+// tagint can be 32-bit or 64-bit int, must be >= smallint
+// NOTE: 64-bit tagint is not yet supported
+// bigint can be 32-bit or 64-bit int, must be >= tagint
+
+// MAXSMALLINT = max value of a smallint
+// MAXTAGINT = max value of a tagint
+// MAXBIGINT = max value of a bigint
+
+// MPI_LMP_TAGINT = MPI data type corresponding to tagint
+// MPI_LMP_BIGINT = MPI data type corresponding to bigint
+
+// NOTE: if your machine/MPI does not support "long long" ints,
+//       but only "long" ints, then you will likely need to set
+//       MPI_LMP_BIGINT to MPI_LONG, LLONG_MAX to LONG_MAX,
+//       "lld" to "ld", and ATOBIGINT to atol
+
 #ifndef LMP_LMPTYPE_H
 #define LMP_LMPTYPE_H
 
+#include "limits.h"
 #include "stdint.h"
 
 namespace LAMMPS_NS {
 
-typedef uint64_t bigint;
-#define MAXINT32 0x7FFFFFFF
+// default settings
+// 32-bit smallint and tagint, 64-bit bigint
+
+typedef int smallint;
+typedef int tagint;
+typedef int64_t bigint;
+
+#define MAXSMALLINT INT_MAX
+#define MAXTAGINT INT_MAX
+#define MAXBIGINT LLONG_MAX
+
+#define MPI_LMP_TAGINT MPI_INT
+#define MPI_LMP_BIGINT MPI_LONG_LONG
+
+#define TAGINT_FORMAT "%d"
+#define BIGINT_FORMAT "%lld"
+#define TAGINT_FORMAT_NL "%d\n"
+#define BIGINT_FORMAT_NL "%lld\n"
+
+#define ATOTAGINT atoi
+#define ATOBIGINT atoll
+
+// for molecular problems that exceed 2 billion (2^31) atoms
+// 32-bit smallint, 64-bit tagint and bigint
+// NOTE: 64-bit tagint is not yet supported
+
+/*
+typedef int smallint;
+typedef int64_t tagint;
+typedef int64_t bigint;
+
+#define MAXSMALLINT INT_MAX
+#define MAXTAGINT LLONG_MAX
+#define MAXBIGINT LLONG_MAX
+
+#define MPI_LMP_TAGINT MPI_LONG_LONG
+#define MPI_LMP_BIGINT MPI_LONG_LONG
+
+#define TAGINT_FORMAT "%lld"
+#define BIGINT_FORMAT "%lld"
+#define TAGINT_FORMAT_NL "%lld\n"
+#define BIGINT_FORMAT_NL "%lld\n"
+
+#define ATOTAGINT atoll
+#define ATOBIGINT atoll
+*/
+
+// for machines that do not support 64-bit ints
+// 32-bit smallint and tagint and bigint
+
+/*
+typedef int smallint;
+typedef int tagint;
+typedef int bigint;
+
+#define MAXSMALLINT INT_MAX
+#define MAXTAGINT INT_MAX
+#define MAXBIGINT INT_MAX
+
+#define MPI_LMP_TAGINT MPI_INT
+#define MPI_LMP_BIGINT MPI_INT
+
+#define TAGINT_FORMAT "%d"
+#define BIGINT_FORMAT "%d"
+#define TAGINT_FORMAT_NL "%d\n"
+#define BIGINT_FORMAT_NL "%d\n"
+
+#define ATOTAGINT atoi
+#define ATOBIGINT atoi
+*/
 
 }
 
 #endif
diff --git a/src/min.cpp b/src/min.cpp
index 8f58ceae5..255bdfb60 100644
--- a/src/min.cpp
+++ b/src/min.cpp
@@ -1,764 +1,765 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 /* ----------------------------------------------------------------------
    Contributing author: Aidan Thompson (SNL)
                         improved CG and backtrack ls, added quadratic ls
    Sources: Numerical Recipes frprmn routine
             "Conjugate Gradient Method Without the Agonizing Pain" by
             JR Shewchuk, http://www-2.cs.cmu.edu/~jrs/jrspapers.html#cg
 ------------------------------------------------------------------------- */
 
 #include "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "min.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "domain.h"
 #include "comm.h"
 #include "update.h"
 #include "modify.h"
 #include "fix_minimize.h"
 #include "compute.h"
 #include "neighbor.h"
 #include "force.h"
 #include "pair.h"
 #include "bond.h"
 #include "angle.h"
 #include "dihedral.h"
 #include "improper.h"
 #include "kspace.h"
 #include "output.h"
 #include "thermo.h"
 #include "timer.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 /* ---------------------------------------------------------------------- */
 
 Min::Min(LAMMPS *lmp) : Pointers(lmp)
 {
   dmax = 0.1;
   searchflag = 0;
   linestyle = 0;
 
   elist_global = elist_atom = NULL;
   vlist_global = vlist_atom = NULL;
 
   nextra_global = 0;
   fextra = NULL;
 
   nextra_atom = 0;
   xextra_atom = fextra_atom = NULL;
   extra_peratom = extra_nlen = NULL;
   extra_max = NULL;
   requestor = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
 
 Min::~Min()
 {
   delete [] elist_global;
   delete [] elist_atom;
   delete [] vlist_global;
   delete [] vlist_atom;
 
   delete [] fextra;
 
   memory->sfree(xextra_atom);
   memory->sfree(fextra_atom);
   memory->sfree(extra_peratom);
   memory->sfree(extra_nlen);
   memory->sfree(extra_max);
   memory->sfree(requestor);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Min::init()
 {
   // create fix needed for storing atom-based quantities
   // will delete it at end of run
 
   char **fixarg = new char*[3];
   fixarg[0] = (char *) "MINIMIZE";
   fixarg[1] = (char *) "all";
   fixarg[2] = (char *) "MINIMIZE";
   modify->add_fix(3,fixarg);
   delete [] fixarg;
   fix_minimize = (FixMinimize *) modify->fix[modify->nfix-1];
 
   // clear out extra global and per-atom dof
   // will receive requests for new per-atom dof during pair init()
   // can then add vectors to fix_minimize in setup()
 
   nextra_global = 0;
   delete [] fextra;
   fextra = NULL;
 
   nextra_atom = 0;
   memory->sfree(xextra_atom);
   memory->sfree(fextra_atom);
   memory->sfree(extra_peratom);
   memory->sfree(extra_nlen);
   memory->sfree(extra_max);
   memory->sfree(requestor);
   xextra_atom = fextra_atom = NULL;
   extra_peratom = extra_nlen = NULL;
   extra_max = NULL;
   requestor = NULL;
 
   // virial_style:
   // 1 if computed explicitly by pair->compute via sum over pair interactions
   // 2 if computed implicitly by pair->virial_compute via sum over ghost atoms
 
   if (force->newton_pair) virial_style = 2;
   else virial_style = 1;
 
   // setup lists of computes for global and per-atom PE and pressure
 
   ev_setup();
 
   // set flags for what arrays to clear in force_clear()
   // need to clear torques,erforce if arrays exists
 
   torqueflag = 0;
   if (atom->torque_flag) torqueflag = 1;
   erforceflag = 0;
   if (atom->erforce_flag) erforceflag = 1;
 
   // orthogonal vs triclinic simulation box
 
   triclinic = domain->triclinic;
 
   // reset reneighboring criteria if necessary
 
   neigh_every = neighbor->every;
   neigh_delay = neighbor->delay;
   neigh_dist_check = neighbor->dist_check;
   
   if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) {
     if (comm->me == 0) 
       error->warning("Resetting reneighboring criteria during minimization");
   }
 
   neighbor->every = 1;
   neighbor->delay = 0;
   neighbor->dist_check = 1;
 
   niter = neval = 0;
 
   // style-specific initialization
 
   init_style();
 }
 
 /* ----------------------------------------------------------------------
    setup before run
 ------------------------------------------------------------------------- */
 
 void Min::setup()
 {
   if (comm->me == 0 && screen) fprintf(screen,"Setting up minimization ...\n");
 
   // setup extra global dof due to fixes
   // cannot be done in init() b/c update init() is before modify init()
 
   nextra_global = modify->min_dof();
   if (nextra_global) fextra = new double[nextra_global];
 
   // compute for potential energy
 
   int id = modify->find_compute("thermo_pe");
   if (id < 0) error->all("Minimization could not find thermo_pe compute");
   pe_compute = modify->compute[id];
 
   // style-specific setup does two tasks
   // setup extra global dof vectors
   // setup extra per-atom dof vectors due to requests from Pair classes
   // cannot be done in init() b/c update init() is before modify/pair init()
 
   setup_style();
 
   // ndoftotal = total dof for entire minimization problem
   // dof for atoms, extra per-atom, extra global
 
   bigint ndofme = 3*atom->nlocal;
   for (int m = 0; m < nextra_atom; m++)
     ndofme += extra_peratom[m]*atom->nlocal;
-  MPI_Allreduce(&ndofme,&ndoftotal,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&ndofme,&ndoftotal,1,MPI_LMP_BIGINT,MPI_SUM,world);
   ndoftotal += nextra_global;
 
   // setup domain, communication and neighboring
   // acquire ghosts
   // build neighbor lists
 
   atom->setup();
   if (triclinic) domain->x2lamda(atom->nlocal);
   domain->pbc();
   domain->reset_box();
   comm->setup();
   if (neighbor->style) neighbor->setup_bins();
   comm->exchange();
   if (atom->sortfreq > 0) atom->sort();
   comm->borders();
   if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
   neighbor->build();
   neighbor->ncalls = 0;
 
   // remove these restriction eventually
 
   if (nextra_global && searchflag == 0)
     error->all("Cannot use a damped dynamics min style with fix box/relax");
   if (nextra_atom && searchflag == 0)
     error->all("Cannot use a damped dynamics min style with per-atom DOF");
 
   // atoms may have migrated in comm->exchange()
 
   reset_vectors();
 
   // compute all forces
 
   ev_set(update->ntimestep);
   force_clear();
   modify->setup_pre_force(vflag);
 
   if (force->pair) force->pair->compute(eflag,vflag);
 
   if (atom->molecular) {
     if (force->bond) force->bond->compute(eflag,vflag);
     if (force->angle) force->angle->compute(eflag,vflag);
     if (force->dihedral) force->dihedral->compute(eflag,vflag);
     if (force->improper) force->improper->compute(eflag,vflag);
   }
 
   if (force->kspace) {
     force->kspace->setup();
     force->kspace->compute(eflag,vflag);
   }
 
   if (force->newton) comm->reverse_comm();
 
   // update per-atom minimization variables stored by pair styles
 
   if (nextra_atom)
     for (int m = 0; m < nextra_atom; m++)
       requestor[m]->min_xf_get(m);
 
   modify->setup(vflag);
   output->setup(1);
 
   // stats for Finish to print
 
   ecurrent = pe_compute->compute_scalar();
   if (nextra_global) ecurrent += modify->min_energy(fextra);
   if (output->thermo->normflag) ecurrent /= atom->natoms;
 	
   einitial = ecurrent;
   fnorm2_init = sqrt(fnorm_sqr());
   fnorminf_init = fnorm_inf();
 }
 
 /* ----------------------------------------------------------------------
    setup without output or one-time post-init setup
    flag = 0 = just force calculation
    flag = 1 = reneighbor and force calculation
 ------------------------------------------------------------------------- */
 
 void Min::setup_minimal(int flag)
 {
   // setup domain, communication and neighboring
   // acquire ghosts
   // build neighbor lists
 
   if (flag) {
     if (triclinic) domain->x2lamda(atom->nlocal);
     domain->pbc();
     domain->reset_box();
     comm->setup();
     if (neighbor->style) neighbor->setup_bins();
     comm->exchange();
     comm->borders();
     if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
     neighbor->build();
     neighbor->ncalls = 0;
   }
 
   // atoms may have migrated in comm->exchange()
 
   reset_vectors();
 
   // compute all forces
 
   ev_set(update->ntimestep);
   force_clear();
   modify->setup_pre_force(vflag);
 
   if (force->pair) force->pair->compute(eflag,vflag);
 
   if (atom->molecular) {
     if (force->bond) force->bond->compute(eflag,vflag);
     if (force->angle) force->angle->compute(eflag,vflag);
     if (force->dihedral) force->dihedral->compute(eflag,vflag);
     if (force->improper) force->improper->compute(eflag,vflag);
   }
 
   if (force->kspace) {
     force->kspace->setup();
     force->kspace->compute(eflag,vflag);
   }
 
   if (force->newton) comm->reverse_comm();
 
   // update per-atom minimization variables stored by pair styles
 
   if (nextra_atom)
     for (int m = 0; m < nextra_atom; m++)
       requestor[m]->min_xf_get(m);
 
   modify->setup(vflag);
 
   // stats for Finish to print
 
   ecurrent = pe_compute->compute_scalar();
   if (nextra_global) ecurrent += modify->min_energy(fextra);
   if (output->thermo->normflag) ecurrent /= atom->natoms;
 	
   einitial = ecurrent;
   fnorm2_init = sqrt(fnorm_sqr());
   fnorminf_init = fnorm_inf();
 }
 
 /* ----------------------------------------------------------------------
    perform minimization, calling iterate() for N steps
 ------------------------------------------------------------------------- */
 
 void Min::run(int n)
 {
   // minimizer iterations
 
   int iter_start = niter;
   stop_condition = iterate(n);
   stopstr = stopstrings(stop_condition);
 
   // if early exit from iterate loop:
   // set update->nsteps to niter for Finish stats to print
   // set output->next values to this timestep
   // call energy_force() to insure vflag is set when forces computed
   // output->write does final output for thermo, dump, restart files
   // add ntimestep to all computes that store invocation times
   //   since are hardwiring call to thermo/dumps and computes may not be ready
 
   if (stop_condition) {
     update->nsteps = niter;
 
     if (update->restrict_output == 0) {
       for (int idump = 0; idump < output->ndump; idump++)
 	output->next_dump[idump] = update->ntimestep;
       output->next_dump_any = update->ntimestep;
       if (output->restart_every) output->next_restart = update->ntimestep;
     }
     output->next_thermo = update->ntimestep;
 
     modify->addstep_compute_all(update->ntimestep);
     ecurrent = energy_force(0);
     output->write(update->ntimestep);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Min::cleanup()
 {
   // stats for Finish to print
 	
   efinal = ecurrent;
   fnorm2_final = sqrt(fnorm_sqr());
   fnorminf_final = fnorm_inf();
 
   // reset reneighboring criteria
 
   neighbor->every = neigh_every;
   neighbor->delay = neigh_delay;
   neighbor->dist_check = neigh_dist_check;
 
   // delete fix at end of run, so its atom arrays won't persist
 
   modify->delete_fix("MINIMIZE");
 }
 
 /* ----------------------------------------------------------------------
    evaluate potential energy and forces
    may migrate atoms due to reneighboring
    return new energy, which should include nextra_global dof
    return negative gradient stored in atom->f
    return negative gradient for nextra_global dof in fextra
 ------------------------------------------------------------------------- */
 
 double Min::energy_force(int resetflag)
 {
   // check for reneighboring
   // always communicate since minimizer moved atoms
 
   int nflag = neighbor->decide();
 
   if (nflag == 0) {
     timer->stamp();
     comm->forward_comm();
     timer->stamp(TIME_COMM);
   } else {
     if (modify->n_min_pre_exchange) modify->min_pre_exchange();
     if (triclinic) domain->x2lamda(atom->nlocal);
     domain->pbc();
     if (domain->box_change) {
       domain->reset_box();
       comm->setup();
       if (neighbor->style) neighbor->setup_bins();
     }
     timer->stamp();
     comm->exchange();
     if (atom->sortfreq > 0 && 
 	update->ntimestep >= atom->nextsort) atom->sort();
     comm->borders();
     if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
     timer->stamp(TIME_COMM);
     neighbor->build();
     timer->stamp(TIME_NEIGHBOR);
   }
 
   ev_set(update->ntimestep);
   force_clear();
   if (modify->n_min_pre_force) modify->min_pre_force(vflag);
 
   timer->stamp();
 
   if (force->pair) {
     force->pair->compute(eflag,vflag);
     timer->stamp(TIME_PAIR);
   }
 
   if (atom->molecular) {
     if (force->bond) force->bond->compute(eflag,vflag);
     if (force->angle) force->angle->compute(eflag,vflag);
     if (force->dihedral) force->dihedral->compute(eflag,vflag);
     if (force->improper) force->improper->compute(eflag,vflag);
     timer->stamp(TIME_BOND);
   }
 
   if (force->kspace) {
     force->kspace->compute(eflag,vflag);
     timer->stamp(TIME_KSPACE);
   }
 
   if (force->newton) {
     comm->reverse_comm();
     timer->stamp(TIME_COMM);
   }
 
   // update per-atom minimization variables stored by pair styles
 
   if (nextra_atom)
     for (int m = 0; m < nextra_atom; m++)
       requestor[m]->min_xf_get(m);
 
   // fixes that affect minimization
 
   if (modify->n_min_post_force) modify->min_post_force(vflag);
 
   // compute potential energy of system
   // normalize if thermo PE does
 
   double energy = pe_compute->compute_scalar();
   if (nextra_global) energy += modify->min_energy(fextra);
   if (output->thermo->normflag) energy /= atom->natoms;
 
   // if reneighbored, atoms migrated
   // if resetflag = 1, update x0 of atoms crossing PBC
   // reset vectors used by lo-level minimizer
 
   if (nflag) {
     if (resetflag) fix_minimize->reset_coords();
     reset_vectors();
   }
 
   return energy;
 }
 
 /* ----------------------------------------------------------------------
    clear force on own & ghost atoms
    setup and clear other arrays as needed
 ------------------------------------------------------------------------- */
 
 void Min::force_clear()
 {
   int i;
 
   // clear global force array
   // nall includes ghosts only if either newton flag is set
 
   int nall;
   if (force->newton) nall = atom->nlocal + atom->nghost;
   else nall = atom->nlocal;
 
   double **f = atom->f;
   for (i = 0; i < nall; i++) {
     f[i][0] = 0.0;
     f[i][1] = 0.0;
     f[i][2] = 0.0;
   }
 
   if (torqueflag) {
     double **torque = atom->torque;
     for (i = 0; i < nall; i++) {
       torque[i][0] = 0.0;
       torque[i][1] = 0.0;
       torque[i][2] = 0.0;
     }
   }
 
   if (erforceflag) {
     double *erforce = atom->erforce;
     for (i = 0; i < nall; i++)
       erforce[i] = 0.0;
   }
 }
 
 /* ----------------------------------------------------------------------
    pair style makes request to add a per-atom variables to minimization
    requestor stores callback to pair class to invoke during min
      to get current variable and forces on it and to update the variable
    return flag that pair can use if it registers multiple variables
 ------------------------------------------------------------------------- */
 
 int Min::request(Pair *pair, int peratom, double maxvalue)
 {
   int n = nextra_atom + 1;
   xextra_atom = (double **) memory->srealloc(xextra_atom,n*sizeof(double *),
 					     "min:xextra_atom");
   fextra_atom = (double **) memory->srealloc(fextra_atom,n*sizeof(double *),
 					     "min:fextra_atom");
   extra_peratom = (int *) memory->srealloc(extra_peratom,n*sizeof(int),
 					   "min:extra_peratom");
   extra_nlen = (int *) memory->srealloc(extra_nlen,n*sizeof(int),
 					"min:extra_nlen");
   extra_max = (double *) memory->srealloc(extra_max,n*sizeof(double),
 					  "min:extra_max");
   requestor = (Pair **) memory->srealloc(requestor,n*sizeof(Pair *),
 					 "min:requestor");
 
   requestor[nextra_atom] = pair;
   extra_peratom[nextra_atom] = peratom;
   extra_max[nextra_atom] = maxvalue;
   nextra_atom++;
   return nextra_atom-1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Min::modify_params(int narg, char **arg)
 {
   if (narg == 0) error->all("Illegal min_modify command");
 
   int iarg = 0;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"dmax") == 0) {
       if (iarg+2 > narg) error->all("Illegal min_modify command");
       dmax = atof(arg[iarg+1]);
       iarg += 2;
     } else if (strcmp(arg[iarg],"line") == 0) {
       if (iarg+2 > narg) error->all("Illegal min_modify command");
       if (strcmp(arg[iarg+1],"backtrack") == 0) linestyle = 0;
       else if (strcmp(arg[iarg+1],"quadratic") == 0) linestyle = 1;
       else error->all("Illegal min_modify command");
       iarg += 2;
     } else error->all("Illegal min_modify command");
   }
 }
 
 /* ----------------------------------------------------------------------
    setup lists of computes for global and per-atom PE and pressure
 ------------------------------------------------------------------------- */
 
 void Min::ev_setup()
 {
   delete [] elist_global;
   delete [] elist_atom;
   delete [] vlist_global;
   delete [] vlist_atom;
   elist_global = elist_atom = NULL;
   vlist_global = vlist_atom = NULL;
 
   nelist_global = nelist_atom = 0;
   nvlist_global = nvlist_atom = 0;
   for (int i = 0; i < modify->ncompute; i++) {
     if (modify->compute[i]->peflag) nelist_global++;
     if (modify->compute[i]->peatomflag) nelist_atom++;
     if (modify->compute[i]->pressflag) nvlist_global++;
     if (modify->compute[i]->pressatomflag) nvlist_atom++;
   }
 
   if (nelist_global) elist_global = new Compute*[nelist_global];
   if (nelist_atom) elist_atom = new Compute*[nelist_atom];
   if (nvlist_global) vlist_global = new Compute*[nvlist_global];
   if (nvlist_atom) vlist_atom = new Compute*[nvlist_atom];
 
   nelist_global = nelist_atom = 0;
   nvlist_global = nvlist_atom = 0;
   for (int i = 0; i < modify->ncompute; i++) {
     if (modify->compute[i]->peflag)
       elist_global[nelist_global++] = modify->compute[i];
     if (modify->compute[i]->peatomflag)
       elist_atom[nelist_atom++] = modify->compute[i];
     if (modify->compute[i]->pressflag)
       vlist_global[nvlist_global++] = modify->compute[i];
     if (modify->compute[i]->pressatomflag)
       vlist_atom[nvlist_atom++] = modify->compute[i];
   }
 }
 
 /* ----------------------------------------------------------------------
    set eflag,vflag for current iteration
    invoke matchstep() on all timestep-dependent computes to clear their arrays
    eflag/vflag based on computes that need info on this ntimestep
    always set eflag_global = 1, since need energy every iteration
    eflag = 0 = no energy computation
    eflag = 1 = global energy only
    eflag = 2 = per-atom energy only
    eflag = 3 = both global and per-atom energy
    vflag = 0 = no virial computation (pressure)
    vflag = 1 = global virial with pair portion via sum of pairwise interactions
    vflag = 2 = global virial with pair portion via F dot r including ghosts
    vflag = 4 = per-atom virial only
    vflag = 5 or 6 = both global and per-atom virial
 ------------------------------------------------------------------------- */
 
-void Min::ev_set(int ntimestep)
+void Min::ev_set(bigint ntimestep)
 {
   int i,flag;
 
   int eflag_global = 1;
   for (i = 0; i < nelist_global; i++)
     elist_global[i]->matchstep(ntimestep);
 
   flag = 0;
   int eflag_atom = 0;
   for (i = 0; i < nelist_atom; i++)
     if (elist_atom[i]->matchstep(ntimestep)) flag = 1;
   if (flag) eflag_atom = 2;
 
   if (eflag_global) update->eflag_global = update->ntimestep;
   if (eflag_atom) update->eflag_atom = update->ntimestep;
   eflag = eflag_global + eflag_atom;
 
   flag = 0;
   int vflag_global = 0;
   for (i = 0; i < nvlist_global; i++)
     if (vlist_global[i]->matchstep(ntimestep)) flag = 1;
   if (flag) vflag_global = virial_style;
 
   flag = 0;
   int vflag_atom = 0;
   for (i = 0; i < nvlist_atom; i++)
     if (vlist_atom[i]->matchstep(ntimestep)) flag = 1;
   if (flag) vflag_atom = 4;
 
   if (vflag_global) update->vflag_global = update->ntimestep;
   if (vflag_atom) update->vflag_atom = update->ntimestep;
   vflag = vflag_global + vflag_atom;
 }
 
 /* ----------------------------------------------------------------------
    compute and return ||force||_2^2
 ------------------------------------------------------------------------- */
 
 double Min::fnorm_sqr()
 {
   int i,n;
   double *fatom;
 
   double local_norm2_sqr = 0.0;
   for (i = 0; i < nvec; i++) local_norm2_sqr += fvec[i]*fvec[i];
   if (nextra_atom) {
     for (int m = 0; m < nextra_atom; m++) {
       fatom = fextra_atom[m];
       n = extra_nlen[m];
       for (i = 0; i < n; i++)
 	local_norm2_sqr += fatom[i]*fatom[i];
     }
   }
 
   double norm2_sqr = 0.0;
   MPI_Allreduce(&local_norm2_sqr,&norm2_sqr,1,MPI_DOUBLE,MPI_SUM,world);
 
   if (nextra_global)
     for (i = 0; i < nextra_global; i++) 
       norm2_sqr += fextra[i]*fextra[i];
   
   return norm2_sqr;
 }
 
 /* ----------------------------------------------------------------------
    compute and return ||force||_inf
 ------------------------------------------------------------------------- */
 
 double Min::fnorm_inf()
 {
   int i,n;
   double *fatom;
 
   double local_norm_inf = 0.0;
   for (i = 0; i < nvec; i++)
     local_norm_inf = MAX(fabs(fvec[i]),local_norm_inf);
   if (nextra_atom) {
     for (int m = 0; m < nextra_atom; m++) {
       fatom = fextra_atom[m];
       n = extra_nlen[m];
       for (i = 0; i < n; i++)
 	local_norm_inf = MAX(fabs(fatom[i]),local_norm_inf);
     }
   }
 
   double norm_inf = 0.0;
   MPI_Allreduce(&local_norm_inf,&norm_inf,1,MPI_DOUBLE,MPI_MAX,world);
 
   if (nextra_global)
     for (i = 0; i < nextra_global; i++) 
       norm_inf = MAX(fabs(fextra[i]),norm_inf);
 
   return norm_inf;
 }
 
 /* ----------------------------------------------------------------------
    possible stop conditions
 ------------------------------------------------------------------------- */
 
 char *Min::stopstrings(int n)
 {
   char *strings[] = {"max iterations",
 		     "max force evaluations",
 		     "energy tolerance",
 		     "force tolerance",
 		     "search direction is not downhill",
 		     "linesearch alpha is zero",
 		     "forces are zero",
 		     "quadratic factors are zero",
 		     "trust region too small",
 		     "HFTN minimizer error"};
   return strings[n];
 }
diff --git a/src/min.h b/src/min.h
index f4626514e..7b0990333 100644
--- a/src/min.h
+++ b/src/min.h
@@ -1,108 +1,108 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_MIN_H
 #define LMP_MIN_H
 
 #include "pointers.h"
 #include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class Min : protected Pointers {
  public:
   double einitial,efinal,eprevious;
   double fnorm2_init,fnorminf_init,fnorm2_final,fnorminf_final;
   double alpha_final;
   int niter,neval;
   int stop_condition;
   char *stopstr;
   int searchflag;     // 0 if damped dynamics, 1 if sub-cycles on local search
 
   Min(class LAMMPS *);
   virtual ~Min();
   void init();
   void setup();
   void setup_minimal(int);
   void run(int);
   void cleanup();
   int request(class Pair *, int, double);
   double memory_usage() {return 0.0;}
   void modify_params(int, char **);
   double fnorm_sqr();
   double fnorm_inf();
 
   virtual void init_style() {}
   virtual void setup_style() = 0;
   virtual void reset_vectors() = 0;
   virtual int iterate(int) = 0;
 
  protected:
   int eflag,vflag;            // flags for energy/virial computation
   int virial_style;           // compute virial explicitly or implicitly
 
   double dmax;                // max dist to move any atom in one step
   int linestyle;              // 0 = backtrack, 1 = quadratic
 
   int nelist_global,nelist_atom;    // # of PE,virial computes to check
   int nvlist_global,nvlist_atom;
   class Compute **elist_global;     // lists of PE,virial Computes
   class Compute **elist_atom;
   class Compute **vlist_global;
   class Compute **vlist_atom;
 
   int pairflag;
   int torqueflag,erforceflag;
   int triclinic;              // 0 if domain is orthog, 1 if triclinic
 
   int narray;                       // # of arrays stored by fix_minimize
   class FixMinimize *fix_minimize;  // fix that stores auxiliary data
 
   class Compute *pe_compute;        // compute for potential energy
   double ecurrent;                  // current potential energy
 
   bigint ndoftotal;           // total dof for entire problem
 
   int nvec;                   // local atomic dof = length of xvec
   double *xvec;               // variables for atomic dof, as 1d vector
   double *fvec;               // force vector for atomic dof, as 1d vector
 
   int nextra_global;          // # of extra global dof due to fixes
   double *fextra;             // force vector for extra global dof
                               // xextra is stored by fix
 
   int nextra_atom;            // # of extra per-atom variables
   double **xextra_atom;       // ptr to the variable
   double **fextra_atom;       // ptr to the force on the variable
   int *extra_peratom;         // # of values in variable, e.g. 3 in x
   int *extra_nlen;            // total local length of variable, e.g 3*nlocal
   double *extra_max;          // max allowed change per iter for atom's var
   class Pair **requestor;     // Pair that stores/manipulates the variable
 
   int neigh_every,neigh_delay,neigh_dist_check;  // neighboring params
 
   double energy_force(int);
   void force_clear();
 
   double compute_force_norm_sqr();
   double compute_force_norm_inf();
 
   void ev_setup();
-  void ev_set(int);
+  void ev_set(bigint);
 
   char *stopstrings(int);
 };
 
 }
 
 #endif
diff --git a/src/min_cg.cpp b/src/min_cg.cpp
index 63ed35fdd..9ad87904f 100644
--- a/src/min_cg.cpp
+++ b/src/min_cg.cpp
@@ -1,187 +1,187 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "string.h"
 #include "min_cg.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "update.h"
 #include "output.h"
 #include "timer.h"
 
 using namespace LAMMPS_NS;
 
 // EPS_ENERGY = minimum normalization for energy tolerance
 
 #define EPS_ENERGY 1.0e-8
 
 // same as in other min classes
 
 enum{MAXITER,MAXEVAL,ETOL,FTOL,DOWNHILL,ZEROALPHA,ZEROFORCE,ZEROQUAD};
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 /* ---------------------------------------------------------------------- */
 
 MinCG::MinCG(LAMMPS *lmp) : MinLineSearch(lmp) {}
 
 /* ----------------------------------------------------------------------
    minimization via conjugate gradient iterations
 ------------------------------------------------------------------------- */
 
 int MinCG::iterate(int maxiter)
 {
   int i,m,n,fail,ntimestep;
   double beta,gg,dot[2],dotall[2];
   double *fatom,*gatom,*hatom;
 
   // nlimit = max # of CG iterations before restarting
   // set to ndoftotal unless too big
 
-  int nlimit = static_cast<int> (MIN(MAXINT32,ndoftotal));
+  int nlimit = static_cast<int> (MIN(MAXSMALLINT,ndoftotal));
 
   // initialize working vectors
 
   for (i = 0; i < nvec; i++) h[i] = g[i] = fvec[i];
   if (nextra_atom)
     for (m = 0; m < nextra_atom; m++) {
       fatom = fextra_atom[m];
       gatom = gextra_atom[m];
       hatom = hextra_atom[m];
       n = extra_nlen[m];
       for (i = 0; i < n; i++) hatom[i] = gatom[i] = fatom[i];
     }
   if (nextra_global)
     for (i = 0; i < nextra_global; i++) hextra[i] = gextra[i] = fextra[i];
 
   gg = fnorm_sqr();
 
   for (int iter = 0; iter < maxiter; iter++) {
     ntimestep = ++update->ntimestep;
     niter++;
 
     // line minimization along direction h from current atom->x
 
     eprevious = ecurrent;
     fail = (this->*linemin)(ecurrent,alpha_final);    
     if (fail) return fail;
 
     // function evaluation criterion
 
     if (neval >= update->max_eval) return MAXEVAL;
 
     // energy tolerance criterion
 
     if (fabs(ecurrent-eprevious) < 
 	update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY))
       return ETOL;
 
     // force tolerance criterion
 
     dot[0] = dot[1] = 0.0;
     for (i = 0; i < nvec; i++) {
       dot[0] += fvec[i]*fvec[i];
       dot[1] += fvec[i]*g[i];
     }
     if (nextra_atom)
       for (m = 0; m < nextra_atom; m++) {
 	fatom = fextra_atom[m];
 	gatom = gextra_atom[m];
 	n = extra_nlen[m];
 	for (i = 0; i < n; i++) {
 	  dot[0] += fatom[i]*fatom[i];
 	  dot[1] += fatom[i]*gatom[i];
 	}
       }
     MPI_Allreduce(dot,dotall,2,MPI_DOUBLE,MPI_SUM,world);
     if (nextra_global)
       for (i = 0; i < nextra_global; i++) {
 	dotall[0] += fextra[i]*fextra[i];
 	dotall[1] += fextra[i]*gextra[i];
       }
 
     if (dotall[0] < update->ftol*update->ftol) return FTOL;
 
     // update new search direction h from new f = -Grad(x) and old g
     // this is Polak-Ribieri formulation
     // beta = dotall[0]/gg would be Fletcher-Reeves
     // reinitialize CG every ndof iterations by setting beta = 0.0
 
     beta = MAX(0.0,(dotall[0] - dotall[1])/gg);
     if ((niter+1) % nlimit == 0) beta = 0.0;
     gg = dotall[0];
 
     for (i = 0; i < nvec; i++) {
       g[i] = fvec[i];
       h[i] = g[i] + beta*h[i];
     }
     if (nextra_atom)
       for (m = 0; m < nextra_atom; m++) {
 	fatom = fextra_atom[m];
 	gatom = gextra_atom[m];
 	hatom = hextra_atom[m];
 	n = extra_nlen[m];
 	for (i = 0; i < n; i++) {
 	  gatom[i] = fatom[i];
 	  hatom[i] = gatom[i] + beta*hatom[i];
 	}
       }
     if (nextra_global)
       for (i = 0; i < nextra_global; i++) {
 	gextra[i] = fextra[i];
 	hextra[i] = gextra[i] + beta*hextra[i];
       }
 
     // reinitialize CG if new search direction h is not downhill
 
     dot[0] = 0.0;
     for (i = 0; i < nvec; i++) dot[0] += g[i]*h[i];
     if (nextra_atom)
       for (m = 0; m < nextra_atom; m++) {
 	gatom = gextra_atom[m];
 	hatom = hextra_atom[m];
 	n = extra_nlen[m];
 	for (i = 0; i < n; i++) dot[0] += gatom[i]*hatom[i];
       }
     MPI_Allreduce(dot,dotall,1,MPI_DOUBLE,MPI_SUM,world);
     if (nextra_global)
       for (i = 0; i < nextra_global; i++)
 	dotall[0] += gextra[i]*hextra[i];
 
     if (dotall[0] <= 0.0) {
       for (i = 0; i < nvec; i++) h[i] = g[i];
       if (nextra_atom)
 	for (m = 0; m < nextra_atom; m++) {
 	  gatom = gextra_atom[m];
 	  hatom = hextra_atom[m];
 	  n = extra_nlen[m];
 	  for (i = 0; i < n; i++) hatom[i] = gatom[i];
 	}
       if (nextra_global)
 	for (i = 0; i < nextra_global; i++) hextra[i] = gextra[i];
     }
 
     // output for thermo, dump, restart files
 
     if (output->next == ntimestep) {
       timer->stamp();
       output->write(ntimestep);
       timer->stamp(TIME_OUTPUT);
     }
   }
 
   return MAXITER;
 }
diff --git a/src/min_fire.cpp b/src/min_fire.cpp
index 135e51742..0c4e73dc2 100644
--- a/src/min_fire.cpp
+++ b/src/min_fire.cpp
@@ -1,272 +1,273 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "min_fire.h"
 #include "universe.h"
 #include "atom.h"
 #include "force.h"
 #include "update.h"
 #include "output.h"
 #include "timer.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 // EPS_ENERGY = minimum normalization for energy tolerance
 
 #define EPS_ENERGY 1.0e-8
 
 // same as in other min classes
 
 enum{MAXITER,MAXEVAL,ETOL,FTOL,DOWNHILL,ZEROALPHA,ZEROFORCE,ZEROQUAD};
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define DELAYSTEP 5
 #define DT_GROW 1.1
 #define DT_SHRINK 0.5
 #define ALPHA0 0.1
 #define ALPHA_SHRINK 0.99
 #define TMAX 10.0
 
 /* ---------------------------------------------------------------------- */
 
 MinFire::MinFire(LAMMPS *lmp) : Min(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 void MinFire::init_style()
 {
   dt = update->dt;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void MinFire::setup_style()
 {
   double **v = atom->v;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     v[i][0] = v[i][1] = v[i][2] = 0.0;
 }
 
 /* ----------------------------------------------------------------------
    set current vector lengths and pointers
    called after atoms have migrated
 ------------------------------------------------------------------------- */
 
 void MinFire::reset_vectors()
 {
   // atomic dof
 
   nvec = 3 * atom->nlocal;
   if (nvec) xvec = atom->x[0];
   if (nvec) fvec = atom->f[0];
 }
 
 /* ---------------------------------------------------------------------- */
 
 int MinFire::iterate(int maxiter)
 {
-  int ntimestep,flag,flagall;
+  bigint ntimestep;
   double vmax,vdotf,vdotfall,vdotv,vdotvall,fdotf,fdotfall;
   double scale1,scale2;
   double dtvone,dtv,dtfm;
+  int flag,flagall;
 
   alpha_final = 0.0;
   double alpha = ALPHA0;
   double dtmax = TMAX * dt;
-  int last_negative = update->ntimestep;
+  bigint last_negative = update->ntimestep;
 
   for (int iter = 0; iter < maxiter; iter++) {
     ntimestep = ++update->ntimestep;
     niter++;
 
     // vdotfall = v dot f
 
     double **v = atom->v;
     double **f = atom->f;
     int nlocal = atom->nlocal;
 
     vdotf = 0.0;
     for (int i = 0; i < nlocal; i++)
       vdotf += v[i][0]*f[i][0] + v[i][1]*f[i][1] + v[i][2]*f[i][2];
     MPI_Allreduce(&vdotf,&vdotfall,1,MPI_DOUBLE,MPI_SUM,world);
 
     // sum vdotf over replicas, if necessary
     // this communicator would be invalid for multiprocess replicas
 
     if (update->multireplica == 1) {
       vdotf = vdotfall;
       MPI_Allreduce(&vdotf,&vdotfall,1,MPI_DOUBLE,MPI_SUM,universe->uworld);
     }
 
     // if (v dot f) > 0:
     // v = (1-alpha) v + alpha |v| Fhat
     // |v| = length of v, Fhat = unit f
     // if more than DELAYSTEP since v dot f was negative:
     // increase timestep and decrease alpha
 
     if (vdotfall > 0.0) {
       vdotv = 0.0;
       for (int i = 0; i < nlocal; i++)
 	vdotv += v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2];
       MPI_Allreduce(&vdotv,&vdotvall,1,MPI_DOUBLE,MPI_SUM,world);
 
       // sum vdotv over replicas, if necessary
       // this communicator would be invalid for multiprocess replicas
 
       if (update->multireplica == 1) {
 	vdotv = vdotvall;
 	MPI_Allreduce(&vdotv,&vdotvall,1,MPI_DOUBLE,MPI_SUM,universe->uworld);
       }
 
       fdotf = 0.0;
       for (int i = 0; i < nlocal; i++)
 	fdotf += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2];
       MPI_Allreduce(&fdotf,&fdotfall,1,MPI_DOUBLE,MPI_SUM,world);
 
       // sum fdotf over replicas, if necessary
       // this communicator would be invalid for multiprocess replicas
       
       if (update->multireplica == 1) {
 	fdotf = fdotfall;
 	MPI_Allreduce(&fdotf,&fdotfall,1,MPI_DOUBLE,MPI_SUM,universe->uworld);
       }
 
       scale1 = 1.0 - alpha;
       if (fdotfall == 0.0) scale2 = 0.0;
       else scale2 = alpha * sqrt(vdotvall/fdotfall);
       for (int i = 0; i < nlocal; i++) {
 	v[i][0] = scale1*v[i][0] + scale2*f[i][0];
 	v[i][1] = scale1*v[i][1] + scale2*f[i][1];
 	v[i][2] = scale1*v[i][2] + scale2*f[i][2];
       }
 
       if (ntimestep - last_negative > DELAYSTEP) {
 	dt = MIN(dt*DT_GROW,dtmax);
 	alpha *= ALPHA_SHRINK;
       }
 
     // else (v dot f) <= 0:
     // decrease timestep, reset alpha, set v = 0
 
     } else {
       last_negative = ntimestep;
       dt *= DT_SHRINK;
       alpha = ALPHA0;
       for (int i = 0; i < nlocal; i++)
 	v[i][0] = v[i][1] = v[i][2] = 0.0;
     }
 
     // limit timestep so no particle moves further than dmax
 
     double *rmass = atom->rmass;
     double *mass = atom->mass;
     int *type = atom->type;
 
     dtvone = dt;
 
     for (int i = 0; i < nlocal; i++) {
       vmax = MAX(fabs(v[i][0]),fabs(v[i][1]));
       vmax = MAX(vmax,fabs(v[i][2]));
       if (dtvone*vmax > dmax) dtvone = dmax/vmax;
     }
     MPI_Allreduce(&dtvone,&dtv,1,MPI_DOUBLE,MPI_MIN,world);
 
     // min dtv over replicas, if necessary
     // this communicator would be invalid for multiprocess replicas
 
     if (update->multireplica == 1) {
       dtvone = dtv;
       MPI_Allreduce(&dtvone,&dtv,1,MPI_DOUBLE,MPI_MIN,universe->uworld);
     }
 
     // Euler integration step
 
     double **x = atom->x;
     
     if (rmass) {
       for (int i = 0; i < nlocal; i++) {
 	dtfm = dtv / rmass[i];
 	x[i][0] += dtv * v[i][0];
 	x[i][1] += dtv * v[i][1];
 	x[i][2] += dtv * v[i][2];
 	v[i][0] += dtfm * f[i][0];
 	v[i][1] += dtfm * f[i][1];
 	v[i][2] += dtfm * f[i][2];
       }
     } else {
       for (int i = 0; i < nlocal; i++) {
 	dtfm = dtv / mass[type[i]];
 	x[i][0] += dtv * v[i][0];
 	x[i][1] += dtv * v[i][1];
 	x[i][2] += dtv * v[i][2];
 	v[i][0] += dtfm * f[i][0];
 	v[i][1] += dtfm * f[i][1];
 	v[i][2] += dtfm * f[i][2];
       }
     }
     
     eprevious = ecurrent;
     ecurrent = energy_force(0);
     neval++;
 
     // energy tolerance criterion
     // only check after DELAYSTEP elapsed since velocties reset to 0
     // sync across replicas if running multi-replica minimization
 
     if (update->etol > 0.0 && ntimestep-last_negative > DELAYSTEP) {
       if (update->multireplica == 0) {
 	if (fabs(ecurrent-eprevious) < 
 	    update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY))
 	  return ETOL;
       } else {
 	if (fabs(ecurrent-eprevious) < 
 	    update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY))
 	  flag = 0;
 	else flag = 1;
 	MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld);
 	if (flagall == 0) return ETOL;
       }
     }
 
     // force tolerance criterion
     // sync across replicas if running multi-replica minimization
 
     if (update->ftol > 0.0) {
       fdotf = fnorm_sqr();
       if (update->multireplica == 0) {
 	if (fdotf < update->ftol*update->ftol) return FTOL;
       } else {
 	if (fdotf < update->ftol*update->ftol) flag = 0;
 	else flag = 1;
 	MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld);
 	if (flagall == 0) return FTOL;
       }
     }
 
     // output for thermo, dump, restart files
 
     if (output->next == ntimestep) {
       timer->stamp();
       output->write(ntimestep);
       timer->stamp(TIME_OUTPUT);
     }
   }
   
   return MAXITER;
 }
diff --git a/src/min_quickmin.cpp b/src/min_quickmin.cpp
index 89a3403d4..6fb15b175 100644
--- a/src/min_quickmin.cpp
+++ b/src/min_quickmin.cpp
@@ -1,238 +1,240 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "min_quickmin.h"
+#include "lmptype.h"
 #include "universe.h"
 #include "atom.h"
 #include "force.h"
 #include "update.h"
 #include "output.h"
 #include "timer.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 // EPS_ENERGY = minimum normalization for energy tolerance
 
 #define EPS_ENERGY 1.0e-8
 
 // same as in other min classes
 
 enum{MAXITER,MAXEVAL,ETOL,FTOL,DOWNHILL,ZEROALPHA,ZEROFORCE,ZEROQUAD};
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define DELAYSTEP 5
 
 /* ---------------------------------------------------------------------- */
 
 MinQuickMin::MinQuickMin(LAMMPS *lmp) : Min(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 void MinQuickMin::init_style()
 {
   dt = update->dt;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void MinQuickMin::setup_style()
 {
   double **v = atom->v;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     v[i][0] = v[i][1] = v[i][2] = 0.0;
 }
 
 /* ----------------------------------------------------------------------
    set current vector lengths and pointers
    called after atoms have migrated
 ------------------------------------------------------------------------- */
 
 void MinQuickMin::reset_vectors()
 {
   // atomic dof
 
   nvec = 3 * atom->nlocal;
   if (nvec) xvec = atom->x[0];
   if (nvec) fvec = atom->f[0];
 }
 
 /* ----------------------------------------------------------------------
    minimization via QuickMin damped dynamics
 /* ---------------------------------------------------------------------- */
 
 int MinQuickMin::iterate(int maxiter)
 {
-  int ntimestep,flag,flagall;
+  bigint ntimestep;
   double vmax,vdotf,vdotfall,fdotf,fdotfall,scale;
   double dtvone,dtv,dtfm;
+  int flag,flagall;
 
   alpha_final = 0.0;
-  int last_negative = update->ntimestep;
+  bigint last_negative = update->ntimestep;
 
   for (int iter = 0; iter < maxiter; iter++) {
     ntimestep = ++update->ntimestep;
     niter++;
 
     // zero velocity if anti-parallel to force
     // else project velocity in direction of force
 
     double **v = atom->v;
     double **f = atom->f;
     int nlocal = atom->nlocal;
 
     vdotf = 0.0;
     for (int i = 0; i < nlocal; i++)
       vdotf += v[i][0]*f[i][0] + v[i][1]*f[i][1] + v[i][2]*f[i][2];
     MPI_Allreduce(&vdotf,&vdotfall,1,MPI_DOUBLE,MPI_SUM,world);
 
     // sum vdotf over replicas, if necessary
     // this communicator would be invalid for multiprocess replicas
 
     if (update->multireplica == 1) {
       vdotf = vdotfall;
       MPI_Allreduce(&vdotf,&vdotfall,1,MPI_DOUBLE,MPI_SUM,universe->uworld);
     }
 
     if (vdotfall < 0.0) {
       last_negative = ntimestep;
       for (int i = 0; i < nlocal; i++)
 	v[i][0] = v[i][1] = v[i][2] = 0.0;
 
     } else {
       fdotf = 0.0;
       for (int i = 0; i < nlocal; i++)
 	fdotf += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2];
       MPI_Allreduce(&fdotf,&fdotfall,1,MPI_DOUBLE,MPI_SUM,world);
 
       // sum fdotf over replicas, if necessary
       // this communicator would be invalid for multiprocess replicas
 
       if (update->multireplica == 1) {
 	fdotf = fdotfall;
 	MPI_Allreduce(&fdotf,&fdotfall,1,MPI_DOUBLE,MPI_SUM,universe->uworld);
       }
 
       if (fdotfall == 0.0) scale = 0.0;
       else scale = vdotfall/fdotfall;
       for (int i = 0; i < nlocal; i++) {
 	v[i][0] = scale * f[i][0];
 	v[i][1] = scale * f[i][1];
 	v[i][2] = scale * f[i][2];
       }
     }
 
     // limit timestep so no particle moves further than dmax
 
     double *rmass = atom->rmass;
     double *mass = atom->mass;
     int *type = atom->type;
 
     dtvone = dt;
 
     for (int i = 0; i < nlocal; i++) {
       vmax = MAX(fabs(v[i][0]),fabs(v[i][1]));
       vmax = MAX(vmax,fabs(v[i][2]));
       if (dtvone*vmax > dmax) dtvone = dmax/vmax;
     }
     MPI_Allreduce(&dtvone,&dtv,1,MPI_DOUBLE,MPI_MIN,world);
 
     // min dtv over replicas, if necessary
     // this communicator would be invalid for multiprocess replicas
 
     if (update->multireplica == 1) {
       dtvone = dtv;
       MPI_Allreduce(&dtvone,&dtv,1,MPI_DOUBLE,MPI_MIN,universe->uworld);
     }
 
     // Euler integration step
 
     double **x = atom->x;
     
     if (rmass) {
       for (int i = 0; i < nlocal; i++) {
 	dtfm = dtv / rmass[i];
 	x[i][0] += dtv * v[i][0];
 	x[i][1] += dtv * v[i][1];
 	x[i][2] += dtv * v[i][2];
 	v[i][0] += dtfm * f[i][0];
 	v[i][1] += dtfm * f[i][1];
 	v[i][2] += dtfm * f[i][2];
       }
     } else {
       for (int i = 0; i < nlocal; i++) {
 	dtfm = dtv / mass[type[i]];
 	x[i][0] += dtv * v[i][0];
 	x[i][1] += dtv * v[i][1];
 	x[i][2] += dtv * v[i][2];
 	v[i][0] += dtfm * f[i][0];
 	v[i][1] += dtfm * f[i][1];
 	v[i][2] += dtfm * f[i][2];
       }
     }
     
     eprevious = ecurrent;
     ecurrent = energy_force(0);
     neval++;
 
     // energy tolerance criterion
     // only check after DELAYSTEP elapsed since velocties reset to 0
     // sync across replicas if running multi-replica minimization
 
     if (update->etol > 0.0 && ntimestep-last_negative > DELAYSTEP) {
       if (update->multireplica == 0) {
 	if (fabs(ecurrent-eprevious) < 
 	    update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY))
 	  return ETOL;
       } else {
 	if (fabs(ecurrent-eprevious) < 
 	    update->etol * 0.5*(fabs(ecurrent) + fabs(eprevious) + EPS_ENERGY))
 	  flag = 0;
 	else flag = 1;
 	MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld);
 	if (flagall == 0) return ETOL;
       }
     }
 
     // force tolerance criterion
     // sync across replicas if running multi-replica minimization
 
     if (update->ftol > 0.0) {
       fdotf = fnorm_sqr();
       if (update->multireplica == 0) {
 	if (fdotf < update->ftol*update->ftol) return FTOL;
       } else {
 	if (fdotf < update->ftol*update->ftol) flag = 0;
 	else flag = 1;
 	MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,universe->uworld);
 	if (flagall == 0) return FTOL;
       }
     }
 
     // output for thermo, dump, restart files
 
     if (output->next == ntimestep) {
       timer->stamp();
       output->write(ntimestep);
       timer->stamp(TIME_OUTPUT);
     }
   }
   
   return MAXITER;
 }
diff --git a/src/modify.cpp b/src/modify.cpp
index f70ee43a3..99cb49cf1 100644
--- a/src/modify.cpp
+++ b/src/modify.cpp
@@ -1,1111 +1,1111 @@
 /* ----------------------------------------------------------------------
    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 "stdio.h"
 #include "string.h"
 #include "modify.h"
 #include "style_compute.h"
 #include "style_fix.h"
 #include "atom.h"
 #include "comm.h"
 #include "fix.h"
 #include "compute.h"
 #include "group.h"
 #include "update.h"
 #include "domain.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define DELTA 4
 
 // mask settings - same as in fix.cpp
 
 #define INITIAL_INTEGRATE   1
 #define POST_INTEGRATE      2
 #define PRE_EXCHANGE        4
 #define PRE_NEIGHBOR        8
 #define PRE_FORCE          16
 #define POST_FORCE         32
 #define FINAL_INTEGRATE    64
 #define END_OF_STEP       128
 #define THERMO_ENERGY     256
 #define INITIAL_INTEGRATE_RESPA   512
 #define POST_INTEGRATE_RESPA     1024
 #define PRE_FORCE_RESPA          2048
 #define POST_FORCE_RESPA         4096
 #define FINAL_INTEGRATE_RESPA    8192
 #define MIN_PRE_EXCHANGE        16384
 #define MIN_PRE_FORCE           32768
 #define MIN_POST_FORCE          65536
 #define MIN_ENERGY             131072
 #define POST_RUN               262144
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 #define BIG 1.0e20
 
 /* ---------------------------------------------------------------------- */
 
 Modify::Modify(LAMMPS *lmp) : Pointers(lmp)
 {
   nfix = maxfix = 0;
   n_initial_integrate = n_post_integrate = 0;
   n_pre_exchange = n_pre_neighbor = 0;
   n_pre_force = n_post_force = 0;
   n_final_integrate = n_end_of_step = n_thermo_energy = 0;
   n_initial_integrate_respa = n_post_integrate_respa = 0;
   n_pre_force_respa = n_post_force_respa = n_final_integrate_respa = 0;
   n_min_pre_exchange = n_min_pre_force = n_min_post_force = n_min_energy = 0;
 
   fix = NULL;
   fmask = NULL;
   list_initial_integrate = list_post_integrate = NULL;
   list_pre_exchange = list_pre_neighbor = NULL;
   list_pre_force = list_post_force = NULL;
   list_final_integrate = list_end_of_step = NULL;
   list_thermo_energy = NULL;
   list_initial_integrate_respa = list_post_integrate_respa = NULL;
   list_pre_force_respa = list_post_force_respa = NULL;
   list_final_integrate_respa = NULL;
   list_min_pre_exchange = list_min_pre_force = 
   list_min_post_force = list_min_energy = NULL;
 
   end_of_step_every = NULL;
 
   list_timeflag = NULL;
 
   nfix_restart_global = 0;
   id_restart_global = style_restart_global = state_restart_global = NULL;
   nfix_restart_peratom = 0;
   id_restart_peratom = style_restart_peratom = NULL;
   index_restart_peratom = NULL;
 
   ncompute = maxcompute = 0;
   compute = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
 
 Modify::~Modify()
 {
   // delete all fixes
   // do it via delete_fix() so callbacks in Atom are also updated correctly
 
   while (nfix) delete_fix(fix[0]->id);
   memory->sfree(fix);
   memory->sfree(fmask);
 
   // delete all computes
 
   for (int i = 0; i < ncompute; i++) delete compute[i];
   memory->sfree(compute);
 
   delete [] list_initial_integrate;
   delete [] list_post_integrate;
   delete [] list_pre_exchange;
   delete [] list_pre_neighbor;
   delete [] list_pre_force;
   delete [] list_post_force;
   delete [] list_final_integrate;
   delete [] list_end_of_step;
   delete [] list_thermo_energy;
   delete [] list_initial_integrate_respa;
   delete [] list_post_integrate_respa;
   delete [] list_pre_force_respa;
   delete [] list_post_force_respa;
   delete [] list_final_integrate_respa;
   delete [] list_min_pre_exchange;
   delete [] list_min_pre_force;
   delete [] list_min_post_force;
   delete [] list_min_energy;
 
   delete [] end_of_step_every;
   delete [] list_timeflag;
 
   restart_deallocate();
 }
 
 /* ----------------------------------------------------------------------
    initialize all fixes and computes
 ------------------------------------------------------------------------- */
 
 void Modify::init()
 {
   int i,j;
 
   // delete storage of restart info since it is not valid after 1st run
 
   restart_deallocate();
 
   // create lists of fixes to call at each stage of run
 
   list_init(INITIAL_INTEGRATE,n_initial_integrate,list_initial_integrate);
   list_init(POST_INTEGRATE,n_post_integrate,list_post_integrate);
   list_init(PRE_EXCHANGE,n_pre_exchange,list_pre_exchange);
   list_init(PRE_NEIGHBOR,n_pre_neighbor,list_pre_neighbor);
   list_init(PRE_FORCE,n_pre_force,list_pre_force);
   list_init(POST_FORCE,n_post_force,list_post_force);
   list_init(FINAL_INTEGRATE,n_final_integrate,list_final_integrate);
   list_init_end_of_step(END_OF_STEP,n_end_of_step,list_end_of_step);
   list_init_thermo_energy(THERMO_ENERGY,n_thermo_energy,list_thermo_energy);
 
   list_init(INITIAL_INTEGRATE_RESPA,
 	    n_initial_integrate_respa,list_initial_integrate_respa);
   list_init(POST_INTEGRATE_RESPA,
 	    n_post_integrate_respa,list_post_integrate_respa);
   list_init(POST_FORCE_RESPA,
 	    n_post_force_respa,list_post_force_respa);
   list_init(PRE_FORCE_RESPA,
 	    n_pre_force_respa,list_pre_force_respa);
   list_init(FINAL_INTEGRATE_RESPA,
 	    n_final_integrate_respa,list_final_integrate_respa);
 
   list_init(MIN_PRE_EXCHANGE,n_min_pre_exchange,list_min_pre_exchange);
   list_init(MIN_PRE_FORCE,n_min_pre_force,list_min_pre_force);
   list_init(MIN_POST_FORCE,n_min_post_force,list_min_post_force);
   list_init(MIN_ENERGY,n_min_energy,list_min_energy);
 
   // init each fix
   // needs to come before compute init
   // this is b/c some computes call fix->dof()
   // FixRigid::dof() depends on its own init having been called
 
   comm->maxforward_fix = comm->maxreverse_fix = 0;
   for (i = 0; i < nfix; i++) fix[i]->init();
 
   // set global flag if any fix has its restart_pbc flag set
 
   restart_pbc_any = 0;
   for (i = 0; i < nfix; i++)
     if (fix[i]->restart_pbc) restart_pbc_any = 1;
 
   // create list of computes that store invocation times
 
   list_init_compute();
 
   // init each compute
   // set invoked_scalar,vector,etc to -1 to force new run to re-compute them
   // add initial timestep to all computes that store invocation times
   //   since any of them may be invoked by initial thermo
   // do not clear out invocation times stored within a compute,
   //   b/c some may be holdovers from previous run, like for ave fixes
 
   for (i = 0; i < ncompute; i++) {
     compute[i]->init();
     compute[i]->invoked_scalar = -1;
     compute[i]->invoked_vector = -1;
     compute[i]->invoked_array = -1;
     compute[i]->invoked_peratom = -1;
     compute[i]->invoked_local = -1;
   }
   addstep_compute_all(update->ntimestep);
 
   // warn if any particle is time integrated more than once
 
   int nlocal = atom->nlocal;
   int *mask = atom->mask;
 
   int *flag = new int[nlocal];
   for (i = 0; i < nlocal; i++) flag[i] = 0;
 
   int groupbit;
   for (i = 0; i < nfix; i++) {
     if (fix[i]->time_integrate == 0) continue;
     groupbit = fix[i]->groupbit;
     for (j = 0; j < nlocal; j++)
       if (mask[j] & groupbit) flag[j]++;
   }
 
   int check = 0;
   for (i = 0; i < nlocal; i++)
     if (flag[i] > 1) check = 1;
 
   delete [] flag;
 
   int checkall;
   MPI_Allreduce(&check,&checkall,1,MPI_INT,MPI_SUM,world);
   if (comm->me == 0 && checkall)
     error->warning("One or more atoms are time integrated more than once");
 }
 
 /* ----------------------------------------------------------------------
    setup for run, calls setup() of all fixes
 ------------------------------------------------------------------------- */
 
 void Modify::setup(int vflag)
 {
   if (update->whichflag == 1)
     for (int i = 0; i < nfix; i++) fix[i]->setup(vflag);
   else if (update->whichflag == 2)
     for (int i = 0; i < nfix; i++) fix[i]->min_setup(vflag);
 }
 
 /* ----------------------------------------------------------------------
    setup pre_force call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::setup_pre_force(int vflag)
 {
   if (update->whichflag == 1)
     for (int i = 0; i < n_pre_force; i++)
       fix[list_pre_force[i]]->setup_pre_force(vflag);
   else if (update->whichflag == 2)
     for (int i = 0; i < n_pre_force; i++)
       fix[list_min_pre_force[i]]->min_setup_pre_force(vflag);
 }
 
 /* ----------------------------------------------------------------------
    1st half of integrate call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::initial_integrate(int vflag)
 {
   for (int i = 0; i < n_initial_integrate; i++)
     fix[list_initial_integrate[i]]->initial_integrate(vflag);
 }
 
 /* ----------------------------------------------------------------------
    post_integrate call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::post_integrate()
 {
   for (int i = 0; i < n_post_integrate; i++)
     fix[list_post_integrate[i]]->post_integrate();
 }
 
 /* ----------------------------------------------------------------------
    pre_exchange call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::pre_exchange()
 {
   for (int i = 0; i < n_pre_exchange; i++)
     fix[list_pre_exchange[i]]->pre_exchange();
 }
 
 /* ----------------------------------------------------------------------
    pre_neighbor call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::pre_neighbor()
 {
   for (int i = 0; i < n_pre_neighbor; i++)
     fix[list_pre_neighbor[i]]->pre_neighbor();
 }
 
 /* ----------------------------------------------------------------------
    pre_force call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::pre_force(int vflag)
 {
   for (int i = 0; i < n_pre_force; i++)
     fix[list_pre_force[i]]->pre_force(vflag);
 }
 
 /* ----------------------------------------------------------------------
    post_force call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::post_force(int vflag)
 {
   for (int i = 0; i < n_post_force; i++)
     fix[list_post_force[i]]->post_force(vflag);
 }
 
 /* ----------------------------------------------------------------------
    2nd half of integrate call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::final_integrate()
 {
   for (int i = 0; i < n_final_integrate; i++)
     fix[list_final_integrate[i]]->final_integrate();
 }
 
 /* ----------------------------------------------------------------------
    end-of-timestep call, only for relevant fixes
    only call fix->end_of_step() on timesteps that are multiples of nevery
 ------------------------------------------------------------------------- */
 
 void Modify::end_of_step()
 {
   for (int i = 0; i < n_end_of_step; i++)
     if (update->ntimestep % end_of_step_every[i] == 0)
       fix[list_end_of_step[i]]->end_of_step();
 }
 
 /* ----------------------------------------------------------------------
    thermo energy call, only for relevant fixes
    called by Thermo class
    compute_scalar() is fix call to return energy
 ------------------------------------------------------------------------- */
 
 double Modify::thermo_energy()
 {
   double energy = 0.0;
   for (int i = 0; i < n_thermo_energy; i++)
     energy += fix[list_thermo_energy[i]]->compute_scalar();
   return energy;
 }
 
 /* ----------------------------------------------------------------------
    post_run call
 ------------------------------------------------------------------------- */
 
 void Modify::post_run()
 {
   for (int i = 0; i < nfix; i++) fix[i]->post_run();
 }
 
 /* ----------------------------------------------------------------------
    setup rRESPA pre_force call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::setup_pre_force_respa(int vflag, int ilevel)
 {
   for (int i = 0; i < n_pre_force; i++)
     fix[list_pre_force[i]]->setup_pre_force_respa(vflag,ilevel);
 }
 
 /* ----------------------------------------------------------------------
    1st half of rRESPA integrate call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::initial_integrate_respa(int vflag, int ilevel, int iloop)
 {
   for (int i = 0; i < n_initial_integrate_respa; i++)
     fix[list_initial_integrate_respa[i]]->
       initial_integrate_respa(vflag,ilevel,iloop);
 }
 
 /* ----------------------------------------------------------------------
    rRESPA post_integrate call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::post_integrate_respa(int ilevel, int iloop)
 {
   for (int i = 0; i < n_post_integrate_respa; i++)
     fix[list_post_integrate_respa[i]]->post_integrate_respa(ilevel,iloop);
 }
 
 /* ----------------------------------------------------------------------
    rRESPA pre_force call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::pre_force_respa(int vflag, int ilevel, int iloop)
 {
   for (int i = 0; i < n_pre_force_respa; i++)
     fix[list_pre_force_respa[i]]->pre_force_respa(vflag,ilevel,iloop);
 }
 
 /* ----------------------------------------------------------------------
    rRESPA post_force call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::post_force_respa(int vflag, int ilevel, int iloop)
 {
   for (int i = 0; i < n_post_force_respa; i++)
     fix[list_post_force_respa[i]]->post_force_respa(vflag,ilevel,iloop);
 }
 
 /* ----------------------------------------------------------------------
    2nd half of rRESPA integrate call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::final_integrate_respa(int ilevel, int iloop)
 {
   for (int i = 0; i < n_final_integrate_respa; i++)
     fix[list_final_integrate_respa[i]]->final_integrate_respa(ilevel,iloop);
 }
 
 /* ----------------------------------------------------------------------
    minimizer pre-exchange call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::min_pre_exchange()
 {
   for (int i = 0; i < n_min_pre_exchange; i++)
     fix[list_min_pre_exchange[i]]->min_pre_exchange();
 }
 
 /* ----------------------------------------------------------------------
    minimizer pre-force call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::min_pre_force(int vflag)
 {
   for (int i = 0; i < n_min_pre_force; i++)
     fix[list_min_pre_force[i]]->min_pre_force(vflag);
 }
 
 /* ----------------------------------------------------------------------
    minimizer force adjustment call, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::min_post_force(int vflag)
 {
   for (int i = 0; i < n_min_post_force; i++)
     fix[list_min_post_force[i]]->min_post_force(vflag);
 }
 
 /* ----------------------------------------------------------------------
    minimizer energy/force evaluation, only for relevant fixes
    return energy and forces on extra degrees of freedom
 ------------------------------------------------------------------------- */
 
 double Modify::min_energy(double *fextra)
 {
   int ifix,index;
 
   index = 0;
   double eng = 0.0;
   for (int i = 0; i < n_min_energy; i++) {
     ifix = list_min_energy[i];
     eng += fix[ifix]->min_energy(&fextra[index]);
     index += fix[ifix]->min_dof();
   }
   return eng;
 }
 
 /* ----------------------------------------------------------------------
    store current state of extra dof, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::min_store()
 {
   for (int i = 0; i < n_min_energy; i++)
     fix[list_min_energy[i]]->min_store();
 }
 
 /* ----------------------------------------------------------------------
    mange state of extra dof on a stack, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::min_clearstore()
 {
   for (int i = 0; i < n_min_energy; i++)
     fix[list_min_energy[i]]->min_clearstore();
 }
 
 void Modify::min_pushstore()
 {
   for (int i = 0; i < n_min_energy; i++)
     fix[list_min_energy[i]]->min_pushstore();
 }
 
 void Modify::min_popstore()
 {
   for (int i = 0; i < n_min_energy; i++)
     fix[list_min_energy[i]]->min_popstore();
 }
 
 /* ----------------------------------------------------------------------
    displace extra dof along vector hextra, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 void Modify::min_step(double alpha, double *hextra)
 {
   int ifix,index;
 
   index = 0;
   for (int i = 0; i < n_min_energy; i++) {
     ifix = list_min_energy[i];
     fix[ifix]->min_step(alpha,&hextra[index]);
     index += fix[ifix]->min_dof();
   }
 }
 
 /* ----------------------------------------------------------------------
    compute max allowed step size along vector hextra, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 double Modify::max_alpha(double *hextra)
 {
   int ifix,index;
 
   double alpha = BIG;
   index = 0;
   for (int i = 0; i < n_min_energy; i++) {
     ifix = list_min_energy[i];
     double alpha_one = fix[ifix]->max_alpha(&hextra[index]);
     alpha = MIN(alpha,alpha_one);
     index += fix[ifix]->min_dof();
   }
   return alpha;
 }
 
 /* ----------------------------------------------------------------------
    extract extra dof for minimization, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 int Modify::min_dof()
 {
   int ndof = 0;
   for (int i = 0; i < n_min_energy; i++)
     ndof += fix[list_min_energy[i]]->min_dof();
   return ndof;
 }
 
 /* ----------------------------------------------------------------------
    reset reference state of fix, only for relevant fixes
 ------------------------------------------------------------------------- */
 
 int Modify::min_reset_ref()
 {
   int itmp,itmpall;
   itmpall = 0;
   for (int i = 0; i < n_min_energy; i++) {
     itmp = fix[list_min_energy[i]]->min_reset_ref();
     if (itmp) itmpall = 1;
   }
   return itmpall;
 }
 
 /* ----------------------------------------------------------------------
    add a new fix or replace one with same ID
 ------------------------------------------------------------------------- */
 
 void Modify::add_fix(int narg, char **arg)
 {
   if (domain->box_exist == 0) 
     error->all("Fix command before simulation box is defined");
   if (narg < 3) error->all("Illegal fix command");
 
   // check group ID
 
   int igroup = group->find(arg[1]);
   if (igroup == -1) error->all("Could not find fix group ID");
 
   // if fix ID exists:
   //   set newflag = 0 so create new fix in same location in fix list
   //   error if new style does not match old style
   //     since can't replace it (all when-to-invoke ptrs would be invalid)
   //   warn if new group != old group
   //   delete old fix, but do not call update_callback(),
   //     since will replace this fix and thus other fix locs will not change
   //   set ptr to NULL in case new fix scans list of fixes,
   //     e.g. scan will occur in add_callback() if called by new fix
   // if fix ID does not exist:
   //   set newflag = 1 so create new fix
   //   extend fix and fmask lists as necessary
 
   int ifix,newflag;
   for (ifix = 0; ifix < nfix; ifix++)
     if (strcmp(arg[0],fix[ifix]->id) == 0) break;
 
   if (ifix < nfix) {
     newflag = 0;
     if (strcmp(arg[2],fix[ifix]->style) != 0)
       error->all("Replacing a fix, but new style != old style");
     if (fix[ifix]->igroup != igroup && comm->me == 0)
       error->warning("Replacing a fix, but new group != old group");
     delete fix[ifix];
     fix[ifix] = NULL;
   } else {
     newflag = 1;
     if (nfix == maxfix) {
       maxfix += DELTA;
       fix = (Fix **) memory->srealloc(fix,maxfix*sizeof(Fix *),"modify:fix");
       fmask = (int *) 
 	memory->srealloc(fmask,maxfix*sizeof(int),"modify:fmask");
     }
   }
 
   // create the Fix
 
   if (0) return;         // dummy line to enable else-if macro expansion
 
 #define FIX_CLASS
 #define FixStyle(key,Class) \
   else if (strcmp(arg[2],#key) == 0) fix[ifix] = new Class(lmp,narg,arg);
 #include "style_fix.h"
 #undef FIX_CLASS
 
   else error->all("Invalid fix style");
 
   // set fix mask values and increment nfix (if new)
 
   fmask[ifix] = fix[ifix]->setmask();
   if (newflag) nfix++;
 
   // check if Fix is in restart_global list
   // if yes, pass state info to the Fix so it can reset itself
 
   for (int i = 0; i < nfix_restart_global; i++)
     if (strcmp(id_restart_global[i],fix[ifix]->id) == 0 &&
 	strcmp(style_restart_global[i],fix[ifix]->style) == 0) {
       fix[ifix]->restart(state_restart_global[i]);
       if (comm->me == 0) {
 	char *str = (char *) ("Resetting global state of Fix %s Style %s "
 			      "from restart file info\n");
 	if (screen) fprintf(screen,str,fix[ifix]->id,fix[ifix]->style);
 	if (logfile) fprintf(logfile,str,fix[ifix]->id,fix[ifix]->style);
       }
     }
 
   // check if Fix is in restart_peratom list
   // if yes, loop over atoms so they can extract info from atom->extra array
 
   for (int i = 0; i < nfix_restart_peratom; i++)
     if (strcmp(id_restart_peratom[i],fix[ifix]->id) == 0 &&
 	strcmp(style_restart_peratom[i],fix[ifix]->style) == 0) {
       for (int j = 0; j < atom->nlocal; j++)
 	fix[ifix]->unpack_restart(j,index_restart_peratom[i]);
       if (comm->me == 0) {
 	char *str = (char *) ("Resetting per-atom state of Fix %s Style %s "
 		     "from restart file info\n");
 	if (screen) fprintf(screen,str,fix[ifix]->id,fix[ifix]->style);
 	if (logfile) fprintf(logfile,str,fix[ifix]->id,fix[ifix]->style);
       }
     }
 }
 
 /* ----------------------------------------------------------------------
    modify a Fix's parameters
 ------------------------------------------------------------------------- */
 
 void Modify::modify_fix(int narg, char **arg)
 {
   if (narg < 2) error->all("Illegal fix_modify command");
 
   // lookup Fix ID
 
   int ifix;
   for (ifix = 0; ifix < nfix; ifix++)
     if (strcmp(arg[0],fix[ifix]->id) == 0) break;
   if (ifix == nfix) error->all("Could not find fix_modify ID");
   
   fix[ifix]->modify_params(narg-1,&arg[1]);
 }
 
 /* ----------------------------------------------------------------------
    delete a Fix from list of Fixes
    Atom class must update indices in its list of callbacks to fixes
 ------------------------------------------------------------------------- */
 
 void Modify::delete_fix(const char *id)
 {
   int ifix = find_fix(id);
   if (ifix < 0) error->all("Could not find fix ID to delete");
   delete fix[ifix];
   atom->update_callback(ifix);
 
   // move other Fixes and fmask down in list one slot
 
   for (int i = ifix+1; i < nfix; i++) fix[i-1] = fix[i];
   for (int i = ifix+1; i < nfix; i++) fmask[i-1] = fmask[i];
   nfix--;
 }
 
 /* ----------------------------------------------------------------------
    find a fix by ID
    return index of fix or -1 if not found
 ------------------------------------------------------------------------- */
 
 int Modify::find_fix(const char *id)
 {
   int ifix;
   for (ifix = 0; ifix < nfix; ifix++)
     if (strcmp(id,fix[ifix]->id) == 0) break;
   if (ifix == nfix) return -1;
   return ifix;
 }
 
 /* ----------------------------------------------------------------------
    add a new compute
 ------------------------------------------------------------------------- */
 
 void Modify::add_compute(int narg, char **arg)
 {
   if (narg < 3) error->all("Illegal compute command");
 
   // error check
 
   for (int icompute = 0; icompute < ncompute; icompute++)
     if (strcmp(arg[0],compute[icompute]->id) == 0)
       error->all("Reuse of compute ID");
 
   // extend Compute list if necessary
 
   if (ncompute == maxcompute) {
     maxcompute += DELTA;
     compute = (Compute **)
       memory->srealloc(compute,maxcompute*sizeof(Compute *),"modify:compute");
   }
 
   // create the Compute
 
   if (0) return;         // dummy line to enable else-if macro expansion
 
 #define COMPUTE_CLASS
 #define ComputeStyle(key,Class) \
   else if (strcmp(arg[2],#key) == 0) \
     compute[ncompute] = new Class(lmp,narg,arg);
 #include "style_compute.h"
 #undef COMPUTE_CLASS
 
   else error->all("Invalid compute style");
 
   ncompute++;
 }
 
 /* ----------------------------------------------------------------------
    modify a Compute's parameters
 ------------------------------------------------------------------------- */
 
 void Modify::modify_compute(int narg, char **arg)
 {
   if (narg < 2) error->all("Illegal compute_modify command");
 
   // lookup Compute ID
 
   int icompute;
   for (icompute = 0; icompute < ncompute; icompute++)
     if (strcmp(arg[0],compute[icompute]->id) == 0) break;
   if (icompute == ncompute) error->all("Could not find compute_modify ID");
   
   compute[icompute]->modify_params(narg-1,&arg[1]);
 }
 
 /* ----------------------------------------------------------------------
    delete a Compute from list of Computes
 ------------------------------------------------------------------------- */
 
 void Modify::delete_compute(char *id)
 {
   int icompute = find_compute(id);
   if (icompute < 0) error->all("Could not find compute ID to delete");
   delete compute[icompute];
 
   // move other Computes down in list one slot
 
   for (int i = icompute+1; i < ncompute; i++) compute[i-1] = compute[i];
   ncompute--;
 }
 
 /* ----------------------------------------------------------------------
    find a compute by ID
    return index of compute or -1 if not found
 ------------------------------------------------------------------------- */
 
 int Modify::find_compute(char *id)
 {
   int icompute;
   for (icompute = 0; icompute < ncompute; icompute++)
     if (strcmp(id,compute[icompute]->id) == 0) break;
   if (icompute == ncompute) return -1;
   return icompute;
 }
 
 /* ----------------------------------------------------------------------
    clear invoked flag of all computes
    called everywhere that computes are used, before computes are invoked
    invoked flag used to avoid re-invoking same compute multiple times
    and to flag computes that store invocation times as having been invoked
 ------------------------------------------------------------------------- */
 
 void Modify::clearstep_compute()
 {
   for (int icompute = 0; icompute < ncompute; icompute++)
     compute[icompute]->invoked_flag = 0;
 }
 
 /* ----------------------------------------------------------------------
    loop over computes that store invocation times
    if its invoked flag set on this timestep, schedule next invocation
    called everywhere that computes are used, after computes are invoked
 ------------------------------------------------------------------------- */
 
-void Modify::addstep_compute(int newstep)
+void Modify::addstep_compute(bigint newstep)
 {
   for (int icompute = 0; icompute < n_timeflag; icompute++)
     if (compute[list_timeflag[icompute]]->invoked_flag)
       compute[list_timeflag[icompute]]->addstep(newstep);
 }
 
 /* ----------------------------------------------------------------------
    loop over all computes
    schedule next invocation for those that store invocation times
    called when not sure what computes will be needed on newstep
    do not loop only over n_timeflag, since may not be set yet
 ------------------------------------------------------------------------- */
 
-void Modify::addstep_compute_all(int newstep)
+void Modify::addstep_compute_all(bigint newstep)
 {
   for (int icompute = 0; icompute < ncompute; icompute++)
     if (compute[icompute]->timeflag) compute[icompute]->addstep(newstep);
 }
 
 /* ----------------------------------------------------------------------
    write to restart file for all Fixes with restart info
    (1) fixes that have global state
    (2) fixes that store per-atom quantities
 ------------------------------------------------------------------------- */
 
 void Modify::write_restart(FILE *fp)
 {
   int me = comm->me;
 
   int count = 0;
   for (int i = 0; i < nfix; i++) 
     if (fix[i]->restart_global) count++;
 
   if (me == 0) fwrite(&count,sizeof(int),1,fp);
 
   int n;
   for (int i = 0; i < nfix; i++)
     if (fix[i]->restart_global) {
       if (me == 0) {
 	n = strlen(fix[i]->id) + 1;
 	fwrite(&n,sizeof(int),1,fp);
 	fwrite(fix[i]->id,sizeof(char),n,fp);
 	n = strlen(fix[i]->style) + 1;
 	fwrite(&n,sizeof(int),1,fp);
 	fwrite(fix[i]->style,sizeof(char),n,fp);
       }
       fix[i]->write_restart(fp);
     }
 
   count = 0;
   for (int i = 0; i < nfix; i++) 
     if (fix[i]->restart_peratom) count++;
 
   if (me == 0) fwrite(&count,sizeof(int),1,fp);
 
   for (int i = 0; i < nfix; i++)
     if (fix[i]->restart_peratom) {
       if (me == 0) {
 	n = strlen(fix[i]->id) + 1;
 	fwrite(&n,sizeof(int),1,fp);
 	fwrite(fix[i]->id,sizeof(char),n,fp);
 	n = strlen(fix[i]->style) + 1;
 	fwrite(&n,sizeof(int),1,fp);
 	fwrite(fix[i]->style,sizeof(char),n,fp);
 	n = fix[i]->maxsize_restart();
 	fwrite(&n,sizeof(int),1,fp);
       }
     }
 }
 
 /* ----------------------------------------------------------------------
    read in restart file data on all previously defined Fixes with restart info
    (1) fixes that have global state
    (2) fixes that store per-atom quantities
    return maxsize of extra info that will be stored with any atom
 ------------------------------------------------------------------------- */
 
 int Modify::read_restart(FILE *fp)
 {
   // nfix_restart_global = # of restart entries with global state info
 
   int me = comm->me;
   if (me == 0) fread(&nfix_restart_global,sizeof(int),1,fp);
   MPI_Bcast(&nfix_restart_global,1,MPI_INT,0,world);
 
   // allocate space for each entry
 
   if (nfix_restart_global) {
     id_restart_global = new char*[nfix_restart_global];
     style_restart_global = new char*[nfix_restart_global];
     state_restart_global = new char*[nfix_restart_global];
   }
 
   // read each entry and Bcast to all procs
   // each entry has id string, style string, chunk of state data
 
   int n;
   for (int i = 0; i < nfix_restart_global; i++) {
     if (me == 0) fread(&n,sizeof(int),1,fp);
     MPI_Bcast(&n,1,MPI_INT,0,world);
     id_restart_global[i] = new char[n];
     if (me == 0) fread(id_restart_global[i],sizeof(char),n,fp);
     MPI_Bcast(id_restart_global[i],n,MPI_CHAR,0,world);
 
     if (me == 0) fread(&n,sizeof(int),1,fp);
     MPI_Bcast(&n,1,MPI_INT,0,world);
     style_restart_global[i] = new char[n];
     if (me == 0) fread(style_restart_global[i],sizeof(char),n,fp);
     MPI_Bcast(style_restart_global[i],n,MPI_CHAR,0,world);
 
     if (me == 0) fread(&n,sizeof(int),1,fp);
     MPI_Bcast(&n,1,MPI_INT,0,world);
     state_restart_global[i] = new char[n];
     if (me == 0) fread(state_restart_global[i],sizeof(char),n,fp);
     MPI_Bcast(state_restart_global[i],n,MPI_CHAR,0,world);
   }
 
   // nfix_restart_peratom = # of restart entries with peratom info
 
   int maxsize = 0;
 
   if (me == 0) fread(&nfix_restart_peratom,sizeof(int),1,fp);
   MPI_Bcast(&nfix_restart_peratom,1,MPI_INT,0,world);
 
   // allocate space for each entry
 
   if (nfix_restart_peratom) {
     id_restart_peratom = new char*[nfix_restart_peratom];
     style_restart_peratom = new char*[nfix_restart_peratom];
     index_restart_peratom = new int[nfix_restart_peratom];
   }
 
   // read each entry and Bcast to all procs
   // each entry has id string, style string, maxsize of one atom's data
   // set index = which set of extra data this fix represents
 
   for (int i = 0; i < nfix_restart_peratom; i++) {
     if (me == 0) fread(&n,sizeof(int),1,fp);
     MPI_Bcast(&n,1,MPI_INT,0,world);
     id_restart_peratom[i] = new char[n];
     if (me == 0) fread(id_restart_peratom[i],sizeof(char),n,fp);
     MPI_Bcast(id_restart_peratom[i],n,MPI_CHAR,0,world);
 
     if (me == 0) fread(&n,sizeof(int),1,fp);
     MPI_Bcast(&n,1,MPI_INT,0,world);
     style_restart_peratom[i] = new char[n];
     if (me == 0) fread(style_restart_peratom[i],sizeof(char),n,fp);
     MPI_Bcast(style_restart_peratom[i],n,MPI_CHAR,0,world);
 
     if (me == 0) fread(&n,sizeof(int),1,fp);
     MPI_Bcast(&n,1,MPI_INT,0,world);
     maxsize += n;
 
     index_restart_peratom[i] = i;
   }
 
   return maxsize;
 }
 
 /* ----------------------------------------------------------------------
    delete all lists of restart file Fix info
 ------------------------------------------------------------------------- */
 
 void Modify::restart_deallocate()
 {
   if (nfix_restart_global) {
     for (int i = 0; i < nfix_restart_global; i++) {
       delete [] id_restart_global[i];
       delete [] style_restart_global[i];
       delete [] state_restart_global[i];
     }
     delete [] id_restart_global;
     delete [] style_restart_global;
     delete [] state_restart_global;
   }
 
   if (nfix_restart_peratom) {
     for (int i = 0; i < nfix_restart_peratom; i++) {
       delete [] id_restart_peratom[i];
       delete [] style_restart_peratom[i];
     }
     delete [] id_restart_peratom;
     delete [] style_restart_peratom;
     delete [] index_restart_peratom;
   }
 
   nfix_restart_global = nfix_restart_peratom = 0;
 }
 
 /* ----------------------------------------------------------------------
    create list of fix indices for fixes which match mask
 ------------------------------------------------------------------------- */
 
 void Modify::list_init(int mask, int &n, int *&list)
 {
   delete [] list;
 
   n = 0;
   for (int i = 0; i < nfix; i++) if (fmask[i] & mask) n++;
   list = new int[n];
 
   n = 0;
   for (int i = 0; i < nfix; i++) if (fmask[i] & mask) list[n++] = i;
 }
 
 /* ----------------------------------------------------------------------
    create list of fix indices for end_of_step fixes
    also create end_of_step_every[]
 ------------------------------------------------------------------------- */
 
 void Modify::list_init_end_of_step(int mask, int &n, int *&list)
 {
   delete [] list;
   delete [] end_of_step_every;
 
   n = 0;
   for (int i = 0; i < nfix; i++) if (fmask[i] & mask) n++;
   list = new int[n];
   end_of_step_every = new int[n];
 
   n = 0;
   for (int i = 0; i < nfix; i++)
     if (fmask[i] & mask) {
       list[n] = i;
       end_of_step_every[n++] = fix[i]->nevery;
     }
 }
 
 /* ----------------------------------------------------------------------
    create list of fix indices for thermo energy fixes
    only added to list if fix has THERMO_ENERGY mask
    and its thermo_energy flag was set via fix_modify
 ------------------------------------------------------------------------- */
 
 void Modify::list_init_thermo_energy(int mask, int &n, int *&list)
 {
   delete [] list;
 
   n = 0;
   for (int i = 0; i < nfix; i++)
     if (fmask[i] & mask && fix[i]->thermo_energy) n++;
   list = new int[n];
 
   n = 0;
   for (int i = 0; i < nfix; i++)
     if (fmask[i] & mask && fix[i]->thermo_energy) list[n++] = i;
 }
 
 /* ----------------------------------------------------------------------
    create list of compute indices for computes which store invocation times
 ------------------------------------------------------------------------- */
 
 void Modify::list_init_compute()
 {
   delete [] list_timeflag;
 
   n_timeflag = 0;
   for (int i = 0; i < ncompute; i++)
     if (compute[i]->timeflag) n_timeflag++;
   list_timeflag = new int[n_timeflag];
 
   n_timeflag = 0;
   for (int i = 0; i < ncompute; i++)
     if (compute[i]->timeflag) list_timeflag[n_timeflag++] = i;
 }
 
 /* ----------------------------------------------------------------------
    return # of bytes of allocated memory from all fixes
 ------------------------------------------------------------------------- */
 
 double Modify::memory_usage()
 {
   double bytes = 0.0;
   for (int i = 0; i < nfix; i++) bytes += fix[i]->memory_usage();
   for (int i = 0; i < ncompute; i++) bytes += compute[i]->memory_usage();
   return bytes;
 }
diff --git a/src/modify.h b/src/modify.h
index 0601e1b85..f211167a1 100644
--- a/src/modify.h
+++ b/src/modify.h
@@ -1,137 +1,138 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_MODIFY_H
 #define LMP_MODIFY_H
 
 #include "stdio.h"
 #include "pointers.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class Modify : protected Pointers {
  public:
   int nfix,maxfix;
   int n_initial_integrate,n_post_integrate,n_pre_exchange,n_pre_neighbor;
   int n_pre_force,n_post_force;
   int n_final_integrate,n_end_of_step,n_thermo_energy;
   int n_initial_integrate_respa,n_post_integrate_respa;
   int n_pre_force_respa,n_post_force_respa,n_final_integrate_respa;
   int n_min_pre_exchange,n_min_pre_force,n_min_post_force,n_min_energy;
 
   int restart_pbc_any;       // 1 if any fix sets restart_pbc
   int nfix_restart_global;   // stored fix global info from restart file
   int nfix_restart_peratom;  // stored fix peratom info from restart file
 
   class Fix **fix;           // list of fixes
   int *fmask;                // bit mask for when each fix is applied
 
   int ncompute,maxcompute;   // list of computes
   class Compute **compute;
 
   Modify(class LAMMPS *);
   ~Modify();
   void init();
   void setup(int);
   void setup_pre_force(int);
   void initial_integrate(int);
   void post_integrate();
   void pre_decide();
   void pre_exchange();
   void pre_neighbor();
   void pre_force(int);
   void post_force(int);
   void final_integrate();
   void end_of_step();
   double thermo_energy();
   void post_run();
 
   void setup_pre_force_respa(int, int);
   void initial_integrate_respa(int, int, int);
   void post_integrate_respa(int, int);
   void pre_force_respa(int, int, int);
   void post_force_respa(int, int, int);
   void final_integrate_respa(int, int);
 
   void setup_min_pre_force(int);
   void min_pre_exchange();
   void min_pre_force(int);
   void min_post_force(int);
 
   double min_energy(double *);
   void min_store();
   void min_step(double, double *);
   void min_clearstore();
   void min_pushstore();
   void min_popstore();
   int min_reset_ref();
   double max_alpha(double *);
   int min_dof();
 
   void add_fix(int, char **);
   void modify_fix(int, char **);
   void delete_fix(const char *);
   int find_fix(const char *);
 
   void add_compute(int, char **);
   void modify_compute(int, char **);
   void delete_compute(char *);
   int find_compute(char *);
   void clearstep_compute();
-  void addstep_compute(int);
-  void addstep_compute_all(int);
+  void addstep_compute(bigint);
+  void addstep_compute_all(bigint);
 
   void write_restart(FILE *);
   int read_restart(FILE *);
   void restart_deallocate();
 
   double memory_usage();
 
  private:
 
   // lists of fixes to apply at different stages of timestep
 
   int *list_initial_integrate,*list_post_integrate;
   int *list_pre_exchange,*list_pre_neighbor;
   int *list_pre_force,*list_post_force;
   int *list_final_integrate,*list_end_of_step,*list_thermo_energy;
   int *list_initial_integrate_respa,*list_post_integrate_respa;
   int *list_pre_force_respa,*list_post_force_respa;
   int *list_final_integrate_respa;
   int *list_min_pre_exchange,*list_min_pre_force;
   int *list_min_post_force,*list_min_energy;
 
   int *end_of_step_every;
 
   int n_timeflag;            // list of computes that store time invocation
   int *list_timeflag;
 
   char **id_restart_global;           // stored fix global info
   char **style_restart_global;        // from read-in restart file
   char **state_restart_global;
 
   char **id_restart_peratom;          // stored fix peratom info
   char **style_restart_peratom;       // from read-in restart file
   int *index_restart_peratom;
 
   int index_permanent;        // fix/compute index returned to library call
 
   void list_init(int, int &, int *&);
   void list_init_end_of_step(int, int &, int *&);
   void list_init_thermo_energy(int, int &, int *&);
   void list_init_compute();
 };
 
 }
 
 #endif
diff --git a/src/neigh_bond.cpp b/src/neigh_bond.cpp
index 57245abd3..6383dae8f 100644
--- a/src/neigh_bond.cpp
+++ b/src/neigh_bond.cpp
@@ -1,385 +1,400 @@
 /* ----------------------------------------------------------------------
    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 "neighbor.h"
+#include "lmptype.h"
 #include "atom.h"
 #include "force.h"
 #include "update.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define BONDDELTA 10000
 
 /* ---------------------------------------------------------------------- */
 
 void Neighbor::bond_all()
 {
   int i,m,atom1;
 
   int nlocal = atom->nlocal;
   int *num_bond = atom->num_bond;
   int **bond_atom = atom->bond_atom;
   int **bond_type = atom->bond_type;
   int *tag = atom->tag;
   int newton_bond = force->newton_bond;
 
   nbondlist = 0;
 
   for (i = 0; i < nlocal; i++)
     for (m = 0; m < num_bond[i]; m++) {
       atom1 = atom->map(bond_atom[i][m]);
       if (atom1 == -1) {
-	char str[128];
-	sprintf(str,"Bond atoms %d %d missing on proc %d at step %d",
-		tag[i],bond_atom[i][m],me,update->ntimestep);
+	char str[128],fstr[64];
+	sprintf(fstr,"Bond atoms %%d %%d missing on proc %%d at step %s",
+		BIGINT_FORMAT);
+	sprintf(str,fstr,tag[i],bond_atom[i][m],me,update->ntimestep);
 	error->one(str);
       }
       if (newton_bond || i < atom1) {
 	if (nbondlist == maxbond) {
 	  maxbond += BONDDELTA;
 	  bondlist = memory->grow_2d_int_array(bondlist,maxbond,3,
 					       "neighbor:bondlist");
 	}
 	bondlist[nbondlist][0] = i;
 	bondlist[nbondlist][1] = atom1;
 	bondlist[nbondlist][2] = bond_type[i][m];
 	nbondlist++;
       }
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Neighbor::bond_partial()
 {
   int i,m,atom1;
 
   int nlocal = atom->nlocal;
   int *num_bond = atom->num_bond;
   int **bond_atom = atom->bond_atom;
   int **bond_type = atom->bond_type;
   int *tag = atom->tag;
   int newton_bond = force->newton_bond;
 
   nbondlist = 0;
 
   for (i = 0; i < nlocal; i++)
     for (m = 0; m < num_bond[i]; m++) {
       if (bond_type[i][m] <= 0) continue;
       atom1 = atom->map(bond_atom[i][m]);
       if (atom1 == -1) {
-	char str[128];
-	sprintf(str,"Bond atoms %d %d missing on proc %d at step %d",
-		tag[i],bond_atom[i][m],me,update->ntimestep);
+	char str[128],fstr[64];
+	sprintf(fstr,"Bond atoms %%d %%d missing on proc %%d at step %s",
+		BIGINT_FORMAT);
+	sprintf(str,fstr,tag[i],bond_atom[i][m],me,update->ntimestep);
 	error->one(str);
       }
       if (newton_bond || i < atom1) {
 	if (nbondlist == maxbond) {
 	  maxbond += BONDDELTA;
 	  bondlist = memory->grow_2d_int_array(bondlist,maxbond,3,
 					       "neighbor:bondlist");
 	}
 	bondlist[nbondlist][0] = i;
 	bondlist[nbondlist][1] = atom1;
 	bondlist[nbondlist][2] = bond_type[i][m];
 	nbondlist++;
       }
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Neighbor::angle_all()
 {
   int i,m,atom1,atom2,atom3;
 
   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;
   int **angle_type = atom->angle_type;
   int newton_bond = force->newton_bond;
 
   nanglelist = 0;
 
   for (i = 0; i < nlocal; i++)
     for (m = 0; m < num_angle[i]; m++) {
       atom1 = atom->map(angle_atom1[i][m]);
       atom2 = atom->map(angle_atom2[i][m]);
       atom3 = atom->map(angle_atom3[i][m]);
       if (atom1 == -1 || atom2 == -1 || atom3 == -1) {
-	char str[128];
-	sprintf(str,"Angle atoms %d %d %d missing on proc %d at step %d",
+	char str[128],fstr[64];
+	sprintf(fstr,"Angle atoms %%d %%d %%d missing on proc %%d at step %s",
+		BIGINT_FORMAT);
+	sprintf(str,fstr,
 		angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m],
 		me,update->ntimestep);
 	error->one(str);
       }
       if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) {
 	if (nanglelist == maxangle) {
 	  maxangle += BONDDELTA;
 	  anglelist = memory->grow_2d_int_array(anglelist,maxangle,4,
 						  "neighbor:anglelist");
 	}
 	anglelist[nanglelist][0] = atom1;
 	anglelist[nanglelist][1] = atom2;
 	anglelist[nanglelist][2] = atom3;
 	anglelist[nanglelist][3] = angle_type[i][m];
 	nanglelist++;
       }
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Neighbor::angle_partial()
 {
   int i,m,atom1,atom2,atom3;
 
   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;
   int **angle_type = atom->angle_type;
   int newton_bond = force->newton_bond;
 
   nanglelist = 0;
 
   for (i = 0; i < nlocal; i++)
     for (m = 0; m < num_angle[i]; m++) {
       if (angle_type[i][m] <= 0) continue;
       atom1 = atom->map(angle_atom1[i][m]);
       atom2 = atom->map(angle_atom2[i][m]);
       atom3 = atom->map(angle_atom3[i][m]);
       if (atom1 == -1 || atom2 == -1 || atom3 == -1) {
-	char str[128];
-	sprintf(str,"Angle atoms %d %d %d missing on proc %d at step %d",
+	char str[128],fstr[64];
+	sprintf(fstr,"Angle atoms %%d %%d %%d missing on proc %%d at step %s",
+		BIGINT_FORMAT);
+	sprintf(str,fstr,
 		angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m],
 		me,update->ntimestep);
 	error->one(str);
       }
       if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) {
 	if (nanglelist == maxangle) {
 	  maxangle += BONDDELTA;
 	  anglelist = memory->grow_2d_int_array(anglelist,maxangle,4,
 						  "neighbor:anglelist");
 	}
 	anglelist[nanglelist][0] = atom1;
 	anglelist[nanglelist][1] = atom2;
 	anglelist[nanglelist][2] = atom3;
 	anglelist[nanglelist][3] = angle_type[i][m];
 	nanglelist++;
       }
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Neighbor::dihedral_all()
 {
   int i,m,atom1,atom2,atom3,atom4;
 
   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;
   int **dihedral_type = atom->dihedral_type;
   int newton_bond = force->newton_bond;
 
   ndihedrallist = 0;
 
   for (i = 0; i < nlocal; i++)
     for (m = 0; m < num_dihedral[i]; m++) {
       atom1 = atom->map(dihedral_atom1[i][m]);
       atom2 = atom->map(dihedral_atom2[i][m]);
       atom3 = atom->map(dihedral_atom3[i][m]);
       atom4 = atom->map(dihedral_atom4[i][m]);
       if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) {
-	char str[128];
-	sprintf(str,"Dihedral atoms %d %d %d %d missing on proc %d at step %d",
+	char str[128],fstr[128];
+	sprintf(fstr,"Dihedral atoms %%d %%d %%d %%d "
+		"missing on proc %%d at step %s",BIGINT_FORMAT);
+	sprintf(str,fstr,
 		dihedral_atom1[i][m],dihedral_atom2[i][m],
 		dihedral_atom3[i][m],dihedral_atom4[i][m],
 		me,update->ntimestep);
 	error->one(str);
       }
       if (newton_bond || 
 	  (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) {
 	if (ndihedrallist == maxdihedral) {
 	  maxdihedral += BONDDELTA;
 	  dihedrallist = 
 	    memory->grow_2d_int_array(dihedrallist,maxdihedral,5,
 				      "neighbor:dihedrallist");
 	}
 	dihedrallist[ndihedrallist][0] = atom1;
 	dihedrallist[ndihedrallist][1] = atom2;
 	dihedrallist[ndihedrallist][2] = atom3;
 	dihedrallist[ndihedrallist][3] = atom4;
 	dihedrallist[ndihedrallist][4] = dihedral_type[i][m];
 	ndihedrallist++;
       }
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Neighbor::dihedral_partial()
 {
   int i,m,atom1,atom2,atom3,atom4;
 
   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;
   int **dihedral_type = atom->dihedral_type;
   int newton_bond = force->newton_bond;
 
   ndihedrallist = 0;
 
   for (i = 0; i < nlocal; i++)
     for (m = 0; m < num_dihedral[i]; m++) {
       if (dihedral_type[i][m] <= 0) continue;
       atom1 = atom->map(dihedral_atom1[i][m]);
       atom2 = atom->map(dihedral_atom2[i][m]);
       atom3 = atom->map(dihedral_atom3[i][m]);
       atom4 = atom->map(dihedral_atom4[i][m]);
       if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) {
-	char str[128];
-	sprintf(str,"Dihedral atoms %d %d %d %d missing on proc %d at step %d",
+	char str[128],fstr[128];
+	sprintf(fstr,"Dihedral atoms %%d %%d %%d %%d "
+		"missing on proc %%d at step %s",BIGINT_FORMAT);
+	sprintf(str,fstr,
 		dihedral_atom1[i][m],dihedral_atom2[i][m],
 		dihedral_atom3[i][m],dihedral_atom4[i][m],
 		me,update->ntimestep);
 	error->one(str);
       }
       if (newton_bond || 
 	  (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) {
 	if (ndihedrallist == maxdihedral) {
 	  maxdihedral += BONDDELTA;
 	  dihedrallist = 
 	    memory->grow_2d_int_array(dihedrallist,maxdihedral,5,
 				      "neighbor:dihedrallist");
 	}
 	dihedrallist[ndihedrallist][0] = atom1;
 	dihedrallist[ndihedrallist][1] = atom2;
 	dihedrallist[ndihedrallist][2] = atom3;
 	dihedrallist[ndihedrallist][3] = atom4;
 	dihedrallist[ndihedrallist][4] = dihedral_type[i][m];
 	ndihedrallist++;
       }
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Neighbor::improper_all()
 {
   int i,m,atom1,atom2,atom3,atom4;
 
   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;
   int **improper_type = atom->improper_type;
   int newton_bond = force->newton_bond;
 
   nimproperlist = 0;
 
   for (i = 0; i < nlocal; i++)
     for (m = 0; m < num_improper[i]; m++) {
       atom1 = atom->map(improper_atom1[i][m]);
       atom2 = atom->map(improper_atom2[i][m]);
       atom3 = atom->map(improper_atom3[i][m]);
       atom4 = atom->map(improper_atom4[i][m]);
       if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) {
-	char str[128];
-	sprintf(str,"Improper atoms %d %d %d %d missing on proc %d at step %d",
+	char str[128],fstr[128];
+	sprintf(fstr,"Improper atoms %%d %%d %%d %%d "
+		"missing on proc %%d at step %s",BIGINT_FORMAT);
+	sprintf(str,fstr,
 		improper_atom1[i][m],improper_atom2[i][m],
 		improper_atom3[i][m],improper_atom4[i][m],
 		me,update->ntimestep);
 	error->one(str);
       }
       if (newton_bond || 
 	  (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) {
 	if (nimproperlist == maximproper) {
 	  maximproper += BONDDELTA;
 	  improperlist = 
 	    memory->grow_2d_int_array(improperlist,maximproper,5,
 				      "neighbor:improperlist");
 	}
 	improperlist[nimproperlist][0] = atom1;
 	improperlist[nimproperlist][1] = atom2;
 	improperlist[nimproperlist][2] = atom3;
 	improperlist[nimproperlist][3] = atom4;
 	improperlist[nimproperlist][4] = improper_type[i][m];
 	nimproperlist++;
       }
     }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Neighbor::improper_partial()
 {
   int i,m,atom1,atom2,atom3,atom4;
 
   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;
   int **improper_type = atom->improper_type;
   int newton_bond = force->newton_bond;
 
   nimproperlist = 0;
 
   for (i = 0; i < nlocal; i++)
     for (m = 0; m < num_improper[i]; m++) {
       if (improper_type[i][m] <= 0) continue;
       atom1 = atom->map(improper_atom1[i][m]);
       atom2 = atom->map(improper_atom2[i][m]);
       atom3 = atom->map(improper_atom3[i][m]);
       atom4 = atom->map(improper_atom4[i][m]);
       if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) {
-	char str[128];
-	sprintf(str,"Improper atoms %d %d %d %d missing on proc %d at step %d",
+	char str[128],fstr[128];
+	sprintf(fstr,"Improper atoms %%d %%d %%d %%d "
+		"missing on proc %%d at step %s",BIGINT_FORMAT);
+	sprintf(str,fstr,
 		improper_atom1[i][m],improper_atom2[i][m],
 		improper_atom3[i][m],improper_atom4[i][m],
 		me,update->ntimestep);
 	error->one(str);
       }
       if (newton_bond || 
 	  (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) {
 	if (nimproperlist == maximproper) {
 	  maximproper += BONDDELTA;
 	  improperlist = 
 	    memory->grow_2d_int_array(improperlist,maximproper,5,
 				      "neighbor:improperlist");
 	}
 	improperlist[nimproperlist][0] = atom1;
 	improperlist[nimproperlist][1] = atom2;
 	improperlist[nimproperlist][2] = atom3;
 	improperlist[nimproperlist][3] = atom4;
 	improperlist[nimproperlist][4] = improper_type[i][m];
 	nimproperlist++;
       }
     }
 }
diff --git a/src/output.cpp b/src/output.cpp
index 720c02060..a9b701848 100644
--- a/src/output.cpp
+++ b/src/output.cpp
@@ -1,542 +1,546 @@
 /* ----------------------------------------------------------------------
    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 "stdio.h"
 #include "stdlib.h"
 #include "string.h"
 #include "output.h"
 #include "style_dump.h"
 #include "atom.h"
 #include "neighbor.h"
 #include "input.h"
 #include "variable.h"
 #include "comm.h"
 #include "update.h"
 #include "group.h"
 #include "domain.h"
 #include "thermo.h"
 #include "modify.h"
 #include "compute.h"
 #include "force.h"
 #include "dump.h"
 #include "write_restart.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define DELTA 1
 
 #define MYMIN(a,b) ((a) < (b) ? (a) : (b))
 #define MYMAX(a,b) ((a) > (b) ? (a) : (b))
 
 /* ----------------------------------------------------------------------
    initialize all output 
 ------------------------------------------------------------------------- */
 
 Output::Output(LAMMPS *lmp) : Pointers(lmp)
 {
   // create default computes for temp,pressure,pe
 
   char **newarg = new char*[4];
   newarg[0] = (char *) "thermo_temp";
   newarg[1] = (char *) "all";
   newarg[2] = (char *) "temp";
   modify->add_compute(3,newarg);
 
   newarg[0] = (char *) "thermo_press";
   newarg[1] = (char *) "all";
   newarg[2] = (char *) "pressure";
   newarg[3] = (char *) "thermo_temp";
   modify->add_compute(4,newarg);
 
   newarg[0] = (char *) "thermo_pe";
   newarg[1] = (char *) "all";
   newarg[2] = (char *) "pe";
   modify->add_compute(3,newarg);
 
   delete [] newarg;
 
   // create default Thermo class
 
   newarg = new char*[1];
   newarg[0] = (char *) "one";
   thermo = new Thermo(lmp,1,newarg);
   delete [] newarg;
     
   thermo_every = 0;
   var_thermo = NULL;
   
   ndump = 0;
   max_dump = 0;
   every_dump = NULL;
   next_dump = NULL;
   last_dump = NULL;
   var_dump = NULL;
   ivar_dump = NULL;
   dump = NULL;
 
   restart = NULL;
   restart1 = restart2 = NULL;
   restart_every = 0;
   last_restart = -1;
 }
 
 /* ----------------------------------------------------------------------
    free all memory 
 ------------------------------------------------------------------------- */
 
 Output::~Output()
 {
   if (thermo) delete thermo;
   delete [] var_thermo;
 
   memory->sfree(every_dump);
   memory->sfree(next_dump);
   memory->sfree(last_dump);
   for (int i = 0; i < ndump; i++) delete [] var_dump[i];
   memory->sfree(var_dump);
   memory->sfree(ivar_dump);
   for (int i = 0; i < ndump; i++) delete dump[i];
   memory->sfree(dump);
 
   delete restart;
   delete [] restart1;
   delete [] restart2;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Output::init()
 {
   thermo->init();
   if (thermo_every) delete [] var_thermo;
   else if (var_thermo) {
     ivar_thermo = input->variable->find(var_thermo);
     if (ivar_thermo < 0)
       error->all("Variable name for thermo every does not exist");
     if (!input->variable->equalstyle(ivar_thermo))
       error->all("Variable for thermo every is invalid style");
   }
 
   for (int i = 0; i < ndump; i++) dump[i]->init();
   for (int i = 0; i < ndump; i++)
     if (every_dump[i] == 0) {
       ivar_dump[i] = input->variable->find(var_dump[i]);
       if (ivar_dump[i] < 0)
 	error->all("Variable name for dump every does not exist");
       if (!input->variable->equalstyle(ivar_dump[i]))
 	error->all("Variable for dump every is invalid style");
     }
 }
 
 /* ----------------------------------------------------------------------
    perform output for setup of run/min
    do dump first, so memory_usage will include dump allocation
    do thermo last, so will print after memory_usage
 ------------------------------------------------------------------------- */
 
 void Output::setup(int flag)
 {
-  int ntimestep = update->ntimestep;
+  bigint ntimestep = update->ntimestep;
 
   // perform dump at start of run if current timestep is multiple of every
   //   and last dump was not on this timestep
   // set next_dump to multiple of every
   // will not write on last step of run unless multiple of every
   // set next_dump_any to smallest next_dump
   // if no dumps, set next_dump_any to last+1 so will not influence next
   // wrap dumps that invoke computes with clear/add
   // if dump not written now, add_all on future step since clear/add is noop
 
   int writeflag;
 
   if (ndump && update->restrict_output == 0) {
     for (int idump = 0; idump < ndump; idump++) {
       if (dump[idump]->clearstep) modify->clearstep_compute();
       writeflag = 0;
       if (every_dump[idump] && ntimestep % every_dump[idump] == 0 && 
 	  last_dump[idump] != ntimestep) writeflag = 1;
       if (last_dump[idump] < 0 && dump[idump]->first_flag == 1) writeflag = 1;
       if (writeflag) {
 	dump[idump]->write();
 	last_dump[idump] = ntimestep;
       }
       if (every_dump[idump])
 	next_dump[idump] = 
 	  (ntimestep/every_dump[idump])*every_dump[idump] + every_dump[idump];
       else {
 	int nextdump = static_cast<int> 
 	  (input->variable->compute_equal(ivar_dump[idump]));
 	if (nextdump <= ntimestep)
 	  error->all("Dump every variable returned a bad timestep");
 	next_dump[idump] = nextdump;
       }
       if (dump[idump]->clearstep) {
 	if (writeflag) modify->addstep_compute(next_dump[idump]);
 	else modify->addstep_compute_all(next_dump[idump]);
       }
       if (idump) next_dump_any = MYMIN(next_dump_any,next_dump[idump]);
       else next_dump_any = next_dump[0];
     }
   } else next_dump_any = update->laststep + 1;
 
   // do not write a restart file at start of run
   // set next_restart to multiple of every
   // will not write on last step of run unless multiple of every
   // if every = 0, set next_restart to last+1 so will not influence next
 
   if (restart_every && update->restrict_output == 0)
     next_restart = (ntimestep/restart_every)*restart_every + restart_every;
   else next_restart = update->laststep + 1;
 
   // print memory usage unless being called between multiple runs
 
   if (flag) memory_usage();
 
   // always do thermo with header at start of run
   // set next_thermo to multiple of every or last step of run (if smaller)
   // if every = 0, set next_thermo to last step of run
   // thermo may invoke computes so wrap with clear/add
 
   modify->clearstep_compute();
 
   thermo->header();
   thermo->compute(0);
   last_thermo = ntimestep;
 
   if (thermo_every) {
     next_thermo = (ntimestep/thermo_every)*thermo_every + thermo_every;
     next_thermo = MYMIN(next_thermo,update->laststep);
   } else if (var_thermo) {
     next_thermo = static_cast<int> 
       (input->variable->compute_equal(ivar_thermo));
     if (next_thermo <= ntimestep)
       error->all("Thermo every variable returned a bad timestep");
   } else next_thermo = update->laststep;
 
   modify->addstep_compute(next_thermo);
 
   // next = next timestep any output will be done
 
   next = MYMIN(next_dump_any,next_restart);
   next = MYMIN(next,next_thermo);
 }
 
 /* ----------------------------------------------------------------------
    perform all output for this timestep
    only perform output if next matches current step and last doesn't
    do dump/restart before thermo so thermo CPU time will include them
 ------------------------------------------------------------------------- */
 
-void Output::write(int ntimestep)
+void Output::write(bigint ntimestep)
 {
   // next_dump does not force output on last step of run
   // wrap dumps that invoke computes with clear/add
 
   if (next_dump_any == ntimestep) {
     for (int idump = 0; idump < ndump; idump++) {
       if (next_dump[idump] == ntimestep && last_dump[idump] != ntimestep) {
         if (dump[idump]->clearstep) modify->clearstep_compute();
 	dump[idump]->write();
 	last_dump[idump] = ntimestep;
 	if (every_dump[idump]) next_dump[idump] += every_dump[idump];
 	else {
 	  int nextdump = static_cast<int> 
 	    (input->variable->compute_equal(ivar_dump[idump]));
 	  if (nextdump <= ntimestep)
 	    error->all("Dump every variable returned a bad timestep");
 	  next_dump[idump] = nextdump;
 	}
         if (dump[idump]->clearstep) modify->addstep_compute(next_dump[idump]);
       }
       if (idump) next_dump_any = MYMIN(next_dump_any,next_dump[idump]);
       else next_dump_any = next_dump[0];
     }
   }
 
   // next_restart does not force output on last step of run
   // for toggle = 0, replace "*" with current timestep in restart filename
 
   if (next_restart == ntimestep && last_restart != ntimestep) {
     if (restart_toggle == 0) {
       char *file = new char[strlen(restart1) + 16];
       char *ptr = strchr(restart1,'*');
       *ptr = '\0';
-      sprintf(file,"%s%d%s",restart1,ntimestep,ptr+1);
+      char fstr[16];
+      sprintf(fstr,"%%s%s%%s",BIGINT_FORMAT);
+      sprintf(file,fstr,restart1,ntimestep,ptr+1);
       *ptr = '*';
       restart->write(file);
       delete [] file;
     } else if (restart_toggle == 1) {
       restart->write(restart1);
       restart_toggle = 2;
     } else if (restart_toggle == 2) {
       restart->write(restart2);
       restart_toggle = 1;
     }
     last_restart = ntimestep;
     next_restart += restart_every;
   }
 
   // insure next_thermo forces output on last step of run
   // thermo may invoke computes so wrap with clear/add
 
   if (next_thermo == ntimestep && last_thermo != ntimestep) {
     modify->clearstep_compute();
     thermo->compute(1);
     last_thermo = ntimestep;
     if (thermo_every) next_thermo += thermo_every;
     else if (var_thermo) {
       next_thermo = static_cast<int> 
 	(input->variable->compute_equal(ivar_thermo));
       if (next_thermo <= ntimestep)
 	error->all("Thermo every variable returned a bad timestep");
     } else next_thermo = update->laststep;
     next_thermo = MYMIN(next_thermo,update->laststep);
     modify->addstep_compute(next_thermo);
   }
 
   // next = next timestep any output will be done
 
   next = MYMIN(next_dump_any,next_restart);
   next = MYMIN(next,next_thermo);
 }
 
 /* ----------------------------------------------------------------------
    force a snapshot to be written for all dumps
 ------------------------------------------------------------------------- */
 
-void Output::write_dump(int ntimestep)
+void Output::write_dump(bigint ntimestep)
 {
   for (int idump = 0; idump < ndump; idump++) {
     dump[idump]->write();
     last_dump[idump] = ntimestep;
   }
 }
 
 /* ----------------------------------------------------------------------
    force a restart file to be written
 ------------------------------------------------------------------------- */
 
-void Output::write_restart(int ntimestep)
+void Output::write_restart(bigint ntimestep)
 {
   if (restart_toggle == 0) {
     char *file = new char[strlen(restart1) + 16];
     char *ptr = strchr(restart1,'*');
     *ptr = '\0';
-    sprintf(file,"%s%d%s",restart1,ntimestep,ptr+1);
+    char fstr[16];
+    sprintf(fstr,"%%s%s%%s",BIGINT_FORMAT);
+    sprintf(file,fstr,restart1,ntimestep,ptr+1);
     *ptr = '*';
     restart->write(file);
     delete [] file;
   } else if (restart_toggle == 1) {
     restart->write(restart1);
     restart_toggle = 2;
   } else if (restart_toggle == 2) {
     restart->write(restart2);
     restart_toggle = 1;
   }
 
   last_restart = ntimestep;
 }
 
 /* ----------------------------------------------------------------------
    add a Dump to list of Dumps 
 ------------------------------------------------------------------------- */
 
 void Output::add_dump(int narg, char **arg)
 {
   if (narg < 5) error->all("Illegal dump command");
 
   // error checks
 
   for (int idump = 0; idump < ndump; idump++)
     if (strcmp(arg[0],dump[idump]->id) == 0) error->all("Reuse of dump ID");
   int igroup = group->find(arg[1]);
   if (igroup == -1) error->all("Could not find dump group ID");
   if (atoi(arg[3]) <= 0) error->all("Invalid dump frequency");
 
   // extend Dump list if necessary
 
   if (ndump == max_dump) {
     max_dump += DELTA;
     dump = (Dump **)
       memory->srealloc(dump,max_dump*sizeof(Dump *),"output:dump");
     every_dump = (int *)
       memory->srealloc(every_dump,max_dump*sizeof(int),"output:every_dump");
-    next_dump = (int *)
-      memory->srealloc(next_dump,max_dump*sizeof(int),"output:next_dump");
-    last_dump = (int *)
-      memory->srealloc(last_dump,max_dump*sizeof(int),"output:last_dump");
+    next_dump = (bigint *)
+      memory->srealloc(next_dump,max_dump*sizeof(bigint),"output:next_dump");
+    last_dump = (bigint *)
+      memory->srealloc(last_dump,max_dump*sizeof(bigint),"output:last_dump");
     var_dump = (char **)
       memory->srealloc(var_dump,max_dump*sizeof(char *),"output:var_dump");
     ivar_dump = (int *)
       memory->srealloc(ivar_dump,max_dump*sizeof(int),"output:ivar_dump");
   }
 
   // create the Dump
 
   if (0) return;         // dummy line to enable else-if macro expansion
 
 #define DUMP_CLASS
 #define DumpStyle(key,Class) \
   else if (strcmp(arg[2],#key) == 0) dump[ndump] = new Class(lmp,narg,arg);
 #include "style_dump.h"
 #undef DUMP_CLASS
 
   else error->all("Invalid dump style");
 
   every_dump[ndump] = atoi(arg[3]);
   if (every_dump[ndump] <= 0) error->all("Illegal dump command");
   last_dump[ndump] = -1;
   var_dump[ndump] = NULL;
   ndump++;
 }
 
 /* ----------------------------------------------------------------------
    modify parameters of a Dump 
 ------------------------------------------------------------------------- */
 
 void Output::modify_dump(int narg, char **arg)
 {
   if (narg < 1) error->all("Illegal dump_modify command");
 
   // find which dump it is
 
   int idump;
   for (idump = 0; idump < ndump; idump++)
     if (strcmp(arg[0],dump[idump]->id) == 0) break;
   if (idump == ndump) error->all("Cound not find dump_modify ID");
 
   dump[idump]->modify_params(narg-1,&arg[1]);
 }
 
 /* ----------------------------------------------------------------------
    delete a Dump from list of Dumps 
 ------------------------------------------------------------------------- */
 
 void Output::delete_dump(char *id)
 {
   // find which dump it is and delete it
 
   int idump;
   for (idump = 0; idump < ndump; idump++)
     if (strcmp(id,dump[idump]->id) == 0) break;
   if (idump == ndump) error->all("Could not find undump ID");
 
   delete dump[idump];
   delete [] var_dump[idump];
 
   // move other dumps down in list one slot
 
   for (int i = idump+1; i < ndump; i++) {
     dump[i-1] = dump[i];
     every_dump[i-1] = every_dump[i];
     next_dump[i-1] = next_dump[i];
     last_dump[i-1] = last_dump[i];
     var_dump[i-1] = var_dump[i];
     ivar_dump[i-1] = ivar_dump[i];
   }
   ndump--;
 }
 
 /* ----------------------------------------------------------------------
    new Thermo style 
 ------------------------------------------------------------------------- */
 
 void Output::create_thermo(int narg, char **arg)
 {
   if (narg < 1) error->all("Illegal thermo_style command");
 
   // don't allow this so that dipole style can safely allocate inertia vector
 
   if (domain->box_exist == 0) 
     error->all("Thermo_style command before simulation box is defined");
 
   // warn if previous thermo had been modified via thermo_modify command
 
   if (thermo->modified && comm->me == 0)
     error->warning("New thermo_style command, "
 		   "previous thermo_modify settings will be lost");
 
   // set thermo = NULL in case new Thermo throws an error
 
   delete thermo;
   thermo = NULL;
   thermo = new Thermo(lmp,narg,arg);
 }
 
 /* ----------------------------------------------------------------------
    setup restart capability
    if only one filename and it contains no "*", then append ".*"
 ------------------------------------------------------------------------- */
 
 void Output::create_restart(int narg, char **arg)
 {
   if (narg < 1) error->all("Illegal restart command");
 
   if (restart) delete restart;
   delete [] restart1;
   delete [] restart2;
   restart = NULL;
   restart1 = restart2 = NULL;
   last_restart = -1;
 
   restart_every = atoi(arg[0]);
   if (restart_every == 0) {
     if (narg != 1) error->all("Illegal restart command");
     return;
   }
 
   restart = new WriteRestart(lmp);
 
   int n = strlen(arg[1]) + 3;
   restart1 = new char[n];
   strcpy(restart1,arg[1]);
 
   if (narg == 2) {
     restart_toggle = 0;
     restart2 = NULL;
     if (strchr(restart1,'*') == NULL) strcat(restart1,".*");
   } else if (narg == 3) {
     restart_toggle = 1;
     n = strlen(arg[2]) + 1;
     restart2 = new char[n];
     strcpy(restart2,arg[2]);
   } else error->all("Illegal restart command");
 }
 
 /* ----------------------------------------------------------------------
    sum and print memory usage
    is only memory on proc 0, not averaged across procs
 ------------------------------------------------------------------------- */
 
 void Output::memory_usage()
 {
   double bytes = 0.0;
   bytes += atom->memory_usage();
   bytes += neighbor->memory_usage();
   bytes += comm->memory_usage();
   bytes += update->memory_usage();
   bytes += force->memory_usage();
   bytes += modify->memory_usage();
   for (int i = 0; i < ndump; i++) bytes += dump[i]->memory_usage();
 
   double mbytes = bytes/1024.0/1024.0;
 
   if (comm->me == 0) {
     if (screen)
       fprintf(screen,"Memory usage per processor = %g Mbytes\n",mbytes);
     if (logfile) 
       fprintf(logfile,"Memory usage per processor = %g Mbytes\n",mbytes);
   }
 }
diff --git a/src/output.h b/src/output.h
index 12668c2cf..9e0c72acb 100644
--- a/src/output.h
+++ b/src/output.h
@@ -1,70 +1,71 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_OUTPUT_H
 #define LMP_OUTPUT_H
 
 #include "pointers.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class Output : protected Pointers {
  public:
-  int next;                    // next timestep for any kind of output
+  bigint next;                 // next timestep for any kind of output
 
-  int next_thermo;             // next timestep for thermo output
+  bigint next_thermo;          // next timestep for thermo output
   int thermo_every;            // thermo output every this many steps
-  int last_thermo;             // last timestep thermo was output
+  bigint last_thermo;          // last timestep thermo was output
   char *var_thermo;            // variable name for thermo frequency
   int ivar_thermo;             // variable index for thermo frequency
   class Thermo *thermo;        // Thermodynamic computations
 
   int ndump;                   // # of Dumps defined
   int max_dump;                // max size of Dump list
-  int next_dump_any;           // next timestep for any Dump
+  bigint next_dump_any;        // next timestep for any Dump
   int *every_dump;             // output of each Dump every this many steps
-  int *next_dump;              // next timestep to do each Dump
-  int *last_dump;              // last timestep each a snapshot was output
+  bigint *next_dump;           // next timestep to do each Dump
+  bigint *last_dump;           // last timestep each snapshot was output
   char **var_dump;             // variable name for dump frequency
   int *ivar_dump;              // variable index for dump frequency
   class Dump **dump;           // list of defined Dumps
 
-  int next_restart;            // next timestep to write a restart file
+  bigint next_restart;         // next timestep to write a restart file
   int restart_every;           // write a restart file every this many steps
-  int last_restart;            // last timestep a restart file was output
+  bigint last_restart;         // last timestep a restart file was output
   int restart_toggle;          // 0 if use restart1 as prefix
                                // 1 if use restart1 as file, 2 for restart2
   char *restart1,*restart2;    // names for restart files
   class WriteRestart *restart; // Restart output
 
   Output(class LAMMPS *);
   ~Output();
   void init();
   void setup(int);                   // initial output before run/min
-  void write(int);                   // output for current timestep
-  void write_dump(int);              // force output of dump snapshots
-  void write_restart(int);           // force output of a restart file
+  void write(bigint);                // output for current timestep
+  void write_dump(bigint);           // force output of dump snapshots
+  void write_restart(bigint);        // force output of a restart file
 
   void add_dump(int, char **);       // add a Dump to Dump list
   void modify_dump(int, char **);    // modify a Dump
   void delete_dump(char *);          // delete a Dump from Dump list
 
   void create_thermo(int, char **);  // create a thermo style
   void create_restart(int, char **); // create Restart and restart files
 
   void memory_usage();               // print out memory usage
 };
 
 }
 
 #endif
diff --git a/src/read_data.cpp b/src/read_data.cpp
index f8229bdfd..b38f22869 100644
--- a/src/read_data.cpp
+++ b/src/read_data.cpp
@@ -1,1364 +1,1390 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "mpi.h"
 #include "string.h"
 #include "stdlib.h"
 #include "read_data.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "comm.h"
 #include "update.h"
 #include "force.h"
 #include "pair.h"
 #include "domain.h"
 #include "bond.h"
 #include "angle.h"
 #include "dihedral.h"
 #include "improper.h"
 #include "error.h"
 #include "memory.h"
 #include "special.h"
 
 using namespace LAMMPS_NS;
 
 #define MAXLINE 256
 #define LB_FACTOR 1.1
 #define CHUNK 1024
 #define DELTA 4            // must be 2 or larger
 
 #define NSECTIONS 22       // change when add to header::section_keywords
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 /* ---------------------------------------------------------------------- */
 
 ReadData::ReadData(LAMMPS *lmp) : Pointers(lmp)
 {
   MPI_Comm_rank(world,&me);
   line = new char[MAXLINE];
   keyword = new char[MAXLINE];
   buffer = new char[CHUNK*MAXLINE];
   narg = maxarg = 0;
   arg = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
 
 ReadData::~ReadData()
 {
   delete [] line;
   delete [] keyword;
   delete [] buffer;
   memory->sfree(arg);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::command(int narg, char **arg)
 {
   if (narg != 1) error->all("Illegal read_data command");
 
   if (domain->box_exist) 
     error->all("Cannot read_data after simulation box is defined");
   if (domain->dimension == 2 && domain->zperiodic == 0)
     error->all("Cannot run 2d simulation with nonperiodic Z dimension");
 
   // 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;
     }
 
     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);
 
   } else
     atom->bond_per_atom = atom->angle_per_atom =
       atom->dihedral_per_atom = atom->improper_per_atom = 0;
 
   // read header info
 
   if (me == 0) {
     if (screen) fprintf(screen,"Reading data file ...\n");
     open(arg[0]);
   }
   header(1);
   domain->box_exist = 1;
 
   // problem setup using info from header
 
   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_procs();
   domain->set_local_box();
 
   // read rest of file in free format
   // if add a section keyword, add to header::section_keywords and NSECTIONS
 
   int atomflag = 0;
 
   while (strlen(keyword)) {
     if (strcmp(keyword,"Atoms") == 0) {
       atoms();
       atomflag = 1;
     } else if (strcmp(keyword,"Velocities") == 0) {
       if (atomflag == 0) error->all("Must read Atoms before Velocities");
       velocities();
     } else if (strcmp(keyword,"Bonds") == 0) {
       if (atom->avec->bonds_allow == 0) 
 	error->all("Invalid data file section: Bonds");
       if (atomflag == 0) error->all("Must read Atoms before Bonds");
       bonds();
     } else if (strcmp(keyword,"Angles") == 0) {
       if (atom->avec->angles_allow == 0)
 	error->all("Invalid data file section: Angles");
       if (atomflag == 0) error->all("Must read Atoms before Angles");
       angles();
     } else if (strcmp(keyword,"Dihedrals") == 0) {
       if (atom->avec->dihedrals_allow == 0)
 	error->all("Invalid data file section: Dihedrals");
       if (atomflag == 0) error->all("Must read Atoms before Dihedrals");
       dihedrals();
     } else if (strcmp(keyword,"Impropers") == 0) {
       if (atom->avec->impropers_allow == 0) 
 	error->all("Invalid data file section: Impropers");
       if (atomflag == 0) error->all("Must read Atoms before Impropers");
       impropers();
 
     } else if (strcmp(keyword,"Masses") == 0) {
       mass();
     } else if (strcmp(keyword,"Shapes") == 0) {
       shape();
     } else if (strcmp(keyword,"Dipoles") == 0) {
       dipole();
     } else if (strcmp(keyword,"Pair Coeffs") == 0) {
       if (force->pair == NULL) 
 	error->all("Must define pair_style before Pair Coeffs");
       paircoeffs();
     } else if (strcmp(keyword,"Bond Coeffs") == 0) {
       if (atom->avec->bonds_allow == 0) 
 	error->all("Invalid data file section: Bond Coeffs");
       if (force->bond == NULL) 
 	error->all("Must define bond_style before Bond Coeffs");
       bondcoeffs();
     } else if (strcmp(keyword,"Angle Coeffs") == 0) {
       if (atom->avec->angles_allow == 0) 
 	error->all("Invalid data file section: Angle Coeffs");
       if (force->angle == NULL) 
 	error->all("Must define angle_style before Angle Coeffs");
       anglecoeffs(0);
     } else if (strcmp(keyword,"Dihedral Coeffs") == 0) {
       if (atom->avec->dihedrals_allow == 0) 
 	error->all("Invalid data file section: Dihedral Coeffs");
       if (force->dihedral == NULL) 
 	error->all("Must define dihedral_style before Dihedral Coeffs");
       dihedralcoeffs(0);
     } else if (strcmp(keyword,"Improper Coeffs") == 0) {
       if (atom->avec->impropers_allow == 0) 
 	error->all("Invalid data file section: Improper Coeffs");
       if (force->improper == NULL) 
 	error->all("Must define improper_style before Improper Coeffs");
       impropercoeffs(0);
 
     } else if (strcmp(keyword,"BondBond Coeffs") == 0) {
       if (atom->avec->angles_allow == 0) 
 	error->all("Invalid data file section: BondBond Coeffs");
       if (force->angle == NULL) 
 	error->all("Must define angle_style before BondBond Coeffs");
       anglecoeffs(1);
     } else if (strcmp(keyword,"BondAngle Coeffs") == 0) {
       if (atom->avec->angles_allow == 0) 
 	error->all("Invalid data file section: BondAngle Coeffs");
       if (force->angle == NULL) 
 	error->all("Must define angle_style before BondAngle Coeffs");
       anglecoeffs(2);
 
     } else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) {
       if (atom->avec->dihedrals_allow == 0) 
 	error->all("Invalid data file section: MiddleBondTorsion Coeffs");
       if (force->dihedral == NULL) 
 	error->all("Must define dihedral_style before MiddleBondTorsion Coeffs");
       dihedralcoeffs(1);
     } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
       if (atom->avec->dihedrals_allow == 0) 
 	error->all("Invalid data file section: EndBondTorsion Coeffs");
       if (force->dihedral == NULL) 
 	error->all("Must define dihedral_style before EndBondTorsion Coeffs");
       dihedralcoeffs(2);
     } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
       if (atom->avec->dihedrals_allow == 0) 
 	error->all("Invalid data file section: AngleTorsion Coeffs");
       if (force->dihedral == NULL) 
 	error->all("Must define dihedral_style before AngleTorsion Coeffs");
       dihedralcoeffs(3);
     } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
       if (atom->avec->dihedrals_allow == 0) 
 	error->all("Invalid data file section: AngleAngleTorsion Coeffs");
       if (force->dihedral == NULL) 
 	error->all("Must define dihedral_style before AngleAngleTorsion Coeffs");
       dihedralcoeffs(4);
     } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
       if (atom->avec->dihedrals_allow == 0) 
 	error->all("Invalid data file section: BondBond13 Coeffs");
       if (force->dihedral == NULL) 
 	error->all("Must define dihedral_style before BondBond13 Coeffs");
       dihedralcoeffs(5);
 
     } else if (strcmp(keyword,"AngleAngle Coeffs") == 0) {
       if (atom->avec->impropers_allow == 0) 
 	error->all("Invalid data file section: AngleAngle Coeffs");
       if (force->improper == NULL) 
 	error->all("Must define improper_style before AngleAngle Coeffs");
       impropercoeffs(1);
 
     } else {
       char str[128];
       sprintf(str,"Unknown identifier in data file: %s",keyword);
       error->all(str);
     }
 
     parse_keyword(0,1);
   }
 
   // close file
 
   if (me == 0) {
     if (compressed) pclose(fp);
     else fclose(fp);
   }
   
   // error if natoms > 0 yet no atoms were read
 
   if (atom->natoms > 0 && atomflag == 0) error->all("No atoms in data file");
 
   // create bond topology now that system is defined
 
   if (atom->molecular) {
     Special special(lmp);
     special.build();
   }
 }
 
 /* ----------------------------------------------------------------------
    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
      if EOF, line is set to blank line
      else line has first keyword line for rest of file
 ------------------------------------------------------------------------- */
 
 void ReadData::header(int flag)
 {
   int n;
   char *ptr;
 
   char *section_keywords[NSECTIONS] = 
     {"Atoms","Velocities","Bonds","Angles","Dihedrals","Impropers",
      "Masses","Shapes","Dipoles",
      "Pair Coeffs","Bond Coeffs","Angle Coeffs",
      "Dihedral Coeffs","Improper Coeffs",
      "BondBond Coeffs","BondAngle Coeffs","MiddleBondTorsion Coeffs",
      "EndBondTorsion Coeffs","AngleTorsion Coeffs",
      "AngleAngleTorsion Coeffs","BondBond13 Coeffs","AngleAngle Coeffs"};
   
   // skip 1st line of file
 
   if (me == 0) {
     char *eof = fgets(line,MAXLINE,fp);
     if (eof == NULL) error->one("Unexpected end of data file");
   }
 
   while (1) {
 
     // read a line and bcast length if flag is set
 
     if (me == 0) {
       if (fgets(line,MAXLINE,fp) == NULL) n = 0;
       else n = strlen(line) + 1;
     }
     if (flag) MPI_Bcast(&n,1,MPI_INT,0,world);
 
     // if n = 0 then end-of-file so return with blank line
 
     if (n == 0) {
       line[0] = '\0';
       return;
     }
 
     // bcast line if flag is set
 
     if (flag) MPI_Bcast(line,n,MPI_CHAR,0,world);
 
     // trim anything from '#' onward
     // if line is blank, continue
 
     if (ptr = strchr(line,'#')) *ptr = '\0';
     if (strspn(line," \t\n\r") == strlen(line)) continue;
 
     // search line for header keyword and set corresponding variable
 
-    if (strstr(line,"atoms")) sscanf(line,"%lu",&atom->natoms);
-    else if (strstr(line,"bonds")) sscanf(line,"%lu",&atom->nbonds);
-    else if (strstr(line,"angles")) sscanf(line,"%lu",&atom->nangles);
-    else if (strstr(line,"dihedrals")) sscanf(line,"%lu",&atom->ndihedrals);
-    else if (strstr(line,"impropers")) sscanf(line,"%lu",&atom->nimpropers);
+    if (strstr(line,"atoms")) sscanf(line,BIGINT_FORMAT,&atom->natoms);
+
+    else if (strstr(line,"bonds")) sscanf(line,BIGINT_FORMAT,&atom->nbonds);
+    else if (strstr(line,"angles")) sscanf(line,BIGINT_FORMAT,&atom->nangles);
+    else if (strstr(line,"dihedrals")) sscanf(line,BIGINT_FORMAT,
+					      &atom->ndihedrals);
+    else if (strstr(line,"impropers")) sscanf(line,BIGINT_FORMAT,
+					      &atom->nimpropers);
 
     else if (strstr(line,"atom types")) sscanf(line,"%d",&atom->ntypes);
     else if (strstr(line,"bond types")) sscanf(line,"%d",&atom->nbondtypes);
     else if (strstr(line,"angle types")) sscanf(line,"%d",&atom->nangletypes);
     else if (strstr(line,"dihedral types")) 
       sscanf(line,"%d",&atom->ndihedraltypes);
     else if (strstr(line,"improper types")) 
       sscanf(line,"%d",&atom->nimpropertypes);
 
     else if (strstr(line,"extra bond per atom"))
       sscanf(line,"%d",&atom->extra_bond_per_atom);
 
     else if (strstr(line,"xlo xhi")) 
       sscanf(line,"%lg %lg",&domain->boxlo[0],&domain->boxhi[0]);
     else if (strstr(line,"ylo yhi")) 
       sscanf(line,"%lg %lg",&domain->boxlo[1],&domain->boxhi[1]);
     else if (strstr(line,"zlo zhi")) 
       sscanf(line,"%lg %lg",&domain->boxlo[2],&domain->boxhi[2]);
     else if (strstr(line,"xy xz yz")) {
       domain->triclinic = 1;
       sscanf(line,"%lg %lg %lg",&domain->xy,&domain->xz,&domain->yz);
     } else break;
   }
 
+  // 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 (flag == 0) error->one("System in data file is too big");
+    else error->all("System in data file is too big");
+  }
+
   // check that exiting string is a valid section keyword
 
   parse_keyword(1,flag);
   for (n = 0; n < NSECTIONS; n++)
     if (strcmp(keyword,section_keywords[n]) == 0) break;
   if (n == NSECTIONS) {
     char str[128];
     sprintf(str,"Unknown identifier in data file: %s",keyword);
     error->all(str);
   }
 
   // error check on consistency of header values
 
   if ((atom->nbonds || atom->nbondtypes) && 
       atom->avec->bonds_allow == 0)
     error->one("No bonds allowed with this atom style");
   if ((atom->nangles || atom->nangletypes) && 
       atom->avec->angles_allow == 0)
     error->one("No angles allowed with this atom style");
   if ((atom->ndihedrals || atom->ndihedraltypes) && 
       atom->avec->dihedrals_allow == 0)
     error->one("No dihedrals allowed with this atom style");
   if ((atom->nimpropers || atom->nimpropertypes) && 
       atom->avec->impropers_allow == 0)
     error->one("No impropers allowed with this atom style");
 
   if (atom->nbonds > 0 && atom->nbondtypes <= 0)
     error->one("Bonds defined but no bond types");
   if (atom->nangles > 0 && atom->nangletypes <= 0)
     error->one("Angles defined but no angle types");
   if (atom->ndihedrals > 0 && atom->ndihedraltypes <= 0)
     error->one("Dihedrals defined but no dihedral types");
   if (atom->nimpropers > 0 && atom->nimpropertypes <= 0)
     error->one("Impropers defined but no improper types");
 }
 
 /* ----------------------------------------------------------------------
    read all atoms
 ------------------------------------------------------------------------- */
 
 void ReadData::atoms()
 {
   int i,m,nchunk;
   
   bigint nread = 0;
   bigint natoms = atom->natoms;
 
   while (nread < natoms) {
     if (natoms-nread > CHUNK) nchunk = CHUNK;
     else nchunk = natoms-nread;
     if (me == 0) {
       char *eof;
       m = 0;
       for (i = 0; i < nchunk; i++) {
 	eof = fgets(&buffer[m],MAXLINE,fp);
 	if (eof == NULL) error->one("Unexpected end of data file");
 	m += strlen(&buffer[m]);
       }
       buffer[m++] = '\n';
     }
     MPI_Bcast(&m,1,MPI_INT,0,world);
     MPI_Bcast(buffer,m,MPI_CHAR,0,world);
 
     atom->data_atoms(nchunk,buffer);
     nread += nchunk;
   }
 
   // check that all atoms were assigned correctly
 
   bigint tmp = atom->nlocal;
-  MPI_Allreduce(&tmp,&natoms,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&tmp,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
 
   if (me == 0) {
-    if (screen) fprintf(screen,"  %lu atoms\n",natoms);
-    if (logfile) fprintf(logfile,"  %lu atoms\n",natoms);
+    char str[32];
+    sprintf(str,"  %s atoms\n",BIGINT_FORMAT);
+    if (screen) fprintf(screen,str,natoms);
+    if (logfile) fprintf(logfile,str,natoms);
   }
 
   if (natoms != atom->natoms) error->all("Did not assign all atoms correctly");
   
   // 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("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("Invalid atom ID in Atoms section of data file");
   }
 
   // create global mapping
 
   if (atom->map_style) {
     atom->map_init();
     atom->map_set();
   }
 }
 
 /* ----------------------------------------------------------------------
    read all velocities
    to find atoms, must build atom map if not a molecular system 
 ------------------------------------------------------------------------- */
 
 void ReadData::velocities()
 {
   int i,m,nchunk;
 
   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 = atom->natoms;
 
   while (nread < natoms) {
     if (natoms-nread > CHUNK) nchunk = CHUNK;
     else nchunk = natoms-nread;
     if (me == 0) {
       char *eof;
       m = 0;
       for (i = 0; i < nchunk; i++) {
 	eof = fgets(&buffer[m],MAXLINE,fp);
 	if (eof == NULL) error->one("Unexpected end of data file");
 	m += strlen(&buffer[m]);
       }
       buffer[m++] = '\n';
     }
     MPI_Bcast(&m,1,MPI_INT,0,world);
     MPI_Bcast(buffer,m,MPI_CHAR,0,world);
 
     atom->data_vels(nchunk,buffer);
     nread += nchunk;
   }
 
   if (mapflag) {
     atom->map_delete();
     atom->map_style = 0;
   }
 
   if (me == 0) {
-    if (screen) fprintf(screen,"  %lu velocities\n",natoms);
-    if (logfile) fprintf(logfile,"  %lu velocities\n",natoms);
+    char str[32];
+    sprintf(str,"  %s velocities\n",BIGINT_FORMAT);
+    if (screen) fprintf(screen,str,natoms);
+    if (logfile) fprintf(logfile,str,natoms);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::bonds()
 {
   int i,m,nchunk;
 
   bigint nread = 0;
   bigint nbonds = atom->nbonds;
 
   while (nread < nbonds) {
     nchunk = MIN(nbonds-nread,CHUNK);
     if (me == 0) {
       char *eof;
       m = 0;
       for (i = 0; i < nchunk; i++) {
 	eof = fgets(&buffer[m],MAXLINE,fp);
 	if (eof == NULL) error->one("Unexpected end of data file");
 	m += strlen(&buffer[m]);
       }
       buffer[m++] = '\n';
     }
     MPI_Bcast(&m,1,MPI_INT,0,world);
     MPI_Bcast(buffer,m,MPI_CHAR,0,world);
 
     atom->data_bonds(nchunk,buffer);
     nread += nchunk;
   }
 
   // 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];
-  MPI_Allreduce(&n,&sum,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
   int factor = 1;
   if (!force->newton_bond) factor = 2;
 
   if (me == 0) {
-    if (screen) fprintf(screen,"  %lu bonds\n",sum/factor);
-    if (logfile) fprintf(logfile,"  %lu bonds\n",sum/factor);
+    char str[32];
+    sprintf(str,"  %s bonds\n",BIGINT_FORMAT);
+    if (screen) fprintf(screen,str,sum/factor);
+    if (logfile) fprintf(logfile,str,sum/factor);
   }
   if (sum != factor*atom->nbonds) error->all("Bonds assigned incorrectly");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::angles()
 {
   int i,m,nchunk;
 
   bigint nread = 0;
   bigint nangles = atom->nangles;
 
   while (nread < nangles) {
     nchunk = MIN(nangles-nread,CHUNK);
     if (me == 0) {
       char *eof;
       m = 0;
       for (i = 0; i < nchunk; i++) {
 	eof = fgets(&buffer[m],MAXLINE,fp);
 	if (eof == NULL) error->one("Unexpected end of data file");
 	m += strlen(&buffer[m]);
       }
       buffer[m++] = '\n';
     }
     MPI_Bcast(&m,1,MPI_INT,0,world);
     MPI_Bcast(buffer,m,MPI_CHAR,0,world);
 
     atom->data_angles(nchunk,buffer);
     nread += nchunk;
   }
 
   // check that ang
 
   int nlocal = atom->nlocal;
   bigint sum;
   bigint n = 0;
   for (i = 0; i < nlocal; i++) n += atom->num_angle[i];
-  MPI_Allreduce(&n,&sum,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
   int factor = 1;
   if (!force->newton_bond) factor = 3;
 
   if (me == 0) {
-    if (screen) fprintf(screen,"  %lu angles\n",sum/factor);
-    if (logfile) fprintf(logfile,"  %lu angles\n",sum/factor);
+    char str[32];
+    sprintf(str,"  %s angles\n",BIGINT_FORMAT);
+    if (screen) fprintf(screen,str,sum/factor);
+    if (logfile) fprintf(logfile,str,sum/factor);
   }
   if (sum != factor*atom->nangles) error->all("Angles assigned incorrectly");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::dihedrals()
 {
   int i,m,nchunk;
 
   bigint nread = 0;
   bigint ndihedrals = atom->ndihedrals;
 
   while (nread < ndihedrals) {
     nchunk = MIN(ndihedrals-nread,CHUNK);
     if (me == 0) {
       char *eof;
       m = 0;
       for (i = 0; i < nchunk; i++) {
 	eof = fgets(&buffer[m],MAXLINE,fp);
 	if (eof == NULL) error->one("Unexpected end of data file");
 	m += strlen(&buffer[m]);
       }
       buffer[m++] = '\n';
     }
     MPI_Bcast(&m,1,MPI_INT,0,world);
     MPI_Bcast(buffer,m,MPI_CHAR,0,world);
 
     atom->data_dihedrals(nchunk,buffer);
     nread += nchunk;
   }
 
   // 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];
-  MPI_Allreduce(&n,&sum,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
   int factor = 1;
   if (!force->newton_bond) factor = 4;
 
   if (me == 0) {
-    if (screen) fprintf(screen,"  %lu dihedrals\n",sum/factor);
-    if (logfile) fprintf(logfile,"  %lu dihedrals\n",sum/factor);
+    char str[32];
+    sprintf(str,"  %s dihedrals\n",BIGINT_FORMAT);
+    if (screen) fprintf(screen,str,sum/factor);
+    if (logfile) fprintf(logfile,str,sum/factor);
   }
   if (sum != factor*atom->ndihedrals) 
     error->all("Dihedrals assigned incorrectly");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::impropers()
 {
   int i,m,nchunk;
 
   bigint nread = 0;
   bigint nimpropers = atom->nimpropers;
 
   while (nread < nimpropers) {
     nchunk = MIN(nimpropers-nread,CHUNK);
     if (me == 0) {
       char *eof;
       m = 0;
       for (i = 0; i < nchunk; i++) {
 	eof = fgets(&buffer[m],MAXLINE,fp);
 	if (eof == NULL) error->one("Unexpected end of data file");
 	m += strlen(&buffer[m]);
       }
       buffer[m++] = '\n';
     }
     MPI_Bcast(&m,1,MPI_INT,0,world);
     MPI_Bcast(buffer,m,MPI_CHAR,0,world);
 
     atom->data_impropers(nchunk,buffer);
     nread += nchunk;
   }
 
   // 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];
-  MPI_Allreduce(&n,&sum,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world);
   int factor = 1;
   if (!force->newton_bond) factor = 4;
 
   if (me == 0) {
-    if (screen) fprintf(screen,"  %lu impropers\n",sum/factor);
-    if (logfile) fprintf(logfile,"  %lu impropers\n",sum/factor);
+    char str[32];
+    sprintf(str,"  %s impropers\n",BIGINT_FORMAT);
+    if (screen) fprintf(screen,str,sum/factor);
+    if (logfile) fprintf(logfile,str,sum/factor);
   }
   if (sum != factor*atom->nimpropers) 
     error->all("Impropers assigned incorrectly");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::mass()
 {
   int i,m;
   char *buf = new char[atom->ntypes*MAXLINE];
   char *original = buf;
 
   if (me == 0) {
     char *eof;
     m = 0;
     for (i = 0; i < atom->ntypes; i++) {
       eof = fgets(&buf[m],MAXLINE,fp);
       if (eof == NULL) error->one("Unexpected end of data file");
       m += strlen(&buf[m]);
       buf[m-1] = '\0';
     }
   }
 
   MPI_Bcast(&m,1,MPI_INT,0,world);
   MPI_Bcast(buf,m,MPI_CHAR,0,world);
 
   for (i = 0; i < atom->ntypes; i++) {
     atom->set_mass(buf);
     buf += strlen(buf) + 1;
   }
   delete [] original;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::shape()
 {
   int i,m;
   char *buf = new char[atom->ntypes*MAXLINE];
   char *original = buf;
 
   if (me == 0) {
     char *eof;
     m = 0;
     for (i = 0; i < atom->ntypes; i++) {
       eof = fgets(&buf[m],MAXLINE,fp);
       if (eof == NULL) error->one("Unexpected end of data file");
       m += strlen(&buf[m]);
       buf[m-1] = '\0';
     }
   }
 
   MPI_Bcast(&m,1,MPI_INT,0,world);
   MPI_Bcast(buf,m,MPI_CHAR,0,world);
 
   for (i = 0; i < atom->ntypes; i++) {
     atom->set_shape(buf);
     buf += strlen(buf) + 1;
   }
   delete [] original;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::dipole()
 {
   int i,m;
   char *buf = new char[atom->ntypes*MAXLINE];
   char *original = buf;
 
   if (me == 0) {
     char *eof;
     m = 0;
     for (i = 0; i < atom->ntypes; i++) {
       eof = fgets(&buf[m],MAXLINE,fp);
       if (eof == NULL) error->one("Unexpected end of data file");
       m += strlen(&buf[m]);
       buf[m-1] = '\0';
     }
   }
 
   MPI_Bcast(&m,1,MPI_INT,0,world);
   MPI_Bcast(buf,m,MPI_CHAR,0,world);
 
   for (i = 0; i < atom->ntypes; i++) {
     atom->set_dipole(buf);
     buf += strlen(buf) + 1;
   }
   delete [] original;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::paircoeffs()
 {
   int i,m;
   char *buf = new char[atom->ntypes*MAXLINE];
   char *original = buf;
 
   if (me == 0) {
     char *eof;
     m = 0;
     for (i = 0; i < atom->ntypes; i++) {
       eof = fgets(&buf[m],MAXLINE,fp);
       if (eof == NULL) error->one("Unexpected end of data file");
       m += strlen(&buf[m]);
       buf[m-1] = '\0';
     }
   }
 
   MPI_Bcast(&m,1,MPI_INT,0,world);
   MPI_Bcast(buf,m,MPI_CHAR,0,world);
 
   for (i = 0; i < atom->ntypes; i++) {
     m = strlen(buf) + 1;
     parse_coeffs(buf,NULL,1);
     force->pair->coeff(narg,arg);
     buf += m;
   }
   delete [] original;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::bondcoeffs()
 {
   int i,m;
   char *buf = new char[atom->nbondtypes*MAXLINE];
   char *original = buf;
 
   if (me == 0) {
     char *eof;
     m = 0;
     for (i = 0; i < atom->nbondtypes; i++) {
       eof = fgets(&buf[m],MAXLINE,fp);
       if (eof == NULL) error->one("Unexpected end of data file");
       m += strlen(&buf[m]);
       buf[m-1] = '\0';
     }
   }
 
   MPI_Bcast(&m,1,MPI_INT,0,world);
   MPI_Bcast(buf,m,MPI_CHAR,0,world);
 
   for (i = 0; i < atom->nbondtypes; i++) {
     m = strlen(buf) + 1;
     parse_coeffs(buf,NULL,0);
     force->bond->coeff(narg,arg);
     buf += m;
   }
   delete [] original;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::anglecoeffs(int which)
 {
   int i,m;
   char *buf = new char[atom->nangletypes*MAXLINE];
   char *original = buf;
 
   if (me == 0) {
     char *eof;
     m = 0;
     for (i = 0; i < atom->nangletypes; i++) {
       eof = fgets(&buf[m],MAXLINE,fp);
       if (eof == NULL) error->one("Unexpected end of data file");
       m += strlen(&buf[m]);
       buf[m-1] = '\0';
     }
   }
 
   MPI_Bcast(&m,1,MPI_INT,0,world);
   MPI_Bcast(buf,m,MPI_CHAR,0,world);
 
   for (i = 0; i < atom->nangletypes; i++) {
     m = strlen(buf) + 1;
     if (which == 0) parse_coeffs(buf,NULL,0);
     else if (which == 1) parse_coeffs(buf,"bb",0);
     else if (which == 2) parse_coeffs(buf,"ba",0);
     force->angle->coeff(narg,arg);
     buf += m;
   }
   delete [] original;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::dihedralcoeffs(int which)
 {
   int i,m;
   char *buf = new char[atom->ndihedraltypes*MAXLINE];
   char *original = buf;
 
   if (me == 0) {
     char *eof;
     m = 0;
     for (i = 0; i < atom->ndihedraltypes; i++) {
       eof = fgets(&buf[m],MAXLINE,fp);
       if (eof == NULL) error->one("Unexpected end of data file");
       m += strlen(&buf[m]);
       buf[m-1] = '\0';
     }
   }
 
   MPI_Bcast(&m,1,MPI_INT,0,world);
   MPI_Bcast(buf,m,MPI_CHAR,0,world);
 
   for (i = 0; i < atom->ndihedraltypes; i++) {
     m = strlen(buf) + 1;
     if (which == 0) parse_coeffs(buf,NULL,0);
     else if (which == 1) parse_coeffs(buf,"mbt",0);
     else if (which == 2) parse_coeffs(buf,"ebt",0);
     else if (which == 3) parse_coeffs(buf,"at",0);
     else if (which == 4) parse_coeffs(buf,"aat",0);
     else if (which == 5) parse_coeffs(buf,"bb13",0);
     force->dihedral->coeff(narg,arg);
     buf += m;
   }
   delete [] original;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadData::impropercoeffs(int which)
 {
   int i,m;
   char *buf = new char[atom->nimpropertypes*MAXLINE];
   char *original = buf;
 
   if (me == 0) {
     char *eof;
     m = 0;
     for (i = 0; i < atom->nimpropertypes; i++) {
       eof = fgets(&buf[m],MAXLINE,fp);
       if (eof == NULL) error->one("Unexpected end of data file");
       m += strlen(&buf[m]);
       buf[m-1] = '\0';
     }
   }
 
   MPI_Bcast(&m,1,MPI_INT,0,world);
   MPI_Bcast(buf,m,MPI_CHAR,0,world);
 
   for (i = 0; i < atom->nimpropertypes; i++) {
     m = strlen(buf) + 1;
     if (which == 0) parse_coeffs(buf,NULL,0);
     else if (which == 1) parse_coeffs(buf,"aa",0);
     force->improper->coeff(narg,arg);
     buf += m;
   }
   delete [] original;
 }
 
 /* ----------------------------------------------------------------------
    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 > MAXINT32)
+  if (atom->natoms > MAXSMALLINT)
     error->all("Molecular data file has too many atoms");
 
   int natoms = static_cast<int> (atom->natoms);
   bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0;
 
   // allocate topology counting vector
   // initially, array length = 1 to natoms
   // will grow via reallocate() if atom IDs > natoms
 
   int cmax = natoms + 1;
   int *count = (int *) memory->smalloc(cmax*sizeof(int),"read_data:count");
 
   while (strlen(keyword)) {
 
     if (strcmp(keyword,"Masses") == 0) skip_lines(atom->ntypes);
     else if (strcmp(keyword,"Dipoles") == 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,"Pair Coeffs") == 0) {
       if (force->pair == NULL) 
 	error->all("Must define pair_style before Pair Coeffs");
       skip_lines(atom->ntypes);
 
     } else if (strcmp(keyword,"Bond Coeffs") == 0) {
       if (atom->avec->bonds_allow == 0) 
 	error->all("Invalid data file section: Bond Coeffs");
       if (force->bond == NULL) 
 	error->all("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->all("Invalid data file section: Angle Coeffs");
       if (force->angle == NULL) 
 	error->all("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->all("Invalid data file section: Dihedral Coeffs");
       if (force->dihedral == NULL) 
 	error->all("Must define dihedral_style before Dihedral Coeffs");
 
     }  else if (strcmp(keyword,"Improper Coeffs") == 0) {
       if (atom->avec->impropers_allow == 0) 
 	error->all("Invalid data file section: Improper Coeffs");
       if (force->improper == NULL) 
 	error->all("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->all("Invalid data file section: BondBond Coeffs");
       if (force->angle == NULL) 
 	error->all("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->all("Invalid data file section: BondAngle Coeffs");
       if (force->angle == NULL) 
 	error->all("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->all("Invalid data file section: MiddleBondTorsion Coeffs");
       if (force->dihedral == NULL) 
 	error->all("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->all("Invalid data file section: EndBondTorsion Coeffs");
       if (force->dihedral == NULL) 
 	error->all("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->all("Invalid data file section: AngleTorsion Coeffs");
       if (force->dihedral == NULL) 
 	error->all("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->all("Invalid data file section: AngleAngleTorsion Coeffs");
       if (force->dihedral == NULL) 
 	error->all("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->all("Invalid data file section: BondBond13 Coeffs");
       if (force->dihedral == NULL) 
 	error->all("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->all("Invalid data file section: AngleAngle Coeffs");
       if (force->improper == NULL) 
 	error->all("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("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("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("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("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("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("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("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("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(str);
     }
 
     parse_keyword(0,0);
   }
 
   // free topology counting vector
 
   memory->sfree(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("Needed topology not in data file");
 }
 
 /* ----------------------------------------------------------------------
    reallocate the count vector from cmax to amax+1 and return new length
    zero new locations
 ------------------------------------------------------------------------- */
 
 int ReadData::reallocate(int **pcount, int cmax, int amax)
 {
   int *count = *pcount;
   count = (int *) 
     memory->srealloc(count,(amax+1)*sizeof(int),"read_data:count");
   for (int i = cmax; i <= amax; i++) count[i] = 0;
   *pcount = count;
   return amax+1;
 }
 
 /* ----------------------------------------------------------------------
    proc 0 opens data file
    test if gzipped
 ------------------------------------------------------------------------- */
 
 void ReadData::open(char *file)
 {
   compressed = 0;
   char *suffix = file + strlen(file) - 3;
   if (suffix > file && strcmp(suffix,".gz") == 0) compressed = 1;
   if (!compressed) fp = fopen(file,"r");
   else {
 #ifdef LAMMPS_GZIP
     char gunzip[128];
     sprintf(gunzip,"gunzip -c %s",file);
     fp = popen(gunzip,"r");
 #else
     error->one("Cannot open gzipped file");
 #endif
   }
 
   if (fp == NULL) {
     char str[128];
     sprintf(str,"Cannot open file %s",file);
     error->one(str);
   }
 }
 
 /* ----------------------------------------------------------------------
    grab next keyword
    read lines until one is non-blank
    keyword is all text on line w/out leading & trailing white space
    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)
 {
   int eof = 0;
 
   // proc 0 reads upto non-blank line plus 1 following line
   // eof is set to 1 if any read hits end-of-file
 
   if (me == 0) {
     if (!first) {
       if (fgets(line,MAXLINE,fp) == NULL) eof = 1;
     }
     while (eof == 0 && strspn(line," \t\n\r") == strlen(line)) {
       if (fgets(line,MAXLINE,fp) == NULL) eof = 1;
     }
     if (fgets(buffer,MAXLINE,fp) == NULL) eof = 1;
   }
 
   // if eof, set keyword empty and return
 
   if (flag) MPI_Bcast(&eof,1,MPI_INT,0,world);
   if (eof) {
     keyword[0] = '\0';
     return;
   }
 
   // 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);
   }
 
   // copy non-whitespace portion of line into keyword
 
   int start = strspn(line," \t\n\r");
   int stop = strlen(line) - 1;
   while (line[stop] == ' ' || line[stop] == '\t' 
 	 || line[stop] == '\n' || line[stop] == '\r') stop--;
   line[stop+1] = '\0';
   strcpy(keyword,&line[start]);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 reads N lines from file
 ------------------------------------------------------------------------- */
 
 void ReadData::skip_lines(int n)
 {
   char *eof;
   for (int i = 0; i < n; i++) eof = fgets(line,MAXLINE,fp);
   if (eof == NULL) error->one("Unexpected end of data file");
 }
 
 /* ----------------------------------------------------------------------
    parse a line of coeffs into words, storing them in narg,arg
    trim anything from '#' onward
    word strings remain in line, are not copied
    if addstr != NULL, add addstr as 2nd arg for class2 angle/dihedral/improper
    if dupflag, duplicate 1st word, so pair_coeff "2" becomes "2 2"
 ------------------------------------------------------------------------- */
 
 void ReadData::parse_coeffs(char *line, char *addstr, int dupflag)
 {
   char *ptr;
   if (ptr = strchr(line,'#')) *ptr = '\0';
 
   narg = 0;
   char *word = strtok(line," \t\n\r\f");
   while (word) {
     if (narg == maxarg) {
       maxarg += DELTA;
       arg = (char **) 
 	memory->srealloc(arg,maxarg*sizeof(char *),"read_data:arg");
     }
     arg[narg++] = word;
     if (addstr && narg == 1) arg[narg++] = addstr;
     if (dupflag && narg == 1) arg[narg++] = word;
     word = strtok(NULL," \t\n\r\f");
   }
 }
diff --git a/src/read_restart.cpp b/src/read_restart.cpp
index f325bc67b..15ddcf72e 100644
--- a/src/read_restart.cpp
+++ b/src/read_restart.cpp
@@ -1,824 +1,852 @@
 /* ----------------------------------------------------------------------
    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 "string.h"
 #include "stdlib.h"
 #include "sys/types.h"
 #include "dirent.h"
 #include "read_restart.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "domain.h"
 #include "comm.h"
 #include "irregular.h"
 #include "update.h"
 #include "modify.h"
 #include "fix.h"
 #include "fix_read_restart.h"
 #include "group.h"
 #include "force.h"
 #include "pair.h"
 #include "bond.h"
 #include "angle.h"
 #include "dihedral.h"
 #include "improper.h"
 #include "special.h"
 #include "universe.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 // same as write_restart.cpp
 
-enum{VERSION,UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2,
+enum{VERSION,SMALLINT,TAGINT,BIGINT,
+       UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2,
        NEWTON_PAIR,NEWTON_BOND,XPERIODIC,YPERIODIC,ZPERIODIC,
        BOUNDARY_00,BOUNDARY_01,BOUNDARY_10,BOUNDARY_11,BOUNDARY_20,BOUNDARY_21,
        ATOM_STYLE,NATOMS,NTYPES,
        NBONDS,NBONDTYPES,BOND_PER_ATOM,
        NANGLES,NANGLETYPES,ANGLE_PER_ATOM,
        NDIHEDRALS,NDIHEDRALTYPES,DIHEDRAL_PER_ATOM,
        NIMPROPERS,NIMPROPERTYPES,IMPROPER_PER_ATOM,
        BOXLO_0,BOXHI_0,BOXLO_1,BOXHI_1,BOXLO_2,BOXHI_2,
        SPECIAL_LJ_1,SPECIAL_LJ_2,SPECIAL_LJ_3,
        SPECIAL_COUL_1,SPECIAL_COUL_2,SPECIAL_COUL_3,
        XY,XZ,YZ};
 enum{MASS,SHAPE,DIPOLE};
 enum{PAIR,BOND,ANGLE,DIHEDRAL,IMPROPER};
 
 #define LB_FACTOR 1.1
 
 /* ---------------------------------------------------------------------- */
 
 ReadRestart::ReadRestart(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 void ReadRestart::command(int narg, char **arg)
 {
   if (narg != 1) error->all("Illegal read_restart command");
 
   if (domain->box_exist) 
     error->all("Cannot read_restart after simulation box is defined");
 
   MPI_Comm_rank(world,&me);
   MPI_Comm_size(world,&nprocs);
 
   // if filename contains "*", search dir for latest restart file
 
   char *file = new char[strlen(arg[0]) + 16];
   if (strchr(arg[0],'*')) file_search(arg[0],file);
   else strcpy(file,arg[0]);
 
   // check if filename contains "%"
 
   int multiproc;
   if (strchr(file,'%')) multiproc = 1;
   else multiproc = 0;
 
   // open single restart file or base file for multiproc case
 
   if (me == 0) {
     if (screen) fprintf(screen,"Reading restart file ...\n");
     char *hfile;
     if (multiproc) {
       hfile = new char[strlen(file) + 16];
       char *ptr = strchr(file,'%');
       *ptr = '\0';
       sprintf(hfile,"%s%s%s",file,"base",ptr+1);
       *ptr = '%';
     } else hfile = file;
     fp = fopen(hfile,"rb");
     if (fp == NULL) {
       char str[128];
       sprintf(str,"Cannot open restart file %s",hfile);
       error->one(str);
     }
     if (multiproc) delete [] hfile;
   }
 
   // read header info and create atom style and simulation box
 
   header();
   domain->box_exist = 1;
 
   // problem setup using info from header
 
   int n;
   if (nprocs == 1) n = static_cast<int> (atom->natoms);
   else n = static_cast<int> (LB_FACTOR * atom->natoms / 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_procs();
   domain->set_local_box();
 
   // read groups, ntype-length arrays, force field, fix info from file
   // nextra = max # of extra quantities stored with each atom
 
   group->read_restart(fp);
   type_arrays();
   force_fields();
 
   int nextra = modify->read_restart(fp);
   atom->nextra_store = nextra;
   atom->extra = memory->create_2d_double_array(n,nextra,"atom:extra");
 
   // single file:
   // nprocs_file = # of chunks in file
   // proc 0 reads chunks one at a time and bcasts it to other procs
   // each proc unpacks the atoms, saving ones in it's sub-domain
   // check for atom in sub-domain differs for orthogonal vs triclinic box
   // close restart file when done
 
   AtomVec *avec = atom->avec;
 
   int maxbuf = 0;
   double *buf = NULL;
   int m;
 
   if (multiproc == 0) {
     int triclinic = domain->triclinic;
     double *x,lamda[3];
     double *coord,*sublo,*subhi;
     if (triclinic == 0) {
       sublo = domain->sublo;
       subhi = domain->subhi;
     } else {
       sublo = domain->sublo_lamda;
       subhi = domain->subhi_lamda;
     }
 
     for (int iproc = 0; iproc < nprocs_file; iproc++) {
       if (me == 0) fread(&n,sizeof(int),1,fp);
       MPI_Bcast(&n,1,MPI_INT,0,world);
       if (n > maxbuf) {
 	maxbuf = n;
 	memory->sfree(buf);
 	buf = (double *) memory->smalloc(maxbuf*sizeof(double),
 					 "read_restart:buf");
       }
 
       if (n > 0) {
 	if (me == 0) fread(buf,sizeof(double),n,fp);
 	MPI_Bcast(buf,n,MPI_DOUBLE,0,world);
       }
 
       m = 0;
       while (m < n) {
 	x = &buf[m+1];
 	if (triclinic) {
 	  domain->x2lamda(x,lamda);
 	  coord = lamda;
 	} else coord = x;
 	
 	if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
 	    coord[1] >= sublo[1] && coord[1] < subhi[1] &&
 	    coord[2] >= sublo[2] && coord[2] < subhi[2]) {
 	  m += avec->unpack_restart(&buf[m]);
 	}
 	else m += static_cast<int> (buf[m]);
       }
     }
 
     if (me == 0) fclose(fp);
 
   // one file per proc:
   // nprocs_file = # of files
   // each proc reads 1/P fraction of files, keeping all atoms in the files
   // perform irregular comm to migrate atoms to correct procs
   // close restart file when done
 
   } else {
     if (me == 0) fclose(fp);
     char *perproc = new char[strlen(file) + 16];
     char *ptr = strchr(file,'%');
 
     for (int iproc = me; iproc < nprocs_file; iproc += nprocs) {
       *ptr = '\0';
       sprintf(perproc,"%s%d%s",file,iproc,ptr+1);
       *ptr = '%';
       fp = fopen(perproc,"rb");
       if (fp == NULL) {
 	char str[128];
 	sprintf(str,"Cannot open restart file %s",perproc);
 	error->one(str);
       }
 
       fread(&n,sizeof(int),1,fp);
       if (n > maxbuf) {
 	maxbuf = n;
 	memory->sfree(buf);
 	buf = (double *) memory->smalloc(maxbuf*sizeof(double),
 					 "read_restart:buf");
       }
       if (n > 0) fread(buf,sizeof(double),n,fp);
 
       m = 0;
       while (m < n) m += avec->unpack_restart(&buf[m]);
       fclose(fp);
     }
 
     delete [] perproc;
 
     // create a temporary fix to hold and migrate extra atom info
     // necessary b/c irregular will migrate atoms
 
     if (nextra) {
       char cextra[8],fixextra[8];
       sprintf(cextra,"%d",nextra);
       sprintf(fixextra,"%d",modify->nfix_restart_peratom);
       char **newarg = new char*[5];
       newarg[0] = (char *) "_read_restart";
       newarg[1] = (char *) "all";
       newarg[2] = (char *) "READ_RESTART";
       newarg[3] = cextra;
       newarg[4] = fixextra;
       modify->add_fix(5,newarg);
       delete [] newarg;
     }
 
     // move atoms to new processors via irregular()
     // in case read by different proc than wrote restart file
+    // first do map_init() since irregular->migrate_atoms() will do map_clear()
 
+    if (atom->map_style) atom->map_init();
     if (domain->triclinic) domain->x2lamda(atom->nlocal);
     Irregular *irregular = new Irregular(lmp);
     irregular->migrate_atoms();
     delete irregular;
     if (domain->triclinic) domain->lamda2x(atom->nlocal);
 
     // put extra atom info held by fix back into atom->extra
     // destroy temporary fix
 
     if (nextra) {
       memory->destroy_2d_double_array(atom->extra);
       atom->extra = memory->create_2d_double_array(atom->nmax,nextra,
       						   "atom:extra");
       int ifix = modify->find_fix("_read_restart");
       FixReadRestart *fix = (FixReadRestart *) modify->fix[ifix];
       int *count = fix->count;
       double **extra = fix->extra;
       double **atom_extra = atom->extra;
       int nlocal = atom->nlocal;
       for (int i = 0; i < nlocal; i++)
 	for (int j = 0; j < count[i]; j++)
 	  atom_extra[i][j] = extra[i][j];
       modify->delete_fix("_read_restart");
     }
   }
 
   // clean-up memory
 
   delete [] file;
   memory->sfree(buf);
 
   // check that all atoms were assigned to procs
 
   bigint natoms;
   bigint nblocal = atom->nlocal;
-  MPI_Allreduce(&nblocal,&natoms,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&nblocal,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
 
   if (me == 0) {
-    if (screen) fprintf(screen,"  %lu atoms\n",natoms);
-    if (logfile) fprintf(logfile,"  %lu atoms\n",natoms);
+    char str[32];
+    sprintf(str,"  %s atoms\n",BIGINT_FORMAT);
+    if (screen) fprintf(screen,str,natoms);
+    if (logfile) fprintf(logfile,str,natoms);
   }
 
   if (natoms != atom->natoms) error->all("Did not assign all atoms correctly");
 
   if (me == 0) {
     if (atom->nbonds) {
-      if (screen) fprintf(screen,"  %lu bonds\n",atom->nbonds);
-      if (logfile) fprintf(logfile,"  %lu bonds\n",atom->nbonds);
+      char str[32];
+      sprintf(str,"  %s bonds\n",BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->nbonds);
+      if (logfile) fprintf(logfile,str,atom->nbonds);
     }
     if (atom->nangles) {
-      if (screen) fprintf(screen,"  %lu angles\n",atom->nangles);
-      if (logfile) fprintf(logfile,"  %lu angles\n",atom->nangles);
+      char str[32];
+      sprintf(str,"  %s angles\n",BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->nangles);
+      if (logfile) fprintf(logfile,str,atom->nangles);
     }
     if (atom->ndihedrals) {
-      if (screen) fprintf(screen,"  %lu dihedrals\n",atom->ndihedrals);
-      if (logfile) fprintf(logfile,"  %lu dihedrals\n",atom->ndihedrals);
+      char str[32];
+      sprintf(str,"  %s dihedrals\n",BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->ndihedrals);
+      if (logfile) fprintf(logfile,str,atom->ndihedrals);
     }
     if (atom->nimpropers) {
-      if (screen) fprintf(screen,"  %lu impropers\n",atom->nimpropers);
-      if (logfile) fprintf(logfile,"  %lu impropers\n",atom->nimpropers);
+      char str[32];
+      sprintf(str,"  %s impropers\n",BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->nimpropers);
+      if (logfile) fprintf(logfile,str,atom->nimpropers);
     }
   }
 
   // check if tags are being used
   // create global mapping and bond topology now that system is defined
 
   int 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;
 
   if (atom->map_style) {
     atom->map_init();
     atom->map_set();
   }
   if (atom->molecular) {
     Special special(lmp);
     special.build();
   }
 }
 
 /* ----------------------------------------------------------------------
    search for all files matching infile which contains a "*"
    replace "*" with latest timestep value to create outfile name
    search dir referenced by initial pathname of file
    if infile also contains "%", need to use "base" when search directory
 ------------------------------------------------------------------------- */
 
 void ReadRestart::file_search(char *infile, char *outfile)
 {
   char *ptr;
 
   // separate infile into dir + filename
 
   char *dirname = new char[strlen(infile) + 1];
   char *filename = new char[strlen(infile) + 1];
 
   if (strchr(infile,'/')) {
     ptr = strrchr(infile,'/');
     *ptr = '\0';
     strcpy(dirname,infile);
     strcpy(filename,ptr+1);
     *ptr = '/';
   } else {
     strcpy(dirname,"./");
     strcpy(filename,infile);
   }
 
   // if filename contains "%" replace "%" with "base"
 
   char *pattern = new char[strlen(filename) + 16];
 
   if (ptr = strchr(filename,'%')) {
     *ptr = '\0';
     sprintf(pattern,"%s%s%s",filename,"base",ptr+1);
     *ptr = '%';
   } else strcpy(pattern,filename);
 
   // scan all files in directory, searching for files that match pattern
   // maxnum = largest int that matches "*"
 
   int n = strlen(pattern) + 16;
   char *begin = new char[n];
   char *middle = new char[n];
   char *end = new char[n];
 
   ptr = strchr(pattern,'*');
   *ptr = '\0';
   strcpy(begin,pattern);
   strcpy(end,ptr+1);
   int nbegin = strlen(begin);
   int maxnum = -1;
 
   if (me == 0) {
     struct dirent *ep;
     DIR *dp = opendir(dirname);
     if (dp == NULL) 
       error->one("Cannot open dir to search for restart file");
     while (ep = readdir(dp)) {
       if (strstr(ep->d_name,begin) != ep->d_name) continue;
       if ((ptr = strstr(&ep->d_name[nbegin],end)) == NULL) continue;
       if (strlen(end) == 0) ptr = ep->d_name + strlen(ep->d_name);
       *ptr = '\0';
       if (strlen(&ep->d_name[nbegin]) < n) {
 	strcpy(middle,&ep->d_name[nbegin]);
 	if (atoi(middle) > maxnum) maxnum = atoi(middle);
       }
     }
     closedir(dp);
     if (maxnum < 0) error->one("Found no restart file matching pattern");
   }
 
   // create outfile with maxint substituted for "*"
   // use original infile, not pattern, since need to retain "%" in filename
 
   ptr = strchr(infile,'*');
   *ptr = '\0';
   sprintf(outfile,"%s%d%s",infile,maxnum,ptr+1);
   *ptr = '*';
 
   // clean up
 
   delete [] dirname;
   delete [] filename;
   delete [] pattern;
   delete [] begin;
   delete [] middle;
   delete [] end;
 }
 
 /* ----------------------------------------------------------------------
    read header of restart file 
 ------------------------------------------------------------------------- */
 
 void ReadRestart::header()
 {
   int px,py,pz;
   int xperiodic,yperiodic,zperiodic;
   int boundary[3][2];
 
   // read flags and values until flag = -1
 
   int flag = read_int();
   while (flag >= 0) {
 
     // check restart file version, warn if different
 
     if (flag == VERSION) {
       char *version = read_char();
       if (strcmp(version,universe->version) != 0 && me == 0) {
 	error->warning("Restart file version does not match LAMMPS version");
 	if (screen) fprintf(screen,"  restart file = %s, LAMMPS = %s\n",
 			    version,universe->version);
       }
       delete [] version;
+      
+      // check lmptype.h sizes, error if different
+
+    } else if (flag == SMALLINT) {
+      int size = read_int();
+      if (size != sizeof(smallint))
+	error->all("Smallint setting in lmptype.h is not compatible");
+    } else if (flag == TAGINT) {
+      int size = read_int();
+      if (size != sizeof(tagint))
+	error->all("Tagint setting in lmptype.h is not compatible");
+    } else if (flag == BIGINT) {
+      int size = read_int();
+      if (size != sizeof(bigint))
+	error->all("Bigint setting in lmptype.h is not compatible");
 
       // reset unit_style only if different
       // so that timestep,neighbor-skin are not changed
 
     } else if (flag == UNITS) {
       char *style = read_char();
       if (strcmp(style,update->unit_style) != 0) update->set_units(style);
       delete [] style;
 
     } else if (flag == NTIMESTEP) {
-      update->ntimestep = read_int();
+      update->ntimestep = read_bigint();
 
       // set dimension from restart file
 
     } else if (flag == DIMENSION) {
       int dimension = read_int();
       domain->dimension = dimension;
       if (domain->dimension == 2 && domain->zperiodic == 0)
 	error->all("Cannot run 2d simulation with nonperiodic Z dimension");
 
       // read nprocs from restart file, warn if different
 
     } else if (flag == NPROCS) {
       nprocs_file = read_int();
       if (nprocs_file != comm->nprocs && me == 0)
 	error->warning("Restart file used different # of processors");
 
       // don't set procgrid, warn if different
 
     } else if (flag == PROCGRID_0) {
       px = read_int();
     } else if (flag == PROCGRID_1) {
       py = read_int();
     } else if (flag == PROCGRID_2) {
       pz = read_int();
       if (comm->user_procgrid[0] != 0 && 
 	  (px != comm->user_procgrid[0] || py != comm->user_procgrid[1] || 
 	   pz != comm->user_procgrid[2]) && me == 0)
 	error->warning("Restart file used different 3d processor grid");
 
     // don't set newton_pair, leave input script value unchanged
     // set newton_bond from restart file
     // warn if different and input script settings are not default
 
     } else if (flag == NEWTON_PAIR) {
       int newton_pair_file = read_int();
       if (force->newton_pair != 1) {
 	if (newton_pair_file != force->newton_pair && me == 0)
 	  error->warning("Restart file used different newton pair setting, "
 			 "using input script value");
       }
     } else if (flag == NEWTON_BOND) {
       int newton_bond_file = read_int();
       if (force->newton_bond != 1) {
 	if (newton_bond_file != force->newton_bond && me == 0)
 	  error->warning("Restart file used different newton bond setting, "
 			 "using restart file value");
       }
       force->newton_bond = newton_bond_file;
       if (force->newton_pair || force->newton_bond) force->newton = 1;
       else force->newton = 0;
 
       // set boundary settings from restart file
       // warn if different and input script settings are not default
 
     } else if (flag == XPERIODIC) {
       xperiodic = read_int();
     } else if (flag == YPERIODIC) {
       yperiodic = read_int();
     } else if (flag == ZPERIODIC) {
       zperiodic = read_int();
     } else if (flag == BOUNDARY_00) {
       boundary[0][0] = read_int();
     } else if (flag == BOUNDARY_01) {
       boundary[0][1] = read_int();
     } else if (flag == BOUNDARY_10) {
       boundary[1][0] = read_int();
     } else if (flag == BOUNDARY_11) {
       boundary[1][1] = read_int();
     } else if (flag == BOUNDARY_20) {
       boundary[2][0] = read_int();
     } else if (flag == BOUNDARY_21) {
       boundary[2][1] = read_int();
 
       if (domain->boundary[0][0] || domain->boundary[0][1] || 
 	  domain->boundary[1][0] || domain->boundary[1][1] || 
 	  domain->boundary[2][0] || domain->boundary[2][1]) {
 	if (boundary[0][0] != domain->boundary[0][0] ||
 	    boundary[0][1] != domain->boundary[0][1] ||
 	    boundary[1][0] != domain->boundary[1][0] ||
 	    boundary[1][1] != domain->boundary[1][1] ||
 	    boundary[2][0] != domain->boundary[2][0] ||
 	    boundary[2][1] != domain->boundary[2][1]) {
 	  if (me == 0) 
 	    error->warning("Restart file used different boundary settings, "
 			   "using restart file values");
 	}
       }
 
       domain->boundary[0][0] = boundary[0][0];
       domain->boundary[0][1] = boundary[0][1];
       domain->boundary[1][0] = boundary[1][0];
       domain->boundary[1][1] = boundary[1][1];
       domain->boundary[2][0] = boundary[2][0];
       domain->boundary[2][1] = boundary[2][1];
 
       domain->periodicity[0] = domain->xperiodic = xperiodic;
       domain->periodicity[1] = domain->yperiodic = yperiodic;
       domain->periodicity[2] = domain->zperiodic = zperiodic;
   
       domain->nonperiodic = 0;
       if (xperiodic == 0 || yperiodic == 0 || zperiodic == 0) {
 	domain->nonperiodic = 1;
 	if (boundary[0][0] >= 2 || boundary[0][1] >= 2 ||
 	    boundary[1][0] >= 2 || boundary[1][1] >= 2 ||
 	    boundary[2][0] >= 2 || boundary[2][1] >= 2)
 	  domain->nonperiodic = 2;
       }
 
       // create new AtomVec class
       // if style = hybrid, read additional sub-class arguments
 
     } else if (flag == ATOM_STYLE) {
       char *style = read_char();
 
       int nwords = 0;
       char **words = NULL;
 
       if (strcmp(style,"hybrid") == 0) {
 	nwords = read_int();
 	words = new char*[nwords];
 	for (int i = 0; i < nwords; i++) words[i] = read_char();
       }
 
       atom->create_avec(style,nwords,words);
       for (int i = 0; i < nwords; i++) delete [] words[i];
       delete [] words;
       delete [] style;
 
     } else if (flag == NATOMS) {
       atom->natoms = read_bigint();
     } else if (flag == NTYPES) {
       atom->ntypes = read_int();
     } else if (flag == NBONDS) {
       atom->nbonds = read_bigint();
     } else if (flag == NBONDTYPES) {
       atom->nbondtypes = read_int();
     } else if (flag == BOND_PER_ATOM) {
       atom->bond_per_atom = read_int();
     } else if (flag == NANGLES) {
       atom->nangles = read_bigint();
     } else if (flag == NANGLETYPES) {
       atom->nangletypes = read_int();
     } else if (flag == ANGLE_PER_ATOM) {
       atom->angle_per_atom = read_int();
     } else if (flag == NDIHEDRALS) {
       atom->ndihedrals = read_bigint();
     } else if (flag == NDIHEDRALTYPES) {
       atom->ndihedraltypes = read_int();
     } else if (flag == DIHEDRAL_PER_ATOM) {
       atom->dihedral_per_atom = read_int();
     } else if (flag == NIMPROPERS) {
       atom->nimpropers = read_bigint();
     } else if (flag == NIMPROPERTYPES) {
       atom->nimpropertypes = read_int();
     } else if (flag == IMPROPER_PER_ATOM) {
       atom->improper_per_atom = read_int();
 
     } else if (flag == BOXLO_0) {
       domain->boxlo[0] = read_double();
     } else if (flag == BOXHI_0) {
       domain->boxhi[0] = read_double();
     } else if (flag == BOXLO_1) {
       domain->boxlo[1] = read_double();
     } else if (flag == BOXHI_1) {
       domain->boxhi[1] = read_double();
     } else if (flag == BOXLO_2) {
       domain->boxlo[2] = read_double();
     } else if (flag == BOXHI_2) {
       domain->boxhi[2] = read_double();
 
     } else if (flag == SPECIAL_LJ_1) {
       force->special_lj[1] = read_double();
     } else if (flag == SPECIAL_LJ_2) {
       force->special_lj[2] = read_double();
     } else if (flag == SPECIAL_LJ_3) {
       force->special_lj[3] = read_double();
     } else if (flag == SPECIAL_COUL_1) {
       force->special_coul[1] = read_double();
     } else if (flag == SPECIAL_COUL_2) {
       force->special_coul[2] = read_double();
     } else if (flag == SPECIAL_COUL_3) {
       force->special_coul[3] = read_double();
 
     } else if (flag == XY) {
       domain->triclinic = 1;
       domain->xy = read_double();
     } else if (flag == XZ) {
       domain->triclinic = 1;
       domain->xz = read_double();
     } else if (flag == YZ) {
       domain->triclinic = 1;
       domain->yz = read_double();
 
     } else error->all("Invalid flag in header section of restart file");
 
     flag = read_int();
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadRestart::type_arrays()
 {
   int flag = read_int();
   while (flag >= 0) {
 
     if (flag == MASS) {
       double *mass = new double[atom->ntypes+1];
       if (me == 0) fread(&mass[1],sizeof(double),atom->ntypes,fp);
       MPI_Bcast(&mass[1],atom->ntypes,MPI_DOUBLE,0,world);
       atom->set_mass(mass);
       delete [] mass;
 
     } else if (flag == SHAPE) {
       double **shape =
 	memory->create_2d_double_array(atom->ntypes+1,3,"restart:shape");
       if (me == 0) fread(&shape[1][0],sizeof(double),atom->ntypes*3,fp);
       MPI_Bcast(&shape[1][0],atom->ntypes*3,MPI_DOUBLE,0,world);
       atom->set_shape(shape);
       memory->destroy_2d_double_array(shape);
 
     } else if (flag == DIPOLE) {
       double *dipole = new double[atom->ntypes+1];
       if (me == 0) fread(&dipole[1],sizeof(double),atom->ntypes,fp);
       MPI_Bcast(&dipole[1],atom->ntypes,MPI_DOUBLE,0,world);
       atom->set_dipole(dipole);
       delete [] dipole;
 
     } else error->all("Invalid flag in type arrays section of restart file");
 
     flag = read_int();
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void ReadRestart::force_fields()
 {
   int n;
   char *style;
 
   int flag = read_int();
   while (flag >= 0) {
 
     if (flag == PAIR) {
       if (me == 0) fread(&n,sizeof(int),1,fp);
       MPI_Bcast(&n,1,MPI_INT,0,world);
       style = new char[n];
       if (me == 0) fread(style,sizeof(char),n,fp);
       MPI_Bcast(style,n,MPI_CHAR,0,world);
 
       force->create_pair(style);
       delete [] style;
       force->pair->read_restart(fp);
 
     } else if (flag == BOND) {
       if (me == 0) fread(&n,sizeof(int),1,fp);
       MPI_Bcast(&n,1,MPI_INT,0,world);
       style = new char[n];
       if (me == 0) fread(style,sizeof(char),n,fp);
       MPI_Bcast(style,n,MPI_CHAR,0,world);
       
       force->create_bond(style);
       delete [] style;
       force->bond->read_restart(fp);
 
     } else if (flag == ANGLE) {
       if (me == 0) fread(&n,sizeof(int),1,fp);
       MPI_Bcast(&n,1,MPI_INT,0,world);
       style = new char[n];
       if (me == 0) fread(style,sizeof(char),n,fp);
       MPI_Bcast(style,n,MPI_CHAR,0,world);
 
       force->create_angle(style);
       delete [] style;
       force->angle->read_restart(fp);
 
     } else if (flag == DIHEDRAL) {
       if (me == 0) fread(&n,sizeof(int),1,fp);
       MPI_Bcast(&n,1,MPI_INT,0,world);
       style = new char[n];
       if (me == 0) fread(style,sizeof(char),n,fp);
       MPI_Bcast(style,n,MPI_CHAR,0,world);
 
       force->create_dihedral(style);
       delete [] style;
       force->dihedral->read_restart(fp);
 
     } else if (flag == IMPROPER) {
       if (me == 0) fread(&n,sizeof(int),1,fp);
       MPI_Bcast(&n,1,MPI_INT,0,world);
       style = new char[n];
       if (me == 0) fread(style,sizeof(char),n,fp);
       MPI_Bcast(style,n,MPI_CHAR,0,world);
 
       force->create_improper(style);
       delete [] style;
       force->improper->read_restart(fp);
 
     } else error->all("Invalid flag in force field section of restart file");
 
     flag = read_int();
   }
 }
 
 /* ----------------------------------------------------------------------
    read an int from restart file and bcast it
 ------------------------------------------------------------------------- */
 
 int ReadRestart::read_int()
 {
   int value;
   if (me == 0) fread(&value,sizeof(int),1,fp);
   MPI_Bcast(&value,1,MPI_INT,0,world);
   return value;
 }
 
 /* ----------------------------------------------------------------------
    read a double from restart file and bcast it
 ------------------------------------------------------------------------- */
 
 double ReadRestart::read_double()
 {
   double value;
   if (me == 0) fread(&value,sizeof(double),1,fp);
   MPI_Bcast(&value,1,MPI_DOUBLE,0,world);
   return value;
 }
 
 /* ----------------------------------------------------------------------
    read a char str from restart file and bcast it
    str is allocated here, ptr is returned, caller must deallocate
 ------------------------------------------------------------------------- */
 
 char *ReadRestart::read_char()
 {
   int n;
   if (me == 0) fread(&n,sizeof(int),1,fp);
   MPI_Bcast(&n,1,MPI_INT,0,world);
   char *value = new char[n];
   if (me == 0) fread(value,sizeof(char),n,fp);
   MPI_Bcast(value,n,MPI_CHAR,0,world);
   return value;
 }
 
 /* ----------------------------------------------------------------------
    read a bigint from restart file and bcast it
 ------------------------------------------------------------------------- */
 
 bigint ReadRestart::read_bigint()
 {
   bigint value;
   if (me == 0) fread(&value,sizeof(bigint),1,fp);
-  MPI_Bcast(&value,1,MPI_UNSIGNED_LONG_LONG,0,world);
+  MPI_Bcast(&value,1,MPI_LMP_BIGINT,0,world);
   return value;
 }
diff --git a/src/region.h b/src/region.h
index f269958b9..c4a1e18a7 100644
--- a/src/region.h
+++ b/src/region.h
@@ -1,72 +1,73 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_REGION_H
 #define LMP_REGION_H
 
 #include "pointers.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class Region : protected Pointers {
  public:
   char *id,*style;
   int interior;                     // 1 for interior, 0 for exterior
   int scaleflag;                    // 1 for lattice, 0 for box
   double xscale,yscale,zscale;      // scale factors for box/lattice units
   double extent_xlo,extent_xhi;     // bounding box on region
   double extent_ylo,extent_yhi;
   double extent_zlo,extent_zhi;
   int bboxflag;                     // 1 if bounding box is computable
 
   // contact = particle near region surface
 
   struct Contact {
     double r;                 // distance between particle & surf, r > 0.0
     double delx,dely,delz;    // vector from surface pt to particle
   };
   Contact *contact;           // list of contacts
   int cmax;                   // max # of contacts possible with region
  
   Region(class LAMMPS *, int, char **);
   virtual ~Region();
   void init();
   virtual int dynamic_check();
   int match(double, double, double);
   int surface(double, double, double, double);
 
   virtual int inside(double, double, double) = 0;
   virtual int surface_interior(double *, double) = 0;
   virtual int surface_exterior(double *, double) = 0;
 
  protected:
   void add_contact(int, double *, double, double, double);
   void options(int, char **);
 
  private:
   int dynamic;                      // 1 if region changes over time
   int moveflag,rotateflag;
   double point[3],axis[3],runit[3];
   char *xstr,*ystr,*zstr,*tstr;
   int xvar,yvar,zvar,tvar;
   double dx,dy,dz,theta;
-  int laststep;
+  bigint laststep;
 
   void forward_transform(double &, double &, double &);
   void inverse_transform(double &, double &, double &);
   void rotate(double &, double &, double &, double);
 };
 
 }
 
 #endif
diff --git a/src/replicate.cpp b/src/replicate.cpp
index a4e02bd12..5ade979e6 100644
--- a/src/replicate.cpp
+++ b/src/replicate.cpp
@@ -1,408 +1,420 @@
 /* ----------------------------------------------------------------------
    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 "stdlib.h"
 #include "string.h"
 #include "replicate.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "atom_vec_hybrid.h"
 #include "force.h"
 #include "domain.h"
 #include "comm.h"
 #include "special.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define LB_FACTOR 1.1
 #define EPSILON   1.0e-6
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 /* ---------------------------------------------------------------------- */
 
 Replicate::Replicate(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 void Replicate::command(int narg, char **arg)
 {
   int i,j,m,n;
 
   if (domain->box_exist == 0)
     error->all("Replicate command before simulation box is defined");
   if (narg != 3) error->all("Illegal replicate command");
 
   int me = comm->me;
   int nprocs = comm->nprocs;
 
   if (me == 0 && screen) fprintf(screen,"Replicating atoms ...\n");
 
   // nrep = total # of replications
 
   int nx = atoi(arg[0]);
   int ny = atoi(arg[1]);
   int nz = atoi(arg[2]);
   int nrep = nx*ny*nz;
 
   // error and warning checks
 
   if (nx <= 0 || ny <= 0 || nz <= 0) error->all("Illegal replicate command");
   if (domain->dimension == 2 && nz != 1)
     error->all("Cannot replicate 2d simulation in z dimension");
   if ((nx > 1 && domain->xperiodic == 0) || 
       (ny > 1 && domain->yperiodic == 0) ||
       (nz > 1 && domain->zperiodic == 0)) 
     error->warning("Replicating in a non-periodic dimension");
 
   if (atom->nextra_grow || atom->nextra_restart || atom->nextra_store)
     error->all("Cannot replicate with fixes that store atom quantities");
 
   // 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;
 
   // maxmol = largest molecule tag across all existing atoms
 
   int maxmol = 0;
   if (atom->molecular) {
     for (i = 0; i < atom->nlocal; i++) maxmol = MAX(atom->molecule[i],maxmol);
     int maxmol_all;
     MPI_Allreduce(&maxmol,&maxmol_all,1,MPI_INT,MPI_MAX,world);
     maxmol = maxmol_all;
   }
 
   // unmap existing atoms via image flags
 
   for (i = 0; i < atom->nlocal; i++)
     domain->unmap(atom->x[i],atom->image[i]);
 
   // communication buffer for all my atom's info
   // max_size = largest buffer needed by any proc
   // must do before new Atom class created,
   //   since size_restart() uses atom->nlocal
 
   int max_size;
   int send_size = atom->avec->size_restart();
   MPI_Allreduce(&send_size,&max_size,1,MPI_INT,MPI_MAX,world);
 
   double *buf = 
     (double *) memory->smalloc(max_size*sizeof(double),"replicate:buf");
 
   // old = original atom class
   // atom = new replicated atom class
   // if old atom style was hybrid, pass sub-style names to create_avec
 
   Atom *old = atom;
   atom = new Atom(lmp);
   atom->settings(old);
 
   int nstyles = 0;
   char **keywords = NULL;
   if (strcmp(old->atom_style,"hybrid") == 0) {
     AtomVecHybrid *avec_hybrid = (AtomVecHybrid *) old->avec;
     nstyles = avec_hybrid->nstyles;
     keywords = avec_hybrid->keywords;
   }
   atom->create_avec(old->atom_style,nstyles,keywords);
 
-  // check that new problem size will not be too large
-  // if N > 2^31, turn off tags for existing and new atoms
-  // if molecular, N/Nbonds/etc cannot be > 2^31 else tags/counts invalid
-
-  double rep = nrep;
-  if (rep*old->natoms > MAXINT32) atom->tag_enable = 0;
-
+  // 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
+
+  if (atom->molecular && (nrep*old->natoms < 0 || nrep*old->natoms > MAXTAGINT))
+    error->all("Replicated molecular system atom IDs are too big");
+  if (nrep*old->natoms < 0 || nrep*old->natoms > MAXTAGINT)
+    atom->tag_enable = 0;
   if (atom->tag_enable == 0)
     for (int i = 0; i < atom->nlocal; i++)
       atom->tag[i] = 0;
 
-  if (atom->molecular) {
-    if (rep*old->natoms > MAXINT32 || rep*old->nbonds > MAXINT32 ||
-	rep*old->nangles > MAXINT32 || rep*old->ndihedrals > MAXINT32 ||
-	rep*old->nimpropers > MAXINT32)
-      error->all("Too big a problem to replicate with molecular atom style");
-  }
+  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("Replicated system is too big");
 
   // assign atom and topology counts in new class from old one
 
   atom->natoms = old->natoms * nrep;
   atom->nbonds = old->nbonds * nrep;
   atom->nangles = old->nangles * nrep;
   atom->ndihedrals = old->ndihedrals * nrep;
   atom->nimpropers = old->nimpropers * nrep;
 
   atom->ntypes = old->ntypes;
   atom->nbondtypes = old->nbondtypes;
   atom->nangletypes = old->nangletypes;
   atom->ndihedraltypes = old->ndihedraltypes;
   atom->nimpropertypes = old->nimpropertypes;
   
   atom->bond_per_atom = old->bond_per_atom;
   atom->angle_per_atom = old->angle_per_atom;
   atom->dihedral_per_atom = old->dihedral_per_atom;
   atom->improper_per_atom = old->improper_per_atom;
 
   // store old simulation box
 
   int triclinic = domain->triclinic;
   double old_xprd = domain->xprd;
   double old_yprd = domain->yprd;
   double old_zprd = domain->zprd;
   double old_xy = domain->xy;
   double old_xz = domain->xz;
   double old_yz = domain->yz;
 
   // setup new simulation box
 
   domain->boxhi[0] = domain->boxlo[0] + nx*old_xprd;
   domain->boxhi[1] = domain->boxlo[1] + ny*old_yprd;
   domain->boxhi[2] = domain->boxlo[2] + nz*old_zprd;
   if (triclinic) {
     domain->xy *= ny;
     domain->xz *= nz;
     domain->yz *= nz;
   }
 
   // new problem setup using new box boundaries
 
   if (nprocs == 1) n = static_cast<int> (atom->natoms);
   else n = static_cast<int> (LB_FACTOR * atom->natoms / 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_procs();
   domain->set_local_box();
 
   // copy type arrays to new atom class
 
   if (atom->mass) {
     for (int itype = 1; itype <= atom->ntypes; itype++) {
       atom->mass_setflag[itype] = old->mass_setflag[itype];
       if (atom->mass_setflag[itype]) atom->mass[itype] = old->mass[itype];
     }
   }
 
   if (atom->shape) {
     for (int itype = 1; itype <= atom->ntypes; itype++) {
       atom->shape_setflag[itype] = old->shape_setflag[itype];
       if (atom->shape_setflag[itype]) {
 	atom->shape[itype][0] = old->shape[itype][0];
 	atom->shape[itype][1] = old->shape[itype][1];
 	atom->shape[itype][2] = old->shape[itype][2];
       }
     }
   }
 
   if (atom->dipole) {
     for (int itype = 1; itype <= atom->ntypes; itype++) {
       atom->dipole_setflag[itype] = old->dipole_setflag[itype];
       if (atom->dipole_setflag[itype]) 
 	atom->dipole[itype] = old->dipole[itype];
     }
   }
 
   // set bounds for my proc
   // if periodic and I am lo/hi proc, adjust bounds by EPSILON
   // insures all replicated atoms will be owned even with round-off
 
   double sublo[3],subhi[3];
 
   if (triclinic == 0) {
     sublo[0] = domain->sublo[0]; subhi[0] = domain->subhi[0];
     sublo[1] = domain->sublo[1]; subhi[1] = domain->subhi[1];
     sublo[2] = domain->sublo[2]; subhi[2] = domain->subhi[2];
   } else {
     sublo[0] = domain->sublo_lamda[0]; subhi[0] = domain->subhi_lamda[0];
     sublo[1] = domain->sublo_lamda[1]; subhi[1] = domain->subhi_lamda[1];
     sublo[2] = domain->sublo_lamda[2]; subhi[2] = domain->subhi_lamda[2];
   }
 
   if (domain->xperiodic) {
     if (comm->myloc[0] == 0) sublo[0] -= EPSILON;
     if (comm->myloc[0] == comm->procgrid[0]-1) subhi[0] += EPSILON;
   }
   if (domain->yperiodic) {
     if (comm->myloc[1] == 0) sublo[1] -= EPSILON;
     if (comm->myloc[1] == comm->procgrid[1]-1) subhi[1] += EPSILON;
   }
   if (domain->zperiodic) {
     if (comm->myloc[2] == 0) sublo[2] -= EPSILON;
     if (comm->myloc[2] == comm->procgrid[2]-1) subhi[2] += EPSILON;
   }
 
   // loop over all procs
   // if this iteration of loop is me:
   //   pack my unmapped atom data into buf
   //   bcast it to all other procs
   // performs 3d replicate loop with while loop over atoms in buf
   //   x = new replicated position, remapped into simulation box
   //   unpack atom into new atom class from buf if I own it
   //   adjust tag, mol #, coord, topology info as needed
 
   AtomVec *old_avec = old->avec;
   AtomVec *avec = atom->avec;
 
   int ix,iy,iz,image,atom_offset,mol_offset;
   double x[3],lamda[3];
   double *coord;
   int tag_enable = atom->tag_enable;
 
   for (int iproc = 0; iproc < nprocs; iproc++) {
     if (me == iproc) {
       n = 0;
       for (i = 0; i < old->nlocal; i++) n += old_avec->pack_restart(i,&buf[n]);
     }
     MPI_Bcast(&n,1,MPI_INT,iproc,world);
     MPI_Bcast(buf,n,MPI_DOUBLE,iproc,world);
 
     for (ix = 0; ix < nx; ix++) {
       for (iy = 0; iy < ny; iy++) {
 	for (iz = 0; iz < nz; iz++) {
 
 	  // while loop over one proc's atom list
 
 	  m = 0;
 	  while (m < n) {
 	    image = (512 << 20) | (512 << 10) | 512;
 	    if (triclinic == 0) {
 	      x[0] = buf[m+1] + ix*old_xprd;
 	      x[1] = buf[m+2] + iy*old_yprd;
 	      x[2] = buf[m+3] + iz*old_zprd;
 	    } else {
 	      x[0] = buf[m+1] + ix*old_xprd + iy*old_xy + iz*old_xz;
 	      x[1] = buf[m+2] + iy*old_yprd + iz*old_yz;
 	      x[2] = buf[m+3] + iz*old_zprd;
 	    }
 	    domain->remap(x,image);
 	    if (triclinic) {
 	      domain->x2lamda(x,lamda);
 	      coord = lamda;
 	    } else coord = x;
 
 	    if (coord[0] >= sublo[0] && coord[0] < subhi[0] && 
 		coord[1] >= sublo[1] && coord[1] < subhi[1] && 
 		coord[2] >= sublo[2] && coord[2] < subhi[2]) {
 
 	      m += avec->unpack_restart(&buf[m]);
 
 	      i = atom->nlocal - 1;
 	      if (tag_enable)
 		atom_offset = iz*ny*nx*maxtag + iy*nx*maxtag + ix*maxtag;
 	      else atom_offset = 0;
 	      mol_offset = iz*ny*nx*maxmol + iy*nx*maxmol + ix*maxmol;
 
 	      atom->x[i][0] = x[0];
 	      atom->x[i][1] = x[1];
 	      atom->x[i][2] = x[2];
 
 	      atom->tag[i] += atom_offset;
 	      atom->image[i] = image;
 
 	      if (atom->molecular) {
 		if (atom->molecule[i] > 0)
 		  atom->molecule[i] += mol_offset;
 		if (atom->avec->bonds_allow)
 		  for (j = 0; j < atom->num_bond[i]; j++)
 		    atom->bond_atom[i][j] += atom_offset;
 		if (atom->avec->angles_allow)
 		  for (j = 0; j < atom->num_angle[i]; j++) {
 		    atom->angle_atom1[i][j] += atom_offset;
 		    atom->angle_atom2[i][j] += atom_offset;
 		    atom->angle_atom3[i][j] += atom_offset;
 		  }
 		if (atom->avec->dihedrals_allow)
 		  for (j = 0; j < atom->num_dihedral[i]; j++) {
 		    atom->dihedral_atom1[i][j] += atom_offset;
 		    atom->dihedral_atom2[i][j] += atom_offset;
 		    atom->dihedral_atom3[i][j] += atom_offset;
 		    atom->dihedral_atom4[i][j] += atom_offset;
 		  }
 		if (atom->avec->impropers_allow)
 		  for (j = 0; j < atom->num_improper[i]; j++) {
 		    atom->improper_atom1[i][j] += atom_offset;
 		    atom->improper_atom2[i][j] += atom_offset;
 		    atom->improper_atom3[i][j] += atom_offset;
 		    atom->improper_atom4[i][j] += atom_offset;
 		  }
 	      }
 	    } else m += static_cast<int> (buf[m]);
 	  }
 	}
       }
     }
   } // end of proc loop
 
   // free communication buffer and old atom class
 
   memory->sfree(buf);
   delete old;
 
   // check that all atoms were assigned to procs
 
   bigint natoms;
   bigint nblocal = atom->nlocal;
-  MPI_Allreduce(&nblocal,&natoms,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&nblocal,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
 
   if (me == 0) {
-    if (screen) fprintf(screen,"  %lu atoms\n",natoms);
-    if (logfile) fprintf(logfile,"  %lu atoms\n",natoms);
+    char str[32];
+    sprintf(str,"  %s atoms\n",BIGINT_FORMAT);
+    if (screen) fprintf(screen,str,natoms);
+    if (logfile) fprintf(logfile,str,natoms);
   }
 
   if (natoms != atom->natoms)
     error->all("Replicate did not assign all atoms correctly");
 
   if (me == 0) {
     if (atom->nbonds) {
-      if (screen) fprintf(screen,"  %lu bonds\n",atom->nbonds);
-      if (logfile) fprintf(logfile,"  %lu bonds\n",atom->nbonds);
+      char str[32];
+      sprintf(str,"  %s bonds\n",BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->nbonds);
+      if (logfile) fprintf(logfile,str,atom->nbonds);
     }
     if (atom->nangles) {
-      if (screen) fprintf(screen,"  %lu angles\n",atom->nangles);
-      if (logfile) fprintf(logfile,"  %lu angles\n",atom->nangles);
+      char str[32];
+      sprintf(str,"  %s angles\n",BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->nangles);
+      if (logfile) fprintf(logfile,str,atom->nangles);
     }
     if (atom->ndihedrals) {
-      if (screen) fprintf(screen,"  %lu dihedrals\n",atom->ndihedrals);
-      if (logfile) fprintf(logfile,"  %lu dihedrals\n",atom->ndihedrals);
+      char str[32];
+      sprintf(str,"  %s dihedrals\n",BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->ndihedrals);
+      if (logfile) fprintf(logfile,str,atom->ndihedrals);
     }
     if (atom->nimpropers) {
-      if (screen) fprintf(screen,"  %lu impropers\n",atom->nimpropers);
-      if (logfile) fprintf(logfile,"  %lu impropers\n",atom->nimpropers);
+      char str[32];
+      sprintf(str,"  %s impropers\n",BIGINT_FORMAT);
+      if (screen) fprintf(screen,str,atom->nimpropers);
+      if (logfile) fprintf(logfile,str,atom->nimpropers);
     }
   }
 
   // create global mapping and bond topology now that system is defined
 
   if (atom->map_style) {
     atom->nghost = 0;
     atom->map_init();
     atom->map_set();
   }
   if (atom->molecular) {
     Special special(lmp);
     special.build();
   }
 }
diff --git a/src/respa.cpp b/src/respa.cpp
index 209c7dd16..cb3425b13 100644
--- a/src/respa.cpp
+++ b/src/respa.cpp
@@ -1,680 +1,680 @@
 /* ----------------------------------------------------------------------
    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: Mark Stevens (SNL), Paul Crozier (SNL)
 ------------------------------------------------------------------------- */
 
 #include "stdlib.h"
 #include "string.h"
 #include "respa.h"
 #include "neighbor.h"
 #include "atom.h"
 #include "domain.h"
 #include "comm.h"
 #include "atom.h"
 #include "force.h"
 #include "pair.h"
 #include "bond.h"
 #include "angle.h"
 #include "dihedral.h"
 #include "improper.h"
 #include "kspace.h"
 #include "output.h"
 #include "update.h"
 #include "modify.h"
 #include "compute.h"
 #include "fix_respa.h"
 #include "memory.h"
 #include "timer.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 Respa::Respa(LAMMPS *lmp, int narg, char **arg) : Integrate(lmp, narg, arg)
 {
   if (narg < 1) error->all("Illegal run_style respa command");
 
   nlevels = atoi(arg[0]);
   if (nlevels < 1) error->all("Respa levels must be >= 1");
 
   if (narg < nlevels) error->all("Illegal run_style respa command");
   loop = new int[nlevels];
   for (int iarg = 1; iarg < nlevels; iarg++) {
     loop[iarg-1] = atoi(arg[iarg]);
     if (loop[iarg-1] <= 0) error->all("Illegal run_style respa command");
   }
   loop[nlevels-1] = 1;
 
   // set level at which each force is computed
   // argument settings override defaults
 
   level_bond = level_angle = level_dihedral = level_improper = -1;
   level_pair = level_kspace = -1;
   level_inner = level_middle = level_outer = -1;
 
   int iarg = nlevels;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"bond") == 0) {
       if (iarg+2 > narg) error->all("Illegal run_style respa command");
       level_bond = atoi(arg[iarg+1]) - 1;
       iarg += 2;
     } else if (strcmp(arg[iarg],"angle") == 0) {
       if (iarg+2 > narg) error->all("Illegal run_style respa command");
       level_angle = atoi(arg[iarg+1]) - 1;
       iarg += 2;
     } else if (strcmp(arg[iarg],"dihedral") == 0) {
       if (iarg+2 > narg) error->all("Illegal run_style respa command");
       level_dihedral = atoi(arg[iarg+1]) - 1;
       iarg += 2;
     } else if (strcmp(arg[iarg],"improper") == 0) {
       if (iarg+2 > narg) error->all("Illegal run_style respa command");
       level_improper = atoi(arg[iarg+1]) - 1;
       iarg += 2;
     } else if (strcmp(arg[iarg],"pair") == 0) {
       if (iarg+2 > narg) error->all("Illegal run_style respa command");
       level_pair = atoi(arg[iarg+1]) - 1;
       iarg += 2;
     } else if (strcmp(arg[iarg],"inner") == 0) {
       if (iarg+4 > narg) error->all("Illegal run_style respa command");
       level_inner = atoi(arg[iarg+1]) - 1;
       cutoff[0] = atof(arg[iarg+2]);
       cutoff[1] = atof(arg[iarg+3]);
       iarg += 4;
     } else if (strcmp(arg[iarg],"middle") == 0) {
       if (iarg+4 > narg) error->all("Illegal run_style respa command");
       level_middle = atoi(arg[iarg+1]) - 1;
       cutoff[2] = atof(arg[iarg+2]);
       cutoff[3] = atof(arg[iarg+3]);
       iarg += 4;
     } else if (strcmp(arg[iarg],"outer") == 0) {
       if (iarg+2 > narg) error->all("Illegal run_style respa command");
       level_outer = atoi(arg[iarg+1]) - 1;
       iarg += 2;
     } else if (strcmp(arg[iarg],"kspace") == 0) {
       if (iarg+2 > narg) error->all("Illegal run_style respa command");
       level_kspace = atoi(arg[iarg+1]) - 1;
       iarg += 2;
     } else error->all("Illegal run_style respa command");
   }
 
   // cannot specify both pair and inner/middle/outer
 
   if (level_pair >= 0 && 
       (level_inner >= 0 || level_middle >= 0 || level_outer >= 0))
     error->all("Cannot set both respa pair and inner/middle/outer");
 
   // if either inner and outer is specified, then both must be
 
   if ((level_inner >= 0 && level_outer == -1) || 
       (level_outer >= 0 && level_inner == -1))
     error->all("Must set both respa inner and outer");
 
   // middle cannot be set without inner/outer
 
   if (level_middle >= 0 && level_inner == -1)
     error->all("Cannot set respa middle without inner/outer");
 
   // set defaults if user did not specify level
   // bond to innermost level
   // angle same as bond, dihedral same as angle, improper same as dihedral
   // pair to outermost level if no inner/middle/outer
   // inner/middle/outer have no defaults
   // kspace same as pair or outer
 
   if (level_bond == -1) level_bond = 0;
   if (level_angle == -1) level_angle = level_bond;
   if (level_dihedral == -1) level_dihedral = level_angle;
   if (level_improper == -1) level_improper = level_dihedral;
   if (level_pair == -1 && level_inner == -1) level_pair = nlevels-1;
   if (level_kspace == -1 && level_pair >= 0) level_kspace = level_pair;
   if (level_kspace == -1 && level_pair == -1) level_kspace = level_outer;
 
   // print respa levels
 
   if (comm->me == 0) {
     if (screen) {
       fprintf(screen,"Respa levels:\n");
       for (int i = 0; i < nlevels; i++) {
 	fprintf(screen,"  %d =",i);
 	if (level_bond == i) fprintf(screen," bond");
 	if (level_angle == i) fprintf(screen," angle");
 	if (level_dihedral == i) fprintf(screen," dihedral");
 	if (level_improper == i) fprintf(screen," improper");
 	if (level_pair == i) fprintf(screen," pair");
 	if (level_inner == i) fprintf(screen," pair-inner");
 	if (level_middle == i) fprintf(screen," pair-middle");
 	if (level_outer == i) fprintf(screen," pair-outer");
 	if (level_kspace == i) fprintf(screen," kspace");
 	fprintf(screen,"\n");
       }
     }
     if (logfile) {
       fprintf(logfile,"Respa levels:\n");
       for (int i = 0; i < nlevels; i++) {
 	fprintf(logfile,"  %d =",i);
 	if (level_bond == i) fprintf(logfile," bond");
 	if (level_angle == i) fprintf(logfile," angle");
 	if (level_dihedral == i) fprintf(logfile," dihedral");
 	if (level_improper == i) fprintf(logfile," improper");
 	if (level_pair == i) fprintf(logfile," pair");
 	if (level_inner == i) fprintf(logfile," pair-inner");
 	if (level_middle == i) fprintf(logfile," pair-middle");
 	if (level_outer == i) fprintf(logfile," pair-outer");
 	if (level_kspace == i) fprintf(logfile," kspace");
 	fprintf(logfile,"\n");
       }
     }
   }
 
   // check that levels are in correct order
   
   if (level_angle < level_bond || level_dihedral < level_angle ||
       level_improper < level_dihedral)
     error->all("Invalid order of forces within respa levels");
   if (level_pair >= 0) {
     if (level_pair < level_improper || level_kspace < level_pair)
       error->all("Invalid order of forces within respa levels");
   }
   if (level_pair == -1 && level_middle == -1) {
     if (level_inner < level_improper || level_outer < level_inner ||
 	level_kspace != level_outer)
       error->all("Invalid order of forces within respa levels");
   }
   if (level_pair == -1 && level_middle >= 0) {
     if (level_inner < level_improper || level_middle < level_inner ||
 	level_outer < level_inner || level_kspace != level_outer)
       error->all("Invalid order of forces within respa levels");
   }
 
   // warn if any levels are devoid of forces
 
   int flag = 0;
   for (int i = 0; i < nlevels; i++)
     if (level_bond != i && level_angle != i && level_dihedral != i &&
 	level_improper != i && level_pair != i && level_inner != i &&
 	level_middle != i && level_outer != i && level_kspace != i) flag = 1;
   if (flag && comm->me == 0) 
     error->warning("One or more respa levels compute no forces");
 
   // check cutoff consistency if inner/middle/outer are enabled
 
   if (level_inner >= 0 && cutoff[1] < cutoff[0])
     error->all("Respa inner cutoffs are invalid");
   if (level_middle >= 0 && (cutoff[3] < cutoff[2] || cutoff[2] < cutoff[1]))
     error->all("Respa middle cutoffs are invalid");
 
   // set outer pair of cutoffs to inner pair if middle is not enabled
 
   if (level_inner >= 0 && level_middle < 0) {
     cutoff[2] = cutoff[0];
     cutoff[3] = cutoff[1];
   }
 
   // allocate other needed arrays
 
   newton = new int[nlevels];
   step = new double[nlevels];
 }
 
 /* ---------------------------------------------------------------------- */
 
 Respa::~Respa()
 {
   delete [] loop;
   delete [] newton;
   delete [] step;
 }
 
 /* ----------------------------------------------------------------------
    initialization before run
 ------------------------------------------------------------------------- */
 
 void Respa::init()
 {
   // warn if no fixes
 
   if (modify->nfix == 0 && comm->me == 0)
     error->warning("No fixes defined, atoms won't move");
 
   // create fix needed for storing atom-based respa level forces
   // will delete it at end of run
 
   char **fixarg = new char*[4];
   fixarg[0] = (char *) "RESPA";
   fixarg[1] = (char *) "all";
   fixarg[2] = (char *) "RESPA";
   fixarg[3] = new char[8];
   sprintf(fixarg[3],"%d",nlevels);
   modify->add_fix(4,fixarg);
   delete [] fixarg[3];
   delete [] fixarg;
   fix_respa = (FixRespa *) modify->fix[modify->nfix-1];
 
   // insure respa inner/middle/outer is using Pair class that supports it
 
   if (level_inner >= 0)
     if (force->pair && force->pair->respa_enable == 0)
       error->all("Pair style does not support rRESPA inner/middle/outer");
 
   // virial_style = 1 (explicit) since never computed implicitly like Verlet
 
   virial_style = 1;
 
   // setup lists of computes for global and per-atom PE and pressure
 
   ev_setup();
 
   // set flags for what arrays to clear in force_clear()
   // need to clear torques,erforce if arrays exists
 
   torqueflag = 0;
   if (atom->torque_flag) torqueflag = 1;
   erforceflag = 0;
   if (atom->erforce_flag) erforceflag = 1;
 
   // step[] = timestep for each level
 
   step[nlevels-1] = update->dt;
   for (int ilevel = nlevels-2; ilevel >= 0; ilevel--) 
     step[ilevel] = step[ilevel+1]/loop[ilevel];
 
   // set newton flag for each level
 
   for (int ilevel = 0; ilevel < nlevels; ilevel++) {
     newton[ilevel] = 0;
     if (force->newton_bond) {
       if (level_bond == ilevel || level_angle == ilevel || 
 	  level_dihedral == ilevel || level_improper == ilevel)
 	newton[ilevel] = 1;
     }
     if (force->newton_pair) {
       if (level_pair == ilevel || level_inner == ilevel || 
 	  level_middle == ilevel || level_outer == ilevel)
 	newton[ilevel] = 1;
     }
   }
 
   // orthogonal vs triclinic simulation box
 
   triclinic = domain->triclinic;
 }
 
 /* ----------------------------------------------------------------------
    setup before run
 ------------------------------------------------------------------------- */
 
 void Respa::setup()
 {
   if (comm->me == 0 && screen) fprintf(screen,"Setting up run ...\n");
 
   update->setupflag = 1;
 
   // setup domain, communication and neighboring
   // acquire ghosts
   // build neighbor lists
 
   atom->setup();
   if (triclinic) domain->x2lamda(atom->nlocal);
   domain->pbc();
   domain->reset_box();
   comm->setup();
   if (neighbor->style) neighbor->setup_bins();
   comm->exchange();
   if (atom->sortfreq > 0) atom->sort();
   comm->borders();
   if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
   neighbor->build();
   neighbor->ncalls = 0;
 
   // compute all forces
 
   ev_set(update->ntimestep);
 
   for (int ilevel = 0; ilevel < nlevels; ilevel++) {
     force_clear(newton[ilevel]);
     modify->setup_pre_force_respa(vflag,ilevel);
     if (level_bond == ilevel && force->bond)
       force->bond->compute(eflag,vflag);
     if (level_angle == ilevel && force->angle) 
       force->angle->compute(eflag,vflag);
     if (level_dihedral == ilevel && force->dihedral) 
       force->dihedral->compute(eflag,vflag);
     if (level_improper == ilevel && force->improper) 
       force->improper->compute(eflag,vflag);
     if (level_pair == ilevel && force->pair)
       force->pair->compute(eflag,vflag);
     if (level_inner == ilevel && force->pair)
       force->pair->compute_inner();
     if (level_middle == ilevel && force->pair)
       force->pair->compute_middle();
     if (level_outer == ilevel && force->pair)
       force->pair->compute_outer(eflag,vflag);
     if (level_kspace == ilevel && force->kspace) {
       force->kspace->setup();
       force->kspace->compute(eflag,vflag);
     }
     if (newton[ilevel]) comm->reverse_comm();
     copy_f_flevel(ilevel);
   }
   
   modify->setup(vflag);
   sum_flevel_f();
   output->setup(1);
   update->setupflag = 0;
 }
 
 /* ----------------------------------------------------------------------
    setup without output
    flag = 0 = just force calculation
    flag = 1 = reneighbor and force calculation
 ------------------------------------------------------------------------- */
 
 void Respa::setup_minimal(int flag)
 {
   update->setupflag = 1;
 
   // setup domain, communication and neighboring
   // acquire ghosts
   // build neighbor lists
 
   if (flag) {
     if (triclinic) domain->x2lamda(atom->nlocal);
     domain->pbc();
     domain->reset_box();
     comm->setup();
     if (neighbor->style) neighbor->setup_bins();
     comm->exchange();
     comm->borders();
     if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
     neighbor->build();
     neighbor->ncalls = 0;
   }
 
   // compute all forces
 
   ev_set(update->ntimestep);
 
   for (int ilevel = 0; ilevel < nlevels; ilevel++) {
     force_clear(newton[ilevel]);
     modify->setup_pre_force_respa(vflag,ilevel);
     if (level_bond == ilevel && force->bond)
       force->bond->compute(eflag,vflag);
     if (level_angle == ilevel && force->angle) 
       force->angle->compute(eflag,vflag);
     if (level_dihedral == ilevel && force->dihedral) 
       force->dihedral->compute(eflag,vflag);
     if (level_improper == ilevel && force->improper) 
       force->improper->compute(eflag,vflag);
     if (level_pair == ilevel && force->pair)
       force->pair->compute(eflag,vflag);
     if (level_inner == ilevel && force->pair)
       force->pair->compute_inner();
     if (level_middle == ilevel && force->pair)
       force->pair->compute_middle();
     if (level_outer == ilevel && force->pair)
       force->pair->compute_outer(eflag,vflag);
     if (level_kspace == ilevel && force->kspace) {
       force->kspace->setup();
       force->kspace->compute(eflag,vflag);
     }
     if (newton[ilevel]) comm->reverse_comm();
     copy_f_flevel(ilevel);
   }
   
   modify->setup(vflag);
   sum_flevel_f();
   update->setupflag = 0;
 }
 
 /* ----------------------------------------------------------------------
    run for N steps
 ------------------------------------------------------------------------- */
 
 void Respa::run(int n)
 {
-  int ntimestep;
+  bigint ntimestep;
 
   for (int i = 0; i < n; i++) {
 
     ntimestep = ++update->ntimestep;
     ev_set(ntimestep);
 
     recurse(nlevels-1);
 
     if (modify->n_end_of_step) modify->end_of_step();
 
     if (ntimestep == output->next) {
       timer->stamp();
       sum_flevel_f();
       output->write(update->ntimestep);
       timer->stamp(TIME_OUTPUT);
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    delete rRESPA fix at end of run, so its atom arrays won't persist
 ------------------------------------------------------------------------- */
 
 void Respa::cleanup()
 {
   modify->post_run();
   modify->delete_fix("RESPA");
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Respa::reset_dt()
 {
   step[nlevels-1] = update->dt;
   for (int ilevel = nlevels-2; ilevel >= 0; ilevel--) 
     step[ilevel] = step[ilevel+1]/loop[ilevel];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Respa::recurse(int ilevel)
 {
   copy_flevel_f(ilevel);
 
   for (int iloop = 0; iloop < loop[ilevel]; iloop++) {
 
     modify->initial_integrate_respa(vflag,ilevel,iloop);
     if (modify->n_post_integrate_respa)
       modify->post_integrate_respa(ilevel,iloop);
 
     if (ilevel) recurse(ilevel-1);
 
     // at outermost level, check on rebuilding neighbor list
     // at innermost level, communicate
     // at middle levels, do nothing
 
     if (ilevel == nlevels-1) {
       int nflag = neighbor->decide();
       if (nflag) {
 	if (modify->n_pre_exchange) modify->pre_exchange();
 	if (triclinic) domain->x2lamda(atom->nlocal);
 	domain->pbc();
 	if (domain->box_change) {
 	  domain->reset_box();
 	  comm->setup();
 	  if (neighbor->style) neighbor->setup_bins();
 	}
 	timer->stamp();
 	comm->exchange();
 	if (atom->sortfreq > 0 && 
 	    update->ntimestep >= atom->nextsort) atom->sort();
 	comm->borders();
 	if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
 	timer->stamp(TIME_COMM);
 	if (modify->n_pre_neighbor) modify->pre_neighbor();
 	neighbor->build();
 	timer->stamp(TIME_NEIGHBOR);
       }
 
     } else if (ilevel == 0) {
       timer->stamp();
       comm->forward_comm();
       timer->stamp(TIME_COMM);
     }
 
     force_clear(newton[ilevel]);
     if (modify->n_pre_force_respa)
       modify->pre_force_respa(vflag,ilevel,iloop);
 
     timer->stamp();
     if (level_bond == ilevel && force->bond) {
       force->bond->compute(eflag,vflag);
       timer->stamp(TIME_BOND);
     }
     if (level_angle == ilevel && force->angle) {
       force->angle->compute(eflag,vflag);
       timer->stamp(TIME_BOND);
     }
     if (level_dihedral == ilevel && force->dihedral) {
       force->dihedral->compute(eflag,vflag);
       timer->stamp(TIME_BOND);
     }
     if (level_improper == ilevel && force->improper) {
       force->improper->compute(eflag,vflag);
       timer->stamp(TIME_BOND);
     }
     if (level_pair == ilevel && force->pair) {
       force->pair->compute(eflag,vflag);
       timer->stamp(TIME_PAIR);
     }
     if (level_inner == ilevel && force->pair) {
       force->pair->compute_inner();
       timer->stamp(TIME_PAIR);
     }
     if (level_middle == ilevel && force->pair) {
       force->pair->compute_middle();
       timer->stamp(TIME_PAIR);
     }
     if (level_outer == ilevel && force->pair) {
       force->pair->compute_outer(eflag,vflag);
       timer->stamp(TIME_PAIR);
     }
     if (level_kspace == ilevel && force->kspace) {
       force->kspace->compute(eflag,vflag);
       timer->stamp(TIME_KSPACE);
     }
 
     if (newton[ilevel]) {
       comm->reverse_comm();
       timer->stamp(TIME_COMM);
     }
   
     if (modify->n_post_force_respa)
       modify->post_force_respa(vflag,ilevel,iloop);
     modify->final_integrate_respa(ilevel,iloop);
   }
 
   copy_f_flevel(ilevel);
 }
 
 /* ----------------------------------------------------------------------
    clear force on own & ghost atoms
 ------------------------------------------------------------------------- */
 
 void Respa::force_clear(int newtonflag)
 {
   int i;
 
   // clear global force array
   // nall includes ghosts only if newton flag is set
 
   int nall;
   if (newtonflag) nall = atom->nlocal + atom->nghost;
   else nall = atom->nlocal;
 
   double **f = atom->f;
   for (i = 0; i < nall; i++) {
     f[i][0] = 0.0;
     f[i][1] = 0.0;
     f[i][2] = 0.0;
   }
 
   if (torqueflag) {
     double **torque = atom->torque;
     for (i = 0; i < nall; i++) {
       torque[i][0] = 0.0;
       torque[i][1] = 0.0;
       torque[i][2] = 0.0;
     }
   }
 
   if (erforceflag) {
     double *erforce = atom->erforce;
     for (i = 0; i < nall; i++)
       erforce[i] = 0.0;
   }
 }
 
 /* ----------------------------------------------------------------------
    copy force components from atom->f to FixRespa->f_level
 ------------------------------------------------------------------------- */
 
 void Respa::copy_f_flevel(int ilevel)
 {
   double ***f_level = fix_respa->f_level;
   double **f = atom->f;
   int n = atom->nlocal;
 
   for (int i = 0; i < n; i++) {
     f_level[i][ilevel][0] = f[i][0];
     f_level[i][ilevel][1] = f[i][1];
     f_level[i][ilevel][2] = f[i][2];
   }
 }
 
 /* ----------------------------------------------------------------------
    copy force components from FixRespa->f_level to atom->f
 ------------------------------------------------------------------------- */
 
 void Respa::copy_flevel_f(int ilevel)
 {
   double ***f_level = fix_respa->f_level;
   double **f = atom->f;
   int n = atom->nlocal;
 
   for (int i = 0; i < n; i++) {
     f[i][0] = f_level[i][ilevel][0];
     f[i][1] = f_level[i][ilevel][1];
     f[i][2] = f_level[i][ilevel][2];
   }
 }
 
 /* ----------------------------------------------------------------------
    sum all force components from FixRespa->f_level to create full atom->f
 ------------------------------------------------------------------------- */
 
 void Respa::sum_flevel_f()
 {
   copy_flevel_f(0);
 
   double ***f_level = fix_respa->f_level;
   double **f = atom->f;
   int n = atom->nlocal;
 
   for (int ilevel = 1; ilevel < nlevels; ilevel++) {
     for (int i = 0; i < n; i++) {
       f[i][0] += f_level[i][ilevel][0];
       f[i][1] += f_level[i][ilevel][1];
       f[i][2] += f_level[i][ilevel][2];
     }
   }
 }
diff --git a/src/thermo.cpp b/src/thermo.cpp
index 042a28fce..b3d6cece7 100644
--- a/src/thermo.cpp
+++ b/src/thermo.cpp
@@ -1,1807 +1,1816 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdlib.h"
 #include "string.h"
 #include "thermo.h"
 #include "atom.h"
 #include "update.h"
 #include "comm.h"
 #include "domain.h"
 #include "lattice.h"
 #include "modify.h"
 #include "fix.h"
 #include "compute.h"
 #include "input.h"
 #include "variable.h"
 #include "force.h"
 #include "pair.h"
 #include "bond.h"
 #include "angle.h"
 #include "dihedral.h"
 #include "improper.h"
 #include "kspace.h"
 #include "output.h"
 #include "timer.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 // customize a new keyword by adding to this list:
 
 // step, elapsed, elaplong, dt, cpu, tpcpu, spcpu
 // atoms, temp, press, pe, ke, etotal, enthalpy
 // evdwl, ecoul, epair, ebond, eangle, edihed, eimp, emol, elong, etail
 // vol, lx, ly, lz, xlo, xhi, ylo, yhi, zlo, zhi, xy, xz, yz, xlat, ylat, zlat
 // pxx, pyy, pzz, pxy, pxz, pyz
 // fmax, fnorm
 
 // customize a new thermo style by adding a DEFINE to this list
 
 #define ONE "step temp epair emol etotal press"
 #define MULTI "etotal ke temp pe ebond eangle edihed eimp evdwl ecoul elong press"
 
 enum{IGNORE,WARN,ERROR};           // same as write_restart.cpp
 enum{ONELINE,MULTILINE};
 enum{INT,FLOAT,BIGINT};
 enum{SCALAR,VECTOR,ARRAY};
 
 #define INVOKED_SCALAR 1
 #define INVOKED_VECTOR 2
 #define INVOKED_ARRAY 4
 
 #define MAXLINE 8192               // make this 4x longer than Input::MAXLINE
 #define DELTA 8
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 /* ---------------------------------------------------------------------- */
 
 Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
 {
   MPI_Comm_rank(world,&me);
 
   int n = strlen(arg[0]) + 1;
   style = new char[n];
   strcpy(style,arg[0]);
 
   // set thermo_modify defaults
 
   modified = 0;
   normuserflag = 0;
   lineflag = ONELINE;
   lostflag = ERROR;
   lostbefore = 0;
   flushflag = 0;
 
   // set style and corresponding lineflag
   // custom style builds its own line of keywords
   // customize a new thermo style by adding to if statement
 
   line = new char[MAXLINE];
 
   if (strcmp(style,"one") == 0) {
     strcpy(line,ONE);
   } else if (strcmp(style,"multi") == 0) {
     strcpy(line,MULTI);
     lineflag = MULTILINE;
 
   } else if (strcmp(style,"custom") == 0) {
     if (narg == 1) error->all("Illegal thermo style custom command");
     line[0] = '\0';
     for (int iarg = 1; iarg < narg; iarg++) {
       strcat(line,arg[iarg]);
       strcat(line," ");
     }
     line[strlen(line)-1] = '\0';
 
   } else error->all("Illegal thermo style command");
 
   // ptrs, flags, IDs for compute objects thermo may use or create
 
   temperature = NULL;
   pressure = NULL;
   pe = NULL;
 
   index_temp = index_press_scalar = index_press_vector = index_pe = -1;
 
   id_temp = (char *) "thermo_temp";
   id_press = (char *) "thermo_press";
   id_pe = (char *) "thermo_pe";
 
   // count fields in line
   // allocate per-field memory
   // process line of keywords
 
   nfield_initial = atom->count_words(line);
   allocate();
   parse_fields(line);
 
   // format strings
 
-  format_multi = (char *) "---------------- Step %8d ----- "
-                          "CPU = %11.4f (sec) ----------------";
+  char *bigint_format = BIGINT_FORMAT;
+  char *fformat_multi = (char *) "---------------- Step %%8%s ----- "
+    "CPU = %%11.4f (sec) ----------------";
+
+  sprintf(format_multi,fformat_multi,&bigint_format[1]);
   format_float_one_def = (char *) "%12.8g";
   format_float_multi_def = (char *) "%14.4f";
   format_int_one_def = (char *) "%8d";
   format_int_multi_def = (char *) "%14d";
-  format_bigint_one_def = (char *) "%8lu";
-  format_bigint_multi_def = (char *) "%14lu";
+  sprintf(format_bigint_one_def,"%%8%s",&bigint_format[1]);
+  sprintf(format_bigint_multi_def,"%%14%s",&bigint_format[1]);
+
   format_float_user = NULL;
   format_int_user = NULL;
   format_bigint_user = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
 
 Thermo::~Thermo()
 {
   delete [] style;
   delete [] line;
 
   deallocate();
 
   // format strings
 
   delete [] format_float_user;
   delete [] format_int_user;
   delete [] format_bigint_user;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::init()
 {
   int i,n;
 
   // set normvalue to default setting unless user has specified it
 
   if (normuserflag) normvalue = normuser;
   else if (strcmp(update->unit_style,"lj") == 0) normvalue = 1;
   else normvalue = 0;
 
   // add Volume field if volume changes and not style = custom
   // this check must come after domain init, so box_change is set
 
   nfield = nfield_initial;
   if (domain->box_change && strcmp(style,"custom") != 0)
     addfield("Volume",&Thermo::compute_vol,FLOAT);
 
   // set format string for each field
   // include keyword if lineflag = MULTILINE
   // add '/n' every 3 values if lineflag = MULTILINE
   // add trailing '/n' to last value
 
   char *ptr;
   for (i = 0; i < nfield; i++) {
     format[i][0] = '\0';
     if (lineflag == MULTILINE && i % 3 == 0) strcat(format[i],"\n");
 
     if (format_user[i]) ptr = format_user[i];
     else if (vtype[i] == FLOAT) {
       if (format_float_user) ptr = format_float_user;
       else if (lineflag == ONELINE) ptr = format_float_one_def;
       else if (lineflag == MULTILINE) ptr = format_float_multi_def;
     } else if (vtype[i] == INT) {
       if (format_int_user) ptr = format_int_user;
       else if (lineflag == ONELINE) ptr = format_int_one_def;
       else if (lineflag == MULTILINE) ptr = format_int_multi_def;
     } else if (vtype[i] == BIGINT) {
       if (format_bigint_user) ptr = format_bigint_user;
       else if (lineflag == ONELINE) ptr = format_bigint_one_def;
       else if (lineflag == MULTILINE) ptr = format_bigint_multi_def;
     }
 
     n = strlen(format[i]);
     if (lineflag == ONELINE) sprintf(&format[i][n],"%s ",ptr);
     else sprintf(&format[i][n],"%-8s = %s ",keyword[i],ptr);
 
     if (i == nfield-1) strcat(format[i],"\n");
   }
 
   // find current ptr for each Compute ID
 
   int icompute;
   for (i = 0; i < ncompute; i++) {
     icompute = modify->find_compute(id_compute[i]);
     if (icompute < 0) error->all("Could not find thermo compute ID");
     computes[i] = modify->compute[icompute];
   }
 
   // find current ptr for each Fix ID
   // check that fix frequency is acceptable with thermo output frequency
 
   int ifix;
   for (i = 0; i < nfix; i++) {
     ifix = modify->find_fix(id_fix[i]);
     if (ifix < 0) error->all("Could not find thermo fix ID");
     fixes[i] = modify->fix[ifix];
     if (output->thermo_every % fixes[i]->global_freq)
       error->all("Thermo and fix not computed at compatible times");
   }
 
   // find current ptr for each Variable ID
 
   int ivariable;
   for (i = 0; i < nvariable; i++) {
     ivariable = input->variable->find(id_variable[i]);
     if (ivariable < 0) 
       error->all("Could not find thermo custom variable name");
     variables[i] = ivariable;
   }
 
   // set ptrs to keyword-specific Compute objects
 
   if (index_temp >= 0) temperature = computes[index_temp];
   if (index_press_scalar >= 0) pressure = computes[index_press_scalar];
   if (index_press_vector >= 0) pressure = computes[index_press_vector];
   if (index_pe >= 0) pe = computes[index_pe];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::header()
 {
   if (lineflag == MULTILINE) return;
 
   int loc = 0;
   for (int i = 0; i < nfield; i++)
     loc += sprintf(&line[loc],"%s ",keyword[i]);
   sprintf(&line[loc],"\n");
   
   if (me == 0) {
     if (screen) fprintf(screen,line);
     if (logfile) fprintf(logfile,line);
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute(int flag)
 {
   int i;
 
   firststep = flag;
-  int ntimestep = update->ntimestep;
+  bigint ntimestep = update->ntimestep;
 
   // check for lost atoms
   // turn off normflag if natoms = 0 to avoid divide by 0
 
   natoms = lost_check();
   if (natoms == 0) normflag = 0;
   else normflag = normvalue;
 
   // invoke Compute methods needed for thermo keywords
   // which = 0 is global scalar, which = 1 is global vector
 
   for (i = 0; i < ncompute; i++)
     if (compute_which[i] == SCALAR) {
       if (!(computes[i]->invoked_flag & INVOKED_SCALAR)) {
 	computes[i]->compute_scalar();
 	computes[i]->invoked_flag |= INVOKED_SCALAR;
       }
     } else if (compute_which[i] == VECTOR) {
       if (!(computes[i]->invoked_flag & INVOKED_VECTOR)) {
 	computes[i]->compute_vector();
 	computes[i]->invoked_flag |= INVOKED_VECTOR;
       }
     } else if (compute_which[i] == ARRAY) {
       if (!(computes[i]->invoked_flag & INVOKED_ARRAY)) {
 	computes[i]->compute_array();
 	computes[i]->invoked_flag |= INVOKED_ARRAY;
       }
     }
 
   // if lineflag = MULTILINE, prepend step/cpu header line
 
   int loc = 0;
   if (lineflag == MULTILINE) {
     double cpu;
     if (flag) cpu = timer->elapsed(TIME_LOOP);
     else cpu = 0.0;
     loc = sprintf(&line[loc],format_multi,ntimestep,cpu);
   }
 
   // add each thermo value to line with its specific format
 
   for (ifield = 0; ifield < nfield; ifield++) {
     (this->*vfunc[ifield])();
     if (vtype[ifield] == FLOAT)
       loc += sprintf(&line[loc],format[ifield],dvalue);
     else if (vtype[ifield] == INT) 
       loc += sprintf(&line[loc],format[ifield],ivalue);
     else if (vtype[ifield] == BIGINT) {
       loc += sprintf(&line[loc],format[ifield],bivalue);
     }
   }
 
   // kludge for RedStorm timing issue
   // if (ntimestep == 100) return;
 
   // print line to screen and logfile
 
   if (me == 0) {
     if (screen) fprintf(screen,line);
     if (logfile) {
       fprintf(logfile,line);
       if (flushflag) fflush(logfile);
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    check for lost atoms, return current number of atoms
 ------------------------------------------------------------------------- */
 
 bigint Thermo::lost_check()
 {
   // ntotal = current # of atoms
 
   bigint ntotal;
   bigint nblocal = atom->nlocal;
-  MPI_Allreduce(&nblocal,&ntotal,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&nblocal,&ntotal,1,MPI_LMP_BIGINT,MPI_SUM,world);
+  if (ntotal < 0 || ntotal > MAXBIGINT) error->all("Too many total atoms");
   if (ntotal == atom->natoms) return ntotal;
 
   // if not checking or already warned, just return
 
   if (lostflag == IGNORE) return ntotal;
   if (lostflag == WARN && lostbefore == 1) return ntotal;
 
   // error message
 
   if (lostflag == ERROR) {
-    char str[128];
-    sprintf(str,"Lost atoms: original %lu current %lu",atom->natoms,ntotal);
+    char fstr[64],str[64];
+    sprintf(fstr,
+	    "Lost atoms: original %s current %s",BIGINT_FORMAT,BIGINT_FORMAT);
+    sprintf(str,fstr,atom->natoms,ntotal);
     error->all(str);
   }
 
   // warning message
 
-  char str[128];
-  sprintf(str,"Lost atoms: original %lu current %lu",atom->natoms,ntotal);
+  char fstr[64],str[64];
+  sprintf(fstr,
+	  "Lost atoms: original %s current %s",BIGINT_FORMAT,BIGINT_FORMAT);
+  sprintf(str,fstr,atom->natoms,ntotal);
   if (me == 0) error->warning(str,0);
   lostbefore = 1;
   return ntotal;
 }
 
 /* ----------------------------------------------------------------------
    modify thermo parameters
 ------------------------------------------------------------------------- */
 
 void Thermo::modify_params(int narg, char **arg)
 {
   if (narg == 0) error->all("Illegal thermo_modify command");
 
   modified = 1;
 
   int iarg = 0;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"every") == 0) {
       if (iarg+2 > narg) error->all("Illegal thermo_modify command");
       if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) {
 	delete [] output->var_thermo;
 	int n = strlen(&arg[iarg+1][2]) + 1;
 	output->var_thermo = new char[n];
 	strcpy(output->var_thermo,&arg[iarg+1][2]);
       } else error->all("Illegal thermo_modify command");
       output->thermo_every = 0;
       iarg += 2;
     } else if (strcmp(arg[iarg],"temp") == 0) {
       if (iarg+2 > narg) error->all("Illegal thermo_modify command");
       if (index_temp < 0) error->all("Thermo style does not use temp");
       delete [] id_compute[index_temp];
       int n = strlen(arg[iarg+1]) + 1;
       id_compute[index_temp] = new char[n];
       strcpy(id_compute[index_temp],arg[iarg+1]);
 
       int icompute = modify->find_compute(arg[iarg+1]);
       if (icompute < 0) 
 	error->all("Could not find thermo_modify temperature ID");
       temperature = modify->compute[icompute];
 
       if (temperature->tempflag == 0)
 	error->all("Thermo_modify temperature ID does not "
 		   "compute temperature");
       if (temperature->igroup != 0 && comm->me == 0)
 	error->warning("Temperature for thermo pressure is not for group all");
 
       // reset id_temp of pressure to new temperature ID
       // either pressure currently being used by thermo or "thermo_press"
 
       if (index_press_scalar >= 0) {
 	icompute = modify->find_compute(id_compute[index_press_scalar]);
 	if (icompute < 0) error->all("Pressure ID for thermo does not exist");
       } else if (index_press_vector >= 0) {
 	icompute = modify->find_compute(id_compute[index_press_vector]);
 	if (icompute < 0) error->all("Pressure ID for thermo does not exist");
       } else icompute = modify->find_compute((char *) "thermo_press");
 
       modify->compute[icompute]->reset_extra_compute_fix(arg[iarg+1]);
 
       iarg += 2;
 
     } else if (strcmp(arg[iarg],"press") == 0) {
       if (iarg+2 > narg) error->all("Illegal thermo_modify command");
       if (index_press_scalar < 0 && index_press_vector < 0)
 	error->all("Thermo style does not use press");
 
       if (index_press_scalar >= 0) {
 	delete [] id_compute[index_press_scalar];
 	int n = strlen(arg[iarg+1]) + 1;
 	id_compute[index_press_scalar] = new char[n];
 	strcpy(id_compute[index_press_scalar],arg[iarg+1]);
       }
       if (index_press_vector >= 0) {
 	delete [] id_compute[index_press_vector];
 	int n = strlen(arg[iarg+1]) + 1;
 	id_compute[index_press_vector] = new char[n];
 	strcpy(id_compute[index_press_vector],arg[iarg+1]);
       }
 
       int icompute = modify->find_compute(arg[iarg+1]);
       if (icompute < 0) error->all("Could not find thermo_modify pressure ID");
       pressure = modify->compute[icompute];
 
       if (pressure->pressflag == 0)
 	error->all("Thermo_modify pressure ID does not compute pressure");
 
       iarg += 2;
 
     } else if (strcmp(arg[iarg],"lost") == 0) {
       if (iarg+2 > narg) error->all("Illegal thermo_modify command");
       if (strcmp(arg[iarg+1],"ignore") == 0) lostflag = IGNORE;
       else if (strcmp(arg[iarg+1],"warn") == 0) lostflag = WARN;
       else if (strcmp(arg[iarg+1],"error") == 0) lostflag = ERROR;
       else error->all("Illegal thermo_modify command");
       iarg += 2;
 
     } else if (strcmp(arg[iarg],"norm") == 0) {
       if (iarg+2 > narg) error->all("Illegal thermo_modify command");
       normuserflag = 1;
       if (strcmp(arg[iarg+1],"no") == 0) normuser = 0;
       else if (strcmp(arg[iarg+1],"yes") == 0) normuser = 1;
       else error->all("Illegal thermo_modify command");
       iarg += 2;
 
     } else if (strcmp(arg[iarg],"flush") == 0) {
       if (iarg+2 > narg) error->all("Illegal thermo_modify command");
       if (strcmp(arg[iarg+1],"no") == 0) flushflag = 0;
       else if (strcmp(arg[iarg+1],"yes") == 0) flushflag = 1;
       else error->all("Illegal thermo_modify command");
       iarg += 2;
 
     } else if (strcmp(arg[iarg],"line") == 0) {
       if (iarg+2 > narg) error->all("Illegal thermo_modify command");
       if (strcmp(arg[iarg+1],"one") == 0) lineflag = ONELINE;
       else if (strcmp(arg[iarg+1],"multi") == 0) lineflag = MULTILINE;
       else error->all("Illegal thermo_modify command");
       iarg += 2;
 
     } else if (strcmp(arg[iarg],"format") == 0) {
       if (iarg+3 > narg) error->all("Illegal thermo_modify command");
       if (strcmp(arg[iarg+1],"int") == 0) {
 	if (format_int_user) delete [] format_int_user;
 	int n = strlen(arg[iarg+2]) + 1;
 	format_int_user = new char[n];
 	strcpy(format_int_user,arg[iarg+2]);
 	if (format_bigint_user) delete [] format_bigint_user;
-	n = strlen(format_int_user) + 2;
+	n = strlen(format_int_user) + 3;
 	format_bigint_user = new char[n];
 	char *ptr = strchr(format_int_user,'d');
 	if (ptr == NULL) 
 	  error->all("Thermo_modify int format does not contain d character");
 	*ptr = '\0';
-	sprintf(format_bigint_user,"%s%s%s",format_int_user,"lu",ptr+1);
+	sprintf(format_bigint_user,"%s%s%s",format_int_user,
+		BIGINT_FORMAT,ptr+1);
 	*ptr = 'd';
       } else if (strcmp(arg[iarg+1],"float") == 0) {
 	if (format_float_user) delete [] format_float_user;
 	int n = strlen(arg[iarg+2]) + 1;
 	format_float_user = new char[n];
 	strcpy(format_float_user,arg[iarg+2]);
       } else {
 	int i = atoi(arg[iarg+1]) - 1;
 	if (i < 0 || i >= nfield_initial)
 	  error->all("Illegal thermo_modify command");
 	if (format_user[i]) delete [] format_user[i];
 	int n = strlen(arg[iarg+2]) + 1;
 	format_user[i] = new char[n];
 	strcpy(format_user[i],arg[iarg+2]);
       }
       iarg += 3;
 
     } else error->all("Illegal thermo_modify command");
   }
 }
 
 /* ----------------------------------------------------------------------
    allocate all per-field memory
 ------------------------------------------------------------------------- */
 
 void Thermo::allocate()
 {
   // n = specified fields + Volume field (added at run time)
 
   int n = nfield_initial + 1;
 
   keyword = new char*[n];
   for (int i = 0; i < n; i++) keyword[i] = new char[32];
   vfunc = new FnPtr[n];
   vtype = new int[n];
 
   format = new char*[n];
   for (int i = 0; i < n; i++) format[i] = new char[32];
   format_user = new char*[n];
   for (int i = 0; i < n; i++) format_user[i] = NULL;
 
   field2index = new int[n];
   argindex1 = new int[n];
   argindex2 = new int[n];
 
   // factor of 3 is max number of computes a single field can add
 
   ncompute = 0;
   id_compute = new char*[3*n];
   compute_which = new int[3*n];
   computes = new Compute*[3*n];
 
   nfix = 0;
   id_fix = new char*[n];
   fixes = new Fix*[n];
 
   nvariable = 0;
   id_variable = new char*[n];
   variables = new int[n];
 }
 
 /* ----------------------------------------------------------------------
    deallocate all per-field memory
 ------------------------------------------------------------------------- */
 
 void Thermo::deallocate()
 {
   int n = nfield_initial + 1;
 
   for (int i = 0; i < n; i++) delete [] keyword[i];
   delete [] keyword;
   delete [] vfunc;
   delete [] vtype;
 
   for (int i = 0; i < n; i++) delete [] format[i];
   delete [] format;
   for (int i = 0; i < n; i++) delete [] format_user[i];
   delete [] format_user;
 
   delete [] field2index;
   delete [] argindex1;
   delete [] argindex2;
 
   for (int i = 0; i < ncompute; i++) delete [] id_compute[i];
   delete [] id_compute;
   delete [] compute_which;
   delete [] computes;
 
   for (int i = 0; i < nfix; i++) delete [] id_fix[i];
   delete [] id_fix;
   delete [] fixes;
 
   for (int i = 0; i < nvariable; i++) delete [] id_variable[i];
   delete [] id_variable;
   delete [] variables;
 }
 
 /* ----------------------------------------------------------------------
    parse list of thermo keywords from str
    set compute flags (temp, press, pe, etc)
 ------------------------------------------------------------------------- */
 
 void Thermo::parse_fields(char *str)
 {
   nfield = 0;
 
   // customize a new keyword by adding to if statement
 
   char *word = strtok(str," \0");
   while (word) {
 
     if (strcmp(word,"step") == 0) {
-      addfield("Step",&Thermo::compute_step,INT);
+      addfield("Step",&Thermo::compute_step,BIGINT);
     } else if (strcmp(word,"elapsed") == 0) {
-      addfield("Elapsed",&Thermo::compute_elapsed,INT);
+      addfield("Elapsed",&Thermo::compute_elapsed,BIGINT);
     } else if (strcmp(word,"elaplong") == 0) {
-      addfield("Elaplong",&Thermo::compute_elapsed_long,INT);
+      addfield("Elaplong",&Thermo::compute_elapsed_long,BIGINT);
     } else if (strcmp(word,"dt") == 0) {
       addfield("Dt",&Thermo::compute_dt,FLOAT);
     } else if (strcmp(word,"cpu") == 0) {
       addfield("CPU",&Thermo::compute_cpu,FLOAT);
     } else if (strcmp(word,"tpcpu") == 0) {
       addfield("T/CPU",&Thermo::compute_tpcpu,FLOAT);
     } else if (strcmp(word,"spcpu") == 0) {
       addfield("S/CPU",&Thermo::compute_spcpu,FLOAT);
 
     } else if (strcmp(word,"atoms") == 0) {
       addfield("Atoms",&Thermo::compute_atoms,BIGINT);
     } else if (strcmp(word,"temp") == 0) {
       addfield("Temp",&Thermo::compute_temp,FLOAT);
       index_temp = add_compute(id_temp,SCALAR);
     } else if (strcmp(word,"press") == 0) {
       addfield("Press",&Thermo::compute_press,FLOAT);
       index_press_scalar = add_compute(id_press,SCALAR);
     } else if (strcmp(word,"pe") == 0) {
       addfield("PotEng",&Thermo::compute_pe,FLOAT);
       index_pe = add_compute(id_pe,SCALAR);
     } else if (strcmp(word,"ke") == 0) {
       addfield("KinEng",&Thermo::compute_ke,FLOAT);
       index_temp = add_compute(id_temp,SCALAR);
     } else if (strcmp(word,"etotal") == 0) {
       addfield("TotEng",&Thermo::compute_etotal,FLOAT);
       index_temp = add_compute(id_temp,SCALAR);
       index_pe = add_compute(id_pe,SCALAR);
     } else if (strcmp(word,"enthalpy") == 0) {
       addfield("Enthalpy",&Thermo::compute_enthalpy,FLOAT);
       index_temp = add_compute(id_temp,SCALAR);
       index_press_scalar = add_compute(id_press,SCALAR);
       index_pe = add_compute(id_pe,SCALAR);
 
     } else if (strcmp(word,"evdwl") == 0) {
       addfield("E_vdwl",&Thermo::compute_evdwl,FLOAT);
       index_pe = add_compute(id_pe,SCALAR);
     } else if (strcmp(word,"ecoul") == 0) {
       addfield("E_coul",&Thermo::compute_ecoul,FLOAT);
       index_pe = add_compute(id_pe,SCALAR);
     } else if (strcmp(word,"epair") == 0) {
       addfield("E_pair",&Thermo::compute_epair,FLOAT);
       index_pe = add_compute(id_pe,SCALAR);
     } else if (strcmp(word,"ebond") == 0) {
       addfield("E_bond",&Thermo::compute_ebond,FLOAT);
       index_pe = add_compute(id_pe,SCALAR);
     } else if (strcmp(word,"eangle") == 0) {
       addfield("E_angle",&Thermo::compute_eangle,FLOAT);
       index_pe = add_compute(id_pe,SCALAR);
     } else if (strcmp(word,"edihed") == 0) {
       addfield("E_dihed",&Thermo::compute_edihed,FLOAT);
       index_pe = add_compute(id_pe,SCALAR);
     } else if (strcmp(word,"eimp") == 0) {
       addfield("E_impro",&Thermo::compute_eimp,FLOAT);
       index_pe = add_compute(id_pe,SCALAR);
     } else if (strcmp(word,"emol") == 0) {
       addfield("E_mol",&Thermo::compute_emol,FLOAT);
       index_pe = add_compute(id_pe,SCALAR);
     } else if (strcmp(word,"elong") == 0) {
       addfield("E_long",&Thermo::compute_elong,FLOAT);
       index_pe = add_compute(id_pe,SCALAR);
     } else if (strcmp(word,"etail") == 0) {
       addfield("E_tail",&Thermo::compute_etail,FLOAT);
       index_pe = add_compute(id_pe,SCALAR);
 
     } else if (strcmp(word,"vol") == 0) {
       addfield("Volume",&Thermo::compute_vol,FLOAT);
     } else if (strcmp(word,"lx") == 0) {
       addfield("Lx",&Thermo::compute_lx,FLOAT);
     } else if (strcmp(word,"ly") == 0) {
       addfield("Ly",&Thermo::compute_ly,FLOAT);
     } else if (strcmp(word,"lz") == 0) {
       addfield("Lz",&Thermo::compute_lz,FLOAT);
 
     } else if (strcmp(word,"xlo") == 0) {
       addfield("Xlo",&Thermo::compute_xlo,FLOAT);
     } else if (strcmp(word,"xhi") == 0) {
       addfield("Xhi",&Thermo::compute_xhi,FLOAT);
     } else if (strcmp(word,"ylo") == 0) {
       addfield("Ylo",&Thermo::compute_ylo,FLOAT);
     } else if (strcmp(word,"yhi") == 0) {
       addfield("Yhi",&Thermo::compute_yhi,FLOAT);
     } else if (strcmp(word,"zlo") == 0) {
       addfield("Zlo",&Thermo::compute_zlo,FLOAT);
     } else if (strcmp(word,"zhi") == 0) {
       addfield("Zhi",&Thermo::compute_zhi,FLOAT);
 
     } else if (strcmp(word,"xy") == 0) {
       addfield("Xy",&Thermo::compute_xy,FLOAT);
     } else if (strcmp(word,"xz") == 0) {
       addfield("Xz",&Thermo::compute_xz,FLOAT);
     } else if (strcmp(word,"yz") == 0) {
       addfield("Yz",&Thermo::compute_yz,FLOAT);
 
     } else if (strcmp(word,"xlat") == 0) {
       if (domain->lattice == NULL) 
 	error->all("Thermo keyword requires lattice be defined");
       addfield("Xlat",&Thermo::compute_xlat,FLOAT);
     } else if (strcmp(word,"ylat") == 0) {
       if (domain->lattice == NULL) 
 	error->all("Thermo keyword requires lattice be defined");
       addfield("Ylat",&Thermo::compute_ylat,FLOAT);
     } else if (strcmp(word,"zlat") == 0) {
       if (domain->lattice == NULL) 
 	error->all("Thermo keyword requires lattice be defined");
       addfield("Zlat",&Thermo::compute_zlat,FLOAT);
 
     } else if (strcmp(word,"pxx") == 0) {
       addfield("Pxx",&Thermo::compute_pxx,FLOAT);
       index_press_vector = add_compute(id_press,VECTOR);
     } else if (strcmp(word,"pyy") == 0) {
       addfield("Pyy",&Thermo::compute_pyy,FLOAT);
       index_press_vector = add_compute(id_press,VECTOR);
     } else if (strcmp(word,"pzz") == 0) {
       addfield("Pzz",&Thermo::compute_pzz,FLOAT);
       index_press_vector = add_compute(id_press,VECTOR);
     } else if (strcmp(word,"pxy") == 0) {
       addfield("Pxy",&Thermo::compute_pxy,FLOAT);
       index_press_vector = add_compute(id_press,VECTOR);
     } else if (strcmp(word,"pxz") == 0) {
       addfield("Pxz",&Thermo::compute_pxz,FLOAT);
       index_press_vector = add_compute(id_press,VECTOR);
     } else if (strcmp(word,"pyz") == 0) {
       addfield("Pyz",&Thermo::compute_pyz,FLOAT);
       index_press_vector = add_compute(id_press,VECTOR);
 
     } else if (strcmp(word,"fmax") == 0) {
       addfield("Fmax",&Thermo::compute_fmax,FLOAT);
     } else if (strcmp(word,"fnorm") == 0) {
       addfield("Fnorm",&Thermo::compute_fnorm,FLOAT);
 
     // compute value = c_ID, fix value = f_ID, variable value = v_ID
     // count trailing [] and store int arguments
     // copy = at most 8 chars of ID to pass to addfield
 
     } else if ((strncmp(word,"c_",2) == 0) || (strncmp(word,"f_",2) == 0) ||
 	       (strncmp(word,"v_",2) == 0)) {
 
       int n = strlen(word);
       char *id = new char[n];
       strcpy(id,&word[2]);
       char copy[9];
       strncpy(copy,id,8);
       copy[8] = '\0';
 
       // parse zero or one or two trailing brackets from ID
       // argindex1,argindex2 = int inside each bracket pair, 0 if no bracket
 
       char *ptr = strchr(id,'[');
       if (ptr == NULL) argindex1[nfield] = 0;
       else {
 	*ptr = '\0';
 	argindex1[nfield] = input->variable->int_between_brackets(ptr);
 	ptr++;
 	if (*ptr == '[') {
 	  argindex2[nfield] = input->variable->int_between_brackets(ptr);
 	  ptr++;
 	} else argindex2[nfield] = 0;
       }
 
       if (word[0] == 'c') {
 	n = modify->find_compute(id);
 	if (n < 0) error->all("Could not find thermo custom compute ID");
 	if (argindex1[nfield] == 0 && modify->compute[n]->scalar_flag == 0)
 	  error->all("Thermo compute does not compute scalar");
 	if (argindex1[nfield] > 0 && argindex2[nfield] == 0) {
 	  if (modify->compute[n]->vector_flag == 0)
 	    error->all("Thermo compute does not compute vector");
 	  if (argindex1[nfield] > modify->compute[n]->size_vector)
 	    error->all("Thermo compute vector is accessed out-of-range");
 	}
 	if (argindex1[nfield] > 0 && argindex2[nfield] > 0) {
 	  if (modify->compute[n]->array_flag == 0)
 	    error->all("Thermo compute does not compute array");
 	  if (argindex1[nfield] > modify->compute[n]->size_array_rows ||
 	      argindex2[nfield] > modify->compute[n]->size_array_cols)
 	    error->all("Thermo compute array is accessed out-of-range");
 	}
 
 	if (argindex1[nfield] == 0)
 	  field2index[nfield] = add_compute(id,SCALAR);
 	else if (argindex2[nfield] == 0)
 	  field2index[nfield] = add_compute(id,VECTOR);
 	else 
 	  field2index[nfield] = add_compute(id,ARRAY);
 	addfield(copy,&Thermo::compute_compute,FLOAT);
 
       } else if (word[0] == 'f') {
 	n = modify->find_fix(id);
 	if (n < 0) error->all("Could not find thermo custom fix ID");
 	if (argindex1[nfield] == 0 && modify->fix[n]->scalar_flag == 0)
 	  error->all("Thermo fix does not compute scalar");
 	if (argindex1[nfield] > 0 && argindex2[nfield] == 0) {
 	  if (modify->fix[n]->vector_flag == 0)
 	    error->all("Thermo fix does not compute vector");
 	  if (argindex1[nfield] > modify->fix[n]->size_vector)
 	    error->all("Thermo fix vector is accessed out-of-range");
 	}
 	if (argindex1[nfield] > 0 && argindex2[nfield] > 0) {
 	  if (modify->fix[n]->array_flag == 0)
 	    error->all("Thermo fix does not compute array");
 	  if (argindex1[nfield] > modify->fix[n]->size_array_rows ||
 	      argindex2[nfield] > modify->fix[n]->size_array_cols)
 	    error->all("Thermo fix array is accessed out-of-range");
 	}
 
 	field2index[nfield] = add_fix(id);
 	addfield(copy,&Thermo::compute_fix,FLOAT);
 
       } else if (word[0] == 'v') {
 	n = input->variable->find(id);
 	if (n < 0) error->all("Could not find thermo custom variable name");
 	if (input->variable->equalstyle(n) == 0)
 	  error->all("Thermo custom variable is not equal-style variable");
 	if (argindex1[nfield]) 
 	  error->all("Thermo custom variable cannot be indexed");
 
 	field2index[nfield] = add_variable(id);
 	addfield(copy,&Thermo::compute_variable,FLOAT);
       }
 
       delete [] id;
 
     } else error->all("Invalid keyword in thermo_style custom command");
 
     word = strtok(NULL," \0");
   }
 }
 
 /* ----------------------------------------------------------------------
    add field to list of quantities to print
 ------------------------------------------------------------------------- */
 
 void Thermo::addfield(const char *key, FnPtr func, int typeflag)
 {
   strcpy(keyword[nfield],key);
   vfunc[nfield] = func;
   vtype[nfield] = typeflag;
   nfield++;
 }
 
 /* ----------------------------------------------------------------------
    add compute ID to list of Compute objects to call
    return location of where this Compute is in list
    if already in list with same which, do not add, just return index
 ------------------------------------------------------------------------- */
 
 int Thermo::add_compute(const char *id, int which)
 {
   int icompute;
   for (icompute = 0; icompute < ncompute; icompute++)
     if ((strcmp(id,id_compute[icompute]) == 0) && 
 	which == compute_which[icompute]) break;
   if (icompute < ncompute) return icompute;
 
   int n = strlen(id) + 1;
   id_compute[ncompute] = new char[n];
   strcpy(id_compute[ncompute],id);
   compute_which[ncompute] = which;
   ncompute++;
   return ncompute-1;
 }
 
 /* ----------------------------------------------------------------------
    add fix ID to list of Fix objects to call
 ------------------------------------------------------------------------- */
 
 int Thermo::add_fix(const char *id)
 {
   int n = strlen(id) + 1;
   id_fix[nfix] = new char[n];
   strcpy(id_fix[nfix],id);
   nfix++;
   return nfix-1;
 }
 
 /* ----------------------------------------------------------------------
    add variable ID to list of Variables to evaluate
 ------------------------------------------------------------------------- */
 
 int Thermo::add_variable(const char *id)
 {
   int n = strlen(id) + 1;
   id_variable[nvariable] = new char[n];
   strcpy(id_variable[nvariable],id);
   nvariable++;
   return nvariable-1;
 }
 
 /* ----------------------------------------------------------------------
    compute a single thermodyanmic value, word is any keyword in custom list
    called when a variable is evaluated by Variable class
    return value as double in answer
    return 0 if str is recoginzed keyword, 1 if unrecognized
    customize a new keyword by adding to if statement
 ------------------------------------------------------------------------- */
 
 int Thermo::evaluate_keyword(char *word, double *answer)
 {
   // invoke a lo-level thermo routine to compute the variable value
   // if keyword requires a compute, error if thermo doesn't use the compute
   // if inbetween runs and needed compute is not current, error
   // if in middle of run and needed compute is not current, invoke it
   // for keywords that use pe indirectly (evdwl, ebond, etc):
   //   check if energy was tallied on this timestep and set pe->invoked_flag 
   //   this will trigger next timestep for energy tallying via addstep()
 
   if (strcmp(word,"step") == 0) {
     compute_step();
-    dvalue = ivalue;
 
   } else if (strcmp(word,"elapsed") == 0) {
     if (update->whichflag == 0) 
       error->all("This variable thermo keyword cannot be used between runs");
     compute_elapsed();
     dvalue = ivalue;
 
   } else if (strcmp(word,"elaplong") == 0) {
     if (update->whichflag == 0) 
       error->all("This variable thermo keyword cannot be used between runs");
     compute_elapsed_long();
     dvalue = ivalue;
 
   } else if (strcmp(word,"dt") == 0) {
     compute_dt();
 
   } else if (strcmp(word,"cpu") == 0) {
     if (update->whichflag == 0) 
       error->all("This variable thermo keyword cannot be used between runs");
     compute_cpu();
 
   } else if (strcmp(word,"tpcpu") == 0) {
     if (update->whichflag == 0) 
       error->all("This variable thermo keyword cannot be used between runs");
     compute_tpcpu();
 
   } else if (strcmp(word,"spcpu") == 0) {
     if (update->whichflag == 0) 
       error->all("This variable thermo keyword cannot be used between runs");
     compute_spcpu();
 
   } else if (strcmp(word,"atoms") == 0) {
     compute_atoms();
 
   } else if (strcmp(word,"temp") == 0) {
     if (!temperature)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init temp");	  
     if (update->whichflag == 0) {
       if (temperature->invoked_scalar != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(temperature->invoked_flag & INVOKED_SCALAR)) {
       temperature->compute_scalar();
       temperature->invoked_flag |= INVOKED_SCALAR;
     }
     compute_temp();
     
   } else if (strcmp(word,"press") == 0) {
     if (!pressure)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init press");
     if (update->whichflag == 0) {
       if (pressure->invoked_scalar != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(pressure->invoked_flag & INVOKED_SCALAR)) {
       pressure->compute_scalar();
       pressure->invoked_flag |= INVOKED_SCALAR;
     }
     compute_press();
 
   } else if (strcmp(word,"pe") == 0) {
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     if (update->whichflag == 0) {
       if (pe->invoked_scalar != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(pe->invoked_flag & INVOKED_SCALAR)) {
       pe->compute_scalar();
       pe->invoked_flag |= INVOKED_SCALAR;
     }
     compute_pe();
 
   } else if (strcmp(word,"ke") == 0) {
     if (!temperature)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init temp");
     if (update->whichflag == 0) {
       if (temperature->invoked_scalar != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(temperature->invoked_flag & INVOKED_SCALAR)) {
       temperature->compute_scalar();
       temperature->invoked_flag |= INVOKED_SCALAR;
     }
     compute_ke();
 
   } else if (strcmp(word,"etotal") == 0) {
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     if (update->whichflag == 0) {
       if (pe->invoked_scalar != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(pe->invoked_flag & INVOKED_SCALAR)) {
       pe->compute_scalar();
       pe->invoked_flag |= INVOKED_SCALAR;
     }
     if (!temperature)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init temp");
     if (update->whichflag == 0) {
       if (temperature->invoked_scalar != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(temperature->invoked_flag & INVOKED_SCALAR)) {
       temperature->compute_scalar();
       temperature->invoked_flag |= INVOKED_SCALAR;
     }
     compute_etotal();
 
   } else if (strcmp(word,"enthalpy") == 0) {
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     if (update->whichflag == 0) {
       if (pe->invoked_scalar != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(pe->invoked_flag & INVOKED_SCALAR)) {
       pe->compute_scalar();
       pe->invoked_flag |= INVOKED_SCALAR;
     }
     if (!temperature)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init temp");
     if (update->whichflag == 0) {
       if (temperature->invoked_scalar != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(temperature->invoked_flag & INVOKED_SCALAR)) {
       temperature->compute_scalar();
       temperature->invoked_flag |= INVOKED_SCALAR;
     }
     if (!pressure)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init press");
     if (update->whichflag == 0) {
       if (pressure->invoked_scalar != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(pressure->invoked_flag & INVOKED_SCALAR)) {
       pressure->compute_scalar();
       pressure->invoked_flag |= INVOKED_SCALAR;
     }
     compute_enthalpy();
 
   } else if (strcmp(word,"evdwl") == 0) {
     if (update->eflag_global != update->ntimestep)
       error->all("Energy was not tallied on needed timestep");
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     pe->invoked_flag |= INVOKED_SCALAR;
     compute_evdwl();
 
   } else if (strcmp(word,"ecoul") == 0) {
     if (update->eflag_global != update->ntimestep)
       error->all("Energy was not tallied on needed timestep");
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     pe->invoked_flag |= INVOKED_SCALAR;
     compute_ecoul();
 
   } else if (strcmp(word,"epair") == 0) {
     if (update->eflag_global != update->ntimestep)
       error->all("Energy was not tallied on needed timestep");
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     pe->invoked_flag |= INVOKED_SCALAR;
     compute_epair();
 
   } else if (strcmp(word,"ebond") == 0) {
     if (update->eflag_global != update->ntimestep)
       error->all("Energy was not tallied on needed timestep");
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     pe->invoked_flag |= INVOKED_SCALAR;
     compute_ebond();
 
   } else if (strcmp(word,"eangle") == 0) {
     if (update->eflag_global != update->ntimestep)
       error->all("Energy was not tallied on needed timestep");
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     pe->invoked_flag |= INVOKED_SCALAR;
     compute_eangle();
 
   } else if (strcmp(word,"edihed") == 0) {
     if (update->eflag_global != update->ntimestep)
       error->all("Energy was not tallied on needed timestep");
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     pe->invoked_flag |= INVOKED_SCALAR;
     compute_edihed();
 
   } else if (strcmp(word,"eimp") == 0) {
     if (update->eflag_global != update->ntimestep)
       error->all("Energy was not tallied on needed timestep");
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     pe->invoked_flag |= INVOKED_SCALAR;
     compute_eimp();
 
   } else if (strcmp(word,"emol") == 0) {
     if (update->eflag_global != update->ntimestep)
       error->all("Energy was not tallied on needed timestep");
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     pe->invoked_flag |= INVOKED_SCALAR;
     compute_emol();
 
   } else if (strcmp(word,"elong") == 0) {
     if (update->eflag_global != update->ntimestep)
       error->all("Energy was not tallied on needed timestep");
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     pe->invoked_flag |= INVOKED_SCALAR;
     compute_elong();
 
   } else if (strcmp(word,"etail") == 0) {
     if (update->eflag_global != update->ntimestep)
       error->all("Energy was not tallied on needed timestep");
     if (!pe)
       error->all("Thermo keyword in variable requires thermo to use/init pe");
     pe->invoked_flag |= INVOKED_SCALAR;
     compute_etail();
 
   } else if (strcmp(word,"vol") == 0) compute_vol();
   else if (strcmp(word,"lx") == 0) compute_lx();
   else if (strcmp(word,"ly") == 0) compute_ly();
   else if (strcmp(word,"lz") == 0) compute_lz();
 
   else if (strcmp(word,"xlo") == 0) compute_xlo();
   else if (strcmp(word,"xhi") == 0) compute_xhi();
   else if (strcmp(word,"ylo") == 0) compute_ylo();
   else if (strcmp(word,"yhi") == 0) compute_yhi();
   else if (strcmp(word,"zlo") == 0) compute_zlo();
   else if (strcmp(word,"zhi") == 0) compute_zhi();
 
   else if (strcmp(word,"xy") == 0) compute_xy();
   else if (strcmp(word,"xz") == 0) compute_xz();
   else if (strcmp(word,"yz") == 0) compute_yz();
 
   else if (strcmp(word,"xlat") == 0) {
     if (domain->lattice == NULL) 
       error->all("Thermo keyword in variable requires lattice be defined");
     compute_xlat();
   } else if (strcmp(word,"ylat") == 0) {
     if (domain->lattice == NULL) 
       error->all("Thermo keyword in variable requires lattice be defined");
     compute_ylat(); 
   } else if (strcmp(word,"zlat") == 0) {
     if (domain->lattice == NULL) 
       error->all("Thermo keyword in variable requires lattice be defined");
     compute_zlat();
 
   } else if (strcmp(word,"pxx") == 0) {
     if (!pressure)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init press");
     if (update->whichflag == 0) {
       if (pressure->invoked_vector != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) {
       pressure->compute_vector();
       pressure->invoked_flag |= INVOKED_VECTOR;
     }
     compute_pxx();
 
   } else if (strcmp(word,"pyy") == 0) {
     if (!pressure)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init press");
     if (update->whichflag == 0) {
       if (pressure->invoked_vector != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) {
       pressure->compute_vector();
       pressure->invoked_flag |= INVOKED_VECTOR;
     }
     compute_pyy();
 
   } else if (strcmp(word,"pzz") == 0) {
     if (!pressure)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init press");
     if (update->whichflag == 0) {
       if (pressure->invoked_vector != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) {
       pressure->compute_vector();
       pressure->invoked_flag |= INVOKED_VECTOR;
     }
     compute_pzz();
 
   } else if (strcmp(word,"pxy") == 0) {
     if (!pressure)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init press");
     if (update->whichflag == 0) {
       if (pressure->invoked_vector != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) {
       pressure->compute_vector();
       pressure->invoked_flag |= INVOKED_VECTOR;
     }
     compute_pxy();
 
   } else if (strcmp(word,"pxz") == 0) {
     if (!pressure)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init press");
     if (update->whichflag == 0) {
       if (pressure->invoked_vector != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) {
       pressure->compute_vector();
       pressure->invoked_flag |= INVOKED_VECTOR;
     }
     compute_pxz();
 
   } else if (strcmp(word,"pyz") == 0) {
     if (!pressure)
       error->all("Thermo keyword in variable requires "
 		 "thermo to use/init press");
     if (update->whichflag == 0) {
       if (pressure->invoked_vector != update->ntimestep)
 	error->all("Compute used in variable thermo keyword between runs "
 		   "is not current");
     } else if (!(pressure->invoked_flag & INVOKED_VECTOR)) {
       pressure->compute_vector();
       pressure->invoked_flag |= INVOKED_VECTOR;
     }
     compute_pyz();
 
   } else if (strcmp(word,"fmax") == 0) compute_fmax();
   else if (strcmp(word,"fnorm") == 0) compute_fnorm();
 
   else return 1;
 
   *answer = dvalue;
   return 0;
 }
 
 /* ----------------------------------------------------------------------
    extraction of Compute, Fix, Variable results
    compute/fix are normalized by atoms if returning extensive value
    variable value is not normalized (formula should normalize if desired)
 ------------------------------------------------------------------------- */
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_compute()
 {
   int m = field2index[ifield];
   Compute *compute = computes[m];
 
   if (compute_which[m] == SCALAR) {
     dvalue = compute->scalar;
     if (normflag && compute->extscalar) dvalue /= natoms;
   } else if (compute_which[m] == VECTOR) {
     dvalue = compute->vector[argindex1[ifield]-1];
     if (normflag) {
       if (compute->extvector == 0) return;
       else if (compute->extvector == 1) dvalue /= natoms;
       else if (compute->extlist[argindex1[ifield]-1]) dvalue /= natoms;
     }
   } else {
     dvalue = compute->array[argindex1[ifield]-1][argindex2[ifield]-1];
     if (normflag && compute->extarray) dvalue /= natoms;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_fix()
 {
   int m = field2index[ifield];
   Fix *fix = fixes[m];
 
   if (argindex1[ifield] == 0) {
     dvalue = fix->compute_scalar();
     if (normflag && fix->extscalar) dvalue /= natoms;
   } else if (argindex2[ifield] == 0) {
     dvalue = fix->compute_vector(argindex1[ifield]-1);
     if (normflag) {
       if (fix->extvector == 0) return;
       else if (fix->extvector == 1) dvalue /= natoms;
       else if (fix->extlist[argindex1[ifield]-1]) dvalue /= natoms;
     }
   } else {
     dvalue = fix->compute_array(argindex1[ifield]-1,argindex2[ifield]-1);
     if (normflag && fix->extarray) dvalue /= natoms;
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_variable()
 {
   dvalue = input->variable->compute_equal(variables[field2index[ifield]]);
 }
 
 /* ----------------------------------------------------------------------
    one method for every keyword thermo can output
    called by compute() or evaluate_keyword()
    compute will have already been called
-   set ivalue/dvalue if value is integer/double
+   set ivalue/dvalue/bivalue if value is int/double/bigint
    customize a new keyword by adding a method
 ------------------------------------------------------------------------- */
 
 void Thermo::compute_step()
 {
-  ivalue = update->ntimestep;
+  bivalue = update->ntimestep;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_elapsed()
 {
-  ivalue = update->ntimestep - update->firststep;
+  bivalue = update->ntimestep - update->firststep;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_elapsed_long()
 {
-  ivalue = update->ntimestep - update->beginstep;
+  bivalue = update->ntimestep - update->beginstep;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_dt()
 {
   dvalue = update->dt;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_cpu()
 {
   if (firststep == 0) dvalue = 0.0;
   else dvalue = timer->elapsed(TIME_LOOP);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_tpcpu()
 {
   double new_cpu;
   double new_time = update->ntimestep * update->dt;
 
   if (firststep == 0) {
     new_cpu = 0.0;
     dvalue = 0.0;
   } else {
     new_cpu = timer->elapsed(TIME_LOOP);
     double cpu_diff = new_cpu - last_tpcpu;
     double time_diff = new_time - last_time;
     if (time_diff > 0.0 && cpu_diff > 0.0) dvalue = time_diff/cpu_diff;
     else dvalue = 0.0;
   }
 
   last_time = new_time;
   last_tpcpu = new_cpu;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_spcpu()
 {
   double new_cpu;
   int new_step = update->ntimestep;
 
   if (firststep == 0) {
     new_cpu = 0.0;
     dvalue = 0.0;
   } else {
     new_cpu = timer->elapsed(TIME_LOOP);
     double cpu_diff = new_cpu - last_spcpu;
     int step_diff = new_step - last_step;
     if (cpu_diff > 0.0) dvalue = step_diff/cpu_diff;
     else dvalue = 0.0;
   }
 
   last_step = new_step;
   last_spcpu = new_cpu;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_atoms()
 {
   bivalue = natoms;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_temp()
 {
   dvalue = temperature->scalar;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_press()
 {
   dvalue = pressure->scalar;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_pe()
 {
   dvalue = pe->scalar;
   if (normflag) dvalue /= natoms;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_ke()
 {
   dvalue = temperature->scalar;
   dvalue *= 0.5 * temperature->dof * force->boltz;
   if (normflag) dvalue /= natoms;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_etotal()
 {
   compute_pe();
   double ke = temperature->scalar;
   ke *= 0.5 * temperature->dof * force->boltz;
   if (normflag) ke /= natoms;
   dvalue += ke;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_enthalpy()
 {
   compute_etotal();
   double etmp = dvalue;
 
   compute_vol();
   double vtmp = dvalue;
   if (normflag) vtmp /= natoms;
 
   compute_press();
   double ptmp = dvalue;
 
   dvalue = etmp + ptmp*vtmp/(force->nktv2p);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_evdwl()
 {
   double tmp = 0.0;
   if (force->pair) tmp += force->pair->eng_vdwl;
   MPI_Allreduce(&tmp,&dvalue,1,MPI_DOUBLE,MPI_SUM,world);
 
   if (force->pair && force->pair->tail_flag) {
     double volume = domain->xprd * domain->yprd * domain->zprd;
     dvalue += force->pair->etail / volume;
   }
 
   if (normflag) dvalue /= natoms;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_ecoul()
 {
   double tmp = 0.0;
   if (force->pair) tmp += force->pair->eng_coul;
   MPI_Allreduce(&tmp,&dvalue,1,MPI_DOUBLE,MPI_SUM,world);
   if (normflag) dvalue /= natoms;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_epair()
 {
   double tmp = 0.0;
   if (force->pair) tmp += force->pair->eng_vdwl + force->pair->eng_coul;
   MPI_Allreduce(&tmp,&dvalue,1,MPI_DOUBLE,MPI_SUM,world);
 
   if (force->kspace) dvalue += force->kspace->energy;
   if (force->pair && force->pair->tail_flag) {
     double volume = domain->xprd * domain->yprd * domain->zprd;
     dvalue += force->pair->etail / volume;
   }
 
   if (normflag) dvalue /= natoms;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_ebond()
 {
   if (force->bond) {
     double tmp = force->bond->energy;
     MPI_Allreduce(&tmp,&dvalue,1,MPI_DOUBLE,MPI_SUM,world);
     if (normflag) dvalue /= natoms;
   } else dvalue = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_eangle()
 {
   if (force->angle) {
     double tmp = force->angle->energy;
     MPI_Allreduce(&tmp,&dvalue,1,MPI_DOUBLE,MPI_SUM,world);
     if (normflag) dvalue /= natoms;
   } else dvalue = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_edihed()
 {
   if (force->dihedral) {
     double tmp = force->dihedral->energy;
     MPI_Allreduce(&tmp,&dvalue,1,MPI_DOUBLE,MPI_SUM,world);
     if (normflag) dvalue /= natoms;
   } else dvalue = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_eimp()
 {
   if (force->improper) {
     double tmp = force->improper->energy;
     MPI_Allreduce(&tmp,&dvalue,1,MPI_DOUBLE,MPI_SUM,world);
     if (normflag) dvalue /= natoms;
   } else dvalue = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_emol()
 {
   double tmp = 0.0;
   if (atom->molecular) {
     if (force->bond) tmp += force->bond->energy;
     if (force->angle) tmp += force->angle->energy;
     if (force->dihedral) tmp += force->dihedral->energy;
     if (force->improper) tmp += force->improper->energy;
     MPI_Allreduce(&tmp,&dvalue,1,MPI_DOUBLE,MPI_SUM,world);
     if (normflag) dvalue /= natoms;
   } else dvalue = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_elong()
 {
   if (force->kspace) {
     dvalue = force->kspace->energy;
     if (normflag) dvalue /= natoms;
   } else dvalue = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_etail()
 {
   if (force->pair && force->pair->tail_flag) {
     double volume = domain->xprd * domain->yprd * domain->zprd;
     dvalue = force->pair->etail / volume;
     if (normflag) dvalue /= natoms;
   } else dvalue = 0.0;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_vol()
 {
   if (domain->dimension == 3)
     dvalue = domain->xprd * domain->yprd * domain->zprd;
   else
     dvalue = domain->xprd * domain->yprd;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_lx()
 {
   dvalue = domain->xprd;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_ly()
 {
   dvalue = domain->yprd;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_lz()
 {
   dvalue = domain->zprd;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_xlo()
 {
   dvalue = domain->boxlo[0];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_xhi()
 {
   dvalue = domain->boxhi[0];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_ylo()
 {
   dvalue = domain->boxlo[1];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_yhi()
 {
   dvalue = domain->boxhi[1];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_zlo()
 {
   dvalue = domain->boxlo[2];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_zhi()
 {
   dvalue = domain->boxhi[2];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_xy()
 {
   dvalue = domain->xy;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_xz()
 {
   dvalue = domain->xz;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_yz()
 {
   dvalue = domain->yz;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_xlat()
 {
   dvalue = domain->lattice->xlattice;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_ylat()
 {
   dvalue = domain->lattice->ylattice;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_zlat()
 {
   dvalue = domain->lattice->zlattice;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_pxx()
 {
   dvalue = pressure->vector[0];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_pyy()
 {
   dvalue = pressure->vector[1];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_pzz()
 {
   dvalue = pressure->vector[2];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_pxy()
 {
   dvalue = pressure->vector[3];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_pxz()
 {
   dvalue = pressure->vector[4];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_pyz()
 {
   dvalue = pressure->vector[5];
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_fmax()
 {
   double **f = atom->f;
   int nlocal = atom->nlocal;
 
   double max = 0.0;
   for (int i = 0; i < nlocal; i++) {
     max = MAX(max,fabs(f[i][0]));
     max = MAX(max,fabs(f[i][1]));
     max = MAX(max,fabs(f[i][2]));
   }
   double maxall;
   MPI_Allreduce(&max,&maxall,1,MPI_DOUBLE,MPI_MAX,world);
   dvalue = maxall;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Thermo::compute_fnorm()
 {
   double **f = atom->f;
   int nlocal = atom->nlocal;
 
   double dot = 0.0;
   for (int i = 0; i < nlocal; i++)
     dot += f[i][0]*f[i][0] + f[i][1]*f[i][1] + f[i][2]*f[i][2];
   double dotall;
   MPI_Allreduce(&dot,&dotall,1,MPI_DOUBLE,MPI_SUM,world);
   dvalue = sqrt(dotall);
 }
diff --git a/src/thermo.h b/src/thermo.h
index 526fcfa89..8b954ebb8 100644
--- a/src/thermo.h
+++ b/src/thermo.h
@@ -1,179 +1,179 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_THERMO_H
 #define LMP_THERMO_H
 
 #include "pointers.h"
 #include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class Thermo : protected Pointers {
   friend class WriteRestart;           // accesses lostflag
   friend class MinCG;                  // accesses compute_pe
 
  public:
   char *style;
   int normflag;          // 0 if do not normalize by atoms, 1 if normalize
   int modified;          // 1 if thermo_modify has been used, else 0
 
   Thermo(class LAMMPS *, int, char **);
   ~Thermo();
   void init();
   bigint lost_check();
   void modify_params(int, char **);
   void header();
   void compute(int);
   int evaluate_keyword(char *, double *);
 
  private:
   int me;
 
   char *line;
   int nfield,nfield_initial;
   char **keyword;
   int *vtype;
 
   char **format,**format_user;
-  char *format_multi;
   char *format_float_one_def,*format_float_multi_def;
   char *format_int_one_def,*format_int_multi_def;
-  char *format_bigint_one_def,*format_bigint_multi_def;
   char *format_float_user,*format_int_user,*format_bigint_user;
+  char format_multi[128];
+  char format_bigint_one_def[8],format_bigint_multi_def[8];
 
   int normvalue;         // use this for normflag unless natoms = 0
   int normuserflag;      // 0 if user has not set, 1 if has
   int normuser;
 
   int firststep;
   int lostflag,lostbefore;
   int flushflag,lineflag;
 
   double last_tpcpu,last_spcpu;
   double last_time;
-  int last_step;
+  bigint last_step;
 
   bigint natoms;
 
                          // data used by routines that compute single values
   int ivalue;            // integer value to print
-  double dvalue;         // dvalue = double value to print
+  double dvalue;         // double value to print
   bigint bivalue;        // big integer value to print
   int ifield;            // which field in thermo output is being computed
   int *field2index;      // which compute,fix,variable calcs this field
   int *argindex1;        // indices into compute,fix scalar,vector
   int *argindex2;
                          // data for keyword-specific Compute objects
                          // index = where they are in computes list
                          // id = ID of Compute objects
                          // Compute * = ptrs to the Compute objects
   int index_temp,index_press_scalar,index_press_vector,index_pe;
   char *id_temp,*id_press,*id_pe;
   class Compute *temperature,*pressure,*pe;
 
   int ncompute;                // # of Compute objects called by thermo
   char **id_compute;           // their IDs
   int *compute_which;          // 0/1 if should call scalar() or vector()
   class Compute **computes;    // list of ptrs to the Compute objects
 
   int nfix;                    // # of Fix objects called by thermo
   char **id_fix;               // their IDs
   class Fix **fixes;           // list of ptrs to the Fix objects
 
   int nvariable;               // # of variables evaulated by thermo
   char **id_variable;          // list of variable names
   int *variables;              // list of Variable indices
 
   // private methods
 
   void allocate();
   void deallocate();
 
   void parse_fields(char *);
   int add_compute(const char *, int);
   int add_fix(const char *);
   int add_variable(const char *);
 
   typedef void (Thermo::*FnPtr)();
   void addfield(const char *, FnPtr, int);
   FnPtr *vfunc;                // list of ptrs to functions
 
   void compute_compute();      // functions that compute a single value
   void compute_fix();          // via calls to  Compute,Fix,Variable classes
   void compute_variable();
 
   // functions that compute a single value
   // customize a new keyword by adding a method prototype
 
   void compute_step();
   void compute_elapsed();
   void compute_elapsed_long();
   void compute_dt();
   void compute_cpu();
   void compute_tpcpu();
   void compute_spcpu();
 
   void compute_atoms();
   void compute_temp();
   void compute_press();
   void compute_pe();
   void compute_ke();
   void compute_etotal();
   void compute_enthalpy();
 
   void compute_evdwl();
   void compute_ecoul();
   void compute_epair();
   void compute_ebond();
   void compute_eangle();
   void compute_edihed();
   void compute_eimp();
   void compute_emol();
   void compute_elong();
   void compute_etail();
 
   void compute_vol();
   void compute_lx();
   void compute_ly();
   void compute_lz();
 
   void compute_xlo();
   void compute_xhi();
   void compute_ylo();
   void compute_yhi();
   void compute_zlo();
   void compute_zhi();
 
   void compute_xy();
   void compute_xz();
   void compute_yz();
 
   void compute_xlat();
   void compute_ylat();
   void compute_zlat();
 
   void compute_pxx();
   void compute_pyy();
   void compute_pzz();
   void compute_pxy();
   void compute_pyz();
   void compute_pxz();
 
   void compute_fmax();
   void compute_fnorm();
 };
 
 }
 
 #endif
diff --git a/src/update.cpp b/src/update.cpp
index 82b9cf886..a5a79bdb4 100644
--- a/src/update.cpp
+++ b/src/update.cpp
@@ -1,295 +1,296 @@
 /* ----------------------------------------------------------------------
    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 "string.h"
 #include "stdlib.h"
 #include "update.h"
 #include "style_integrate.h"
 #include "style_minimize.h"
 #include "neighbor.h"
 #include "force.h"
 #include "modify.h"
 #include "fix.h"
 #include "domain.h"
 #include "region.h"
 #include "compute.h"
 #include "output.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 Update::Update(LAMMPS *lmp) : Pointers(lmp)
 {
   int n;
   char *str;
 
   ntimestep = 0;
   first_update = 0;
 
   whichflag = 0;
   firststep = laststep = 0;
   beginstep = endstep = 0;
   setupflag = 0;
   multireplica = 0;
 
   restrict_output = 0;
 
   eflag_global = vflag_global = -1;
 
   unit_style = NULL;
   set_units("lj");
 
   str = (char *) "verlet";
   n = strlen(str) + 1;
   integrate_style = new char[n];
   strcpy(integrate_style,str);
   integrate = new Verlet(lmp,0,NULL);
 
   str = (char *) "cg";
   n = strlen(str) + 1;
   minimize_style = new char[n];
   strcpy(minimize_style,str);
   minimize = new MinCG(lmp);
 }
 
 /* ---------------------------------------------------------------------- */
 
 Update::~Update()
 {
   delete [] unit_style;
 
   delete [] integrate_style;
   delete integrate;
 
   delete [] minimize_style;
   delete minimize;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Update::init()
 {
   // init the appropriate integrate and/or minimize class
   // if neither (e.g. from write_restart) then just return
 
   if (whichflag == 0) return;
   if (whichflag == 1) integrate->init();
   else if (whichflag == 2) minimize->init();
 
   // only set first_update if a run or minimize is being performed
 
   first_update = 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Update::set_units(const char *style)
 {
   // physical constants from:
   // http://physics.nist.gov/cuu/Constants/Table/allascii.txt
   // using thermochemical calorie = 4.184 J
   
   if (strcmp(style,"lj") == 0) {
     force->boltz = 1.0;
     force->mvv2e = 1.0;
     force->ftm2v = 1.0;
     force->mv2d = 1.0;
     force->nktv2p = 1.0;
     force->qqr2e = 1.0;
     force->qe2f = 1.0;
     force->vxmu2f = 1.0;
     force->xxt2kmu = 1.0;
     dt = 0.005;
     neighbor->skin = 0.3;
     
   } else if (strcmp(style,"real") == 0) {
     force->boltz = 0.0019872067;
     force->mvv2e = 48.88821291 * 48.88821291;
     force->ftm2v = 1.0 / 48.88821291 / 48.88821291;
     force->mv2d = 1.0 / 0.602214179;
     force->nktv2p = 68568.415;
     force->qqr2e = 332.06371;
     force->qe2f = 23.060549; 
     force->vxmu2f = 1.4393264316e4;
     force->xxt2kmu = 0.1;
     dt = 1.0;
     neighbor->skin = 2.0;
 
   } else if (strcmp(style,"metal") == 0) {
     force->boltz = 8.617343e-5;
     force->mvv2e = 1.0364269e-4;
     force->ftm2v = 1.0 / 1.0364269e-4;
     force->mv2d = 1.0 / 0.602214179;
     force->nktv2p = 1.6021765e6;
     force->qqr2e = 14.399645;
     force->qe2f = 1.0;
     force->vxmu2f = 0.6241509647;
     force->xxt2kmu = 1.0e-4;
     dt = 0.001;
     neighbor->skin = 2.0;
 
   } else if (strcmp(style,"si") == 0) {
     force->boltz = 1.3806504e-23;
     force->mvv2e = 1.0;
     force->ftm2v = 1.0;
     force->mv2d = 1.0;
     force->nktv2p = 1.0;
     force->qqr2e = 8.9876e9;
     force->qe2f = 1.0;
     force->vxmu2f = 1.0;
     force->xxt2kmu = 1.0;
     dt = 1.0e-8;
     neighbor->skin = 0.001;
 
   } else if (strcmp(style,"cgs") == 0) {
     force->boltz = 1.3806504e-16;
     force->mvv2e = 1.0;
     force->ftm2v = 1.0;
     force->mv2d = 1.0;
     force->nktv2p = 1.0;
     force->qqr2e = 1.0;
     force->qe2f = 1.0;
     force->vxmu2f = 1.0;
     force->xxt2kmu = 1.0;
     dt = 1.0e-8;
     neighbor->skin = 0.1;
 
   } else if (strcmp(style,"electron") == 0) {
     force->boltz = 3.16679e-6;
     force->mvv2e = 1.0;
     force->ftm2v = 1 / 1.0327499;	
     force->mv2d = 1.0;
     force->nktv2p = 2.9421e13;
     force->qqr2e = 1.0;
     force->qe2f = 1.0;
     force->vxmu2f = 0.6241509647;
     force->xxt2kmu = 1.0e-4;
     dt = 0.001;
     neighbor->skin = 2.0;
 
   } else error->all("Illegal units command");
 
   delete [] unit_style;
   int n = strlen(style) + 1;
   unit_style = new char[n];
   strcpy(unit_style,style);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Update::create_integrate(int narg, char **arg)
 {
   if (narg < 1) error->all("Illegal run_style command");
 
   delete [] integrate_style;
   delete integrate;
 
   if (0) return;      // dummy line to enable else-if macro expansion
 
 #define INTEGRATE_CLASS
 #define IntegrateStyle(key,Class) \
   else if (strcmp(arg[0],#key) == 0) integrate = new Class(lmp,narg-1,&arg[1]);
 #include "style_integrate.h"
 #undef INTEGRATE_CLASS
 
   else error->all("Illegal run_style command");
 
   int n = strlen(arg[0]) + 1;
   integrate_style = new char[n];
   strcpy(integrate_style,arg[0]);
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Update::create_minimize(int narg, char **arg)
 {
   if (narg != 1) error->all("Illegal min_style command");
 
   delete [] minimize_style;
   delete minimize;
 
   if (0) return;      // dummy line to enable else-if macro expansion
 
 #define MINIMIZE_CLASS
 #define MinimizeStyle(key,Class) \
   else if (strcmp(arg[0],#key) == 0) minimize = new Class(lmp);
 #include "style_minimize.h"
 #undef MINIMIZE_CLASS
 
   else error->all("Illegal min_style command");
 
   int n = strlen(arg[0]) + 1;
   minimize_style = new char[n];
   strcpy(minimize_style,arg[0]);
 }
 
 /* ----------------------------------------------------------------------
    reset timestep from input script
    do not allow dump files or a restart to be defined
    do not allow any timestep-dependent fixes to be defined
    do not allow any dynamic regions to be defined
    reset eflag/vflag global so nothing will think eng/virial are current
    reset invoked flags of computes,
      so nothing will think they are current between runs
    clear timestep list of computes that store future invocation times
 ------------------------------------------------------------------------- */
 
 void Update::reset_timestep(int narg, char **arg)
 {
   if (narg != 1) error->all("Illegal reset_timestep command");
 
   for (int i = 0; i < output->ndump; i++)
     if (output->last_dump[i] >= 0)
       error->all("Cannot reset timestep with dump file already written to");
   if (output->restart && output->last_restart >= 0)
     error->all("Cannot reset timestep with restart file already written");
 
   for (int i = 0; i < modify->nfix; i++)
     if (modify->fix[i]->time_depend)
       error->all("Cannot reset timestep with a time-dependent fix defined");
 
   for (int i = 0; i < domain->nregion; i++)
     if (domain->regions[i]->dynamic_check())
       error->all("Cannot reset timestep with a dynamic region defined");
 
   eflag_global = vflag_global = -1;
 
   for (int i = 0; i < modify->ncompute; i++) {
     modify->compute[i]->invoked_scalar = -1;
     modify->compute[i]->invoked_vector = -1;
     modify->compute[i]->invoked_array = -1;
     modify->compute[i]->invoked_peratom = -1;
     modify->compute[i]->invoked_local = -1;
   }
 
   for (int i = 0; i < modify->ncompute; i++)
     if (modify->compute[i]->timeflag) modify->compute[i]->clearstep();
 
-  ntimestep = atoi(arg[0]);
+  ntimestep = ATOBIGINT(arg[0]);
   if (ntimestep < 0) error->all("Timestep must be >= 0");
+  if (ntimestep > MAXBIGINT) error->all("Too big a timestep");
 }
 
 /* ----------------------------------------------------------------------
    memory usage of update and integrate/minimize
 ------------------------------------------------------------------------- */
 
 double Update::memory_usage()
 {
   double bytes = 0.0;
   if (whichflag == 1) bytes += integrate->memory_usage();
   else if (whichflag == 2) bytes += minimize->memory_usage();
   return bytes;
 }
diff --git a/src/update.h b/src/update.h
index 43b7eb0ea..75edc7e2f 100644
--- a/src/update.h
+++ b/src/update.h
@@ -1,59 +1,60 @@
 /* ----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
    certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
 ------------------------------------------------------------------------- */
 
 #ifndef LMP_UPDATE_H
 #define LMP_UPDATE_H
 
 #include "pointers.h"
+#include "lmptype.h"
 
 namespace LAMMPS_NS {
 
 class Update : protected Pointers {
  public:
   double dt;                      // timestep
   double etol,ftol;               // minimizer tolerances on energy/force
-  int ntimestep;                  // current step (dynamics or min iterations)
+  bigint ntimestep;               // current step (dynamics or min iterations)
   int nsteps;                     // # of steps to run (dynamics or min iter)
   int whichflag;                  // 0 for unset, 1 for dynamics, 2 for min
-  int firststep,laststep;         // 1st & last step of this run
-  int beginstep,endstep;          // 1st and last step of multiple runs
+  bigint firststep,laststep;      // 1st & last step of this run
+  bigint beginstep,endstep;       // 1st and last step of multiple runs
   int first_update;               // 0 before initial update, 1 after
   int max_eval;                   // max force evaluations for minimizer
   int restrict_output;            // 1 if output should not write dump/restart
   int setupflag;                  // set when setup() is computing forces
   int multireplica;               // 1 if min across replicas, else 0
 
-  int eflag_global,eflag_atom;    // timestep global/peratom eng is tallied on
-  int vflag_global,vflag_atom;    // ditto for virial
+  bigint eflag_global,eflag_atom;  // timestep global/peratom eng is tallied on
+  bigint vflag_global,vflag_atom;  // ditto for virial
 
   char *unit_style;
 
   class Integrate *integrate;
   char *integrate_style;
 
   class Min *minimize;
   char *minimize_style;
 
   Update(class LAMMPS *);
   ~Update();
   void init();
   void set_units(const char *);
   void create_integrate(int, char **);
   void create_minimize(int, char **);
   void reset_timestep(int, char **);
   double memory_usage();
 };
 
 }
 
 #endif
diff --git a/src/velocity.cpp b/src/velocity.cpp
index 0a9e944b0..4cadf22de 100644
--- a/src/velocity.cpp
+++ b/src/velocity.cpp
@@ -1,674 +1,674 @@
 /* ----------------------------------------------------------------------
    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 "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "string.h"
 #include "velocity.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "update.h"
 #include "domain.h"
 #include "lattice.h"
 #include "force.h"
 #include "modify.h"
 #include "compute.h"
 #include "compute_temp.h"
 #include "random_park.h"
 #include "group.h"
 #include "comm.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 enum{CREATE,SET,SCALE,RAMP,ZERO};
 enum{ALL,LOCAL,GEOM};
 
 #define WARMUP 100
 #define SMALL  0.001
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 /* ---------------------------------------------------------------------- */
 
 Velocity::Velocity(LAMMPS *lmp) : Pointers(lmp) {}
 
 /* ---------------------------------------------------------------------- */
 
 void Velocity::command(int narg, char **arg)
 {
   if (narg < 2) error->all("Illegal velocity command");
 
   if (domain->box_exist == 0) 
     error->all("Velocity command before simulation box is defined");
   if (atom->natoms == 0)
     error->all("Velocity command with no atoms existing");
 
   // atom masses must all be set
 
   atom->check_mass();
 
   // identify group
 
   igroup = group->find(arg[0]);
   if (igroup == -1) error->all("Could not find velocity group ID");
   groupbit = group->bitmask[igroup];
 
   // identify style
 
   if (strcmp(arg[1],"create") == 0) style = CREATE;
   else if (strcmp(arg[1],"set") == 0) style = SET;
   else if (strcmp(arg[1],"scale") == 0) style = SCALE;
   else if (strcmp(arg[1],"ramp") == 0) style = RAMP;
   else if (strcmp(arg[1],"zero") == 0) style = ZERO;
   else error->all("Illegal velocity command");
 
   // set defaults
 
   temperature = NULL;
   dist_flag = 0;
   sum_flag = 0;
   momentum_flag = 1;
   rotation_flag = 0;
   loop_flag = ALL;
   scale_flag = 1;
 
   // read options from end of input line
   // change defaults as options specify
 
   if (style == CREATE) options(narg-4,&arg[4]);
   else if (style == SET) options(narg-5,&arg[5]);
   else if (style == SCALE) options(narg-3,&arg[3]);
   else if (style == RAMP) options(narg-8,&arg[8]);
   else if (style == ZERO) options(narg-3,&arg[3]);
 
   // set scaling for SET and RAMP styles
 
   if (style == SET || style == RAMP) {
     if (scale_flag && domain->lattice == NULL)
       error->all("Use of velocity with undefined lattice");
 
     if (scale_flag) {
       xscale = domain->lattice->xlattice;
       yscale = domain->lattice->ylattice;
       zscale = domain->lattice->zlattice;
     }
     else xscale = yscale = zscale = 1.0;
   }
 
   // initialize velocities based on style
   // create() invoked differently, so can be called externally
 
   if (style == CREATE) {
     double t_desired = atof(arg[2]);
     int seed = atoi(arg[3]);
     create(t_desired,seed);
   }
   else if (style == SET) set(narg-2,&arg[2]);
   else if (style == SCALE) scale(narg-2,&arg[2]);
   else if (style == RAMP) ramp(narg-2,&arg[2]);
   else if (style == ZERO) zero(narg-2,&arg[2]);
 }
 
 /* ----------------------------------------------------------------------
    initialization of defaults before calling velocity methods externaly
 ------------------------------------------------------------------------- */
 
 void Velocity::init_external(char *extgroup)
 {
   igroup = group->find(extgroup);
   if (igroup == -1) error->all("Could not find velocity group ID");
   groupbit = group->bitmask[igroup];
 
   temperature = NULL;
   dist_flag = 0;
   sum_flag = 0;
   momentum_flag = 1;
   rotation_flag = 0;
   loop_flag = ALL;
   scale_flag = 1;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Velocity::create(double t_desired, int seed)
 {
   int i;
 
   if (seed <= 0) error->all("Illegal velocity create command");
 
   // if temperature = NULL, create a new ComputeTemp with the velocity group
 
   int tflag = 0;
   if (temperature == NULL) {
     char **arg = new char*[3];
     arg[0] = (char *) "velocity_temp";
     arg[1] = group->names[igroup];
     arg[2] = (char *) "temp";
     temperature = new ComputeTemp(lmp,3,arg);
     tflag = 1;
     delete [] arg;
   }
 
   // initialize temperature computation
   // warn if groups don't match
 
   if (igroup != temperature->igroup && comm->me == 0)
     error->warning("Mismatch between velocity and compute groups");
   temperature->init();
 
   // store a copy of current velocities
 
   double **v = atom->v;
   int nlocal = atom->nlocal;
   double **vhold = memory->create_2d_double_array(nlocal,3,"velocity:vnew");
 
   for (i = 0; i < nlocal; i++) {
     vhold[i][0] = v[i][0];
     vhold[i][1] = v[i][1];
     vhold[i][2] = v[i][2];
   }
 
   // create new velocities, in uniform or gaussian distribution
   // loop option determines looping style, ALL is default
   //   ALL = loop over all natoms, only set those I own via atom->map
   //    cannot do this if atom IDs do not span 1-Natoms (some were deleted)
   //    will produce same V, independent of P, if atoms were read-in
   //    will NOT produce same V, independent of P, if used create_atoms
   //   LOCAL = only loop over my atoms, adjust RNG to be proc-specific
   //    will never produce same V, independent of P
   //   GEOM = only loop over my atoms
   //    choose RNG for each atom based on its xyz coord (geometry)
   //      via random->reset()
   //    will always produce same V, independent of P
   // adjust by factor for atom mass
   // for 2d, set Vz to 0.0
 
   double *rmass = atom->rmass;
   double *mass = atom->mass;
   int *type = atom->type;
   int *mask = atom->mask;
   int dimension = domain->dimension;
 
   int m;
   double vx,vy,vz,factor;
   RanPark *random;
   
   if (loop_flag == ALL) {
 
     // create an atom map if one doesn't exist already
 
     int mapflag = 0;
     if (atom->map_style == 0) {
       mapflag = 1;
       atom->map_style = 1;
       atom->nghost = 0;
       atom->map_init();
       atom->map_set();
     }
 
     // error check
 
-    if (atom->natoms > MAXINT32)
+    if (atom->natoms > MAXSMALLINT)
       error->all("Too big a problem to use velocity create loop all");
     if (atom->tag_enable == 0)
       error->all("Cannot use velocity create loop all unless atoms have IDs");
     if (atom->tag_consecutive() == 0)
       error->all("Atom IDs must be consecutive for velocity create loop all");
 
     // loop over all atoms in system
     // generate RNGs for all atoms, only assign to ones I own
     // use either per-type mass or per-atom rmass
 
     random = new RanPark(lmp,seed);
     int natoms = static_cast<int> (atom->natoms);
 
     for (i = 1; i <= natoms; i++) {
       if (dist_flag == 0) {
 	vx = random->uniform();
 	vy = random->uniform();
 	vz = random->uniform();
       } else {
 	vx = random->gaussian();
 	vy = random->gaussian();
 	vz = random->gaussian();
       }
       m = atom->map(i);
       if (m >= 0 && m < nlocal) {
 	if (mask[m] & groupbit) {
 	  if (rmass) factor = 1.0/sqrt(rmass[m]);
 	  else factor = 1.0/sqrt(mass[type[m]]);
 	  v[m][0] = vx * factor;
 	  v[m][1] = vy * factor;
 	  if (dimension == 3) v[m][2] = vz * factor;
 	  else v[m][2] = 0.0;
 	}
       }
     }
 
     // delete temporary atom map
 
     if (mapflag) {
       atom->map_delete();
       atom->map_style = 0;
     }
 
   } else if (loop_flag == LOCAL) {
     random = new RanPark(lmp,seed + comm->me);
     for (i = 0; i < WARMUP; i++) random->uniform();
 
     for (i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
 	if (dist_flag == 0) {
 	  vx = random->uniform();
 	  vy = random->uniform();
 	  vz = random->uniform();
 	} else {
 	  vx = random->gaussian();
 	  vy = random->gaussian();
 	  vz = random->gaussian();
 	}
 	if (rmass) factor = 1.0/sqrt(rmass[i]);
 	else factor = 1.0/sqrt(mass[type[i]]);
 	v[i][0] = vx * factor;
 	v[i][1] = vy * factor;
 	if (dimension == 3) v[i][2] = vz * factor;
 	else v[i][2] = 0.0;
       }
     }
 
   } else if (loop_flag == GEOM) {
     random = new RanPark(lmp,1);
     double **x = atom->x;
     
     for (i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
 	random->reset(seed,x[i]);
 	if (dist_flag == 0) {
 	  vx = random->uniform();
 	  vy = random->uniform();
 	  vz = random->uniform();
 	} else {
 	  vx = random->gaussian();
 	  vy = random->gaussian();
 	  vz = random->gaussian();
 	}
 
 	if (rmass) factor = 1.0/sqrt(rmass[i]);
 	else factor = 1.0/sqrt(mass[type[i]]);
 	v[i][0] = vx * factor;
 	v[i][1] = vy * factor;
 	if (dimension == 3) v[i][2] = vz * factor;
 	else v[i][2] = 0.0;
       }
     }
   }
 
   // apply momentum and rotation zeroing
 
   if (momentum_flag) zero_momentum();
   if (rotation_flag) zero_rotation();
 
   // scale temp to desired value
 
   double t = temperature->compute_scalar();
   rescale(t,t_desired);
 
   // if sum_flag set, add back in previous velocities 
 
   if (sum_flag) {
     for (i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
 	v[i][0] += vhold[i][0];
 	v[i][1] += vhold[i][1];
 	v[i][2] += vhold[i][2];
       }
     }
   }
 
   // free local memory
   // if temperature was created, delete it
 
   memory->destroy_2d_double_array(vhold);
   delete random;
   if (tflag) delete temperature;
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Velocity::set(int narg, char **arg)
 {
   int xflag,yflag,zflag;
   double vx,vy,vz;
 
   if (strcmp(arg[0],"NULL") == 0) xflag = 0;
   else {
     xflag = 1;
     vx = xscale * atof(arg[0]);
   }
   if (strcmp(arg[1],"NULL") == 0) yflag = 0;
   else {
     yflag = 1;
     vy = yscale * atof(arg[1]);
   }
   if (strcmp(arg[2],"NULL") == 0) zflag = 0;
   else {
     zflag = 1;
     vz = zscale * atof(arg[2]);
   }
 
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   int dimension = domain->dimension;
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
       if (sum_flag == 0) {
 	if (xflag) v[i][0] = vx;
 	if (yflag) v[i][1] = vy;
 	if (zflag && dimension == 3) v[i][2] = vz;
       } else {
 	if (xflag) v[i][0] += vx;
 	if (yflag) v[i][1] += vy;
 	if (zflag && dimension == 3) v[i][2] += vz;
       }
     }
   }
 }
 
 /* ----------------------------------------------------------------------
    rescale velocities of a group after computing its temperature 
 ------------------------------------------------------------------------- */
 
 void Velocity::scale(int narg, char **arg)
 {
   double t_desired = atof(arg[0]);
 
   // if temperature = NULL, create a new ComputeTemp with the velocity group
 
   int tflag = 0;
   if (temperature == NULL) {
     char **arg = new char*[3];
     arg[0] = (char *) "velocity_temp";
     arg[1] = group->names[igroup];
     arg[2] = (char *) "temp";
     temperature = new ComputeTemp(lmp,3,arg);
     tflag = 1;
     delete [] arg;
   }
 
   // initialize temperature computation
   // warn if groups don't match
 
   if (igroup != temperature->igroup && comm->me == 0)
     error->warning("Mismatch between velocity and compute groups");
   temperature->init();
 
   // scale temp to desired value
 
   double t = temperature->compute_scalar();
   rescale(t,t_desired);
 
   // if temperature was created, delete it
 
   if (tflag) delete temperature;
 }
 
 /* ----------------------------------------------------------------------
    apply a ramped set of velocities 
 ------------------------------------------------------------------------- */
 
 void Velocity::ramp(int narg, char **arg)
 {
   int v_dim;
   if (strcmp(arg[0],"vx") == 0) v_dim = 0;
   else if (strcmp(arg[0],"vy") == 0) v_dim = 1;
   else if (strcmp(arg[0],"vz") == 0) v_dim = 2;
   else error->all("Illegal velocity command");
 
   if (v_dim == 2 && domain->dimension == 2) 
     error->all("Velocity ramp in z for a 2d problem");
 
   double v_lo,v_hi;
   if (v_dim == 0) {
     v_lo = xscale*atof(arg[1]);
     v_hi = xscale*atof(arg[2]);
   } else if (v_dim == 1) {
     v_lo = yscale*atof(arg[1]);
     v_hi = yscale*atof(arg[2]);
   } else if (v_dim == 2) {
     v_lo = zscale*atof(arg[1]);
     v_hi = zscale*atof(arg[2]);
   }
 
   int coord_dim;
   if (strcmp(arg[3],"x") == 0) coord_dim = 0;
   else if (strcmp(arg[3],"y") == 0) coord_dim = 1;
   else if (strcmp(arg[3],"z") == 0) coord_dim = 2;
   else error->all("Illegal velocity command");
 
   double coord_lo,coord_hi;
   if (coord_dim == 0) {
     coord_lo = xscale*atof(arg[4]);
     coord_hi = xscale*atof(arg[5]);
   } else if (coord_dim == 1) {
     coord_lo = yscale*atof(arg[4]);
     coord_hi = yscale*atof(arg[5]);
   } else if (coord_dim == 2) {
     coord_lo = zscale*atof(arg[4]);
     coord_hi = zscale*atof(arg[5]);
   }
 
   // vramp = ramped velocity component for v_dim
   // add or set based on sum_flag
   
   double **x = atom->x;
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   double fraction,vramp;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       fraction = (x[i][coord_dim] - coord_lo) / (coord_hi - coord_lo);
       fraction = MAX(fraction,0.0);
       fraction = MIN(fraction,1.0);
       vramp = v_lo + fraction*(v_hi - v_lo);
       if (sum_flag) v[i][v_dim] += vramp;
       else v[i][v_dim] = vramp;
     }
 }
 
 /* ----------------------------------------------------------------------
    zero linear or angular momentum of a group
 ------------------------------------------------------------------------- */
 
 void Velocity::zero(int narg, char **arg)
 {
   if (strcmp(arg[0],"linear") == 0) zero_momentum();
   else if (strcmp(arg[0],"angular") == 0) zero_rotation();
   else error->all("Illegal velocity command");
 }
 
 /* ----------------------------------------------------------------------
    rescale velocities of group atoms to t_new from t_old 
 ------------------------------------------------------------------------- */
 
 void Velocity::rescale(double t_old, double t_new)
 {
   if (t_old == 0.0) error->all("Attempting to rescale a 0.0 temperature");
 
   double factor = sqrt(t_new/t_old);
 
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       v[i][0] *= factor;
       v[i][1] *= factor;
       v[i][2] *= factor;
     }
 }
 
 /* ----------------------------------------------------------------------
    zero the linear momentum of a group of atoms by adjusting v by -Vcm
 ------------------------------------------------------------------------- */
 
 void Velocity::zero_momentum()
 {
   // cannot have 0 atoms in group
 
   if (group->count(igroup) == 0)
     error->all("Cannot zero momentum of 0 atoms");
 
   // compute velocity of center-of-mass of group
 
   double masstotal = group->mass(igroup);
   double vcm[3];
   group->vcm(igroup,masstotal,vcm);
 
   // adjust velocities by vcm to zero linear momentum
 
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       v[i][0] -= vcm[0];
       v[i][1] -= vcm[1];
       v[i][2] -= vcm[2];
     }
 }
 
 /* ----------------------------------------------------------------------
    zero the angular momentum of a group of atoms by adjusting v by -(w x r)
 ------------------------------------------------------------------------- */
 
 void Velocity::zero_rotation()
 {
   int i;
 
   // cannot have 0 atoms in group
 
   if (group->count(igroup) == 0)
     error->all("Cannot zero momentum of 0 atoms");
 
   // compute omega (angular velocity) of group around center-of-mass
 
   double xcm[3],angmom[3],inertia[3][3],omega[3];
   double masstotal = group->mass(igroup);
   group->xcm(igroup,masstotal,xcm);
   group->angmom(igroup,xcm,angmom);
   group->inertia(igroup,xcm,inertia);
   group->omega(angmom,inertia,omega);
 
   // adjust velocities to zero omega
   // vnew_i = v_i - w x r_i
   // must use unwrapped coords to compute r_i correctly
 
   double **x = atom->x;
   double **v = atom->v;
   int *mask = atom->mask;
   int *image = atom->image;
   int nlocal = atom->nlocal;
   
   int xbox,ybox,zbox;
   double dx,dy,dz;
   double xprd = domain->xprd;
   double yprd = domain->yprd;
   double zprd = domain->zprd;
   
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       xbox = (image[i] & 1023) - 512;
       ybox = (image[i] >> 10 & 1023) - 512;
       zbox = (image[i] >> 20) - 512;
       dx = (x[i][0] + xbox*xprd) - xcm[0];
       dy = (x[i][1] + ybox*yprd) - xcm[1];
       dz = (x[i][2] + zbox*zprd) - xcm[2];
       v[i][0] -= omega[1]*dz - omega[2]*dy;
       v[i][1] -= omega[2]*dx - omega[0]*dz;
       v[i][2] -= omega[0]*dy - omega[1]*dx;
     }
 }
 
 /* ----------------------------------------------------------------------
    parse optional parameters at end of velocity input line 
 ------------------------------------------------------------------------- */
 
 void Velocity::options(int narg, char **arg)
 {
   if (narg < 0) error->all("Illegal velocity command");
 
   int iarg = 0;
   while (iarg < narg) {
     if (strcmp(arg[iarg],"dist") == 0) {
       if (iarg+2 > narg) error->all("Illegal velocity command");
       if (strcmp(arg[iarg+1],"uniform") == 0) dist_flag = 0;
       else if (strcmp(arg[iarg+1],"gaussian") == 0) dist_flag = 1;
       else error->all("Illegal velocity command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"sum") == 0) {
       if (iarg+2 > narg) error->all("Illegal velocity command");
       if (strcmp(arg[iarg+1],"no") == 0) sum_flag = 0;
       else if (strcmp(arg[iarg+1],"yes") == 0) sum_flag = 1;
       else error->all("Illegal velocity command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"mom") == 0) {
       if (iarg+2 > narg) error->all("Illegal velocity command");
       if (strcmp(arg[iarg+1],"no") == 0) momentum_flag = 0;
       else if (strcmp(arg[iarg+1],"yes") == 0) momentum_flag = 1;
       else error->all("Illegal velocity command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"rot") == 0) {
       if (iarg+2 > narg) error->all("Illegal velocity command");
       if (strcmp(arg[iarg+1],"no") == 0) rotation_flag = 0;
       else if (strcmp(arg[iarg+1],"yes") == 0) rotation_flag = 1;
       else error->all("Illegal velocity command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"temp") == 0) {
       if (iarg+2 > narg) error->all("Illegal velocity command");
       int icompute;
       for (icompute = 0; icompute < modify->ncompute; icompute++)
 	if (strcmp(arg[iarg+1],modify->compute[icompute]->id) == 0) break;
       if (icompute == modify->ncompute) 
 	error->all("Could not find velocity temperature ID");
       temperature = modify->compute[icompute];
       if (temperature->tempflag == 0)
 	error->all("Velocity temperature ID does not compute temperature");
       iarg += 2;
     } else if (strcmp(arg[iarg],"loop") == 0) {
       if (iarg+2 > narg) error->all("Illegal velocity command");
       if (strcmp(arg[iarg+1],"all") == 0) loop_flag = ALL;
       else if (strcmp(arg[iarg+1],"local") == 0) loop_flag = LOCAL;
       else if (strcmp(arg[iarg+1],"geom") == 0) loop_flag = GEOM;
       else error->all("Illegal velocity command");
       iarg += 2;
     } else if (strcmp(arg[iarg],"units") == 0) {
       if (iarg+2 > narg) error->all("Illegal velocity command");
       if (strcmp(arg[iarg+1],"box") == 0) scale_flag = 0;
       else if (strcmp(arg[iarg+1],"lattice") == 0) scale_flag = 1;
       else error->all("Illegal velocity command");
       iarg += 2;
     } else error->all("Illegal velocity command");
   }
 }
diff --git a/src/verlet.cpp b/src/verlet.cpp
index c7a6180d6..0546e5557 100644
--- a/src/verlet.cpp
+++ b/src/verlet.cpp
@@ -1,389 +1,390 @@
 /* ----------------------------------------------------------------------
    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 "string.h"
 #include "verlet.h"
 #include "neighbor.h"
 #include "domain.h"
 #include "comm.h"
 #include "atom.h"
 #include "force.h"
 #include "pair.h"
 #include "bond.h"
 #include "angle.h"
 #include "dihedral.h"
 #include "improper.h"
 #include "kspace.h"
 #include "output.h"
 #include "update.h"
 #include "modify.h"
 #include "compute.h"
 #include "fix.h"
 #include "timer.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 /* ---------------------------------------------------------------------- */
 
 Verlet::Verlet(LAMMPS *lmp, int narg, char **arg) :
   Integrate(lmp, narg, arg) {}
 
 /* ----------------------------------------------------------------------
    initialization before run
 ------------------------------------------------------------------------- */
 
 void Verlet::init()
 {
   // warn if no fixes
 
   if (modify->nfix == 0 && comm->me == 0)
     error->warning("No fixes defined, atoms won't move");
 
   // virial_style:
   // 1 if computed explicitly by pair->compute via sum over pair interactions
   // 2 if computed implicitly by pair->virial_compute via sum over ghost atoms
 
   if (force->newton_pair) virial_style = 2;
   else virial_style = 1;
 
   // setup lists of computes for global and per-atom PE and pressure
 
   ev_setup();
 
   // set flags for what arrays to clear in force_clear()
   // need to clear torques,erforce if arrays exists
 
   torqueflag = 0;
   if (atom->torque_flag) torqueflag = 1;
   erforceflag = 0;
   if (atom->erforce_flag) erforceflag = 1;
 
   // orthogonal vs triclinic simulation box
 
   triclinic = domain->triclinic;
 }
 
 /* ----------------------------------------------------------------------
    setup before run
 ------------------------------------------------------------------------- */
 
 void Verlet::setup()
 {
   if (comm->me == 0 && screen) fprintf(screen,"Setting up run ...\n");
 
   update->setupflag = 1;
 
   // setup domain, communication and neighboring
   // acquire ghosts
   // build neighbor lists
 
   atom->setup();
   if (triclinic) domain->x2lamda(atom->nlocal);
   domain->pbc();
   domain->reset_box();
   comm->setup();
   if (neighbor->style) neighbor->setup_bins();
   comm->exchange();
   if (atom->sortfreq > 0) atom->sort();
   comm->borders();
   if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
   neighbor->build();
   neighbor->ncalls = 0;
 
   // compute all forces
 
   ev_set(update->ntimestep);
   force_clear();
   modify->setup_pre_force(vflag);
 
   if (force->pair) force->pair->compute(eflag,vflag);
 
   if (atom->molecular) {
     if (force->bond) force->bond->compute(eflag,vflag);
     if (force->angle) force->angle->compute(eflag,vflag);
     if (force->dihedral) force->dihedral->compute(eflag,vflag);
     if (force->improper) force->improper->compute(eflag,vflag);
   }
 
   if (force->kspace) {
     force->kspace->setup();
     force->kspace->compute(eflag,vflag);
   }
 
   if (force->newton) comm->reverse_comm();
 
   modify->setup(vflag);
   output->setup(1);
   update->setupflag = 0;
 }
 
 /* ----------------------------------------------------------------------
    setup without output
    flag = 0 = just force calculation
    flag = 1 = reneighbor and force calculation
 ------------------------------------------------------------------------- */
 
 void Verlet::setup_minimal(int flag)
 {
   update->setupflag = 1;
 
   // setup domain, communication and neighboring
   // acquire ghosts
   // build neighbor lists
 
   if (flag) {
     if (triclinic) domain->x2lamda(atom->nlocal);
     domain->pbc();
     domain->reset_box();
     comm->setup();
     if (neighbor->style) neighbor->setup_bins();
     comm->exchange();
     comm->borders();
     if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
     neighbor->build();
     neighbor->ncalls = 0;
   }
 
   // compute all forces
 
   ev_set(update->ntimestep);
   force_clear();
   modify->setup_pre_force(vflag);
 
   if (force->pair) force->pair->compute(eflag,vflag);
 
   if (atom->molecular) {
     if (force->bond) force->bond->compute(eflag,vflag);
     if (force->angle) force->angle->compute(eflag,vflag);
     if (force->dihedral) force->dihedral->compute(eflag,vflag);
     if (force->improper) force->improper->compute(eflag,vflag);
   }
 
   if (force->kspace) {
     force->kspace->setup();
     force->kspace->compute(eflag,vflag);
   }
 
   if (force->newton) comm->reverse_comm();
 
   modify->setup(vflag);
   update->setupflag = 0;
 }
 
 /* ----------------------------------------------------------------------
    run for N steps
 ------------------------------------------------------------------------- */
 
 void Verlet::run(int n)
 {
-  int nflag,ntimestep,sortflag;
+  bigint ntimestep;
+  int nflag,sortflag;
 
   int n_post_integrate = modify->n_post_integrate;
   int n_pre_exchange = modify->n_pre_exchange;
   int n_pre_neighbor = modify->n_pre_neighbor;
   int n_pre_force = modify->n_pre_force;
   int n_post_force = modify->n_post_force;
   int n_end_of_step = modify->n_end_of_step;
 
   if (atom->sortfreq > 0) sortflag = 1;
   else sortflag = 0;
 
   for (int i = 0; i < n; i++) {
 
     ntimestep = ++update->ntimestep;
     ev_set(ntimestep);
 
     // initial time integration
 
     modify->initial_integrate(vflag);
     if (n_post_integrate) modify->post_integrate();
 
     // regular communication vs neighbor list rebuild
 
     nflag = neighbor->decide();
 
     if (nflag == 0) {
       timer->stamp();
       comm->forward_comm();
       timer->stamp(TIME_COMM);
     } else {
       if (n_pre_exchange) modify->pre_exchange();
       if (triclinic) domain->x2lamda(atom->nlocal);
       domain->pbc();
       if (domain->box_change) {
 	domain->reset_box();
 	comm->setup();
 	if (neighbor->style) neighbor->setup_bins();
       }
       timer->stamp();
       comm->exchange();
       if (sortflag && ntimestep >= atom->nextsort) atom->sort();
       comm->borders();
       if (triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
       timer->stamp(TIME_COMM);
       if (n_pre_neighbor) modify->pre_neighbor();
       neighbor->build();
       timer->stamp(TIME_NEIGHBOR);
     }
 
     // force computations
 
     force_clear();
     if (n_pre_force) modify->pre_force(vflag);
 
     timer->stamp();
 
     if (force->pair) {
       force->pair->compute(eflag,vflag);
       timer->stamp(TIME_PAIR);
     }
 
     if (atom->molecular) {
       if (force->bond) force->bond->compute(eflag,vflag);
       if (force->angle) force->angle->compute(eflag,vflag);
       if (force->dihedral) force->dihedral->compute(eflag,vflag);
       if (force->improper) force->improper->compute(eflag,vflag);
       timer->stamp(TIME_BOND);
     }
 
     if (force->kspace) {
       force->kspace->compute(eflag,vflag);
       timer->stamp(TIME_KSPACE);
     }
 
     // reverse communication of forces
 
     if (force->newton) {
       comm->reverse_comm();
       timer->stamp(TIME_COMM);
     }
 
     // force modifications, final time integration, diagnostics
 
     if (n_post_force) modify->post_force(vflag);
     modify->final_integrate();
     if (n_end_of_step) modify->end_of_step();
 
     // all output
 
     if (ntimestep == output->next) {
       timer->stamp();
       output->write(ntimestep);
       timer->stamp(TIME_OUTPUT);
     }
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
 void Verlet::cleanup()
 {
   modify->post_run();
 }
 
 /* ----------------------------------------------------------------------
    clear force on own & ghost atoms
    setup and clear other arrays as needed
 ------------------------------------------------------------------------- */
 
 void Verlet::force_clear()
 {
   int i;
 
   // clear force on all particles
   // if either newton flag is set, also include ghosts
 
   if (neighbor->includegroup == 0) {
     int nall;
     if (force->newton) nall = atom->nlocal + atom->nghost;
     else nall = atom->nlocal;
 
     double **f = atom->f;
     for (i = 0; i < nall; i++) {
       f[i][0] = 0.0;
       f[i][1] = 0.0;
       f[i][2] = 0.0;
     }
     
     if (torqueflag) {
       double **torque = atom->torque;
       for (i = 0; i < nall; i++) {
 	torque[i][0] = 0.0;
 	torque[i][1] = 0.0;
 	torque[i][2] = 0.0;
       }
     }
 
     if (erforceflag) {
       double *erforce = atom->erforce;
       for (i = 0; i < nall; i++)
 	erforce[i] = 0.0;
     }
 
   // neighbor includegroup flag is set
   // clear force only on initial nfirst particles
   // if either newton flag is set, also include ghosts
 
   } else {
     int nall = atom->nfirst;
 
     double **f = atom->f;
     for (i = 0; i < nall; i++) {
       f[i][0] = 0.0;
       f[i][1] = 0.0;
       f[i][2] = 0.0;
     }
     
     if (torqueflag) {
       double **torque = atom->torque;
       for (i = 0; i < nall; i++) {
 	torque[i][0] = 0.0;
 	torque[i][1] = 0.0;
 	torque[i][2] = 0.0;
       }
     }
 
     if (erforceflag) {
       double *erforce = atom->erforce;
       for (i = 0; i < nall; i++)
 	erforce[i] = 0.0;
     }
 
     if (force->newton) {
       nall = atom->nlocal + atom->nghost;
 
       for (i = atom->nlocal; i < nall; i++) {
 	f[i][0] = 0.0;
 	f[i][1] = 0.0;
 	f[i][2] = 0.0;
       }
     
       if (torqueflag) {
 	double **torque = atom->torque;
 	for (i = atom->nlocal; i < nall; i++) {
 	  torque[i][0] = 0.0;
 	  torque[i][1] = 0.0;
 	  torque[i][2] = 0.0;
 	}
       }
 
       if (erforceflag) {
 	double *erforce = atom->erforce;
 	for (i = atom->nlocal; i < nall; i++)
 	  erforce[i] = 0.0;
       }
     }
   }
 }
diff --git a/src/version.h b/src/version.h
index 872b8d5aa..dbe555b16 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define LAMMPS_VERSION "9 Jan 2011"
+#define LAMMPS_VERSION "13 Jan 2011"
diff --git a/src/write_restart.cpp b/src/write_restart.cpp
index 25cba1c04..6fdb24998 100644
--- a/src/write_restart.cpp
+++ b/src/write_restart.cpp
@@ -1,498 +1,504 @@
 /* ----------------------------------------------------------------------
    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 "string.h"
 #include "write_restart.h"
 #include "lmptype.h"
 #include "atom.h"
 #include "atom_vec.h"
 #include "atom_vec_hybrid.h"
 #include "group.h"
 #include "force.h"
 #include "pair.h"
 #include "bond.h"
 #include "angle.h"
 #include "dihedral.h"
 #include "improper.h"
 #include "update.h"
 #include "domain.h"
 #include "modify.h"
 #include "universe.h"
 #include "comm.h"
 #include "output.h"
 #include "thermo.h"
 #include "memory.h"
 #include "error.h"
 
 using namespace LAMMPS_NS;
 
 #define MIN(A,B) ((A) < (B)) ? (A) : (B)
 #define MAX(A,B) ((A) > (B)) ? (A) : (B)
 
 // same as read_restart.cpp and tools/restart2data.cpp
 
-enum{VERSION,UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2,
+enum{VERSION,SMALLINT,TAGINT,BIGINT,
+       UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2,
        NEWTON_PAIR,NEWTON_BOND,XPERIODIC,YPERIODIC,ZPERIODIC,
        BOUNDARY_00,BOUNDARY_01,BOUNDARY_10,BOUNDARY_11,BOUNDARY_20,BOUNDARY_21,
        ATOM_STYLE,NATOMS,NTYPES,
        NBONDS,NBONDTYPES,BOND_PER_ATOM,
        NANGLES,NANGLETYPES,ANGLE_PER_ATOM,
        NDIHEDRALS,NDIHEDRALTYPES,DIHEDRAL_PER_ATOM,
        NIMPROPERS,NIMPROPERTYPES,IMPROPER_PER_ATOM,
        BOXLO_0,BOXHI_0,BOXLO_1,BOXHI_1,BOXLO_2,BOXHI_2,
        SPECIAL_LJ_1,SPECIAL_LJ_2,SPECIAL_LJ_3,
        SPECIAL_COUL_1,SPECIAL_COUL_2,SPECIAL_COUL_3,
        XY,XZ,YZ};
 enum{MASS,SHAPE,DIPOLE};
 enum{PAIR,BOND,ANGLE,DIHEDRAL,IMPROPER};
 
 enum{IGNORE,WARN,ERROR};                    // same as thermo.cpp
 
 /* ---------------------------------------------------------------------- */
 
 WriteRestart::WriteRestart(LAMMPS *lmp) : Pointers(lmp)
 {
   MPI_Comm_rank(world,&me);
   MPI_Comm_size(world,&nprocs);
 }
 
 /* ----------------------------------------------------------------------
    called as write_restart command in input script
 ------------------------------------------------------------------------- */
 
 void WriteRestart::command(int narg, char **arg)
 {
   if (domain->box_exist == 0)
     error->all("Write_restart command before simulation box is defined");
   if (narg != 1) error->all("Illegal write_restart command");
 
   // if filename contains a "*", replace with current timestep
 
   char *ptr;
   int n = strlen(arg[0]) + 16;
   char *file = new char[n];
 
   if (ptr = strchr(arg[0],'*')) {
     *ptr = '\0';
-    sprintf(file,"%s%d%s",arg[0],update->ntimestep,ptr+1);
+    char fstr[16];
+    sprintf(fstr,"%%s%s%%s",BIGINT_FORMAT);
+    sprintf(file,fstr,arg[0],update->ntimestep,ptr+1);
   } else strcpy(file,arg[0]);
 
   // init entire system since comm->exchange is done
   // comm::init needs neighbor::init needs pair::init needs kspace::init, etc
 
   if (comm->me == 0 && screen)
     fprintf(screen,"System init for write_restart ...\n");
   lmp->init();
 
   // move atoms to new processors before writing file
   // enforce PBC before in case atoms are outside box
   // call borders() to rebuild atom map since exchange() destroys map
 
   if (domain->triclinic) domain->x2lamda(atom->nlocal);
   domain->pbc();
   domain->reset_box();
   comm->setup();
   comm->exchange();
   comm->borders();
   if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
 
   write(file);
   delete [] file;
 }
 
 /* ----------------------------------------------------------------------
    called from command() and directly from output within run/minimize loop
    file = final file name to write, except may contain a "%"
 ------------------------------------------------------------------------- */
 
 void WriteRestart::write(char *file)
 {
   // natoms = sum of nlocal = value to write into restart file
   // if unequal and thermo lostflag is "error", don't write restart file
 
   bigint nblocal = atom->nlocal;
-  MPI_Allreduce(&nblocal,&natoms,1,MPI_UNSIGNED_LONG_LONG,MPI_SUM,world);
+  MPI_Allreduce(&nblocal,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
   if (natoms != atom->natoms && output->thermo->lostflag == ERROR) 
     error->all("Atom count is inconsistent, cannot write restart file");
 
   // check if filename contains "%"
 
   int multiproc;
   if (strchr(file,'%')) multiproc = 1;
   else multiproc = 0;
 
   // open single restart file or base file for multiproc case
 
   if (me == 0) {
     char *hfile;
     if (multiproc) {
       hfile = new char[strlen(file) + 16];
       char *ptr = strchr(file,'%');
       *ptr = '\0';
       sprintf(hfile,"%s%s%s",file,"base",ptr+1);
       *ptr = '%';
     } else hfile = file;
     fp = fopen(hfile,"wb");
     if (fp == NULL) {
       char str[128];
       sprintf(str,"Cannot open restart file %s",hfile);
       error->one(str);
     }
     if (multiproc) delete [] hfile;
   }
 
   // proc 0 writes header, groups, ntype-length arrays, force field
   // all procs write fix info
 
   if (me == 0) {
     header();
     group->write_restart(fp);
     type_arrays();
     force_fields();
   }
 
   modify->write_restart(fp);
 
   // communication buffer for all my atom's info
   // max_size = largest buffer needed by any proc
 
   int max_size;
   int send_size = atom->avec->size_restart();
   MPI_Allreduce(&send_size,&max_size,1,MPI_INT,MPI_MAX,world);
 
   double *buf;
   if (me == 0) 
     buf = (double *) 
       memory->smalloc(max_size*sizeof(double),"write_restart:buf");
   else
     buf = (double *) 
       memory->smalloc(send_size*sizeof(double),"write_restart:buf");
 
   // pack my atom data into buf
 
   AtomVec *avec = atom->avec;
   int n = 0;
   for (int i = 0; i < atom->nlocal; i++) n += avec->pack_restart(i,&buf[n]);
 
   // if any fix requires it, remap each atom's coords via PBC
   // is because fix changes atom coords (excepting an integrate fix)
   // just remap in buffer, not actual atoms
 
   if (modify->restart_pbc_any) {
     int triclinic = domain->triclinic;
     double *lo,*hi,*period;
 
     if (triclinic == 0) {
       lo = domain->boxlo;
       hi = domain->boxhi;
       period = domain->prd;
     } else {
       lo = domain->boxlo_lamda;
       hi = domain->boxhi_lamda;
       period = domain->prd_lamda;
     }
 
     int xperiodic = domain->xperiodic;
     int yperiodic = domain->yperiodic;
     int zperiodic = domain->zperiodic;
 
     double *x;
     int m = 0;
     for (int i = 0; i < atom->nlocal; i++) {
       x = &buf[m+1];
       if (triclinic) domain->x2lamda(x,x);
 
       if (xperiodic) {
 	if (x[0] < lo[0]) x[0] += period[0];
 	if (x[0] >= hi[0]) x[0] -= period[0];
 	x[0] = MAX(x[0],lo[0]);
       }
       if (yperiodic) {
 	if (x[1] < lo[1]) x[1] += period[1];
 	if (x[1] >= hi[1]) x[1] -= period[1];
 	x[1] = MAX(x[1],lo[1]);
       }
       if (zperiodic) {
 	if (x[2] < lo[2]) x[2] += period[2];
 	if (x[2] >= hi[2]) x[2] -= period[2];
 	x[2] = MAX(x[2],lo[2]);
       }
 
       if (triclinic) domain->lamda2x(x,x);
       m += static_cast<int> (buf[m]);
     }
   }
 
   // if single file:
   //   write one chunk of atoms per proc to file
   //   proc 0 pings each proc, receives its chunk, writes to file
   //   all other procs wait for ping, send their chunk to proc 0
   // else if one file per proc:
   //   each proc opens its own file and writes its chunk directly
 
   if (multiproc == 0) {
     int tmp,recv_size;
     MPI_Status status;
     MPI_Request request;
 
     if (me == 0) {
       for (int iproc = 0; iproc < nprocs; iproc++) {
 	if (iproc) {
 	  MPI_Irecv(buf,max_size,MPI_DOUBLE,iproc,0,world,&request);
 	  MPI_Send(&tmp,0,MPI_INT,iproc,0,world);
 	  MPI_Wait(&request,&status);
 	  MPI_Get_count(&status,MPI_DOUBLE,&recv_size);
 	} else recv_size = send_size;
 	
 	fwrite(&recv_size,sizeof(int),1,fp);
 	fwrite(buf,sizeof(double),recv_size,fp);
       }
       fclose(fp);
 
     } else {
       MPI_Recv(&tmp,0,MPI_INT,0,0,world,&status);
       MPI_Rsend(buf,send_size,MPI_DOUBLE,0,0,world);
     }
 
   } else {
     if (me == 0) fclose(fp);
 
     char *perproc = new char[strlen(file) + 16];
     char *ptr = strchr(file,'%');
     *ptr = '\0';
     sprintf(perproc,"%s%d%s",file,me,ptr+1);
     *ptr = '%';
     fp = fopen(perproc,"wb");
     if (fp == NULL) {
       char str[128];
       sprintf(str,"Cannot open restart file %s",perproc);
       error->one(str);
     }
     delete [] perproc;
     fwrite(&send_size,sizeof(int),1,fp);
     fwrite(buf,sizeof(double),send_size,fp);
     fclose(fp);
   }
     
   memory->sfree(buf);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out problem description 
 ------------------------------------------------------------------------- */
 
 void WriteRestart::header()
 {
   write_char(VERSION,universe->version);
+  write_int(SMALLINT,sizeof(smallint));
+  write_int(TAGINT,sizeof(tagint));
+  write_int(BIGINT,sizeof(bigint));
   write_char(UNITS,update->unit_style);
-  write_int(NTIMESTEP,update->ntimestep);
+  write_bigint(NTIMESTEP,update->ntimestep);
   write_int(DIMENSION,domain->dimension);
   write_int(NPROCS,nprocs);
   write_int(PROCGRID_0,comm->procgrid[0]);
   write_int(PROCGRID_1,comm->procgrid[1]);
   write_int(PROCGRID_2,comm->procgrid[2]);
   write_int(NEWTON_PAIR,force->newton_pair);
   write_int(NEWTON_BOND,force->newton_bond);
   write_int(XPERIODIC,domain->xperiodic);
   write_int(YPERIODIC,domain->yperiodic);
   write_int(ZPERIODIC,domain->zperiodic);
   write_int(BOUNDARY_00,domain->boundary[0][0]);
   write_int(BOUNDARY_01,domain->boundary[0][1]);
   write_int(BOUNDARY_10,domain->boundary[1][0]);
   write_int(BOUNDARY_11,domain->boundary[1][1]);
   write_int(BOUNDARY_20,domain->boundary[2][0]);
   write_int(BOUNDARY_21,domain->boundary[2][1]);
 
   // atom_style must be written before atom class values
   // so read_restart can create class before reading class values
   // if style = hybrid, also write sub-class styles
 
   write_char(ATOM_STYLE,atom->atom_style);
 
   if (strcmp(atom->atom_style,"hybrid") == 0) {
     AtomVecHybrid *avec_hybrid = (AtomVecHybrid *) atom->avec;
     int nstyles = avec_hybrid->nstyles;
     char **keywords = avec_hybrid->keywords;
     fwrite(&nstyles,sizeof(int),1,fp);
     for (int i = 0; i < nstyles; i++) {
       int n = strlen(keywords[i]) + 1;
       fwrite(&n,sizeof(int),1,fp);
       fwrite(keywords[i],sizeof(char),n,fp);
     }
   }
 
   write_bigint(NATOMS,natoms);
   write_int(NTYPES,atom->ntypes);
   write_bigint(NBONDS,atom->nbonds);
   write_int(NBONDTYPES,atom->nbondtypes);
   write_int(BOND_PER_ATOM,atom->bond_per_atom);
   write_bigint(NANGLES,atom->nangles);
   write_int(NANGLETYPES,atom->nangletypes);
   write_int(ANGLE_PER_ATOM,atom->angle_per_atom);
   write_bigint(NDIHEDRALS,atom->ndihedrals);
   write_int(NDIHEDRALTYPES,atom->ndihedraltypes);
   write_int(DIHEDRAL_PER_ATOM,atom->dihedral_per_atom);
   write_bigint(NIMPROPERS,atom->nimpropers);
   write_int(NIMPROPERTYPES,atom->nimpropertypes);
   write_int(IMPROPER_PER_ATOM,atom->improper_per_atom);
 
   write_double(BOXLO_0,domain->boxlo[0]);
   write_double(BOXHI_0,domain->boxhi[0]);
   write_double(BOXLO_1,domain->boxlo[1]);
   write_double(BOXHI_1,domain->boxhi[1]);
   write_double(BOXLO_2,domain->boxlo[2]);
   write_double(BOXHI_2,domain->boxhi[2]);
 
   write_double(SPECIAL_LJ_1,force->special_lj[1]);
   write_double(SPECIAL_LJ_2,force->special_lj[2]);
   write_double(SPECIAL_LJ_3,force->special_lj[3]);
   write_double(SPECIAL_COUL_1,force->special_coul[1]);
   write_double(SPECIAL_COUL_2,force->special_coul[2]);
   write_double(SPECIAL_COUL_3,force->special_coul[3]);
 
   if (domain->triclinic) {
     write_double(XY,domain->xy);
     write_double(XZ,domain->xz);
     write_double(YZ,domain->yz);
   }
 
   // -1 flag signals end of header
 
   int flag = -1;
   fwrite(&flag,sizeof(int),1,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out any type-based arrays that are defined
 ------------------------------------------------------------------------- */
 
 void WriteRestart::type_arrays()
 {
   if (atom->mass) {
     int flag = MASS;
     fwrite(&flag,sizeof(int),1,fp);
     fwrite(&atom->mass[1],sizeof(double),atom->ntypes,fp);
   }
   if (atom->shape) {
     int flag = SHAPE;
     fwrite(&flag,sizeof(int),1,fp);
     fwrite(&atom->shape[1][0],sizeof(double),atom->ntypes*3,fp);
   }
   if (atom->dipole) {
     int flag = DIPOLE;
     fwrite(&flag,sizeof(int),1,fp);
     fwrite(&atom->dipole[1],sizeof(double),atom->ntypes,fp);
   }
 
   // -1 flag signals end of type arrays
 
   int flag = -1;
   fwrite(&flag,sizeof(int),1,fp);
 }
 
 /* ----------------------------------------------------------------------
    proc 0 writes out and force field styles and data that are defined
 ------------------------------------------------------------------------- */
 
 void WriteRestart::force_fields()
 {
   if (force->pair) {
     int flag = PAIR;
     fwrite(&flag,sizeof(int),1,fp);
     int n = strlen(force->pair_style) + 1;
     fwrite(&n,sizeof(int),1,fp);
     fwrite(force->pair_style,sizeof(char),n,fp);
     force->pair->write_restart(fp);
   }
   if (atom->avec->bonds_allow && force->bond) {
     int flag = BOND;
     fwrite(&flag,sizeof(int),1,fp);
     int n = strlen(force->bond_style) + 1;
     fwrite(&n,sizeof(int),1,fp);
     fwrite(force->bond_style,sizeof(char),n,fp);
     force->bond->write_restart(fp);
   }
   if (atom->avec->angles_allow && force->angle) {
     int flag = ANGLE;
     fwrite(&flag,sizeof(int),1,fp);
     int n = strlen(force->angle_style) + 1;
     fwrite(&n,sizeof(int),1,fp);
     fwrite(force->angle_style,sizeof(char),n,fp);
     force->angle->write_restart(fp);
   }
   if (atom->avec->dihedrals_allow && force->dihedral) {
     int flag = DIHEDRAL;
     fwrite(&flag,sizeof(int),1,fp);
     int n = strlen(force->dihedral_style) + 1;
     fwrite(&n,sizeof(int),1,fp);
     fwrite(force->dihedral_style,sizeof(char),n,fp);
     force->dihedral->write_restart(fp);
   }
   if (atom->avec->impropers_allow && force->improper) {
     int flag = IMPROPER;
     fwrite(&flag,sizeof(int),1,fp);
     int n = strlen(force->improper_style) + 1;
     fwrite(&n,sizeof(int),1,fp);
     fwrite(force->improper_style,sizeof(char),n,fp);
     force->improper->write_restart(fp);
   }
 
   // -1 flag signals end of force field info
 
   int flag = -1;
   fwrite(&flag,sizeof(int),1,fp);
 }
 
 /* ----------------------------------------------------------------------
    write a flag and an int into restart file 
 ------------------------------------------------------------------------- */
 
 void WriteRestart::write_int(int flag, int value)
 {
   fwrite(&flag,sizeof(int),1,fp);
   fwrite(&value,sizeof(int),1,fp);
 }
 
 /* ----------------------------------------------------------------------
    write a flag and a double into restart file 
 ------------------------------------------------------------------------- */
 
 void WriteRestart::write_double(int flag, double value)
 {
   fwrite(&flag,sizeof(int),1,fp);
   fwrite(&value,sizeof(double),1,fp);
 }
 
 /* ----------------------------------------------------------------------
    write a flag and a char str into restart file 
 ------------------------------------------------------------------------- */
 
 void WriteRestart::write_char(int flag, char *value)
 {
   fwrite(&flag,sizeof(int),1,fp);
   int n = strlen(value) + 1;
   fwrite(&n,sizeof(int),1,fp);
   fwrite(value,sizeof(char),n,fp);
 }
 
 /* ----------------------------------------------------------------------
    write a flag and a bigint into restart file 
 ------------------------------------------------------------------------- */
 
 void WriteRestart::write_bigint(int flag, bigint value)
 {
   fwrite(&flag,sizeof(int),1,fp);
   fwrite(&value,sizeof(bigint),1,fp);
 }
 
diff --git a/tools/binary2txt.cpp b/tools/binary2txt.cpp
index aaa0b6cfb..e76db3c9f 100644
--- a/tools/binary2txt.cpp
+++ b/tools/binary2txt.cpp
@@ -1,135 +1,148 @@
 /* -----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    www.cs.sandia.gov/~sjplimp/lammps.html
    Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
 
    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.
 ------------------------------------------------------------------------ */
 
 // Convert one or more LAMMPS binary dump files to ASCII text files
 //
 // this serial code must be compiled on a platform that can read the binary
 //   dump files since binary formats are not compatible across all platforms
 //
 // Syntax: binary2txt file1 file2 ...
 // Creates:           file1.txt file2.txt ...
 
 #include "stdio.h"
 #include "stdlib.h"
 #include "string.h"
 
+// this should match setting in src/lmptype.h
+
+typedef int64_t bigint;
+
 main(int narg, char **arg)
 {
   int i,j,k,m,n;
-  int ntimestep,natoms,size_one,nchunk,triclinic;
+  bigint ntimestep,natoms;
+  int size_one,nchunk,triclinic;
   double xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz;
   int maxbuf = 0;
   double *buf = NULL;
 
   if (narg == 1) {
     printf("Syntax: binary2txt file1 file2 ...\n");
     exit(1);
   }
 
   // loop over files
 
   for (int iarg = 1; iarg < narg; iarg++) {
     printf("%s:",arg[iarg]);
     fflush(stdout);
     FILE *fp = fopen(arg[iarg],"rb");
     if (!fp) {
       printf("ERROR: Could not open %s\n",arg[iarg]);
       exit(1);
     }
 
     n = strlen(arg[iarg]) + 1 + 4;
     char *filetxt = new char[n];
     strcpy(filetxt,arg[iarg]);
     strcat(filetxt,".txt");
     FILE *fptxt = fopen(filetxt,"w");
     delete [] filetxt;
 
     // loop over snapshots in file
 
     while (1) {
 
-      fread(&ntimestep,sizeof(int),1,fp);
+      fread(&ntimestep,sizeof(bigint),1,fp);
 
       // detect end-of-file
 
       if (feof(fp)) {
 	fclose(fp);
 	fclose(fptxt);
 	break;
       }
 
-      fread(&natoms,sizeof(int),1,fp);
+      fread(&natoms,sizeof(bigint),1,fp);
       fread(&triclinic,sizeof(int),1,fp);
       fread(&xlo,sizeof(double),1,fp);
       fread(&xhi,sizeof(double),1,fp);
       fread(&ylo,sizeof(double),1,fp);
       fread(&yhi,sizeof(double),1,fp);
       fread(&zlo,sizeof(double),1,fp);
       fread(&zhi,sizeof(double),1,fp);
       if (triclinic) {
 	fread(&xy,sizeof(double),1,fp);
 	fread(&xz,sizeof(double),1,fp);
 	fread(&yz,sizeof(double),1,fp);
       }
       fread(&size_one,sizeof(int),1,fp);
       fread(&nchunk,sizeof(int),1,fp);
       
-      fprintf(fptxt,"ITEM: TIMESTEP\n");
-      fprintf(fptxt,"%d\n",ntimestep);
-      fprintf(fptxt,"ITEM: NUMBER OF ATOMS\n");
-      fprintf(fptxt,"%d\n",natoms);
+      if (sizeof(bigint) == 8) {
+	fprintf(fptxt,"ITEM: TIMESTEP\n");
+	fprintf(fptxt,"%ld\n",ntimestep);
+	fprintf(fptxt,"ITEM: NUMBER OF ATOMS\n");
+	fprintf(fptxt,"%ld\n",natoms);
+      } else if (sizeof(bigint) == 4) {
+	fprintf(fptxt,"ITEM: TIMESTEP\n");
+	fprintf(fptxt,"%d\n",ntimestep);
+	fprintf(fptxt,"ITEM: NUMBER OF ATOMS\n");
+	fprintf(fptxt,"%d\n",natoms);
+      }
       if (!triclinic) {
 	fprintf(fptxt,"ITEM: BOX BOUNDS\n");
 	fprintf(fptxt,"%g %g\n",xlo,xhi);
 	fprintf(fptxt,"%g %g\n",ylo,yhi);
 	fprintf(fptxt,"%g %g\n",zlo,zhi);
       } else {
 	fprintf(fptxt,"ITEM: BOX BOUNDS xy xz yz\n");
 	fprintf(fptxt,"%g %g %g\n",xlo,xhi,xy);
 	fprintf(fptxt,"%g %g %g\n",ylo,yhi,xz);
 	fprintf(fptxt,"%g %g %g\n",zlo,zhi,yz);
       }
       fprintf(fptxt,"ITEM: ATOMS\n");
 
       // loop over processor chunks in file
 
       for (i = 0; i < nchunk; i++) {
 	fread(&n,sizeof(int),1,fp);
 
 	// extend buffer to fit chunk size
 	
 	if (n > maxbuf) {
 	  if (buf) delete [] buf;
 	  buf = new double[n];
 	  maxbuf = n;
 	}
 
 	// read chunk and write as size_one values per line
 
 	fread(buf,sizeof(double),n,fp);
 	n /= size_one;
 	m = 0;
 	for (j = 0; j < n; j++) {
 	  for (k = 0; k < size_one; k++) fprintf(fptxt,"%g ",buf[m++]);
 	  fprintf(fptxt,"\n");
 	}
       }
 
-      printf(" %d",ntimestep);
+      if (sizeof(bigint) == 8) printf(" %ld",ntimestep);
+      else if (sizeof(bigint) == 4) printf(" %d",ntimestep);
       fflush(stdout);
     }
     printf("\n");
   }
 
   if (buf) delete [] buf;
 }
diff --git a/tools/restart2data.cpp b/tools/restart2data.cpp
index 594e4b62e..53b2df532 100644
--- a/tools/restart2data.cpp
+++ b/tools/restart2data.cpp
@@ -1,3495 +1,3544 @@
 /* -----------------------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    www.cs.sandia.gov/~sjplimp/lammps.html
    Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
 
    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.
 ------------------------------------------------------------------------ */
 
 // Convert a LAMMPS binary restart file into an ASCII text data file
 //
 // Syntax: restart2data restart-file data-file (input-file)
 //         input-file is optional
 //         if specified it will contain LAMMPS input script commands
 //           for mass and force field info
 //         only a few force field styles support this option
 //
 // this serial code must be compiled on a platform that can read the binary
 //   restart file since binary formats are not compatible across all platforms
 // restart-file can have a '%' character to indicate a multiproc restart
 //   file as written by LAMMPS
 
 #include "math.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "string.h"
 #include "stdint.h"
 
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
 
 #define MAX_GROUP 32
 
+// these should match settings in src/lmptype.h
+
+typedef int tagint;
+typedef int64_t bigint;
+#define BIGINT_FORMAT "%lld"
+
 // same as write_restart.cpp
 
-enum{VERSION,UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2,
+enum{VERSION,SMALLINT,TAGINT,BIGINT,
+       UNITS,NTIMESTEP,DIMENSION,NPROCS,PROCGRID_0,PROCGRID_1,PROCGRID_2,
        NEWTON_PAIR,NEWTON_BOND,XPERIODIC,YPERIODIC,ZPERIODIC,
        BOUNDARY_00,BOUNDARY_01,BOUNDARY_10,BOUNDARY_11,BOUNDARY_20,BOUNDARY_21,
        ATOM_STYLE,NATOMS,NTYPES,
        NBONDS,NBONDTYPES,BOND_PER_ATOM,
        NANGLES,NANGLETYPES,ANGLE_PER_ATOM,
        NDIHEDRALS,NDIHEDRALTYPES,DIHEDRAL_PER_ATOM,
        NIMPROPERS,NIMPROPERTYPES,IMPROPER_PER_ATOM,
        BOXLO_0,BOXHI_0,BOXLO_1,BOXHI_1,BOXLO_2,BOXHI_2,
        SPECIAL_LJ_1,SPECIAL_LJ_2,SPECIAL_LJ_3,
        SPECIAL_COUL_1,SPECIAL_COUL_2,SPECIAL_COUL_3,
        XY,XZ,YZ};
 enum{MASS,SHAPE,DIPOLE};
 enum{PAIR,BOND,ANGLE,DIHEDRAL,IMPROPER};
 
 static const char * const cg_type_list[] =
   {"none", "lj9_6", "lj12_4", "lj12_6"};
 
 // ---------------------------------------------------------------------
 // Data class to hold problem
 // ---------------------------------------------------------------------
 
 class Data {
  public:
 
   // global settings
 
   char *version;
-  int ntimestep;
+  int size_smallint,size_tagint,size_bigint;
+  bigint ntimestep;
   int nprocs;
   char *unit_style;
   int dimension;
   int px,py,pz;
   int newton_pair,newton_bond;
   int xperiodic,yperiodic,zperiodic;
   int boundary[3][2];
 
   char *atom_style;
   int style_angle,style_atomic,style_bond,style_charge,style_dipole;
   int style_ellipsoid,style_full,style_granular;
   int style_hybrid,style_molecular,style_peri;
 
-  uint64_t natoms;
-  uint64_t nbonds,nangles,ndihedrals,nimpropers;
+  bigint natoms;
+  bigint nbonds,nangles,ndihedrals,nimpropers;
   int ntypes,nbondtypes,nangletypes,ndihedraltypes,nimpropertypes;
   int bond_per_atom,angle_per_atom,dihedral_per_atom,improper_per_atom;
   int triclinic;
 
   double xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz;
   double special_lj[4],special_coul[4];
 
   double cut_lj_global,cut_coul_global,kappa;
   int offset_flag,mix_flag;
 
   // force fields
 
   char *pair_style,*bond_style,*angle_style,*dihedral_style,*improper_style;
 
   double *pair_born_A,*pair_born_rho,*pair_born_sigma;
   double *pair_born_C,*pair_born_D;
   double *pair_buck_A,*pair_buck_rho,*pair_buck_C;
   double *pair_colloid_A12,*pair_colloid_sigma;
   double *pair_colloid_d1,*pair_colloid_d2;
   double *pair_dipole_epsilon,*pair_dipole_sigma;
   double *pair_dpd_a0,*pair_dpd_gamma;
   double *pair_charmm_epsilon,*pair_charmm_sigma;
   double *pair_charmm_eps14,*pair_charmm_sigma14;
   double *pair_class2_epsilon,*pair_class2_sigma;
   double *pair_gb_epsilon,*pair_gb_sigma;
   double *pair_gb_epsa,*pair_gb_epsb,*pair_gb_epsc;
   double *pair_lj_epsilon,*pair_lj_sigma;
   double **pair_cg_epsilon,**pair_cg_sigma;
   int **pair_cg_cmm_type, **pair_setflag;
   double **pair_cut_coul, **pair_cut_lj;
   double *pair_ljexpand_epsilon,*pair_ljexpand_sigma,*pair_ljexpand_shift;
   double *pair_ljgromacs_epsilon,*pair_ljgromacs_sigma;
   double *pair_ljsmooth_epsilon,*pair_ljsmooth_sigma;
   double *pair_morse_d0,*pair_morse_alpha,*pair_morse_r0;
   double *pair_soft_A;
   double *pair_yukawa_A;
 
   double *bond_class2_r0,*bond_class2_k2,*bond_class2_k3,*bond_class2_k4;
   double *bond_fene_k,*bond_fene_r0,*bond_fene_epsilon,*bond_fene_sigma;
   double *bond_feneexpand_k,*bond_feneexpand_r0;
   double *bond_feneexpand_epsilon,*bond_feneexpand_sigma;
   double *bond_feneexpand_shift;
   double *bond_harmonic_k,*bond_harmonic_r0;
   double *bond_morse_d0,*bond_morse_alpha,*bond_morse_r0;
   double *bond_nonlinear_epsilon,*bond_nonlinear_r0,*bond_nonlinear_lamda;
   double *bond_quartic_k,*bond_quartic_b1,*bond_quartic_b2;
   double *bond_quartic_rc,*bond_quartic_u0;
 
   double *angle_charmm_k,*angle_charmm_theta0;
   double *angle_charmm_k_ub,*angle_charmm_r_ub;
   double *angle_class2_theta0;
   double *angle_class2_k2,*angle_class2_k3,*angle_class2_k4;
   double *angle_class2_bb_k,*angle_class2_bb_r1,*angle_class2_bb_r2;
   double *angle_class2_ba_k1,*angle_class2_ba_k2;
   double *angle_class2_ba_r1,*angle_class2_ba_r2;
   double *angle_cosine_k;
   double *angle_cosine_squared_k,*angle_cosine_squared_theta0;
   double *angle_harmonic_k,*angle_harmonic_theta0;
   double *angle_cg_cmm_epsilon,*angle_cg_cmm_sigma;
   int *angle_cg_cmm_type;
 
   double *dihedral_charmm_k,*dihedral_charmm_weight;
   int *dihedral_charmm_multiplicity,*dihedral_charmm_sign;
   double *dihedral_class2_k1,*dihedral_class2_k2,*dihedral_class2_k3;
   double *dihedral_class2_phi1,*dihedral_class2_phi2,*dihedral_class2_phi3;
   double *dihedral_class2_mbt_f1,*dihedral_class2_mbt_f2;
   double *dihedral_class2_mbt_f3,*dihedral_class2_mbt_r0;
   double *dihedral_class2_ebt_f1_1,*dihedral_class2_ebt_f2_1;
   double *dihedral_class2_ebt_f3_1,*dihedral_class2_ebt_r0_1;
   double *dihedral_class2_ebt_f1_2,*dihedral_class2_ebt_f2_2;
   double *dihedral_class2_ebt_f3_2,*dihedral_class2_ebt_r0_2;
   double *dihedral_class2_at_f1_1,*dihedral_class2_at_f2_1;
   double *dihedral_class2_at_f3_1,*dihedral_class2_at_theta0_1;
   double *dihedral_class2_at_f1_2,*dihedral_class2_at_f2_2;
   double *dihedral_class2_at_f3_2,*dihedral_class2_at_theta0_2;
   double *dihedral_class2_aat_k;
   double *dihedral_class2_aat_theta0_1,*dihedral_class2_aat_theta0_2;
   double *dihedral_class2_bb13_k;
   double *dihedral_class2_bb13_r10,*dihedral_class2_bb13_r30;
   double *dihedral_harmonic_k;
   int *dihedral_harmonic_multiplicity,*dihedral_harmonic_sign;
   double *dihedral_helix_aphi,*dihedral_helix_bphi,*dihedral_helix_cphi;
   double *dihedral_multi_a1,*dihedral_multi_a2,*dihedral_multi_a3;
   double *dihedral_multi_a4,*dihedral_multi_a5;
   double *dihedral_opls_k1,*dihedral_opls_k2;
   double *dihedral_opls_k3,*dihedral_opls_k4;
 
   double *improper_class2_k0,*improper_class2_chi0;
   double *improper_class2_aa_k1,*improper_class2_aa_k2,*improper_class2_aa_k3;
   double *improper_class2_aa_theta0_1,*improper_class2_aa_theta0_2;
   double *improper_class2_aa_theta0_3;
   double *improper_cvff_k;
   int *improper_cvff_sign,*improper_cvff_multiplicity;
   double *improper_harmonic_k,*improper_harmonic_chi;
 
   // atom quantities
 
   int iatoms,ibonds,iangles,idihedrals,iimpropers;
 
   double *mass,*shape,*dipole;
   double *x,*y,*z,*vx,*vy,*vz;
   double *omegax,*omegay,*omegaz;
-  int *tag,*type,*mask,*image;
+  tagint *tag;
+  int *type,*mask,*image;
   int *molecule;
   double *q,*mux,*muy,*muz,*radius,*density,*vfrac,*rmass;
   double *s0,*x0x,*x0y,*x0z;
   double *quatw,*quati,*quatj,*quatk,*angmomx,*angmomy,*angmomz;
   int *bond_type,*angle_type,*dihedral_type,*improper_type;
   int *bond_atom1,*bond_atom2;
   int *angle_atom1,*angle_atom2,*angle_atom3;
   int *dihedral_atom1,*dihedral_atom2,*dihedral_atom3,*dihedral_atom4;
   int *improper_atom1,*improper_atom2,*improper_atom3,*improper_atom4;
 
   // functions
 
   Data();
   void stats();
   void write(FILE *fp, FILE *fp2=NULL);
 
   void write_atom_angle(FILE *, int, int, int, int);
   void write_atom_atomic(FILE *, int, int, int, int);
   void write_atom_bond(FILE *, int, int, int, int);
   void write_atom_charge(FILE *, int, int, int, int);
   void write_atom_dipole(FILE *, int, int, int, int);
   void write_atom_ellipsoid(FILE *, int, int, int, int);
   void write_atom_full(FILE *, int, int, int, int);
   void write_atom_granular(FILE *, int, int, int, int);
   void write_atom_molecular(FILE *, int, int, int, int);
   void write_atom_peri(FILE *, int, int, int, int);
 
   void write_atom_angle_extra(FILE *, int);
   void write_atom_atomic_extra(FILE *, int);
   void write_atom_bond_extra(FILE *, int);
   void write_atom_charge_extra(FILE *, int);
   void write_atom_dipole_extra(FILE *, int);
   void write_atom_ellipsoid_extra(FILE *, int);
   void write_atom_full_extra(FILE *, int);
   void write_atom_granular_extra(FILE *, int);
   void write_atom_molecular_extra(FILE *, int);
   void write_atom_peri_extra(FILE *, int);
 
   void write_vel_angle(FILE *, int);
   void write_vel_atomic(FILE *, int);
   void write_vel_bond(FILE *, int);
   void write_vel_charge(FILE *, int);
   void write_vel_dipole(FILE *, int);
   void write_vel_ellipsoid(FILE *, int);
   void write_vel_full(FILE *, int);
   void write_vel_granular(FILE *, int);
   void write_vel_molecular(FILE *, int);
   void write_vel_peri(FILE *, int);
 
   void write_vel_angle_extra(FILE *, int);
   void write_vel_atomic_extra(FILE *, int);
   void write_vel_bond_extra(FILE *, int);
   void write_vel_charge_extra(FILE *, int);
   void write_vel_dipole_extra(FILE *, int);
   void write_vel_ellipsoid_extra(FILE *, int);
   void write_vel_full_extra(FILE *, int);
   void write_vel_granular_extra(FILE *, int);
   void write_vel_molecular_extra(FILE *, int);
   void write_vel_peri_extra(FILE *, int);
 };
 
 // ---------------------------------------------------------------------
 // function prototypes
 // ---------------------------------------------------------------------
 
 void header(FILE *, Data &);
 void set_style(char *, Data &, int);
 void groups(FILE *);
 void type_arrays(FILE *, Data &);
 void force_fields(FILE *, Data &);
 void modify(FILE *);
 void pair(FILE *fp, Data &data, char *style, int flag);
 void bond(FILE *fp, Data &data);
 void angle(FILE *fp, Data &data);
 void dihedral(FILE *fp, Data &data);
 void improper(FILE *fp, Data &data);
 int atom(double *, Data &data);
 
 void allocate_angle(Data &data);
 void allocate_atomic(Data &data);
 void allocate_bond(Data &data);
 void allocate_charge(Data &data);
 void allocate_dipole(Data &data);
 void allocate_ellipsoid(Data &data);
 void allocate_full(Data &data);
 void allocate_granular(Data &data);
 void allocate_molecular(Data &data);
 void allocate_peri(Data &data);
 
 int atom_angle(double *, Data &, int);
 int atom_atomic(double *, Data &, int);
 int atom_bond(double *, Data &, int);
 int atom_charge(double *, Data &, int);
 int atom_dipole(double *, Data &, int);
 int atom_ellipsoid(double *, Data &, int);
 int atom_full(double *, Data &, int);
 int atom_granular(double *, Data &, int);
 int atom_molecular(double *, Data &, int);
 int atom_peri(double *, Data &, int);
 
 int read_int(FILE *fp);
 double read_double(FILE *fp);
 char *read_char(FILE *fp);
-uint64_t read_uint64(FILE *fp);
+bigint read_bigint(FILE *fp);
 
 // ---------------------------------------------------------------------
 // main program
 // ---------------------------------------------------------------------
 
 int main (int argc, char **argv)
 {
   // syntax error check
 
     if ((argc != 3) && (argc !=4)) {
     printf("Syntax: restart2data restart-file data-file (input-file)\n");
     return 1;
   }
 
   // if restart file contains '%', file = filename with % replaced by "base"
   // else file = single file
 
   int multiproc;
   char *file,*ptr;
 
   if (ptr = strchr(argv[1],'%')) {
     multiproc = 1;
     file = new char[strlen(argv[1]) + 16];
     *ptr = '\0';
     sprintf(file,"%s%s%s",argv[1],"base",ptr+1);
   } else {
     multiproc = 0;
     file = argv[1];
   }
 
   // open single restart file or base file for multiproc case
 
   printf("Reading restart file ...\n");
   FILE *fp = fopen(file,"rb");
   if (fp == NULL) {
     printf("ERROR: Cannot open restart file %s\n",file);
     return 1;
   }
 
   // read beginning of restart file
 
   Data data;
 
   header(fp,data);
+  if (data.size_smallint != sizeof(int) || 
+      data.size_tagint != sizeof(tagint) || 
+      data.size_bigint != sizeof(bigint)) {
+    printf("ERROR: Data type sizes in restart file "
+	   "are incompatible with restart2data.cpp\n");
+    return 1;
+  }
+
   groups(fp);
   type_arrays(fp,data);
   force_fields(fp,data);
   modify(fp);
 
   // read atoms from single or multiple restart files
 
   double *buf = NULL;
   int n,m;
   int maxbuf = 0;
   data.iatoms = data.ibonds = data.iangles =
     data.idihedrals = data.iimpropers = 0;
 
   for (int iproc = 0; iproc < data.nprocs; iproc++) {
     if (multiproc) {
       fclose(fp);
       sprintf(file,"%s%d%s",argv[1],iproc,ptr+1);
       fp = fopen(file,"rb");
       if (fp == NULL) {
         printf("ERROR: Cannot open restart file %s\n",file);
         return 1;
       }
     }
     n = read_int(fp);
 
     if (n > maxbuf) {
       maxbuf = n;
       delete [] buf;
       buf = new double[maxbuf];
     }
 
     fread(buf,sizeof(double),n,fp);
 
     m = 0;
     while (m < n) m += atom(&buf[m],data);
   }
 
   fclose(fp);
 
   // print out stats
 
   data.stats();
 
   // write out data file and no input file
 
   if (argc == 3) {
     printf("Writing data file ...\n");
     fp = fopen(argv[2],"w");
     if (fp == NULL) {
       printf("ERROR: Cannot open data file %s\n",argv[2]);
       return 1;
     }
     data.write(fp);
     fclose(fp);
 
   // write out data file and input file
 
   } else {
     printf("Writing data file ...\n");
     fp = fopen(argv[2],"w");
     if (fp == NULL) {
       printf("ERROR: Cannot open data file %s\n",argv[2]);
       return 1;
     }
     printf("Writing input file ...\n");
     FILE *fp2 = fopen(argv[3],"w");
     if (fp2 == NULL) {
       printf("ERROR: Cannot open input file %s\n",argv[3]);
       return 1;
     }
 
     data.write(fp,fp2);
     fclose(fp);
     fclose(fp2);
   }
 
   return 0;
 }
 
 // ---------------------------------------------------------------------
 // read header of restart file
 // ---------------------------------------------------------------------
 
 void header(FILE *fp, Data &data)
 {
   char *version = "6 Jan 2011";
 
   data.triclinic = 0;
 
   int flag;
   flag = read_int(fp);
 
   while (flag >= 0) {
 
     if (flag == VERSION) {
       data.version = read_char(fp);
       if (strcmp(version,data.version) != 0) {
 	char *str = "Restart file version does not match restart2data version";
 	printf("WARNING %s\n",str);
 	printf("  restart2data version = %s\n",version);
       }
     }
+    else if (flag == SMALLINT) data.size_smallint = read_int(fp);
+    else if (flag == TAGINT) data.size_tagint = read_int(fp);
+    else if (flag == BIGINT) data.size_bigint = read_int(fp);
     else if (flag == UNITS) data.unit_style = read_char(fp);
-    else if (flag == NTIMESTEP) data.ntimestep = read_int(fp);
+    else if (flag == NTIMESTEP) data.ntimestep = read_bigint(fp);
     else if (flag == DIMENSION) data.dimension = read_int(fp);
     else if (flag == NPROCS) data.nprocs = read_int(fp);
     else if (flag == PROCGRID_0) data.px = read_int(fp);
     else if (flag == PROCGRID_1) data.py = read_int(fp);
     else if (flag == PROCGRID_2) data.pz = read_int(fp);
     else if (flag == NEWTON_PAIR) data.newton_pair = read_int(fp);
     else if (flag == NEWTON_BOND) data.newton_bond = read_int(fp);
     else if (flag == XPERIODIC) data.xperiodic = read_int(fp);
     else if (flag == YPERIODIC) data.yperiodic = read_int(fp);
     else if (flag == ZPERIODIC) data.zperiodic = read_int(fp);
     else if (flag == BOUNDARY_00) data.boundary[0][0] = read_int(fp);
     else if (flag == BOUNDARY_01) data.boundary[0][1] = read_int(fp);
     else if (flag == BOUNDARY_10) data.boundary[1][0] = read_int(fp);
     else if (flag == BOUNDARY_11) data.boundary[1][1] = read_int(fp);
     else if (flag == BOUNDARY_20) data.boundary[2][0] = read_int(fp);
     else if (flag == BOUNDARY_21) data.boundary[2][1] = read_int(fp);
 
     // if atom_style = hybrid:
     //   set data_style_hybrid to # of sub-styles
     //   read additional sub-class arguments
     //   set sub-styles to 1 to N
 
     else if (flag == ATOM_STYLE) {
       data.style_angle = data.style_atomic = data.style_bond =
 	data.style_charge = data.style_dipole =	
 	data.style_ellipsoid = data.style_full = data.style_granular =
 	data.style_hybrid = data.style_molecular = data.style_peri = 0;
 
       data.atom_style = read_char(fp);
       set_style(data.atom_style,data,1);
 
       if (strcmp(data.atom_style,"hybrid") == 0) {
 	int nwords = read_int(fp);
 	set_style(data.atom_style,data,nwords);
 	char *substyle;
 	for (int i = 1; i <= nwords; i++) {
 	  substyle = read_char(fp);
 	  set_style(substyle,data,i);
 	}
       }
     }
 
-    else if (flag == NATOMS) data.natoms = read_uint64(fp);
+    else if (flag == NATOMS) data.natoms = read_bigint(fp);
     else if (flag == NTYPES) data.ntypes = read_int(fp);
-    else if (flag == NBONDS) data.nbonds = read_uint64(fp);
+    else if (flag == NBONDS) data.nbonds = read_bigint(fp);
     else if (flag == NBONDTYPES) data.nbondtypes = read_int(fp);
     else if (flag == BOND_PER_ATOM) data.bond_per_atom = read_int(fp);
-    else if (flag == NANGLES) data.nangles = read_uint64(fp);
+    else if (flag == NANGLES) data.nangles = read_bigint(fp);
     else if (flag == NANGLETYPES) data.nangletypes = read_int(fp);
     else if (flag == ANGLE_PER_ATOM) data.angle_per_atom = read_int(fp);
-    else if (flag == NDIHEDRALS) data.ndihedrals = read_uint64(fp);
+    else if (flag == NDIHEDRALS) data.ndihedrals = read_bigint(fp);
     else if (flag == NDIHEDRALTYPES) data.ndihedraltypes = read_int(fp);
     else if (flag == DIHEDRAL_PER_ATOM) data.dihedral_per_atom = read_int(fp);
-    else if (flag == NIMPROPERS) data.nimpropers = read_uint64(fp);
+    else if (flag == NIMPROPERS) data.nimpropers = read_bigint(fp);
     else if (flag == NIMPROPERTYPES) data.nimpropertypes = read_int(fp);
     else if (flag == IMPROPER_PER_ATOM) data.improper_per_atom = read_int(fp);
     else if (flag == BOXLO_0) data.xlo = read_double(fp);
     else if (flag == BOXHI_0) data.xhi = read_double(fp);
     else if (flag == BOXLO_1) data.ylo = read_double(fp);
     else if (flag == BOXHI_1) data.yhi = read_double(fp);
     else if (flag == BOXLO_2) data.zlo = read_double(fp);
     else if (flag == BOXHI_2) data.zhi = read_double(fp);
     else if (flag == SPECIAL_LJ_1) data.special_lj[1] = read_double(fp);
     else if (flag == SPECIAL_LJ_2) data.special_lj[2] = read_double(fp);
     else if (flag == SPECIAL_LJ_3) data.special_lj[3] = read_double(fp);
     else if (flag == SPECIAL_COUL_1) data.special_coul[1] = read_double(fp);
     else if (flag == SPECIAL_COUL_2) data.special_coul[2] = read_double(fp);
     else if (flag == SPECIAL_COUL_3) data.special_coul[3] = read_double(fp);
     else if (flag == XY) {
       data.triclinic = 1;
       data.xy = read_double(fp);
     } else if (flag == XZ) {
       data.triclinic = 1;
       data.xz = read_double(fp);
     } else if (flag == YZ) {
       data.triclinic = 1;
       data.yz = read_double(fp);
     } else {
       printf("ERROR: Invalid flag in header section of restart file %d\n",
 	     flag);
       exit(1);
     }
 
     flag = read_int(fp);
   }
 }
 
 // ---------------------------------------------------------------------
 // set atom style to flag
 // ---------------------------------------------------------------------
 
 void set_style(char *name, Data &data, int flag)
 {
   if (strcmp(name,"angle") == 0) data.style_angle = flag;
   else if (strcmp(name,"atomic") == 0) data.style_atomic = flag;
   else if (strcmp(name,"bond") == 0) data.style_bond = flag;
   else if (strcmp(name,"charge") == 0) data.style_charge = flag;
   else if (strcmp(name,"dipole") == 0) data.style_dipole = flag;
   else if (strcmp(name,"ellipsoid") == 0) data.style_ellipsoid = flag;
   else if (strcmp(name,"full") == 0) data.style_full = flag;
   else if (strcmp(name,"granular") == 0) data.style_granular = flag;
   else if (strcmp(name,"hybrid") == 0) data.style_hybrid = flag;
   else if (strcmp(name,"molecular") == 0) data.style_molecular = flag;
   else if (strcmp(name,"peri") == 0) data.style_peri = flag;
   else {
     printf("ERROR: Unknown atom style %s\n",name);
     exit(1);
   }
 }
 
 // ---------------------------------------------------------------------
 // read group info from restart file, just ignore it
 // ---------------------------------------------------------------------
 
 void groups(FILE *fp)
 {
   int ngroup = read_int(fp);
 
   int n;
   char *name;
 
   // use count to not change restart format with deleted groups
   // remove this on next major release
 
   int count = 0;
   for (int i = 0; i < MAX_GROUP; i++) {
     name = read_char(fp);
     delete [] name;
     count++;
     if (count == ngroup) break;
   }
 }
 
 // ---------------------------------------------------------------------
 // read type arrays from restart file
 // ---------------------------------------------------------------------
 
 void type_arrays(FILE *fp, Data &data)
 {
   data.mass = NULL;
   data.shape = NULL;
   data.dipole = NULL;
 
   int flag;
   flag = read_int(fp);
 
   while (flag >= 0) {
 
     if (flag == MASS) {
       data.mass = new double[data.ntypes+1];
       fread(&data.mass[1],sizeof(double),data.ntypes,fp);
     } else if (flag == SHAPE) {
       data.shape = new double[3*(data.ntypes+1)];
       fread(&data.shape[3],sizeof(double),3*data.ntypes,fp);
     } else if (flag == DIPOLE) {
       data.dipole = new double[data.ntypes+1];
       fread(&data.dipole[1],sizeof(double),data.ntypes,fp);
     } else {
       printf("ERROR: Invalid flag in type arrays section of restart file %d\n",
 	     flag);
       exit(1);
     }
 
     flag = read_int(fp);
   }
 }
 
 // ---------------------------------------------------------------------
 // read force-field info from restart file
 // ---------------------------------------------------------------------
 
 void force_fields(FILE *fp, Data &data)
 {
   data.pair_style = data.bond_style = data.angle_style =
     data.dihedral_style = data.improper_style = NULL;
 
   int flag;
   flag = read_int(fp);
 
   while (flag >= 0) {
 
     if (flag == PAIR) {
       data.pair_style = read_char(fp);
       pair(fp,data,data.pair_style,1);
     } else if (flag == BOND) {
       data.bond_style = read_char(fp);
       bond(fp,data);
     } else if (flag == ANGLE) {
       data.angle_style = read_char(fp);
       angle(fp,data);
     } else if (flag == DIHEDRAL) {
       data.dihedral_style = read_char(fp);
       dihedral(fp,data);
     } else if (flag == IMPROPER) {
       data.improper_style = read_char(fp);
       improper(fp,data);
     } else {
       printf("ERROR: Invalid flag in force fields section of restart file %d\n",
 	     flag);
       exit(1);
     }
 
     flag = read_int(fp);
   }
 }
 
 // ---------------------------------------------------------------------
 // read fix info from restart file, just ignore it
 // ---------------------------------------------------------------------
 
 void modify(FILE *fp)
 {
   char *buf;
   int n;
 
   // nfix = # of fix entries with state
 
   int nfix = read_int(fp);
 
   // read each entry with id string, style string, chunk of data
 
   for (int i = 0; i < nfix; i++) {
     buf = read_char(fp); delete [] buf;
     buf = read_char(fp); delete [] buf;
     buf = read_char(fp); delete [] buf;
   }
 
   // nfix = # of fix entries with peratom info
 
   int nfix_peratom = read_int(fp);
 
   // read each entry with id string, style string, maxsize of one atom data
 
   for (int i = 0; i < nfix_peratom; i++) {
     buf = read_char(fp); delete [] buf;
     buf = read_char(fp); delete [] buf;
     n = read_int(fp);
   }
 }
 
 // ---------------------------------------------------------------------
 // read atom info from restart file and store in data struct
 // ---------------------------------------------------------------------
 
 int atom(double *buf, Data &data)
 {
   // allocate per-atom arrays
 
   if (data.iatoms == 0) {
 
     // common to all atom styles
 
     data.x = new double[data.natoms];
     data.y = new double[data.natoms];
     data.z = new double[data.natoms];
     data.tag = new int[data.natoms];
     data.type = new int[data.natoms];
     data.mask = new int[data.natoms];
     data.image = new int[data.natoms];
     data.vx = new double[data.natoms];
     data.vy = new double[data.natoms];
     data.vz = new double[data.natoms];
 
     // style-specific arrays
     // don't worry about re-allocating if style = hybrid
 
     if (data.style_angle) allocate_angle(data);
     if (data.style_atomic) allocate_atomic(data);
     if (data.style_bond) allocate_bond(data);
     if (data.style_charge) allocate_charge(data);
     if (data.style_dipole) allocate_dipole(data);
     if (data.style_ellipsoid) allocate_ellipsoid(data);
     if (data.style_full) allocate_full(data);
     if (data.style_granular) allocate_granular(data);
     if (data.style_molecular) allocate_molecular(data);
     if (data.style_peri) allocate_peri(data);
   }
 
   // read atom quantities from buf
   // if hybrid, loop over all sub-styles in order listed
   // if hybrid, loop index k will match style setting to insure correct order
 
   int nloop = 1;
   if (data.style_hybrid) nloop = data.style_hybrid;
 
   int iatoms = data.iatoms;
   int m = 0;
   for (int k = 1; k <= nloop; k++) {
     if (k == data.style_angle) m += atom_angle(&buf[m],data,iatoms);
     if (k == data.style_atomic) m += atom_atomic(&buf[m],data,iatoms);
     if (k == data.style_bond) m += atom_bond(&buf[m],data,iatoms);
     if (k == data.style_charge) m += atom_charge(&buf[m],data,iatoms);
     if (k == data.style_dipole) m += atom_dipole(&buf[m],data,iatoms);
     if (k == data.style_ellipsoid) m += atom_ellipsoid(&buf[m],data,iatoms);
     if (k == data.style_full) m += atom_full(&buf[m],data,iatoms);
     if (k == data.style_granular) m += atom_granular(&buf[m],data,iatoms);
     if (k == data.style_molecular) m += atom_molecular(&buf[m],data,iatoms);
     if (k == data.style_peri) m += atom_peri(&buf[m],data,iatoms);
   }
 
   data.iatoms++;
   m = static_cast<int> (buf[0]);
   return m;
 }
 
 // ---------------------------------------------------------------------
 // read one atom's info from buffer
 // one routine per atom style
 // ---------------------------------------------------------------------
 
 int atom_angle(double *buf, Data &data, int iatoms)
 {
   int type,atom1,atom2,atom3;
 
   int m = 1;
   data.x[iatoms] = buf[m++];
   data.y[iatoms] = buf[m++];
   data.z[iatoms] = buf[m++];
   data.tag[iatoms] = static_cast<int> (buf[m++]);
   data.type[iatoms] = static_cast<int> (buf[m++]);
   data.mask[iatoms] = static_cast<int> (buf[m++]);
   data.image[iatoms] = static_cast<int> (buf[m++]);
   data.vx[iatoms] = buf[m++];
   data.vy[iatoms] = buf[m++];
   data.vz[iatoms] = buf[m++];
 
   data.molecule[iatoms] = static_cast<int> (buf[m++]);
 
   int n = static_cast<int> (buf[m++]);
   for (int k = 0; k < n; k++) {
     type = static_cast<int> (buf[m++]);
     atom1 = static_cast<int> (buf[m++]);
     if (data.newton_bond || data.tag[iatoms] < atom1) {
       data.bond_type[data.ibonds] = type;
       data.bond_atom1[data.ibonds] = data.tag[iatoms];
       data.bond_atom2[data.ibonds] = atom1;
       data.ibonds++;
     }
   }
 
   n = static_cast<int> (buf[m++]);
   for (int k = 0; k < n; k++) {
     type = static_cast<int> (buf[m++]);
     atom1 = static_cast<int> (buf[m++]);
     atom2 = static_cast<int> (buf[m++]);
     atom3 = static_cast<int> (buf[m++]);
     if (data.newton_bond || data.tag[iatoms] == atom2) {
       data.angle_type[data.iangles] = type;
       data.angle_atom1[data.iangles] = atom1;
       data.angle_atom2[data.iangles] = atom2;
       data.angle_atom3[data.iangles] = atom3;
 	  data.iangles++;
     }
   }
 
   return m;
 }
 
 int atom_atomic(double *buf, Data &data, int iatoms)
 {
   int m = 1;
   data.x[iatoms] = buf[m++];
   data.y[iatoms] = buf[m++];
   data.z[iatoms] = buf[m++];
   data.tag[iatoms] = static_cast<int> (buf[m++]);
   data.type[iatoms] = static_cast<int> (buf[m++]);
   data.mask[iatoms] = static_cast<int> (buf[m++]);
   data.image[iatoms] = static_cast<int> (buf[m++]);
   data.vx[iatoms] = buf[m++];
   data.vy[iatoms] = buf[m++];
   data.vz[iatoms] = buf[m++];
 
   return m;
 }
 
 int atom_bond(double *buf, Data &data, int iatoms)
 {
   int type,atom1;
 
   int m = 1;
   data.x[iatoms] = buf[m++];
   data.y[iatoms] = buf[m++];
   data.z[iatoms] = buf[m++];
   data.tag[iatoms] = static_cast<int> (buf[m++]);
   data.type[iatoms] = static_cast<int> (buf[m++]);
   data.mask[iatoms] = static_cast<int> (buf[m++]);
   data.image[iatoms] = static_cast<int> (buf[m++]);
   data.vx[iatoms] = buf[m++];
   data.vy[iatoms] = buf[m++];
   data.vz[iatoms] = buf[m++];
 
   data.molecule[iatoms] = static_cast<int> (buf[m++]);
 
   int n = static_cast<int> (buf[m++]);
   for (int k = 0; k < n; k++) {
     type = static_cast<int> (buf[m++]);
     atom1 = static_cast<int> (buf[m++]);
     if (data.newton_bond || data.tag[iatoms] < atom1) {
       data.bond_type[data.ibonds] = type;
       data.bond_atom1[data.ibonds] = data.tag[iatoms];
       data.bond_atom2[data.ibonds] = atom1;
       data.ibonds++;
     }
   }
 
   return m;
 }
 
 int atom_charge(double *buf, Data &data, int iatoms)
 {
   int m = 1;
   data.x[iatoms] = buf[m++];
   data.y[iatoms] = buf[m++];
   data.z[iatoms] = buf[m++];
   data.tag[iatoms] = static_cast<int> (buf[m++]);
   data.type[iatoms] = static_cast<int> (buf[m++]);
   data.mask[iatoms] = static_cast<int> (buf[m++]);
   data.image[iatoms] = static_cast<int> (buf[m++]);
   data.vx[iatoms] = buf[m++];
   data.vy[iatoms] = buf[m++];
   data.vz[iatoms] = buf[m++];
 
   data.q[iatoms] = buf[m++];
 
   return m;
 }
 
 int atom_dipole(double *buf, Data &data, int iatoms)
 {
   int m = 1;
   data.x[iatoms] = buf[m++];
   data.y[iatoms] = buf[m++];
   data.z[iatoms] = buf[m++];
   data.tag[iatoms] = static_cast<int> (buf[m++]);
   data.type[iatoms] = static_cast<int> (buf[m++]);
   data.mask[iatoms] = static_cast<int> (buf[m++]);
   data.image[iatoms] = static_cast<int> (buf[m++]);
   data.vx[iatoms] = buf[m++];
   data.vy[iatoms] = buf[m++];
   data.vz[iatoms] = buf[m++];
 
   data.q[iatoms] = buf[m++];
   data.mux[iatoms] = buf[m++];
   data.muy[iatoms] = buf[m++];
   data.muz[iatoms] = buf[m++];
 
   return m;
 }
 
 int atom_ellipsoid(double *buf, Data &data, int iatoms)
 {
   int m = 1;
   data.x[iatoms] = buf[m++];
   data.y[iatoms] = buf[m++];
   data.z[iatoms] = buf[m++];
   data.tag[iatoms] = static_cast<int> (buf[m++]);
   data.type[iatoms] = static_cast<int> (buf[m++]);
   data.mask[iatoms] = static_cast<int> (buf[m++]);
   data.image[iatoms] = static_cast<int> (buf[m++]);
   data.vx[iatoms] = buf[m++];
   data.vy[iatoms] = buf[m++];
   data.vz[iatoms] = buf[m++];
 
   data.quatw[iatoms] = buf[m++];
   data.quati[iatoms] = buf[m++];
   data.quatj[iatoms] = buf[m++];
   data.quatk[iatoms] = buf[m++];
   data.angmomx[iatoms] = buf[m++];
   data.angmomy[iatoms] = buf[m++];
   data.angmomz[iatoms] = buf[m++];
 
   return m;
 }
 
 int atom_granular(double *buf, Data &data, int iatoms)
 {
   int m = 1;
   data.x[iatoms] = buf[m++];
   data.y[iatoms] = buf[m++];
   data.z[iatoms] = buf[m++];
   data.tag[iatoms] = static_cast<int> (buf[m++]);
   data.type[iatoms] = static_cast<int> (buf[m++]);
   data.mask[iatoms] = static_cast<int> (buf[m++]);
   data.image[iatoms] = static_cast<int> (buf[m++]);
   data.vx[iatoms] = buf[m++];
   data.vy[iatoms] = buf[m++];
   data.vz[iatoms] = buf[m++];
 
   data.radius[iatoms] = buf[m++];
   data.density[iatoms] = buf[m++];
   data.omegax[iatoms] = buf[m++];
   data.omegay[iatoms] = buf[m++];
   data.omegaz[iatoms] = buf[m++];
 
   return m;
 }
 
 int atom_full(double *buf, Data &data, int iatoms)
 {
   int type,atom1,atom2,atom3,atom4;
 
   int m = 1;
   data.x[iatoms] = buf[m++];
   data.y[iatoms] = buf[m++];
   data.z[iatoms] = buf[m++];
   data.tag[iatoms] = static_cast<int> (buf[m++]);
   data.type[iatoms] = static_cast<int> (buf[m++]);
   data.mask[iatoms] = static_cast<int> (buf[m++]);
   data.image[iatoms] = static_cast<int> (buf[m++]);
   data.vx[iatoms] = buf[m++];
   data.vy[iatoms] = buf[m++];
   data.vz[iatoms] = buf[m++];
 
   data.q[iatoms] = buf[m++];
   data.molecule[iatoms] = static_cast<int> (buf[m++]);
 
   int n = static_cast<int> (buf[m++]);
   for (int k = 0; k < n; k++) {
     type = static_cast<int> (buf[m++]);
     atom1 = static_cast<int> (buf[m++]);
     if (data.newton_bond || data.tag[iatoms] < atom1) {
       data.bond_type[data.ibonds] = type;
       data.bond_atom1[data.ibonds] = data.tag[iatoms];
       data.bond_atom2[data.ibonds] = atom1;
       data.ibonds++;
     }
   }
 
   n = static_cast<int> (buf[m++]);
   for (int k = 0; k < n; k++) {
     type = static_cast<int> (buf[m++]);
     atom1 = static_cast<int> (buf[m++]);
     atom2 = static_cast<int> (buf[m++]);
     atom3 = static_cast<int> (buf[m++]);
     if (data.newton_bond || data.tag[iatoms] == atom2) {
       data.angle_type[data.iangles] = type;
       data.angle_atom1[data.iangles] = atom1;
       data.angle_atom2[data.iangles] = atom2;
       data.angle_atom3[data.iangles] = atom3;
       data.iangles++;
     }
   }
 
   n = static_cast<int> (buf[m++]);
   for (int k = 0; k < n; k++) {
     type = static_cast<int> (buf[m++]);
     atom1 = static_cast<int> (buf[m++]);
     atom2 = static_cast<int> (buf[m++]);
     atom3 = static_cast<int> (buf[m++]);
     atom4 = static_cast<int> (buf[m++]);
     if (data.newton_bond || data.tag[iatoms] == atom2) {
       data.dihedral_type[data.idihedrals] = type;
       data.dihedral_atom1[data.idihedrals] = atom1;
       data.dihedral_atom2[data.idihedrals] = atom2;
       data.dihedral_atom3[data.idihedrals] = atom3;
       data.dihedral_atom4[data.idihedrals] = atom4;
       data.idihedrals++;
     }
   }
 
   n = static_cast<int> (buf[m++]);
   for (int k = 0; k < n; k++) {
     type = static_cast<int> (buf[m++]);
     atom1 = static_cast<int> (buf[m++]);
     atom2 = static_cast<int> (buf[m++]);
     atom3 = static_cast<int> (buf[m++]);
     atom4 = static_cast<int> (buf[m++]);
     if (data.newton_bond || data.tag[iatoms] == atom2) {
       data.improper_type[data.iimpropers] = type;
       data.improper_atom1[data.iimpropers] = atom1;
       data.improper_atom2[data.iimpropers] = atom2;
       data.improper_atom3[data.iimpropers] = atom3;
       data.improper_atom4[data.iimpropers] = atom4;
       data.iimpropers++;
     }
   }
 
   return m;
 }
 
 int atom_molecular(double *buf, Data &data, int iatoms)
 {
   int type,atom1,atom2,atom3,atom4;
 
   int m = 1;
   data.x[iatoms] = buf[m++];
   data.y[iatoms] = buf[m++];
   data.z[iatoms] = buf[m++];
   data.tag[iatoms] = static_cast<int> (buf[m++]);
   data.type[iatoms] = static_cast<int> (buf[m++]);
   data.mask[iatoms] = static_cast<int> (buf[m++]);
   data.image[iatoms] = static_cast<int> (buf[m++]);
   data.vx[iatoms] = buf[m++];
   data.vy[iatoms] = buf[m++];
   data.vz[iatoms] = buf[m++];
 
   data.molecule[iatoms] = static_cast<int> (buf[m++]);
 
   int n = static_cast<int> (buf[m++]);
   for (int k = 0; k < n; k++) {
     type = static_cast<int> (buf[m++]);
     atom1 = static_cast<int> (buf[m++]);
     if (data.newton_bond || data.tag[iatoms] < atom1) {
       data.bond_type[data.ibonds] = type;
       data.bond_atom1[data.ibonds] = data.tag[iatoms];
       data.bond_atom2[data.ibonds] = atom1;
       data.ibonds++;
     }
   }
 
   n = static_cast<int> (buf[m++]);
   for (int k = 0; k < n; k++) {
     type = static_cast<int> (buf[m++]);
     atom1 = static_cast<int> (buf[m++]);
     atom2 = static_cast<int> (buf[m++]);
     atom3 = static_cast<int> (buf[m++]);
     if (data.newton_bond || data.tag[iatoms] == atom2) {
       data.angle_type[data.iangles] = type;
       data.angle_atom1[data.iangles] = atom1;
       data.angle_atom2[data.iangles] = atom2;
       data.angle_atom3[data.iangles] = atom3;
       data.iangles++;
     }
   }
 
   n = static_cast<int> (buf[m++]);
   for (int k = 0; k < n; k++) {
     type = static_cast<int> (buf[m++]);
     atom1 = static_cast<int> (buf[m++]);
     atom2 = static_cast<int> (buf[m++]);
     atom3 = static_cast<int> (buf[m++]);
     atom4 = static_cast<int> (buf[m++]);
     if (data.newton_bond || data.tag[iatoms] == atom2) {
       data.dihedral_type[data.idihedrals] = type;
       data.dihedral_atom1[data.idihedrals] = atom1;
       data.dihedral_atom2[data.idihedrals] = atom2;
       data.dihedral_atom3[data.idihedrals] = atom3;
       data.dihedral_atom4[data.idihedrals] = atom4;
       data.idihedrals++;
     }
   }
 
   n = static_cast<int> (buf[m++]);
   for (int k = 0; k < n; k++) {
     type = static_cast<int> (buf[m++]);
     atom1 = static_cast<int> (buf[m++]);
     atom2 = static_cast<int> (buf[m++]);
     atom3 = static_cast<int> (buf[m++]);
     atom4 = static_cast<int> (buf[m++]);
     if (data.newton_bond || data.tag[iatoms] == atom2) {
       data.improper_type[data.iimpropers] = type;
       data.improper_atom1[data.iimpropers] = atom1;
       data.improper_atom2[data.iimpropers] = atom2;
       data.improper_atom3[data.iimpropers] = atom3;
       data.improper_atom4[data.iimpropers] = atom4;
       data.iimpropers++;
     }
   }
 
   return m;
 }
 
 int atom_peri(double *buf, Data &data, int iatoms)
 {
   int m = 1;
   data.x[iatoms] = buf[m++];
   data.y[iatoms] = buf[m++];
   data.z[iatoms] = buf[m++];
   data.tag[iatoms] = static_cast<int> (buf[m++]);
   data.type[iatoms] = static_cast<int> (buf[m++]);
   data.mask[iatoms] = static_cast<int> (buf[m++]);
   data.image[iatoms] = static_cast<int> (buf[m++]);
   data.vx[iatoms] = buf[m++];
   data.vy[iatoms] = buf[m++];
   data.vz[iatoms] = buf[m++];
 
   data.vfrac[iatoms] = buf[m++];
   data.density[iatoms] = buf[m++];
   data.rmass[iatoms] = buf[m++];
   data.s0[iatoms] = buf[m++];
   data.x0x[iatoms] = buf[m++];
   data.x0y[iatoms] = buf[m++];
   data.x0z[iatoms] = buf[m++];
 
   return m;
 }
 
 // ---------------------------------------------------------------------
 // per-atom memory allocation routines
 // one routine per atom style
 // ---------------------------------------------------------------------
 
 void allocate_angle(Data &data)
 {
   data.molecule = new int[data.natoms];
   data.bond_type = new int[data.nbonds];
   data.bond_atom1 = new int[data.nbonds];
   data.bond_atom2 = new int[data.nbonds];
   data.angle_type = new int[data.nangles];
   data.angle_atom1 = new int[data.nangles];
   data.angle_atom2 = new int[data.nangles];
   data.angle_atom3 = new int[data.nangles];
 }
 
 void allocate_atomic(Data &data) {}
 
 void allocate_bond(Data &data)
 {
   data.molecule = new int[data.natoms];
   data.bond_type = new int[data.nbonds];
   data.bond_atom1 = new int[data.nbonds];
   data.bond_atom2 = new int[data.nbonds];
 }
 
 void allocate_charge(Data &data)
 {
   data.q = new double[data.natoms];
 }
 
 void allocate_dipole(Data &data)
 {
   data.q = new double[data.natoms];
   data.mux = new double[data.natoms];
   data.muy = new double[data.natoms];
   data.muz = new double[data.natoms];
 }
 
 void allocate_full(Data &data)
 {
   data.q = new double[data.natoms];
   data.molecule = new int[data.natoms];
   data.bond_type = new int[data.nbonds];
   data.bond_atom1 = new int[data.nbonds];
   data.bond_atom2 = new int[data.nbonds];
   data.angle_type = new int[data.nangles];
   data.angle_atom1 = new int[data.nangles];
   data.angle_atom2 = new int[data.nangles];
   data.angle_atom3 = new int[data.nangles];
   data.dihedral_type = new int[data.ndihedrals];
   data.dihedral_atom1 = new int[data.ndihedrals];
   data.dihedral_atom2 = new int[data.ndihedrals];
   data.dihedral_atom3 = new int[data.ndihedrals];
   data.dihedral_atom4 = new int[data.ndihedrals];
   data.improper_type = new int[data.nimpropers];
   data.improper_atom1 = new int[data.nimpropers];
   data.improper_atom2 = new int[data.nimpropers];
   data.improper_atom3 = new int[data.nimpropers];
   data.improper_atom4 = new int[data.nimpropers];
 }
 
 void allocate_ellipsoid(Data &data)
 {
   data.quatw = new double[data.natoms];
   data.quati = new double[data.natoms];
   data.quatj = new double[data.natoms];
   data.quatk = new double[data.natoms];
   data.angmomx = new double[data.natoms];
   data.angmomy = new double[data.natoms];
   data.angmomz = new double[data.natoms];
 }
 
 void allocate_granular(Data &data)
 {
   data.radius = new double[data.natoms];
   data.density = new double[data.natoms];
   data.omegax = new double[data.natoms];
   data.omegay = new double[data.natoms];
   data.omegaz = new double[data.natoms];
 }
 
 void allocate_molecular(Data &data)
 {
   data.molecule = new int[data.natoms];
   data.bond_type = new int[data.nbonds];
   data.bond_atom1 = new int[data.nbonds];
   data.bond_atom2 = new int[data.nbonds];
   data.angle_type = new int[data.nangles];
   data.angle_atom1 = new int[data.nangles];
   data.angle_atom2 = new int[data.nangles];
   data.angle_atom3 = new int[data.nangles];
   data.dihedral_type = new int[data.ndihedrals];
   data.dihedral_atom1 = new int[data.ndihedrals];
   data.dihedral_atom2 = new int[data.ndihedrals];
   data.dihedral_atom3 = new int[data.ndihedrals];
   data.dihedral_atom4 = new int[data.ndihedrals];
   data.improper_type = new int[data.nimpropers];
   data.improper_atom1 = new int[data.nimpropers];
   data.improper_atom2 = new int[data.nimpropers];
   data.improper_atom3 = new int[data.nimpropers];
   data.improper_atom4 = new int[data.nimpropers];
 }
 
 void allocate_peri(Data &data)
 {
   data.vfrac = new double[data.natoms];
   data.density = new double[data.natoms];
   data.rmass = new double[data.natoms];
   data.s0 = new double[data.natoms];
   data.x0x = new double[data.natoms];
   data.x0y = new double[data.natoms];
   data.x0z = new double[data.natoms];
 }
 
 // ---------------------------------------------------------------------
 // pair coeffs
 // one section for each pair style
 // flag = 1, read all coeff info and allocation arrays
 // flag = 0, just read global settings (when called recursively by hybrid)
 // ---------------------------------------------------------------------
 
 void pair(FILE *fp, Data &data, char *style, int flag)
 {
   int i,j,m;
   int itmp;
   double rtmp;
 
   if (strcmp(style,"none") == 0) {
 
   } else if (strcmp(style,"airebo") == 0) {
 
   } else if (strcmp(style,"born/coul/long") == 0) {
     double cut_lj_global = read_double(fp);
     double cut_coul = read_double(fp);
     int offset_flag = read_int(fp);
     int mix_flag = read_int(fp);
 
     if (!flag) return;
 
     data.pair_born_A = new double[data.ntypes+1];
     data.pair_born_rho = new double[data.ntypes+1];
     data.pair_born_sigma = new double[data.ntypes+1];
     data.pair_born_C = new double[data.ntypes+1];
     data.pair_born_D = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_born_A[i] = read_double(fp);
 	    data.pair_born_rho[i] = read_double(fp);
 	    data.pair_born_sigma[i] = read_double(fp);
 	    data.pair_born_C[i] = read_double(fp);
 	    data.pair_born_D[i] = read_double(fp);
 	    double cut_lj = read_double(fp);
 	  } else {
 	    double born_A = read_double(fp);
 	    double born_rho = read_double(fp);
 	    double born_sigma = read_double(fp);
 	    double born_C = read_double(fp);
 	    double born_D = read_double(fp);
 	    double cut_lj = read_double(fp);
 	  }
 	}
       }
 
   } else if ((strcmp(style,"buck") == 0)  ||
 	   (strcmp(style,"buck/coul/cut") == 0) ||
 	   (strcmp(style,"buck/coul/long") == 0) ||
 	   (strcmp(style,"buck/coul") == 0)) {
 
     if (strcmp(style,"buck") == 0) {
       m = 0;
       double cut_lj_global = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"buck/coul/cut") == 0) {
       m = 1;
       double cut_lj_global = read_double(fp);
       double cut_lj_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"buck/coul/long") == 0) {
       m = 0;
       double cut_lj_global = read_double(fp);
       double cut_lj_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"buck/coul") == 0) {
       m = 0;
       double cut_buck_global = read_double(fp);
       double cut_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
       int ewald_order = read_int(fp);
     }
 
     if (!flag) return;
 
     data.pair_buck_A = new double[data.ntypes+1];
     data.pair_buck_rho = new double[data.ntypes+1];
     data.pair_buck_C = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_buck_A[i] = read_double(fp);
 	    data.pair_buck_rho[i] = read_double(fp);
 	    data.pair_buck_C[i] = read_double(fp);
 	    double cut_lj = read_double(fp);
 	    if (m) double cut_coul = read_double(fp);
 	  } else {
 	    double buck_A = read_double(fp);
 	    double buck_rho = read_double(fp);
 	    double buck_C = read_double(fp);
 	    double cut_lj = read_double(fp);
 	    if (m) double cut_coul = read_double(fp);
 	  }
 	}
       }
 
   } else if (strcmp(style,"colloid") == 0) {
 
     double cut_global = read_double(fp);
     int offset_flag = read_int(fp);
     int mix_flag = read_int(fp);
 
     if (!flag) return;
 
     data.pair_colloid_A12 = new double[data.ntypes+1];
     data.pair_colloid_sigma = new double[data.ntypes+1];
     data.pair_colloid_d1 = new double[data.ntypes+1];
     data.pair_colloid_d2 = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_colloid_A12[i] = read_double(fp);
 	    data.pair_colloid_sigma[i] = read_double(fp);
 	    data.pair_colloid_d1[i] = read_double(fp);
 	    data.pair_colloid_d2[i] = read_double(fp);
 	    double cut_lj = read_double(fp);
 	  } else {
 	    double colloid_A12 = read_double(fp);
 	    double colloid_sigma = read_double(fp);
 	    double colloid_d1 = read_double(fp);
 	    double colloid_d2 = read_double(fp);
 	    double cut_lj = read_double(fp);
 	  }
 	}
       }
 
   } else if ((strcmp(style,"coul/cut") == 0) ||
 	     (strcmp(style,"coul/debye") == 0) ||
 	     (strcmp(style,"coul/long") == 0)) {
 
     if (strcmp(style,"coul/cut") == 0) {
       double cut_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"coul/debye") == 0) {
       m = 1;
       double cut_coul = read_double(fp);
       double kappa = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"coul/long") == 0) {
       double cut_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     }
 
     if (!flag) return;
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    double cut_coul = read_double(fp);
 	  } else {
 	    double cut_coul = read_double(fp);
 	  }
 	}
       }
 
   } else if (strcmp(style,"dipole/cut") == 0) {
 
     double cut_lj_global = read_double(fp);
     double cut_coul_global = read_double(fp);
     int offset_flag = read_int(fp);
     int mix_flag = read_int(fp);
 
     if (!flag) return;
 
     data.pair_dipole_epsilon = new double[data.ntypes+1];
     data.pair_dipole_sigma = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_dipole_epsilon[i] = read_double(fp);
 	    data.pair_dipole_sigma[i] = read_double(fp);
 	    double cut_lj = read_double(fp);
 	    double cut_coul = read_double(fp);
 	  } else {
 	    double dipole_epsilon = read_double(fp);
 	    double dipole_sigma = read_double(fp);
 	    double cut_lj = read_double(fp);
 	    double cut_coul = read_double(fp);
 	  }
 	}
       }
 
   } else if (strcmp(style,"dpd") == 0) {
 
     double temperature = read_double(fp);
     double cut_global = read_double(fp);
     int seed = read_int(fp);
     int mix_flag = read_int(fp);
     
     if (!flag) return;
     
     data.pair_dpd_a0 = new double[data.ntypes+1];
     data.pair_dpd_gamma = new double[data.ntypes+1];
     
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_dpd_a0[i] = read_double(fp);
 	    data.pair_dpd_gamma[i] = read_double(fp);
 	    double cut = read_double(fp);
 	  } else {
 	    double dpd_a0 = read_double(fp);
 	    double dpd_gamma = read_double(fp);
 	    double cut = read_double(fp);
 	  }
 	}
       }
     
   } else if (strcmp(style,"dpd/tstat") == 0) {
 
     double tstart = read_double(fp);
     double tstop = read_double(fp);
     double cut_global = read_double(fp);
     int seed = read_int(fp);
     int mix_flag = read_int(fp);
 
     if (!flag) return;
 
     data.pair_dpd_a0 = new double[data.ntypes+1];
     data.pair_dpd_gamma = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_dpd_a0[i] = read_double(fp);
 	    data.pair_dpd_gamma[i] = read_double(fp);
 	    double cut = read_double(fp);
 	  } else {
 	    double dpd_a0 = read_double(fp);
 	    double dpd_gamma = read_double(fp);
 	    double cut = read_double(fp);
 	  }
 	}
       }
 
   } else if (strcmp(style,"eam") == 0) {
   } else if (strcmp(style,"eam/opt") == 0) {
   } else if (strcmp(style,"eam/alloy") == 0) {
   } else if (strcmp(style,"eam/alloy/opt") == 0) {
   } else if (strcmp(style,"eam/fs") == 0) {
   } else if (strcmp(style,"eam/fs/opt") == 0) {
   } else if (strcmp(style,"eim") == 0) {
 
   } else if (strcmp(style,"eff/cut") == 0) {
 
     double cut_coul = read_double(fp);
     int limit_size_flag = read_int(fp);
     int flexible_pressure_flag = read_int(fp);
     int offset_flag = read_int(fp);
     int mix_flag = read_int(fp);
 
     if (!flag) return;
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    double cut = read_double(fp);
 	  } else {
 	    double cut = read_double(fp);
 	  }
 	}
       }
 
   } else if (strcmp(style,"gayberne") == 0) {
 
     double gamma = read_double(fp);
     double upsilon = read_double(fp);
     double mu = read_double(fp);
     double cut_global = read_double(fp);
     int offset_flag = read_int(fp);
     int mix_flag = read_int(fp);
 
     if (!flag) return;
 
     data.pair_gb_epsilon = new double[data.ntypes+1];
     data.pair_gb_sigma = new double[data.ntypes+1];
     data.pair_gb_epsa = new double[data.ntypes+1];
     data.pair_gb_epsb = new double[data.ntypes+1];
     data.pair_gb_epsc = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++) {
       itmp = read_int(fp);
       if (itmp) {
 	data.pair_gb_epsa[i] = read_double(fp);
 	data.pair_gb_epsb[i] = read_double(fp);
 	data.pair_gb_epsc[i] = read_double(fp);
 	data.pair_gb_epsa[i] = pow(data.pair_gb_epsa[i],-mu);
 	data.pair_gb_epsb[i] = pow(data.pair_gb_epsb[i],-mu);
 	data.pair_gb_epsc[i] = pow(data.pair_gb_epsc[i],-mu);
       }
 
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_gb_epsilon[i] = read_double(fp);
 	    data.pair_gb_sigma[i] = read_double(fp);
 	    double cut = read_double(fp);
 	  } else {
 	    double gb_epsilon = read_double(fp);
 	    double gb_sigma = read_double(fp);
 	    double cut = read_double(fp);
 	  }
 	}
       }
     }
 
   } else if ((strcmp(style,"gran/hooke") == 0) ||
 	   (strcmp(style,"gran/hooke/history") == 0) ||
 	   (strcmp(style,"gran/hertz/history") == 0)) {
 
     double kn = read_double(fp);
     double kt = read_double(fp);
     double gamman = read_double(fp);
     double gammat = read_double(fp);
     double xmu = read_double(fp);
     int dampflag = read_int(fp);
 
   } else if ((strcmp(style,"lj/charmm/coul/charmm") == 0) ||
 	   (strcmp(style,"lj/charmm/coul/charmm/implicit") == 0) ||
 	   (strcmp(style,"lj/charmm/coul/long") == 0) ||
 	   (strcmp(style,"lj/charmm/coul/long/gpu") == 0) ||
 	   (strcmp(style,"lj/charmm/coul/long/opt") == 0)) {
 
     if (strcmp(style,"lj/charmm/coul/charmm") == 0) {
       double cut_lj_inner = read_double(fp);
       double cut_lj = read_double(fp);
       double cut_coul_inner = read_double(fp);
       double cut_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"lj/charmm/coul/charmm/implicit") == 0) {
       double cut_lj_inner = read_double(fp);
       double cut_lj = read_double(fp);
       double cut_coul_inner = read_double(fp);
       double cut_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if ((strcmp(style,"lj/charmm/coul/long") == 0) ||
 	       (strcmp(style,"lj/charmm/coul/long/gpu") == 0) ||
 	       (strcmp(style,"lj/charmm/coul/long/opt") == 0)) {
       double cut_lj_inner = read_double(fp);
       double cut_lj = read_double(fp);
       double cut_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     }
 
     if (!flag) return;
 
     data.pair_charmm_epsilon = new double[data.ntypes+1];
     data.pair_charmm_sigma = new double[data.ntypes+1];
     data.pair_charmm_eps14 = new double[data.ntypes+1];
     data.pair_charmm_sigma14 = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_charmm_epsilon[i] = read_double(fp);
 	    data.pair_charmm_sigma[i] = read_double(fp);
 	    data.pair_charmm_eps14[i] = read_double(fp);
 	    data.pair_charmm_sigma14[i] = read_double(fp);
 	  } else {
 	    double charmm_epsilon = read_double(fp);
 	    double charmm_sigma = read_double(fp);
 	    double charmm_eps14 = read_double(fp);
 	    double charmm_sigma14 = read_double(fp);
 	  }
 	}
       }
 
   } else if ((strcmp(style,"lj/class2") == 0) ||
 	   (strcmp(style,"lj/class2/coul/cut") == 0) ||
 	   (strcmp(style,"lj/class2/coul/long") == 0)) {
 
     if (strcmp(style,"lj/class2") == 0) {
       m = 0;
       double cut_lj_global = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"lj/class2/coul/cut") == 0) {
       m = 1;
       double cut_lj_global = read_double(fp);
       double cut_lj_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"lj/class2/coul/long") == 0) {
       m = 0;
       double cut_lj_global = read_double(fp);
       double cut_lj_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     }
 
     if (!flag) return;
 
     data.pair_class2_epsilon = new double[data.ntypes+1];
     data.pair_class2_sigma = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_class2_epsilon[i] = read_double(fp);
 	    data.pair_class2_sigma[i] = read_double(fp);
 	    double cut_lj = read_double(fp);
 	    if (m) double cut_coul = read_double(fp);
 	  } else {
 	    double class2_epsilon = read_double(fp);
 	    double class2_sigma = read_double(fp);
 	    double cut_lj = read_double(fp);
 	    if (m) double cut_coul = read_double(fp);
 	  }
 	}
       }
 
   } else if ((strcmp(style,"lj/cut") == 0) ||
 	   (strcmp(style,"lj/cut/gpu") == 0) ||
 	   (strcmp(style,"lj/cut/opt") == 0) ||
 	   (strcmp(style,"lj/cut/coul/cut") == 0) ||
 	   (strcmp(style,"lj/cut/coul/cut/gpu") == 0) ||
 	   (strcmp(style,"lj/cut/coul/debye") == 0) ||
 	   (strcmp(style,"lj/cut/coul/long") == 0) ||
 	   (strcmp(style,"lj/cut/coul/long/gpu") == 0) ||
 	   (strcmp(style,"lj/cut/coul/long/tip4p") == 0) ||
 	   (strcmp(style,"lj/coul") == 0)) {
 
     if ((strcmp(style,"lj/cut") == 0) ||
 	(strcmp(style,"lj/cut/gpu") == 0) ||
 	(strcmp(style,"lj/cut/opt") == 0)) {
       m = 0;
       double cut_lj_global = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if ((strcmp(style,"lj/cut/coul/cut") == 0) ||
 	       (strcmp(style,"lj/cut/coul/cut/gpu") == 0)) {
       m = 1;
       double cut_lj_global = read_double(fp);
       double cut_lj_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"lj/cut/coul/debye") == 0) {
       m = 1;
       double cut_lj_global = read_double(fp);
       double cut_lj_coul = read_double(fp);
       double kappa = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if ((strcmp(style,"lj/cut/coul/long") == 0) ||
 	       (strcmp(style,"lj/cut/coul/long/gpu") == 0)) {
       m = 0;
       double cut_lj_global = read_double(fp);
       double cut_lj_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"lj/cut/coul/long/tip4p") == 0) {
       m = 0;
       int typeO = read_int(fp);
       int typeH = read_int(fp);
       int typeB = read_int(fp);
       int typeA = read_int(fp);
       double qdist = read_double(fp);
       double cut_lj_global = read_double(fp);
       double cut_lj_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"lj/coul") == 0) {
       m = 0;
       double cut_lj_global = read_double(fp);
       double cut_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
       int ewald_order = read_int(fp);
     }
 
     if (!flag) return;
 
     data.pair_lj_epsilon = new double[data.ntypes+1];
     data.pair_lj_sigma = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_lj_epsilon[i] = read_double(fp);
 	    data.pair_lj_sigma[i] = read_double(fp);
 	    double cut_lj = read_double(fp);
 	    if (m) double cut_coul = read_double(fp);
 	  } else {
 	    double lj_epsilon = read_double(fp);
 	    double lj_sigma = read_double(fp);
 	    double cut_lj = read_double(fp);
 	    if (m) double cut_coul = read_double(fp);
 	  }
 	}
       }
 
   } else if (strcmp(style,"lj/expand") == 0) {
 
     double cut_global = read_double(fp);
     int offset_flag = read_int(fp);
     int mix_flag = read_int(fp);
 
     if (!flag) return;
 
     data.pair_ljexpand_epsilon = new double[data.ntypes+1];
     data.pair_ljexpand_sigma = new double[data.ntypes+1];
     data.pair_ljexpand_shift = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_ljexpand_epsilon[i] = read_double(fp);
 	    data.pair_ljexpand_sigma[i] = read_double(fp);
 	    data.pair_ljexpand_shift[i] = read_double(fp);
 	    double cut_lj = read_double(fp);
 	  } else {
 	    double ljexpand_epsilon = read_double(fp);
 	    double ljexpand_sigma = read_double(fp);
 	    double ljexpand_shift = read_double(fp);
 	    double cut_lj = read_double(fp);
 	  }
 	}
       }
 
   } else if ((strcmp(style,"lj/gromacs") == 0) ||
 	     (strcmp(style,"lj/gromacs/coul/gromacs") == 0)) {
 
     if (strcmp(style,"lj/gromacs") == 0) {
       m = 1;
       double cut_inner_global = read_double(fp);
       double cut_global = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     } else if (strcmp(style,"lj/gromacs/coul/gromacs") == 0) {
       m = 0;
       double cut_lj_inner_global = read_double(fp);
       double cut_lj = read_double(fp);
       double cut_coul_inner_global = read_double(fp);
       double cut_coul = read_double(fp);
       int offset_flag = read_int(fp);
       int mix_flag = read_int(fp);
     }
 
     if (!flag) return;
 
     data.pair_ljgromacs_epsilon = new double[data.ntypes+1];
     data.pair_ljgromacs_sigma = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_ljgromacs_epsilon[i] = read_double(fp);
 	    data.pair_ljgromacs_sigma[i] = read_double(fp);
 	    if (m) {
 	      double cut_inner = read_double(fp);
 	      double cut = read_double(fp);
 	    }
 	    } else {
 	    double ljgromacs_epsilon = read_double(fp);
 	    double ljgromacs_sigma = read_double(fp);
 	    if (m) {
 	      double cut_inner = read_double(fp);
 	      double cut = read_double(fp);
 	    }
 	  }
 	}
       }
 
   } else if (strcmp(style,"lj/smooth") == 0) {
 
     double cut_inner_global = read_double(fp);
     double cut_global = read_double(fp);
     int offset_flag = read_int(fp);
     int mix_flag = read_int(fp);
 
     if (!flag) return;
 
     data.pair_ljsmooth_epsilon = new double[data.ntypes+1];
     data.pair_ljsmooth_sigma = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_ljsmooth_epsilon[i] = read_double(fp);
 	    data.pair_ljsmooth_sigma[i] = read_double(fp);
 	    double cut_inner = read_double(fp);
 	    double cut = read_double(fp);
 	  } else {
 	    double ljsmooth_epsilon = read_double(fp);
 	    double ljsmooth_sigma = read_double(fp);
 	    double cut_inner = read_double(fp);
 	    double cut = read_double(fp);
 	  }
 	}
       }
 
   } else if (strcmp(style,"meam") == 0) {
 
   } else if ((strcmp(style,"morse") == 0) ||
 	     (strcmp(style,"morse/opt") == 0)) {
 
     double cut_global = read_double(fp);
     int offset_flag = read_int(fp);
     int mix_flag = read_int(fp);
 
     if (!flag) return;
 
     data.pair_morse_d0 = new double[data.ntypes+1];
     data.pair_morse_alpha = new double[data.ntypes+1];
     data.pair_morse_r0 = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_morse_d0[i] = read_double(fp);
 	    data.pair_morse_alpha[i] = read_double(fp);
 	    data.pair_morse_r0[i] = read_double(fp);
 	    double cut = read_double(fp);
 	  } else {
 	    double morse_d0 = read_double(fp);
 	    double morse_alpha = read_double(fp);
 	    double morse_r0 = read_double(fp);
 	    double cut = read_double(fp);
 	  }
 	}
       }
 
   } else if (strcmp(style,"reax") == 0) {
   } else if (strcmp(style,"reax/c") == 0) {
 
   } else if (strcmp(style,"soft") == 0) {
 
     double cut_global = read_double(fp);
     int mix_flag = read_int(fp);
 
     if (!flag) return;
 
     data.pair_soft_A = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_soft_A[i] = read_double(fp);
 	    double cut = read_double(fp);
 	  } else {
 	    double soft_A = read_double(fp);
 	    double cut = read_double(fp);
 	  }
 	}
       }
 
   } else if (strcmp(style,"sw") == 0) {
 
   } else if (strcmp(style,"table") == 0) {
 
     int tabstyle = read_int(fp);
     int n = read_int(fp);
 
   } else if (strcmp(style,"tersoff") == 0) {
   } else if (strcmp(style,"tersoff/zbl") == 0) {
 
   } else if (strcmp(style,"yukawa") == 0) {
 
     double kappa = read_double(fp);
     double cut_global = read_double(fp);
     int offset_flag = read_int(fp);
     int mix_flag = read_int(fp);
 
     if (!flag) return;
 
     data.pair_yukawa_A = new double[data.ntypes+1];
 
     for (i = 1; i <= data.ntypes; i++)
       for (j = i; j <= data.ntypes; j++) {
 	itmp = read_int(fp);
 	if (i == j && itmp == 0) {
 	  printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
 	  exit(1);
 	}
 	if (itmp) {
 	  if (i == j) {
 	    data.pair_yukawa_A[i] = read_double(fp);
 	    double cut = read_double(fp);
 	  } else {
 	    double yukawa_A = read_double(fp);
 	    double cut = read_double(fp);
 	  }
 	}
       }
 
   } else if ((strcmp(style,"cg/cmm") == 0) ||
              (strcmp(style,"cg/cmm/gpu") == 0) ||
              (strcmp(style,"cg/cmm/coul/cut") == 0) ||
              (strcmp(style,"cg/cmm/coul/long") == 0) ||
              (strcmp(style,"cg/cmm/coul/long/gpu") == 0)) {
     m = 0;
     data.cut_lj_global = read_double(fp);
     data.cut_coul_global = read_double(fp);
     data.kappa = read_double(fp);
     data.offset_flag = read_int(fp);
     data.mix_flag = read_int(fp);
 
     if (!flag) return;
 
     const int numtyp=data.ntypes+1;
     data.pair_cg_cmm_type = new int*[numtyp];
     data.pair_setflag = new int*[numtyp];
     data.pair_cg_epsilon = new double*[numtyp];
     data.pair_cg_sigma = new double*[numtyp];
     data.pair_cut_lj = new double*[numtyp];
     if  ((strcmp(style,"cg/cmm/coul/cut") == 0) ||
 	 (strcmp(style,"cg/cmm/coul/long") == 0) ||
 	 (strcmp(style,"cg/cmm/coul/long/gpu") == 0)) {
       data.pair_cut_coul = new double*[numtyp];
       m=1;
     } else {
       data.pair_cut_coul = NULL;
       m=0;
     }
 
     for (i = 1; i <= data.ntypes; i++) {
       data.pair_cg_cmm_type[i] = new int[numtyp];
       data.pair_setflag[i] = new int[numtyp];
       data.pair_cg_epsilon[i] = new double[numtyp];
       data.pair_cg_sigma[i] = new double[numtyp];
       data.pair_cut_lj[i] = new double[numtyp];
       if ((strcmp(style,"cg/cmm/coul/cut") == 0) ||
           (strcmp(style,"cg/cmm/coul/long") == 0) ||
           (strcmp(style,"cg/cmm/coul/long/gpu") == 0)) {
         data.pair_cut_coul[i] = new double[numtyp];
       }
 
       for (j = i; j <= data.ntypes; j++) {
         itmp = read_int(fp);
         data.pair_setflag[i][j] = itmp;
         if (i == j && itmp == 0) {
           printf("ERROR: Pair coeff %d,%d is not in restart file\n",i,j);
           exit(1);
         }
         if (itmp) {
           data.pair_cg_cmm_type[i][j] = read_int(fp);
           data.pair_cg_epsilon[i][j] = read_double(fp);
           data.pair_cg_sigma[i][j] = read_double(fp);
           data.pair_cut_lj[i][j] = read_double(fp);
           if (m) {
 	    data.pair_cut_lj[i][j] = read_double(fp);
 	    data.pair_cut_coul[i][j] = read_double(fp);
 	  }
         }
       }
     }
 
   } else if ((strcmp(style,"hybrid") == 0) ||
 	     (strcmp(style,"hybrid/overlay") == 0)) {
 
     // for each substyle of hybrid,
     //   read its settings by calling pair() recursively with flag = 0
     //   so that coeff array allocation is skipped
 
     int nstyles = read_int(fp);
     for (int i = 0; i < nstyles; i++) {
       char *substyle = read_char(fp);
       pair(fp,data,substyle,0);
     }
 
   } else {
     printf("ERROR: Unknown pair style %s\n",style);
     exit(1);
   }
 }
 
 // ---------------------------------------------------------------------
 // bond coeffs
 // one section for each bond style
 // ---------------------------------------------------------------------
 
 void bond(FILE *fp, Data &data)
 {
   if (strcmp(data.bond_style,"none") == 0) {
 
   } else if (strcmp(data.bond_style,"class2") == 0) {
 
     data.bond_class2_r0 = new double[data.nbondtypes+1];
     data.bond_class2_k2 = new double[data.nbondtypes+1];
     data.bond_class2_k3 = new double[data.nbondtypes+1];
     data.bond_class2_k4 = new double[data.nbondtypes+1];
     fread(&data.bond_class2_r0[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_class2_k2[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_class2_k3[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_class2_k4[1],sizeof(double),data.nbondtypes,fp);
 
   } else if (strcmp(data.bond_style,"fene") == 0) {
 
     data.bond_fene_k = new double[data.nbondtypes+1];
     data.bond_fene_r0 = new double[data.nbondtypes+1];
     data.bond_fene_epsilon = new double[data.nbondtypes+1];
     data.bond_fene_sigma = new double[data.nbondtypes+1];
     fread(&data.bond_fene_k[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_fene_r0[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_fene_epsilon[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_fene_sigma[1],sizeof(double),data.nbondtypes,fp);
 
   } else if (strcmp(data.bond_style,"fene/expand") == 0) {
 
     data.bond_feneexpand_k = new double[data.nbondtypes+1];
     data.bond_feneexpand_r0 = new double[data.nbondtypes+1];
     data.bond_feneexpand_epsilon = new double[data.nbondtypes+1];
     data.bond_feneexpand_sigma = new double[data.nbondtypes+1];
     data.bond_feneexpand_shift = new double[data.nbondtypes+1];
     fread(&data.bond_feneexpand_k[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_feneexpand_r0[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_feneexpand_epsilon[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_feneexpand_sigma[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_feneexpand_shift[1],sizeof(double),data.nbondtypes,fp);
 
   } else if (strcmp(data.bond_style,"harmonic") == 0) {
 
     data.bond_harmonic_k = new double[data.nbondtypes+1];
     data.bond_harmonic_r0 = new double[data.nbondtypes+1];
     fread(&data.bond_harmonic_k[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_harmonic_r0[1],sizeof(double),data.nbondtypes,fp);
 
   } else if (strcmp(data.bond_style,"morse") == 0) {
 
     data.bond_morse_d0 = new double[data.nbondtypes+1];
     data.bond_morse_alpha = new double[data.nbondtypes+1];
     data.bond_morse_r0 = new double[data.nbondtypes+1];
     fread(&data.bond_morse_d0[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_morse_alpha[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_morse_r0[1],sizeof(double),data.nbondtypes,fp);
 
   } else if (strcmp(data.bond_style,"nonlinear") == 0) {
 
     data.bond_nonlinear_epsilon = new double[data.nbondtypes+1];
     data.bond_nonlinear_r0 = new double[data.nbondtypes+1];
     data.bond_nonlinear_lamda = new double[data.nbondtypes+1];
     fread(&data.bond_nonlinear_epsilon[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_nonlinear_r0[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_nonlinear_lamda[1],sizeof(double),data.nbondtypes,fp);
 
   } else if (strcmp(data.bond_style,"quartic") == 0) {
 
     data.bond_quartic_k = new double[data.nbondtypes+1];
     data.bond_quartic_b1 = new double[data.nbondtypes+1];
     data.bond_quartic_b2 = new double[data.nbondtypes+1];
     data.bond_quartic_rc = new double[data.nbondtypes+1];
     data.bond_quartic_u0 = new double[data.nbondtypes+1];
     fread(&data.bond_quartic_k[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_quartic_b1[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_quartic_b2[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_quartic_rc[1],sizeof(double),data.nbondtypes,fp);
     fread(&data.bond_quartic_u0[1],sizeof(double),data.nbondtypes,fp);
 
   } else if (strcmp(data.bond_style,"table") == 0) {
 
     int tabstyle = read_int(fp);
     int n = read_int(fp);
 
   } else if (strcmp(data.bond_style,"hybrid") == 0) {
 
     int nstyles = read_int(fp);
     for (int i = 0; i < nstyles; i++)
       char *substyle = read_char(fp);
 
   } else {
     printf("ERROR: Unknown bond style %s\n",data.bond_style);
     exit(1);
   }
 }
 
 // ---------------------------------------------------------------------
 // angle coeffs
 // one section for each angle style
 // ---------------------------------------------------------------------
 
 void angle(FILE *fp, Data &data)
 {
   if (strcmp(data.angle_style,"none") == 0) {
 
   } else if (strcmp(data.angle_style,"cg/cmm") == 0) {
 
     data.angle_harmonic_k = new double[data.nangletypes+1];
     data.angle_harmonic_theta0 = new double[data.nangletypes+1];
     data.angle_cg_cmm_epsilon = new double[data.nangletypes+1];
     data.angle_cg_cmm_sigma = new double[data.nangletypes+1];
     double *angle_cg_cmm_rcut = new double[data.nangletypes+1];
     data.angle_cg_cmm_type = new int[data.nangletypes+1];
 
     fread(&data.angle_harmonic_k[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_harmonic_theta0[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_cg_cmm_epsilon[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_cg_cmm_sigma[1],sizeof(double),data.nangletypes,fp);
     fread(angle_cg_cmm_rcut,sizeof(double),data.nangletypes,fp);
     fread(&data.angle_cg_cmm_type[1],sizeof(int),data.nangletypes,fp);
 
   } else if (strcmp(data.angle_style,"charmm") == 0) {
 
     data.angle_charmm_k = new double[data.nangletypes+1];
     data.angle_charmm_theta0 = new double[data.nangletypes+1];
     data.angle_charmm_k_ub = new double[data.nangletypes+1];
     data.angle_charmm_r_ub = new double[data.nangletypes+1];
     fread(&data.angle_charmm_k[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_charmm_theta0[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_charmm_k_ub[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_charmm_r_ub[1],sizeof(double),data.nangletypes,fp);
 
   } else if (strcmp(data.angle_style,"class2") == 0) {
 
     data.angle_class2_theta0 = new double[data.nangletypes+1];
     data.angle_class2_k2 = new double[data.nangletypes+1];
     data.angle_class2_k3 = new double[data.nangletypes+1];
     data.angle_class2_k4 = new double[data.nangletypes+1];
 
     data.angle_class2_bb_k = new double[data.nangletypes+1];
     data.angle_class2_bb_r1 = new double[data.nangletypes+1];
     data.angle_class2_bb_r2 = new double[data.nangletypes+1];
 
     data.angle_class2_ba_k1 = new double[data.nangletypes+1];
     data.angle_class2_ba_k2 = new double[data.nangletypes+1];
     data.angle_class2_ba_r1 = new double[data.nangletypes+1];
     data.angle_class2_ba_r2 = new double[data.nangletypes+1];
 
     fread(&data.angle_class2_theta0[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_class2_k2[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_class2_k3[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_class2_k4[1],sizeof(double),data.nangletypes,fp);
 
     fread(&data.angle_class2_bb_k[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_class2_bb_r1[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_class2_bb_r2[1],sizeof(double),data.nangletypes,fp);
 
     fread(&data.angle_class2_ba_k1[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_class2_ba_k2[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_class2_ba_r1[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_class2_ba_r2[1],sizeof(double),data.nangletypes,fp);
 
   } else if (strcmp(data.angle_style,"cosine") == 0) {
 
     data.angle_cosine_k = new double[data.nangletypes+1];
     fread(&data.angle_cosine_k[1],sizeof(double),data.nangletypes,fp);
 
   } else if ((strcmp(data.angle_style,"cosine/squared") == 0) ||
              (strcmp(data.angle_style,"cosine/delta") == 0)) {
 
     data.angle_cosine_squared_k = new double[data.nangletypes+1];
     data.angle_cosine_squared_theta0 = new double[data.nangletypes+1];
     fread(&data.angle_cosine_squared_k[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_cosine_squared_theta0[1],
 	  sizeof(double),data.nangletypes,fp);
 
   } else if (strcmp(data.angle_style,"harmonic") == 0) {
 
     data.angle_harmonic_k = new double[data.nangletypes+1];
     data.angle_harmonic_theta0 = new double[data.nangletypes+1];
     fread(&data.angle_harmonic_k[1],sizeof(double),data.nangletypes,fp);
     fread(&data.angle_harmonic_theta0[1],sizeof(double),data.nangletypes,fp);
 
   } else if (strcmp(data.angle_style,"table") == 0) {
 
     int tabstyle = read_int(fp);
     int n = read_int(fp);
 
   } else if (strcmp(data.angle_style,"hybrid") == 0) {
 
     int nstyles = read_int(fp);
     for (int i = 0; i < nstyles; i++)
       char *substyle = read_char(fp);
 
   } else {
     printf("ERROR: Unknown angle style %s\n",data.angle_style);
     exit(1);
   }
 }
 
 // ---------------------------------------------------------------------
 // dihedral coeffs
 // one section for each dihedral style
 // ---------------------------------------------------------------------
 
 void dihedral(FILE *fp, Data &data)
 {
   if (strcmp(data.dihedral_style,"none") == 0) {
 
   } else if (strcmp(data.dihedral_style,"charmm") == 0) {
 
     data.dihedral_charmm_k = new double[data.ndihedraltypes+1];
     data.dihedral_charmm_multiplicity = new int[data.ndihedraltypes+1];
     data.dihedral_charmm_sign = new int[data.ndihedraltypes+1];
     data.dihedral_charmm_weight = new double[data.ndihedraltypes+1];
     fread(&data.dihedral_charmm_k[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_charmm_multiplicity[1],sizeof(int),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_charmm_sign[1],sizeof(int),data.ndihedraltypes,fp);
     fread(&data.dihedral_charmm_weight[1],sizeof(double),
 	  data.ndihedraltypes,fp);
 
   } else if (strcmp(data.dihedral_style,"class2") == 0) {
 
     data.dihedral_class2_k1 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_k2 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_k3 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_phi1 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_phi2 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_phi3 = new double[data.ndihedraltypes+1];
 
     data.dihedral_class2_mbt_f1 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_mbt_f2 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_mbt_f3 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_mbt_r0 = new double[data.ndihedraltypes+1];
 
     data.dihedral_class2_ebt_f1_1 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_ebt_f2_1 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_ebt_f3_1 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_ebt_r0_1 = new double[data.ndihedraltypes+1];
 
     data.dihedral_class2_ebt_f1_2 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_ebt_f2_2 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_ebt_f3_2 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_ebt_r0_2 = new double[data.ndihedraltypes+1];
 
     data.dihedral_class2_at_f1_1 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_at_f2_1 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_at_f3_1 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_at_theta0_1 = new double[data.ndihedraltypes+1];
 
     data.dihedral_class2_at_f1_2 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_at_f2_2 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_at_f3_2 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_at_theta0_2 = new double[data.ndihedraltypes+1];
 
     data.dihedral_class2_aat_k = new double[data.ndihedraltypes+1];
     data.dihedral_class2_aat_theta0_1 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_aat_theta0_2 = new double[data.ndihedraltypes+1];
 
     data.dihedral_class2_bb13_k = new double[data.ndihedraltypes+1];
     data.dihedral_class2_bb13_r10 = new double[data.ndihedraltypes+1];
     data.dihedral_class2_bb13_r30 = new double[data.ndihedraltypes+1];
 
     fread(&data.dihedral_class2_k1[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_k2[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_k3[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_phi1[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_phi2[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_phi3[1],sizeof(double),data.ndihedraltypes,fp);
 
     fread(&data.dihedral_class2_mbt_f1[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_mbt_f2[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_mbt_f3[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_mbt_r0[1],sizeof(double),
 	  data.ndihedraltypes,fp);
 
     fread(&data.dihedral_class2_ebt_f1_1[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_ebt_f2_1[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_ebt_f3_1[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_ebt_r0_1[1],sizeof(double),
 	  data.ndihedraltypes,fp);
 
     fread(&data.dihedral_class2_ebt_f1_2[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_ebt_f2_2[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_ebt_f3_2[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_ebt_r0_2[1],sizeof(double),
 	  data.ndihedraltypes,fp);
 
     fread(&data.dihedral_class2_at_f1_1[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_at_f2_1[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_at_f3_1[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_at_theta0_1[1],sizeof(double),
 	  data.ndihedraltypes,fp);
 
     fread(&data.dihedral_class2_at_f1_2[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_at_f2_2[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_at_f3_2[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_at_theta0_2[1],sizeof(double),
 	  data.ndihedraltypes,fp);
 
     fread(&data.dihedral_class2_aat_k[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_aat_theta0_1[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_aat_theta0_2[1],sizeof(double),
 	  data.ndihedraltypes,fp);
 
     fread(&data.dihedral_class2_bb13_k[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_bb13_r10[1],sizeof(double),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_class2_bb13_r30[1],sizeof(double),
 	  data.ndihedraltypes,fp);
 
   } else if (strcmp(data.dihedral_style,"harmonic") == 0) {
 
     data.dihedral_harmonic_k = new double[data.ndihedraltypes+1];
     data.dihedral_harmonic_multiplicity = new int[data.ndihedraltypes+1];
     data.dihedral_harmonic_sign = new int[data.ndihedraltypes+1];
     fread(&data.dihedral_harmonic_k[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_harmonic_multiplicity[1],sizeof(int),
 	  data.ndihedraltypes,fp);
     fread(&data.dihedral_harmonic_sign[1],sizeof(int),data.ndihedraltypes,fp);
 
   } else if (strcmp(data.dihedral_style,"helix") == 0) {
 
     data.dihedral_helix_aphi = new double[data.ndihedraltypes+1];
     data.dihedral_helix_bphi = new double[data.ndihedraltypes+1];
     data.dihedral_helix_cphi = new double[data.ndihedraltypes+1];
     fread(&data.dihedral_helix_aphi[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_helix_bphi[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_helix_cphi[1],sizeof(double),data.ndihedraltypes,fp);
 
   } else if (strcmp(data.dihedral_style,"multi/harmonic") == 0) {
 
     data.dihedral_multi_a1 = new double[data.ndihedraltypes+1];
     data.dihedral_multi_a2 = new double[data.ndihedraltypes+1];
     data.dihedral_multi_a3 = new double[data.ndihedraltypes+1];
     data.dihedral_multi_a4 = new double[data.ndihedraltypes+1];
     data.dihedral_multi_a5 = new double[data.ndihedraltypes+1];
     fread(&data.dihedral_multi_a1[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_multi_a2[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_multi_a3[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_multi_a4[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_multi_a5[1],sizeof(double),data.ndihedraltypes,fp);
 
   } else if (strcmp(data.dihedral_style,"opls") == 0) {
 
     data.dihedral_opls_k1 = new double[data.ndihedraltypes+1];
     data.dihedral_opls_k2 = new double[data.ndihedraltypes+1];
     data.dihedral_opls_k3 = new double[data.ndihedraltypes+1];
     data.dihedral_opls_k4 = new double[data.ndihedraltypes+1];
     fread(&data.dihedral_opls_k1[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_opls_k2[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_opls_k3[1],sizeof(double),data.ndihedraltypes,fp);
     fread(&data.dihedral_opls_k4[1],sizeof(double),data.ndihedraltypes,fp);
 
   } else if (strcmp(data.dihedral_style,"table") == 0) {
 
     int tabstyle = read_int(fp);
     int n = read_int(fp);
 
   } else if (strcmp(data.dihedral_style,"hybrid") == 0) {
 
     int nstyles = read_int(fp);
     for (int i = 0; i < nstyles; i++)
       char *substyle = read_char(fp);
 
   } else {
     printf("ERROR: Unknown dihedral style %s\n",data.dihedral_style);
     exit(1);
   }
 }
 
 // ---------------------------------------------------------------------
 // improper coeffs
 // one section for each improper style
 // ---------------------------------------------------------------------
 
 void improper(FILE *fp, Data &data)
 {
   if (strcmp(data.improper_style,"none") == 0) {
 
   } else if (strcmp(data.improper_style,"class2") == 0) {
 
     data.improper_class2_k0 = new double[data.nimpropertypes+1];
     data.improper_class2_chi0 = new double[data.nimpropertypes+1];
 
     data.improper_class2_aa_k1 = new double[data.nimpropertypes+1];
     data.improper_class2_aa_k2 = new double[data.nimpropertypes+1];
     data.improper_class2_aa_k3 = new double[data.nimpropertypes+1];
     data.improper_class2_aa_theta0_1 = new double[data.nimpropertypes+1];
     data.improper_class2_aa_theta0_2 = new double[data.nimpropertypes+1];
     data.improper_class2_aa_theta0_3 = new double[data.nimpropertypes+1];
 
     fread(&data.improper_class2_k0[1],sizeof(double),
 	  data.nimpropertypes,fp);
     fread(&data.improper_class2_chi0[1],sizeof(double),
 	  data.nimpropertypes,fp);
 
     fread(&data.improper_class2_aa_k1[1],sizeof(double),
 	  data.nimpropertypes,fp);
     fread(&data.improper_class2_aa_k2[1],sizeof(double),
 	  data.nimpropertypes,fp);
     fread(&data.improper_class2_aa_k3[1],sizeof(double),
 	  data.nimpropertypes,fp);
     fread(&data.improper_class2_aa_theta0_1[1],sizeof(double),
 	  data.nimpropertypes,fp);
     fread(&data.improper_class2_aa_theta0_2[1],sizeof(double),
 	  data.nimpropertypes,fp);
     fread(&data.improper_class2_aa_theta0_3[1],sizeof(double),
 	  data.nimpropertypes,fp);
 
   } else if (strcmp(data.improper_style,"cvff") == 0) {
 
     data.improper_cvff_k = new double[data.nimpropertypes+1];
     data.improper_cvff_sign = new int[data.nimpropertypes+1];
     data.improper_cvff_multiplicity = new int[data.nimpropertypes+1];
     fread(&data.improper_cvff_k[1],sizeof(double),data.nimpropertypes,fp);
     fread(&data.improper_cvff_sign[1],sizeof(int),data.nimpropertypes,fp);
     fread(&data.improper_cvff_multiplicity[1],sizeof(int),
 	  data.nimpropertypes,fp);
 
   } else if (strcmp(data.improper_style,"harmonic") == 0) {
 
     data.improper_harmonic_k = new double[data.nimpropertypes+1];
     data.improper_harmonic_chi = new double[data.nimpropertypes+1];
     fread(&data.improper_harmonic_k[1],sizeof(double),data.nimpropertypes,fp);
     fread(&data.improper_harmonic_chi[1],sizeof(double),
 	  data.nimpropertypes,fp);
 
   } else if (strcmp(data.improper_style,"hybrid") == 0) {
 
     int nstyles = read_int(fp);
     for (int i = 0; i < nstyles; i++)
       char *substyle = read_char(fp);
 
   } else {
     printf("ERROR: Unknown improper style %s\n",data.improper_style);
     exit(1);
   }
 }
 
 // ---------------------------------------------------------------------
 // initialize Data
 // ---------------------------------------------------------------------
 
 Data::Data() {}
 
 // ---------------------------------------------------------------------
 // print out stats on problem
 // ---------------------------------------------------------------------
 
 void Data::stats()
 {
+  char fstr[64];
+
   printf("  Restart file version = %s\n",version);
-  printf("  Ntimestep = %d\n",ntimestep);
+  sprintf(fstr,"  Ntimestep = %s\n",BIGINT_FORMAT);
+  printf(fstr,ntimestep);
+
   printf("  Nprocs = %d\n",nprocs);
-  printf("  Natoms = %lu\n",natoms);
-  printf("  Nbonds = %lu\n",nbonds);
-  printf("  Nangles = %lu\n",nangles);
-  printf("  Ndihedrals = %lu\n",ndihedrals);
-  printf("  Nimpropers = %lu\n",nimpropers);
+
+  sprintf(fstr,"  Natoms = %s\n",BIGINT_FORMAT);
+  printf(fstr,natoms);
+  sprintf(fstr,"  Nbonds = %s\n",BIGINT_FORMAT);
+  printf(fstr,nbonds);
+  sprintf(fstr,"  Nangles = %s\n",BIGINT_FORMAT);
+  printf(fstr,nangles);
+  sprintf(fstr,"  Ndihedrals = %s\n",BIGINT_FORMAT);
+  printf(fstr,ndihedrals);
+  sprintf(fstr,"  Nimpropers = %s\n",BIGINT_FORMAT);
+  printf(fstr,nimpropers);
+
   printf("  Unit style = %s\n",unit_style);
   printf("  Atom style = %s\n",atom_style);
   printf("  Pair style = %s\n",pair_style);
   printf("  Bond style = %s\n",bond_style);
   printf("  Angle style = %s\n",angle_style);
   printf("  Dihedral style = %s\n",dihedral_style);
   printf("  Improper style = %s\n",improper_style);
   printf("  Xlo xhi = %g %g\n",xlo,xhi);
   printf("  Ylo yhi = %g %g\n",ylo,yhi);
   printf("  Zlo zhi = %g %g\n",zlo,zhi);
   if (triclinic) printf("  Xy xz yz = %g %g %g\n",xy,xz,yz);
   printf("  Periodicity = %d %d %d\n",xperiodic,yperiodic,zperiodic);
   printf("  Boundary = %d %d, %d %d, %d %d\n",boundary[0][0],boundary[0][1],
 	 boundary[1][0],boundary[1][1],boundary[2][0],boundary[2][1]);
 }
 
 // ---------------------------------------------------------------------
-// write the data file
+// write the data file and input file
 // ---------------------------------------------------------------------
 
 void Data::write(FILE *fp, FILE *fp2)
 {
-  fprintf(fp,"LAMMPS data file from restart file: timestep = %d, procs = %d\n",
-	  ntimestep,nprocs);
-
+  char fstr[128];
+  sprintf(fstr,
+	  "LAMMPS data file from restart file: timestep = %s, procs = %%d\n",
+	  BIGINT_FORMAT);
+  fprintf(fp,fstr,ntimestep,nprocs);
   fprintf(fp,"\n");
 
-  fprintf(fp,"%lu atoms\n",natoms);
-  if (nbonds) fprintf(fp,"%lu bonds\n",nbonds);
-  if (nangles) fprintf(fp,"%lu angles\n",nangles);
-  if (ndihedrals) fprintf(fp,"%lu dihedrals\n",ndihedrals);
-  if (nimpropers) fprintf(fp,"%lu impropers\n",nimpropers);
+  sprintf(fstr,"%s atoms\n",BIGINT_FORMAT);
+  fprintf(fp,fstr,natoms);
+  if (nbonds) {
+    sprintf(fstr,"%s bonds\n",BIGINT_FORMAT);
+    fprintf(fp,fstr,nbonds);
+  }
+  if (nangles) {
+    sprintf(fstr,"%s angles\n",BIGINT_FORMAT);
+    fprintf(fp,fstr,nangles);
+  }
+  if (ndihedrals) {
+    sprintf(fstr,"%s dihedrals\n",BIGINT_FORMAT);
+    fprintf(fp,fstr,ndihedrals);
+  }
+  if (nimpropers) {
+    sprintf(fstr,"%s impropers\n",BIGINT_FORMAT);
+    fprintf(fp,fstr,nimpropers);
+  }
 
   fprintf(fp,"\n");
 
   fprintf(fp,"%d atom types\n",ntypes);
   if (nbondtypes) fprintf(fp,"%d bond types\n",nbondtypes);
   if (nangletypes) fprintf(fp,"%d angle types\n",nangletypes);
   if (ndihedraltypes) fprintf(fp,"%d dihedral types\n",ndihedraltypes);
   if (nimpropertypes) fprintf(fp,"%d improper types\n",nimpropertypes);
 
   fprintf(fp,"\n");
 
   fprintf(fp,"%-1.16e %-1.16e xlo xhi\n",xlo,xhi);
   fprintf(fp,"%-1.16e %-1.16e ylo yhi\n",ylo,yhi);
   fprintf(fp,"%-1.16e %-1.16e zlo zhi\n",zlo,zhi);
   if (triclinic) fprintf(fp,"%-1.16e %-1.16e %-1.16e xy xz yz\n",xy,xz,yz);
 
   // write ff styles to input file
 
   if (fp2) {
-    fprintf(fp2,"# LAMMPS input file from restart file: timestep = %d, procs = %d\n\n",
-	  ntimestep,nprocs);
+    sprintf(fstr,
+	    "# LAMMPS input file from restart file: "
+	    "timestep = %s, procs = %%d\n\n",
+	    BIGINT_FORMAT);
+    fprintf(fp2,fstr,ntimestep,nprocs);
+
     if (pair_style) fprintf(fp2,"pair_style %s\n",pair_style);
     if (bond_style) fprintf(fp2,"bond_style %s\n",bond_style);
     if (angle_style) fprintf(fp2,"angle_style %s\n",angle_style);
     if (dihedral_style) fprintf(fp2,"dihedral_style %s\n",dihedral_style);
     if (improper_style) fprintf(fp2,"improper_style %s\n",improper_style);
     fprintf(fp2,"special_bonds %g %g %g %g %g %g\n",
             special_lj[1],special_lj[2],special_lj[3],
             special_lj[1],special_coul[2],special_coul[3]);
     fprintf(fp2,"\n");
   }
 
   // mass to either data file or input file
 
   if (mass) {
     if (fp2) {
       fprintf(fp2,"\n");
       for (int i = 1; i <= ntypes; i++) fprintf(fp2,"mass %d %g\n",i,mass[i]);
       fprintf(fp2,"\n");
     } else {
       fprintf(fp,"\nMasses\n\n");
       for (int i = 1; i <= ntypes; i++) fprintf(fp,"%d %g\n",i,mass[i]);
     }
   }
 
   // shape and dipole to data file
   // convert shape from radius to diameter
 
   if (shape) {
     fprintf(fp,"\nShapes\n\n");
     for (int i = 1; i <= ntypes; i++)
       fprintf(fp,"%d %g %g %g\n",i,
 	      2.0*shape[3*i+0],2.0*shape[3*i+1],2.0*shape[3*i+2]);
   }
 
   if (dipole) {
     fprintf(fp,"\nDipoles\n\n");
     for (int i = 1; i <= ntypes; i++) fprintf(fp,"%d %g\n",i,dipole[i]);
   }
 
   // pair coeffs to data file
 
   if (pair_style && fp2 == NULL) {
     if ((strcmp(pair_style,"none") != 0) &&
 	(strcmp(pair_style,"airebo") != 0) &&
 	(strcmp(pair_style,"coul/cut") != 0) &&
 	(strcmp(pair_style,"coul/debye") != 0) &&
 	(strcmp(pair_style,"coul/long") != 0) &&
 	(strcmp(pair_style,"eam") != 0) &&
 	(strcmp(pair_style,"eam/opt") != 0) &&
 	(strcmp(pair_style,"eam/alloy") != 0) &&
 	(strcmp(pair_style,"eam/alloy/opt") != 0) &&
 	(strcmp(pair_style,"eam/fs") != 0) &&
 	(strcmp(pair_style,"eam/fs/opt") != 0) &&
 	(strcmp(pair_style,"eim") != 0) &&
 	(strcmp(pair_style,"eff/cut") != 0) &&
 	(strcmp(pair_style,"gran/history") != 0) &&
 	(strcmp(pair_style,"gran/no_history") != 0) &&
 	(strcmp(pair_style,"gran/hertzian") != 0) &&
 	(strcmp(pair_style,"meam") != 0) &&
 	(strcmp(pair_style,"reax") != 0) &&
 	(strcmp(pair_style,"reax/c") != 0) &&
 	(strcmp(pair_style,"sw") != 0) &&
 	(strcmp(pair_style,"table") != 0) &&
 	(strcmp(pair_style,"tersoff") != 0) &&
 	(strcmp(pair_style,"tersoff/zbl") != 0) &&
 	(strcmp(pair_style,"hybrid") != 0) &&
 	(strcmp(pair_style,"hybrid/overlay") != 0))
       fprintf(fp,"\nPair Coeffs\n\n");
 
     if (strcmp(pair_style,"born/coul/long") == 0) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g %g %g %g\n",i,
 		pair_born_A[i],pair_born_rho[i],pair_born_sigma[i],
 		pair_born_C[i],pair_born_D[i]);
 
     } else if ((strcmp(pair_style,"buck") == 0) ||
 	(strcmp(pair_style,"buck/coul/cut") == 0) ||
 	(strcmp(pair_style,"buck/coul/long") == 0) ||
 	(strcmp(pair_style,"buck/long") == 0)) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g %g\n",i,
 		pair_buck_A[i],pair_buck_rho[i],pair_buck_C[i]);
 
     } else if (strcmp(pair_style,"colloid") == 0) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g %g %g\n",i,
 		pair_colloid_A12[i],pair_colloid_sigma[i],
 		pair_colloid_d2[i],pair_colloid_d2[i]);
 
     } else if (strcmp(pair_style,"dipole/cut") == 0) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g\n",i,
 		pair_dipole_epsilon[i],pair_dipole_sigma[i]);
 
     } else if (strcmp(pair_style,"dpd") == 0) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g\n",i,
 		pair_dpd_a0[i],pair_dpd_gamma[i]);
 
     } else if (strcmp(pair_style,"dpd/tstat") == 0) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g\n",i,
 		pair_dpd_gamma[i]);
 
     } else if ((strcmp(pair_style,"gayberne") == 0) ||
 	       (strcmp(pair_style,"gayberne/gpu") == 0)) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g %g %g %g %g %g %g\n",i,
 		pair_gb_epsilon[i],pair_gb_sigma[i],
 		pair_gb_epsa[i],pair_gb_epsb[i],pair_gb_epsc[i],
 		pair_gb_epsa[i],pair_gb_epsb[i],pair_gb_epsc[i]);
 
     } else if ((strcmp(pair_style,"lj/charmm/coul/charmm") == 0) ||
 	       (strcmp(pair_style,"lj/charmm/coul/charmm/implicit") == 0) ||
 	       (strcmp(pair_style,"lj/charmm/coul/long") == 0) ||
 	       (strcmp(pair_style,"lj/charmm/coul/long") == 0)) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g %g %g\n",i,
 		pair_charmm_epsilon[i],pair_charmm_sigma[i],
 		pair_charmm_eps14[i],pair_charmm_sigma14[i]);
 
     } else if ((strcmp(pair_style,"lj/class2") == 0) ||
 	       (strcmp(pair_style,"lj/class2/coul/cut") == 0) ||
 	       (strcmp(pair_style,"lj/class2/coul/long") == 0)) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g\n",i,
 		pair_class2_epsilon[i],pair_class2_sigma[i]);
 
     } else if ((strcmp(pair_style,"lj/cut") == 0) ||
 	       (strcmp(pair_style,"lj/cut/gpu") == 0) ||
 	       (strcmp(pair_style,"lj/cut/opt") == 0) ||
 	       (strcmp(pair_style,"lj/cut/coul/cut") == 0) ||
 	       (strcmp(pair_style,"lj/cut/coul/cut/gpu") == 0) ||
 	       (strcmp(pair_style,"lj/cut/coul/debye") == 0) ||
 	       (strcmp(pair_style,"lj/cut/coul/long") == 0) ||
 	       (strcmp(pair_style,"lj/cut/coul/long/gpu") == 0) ||
 	       (strcmp(pair_style,"lj/cut/coul/long/tip4p") == 0) ||
 	       (strcmp(pair_style,"lj/coul") == 0)) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g\n",i,
 		pair_lj_epsilon[i],pair_lj_sigma[i]);
 
     } else if (strcmp(pair_style,"lj/expand") == 0) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g %g\n",i,
 		pair_ljexpand_epsilon[i],pair_ljexpand_sigma[i],
 		pair_ljexpand_shift[i]);
 
     } else if ((strcmp(pair_style,"lj/gromacs") == 0) ||
 	       (strcmp(pair_style,"lj/gromacs/coul/gromacs") == 0)) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g\n",i,
 		pair_ljgromacs_epsilon[i],pair_ljgromacs_sigma[i]);
 
     } else if (strcmp(pair_style,"lj/smooth") == 0) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g\n",i,
 		pair_ljsmooth_epsilon[i],pair_ljsmooth_sigma[i]);
 
     } else if ((strcmp(pair_style,"morse") == 0) ||
 	       (strcmp(pair_style,"morse/opt") == 0)) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g %g %g\n",i,
 		pair_morse_d0[i],pair_morse_alpha[i],pair_morse_r0[i]);
 
     } else if (strcmp(pair_style,"soft") == 0) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g\n",i,
 		pair_soft_A[i]);
 
     } else if (strcmp(pair_style,"yukawa") == 0) {
       for (int i = 1; i <= ntypes; i++)
 	fprintf(fp,"%d %g\n",i,
 		pair_yukawa_A[i]);
 
     } else if ((strcmp(pair_style,"cg/cmm") == 0) ||
                (strcmp(pair_style,"cg/cmm/coul/cut") == 0) ||
                (strcmp(pair_style,"cg/cmm/coul/long") == 0)) {
       printf("ERROR: Cannot write pair_style %s to data file\n",
 	     pair_style);
       exit(1);
     }
   }
 
   // pair coeffs to input file
   // only supported styles = cg/cmm
 
   if (pair_style && fp2) {
     if ((strcmp(pair_style,"cg/cmm") == 0) ||
 	(strcmp(pair_style,"cg/cmm/gpu") == 0) ||
 	(strcmp(pair_style,"cg/cmm/coul/cut") == 0) ||
 	(strcmp(pair_style,"cg/cmm/coul/long") == 0) ||
 	(strcmp(pair_style,"cg/cmm/coul/long/gpu") == 0)) {
       for (int i = 1; i <= ntypes; i++) {
 	for (int j = i; j <= ntypes; j++) {
 	  fprintf(fp2,"pair_coeff %d %d %s %g %g\n",i,j,
 		  cg_type_list[pair_cg_cmm_type[i][j]],
 		  pair_cg_epsilon[i][j],pair_cg_sigma[i][j]);
 	}
       }
 
     } else {
       printf("ERROR: Cannot write pair_style %s to input file\n",
 	     pair_style);
       exit(1);
     }
   }
 
   // bond coeffs to data file
 
   if (bond_style && fp2 == NULL) {
     if ((strcmp(bond_style,"none") != 0) &&
 	(strcmp(bond_style,"table") != 0) &&
 	(strcmp(bond_style,"hybrid") != 0))
       fprintf(fp,"\nBond Coeffs\n\n");
 
     if (strcmp(bond_style,"class2") == 0) {
       for (int i = 1; i <= nbondtypes; i++)
 	fprintf(fp,"%d %g %g %g %g\n",i,
 		bond_class2_r0[i],bond_class2_k2[i],
 		bond_class2_k3[i],bond_class2_k4[i]);
 
     } else if (strcmp(bond_style,"fene") == 0) {
       for (int i = 1; i <= nbondtypes; i++)
 	fprintf(fp,"%d %g %g %g %g\n",i,
 		bond_fene_k[i],bond_fene_r0[i],
 		bond_fene_epsilon[i],bond_fene_sigma[i]);
 
     } else if (strcmp(bond_style,"fene/expand") == 0) {
       for (int i = 1; i <= nbondtypes; i++)
 	fprintf(fp,"%d %g %g %g %g %g\n",i,
 		bond_feneexpand_k[i],bond_feneexpand_r0[i],
 		bond_feneexpand_epsilon[i],bond_feneexpand_sigma[i],
 		bond_feneexpand_shift[i]);
 
     } else if (strcmp(bond_style,"harmonic") == 0) {
       for (int i = 1; i <= nbondtypes; i++)
 	fprintf(fp,"%d %g %g\n",i,
 		bond_harmonic_k[i],bond_harmonic_r0[i]);
 
     } else if (strcmp(bond_style,"morse") == 0) {
       for (int i = 1; i <= nbondtypes; i++)
 	fprintf(fp,"%d %g %g %g\n",i,
 		bond_morse_d0[i],bond_morse_alpha[i],bond_morse_r0[i]);
 
     } else if (strcmp(bond_style,"nonlinear") == 0) {
       for (int i = 1; i <= nbondtypes; i++)
 	fprintf(fp,"%d %g %g %g\n",i,
 		bond_nonlinear_epsilon[i],bond_nonlinear_r0[i],
 		bond_nonlinear_lamda[i]);
 
     } else if (strcmp(bond_style,"quartic") == 0) {
       for (int i = 1; i <= nbondtypes; i++)
         fprintf(fp,"%d %g %g %g %g %g\n",i,
                 bond_quartic_k[i],bond_quartic_b1[i],bond_quartic_b2[i],
                 bond_quartic_rc[i],bond_quartic_u0[i]);
     }
   }
 
   // bond coeffs to input file
   // only supported styles = harmonic
 
   if (bond_style && fp2) {
     if (strcmp(bond_style,"harmonic") == 0) {
       for (int i = 1; i <= nbondtypes; i++)
 	fprintf(fp2,"bond_coeff  %d %g %g\n",i,
 		bond_harmonic_k[i],bond_harmonic_r0[i]);
 
     } else {
       printf("ERROR: Cannot write bond_style %s to input file\n",
 	     bond_style);
       exit(1);
     }
   }
 
   // angle coeffs to data file
 
   if (angle_style && fp2 == NULL) {
     double PI = 3.1415926;           // convert back to degrees
 
     if ((strcmp(angle_style,"none") != 0) &&
 	(strcmp(angle_style,"table") != 0) &&
 	(strcmp(angle_style,"hybrid") != 0))
       fprintf(fp,"\nAngle Coeffs\n\n");
 
     if (strcmp(angle_style,"charmm") == 0) {
       for (int i = 1; i <= nangletypes; i++)
 	fprintf(fp,"%d %g %g %g %g\n",i,
 		angle_charmm_k[i],angle_charmm_theta0[i]/PI*180.0,
 		angle_charmm_k_ub[i],angle_charmm_r_ub[i]);
 
     } else if (strcmp(angle_style,"class2") == 0) {
       for (int i = 1; i <= nangletypes; i++)
 	fprintf(fp,"%d %g %g %g %g\n",i,
 		angle_class2_theta0[i]/PI*180.0,angle_class2_k2[i],
 		angle_class2_k3[i],angle_class2_k4[i]);
 
       fprintf(fp,"\nBondBond Coeffs\n\n");
       for (int i = 1; i <= nangletypes; i++)
 	fprintf(fp,"%d %g %g %g\n",i,
 		angle_class2_bb_k[i],
 		angle_class2_bb_r1[i],angle_class2_bb_r2[i]);
 
       fprintf(fp,"\nBondAngle Coeffs\n\n");
       for (int i = 1; i <= nangletypes; i++)
 	fprintf(fp,"%d %g %g %g %g\n",i,
 		angle_class2_ba_k1[i],angle_class2_ba_k2[i],
 		angle_class2_ba_r1[i],angle_class2_ba_r2[i]);
 
     } else if (strcmp(angle_style,"cosine") == 0) {
       for (int i = 1; i <= nangletypes; i++)
 	fprintf(fp,"%d %g\n",i,angle_cosine_k[i]);
 
     } else if ((strcmp(angle_style,"cosine/squared") == 0) ||
                (strcmp(angle_style,"cosine/delta") == 0)) {
       for (int i = 1; i <= nangletypes; i++)
 	fprintf(fp,"%d %g %g\n",i,
 		angle_cosine_squared_k[i],
 		angle_cosine_squared_theta0[i]/PI*180.0);
 
     } else if (strcmp(angle_style,"harmonic") == 0) {
       for (int i = 1; i <= nangletypes; i++)
 	fprintf(fp,"%d %g %g\n",i,
 		angle_harmonic_k[i],angle_harmonic_theta0[i]/PI*180.0);
 
     } else if (strcmp(angle_style,"cg/cmm") == 0) {
       for (int i = 1; i <= nangletypes; i++)
 	fprintf(fp,"%d %g %g %s %g %g\n",i,
 		angle_harmonic_k[i],angle_harmonic_theta0[i]/PI*180.0,
 		cg_type_list[angle_cg_cmm_type[i]],angle_cg_cmm_epsilon[i],
 		angle_cg_cmm_sigma[i]);
     }
   }
 
   // angle coeffs to input file
   // only supported styles = cosine/squared, harmonic, cg/cmm
 
   if (angle_style && fp2) {
     double PI = 3.1415926;           // convert back to degrees
 
     if ((strcmp(angle_style,"cosine/squared") == 0) ||
         (strcmp(angle_style,"cosine/delta") == 0)) {
       for (int i = 1; i <= nangletypes; i++)
 	fprintf(fp2,"angle_coeffs  %d %g %g\n",i,
 		angle_cosine_squared_k[i],
 		angle_cosine_squared_theta0[i]/PI*180.0);
 
     } else if (strcmp(angle_style,"harmonic") == 0) {
       for (int i = 1; i <= nangletypes; i++)
 	fprintf(fp2,"angle_coeffs  %d %g %g\n",i,
 		angle_harmonic_k[i],angle_harmonic_theta0[i]/PI*180.0);
 
     } else if (strcmp(angle_style,"cg/cmm") == 0) {
       for (int i = 1; i <= nangletypes; i++)
 	fprintf(fp2,"angle_coeffs  %d %g %g %s %g %g\n",i,
 		angle_harmonic_k[i],angle_harmonic_theta0[i]/PI*180.0,
 		cg_type_list[angle_cg_cmm_type[i]],angle_cg_cmm_epsilon[i],
 		angle_cg_cmm_sigma[i]);
 
     } else {
       printf("ERROR: Cannot write angle_style %s to input file\n",
 	     angle_style);
       exit(1);
     }
   }
 
   if (dihedral_style) {
     double PI = 3.1415926;           // convert back to degrees
 
     if ((strcmp(dihedral_style,"none") != 0) &&
 	(strcmp(dihedral_style,"table") != 0) &&
 	(strcmp(dihedral_style,"hybrid") != 0))
       fprintf(fp,"\nDihedral Coeffs\n\n");
 
     if (strcmp(dihedral_style,"charmm") == 0) {
       for (int i = 1; i <= ndihedraltypes; i++)
 	fprintf(fp,"%d %g %d %d %g\n",i,
 		dihedral_charmm_k[i],dihedral_charmm_multiplicity[i],
 		dihedral_charmm_sign[i],dihedral_charmm_weight[i]);
 
     } else if (strcmp(dihedral_style,"class2") == 0) {
       for (int i = 1; i <= ndihedraltypes; i++)
 	fprintf(fp,"%d %g %g %g %g %g %g\n",i,
 		dihedral_class2_k1[i],
 		dihedral_class2_phi1[i]/PI*180.0,
 		dihedral_class2_k2[i],
 		dihedral_class2_phi2[i]/PI*180.0,
 		dihedral_class2_k3[i],
 		dihedral_class2_phi3[i]/PI*180.0);
 
       fprintf(fp,"\nMiddleBondTorsion Coeffs\n\n");
       for (int i = 1; i <= ndihedraltypes; i++)
 	fprintf(fp,"%d %g %g %g %g\n",i,
 		dihedral_class2_mbt_f1[i],dihedral_class2_mbt_f2[i],
 		dihedral_class2_mbt_f3[i],dihedral_class2_mbt_r0[i]);
 
       fprintf(fp,"\nEndBondTorsion Coeffs\n\n");
       for (int i = 1; i <= ndihedraltypes; i++)
 	fprintf(fp,"%d %g %g %g %g %g %g %g %g\n",i,
 		dihedral_class2_ebt_f1_1[i],dihedral_class2_ebt_f2_1[i],
 		dihedral_class2_ebt_f3_1[i],
 		dihedral_class2_ebt_f1_2[i],dihedral_class2_ebt_f2_2[i],
 		dihedral_class2_ebt_f3_2[i],
 		dihedral_class2_ebt_r0_1[i],
 		dihedral_class2_ebt_r0_2[i]);
 
       fprintf(fp,"\nAngleTorsion Coeffs\n\n");
       for (int i = 1; i <= ndihedraltypes; i++)
 	fprintf(fp,"%d %g %g %g %g %g %g %g %g\n",i,
 		dihedral_class2_at_f1_1[i],dihedral_class2_at_f2_1[i],
 		dihedral_class2_at_f3_1[i],
 		dihedral_class2_at_f1_2[i],dihedral_class2_at_f2_2[i],
 		dihedral_class2_at_f3_2[i],
 		dihedral_class2_at_theta0_1[i]/PI*180.0,
 		dihedral_class2_at_theta0_2[i]/PI*180.0);
 
       fprintf(fp,"\nAngleAngleTorsion Coeffs\n\n");
       for (int i = 1; i <= ndihedraltypes; i++)
 	fprintf(fp,"%d %g %g %g\n",i,
 		dihedral_class2_aat_k[i],
 		dihedral_class2_aat_theta0_1[i]/PI*180.0,
 		dihedral_class2_aat_theta0_2[i]/PI*180.0);
 
       fprintf(fp,"\nBondBond13 Coeffs\n\n");
       for (int i = 1; i <= ndihedraltypes; i++)
 	fprintf(fp,"%d %g %g %g\n",i,
 		dihedral_class2_bb13_k[i],
 		dihedral_class2_bb13_r10[i],dihedral_class2_bb13_r30[i]);
 
     } else if (strcmp(dihedral_style,"harmonic") == 0) {
       for (int i = 1; i <= ndihedraltypes; i++)
 	fprintf(fp,"%d %g %d %d\n",i,
 		dihedral_harmonic_k[i],dihedral_harmonic_multiplicity[i],
 		dihedral_harmonic_sign[i]);
 
     } else if (strcmp(dihedral_style,"helix") == 0) {
       for (int i = 1; i <= ndihedraltypes; i++)
 	fprintf(fp,"%d %g %g %g\n",i,dihedral_helix_aphi[i],
 		dihedral_helix_bphi[i],dihedral_helix_cphi[i]);
 
     } else if (strcmp(dihedral_style,"multi/harmonic") == 0) {
       for (int i = 1; i <= ndihedraltypes; i++)
 	fprintf(fp,"%d %g %g %g %g %g\n",i,
 		dihedral_multi_a1[i],dihedral_multi_a2[i],
 		dihedral_multi_a3[i],dihedral_multi_a4[i],
 		dihedral_multi_a5[i]);
 
     } else if (strcmp(dihedral_style,"opls") == 0) {
       for (int i = 1; i <= ndihedraltypes; i++)        // restore factor of 2
 	fprintf(fp,"%d %g %g %g %g\n",i,
 		2.0*dihedral_opls_k1[i],2.0*dihedral_opls_k2[i],
 		2.0*dihedral_opls_k3[i],2.0*dihedral_opls_k4[i]);
     }
   }
 
   if (improper_style) {
     double PI = 3.1415926;           // convert back to degrees
 
     if ((strcmp(improper_style,"none") != 0) &&
 	(strcmp(improper_style,"hybrid") != 0))
       fprintf(fp,"\nImproper Coeffs\n\n");
 
     if (strcmp(improper_style,"class2") == 0) {
       for (int i = 1; i <= nimpropertypes; i++)
 	fprintf(fp,"%d %g %g\n",i,
 		improper_class2_k0[i],improper_class2_chi0[i]/PI*180.0);
 
       fprintf(fp,"\nAngleAngle Coeffs\n\n");
       for (int i = 1; i <= nimpropertypes; i++)
 	fprintf(fp,"%d %g %g %g %g %g %g\n",i,
 		improper_class2_aa_k1[i],improper_class2_aa_k2[i],
 		improper_class2_aa_k3[i],
 		improper_class2_aa_theta0_1[i]/PI*180.0,
 		improper_class2_aa_theta0_2[i]/PI*180.0,
 		improper_class2_aa_theta0_3[i]/PI*180.0);
 
     } else if (strcmp(improper_style,"cvff") == 0) {
       for (int i = 1; i <= nimpropertypes; i++)
 	fprintf(fp,"%d %g %d %d\n",i,
 		improper_cvff_k[i],improper_cvff_sign[i],
 		improper_cvff_multiplicity[i]);
 
     } else if (strcmp(improper_style,"harmonic") == 0) {
       for (int i = 1; i <= nimpropertypes; i++)
 	fprintf(fp,"%d %g %g\n",i,
 		improper_harmonic_k[i],improper_harmonic_chi[i]/PI*180.0);
     }
   }
 
   if (natoms) {
     fprintf(fp,"\nAtoms\n\n");
 
     int ix,iy,iz;
     for (uint64_t i = 0; i < natoms; i++) {
 
       ix = (image[i] & 1023) - 512;
       iy = (image[i] >> 10 & 1023) - 512;
       iz = (image[i] >> 20) - 512;
 
       if (style_hybrid == 0) {
 	if (style_angle) write_atom_angle(fp,i,ix,iy,iz);
 	if (style_atomic) write_atom_atomic(fp,i,ix,iy,iz);
 	if (style_bond) write_atom_bond(fp,i,ix,iy,iz);
 	if (style_charge) write_atom_charge(fp,i,ix,iy,iz);
 	if (style_dipole) write_atom_dipole(fp,i,ix,iy,iz);
 	if (style_ellipsoid) write_atom_ellipsoid(fp,i,ix,iy,iz);
 	if (style_full) write_atom_full(fp,i,ix,iy,iz);
 	if (style_granular) write_atom_granular(fp,i,ix,iy,iz);
 	if (style_molecular) write_atom_molecular(fp,i,ix,iy,iz);
 	if (style_peri) write_atom_peri(fp,i,ix,iy,iz);
 	fprintf(fp,"\n");
 
       } else {
 	fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e",
 		tag[i],type[i],x[i],y[i],z[i]);
 	for (int k = 1; k <= style_hybrid; k++) {
 	  if (k == style_angle) write_atom_angle_extra(fp,i);
 	  if (k == style_atomic) write_atom_atomic_extra(fp,i);
 	  if (k == style_bond) write_atom_bond_extra(fp,i);
 	  if (k == style_charge) write_atom_charge_extra(fp,i);
 	  if (k == style_dipole) write_atom_dipole_extra(fp,i);
 	  if (k == style_ellipsoid) write_atom_ellipsoid_extra(fp,i);
 	  if (k == style_full) write_atom_full_extra(fp,i);
 	  if (k == style_granular) write_atom_granular_extra(fp,i);
 	  if (k == style_molecular) write_atom_molecular_extra(fp,i);
 	  if (k == style_peri) write_atom_peri_extra(fp,i);
 	}
 	fprintf(fp," %d %d %d\n",ix,iy,iz);
       }
     }
   }
 
   if (natoms) {
     fprintf(fp,"\nVelocities\n\n");
     for (uint64_t i = 0; i < natoms; i++)
 
       if (style_hybrid == 0) {
 	if (style_angle) write_vel_angle(fp,i);
 	if (style_atomic) write_vel_atomic(fp,i);
 	if (style_bond) write_vel_bond(fp,i);
 	if (style_charge) write_vel_charge(fp,i);
 	if (style_dipole) write_vel_dipole(fp,i);
 	if (style_ellipsoid) write_vel_ellipsoid(fp,i);
 	if (style_full) write_vel_full(fp,i);
 	if (style_granular) write_vel_granular(fp,i);
 	if (style_molecular) write_vel_molecular(fp,i);
 	if (style_peri) write_vel_peri(fp,i);
 	fprintf(fp,"\n");
 
       } else {
 	fprintf(fp,"%d %-1.16e %-1.16e %-1.16e",tag[i],vx[i],vy[i],vz[i]);
 	for (int k = 1; k <= style_hybrid; k++) {
 	  if (k == style_angle) write_vel_angle_extra(fp,i);
 	  if (k == style_atomic) write_vel_atomic_extra(fp,i);
 	  if (k == style_bond) write_vel_bond_extra(fp,i);
 	  if (k == style_charge) write_vel_charge_extra(fp,i);
 	  if (k == style_dipole) write_vel_dipole_extra(fp,i);
 	  if (k == style_ellipsoid) write_vel_ellipsoid_extra(fp,i);
 	  if (k == style_full) write_vel_full_extra(fp,i);
 	  if (k == style_granular) write_vel_granular_extra(fp,i);
 	  if (k == style_molecular) write_vel_molecular_extra(fp,i);
 	  if (k == style_peri) write_vel_peri_extra(fp,i);
 	}
 	fprintf(fp,"\n");
       }
   }
 
   if (nbonds) {
     fprintf(fp,"\nBonds\n\n");
     for (uint64_t i = 0; i < nbonds; i++)
       fprintf(fp,"%d %d %d %d\n",
 	      i+1,bond_type[i],bond_atom1[i],bond_atom2[i]);
   }
 
   if (nangles) {
     fprintf(fp,"\nAngles\n\n");
     for (uint64_t i = 0; i < nangles; i++)
       fprintf(fp,"%d %d %d %d %d\n",
 	      i+1,angle_type[i],angle_atom1[i],angle_atom2[i],angle_atom3[i]);
   }
 
   if (ndihedrals) {
     fprintf(fp,"\nDihedrals\n\n");
     for (uint64_t i = 0; i < ndihedrals; i++)
       fprintf(fp,"%d %d %d %d %d %d\n",
 	      i+1,dihedral_type[i],dihedral_atom1[i],dihedral_atom2[i],
 	      dihedral_atom3[i],dihedral_atom4[i]);
   }
 
   if (nimpropers) {
     fprintf(fp,"\nImpropers\n\n");
     for (uint64_t i = 0; i < nimpropers; i++)
       fprintf(fp,"%d %d %d %d %d %d\n",
 	      i+1,improper_type[i],improper_atom1[i],improper_atom2[i],
 	      improper_atom3[i],improper_atom4[i]);
   }
 }
 
 // ---------------------------------------------------------------------
 // per-atom write routines
 // one routine per atom style
 // ---------------------------------------------------------------------
 
 void Data::write_atom_angle(FILE *fp, int i, int ix, int iy, int iz)
 {
   fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %d %d %d",
 	  tag[i],molecule[i],type[i],x[i],y[i],z[i],ix,iy,iz);
 }
 
 void Data::write_atom_atomic(FILE *fp, int i, int ix, int iy, int iz)
 {
   fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %d %d %d",
 	  tag[i],type[i],x[i],y[i],z[i],ix,iy,iz);
 }
 
 void Data::write_atom_bond(FILE *fp, int i, int ix, int iy, int iz)
 {
   fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %d %d %d",
 	  tag[i],molecule[i],type[i],x[i],y[i],z[i],ix,iy,iz);
 }
 
 void Data::write_atom_charge(FILE *fp, int i, int ix, int iy, int iz)
 {
   fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d",
 	  tag[i],type[i],q[i],x[i],y[i],z[i],ix,iy,iz);
 }
 
 void Data::write_atom_dipole(FILE *fp, int i, int ix, int iy, int iz)
 {
   fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d",
 	  tag[i],type[i],q[i],x[i],y[i],z[i],mux[i],muy[i],muz[i],ix,iy,iz);
 }
 
 void Data::write_atom_ellipsoid(FILE *fp, int i, int ix, int iy, int iz)
 {
   fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d",
 	  tag[i],type[i],x[i],y[i],z[i],
 	  quatw[i],quati[i],quatj[i],quatk[i],ix,iy,iz);
 }
 
 void Data::write_atom_full(FILE *fp, int i, int ix, int iy, int iz)
 {
   fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d",
 	  tag[i],molecule[i],type[i],q[i],x[i],y[i],z[i],ix,iy,iz);
 }
 
 void Data::write_atom_granular(FILE *fp, int i, int ix, int iy, int iz)
 {
   fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d",
 	  tag[i],type[i],2.0*radius[i],density[i],x[i],y[i],z[i],ix,iy,iz);
 }
 
 void Data::write_atom_molecular(FILE *fp, int i, int ix, int iy, int iz)
 {
   fprintf(fp,"%d %d %d %-1.16e %-1.16e %-1.16e %d %d %d",
 	  tag[i],molecule[i],type[i],x[i],y[i],z[i],ix,iy,iz);
 }
 
 void Data::write_atom_peri(FILE *fp, int i, int ix, int iy, int iz)
 {
   fprintf(fp,"%d %d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %d %d %d",
 	  tag[i],type[i],vfrac[i],density[i],rmass[i],x[i],y[i],z[i],ix,iy,iz);
 }
 
 // ---------------------------------------------------------------------
 // per-atom write routines of extra quantities unique to style
 // one routine per atom style
 // ---------------------------------------------------------------------
 
 void Data::write_atom_angle_extra(FILE *fp, int i)
 {
   fprintf(fp," %d",molecule[i]);
 }
 
 void Data::write_atom_atomic_extra(FILE *fp, int i) {}
 
 void Data::write_atom_bond_extra(FILE *fp, int i)
 {
   fprintf(fp," %d",molecule[i]);
 }
 
 void Data::write_atom_charge_extra(FILE *fp, int i)
 {
   fprintf(fp," %-1.16e",q[i]);
 }
 
 void Data::write_atom_dipole_extra(FILE *fp, int i)
 {
   fprintf(fp," %-1.16e %-1.16e %-1.16e %-1.16e",q[i],mux[i],muy[i],muz[i]);
 }
 
 void Data::write_atom_ellipsoid_extra(FILE *fp, int i)
 {
   fprintf(fp," %-1.16e %-1.16e %-1.16e %-1.16e",quatw[i],quati[i],quatj[i],quatk[i]);
 }
 
 void Data::write_atom_full_extra(FILE *fp, int i)
 {
   fprintf(fp," %d %-1.16e",molecule[i],q[i]);
 }
 
 void Data::write_atom_granular_extra(FILE *fp, int i)
 {
   fprintf(fp," %-1.16e %-1.16e",2.0*radius[i],density[i]);
 }
 
 void Data::write_atom_molecular_extra(FILE *fp, int i)
 {
   fprintf(fp," %d",molecule[i]);
 }
 
 void Data::write_atom_peri_extra(FILE *fp, int i)
 {
   fprintf(fp," %-1.16e %-1.16e %-1.16e",vfrac[i],density[i],rmass[i]);
 }
 
 // ---------------------------------------------------------------------
 // per-atom velocity write routines
 // one routine per atom style
 // ---------------------------------------------------------------------
 
 void Data::write_vel_angle(FILE *fp, int i)
 {
   fprintf(fp,"%d %-1.16e %-1.16e %-1.16e",tag[i],vx[i],vy[i],vz[i]);
 }
 
 void Data::write_vel_atomic(FILE *fp, int i)
 {
   fprintf(fp,"%d %-1.16e %-1.16e %-1.16e",tag[i],vx[i],vy[i],vz[i]);
 }
 
 void Data::write_vel_bond(FILE *fp, int i)
 {
   fprintf(fp,"%d %-1.16e %-1.16e %-1.16e",tag[i],vx[i],vy[i],vz[i]);
 }
 
 void Data::write_vel_charge(FILE *fp, int i)
 {
   fprintf(fp,"%d %-1.16e %-1.16e %-1.16e",tag[i],vx[i],vy[i],vz[i]);
 }
 
 void Data::write_vel_dipole(FILE *fp, int i)
 {
   fprintf(fp,"%d %-1.16e %-1.16e %-1.16e",tag[i],vx[i],vy[i],vz[i]);
 }
 
 void Data::write_vel_ellipsoid(FILE *fp, int i)
 {
   fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e",
 	  tag[i],vx[i],vy[i],vz[i],angmomx[i],angmomy[i],angmomz[i]);
 }
 
 void Data::write_vel_full(FILE *fp, int i)
 {
   fprintf(fp,"%d %-1.16e %-1.16e %-1.16e",tag[i],vx[i],vy[i],vz[i]);
 }
 
 void Data::write_vel_granular(FILE *fp, int i)
 {
   fprintf(fp,"%d %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e %-1.16e",
 	  tag[i],vx[i],vy[i],vz[i],omegax[i],omegay[i],omegaz[i]);
 }
 
 void Data::write_vel_molecular(FILE *fp, int i)
 {
   fprintf(fp,"%d %-1.16e %-1.16e %-1.16e",tag[i],vx[i],vy[i],vz[i]);
 }
 
 void Data::write_vel_peri(FILE *fp, int i)
 {
   fprintf(fp,"%d %-1.16e %-1.16e %-1.16e",tag[i],vx[i],vy[i],vz[i]);
 }
 
 // ---------------------------------------------------------------------
 // per-atom velocity write routines of extra quantities unique to style
 // one routine per atom style
 // ---------------------------------------------------------------------
 
 void Data::write_vel_angle_extra(FILE *fp, int i) {}
 void Data::write_vel_atomic_extra(FILE *fp, int i) {}
 void Data::write_vel_bond_extra(FILE *fp, int i) {}
 void Data::write_vel_charge_extra(FILE *fp, int i) {}
 void Data::write_vel_dipole_extra(FILE *fp, int i) {}
 
 void Data::write_vel_ellipsoid_extra(FILE *fp, int i)
 {
   fprintf(fp," %-1.16e %-1.16e %-1.16e",angmomx[i],angmomy[i],angmomz[i]);
 }
 
 void Data::write_vel_full_extra(FILE *fp, int i) {}
 
 void Data::write_vel_granular_extra(FILE *fp, int i)
 {
   fprintf(fp," %-1.16e %-1.16e %-1.16e",omegax[i],omegay[i],omegaz[i]);
 }
 
 void Data::write_vel_molecular_extra(FILE *fp, int i) {}
 void Data::write_vel_peri_extra(FILE *fp, int i) {}
 
 // ---------------------------------------------------------------------
 // binary reads from restart file
 // ---------------------------------------------------------------------
 
 int read_int(FILE *fp)
 {
   int value;
   fread(&value,sizeof(int),1,fp);
   return value;
 }
 
 double read_double(FILE *fp)
 {
   double value;
   fread(&value,sizeof(double),1,fp);
   return value;
 }
 
 char *read_char(FILE *fp)
 {
   int n;
   fread(&n,sizeof(int),1,fp);
   if (n == 0) return NULL;
   char *value = new char[n];
   fread(value,sizeof(char),n,fp);
   return value;
 }
 
-uint64_t read_uint64(FILE *fp)
+bigint read_bigint(FILE *fp)
 {
-  uint64_t value;
-  fread(&value,sizeof(uint64_t),1,fp);
+  bigint value;
+  fread(&value,sizeof(bigint),1,fp);
   return value;
 }
-