Page MenuHomec4science

No OneTemporary

File Metadata

Created
Sun, Jun 15, 06:15
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/doc/Eqs/pair_bop.jpg b/doc/Eqs/pair_bop.jpg
new file mode 100644
index 000000000..d1fbb14b0
Binary files /dev/null and b/doc/Eqs/pair_bop.jpg differ
diff --git a/doc/Eqs/pair_bop.tex b/doc/Eqs/pair_bop.tex
new file mode 100644
index 000000000..371bc035f
--- /dev/null
+++ b/doc/Eqs/pair_bop.tex
@@ -0,0 +1,9 @@
+\documentclass[12pt]{article}
+
+\begin{document}
+
+$$
+ E = \frac{1}{2} \sum_{i=1}^{N} \sum_{j=i_1}^{i_N} \phi_{ij} \left( r_{ij} \right) - \sum_{i=1}^{N} \sum_{j=i_1}^{i_N} \beta_{\sigma,ij} \left( r_{ij} \right) \cdot \Theta_{\sigma,ij} - \sum_{i=1}^{N} \sum_{j=i_1}^{i_N} \beta_{\pi,ij} \left( r_{ij} \right) \cdot \Theta_{\pi,ij} + U_{prom}
+$$
+
+\end{document}
diff --git a/doc/Eqs/pair_meam_spline.jpg b/doc/Eqs/pair_meam_spline.jpg
index 7efcd076d..29f1c7254 100644
Binary files a/doc/Eqs/pair_meam_spline.jpg and b/doc/Eqs/pair_meam_spline.jpg differ
diff --git a/doc/Manual.pdf b/doc/Manual.pdf
index 5d98d7beb..2ee3bee3f 100644
Binary files a/doc/Manual.pdf and b/doc/Manual.pdf differ
diff --git a/doc/Section_commands.html b/doc/Section_commands.html
index e76626a5a..3abb5ccfb 100644
--- a/doc/Section_commands.html
+++ b/doc/Section_commands.html
@@ -1,644 +1,644 @@
<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_packages.html">Next Section</A>
</CENTER>
<HR>
<H3>3. Commands
</H3>
<P>This section describes how a LAMMPS input script is formatted and the
input script commands used to define a LAMMPS simulation.
</P>
3.1 <A HREF = "#cmd_1">LAMMPS input script</A><BR>
3.2 <A HREF = "#cmd_2">Parsing rules</A><BR>
3.3 <A HREF = "#cmd_3">Input script structure</A><BR>
3.4 <A HREF = "#cmd_4">Commands listed by category</A><BR>
3.5 <A HREF = "#cmd_5">Commands listed alphabetically</A> <BR>
<HR>
<HR>
<A NAME = "cmd_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 = "cmd_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 = "cmd_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">Section_example</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 = "cmd_4"></A><H4>3.4 Commands listed by category
</H4>
<P>This section lists all LAMMPS commands, grouped by category. The
<A HREF = "#cmd_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_dump.html">read_dump</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 = "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 = "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_image.html">dump image</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 = "change_box.html">change_box</A>,
<A HREF = "minimize.html">minimize</A>, <A HREF = "neb.html">neb</A> <A HREF = "prd.html">prd</A>,
<A HREF = "rerun.html">rerun</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 = "cmd_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 = "#cmd_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 = "balance.html">balance</A></TD><TD ><A HREF = "bond_coeff.html">bond_coeff</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "bond_style.html">bond_style</A></TD><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></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_modify.html">compute_modify</A></TD><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></TR>
<TR ALIGN="center"><TD ><A HREF = "dihedral_coeff.html">dihedral_coeff</A></TD><TD ><A HREF = "dihedral_style.html">dihedral_style</A></TD><TD ><A HREF = "dimension.html">dimension</A></TD><TD ><A HREF = "displace_atoms.html">displace_atoms</A></TD><TD ><A HREF = "dump.html">dump</A></TD><TD ><A HREF = "dump_image.html">dump image</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 = "package.html">package</A></TD><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 = "partition.html">partition</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "prd.html">prd</A></TD><TD ><A HREF = "print.html">print</A></TD><TD ><A HREF = "processors.html">processors</A></TD><TD ><A HREF = "quit.html">quit</A></TD><TD ><A HREF = "read_data.html">read_data</A></TD><TD ><A HREF = "read_dump.html">read_dump</A></TD></TR>
<TR ALIGN="center"><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 = "rerun.html">rerun</A></TD><TD ><A HREF = "reset_timestep.html">reset_timestep</A></TD><TD ><A HREF = "restart.html">restart</A></TD></TR>
<TR ALIGN="center"><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 = "shell.html">shell</A></TD><TD ><A HREF = "special_bonds.html">special_bonds</A></TD><TD ><A HREF = "suffix.html">suffix</A></TD></TR>
<TR ALIGN="center"><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><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>
</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_append_atoms.html">append/atoms</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></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_ave_time.html">ave/time</A></TD><TD ><A HREF = "fix_balance.html">balance</A></TD><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></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_drag.html">drag</A></TD><TD ><A HREF = "fix_dt_reset.html">dt/reset</A></TD><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_gcmc.html">gcmc</A></TD></TR>
<TR ALIGN="center"><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><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></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_neb.html">neb</A></TD><TD ><A HREF = "fix_nh.html">nph</A></TD><TD ><A HREF = "fix_nphug.html">nphug</A></TD><TD ><A HREF = "fix_nph_asphere.html">nph/asphere</A></TD><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></TR>
<TR ALIGN="center"><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_asphere_noforce.html">nve/asphere/noforce</A></TD><TD ><A HREF = "fix_nve_limit.html">nve/limit</A></TD><TD ><A HREF = "fix_nve_line.html">nve/line</A></TD><TD ><A HREF = "fix_nve_noforce.html">nve/noforce</A></TD><TD ><A HREF = "fix_nve_sphere.html">nve/sphere</A></TD><TD ><A HREF = "fix_nve_tri.html">nve/tri</A></TD></TR>
<TR ALIGN="center"><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><TD ><A HREF = "fix_pour.html">pour</A></TD></TR>
<TR ALIGN="center"><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_restrain.html">restrain</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_piston.html">wall/piston</A></TD><TD ><A HREF = "fix_wall_reflect.html">wall/reflect</A></TD><TD ><A HREF = "fix_wall_region.html">wall/region</A></TD></TR>
<TR ALIGN="center"><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#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "fix_addtorque.html">addtorque</A></TD><TD ><A HREF = "fix_atc.html">atc</A></TD><TD ><A HREF = "fix_colvars.html">colvars</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_meso.html">meso</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_meso_stationary.html">meso/stationary</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><TD ><A HREF = "fix_nh_eff.html">nvt/eff</A></TD><TD ><A HREF = "fix_nvt_sllod_eff.html">nvt/sllod/eff</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_qeq_reax.html">qeq/reax</A></TD><TD ><A HREF = "fix_reaxc_bonds.html">reax/c/bonds</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>
<P>These are accelerated fix styles, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "fix_freeze.html">freeze/cuda</A></TD><TD ><A HREF = "fix_addforce.html">addforce/cuda</A></TD><TD ><A HREF = "fix_aveforce.html">aveforce/cuda</A></TD><TD ><A HREF = "fix_enforce2d.html">enforce2d/cuda</A></TD><TD ><A HREF = "fix_gravity.html">gravity/cuda</A></TD><TD ><A HREF = "fix_gravity.html">gravity/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_nh.html">npt/cuda</A></TD><TD ><A HREF = "fix_nh.html">nve/cuda</A></TD><TD ><A HREF = "fix_nve_sphere.html">nve/sphere/omp</A></TD><TD ><A HREF = "fix_nh.html">nvt/cuda</A></TD><TD ><A HREF = "fix_qeq_comb.html">qeq/comb/omp</A></TD><TD ><A HREF = "fix_setforce.html">setforce/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "fix_shake.html">shake/cuda</A></TD><TD ><A HREF = "fix_temp_berendsen.html">temp/berendsen/cuda</A></TD><TD ><A HREF = "fix_temp_rescale.html">temp/rescale/cuda</A></TD><TD ><A HREF = "fix_temp_rescale.html">temp/rescale/limit/cuda</A></TD><TD ><A HREF = "fix_viscous.html">viscous/cuda</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_cluster_atom.html">cluster/atom</A></TD><TD ><A HREF = "compute_cna_atom.html">cna/atom</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_com.html">com</A></TD><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></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_erotate_asphere.html">erotate/asphere</A></TD><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></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_heat_flux.html">heat/flux</A></TD><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></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_pair.html">pair</A></TD><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></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_property_local.html">property/local</A></TD><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_slice.html">slice</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_stress_atom.html">stress/atom</A></TD><TD ><A HREF = "compute_temp.html">temp</A></TD><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></TR>
<TR ALIGN="center"><TD ><A HREF = "compute_temp_profile.html">temp/profile</A></TD><TD ><A HREF = "compute_temp_ramp.html">temp/ramp</A></TD><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#start_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_meso_e_atom.html">meso_e/atom</A></TD><TD ><A HREF = "compute_meso_rho_atom.html">meso_rho/atom</A></TD><TD ><A HREF = "compute_meso_t_atom.html">meso_t/atom</A></TD></TR>
<TR ALIGN="center"><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><TD ><A HREF = "compute_temp_rotate.html">temp/rotate</A>
</TD></TR></TABLE></DIV>
<P>These are accelerated compute styles, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "compute_pe.html">pe/cuda</A></TD><TD ><A HREF = "compute_pressure.html">pressure/cuda</A></TD><TD ><A HREF = "compute_temp.html">temp/cuda</A></TD><TD ><A HREF = "compute_temp_partial.html">temp/partial/cuda</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_adp.html">adp</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_airebo.html">airebo</A></TD><TD ><A HREF = "pair_beck.html">beck</A></TD><TD ><A HREF = "pair_born.html">born</A></TD><TD ><A HREF = "pair_born.html">born/coul/long</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_born.html">born/coul/wolf</A></TD><TD ><A HREF = "pair_brownian.html">brownian</A></TD><TD ><A HREF = "pair_brownian.html">brownian/poly</A></TD><TD ><A HREF = "pair_buck.html">buck</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_buck.html">buck/coul/cut</A></TD><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></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/cut</A></TD><TD ><A HREF = "pair_coul.html">coul/debye</A></TD><TD ><A HREF = "pair_coul.html">coul/long</A></TD><TD ><A HREF = "pair_coul.html">coul/wolf</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_dipole.html">dipole/cut</A></TD><TD ><A HREF = "pair_dpd.html">dpd</A></TD><TD ><A HREF = "pair_dpd.html">dpd/tstat</A></TD><TD ><A HREF = "pair_dsmc.html">dsmc</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy</A></TD><TD ><A HREF = "pair_eam.html">eam/fs</A></TD><TD ><A HREF = "pair_eim.html">eim</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_gauss.html">gauss</A></TD><TD ><A HREF = "pair_gayberne.html">gayberne</A></TD><TD ><A HREF = "pair_gran.html">gran/hertz/history</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_gran.html">gran/hooke/history</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/lj</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/morse</A></TD><TD ><A HREF = "pair_kim.html">kim</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_lcbop.html">lcbop</A></TD><TD ><A HREF = "pair_line_lj.html">line/lj</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></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long</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/coul/cut</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></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_lj_smooth_linear.html">lj/smooth/linear</A></TD><TD ><A HREF = "pair_lj96.html">lj96/cut</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_lubricate.html">lubricate/poly</A></TD><TD ><A HREF = "pair_lubricateU.html">lubricateU</A></TD><TD ><A HREF = "pair_lubricateU.html">lubricateU/poly</A></TD><TD ><A HREF = "pair_meam.html">meam</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_morse.html">morse</A></TD><TD ><A HREF = "pair_peri.html">peri/lps</A></TD><TD ><A HREF = "pair_peri.html">peri/pmb</A></TD><TD ><A HREF = "pair_reax.html">reax</A></TD></TR>
-<TR ALIGN="center"><TD ><A HREF = "pair_airebo.html">rebo</A></TD><TD ><A HREF = "pair_resquared.html">resquared</A></TD><TD ><A HREF = "pair_soft.html">soft</A></TD><TD ><A HREF = "pair_sw.html">sw</A></TD></TR>
-<TR ALIGN="center"><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><TD ><A HREF = "pair_tri_lj.html">tri/lj</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>
+<TR ALIGN="center"><TD ><A HREF = "pair_airebo.html">airebo</A></TD><TD ><A HREF = "pair_beck.html">beck</A></TD><TD ><A HREF = "pair_bop.html">bop</A></TD><TD ><A HREF = "pair_born.html">born</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_born.html">born/coul/long</A></TD><TD ><A HREF = "pair_born.html">born/coul/wolf</A></TD><TD ><A HREF = "pair_brownian.html">brownian</A></TD><TD ><A HREF = "pair_brownian.html">brownian/poly</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_buck.html">buck</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/cut</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/long</A></TD><TD ><A HREF = "pair_colloid.html">colloid</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_comb.html">comb</A></TD><TD ><A HREF = "pair_coul.html">coul/cut</A></TD><TD ><A HREF = "pair_coul.html">coul/debye</A></TD><TD ><A HREF = "pair_coul.html">coul/long</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/wolf</A></TD><TD ><A HREF = "pair_dipole.html">dipole/cut</A></TD><TD ><A HREF = "pair_dpd.html">dpd</A></TD><TD ><A HREF = "pair_dpd.html">dpd/tstat</A></TD></TR>
+<TR ALIGN="center"><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/alloy</A></TD><TD ><A HREF = "pair_eam.html">eam/fs</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_gran.html">gran/hertz/history</A></TD></TR>
+<TR ALIGN="center"><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><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/morse</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_kim.html">kim</A></TD><TD ><A HREF = "pair_lcbop.html">lcbop</A></TD><TD ><A HREF = "pair_line_lj.html">line/lj</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm</A></TD></TR>
+<TR ALIGN="center"><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><TD ><A HREF = "pair_class2.html">lj/class2</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_class2.html">lj/class2/coul/long</A></TD><TD ><A HREF = "pair_lj.html">lj/cut</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/debye</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/long</A></TD><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></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs</A></TD><TD ><A HREF = "pair_lj_smooth.html">lj/smooth</A></TD><TD ><A HREF = "pair_lj_smooth_linear.html">lj/smooth/linear</A></TD><TD ><A HREF = "pair_lj96.html">lj96/cut</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_lubricate.html">lubricate</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate/poly</A></TD><TD ><A HREF = "pair_lubricateU.html">lubricateU</A></TD><TD ><A HREF = "pair_lubricateU.html">lubricateU/poly</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_peri.html">peri/lps</A></TD><TD ><A HREF = "pair_peri.html">peri/pmb</A></TD></TR>
+<TR ALIGN="center"><TD ><A HREF = "pair_reax.html">reax</A></TD><TD ><A HREF = "pair_airebo.html">rebo</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_tri_lj.html">tri/lj</A></TD><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#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "pair_awpmd.html">awpmd/cut</A></TD><TD ><A HREF = "pair_buck_coul.html">buck/coul</A></TD><TD ><A HREF = "pair_coul_diel.html">coul/diel</A></TD><TD ><A HREF = "pair_dipole.html">dipole/sf</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/cd</A></TD><TD ><A HREF = "pair_edip.html">edip</A></TD><TD ><A HREF = "pair_eff.html">eff/cut</A></TD><TD ><A HREF = "pair_gauss.html">gauss/cut</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_lj_coul.html">lj/coul</A></TD><TD ><A HREF = "pair_sdk.html">lj/sdk</A></TD><TD ><A HREF = "pair_sdk.html">lj/sdk/coul/long</A></TD><TD ><A HREF = "pair_lj_sf.html">lj/sf</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_meam_spline.html">meam/spline</A></TD><TD ><A HREF = "pair_reax_c.html">reax/c</A></TD><TD ><A HREF = "pair_sph_heatconduction.html">sph/heatconduction</A></TD><TD ><A HREF = "pair_sph_idealgas.html">sph/idealgas</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_sph_lj.html">sph/lj</A></TD><TD ><A HREF = "pair_sph_rhosum.html">sph/rhosum</A></TD><TD ><A HREF = "pair_sph_taitwater.html">sph/taitwater</A></TD><TD ><A HREF = "pair_sph_taitwater_morris.html">sph/taitwater/morris</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_tersoff.html">tersoff/table</A>
</TD></TR></TABLE></DIV>
<P>These are accelerated pair styles, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "pair_adp.html">adp/omp</A></TD><TD ><A HREF = "pair_airebo.html">airebo/omp</A></TD><TD ><A HREF = "pair_beck.html">beck/omp</A></TD><TD ><A HREF = "pair_born.html">born/coul/long/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_born.html">born/coul/long/omp</A></TD><TD ><A HREF = "pair_born.html">born/coul/wolf/omp</A></TD><TD ><A HREF = "pair_born.html">born/omp</A></TD><TD ><A HREF = "pair_brownian.html">brownian/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_brownian.html">brownian/poly/omp</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/cut/cuda</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/cut/gpu</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/cut/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_buck.html">buck/coul/long/cuda</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/long/gpu</A></TD><TD ><A HREF = "pair_buck.html">buck/coul/long/omp</A></TD><TD ><A HREF = "pair_buck_coul.html">buck/coul/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_buck.html">buck/cuda</A></TD><TD ><A HREF = "pair_buck.html">buck/gpu</A></TD><TD ><A HREF = "pair_buck.html">buck/omp</A></TD><TD ><A HREF = "pair_colloid.html">colloid/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_comb.html">comb/omp</A></TD><TD ><A HREF = "pair_coul.html">coul/cut/omp</A></TD><TD ><A HREF = "pair_coul.html">coul/debye/omp</A></TD><TD ><A HREF = "pair_coul.html">coul/long/gpu</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_coul.html">coul/long/omp</A></TD><TD ><A HREF = "pair_coul.html">coul/wolf</A></TD><TD ><A HREF = "pair_dipole.html">dipole/cut/omp</A></TD><TD ><A HREF = "pair_dipole.html">dipole/sf/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_dpd.html">dpd/omp</A></TD><TD ><A HREF = "pair_dpd.html">dpd/tstat/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy/cuda</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy/gpu</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/alloy/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/alloy/opt</A></TD><TD ><A HREF = "pair_eam.html">eam/cd/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/fs/cuda</A></TD><TD ><A HREF = "pair_eam.html">eam/fs/gpu</A></TD><TD ><A HREF = "pair_eam.html">eam/fs/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/fs/opt</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_eam.html">eam/gpu</A></TD><TD ><A HREF = "pair_eam.html">eam/omp</A></TD><TD ><A HREF = "pair_eam.html">eam/opt</A></TD><TD ><A HREF = "pair_edip.html">edip/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_eim.html">eim/omp</A></TD><TD ><A HREF = "pair_gauss.html">gauss/omp</A></TD><TD ><A HREF = "pair_gayberne.html">gayberne/gpu</A></TD><TD ><A HREF = "pair_gayberne.html">gayberne/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_gran.html">gran/hertz/history/omp</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke/cuda</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke/history/omp</A></TD><TD ><A HREF = "pair_gran.html">gran/hooke/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/lj/omp</A></TD><TD ><A HREF = "pair_hbond_dreiding.html">hbond/dreiding/morse/omp</A></TD><TD ><A HREF = "pair_line_lj.html">line/lj/omp</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/omp</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/implicit/cuda</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/charmm/implicit/omp</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/gpu</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/omp</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/long/opt</A></TD><TD ><A HREF = "pair_charmm.html">lj/charmm/coul/pppm/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut/cuda</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/cut/omp</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/long/cuda</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/long/gpu</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_class2.html">lj/class2/coul/pppm/omp</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/coul/long/omp</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/cuda</A></TD><TD ><A HREF = "pair_class2.html">lj/class2/gpu</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_class2.html">lj/class2/omp</A></TD><TD ><A HREF = "pair_lj_coul.html">lj/coul/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut/cuda</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut/gpu</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/cut/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/debye/cuda</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/debye/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/gpu</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/opt</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/tip4p/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/coul/long/tip4p/opt</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/pppm/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/coul/pppm/tip4p/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_lj.html">lj/cut/experimental/cuda</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/gpu</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/omp</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/opt</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_lj_expand.html">lj/expand/cuda</A></TD><TD ><A HREF = "pair_lj_expand.html">lj/expand/gpu</A></TD><TD ><A HREF = "pair_lj_expand.html">lj/expand/omp</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_gromacs.html">lj/gromacs/coul/gromacs/omp</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/cuda</A></TD><TD ><A HREF = "pair_gromacs.html">lj/gromacs/omp</A></TD><TD ><A HREF = "pair_sdk.html">lj/sdk/gpu</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_sdk.html">lj/sdk/omp</A></TD><TD ><A HREF = "pair_sdk.html">lj/sdk/coul/long/gpu</A></TD><TD ><A HREF = "pair_sdk.html">lj/sdk/coul/long/omp</A></TD><TD ><A HREF = "pair_lj_sf.html">lj/sf/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_lj_smooth.html">lj/smooth/cuda</A></TD><TD ><A HREF = "pair_lj_smooth.html">lj/smooth/omp</A></TD><TD ><A HREF = "pair_lj_smooth_linear.html">lj/smooth/linear/omp</A></TD><TD ><A HREF = "pair_lj96.html">lj96/cut/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_lj96.html">lj96/cut/gpu</A></TD><TD ><A HREF = "pair_lj96.html">lj96/cut/omp</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate/omp</A></TD><TD ><A HREF = "pair_lubricate.html">lubricate/poly/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_meam_spline.html">meam/spline/omp</A></TD><TD ><A HREF = "pair_morse.html">morse/cuda</A></TD><TD ><A HREF = "pair_morse.html">morse/gpu</A></TD><TD ><A HREF = "pair_morse.html">morse/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_morse.html">morse/opt</A></TD><TD ><A HREF = "pair_peri.html">peri/lps/omp</A></TD><TD ><A HREF = "pair_peri.html">peri/pmb/omp</A></TD><TD ><A HREF = "pair_airebo.html">rebo/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_resquared.html">resquared/gpu</A></TD><TD ><A HREF = "pair_resquared.html">resquared/omp</A></TD><TD ><A HREF = "pair_soft.html">soft/omp</A></TD><TD ><A HREF = "pair_sw.html">sw/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_sw.html">sw/omp</A></TD><TD ><A HREF = "pair_table.html">table/gpu</A></TD><TD ><A HREF = "pair_table.html">table/omp</A></TD><TD ><A HREF = "pair_tersoff.html">tersoff/cuda</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_tersoff.html">tersoff/omp</A></TD><TD ><A HREF = "pair_tersoff.html">tersoff/table/omp</A></TD><TD ><A HREF = "pair_tersoff_zbl.html">tersoff/zbl/omp</A></TD><TD ><A HREF = "pair_tri_lj.html">tri/lj/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "pair_yukawa.html">yukawa/gpu</A></TD><TD ><A HREF = "pair_yukawa.html">yukawa/omp</A></TD><TD ><A HREF = "pair_yukawa_colloid.html">yukawa/colloid/omp</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>
<P>These are bond styles contributed by users, which can be used if
<A HREF = "Section_start.html#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "bond_harmonic_shift.html">harmonic/shift</A></TD><TD ><A HREF = "bond_harmonic_shift_cut.html">harmonic/shift/cut</A>
</TD></TR></TABLE></DIV>
<P>These are accelerated bond styles, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_class2.html">class2/omp</A></TD><TD WIDTH="100"><A HREF = "bond_fene.html">fene/omp</A></TD><TD WIDTH="100"><A HREF = "bond_fene_expand.html">fene/expand/omp</A></TD><TD WIDTH="100"><A HREF = "bond_harmonic.html">harmonic/omp</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_harmonic_shift.html">harmonic/shift/omp</A></TD><TD WIDTH="100"><A HREF = "bond_harmonic_shift_cut.html">harmonic/shift/cut/omp</A></TD><TD WIDTH="100"><A HREF = "bond_morse.html">morse/omp</A></TD><TD WIDTH="100"><A HREF = "bond_nonlinear.html">nonlinear/omp</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "bond_quartic.html">quartic/omp</A></TD><TD WIDTH="100"><A HREF = "bond_table.html">table/omp</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#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "angle_sdk.html">sdk</A></TD><TD ><A HREF = "angle_cosine_shift.html">cosine/shift</A></TD><TD ><A HREF = "angle_cosine_shift_exp.html">cosine/shift/exp</A></TD><TD ><A HREF = "angle_dipole.html">dipole</A>
</TD></TR></TABLE></DIV>
<P>These are accelerated angle styles, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_charmm.html">charmm/omp</A></TD><TD WIDTH="100"><A HREF = "angle_class2.html">class2/omp</A></TD><TD WIDTH="100"><A HREF = "angle_cosine.html">cosine/omp</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_delta.html">cosine/delta/omp</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_cosine_periodic.html">cosine/periodic/omp</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_shift.html">cosine/shift/omp</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_shift_exp.html">cosine/shift/exp/omp</A></TD><TD WIDTH="100"><A HREF = "angle_cosine_squared.html">cosine/squared/omp</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "angle_dipole.html">dipole/omp</A><A HREF = "angle_harmonic.html">harmonic/omp</A></TD><TD WIDTH="100"><A HREF = "angle_table.html">table/omp</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>
<P>These are dihedral styles contributed by users, which can be used if
<A HREF = "Section_start.html#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "dihedral_cosine_shift_exp.html">cosine/shift/exp</A></TD><TD ><A HREF = "dihedral_table.html">table</A>
</TD></TR></TABLE></DIV>
<P>These are accelerated dihedral styles, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "dihedral_charmm.html">charmm/omp</A></TD><TD WIDTH="100"><A HREF = "dihedral_class2.html">class2/omp</A></TD><TD WIDTH="100"><A HREF = "dihedral_cosine_shift_exp.html">cosine/shift/exp/omp</A></TD><TD WIDTH="100"><A HREF = "dihedral_harmonic.html">harmonic/omp</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "dihedral_helix.html">helix/omp</A></TD><TD WIDTH="100"><A HREF = "dihedral_multi_harmonic.html">multi/harmonic/omp</A></TD><TD WIDTH="100"><A HREF = "dihedral_opls.html">opls/omp</A><A HREF = "dihedral_table.html">table/omp</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>
<P>These are improper styles contributed by users, which can be used if
<A HREF = "Section_start.html#start_3">LAMMPS is built with the appropriate
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "improper_cossq.html">cossq</A></TD><TD ><A HREF = "improper_ring.html">ring</A>
</TD></TR></TABLE></DIV>
<P>These are accelerated improper styles, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "improper_class2.html">class2/omp</A></TD><TD WIDTH="100"><A HREF = "improper_cossq.html">cossq/omp</A></TD><TD WIDTH="100"><A HREF = "improper_cvff.html">cvff/omp</A></TD><TD WIDTH="100"><A HREF = "improper_harmonic.html">harmonic/omp</A></TD></TR>
<TR ALIGN="center"><TD WIDTH="100"><A HREF = "improper_ring.html">ring/omp</A></TD><TD WIDTH="100"><A HREF = "improper_umbrella.html">umbrella/omp</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/cg</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#start_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>
<P>These are accelerated Kspace solvers, which can be used if LAMMPS is
built with the <A HREF = "Section_accelerate.html">appropriate accelerated
package</A>.
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD ><A HREF = "kspace_style.html">ewald/omp</A></TD><TD ><A HREF = "kspace_style.html">pppm/cuda</A></TD><TD ><A HREF = "kspace_style.html">pppm/gpu</A></TD><TD ><A HREF = "kspace_style.html">pppm/omp</A></TD></TR>
<TR ALIGN="center"><TD ><A HREF = "kspace_style.html">pppm/cg/omp</A></TD><TD ><A HREF = "kspace_style.html">pppm/tip4p/omp</A></TD><TD ><A HREF = "kspace_style.html">pppm/proxy</A></TD><TD ><A HREF = "kspace_style.html">pppm/tip4p/proxy</A>
</TD></TR></TABLE></DIV>
</HTML>
diff --git a/doc/Section_commands.txt b/doc/Section_commands.txt
index ac2a2bb19..fc8e881c2 100644
--- a/doc/Section_commands.txt
+++ b/doc/Section_commands.txt
@@ -1,1047 +1,1048 @@
"Previous Section"_Section_start.html - "LAMMPS WWW Site"_lws - "LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next Section"_Section_packages.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
3. Commands :h3
This section describes how a LAMMPS input script is formatted and the
input script commands used to define a LAMMPS simulation.
3.1 "LAMMPS input script"_#cmd_1
3.2 "Parsing rules"_#cmd_2
3.3 "Input script structure"_#cmd_3
3.4 "Commands listed by category"_#cmd_4
3.5 "Commands listed alphabetically"_#cmd_5 :all(b)
:line
:line
3.1 LAMMPS input script :link(cmd_1),h4
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.
In many cases, the ordering of commands in an input script is not
important. However the following rules apply:
(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:
timestep 0.5
run 100
run 100 :pre
does something different than this sequence:
run 100
timestep 0.5
run 100 :pre
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.
(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.
(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
"read_data"_read_data.html command initializes the system by setting
up the simulation box and assigning atoms to processors. If default
values are not desired, the "processors"_processors.html and
"boundary"_boundary.html commands need to be used before read_data to
tell LAMMPS how to map processors to the simulation box.
Many input script errors are detected by LAMMPS and an ERROR or
WARNING message is printed. "This section"_Section_errors.html gives
more information on what errors mean. The documentation for each
command lists restrictions on how the command can be used.
:line
3.2 Parsing rules :link(cmd_2),h4
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.
Here is how each line in the input script is parsed by LAMMPS:
(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.
(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.
(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 "variable"_variable.html command for
details of how strings are assigned to variables and how they are
substituted for in input script commands.
(4) The line is broken into "words" separated by whitespace (tabs,
spaces). Note that words can thus contain letters, digits,
underscores, or punctuation characters.
(5) The first word is the command name. All successive words in the
line are arguments.
(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.
print "Volume = $v"
print 'Volume = $v' :pre
The quotes are removed when the single argument is stored internally.
See the "dump modify format"_dump_modify.html or "if"_if.html 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).
IMPORTANT NOTE: If the argument is itself a command that requires a
quoted argument (e.g. using a "print"_print.html command as part of an
"if"_if.html or "run every"_run.html 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.
:line
3.3 Input script structure :h4,link(cmd_3)
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
"Section_example"_Section_example.html, and animated on the "LAMMPS
WWW Site"_lws.
A LAMMPS input script typically has 4 parts:
Initialization
Atom definition
Settings
Run a simulation :ol
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.
(1) Initialization
Set parameters that need to be defined before atoms are created or
read-in from a file.
The relevant commands are "units"_units.html,
"dimension"_dimension.html, "newton"_newton.html,
"processors"_processors.html, "boundary"_boundary.html,
"atom_style"_atom_style.html, "atom_modify"_atom_modify.html.
If force-field parameters appear in the files that will be read, these
commands tell LAMMPS what kinds of force fields are being used:
"pair_style"_pair_style.html, "bond_style"_bond_style.html,
"angle_style"_angle_style.html, "dihedral_style"_dihedral_style.html,
"improper_style"_improper_style.html.
(2) Atom definition
There are 3 ways to define atoms in LAMMPS. Read them in from a data
or restart file via the "read_data"_read_data.html or
"read_restart"_read_restart.html commands. These files can contain
molecular topology information. Or create atoms on a lattice (with no
molecular topology), using these commands: "lattice"_lattice.html,
"region"_region.html, "create_box"_create_box.html,
"create_atoms"_create_atoms.html. The entire set of atoms can be
duplicated to make a larger simulation using the
"replicate"_replicate.html command.
(3) Settings
Once atoms and molecular topology are defined, a variety of settings
can be specified: force field coefficients, simulation parameters,
output options, etc.
Force field coefficients are set by these commands (they can also be
set in the read-in files): "pair_coeff"_pair_coeff.html,
"bond_coeff"_bond_coeff.html, "angle_coeff"_angle_coeff.html,
"dihedral_coeff"_dihedral_coeff.html,
"improper_coeff"_improper_coeff.html,
"kspace_style"_kspace_style.html, "dielectric"_dielectric.html,
"special_bonds"_special_bonds.html.
Various simulation parameters are set by these commands:
"neighbor"_neighbor.html, "neigh_modify"_neigh_modify.html,
"group"_group.html, "timestep"_timestep.html,
"reset_timestep"_reset_timestep.html, "run_style"_run_style.html,
"min_style"_min_style.html, "min_modify"_min_modify.html.
Fixes impose a variety of boundary conditions, time integration, and
diagnostic options. The "fix"_fix.html command comes in many flavors.
Various computations can be specified for execution during a
simulation using the "compute"_compute.html,
"compute_modify"_compute_modify.html, and "variable"_variable.html
commands.
Output options are set by the "thermo"_thermo.html, "dump"_dump.html,
and "restart"_restart.html commands.
(4) Run a simulation
A molecular dynamics simulation is run using the "run"_run.html
command. Energy minimization (molecular statics) is performed using
the "minimize"_minimize.html command. A parallel tempering
(replica-exchange) simulation can be run using the
"temper"_temper.html command.
:line
3.4 Commands listed by category :link(cmd_4),h4
This section lists all LAMMPS commands, grouped by category. The
"next section"_#cmd_5 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.
Initialization:
"atom_modify"_atom_modify.html, "atom_style"_atom_style.html,
"boundary"_boundary.html, "dimension"_dimension.html,
"newton"_newton.html, "processors"_processors.html, "units"_units.html
Atom definition:
"create_atoms"_create_atoms.html, "create_box"_create_box.html,
"lattice"_lattice.html, "read_data"_read_data.html,
"read_dump"_read_dump.html, "read_restart"_read_restart.html,
"region"_region.html, "replicate"_replicate.html
Force fields:
"angle_coeff"_angle_coeff.html, "angle_style"_angle_style.html,
"bond_coeff"_bond_coeff.html, "bond_style"_bond_style.html,
"dielectric"_dielectric.html, "dihedral_coeff"_dihedral_coeff.html,
"dihedral_style"_dihedral_style.html,
"improper_coeff"_improper_coeff.html,
"improper_style"_improper_style.html,
"kspace_modify"_kspace_modify.html, "kspace_style"_kspace_style.html,
"pair_coeff"_pair_coeff.html, "pair_modify"_pair_modify.html,
"pair_style"_pair_style.html, "pair_write"_pair_write.html,
"special_bonds"_special_bonds.html
Settings:
"communicate"_communicate.html, "group"_group.html, "mass"_mass.html,
"min_modify"_min_modify.html, "min_style"_min_style.html,
"neigh_modify"_neigh_modify.html, "neighbor"_neighbor.html,
"reset_timestep"_reset_timestep.html, "run_style"_run_style.html,
"set"_set.html, "timestep"_timestep.html, "velocity"_velocity.html
Fixes:
"fix"_fix.html, "fix_modify"_fix_modify.html, "unfix"_unfix.html
Computes:
"compute"_compute.html, "compute_modify"_compute_modify.html,
"uncompute"_uncompute.html
Output:
"dump"_dump.html, "dump image"_dump_image.html,
"dump_modify"_dump_modify.html, "restart"_restart.html,
"thermo"_thermo.html, "thermo_modify"_thermo_modify.html,
"thermo_style"_thermo_style.html, "undump"_undump.html,
"write_restart"_write_restart.html
Actions:
"delete_atoms"_delete_atoms.html, "delete_bonds"_delete_bonds.html,
"displace_atoms"_displace_atoms.html, "change_box"_change_box.html,
"minimize"_minimize.html, "neb"_neb.html "prd"_prd.html,
"rerun"_rerun.html, "run"_run.html, "temper"_temper.html
Miscellaneous:
"clear"_clear.html, "echo"_echo.html, "if"_if.html,
"include"_include.html, "jump"_jump.html, "label"_label.html,
"log"_log.html, "next"_next.html, "print"_print.html,
"shell"_shell.html, "variable"_variable.html
:line
3.5 Individual commands :h4,link(cmd_5),link(comm)
This section lists all LAMMPS commands alphabetically, with a separate
listing below of styles within certain commands. The "previous
section"_#cmd_4 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.
"angle_coeff"_angle_coeff.html,
"angle_style"_angle_style.html,
"atom_modify"_atom_modify.html,
"atom_style"_atom_style.html,
"balance"_balance.html,
"bond_coeff"_bond_coeff.html,
"bond_style"_bond_style.html,
"boundary"_boundary.html,
"change_box"_change_box.html,
"clear"_clear.html,
"communicate"_communicate.html,
"compute"_compute.html,
"compute_modify"_compute_modify.html,
"create_atoms"_create_atoms.html,
"create_box"_create_box.html,
"delete_atoms"_delete_atoms.html,
"delete_bonds"_delete_bonds.html,
"dielectric"_dielectric.html,
"dihedral_coeff"_dihedral_coeff.html,
"dihedral_style"_dihedral_style.html,
"dimension"_dimension.html,
"displace_atoms"_displace_atoms.html,
"dump"_dump.html,
"dump image"_dump_image.html,
"dump_modify"_dump_modify.html,
"echo"_echo.html,
"fix"_fix.html,
"fix_modify"_fix_modify.html,
"group"_group.html,
"if"_if.html,
"improper_coeff"_improper_coeff.html,
"improper_style"_improper_style.html,
"include"_include.html,
"jump"_jump.html,
"kspace_modify"_kspace_modify.html,
"kspace_style"_kspace_style.html,
"label"_label.html,
"lattice"_lattice.html,
"log"_log.html,
"mass"_mass.html,
"minimize"_minimize.html,
"min_modify"_min_modify.html,
"min_style"_min_style.html,
"neb"_neb.html,
"neigh_modify"_neigh_modify.html,
"neighbor"_neighbor.html,
"newton"_newton.html,
"next"_next.html,
"package"_package.html,
"pair_coeff"_pair_coeff.html,
"pair_modify"_pair_modify.html,
"pair_style"_pair_style.html,
"pair_write"_pair_write.html,
"partition"_partition.html,
"prd"_prd.html,
"print"_print.html,
"processors"_processors.html,
"quit"_quit.html,
"read_data"_read_data.html,
"read_dump"_read_dump.html,
"read_restart"_read_restart.html,
"region"_region.html,
"replicate"_replicate.html,
"rerun"_rerun.html,
"reset_timestep"_reset_timestep.html,
"restart"_restart.html,
"run"_run.html,
"run_style"_run_style.html,
"set"_set.html,
"shell"_shell.html,
"special_bonds"_special_bonds.html,
"suffix"_suffix.html,
"tad"_tad.html,
"temper"_temper.html,
"thermo"_thermo.html,
"thermo_modify"_thermo_modify.html,
"thermo_style"_thermo_style.html,
"timestep"_timestep.html,
"uncompute"_uncompute.html,
"undump"_undump.html,
"unfix"_unfix.html,
"units"_units.html,
"variable"_variable.html,
"velocity"_velocity.html,
"write_restart"_write_restart.html :tb(c=6,ea=c)
:line
Fix styles :h4
See the "fix"_fix.html command for one-line descriptions
of each style or click on the style itself for a full description:
"adapt"_fix_adapt.html,
"addforce"_fix_addforce.html,
"append/atoms"_fix_append_atoms.html,
"aveforce"_fix_aveforce.html,
"ave/atom"_fix_ave_atom.html,
"ave/correlate"_fix_ave_correlate.html,
"ave/histo"_fix_ave_histo.html,
"ave/spatial"_fix_ave_spatial.html,
"ave/time"_fix_ave_time.html,
"balance"_fix_balance.html,
"bond/break"_fix_bond_break.html,
"bond/create"_fix_bond_create.html,
"bond/swap"_fix_bond_swap.html,
"box/relax"_fix_box_relax.html,
"deform"_fix_deform.html,
"deposit"_fix_deposit.html,
"drag"_fix_drag.html,
"dt/reset"_fix_dt_reset.html,
"efield"_fix_efield.html,
"enforce2d"_fix_enforce2d.html,
"evaporate"_fix_evaporate.html,
"external"_fix_external.html,
"freeze"_fix_freeze.html,
"gcmc"_fix_gcmc.html,
"gravity"_fix_gravity.html,
"heat"_fix_heat.html,
"indent"_fix_indent.html,
"langevin"_fix_langevin.html,
"lineforce"_fix_lineforce.html,
"momentum"_fix_momentum.html,
"move"_fix_move.html,
"msst"_fix_msst.html,
"neb"_fix_neb.html,
"nph"_fix_nh.html,
"nphug"_fix_nphug.html,
"nph/asphere"_fix_nph_asphere.html,
"nph/sphere"_fix_nph_sphere.html,
"npt"_fix_nh.html,
"npt/asphere"_fix_npt_asphere.html,
"npt/sphere"_fix_npt_sphere.html,
"nve"_fix_nve.html,
"nve/asphere"_fix_nve_asphere.html,
"nve/asphere/noforce"_fix_nve_asphere_noforce.html,
"nve/limit"_fix_nve_limit.html,
"nve/line"_fix_nve_line.html,
"nve/noforce"_fix_nve_noforce.html,
"nve/sphere"_fix_nve_sphere.html,
"nve/tri"_fix_nve_tri.html,
"nvt"_fix_nh.html,
"nvt/asphere"_fix_nvt_asphere.html,
"nvt/sllod"_fix_nvt_sllod.html,
"nvt/sphere"_fix_nvt_sphere.html,
"orient/fcc"_fix_orient_fcc.html,
"planeforce"_fix_planeforce.html,
"poems"_fix_poems.html,
"pour"_fix_pour.html,
"press/berendsen"_fix_press_berendsen.html,
"print"_fix_print.html,
"qeq/comb"_fix_qeq_comb.html,
"reax/bonds"_fix_reax_bonds.html,
"recenter"_fix_recenter.html,
"restrain"_fix_restrain.html,
"rigid"_fix_rigid.html,
"rigid/nve"_fix_rigid.html,
"rigid/nvt"_fix_rigid.html,
"setforce"_fix_setforce.html,
"shake"_fix_shake.html,
"spring"_fix_spring.html,
"spring/rg"_fix_spring_rg.html,
"spring/self"_fix_spring_self.html,
"srd"_fix_srd.html,
"store/force"_fix_store_force.html,
"store/state"_fix_store_state.html,
"temp/berendsen"_fix_temp_berendsen.html,
"temp/rescale"_fix_temp_rescale.html,
"thermal/conductivity"_fix_thermal_conductivity.html,
"tmd"_fix_tmd.html,
"ttm"_fix_ttm.html,
"viscosity"_fix_viscosity.html,
"viscous"_fix_viscous.html,
"wall/colloid"_fix_wall.html,
"wall/gran"_fix_wall_gran.html,
"wall/harmonic"_fix_wall.html,
"wall/lj126"_fix_wall.html,
"wall/lj93"_fix_wall.html,
"wall/piston"_fix_wall_piston.html,
"wall/reflect"_fix_wall_reflect.html,
"wall/region"_fix_wall_region.html,
"wall/srd"_fix_wall_srd.html :tb(c=8,ea=c)
These are fix styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"addtorque"_fix_addtorque.html,
"atc"_fix_atc.html,
"colvars"_fix_colvars.html,
"imd"_fix_imd.html,
"langevin/eff"_fix_langevin_eff.html,
"meso"_fix_meso.html,
"meso/stationary"_fix_meso_stationary.html,
"nph/eff"_fix_nh_eff.html,
"npt/eff"_fix_nh_eff.html,
"nve/eff"_fix_nve_eff.html,
"nvt/eff"_fix_nh_eff.html,
"nvt/sllod/eff"_fix_nvt_sllod_eff.html,
"qeq/reax"_fix_qeq_reax.html,
"reax/c/bonds"_fix_reaxc_bonds.html,
"smd"_fix_smd.html,
"temp/rescale/eff"_fix_temp_rescale_eff.html :tb(c=6,ea=c)
These are accelerated fix styles, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"freeze/cuda"_fix_freeze.html,
"addforce/cuda"_fix_addforce.html,
"aveforce/cuda"_fix_aveforce.html,
"enforce2d/cuda"_fix_enforce2d.html,
"gravity/cuda"_fix_gravity.html,
"gravity/omp"_fix_gravity.html,
"npt/cuda"_fix_nh.html,
"nve/cuda"_fix_nh.html,
"nve/sphere/omp"_fix_nve_sphere.html,
"nvt/cuda"_fix_nh.html,
"qeq/comb/omp"_fix_qeq_comb.html,
"setforce/cuda"_fix_setforce.html,
"shake/cuda"_fix_shake.html,
"temp/berendsen/cuda"_fix_temp_berendsen.html,
"temp/rescale/cuda"_fix_temp_rescale.html,
"temp/rescale/limit/cuda"_fix_temp_rescale.html,
"viscous/cuda"_fix_viscous.html :tb(c=6,ea=c)
:line
Compute styles :h4
See the "compute"_compute.html command for one-line descriptions of
each style or click on the style itself for a full description:
"angle/local"_compute_angle_local.html,
"atom/molecule"_compute_atom_molecule.html,
"bond/local"_compute_bond_local.html,
"centro/atom"_compute_centro_atom.html,
"cluster/atom"_compute_cluster_atom.html,
"cna/atom"_compute_cna_atom.html,
"com"_compute_com.html,
"com/molecule"_compute_com_molecule.html,
"coord/atom"_compute_coord_atom.html,
"damage/atom"_compute_damage_atom.html,
"dihedral/local"_compute_dihedral_local.html,
"displace/atom"_compute_displace_atom.html,
"erotate/asphere"_compute_erotate_asphere.html,
"erotate/sphere"_compute_erotate_sphere.html,
"event/displace"_compute_event_displace.html,
"group/group"_compute_group_group.html,
"gyration"_compute_gyration.html,
"gyration/molecule"_compute_gyration_molecule.html,
"heat/flux"_compute_heat_flux.html,
"improper/local"_compute_improper_local.html,
"ke"_compute_ke.html,
"ke/atom"_compute_ke_atom.html,
"msd"_compute_msd.html,
"msd/molecule"_compute_msd_molecule.html,
"pair"_compute_pair.html,
"pair/local"_compute_pair_local.html,
"pe"_compute_pe.html,
"pe/atom"_compute_pe_atom.html,
"pressure"_compute_pressure.html,
"property/atom"_compute_property_atom.html,
"property/local"_compute_property_local.html,
"property/molecule"_compute_property_molecule.html,
"rdf"_compute_rdf.html,
"reduce"_compute_reduce.html,
"reduce/region"_compute_reduce.html,
"slice"_compute_slice.html,
"stress/atom"_compute_stress_atom.html,
"temp"_compute_temp.html,
"temp/asphere"_compute_temp_asphere.html,
"temp/com"_compute_temp_com.html,
"temp/deform"_compute_temp_deform.html,
"temp/partial"_compute_temp_partial.html,
"temp/profile"_compute_temp_profile.html,
"temp/ramp"_compute_temp_ramp.html,
"temp/region"_compute_temp_region.html,
"temp/sphere"_compute_temp_sphere.html,
"ti"_compute_ti.html :tb(c=6,ea=c)
These are compute styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"ackland/atom"_compute_ackland_atom.html,
"ke/eff"_compute_ke_eff.html,
"ke/atom/eff"_compute_ke_atom_eff.html,
"meso_e/atom"_compute_meso_e_atom.html,
"meso_rho/atom"_compute_meso_rho_atom.html,
"meso_t/atom"_compute_meso_t_atom.html,
"temp/eff"_compute_temp_eff.html,
"temp/deform/eff"_compute_temp_deform_eff.html,
"temp/region/eff"_compute_temp_region_eff.html,
"temp/rotate"_compute_temp_rotate.html :tb(c=6,ea=c)
These are accelerated compute styles, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"pe/cuda"_compute_pe.html,
"pressure/cuda"_compute_pressure.html,
"temp/cuda"_compute_temp.html,
"temp/partial/cuda"_compute_temp_partial.html :tb(c=6,ea=c)
:line
Pair_style potentials :h4
See the "pair_style"_pair_style.html command for an overview of pair
potentials. Click on the style itself for a full description:
"none"_pair_none.html,
"hybrid"_pair_hybrid.html,
"hybrid/overlay"_pair_hybrid.html,
"adp"_pair_adp.html,
"airebo"_pair_airebo.html,
"beck"_pair_beck.html,
+"bop"_pair_bop.html,
"born"_pair_born.html,
"born/coul/long"_pair_born.html,
"born/coul/wolf"_pair_born.html,
"brownian"_pair_brownian.html,
"brownian/poly"_pair_brownian.html,
"buck"_pair_buck.html,
"buck/coul/cut"_pair_buck.html,
"buck/coul/long"_pair_buck.html,
"colloid"_pair_colloid.html,
"comb"_pair_comb.html,
"coul/cut"_pair_coul.html,
"coul/debye"_pair_coul.html,
"coul/long"_pair_coul.html,
"coul/wolf"_pair_coul.html,
"dipole/cut"_pair_dipole.html,
"dpd"_pair_dpd.html,
"dpd/tstat"_pair_dpd.html,
"dsmc"_pair_dsmc.html,
"eam"_pair_eam.html,
"eam/alloy"_pair_eam.html,
"eam/fs"_pair_eam.html,
"eim"_pair_eim.html,
"gauss"_pair_gauss.html,
"gayberne"_pair_gayberne.html,
"gran/hertz/history"_pair_gran.html,
"gran/hooke"_pair_gran.html,
"gran/hooke/history"_pair_gran.html,
"hbond/dreiding/lj"_pair_hbond_dreiding.html,
"hbond/dreiding/morse"_pair_hbond_dreiding.html,
"kim"_pair_kim.html,
"lcbop"_pair_lcbop.html,
"line/lj"_pair_line_lj.html,
"lj/charmm/coul/charmm"_pair_charmm.html,
"lj/charmm/coul/charmm/implicit"_pair_charmm.html,
"lj/charmm/coul/long"_pair_charmm.html,
"lj/class2"_pair_class2.html,
"lj/class2/coul/cut"_pair_class2.html,
"lj/class2/coul/long"_pair_class2.html,
"lj/cut"_pair_lj.html,
"lj/cut/coul/cut"_pair_lj.html,
"lj/cut/coul/debye"_pair_lj.html,
"lj/cut/coul/long"_pair_lj.html,
"lj/cut/coul/long/tip4p"_pair_lj.html,
"lj/expand"_pair_lj_expand.html,
"lj/gromacs"_pair_gromacs.html,
"lj/gromacs/coul/gromacs"_pair_gromacs.html,
"lj/smooth"_pair_lj_smooth.html,
"lj/smooth/linear"_pair_lj_smooth_linear.html,
"lj96/cut"_pair_lj96.html,
"lubricate"_pair_lubricate.html,
"lubricate/poly"_pair_lubricate.html,
"lubricateU"_pair_lubricateU.html,
"lubricateU/poly"_pair_lubricateU.html,
"meam"_pair_meam.html,
"morse"_pair_morse.html,
"peri/lps"_pair_peri.html,
"peri/pmb"_pair_peri.html,
"reax"_pair_reax.html,
"rebo"_pair_airebo.html,
"resquared"_pair_resquared.html,
"soft"_pair_soft.html,
"sw"_pair_sw.html,
"table"_pair_table.html,
"tersoff"_pair_tersoff.html,
"tersoff/zbl"_pair_tersoff_zbl.html,
"tri/lj"_pair_tri_lj.html,
"yukawa"_pair_yukawa.html,
"yukawa/colloid"_pair_yukawa_colloid.html :tb(c=4,ea=c)
These are pair styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"awpmd/cut"_pair_awpmd.html,
"buck/coul"_pair_buck_coul.html,
"coul/diel"_pair_coul_diel.html,
"dipole/sf"_pair_dipole.html,
"eam/cd"_pair_eam.html,
"edip"_pair_edip.html,
"eff/cut"_pair_eff.html,
"gauss/cut"_pair_gauss.html,
"lj/coul"_pair_lj_coul.html,
"lj/sdk"_pair_sdk.html,
"lj/sdk/coul/long"_pair_sdk.html,
"lj/sf"_pair_lj_sf.html,
"meam/spline"_pair_meam_spline.html,
"reax/c"_pair_reax_c.html,
"sph/heatconduction"_pair_sph_heatconduction.html,
"sph/idealgas"_pair_sph_idealgas.html,
"sph/lj"_pair_sph_lj.html,
"sph/rhosum"_pair_sph_rhosum.html,
"sph/taitwater"_pair_sph_taitwater.html,
"sph/taitwater/morris"_pair_sph_taitwater_morris.html,
"tersoff/table"_pair_tersoff.html :tb(c=4,ea=c)
These are accelerated pair styles, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"adp/omp"_pair_adp.html,
"airebo/omp"_pair_airebo.html,
"beck/omp"_pair_beck.html,
"born/coul/long/cuda"_pair_born.html,
"born/coul/long/omp"_pair_born.html,
"born/coul/wolf/omp"_pair_born.html,
"born/omp"_pair_born.html,
"brownian/omp"_pair_brownian.html,
"brownian/poly/omp"_pair_brownian.html,
"buck/coul/cut/cuda"_pair_buck.html,
"buck/coul/cut/gpu"_pair_buck.html,
"buck/coul/cut/omp"_pair_buck.html,
"buck/coul/long/cuda"_pair_buck.html,
"buck/coul/long/gpu"_pair_buck.html,
"buck/coul/long/omp"_pair_buck.html,
"buck/coul/omp"_pair_buck_coul.html,
"buck/cuda"_pair_buck.html,
"buck/gpu"_pair_buck.html,
"buck/omp"_pair_buck.html,
"colloid/omp"_pair_colloid.html,
"comb/omp"_pair_comb.html,
"coul/cut/omp"_pair_coul.html,
"coul/debye/omp"_pair_coul.html,
"coul/long/gpu"_pair_coul.html,
"coul/long/omp"_pair_coul.html,
"coul/wolf"_pair_coul.html,
"dipole/cut/omp"_pair_dipole.html,
"dipole/sf/omp"_pair_dipole.html,
"dpd/omp"_pair_dpd.html,
"dpd/tstat/omp"_pair_dpd.html,
"eam/alloy/cuda"_pair_eam.html,
"eam/alloy/gpu"_pair_eam.html,
"eam/alloy/omp"_pair_eam.html,
"eam/alloy/opt"_pair_eam.html,
"eam/cd/omp"_pair_eam.html,
"eam/cuda"_pair_eam.html,
"eam/fs/cuda"_pair_eam.html,
"eam/fs/gpu"_pair_eam.html,
"eam/fs/omp"_pair_eam.html,
"eam/fs/opt"_pair_eam.html,
"eam/gpu"_pair_eam.html,
"eam/omp"_pair_eam.html,
"eam/opt"_pair_eam.html,
"edip/omp"_pair_edip.html,
"eim/omp"_pair_eim.html,
"gauss/omp"_pair_gauss.html,
"gayberne/gpu"_pair_gayberne.html,
"gayberne/omp"_pair_gayberne.html,
"gran/hertz/history/omp"_pair_gran.html,
"gran/hooke/cuda"_pair_gran.html,
"gran/hooke/history/omp"_pair_gran.html,
"gran/hooke/omp"_pair_gran.html,
"hbond/dreiding/lj/omp"_pair_hbond_dreiding.html,
"hbond/dreiding/morse/omp"_pair_hbond_dreiding.html,
"line/lj/omp"_pair_line_lj.html,
"lj/charmm/coul/charmm/cuda"_pair_charmm.html,
"lj/charmm/coul/charmm/omp"_pair_charmm.html,
"lj/charmm/coul/charmm/implicit/cuda"_pair_charmm.html,
"lj/charmm/coul/charmm/implicit/omp"_pair_charmm.html,
"lj/charmm/coul/long/cuda"_pair_charmm.html,
"lj/charmm/coul/long/gpu"_pair_charmm.html,
"lj/charmm/coul/long/omp"_pair_charmm.html,
"lj/charmm/coul/long/opt"_pair_charmm.html,
"lj/charmm/coul/pppm/omp"_pair_charmm.html,
"lj/class2/coul/cut/cuda"_pair_class2.html,
"lj/class2/coul/cut/omp"_pair_class2.html,
"lj/class2/coul/long/cuda"_pair_class2.html,
"lj/class2/coul/long/gpu"_pair_class2.html,
"lj/class2/coul/pppm/omp"_pair_class2.html,
"lj/class2/coul/long/omp"_pair_class2.html,
"lj/class2/cuda"_pair_class2.html,
"lj/class2/gpu"_pair_class2.html,
"lj/class2/omp"_pair_class2.html,
"lj/coul/omp"_pair_lj_coul.html,
"lj/cut/coul/cut/cuda"_pair_lj.html,
"lj/cut/coul/cut/gpu"_pair_lj.html,
"lj/cut/coul/cut/omp"_pair_lj.html,
"lj/cut/coul/debye/cuda"_pair_lj.html,
"lj/cut/coul/debye/omp"_pair_lj.html,
"lj/cut/coul/long/cuda"_pair_lj.html,
"lj/cut/coul/long/gpu"_pair_lj.html,
"lj/cut/coul/long/omp"_pair_lj.html,
"lj/cut/coul/long/opt"_pair_lj.html,
"lj/cut/coul/long/tip4p/omp"_pair_lj.html,
"lj/cut/coul/long/tip4p/opt"_pair_lj.html,
"lj/cut/coul/pppm/omp"_pair_lj.html,
"lj/cut/coul/pppm/tip4p/omp"_pair_lj.html,
"lj/cut/cuda"_pair_lj.html,
"lj/cut/experimental/cuda"_pair_lj.html,
"lj/cut/gpu"_pair_lj.html,
"lj/cut/omp"_pair_lj.html,
"lj/cut/opt"_pair_lj.html,
"lj/expand/cuda"_pair_lj_expand.html,
"lj/expand/gpu"_pair_lj_expand.html,
"lj/expand/omp"_pair_lj_expand.html,
"lj/gromacs/coul/gromacs/cuda"_pair_gromacs.html,
"lj/gromacs/coul/gromacs/omp"_pair_gromacs.html,
"lj/gromacs/cuda"_pair_gromacs.html,
"lj/gromacs/omp"_pair_gromacs.html,
"lj/sdk/gpu"_pair_sdk.html,
"lj/sdk/omp"_pair_sdk.html,
"lj/sdk/coul/long/gpu"_pair_sdk.html,
"lj/sdk/coul/long/omp"_pair_sdk.html,
"lj/sf/omp"_pair_lj_sf.html,
"lj/smooth/cuda"_pair_lj_smooth.html,
"lj/smooth/omp"_pair_lj_smooth.html,
"lj/smooth/linear/omp"_pair_lj_smooth_linear.html,
"lj96/cut/cuda"_pair_lj96.html,
"lj96/cut/gpu"_pair_lj96.html,
"lj96/cut/omp"_pair_lj96.html,
"lubricate/omp"_pair_lubricate.html,
"lubricate/poly/omp"_pair_lubricate.html,
"meam/spline/omp"_pair_meam_spline.html,
"morse/cuda"_pair_morse.html,
"morse/gpu"_pair_morse.html,
"morse/omp"_pair_morse.html,
"morse/opt"_pair_morse.html,
"peri/lps/omp"_pair_peri.html,
"peri/pmb/omp"_pair_peri.html,
"rebo/omp"_pair_airebo.html,
"resquared/gpu"_pair_resquared.html,
"resquared/omp"_pair_resquared.html,
"soft/omp"_pair_soft.html,
"sw/cuda"_pair_sw.html,
"sw/omp"_pair_sw.html,
"table/gpu"_pair_table.html,
"table/omp"_pair_table.html,
"tersoff/cuda"_pair_tersoff.html,
"tersoff/omp"_pair_tersoff.html,
"tersoff/table/omp"_pair_tersoff.html,
"tersoff/zbl/omp"_pair_tersoff_zbl.html,
"tri/lj/omp"_pair_tri_lj.html,
"yukawa/gpu"_pair_yukawa.html,
"yukawa/omp"_pair_yukawa.html,
"yukawa/colloid/omp"_pair_yukawa_colloid.html :tb(c=4,ea=c)
:line
Bond_style potentials :h4
See the "bond_style"_bond_style.html command for an overview of bond
potentials. Click on the style itself for a full description:
"none"_bond_none.html,
"hybrid"_bond_hybrid.html,
"class2"_bond_class2.html,
"fene"_bond_fene.html,
"fene/expand"_bond_fene_expand.html,
"harmonic"_bond_harmonic.html,
"morse"_bond_morse.html,
"nonlinear"_bond_nonlinear.html,
"quartic"_bond_quartic.html,
"table"_bond_table.html :tb(c=4,ea=c,w=100)
These are bond styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"harmonic/shift"_bond_harmonic_shift.html,
"harmonic/shift/cut"_bond_harmonic_shift_cut.html :tb(c=4,ea=c)
These are accelerated bond styles, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"class2/omp"_bond_class2.html,
"fene/omp"_bond_fene.html,
"fene/expand/omp"_bond_fene_expand.html,
"harmonic/omp"_bond_harmonic.html,
"harmonic/shift/omp"_bond_harmonic_shift.html,
"harmonic/shift/cut/omp"_bond_harmonic_shift_cut.html,
"morse/omp"_bond_morse.html,
"nonlinear/omp"_bond_nonlinear.html,
"quartic/omp"_bond_quartic.html,
"table/omp"_bond_table.html :tb(c=4,ea=c,w=100)
:line
Angle_style potentials :h4
See the "angle_style"_angle_style.html command for an overview of
angle potentials. Click on the style itself for a full description:
"none"_angle_none.html,
"hybrid"_angle_hybrid.html,
"charmm"_angle_charmm.html,
"class2"_angle_class2.html,
"cosine"_angle_cosine.html,
"cosine/delta"_angle_cosine_delta.html,
"cosine/periodic"_angle_cosine_periodic.html,
"cosine/squared"_angle_cosine_squared.html,
"harmonic"_angle_harmonic.html,
"table"_angle_table.html :tb(c=4,ea=c,w=100)
These are angle styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"sdk"_angle_sdk.html,
"cosine/shift"_angle_cosine_shift.html,
"cosine/shift/exp"_angle_cosine_shift_exp.html,
"dipole"_angle_dipole.html :tb(c=4,ea=c)
These are accelerated angle styles, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"charmm/omp"_angle_charmm.html,
"class2/omp"_angle_class2.html,
"cosine/omp"_angle_cosine.html,
"cosine/delta/omp"_angle_cosine_delta.html,
"cosine/periodic/omp"_angle_cosine_periodic.html,
"cosine/shift/omp"_angle_cosine_shift.html,
"cosine/shift/exp/omp"_angle_cosine_shift_exp.html,
"cosine/squared/omp"_angle_cosine_squared.html,
"dipole/omp"_angle_dipole.html
"harmonic/omp"_angle_harmonic.html,
"table/omp"_angle_table.html :tb(c=4,ea=c,w=100)
:line
Dihedral_style potentials :h4
See the "dihedral_style"_dihedral_style.html command for an overview
of dihedral potentials. Click on the style itself for a full
description:
"none"_dihedral_none.html,
"hybrid"_dihedral_hybrid.html,
"charmm"_dihedral_charmm.html,
"class2"_dihedral_class2.html,
"harmonic"_dihedral_harmonic.html,
"helix"_dihedral_helix.html,
"multi/harmonic"_dihedral_multi_harmonic.html,
"opls"_dihedral_opls.html :tb(c=4,ea=c,w=100)
These are dihedral styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"cosine/shift/exp"_dihedral_cosine_shift_exp.html,
"table"_dihedral_table.html :tb(c=4,ea=c)
These are accelerated dihedral styles, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"charmm/omp"_dihedral_charmm.html,
"class2/omp"_dihedral_class2.html,
"cosine/shift/exp/omp"_dihedral_cosine_shift_exp.html,
"harmonic/omp"_dihedral_harmonic.html,
"helix/omp"_dihedral_helix.html,
"multi/harmonic/omp"_dihedral_multi_harmonic.html,
"opls/omp"_dihedral_opls.html
"table/omp"_dihedral_table.html :tb(c=4,ea=c,w=100)
:line
Improper_style potentials :h4
See the "improper_style"_improper_style.html command for an overview
of improper potentials. Click on the style itself for a full
description:
"none"_improper_none.html,
"hybrid"_improper_hybrid.html,
"class2"_improper_class2.html,
"cvff"_improper_cvff.html,
"harmonic"_improper_harmonic.html,
"umbrella"_improper_umbrella.html :tb(c=4,ea=c,w=100)
These are improper styles contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"cossq"_improper_cossq.html,
"ring"_improper_ring.html :tb(c=4,ea=c)
These are accelerated improper styles, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"class2/omp"_improper_class2.html,
"cossq/omp"_improper_cossq.html,
"cvff/omp"_improper_cvff.html,
"harmonic/omp"_improper_harmonic.html,
"ring/omp"_improper_ring.html,
"umbrella/omp"_improper_umbrella.html :tb(c=4,ea=c,w=100)
:line
Kspace solvers :h4
See the "kspace_style"_kspace_style.html command for an overview of
Kspace solvers. Click on the style itself for a full description:
"ewald"_kspace_style.html,
"pppm"_kspace_style.html,
"pppm/cg"_kspace_style.html,
"pppm/tip4p"_kspace_style.html :tb(c=4,ea=c,w=100)
These are Kspace solvers contributed by users, which can be used if
"LAMMPS is built with the appropriate
package"_Section_start.html#start_3.
"ewald/n"_kspace_style.html :tb(c=4,ea=c,w=100)
These are accelerated Kspace solvers, which can be used if LAMMPS is
built with the "appropriate accelerated
package"_Section_accelerate.html.
"ewald/omp"_kspace_style.html,
"pppm/cuda"_kspace_style.html,
"pppm/gpu"_kspace_style.html,
"pppm/omp"_kspace_style.html,
"pppm/cg/omp"_kspace_style.html,
"pppm/tip4p/omp"_kspace_style.html,
"pppm/proxy"_kspace_style.html,
"pppm/tip4p/proxy"_kspace_style.html :tb(c=4,ea=c)
diff --git a/doc/Section_errors.html b/doc/Section_errors.html
index 7f7acdc87..93a62a31b 100644
--- a/doc/Section_errors.html
+++ b/doc/Section_errors.html
@@ -1,7493 +1,7760 @@
<HTML>
<CENTER><A HREF = "Section_python.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_history.html">Next
Section</A>
</CENTER>
<HR>
<H3>12. Errors
</H3>
<P>This section describes the errors you can encounter when using LAMMPS,
either conceptually, or as printed out by the program.
</P>
12.1 <A HREF = "#err_1">Common problems</A><BR>
12.2 <A HREF = "#err_2">Reporting bugs</A><BR>
12.3 <A HREF = "#err_3">Error & warning messages</A> <BR>
<HR>
<HR>
<A NAME = "err_1"></A><H4>12.1 Common problems
</H4>
<P>If two LAMMPS runs do not produce the same answer on different
machines or different numbers of processors, this is typically not a
bug. 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 within a few 100s or few 1000s of timesteps.
However, the statistical properties of the two runs (e.g. average
energy or temperature) should still be the same.
</P>
<P>If the <A HREF = "velocity.html">velocity</A> command is used to set initial atom
velocities, a particular atom can be assigned a different velocity
when the problem is run on a different number of processors or on
different machines. If this happens, the phase space trajectories of
the two simulations will rapidly diverge. See the discussion of the
<I>loop</I> option in the <A HREF = "velocity.html">velocity</A> command for details and
options that avoid this issue.
</P>
<P>Similarly, the <A HREF = "create_atoms.html">create_atoms</A> command generates a
lattice of atoms. For the same physical system, the ordering and
numbering of atoms by atom ID may be different depending on the number
of processors.
</P>
<P>Some commands use random number generators which may be setup to
produce different random number streams on each processor and hence
will produce different effects when run on different numbers of
processors. A commonly-used example is the <A HREF = "fix_langevin.html">fix
langevin</A> command for thermostatting.
</P>
<P>A LAMMPS simulation typically has two stages, setup and run. Most
LAMMPS errors are detected at setup time; others like a bond
stretching too far may not occur until the middle of a run.
</P>
<P>LAMMPS tries to flag errors and print informative error messages so
you can fix the problem. Of course, LAMMPS cannot figure out your
physics or numerical mistakes, like choosing too big a timestep,
specifying erroneous force field coefficients, or putting 2 atoms on
top of each other! If you run into errors that LAMMPS doesn't catch
that you think it should flag, please send an email to the
<A HREF = "http://lammps.sandia.gov/authors.html">developers</A>.
</P>
<P>If you get an error message about an invalid command in your input
script, you can determine what command is causing the problem by
looking in the log.lammps file or using the <A HREF = "echo.html">echo command</A>
to see it on the screen. For a given command, LAMMPS expects certain
arguments in a specified order. If you mess this up, LAMMPS will
often flag the error, but it may read a bogus argument and assign a
value that is valid, but not what you wanted. E.g. trying to read the
string "abc" as an integer value and assigning the associated variable
a value of 0.
</P>
<P>Generally, LAMMPS will print a message to the screen and logfile and
exit gracefully when it encounters a fatal error. Sometimes it will
print a WARNING to the screen and logfile and continue on; you can
decide if the WARNING is important or not. A WARNING message that is
generated in the middle of a run is only printed to the screen, not to
the logfile, to avoid cluttering up thermodynamic output. If LAMMPS
crashes or hangs without spitting out an error message first then it
could be a bug (see <A HREF = "#err_2">this section</A>) or one of the following
cases:
</P>
<P>LAMMPS runs in the available memory a processor allows to be
allocated. Most reasonable MD runs are compute limited, not memory
limited, so this shouldn't be a bottleneck on most platforms. Almost
all large memory allocations in the code are done via C-style malloc's
which will generate an error message if you run out of memory.
Smaller chunks of memory are allocated via C++ "new" statements. If
you are unlucky you could run out of memory just when one of these
small requests is made, in which case the code will crash or hang (in
parallel), since LAMMPS doesn't trap on those errors.
</P>
<P>Illegal arithmetic can cause LAMMPS to run slow or crash. This is
typically due to invalid physics and numerics that your simulation is
computing. If you see wild thermodynamic values or NaN values in your
LAMMPS output, something is wrong with your simulation. If you
suspect this is happening, it is a good idea to print out
thermodynamic info frequently (e.g. every timestep) via the
<A HREF = "thermo.html">thermo</A> so you can monitor what is happening.
Visualizing the atom movement is also a good idea to insure your model
is behaving as you expect.
</P>
<P>In parallel, one way LAMMPS can hang is due to how different MPI
implementations handle buffering of messages. If the code hangs
without an error message, it may be that you need to specify an MPI
setting or two (usually via an environment variable) to enable
buffering or boost the sizes of messages that can be buffered.
</P>
<HR>
<A NAME = "err_2"></A><H4>12.2 Reporting bugs
</H4>
<P>If you are confident that you have found a bug in LAMMPS, follow these
steps.
</P>
<P>Check the <A HREF = "http://lammps.sandia.gov/bug.html">New features and bug
fixes</A> section of the <A HREF = "http://lammps.sandia.gov">LAMMPS WWW
site</A> to see if the bug has already been reported or fixed or the
<A HREF = "http://lammps.sandia.gov/unbug.html">Unfixed bug</A> to see if a fix is
pending.
</P>
<P>Check the <A HREF = "http://lammps.sandia.gov/mail.html">mailing list</A>
to see if it has been discussed before.
</P>
<P>If not, send an email to the mailing list describing the problem with
any ideas you have as to what is causing it or where in the code the
problem might be. The developers will ask for more info if needed,
such as an input script or data files.
</P>
<P>The most useful thing you can do to help us fix the bug is to isolate
the problem. Run it on the smallest number of atoms and fewest number
of processors and with the simplest input script that reproduces the
bug and try to identify what command or combination of commands is
causing the problem.
</P>
<P>As a last resort, you can send an email directly to the
<A HREF = "http://lammps.sandia.gov/authors.html">developers</A>.
</P>
<HR>
<H4><A NAME = "err_3"></A>12.3 Error & warning messages
</H4>
<P>These are two alphabetic lists of the <A HREF = "#error">ERROR</A> and
<A HREF = "#warn">WARNING</A> messages LAMMPS prints out and the reason why. If the
explanation here is not sufficient, the documentation for the
offending command may help.
Error and warning messages also list the source file and line number
where the error was generated. For example, this message
</P>
<P>ERROR: Illegal velocity command (velocity.cpp:78)
</P>
<P>means that line #78 in the file src/velocity.cpp generated the error.
Looking in the source code may help you figure out what went wrong.
</P>
<P>Note that error messages from <A HREF = "Section_start.html#start_3">user-contributed
packages</A> are not listed here. If such an
error occurs and is not self-explanatory, you'll need to look in the
source code or contact the author of the package.
</P>
<H4><A NAME = "error"></A>Errors:
</H4>
<DL>
<DT><I>1-3 bond count is inconsistent</I>
<DD>An inconsistency was detected when computing the number of 1-3
neighbors for each atom. This likely means something is wrong with
the bond topologies you have defined.
<DT><I>1-4 bond count is inconsistent</I>
<DD>An inconsistency was detected when computing the number of 1-4
neighbors for each atom. This likely means something is wrong with
the bond topologies you have defined.
<DT><I>64-bit atom IDs are not yet supported</I>
<DD>See description of this data type in src/lmptype.h.
<DT><I>Accelerator sharing is not currently supported on system</I>
<DD>Multiple MPI processes cannot share the accelerator on your
system. For NVIDIA GPUs, see the nvidia-smi command to change this
setting.
<DT><I>All angle coeffs are not set</I>
<DD>All angle coefficients must be set in the data file or by the
angle_coeff command before running a simulation.
<DT><I>All bond coeffs are not set</I>
<DD>All bond coefficients must be set in the data file or by the
bond_coeff command before running a simulation.
<DT><I>All dihedral coeffs are not set</I>
<DD>All dihedral coefficients must be set in the data file or by the
dihedral_coeff command before running a simulation.
<DT><I>All improper coeffs are not set</I>
<DD>All improper coefficients must be set in the data file or by the
improper_coeff command before running a simulation.
<DT><I>All masses are not set</I>
<DD>For atom styles that define masses for each atom type, all masses must
be set in the data file or by the mass command before running a
simulation. They must also be set before using the velocity
command.
<DT><I>All pair coeffs are not set</I>
<DD>All pair coefficients must be set in the data file or by the
pair_coeff command before running a simulation.
+<DT><I>All read_dump x,y,z fields must be specified for scaled, triclinic coords</I>
+
+<DD>For triclinic boxes and scaled coordinates you must specify all 3 of
+the x,y,z fields, else LAMMPS cannot reconstruct the unscaled
+coordinates.
+
<DT><I>All universe/uloop variables must have same # of values</I>
<DD>Self-explanatory.
<DT><I>All variables in next command must be same style</I>
<DD>Self-explanatory.
<DT><I>Angle atom missing in delete_bonds</I>
<DD>The delete_bonds command cannot find one or more atoms in a particular
angle on a particular processor. The pairwise cutoff is too short or
the atoms are too far apart to make a valid angle.
<DT><I>Angle atom missing in set command</I>
<DD>The set command cannot find one or more atoms in a particular angle on
a particular processor. The pairwise cutoff is too short or the atoms
are too far apart to make a valid angle.
<DT><I>Angle atoms %d %d %d missing on proc %d at step %ld</I>
<DD>One or more of 3 atoms needed to compute a particular angle are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the angle has blown apart and an atom is
too far away.
<DT><I>Angle coeff for hybrid has invalid style</I>
<DD>Angle style hybrid uses another angle style as one of its
coefficients. The angle style used in the angle_coeff command or read
from a restart file is not recognized.
<DT><I>Angle coeffs are not set</I>
<DD>No angle coefficients have been assigned in the data file or via the
angle_coeff command.
<DT><I>Angle potential must be defined for SHAKE</I>
<DD>When shaking angles, an angle_style potential must be used.
<DT><I>Angle style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Angle style hybrid cannot have none as an argument</I>
<DD>Self-explanatory.
<DT><I>Angle style hybrid cannot use same pair style twice</I>
<DD>Self-explanatory.
<DT><I>Angle table must range from 0 to 180 degrees</I>
<DD>Self-explanatory.
<DT><I>Angle table parameters did not set N</I>
<DD>List of angle table parameters must include N setting.
<DT><I>Angle_coeff command before angle_style is defined</I>
<DD>Coefficients cannot be set in the data file or via the angle_coeff
command until an angle_style has been assigned.
<DT><I>Angle_coeff command before simulation box is defined</I>
<DD>The angle_coeff command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Angle_coeff command when no angles allowed</I>
<DD>The chosen atom style does not allow for angles to be defined.
<DT><I>Angle_style command when no angles allowed</I>
<DD>The chosen atom style does not allow for angles to be defined.
<DT><I>Angles assigned incorrectly</I>
<DD>Angles read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions.
<DT><I>Angles defined but no angle types</I>
<DD>The data file header lists angles but no angle types.
<DT><I>Another input script is already being processed</I>
<DD>Cannot attempt to open a 2nd input script, when the original file is
still being processed.
<DT><I>Append boundary must be shrink/minimum</I>
<DD>The boundary style of the face where atoms are added
-must be of type m (shrink/minimum).
+must be of type m (shrink/minimum).
<DT><I>Arccos of invalid value in variable formula</I>
<DD>Argument of arccos() must be between -1 and 1.
<DT><I>Arcsin of invalid value in variable formula</I>
<DD>Argument of arcsin() must be between -1 and 1.
<DT><I>Assigning ellipsoid parameters to non-ellipsoid atom</I>
<DD>Self-explanatory.
<DT><I>Assigning line parameters to non-line atom</I>
<DD>Self-explanatory.
<DT><I>Assigning tri parameters to non-tri atom</I>
<DD>Self-explanatory.
<DT><I>Atom IDs must be consecutive for velocity create loop all</I>
<DD>Self-explanatory.
<DT><I>Atom count changed in fix neb</I>
<DD>This is not allowed in a NEB calculation.
<DT><I>Atom count is inconsistent, cannot write restart file</I>
<DD>Sum of atoms across processors does not equal initial total count.
This is probably because you have lost some atoms.
<DT><I>Atom in too many rigid bodies - boost MAXBODY</I>
<DD>Fix poems has a parameter MAXBODY (in fix_poems.cpp) which determines
the maximum number of rigid bodies a single atom can belong to (i.e. a
multibody joint). The bodies you have defined exceed this limit.
<DT><I>Atom sort did not operate correctly</I>
<DD>This is an internal LAMMPS error. Please report it to the
developers.
<DT><I>Atom sorting has bin size = 0.0</I>
<DD>The neighbor cutoff is being used as the bin size, but it is zero.
Thus you must explicitly list a bin size in the atom_modify sort
command or turn off sorting.
<DT><I>Atom style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Atom style hybrid cannot use same atom style twice</I>
<DD>Self-explanatory.
<DT><I>Atom vector in equal-style variable formula</I>
<DD>Atom vectors generate one value per atom which is not allowed
in an equal-style variable.
<DT><I>Atom-style variable in equal-style variable formula</I>
<DD>Atom-style variables generate one value per atom which is not allowed
in an equal-style variable.
<DT><I>Atom_modify map command after simulation box is defined</I>
<DD>The atom_modify map command cannot be used after a read_data,
read_restart, or create_box command.
<DT><I>Atom_modify sort and first options cannot be used together</I>
<DD>Self-explanatory.
<DT><I>Atom_style command after simulation box is defined</I>
<DD>The atom_style command cannot be used after a read_data,
read_restart, or create_box command.
<DT><I>Atom_style line can only be used in 2d simulations</I>
<DD>Self-explanatory.
<DT><I>Atom_style tri can only be used in 3d simulations</I>
<DD>Self-explanatory.
<DT><I>Attempt to pop empty stack in fix box/relax</I>
<DD>Internal LAMMPS error. Please report it to the developers.
<DT><I>Attempt to push beyond stack limit in fix box/relax</I>
<DD>Internal LAMMPS error. Please report it to the developers.
<DT><I>Attempting to rescale a 0.0 temperature</I>
<DD>Cannot rescale a temperature that is already 0.0.
<DT><I>Bad FENE bond</I>
<DD>Two atoms in a FENE bond have become so far apart that the bond cannot
be computed.
<DT><I>Bad TIP4P angle type for PPPM/TIP4P</I>
<DD>Specified angle type is not valid.
<DT><I>Bad TIP4P bond type for PPPM/TIP4P</I>
<DD>Specified bond type is not valid.
<DT><I>Bad fix ID in fix append/atoms command</I>
<DD>The value of the fix_id for keyword spatial must start with the suffix
f_.
<DT><I>Bad grid of processors</I>
<DD>The 3d grid of processors defined by the processors command does not
match the number of processors LAMMPS is being run on.
<DT><I>Bad kspace_modify slab parameter</I>
<DD>Kspace_modify value for the slab/volume keyword must be >= 2.0.
<DT><I>Bad matrix inversion in mldivide3</I>
<DD>This error should not occur unless the matrix is badly formed.
<DT><I>Bad principal moments</I>
<DD>Fix rigid did not compute the principal moments of inertia of a rigid
group of atoms correctly.
<DT><I>Bad quadratic solve for particle/line collision</I>
<DD>This is an internal error. It should nornally not occur.
<DT><I>Bad quadratic solve for particle/tri collision</I>
<DD>This is an internal error. It should nornally not occur.
<DT><I>Balance command before simulation box is defined</I>
<DD>The balance command cannot be used before a read_data, read_restart,
or create_box command.
<DT><I>Balance dynamic string is invalid</I>
<DD>The string can only contain the characters "x", "y", or "z".
-<DT><I>Balance dynamic string is invalid for 2d simulation</I>
+<DT><I>Balance produced bad splits</I>
-<DD>The string cannot contain the letter "z".
+<DD>This should not occur. It means two or more cutting plane locations
+are on top of each other or out of order. Report the problem to the
+developers.
<DT><I>Bias compute does not calculate a velocity bias</I>
<DD>The specified compute must compute a bias for temperature.
<DT><I>Bias compute does not calculate temperature</I>
<DD>The specified compute must compute temperature.
<DT><I>Bias compute group does not match compute group</I>
<DD>The specified compute must operate on the same group as the parent
compute.
<DT><I>Big particle in fix srd cannot be point particle</I>
<DD>Big particles must be extended spheriods or ellipsoids.
<DT><I>Bigint setting in lmptype.h is invalid</I>
<DD>Size of bigint is less than size of tagint.
<DT><I>Bigint setting in lmptype.h is not compatible</I>
<DD>Bigint stored in restart file is not consistent with LAMMPS version
you are running.
<DT><I>Bitmapped lookup tables require int/float be same size</I>
<DD>Cannot use pair tables on this machine, because of word sizes. Use
the pair_modify command with table 0 instead.
<DT><I>Bitmapped table in file does not match requested table</I>
<DD>Setting for bitmapped table in pair_coeff command must match table
in file exactly.
<DT><I>Bitmapped table is incorrect length in table file</I>
<DD>Number of table entries is not a correct power of 2.
<DT><I>Bond and angle potentials must be defined for TIP4P</I>
<DD>Cannot use TIP4P pair potential unless bond and angle potentials
are defined.
+<DT><I>Bond atom missing in box size check</I>
+
+<DD>The 2nd atoms needed to compute a particular bond is missing on this
+processor. Typically this is because the pairwise cutoff is set too
+short or the bond has blown apart and an atom is too far away.
+
<DT><I>Bond atom missing in delete_bonds</I>
<DD>The delete_bonds command cannot find one or more atoms in a particular
bond on a particular processor. The pairwise cutoff is too short or
the atoms are too far apart to make a valid bond.
<DT><I>Bond atom missing in set command</I>
<DD>The set command cannot find one or more atoms in a particular bond on
a particular processor. The pairwise cutoff is too short or the atoms
are too far apart to make a valid bond.
<DT><I>Bond atoms %d %d missing on proc %d at step %ld</I>
<DD>One or both of 2 atoms needed to compute a particular bond are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the bond has blown apart and an atom is
too far away.
<DT><I>Bond coeff for hybrid has invalid style</I>
<DD>Bond style hybrid uses another bond style as one of its coefficients.
The bond style used in the bond_coeff command or read from a restart
file is not recognized.
<DT><I>Bond coeffs are not set</I>
<DD>No bond coefficients have been assigned in the data file or via the
bond_coeff command.
<DT><I>Bond potential must be defined for SHAKE</I>
<DD>Cannot use fix shake unless bond potential is defined.
<DT><I>Bond style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Bond style hybrid cannot have none as an argument</I>
<DD>Self-explanatory.
<DT><I>Bond style hybrid cannot use same pair style twice</I>
<DD>Self-explanatory.
<DT><I>Bond style quartic cannot be used with 3,4-body interactions</I>
<DD>No angle, dihedral, or improper styles can be defined when using
bond style quartic.
<DT><I>Bond style quartic requires special_bonds = 1,1,1</I>
<DD>This is a restriction of the current bond quartic implementation.
<DT><I>Bond table parameters did not set N</I>
<DD>List of bond table parameters must include N setting.
<DT><I>Bond table values are not increasing</I>
<DD>The values in the tabulated file must be monotonically increasing.
+<DT><I>Bond/angle/dihedral extent > half of periodic box length</I>
+
+<DD>This is a restriction because LAMMPS can be confused about which image
+of an atom in the bonded interaction is the correct one to use.
+"Extent" in this context means the maximum end-to-end length of the
+bond/angle/dihedral. LAMMPS computes this by taking the maximum bond
+length, multiplying by the number of bonds in the interaction (e.g. 3
+for a dihedral) and adding a small amount of stretch.
+
<DT><I>Bond_coeff command before bond_style is defined</I>
<DD>Coefficients cannot be set in the data file or via the bond_coeff
command until an bond_style has been assigned.
<DT><I>Bond_coeff command before simulation box is defined</I>
<DD>The bond_coeff command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Bond_coeff command when no bonds allowed</I>
<DD>The chosen atom style does not allow for bonds to be defined.
<DT><I>Bond_style command when no bonds allowed</I>
<DD>The chosen atom style does not allow for bonds to be defined.
<DT><I>Bonds assigned incorrectly</I>
<DD>Bonds read in from the data file were not assigned correctly to atoms.
This means there is something invalid about the topology definitions.
<DT><I>Bonds defined but no bond types</I>
<DD>The data file header lists bonds but no bond types.
<DT><I>Both sides of boundary must be periodic</I>
<DD>Cannot specify a boundary as periodic only on the lo or hi side. Must
be periodic on both sides.
<DT><I>Boundary command after simulation box is defined</I>
<DD>The boundary command cannot be used after a read_data, read_restart,
or create_box command.
<DT><I>Box bounds are invalid</I>
<DD>The box boundaries specified in the read_data file are invalid. The
lo value must be less than the hi value for all 3 dimensions.
<DT><I>Can not specify Pxy/Pxz/Pyz in fix box/relax with non-triclinic box</I>
<DD>Only triclinic boxes can be used with off-diagonal pressure components.
See the region prism command for details.
<DT><I>Can not specify Pxy/Pxz/Pyz in fix nvt/npt/nph with non-triclinic box</I>
<DD>Only triclinic boxes can be used with off-diagonal pressure components.
See the region prism command for details.
<DT><I>Can only use -plog with multiple partitions</I>
<DD>Self-explanatory. See doc page discussion of command-line switches.
<DT><I>Can only use -pscreen with multiple partitions</I>
<DD>Self-explanatory. See doc page discussion of command-line switches.
<DT><I>Can only use NEB with 1-processor replicas</I>
<DD>This is current restriction for NEB as implemented in LAMMPS.
<DT><I>Can only use TAD with 1-processor replicas for NEB</I>
<DD>This is current restriction for NEB as implemented in LAMMPS.
+<DT><I>Cannot (yet) use K-space slab correction with compute group/group</I>
+
+<DD>This option is not yet supported.
+
+<DT><I>Cannot (yet) use Kspace slab correction with compute group/group</I>
+
+<DD>This option is not yet supported.
+
<DT><I>Cannot (yet) use PPPM with triclinic box</I>
<DD>This feature is not yet supported.
<DT><I>Cannot add atoms to fix move variable</I>
<DD>Atoms can not be added afterwards to this fix option.
<DT><I>Cannot append atoms to a triclinic box</I>
<DD>The simulation box must be defined with edges alligned with the
Cartesian axes.
<DT><I>Cannot balance in z dimension for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot change box ortho/triclinic with certain fixes defined</I>
<DD>This is because those fixes store the shape of the box. You need to
use unfix to discard the fix, change the box, then redefine a new
fix.
<DT><I>Cannot change box ortho/triclinic with dumps defined</I>
<DD>This is because some dumps store the shape of the box. You need to
use undump to discard the dump, change the box, then redefine a new
dump.
<DT><I>Cannot change box tilt factors for orthogonal box</I>
<DD>Cannot use tilt factors unless the simulation box is non-orthogonal.
<DT><I>Cannot change box to orthogonal when tilt is non-zero</I>
<DD>Self-explanatory.
<DT><I>Cannot change box z boundary to nonperiodic for a 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot change dump_modify every for dump dcd</I>
<DD>The frequency of writing dump dcd snapshots cannot be changed.
<DT><I>Cannot change dump_modify every for dump xtc</I>
<DD>The frequency of writing dump xtc snapshots cannot be changed.
<DT><I>Cannot change timestep once fix srd is setup</I>
<DD>This is because various SRD properties depend on the timestep
size.
<DT><I>Cannot change timestep with fix pour</I>
<DD>This fix pre-computes some values based on the timestep, so it cannot
be changed during a simulation run.
<DT><I>Cannot change_box after reading restart file with per-atom info</I>
<DD>This is because the restart file info cannot be migrated with the
atoms. You can get around this by performing a 0-timestep run which
will assign the restart file info to actual atoms.
<DT><I>Cannot change_box in xz or yz for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot change_box in z dimension for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot compute PPPM G</I>
<DD>LAMMPS failed to compute a valid approximation for the PPPM g_ewald
factor that partitions the computation between real space and k-space.
<DT><I>Cannot create an atom map unless atoms have IDs</I>
<DD>The simulation requires a mapping from global atom IDs to local atoms,
but the atoms that have been defined have no IDs.
<DT><I>Cannot create atoms with undefined lattice</I>
<DD>Must use the lattice command before using the create_atoms
command.
<DT><I>Cannot create/grow a vector/array of pointers for %s</I>
<DD>LAMMPS code is making an illegal call to the templated memory
allocaters, to create a vector or array of pointers.
<DT><I>Cannot create_atoms after reading restart file with per-atom info</I>
<DD>The per-atom info was stored to be used when by a fix that you
may re-define. If you add atoms before re-defining the fix, then
there will not be a correct amount of per-atom info.
<DT><I>Cannot create_box after simulation box is defined</I>
<DD>The create_box command cannot be used after a read_data, read_restart,
or create_box command.
<DT><I>Cannot currently use pair reax with pair hybrid</I>
<DD>This is not yet supported.
<DT><I>Cannot delete group all</I>
<DD>Self-explanatory.
<DT><I>Cannot delete group currently used by a compute</I>
<DD>Self-explanatory.
<DT><I>Cannot delete group currently used by a dump</I>
<DD>Self-explanatory.
<DT><I>Cannot delete group currently used by a fix</I>
<DD>Self-explanatory.
<DT><I>Cannot delete group currently used by atom_modify first</I>
<DD>Self-explanatory.
<DT><I>Cannot displace_atoms after reading restart file with per-atom info</I>
<DD>This is because the restart file info cannot be migrated with the
atoms. You can get around this by performing a 0-timestep run which
will assign the restart file info to actual atoms.
<DT><I>Cannot do GCMC on atoms in atom_modify first group</I>
<DD>This is a restriction due to the way atoms are organized in a list to
enable the atom_modify first command.
<DT><I>Cannot dump JPG file</I>
<DD>LAMMPS was not built with the -DLAMMPS_JPEG switch in the Makefile.
<DT><I>Cannot dump sort on atom IDs with no atom IDs defined</I>
<DD>Self-explanatory.
<DT><I>Cannot evaporate atoms in atom_modify first group</I>
<DD>This is a restriction due to the way atoms are organized in
a list to enable the atom_modify first command.
<DT><I>Cannot find delete_bonds group ID</I>
<DD>Group ID used in the delete_bonds command does not exist.
<DT><I>Cannot have both pair_modify shift and tail set to yes</I>
<DD>These 2 options are contradictory.
<DT><I>Cannot open -reorder file</I>
<DD>Self-explanatory.
<DT><I>Cannot open ADP potential file %s</I>
<DD>The specified ADP potential file cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open AIREBO potential file %s</I>
<DD>The specified AIREBO potential file cannot be opened. Check that the
path and name are correct.
+<DT><I>Cannot open BOP potential file %s</I>
+
+<DD>The specified BOP potential file cannot be opened. Check that the
+path and name are correct.
+
<DT><I>Cannot open COMB potential file %s</I>
<DD>The specified COMB potential file cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open EAM potential file %s</I>
<DD>The specified EAM potential file cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open EIM potential file %s</I>
<DD>The specified EIM potential file cannot be opened. Check that the
path and name are correct.
+<DT><I>Cannot open LCBOP potential file %s</I>
+
+<DD>The specified LCBOP potential file cannot be opened. Check that the
+path and name are correct.
+
<DT><I>Cannot open MEAM potential file %s</I>
<DD>The specified MEAM potential file cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open Stillinger-Weber potential file %s</I>
<DD>The specified SW potential file cannot be opened. Check that the path
and name are correct.
<DT><I>Cannot open Tersoff potential file %s</I>
<DD>The specified Tersoff potential file cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open balance output file</I>
-<DD>This error message can only occur if debug options
-are uncommented in src/balance.cpp.
+<DD>Self-explanatory.
<DT><I>Cannot open custom file</I>
<DD>Self-explanatory.
<DT><I>Cannot open dir to search for restart file</I>
<DD>Using a "*" in the name of the restart file will open the current
directory to search for matching file names.
<DT><I>Cannot open dump file</I>
<DD>The output file for the dump command cannot be opened. Check that the
path and name are correct.
<DT><I>Cannot open file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
<DT><I>Cannot open fix ave/correlate file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
<DT><I>Cannot open fix ave/histo file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
<DT><I>Cannot open fix ave/spatial file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
<DT><I>Cannot open fix ave/time file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
+<DT><I>Cannot open fix balance output file</I>
+
+<DD>Self-explanatory.
+
<DT><I>Cannot open fix poems file %s</I>
<DD>The specified file cannot be opened. Check that the path and name are
correct.
<DT><I>Cannot open fix print file %s</I>
<DD>The output file generated by the fix print command cannot be opened
<DT><I>Cannot open fix qeq/comb file %s</I>
<DD>The output file for the fix qeq/combs command cannot be opened.
Check that the path and name are correct.
<DT><I>Cannot open fix reax/bonds file %s</I>
<DD>The output file for the fix reax/bonds command cannot be opened.
Check that the path and name are correct.
+<DT><I>Cannot open fix rigid infile %s</I>
+
+<DD>The specified file cannot be opened. Check that the path and name are
+correct.
+
<DT><I>Cannot open fix tmd file %s</I>
<DD>The output file for the fix tmd command cannot be opened. Check that
the path and name are correct.
<DT><I>Cannot open fix ttm file %s</I>
<DD>The output file for the fix ttm command cannot be opened. Check that
the path and name are correct.
<DT><I>Cannot open gzipped file</I>
<DD>LAMMPS is attempting to open a gzipped version of the specified file
but was unsuccessful. Check that the path and name are correct.
<DT><I>Cannot open input script %s</I>
<DD>Self-explanatory.
<DT><I>Cannot open log.lammps</I>
<DD>The default LAMMPS log file cannot be opened. Check that the
directory you are running in allows for files to be created.
<DT><I>Cannot open logfile</I>
<DD>The LAMMPS log file named in a command-line argument cannot be opened.
Check that the path and name are correct.
<DT><I>Cannot open logfile %s</I>
<DD>The LAMMPS log file specified in the input script cannot be opened.
Check that the path and name are correct.
<DT><I>Cannot open pair_write file</I>
<DD>The specified output file for pair energies and forces cannot be
opened. Check that the path and name are correct.
<DT><I>Cannot open processors output file</I>
<DD>Self-explanatory.
<DT><I>Cannot open restart file %s</I>
<DD>Self-explanatory.
<DT><I>Cannot open screen file</I>
<DD>The screen file specified as a command-line argument cannot be
opened. Check that the directory you are running in allows for files
to be created.
<DT><I>Cannot open universe log file</I>
<DD>For a multi-partition run, the master log file cannot be opened.
Check that the directory you are running in allows for files to be
created.
<DT><I>Cannot open universe screen file</I>
<DD>For a multi-partition run, the master screen file cannot be opened.
Check that the directory you are running in allows for files to be
created.
<DT><I>Cannot read_data after simulation box is defined</I>
<DD>The read_data command cannot be used after a read_data,
read_restart, or create_box command.
<DT><I>Cannot read_restart after simulation box is defined</I>
<DD>The read_restart command cannot be used after a read_data,
read_restart, or create_box command.
<DT><I>Cannot redefine variable as a different style</I>
<DD>An equal-style variable can be re-defined but only if it was
originally an equal-style variable.
<DT><I>Cannot replicate 2d simulation in z dimension</I>
<DD>The replicate command cannot replicate a 2d simulation in the z
dimension.
<DT><I>Cannot replicate with fixes that store atom quantities</I>
<DD>Either fixes are defined that create and store atom-based vectors or a
restart file was read which included atom-based vectors for fixes.
The replicate command cannot duplicate that information for new atoms.
You should use the replicate command before fixes are applied to the
system.
<DT><I>Cannot reset timestep with a dynamic region defined</I>
<DD>Dynamic regions (see the region command) have a time dependence.
Thus you cannot change the timestep when one or more of these
are defined.
<DT><I>Cannot reset timestep with a time-dependent fix defined</I>
<DD>You cannot reset the timestep when a fix that keeps track of elapsed
time is in place.
-<DT><I>Cannot reset timestep with dump file already written to</I>
-
-<DD>Changing the timestep will confuse when a dump file is written. Use
-the undump command, then restart the dump file.
-
-<DT><I>Cannot reset timestep with restart file already written</I>
-
-<DD>Changing the timestep will confuse when a restart file is written.
-Use the "restart 0" command to turn off restarts, then start them
-again.
-
<DT><I>Cannot restart fix rigid/nvt with different # of chains</I>
<DD>This is because the restart file contains per-chain info.
<DT><I>Cannot run 2d simulation with nonperiodic Z dimension</I>
<DD>Use the boundary command to make the z dimension periodic in order to
run a 2d simulation.
<DT><I>Cannot set both respa pair and inner/middle/outer</I>
<DD>In the rRESPA integrator, you must compute pairwise potentials either
all together (pair), or in pieces (inner/middle/outer). You can't do
both.
<DT><I>Cannot set dump_modify flush for dump xtc</I>
<DD>Self-explanatory.
<DT><I>Cannot set mass for this atom style</I>
<DD>This atom style does not support mass settings for each atom type.
Instead they are defined on a per-atom basis in the data file.
<DT><I>Cannot set meso_rho for this atom style</I>
<DD>Self-explanatory.
<DT><I>Cannot set non-zero image flag for non-periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot set non-zero z velocity for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot set quaternion for atom that has none</I>
<DD>Self-explanatory.
<DT><I>Cannot set respa middle without inner/outer</I>
<DD>In the rRESPA integrator, you must define both a inner and outer
setting in order to use a middle setting.
<DT><I>Cannot set theta for atom that is not a line</I>
<DD>Self-explanatory.
<DT><I>Cannot set this attribute for this atom style</I>
<DD>The attribute being set does not exist for the defined atom style.
<DT><I>Cannot set variable z velocity for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot skew triclinic box in z for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot use -cuda on without USER-CUDA installed</I>
<DD>The USER-CUDA package must be installed via "make yes-user-cuda"
before LAMMPS is built.
<DT><I>Cannot use -reorder after -partition</I>
<DD>Self-explanatory. See doc page discussion of command-line switches.
<DT><I>Cannot use Ewald with 2d simulation</I>
<DD>The kspace style ewald cannot be used in 2d simulations. You can use
2d Ewald in a 3d simulation; see the kspace_modify command.
<DT><I>Cannot use Ewald with triclinic box</I>
<DD>This feature is not yet supported.
<DT><I>Cannot use NEB unless atom map exists</I>
<DD>Use the atom_modify command to create an atom map.
<DT><I>Cannot use NEB with a single replica</I>
<DD>Self-explanatory.
<DT><I>Cannot use NEB with atom_modify sort enabled</I>
<DD>This is current restriction for NEB implemented in LAMMPS.
<DT><I>Cannot use PPPM with 2d simulation</I>
<DD>The kspace style pppm cannot be used in 2d simulations. You can use
2d PPPM in a 3d simulation; see the kspace_modify command.
<DT><I>Cannot use PRD with a time-dependent fix defined</I>
<DD>PRD alters the timestep in ways that will mess up these fixes.
<DT><I>Cannot use PRD with a time-dependent region defined</I>
<DD>PRD alters the timestep in ways that will mess up these regions.
<DT><I>Cannot use PRD with atom_modify sort enabled</I>
<DD>This is a current restriction of PRD. You must turn off sorting,
which is enabled by default, via the atom_modify command.
<DT><I>Cannot use PRD with multi-processor replicas unless atom map exists</I>
<DD>Use the atom_modify command to create an atom map.
<DT><I>Cannot use TAD unless atom map exists for NEB</I>
<DD>See atom_modify map command to set this.
<DT><I>Cannot use TAD with a single replica for NEB</I>
<DD>NEB requires multiple replicas.
<DT><I>Cannot use TAD with atom_modify sort enabled for NEB</I>
<DD>This is a current restriction of NEB.
<DT><I>Cannot use a damped dynamics min style with fix box/relax</I>
<DD>This is a current restriction in LAMMPS. Use another minimizer
style.
<DT><I>Cannot use a damped dynamics min style with per-atom DOF</I>
<DD>This is a current restriction in LAMMPS. Use another minimizer
style.
<DT><I>Cannot use append/atoms in periodic dimension</I>
<DD>The boundary style of the face where atoms are added can not be of
type p (periodic).
<DT><I>Cannot use compute cluster/atom unless atoms have IDs</I>
<DD>Atom IDs are used to identify clusters.
<DT><I>Cannot use cwiggle in variable formula between runs</I>
<DD>This is a function of elapsed time.
<DT><I>Cannot use delete_atoms unless atoms have IDs</I>
<DD>Your atoms do not have IDs, so the delete_atoms command cannot be
used.
<DT><I>Cannot use delete_bonds with non-molecular system</I>
<DD>Your choice of atom style does not have bonds.
<DT><I>Cannot use fix GPU with USER-CUDA mode enabled</I>
<DD>You cannot use both the GPU and USER-CUDA packages
together. Use one or the other.
<DT><I>Cannot use fix TMD unless atom map exists</I>
<DD>Using this fix requires the ability to lookup an atom index, which is
provided by an atom map. An atom map does not exist (by default) for
non-molecular problems. Using the atom_modify map command will force
an atom map to be created.
<DT><I>Cannot use fix ave/spatial z for 2 dimensional model</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix bond/break with non-molecular systems</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix bond/create with non-molecular systems</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix box/relax on a 2nd non-periodic dimension</I>
<DD>When specifying an off-diagonal pressure component, the 2nd of the two
dimensions must be periodic. E.g. if the xy component is specified,
then the y dimension must be periodic.
<DT><I>Cannot use fix box/relax on a non-periodic dimension</I>
<DD>When specifying a diagonal pressure component, the dimension must be
periodic.
<DT><I>Cannot use fix deform on a shrink-wrapped boundary</I>
<DD>The x, y, z options cannot be applied to shrink-wrapped
dimensions.
<DT><I>Cannot use fix deform tilt on a shrink-wrapped 2nd dim</I>
<DD>This is because the shrink-wrapping will change the value
of the strain implied by the tilt factor.
<DT><I>Cannot use fix deform trate on a box with zero tilt</I>
<DD>The trate style alters the current strain.
<DT><I>Cannot use fix enforce2d with 3d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix msst without per-type mass defined</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix npt and fix deform on same component of stress tensor</I>
<DD>This would be changing the same box dimension twice.
<DT><I>Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension</I>
<DD>When specifying an off-diagonal pressure component, the 2nd of the two
dimensions must be periodic. E.g. if the xy component is specified,
then the y dimension must be periodic.
<DT><I>Cannot use fix nvt/npt/nph on a non-periodic dimension</I>
<DD>When specifying a diagonal pressure component, the dimension must be
periodic.
<DT><I>Cannot use fix nvt/npt/nph with both xy dynamics and xy scaling</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix nvt/npt/nph with both xz dynamics and xz scaling</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix nvt/npt/nph with both yz dynamics and yz scaling</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix nvt/npt/nph with xy dynamics when y is non-periodic dimension</I>
<DD>The 2nd dimension in the barostatted tilt factor must be periodic.
<DT><I>Cannot use fix nvt/npt/nph with xz dynamics when z is non-periodic dimension</I>
<DD>The 2nd dimension in the barostatted tilt factor must be periodic.
<DT><I>Cannot use fix nvt/npt/nph with yz dynamics when z is non-periodic dimension</I>
<DD>The 2nd dimension in the barostatted tilt factor must be periodic.
<DT><I>Cannot use fix pour with triclinic box</I>
<DD>This feature is not yet supported.
<DT><I>Cannot use fix press/berendsen and fix deform on same component of stress tensor</I>
<DD>These commands both change the box size/shape, so you cannot use both
together.
<DT><I>Cannot use fix press/berendsen on a non-periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix press/berendsen with triclinic box</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix reax/bonds without pair_style reax</I>
<DD>Self-explantory.
<DT><I>Cannot use fix shake with non-molecular system</I>
<DD>Your choice of atom style does not have bonds.
<DT><I>Cannot use fix ttm with 2d simulation</I>
<DD>This is a current restriction of this fix due to the grid it creates.
<DT><I>Cannot use fix ttm with triclinic box</I>
<DD>This is a current restriction of this fix due to the grid it creates.
<DT><I>Cannot use fix wall in periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall zlo/zhi for a 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall/reflect in periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall/reflect zlo/zhi for a 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall/srd in periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall/srd more than once</I>
<DD>Nor is their a need to since multiple walls can be specified
in one command.
<DT><I>Cannot use fix wall/srd without fix srd</I>
<DD>Self-explanatory.
<DT><I>Cannot use fix wall/srd zlo/zhi for a 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Cannot use force/hybrid_neigh with triclinic box</I>
<DD>Self-explanatory.
<DT><I>Cannot use force/neigh with triclinic box</I>
<DD>This is a current limitation of the GPU implementation
in LAMMPS.
<DT><I>Cannot use kspace solver on system with no charge</I>
<DD>No atoms in system have a non-zero charge.
<DT><I>Cannot use lines with fix srd unless overlap is set</I>
<DD>This is because line segements are connected to each other.
<DT><I>Cannot use neigh_modify exclude with GPU neighbor builds</I>
<DD>This is a current limitation of the GPU implementation
in LAMMPS.
<DT><I>Cannot use neighbor bins - box size << cutoff</I>
<DD>Too many neighbor bins will be created. This typically happens when
the simulation box is very small in some dimension, compared to the
neighbor cutoff. Use the "nsq" style instead of "bin" style.
<DT><I>Cannot use newton pair with buck/coul/cut/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with buck/coul/long/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with buck/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with coul/long/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with eam/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with gayberne/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with lj/charmm/coul/long/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with lj/class2/coul/long/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with lj/class2/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with lj/cut/coul/cut/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with lj/cut/coul/long/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with lj/cut/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with lj/expand/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with lj96/cut/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with morse/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with resquared/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with table/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use newton pair with yukawa/gpu pair style</I>
<DD>Self-explanatory.
<DT><I>Cannot use non-zero forces in an energy minimization</I>
<DD>Fix setforce cannot be used in this manner. Use fix addforce
instead.
<DT><I>Cannot use nonperiodic boundares with fix ttm</I>
<DD>This fix requires a fully periodic simulation box.
<DT><I>Cannot use nonperiodic boundaries with Ewald</I>
<DD>For kspace style ewald, all 3 dimensions must have periodic boundaries
unless you use the kspace_modify command to define a 2d slab with a
non-periodic z dimension.
<DT><I>Cannot use nonperiodic boundaries with PPPM</I>
<DD>For kspace style pppm, all 3 dimensions must have periodic boundaries
unless you use the kspace_modify command to define a 2d slab with a
non-periodic z dimension.
<DT><I>Cannot use order greater than 8 with pppm/gpu.</I>
<DD>Self-explanatory.
<DT><I>Cannot use pair hybrid with GPU neighbor builds</I>
<DD>See documentation for fix gpu.
<DT><I>Cannot use pair tail corrections with 2d simulations</I>
<DD>The correction factors are only currently defined for 3d systems.
<DT><I>Cannot use processors part command without using partitions</I>
<DD>See the command-line -partition switch.
<DT><I>Cannot use ramp in variable formula between runs</I>
<DD>This is because the ramp() function is time dependent.
<DT><I>Cannot use region INF or EDGE when box does not exist</I>
<DD>Regions that extend to the box boundaries can only be used after the
create_box command has been used.
<DT><I>Cannot use set atom with no atom IDs defined</I>
<DD>Atom IDs are not defined, so they cannot be used to identify an atom.
<DT><I>Cannot use set mol with no molecule IDs defined</I>
<DD>Self-explanatory.
<DT><I>Cannot use swiggle in variable formula between runs</I>
<DD>This is a function of elapsed time.
<DT><I>Cannot use tris with fix srd unless overlap is set</I>
<DD>This is because triangles are connected to each other.
<DT><I>Cannot use variable energy with constant force in fix addforce</I>
<DD>This is because for constant force, LAMMPS can compute the change
in energy directly.
<DT><I>Cannot use variable every setting for dump dcd</I>
<DD>The format of DCD dump files requires snapshots be output
at a constant frequency.
<DT><I>Cannot use variable every setting for dump xtc</I>
<DD>The format of this file requires snapshots at regular intervals.
<DT><I>Cannot use vdisplace in variable formula between runs</I>
<DD>This is a function of elapsed time.
<DT><I>Cannot use velocity create loop all unless atoms have IDs</I>
<DD>Atoms in the simulation to do not have IDs, so this style
of velocity creation cannot be performed.
<DT><I>Cannot use wall in periodic dimension</I>
<DD>Self-explanatory.
<DT><I>Cannot wiggle and shear fix wall/gran</I>
<DD>Cannot specify both options at the same time.
+<DT><I>Cannot yet use fix balance with PPPM</I>
+
+<DD>This is a current limitation of LAMMPS.
+
<DT><I>Cannot zero Langevin force of 0 atoms</I>
<DD>The group has zero atoms, so you cannot request its force
be zeroed.
<DT><I>Cannot zero momentum of 0 atoms</I>
<DD>The collection of atoms for which momentum is being computed has no
atoms.
<DT><I>Change_box command before simulation box is defined</I>
<DD>Self-explanatory.
<DT><I>Change_box volume used incorrectly</I>
<DD>The "dim volume" option must be used immediately following one or two
settings for "dim1 ..." (and optionally "dim2 ...") and must be for a
different dimension, i.e. dim != dim1 and dim != dim2.
<DT><I>Communicate group != atom_modify first group</I>
<DD>Self-explanatory.
<DT><I>Compute ID for compute atom/molecule does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for compute reduce does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for compute slice does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix ave/atom does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix ave/correlate does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix ave/histo does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix ave/spatial does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix ave/time does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID for fix store/state does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ID must be alphanumeric or underscore characters</I>
<DD>Self-explanatory.
<DT><I>Compute angle/local used when angles are not allowed</I>
<DD>The atom style does not support angles.
<DT><I>Compute atom/molecule compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule compute does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule compute does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule compute does not calculate per-atom values</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule fix does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule fix does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule fix does not calculate per-atom values</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule requires molecular atom style</I>
<DD>Self-explanatory.
<DT><I>Compute atom/molecule variable is not atom-style variable</I>
<DD>Self-explanatory.
<DT><I>Compute bond/local used when bonds are not allowed</I>
<DD>The atom style does not support bonds.
<DT><I>Compute centro/atom requires a pair style be defined</I>
<DD>This is because the computation of the centro-symmetry values
uses a pairwise neighbor list.
<DT><I>Compute cluster/atom cutoff is longer than pairwise cutoff</I>
<DD>Cannot identify clusters beyond cutoff.
<DT><I>Compute cluster/atom requires a pair style be defined</I>
<DD>This is so that the pair style defines a cutoff distance which
is used to find clusters.
<DT><I>Compute cna/atom cutoff is longer than pairwise cutoff</I>
<DD>Self-explantory.
<DT><I>Compute cna/atom requires a pair style be defined</I>
<DD>Self-explantory.
<DT><I>Compute com/molecule requires molecular atom style</I>
<DD>Self-explanatory.
<DT><I>Compute coord/atom cutoff is longer than pairwise cutoff</I>
<DD>Cannot compute coordination at distances longer than the pair cutoff,
since those atoms are not in the neighbor list.
<DT><I>Compute coord/atom requires a pair style be defined</I>
<DD>Self-explantory.
<DT><I>Compute damage/atom requires peridynamic potential</I>
<DD>Damage is a Peridynamic-specific metric. It requires you
to be running a Peridynamics simulation.
<DT><I>Compute dihedral/local used when dihedrals are not allowed</I>
<DD>The atom style does not support dihedrals.
<DT><I>Compute does not allow an extra compute or fix to be reset</I>
<DD>This is an internal LAMMPS error. Please report it to the
developers.
<DT><I>Compute erotate/asphere requires atom style ellipsoid or line or tri</I>
<DD>Self-explanatory.
<DT><I>Compute erotate/asphere requires extended particles</I>
<DD>This compute cannot be used with point paritlces.
<DT><I>Compute erotate/sphere requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Compute event/displace has invalid fix event assigned</I>
<DD>This is an internal LAMMPS error. Please report it to the
developers.
<DT><I>Compute group/group group ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute gyration/molecule requires molecular atom style</I>
<DD>Self-explanatory.
<DT><I>Compute heat/flux compute ID does not compute ke/atom</I>
<DD>Self-explanatory.
<DT><I>Compute heat/flux compute ID does not compute pe/atom</I>
<DD>Self-explanatory.
<DT><I>Compute heat/flux compute ID does not compute stress/atom</I>
<DD>Self-explanatory.
<DT><I>Compute improper/local used when impropers are not allowed</I>
<DD>The atom style does not support impropers.
<DT><I>Compute msd/molecule requires molecular atom style</I>
<DD>Self-explanatory.
<DT><I>Compute nve/asphere requires atom style ellipsoid</I>
<DD>Self-explanatory.
<DT><I>Compute nvt/nph/npt asphere requires atom style ellipsoid</I>
<DD>Self-explanatory.
<DT><I>Compute pair must use group all</I>
<DD>Pair styles accumlate energy on all atoms.
<DT><I>Compute pe must use group all</I>
<DD>Energies computed by potentials (pair, bond, etc) are computed on all
atoms.
<DT><I>Compute pressure must use group all</I>
<DD>Virial contributions computed by potentials (pair, bond, etc) are
computed on all atoms.
<DT><I>Compute pressure temperature ID does not compute temperature</I>
<DD>The compute ID assigned to a pressure computation must compute
temperature.
<DT><I>Compute property/atom for atom property that isn't allocated</I>
<DD>Self-explanatory.
<DT><I>Compute property/local cannot use these inputs together</I>
<DD>Only inputs that generate the same number of datums can be used
togther. E.g. bond and angle quantities cannot be mixed.
<DT><I>Compute property/local for property that isn't allocated</I>
<DD>Self-explanatory.
<DT><I>Compute property/molecule requires molecular atom style</I>
<DD>Self-explanatory.
<DT><I>Compute rdf requires a pair style be defined</I>
<DD>Self-explanatory.
<DT><I>Compute reduce compute array is accessed out-of-range</I>
<DD>An index for the array is out of bounds.
<DT><I>Compute reduce compute calculates global values</I>
<DD>A compute that calculates peratom or local values is required.
<DT><I>Compute reduce compute does not calculate a local array</I>
<DD>Self-explanatory.
<DT><I>Compute reduce compute does not calculate a local vector</I>
<DD>Self-explanatory.
<DT><I>Compute reduce compute does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Compute reduce compute does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Compute reduce fix array is accessed out-of-range</I>
<DD>An index for the array is out of bounds.
<DT><I>Compute reduce fix calculates global values</I>
<DD>A fix that calculates peratom or local values is required.
<DT><I>Compute reduce fix does not calculate a local array</I>
<DD>Self-explanatory.
<DT><I>Compute reduce fix does not calculate a local vector</I>
<DD>Self-explanatory.
<DT><I>Compute reduce fix does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Compute reduce fix does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Compute reduce replace requires min or max mode</I>
<DD>Self-explanatory.
<DT><I>Compute reduce variable is not atom-style variable</I>
<DD>Self-explanatory.
<DT><I>Compute slice compute array is accessed out-of-range</I>
<DD>An index for the array is out of bounds.
<DT><I>Compute slice compute does not calculate a global array</I>
<DD>Self-explanatory.
<DT><I>Compute slice compute does not calculate a global vector</I>
<DD>Self-explanatory.
<DT><I>Compute slice compute does not calculate global vector or array</I>
<DD>Self-explanatory.
<DT><I>Compute slice compute vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
<DT><I>Compute slice fix array is accessed out-of-range</I>
<DD>An index for the array is out of bounds.
<DT><I>Compute slice fix does not calculate a global array</I>
<DD>Self-explanatory.
<DT><I>Compute slice fix does not calculate a global vector</I>
<DD>Self-explanatory.
<DT><I>Compute slice fix does not calculate global vector or array</I>
<DD>Self-explanatory.
<DT><I>Compute slice fix vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
<DT><I>Compute temp/asphere requires atom style ellipsoid</I>
<DD>Self-explanatory.
<DT><I>Compute temp/asphere requires extended particles</I>
<DD>This compute cannot be used with point paritlces.
<DT><I>Compute temp/partial cannot use vz for 2d systemx</I>
<DD>Self-explanatory.
<DT><I>Compute temp/profile cannot bin z for 2d systems</I>
<DD>Self-explanatory.
<DT><I>Compute temp/profile cannot use vz for 2d systemx</I>
<DD>Self-explanatory.
<DT><I>Compute temp/sphere requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Compute ti kspace style does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ti pair style does not exist</I>
<DD>Self-explanatory.
<DT><I>Compute ti tail when pair style does not compute tail corrections</I>
<DD>Self-explanatory.
<DT><I>Compute used in variable between runs is not current</I>
<DD>Computes cannot be invoked by a variable in between runs. Thus they
must have been evaluated on the last timestep of the previous run in
order for their value(s) to be accessed. See the doc page for the
variable command for more info.
<DT><I>Compute used in variable thermo keyword between runs is not current</I>
<DD>Some thermo keywords rely on a compute to calculate their value(s).
Computes cannot be invoked by a variable in between runs. Thus they
must have been evaluated on the last timestep of the previous run in
order for their value(s) to be accessed. See the doc page for the
variable command for more info.
<DT><I>Computed temperature for fix temp/berendsen cannot be 0.0</I>
<DD>Self-explanatory.
<DT><I>Computed temperature for fix temp/rescale cannot be 0.0</I>
<DD>Cannot rescale the temperature to a new value if the current
temperature is 0.0.
<DT><I>Could not count initial bonds in fix bond/create</I>
<DD>Could not find one of the atoms in a bond on this processor.
<DT><I>Could not create 3d FFT plan</I>
<DD>The FFT setup in pppm failed.
<DT><I>Could not create 3d grid of processors</I>
<DD>The specified constraints did not allow a Px by Py by Pz grid to be
created where Px * Py * Pz = P = total number of processors.
<DT><I>Could not create 3d remap plan</I>
<DD>The FFT setup in pppm failed.
<DT><I>Could not create numa grid of processors</I>
<DD>The specified constraints did not allow this style of grid to be
created. Usually this is because the total processor count is not a
multiple of the cores/node or the user specified processor count is >
1 in one of the dimensions.
<DT><I>Could not create twolevel 3d grid of processors</I>
<DD>The specified constraints did not allow this style of grid to be
created.
<DT><I>Could not find atom_modify first group ID</I>
<DD>Self-explanatory.
<DT><I>Could not find change_box group ID</I>
<DD>Group ID used in the change_box command does not exist.
<DT><I>Could not find compute ID for PRD</I>
<DD>Self-explanatory.
<DT><I>Could not find compute ID for TAD</I>
<DD>Self-explanatory.
<DT><I>Could not find compute ID for temperature bias</I>
<DD>Self-explanatory.
<DT><I>Could not find compute ID to delete</I>
<DD>Self-explanatory.
<DT><I>Could not find compute displace/atom fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find compute event/displace fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find compute group ID</I>
<DD>Self-explanatory.
<DT><I>Could not find compute heat/flux compute ID</I>
<DD>Self-explanatory.
<DT><I>Could not find compute msd fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find compute pressure temperature ID</I>
<DD>The compute ID for calculating temperature does not exist.
<DT><I>Could not find compute_modify ID</I>
<DD>Self-explanatory.
<DT><I>Could not find delete_atoms group ID</I>
<DD>Group ID used in the delete_atoms command does not exist.
<DT><I>Could not find delete_atoms region ID</I>
<DD>Region ID used in the delete_atoms command does not exist.
<DT><I>Could not find displace_atoms group ID</I>
<DD>Group ID used in the displace_atoms command does not exist.
<DT><I>Could not find dump custom compute ID</I>
<DD>The compute ID needed by dump custom to compute a per-atom quantity
does not exist.
<DT><I>Could not find dump custom fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump custom variable name</I>
<DD>Self-explanatory.
<DT><I>Could not find dump group ID</I>
<DD>A group ID used in the dump command does not exist.
<DT><I>Could not find dump local compute ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump local fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump modify compute ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump modify fix ID</I>
<DD>Self-explanatory.
<DT><I>Could not find dump modify variable name</I>
<DD>Self-explanatory.
<DT><I>Could not find fix ID to delete</I>
<DD>Self-explanatory.
<DT><I>Could not find fix group ID</I>
<DD>A group ID used in the fix command does not exist.
<DT><I>Could not find fix msst compute ID</I>
<DD>Self-explanatory.
<DT><I>Could not find fix poems group ID</I>
<DD>A group ID used in the fix poems command does not exist.
<DT><I>Could not find fix recenter group ID</I>
<DD>A group ID used in the fix recenter command does not exist.
<DT><I>Could not find fix rigid group ID</I>
<DD>A group ID used in the fix rigid command does not exist.
<DT><I>Could not find fix srd group ID</I>
<DD>Self-explanatory.
<DT><I>Could not find fix_modify ID</I>
<DD>A fix ID used in the fix_modify command does not exist.
<DT><I>Could not find fix_modify pressure ID</I>
<DD>The compute ID for computing pressure does not exist.
<DT><I>Could not find fix_modify temperature ID</I>
<DD>The compute ID for computing temperature does not exist.
<DT><I>Could not find group delete group ID</I>
<DD>Self-explanatory.
<DT><I>Could not find set group ID</I>
<DD>Group ID specified in set command does not exist.
<DT><I>Could not find thermo compute ID</I>
<DD>Compute ID specified in thermo_style command does not exist.
<DT><I>Could not find thermo custom compute ID</I>
<DD>The compute ID needed by thermo style custom to compute a requested
quantity does not exist.
<DT><I>Could not find thermo custom fix ID</I>
<DD>The fix ID needed by thermo style custom to compute a requested
quantity does not exist.
<DT><I>Could not find thermo custom variable name</I>
<DD>Self-explanatory.
<DT><I>Could not find thermo fix ID</I>
<DD>Fix ID specified in thermo_style command does not exist.
<DT><I>Could not find thermo variable name</I>
<DD>Self-explanatory.
<DT><I>Could not find thermo_modify pressure ID</I>
<DD>The compute ID needed by thermo style custom to compute pressure does
not exist.
<DT><I>Could not find thermo_modify temperature ID</I>
<DD>The compute ID needed by thermo style custom to compute temperature does
not exist.
<DT><I>Could not find undump ID</I>
<DD>A dump ID used in the undump command does not exist.
<DT><I>Could not find velocity group ID</I>
<DD>A group ID used in the velocity command does not exist.
<DT><I>Could not find velocity temperature ID</I>
<DD>The compute ID needed by the velocity command to compute temperature
does not exist.
<DT><I>Could not find/initialize a specified accelerator device</I>
<DD>Could not initialize at least one of the devices specified for the gpu
package
<DT><I>Could not grab element entry from EIM potential file</I>
<DD>Self-explanatory
<DT><I>Could not grab global entry from EIM potential file</I>
<DD>Self-explanatory.
<DT><I>Could not grab pair entry from EIM potential file</I>
<DD>Self-explanatory.
<DT><I>Coulomb cutoffs of pair hybrid sub-styles do not match</I>
<DD>If using a Kspace solver, all Coulomb cutoffs of long pair styles must
be the same.
<DT><I>Cound not find dump_modify ID</I>
<DD>Self-explanatory.
<DT><I>Create_atoms command before simulation box is defined</I>
<DD>The create_atoms command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Create_atoms region ID does not exist</I>
<DD>A region ID used in the create_atoms command does not exist.
<DT><I>Create_box region ID does not exist</I>
<DD>A region ID used in the create_box command does not exist.
<DT><I>Create_box region does not support a bounding box</I>
<DD>Not all regions represent bounded volumes. You cannot use
such a region with the create_box command.
<DT><I>Cyclic loop in joint connections</I>
<DD>Fix poems cannot (yet) work with coupled bodies whose joints connect
the bodies in a ring (or cycle).
<DT><I>Degenerate lattice primitive vectors</I>
<DD>Invalid set of 3 lattice vectors for lattice command.
<DT><I>Delete region ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Delete_atoms command before simulation box is defined</I>
<DD>The delete_atoms command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Delete_atoms cutoff > neighbor cutoff</I>
<DD>Cannot delete atoms further away than a processor knows about.
<DT><I>Delete_atoms requires a pair style be defined</I>
<DD>This is because atom deletion within a cutoff uses a pairwise
neighbor list.
<DT><I>Delete_bonds command before simulation box is defined</I>
<DD>The delete_bonds command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Delete_bonds command with no atoms existing</I>
<DD>No atoms are yet defined so the delete_bonds command cannot be used.
<DT><I>Deposition region extends outside simulation box</I>
<DD>Self-explanatory.
<DT><I>Did not assign all atoms correctly</I>
<DD>Atoms read in from a data file were not assigned correctly to
processors. This is likely due to some atom coordinates being
outside a non-periodic simulation box.
<DT><I>Did not find all elements in MEAM library file</I>
<DD>The requested elements were not found in the MEAM file.
<DT><I>Did not find fix shake partner info</I>
<DD>Could not find bond partners implied by fix shake command. This error
can be triggered if the delete_bonds command was used before fix
shake, and it removed bonds without resetting the 1-2, 1-3, 1-4
weighting list via the special keyword.
<DT><I>Did not find keyword in table file</I>
<DD>Keyword used in pair_coeff command was not found in table file.
<DT><I>Did not set temp for fix rigid/nvt</I>
<DD>The temp keyword must be used.
<DT><I>Dihedral atom missing in delete_bonds</I>
<DD>The delete_bonds command cannot find one or more atoms in a particular
dihedral on a particular processor. The pairwise cutoff is too short
or the atoms are too far apart to make a valid dihedral.
<DT><I>Dihedral atom missing in set command</I>
<DD>The set command cannot find one or more atoms in a particular dihedral
on a particular processor. The pairwise cutoff is too short or the
atoms are too far apart to make a valid dihedral.
<DT><I>Dihedral atoms %d %d %d %d missing on proc %d at step %ld</I>
<DD>One or more of 4 atoms needed to compute a particular dihedral are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the dihedral has blown apart and an atom is
too far away.
<DT><I>Dihedral charmm is incompatible with Pair style</I>
<DD>Dihedral style charmm must be used with a pair style charmm
in order for the 1-4 epsilon/sigma parameters to be defined.
<DT><I>Dihedral coeff for hybrid has invalid style</I>
<DD>Dihedral style hybrid uses another dihedral style as one of its
coefficients. The dihedral style used in the dihedral_coeff command
or read from a restart file is not recognized.
<DT><I>Dihedral coeffs are not set</I>
<DD>No dihedral coefficients have been assigned in the data file or via
the dihedral_coeff command.
<DT><I>Dihedral style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Dihedral style hybrid cannot have none as an argument</I>
<DD>Self-explanatory.
<DT><I>Dihedral style hybrid cannot use same dihedral style twice</I>
<DD>Self-explanatory.
<DT><I>Dihedral_coeff command before dihedral_style is defined</I>
<DD>Coefficients cannot be set in the data file or via the dihedral_coeff
command until an dihedral_style has been assigned.
<DT><I>Dihedral_coeff command before simulation box is defined</I>
<DD>The dihedral_coeff command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Dihedral_coeff command when no dihedrals allowed</I>
<DD>The chosen atom style does not allow for dihedrals to be defined.
<DT><I>Dihedral_style command when no dihedrals allowed</I>
<DD>The chosen atom style does not allow for dihedrals to be defined.
<DT><I>Dihedrals assigned incorrectly</I>
<DD>Dihedrals read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions.
<DT><I>Dihedrals defined but no dihedral types</I>
<DD>The data file header lists dihedrals but no dihedral types.
<DT><I>Dimension command after simulation box is defined</I>
<DD>The dimension command cannot be used after a read_data,
read_restart, or create_box command.
<DT><I>Displace_atoms command before simulation box is defined</I>
<DD>The displace_atoms command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Distance must be > 0 for compute event/displace</I>
<DD>Self-explanatory.
<DT><I>Divide by 0 in influence function of pair peri/lps</I>
<DD>This should not normally occur. It is likely a problem with your
model.
<DT><I>Divide by 0 in variable formula</I>
<DD>Self-explanatory.
<DT><I>Domain too large for neighbor bins</I>
<DD>The domain has become extremely large so that neighbor bins cannot be
used. Most likely, one or more atoms have been blown out of the
simulation box to a great distance.
<DT><I>Double precision is not supported on this accelerator</I>
<DD>Self-explanatory
<DT><I>Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu</I>
<DD>Self-explanatory.
<DT><I>Dump cfg arguments must start with 'id type xs ys zs' or 'id type xsu ysu zsu'</I>
<DD>This is a requirement of the CFG output format.
<DT><I>Dump cfg requires one snapshot per file</I>
<DD>Use the wildcard "*" character in the filename.
<DT><I>Dump custom and fix not computed at compatible times</I>
<DD>The fix must produce per-atom quantities on timesteps that dump custom
needs them.
<DT><I>Dump custom compute does not calculate per-atom array</I>
<DD>Self-explanatory.
<DT><I>Dump custom compute does not calculate per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Dump custom compute does not compute per-atom info</I>
<DD>Self-explanatory.
<DT><I>Dump custom compute vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Dump custom fix does not compute per-atom array</I>
<DD>Self-explanatory.
<DT><I>Dump custom fix does not compute per-atom info</I>
<DD>Self-explanatory.
<DT><I>Dump custom fix does not compute per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Dump custom fix vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Dump custom variable is not atom-style variable</I>
<DD>Only atom-style variables generate per-atom quantities, needed for
dump output.
<DT><I>Dump dcd of non-matching # of atoms</I>
<DD>Every snapshot written by dump dcd must contain the same # of atoms.
<DT><I>Dump dcd requires sorting by atom ID</I>
<DD>Use the dump_modify sort command to enable this.
<DT><I>Dump every variable returned a bad timestep</I>
<DD>The variable must return a timestep greater than the current timestep.
+<DT><I>Dump file does not contain requested snapshot</I>
+
+<DD>Self-explanatory.
+
+<DT><I>Dump file is incorrectly formatted</I>
+
+<DD>No atoms were found in file.
+
<DT><I>Dump image bond not allowed with no bond types</I>
<DD>Self-explanatory.
<DT><I>Dump image cannot perform sorting</I>
<DD>Self-explanatory.
<DT><I>Dump image persp option is not yet supported</I>
<DD>Self-explanatory.
<DT><I>Dump image requires one snapshot per file</I>
<DD>Use a "*" in the filename.
<DT><I>Dump local and fix not computed at compatible times</I>
<DD>The fix must produce per-atom quantities on timesteps that dump local
needs them.
<DT><I>Dump local attributes contain no compute or fix</I>
<DD>Self-explanatory.
<DT><I>Dump local cannot sort by atom ID</I>
<DD>This is because dump local does not really dump per-atom info.
<DT><I>Dump local compute does not calculate local array</I>
<DD>Self-explanatory.
<DT><I>Dump local compute does not calculate local vector</I>
<DD>Self-explanatory.
<DT><I>Dump local compute does not compute local info</I>
<DD>Self-explanatory.
<DT><I>Dump local compute vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Dump local count is not consistent across input fields</I>
<DD>Every column of output must be the same length.
<DT><I>Dump local fix does not compute local array</I>
<DD>Self-explanatory.
<DT><I>Dump local fix does not compute local info</I>
<DD>Self-explanatory.
<DT><I>Dump local fix does not compute local vector</I>
<DD>Self-explanatory.
<DT><I>Dump local fix vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Dump modify bcolor not allowed with no bond types</I>
<DD>Self-explanatory.
<DT><I>Dump modify bdiam not allowed with no bond types</I>
<DD>Self-explanatory.
<DT><I>Dump modify compute ID does not compute per-atom array</I>
<DD>Self-explanatory.
<DT><I>Dump modify compute ID does not compute per-atom info</I>
<DD>Self-explanatory.
<DT><I>Dump modify compute ID does not compute per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Dump modify compute ID vector is not large enough</I>
<DD>Self-explanatory.
<DT><I>Dump modify element names do not match atom types</I>
<DD>Number of element names must equal number of atom types.
<DT><I>Dump modify fix ID does not compute per-atom array</I>
<DD>Self-explanatory.
<DT><I>Dump modify fix ID does not compute per-atom info</I>
<DD>Self-explanatory.
<DT><I>Dump modify fix ID does not compute per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Dump modify fix ID vector is not large enough</I>
<DD>Self-explanatory.
<DT><I>Dump modify variable is not atom-style variable</I>
<DD>Self-explanatory.
<DT><I>Dump sort column is invalid</I>
<DD>Self-explanatory.
<DT><I>Dump xtc requires sorting by atom ID</I>
<DD>Use the dump_modify sort command to enable this.
<DT><I>Dump_modify region ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Dumping an atom property that isn't allocated</I>
<DD>The chosen atom style does not define the per-atom quantity being
dumped.
<DT><I>Dumping an atom quantity that isn't allocated</I>
<DD>Only per-atom quantities that are defined for the atom style being
used are allowed.
+<DT><I>Duplicate fields in read_dump command</I>
+
+<DD>Self-explanatory.
+
<DT><I>Duplicate particle in PeriDynamic bond - simulation box is too small</I>
<DD>This is likely because your box length is shorter than 2 times
the bond length.
<DT><I>Electronic temperature dropped below zero</I>
<DD>Something has gone wrong with the fix ttm electron temperature model.
<DT><I>Empty brackets in variable</I>
<DD>There is no variable syntax that uses empty brackets. Check
the variable doc page.
<DT><I>Energy was not tallied on needed timestep</I>
<DD>You are using a thermo keyword that requires potentials to
have tallied energy, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work.
<DT><I>Expected floating point parameter in input script or data file</I>
<DD>The quantity being read is an integer on non-numeric value.
<DT><I>Expected floating point parameter in variable definition</I>
<DD>The quantity being read is a non-numeric value.
<DT><I>Expected integer parameter in input script or data file</I>
<DD>The quantity being read is a floating point or non-numeric value.
<DT><I>Expected integer parameter in variable definition</I>
<DD>The quantity being read is a floating point or non-numeric value.
<DT><I>Failed to allocate %ld bytes for array %s</I>
<DD>Your LAMMPS simulation has run out of memory. You need to run a
smaller simulation or on more processors.
<DT><I>Failed to reallocate %ld bytes for array %s</I>
<DD>Your LAMMPS simulation has run out of memory. You need to run a
smaller simulation or on more processors.
<DT><I>Fewer SRD bins than processors in some dimension</I>
<DD>This is not allowed. Make your SRD bin size smaller.
<DT><I>Final box dimension due to fix deform is < 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix GCMC incompatible with given pair_style</I>
<DD>Some pair_styles do not provide single-atom energies, which are needed
by fix GCMC.
<DT><I>Fix GCMC molecule command requires atom attribute molecule</I>
<DD>Should not choose the GCMC molecule feature if no molecules are being
simulated. The general molecule flag is off, but GCMC's molecule flag
is on.
<DT><I>Fix GCMC molecule feature does not yet work</I>
<DD>Fix GCMC cannot (yet) be used to exchange molecules, only atoms.
<DT><I>Fix GPU split must be positive for hybrid pair styles</I>
<DD>Self-explanatory.
<DT><I>Fix ID for compute atom/molecule does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for compute reduce does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for compute slice does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix ave/atom does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix ave/correlate does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix ave/histo does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix ave/spatial does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix ave/time does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix ID for fix store/state does not exist</I>
<DD>Self-explanatory
+<DT><I>Fix ID for read_data does not exist</I>
+
+<DD>Self-explanatory.
+
<DT><I>Fix ID must be alphanumeric or underscore characters</I>
<DD>Self-explanatory.
<DT><I>Fix SRD no-slip requires atom attribute torque</I>
<DD>This is because the SRD collisions will impart torque to the solute
particles.
<DT><I>Fix SRD: bad bin assignment for SRD advection</I>
<DD>Something has gone wrong in your SRD model; try using more
conservative settings.
<DT><I>Fix SRD: bad search bin assignment</I>
<DD>Something has gone wrong in your SRD model; try using more
conservative settings.
<DT><I>Fix SRD: bad stencil bin for big particle</I>
<DD>Something has gone wrong in your SRD model; try using more
conservative settings.
<DT><I>Fix SRD: too many big particles in bin</I>
<DD>Reset the ATOMPERBIN parameter at the top of fix_srd.cpp
to a larger value, and re-compile the code.
<DT><I>Fix SRD: too many walls in bin</I>
<DD>This should not happen unless your system has been setup incorrectly.
<DT><I>Fix adapt kspace style does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix adapt pair style does not exist</I>
<DD>Self-explanatory
<DT><I>Fix adapt pair style param not supported</I>
<DD>The pair style does not know about the parameter you specified.
<DT><I>Fix adapt requires atom attribute diameter</I>
<DD>The atom style being used does not specify an atom diameter.
<DT><I>Fix adapt type pair range is not valid for pair hybrid sub-style</I>
<DD>Self-explanatory.
<DT><I>Fix ave/atom compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/atom compute does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/atom compute does not calculate a per-atom vector</I>
<DD>A compute used by fix ave/atom must generate per-atom values.
<DT><I>Fix ave/atom compute does not calculate per-atom values</I>
<DD>A compute used by fix ave/atom must generate per-atom values.
<DT><I>Fix ave/atom fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/atom fix does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/atom fix does not calculate a per-atom vector</I>
<DD>A fix used by fix ave/atom must generate per-atom values.
<DT><I>Fix ave/atom fix does not calculate per-atom values</I>
<DD>A fix used by fix ave/atom must generate per-atom values.
+<DT><I>Fix ave/atom missed timestep</I>
+
+<DD>You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging.
+
<DT><I>Fix ave/atom variable is not atom-style variable</I>
<DD>A variable used by fix ave/atom must generate per-atom values.
<DT><I>Fix ave/correlate compute does not calculate a scalar</I>
<DD>Self-explanatory.
<DT><I>Fix ave/correlate compute does not calculate a vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/correlate compute vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
<DT><I>Fix ave/correlate fix does not calculate a scalar</I>
<DD>Self-explanatory.
<DT><I>Fix ave/correlate fix does not calculate a vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/correlate fix vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
+<DT><I>Fix ave/correlate missed timestep</I>
+
+<DD>You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging.
+
<DT><I>Fix ave/correlate variable is not equal-style variable</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo cannot input local values in scalar mode</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo cannot input per-atom values in scalar mode</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a global array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a global scalar</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a global vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a local array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a local vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate local values</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute does not calculate per-atom values</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo compute vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a global array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a global scalar</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a global vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a local array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a local vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate a per-atom vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate local values</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix does not calculate per-atom values</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo fix vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo input is invalid compute</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo input is invalid fix</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo input is invalid variable</I>
<DD>Self-explanatory.
<DT><I>Fix ave/histo inputs are not all global, peratom, or local</I>
<DD>All inputs in a single fix ave/histo command must be of the
same style.
+<DT><I>Fix ave/histo missed timestep</I>
+
+<DD>You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging.
+
<DT><I>Fix ave/spatial compute does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/spatial compute does not calculate a per-atom vector</I>
<DD>A compute used by fix ave/spatial must generate per-atom values.
<DT><I>Fix ave/spatial compute does not calculate per-atom values</I>
<DD>A compute used by fix ave/spatial must generate per-atom values.
<DT><I>Fix ave/spatial compute vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
<DT><I>Fix ave/spatial fix does not calculate a per-atom array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/spatial fix does not calculate a per-atom vector</I>
<DD>A fix used by fix ave/spatial must generate per-atom values.
<DT><I>Fix ave/spatial fix does not calculate per-atom values</I>
<DD>A fix used by fix ave/spatial must generate per-atom values.
<DT><I>Fix ave/spatial fix vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
<DT><I>Fix ave/spatial for triclinic boxes requires units reduced</I>
<DD>Self-explanatory.
+<DT><I>Fix ave/spatial missed timestep</I>
+
+<DD>You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging.
+
<DT><I>Fix ave/spatial settings invalid with changing box</I>
<DD>If the ave setting is "running" or "window" and the box size/shape
changes during the simulation, then the units setting must be
"reduced", else the number of bins may change.
<DT><I>Fix ave/spatial variable is not atom-style variable</I>
<DD>A variable used by fix ave/spatial must generate per-atom values.
<DT><I>Fix ave/time cannot set output array intensive/extensive from these inputs</I>
<DD>One of more of the vector inputs has individual elements which are
flagged as intensive or extensive. Such an input cannot be flagged as
all intensive/extensive when turned into an array by fix ave/time.
<DT><I>Fix ave/time cannot use variable with vector mode</I>
<DD>Variables produce scalar values.
<DT><I>Fix ave/time columns are inconsistent lengths</I>
<DD>Self-explanatory.
<DT><I>Fix ave/time compute array is accessed out-of-range</I>
<DD>An index for the array is out of bounds.
<DT><I>Fix ave/time compute does not calculate a scalar</I>
<DD>Self-explantory.
<DT><I>Fix ave/time compute does not calculate a vector</I>
<DD>Self-explantory.
<DT><I>Fix ave/time compute does not calculate an array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/time compute vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
<DT><I>Fix ave/time fix array is accessed out-of-range</I>
<DD>An index for the array is out of bounds.
<DT><I>Fix ave/time fix does not calculate a scalar</I>
<DD>Self-explanatory.
<DT><I>Fix ave/time fix does not calculate a vector</I>
<DD>Self-explanatory.
<DT><I>Fix ave/time fix does not calculate an array</I>
<DD>Self-explanatory.
<DT><I>Fix ave/time fix vector is accessed out-of-range</I>
<DD>The index for the vector is out of bounds.
+<DT><I>Fix ave/time missed timestep</I>
+
+<DD>You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging.
+
<DT><I>Fix ave/time variable is not equal-style variable</I>
<DD>Self-explanatory.
<DT><I>Fix balance string is invalid</I>
<DD>The string can only contain the characters "x", "y", or "z".
<DT><I>Fix balance string is invalid for 2d simulation</I>
<DD>The string cannot contain the letter "z".
<DT><I>Fix bond/break requires special_bonds = 0,1,1</I>
<DD>This is a restriction of the current fix bond/break implementation.
<DT><I>Fix bond/create cutoff is longer than pairwise cutoff</I>
<DD>This is not allowed because bond creation is done using the
pairwise neighbor list.
<DT><I>Fix bond/create requires special_bonds coul = 0,1,1</I>
<DD>Self-explanatory.
<DT><I>Fix bond/create requires special_bonds lj = 0,1,1</I>
<DD>Self-explanatory.
<DT><I>Fix bond/swap cannot use dihedral or improper styles</I>
<DD>These styles cannot be defined when using this fix.
<DT><I>Fix bond/swap requires pair and bond styles</I>
<DD>Self-explanatory.
<DT><I>Fix bond/swap requires special_bonds = 0,1,1</I>
<DD>Self-explanatory.
<DT><I>Fix box/relax generated negative box length</I>
<DD>The pressure being applied is likely too large. Try applying
it incrementally, to build to the high pressure.
<DT><I>Fix command before simulation box is defined</I>
<DD>The fix command cannot be used before a read_data, read_restart, or
create_box command.
<DT><I>Fix deform cannot use yz variable with xy</I>
<DD>The yz setting cannot be a variable if xy deformation is also
specified. This is because LAMMPS cannot determine if the yz setting
will induce a box flip which would be invalid if xy is also changing.
<DT><I>Fix deform is changing yz too much with xy</I>
<DD>When both yz and xy are changing, it induces changes in xz if the
box must flip from one tilt extreme to another. Thus it is not
allowed for yz to grow so much that a flip is induced.
<DT><I>Fix deform tilt factors require triclinic box</I>
<DD>Cannot deform the tilt factors of a simulation box unless it
is a triclinic (non-orthogonal) box.
<DT><I>Fix deform volume setting is invalid</I>
<DD>Cannot use volume style unless other dimensions are being controlled.
<DT><I>Fix deposit region cannot be dynamic</I>
<DD>Only static regions can be used with fix deposit.
<DT><I>Fix deposit region does not support a bounding box</I>
<DD>Not all regions represent bounded volumes. You cannot use
such a region with the fix deposit command.
<DT><I>Fix efield requires atom attribute q</I>
<DD>Self-explanatory.
<DT><I>Fix evaporate molecule requires atom attribute molecule</I>
<DD>The atom style being used does not define a molecule ID.
<DT><I>Fix external callback function not set</I>
<DD>This must be done by an external program in order to use this fix.
<DT><I>Fix for fix ave/atom not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix ave/atom is
requesting a value on a non-allowed timestep.
<DT><I>Fix for fix ave/correlate not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix ave/correlate
is requesting a value on a non-allowed timestep.
<DT><I>Fix for fix ave/histo not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix ave/histo is
requesting a value on a non-allowed timestep.
<DT><I>Fix for fix ave/spatial not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix ave/spatial is
requesting a value on a non-allowed timestep.
<DT><I>Fix for fix ave/time not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix ave/time
is requesting a value on a non-allowed timestep.
<DT><I>Fix for fix store/state not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Fix store/state
is requesting a value on a non-allowed timestep.
<DT><I>Fix freeze requires atom attribute torque</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Fix heat group has no atoms</I>
<DD>Self-explanatory.
<DT><I>Fix heat kinetic energy went negative</I>
<DD>This will cause the velocity rescaling about to be performed by fix
heat to be invalid.
<DT><I>Fix in variable not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. The variable is
requesting the values on a non-allowed timestep.
<DT><I>Fix langevin angmom requires atom style ellipsoid</I>
<DD>Self-explanatory.
<DT><I>Fix langevin angmom requires extended particles</I>
<DD>This fix option cannot be used with point paritlces.
<DT><I>Fix langevin omega requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Fix langevin omega requires extended particles</I>
<DD>One of the particles has radius 0.0.
<DT><I>Fix langevin period must be > 0.0</I>
<DD>The time window for temperature relaxation must be > 0
<DT><I>Fix langevin variable returned negative temperature</I>
<DD>Self-explanatory.
<DT><I>Fix momentum group has no atoms</I>
<DD>Self-explanatory.
<DT><I>Fix move cannot define z or vz variable for 2d problem</I>
<DD>Self-explanatory.
<DT><I>Fix move cannot have 0 length rotation vector</I>
<DD>Self-explanatory.
<DT><I>Fix move cannot rotate aroung non z-axis for 2d problem</I>
<DD>Self-explanatory.
<DT><I>Fix move cannot set linear z motion for 2d problem</I>
<DD>Self-explanatory.
<DT><I>Fix move cannot set wiggle z motion for 2d problem</I>
<DD>Self-explanatory.
<DT><I>Fix msst compute ID does not compute potential energy</I>
<DD>Self-explanatory.
<DT><I>Fix msst compute ID does not compute pressure</I>
<DD>Self-explanatory.
<DT><I>Fix msst compute ID does not compute temperature</I>
<DD>Self-explanatory.
<DT><I>Fix msst requires a periodic box</I>
<DD>Self-explanatory.
<DT><I>Fix msst tscale must satisfy 0 <= tscale < 1</I>
<DD>Self-explanatory.
<DT><I>Fix npt/nph has tilted box too far in one step - periodic cell is too far from equilibrium state</I>
<DD>Self-explanatory. The change in the box tilt is too extreme
on a short timescale.
<DT><I>Fix nve/asphere requires extended particles</I>
<DD>This fix can only be used for particles with a shape setting.
<DT><I>Fix nve/asphere/noforce requires atom style ellipsoid</I>
<DD>Self-explanatory.
<DT><I>Fix nve/asphere/noforce requires extended particles</I>
<DD>One of the particles is not an ellipsoid.
<DT><I>Fix nve/line can only be used for 2d simulations</I>
<DD>Self-explanatory.
<DT><I>Fix nve/line requires atom style line</I>
<DD>Self-explanatory.
<DT><I>Fix nve/line requires line particles</I>
<DD>Self-explanatory.
<DT><I>Fix nve/sphere requires atom attribute mu</I>
<DD>An atom style with this attribute is needed.
<DT><I>Fix nve/sphere requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Fix nve/sphere requires extended particles</I>
<DD>This fix can only be used for particles of a finite size.
<DT><I>Fix nve/tri can only be used for 3d simulations</I>
<DD>Self-explanatory.
<DT><I>Fix nve/tri requires atom style tri</I>
<DD>Self-explanatory.
<DT><I>Fix nve/tri requires tri particles</I>
<DD>Self-explanatory.
<DT><I>Fix nvt/nph/npt asphere requires extended particles</I>
<DD>The shape setting for a particle in the fix group has shape = 0.0,
which means it is a point particle.
<DT><I>Fix nvt/nph/npt sphere requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Fix nvt/npt/nph damping parameters must be > 0.0</I>
<DD>Self-explanatory.
+<DT><I>Fix nvt/npt/nph dilate group ID does not exist</I>
+
+<DD>Self-explanatory.
+
<DT><I>Fix nvt/sphere requires extended particles</I>
<DD>This fix can only be used for particles of a finite size.
<DT><I>Fix orient/fcc file open failed</I>
<DD>The fix orient/fcc command could not open a specified file.
<DT><I>Fix orient/fcc file read failed</I>
<DD>The fix orient/fcc command could not read the needed parameters from a
specified file.
<DT><I>Fix orient/fcc found self twice</I>
<DD>The neighbor lists used by fix orient/fcc are messed up. If this
error occurs, it is likely a bug, so send an email to the
<A HREF = "http://lammps.sandia.gov/authors.html">developers</A>.
<DT><I>Fix peri neigh does not exist</I>
<DD>Somehow a fix that the pair style defines has been deleted.
<DT><I>Fix pour region ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix pour region cannot be dynamic</I>
<DD>Only static regions can be used with fix pour.
<DT><I>Fix pour region does not support a bounding box</I>
<DD>Not all regions represent bounded volumes. You cannot use
such a region with the fix pour command.
<DT><I>Fix pour requires atom attributes radius, rmass</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Fix press/berendsen damping parameters must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix qeq/comb group has no atoms</I>
<DD>Self-explanatory.
<DT><I>Fix qeq/comb requires atom attribute q</I>
<DD>An atom style with charge must be used to perform charge equilibration.
<DT><I>Fix reax/bonds numbonds > nsbmax_most</I>
<DD>The limit of the number of bonds expected by the ReaxFF force field
was exceeded.
<DT><I>Fix recenter group has no atoms</I>
<DD>Self-explanatory.
<DT><I>Fix restrain requires an atom map, see atom_modify</I>
<DD>Self-explanatory.
<DT><I>Fix rigid atom has non-zero image flag in a non-periodic dimension</I>
<DD>You cannot set image flags for non-periodic dimensions.
<DT><I>Fix rigid langevin period must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix rigid molecule requires atom attribute molecule</I>
<DD>Self-explanatory.
<DT><I>Fix rigid xy torque cannot be on for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Fix rigid z force cannot be on for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Fix rigid/nvt period must be > 0.0</I>
<DD>Self-explanatory
<DT><I>Fix rigid: Bad principal moments</I>
<DD>The principal moments of inertia computed for a rigid body
are not within the required tolerances.
<DT><I>Fix shake cannot be used with minimization</I>
<DD>Cannot use fix shake while doing an energy minimization since
it turns off bonds that should contribute to the energy.
<DT><I>Fix spring couple group ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Fix srd lamda must be >= 0.6 of SRD grid size</I>
<DD>This is a requirement for accuracy reasons.
<DT><I>Fix srd requires SRD particles all have same mass</I>
<DD>Self-explanatory.
<DT><I>Fix srd requires ghost atoms store velocity</I>
<DD>Use the communicate vel yes command to enable this.
<DT><I>Fix srd requires newton pair on</I>
<DD>Self-explanatory.
<DT><I>Fix store/state compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix store/state compute does not calculate a per-atom array</I>
<DD>The compute calculates a per-atom vector.
<DT><I>Fix store/state compute does not calculate a per-atom vector</I>
<DD>The compute calculates a per-atom vector.
<DT><I>Fix store/state compute does not calculate per-atom values</I>
<DD>Computes that calculate global or local quantities cannot be used
with fix store/state.
<DT><I>Fix store/state fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Fix store/state fix does not calculate a per-atom array</I>
<DD>The fix calculates a per-atom vector.
<DT><I>Fix store/state fix does not calculate a per-atom vector</I>
<DD>The fix calculates a per-atom array.
<DT><I>Fix store/state fix does not calculate per-atom values</I>
<DD>Fixes that calculate global or local quantities cannot be used with
fix store/state.
<DT><I>Fix store/state for atom property that isn't allocated</I>
<DD>Self-explanatory.
<DT><I>Fix store/state variable is not atom-style variable</I>
<DD>Only atom-style variables calculate per-atom quantities.
<DT><I>Fix temp/berendsen period must be > 0.0</I>
<DD>Self-explanatory.
+<DT><I>Fix temp/berendsen variable returned negative temperature</I>
+
+<DD>Self-explanatory.
+
+<DT><I>Fix temp/rescale variable returned negative temperature</I>
+
+<DD>Self-explanatory.
+
<DT><I>Fix thermal/conductivity swap value must be positive</I>
<DD>Self-explanatory.
<DT><I>Fix tmd must come after integration fixes</I>
<DD>Any fix tmd command must appear in the input script after all time
integration fixes (nve, nvt, npt). See the fix tmd documentation for
details.
<DT><I>Fix ttm electron temperatures must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm electronic_density must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm electronic_specific_heat must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm electronic_thermal_conductivity must be >= 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm gamma_p must be > 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm gamma_s must be >= 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm number of nodes must be > 0</I>
<DD>Self-explanatory.
<DT><I>Fix ttm v_0 must be >= 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix used in compute atom/molecule not computed at compatible time</I>
<DD>The fix must produce per-atom quantities on timesteps that the compute
needs them.
<DT><I>Fix used in compute reduce not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Compute reduce is
requesting a value on a non-allowed timestep.
<DT><I>Fix used in compute slice not computed at compatible time</I>
<DD>Fixes generate their values on specific timesteps. Compute slice is
requesting a value on a non-allowed timestep.
<DT><I>Fix viscosity swap value must be positive</I>
<DD>Self-explanatory.
<DT><I>Fix viscosity vtarget value must be positive</I>
<DD>Self-explanatory.
<DT><I>Fix wall cutoff <= 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix wall/colloid requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Fix wall/colloid requires extended particles</I>
<DD>One of the particles has radius 0.0.
<DT><I>Fix wall/gran is incompatible with Pair style</I>
<DD>Must use a granular pair style to define the parameters needed for
this fix.
<DT><I>Fix wall/gran requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Fix wall/piston command only available at zlo</I>
<DD>The face keyword must be zlo.
<DT><I>Fix wall/region colloid requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Fix wall/region colloid requires extended particles</I>
<DD>One of the particles has radius 0.0.
<DT><I>Fix wall/region cutoff <= 0.0</I>
<DD>Self-explanatory.
<DT><I>Fix_modify order must be 3 or 5</I>
<DD>Self-explanatory.
<DT><I>Fix_modify pressure ID does not compute pressure</I>
<DD>The compute ID assigned to the fix must compute pressure.
<DT><I>Fix_modify temperature ID does not compute temperature</I>
<DD>The compute ID assigned to the fix must compute temperature.
<DT><I>For triclinic deformation, specified target stress must be hydrostatic</I>
<DD>Triclinic pressure control is allowed using the tri keyword, but
non-hydrostatic pressure control can not be used in this case.
<DT><I>Found no restart file matching pattern</I>
<DD>When using a "*" in the restart file name, no matching file was found.
<DT><I>GPU library not compiled for this accelerator</I>
<DD>Self-explanatory.
<DT><I>GPU particle split must be set to 1 for this pair style.</I>
<DD>For this pair style, you cannot run part of the force calculation on
the host. See the package command.
<DT><I>Gmask function in equal-style variable formula</I>
<DD>Gmask is per-atom operation.
<DT><I>Gravity changed since fix pour was created</I>
<DD>Gravity must be static and not dynamic for use with fix pour.
<DT><I>Gravity must point in -y to use with fix pour in 2d</I>
<DD>Gravity must be pointing "down" in a 2d box.
<DT><I>Gravity must point in -z to use with fix pour in 3d</I>
<DD>Gravity must be pointing "down" in a 3d box, i.e. theta = 180.0.
<DT><I>Grmask function in equal-style variable formula</I>
<DD>Grmask is per-atom operation.
<DT><I>Group ID does not exist</I>
<DD>A group ID used in the group command does not exist.
<DT><I>Group ID in variable formula does not exist</I>
<DD>Self-explanatory.
<DT><I>Group command before simulation box is defined</I>
<DD>The group command cannot be used before a read_data, read_restart, or
create_box command.
<DT><I>Group region ID does not exist</I>
<DD>A region ID used in the group command does not exist.
+<DT><I>If read_dump purges it cannot replace or trim</I>
+
+<DD>These operations are not compatible. See the read_dump doc
+page for details.
+
<DT><I>Illegal ... command</I>
<DD>Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
<DT><I>Illegal COMB parameter</I>
<DD>One or more of the coefficients defined in the potential file is
invalid.
<DT><I>Illegal Stillinger-Weber parameter</I>
<DD>One or more of the coefficients defined in the potential file is
invalid.
<DT><I>Illegal Tersoff parameter</I>
<DD>One or more of the coefficients defined in the potential file is
invalid.
<DT><I>Illegal fix wall/piston velocity</I>
<DD>The piston velocity must be positive.
<DT><I>Illegal integrate style</I>
<DD>Self-explanatory.
<DT><I>Illegal number of angle table entries</I>
<DD>There must be at least 2 table entries.
<DT><I>Illegal number of bond table entries</I>
<DD>There must be at least 2 table entries.
<DT><I>Illegal number of pair table entries</I>
<DD>There must be at least 2 table entries.
<DT><I>Illegal simulation box</I>
<DD>The lower bound of the simulation box is greater than the upper bound.
<DT><I>Improper atom missing in delete_bonds</I>
<DD>The delete_bonds command cannot find one or more atoms in a particular
improper on a particular processor. The pairwise cutoff is too short
or the atoms are too far apart to make a valid improper.
<DT><I>Improper atom missing in set command</I>
<DD>The set command cannot find one or more atoms in a particular improper
on a particular processor. The pairwise cutoff is too short or the
atoms are too far apart to make a valid improper.
<DT><I>Improper atoms %d %d %d %d missing on proc %d at step %ld</I>
<DD>One or more of 4 atoms needed to compute a particular improper are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the improper has blown apart and an atom is
too far away.
<DT><I>Improper coeff for hybrid has invalid style</I>
<DD>Improper style hybrid uses another improper style as one of its
coefficients. The improper style used in the improper_coeff command
or read from a restart file is not recognized.
<DT><I>Improper coeffs are not set</I>
<DD>No improper coefficients have been assigned in the data file or via
the improper_coeff command.
<DT><I>Improper style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Improper style hybrid cannot have none as an argument</I>
<DD>Self-explanatory.
<DT><I>Improper style hybrid cannot use same improper style twice</I>
<DD>Self-explanatory.
<DT><I>Improper_coeff command before improper_style is defined</I>
<DD>Coefficients cannot be set in the data file or via the improper_coeff
command until an improper_style has been assigned.
<DT><I>Improper_coeff command before simulation box is defined</I>
<DD>The improper_coeff command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Improper_coeff command when no impropers allowed</I>
<DD>The chosen atom style does not allow for impropers to be defined.
<DT><I>Improper_style command when no impropers allowed</I>
<DD>The chosen atom style does not allow for impropers to be defined.
<DT><I>Impropers assigned incorrectly</I>
<DD>Impropers read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions.
<DT><I>Impropers defined but no improper types</I>
<DD>The data file header lists improper but no improper types.
<DT><I>Inconsistent iparam/jparam values in fix bond/create command</I>
-<DD>If itype and jtype are the same, then their maxbond and newtype
+<DD>If itype and jtype are the same, then their maxbond and newtype
settings must also be the same.
<DT><I>Inconsistent line segment in data file</I>
<DD>The end points of the line segment are not equal distances from the
center point which is the atom coordinate.
<DT><I>Inconsistent triangle in data file</I>
<DD>The centroid of the triangle as defined by the corner points is not
the atom coordinate.
<DT><I>Incorrect args for angle coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect args for bond coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect args for dihedral coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect args for improper coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect args for pair coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect args in pair_style command</I>
<DD>Self-explanatory.
<DT><I>Incorrect atom format in data file</I>
<DD>Number of values per atom line in the data file is not consistent with
the atom style.
<DT><I>Incorrect bonus data format in data file</I>
<DD>See the read_data doc page for a description of how various kinds of
bonus data must be formatted for certain atom styles.
<DT><I>Incorrect boundaries with slab Ewald</I>
<DD>Must have periodic x,y dimensions and non-periodic z dimension to use
2d slab option with Ewald.
<DT><I>Incorrect boundaries with slab PPPM</I>
<DD>Must have periodic x,y dimensions and non-periodic z dimension to use
2d slab option with PPPM.
<DT><I>Incorrect element names in ADP potential file</I>
<DD>The element names in the ADP file do not match those requested.
<DT><I>Incorrect element names in EAM potential file</I>
<DD>The element names in the EAM file do not match those requested.
<DT><I>Incorrect format in COMB potential file</I>
<DD>Incorrect number of words per line in the potential file.
<DT><I>Incorrect format in MEAM potential file</I>
<DD>Incorrect number of words per line in the potential file.
<DT><I>Incorrect format in NEB coordinate file</I>
<DD>Self-explanatory.
<DT><I>Incorrect format in Stillinger-Weber potential file</I>
<DD>Incorrect number of words per line in the potential file.
<DT><I>Incorrect format in TMD target file</I>
<DD>Format of file read by fix tmd command is incorrect.
<DT><I>Incorrect format in Tersoff potential file</I>
<DD>Incorrect number of words per line in the potential file.
<DT><I>Incorrect multiplicity arg for dihedral coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
+<DT><I>Incorrect rigid body format in fix rigid file</I>
+
+<DD>The number of fields per line is not what expected.
+
<DT><I>Incorrect sign arg for dihedral coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Incorrect velocity format in data file</I>
<DD>Each atom style defines a format for the Velocity section
of the data file. The read-in lines do not match.
<DT><I>Incorrect weight arg for dihedral coefficients</I>
<DD>Self-explanatory. Check the input script or data file.
<DT><I>Index between variable brackets must be positive</I>
<DD>Self-explanatory.
<DT><I>Indexed per-atom vector in variable formula without atom map</I>
<DD>Accessing a value from an atom vector requires the ability to lookup
an atom index, which is provided by an atom map. An atom map does not
exist (by default) for non-molecular problems. Using the atom_modify
map command will force an atom map to be created.
<DT><I>Initial temperatures not all set in fix ttm</I>
<DD>Self-explantory.
<DT><I>Input line quote not followed by whitespace</I>
<DD>An end quote must be followed by whitespace.
<DT><I>Input line too long after variable substitution</I>
<DD>This is a hard (very large) limit defined in the input.cpp file.
<DT><I>Input line too long: %s</I>
<DD>This is a hard (very large) limit defined in the input.cpp file.
<DT><I>Insertion region extends outside simulation box</I>
<DD>Region specified with fix pour command extends outside the global
simulation box.
<DT><I>Insufficient Jacobi rotations for POEMS body</I>
<DD>Eigensolve for rigid body was not sufficiently accurate.
<DT><I>Insufficient Jacobi rotations for rigid body</I>
<DD>Eigensolve for rigid body was not sufficiently accurate.
<DT><I>Insufficient Jacobi rotations for triangle</I>
<DD>The calculation of the intertia tensor of the triangle failed. This
should not happen if it is a reasonably shaped triangle.
<DT><I>Insufficient memory on accelerator</I>
<DD>There is insufficient memory on one of the devices specified for the gpu
package
<DT><I>Invalid -reorder N value</I>
<DD>Self-explanatory.
<DT><I>Invalid Boolean syntax in if command</I>
<DD>Self-explanatory.
<DT><I>Invalid REAX atom type</I>
<DD>There is a mis-match between LAMMPS atom types and the elements
listed in the ReaxFF force field file.
<DT><I>Invalid angle style</I>
<DD>The choice of angle style is unknown.
<DT><I>Invalid angle table length</I>
<DD>Length must be 2 or greater.
<DT><I>Invalid angle type in Angles section of data file</I>
<DD>Angle type must be positive integer and within range of specified angle
types.
<DT><I>Invalid angle type index for fix shake</I>
<DD>Self-explanatory.
<DT><I>Invalid atom ID in Angles section of data file</I>
<DD>Atom IDs must be positive integers and within range of defined
atoms.
<DT><I>Invalid atom ID in Atoms section of data file</I>
<DD>Atom IDs must be positive integers.
<DT><I>Invalid atom ID in Bonds section of data file</I>
<DD>Atom IDs must be positive integers and within range of defined
atoms.
<DT><I>Invalid atom ID in Bonus section of data file</I>
<DD>Atom IDs must be positive integers and within range of defined
atoms.
<DT><I>Invalid atom ID in Dihedrals section of data file</I>
<DD>Atom IDs must be positive integers and within range of defined
atoms.
<DT><I>Invalid atom ID in Impropers section of data file</I>
<DD>Atom IDs must be positive integers and within range of defined
atoms.
<DT><I>Invalid atom ID in Velocities section of data file</I>
<DD>Atom IDs must be positive integers and within range of defined
atoms.
<DT><I>Invalid atom mass for fix shake</I>
<DD>Mass specified in fix shake command must be > 0.0.
<DT><I>Invalid atom style</I>
<DD>The choice of atom style is unknown.
<DT><I>Invalid atom type in Atoms section of data file</I>
<DD>Atom types must range from 1 to specified # of types.
<DT><I>Invalid atom type in create_atoms command</I>
<DD>The create_box command specified the range of valid atom types.
An invalid type is being requested.
<DT><I>Invalid atom type in fix GCMC command</I>
<DD>The atom type specified in the GCMC command does not exist.
<DT><I>Invalid atom type in fix bond/create command</I>
<DD>Self-explanatory.
<DT><I>Invalid atom type in neighbor exclusion list</I>
<DD>Atom types must range from 1 to Ntypes inclusive.
<DT><I>Invalid atom type index for fix shake</I>
<DD>Atom types must range from 1 to Ntypes inclusive.
<DT><I>Invalid atom types in pair_write command</I>
<DD>Atom types must range from 1 to Ntypes inclusive.
<DT><I>Invalid atom vector in variable formula</I>
<DD>The atom vector is not recognized.
<DT><I>Invalid attribute in dump custom command</I>
<DD>Self-explantory.
<DT><I>Invalid attribute in dump local command</I>
<DD>Self-explantory.
<DT><I>Invalid attribute in dump modify command</I>
<DD>Self-explantory.
<DT><I>Invalid bond style</I>
<DD>The choice of bond style is unknown.
<DT><I>Invalid bond table length</I>
<DD>Length must be 2 or greater.
<DT><I>Invalid bond type in Bonds section of data file</I>
<DD>Bond type must be positive integer and within range of specified bond
types.
<DT><I>Invalid bond type in fix bond/break command</I>
<DD>Self-explanatory.
<DT><I>Invalid bond type in fix bond/create command</I>
<DD>Self-explanatory.
<DT><I>Invalid bond type index for fix shake</I>
<DD>Self-explanatory. Check the fix shake command in the input script.
<DT><I>Invalid coeffs for this dihedral style</I>
<DD>Cannot set class 2 coeffs in data file for this dihedral style.
<DT><I>Invalid color in dump_modify command</I>
<DD>The specified color name was not in the list of recognized colors.
See the dump_modify doc page.
<DT><I>Invalid command-line argument</I>
<DD>One or more command-line arguments is invalid. Check the syntax of
the command you are using to launch LAMMPS.
<DT><I>Invalid compute ID in variable formula</I>
<DD>The compute is not recognized.
<DT><I>Invalid compute style</I>
<DD>Self-explanatory.
<DT><I>Invalid cutoff in communicate command</I>
<DD>Specified cutoff must be >= 0.0.
<DT><I>Invalid cutoffs in pair_write command</I>
<DD>Inner cutoff must be larger than 0.0 and less than outer cutoff.
<DT><I>Invalid d1 or d2 value for pair colloid coeff</I>
<DD>Neither d1 or d2 can be < 0.
<DT><I>Invalid data file section: Angle Coeffs</I>
<DD>Atom style does not allow angles.
<DT><I>Invalid data file section: AngleAngle Coeffs</I>
<DD>Atom style does not allow impropers.
<DT><I>Invalid data file section: AngleAngleTorsion Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: AngleTorsion Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: Angles</I>
<DD>Atom style does not allow angles.
<DT><I>Invalid data file section: Bond Coeffs</I>
<DD>Atom style does not allow bonds.
<DT><I>Invalid data file section: BondAngle Coeffs</I>
<DD>Atom style does not allow angles.
<DT><I>Invalid data file section: BondBond Coeffs</I>
<DD>Atom style does not allow angles.
<DT><I>Invalid data file section: BondBond13 Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: Bonds</I>
<DD>Atom style does not allow bonds.
<DT><I>Invalid data file section: Dihedral Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: Dihedrals</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: Ellipsoids</I>
<DD>Atom style does not allow ellipsoids.
<DT><I>Invalid data file section: EndBondTorsion Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: Improper Coeffs</I>
<DD>Atom style does not allow impropers.
<DT><I>Invalid data file section: Impropers</I>
<DD>Atom style does not allow impropers.
<DT><I>Invalid data file section: Lines</I>
<DD>Atom style does not allow lines.
<DT><I>Invalid data file section: MiddleBondTorsion Coeffs</I>
<DD>Atom style does not allow dihedrals.
<DT><I>Invalid data file section: Triangles</I>
<DD>Atom style does not allow triangles.
<DT><I>Invalid delta_conf in tad command</I>
<DD>The value must be between 0 and 1 inclusive.
<DT><I>Invalid density in Atoms section of data file</I>
<DD>Density value cannot be <= 0.0.
<DT><I>Invalid diameter in set command</I>
<DD>Self-explanatory.
<DT><I>Invalid dihedral style</I>
<DD>The choice of dihedral style is unknown.
<DT><I>Invalid dihedral type in Dihedrals section of data file</I>
<DD>Dihedral type must be positive integer and within range of specified
dihedral types.
<DT><I>Invalid dipole length in set command</I>
<DD>Self-explanatory.
<DT><I>Invalid dump dcd filename</I>
<DD>Filenames used with the dump dcd style cannot be binary or compressed
or cause multiple files to be written.
<DT><I>Invalid dump frequency</I>
<DD>Dump frequency must be 1 or greater.
<DT><I>Invalid dump image element name</I>
<DD>The specified element name was not in the standard list of elements.
See the dump_modify doc page.
<DT><I>Invalid dump image filename</I>
<DD>The file produced by dump image cannot be binary and must
be for a single processor.
<DT><I>Invalid dump image persp value</I>
<DD>Persp value must be >= 0.0.
<DT><I>Invalid dump image theta value</I>
<DD>Theta must be between 0.0 and 180.0 inclusive.
<DT><I>Invalid dump image zoom value</I>
<DD>Zoom value must be > 0.0.
+<DT><I>Invalid dump reader style</I>
+
+<DD>Self-explanatory.
+
<DT><I>Invalid dump style</I>
<DD>The choice of dump style is unknown.
<DT><I>Invalid dump xtc filename</I>
<DD>Filenames used with the dump xtc style cannot be binary or compressed
or cause multiple files to be written.
<DT><I>Invalid dump xyz filename</I>
<DD>Filenames used with the dump xyz style cannot be binary or cause files
to be written by each processor.
<DT><I>Invalid dump_modify threshhold operator</I>
<DD>Operator keyword used for threshold specification in not recognized.
<DT><I>Invalid entry in -reorder file</I>
<DD>Self-explanatory.
<DT><I>Invalid fix ID in variable formula</I>
<DD>The fix is not recognized.
<DT><I>Invalid fix ave/time off column</I>
<DD>Self-explantory.
<DT><I>Invalid fix box/relax command for a 2d simulation</I>
<DD>Fix box/relax styles involving the z dimension cannot be used in
a 2d simulation.
<DT><I>Invalid fix box/relax command pressure settings</I>
<DD>If multiple dimensions are coupled, those dimensions must be specified.
<DT><I>Invalid fix box/relax pressure settings</I>
<DD>Settings for coupled dimensions must be the same.
<DT><I>Invalid fix nvt/npt/nph command for a 2d simulation</I>
<DD>Cannot control z dimension in a 2d model.
<DT><I>Invalid fix nvt/npt/nph command pressure settings</I>
<DD>If multiple dimensions are coupled, those dimensions must be
specified.
<DT><I>Invalid fix nvt/npt/nph pressure settings</I>
<DD>Settings for coupled dimensions must be the same.
<DT><I>Invalid fix press/berendsen for a 2d simulation</I>
<DD>The z component of pressure cannot be controlled for a 2d model.
<DT><I>Invalid fix press/berendsen pressure settings</I>
<DD>Settings for coupled dimensions must be the same.
<DT><I>Invalid fix style</I>
<DD>The choice of fix style is unknown.
<DT><I>Invalid flag in force field section of restart file</I>
<DD>Unrecognized entry in restart file.
<DT><I>Invalid flag in header section of restart file</I>
<DD>Unrecognized entry in restart file.
<DT><I>Invalid flag in type arrays section of restart file</I>
<DD>Unrecognized entry in restart file.
<DT><I>Invalid frequency in temper command</I>
<DD>Nevery must be > 0.
<DT><I>Invalid group ID in neigh_modify command</I>
<DD>A group ID used in the neigh_modify command does not exist.
<DT><I>Invalid group function in variable formula</I>
<DD>Group function is not recognized.
<DT><I>Invalid group in communicate command</I>
<DD>Self-explanatory.
<DT><I>Invalid image color range</I>
<DD>The lo value in the range is larger than the hi value.
<DT><I>Invalid image up vector</I>
<DD>Up vector cannot be (0,0,0).
<DT><I>Invalid improper style</I>
<DD>The choice of improper style is unknown.
<DT><I>Invalid improper type in Impropers section of data file</I>
<DD>Improper type must be positive integer and within range of specified
improper types.
<DT><I>Invalid keyword in angle table parameters</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in bond table parameters</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute angle/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute bond/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute dihedral/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute improper/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute pair/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute property/atom command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute property/local command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in compute property/molecule command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in dump cfg command</I>
<DD>Self-explanatory.
<DT><I>Invalid keyword in pair table parameters</I>
<DD>Keyword used in list of table parameters is not recognized.
<DT><I>Invalid keyword in thermo_style custom command</I>
<DD>One or more specified keywords are not recognized.
<DT><I>Invalid kspace style</I>
<DD>The choice of kspace style is unknown.
<DT><I>Invalid length in set command</I>
<DD>Self-explanatory.
<DT><I>Invalid mass in set command</I>
<DD>Self-explanatory.
<DT><I>Invalid mass line in data file</I>
<DD>Self-explanatory.
<DT><I>Invalid mass value</I>
<DD>Self-explanatory.
<DT><I>Invalid math function in variable formula</I>
<DD>Self-explanatory.
<DT><I>Invalid math/group/special function in variable formula</I>
<DD>Self-explanatory.
<DT><I>Invalid option in lattice command for non-custom style</I>
<DD>Certain lattice keywords are not supported unless the
lattice style is "custom".
<DT><I>Invalid order of forces within respa levels</I>
<DD>For respa, ordering of force computations within respa levels must
obey certain rules. E.g. bonds cannot be compute less frequently than
angles, pairwise forces cannot be computed less frequently than
kspace, etc.
<DT><I>Invalid pair style</I>
<DD>The choice of pair style is unknown.
<DT><I>Invalid pair table cutoff</I>
<DD>Cutoffs in pair_coeff command are not valid with read-in pair table.
<DT><I>Invalid pair table length</I>
<DD>Length of read-in pair table is invalid
<DT><I>Invalid partitions in processors part command</I>
<DD>Valid partitions are numbered 1 to N and the sender and receiver
cannot be the same partition.
<DT><I>Invalid radius in Atoms section of data file</I>
<DD>Radius must be >= 0.0.
<DT><I>Invalid random number seed in fix ttm command</I>
<DD>Random number seed must be > 0.
<DT><I>Invalid random number seed in set command</I>
<DD>Random number seed must be > 0.
<DT><I>Invalid region style</I>
<DD>The choice of region style is unknown.
<DT><I>Invalid replace values in compute reduce</I>
<DD>Self-explanatory.
+<DT><I>Invalid rigid body ID in fix rigid file</I>
+
+<DD>The ID does not match the number or an existing ID of rigid bodies
+that are defined by the fix rigid command.
+
<DT><I>Invalid run command N value</I>
<DD>The number of timesteps must fit in a 32-bit integer. If you want to
run for more steps than this, perform multiple shorter runs.
<DT><I>Invalid run command start/stop value</I>
<DD>Self-explanatory.
<DT><I>Invalid run command upto value</I>
<DD>Self-explanatory.
<DT><I>Invalid seed for Marsaglia random # generator</I>
<DD>The initial seed for this random number generator must be a positive
integer less than or equal to 900 million.
<DT><I>Invalid seed for Park random # generator</I>
<DD>The initial seed for this random number generator must be a positive
integer.
<DT><I>Invalid shape in Ellipsoids section of data file</I>
<DD>Self-explanatory.
<DT><I>Invalid shape in Triangles section of data file</I>
<DD>Two or more of the triangle corners are duplicate points.
<DT><I>Invalid shape in set command</I>
<DD>Self-explanatory.
<DT><I>Invalid shear direction for fix wall/gran</I>
<DD>Self-explanatory.
<DT><I>Invalid special function in variable formula</I>
<DD>Self-explanatory.
<DT><I>Invalid style in pair_write command</I>
<DD>Self-explanatory. Check the input script.
<DT><I>Invalid syntax in variable formula</I>
<DD>Self-explanatory.
<DT><I>Invalid t_event in prd command</I>
<DD>Self-explanatory.
<DT><I>Invalid t_event in tad command</I>
<DD>The value must be greater than 0.
<DT><I>Invalid thermo keyword in variable formula</I>
<DD>The keyword is not recognized.
<DT><I>Invalid tmax in tad command</I>
<DD>The value must be greater than 0.0.
<DT><I>Invalid type for mass set</I>
<DD>Mass command must set a type from 1-N where N is the number of atom
types.
<DT><I>Invalid value in set command</I>
<DD>The value specified for the setting is invalid, likely because it is
too small or too large.
<DT><I>Invalid variable evaluation in variable formula</I>
<DD>A variable used in a formula could not be evaluated.
<DT><I>Invalid variable in next command</I>
<DD>Self-explanatory.
<DT><I>Invalid variable name</I>
<DD>Variable name used in an input script line is invalid.
<DT><I>Invalid variable name in variable formula</I>
<DD>Variable name is not recognized.
<DT><I>Invalid variable style with next command</I>
<DD>Variable styles <I>equal</I> and <I>world</I> cannot be used in a next
command.
<DT><I>Invalid wiggle direction for fix wall/gran</I>
<DD>Self-explanatory.
<DT><I>Invoked angle equil angle on angle style none</I>
<DD>Self-explanatory.
<DT><I>Invoked angle single on angle style none</I>
<DD>Self-explanatory.
<DT><I>Invoked bond equil distance on bond style none</I>
<DD>Self-explanatory.
<DT><I>Invoked bond single on bond style none</I>
<DD>Self-explanatory.
<DT><I>Invoked pair single on pair style none</I>
<DD>A command (e.g. a dump) attempted to invoke the single() function on a
pair style none, which is illegal. You are probably attempting to
compute per-atom quantities with an undefined pair style.
<DT><I>KIM initialization failed</I>
<DD>This is an error generated by the KIM library.
<DT><I>KIM neighbor iterator exceeded range</I>
<DD>This should not happen. It likely indicates a bug
in the KIM implementation of the interatomic potential
where it is requesting neighbors incorrectly.
<DT><I>KIM_DIR environment variable is unset</I>
<DD>This environment variable must be set to use pair_style kim.
See the doc page for pair_style kim.
+<DT><I>KSpace accuracy too large to estimate G vector</I>
+
+<DD>Paul will doc this.
+
<DT><I>KSpace style has not yet been set</I>
<DD>Cannot use kspace_modify command until a kspace style is set.
<DT><I>KSpace style is incompatible with Pair style</I>
<DD>Setting a kspace style requires that a pair style with a long-range
Coulombic component be selected.
<DT><I>Keyword %s in MEAM parameter file not recognized</I>
<DD>Self-explanatory.
+<DT><I>Kspace style does not support compute group/group</I>
+
+<DD>Self-explanatory.
+
<DT><I>Kspace style pppm/tip4p requires newton on</I>
<DD>Self-explanatory.
<DT><I>Kspace style requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Label wasn't found in input script</I>
<DD>Self-explanatory.
<DT><I>Lattice orient vectors are not orthogonal</I>
<DD>The three specified lattice orientation vectors must be mutually
orthogonal.
<DT><I>Lattice orient vectors are not right-handed</I>
<DD>The three specified lattice orientation vectors must create a
right-handed coordinate system such that a1 cross a2 = a3.
<DT><I>Lattice primitive vectors are collinear</I>
<DD>The specified lattice primitive vectors do not for a unit cell with
non-zero volume.
<DT><I>Lattice settings are not compatible with 2d simulation</I>
<DD>One or more of the specified lattice vectors has a non-zero z
component.
<DT><I>Lattice spacings are invalid</I>
<DD>Each x,y,z spacing must be > 0.
<DT><I>Lattice style incompatible with simulation dimension</I>
<DD>2d simulation can use sq, sq2, or hex lattice. 3d simulation can use
sc, bcc, or fcc lattice.
<DT><I>Log of zero/negative value in variable formula</I>
<DD>Self-explanatory.
<DT><I>Lost atoms via balance: original %ld current %ld</I>
<DD>This should not occur. Report the problem to the developers.
<DT><I>Lost atoms: original %ld current %ld</I>
<DD>Lost atoms are checked for each time thermo output is done. See the
thermo_modify lost command for options. Lost atoms usually indicate
bad dynamics, e.g. atoms have been blown far out of the simulation
box, or moved futher than one processor's sub-domain away before
reneighboring.
<DT><I>MEAM library error %d</I>
<DD>A call to the MEAM Fortran library returned an error.
<DT><I>MPI_LMP_BIGINT and bigint in lmptype.h are not compatible</I>
<DD>The size of the MPI datatype does not match the size of a bigint.
<DT><I>MPI_LMP_TAGINT and tagint in lmptype.h are not compatible</I>
<DD>The size of the MPI datatype does not match the size of a tagint.
<DT><I>Mass command before simulation box is defined</I>
<DD>The mass command cannot be used before a read_data, read_restart, or
create_box command.
<DT><I>Min_style command before simulation box is defined</I>
<DD>The min_style command cannot be used before a read_data, read_restart,
or create_box command.
<DT><I>Minimization could not find thermo_pe compute</I>
<DD>This compute is created by the thermo command. It must have been
explicitly deleted by a uncompute command.
<DT><I>Minimize command before simulation box is defined</I>
<DD>The minimize command cannot be used before a read_data, read_restart,
or create_box command.
<DT><I>Mismatched brackets in variable</I>
<DD>Self-explanatory.
<DT><I>Mismatched compute in variable formula</I>
<DD>A compute is referenced incorrectly or a compute that produces per-atom
values is used in an equal-style variable formula.
<DT><I>Mismatched fix in variable formula</I>
<DD>A fix is referenced incorrectly or a fix that produces per-atom
values is used in an equal-style variable formula.
<DT><I>Mismatched variable in variable formula</I>
<DD>A variable is referenced incorrectly or an atom-style variable that
produces per-atom values is used in an equal-style variable
formula.
<DT><I>Molecular data file has too many atoms</I>
<DD>These kids of data files are currently limited to a number
of atoms that fits in a 32-bit integer.
<DT><I>Molecule count changed in compute atom/molecule</I>
<DD>Number of molecules must remain constant over time.
<DT><I>Molecule count changed in compute com/molecule</I>
<DD>Number of molecules must remain constant over time.
<DT><I>Molecule count changed in compute gyration/molecule</I>
<DD>Number of molecules must remain constant over time.
<DT><I>Molecule count changed in compute msd/molecule</I>
<DD>Number of molecules must remain constant over time.
<DT><I>Molecule count changed in compute property/molecule</I>
<DD>Number of molecules must remain constant over time.
<DT><I>More than one fix deform</I>
<DD>Only one fix deform can be defined at a time.
<DT><I>More than one fix freeze</I>
<DD>Only one of these fixes can be defined, since the granular pair
potentials access it.
<DT><I>More than one fix shake</I>
<DD>Only one fix shake can be defined.
<DT><I>Must define angle_style before Angle Coeffs</I>
<DD>Must use an angle_style command before reading a data file that
defines Angle Coeffs.
<DT><I>Must define angle_style before BondAngle Coeffs</I>
<DD>Must use an angle_style command before reading a data file that
defines Angle Coeffs.
<DT><I>Must define angle_style before BondBond Coeffs</I>
<DD>Must use an angle_style command before reading a data file that
defines Angle Coeffs.
<DT><I>Must define bond_style before Bond Coeffs</I>
<DD>Must use a bond_style command before reading a data file that
defines Bond Coeffs.
<DT><I>Must define dihedral_style before AngleAngleTorsion Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines AngleAngleTorsion Coeffs.
<DT><I>Must define dihedral_style before AngleTorsion Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines AngleTorsion Coeffs.
<DT><I>Must define dihedral_style before BondBond13 Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines BondBond13 Coeffs.
<DT><I>Must define dihedral_style before Dihedral Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines Dihedral Coeffs.
<DT><I>Must define dihedral_style before EndBondTorsion Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines EndBondTorsion Coeffs.
<DT><I>Must define dihedral_style before MiddleBondTorsion Coeffs</I>
<DD>Must use a dihedral_style command before reading a data file that
defines MiddleBondTorsion Coeffs.
<DT><I>Must define improper_style before AngleAngle Coeffs</I>
<DD>Must use an improper_style command before reading a data file that
defines AngleAngle Coeffs.
<DT><I>Must define improper_style before Improper Coeffs</I>
<DD>Must use an improper_style command before reading a data file that
defines Improper Coeffs.
<DT><I>Must define lattice to append/atoms</I>
<DD>A lattice must be defined before using this fix.
<DT><I>Must define pair_style before Pair Coeffs</I>
<DD>Must use a pair_style command before reading a data file that defines
Pair Coeffs.
<DT><I>Must have more than one processor partition to temper</I>
<DD>Cannot use the temper command with only one processor partition. Use
the -partition command-line option.
<DT><I>Must read Atoms before Angles</I>
<DD>The Atoms section of a data file must come before an Angles section.
<DT><I>Must read Atoms before Bonds</I>
<DD>The Atoms section of a data file must come before a Bonds section.
<DT><I>Must read Atoms before Dihedrals</I>
<DD>The Atoms section of a data file must come before a Dihedrals section.
<DT><I>Must read Atoms before Ellipsoids</I>
<DD>The Atoms section of a data file must come before a Ellipsoids
section.
<DT><I>Must read Atoms before Impropers</I>
<DD>The Atoms section of a data file must come before an Impropers
section.
<DT><I>Must read Atoms before Lines</I>
<DD>The Atoms section of a data file must come before a Lines section.
<DT><I>Must read Atoms before Triangles</I>
<DD>The Atoms section of a data file must come before a Triangles section.
<DT><I>Must read Atoms before Velocities</I>
<DD>The Atoms section of a data file must come before a Velocities
section.
<DT><I>Must set both respa inner and outer</I>
<DD>Cannot use just the inner or outer option with respa without using the
other.
<DT><I>Must shrink-wrap piston boundary</I>
<DD>The boundary style of the face where the piston is applied must be of
type s (shrink-wrapped).
<DT><I>Must specify a region in fix deposit</I>
<DD>The region keyword must be specified with this fix.
<DT><I>Must specify a region in fix pour</I>
<DD>The region keyword must be specified with this fix.
<DT><I>Must use -in switch with multiple partitions</I>
<DD>A multi-partition simulation cannot read the input script from stdin.
The -in command-line option must be used to specify a file.
<DT><I>Must use a block or cylinder region with fix pour</I>
<DD>Self-explanatory.
<DT><I>Must use a block region with fix pour for 2d simulations</I>
<DD>Self-explanatory.
<DT><I>Must use a bond style with TIP4P potential</I>
<DD>TIP4P potentials assume bond lengths in water are constrained
by a fix shake command.
<DT><I>Must use a molecular atom style with fix poems molecule</I>
<DD>Self-explanatory.
<DT><I>Must use a z-axis cylinder with fix pour</I>
<DD>The axis of the cylinder region used with the fix pour command must
be oriented along the z dimension.
<DT><I>Must use an angle style with TIP4P potential</I>
<DD>TIP4P potentials assume angles in water are constrained by a fix shake
command.
<DT><I>Must use atom style with molecule IDs with fix bond/swap</I>
<DD>Self-explanatory.
<DT><I>Must use pair_style comb with fix qeq/comb</I>
<DD>Self-explanatory.
<DT><I>Must use variable energy with fix addforce</I>
<DD>Must define an energy vartiable when applyting a dynamic
force during minimization.
<DT><I>NEB command before simulation box is defined</I>
<DD>Self-explanatory.
<DT><I>NEB requires damped dynamics minimizer</I>
<DD>Use a different minimization style.
<DT><I>NEB requires use of fix neb</I>
<DD>Self-explanatory.
<DT><I>NL ramp in wall/piston only implemented in zlo for now</I>
<DD>The ramp keyword can only be used for piston applied to face zlo.
<DT><I>Needed bonus data not in data file</I>
<DD>Some atom styles require bonus data. See the read_data doc page for
details.
<DT><I>Needed topology not in data file</I>
<DD>The header of the data file indicated that bonds or angles or
dihedrals or impropers would be included, but they were not present.
<DT><I>Neigh_modify exclude molecule requires atom attribute molecule</I>
<DD>Self-explanatory.
<DT><I>Neigh_modify include group != atom_modify first group</I>
<DD>Self-explanatory.
<DT><I>Neighbor delay must be 0 or multiple of every setting</I>
<DD>The delay and every parameters set via the neigh_modify command are
inconsistent. If the delay setting is non-zero, then it must be a
multiple of the every setting.
<DT><I>Neighbor include group not allowed with ghost neighbors</I>
<DD>This is a current restriction within LAMMPS.
<DT><I>Neighbor list overflow, boost neigh_modify one</I>
<DD>There are too many neighbors of a single atom. Use the neigh_modify
command to increase the max number of neighbors allowed for one atom.
You may also want to boost the page size.
<DT><I>Neighbor list overflow, boost neigh_modify one or page</I>
<DD>There are too many neighbors of a single atom. Use the neigh_modify
command to increase the neighbor page size and the max number of
neighbors allowed for one atom.
<DT><I>Neighbor multi not yet enabled for ghost neighbors</I>
<DD>This is a current restriction within LAMMPS.
<DT><I>Neighbor multi not yet enabled for granular</I>
<DD>Self-explanatory.
<DT><I>Neighbor multi not yet enabled for rRESPA</I>
<DD>Self-explanatory.
<DT><I>Neighbor page size must be >= 10x the one atom setting</I>
<DD>This is required to prevent wasting too much memory.
-<DT><I>Neighbors of ghost atoms only allowed for full neighbor lists</I>
-
-<DD>This is a current restriction within LAMMPS.
-
<DT><I>New bond exceeded bonds per atom in fix bond/create</I>
<DD>See the read_data command for info on setting the "extra bond per
atom" header value to allow for additional bonds to be formed.
<DT><I>New bond exceeded special list size in fix bond/create</I>
<DD>See the special_bonds extra command for info on how to leave space in
the special bonds list to allow for additional bonds to be formed.
<DT><I>Newton bond change after simulation box is defined</I>
<DD>The newton command cannot be used to change the newton bond value
after a read_data, read_restart, or create_box command.
+<DT><I>No Kspace style defined for compute group/group</I>
+
+<DD>Self-explanatory.
+
<DT><I>No OpenMP support compiled in</I>
<DD>An OpenMP flag is set, but LAMMPS was not built with
OpenMP support.
<DT><I>No angle style is defined for compute angle/local</I>
<DD>Self-explanatory.
<DT><I>No angles allowed with this atom style</I>
<DD>Self-explanatory. Check data file.
<DT><I>No atoms in data file</I>
<DD>The header of the data file indicated that atoms would be included,
but they were not present.
<DT><I>No basis atoms in lattice</I>
<DD>Basis atoms must be defined for lattice style user.
<DT><I>No bond style is defined for compute bond/local</I>
<DD>Self-explanatory.
<DT><I>No bonds allowed with this atom style</I>
<DD>Self-explanatory. Check data file.
+<DT><I>No box information in dump. You have to use 'box no'</I>
+
+<DD>Self-explanatory.
+
<DT><I>No dihedral style is defined for compute dihedral/local</I>
<DD>Self-explanatory.
<DT><I>No dihedrals allowed with this atom style</I>
<DD>Self-explanatory. Check data file.
<DT><I>No dump custom arguments specified</I>
<DD>The dump custom command requires that atom quantities be specified to
output to dump file.
<DT><I>No dump local arguments specified</I>
<DD>Self-explanatory.
<DT><I>No ellipsoids allowed with this atom style</I>
<DD>Self-explanatory. Check data file.
<DT><I>No fix gravity defined for fix pour</I>
<DD>Cannot add poured particles without gravity to move them.
<DT><I>No improper style is defined for compute improper/local</I>
<DD>Self-explanatory.
<DT><I>No impropers allowed with this atom style</I>
<DD>Self-explanatory. Check data file.
<DT><I>No lines allowed with this atom style</I>
<DD>Self-explanatory. Check data file.
<DT><I>No matching element in ADP potential file</I>
<DD>The ADP potential file does not contain elements that match the
requested elements.
<DT><I>No matching element in EAM potential file</I>
<DD>The EAM potential file does not contain elements that match the
requested elements.
+<DT><I>No overlap of box and region for create_atoms</I>
+
+<DD>Self-explanatory.
+
<DT><I>No pair hbond/dreiding coefficients set</I>
<DD>Self-explanatory.
<DT><I>No pair style defined for compute group/group</I>
<DD>Cannot calculate group interactions without a pair style defined.
<DT><I>No pair style is defined for compute pair/local</I>
<DD>Self-explanatory.
<DT><I>No pair style is defined for compute property/local</I>
<DD>Self-explanatory.
<DT><I>No rigid bodies defined</I>
<DD>The fix specification did not end up defining any rigid bodies.
<DT><I>No triangles allowed with this atom style</I>
<DD>Self-explanatory. Check data file.
<DT><I>Non digit character between brackets in variable</I>
<DD>Self-explantory.
<DT><I>Non integer # of swaps in temper command</I>
<DD>Swap frequency in temper command must evenly divide the total # of
timesteps.
<DT><I>Nprocs not a multiple of N for -reorder</I>
<DD>Self-explanatory.
<DT><I>Numeric index is out of bounds</I>
<DD>A command with an argument that specifies an integer or range of
integers is using a value that is less than 1 or greater than the
maximum allowed limit.
<DT><I>One or more atoms belong to multiple rigid bodies</I>
<DD>Two or more rigid bodies defined by the fix rigid command cannot
contain the same atom.
<DT><I>One or zero atoms in rigid body</I>
<DD>Any rigid body defined by the fix rigid command must contain 2 or more
atoms.
<DT><I>Only zhi currently implemented for fix append/atoms</I>
<DD>Self-explanatory.
<DT><I>Out of range atoms - cannot compute PPPM</I>
<DD>One or more atoms are attempting to map their charge to a PPPM grid
point that is not owned by a processor. This is likely for one of two
reasons, both of them bad. First, it may mean that an atom near the
boundary of a processor's sub-domain has moved more than 1/2 the
<A HREF = "neighbor.html">neighbor skin distance</A> without neighbor lists being
rebuilt and atoms being migrated to new processors. This also means
you may be missing pairwise interactions that need to be computed.
The solution is to change the re-neighboring criteria via the
<A HREF = "neigh_modify">neigh_modify</A> command. The safest settings are "delay 0
every 1 check yes". Second, it may mean that an atom has moved far
outside a processor's sub-domain or even the entire simulation box.
This indicates bad physics, e.g. due to highly overlapping atoms, too
large a timestep, etc.
<DT><I>Overlapping large/large in pair colloid</I>
<DD>This potential is infinite when there is an overlap.
<DT><I>Overlapping small/large in pair colloid</I>
<DD>This potential is inifinte when there is an overlap.
<DT><I>POEMS fix must come before NPT/NPH fix</I>
<DD>NPT/NPH fix must be defined in input script after all poems fixes,
else the fix contribution to the pressure virial is incorrect.
<DT><I>PPPM grid is too large</I>
<DD>The global PPPM grid is larger than OFFSET in one or more dimensions.
OFFSET is currently set to 4096. You likely need to decrease the
requested accuracy.
-<DT><I>PPPM order cannot be greater than %d</I>
+<DT><I>PPPM order cannot be < 2 or > than %d</I>
-<DD>Self-explanatory.
+<DD>This is a limitation of the PPPM implementation in LAMMPS.
<DT><I>PPPM order has been reduced to 0</I>
<DD>LAMMPS has attempted to reduce the PPPM order to enable the simulation
to run, but can reduce the order no further. Try increasing the
-accuracy of PPPM by reducing the tolerance size, thus inducing a
+accuracy of PPPM by reducing the tolerance size, thus inducing a
larger PPPM grid.
<DT><I>PRD command before simulation box is defined</I>
<DD>The prd command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>PRD nsteps must be multiple of t_event</I>
<DD>Self-explanatory.
<DT><I>PRD t_corr must be multiple of t_event</I>
<DD>Self-explanatory.
<DT><I>PWD environment variable is unset</I>
<DD>This environment variable must be set to use pair_style kim.
See the doc page for pair_style kim.
<DT><I>Package command after simulation box is defined</I>
<DD>The package command cannot be used afer a read_data, read_restart, or
create_box command.
<DT><I>Package cuda command without USER-CUDA installed</I>
<DD>The USER-CUDA package must be installed via "make yes-user-cuda"
before LAMMPS is built.
<DT><I>Pair brownian requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Pair brownian requires extended particles</I>
<DD>One of the particles has radius 0.0.
<DT><I>Pair brownian requires monodisperse particles</I>
<DD>All particles must be the same finite size.
<DT><I>Pair brownian/poly requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Pair brownian/poly requires extended particles</I>
<DD>One of the particles has radius 0.0.
<DT><I>Pair brownian/poly requires newton pair off</I>
<DD>Self-explanatory.
<DT><I>Pair coeff for hybrid has invalid style</I>
<DD>Style in pair coeff must have been listed in pair_style command.
<DT><I>Pair coul/wolf requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair cutoff < Respa interior cutoff</I>
<DD>One or more pairwise cutoffs are too short to use with the specified
rRESPA cutoffs.
<DT><I>Pair dipole/cut requires atom attributes q, mu, torque</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair distance < table inner cutoff</I>
<DD>Two atoms are closer together than the pairwise table allows.
<DT><I>Pair distance > table outer cutoff</I>
<DD>Two atoms are further apart than the pairwise table allows.
<DT><I>Pair dpd requires ghost atoms store velocity</I>
<DD>Use the communicate vel yes command to enable this.
<DT><I>Pair gayberne epsilon a,b,c coeffs are not all set</I>
<DD>Each atom type involved in pair_style gayberne must
have these 3 coefficients set at least once.
<DT><I>Pair gayberne requires atom style ellipsoid</I>
<DD>Self-explanatory.
<DT><I>Pair gayberne requires atoms with same type have same shape</I>
<DD>Self-explanatory.
<DT><I>Pair gayberne/gpu requires atom style ellipsoid</I>
<DD>Self-explanatory.
<DT><I>Pair gayberne/gpu requires atoms with same type have same shape</I>
<DD>Self-explanatory.
<DT><I>Pair granular requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Pair granular requires ghost atoms store velocity</I>
<DD>Use the communicate vel yes command to enable this.
<DT><I>Pair granular with shear history requires newton pair off</I>
<DD>This is a current restriction of the implementation of pair
granular styles with history.
<DT><I>Pair hybrid sub-style does not support single call</I>
<DD>You are attempting to invoke a single() call on a pair style
that doesn't support it.
<DT><I>Pair hybrid sub-style is not used</I>
<DD>No pair_coeff command used a sub-style specified in the pair_style
command.
<DT><I>Pair inner cutoff < Respa interior cutoff</I>
<DD>One or more pairwise cutoffs are too short to use with the specified
rRESPA cutoffs.
<DT><I>Pair inner cutoff >= Pair outer cutoff</I>
<DD>The specified cutoffs for the pair style are inconsistent.
<DT><I>Pair line/lj requires atom style line</I>
<DD>Self-explanatory.
<DT><I>Pair lubricate requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Pair lubricate requires ghost atoms store velocity</I>
<DD>Use the communicate vel yes command to enable this.
<DT><I>Pair lubricate requires monodisperse particles</I>
<DD>All particles must be the same finite size.
<DT><I>Pair lubricate/poly requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Pair lubricate/poly requires extended particles</I>
<DD>One of the particles has radius 0.0.
<DT><I>Pair lubricate/poly requires ghost atoms store velocity</I>
<DD>Use the communicate vel yes command to enable this.
<DT><I>Pair lubricate/poly requires newton pair off</I>
<DD>Self-explanatory.
<DT><I>Pair lubricateU requires atom style sphere</I>
<DD>Self-explanatory.
<DT><I>Pair lubricateU requires ghost atoms store velocity</I>
<DD>Use the communicate vel yes command to enable this.
<DT><I>Pair lubricateU requires monodisperse particles</I>
<DD>All particles must be the same finite size.
<DT><I>Pair lubricateU/poly requires ghost atoms store velocity</I>
<DD>Use the communicate vel yes command to enable this.
<DT><I>Pair lubricateU/poly requires newton pair off</I>
<DD>Self-explanatory.
<DT><I>Pair peri lattice is not identical in x, y, and z</I>
<DD>The lattice defined by the lattice command must be cubic.
<DT><I>Pair peri requires a lattice be defined</I>
<DD>Use the lattice command for this purpose.
<DT><I>Pair peri requires an atom map, see atom_modify</I>
<DD>Even for atomic systems, an atom map is required to find Peridynamic
bonds. Use the atom_modify command to define one.
<DT><I>Pair resquared epsilon a,b,c coeffs are not all set</I>
<DD>Self-explanatory.
<DT><I>Pair resquared epsilon and sigma coeffs are not all set</I>
<DD>Self-explanatory.
<DT><I>Pair resquared requires atom style ellipsoid</I>
<DD>Self-explanatory.
<DT><I>Pair resquared requires atoms with same type have same shape</I>
<DD>Self-explanatory.
<DT><I>Pair resquared/gpu requires atom style ellipsoid</I>
<DD>Self-explanatory.
<DT><I>Pair resquared/gpu requires atoms with same type have same shape</I>
<DD>Self-explanatory.
<DT><I>Pair style AIREBO requires atom IDs</I>
<DD>This is a requirement to use the AIREBO potential.
<DT><I>Pair style AIREBO requires newton pair on</I>
<DD>See the newton command. This is a restriction to use the AIREBO
potential.
+<DT><I>Pair style BOP requires atom IDs</I>
+
+<DD>This is a requirement to use the BOP potential.
+
+<DT><I>Pair style BOP requires newton pair on</I>
+
+<DD>See the newton command. This is a restriction to use the BOP
+potential.
+
<DT><I>Pair style COMB requires atom IDs</I>
<DD>This is a requirement to use the AIREBO potential.
<DT><I>Pair style COMB requires atom attribute q</I>
<DD>Self-explanatory.
<DT><I>Pair style COMB requires newton pair on</I>
<DD>See the newton command. This is a restriction to use the COMB
potential.
+<DT><I>Pair style LCBOP requires atom IDs</I>
+
+<DD>This is a requirement to use the LCBOP potential.
+
+<DT><I>Pair style LCBOP requires newton pair on</I>
+
+<DD>See the newton command. This is a restriction to use the LCBOP
+potential.
+
<DT><I>Pair style MEAM requires newton pair on</I>
<DD>See the newton command. This is a restriction to use the MEAM
potential.
<DT><I>Pair style Stillinger-Weber requires atom IDs</I>
<DD>This is a requirement to use the SW potential.
<DT><I>Pair style Stillinger-Weber requires newton pair on</I>
<DD>See the newton command. This is a restriction to use the SW
potential.
<DT><I>Pair style Tersoff requires atom IDs</I>
<DD>This is a requirement to use the Tersoff potential.
<DT><I>Pair style Tersoff requires newton pair on</I>
<DD>See the newton command. This is a restriction to use the Tersoff
potential.
+<DT><I>Pair style bop requires comm ghost cutoff at least 3x larger than %g</I>
+
+<DD>Use the communicate ghost command to set this. See the pair bop
+doc page for more details.
+
<DT><I>Pair style born/coul/long requires atom attribute q</I>
<DD>An atom style that defines this attribute must be used.
<DT><I>Pair style born/coul/wolf requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style buck/coul/cut requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style buck/coul/long requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair style buck/coul/long/gpu requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style coul/cut requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair style coul/long/gpu requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair style does not have extra field requested by compute pair/local</I>
<DD>The pair style does not support the pN value requested by the compute
pair/local command.
<DT><I>Pair style does not support bond_style quartic</I>
<DD>The pair style does not have a single() function, so it can
not be invoked by bond_style quartic.
<DT><I>Pair style does not support compute group/group</I>
<DD>The pair_style does not have a single() function, so it cannot be
invokded by the compute group/group command.
<DT><I>Pair style does not support compute pair/local</I>
<DD>The pair style does not have a single() function, so it can
not be invoked by compute pair/local.
<DT><I>Pair style does not support compute property/local</I>
<DD>The pair style does not have a single() function, so it can
not be invoked by fix bond/swap.
<DT><I>Pair style does not support fix bond/swap</I>
<DD>The pair style does not have a single() function, so it can
not be invoked by fix bond/swap.
<DT><I>Pair style does not support pair_write</I>
<DD>The pair style does not have a single() function, so it can
not be invoked by pair write.
<DT><I>Pair style does not support rRESPA inner/middle/outer</I>
<DD>You are attempting to use rRESPA options with a pair style that
does not support them.
<DT><I>Pair style granular with history requires atoms have IDs</I>
<DD>Atoms in the simulation do not have IDs, so history effects
cannot be tracked by the granular pair potential.
<DT><I>Pair style hbond/dreiding requires an atom map, see atom_modify</I>
<DD>Self-explanatory.
<DT><I>Pair style hbond/dreiding requires atom IDs</I>
<DD>Self-explanatory.
<DT><I>Pair style hbond/dreiding requires molecular system</I>
<DD>Self-explanatory.
<DT><I>Pair style hbond/dreiding requires newton pair on</I>
<DD>See the newton command for details.
<DT><I>Pair style hybrid cannot have hybrid as an argument</I>
<DD>Self-explanatory.
<DT><I>Pair style hybrid cannot have none as an argument</I>
<DD>Self-explanatory.
<DT><I>Pair style is incompatible with KSpace style</I>
<DD>If a pair style with a long-range Coulombic component is selected,
then a kspace style must also be used.
<DT><I>Pair style kim requires newton pair off</I>
<DD>This is a current restriction of the KIM library.
<DT><I>Pair style lj/charmm/coul/charmm requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair style lj/charmm/coul/long requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair style lj/charmm/coul/long/gpu requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/class2/coul/cut requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/class2/coul/long requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/class2/coul/long/gpu requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/cut/coul/cut requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/cut/coul/cut/gpu requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/cut/coul/long requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/cut/coul/long/gpu requires atom attribute q</I>
<DD>The atom style defined does not have this attribute.
<DT><I>Pair style lj/cut/coul/long/tip4p requires atom IDs</I>
<DD>There are no atom IDs defined in the system and the TIP4P potential
requires them to find O,H atoms with a water molecule.
<DT><I>Pair style lj/cut/coul/long/tip4p requires atom attribute q</I>
<DD>The atom style defined does not have these attributes.
<DT><I>Pair style lj/cut/coul/long/tip4p requires newton pair on</I>
<DD>This is because the computation of constraint forces within a water
molecule adds forces to atoms owned by other processors.
<DT><I>Pair style lj/gromacs/coul/gromacs requires atom attribute q</I>
<DD>An atom_style with this attribute is needed.
<DT><I>Pair style peri requires atom style peri</I>
<DD>Self-explanatory.
<DT><I>Pair style reax requires atom IDs</I>
<DD>This is a requirement to use the ReaxFF potential.
<DT><I>Pair style reax requires newton pair on</I>
<DD>This is a requirement to use the ReaxFF potential.
<DT><I>Pair table cutoffs must all be equal to use with KSpace</I>
<DD>When using pair style table with a long-range KSpace solver, the
cutoffs for all atom type pairs must all be the same, since the
long-range solver starts at that cutoff.
<DT><I>Pair table parameters did not set N</I>
<DD>List of pair table parameters must include N setting.
<DT><I>Pair tersoff/zbl requires metal or real units</I>
<DD>This is a current restriction of this pair potential.
<DT><I>Pair tri/lj requires atom style tri</I>
<DD>Self-explanatory.
<DT><I>Pair yukawa/colloid requires atom style sphere</I>
<DD>Self-explantory.
<DT><I>Pair yukawa/colloid requires atoms with same type have same radius</I>
<DD>Self-explantory.
<DT><I>Pair_coeff command before pair_style is defined</I>
<DD>Self-explanatory.
<DT><I>Pair_coeff command before simulation box is defined</I>
<DD>The pair_coeff command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Pair_modify command before pair_style is defined</I>
<DD>Self-explanatory.
<DT><I>Pair_write command before pair_style is defined</I>
<DD>Self-explanatory.
<DT><I>Particle on or inside fix wall surface</I>
<DD>Particles must be "exterior" to the wall in order for energy/force to
be calculated.
<DT><I>Particle on or inside surface of region used in fix wall/region</I>
<DD>Particles must be "exterior" to the region surface in order for
energy/force to be calculated.
<DT><I>Per-atom compute in equal-style variable formula</I>
<DD>Equal-style variables cannot use per-atom quantities.
<DT><I>Per-atom energy was not tallied on needed timestep</I>
<DD>You are using a thermo keyword that requires potentials to
have tallied energy, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work.
<DT><I>Per-atom fix in equal-style variable formula</I>
<DD>Equal-style variables cannot use per-atom quantities.
<DT><I>Per-atom virial was not tallied on needed timestep</I>
<DD>You are using a thermo keyword that requires potentials to have
tallied the virial, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work.
<DT><I>Per-processor system is too big</I>
<DD>The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
<DT><I>Potential energy ID for fix neb does not exist</I>
<DD>Self-explanatory.
<DT><I>Potential energy ID for fix nvt/nph/npt does not exist</I>
<DD>A compute for potential energy must be defined.
<DT><I>Potential file has duplicate entry</I>
<DD>The potential file for a SW or Tersoff potential has more than
one entry for the same 3 ordered elements.
<DT><I>Potential file is missing an entry</I>
<DD>The potential file for a SW or Tersoff potential does not have a
needed entry.
<DT><I>Power by 0 in variable formula</I>
<DD>Self-explanatory.
<DT><I>Pressure ID for fix box/relax does not exist</I>
<DD>The compute ID needed to compute pressure for the fix does not
exist.
<DT><I>Pressure ID for fix modify does not exist</I>
<DD>Self-explanatory.
<DT><I>Pressure ID for fix npt/nph does not exist</I>
<DD>Self-explanatory.
<DT><I>Pressure ID for fix press/berendsen does not exist</I>
<DD>The compute ID needed to compute pressure for the fix does not
exist.
<DT><I>Pressure ID for thermo does not exist</I>
<DD>The compute ID needed to compute pressure for thermodynamics does not
exist.
<DT><I>Pressure control can not be used with fix nvt</I>
<DD>Self-explanatory.
<DT><I>Pressure control can not be used with fix nvt/asphere</I>
<DD>Self-explanatory.
<DT><I>Pressure control can not be used with fix nvt/sllod</I>
<DD>Self-explanatory.
<DT><I>Pressure control can not be used with fix nvt/sphere</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix nph</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix nph/asphere</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix nph/sphere</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix nphug</I>
<DD>A pressure control keyword (iso, aniso, tri, x, y, or z) must be
provided.
<DT><I>Pressure control must be used with fix npt</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix npt/asphere</I>
<DD>Self-explanatory.
<DT><I>Pressure control must be used with fix npt/sphere</I>
<DD>Self-explanatory.
<DT><I>Processor count in z must be 1 for 2d simulation</I>
<DD>Self-explanatory.
<DT><I>Processor partitions are inconsistent</I>
<DD>The total number of processors in all partitions must match the number
of processors LAMMPS is running on.
<DT><I>Processors command after simulation box is defined</I>
<DD>The processors command cannot be used after a read_data, read_restart,
or create_box command.
<DT><I>Processors custom grid file is inconsistent</I>
<DD>The vales in the custom file are not consistent with the number of
processors you are running on or the Px,Py,Pz settings of the
processors command. Or there was not a setting for every processor.
<DT><I>Processors grid numa and map style are incompatible</I>
<DD>Using numa for gstyle in the processors command requires using
cart for the map option.
<DT><I>Processors part option and grid style are incompatible</I>
<DD>Cannot use gstyle numa or custom with the part option.
<DT><I>Processors twogrid requires proc count be a multiple of core count</I>
<DD>Self-explanatory.
<DT><I>Pstart and Pstop must have the same value</I>
<DD>Self-explanatory.
<DT><I>R0 < 0 for fix spring command</I>
<DD>Equilibrium spring length is invalid.
+<DT><I>Read_dump field not found in dump file</I>
+
+<DD>Self-explanatory.
+
+<DT><I>Read_dump triclinic status does not match simulation</I>
+
+<DD>Both the dump snapshot and the current LAMMPS simulation must
+be using either an orthogonal or triclinic box.
+
+<DT><I>Read_dump x,y,z fields do not have consistent scaling</I>
+
+<DD>Self-explanatory.
+
<DT><I>Reax_defs.h setting for NATDEF is too small</I>
<DD>Edit the setting in the ReaxFF library and re-compile the
library and re-build LAMMPS.
<DT><I>Reax_defs.h setting for NNEIGHMAXDEF is too small</I>
<DD>Edit the setting in the ReaxFF library and re-compile the
library and re-build LAMMPS.
<DT><I>Receiving partition in processors part command is already a receiver</I>
<DD>Cannot specify a partition to be a receiver twice.
<DT><I>Region ID for compute reduce/region does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for compute temp/region does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for dump custom does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix addforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix ave/spatial does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix aveforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix deposit does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix evaporate does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix heat does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix setforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID for fix wall/region does not exist</I>
<DD>Self-explanatory.
<DT><I>Region ID in variable formula does not exist</I>
<DD>Self-explanatory.
<DT><I>Region cannot have 0 length rotation vector</I>
<DD>Self-explanatory.
<DT><I>Region intersect region ID does not exist</I>
<DD>Self-explanatory.
<DT><I>Region union or intersect cannot be dynamic</I>
<DD>The sub-regions can be dynamic, but not the combined region.
<DT><I>Region union region ID does not exist</I>
<DD>One or more of the region IDs specified by the region union command
does not exist.
<DT><I>Replacing a fix, but new style != old style</I>
<DD>A fix ID can be used a 2nd time, but only if the style matches the
previous fix. In this case it is assumed you with to reset a fix's
parameters. This error may mean you are mistakenly re-using a fix ID
when you do not intend to.
<DT><I>Replicate command before simulation box is defined</I>
<DD>The replicate command cannot be used before a read_data, read_restart,
or create_box command.
<DT><I>Replicate did not assign all atoms correctly</I>
<DD>Atoms replicated by the replicate command were not assigned correctly
to processors. This is likely due to some atom coordinates being
outside a non-periodic simulation box.
<DT><I>Replicated molecular system atom IDs are too big</I>
<DD>See the setting for the allowed atom ID size in the src/lmptype.h
file.
<DT><I>Replicated system is too big</I>
<DD>See the setting for bigint in the src/lmptype.h file.
+<DT><I>Rerun command before simulation box is defined</I>
+
+<DD>The rerun command cannot be used before a read_data, read_restart, or
+create_box command.
+
+<DT><I>Rerun dump file does not contain requested snapshot</I>
+
+<DD>Self-explanatory.
+
<DT><I>Resetting timestep is not allowed with fix move</I>
<DD>This is because fix move is moving atoms based on elapsed time.
<DT><I>Respa inner cutoffs are invalid</I>
<DD>The first cutoff must be <= the second cutoff.
<DT><I>Respa levels must be >= 1</I>
<DD>Self-explanatory.
<DT><I>Respa middle cutoffs are invalid</I>
<DD>The first cutoff must be <= the second cutoff.
+<DT><I>Restart variable returned a bad timestep</I>
+
+<DD>The variable must return a timestep greater than the current timestep.
+
<DT><I>Restrain atoms %d %d %d %d missing on proc %d at step %ld</I>
<DD>The 4 atoms in a restrain dihedral specified by the fix restrain
command are not all accessible to a processor. This probably means an
atom has moved too far.
+<DT><I>Restrain atoms %d %d %d missing on proc %d at step %ld</I>
+
+<DD>The 3 atoms in a restrain angle specified by the fix restrain
+command are not all accessible to a processor. This probably means an
+atom has moved too far.
+
+<DT><I>Restrain atoms %d %d missing on proc %d at step %ld</I>
+
+<DD>The 2 atoms in a restrain bond specified by the fix restrain
+command are not all accessible to a processor. This probably means an
+atom has moved too far.
+
<DT><I>Reuse of compute ID</I>
<DD>A compute ID cannot be used twice.
<DT><I>Reuse of dump ID</I>
<DD>A dump ID cannot be used twice.
<DT><I>Reuse of region ID</I>
<DD>A region ID cannot be used twice.
<DT><I>Rigid body has degenerate moment of inertia</I>
<DD>Fix poems will only work with bodies (collections of atoms) that have
non-zero principal moments of inertia. This means they must be 3 or
more non-collinear atoms, even with joint atoms removed.
<DT><I>Rigid fix must come before NPT/NPH fix</I>
<DD>NPT/NPH fix must be defined in input script after all rigid fixes,
else the rigid fix contribution to the pressure virial is
incorrect.
<DT><I>Rmask function in equal-style variable formula</I>
<DD>Rmask is per-atom operation.
<DT><I>Run command before simulation box is defined</I>
<DD>The run command cannot be used before a read_data, read_restart, or
create_box command.
<DT><I>Run command start value is after start of run</I>
<DD>Self-explanatory.
<DT><I>Run command stop value is before end of run</I>
<DD>Self-explanatory.
<DT><I>Run_style command before simulation box is defined</I>
<DD>The run_style command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>SRD bin size for fix srd differs from user request</I>
<DD>Fix SRD had to adjust the bin size to fit the simulation box. See the
cubic keyword if you want this message to be an error vs warning.
<DT><I>SRD bins for fix srd are not cubic enough</I>
<DD>The bin shape is not within tolerance of cubic. See the cubic
keyword if you want this message to be an error vs warning.
<DT><I>SRD particle %d started inside big particle %d on step %ld bounce %d</I>
<DD>See the inside keyword if you want this message to be an error vs
warning.
<DT><I>Same dimension twice in fix ave/spatial</I>
<DD>Self-explanatory.
<DT><I>Sending partition in processors part command is already a sender</I>
<DD>Cannot specify a partition to be a sender twice.
<DT><I>Set command before simulation box is defined</I>
<DD>The set command cannot be used before a read_data, read_restart,
or create_box command.
<DT><I>Set command with no atoms existing</I>
<DD>No atoms are yet defined so the set command cannot be used.
<DT><I>Set region ID does not exist</I>
<DD>Region ID specified in set command does not exist.
<DT><I>Shake angles have different bond types</I>
<DD>All 3-atom angle-constrained SHAKE clusters specified by the fix shake
command that are the same angle type, must also have the same bond
types for the 2 bonds in the angle.
<DT><I>Shake atoms %d %d %d %d missing on proc %d at step %ld</I>
<DD>The 4 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far.
<DT><I>Shake atoms %d %d %d missing on proc %d at step %ld</I>
<DD>The 3 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far.
<DT><I>Shake atoms %d %d missing on proc %d at step %ld</I>
<DD>The 2 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far.
<DT><I>Shake cluster of more than 4 atoms</I>
<DD>A single cluster specified by the fix shake command can have no more
than 4 atoms.
<DT><I>Shake clusters are connected</I>
<DD>A single cluster specified by the fix shake command must have a single
central atom with up to 3 other atoms bonded to it.
<DT><I>Shake determinant = 0.0</I>
<DD>The determinant of the matrix being solved for a single cluster
specified by the fix shake command is numerically invalid.
<DT><I>Shake fix must come before NPT/NPH fix</I>
<DD>NPT fix must be defined in input script after SHAKE fix, else the
SHAKE fix contribution to the pressure virial is incorrect.
<DT><I>Small, tag, big integers are not sized correctly</I>
<DD>See description of these 3 data types in src/lmptype.h.
<DT><I>Smallint setting in lmptype.h is invalid</I>
<DD>It has to be the size of an integer.
<DT><I>Smallint setting in lmptype.h is not compatible</I>
<DD>Smallint stored in restart file is not consistent with LAMMPS version
you are running.
<DT><I>Specified processors != physical processors</I>
<DD>The 3d grid of processors defined by the processors command does not
match the number of processors LAMMPS is being run on.
<DT><I>Specified target stress must be uniaxial or hydrostatic</I>
<DD>Self-explanatory.
<DT><I>Sqrt of negative value in variable formula</I>
<DD>Self-explanatory.
<DT><I>Substitution for illegal variable</I>
<DD>Input script line contained a variable that could not be substituted
for.
<DT><I>System in data file is too big</I>
<DD>See the setting for bigint in the src/lmptype.h file.
<DT><I>TAD nsteps must be multiple of t_event</I>
<DD>Self-explanatory.
<DT><I>TIP4P hydrogen has incorrect atom type</I>
<DD>The TIP4P pairwise computation found an H atom whose type does not
agree with the specified H type.
<DT><I>TIP4P hydrogen is missing</I>
<DD>The TIP4P pairwise computation failed to find the correct H atom
within a water molecule.
<DT><I>TMD target file did not list all group atoms</I>
<DD>The target file for the fix tmd command did not list all atoms in the
fix group.
<DT><I>Tad command before simulation box is defined</I>
<DD>Self-explanatory.
<DT><I>Tagint setting in lmptype.h is invalid</I>
<DD>Tagint must be as large or larger than smallint.
<DT><I>Tagint setting in lmptype.h is not compatible</I>
<DD>Smallint stored in restart file is not consistent with LAMMPS version
you are running.
<DT><I>Target temperature for fix nvt/npt/nph cannot be 0.0</I>
<DD>Self-explanatory.
<DT><I>Target temperature for fix rigid/nvt cannot be 0.0</I>
<DD>Self-explanatory.
<DT><I>Temper command before simulation box is defined</I>
<DD>The temper command cannot be used before a read_data, read_restart, or
create_box command.
<DT><I>Temperature ID for fix bond/swap does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature ID for fix box/relax does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature ID for fix nvt/nph/npt does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature ID for fix press/berendsen does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature ID for fix temp/berendsen does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature ID for fix temp/rescale does not exist</I>
<DD>Self-explanatory.
<DT><I>Temperature control can not be used with fix nph</I>
<DD>Self-explanatory.
<DT><I>Temperature control can not be used with fix nph/asphere</I>
<DD>Self-explanatory.
<DT><I>Temperature control can not be used with fix nph/sphere</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix nphug</I>
<DD>The temp keyword must be provided.
<DT><I>Temperature control must be used with fix npt</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix npt/asphere</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix npt/sphere</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix nvt</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix nvt/asphere</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix nvt/sllod</I>
<DD>Self-explanatory.
<DT><I>Temperature control must be used with fix nvt/sphere</I>
<DD>Self-explanatory.
<DT><I>Temperature for fix nvt/sllod does not have a bias</I>
<DD>The specified compute must compute temperature with a bias.
<DT><I>Tempering could not find thermo_pe compute</I>
<DD>This compute is created by the thermo command. It must have been
explicitly deleted by a uncompute command.
<DT><I>Tempering fix ID is not defined</I>
<DD>The fix ID specified by the temper command does not exist.
<DT><I>Tempering temperature fix is not valid</I>
<DD>The fix specified by the temper command is not one that controls
temperature (nvt or langevin).
<DT><I>The package gpu command is required for gpu styles</I>
<DD>Self-explanatory.
<DT><I>Thermo and fix not computed at compatible times</I>
<DD>Fixes generate values on specific timesteps. The thermo output
does not match these timesteps.
<DT><I>Thermo compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Thermo compute does not compute array</I>
<DD>Self-explanatory.
<DT><I>Thermo compute does not compute scalar</I>
<DD>Self-explanatory.
<DT><I>Thermo compute does not compute vector</I>
<DD>Self-explanatory.
<DT><I>Thermo compute vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Thermo custom variable cannot be indexed</I>
<DD>Self-explanatory.
<DT><I>Thermo custom variable is not equal-style variable</I>
<DD>Only equal-style variables can be output with thermodynamics, not
atom-style variables.
<DT><I>Thermo every variable returned a bad timestep</I>
<DD>The variable must return a timestep greater than the current timestep.
<DT><I>Thermo fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Thermo fix does not compute array</I>
<DD>Self-explanatory.
<DT><I>Thermo fix does not compute scalar</I>
<DD>Self-explanatory.
<DT><I>Thermo fix does not compute vector</I>
<DD>Self-explanatory.
<DT><I>Thermo fix vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Thermo keyword in variable requires lattice be defined</I>
<DD>The xlat, ylat, zlat keywords refer to lattice properties.
<DT><I>Thermo keyword in variable requires thermo to use/init pe</I>
<DD>You are using a thermo keyword in a variable that requires
potential energy to be calculated, but your thermo output
does not use it. Add it to your thermo output.
<DT><I>Thermo keyword in variable requires thermo to use/init press</I>
<DD>You are using a thermo keyword in a variable that requires pressure to
be calculated, but your thermo output does not use it. Add it to your
thermo output.
<DT><I>Thermo keyword in variable requires thermo to use/init temp</I>
<DD>You are using a thermo keyword in a variable that requires temperature
to be calculated, but your thermo output does not use it. Add it to
your thermo output.
<DT><I>Thermo keyword requires lattice be defined</I>
<DD>The xlat, ylat, zlat keywords refer to lattice properties.
<DT><I>Thermo style does not use press</I>
<DD>Cannot use thermo_modify to set this parameter since the thermo_style
is not computing this quantity.
<DT><I>Thermo style does not use temp</I>
<DD>Cannot use thermo_modify to set this parameter since the thermo_style
is not computing this quantity.
<DT><I>Thermo_modify int format does not contain d character</I>
<DD>Self-explanatory.
<DT><I>Thermo_modify pressure ID does not compute pressure</I>
<DD>The specified compute ID does not compute pressure.
<DT><I>Thermo_modify temperature ID does not compute temperature</I>
<DD>The specified compute ID does not compute temperature.
<DT><I>Thermo_style command before simulation box is defined</I>
<DD>The thermo_style command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>This variable thermo keyword cannot be used between runs</I>
<DD>Keywords that refer to time (such as cpu, elapsed) do not
make sense in between runs.
<DT><I>Threshhold for an atom property that isn't allocated</I>
<DD>A dump threshhold has been requested on a quantity that is
not defined by the atom style used in this simulation.
<DT><I>Timestep must be >= 0</I>
<DD>Specified timestep is invalid.
<DT><I>Too big a problem to use velocity create loop all</I>
<DD>The system size must fit in a 32-bit integer to use this option.
<DT><I>Too big a timestep</I>
<DD>Specified timestep is too large.
<DT><I>Too big a timestep for dump dcd</I>
<DD>The timestep must fit in a 32-bit integer to use this dump style.
<DT><I>Too big a timestep for dump xtc</I>
<DD>The timestep must fit in a 32-bit integer to use this dump style.
<DT><I>Too few bits for lookup table</I>
<DD>Table size specified via pair_modify command does not work with your
machine's floating point representation.
+<DT><I>Too many atom pairs for pair bop</I>
+
+<DD>The number of atomic pairs exceeds the expected number. Check your
+atomic structure to ensure that it is realistic.
+
<DT><I>Too many atom sorting bins</I>
<DD>This is likely due to an immense simulation box that has blown up
to a large size.
+<DT><I>Too many atom triplets for pair bop</I>
+
+<DD>The number of three atom groups for angle determinations exceeds the
+expected number. Check your atomic structrure to ensure that it is
+realistic.
+
<DT><I>Too many atoms for dump dcd</I>
<DD>The system size must fit in a 32-bit integer to use this dump
style.
<DT><I>Too many atoms for dump xtc</I>
<DD>The system size must fit in a 32-bit integer to use this dump
style.
<DT><I>Too many atoms to dump sort</I>
<DD>Cannot sort when running with more than 2^31 atoms.
<DT><I>Too many exponent bits for lookup table</I>
<DD>Table size specified via pair_modify command does not work with your
machine's floating point representation.
<DT><I>Too many groups</I>
-<DD>The maximum number of atom groups (including the "all" group) is
+<DD>The maximum number of atom groups (including the "all" group) is
given by MAX_GROUP in group.cpp and is 32.
<DT><I>Too many iterations</I>
-<DD>You must use a number of iterations that fit in a 32-bit integer
+<DD>You must use a number of iterations that fit in a 32-bit integer
for minimization.
<DT><I>Too many local+ghost atoms for neighbor list</I>
<DD>The number of nlocal + nghost atoms on a processor
is limited by the size of a 32-bit integer with 2 bits
removed for masking 1-2, 1-3, 1-4 neighbors.
<DT><I>Too many mantissa bits for lookup table</I>
<DD>Table size specified via pair_modify command does not work with your
machine's floating point representation.
<DT><I>Too many masses for fix shake</I>
<DD>The fix shake command cannot list more masses than there are atom
types.
<DT><I>Too many neighbor bins</I>
<DD>This is likely due to an immense simulation box that has blown up
to a large size.
<DT><I>Too many timesteps</I>
<DD>The cummulative timesteps must fit in a 64-bit integer.
<DT><I>Too many timesteps for NEB</I>
-<DD>You must use a number of timesteps that fit in a 32-bit integer
+<DD>You must use a number of timesteps that fit in a 32-bit integer
for NEB.
<DT><I>Too many total atoms</I>
<DD>See the setting for bigint in the src/lmptype.h file.
<DT><I>Too many total bits for bitmapped lookup table</I>
<DD>Table size specified via pair_modify command is too large. Note that
a value of N generates a 2^N size table.
<DT><I>Too many touching neighbors - boost MAXTOUCH</I>
<DD>A granular simulation has too many neighbors touching one atom. The
MAXTOUCH parameter in fix_shear_history.cpp must be set larger and
LAMMPS must be re-built.
<DT><I>Too much per-proc info for dump</I>
<DD>Number of local atoms times number of columns must fit in a 32-bit
integer for dump.
<DT><I>Tree structure in joint connections</I>
<DD>Fix poems cannot (yet) work with coupled bodies whose joints connect
the bodies in a tree structure.
<DT><I>Triclinic box skew is too large</I>
<DD>The displacement in a skewed direction must be less than half the box
length in that dimension. E.g. the xy tilt must be between -half and
+half of the x box length.
<DT><I>Tried to convert a double to int, but input_double > INT_MAX</I>
<DD>Self-explanatory.
<DT><I>Two groups cannot be the same in fix spring couple</I>
<DD>Self-explanatory.
<DT><I>USER-CUDA mode requires CUDA variant of min style</I>
<DD>CUDA mode is enabled, so the min style must include a cuda suffix.
<DT><I>USER-CUDA mode requires CUDA variant of run style</I>
<DD>CUDA mode is enabled, so the run style must include a cuda suffix.
<DT><I>USER-CUDA package requires a cuda enabled atom_style</I>
<DD>Self-explanatory.
<DT><I>Unable to initialize accelerator for use</I>
<DD>There was a problem initializing an accelerator for the gpu package
<DT><I>Unbalanced quotes in input line</I>
<DD>No matching end double quote was found following a leading double
quote.
<DT><I>Unexpected end of -reorder file</I>
<DD>Self-explanatory.
<DT><I>Unexpected end of custom file</I>
<DD>Self-explanatory.
<DT><I>Unexpected end of data file</I>
<DD>LAMMPS hit the end of the data file while attempting to read a
section. Something is wrong with the format of the data file.
+<DT><I>Unexpected end of dump file</I>
+
+<DD>A read operation from the file failed.
+
+<DT><I>Unexpected end of fix rigid file</I>
+
+<DD>A read operation from the file failed.
+
<DT><I>Units command after simulation box is defined</I>
<DD>The units command cannot be used after a read_data, read_restart, or
create_box command.
<DT><I>Universe/uloop variable count < # of partitions</I>
<DD>A universe or uloop style variable must specify a number of values >= to the
number of processor partitions.
<DT><I>Unknown command: %s</I>
<DD>The command is not known to LAMMPS. Check the input script.
<DT><I>Unknown error in GPU library</I>
<DD>Self-explanatory.
<DT><I>Unknown identifier in data file: %s</I>
<DD>A section of the data file cannot be read by LAMMPS.
<DT><I>Unknown table style in angle style table</I>
<DD>Self-explanatory.
<DT><I>Unknown table style in bond style table</I>
<DD>Self-explanatory.
<DT><I>Unknown table style in pair_style command</I>
<DD>Style of table is invalid for use with pair_style table command.
<DT><I>Unrecognized lattice type in MEAM file 1</I>
<DD>The lattice type in an entry of the MEAM library file is not
valid.
<DT><I>Unrecognized lattice type in MEAM file 2</I>
<DD>The lattice type in an entry of the MEAM parameter file is not
valid.
<DT><I>Unrecognized pair style in compute pair command</I>
<DD>Self-explanatory.
<DT><I>Use of change_box with undefined lattice</I>
<DD>Must use lattice command with displace_box command if units option is
set to lattice.
<DT><I>Use of compute temp/ramp with undefined lattice</I>
<DD>Must use lattice command with compute temp/ramp command if units
option is set to lattice.
<DT><I>Use of displace_atoms with undefined lattice</I>
<DD>Must use lattice command with displace_atoms command if units option
is set to lattice.
<DT><I>Use of fix append/atoms with undefined lattice</I>
<DD>A lattice must be defined before using this fix.
<DT><I>Use of fix ave/spatial with undefined lattice</I>
<DD>A lattice must be defined to use fix ave/spatial with units = lattice.
<DT><I>Use of fix deform with undefined lattice</I>
<DD>A lattice must be defined to use fix deform with units = lattice.
<DT><I>Use of fix deposit with undefined lattice</I>
<DD>Must use lattice command with compute fix deposit command if units
option is set to lattice.
<DT><I>Use of fix dt/reset with undefined lattice</I>
<DD>Must use lattice command with fix dt/reset command if units option is
set to lattice.
<DT><I>Use of fix indent with undefined lattice</I>
<DD>The lattice command must be used to define a lattice before using the
fix indent command.
<DT><I>Use of fix move with undefined lattice</I>
<DD>Must use lattice command with fix move command if units option is
set to lattice.
<DT><I>Use of fix recenter with undefined lattice</I>
<DD>Must use lattice command with fix recenter command if units option is
set to lattice.
<DT><I>Use of fix wall with undefined lattice</I>
<DD>Must use lattice command with fix wall command if units option is set
to lattice.
<DT><I>Use of fix wall/piston with undefined lattice</I>
<DD>A lattice must be defined before using this fix.
<DT><I>Use of region with undefined lattice</I>
<DD>If units = lattice (the default) for the region command, then a
lattice must first be defined via the lattice command.
<DT><I>Use of velocity with undefined lattice</I>
<DD>If units = lattice (the default) for the velocity set or velocity ramp
command, then a lattice must first be defined via the lattice command.
<DT><I>Using fix nvt/sllod with inconsistent fix deform remap option</I>
<DD>Fix nvt/sllod requires that deforming atoms have a velocity profile
provided by "remap v" as a fix deform option.
<DT><I>Using fix nvt/sllod with no fix deform defined</I>
<DD>Self-explanatory.
<DT><I>Using fix srd with inconsistent fix deform remap option</I>
<DD>When shearing the box in an SRD simulation, the remap v option for fix
deform needs to be used.
<DT><I>Using pair lubricate with inconsistent fix deform remap option</I>
-<DD>If fix deform is used, the remap v option is required.
+<DD>Must use remap v option with fix deform with this pair style.
<DT><I>Using pair lubricate/poly with inconsistent fix deform remap option</I>
<DD>If fix deform is used, the remap v option is required.
<DT><I>Variable evaluation before simulation box is defined</I>
<DD>Cannot evaluate a compute or fix or atom-based value in a variable
before the simulation has been setup.
<DT><I>Variable for compute ti is invalid style</I>
<DD>Self-explanatory.
<DT><I>Variable for dump every is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for dump image center is invalid style</I>
<DD>Must be an equal-style variable.
<DT><I>Variable for dump image persp is invalid style</I>
<DD>Must be an equal-style variable.
<DT><I>Variable for dump image phi is invalid style</I>
<DD>Must be an equal-style variable.
<DT><I>Variable for dump image theta is invalid style</I>
<DD>Must be an equal-style variable.
<DT><I>Variable for dump image zoom is invalid style</I>
<DD>Must be an equal-style variable.
<DT><I>Variable for fix adapt is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix addforce is invalid style</I>
<DD>Self-explanatory.
<DT><I>Variable for fix aveforce is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix deform is invalid style</I>
<DD>The variable must be an equal-style variable.
<DT><I>Variable for fix efield is invalid style</I>
<DD>Only equal-style variables can be used.
+<DT><I>Variable for fix gravity is invalid style</I>
+
+<DD>Only equal-style variables can be used.
+
<DT><I>Variable for fix indent is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix indent is not equal style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix langevin is invalid style</I>
<DD>It must be an equal-style variable.
<DT><I>Variable for fix move is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix setforce is invalid style</I>
<DD>Only equal-style variables can be used.
+<DT><I>Variable for fix temp/berendsen is invalid style</I>
+
+<DD>Only equal-style variables can be used.
+
+<DT><I>Variable for fix temp/rescale is invalid style</I>
+
+<DD>Only equal-style variables can be used.
+
<DT><I>Variable for fix wall is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix wall/reflect is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for fix wall/srd is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for region is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for region is not equal style</I>
<DD>Self-explanatory.
+<DT><I>Variable for restart is invalid style</I>
+
+<DD>Only equal-style variables can be used.
+
<DT><I>Variable for thermo every is invalid style</I>
<DD>Only equal-style variables can be used.
<DT><I>Variable for velocity set is invalid style</I>
<DD>Only atom-style variables can be used.
<DT><I>Variable formula compute array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Variable formula compute vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Variable formula fix array is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Variable formula fix vector is accessed out-of-range</I>
<DD>Self-explanatory.
<DT><I>Variable name for compute atom/molecule does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for compute reduce does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for compute ti does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for dump every does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for dump image center does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for dump image persp does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for dump image phi does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for dump image theta does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for dump image zoom does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix adapt does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix addforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix ave/atom does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix ave/correlate does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix ave/histo does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix ave/spatial does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix ave/time does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix aveforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix deform does not exist</I>
<DD>Self-explantory.
<DT><I>Variable name for fix efield does not exist</I>
<DD>Self-explanatory.
+<DT><I>Variable name for fix gravity does not exist</I>
+
+<DD>Self-explanatory.
+
<DT><I>Variable name for fix indent does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix langevin does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix move does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix setforce does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix store/state does not exist</I>
<DD>Self-explanatory.
+<DT><I>Variable name for fix temp/berendsen does not exist</I>
+
+<DD>Self-explanatory.
+
+<DT><I>Variable name for fix temp/rescale does not exist</I>
+
+<DD>Self-explanatory.
+
<DT><I>Variable name for fix wall does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix wall/reflect does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for fix wall/srd does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for region does not exist</I>
<DD>Self-explanatory.
+<DT><I>Variable name for restart does not exist</I>
+
+<DD>Self-explanatory.
+
<DT><I>Variable name for thermo every does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name for velocity set does not exist</I>
<DD>Self-explanatory.
<DT><I>Variable name must be alphanumeric or underscore characters</I>
<DD>Self-explanatory.
<DT><I>Velocity command before simulation box is defined</I>
<DD>The velocity command cannot be used before a read_data, read_restart,
or create_box command.
<DT><I>Velocity command with no atoms existing</I>
<DD>A velocity command has been used, but no atoms yet exist.
<DT><I>Velocity ramp in z for a 2d problem</I>
<DD>Self-explanatory.
<DT><I>Velocity temperature ID does not compute temperature</I>
<DD>The compute ID given to the velocity command must compute
temperature.
<DT><I>Verlet/split requires 2 partitions</I>
<DD>See the -partition command-line switch.
<DT><I>Verlet/split requires Rspace partition layout be multiple of Kspace partition layout in each dim</I>
<DD>This is controlled by the processors command.
<DT><I>Verlet/split requires Rspace partition size be multiple of Kspace partition size</I>
<DD>This is so there is an equal number of Rspace processors for every
Kspace processor.
<DT><I>Virial was not tallied on needed timestep</I>
<DD>You are using a thermo keyword that requires potentials to
have tallied the virial, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work.
<DT><I>Wall defined twice in fix wall command</I>
<DD>Self-explanatory.
<DT><I>Wall defined twice in fix wall/reflect command</I>
<DD>Self-explanatory.
<DT><I>Wall defined twice in fix wall/srd command</I>
<DD>Self-explanatory.
+<DT><I>Water H epsilon must be 0.0 for pair style lj/cut/coul/long/tip4p</I>
+
+<DD>This is because LAMMPS does not compute the Lennard-Jones interactions
+with these particles for efficiency reasons.
+
<DT><I>World variable count doesn't match # of partitions</I>
<DD>A world-style variable must specify a number of values equal to the
number of processor partitions.
<DT><I>Write_restart command before simulation box is defined</I>
<DD>The write_restart command cannot be used before a read_data,
read_restart, or create_box command.
<DT><I>Zero-length lattice orient vector</I>
<DD>Self-explanatory.
</DL>
<H4><A NAME = "warn"></A>Warnings:
</H4>
<DL>
<DT><I>Atom with molecule ID = 0 included in compute molecule group</I>
<DD>The group used in a compute command that operates on moleclues
includes atoms with no molecule ID. This is probably not what you
want.
+<DT><I>Both groups in compute group/group have a net charge; the Kspace boundary correction to energy will be non-zero</I>
+
+<DD>Self-explantory.
+
<DT><I>Broken bonds will not alter angles, dihedrals, or impropers</I>
<DD>See the doc page for fix bond/break for more info on this
restriction.
<DT><I>Building an occasional neighobr list when atoms may have moved too far</I>
<DD>This can cause LAMMPS to crash when the neighbor list is built.
The solution is to check for building the regular neighbor lists
more frequently.
+<DT><I>Cannot include log terms without 1/r terms; setting flagHI to 1</I>
+
+<DD>Self-explanatory.
+
+<DT><I>Cannot include log terms without 1/r terms; setting flagHI to 1.</I>
+
+<DD>Self-explanatory.
+
<DT><I>Compute cna/atom cutoff may be too large to find ghost atom neighbors</I>
<DD>The neighbor cutoff used may not encompass enough ghost atoms
to perform this operation correctly.
<DT><I>Computing temperature of portions of rigid bodies</I>
<DD>The group defined by the temperature compute does not encompass all
the atoms in one or more rigid bodies, so the change in
degrees-of-freedom for the atoms in those partial rigid bodies will
not be accounted for.
<DT><I>Created bonds will not create angles, dihedrals, or impropers</I>
<DD>See the doc page for fix bond/create for more info on this
restriction.
<DT><I>Dihedral problem: %d %ld %d %d %d %d</I>
<DD>Conformation of the 4 listed dihedral atoms is extreme; you may want
to check your simulation geometry.
<DT><I>Dump dcd/xtc timestamp may be wrong with fix dt/reset</I>
<DD>If the fix changes the timestep, the dump dcd file will not
reflect the change.
<DT><I>FENE bond too long: %ld %d %d %g</I>
<DD>A FENE bond has stretched dangerously far. It's interaction strength
will be truncated to attempt to prevent the bond from blowing up.
<DT><I>FENE bond too long: %ld %g</I>
<DD>A FENE bond has stretched dangerously far. It's interaction strength
will be truncated to attempt to prevent the bond from blowing up.
<DT><I>Fix GCMC may delete atom with non-zero molecule ID</I>
<DD>This is probably an error, since you should not delete only one atom
of a molecule. The GCMC molecule exchange feature does not yet work.
<DT><I>Fix SRD walls overlap but fix srd overlap not set</I>
<DD>You likely want to set this in your input script.
<DT><I>Fix bond/swap will ignore defined angles</I>
<DD>See the doc page for fix bond/swap for more info on this
restriction.
<DT><I>Fix evaporate may delete atom with non-zero molecule ID</I>
<DD>This is probably an error, since you should not delete only one atom
of a molecule.
<DT><I>Fix move does not update angular momentum</I>
<DD>Atoms store this quantity, but fix move does not (yet) update it.
<DT><I>Fix move does not update quaternions</I>
<DD>Atoms store this quantity, but fix move does not (yet) update it.
<DT><I>Fix recenter should come after all other integration fixes</I>
-<DD>Other fixes may change the position of the center-of-mass, so
+<DD>Other fixes may change the position of the center-of-mass, so
fix recenter should come last.
+<DT><I>Fix shake with rRESPA computes invalid pressures</I>
+
+<DD>This is a known bug in LAMMPS that has not yet been fixed. If you use
+SHAKE with rRESPA and perform a constant volume simulation (e.g. using
+fix npt) this only affects the output pressure, not the dynamics of
+the simulation. If you use SHAKE with rRESPA and perform a constant
+pressure simulation (e.g. using fix npt) then you will be
+equilibrating to the wrong volume.
+
<DT><I>Fix srd SRD moves may trigger frequent reneighboring</I>
<DD>This is because the SRD particles may move long distances.
<DT><I>Fix srd grid size > 1/4 of big particle diameter</I>
<DD>This may cause accuracy problems.
<DT><I>Fix srd particle moved outside valid domain</I>
<DD>This may indicate a problem with your simulation parameters.
<DT><I>Fix srd particles may move > big particle diameter</I>
<DD>This may cause accuracy problems.
<DT><I>Fix srd viscosity < 0.0 due to low SRD density</I>
<DD>This may cause accuracy problems.
<DT><I>Fix thermal/conductivity comes before fix ave/spatial</I>
<DD>The order of these 2 fixes in your input script is such that fix
thermal/conductivity comes first. If you are using fix ave/spatial to
measure the temperature profile induced by fix viscosity, then this
may cause a glitch in the profile since you are averaging immediately
after swaps have occurred. Flipping the order of the 2 fixes
typically helps.
<DT><I>Fix viscosity comes before fix ave/spatial</I>
<DD>The order of these 2 fixes in your input script is such that
fix viscosity comes first. If you are using fix ave/spatial
to measure the velocity profile induced by fix viscosity, then
this may cause a glitch in the profile since you are averaging
immediately after swaps have occurred. Flipping the order
of the 2 fixes typically helps.
<DT><I>Group for fix_modify temp != fix group</I>
<DD>The fix_modify command is specifying a temperature computation that
computes a temperature on a different group of atoms than the fix
itself operates on. This is probably not what you want to do.
<DT><I>Improper problem: %d %ld %d %d %d %d</I>
<DD>Conformation of the 4 listed improper atoms is extreme; you may want
to check your simulation geometry.
<DT><I>Kspace_modify slab param < 2.0 may cause unphysical behavior</I>
<DD>The kspace_modify slab parameter should be larger to insure periodic
grids padded with empty space do not overlap.
<DT><I>Less insertions than requested</I>
<DD>Less atom insertions occurred on this timestep due to the fix pour
command than were scheduled. This is probably because there were too
many overlaps detected.
<DT><I>Lost atoms via change_box: original %ld current %ld</I>
<DD>The command options you have used caused atoms to be lost.
<DT><I>Lost atoms via displace_atoms: original %ld current %ld</I>
<DD>The command options you have used caused atoms to be lost.
<DT><I>Lost atoms: original %ld current %ld</I>
<DD>Lost atoms are checked for each time thermo output is done. See the
thermo_modify lost command for options. Lost atoms usually indicate
bad dynamics, e.g. atoms have been blown far out of the simulation
box, or moved futher than one processor's sub-domain away before
reneighboring.
<DT><I>Mismatch between velocity and compute groups</I>
<DD>The temperature computation used by the velocity command will not be
on the same group of atoms that velocities are being set for.
<DT><I>More than one compute centro/atom</I>
<DD>It is not efficient to use compute centro/atom more than once.
<DT><I>More than one compute cluster/atom</I>
<DD>It is not efficient to use compute cluster/atom more than once.
<DT><I>More than one compute cna/atom defined</I>
<DD>It is not efficient to use compute cna/atom more than once.
<DT><I>More than one compute coord/atom</I>
<DD>It is not efficient to use compute coord/atom more than once.
<DT><I>More than one compute damage/atom</I>
<DD>It is not efficient to use compute ke/atom more than once.
<DT><I>More than one compute ke/atom</I>
<DD>It is not efficient to use compute ke/atom more than once.
<DT><I>More than one fix poems</I>
<DD>It is not efficient to use fix poems more than once.
<DT><I>More than one fix rigid</I>
<DD>It is not efficient to use fix rigid more than once.
<DT><I>New thermo_style command, previous thermo_modify settings will be lost</I>
<DD>If a thermo_style command is used after a thermo_modify command, the
settings changed by the thermo_modify command will be reset to their
default values. This is because the thermo_modify commmand acts on
the currently defined thermo style, and a thermo_style command creates
a new style.
<DT><I>No Kspace calculation with verlet/split</I>
<DD>The 2nd partition performs a kspace calculation so the kspace_style
command must be used.
<DT><I>No fixes defined, atoms won't move</I>
<DD>If you are not using a fix like nve, nvt, npt then atom velocities and
coordinates will not be updated during timestepping.
<DT><I>No joints between rigid bodies, use fix rigid instead</I>
<DD>The bodies defined by fix poems are not connected by joints. POEMS
will integrate the body motion, but it would be more efficient to use
fix rigid.
<DT><I>Not using real units with pair reax</I>
<DD>This is most likely an error, unless you have created your own ReaxFF
parameter file in a different set of units.
<DT><I>One or more atoms are time integrated more than once</I>
<DD>This is probably an error since you typically do not want to
advance the positions or velocities of an atom more than once
per timestep.
<DT><I>One or more compute molecules has atoms not in group</I>
<DD>The group used in a compute command that operates on moleclues does
not include all the atoms in some molecules. This is probably not
what you want.
<DT><I>One or more respa levels compute no forces</I>
<DD>This is computationally inefficient.
<DT><I>Pair COMB charge %.10f with force %.10f hit max barrier</I>
<DD>Something is possibly wrong with your model.
<DT><I>Pair COMB charge %.10f with force %.10f hit min barrier</I>
<DD>Something is possibly wrong with your model.
<DT><I>Pair brownian needs newton pair on for momentum conservation</I>
<DD>Self-explanatory.
<DT><I>Pair dpd needs newton pair on for momentum conservation</I>
<DD>Self-explanatory.
<DT><I>Pair dsmc: num_of_collisions > number_of_A</I>
<DD>Collision model in DSMC is breaking down.
<DT><I>Pair dsmc: num_of_collisions > number_of_B</I>
<DD>Collision model in DSMC is breaking down.
<DT><I>Particle deposition was unsuccessful</I>
<DD>The fix deposit command was not able to insert as many atoms as
needed. The requested volume fraction may be too high, or other atoms
may be in the insertion region.
<DT><I>Reducing PPPM order b/c stencil extends beyond neighbor processor</I>
<DD>LAMMPS is attempting this in order to allow the simulation
to run. It should not effect the PPPM accuracy.
<DT><I>Replacing a fix, but new group != old group</I>
<DD>The ID and style of a fix match for a fix you are changing with a fix
command, but the new group you are specifying does not match the old
group.
<DT><I>Replicating in a non-periodic dimension</I>
<DD>The parameters for a replicate command will cause a non-periodic
dimension to be replicated; this may cause unwanted behavior.
<DT><I>Resetting reneighboring criteria during PRD</I>
<DD>A PRD simulation requires that neigh_modify settings be delay = 0,
every = 1, check = yes. Since these settings were not in place,
LAMMPS changed them and will restore them to their original values
after the PRD simulation.
<DT><I>Resetting reneighboring criteria during TAD</I>
<DD>A TAD simulation requires that neigh_modify settings be delay = 0,
every = 1, check = yes. Since these settings were not in place,
LAMMPS changed them and will restore them to their original values
after the PRD simulation.
<DT><I>Resetting reneighboring criteria during minimization</I>
<DD>Minimization requires that neigh_modify settings be delay = 0, every =
1, check = yes. Since these settings were not in place, LAMMPS
changed them and will restore them to their original values after the
minimization.
<DT><I>Restart file used different # of processors</I>
<DD>The restart file was written out by a LAMMPS simulation running on a
different number of processors. Due to round-off, the trajectories of
your restarted simulation may diverge a little more quickly than if
you ran on the same # of processors.
<DT><I>Restart file used different 3d processor grid</I>
<DD>The restart file was written out by a LAMMPS simulation running on a
different 3d grid of processors. Due to round-off, the trajectories
of your restarted simulation may diverge a little more quickly than if
you ran on the same # of processors.
<DT><I>Restart file used different boundary settings, using restart file values</I>
<DD>Your input script cannot change these restart file settings.
<DT><I>Restart file used different newton bond setting, using restart file value</I>
<DD>The restart file value will override the setting in the input script.
<DT><I>Restart file used different newton pair setting, using input script value</I>
<DD>The input script value will override the setting in the restart file.
<DT><I>Restart file version does not match LAMMPS version</I>
<DD>This may cause problems when reading the restart file.
<DT><I>Restrain problem: %d %ld %d %d %d %d</I>
<DD>Conformation of the 4 listed dihedral atoms is extreme; you may want
to check your simulation geometry.
<DT><I>Running PRD with only one replica</I>
<DD>This is allowed, but you will get no parallel speed-up.
<DT><I>SRD bin shifting turned on due to small lamda</I>
<DD>This is done to try to preserve accuracy.
<DT><I>SRD bin size for fix srd differs from user request</I>
<DD>Fix SRD had to adjust the bin size to fit the simulation box. See the
cubic keyword if you want this message to be an error vs warning.
<DT><I>SRD bins for fix srd are not cubic enough</I>
<DD>The bin shape is not within tolerance of cubic. See the cubic
keyword if you want this message to be an error vs warning.
<DT><I>SRD particle %d started inside big particle %d on step %ld bounce %d</I>
<DD>See the inside keyword if you want this message to be an error vs
warning.
<DT><I>Shake determinant < 0.0</I>
<DD>The determinant of the quadratic equation being solved for a single
cluster specified by the fix shake command is numerically suspect. LAMMPS
will set it to 0.0 and continue.
<DT><I>Should not allow rigid bodies to bounce off relecting walls</I>
<DD>LAMMPS allows this, but their dynamics are not computed correctly.
<DT><I>System is not charge neutral, net charge = %g</I>
<DD>The total charge on all atoms on the system is not 0.0, which
is not valid for Ewald or PPPM.
<DT><I>Table inner cutoff >= outer cutoff</I>
<DD>You specified an inner cutoff for a Coulombic table that is longer
than the global cutoff. Probably not what you wanted.
<DT><I>Temperature for MSST is not for group all</I>
<DD>User-assigned temperature to MSST fix does not compute temperature for
all atoms. Since MSST computes a global pressure, the kinetic energy
contribution from the temperature is assumed to also be for all atoms.
Thus the pressure used by MSST could be inaccurate.
<DT><I>Temperature for NPT is not for group all</I>
<DD>User-assigned temperature to NPT fix does not compute temperature for
all atoms. Since NPT computes a global pressure, the kinetic energy
contribution from the temperature is assumed to also be for all atoms.
Thus the pressure used by NPT could be inaccurate.
<DT><I>Temperature for fix modify is not for group all</I>
<DD>The temperature compute is being used with a pressure calculation
which does operate on group all, so this may be inconsistent.
<DT><I>Temperature for thermo pressure is not for group all</I>
<DD>User-assigned temperature to thermo via the thermo_modify command does
not compute temperature for all atoms. Since thermo computes a global
pressure, the kinetic energy contribution from the temperature is
assumed to also be for all atoms. Thus the pressure printed by thermo
could be inaccurate.
<DT><I>Too many common neighbors in CNA %d times</I>
<DD>More than the maximum # of neighbors was found multiple times. This
was unexpected.
<DT><I>Too many inner timesteps in fix ttm</I>
<DD>Self-explanatory.
<DT><I>Too many neighbors in CNA for %d atoms</I>
<DD>More than the maximum # of neighbors was found multiple times. This
was unexpected.
<DT><I>Use special bonds = 0,1,1 with bond style fene</I>
<DD>Most FENE models need this setting for the special_bonds command.
<DT><I>Use special bonds = 0,1,1 with bond style fene/expand</I>
<DD>Most FENE models need this setting for the special_bonds command.
<DT><I>Using compute temp/deform with inconsistent fix deform remap option</I>
<DD>Fix nvt/sllod assumes deforming atoms have a velocity profile provided
by "remap v" or "remap none" as a fix deform option.
<DT><I>Using compute temp/deform with no fix deform defined</I>
<DD>This is probably an error, since it makes little sense to use
compute temp/deform in this case.
<DT><I>Using fix srd with box deformation but no SRD thermostat</I>
<DD>The deformation will heat the SRD particles so this can
be dangerous.
<DT><I>Using pair tail corrections with nonperiodic system</I>
<DD>This is probably a bogus thing to do, since tail corrections are
computed by integrating the density of a periodic system out to
infinity.
</DL>
</HTML>
diff --git a/doc/Section_errors.txt b/doc/Section_errors.txt
index 4d7bc690c..ebe1f90f1 100644
--- a/doc/Section_errors.txt
+++ b/doc/Section_errors.txt
@@ -1,7488 +1,7755 @@
"Previous Section"_Section_python.html - "LAMMPS WWW Site"_lws -
"LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next
Section"_Section_history.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
12. Errors :h3
This section describes the errors you can encounter when using LAMMPS,
either conceptually, or as printed out by the program.
12.1 "Common problems"_#err_1
12.2 "Reporting bugs"_#err_2
12.3 "Error & warning messages"_#err_3 :all(b)
:line
:line
12.1 Common problems :link(err_1),h4
If two LAMMPS runs do not produce the same answer on different
machines or different numbers of processors, this is typically not a
bug. 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 within a few 100s or few 1000s of timesteps.
However, the statistical properties of the two runs (e.g. average
energy or temperature) should still be the same.
If the "velocity"_velocity.html command is used to set initial atom
velocities, a particular atom can be assigned a different velocity
when the problem is run on a different number of processors or on
different machines. If this happens, the phase space trajectories of
the two simulations will rapidly diverge. See the discussion of the
{loop} option in the "velocity"_velocity.html command for details and
options that avoid this issue.
Similarly, the "create_atoms"_create_atoms.html command generates a
lattice of atoms. For the same physical system, the ordering and
numbering of atoms by atom ID may be different depending on the number
of processors.
Some commands use random number generators which may be setup to
produce different random number streams on each processor and hence
will produce different effects when run on different numbers of
processors. A commonly-used example is the "fix
langevin"_fix_langevin.html command for thermostatting.
A LAMMPS simulation typically has two stages, setup and run. Most
LAMMPS errors are detected at setup time; others like a bond
stretching too far may not occur until the middle of a run.
LAMMPS tries to flag errors and print informative error messages so
you can fix the problem. Of course, LAMMPS cannot figure out your
physics or numerical mistakes, like choosing too big a timestep,
specifying erroneous force field coefficients, or putting 2 atoms on
top of each other! If you run into errors that LAMMPS doesn't catch
that you think it should flag, please send an email to the
"developers"_http://lammps.sandia.gov/authors.html.
If you get an error message about an invalid command in your input
script, you can determine what command is causing the problem by
looking in the log.lammps file or using the "echo command"_echo.html
to see it on the screen. For a given command, LAMMPS expects certain
arguments in a specified order. If you mess this up, LAMMPS will
often flag the error, but it may read a bogus argument and assign a
value that is valid, but not what you wanted. E.g. trying to read the
string "abc" as an integer value and assigning the associated variable
a value of 0.
Generally, LAMMPS will print a message to the screen and logfile and
exit gracefully when it encounters a fatal error. Sometimes it will
print a WARNING to the screen and logfile and continue on; you can
decide if the WARNING is important or not. A WARNING message that is
generated in the middle of a run is only printed to the screen, not to
the logfile, to avoid cluttering up thermodynamic output. If LAMMPS
crashes or hangs without spitting out an error message first then it
could be a bug (see "this section"_#err_2) or one of the following
cases:
LAMMPS runs in the available memory a processor allows to be
allocated. Most reasonable MD runs are compute limited, not memory
limited, so this shouldn't be a bottleneck on most platforms. Almost
all large memory allocations in the code are done via C-style malloc's
which will generate an error message if you run out of memory.
Smaller chunks of memory are allocated via C++ "new" statements. If
you are unlucky you could run out of memory just when one of these
small requests is made, in which case the code will crash or hang (in
parallel), since LAMMPS doesn't trap on those errors.
Illegal arithmetic can cause LAMMPS to run slow or crash. This is
typically due to invalid physics and numerics that your simulation is
computing. If you see wild thermodynamic values or NaN values in your
LAMMPS output, something is wrong with your simulation. If you
suspect this is happening, it is a good idea to print out
thermodynamic info frequently (e.g. every timestep) via the
"thermo"_thermo.html so you can monitor what is happening.
Visualizing the atom movement is also a good idea to insure your model
is behaving as you expect.
In parallel, one way LAMMPS can hang is due to how different MPI
implementations handle buffering of messages. If the code hangs
without an error message, it may be that you need to specify an MPI
setting or two (usually via an environment variable) to enable
buffering or boost the sizes of messages that can be buffered.
:line
12.2 Reporting bugs :link(err_2),h4
If you are confident that you have found a bug in LAMMPS, follow these
steps.
Check the "New features and bug
fixes"_http://lammps.sandia.gov/bug.html section of the "LAMMPS WWW
site"_lws to see if the bug has already been reported or fixed or the
"Unfixed bug"_http://lammps.sandia.gov/unbug.html to see if a fix is
pending.
Check the "mailing list"_http://lammps.sandia.gov/mail.html
to see if it has been discussed before.
If not, send an email to the mailing list describing the problem with
any ideas you have as to what is causing it or where in the code the
problem might be. The developers will ask for more info if needed,
such as an input script or data files.
The most useful thing you can do to help us fix the bug is to isolate
the problem. Run it on the smallest number of atoms and fewest number
of processors and with the simplest input script that reproduces the
bug and try to identify what command or combination of commands is
causing the problem.
As a last resort, you can send an email directly to the
"developers"_http://lammps.sandia.gov/authors.html.
:line
12.3 Error & warning messages :h4,link(err_3)
These are two alphabetic lists of the "ERROR"_#error and
"WARNING"_#warn messages LAMMPS prints out and the reason why. If the
explanation here is not sufficient, the documentation for the
offending command may help.
Error and warning messages also list the source file and line number
where the error was generated. For example, this message
ERROR: Illegal velocity command (velocity.cpp:78)
means that line #78 in the file src/velocity.cpp generated the error.
Looking in the source code may help you figure out what went wrong.
Note that error messages from "user-contributed
packages"_Section_start.html#start_3 are not listed here. If such an
error occurs and is not self-explanatory, you'll need to look in the
source code or contact the author of the package.
Errors: :h4,link(error)
:dlb
{1-3 bond count is inconsistent} :dt
An inconsistency was detected when computing the number of 1-3
neighbors for each atom. This likely means something is wrong with
the bond topologies you have defined. :dd
{1-4 bond count is inconsistent} :dt
An inconsistency was detected when computing the number of 1-4
neighbors for each atom. This likely means something is wrong with
the bond topologies you have defined. :dd
{64-bit atom IDs are not yet supported} :dt
See description of this data type in src/lmptype.h. :dd
{Accelerator sharing is not currently supported on system} :dt
Multiple MPI processes cannot share the accelerator on your
system. For NVIDIA GPUs, see the nvidia-smi command to change this
setting. :dd
{All angle coeffs are not set} :dt
All angle coefficients must be set in the data file or by the
angle_coeff command before running a simulation. :dd
{All bond coeffs are not set} :dt
All bond coefficients must be set in the data file or by the
bond_coeff command before running a simulation. :dd
{All dihedral coeffs are not set} :dt
All dihedral coefficients must be set in the data file or by the
dihedral_coeff command before running a simulation. :dd
{All improper coeffs are not set} :dt
All improper coefficients must be set in the data file or by the
improper_coeff command before running a simulation. :dd
{All masses are not set} :dt
For atom styles that define masses for each atom type, all masses must
be set in the data file or by the mass command before running a
simulation. They must also be set before using the velocity
command. :dd
{All pair coeffs are not set} :dt
All pair coefficients must be set in the data file or by the
pair_coeff command before running a simulation. :dd
+{All read_dump x,y,z fields must be specified for scaled, triclinic coords} :dt
+
+For triclinic boxes and scaled coordinates you must specify all 3 of
+the x,y,z fields, else LAMMPS cannot reconstruct the unscaled
+coordinates. :dd
+
{All universe/uloop variables must have same # of values} :dt
Self-explanatory. :dd
{All variables in next command must be same style} :dt
Self-explanatory. :dd
{Angle atom missing in delete_bonds} :dt
The delete_bonds command cannot find one or more atoms in a particular
angle on a particular processor. The pairwise cutoff is too short or
the atoms are too far apart to make a valid angle. :dd
{Angle atom missing in set command} :dt
The set command cannot find one or more atoms in a particular angle on
a particular processor. The pairwise cutoff is too short or the atoms
are too far apart to make a valid angle. :dd
{Angle atoms %d %d %d missing on proc %d at step %ld} :dt
One or more of 3 atoms needed to compute a particular angle are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the angle has blown apart and an atom is
too far away. :dd
{Angle coeff for hybrid has invalid style} :dt
Angle style hybrid uses another angle style as one of its
coefficients. The angle style used in the angle_coeff command or read
from a restart file is not recognized. :dd
{Angle coeffs are not set} :dt
No angle coefficients have been assigned in the data file or via the
angle_coeff command. :dd
{Angle potential must be defined for SHAKE} :dt
When shaking angles, an angle_style potential must be used. :dd
{Angle style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Angle style hybrid cannot have none as an argument} :dt
Self-explanatory. :dd
{Angle style hybrid cannot use same pair style twice} :dt
Self-explanatory. :dd
{Angle table must range from 0 to 180 degrees} :dt
Self-explanatory. :dd
{Angle table parameters did not set N} :dt
List of angle table parameters must include N setting. :dd
{Angle_coeff command before angle_style is defined} :dt
Coefficients cannot be set in the data file or via the angle_coeff
command until an angle_style has been assigned. :dd
{Angle_coeff command before simulation box is defined} :dt
The angle_coeff command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Angle_coeff command when no angles allowed} :dt
The chosen atom style does not allow for angles to be defined. :dd
{Angle_style command when no angles allowed} :dt
The chosen atom style does not allow for angles to be defined. :dd
{Angles assigned incorrectly} :dt
Angles read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions. :dd
{Angles defined but no angle types} :dt
The data file header lists angles but no angle types. :dd
{Another input script is already being processed} :dt
Cannot attempt to open a 2nd input script, when the original file is
still being processed. :dd
{Append boundary must be shrink/minimum} :dt
The boundary style of the face where atoms are added
-must be of type m (shrink/minimum). :dd
+must be of type m (shrink/minimum). :dd
{Arccos of invalid value in variable formula} :dt
Argument of arccos() must be between -1 and 1. :dd
{Arcsin of invalid value in variable formula} :dt
Argument of arcsin() must be between -1 and 1. :dd
{Assigning ellipsoid parameters to non-ellipsoid atom} :dt
Self-explanatory. :dd
{Assigning line parameters to non-line atom} :dt
Self-explanatory. :dd
{Assigning tri parameters to non-tri atom} :dt
Self-explanatory. :dd
{Atom IDs must be consecutive for velocity create loop all} :dt
Self-explanatory. :dd
{Atom count changed in fix neb} :dt
This is not allowed in a NEB calculation. :dd
{Atom count is inconsistent, cannot write restart file} :dt
Sum of atoms across processors does not equal initial total count.
This is probably because you have lost some atoms. :dd
{Atom in too many rigid bodies - boost MAXBODY} :dt
Fix poems has a parameter MAXBODY (in fix_poems.cpp) which determines
the maximum number of rigid bodies a single atom can belong to (i.e. a
multibody joint). The bodies you have defined exceed this limit. :dd
{Atom sort did not operate correctly} :dt
This is an internal LAMMPS error. Please report it to the
developers. :dd
{Atom sorting has bin size = 0.0} :dt
The neighbor cutoff is being used as the bin size, but it is zero.
Thus you must explicitly list a bin size in the atom_modify sort
command or turn off sorting. :dd
{Atom style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Atom style hybrid cannot use same atom style twice} :dt
Self-explanatory. :dd
{Atom vector in equal-style variable formula} :dt
Atom vectors generate one value per atom which is not allowed
in an equal-style variable. :dd
{Atom-style variable in equal-style variable formula} :dt
Atom-style variables generate one value per atom which is not allowed
in an equal-style variable. :dd
{Atom_modify map command after simulation box is defined} :dt
The atom_modify map command cannot be used after a read_data,
read_restart, or create_box command. :dd
{Atom_modify sort and first options cannot be used together} :dt
Self-explanatory. :dd
{Atom_style command after simulation box is defined} :dt
The atom_style command cannot be used after a read_data,
read_restart, or create_box command. :dd
{Atom_style line can only be used in 2d simulations} :dt
Self-explanatory. :dd
{Atom_style tri can only be used in 3d simulations} :dt
Self-explanatory. :dd
{Attempt to pop empty stack in fix box/relax} :dt
Internal LAMMPS error. Please report it to the developers. :dd
{Attempt to push beyond stack limit in fix box/relax} :dt
Internal LAMMPS error. Please report it to the developers. :dd
{Attempting to rescale a 0.0 temperature} :dt
Cannot rescale a temperature that is already 0.0. :dd
{Bad FENE bond} :dt
Two atoms in a FENE bond have become so far apart that the bond cannot
be computed. :dd
{Bad TIP4P angle type for PPPM/TIP4P} :dt
Specified angle type is not valid. :dd
{Bad TIP4P bond type for PPPM/TIP4P} :dt
Specified bond type is not valid. :dd
{Bad fix ID in fix append/atoms command} :dt
The value of the fix_id for keyword spatial must start with the suffix
f_. :dd
{Bad grid of processors} :dt
The 3d grid of processors defined by the processors command does not
match the number of processors LAMMPS is being run on. :dd
{Bad kspace_modify slab parameter} :dt
Kspace_modify value for the slab/volume keyword must be >= 2.0. :dd
{Bad matrix inversion in mldivide3} :dt
This error should not occur unless the matrix is badly formed. :dd
{Bad principal moments} :dt
Fix rigid did not compute the principal moments of inertia of a rigid
group of atoms correctly. :dd
{Bad quadratic solve for particle/line collision} :dt
This is an internal error. It should nornally not occur. :dd
{Bad quadratic solve for particle/tri collision} :dt
This is an internal error. It should nornally not occur. :dd
{Balance command before simulation box is defined} :dt
The balance command cannot be used before a read_data, read_restart,
or create_box command. :dd
{Balance dynamic string is invalid} :dt
The string can only contain the characters "x", "y", or "z". :dd
-{Balance dynamic string is invalid for 2d simulation} :dt
+{Balance produced bad splits} :dt
-The string cannot contain the letter "z". :dd
+This should not occur. It means two or more cutting plane locations
+are on top of each other or out of order. Report the problem to the
+developers. :dd
{Bias compute does not calculate a velocity bias} :dt
The specified compute must compute a bias for temperature. :dd
{Bias compute does not calculate temperature} :dt
The specified compute must compute temperature. :dd
{Bias compute group does not match compute group} :dt
The specified compute must operate on the same group as the parent
compute. :dd
{Big particle in fix srd cannot be point particle} :dt
Big particles must be extended spheriods or ellipsoids. :dd
{Bigint setting in lmptype.h is invalid} :dt
Size of bigint is less than size of tagint. :dd
{Bigint setting in lmptype.h is not compatible} :dt
Bigint stored in restart file is not consistent with LAMMPS version
you are running. :dd
{Bitmapped lookup tables require int/float be same size} :dt
Cannot use pair tables on this machine, because of word sizes. Use
the pair_modify command with table 0 instead. :dd
{Bitmapped table in file does not match requested table} :dt
Setting for bitmapped table in pair_coeff command must match table
in file exactly. :dd
{Bitmapped table is incorrect length in table file} :dt
Number of table entries is not a correct power of 2. :dd
{Bond and angle potentials must be defined for TIP4P} :dt
Cannot use TIP4P pair potential unless bond and angle potentials
are defined. :dd
+{Bond atom missing in box size check} :dt
+
+The 2nd atoms needed to compute a particular bond is missing on this
+processor. Typically this is because the pairwise cutoff is set too
+short or the bond has blown apart and an atom is too far away. :dd
+
{Bond atom missing in delete_bonds} :dt
The delete_bonds command cannot find one or more atoms in a particular
bond on a particular processor. The pairwise cutoff is too short or
the atoms are too far apart to make a valid bond. :dd
{Bond atom missing in set command} :dt
The set command cannot find one or more atoms in a particular bond on
a particular processor. The pairwise cutoff is too short or the atoms
are too far apart to make a valid bond. :dd
{Bond atoms %d %d missing on proc %d at step %ld} :dt
One or both of 2 atoms needed to compute a particular bond are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the bond has blown apart and an atom is
too far away. :dd
{Bond coeff for hybrid has invalid style} :dt
Bond style hybrid uses another bond style as one of its coefficients.
The bond style used in the bond_coeff command or read from a restart
file is not recognized. :dd
{Bond coeffs are not set} :dt
No bond coefficients have been assigned in the data file or via the
bond_coeff command. :dd
{Bond potential must be defined for SHAKE} :dt
Cannot use fix shake unless bond potential is defined. :dd
{Bond style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Bond style hybrid cannot have none as an argument} :dt
Self-explanatory. :dd
{Bond style hybrid cannot use same pair style twice} :dt
Self-explanatory. :dd
{Bond style quartic cannot be used with 3,4-body interactions} :dt
No angle, dihedral, or improper styles can be defined when using
bond style quartic. :dd
{Bond style quartic requires special_bonds = 1,1,1} :dt
This is a restriction of the current bond quartic implementation. :dd
{Bond table parameters did not set N} :dt
List of bond table parameters must include N setting. :dd
{Bond table values are not increasing} :dt
The values in the tabulated file must be monotonically increasing. :dd
+{Bond/angle/dihedral extent > half of periodic box length} :dt
+
+This is a restriction because LAMMPS can be confused about which image
+of an atom in the bonded interaction is the correct one to use.
+"Extent" in this context means the maximum end-to-end length of the
+bond/angle/dihedral. LAMMPS computes this by taking the maximum bond
+length, multiplying by the number of bonds in the interaction (e.g. 3
+for a dihedral) and adding a small amount of stretch. :dd
+
{Bond_coeff command before bond_style is defined} :dt
Coefficients cannot be set in the data file or via the bond_coeff
command until an bond_style has been assigned. :dd
{Bond_coeff command before simulation box is defined} :dt
The bond_coeff command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Bond_coeff command when no bonds allowed} :dt
The chosen atom style does not allow for bonds to be defined. :dd
{Bond_style command when no bonds allowed} :dt
The chosen atom style does not allow for bonds to be defined. :dd
{Bonds assigned incorrectly} :dt
Bonds read in from the data file were not assigned correctly to atoms.
This means there is something invalid about the topology definitions. :dd
{Bonds defined but no bond types} :dt
The data file header lists bonds but no bond types. :dd
{Both sides of boundary must be periodic} :dt
Cannot specify a boundary as periodic only on the lo or hi side. Must
be periodic on both sides. :dd
{Boundary command after simulation box is defined} :dt
The boundary command cannot be used after a read_data, read_restart,
or create_box command. :dd
{Box bounds are invalid} :dt
The box boundaries specified in the read_data file are invalid. The
lo value must be less than the hi value for all 3 dimensions. :dd
{Can not specify Pxy/Pxz/Pyz in fix box/relax with non-triclinic box} :dt
Only triclinic boxes can be used with off-diagonal pressure components.
See the region prism command for details. :dd
{Can not specify Pxy/Pxz/Pyz in fix nvt/npt/nph with non-triclinic box} :dt
Only triclinic boxes can be used with off-diagonal pressure components.
See the region prism command for details. :dd
{Can only use -plog with multiple partitions} :dt
Self-explanatory. See doc page discussion of command-line switches. :dd
{Can only use -pscreen with multiple partitions} :dt
Self-explanatory. See doc page discussion of command-line switches. :dd
{Can only use NEB with 1-processor replicas} :dt
This is current restriction for NEB as implemented in LAMMPS. :dd
{Can only use TAD with 1-processor replicas for NEB} :dt
This is current restriction for NEB as implemented in LAMMPS. :dd
+{Cannot (yet) use K-space slab correction with compute group/group} :dt
+
+This option is not yet supported. :dd
+
+{Cannot (yet) use Kspace slab correction with compute group/group} :dt
+
+This option is not yet supported. :dd
+
{Cannot (yet) use PPPM with triclinic box} :dt
This feature is not yet supported. :dd
{Cannot add atoms to fix move variable} :dt
Atoms can not be added afterwards to this fix option. :dd
{Cannot append atoms to a triclinic box} :dt
The simulation box must be defined with edges alligned with the
Cartesian axes. :dd
{Cannot balance in z dimension for 2d simulation} :dt
Self-explanatory. :dd
{Cannot change box ortho/triclinic with certain fixes defined} :dt
This is because those fixes store the shape of the box. You need to
use unfix to discard the fix, change the box, then redefine a new
fix. :dd
{Cannot change box ortho/triclinic with dumps defined} :dt
This is because some dumps store the shape of the box. You need to
use undump to discard the dump, change the box, then redefine a new
dump. :dd
{Cannot change box tilt factors for orthogonal box} :dt
Cannot use tilt factors unless the simulation box is non-orthogonal. :dd
{Cannot change box to orthogonal when tilt is non-zero} :dt
Self-explanatory. :dd
{Cannot change box z boundary to nonperiodic for a 2d simulation} :dt
Self-explanatory. :dd
{Cannot change dump_modify every for dump dcd} :dt
The frequency of writing dump dcd snapshots cannot be changed. :dd
{Cannot change dump_modify every for dump xtc} :dt
The frequency of writing dump xtc snapshots cannot be changed. :dd
{Cannot change timestep once fix srd is setup} :dt
This is because various SRD properties depend on the timestep
size. :dd
{Cannot change timestep with fix pour} :dt
This fix pre-computes some values based on the timestep, so it cannot
be changed during a simulation run. :dd
{Cannot change_box after reading restart file with per-atom info} :dt
This is because the restart file info cannot be migrated with the
atoms. You can get around this by performing a 0-timestep run which
will assign the restart file info to actual atoms. :dd
{Cannot change_box in xz or yz for 2d simulation} :dt
Self-explanatory. :dd
{Cannot change_box in z dimension for 2d simulation} :dt
Self-explanatory. :dd
{Cannot compute PPPM G} :dt
LAMMPS failed to compute a valid approximation for the PPPM g_ewald
factor that partitions the computation between real space and k-space. :dd
{Cannot create an atom map unless atoms have IDs} :dt
The simulation requires a mapping from global atom IDs to local atoms,
but the atoms that have been defined have no IDs. :dd
{Cannot create atoms with undefined lattice} :dt
Must use the lattice command before using the create_atoms
command. :dd
{Cannot create/grow a vector/array of pointers for %s} :dt
LAMMPS code is making an illegal call to the templated memory
allocaters, to create a vector or array of pointers. :dd
{Cannot create_atoms after reading restart file with per-atom info} :dt
The per-atom info was stored to be used when by a fix that you
may re-define. If you add atoms before re-defining the fix, then
there will not be a correct amount of per-atom info. :dd
{Cannot create_box after simulation box is defined} :dt
The create_box command cannot be used after a read_data, read_restart,
or create_box command. :dd
{Cannot currently use pair reax with pair hybrid} :dt
This is not yet supported. :dd
{Cannot delete group all} :dt
Self-explanatory. :dd
{Cannot delete group currently used by a compute} :dt
Self-explanatory. :dd
{Cannot delete group currently used by a dump} :dt
Self-explanatory. :dd
{Cannot delete group currently used by a fix} :dt
Self-explanatory. :dd
{Cannot delete group currently used by atom_modify first} :dt
Self-explanatory. :dd
{Cannot displace_atoms after reading restart file with per-atom info} :dt
This is because the restart file info cannot be migrated with the
atoms. You can get around this by performing a 0-timestep run which
will assign the restart file info to actual atoms. :dd
{Cannot do GCMC on atoms in atom_modify first group} :dt
This is a restriction due to the way atoms are organized in a list to
enable the atom_modify first command. :dd
{Cannot dump JPG file} :dt
LAMMPS was not built with the -DLAMMPS_JPEG switch in the Makefile. :dd
{Cannot dump sort on atom IDs with no atom IDs defined} :dt
Self-explanatory. :dd
{Cannot evaporate atoms in atom_modify first group} :dt
This is a restriction due to the way atoms are organized in
a list to enable the atom_modify first command. :dd
{Cannot find delete_bonds group ID} :dt
Group ID used in the delete_bonds command does not exist. :dd
{Cannot have both pair_modify shift and tail set to yes} :dt
These 2 options are contradictory. :dd
{Cannot open -reorder file} :dt
Self-explanatory. :dd
{Cannot open ADP potential file %s} :dt
The specified ADP potential file cannot be opened. Check that the
path and name are correct. :dd
{Cannot open AIREBO potential file %s} :dt
The specified AIREBO potential file cannot be opened. Check that the
path and name are correct. :dd
+{Cannot open BOP potential file %s} :dt
+
+The specified BOP potential file cannot be opened. Check that the
+path and name are correct. :dd
+
{Cannot open COMB potential file %s} :dt
The specified COMB potential file cannot be opened. Check that the
path and name are correct. :dd
{Cannot open EAM potential file %s} :dt
The specified EAM potential file cannot be opened. Check that the
path and name are correct. :dd
{Cannot open EIM potential file %s} :dt
The specified EIM potential file cannot be opened. Check that the
path and name are correct. :dd
+{Cannot open LCBOP potential file %s} :dt
+
+The specified LCBOP potential file cannot be opened. Check that the
+path and name are correct. :dd
+
{Cannot open MEAM potential file %s} :dt
The specified MEAM potential file cannot be opened. Check that the
path and name are correct. :dd
{Cannot open Stillinger-Weber potential file %s} :dt
The specified SW potential file cannot be opened. Check that the path
and name are correct. :dd
{Cannot open Tersoff potential file %s} :dt
The specified Tersoff potential file cannot be opened. Check that the
path and name are correct. :dd
{Cannot open balance output file} :dt
-This error message can only occur if debug options
-are uncommented in src/balance.cpp. :dd
+Self-explanatory. :dd
{Cannot open custom file} :dt
Self-explanatory. :dd
{Cannot open dir to search for restart file} :dt
Using a "*" in the name of the restart file will open the current
directory to search for matching file names. :dd
{Cannot open dump file} :dt
The output file for the dump command cannot be opened. Check that the
path and name are correct. :dd
{Cannot open file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
{Cannot open fix ave/correlate file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
{Cannot open fix ave/histo file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
{Cannot open fix ave/spatial file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
{Cannot open fix ave/time file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
+{Cannot open fix balance output file} :dt
+
+Self-explanatory. :dd
+
{Cannot open fix poems file %s} :dt
The specified file cannot be opened. Check that the path and name are
correct. :dd
{Cannot open fix print file %s} :dt
The output file generated by the fix print command cannot be opened :dd
{Cannot open fix qeq/comb file %s} :dt
The output file for the fix qeq/combs command cannot be opened.
Check that the path and name are correct. :dd
{Cannot open fix reax/bonds file %s} :dt
The output file for the fix reax/bonds command cannot be opened.
Check that the path and name are correct. :dd
+{Cannot open fix rigid infile %s} :dt
+
+The specified file cannot be opened. Check that the path and name are
+correct. :dd
+
{Cannot open fix tmd file %s} :dt
The output file for the fix tmd command cannot be opened. Check that
the path and name are correct. :dd
{Cannot open fix ttm file %s} :dt
The output file for the fix ttm command cannot be opened. Check that
the path and name are correct. :dd
{Cannot open gzipped file} :dt
LAMMPS is attempting to open a gzipped version of the specified file
but was unsuccessful. Check that the path and name are correct. :dd
{Cannot open input script %s} :dt
Self-explanatory. :dd
{Cannot open log.lammps} :dt
The default LAMMPS log file cannot be opened. Check that the
directory you are running in allows for files to be created. :dd
{Cannot open logfile} :dt
The LAMMPS log file named in a command-line argument cannot be opened.
Check that the path and name are correct. :dd
{Cannot open logfile %s} :dt
The LAMMPS log file specified in the input script cannot be opened.
Check that the path and name are correct. :dd
{Cannot open pair_write file} :dt
The specified output file for pair energies and forces cannot be
opened. Check that the path and name are correct. :dd
{Cannot open processors output file} :dt
Self-explanatory. :dd
{Cannot open restart file %s} :dt
Self-explanatory. :dd
{Cannot open screen file} :dt
The screen file specified as a command-line argument cannot be
opened. Check that the directory you are running in allows for files
to be created. :dd
{Cannot open universe log file} :dt
For a multi-partition run, the master log file cannot be opened.
Check that the directory you are running in allows for files to be
created. :dd
{Cannot open universe screen file} :dt
For a multi-partition run, the master screen file cannot be opened.
Check that the directory you are running in allows for files to be
created. :dd
{Cannot read_data after simulation box is defined} :dt
The read_data command cannot be used after a read_data,
read_restart, or create_box command. :dd
{Cannot read_restart after simulation box is defined} :dt
The read_restart command cannot be used after a read_data,
read_restart, or create_box command. :dd
{Cannot redefine variable as a different style} :dt
An equal-style variable can be re-defined but only if it was
originally an equal-style variable. :dd
{Cannot replicate 2d simulation in z dimension} :dt
The replicate command cannot replicate a 2d simulation in the z
dimension. :dd
{Cannot replicate with fixes that store atom quantities} :dt
Either fixes are defined that create and store atom-based vectors or a
restart file was read which included atom-based vectors for fixes.
The replicate command cannot duplicate that information for new atoms.
You should use the replicate command before fixes are applied to the
system. :dd
{Cannot reset timestep with a dynamic region defined} :dt
Dynamic regions (see the region command) have a time dependence.
Thus you cannot change the timestep when one or more of these
are defined. :dd
{Cannot reset timestep with a time-dependent fix defined} :dt
You cannot reset the timestep when a fix that keeps track of elapsed
time is in place. :dd
-{Cannot reset timestep with dump file already written to} :dt
-
-Changing the timestep will confuse when a dump file is written. Use
-the undump command, then restart the dump file. :dd
-
-{Cannot reset timestep with restart file already written} :dt
-
-Changing the timestep will confuse when a restart file is written.
-Use the "restart 0" command to turn off restarts, then start them
-again. :dd
-
{Cannot restart fix rigid/nvt with different # of chains} :dt
This is because the restart file contains per-chain info. :dd
{Cannot run 2d simulation with nonperiodic Z dimension} :dt
Use the boundary command to make the z dimension periodic in order to
run a 2d simulation. :dd
{Cannot set both respa pair and inner/middle/outer} :dt
In the rRESPA integrator, you must compute pairwise potentials either
all together (pair), or in pieces (inner/middle/outer). You can't do
both. :dd
{Cannot set dump_modify flush for dump xtc} :dt
Self-explanatory. :dd
{Cannot set mass for this atom style} :dt
This atom style does not support mass settings for each atom type.
Instead they are defined on a per-atom basis in the data file. :dd
{Cannot set meso_rho for this atom style} :dt
Self-explanatory. :dd
{Cannot set non-zero image flag for non-periodic dimension} :dt
Self-explanatory. :dd
{Cannot set non-zero z velocity for 2d simulation} :dt
Self-explanatory. :dd
{Cannot set quaternion for atom that has none} :dt
Self-explanatory. :dd
{Cannot set respa middle without inner/outer} :dt
In the rRESPA integrator, you must define both a inner and outer
setting in order to use a middle setting. :dd
{Cannot set theta for atom that is not a line} :dt
Self-explanatory. :dd
{Cannot set this attribute for this atom style} :dt
The attribute being set does not exist for the defined atom style. :dd
{Cannot set variable z velocity for 2d simulation} :dt
Self-explanatory. :dd
{Cannot skew triclinic box in z for 2d simulation} :dt
Self-explanatory. :dd
{Cannot use -cuda on without USER-CUDA installed} :dt
The USER-CUDA package must be installed via "make yes-user-cuda"
before LAMMPS is built. :dd
{Cannot use -reorder after -partition} :dt
Self-explanatory. See doc page discussion of command-line switches. :dd
{Cannot use Ewald with 2d simulation} :dt
The kspace style ewald cannot be used in 2d simulations. You can use
2d Ewald in a 3d simulation; see the kspace_modify command. :dd
{Cannot use Ewald with triclinic box} :dt
This feature is not yet supported. :dd
{Cannot use NEB unless atom map exists} :dt
Use the atom_modify command to create an atom map. :dd
{Cannot use NEB with a single replica} :dt
Self-explanatory. :dd
{Cannot use NEB with atom_modify sort enabled} :dt
This is current restriction for NEB implemented in LAMMPS. :dd
{Cannot use PPPM with 2d simulation} :dt
The kspace style pppm cannot be used in 2d simulations. You can use
2d PPPM in a 3d simulation; see the kspace_modify command. :dd
{Cannot use PRD with a time-dependent fix defined} :dt
PRD alters the timestep in ways that will mess up these fixes. :dd
{Cannot use PRD with a time-dependent region defined} :dt
PRD alters the timestep in ways that will mess up these regions. :dd
{Cannot use PRD with atom_modify sort enabled} :dt
This is a current restriction of PRD. You must turn off sorting,
which is enabled by default, via the atom_modify command. :dd
{Cannot use PRD with multi-processor replicas unless atom map exists} :dt
Use the atom_modify command to create an atom map. :dd
{Cannot use TAD unless atom map exists for NEB} :dt
See atom_modify map command to set this. :dd
{Cannot use TAD with a single replica for NEB} :dt
NEB requires multiple replicas. :dd
{Cannot use TAD with atom_modify sort enabled for NEB} :dt
This is a current restriction of NEB. :dd
{Cannot use a damped dynamics min style with fix box/relax} :dt
This is a current restriction in LAMMPS. Use another minimizer
style. :dd
{Cannot use a damped dynamics min style with per-atom DOF} :dt
This is a current restriction in LAMMPS. Use another minimizer
style. :dd
{Cannot use append/atoms in periodic dimension} :dt
The boundary style of the face where atoms are added can not be of
type p (periodic). :dd
{Cannot use compute cluster/atom unless atoms have IDs} :dt
Atom IDs are used to identify clusters. :dd
{Cannot use cwiggle in variable formula between runs} :dt
This is a function of elapsed time. :dd
{Cannot use delete_atoms unless atoms have IDs} :dt
Your atoms do not have IDs, so the delete_atoms command cannot be
used. :dd
{Cannot use delete_bonds with non-molecular system} :dt
Your choice of atom style does not have bonds. :dd
{Cannot use fix GPU with USER-CUDA mode enabled} :dt
You cannot use both the GPU and USER-CUDA packages
together. Use one or the other. :dd
{Cannot use fix TMD unless atom map exists} :dt
Using this fix requires the ability to lookup an atom index, which is
provided by an atom map. An atom map does not exist (by default) for
non-molecular problems. Using the atom_modify map command will force
an atom map to be created. :dd
{Cannot use fix ave/spatial z for 2 dimensional model} :dt
Self-explanatory. :dd
{Cannot use fix bond/break with non-molecular systems} :dt
Self-explanatory. :dd
{Cannot use fix bond/create with non-molecular systems} :dt
Self-explanatory. :dd
{Cannot use fix box/relax on a 2nd non-periodic dimension} :dt
When specifying an off-diagonal pressure component, the 2nd of the two
dimensions must be periodic. E.g. if the xy component is specified,
then the y dimension must be periodic. :dd
{Cannot use fix box/relax on a non-periodic dimension} :dt
When specifying a diagonal pressure component, the dimension must be
periodic. :dd
{Cannot use fix deform on a shrink-wrapped boundary} :dt
The x, y, z options cannot be applied to shrink-wrapped
dimensions. :dd
{Cannot use fix deform tilt on a shrink-wrapped 2nd dim} :dt
This is because the shrink-wrapping will change the value
of the strain implied by the tilt factor. :dd
{Cannot use fix deform trate on a box with zero tilt} :dt
The trate style alters the current strain. :dd
{Cannot use fix enforce2d with 3d simulation} :dt
Self-explanatory. :dd
{Cannot use fix msst without per-type mass defined} :dt
Self-explanatory. :dd
{Cannot use fix npt and fix deform on same component of stress tensor} :dt
This would be changing the same box dimension twice. :dd
{Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension} :dt
When specifying an off-diagonal pressure component, the 2nd of the two
dimensions must be periodic. E.g. if the xy component is specified,
then the y dimension must be periodic. :dd
{Cannot use fix nvt/npt/nph on a non-periodic dimension} :dt
When specifying a diagonal pressure component, the dimension must be
periodic. :dd
{Cannot use fix nvt/npt/nph with both xy dynamics and xy scaling} :dt
Self-explanatory. :dd
{Cannot use fix nvt/npt/nph with both xz dynamics and xz scaling} :dt
Self-explanatory. :dd
{Cannot use fix nvt/npt/nph with both yz dynamics and yz scaling} :dt
Self-explanatory. :dd
{Cannot use fix nvt/npt/nph with xy dynamics when y is non-periodic dimension} :dt
The 2nd dimension in the barostatted tilt factor must be periodic. :dd
{Cannot use fix nvt/npt/nph with xz dynamics when z is non-periodic dimension} :dt
The 2nd dimension in the barostatted tilt factor must be periodic. :dd
{Cannot use fix nvt/npt/nph with yz dynamics when z is non-periodic dimension} :dt
The 2nd dimension in the barostatted tilt factor must be periodic. :dd
{Cannot use fix pour with triclinic box} :dt
This feature is not yet supported. :dd
{Cannot use fix press/berendsen and fix deform on same component of stress tensor} :dt
These commands both change the box size/shape, so you cannot use both
together. :dd
{Cannot use fix press/berendsen on a non-periodic dimension} :dt
Self-explanatory. :dd
{Cannot use fix press/berendsen with triclinic box} :dt
Self-explanatory. :dd
{Cannot use fix reax/bonds without pair_style reax} :dt
Self-explantory. :dd
{Cannot use fix shake with non-molecular system} :dt
Your choice of atom style does not have bonds. :dd
{Cannot use fix ttm with 2d simulation} :dt
This is a current restriction of this fix due to the grid it creates. :dd
{Cannot use fix ttm with triclinic box} :dt
This is a current restriction of this fix due to the grid it creates. :dd
{Cannot use fix wall in periodic dimension} :dt
Self-explanatory. :dd
{Cannot use fix wall zlo/zhi for a 2d simulation} :dt
Self-explanatory. :dd
{Cannot use fix wall/reflect in periodic dimension} :dt
Self-explanatory. :dd
{Cannot use fix wall/reflect zlo/zhi for a 2d simulation} :dt
Self-explanatory. :dd
{Cannot use fix wall/srd in periodic dimension} :dt
Self-explanatory. :dd
{Cannot use fix wall/srd more than once} :dt
Nor is their a need to since multiple walls can be specified
in one command. :dd
{Cannot use fix wall/srd without fix srd} :dt
Self-explanatory. :dd
{Cannot use fix wall/srd zlo/zhi for a 2d simulation} :dt
Self-explanatory. :dd
{Cannot use force/hybrid_neigh with triclinic box} :dt
Self-explanatory. :dd
{Cannot use force/neigh with triclinic box} :dt
This is a current limitation of the GPU implementation
in LAMMPS. :dd
{Cannot use kspace solver on system with no charge} :dt
No atoms in system have a non-zero charge. :dd
{Cannot use lines with fix srd unless overlap is set} :dt
This is because line segements are connected to each other. :dd
{Cannot use neigh_modify exclude with GPU neighbor builds} :dt
This is a current limitation of the GPU implementation
in LAMMPS. :dd
{Cannot use neighbor bins - box size << cutoff} :dt
Too many neighbor bins will be created. This typically happens when
the simulation box is very small in some dimension, compared to the
neighbor cutoff. Use the "nsq" style instead of "bin" style. :dd
{Cannot use newton pair with buck/coul/cut/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with buck/coul/long/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with buck/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with coul/long/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with eam/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with gayberne/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with lj/charmm/coul/long/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with lj/class2/coul/long/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with lj/class2/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with lj/cut/coul/cut/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with lj/cut/coul/long/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with lj/cut/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with lj/expand/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with lj96/cut/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with morse/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with resquared/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with table/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use newton pair with yukawa/gpu pair style} :dt
Self-explanatory. :dd
{Cannot use non-zero forces in an energy minimization} :dt
Fix setforce cannot be used in this manner. Use fix addforce
instead. :dd
{Cannot use nonperiodic boundares with fix ttm} :dt
This fix requires a fully periodic simulation box. :dd
{Cannot use nonperiodic boundaries with Ewald} :dt
For kspace style ewald, all 3 dimensions must have periodic boundaries
unless you use the kspace_modify command to define a 2d slab with a
non-periodic z dimension. :dd
{Cannot use nonperiodic boundaries with PPPM} :dt
For kspace style pppm, all 3 dimensions must have periodic boundaries
unless you use the kspace_modify command to define a 2d slab with a
non-periodic z dimension. :dd
{Cannot use order greater than 8 with pppm/gpu.} :dt
Self-explanatory. :dd
{Cannot use pair hybrid with GPU neighbor builds} :dt
See documentation for fix gpu. :dd
{Cannot use pair tail corrections with 2d simulations} :dt
The correction factors are only currently defined for 3d systems. :dd
{Cannot use processors part command without using partitions} :dt
See the command-line -partition switch. :dd
{Cannot use ramp in variable formula between runs} :dt
This is because the ramp() function is time dependent. :dd
{Cannot use region INF or EDGE when box does not exist} :dt
Regions that extend to the box boundaries can only be used after the
create_box command has been used. :dd
{Cannot use set atom with no atom IDs defined} :dt
Atom IDs are not defined, so they cannot be used to identify an atom. :dd
{Cannot use set mol with no molecule IDs defined} :dt
Self-explanatory. :dd
{Cannot use swiggle in variable formula between runs} :dt
This is a function of elapsed time. :dd
{Cannot use tris with fix srd unless overlap is set} :dt
This is because triangles are connected to each other. :dd
{Cannot use variable energy with constant force in fix addforce} :dt
This is because for constant force, LAMMPS can compute the change
in energy directly. :dd
{Cannot use variable every setting for dump dcd} :dt
The format of DCD dump files requires snapshots be output
at a constant frequency. :dd
{Cannot use variable every setting for dump xtc} :dt
The format of this file requires snapshots at regular intervals. :dd
{Cannot use vdisplace in variable formula between runs} :dt
This is a function of elapsed time. :dd
{Cannot use velocity create loop all unless atoms have IDs} :dt
Atoms in the simulation to do not have IDs, so this style
of velocity creation cannot be performed. :dd
{Cannot use wall in periodic dimension} :dt
Self-explanatory. :dd
{Cannot wiggle and shear fix wall/gran} :dt
Cannot specify both options at the same time. :dd
+{Cannot yet use fix balance with PPPM} :dt
+
+This is a current limitation of LAMMPS. :dd
+
{Cannot zero Langevin force of 0 atoms} :dt
The group has zero atoms, so you cannot request its force
be zeroed. :dd
{Cannot zero momentum of 0 atoms} :dt
The collection of atoms for which momentum is being computed has no
atoms. :dd
{Change_box command before simulation box is defined} :dt
Self-explanatory. :dd
{Change_box volume used incorrectly} :dt
The "dim volume" option must be used immediately following one or two
settings for "dim1 ..." (and optionally "dim2 ...") and must be for a
different dimension, i.e. dim != dim1 and dim != dim2. :dd
{Communicate group != atom_modify first group} :dt
Self-explanatory. :dd
{Compute ID for compute atom/molecule does not exist} :dt
Self-explanatory. :dd
{Compute ID for compute reduce does not exist} :dt
Self-explanatory. :dd
{Compute ID for compute slice does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix ave/atom does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix ave/correlate does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix ave/histo does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix ave/spatial does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix ave/time does not exist} :dt
Self-explanatory. :dd
{Compute ID for fix store/state does not exist} :dt
Self-explanatory. :dd
{Compute ID must be alphanumeric or underscore characters} :dt
Self-explanatory. :dd
{Compute angle/local used when angles are not allowed} :dt
The atom style does not support angles. :dd
{Compute atom/molecule compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Compute atom/molecule compute does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Compute atom/molecule compute does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Compute atom/molecule compute does not calculate per-atom values} :dt
Self-explanatory. :dd
{Compute atom/molecule fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Compute atom/molecule fix does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Compute atom/molecule fix does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Compute atom/molecule fix does not calculate per-atom values} :dt
Self-explanatory. :dd
{Compute atom/molecule requires molecular atom style} :dt
Self-explanatory. :dd
{Compute atom/molecule variable is not atom-style variable} :dt
Self-explanatory. :dd
{Compute bond/local used when bonds are not allowed} :dt
The atom style does not support bonds. :dd
{Compute centro/atom requires a pair style be defined} :dt
This is because the computation of the centro-symmetry values
uses a pairwise neighbor list. :dd
{Compute cluster/atom cutoff is longer than pairwise cutoff} :dt
Cannot identify clusters beyond cutoff. :dd
{Compute cluster/atom requires a pair style be defined} :dt
This is so that the pair style defines a cutoff distance which
is used to find clusters. :dd
{Compute cna/atom cutoff is longer than pairwise cutoff} :dt
Self-explantory. :dd
{Compute cna/atom requires a pair style be defined} :dt
Self-explantory. :dd
{Compute com/molecule requires molecular atom style} :dt
Self-explanatory. :dd
{Compute coord/atom cutoff is longer than pairwise cutoff} :dt
Cannot compute coordination at distances longer than the pair cutoff,
since those atoms are not in the neighbor list. :dd
{Compute coord/atom requires a pair style be defined} :dt
Self-explantory. :dd
{Compute damage/atom requires peridynamic potential} :dt
Damage is a Peridynamic-specific metric. It requires you
to be running a Peridynamics simulation. :dd
{Compute dihedral/local used when dihedrals are not allowed} :dt
The atom style does not support dihedrals. :dd
{Compute does not allow an extra compute or fix to be reset} :dt
This is an internal LAMMPS error. Please report it to the
developers. :dd
{Compute erotate/asphere requires atom style ellipsoid or line or tri} :dt
Self-explanatory. :dd
{Compute erotate/asphere requires extended particles} :dt
This compute cannot be used with point paritlces. :dd
{Compute erotate/sphere requires atom style sphere} :dt
Self-explanatory. :dd
{Compute event/displace has invalid fix event assigned} :dt
This is an internal LAMMPS error. Please report it to the
developers. :dd
{Compute group/group group ID does not exist} :dt
Self-explanatory. :dd
{Compute gyration/molecule requires molecular atom style} :dt
Self-explanatory. :dd
{Compute heat/flux compute ID does not compute ke/atom} :dt
Self-explanatory. :dd
{Compute heat/flux compute ID does not compute pe/atom} :dt
Self-explanatory. :dd
{Compute heat/flux compute ID does not compute stress/atom} :dt
Self-explanatory. :dd
{Compute improper/local used when impropers are not allowed} :dt
The atom style does not support impropers. :dd
{Compute msd/molecule requires molecular atom style} :dt
Self-explanatory. :dd
{Compute nve/asphere requires atom style ellipsoid} :dt
Self-explanatory. :dd
{Compute nvt/nph/npt asphere requires atom style ellipsoid} :dt
Self-explanatory. :dd
{Compute pair must use group all} :dt
Pair styles accumlate energy on all atoms. :dd
{Compute pe must use group all} :dt
Energies computed by potentials (pair, bond, etc) are computed on all
atoms. :dd
{Compute pressure must use group all} :dt
Virial contributions computed by potentials (pair, bond, etc) are
computed on all atoms. :dd
{Compute pressure temperature ID does not compute temperature} :dt
The compute ID assigned to a pressure computation must compute
temperature. :dd
{Compute property/atom for atom property that isn't allocated} :dt
Self-explanatory. :dd
{Compute property/local cannot use these inputs together} :dt
Only inputs that generate the same number of datums can be used
togther. E.g. bond and angle quantities cannot be mixed. :dd
{Compute property/local for property that isn't allocated} :dt
Self-explanatory. :dd
{Compute property/molecule requires molecular atom style} :dt
Self-explanatory. :dd
{Compute rdf requires a pair style be defined} :dt
Self-explanatory. :dd
{Compute reduce compute array is accessed out-of-range} :dt
An index for the array is out of bounds. :dd
{Compute reduce compute calculates global values} :dt
A compute that calculates peratom or local values is required. :dd
{Compute reduce compute does not calculate a local array} :dt
Self-explanatory. :dd
{Compute reduce compute does not calculate a local vector} :dt
Self-explanatory. :dd
{Compute reduce compute does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Compute reduce compute does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Compute reduce fix array is accessed out-of-range} :dt
An index for the array is out of bounds. :dd
{Compute reduce fix calculates global values} :dt
A fix that calculates peratom or local values is required. :dd
{Compute reduce fix does not calculate a local array} :dt
Self-explanatory. :dd
{Compute reduce fix does not calculate a local vector} :dt
Self-explanatory. :dd
{Compute reduce fix does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Compute reduce fix does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Compute reduce replace requires min or max mode} :dt
Self-explanatory. :dd
{Compute reduce variable is not atom-style variable} :dt
Self-explanatory. :dd
{Compute slice compute array is accessed out-of-range} :dt
An index for the array is out of bounds. :dd
{Compute slice compute does not calculate a global array} :dt
Self-explanatory. :dd
{Compute slice compute does not calculate a global vector} :dt
Self-explanatory. :dd
{Compute slice compute does not calculate global vector or array} :dt
Self-explanatory. :dd
{Compute slice compute vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
{Compute slice fix array is accessed out-of-range} :dt
An index for the array is out of bounds. :dd
{Compute slice fix does not calculate a global array} :dt
Self-explanatory. :dd
{Compute slice fix does not calculate a global vector} :dt
Self-explanatory. :dd
{Compute slice fix does not calculate global vector or array} :dt
Self-explanatory. :dd
{Compute slice fix vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
{Compute temp/asphere requires atom style ellipsoid} :dt
Self-explanatory. :dd
{Compute temp/asphere requires extended particles} :dt
This compute cannot be used with point paritlces. :dd
{Compute temp/partial cannot use vz for 2d systemx} :dt
Self-explanatory. :dd
{Compute temp/profile cannot bin z for 2d systems} :dt
Self-explanatory. :dd
{Compute temp/profile cannot use vz for 2d systemx} :dt
Self-explanatory. :dd
{Compute temp/sphere requires atom style sphere} :dt
Self-explanatory. :dd
{Compute ti kspace style does not exist} :dt
Self-explanatory. :dd
{Compute ti pair style does not exist} :dt
Self-explanatory. :dd
{Compute ti tail when pair style does not compute tail corrections} :dt
Self-explanatory. :dd
{Compute used in variable between runs is not current} :dt
Computes cannot be invoked by a variable in between runs. Thus they
must have been evaluated on the last timestep of the previous run in
order for their value(s) to be accessed. See the doc page for the
variable command for more info. :dd
{Compute used in variable thermo keyword between runs is not current} :dt
Some thermo keywords rely on a compute to calculate their value(s).
Computes cannot be invoked by a variable in between runs. Thus they
must have been evaluated on the last timestep of the previous run in
order for their value(s) to be accessed. See the doc page for the
variable command for more info. :dd
{Computed temperature for fix temp/berendsen cannot be 0.0} :dt
Self-explanatory. :dd
{Computed temperature for fix temp/rescale cannot be 0.0} :dt
Cannot rescale the temperature to a new value if the current
temperature is 0.0. :dd
{Could not count initial bonds in fix bond/create} :dt
Could not find one of the atoms in a bond on this processor. :dd
{Could not create 3d FFT plan} :dt
The FFT setup in pppm failed. :dd
{Could not create 3d grid of processors} :dt
The specified constraints did not allow a Px by Py by Pz grid to be
created where Px * Py * Pz = P = total number of processors. :dd
{Could not create 3d remap plan} :dt
The FFT setup in pppm failed. :dd
{Could not create numa grid of processors} :dt
The specified constraints did not allow this style of grid to be
created. Usually this is because the total processor count is not a
multiple of the cores/node or the user specified processor count is >
1 in one of the dimensions. :dd
{Could not create twolevel 3d grid of processors} :dt
The specified constraints did not allow this style of grid to be
created. :dd
{Could not find atom_modify first group ID} :dt
Self-explanatory. :dd
{Could not find change_box group ID} :dt
Group ID used in the change_box command does not exist. :dd
{Could not find compute ID for PRD} :dt
Self-explanatory. :dd
{Could not find compute ID for TAD} :dt
Self-explanatory. :dd
{Could not find compute ID for temperature bias} :dt
Self-explanatory. :dd
{Could not find compute ID to delete} :dt
Self-explanatory. :dd
{Could not find compute displace/atom fix ID} :dt
Self-explanatory. :dd
{Could not find compute event/displace fix ID} :dt
Self-explanatory. :dd
{Could not find compute group ID} :dt
Self-explanatory. :dd
{Could not find compute heat/flux compute ID} :dt
Self-explanatory. :dd
{Could not find compute msd fix ID} :dt
Self-explanatory. :dd
{Could not find compute pressure temperature ID} :dt
The compute ID for calculating temperature does not exist. :dd
{Could not find compute_modify ID} :dt
Self-explanatory. :dd
{Could not find delete_atoms group ID} :dt
Group ID used in the delete_atoms command does not exist. :dd
{Could not find delete_atoms region ID} :dt
Region ID used in the delete_atoms command does not exist. :dd
{Could not find displace_atoms group ID} :dt
Group ID used in the displace_atoms command does not exist. :dd
{Could not find dump custom compute ID} :dt
The compute ID needed by dump custom to compute a per-atom quantity
does not exist. :dd
{Could not find dump custom fix ID} :dt
Self-explanatory. :dd
{Could not find dump custom variable name} :dt
Self-explanatory. :dd
{Could not find dump group ID} :dt
A group ID used in the dump command does not exist. :dd
{Could not find dump local compute ID} :dt
Self-explanatory. :dd
{Could not find dump local fix ID} :dt
Self-explanatory. :dd
{Could not find dump modify compute ID} :dt
Self-explanatory. :dd
{Could not find dump modify fix ID} :dt
Self-explanatory. :dd
{Could not find dump modify variable name} :dt
Self-explanatory. :dd
{Could not find fix ID to delete} :dt
Self-explanatory. :dd
{Could not find fix group ID} :dt
A group ID used in the fix command does not exist. :dd
{Could not find fix msst compute ID} :dt
Self-explanatory. :dd
{Could not find fix poems group ID} :dt
A group ID used in the fix poems command does not exist. :dd
{Could not find fix recenter group ID} :dt
A group ID used in the fix recenter command does not exist. :dd
{Could not find fix rigid group ID} :dt
A group ID used in the fix rigid command does not exist. :dd
{Could not find fix srd group ID} :dt
Self-explanatory. :dd
{Could not find fix_modify ID} :dt
A fix ID used in the fix_modify command does not exist. :dd
{Could not find fix_modify pressure ID} :dt
The compute ID for computing pressure does not exist. :dd
{Could not find fix_modify temperature ID} :dt
The compute ID for computing temperature does not exist. :dd
{Could not find group delete group ID} :dt
Self-explanatory. :dd
{Could not find set group ID} :dt
Group ID specified in set command does not exist. :dd
{Could not find thermo compute ID} :dt
Compute ID specified in thermo_style command does not exist. :dd
{Could not find thermo custom compute ID} :dt
The compute ID needed by thermo style custom to compute a requested
quantity does not exist. :dd
{Could not find thermo custom fix ID} :dt
The fix ID needed by thermo style custom to compute a requested
quantity does not exist. :dd
{Could not find thermo custom variable name} :dt
Self-explanatory. :dd
{Could not find thermo fix ID} :dt
Fix ID specified in thermo_style command does not exist. :dd
{Could not find thermo variable name} :dt
Self-explanatory. :dd
{Could not find thermo_modify pressure ID} :dt
The compute ID needed by thermo style custom to compute pressure does
not exist. :dd
{Could not find thermo_modify temperature ID} :dt
The compute ID needed by thermo style custom to compute temperature does
not exist. :dd
{Could not find undump ID} :dt
A dump ID used in the undump command does not exist. :dd
{Could not find velocity group ID} :dt
A group ID used in the velocity command does not exist. :dd
{Could not find velocity temperature ID} :dt
The compute ID needed by the velocity command to compute temperature
does not exist. :dd
{Could not find/initialize a specified accelerator device} :dt
Could not initialize at least one of the devices specified for the gpu
package :dd
{Could not grab element entry from EIM potential file} :dt
Self-explanatory :dd
{Could not grab global entry from EIM potential file} :dt
Self-explanatory. :dd
{Could not grab pair entry from EIM potential file} :dt
Self-explanatory. :dd
{Coulomb cutoffs of pair hybrid sub-styles do not match} :dt
If using a Kspace solver, all Coulomb cutoffs of long pair styles must
be the same. :dd
{Cound not find dump_modify ID} :dt
Self-explanatory. :dd
{Create_atoms command before simulation box is defined} :dt
The create_atoms command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Create_atoms region ID does not exist} :dt
A region ID used in the create_atoms command does not exist. :dd
{Create_box region ID does not exist} :dt
A region ID used in the create_box command does not exist. :dd
{Create_box region does not support a bounding box} :dt
Not all regions represent bounded volumes. You cannot use
such a region with the create_box command. :dd
{Cyclic loop in joint connections} :dt
Fix poems cannot (yet) work with coupled bodies whose joints connect
the bodies in a ring (or cycle). :dd
{Degenerate lattice primitive vectors} :dt
Invalid set of 3 lattice vectors for lattice command. :dd
{Delete region ID does not exist} :dt
Self-explanatory. :dd
{Delete_atoms command before simulation box is defined} :dt
The delete_atoms command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Delete_atoms cutoff > neighbor cutoff} :dt
Cannot delete atoms further away than a processor knows about. :dd
{Delete_atoms requires a pair style be defined} :dt
This is because atom deletion within a cutoff uses a pairwise
neighbor list. :dd
{Delete_bonds command before simulation box is defined} :dt
The delete_bonds command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Delete_bonds command with no atoms existing} :dt
No atoms are yet defined so the delete_bonds command cannot be used. :dd
{Deposition region extends outside simulation box} :dt
Self-explanatory. :dd
{Did not assign all atoms correctly} :dt
Atoms read in from a data file were not assigned correctly to
processors. This is likely due to some atom coordinates being
outside a non-periodic simulation box. :dd
{Did not find all elements in MEAM library file} :dt
The requested elements were not found in the MEAM file. :dd
{Did not find fix shake partner info} :dt
Could not find bond partners implied by fix shake command. This error
can be triggered if the delete_bonds command was used before fix
shake, and it removed bonds without resetting the 1-2, 1-3, 1-4
weighting list via the special keyword. :dd
{Did not find keyword in table file} :dt
Keyword used in pair_coeff command was not found in table file. :dd
{Did not set temp for fix rigid/nvt} :dt
The temp keyword must be used. :dd
{Dihedral atom missing in delete_bonds} :dt
The delete_bonds command cannot find one or more atoms in a particular
dihedral on a particular processor. The pairwise cutoff is too short
or the atoms are too far apart to make a valid dihedral. :dd
{Dihedral atom missing in set command} :dt
The set command cannot find one or more atoms in a particular dihedral
on a particular processor. The pairwise cutoff is too short or the
atoms are too far apart to make a valid dihedral. :dd
{Dihedral atoms %d %d %d %d missing on proc %d at step %ld} :dt
One or more of 4 atoms needed to compute a particular dihedral are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the dihedral has blown apart and an atom is
too far away. :dd
{Dihedral charmm is incompatible with Pair style} :dt
Dihedral style charmm must be used with a pair style charmm
in order for the 1-4 epsilon/sigma parameters to be defined. :dd
{Dihedral coeff for hybrid has invalid style} :dt
Dihedral style hybrid uses another dihedral style as one of its
coefficients. The dihedral style used in the dihedral_coeff command
or read from a restart file is not recognized. :dd
{Dihedral coeffs are not set} :dt
No dihedral coefficients have been assigned in the data file or via
the dihedral_coeff command. :dd
{Dihedral style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Dihedral style hybrid cannot have none as an argument} :dt
Self-explanatory. :dd
{Dihedral style hybrid cannot use same dihedral style twice} :dt
Self-explanatory. :dd
{Dihedral_coeff command before dihedral_style is defined} :dt
Coefficients cannot be set in the data file or via the dihedral_coeff
command until an dihedral_style has been assigned. :dd
{Dihedral_coeff command before simulation box is defined} :dt
The dihedral_coeff command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Dihedral_coeff command when no dihedrals allowed} :dt
The chosen atom style does not allow for dihedrals to be defined. :dd
{Dihedral_style command when no dihedrals allowed} :dt
The chosen atom style does not allow for dihedrals to be defined. :dd
{Dihedrals assigned incorrectly} :dt
Dihedrals read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions. :dd
{Dihedrals defined but no dihedral types} :dt
The data file header lists dihedrals but no dihedral types. :dd
{Dimension command after simulation box is defined} :dt
The dimension command cannot be used after a read_data,
read_restart, or create_box command. :dd
{Displace_atoms command before simulation box is defined} :dt
The displace_atoms command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Distance must be > 0 for compute event/displace} :dt
Self-explanatory. :dd
{Divide by 0 in influence function of pair peri/lps} :dt
This should not normally occur. It is likely a problem with your
model. :dd
{Divide by 0 in variable formula} :dt
Self-explanatory. :dd
{Domain too large for neighbor bins} :dt
The domain has become extremely large so that neighbor bins cannot be
used. Most likely, one or more atoms have been blown out of the
simulation box to a great distance. :dd
{Double precision is not supported on this accelerator} :dt
Self-explanatory :dd
{Dump cfg arguments can not mix xs|ys|zs with xsu|ysu|zsu} :dt
Self-explanatory. :dd
{Dump cfg arguments must start with 'id type xs ys zs' or 'id type xsu ysu zsu'} :dt
This is a requirement of the CFG output format. :dd
{Dump cfg requires one snapshot per file} :dt
Use the wildcard "*" character in the filename. :dd
{Dump custom and fix not computed at compatible times} :dt
The fix must produce per-atom quantities on timesteps that dump custom
needs them. :dd
{Dump custom compute does not calculate per-atom array} :dt
Self-explanatory. :dd
{Dump custom compute does not calculate per-atom vector} :dt
Self-explanatory. :dd
{Dump custom compute does not compute per-atom info} :dt
Self-explanatory. :dd
{Dump custom compute vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Dump custom fix does not compute per-atom array} :dt
Self-explanatory. :dd
{Dump custom fix does not compute per-atom info} :dt
Self-explanatory. :dd
{Dump custom fix does not compute per-atom vector} :dt
Self-explanatory. :dd
{Dump custom fix vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Dump custom variable is not atom-style variable} :dt
Only atom-style variables generate per-atom quantities, needed for
dump output. :dd
{Dump dcd of non-matching # of atoms} :dt
Every snapshot written by dump dcd must contain the same # of atoms. :dd
{Dump dcd requires sorting by atom ID} :dt
Use the dump_modify sort command to enable this. :dd
{Dump every variable returned a bad timestep} :dt
The variable must return a timestep greater than the current timestep. :dd
+{Dump file does not contain requested snapshot} :dt
+
+Self-explanatory. :dd
+
+{Dump file is incorrectly formatted} :dt
+
+No atoms were found in file. :dd
+
{Dump image bond not allowed with no bond types} :dt
Self-explanatory. :dd
{Dump image cannot perform sorting} :dt
Self-explanatory. :dd
{Dump image persp option is not yet supported} :dt
Self-explanatory. :dd
{Dump image requires one snapshot per file} :dt
Use a "*" in the filename. :dd
{Dump local and fix not computed at compatible times} :dt
The fix must produce per-atom quantities on timesteps that dump local
needs them. :dd
{Dump local attributes contain no compute or fix} :dt
Self-explanatory. :dd
{Dump local cannot sort by atom ID} :dt
This is because dump local does not really dump per-atom info. :dd
{Dump local compute does not calculate local array} :dt
Self-explanatory. :dd
{Dump local compute does not calculate local vector} :dt
Self-explanatory. :dd
{Dump local compute does not compute local info} :dt
Self-explanatory. :dd
{Dump local compute vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Dump local count is not consistent across input fields} :dt
Every column of output must be the same length. :dd
{Dump local fix does not compute local array} :dt
Self-explanatory. :dd
{Dump local fix does not compute local info} :dt
Self-explanatory. :dd
{Dump local fix does not compute local vector} :dt
Self-explanatory. :dd
{Dump local fix vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Dump modify bcolor not allowed with no bond types} :dt
Self-explanatory. :dd
{Dump modify bdiam not allowed with no bond types} :dt
Self-explanatory. :dd
{Dump modify compute ID does not compute per-atom array} :dt
Self-explanatory. :dd
{Dump modify compute ID does not compute per-atom info} :dt
Self-explanatory. :dd
{Dump modify compute ID does not compute per-atom vector} :dt
Self-explanatory. :dd
{Dump modify compute ID vector is not large enough} :dt
Self-explanatory. :dd
{Dump modify element names do not match atom types} :dt
Number of element names must equal number of atom types. :dd
{Dump modify fix ID does not compute per-atom array} :dt
Self-explanatory. :dd
{Dump modify fix ID does not compute per-atom info} :dt
Self-explanatory. :dd
{Dump modify fix ID does not compute per-atom vector} :dt
Self-explanatory. :dd
{Dump modify fix ID vector is not large enough} :dt
Self-explanatory. :dd
{Dump modify variable is not atom-style variable} :dt
Self-explanatory. :dd
{Dump sort column is invalid} :dt
Self-explanatory. :dd
{Dump xtc requires sorting by atom ID} :dt
Use the dump_modify sort command to enable this. :dd
{Dump_modify region ID does not exist} :dt
Self-explanatory. :dd
{Dumping an atom property that isn't allocated} :dt
The chosen atom style does not define the per-atom quantity being
dumped. :dd
{Dumping an atom quantity that isn't allocated} :dt
Only per-atom quantities that are defined for the atom style being
used are allowed. :dd
+{Duplicate fields in read_dump command} :dt
+
+Self-explanatory. :dd
+
{Duplicate particle in PeriDynamic bond - simulation box is too small} :dt
This is likely because your box length is shorter than 2 times
the bond length. :dd
{Electronic temperature dropped below zero} :dt
Something has gone wrong with the fix ttm electron temperature model. :dd
{Empty brackets in variable} :dt
There is no variable syntax that uses empty brackets. Check
the variable doc page. :dd
{Energy was not tallied on needed timestep} :dt
You are using a thermo keyword that requires potentials to
have tallied energy, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work. :dd
{Expected floating point parameter in input script or data file} :dt
The quantity being read is an integer on non-numeric value. :dd
{Expected floating point parameter in variable definition} :dt
The quantity being read is a non-numeric value. :dd
{Expected integer parameter in input script or data file} :dt
The quantity being read is a floating point or non-numeric value. :dd
{Expected integer parameter in variable definition} :dt
The quantity being read is a floating point or non-numeric value. :dd
{Failed to allocate %ld bytes for array %s} :dt
Your LAMMPS simulation has run out of memory. You need to run a
smaller simulation or on more processors. :dd
{Failed to reallocate %ld bytes for array %s} :dt
Your LAMMPS simulation has run out of memory. You need to run a
smaller simulation or on more processors. :dd
{Fewer SRD bins than processors in some dimension} :dt
This is not allowed. Make your SRD bin size smaller. :dd
{Final box dimension due to fix deform is < 0.0} :dt
Self-explanatory. :dd
{Fix GCMC incompatible with given pair_style} :dt
Some pair_styles do not provide single-atom energies, which are needed
by fix GCMC. :dd
{Fix GCMC molecule command requires atom attribute molecule} :dt
Should not choose the GCMC molecule feature if no molecules are being
simulated. The general molecule flag is off, but GCMC's molecule flag
is on. :dd
{Fix GCMC molecule feature does not yet work} :dt
Fix GCMC cannot (yet) be used to exchange molecules, only atoms. :dd
{Fix GPU split must be positive for hybrid pair styles} :dt
Self-explanatory. :dd
{Fix ID for compute atom/molecule does not exist} :dt
Self-explanatory. :dd
{Fix ID for compute reduce does not exist} :dt
Self-explanatory. :dd
{Fix ID for compute slice does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix ave/atom does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix ave/correlate does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix ave/histo does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix ave/spatial does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix ave/time does not exist} :dt
Self-explanatory. :dd
{Fix ID for fix store/state does not exist} :dt
Self-explanatory :dd
+{Fix ID for read_data does not exist} :dt
+
+Self-explanatory. :dd
+
{Fix ID must be alphanumeric or underscore characters} :dt
Self-explanatory. :dd
{Fix SRD no-slip requires atom attribute torque} :dt
This is because the SRD collisions will impart torque to the solute
particles. :dd
{Fix SRD: bad bin assignment for SRD advection} :dt
Something has gone wrong in your SRD model; try using more
conservative settings. :dd
{Fix SRD: bad search bin assignment} :dt
Something has gone wrong in your SRD model; try using more
conservative settings. :dd
{Fix SRD: bad stencil bin for big particle} :dt
Something has gone wrong in your SRD model; try using more
conservative settings. :dd
{Fix SRD: too many big particles in bin} :dt
Reset the ATOMPERBIN parameter at the top of fix_srd.cpp
to a larger value, and re-compile the code. :dd
{Fix SRD: too many walls in bin} :dt
This should not happen unless your system has been setup incorrectly. :dd
{Fix adapt kspace style does not exist} :dt
Self-explanatory. :dd
{Fix adapt pair style does not exist} :dt
Self-explanatory :dd
{Fix adapt pair style param not supported} :dt
The pair style does not know about the parameter you specified. :dd
{Fix adapt requires atom attribute diameter} :dt
The atom style being used does not specify an atom diameter. :dd
{Fix adapt type pair range is not valid for pair hybrid sub-style} :dt
Self-explanatory. :dd
{Fix ave/atom compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/atom compute does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/atom compute does not calculate a per-atom vector} :dt
A compute used by fix ave/atom must generate per-atom values. :dd
{Fix ave/atom compute does not calculate per-atom values} :dt
A compute used by fix ave/atom must generate per-atom values. :dd
{Fix ave/atom fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/atom fix does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/atom fix does not calculate a per-atom vector} :dt
A fix used by fix ave/atom must generate per-atom values. :dd
{Fix ave/atom fix does not calculate per-atom values} :dt
A fix used by fix ave/atom must generate per-atom values. :dd
+{Fix ave/atom missed timestep} :dt
+
+You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging. :dd
+
{Fix ave/atom variable is not atom-style variable} :dt
A variable used by fix ave/atom must generate per-atom values. :dd
{Fix ave/correlate compute does not calculate a scalar} :dt
Self-explanatory. :dd
{Fix ave/correlate compute does not calculate a vector} :dt
Self-explanatory. :dd
{Fix ave/correlate compute vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
{Fix ave/correlate fix does not calculate a scalar} :dt
Self-explanatory. :dd
{Fix ave/correlate fix does not calculate a vector} :dt
Self-explanatory. :dd
{Fix ave/correlate fix vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
+{Fix ave/correlate missed timestep} :dt
+
+You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging. :dd
+
{Fix ave/correlate variable is not equal-style variable} :dt
Self-explanatory. :dd
{Fix ave/histo cannot input local values in scalar mode} :dt
Self-explanatory. :dd
{Fix ave/histo cannot input per-atom values in scalar mode} :dt
Self-explanatory. :dd
{Fix ave/histo compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a global array} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a global scalar} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a global vector} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a local array} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a local vector} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate local values} :dt
Self-explanatory. :dd
{Fix ave/histo compute does not calculate per-atom values} :dt
Self-explanatory. :dd
{Fix ave/histo compute vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/histo fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a global array} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a global scalar} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a global vector} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a local array} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a local vector} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate a per-atom vector} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate local values} :dt
Self-explanatory. :dd
{Fix ave/histo fix does not calculate per-atom values} :dt
Self-explanatory. :dd
{Fix ave/histo fix vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix ave/histo input is invalid compute} :dt
Self-explanatory. :dd
{Fix ave/histo input is invalid fix} :dt
Self-explanatory. :dd
{Fix ave/histo input is invalid variable} :dt
Self-explanatory. :dd
{Fix ave/histo inputs are not all global, peratom, or local} :dt
All inputs in a single fix ave/histo command must be of the
same style. :dd
+{Fix ave/histo missed timestep} :dt
+
+You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging. :dd
+
{Fix ave/spatial compute does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/spatial compute does not calculate a per-atom vector} :dt
A compute used by fix ave/spatial must generate per-atom values. :dd
{Fix ave/spatial compute does not calculate per-atom values} :dt
A compute used by fix ave/spatial must generate per-atom values. :dd
{Fix ave/spatial compute vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
{Fix ave/spatial fix does not calculate a per-atom array} :dt
Self-explanatory. :dd
{Fix ave/spatial fix does not calculate a per-atom vector} :dt
A fix used by fix ave/spatial must generate per-atom values. :dd
{Fix ave/spatial fix does not calculate per-atom values} :dt
A fix used by fix ave/spatial must generate per-atom values. :dd
{Fix ave/spatial fix vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
{Fix ave/spatial for triclinic boxes requires units reduced} :dt
Self-explanatory. :dd
+{Fix ave/spatial missed timestep} :dt
+
+You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging. :dd
+
{Fix ave/spatial settings invalid with changing box} :dt
If the ave setting is "running" or "window" and the box size/shape
changes during the simulation, then the units setting must be
"reduced", else the number of bins may change. :dd
{Fix ave/spatial variable is not atom-style variable} :dt
A variable used by fix ave/spatial must generate per-atom values. :dd
{Fix ave/time cannot set output array intensive/extensive from these inputs} :dt
One of more of the vector inputs has individual elements which are
flagged as intensive or extensive. Such an input cannot be flagged as
all intensive/extensive when turned into an array by fix ave/time. :dd
{Fix ave/time cannot use variable with vector mode} :dt
Variables produce scalar values. :dd
{Fix ave/time columns are inconsistent lengths} :dt
Self-explanatory. :dd
{Fix ave/time compute array is accessed out-of-range} :dt
An index for the array is out of bounds. :dd
{Fix ave/time compute does not calculate a scalar} :dt
Self-explantory. :dd
{Fix ave/time compute does not calculate a vector} :dt
Self-explantory. :dd
{Fix ave/time compute does not calculate an array} :dt
Self-explanatory. :dd
{Fix ave/time compute vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
{Fix ave/time fix array is accessed out-of-range} :dt
An index for the array is out of bounds. :dd
{Fix ave/time fix does not calculate a scalar} :dt
Self-explanatory. :dd
{Fix ave/time fix does not calculate a vector} :dt
Self-explanatory. :dd
{Fix ave/time fix does not calculate an array} :dt
Self-explanatory. :dd
{Fix ave/time fix vector is accessed out-of-range} :dt
The index for the vector is out of bounds. :dd
+{Fix ave/time missed timestep} :dt
+
+You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging. :dd
+
{Fix ave/time variable is not equal-style variable} :dt
Self-explanatory. :dd
{Fix balance string is invalid} :dt
The string can only contain the characters "x", "y", or "z". :dd
{Fix balance string is invalid for 2d simulation} :dt
The string cannot contain the letter "z". :dd
{Fix bond/break requires special_bonds = 0,1,1} :dt
This is a restriction of the current fix bond/break implementation. :dd
{Fix bond/create cutoff is longer than pairwise cutoff} :dt
This is not allowed because bond creation is done using the
pairwise neighbor list. :dd
{Fix bond/create requires special_bonds coul = 0,1,1} :dt
Self-explanatory. :dd
{Fix bond/create requires special_bonds lj = 0,1,1} :dt
Self-explanatory. :dd
{Fix bond/swap cannot use dihedral or improper styles} :dt
These styles cannot be defined when using this fix. :dd
{Fix bond/swap requires pair and bond styles} :dt
Self-explanatory. :dd
{Fix bond/swap requires special_bonds = 0,1,1} :dt
Self-explanatory. :dd
{Fix box/relax generated negative box length} :dt
The pressure being applied is likely too large. Try applying
it incrementally, to build to the high pressure. :dd
{Fix command before simulation box is defined} :dt
The fix command cannot be used before a read_data, read_restart, or
create_box command. :dd
{Fix deform cannot use yz variable with xy} :dt
The yz setting cannot be a variable if xy deformation is also
specified. This is because LAMMPS cannot determine if the yz setting
will induce a box flip which would be invalid if xy is also changing. :dd
{Fix deform is changing yz too much with xy} :dt
When both yz and xy are changing, it induces changes in xz if the
box must flip from one tilt extreme to another. Thus it is not
allowed for yz to grow so much that a flip is induced. :dd
{Fix deform tilt factors require triclinic box} :dt
Cannot deform the tilt factors of a simulation box unless it
is a triclinic (non-orthogonal) box. :dd
{Fix deform volume setting is invalid} :dt
Cannot use volume style unless other dimensions are being controlled. :dd
{Fix deposit region cannot be dynamic} :dt
Only static regions can be used with fix deposit. :dd
{Fix deposit region does not support a bounding box} :dt
Not all regions represent bounded volumes. You cannot use
such a region with the fix deposit command. :dd
{Fix efield requires atom attribute q} :dt
Self-explanatory. :dd
{Fix evaporate molecule requires atom attribute molecule} :dt
The atom style being used does not define a molecule ID. :dd
{Fix external callback function not set} :dt
This must be done by an external program in order to use this fix. :dd
{Fix for fix ave/atom not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix ave/atom is
requesting a value on a non-allowed timestep. :dd
{Fix for fix ave/correlate not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix ave/correlate
is requesting a value on a non-allowed timestep. :dd
{Fix for fix ave/histo not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix ave/histo is
requesting a value on a non-allowed timestep. :dd
{Fix for fix ave/spatial not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix ave/spatial is
requesting a value on a non-allowed timestep. :dd
{Fix for fix ave/time not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix ave/time
is requesting a value on a non-allowed timestep. :dd
{Fix for fix store/state not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Fix store/state
is requesting a value on a non-allowed timestep. :dd
{Fix freeze requires atom attribute torque} :dt
The atom style defined does not have this attribute. :dd
{Fix heat group has no atoms} :dt
Self-explanatory. :dd
{Fix heat kinetic energy went negative} :dt
This will cause the velocity rescaling about to be performed by fix
heat to be invalid. :dd
{Fix in variable not computed at compatible time} :dt
Fixes generate their values on specific timesteps. The variable is
requesting the values on a non-allowed timestep. :dd
{Fix langevin angmom requires atom style ellipsoid} :dt
Self-explanatory. :dd
{Fix langevin angmom requires extended particles} :dt
This fix option cannot be used with point paritlces. :dd
{Fix langevin omega requires atom style sphere} :dt
Self-explanatory. :dd
{Fix langevin omega requires extended particles} :dt
One of the particles has radius 0.0. :dd
{Fix langevin period must be > 0.0} :dt
The time window for temperature relaxation must be > 0 :dd
{Fix langevin variable returned negative temperature} :dt
Self-explanatory. :dd
{Fix momentum group has no atoms} :dt
Self-explanatory. :dd
{Fix move cannot define z or vz variable for 2d problem} :dt
Self-explanatory. :dd
{Fix move cannot have 0 length rotation vector} :dt
Self-explanatory. :dd
{Fix move cannot rotate aroung non z-axis for 2d problem} :dt
Self-explanatory. :dd
{Fix move cannot set linear z motion for 2d problem} :dt
Self-explanatory. :dd
{Fix move cannot set wiggle z motion for 2d problem} :dt
Self-explanatory. :dd
{Fix msst compute ID does not compute potential energy} :dt
Self-explanatory. :dd
{Fix msst compute ID does not compute pressure} :dt
Self-explanatory. :dd
{Fix msst compute ID does not compute temperature} :dt
Self-explanatory. :dd
{Fix msst requires a periodic box} :dt
Self-explanatory. :dd
{Fix msst tscale must satisfy 0 <= tscale < 1} :dt
Self-explanatory. :dd
{Fix npt/nph has tilted box too far in one step - periodic cell is too far from equilibrium state} :dt
Self-explanatory. The change in the box tilt is too extreme
on a short timescale. :dd
{Fix nve/asphere requires extended particles} :dt
This fix can only be used for particles with a shape setting. :dd
{Fix nve/asphere/noforce requires atom style ellipsoid} :dt
Self-explanatory. :dd
{Fix nve/asphere/noforce requires extended particles} :dt
One of the particles is not an ellipsoid. :dd
{Fix nve/line can only be used for 2d simulations} :dt
Self-explanatory. :dd
{Fix nve/line requires atom style line} :dt
Self-explanatory. :dd
{Fix nve/line requires line particles} :dt
Self-explanatory. :dd
{Fix nve/sphere requires atom attribute mu} :dt
An atom style with this attribute is needed. :dd
{Fix nve/sphere requires atom style sphere} :dt
Self-explanatory. :dd
{Fix nve/sphere requires extended particles} :dt
This fix can only be used for particles of a finite size. :dd
{Fix nve/tri can only be used for 3d simulations} :dt
Self-explanatory. :dd
{Fix nve/tri requires atom style tri} :dt
Self-explanatory. :dd
{Fix nve/tri requires tri particles} :dt
Self-explanatory. :dd
{Fix nvt/nph/npt asphere requires extended particles} :dt
The shape setting for a particle in the fix group has shape = 0.0,
which means it is a point particle. :dd
{Fix nvt/nph/npt sphere requires atom style sphere} :dt
Self-explanatory. :dd
{Fix nvt/npt/nph damping parameters must be > 0.0} :dt
Self-explanatory. :dd
+{Fix nvt/npt/nph dilate group ID does not exist} :dt
+
+Self-explanatory. :dd
+
{Fix nvt/sphere requires extended particles} :dt
This fix can only be used for particles of a finite size. :dd
{Fix orient/fcc file open failed} :dt
The fix orient/fcc command could not open a specified file. :dd
{Fix orient/fcc file read failed} :dt
The fix orient/fcc command could not read the needed parameters from a
specified file. :dd
{Fix orient/fcc found self twice} :dt
The neighbor lists used by fix orient/fcc are messed up. If this
error occurs, it is likely a bug, so send an email to the
"developers"_http://lammps.sandia.gov/authors.html. :dd
{Fix peri neigh does not exist} :dt
Somehow a fix that the pair style defines has been deleted. :dd
{Fix pour region ID does not exist} :dt
Self-explanatory. :dd
{Fix pour region cannot be dynamic} :dt
Only static regions can be used with fix pour. :dd
{Fix pour region does not support a bounding box} :dt
Not all regions represent bounded volumes. You cannot use
such a region with the fix pour command. :dd
{Fix pour requires atom attributes radius, rmass} :dt
The atom style defined does not have these attributes. :dd
{Fix press/berendsen damping parameters must be > 0.0} :dt
Self-explanatory. :dd
{Fix qeq/comb group has no atoms} :dt
Self-explanatory. :dd
{Fix qeq/comb requires atom attribute q} :dt
An atom style with charge must be used to perform charge equilibration. :dd
{Fix reax/bonds numbonds > nsbmax_most} :dt
The limit of the number of bonds expected by the ReaxFF force field
was exceeded. :dd
{Fix recenter group has no atoms} :dt
Self-explanatory. :dd
{Fix restrain requires an atom map, see atom_modify} :dt
Self-explanatory. :dd
{Fix rigid atom has non-zero image flag in a non-periodic dimension} :dt
You cannot set image flags for non-periodic dimensions. :dd
{Fix rigid langevin period must be > 0.0} :dt
Self-explanatory. :dd
{Fix rigid molecule requires atom attribute molecule} :dt
Self-explanatory. :dd
{Fix rigid xy torque cannot be on for 2d simulation} :dt
Self-explanatory. :dd
{Fix rigid z force cannot be on for 2d simulation} :dt
Self-explanatory. :dd
{Fix rigid/nvt period must be > 0.0} :dt
Self-explanatory :dd
{Fix rigid: Bad principal moments} :dt
The principal moments of inertia computed for a rigid body
are not within the required tolerances. :dd
{Fix shake cannot be used with minimization} :dt
Cannot use fix shake while doing an energy minimization since
it turns off bonds that should contribute to the energy. :dd
{Fix spring couple group ID does not exist} :dt
Self-explanatory. :dd
{Fix srd lamda must be >= 0.6 of SRD grid size} :dt
This is a requirement for accuracy reasons. :dd
{Fix srd requires SRD particles all have same mass} :dt
Self-explanatory. :dd
{Fix srd requires ghost atoms store velocity} :dt
Use the communicate vel yes command to enable this. :dd
{Fix srd requires newton pair on} :dt
Self-explanatory. :dd
{Fix store/state compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix store/state compute does not calculate a per-atom array} :dt
The compute calculates a per-atom vector. :dd
{Fix store/state compute does not calculate a per-atom vector} :dt
The compute calculates a per-atom vector. :dd
{Fix store/state compute does not calculate per-atom values} :dt
Computes that calculate global or local quantities cannot be used
with fix store/state. :dd
{Fix store/state fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Fix store/state fix does not calculate a per-atom array} :dt
The fix calculates a per-atom vector. :dd
{Fix store/state fix does not calculate a per-atom vector} :dt
The fix calculates a per-atom array. :dd
{Fix store/state fix does not calculate per-atom values} :dt
Fixes that calculate global or local quantities cannot be used with
fix store/state. :dd
{Fix store/state for atom property that isn't allocated} :dt
Self-explanatory. :dd
{Fix store/state variable is not atom-style variable} :dt
Only atom-style variables calculate per-atom quantities. :dd
{Fix temp/berendsen period must be > 0.0} :dt
Self-explanatory. :dd
+{Fix temp/berendsen variable returned negative temperature} :dt
+
+Self-explanatory. :dd
+
+{Fix temp/rescale variable returned negative temperature} :dt
+
+Self-explanatory. :dd
+
{Fix thermal/conductivity swap value must be positive} :dt
Self-explanatory. :dd
{Fix tmd must come after integration fixes} :dt
Any fix tmd command must appear in the input script after all time
integration fixes (nve, nvt, npt). See the fix tmd documentation for
details. :dd
{Fix ttm electron temperatures must be > 0.0} :dt
Self-explanatory. :dd
{Fix ttm electronic_density must be > 0.0} :dt
Self-explanatory. :dd
{Fix ttm electronic_specific_heat must be > 0.0} :dt
Self-explanatory. :dd
{Fix ttm electronic_thermal_conductivity must be >= 0.0} :dt
Self-explanatory. :dd
{Fix ttm gamma_p must be > 0.0} :dt
Self-explanatory. :dd
{Fix ttm gamma_s must be >= 0.0} :dt
Self-explanatory. :dd
{Fix ttm number of nodes must be > 0} :dt
Self-explanatory. :dd
{Fix ttm v_0 must be >= 0.0} :dt
Self-explanatory. :dd
{Fix used in compute atom/molecule not computed at compatible time} :dt
The fix must produce per-atom quantities on timesteps that the compute
needs them. :dd
{Fix used in compute reduce not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Compute reduce is
requesting a value on a non-allowed timestep. :dd
{Fix used in compute slice not computed at compatible time} :dt
Fixes generate their values on specific timesteps. Compute slice is
requesting a value on a non-allowed timestep. :dd
{Fix viscosity swap value must be positive} :dt
Self-explanatory. :dd
{Fix viscosity vtarget value must be positive} :dt
Self-explanatory. :dd
{Fix wall cutoff <= 0.0} :dt
Self-explanatory. :dd
{Fix wall/colloid requires atom style sphere} :dt
Self-explanatory. :dd
{Fix wall/colloid requires extended particles} :dt
One of the particles has radius 0.0. :dd
{Fix wall/gran is incompatible with Pair style} :dt
Must use a granular pair style to define the parameters needed for
this fix. :dd
{Fix wall/gran requires atom style sphere} :dt
Self-explanatory. :dd
{Fix wall/piston command only available at zlo} :dt
The face keyword must be zlo. :dd
{Fix wall/region colloid requires atom style sphere} :dt
Self-explanatory. :dd
{Fix wall/region colloid requires extended particles} :dt
One of the particles has radius 0.0. :dd
{Fix wall/region cutoff <= 0.0} :dt
Self-explanatory. :dd
{Fix_modify order must be 3 or 5} :dt
Self-explanatory. :dd
{Fix_modify pressure ID does not compute pressure} :dt
The compute ID assigned to the fix must compute pressure. :dd
{Fix_modify temperature ID does not compute temperature} :dt
The compute ID assigned to the fix must compute temperature. :dd
{For triclinic deformation, specified target stress must be hydrostatic} :dt
Triclinic pressure control is allowed using the tri keyword, but
non-hydrostatic pressure control can not be used in this case. :dd
{Found no restart file matching pattern} :dt
When using a "*" in the restart file name, no matching file was found. :dd
{GPU library not compiled for this accelerator} :dt
Self-explanatory. :dd
{GPU particle split must be set to 1 for this pair style.} :dt
For this pair style, you cannot run part of the force calculation on
the host. See the package command. :dd
{Gmask function in equal-style variable formula} :dt
Gmask is per-atom operation. :dd
{Gravity changed since fix pour was created} :dt
Gravity must be static and not dynamic for use with fix pour. :dd
{Gravity must point in -y to use with fix pour in 2d} :dt
Gravity must be pointing "down" in a 2d box. :dd
{Gravity must point in -z to use with fix pour in 3d} :dt
Gravity must be pointing "down" in a 3d box, i.e. theta = 180.0. :dd
{Grmask function in equal-style variable formula} :dt
Grmask is per-atom operation. :dd
{Group ID does not exist} :dt
A group ID used in the group command does not exist. :dd
{Group ID in variable formula does not exist} :dt
Self-explanatory. :dd
{Group command before simulation box is defined} :dt
The group command cannot be used before a read_data, read_restart, or
create_box command. :dd
{Group region ID does not exist} :dt
A region ID used in the group command does not exist. :dd
+{If read_dump purges it cannot replace or trim} :dt
+
+These operations are not compatible. See the read_dump doc
+page for details. :dd
+
{Illegal ... command} :dt
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line. :dd
{Illegal COMB parameter} :dt
One or more of the coefficients defined in the potential file is
invalid. :dd
{Illegal Stillinger-Weber parameter} :dt
One or more of the coefficients defined in the potential file is
invalid. :dd
{Illegal Tersoff parameter} :dt
One or more of the coefficients defined in the potential file is
invalid. :dd
{Illegal fix wall/piston velocity} :dt
The piston velocity must be positive. :dd
{Illegal integrate style} :dt
Self-explanatory. :dd
{Illegal number of angle table entries} :dt
There must be at least 2 table entries. :dd
{Illegal number of bond table entries} :dt
There must be at least 2 table entries. :dd
{Illegal number of pair table entries} :dt
There must be at least 2 table entries. :dd
{Illegal simulation box} :dt
The lower bound of the simulation box is greater than the upper bound. :dd
{Improper atom missing in delete_bonds} :dt
The delete_bonds command cannot find one or more atoms in a particular
improper on a particular processor. The pairwise cutoff is too short
or the atoms are too far apart to make a valid improper. :dd
{Improper atom missing in set command} :dt
The set command cannot find one or more atoms in a particular improper
on a particular processor. The pairwise cutoff is too short or the
atoms are too far apart to make a valid improper. :dd
{Improper atoms %d %d %d %d missing on proc %d at step %ld} :dt
One or more of 4 atoms needed to compute a particular improper are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the improper has blown apart and an atom is
too far away. :dd
{Improper coeff for hybrid has invalid style} :dt
Improper style hybrid uses another improper style as one of its
coefficients. The improper style used in the improper_coeff command
or read from a restart file is not recognized. :dd
{Improper coeffs are not set} :dt
No improper coefficients have been assigned in the data file or via
the improper_coeff command. :dd
{Improper style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Improper style hybrid cannot have none as an argument} :dt
Self-explanatory. :dd
{Improper style hybrid cannot use same improper style twice} :dt
Self-explanatory. :dd
{Improper_coeff command before improper_style is defined} :dt
Coefficients cannot be set in the data file or via the improper_coeff
command until an improper_style has been assigned. :dd
{Improper_coeff command before simulation box is defined} :dt
The improper_coeff command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Improper_coeff command when no impropers allowed} :dt
The chosen atom style does not allow for impropers to be defined. :dd
{Improper_style command when no impropers allowed} :dt
The chosen atom style does not allow for impropers to be defined. :dd
{Impropers assigned incorrectly} :dt
Impropers read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions. :dd
{Impropers defined but no improper types} :dt
The data file header lists improper but no improper types. :dd
{Inconsistent iparam/jparam values in fix bond/create command} :dt
-If itype and jtype are the same, then their maxbond and newtype
+If itype and jtype are the same, then their maxbond and newtype
settings must also be the same. :dd
{Inconsistent line segment in data file} :dt
The end points of the line segment are not equal distances from the
center point which is the atom coordinate. :dd
{Inconsistent triangle in data file} :dt
The centroid of the triangle as defined by the corner points is not
the atom coordinate. :dd
{Incorrect args for angle coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect args for bond coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect args for dihedral coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect args for improper coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect args for pair coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect args in pair_style command} :dt
Self-explanatory. :dd
{Incorrect atom format in data file} :dt
Number of values per atom line in the data file is not consistent with
the atom style. :dd
{Incorrect bonus data format in data file} :dt
See the read_data doc page for a description of how various kinds of
bonus data must be formatted for certain atom styles. :dd
{Incorrect boundaries with slab Ewald} :dt
Must have periodic x,y dimensions and non-periodic z dimension to use
2d slab option with Ewald. :dd
{Incorrect boundaries with slab PPPM} :dt
Must have periodic x,y dimensions and non-periodic z dimension to use
2d slab option with PPPM. :dd
{Incorrect element names in ADP potential file} :dt
The element names in the ADP file do not match those requested. :dd
{Incorrect element names in EAM potential file} :dt
The element names in the EAM file do not match those requested. :dd
{Incorrect format in COMB potential file} :dt
Incorrect number of words per line in the potential file. :dd
{Incorrect format in MEAM potential file} :dt
Incorrect number of words per line in the potential file. :dd
{Incorrect format in NEB coordinate file} :dt
Self-explanatory. :dd
{Incorrect format in Stillinger-Weber potential file} :dt
Incorrect number of words per line in the potential file. :dd
{Incorrect format in TMD target file} :dt
Format of file read by fix tmd command is incorrect. :dd
{Incorrect format in Tersoff potential file} :dt
Incorrect number of words per line in the potential file. :dd
{Incorrect multiplicity arg for dihedral coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
+{Incorrect rigid body format in fix rigid file} :dt
+
+The number of fields per line is not what expected. :dd
+
{Incorrect sign arg for dihedral coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Incorrect velocity format in data file} :dt
Each atom style defines a format for the Velocity section
of the data file. The read-in lines do not match. :dd
{Incorrect weight arg for dihedral coefficients} :dt
Self-explanatory. Check the input script or data file. :dd
{Index between variable brackets must be positive} :dt
Self-explanatory. :dd
{Indexed per-atom vector in variable formula without atom map} :dt
Accessing a value from an atom vector requires the ability to lookup
an atom index, which is provided by an atom map. An atom map does not
exist (by default) for non-molecular problems. Using the atom_modify
map command will force an atom map to be created. :dd
{Initial temperatures not all set in fix ttm} :dt
Self-explantory. :dd
{Input line quote not followed by whitespace} :dt
An end quote must be followed by whitespace. :dd
{Input line too long after variable substitution} :dt
This is a hard (very large) limit defined in the input.cpp file. :dd
{Input line too long: %s} :dt
This is a hard (very large) limit defined in the input.cpp file. :dd
{Insertion region extends outside simulation box} :dt
Region specified with fix pour command extends outside the global
simulation box. :dd
{Insufficient Jacobi rotations for POEMS body} :dt
Eigensolve for rigid body was not sufficiently accurate. :dd
{Insufficient Jacobi rotations for rigid body} :dt
Eigensolve for rigid body was not sufficiently accurate. :dd
{Insufficient Jacobi rotations for triangle} :dt
The calculation of the intertia tensor of the triangle failed. This
should not happen if it is a reasonably shaped triangle. :dd
{Insufficient memory on accelerator} :dt
There is insufficient memory on one of the devices specified for the gpu
package :dd
{Invalid -reorder N value} :dt
Self-explanatory. :dd
{Invalid Boolean syntax in if command} :dt
Self-explanatory. :dd
{Invalid REAX atom type} :dt
There is a mis-match between LAMMPS atom types and the elements
listed in the ReaxFF force field file. :dd
{Invalid angle style} :dt
The choice of angle style is unknown. :dd
{Invalid angle table length} :dt
Length must be 2 or greater. :dd
{Invalid angle type in Angles section of data file} :dt
Angle type must be positive integer and within range of specified angle
types. :dd
{Invalid angle type index for fix shake} :dt
Self-explanatory. :dd
{Invalid atom ID in Angles section of data file} :dt
Atom IDs must be positive integers and within range of defined
atoms. :dd
{Invalid atom ID in Atoms section of data file} :dt
Atom IDs must be positive integers. :dd
{Invalid atom ID in Bonds section of data file} :dt
Atom IDs must be positive integers and within range of defined
atoms. :dd
{Invalid atom ID in Bonus section of data file} :dt
Atom IDs must be positive integers and within range of defined
atoms. :dd
{Invalid atom ID in Dihedrals section of data file} :dt
Atom IDs must be positive integers and within range of defined
atoms. :dd
{Invalid atom ID in Impropers section of data file} :dt
Atom IDs must be positive integers and within range of defined
atoms. :dd
{Invalid atom ID in Velocities section of data file} :dt
Atom IDs must be positive integers and within range of defined
atoms. :dd
{Invalid atom mass for fix shake} :dt
Mass specified in fix shake command must be > 0.0. :dd
{Invalid atom style} :dt
The choice of atom style is unknown. :dd
{Invalid atom type in Atoms section of data file} :dt
Atom types must range from 1 to specified # of types. :dd
{Invalid atom type in create_atoms command} :dt
The create_box command specified the range of valid atom types.
An invalid type is being requested. :dd
{Invalid atom type in fix GCMC command} :dt
The atom type specified in the GCMC command does not exist. :dd
{Invalid atom type in fix bond/create command} :dt
Self-explanatory. :dd
{Invalid atom type in neighbor exclusion list} :dt
Atom types must range from 1 to Ntypes inclusive. :dd
{Invalid atom type index for fix shake} :dt
Atom types must range from 1 to Ntypes inclusive. :dd
{Invalid atom types in pair_write command} :dt
Atom types must range from 1 to Ntypes inclusive. :dd
{Invalid atom vector in variable formula} :dt
The atom vector is not recognized. :dd
{Invalid attribute in dump custom command} :dt
Self-explantory. :dd
{Invalid attribute in dump local command} :dt
Self-explantory. :dd
{Invalid attribute in dump modify command} :dt
Self-explantory. :dd
{Invalid bond style} :dt
The choice of bond style is unknown. :dd
{Invalid bond table length} :dt
Length must be 2 or greater. :dd
{Invalid bond type in Bonds section of data file} :dt
Bond type must be positive integer and within range of specified bond
types. :dd
{Invalid bond type in fix bond/break command} :dt
Self-explanatory. :dd
{Invalid bond type in fix bond/create command} :dt
Self-explanatory. :dd
{Invalid bond type index for fix shake} :dt
Self-explanatory. Check the fix shake command in the input script. :dd
{Invalid coeffs for this dihedral style} :dt
Cannot set class 2 coeffs in data file for this dihedral style. :dd
{Invalid color in dump_modify command} :dt
The specified color name was not in the list of recognized colors.
See the dump_modify doc page. :dd
{Invalid command-line argument} :dt
One or more command-line arguments is invalid. Check the syntax of
the command you are using to launch LAMMPS. :dd
{Invalid compute ID in variable formula} :dt
The compute is not recognized. :dd
{Invalid compute style} :dt
Self-explanatory. :dd
{Invalid cutoff in communicate command} :dt
Specified cutoff must be >= 0.0. :dd
{Invalid cutoffs in pair_write command} :dt
Inner cutoff must be larger than 0.0 and less than outer cutoff. :dd
{Invalid d1 or d2 value for pair colloid coeff} :dt
Neither d1 or d2 can be < 0. :dd
{Invalid data file section: Angle Coeffs} :dt
Atom style does not allow angles. :dd
{Invalid data file section: AngleAngle Coeffs} :dt
Atom style does not allow impropers. :dd
{Invalid data file section: AngleAngleTorsion Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: AngleTorsion Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: Angles} :dt
Atom style does not allow angles. :dd
{Invalid data file section: Bond Coeffs} :dt
Atom style does not allow bonds. :dd
{Invalid data file section: BondAngle Coeffs} :dt
Atom style does not allow angles. :dd
{Invalid data file section: BondBond Coeffs} :dt
Atom style does not allow angles. :dd
{Invalid data file section: BondBond13 Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: Bonds} :dt
Atom style does not allow bonds. :dd
{Invalid data file section: Dihedral Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: Dihedrals} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: Ellipsoids} :dt
Atom style does not allow ellipsoids. :dd
{Invalid data file section: EndBondTorsion Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: Improper Coeffs} :dt
Atom style does not allow impropers. :dd
{Invalid data file section: Impropers} :dt
Atom style does not allow impropers. :dd
{Invalid data file section: Lines} :dt
Atom style does not allow lines. :dd
{Invalid data file section: MiddleBondTorsion Coeffs} :dt
Atom style does not allow dihedrals. :dd
{Invalid data file section: Triangles} :dt
Atom style does not allow triangles. :dd
{Invalid delta_conf in tad command} :dt
The value must be between 0 and 1 inclusive. :dd
{Invalid density in Atoms section of data file} :dt
Density value cannot be <= 0.0. :dd
{Invalid diameter in set command} :dt
Self-explanatory. :dd
{Invalid dihedral style} :dt
The choice of dihedral style is unknown. :dd
{Invalid dihedral type in Dihedrals section of data file} :dt
Dihedral type must be positive integer and within range of specified
dihedral types. :dd
{Invalid dipole length in set command} :dt
Self-explanatory. :dd
{Invalid dump dcd filename} :dt
Filenames used with the dump dcd style cannot be binary or compressed
or cause multiple files to be written. :dd
{Invalid dump frequency} :dt
Dump frequency must be 1 or greater. :dd
{Invalid dump image element name} :dt
The specified element name was not in the standard list of elements.
See the dump_modify doc page. :dd
{Invalid dump image filename} :dt
The file produced by dump image cannot be binary and must
be for a single processor. :dd
{Invalid dump image persp value} :dt
Persp value must be >= 0.0. :dd
{Invalid dump image theta value} :dt
Theta must be between 0.0 and 180.0 inclusive. :dd
{Invalid dump image zoom value} :dt
Zoom value must be > 0.0. :dd
+{Invalid dump reader style} :dt
+
+Self-explanatory. :dd
+
{Invalid dump style} :dt
The choice of dump style is unknown. :dd
{Invalid dump xtc filename} :dt
Filenames used with the dump xtc style cannot be binary or compressed
or cause multiple files to be written. :dd
{Invalid dump xyz filename} :dt
Filenames used with the dump xyz style cannot be binary or cause files
to be written by each processor. :dd
{Invalid dump_modify threshhold operator} :dt
Operator keyword used for threshold specification in not recognized. :dd
{Invalid entry in -reorder file} :dt
Self-explanatory. :dd
{Invalid fix ID in variable formula} :dt
The fix is not recognized. :dd
{Invalid fix ave/time off column} :dt
Self-explantory. :dd
{Invalid fix box/relax command for a 2d simulation} :dt
Fix box/relax styles involving the z dimension cannot be used in
a 2d simulation. :dd
{Invalid fix box/relax command pressure settings} :dt
If multiple dimensions are coupled, those dimensions must be specified. :dd
{Invalid fix box/relax pressure settings} :dt
Settings for coupled dimensions must be the same. :dd
{Invalid fix nvt/npt/nph command for a 2d simulation} :dt
Cannot control z dimension in a 2d model. :dd
{Invalid fix nvt/npt/nph command pressure settings} :dt
If multiple dimensions are coupled, those dimensions must be
specified. :dd
{Invalid fix nvt/npt/nph pressure settings} :dt
Settings for coupled dimensions must be the same. :dd
{Invalid fix press/berendsen for a 2d simulation} :dt
The z component of pressure cannot be controlled for a 2d model. :dd
{Invalid fix press/berendsen pressure settings} :dt
Settings for coupled dimensions must be the same. :dd
{Invalid fix style} :dt
The choice of fix style is unknown. :dd
{Invalid flag in force field section of restart file} :dt
Unrecognized entry in restart file. :dd
{Invalid flag in header section of restart file} :dt
Unrecognized entry in restart file. :dd
{Invalid flag in type arrays section of restart file} :dt
Unrecognized entry in restart file. :dd
{Invalid frequency in temper command} :dt
Nevery must be > 0. :dd
{Invalid group ID in neigh_modify command} :dt
A group ID used in the neigh_modify command does not exist. :dd
{Invalid group function in variable formula} :dt
Group function is not recognized. :dd
{Invalid group in communicate command} :dt
Self-explanatory. :dd
{Invalid image color range} :dt
The lo value in the range is larger than the hi value. :dd
{Invalid image up vector} :dt
Up vector cannot be (0,0,0). :dd
{Invalid improper style} :dt
The choice of improper style is unknown. :dd
{Invalid improper type in Impropers section of data file} :dt
Improper type must be positive integer and within range of specified
improper types. :dd
{Invalid keyword in angle table parameters} :dt
Self-explanatory. :dd
{Invalid keyword in bond table parameters} :dt
Self-explanatory. :dd
{Invalid keyword in compute angle/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute bond/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute dihedral/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute improper/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute pair/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute property/atom command} :dt
Self-explanatory. :dd
{Invalid keyword in compute property/local command} :dt
Self-explanatory. :dd
{Invalid keyword in compute property/molecule command} :dt
Self-explanatory. :dd
{Invalid keyword in dump cfg command} :dt
Self-explanatory. :dd
{Invalid keyword in pair table parameters} :dt
Keyword used in list of table parameters is not recognized. :dd
{Invalid keyword in thermo_style custom command} :dt
One or more specified keywords are not recognized. :dd
{Invalid kspace style} :dt
The choice of kspace style is unknown. :dd
{Invalid length in set command} :dt
Self-explanatory. :dd
{Invalid mass in set command} :dt
Self-explanatory. :dd
{Invalid mass line in data file} :dt
Self-explanatory. :dd
{Invalid mass value} :dt
Self-explanatory. :dd
{Invalid math function in variable formula} :dt
Self-explanatory. :dd
{Invalid math/group/special function in variable formula} :dt
Self-explanatory. :dd
{Invalid option in lattice command for non-custom style} :dt
Certain lattice keywords are not supported unless the
lattice style is "custom". :dd
{Invalid order of forces within respa levels} :dt
For respa, ordering of force computations within respa levels must
obey certain rules. E.g. bonds cannot be compute less frequently than
angles, pairwise forces cannot be computed less frequently than
kspace, etc. :dd
{Invalid pair style} :dt
The choice of pair style is unknown. :dd
{Invalid pair table cutoff} :dt
Cutoffs in pair_coeff command are not valid with read-in pair table. :dd
{Invalid pair table length} :dt
Length of read-in pair table is invalid :dd
{Invalid partitions in processors part command} :dt
Valid partitions are numbered 1 to N and the sender and receiver
cannot be the same partition. :dd
{Invalid radius in Atoms section of data file} :dt
Radius must be >= 0.0. :dd
{Invalid random number seed in fix ttm command} :dt
Random number seed must be > 0. :dd
{Invalid random number seed in set command} :dt
Random number seed must be > 0. :dd
{Invalid region style} :dt
The choice of region style is unknown. :dd
{Invalid replace values in compute reduce} :dt
Self-explanatory. :dd
+{Invalid rigid body ID in fix rigid file} :dt
+
+The ID does not match the number or an existing ID of rigid bodies
+that are defined by the fix rigid command. :dd
+
{Invalid run command N value} :dt
The number of timesteps must fit in a 32-bit integer. If you want to
run for more steps than this, perform multiple shorter runs. :dd
{Invalid run command start/stop value} :dt
Self-explanatory. :dd
{Invalid run command upto value} :dt
Self-explanatory. :dd
{Invalid seed for Marsaglia random # generator} :dt
The initial seed for this random number generator must be a positive
integer less than or equal to 900 million. :dd
{Invalid seed for Park random # generator} :dt
The initial seed for this random number generator must be a positive
integer. :dd
{Invalid shape in Ellipsoids section of data file} :dt
Self-explanatory. :dd
{Invalid shape in Triangles section of data file} :dt
Two or more of the triangle corners are duplicate points. :dd
{Invalid shape in set command} :dt
Self-explanatory. :dd
{Invalid shear direction for fix wall/gran} :dt
Self-explanatory. :dd
{Invalid special function in variable formula} :dt
Self-explanatory. :dd
{Invalid style in pair_write command} :dt
Self-explanatory. Check the input script. :dd
{Invalid syntax in variable formula} :dt
Self-explanatory. :dd
{Invalid t_event in prd command} :dt
Self-explanatory. :dd
{Invalid t_event in tad command} :dt
The value must be greater than 0. :dd
{Invalid thermo keyword in variable formula} :dt
The keyword is not recognized. :dd
{Invalid tmax in tad command} :dt
The value must be greater than 0.0. :dd
{Invalid type for mass set} :dt
Mass command must set a type from 1-N where N is the number of atom
types. :dd
{Invalid value in set command} :dt
The value specified for the setting is invalid, likely because it is
too small or too large. :dd
{Invalid variable evaluation in variable formula} :dt
A variable used in a formula could not be evaluated. :dd
{Invalid variable in next command} :dt
Self-explanatory. :dd
{Invalid variable name} :dt
Variable name used in an input script line is invalid. :dd
{Invalid variable name in variable formula} :dt
Variable name is not recognized. :dd
{Invalid variable style with next command} :dt
Variable styles {equal} and {world} cannot be used in a next
command. :dd
{Invalid wiggle direction for fix wall/gran} :dt
Self-explanatory. :dd
{Invoked angle equil angle on angle style none} :dt
Self-explanatory. :dd
{Invoked angle single on angle style none} :dt
Self-explanatory. :dd
{Invoked bond equil distance on bond style none} :dt
Self-explanatory. :dd
{Invoked bond single on bond style none} :dt
Self-explanatory. :dd
{Invoked pair single on pair style none} :dt
A command (e.g. a dump) attempted to invoke the single() function on a
pair style none, which is illegal. You are probably attempting to
compute per-atom quantities with an undefined pair style. :dd
{KIM initialization failed} :dt
This is an error generated by the KIM library. :dd
{KIM neighbor iterator exceeded range} :dt
This should not happen. It likely indicates a bug
in the KIM implementation of the interatomic potential
where it is requesting neighbors incorrectly. :dd
{KIM_DIR environment variable is unset} :dt
This environment variable must be set to use pair_style kim.
See the doc page for pair_style kim. :dd
+{KSpace accuracy too large to estimate G vector} :dt
+
+Paul will doc this. :dd
+
{KSpace style has not yet been set} :dt
Cannot use kspace_modify command until a kspace style is set. :dd
{KSpace style is incompatible with Pair style} :dt
Setting a kspace style requires that a pair style with a long-range
Coulombic component be selected. :dd
{Keyword %s in MEAM parameter file not recognized} :dt
Self-explanatory. :dd
+{Kspace style does not support compute group/group} :dt
+
+Self-explanatory. :dd
+
{Kspace style pppm/tip4p requires newton on} :dt
Self-explanatory. :dd
{Kspace style requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Label wasn't found in input script} :dt
Self-explanatory. :dd
{Lattice orient vectors are not orthogonal} :dt
The three specified lattice orientation vectors must be mutually
orthogonal. :dd
{Lattice orient vectors are not right-handed} :dt
The three specified lattice orientation vectors must create a
right-handed coordinate system such that a1 cross a2 = a3. :dd
{Lattice primitive vectors are collinear} :dt
The specified lattice primitive vectors do not for a unit cell with
non-zero volume. :dd
{Lattice settings are not compatible with 2d simulation} :dt
One or more of the specified lattice vectors has a non-zero z
component. :dd
{Lattice spacings are invalid} :dt
Each x,y,z spacing must be > 0. :dd
{Lattice style incompatible with simulation dimension} :dt
2d simulation can use sq, sq2, or hex lattice. 3d simulation can use
sc, bcc, or fcc lattice. :dd
{Log of zero/negative value in variable formula} :dt
Self-explanatory. :dd
{Lost atoms via balance: original %ld current %ld} :dt
This should not occur. Report the problem to the developers. :dd
{Lost atoms: original %ld current %ld} :dt
Lost atoms are checked for each time thermo output is done. See the
thermo_modify lost command for options. Lost atoms usually indicate
bad dynamics, e.g. atoms have been blown far out of the simulation
box, or moved futher than one processor's sub-domain away before
reneighboring. :dd
{MEAM library error %d} :dt
A call to the MEAM Fortran library returned an error. :dd
{MPI_LMP_BIGINT and bigint in lmptype.h are not compatible} :dt
The size of the MPI datatype does not match the size of a bigint. :dd
{MPI_LMP_TAGINT and tagint in lmptype.h are not compatible} :dt
The size of the MPI datatype does not match the size of a tagint. :dd
{Mass command before simulation box is defined} :dt
The mass command cannot be used before a read_data, read_restart, or
create_box command. :dd
{Min_style command before simulation box is defined} :dt
The min_style command cannot be used before a read_data, read_restart,
or create_box command. :dd
{Minimization could not find thermo_pe compute} :dt
This compute is created by the thermo command. It must have been
explicitly deleted by a uncompute command. :dd
{Minimize command before simulation box is defined} :dt
The minimize command cannot be used before a read_data, read_restart,
or create_box command. :dd
{Mismatched brackets in variable} :dt
Self-explanatory. :dd
{Mismatched compute in variable formula} :dt
A compute is referenced incorrectly or a compute that produces per-atom
values is used in an equal-style variable formula. :dd
{Mismatched fix in variable formula} :dt
A fix is referenced incorrectly or a fix that produces per-atom
values is used in an equal-style variable formula. :dd
{Mismatched variable in variable formula} :dt
A variable is referenced incorrectly or an atom-style variable that
produces per-atom values is used in an equal-style variable
formula. :dd
{Molecular data file has too many atoms} :dt
These kids of data files are currently limited to a number
of atoms that fits in a 32-bit integer. :dd
{Molecule count changed in compute atom/molecule} :dt
Number of molecules must remain constant over time. :dd
{Molecule count changed in compute com/molecule} :dt
Number of molecules must remain constant over time. :dd
{Molecule count changed in compute gyration/molecule} :dt
Number of molecules must remain constant over time. :dd
{Molecule count changed in compute msd/molecule} :dt
Number of molecules must remain constant over time. :dd
{Molecule count changed in compute property/molecule} :dt
Number of molecules must remain constant over time. :dd
{More than one fix deform} :dt
Only one fix deform can be defined at a time. :dd
{More than one fix freeze} :dt
Only one of these fixes can be defined, since the granular pair
potentials access it. :dd
{More than one fix shake} :dt
Only one fix shake can be defined. :dd
{Must define angle_style before Angle Coeffs} :dt
Must use an angle_style command before reading a data file that
defines Angle Coeffs. :dd
{Must define angle_style before BondAngle Coeffs} :dt
Must use an angle_style command before reading a data file that
defines Angle Coeffs. :dd
{Must define angle_style before BondBond Coeffs} :dt
Must use an angle_style command before reading a data file that
defines Angle Coeffs. :dd
{Must define bond_style before Bond Coeffs} :dt
Must use a bond_style command before reading a data file that
defines Bond Coeffs. :dd
{Must define dihedral_style before AngleAngleTorsion Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines AngleAngleTorsion Coeffs. :dd
{Must define dihedral_style before AngleTorsion Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines AngleTorsion Coeffs. :dd
{Must define dihedral_style before BondBond13 Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines BondBond13 Coeffs. :dd
{Must define dihedral_style before Dihedral Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines Dihedral Coeffs. :dd
{Must define dihedral_style before EndBondTorsion Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines EndBondTorsion Coeffs. :dd
{Must define dihedral_style before MiddleBondTorsion Coeffs} :dt
Must use a dihedral_style command before reading a data file that
defines MiddleBondTorsion Coeffs. :dd
{Must define improper_style before AngleAngle Coeffs} :dt
Must use an improper_style command before reading a data file that
defines AngleAngle Coeffs. :dd
{Must define improper_style before Improper Coeffs} :dt
Must use an improper_style command before reading a data file that
defines Improper Coeffs. :dd
{Must define lattice to append/atoms} :dt
A lattice must be defined before using this fix. :dd
{Must define pair_style before Pair Coeffs} :dt
Must use a pair_style command before reading a data file that defines
Pair Coeffs. :dd
{Must have more than one processor partition to temper} :dt
Cannot use the temper command with only one processor partition. Use
the -partition command-line option. :dd
{Must read Atoms before Angles} :dt
The Atoms section of a data file must come before an Angles section. :dd
{Must read Atoms before Bonds} :dt
The Atoms section of a data file must come before a Bonds section. :dd
{Must read Atoms before Dihedrals} :dt
The Atoms section of a data file must come before a Dihedrals section. :dd
{Must read Atoms before Ellipsoids} :dt
The Atoms section of a data file must come before a Ellipsoids
section. :dd
{Must read Atoms before Impropers} :dt
The Atoms section of a data file must come before an Impropers
section. :dd
{Must read Atoms before Lines} :dt
The Atoms section of a data file must come before a Lines section. :dd
{Must read Atoms before Triangles} :dt
The Atoms section of a data file must come before a Triangles section. :dd
{Must read Atoms before Velocities} :dt
The Atoms section of a data file must come before a Velocities
section. :dd
{Must set both respa inner and outer} :dt
Cannot use just the inner or outer option with respa without using the
other. :dd
{Must shrink-wrap piston boundary} :dt
The boundary style of the face where the piston is applied must be of
type s (shrink-wrapped). :dd
{Must specify a region in fix deposit} :dt
The region keyword must be specified with this fix. :dd
{Must specify a region in fix pour} :dt
The region keyword must be specified with this fix. :dd
{Must use -in switch with multiple partitions} :dt
A multi-partition simulation cannot read the input script from stdin.
The -in command-line option must be used to specify a file. :dd
{Must use a block or cylinder region with fix pour} :dt
Self-explanatory. :dd
{Must use a block region with fix pour for 2d simulations} :dt
Self-explanatory. :dd
{Must use a bond style with TIP4P potential} :dt
TIP4P potentials assume bond lengths in water are constrained
by a fix shake command. :dd
{Must use a molecular atom style with fix poems molecule} :dt
Self-explanatory. :dd
{Must use a z-axis cylinder with fix pour} :dt
The axis of the cylinder region used with the fix pour command must
be oriented along the z dimension. :dd
{Must use an angle style with TIP4P potential} :dt
TIP4P potentials assume angles in water are constrained by a fix shake
command. :dd
{Must use atom style with molecule IDs with fix bond/swap} :dt
Self-explanatory. :dd
{Must use pair_style comb with fix qeq/comb} :dt
Self-explanatory. :dd
{Must use variable energy with fix addforce} :dt
Must define an energy vartiable when applyting a dynamic
force during minimization. :dd
{NEB command before simulation box is defined} :dt
Self-explanatory. :dd
{NEB requires damped dynamics minimizer} :dt
Use a different minimization style. :dd
{NEB requires use of fix neb} :dt
Self-explanatory. :dd
{NL ramp in wall/piston only implemented in zlo for now} :dt
The ramp keyword can only be used for piston applied to face zlo. :dd
{Needed bonus data not in data file} :dt
Some atom styles require bonus data. See the read_data doc page for
details. :dd
{Needed topology not in data file} :dt
The header of the data file indicated that bonds or angles or
dihedrals or impropers would be included, but they were not present. :dd
{Neigh_modify exclude molecule requires atom attribute molecule} :dt
Self-explanatory. :dd
{Neigh_modify include group != atom_modify first group} :dt
Self-explanatory. :dd
{Neighbor delay must be 0 or multiple of every setting} :dt
The delay and every parameters set via the neigh_modify command are
inconsistent. If the delay setting is non-zero, then it must be a
multiple of the every setting. :dd
{Neighbor include group not allowed with ghost neighbors} :dt
This is a current restriction within LAMMPS. :dd
{Neighbor list overflow, boost neigh_modify one} :dt
There are too many neighbors of a single atom. Use the neigh_modify
command to increase the max number of neighbors allowed for one atom.
You may also want to boost the page size. :dd
{Neighbor list overflow, boost neigh_modify one or page} :dt
There are too many neighbors of a single atom. Use the neigh_modify
command to increase the neighbor page size and the max number of
neighbors allowed for one atom. :dd
{Neighbor multi not yet enabled for ghost neighbors} :dt
This is a current restriction within LAMMPS. :dd
{Neighbor multi not yet enabled for granular} :dt
Self-explanatory. :dd
{Neighbor multi not yet enabled for rRESPA} :dt
Self-explanatory. :dd
{Neighbor page size must be >= 10x the one atom setting} :dt
This is required to prevent wasting too much memory. :dd
-{Neighbors of ghost atoms only allowed for full neighbor lists} :dt
-
-This is a current restriction within LAMMPS. :dd
-
{New bond exceeded bonds per atom in fix bond/create} :dt
See the read_data command for info on setting the "extra bond per
atom" header value to allow for additional bonds to be formed. :dd
{New bond exceeded special list size in fix bond/create} :dt
See the special_bonds extra command for info on how to leave space in
the special bonds list to allow for additional bonds to be formed. :dd
{Newton bond change after simulation box is defined} :dt
The newton command cannot be used to change the newton bond value
after a read_data, read_restart, or create_box command. :dd
+{No Kspace style defined for compute group/group} :dt
+
+Self-explanatory. :dd
+
{No OpenMP support compiled in} :dt
An OpenMP flag is set, but LAMMPS was not built with
OpenMP support. :dd
{No angle style is defined for compute angle/local} :dt
Self-explanatory. :dd
{No angles allowed with this atom style} :dt
Self-explanatory. Check data file. :dd
{No atoms in data file} :dt
The header of the data file indicated that atoms would be included,
but they were not present. :dd
{No basis atoms in lattice} :dt
Basis atoms must be defined for lattice style user. :dd
{No bond style is defined for compute bond/local} :dt
Self-explanatory. :dd
{No bonds allowed with this atom style} :dt
Self-explanatory. Check data file. :dd
+{No box information in dump. You have to use 'box no'} :dt
+
+Self-explanatory. :dd
+
{No dihedral style is defined for compute dihedral/local} :dt
Self-explanatory. :dd
{No dihedrals allowed with this atom style} :dt
Self-explanatory. Check data file. :dd
{No dump custom arguments specified} :dt
The dump custom command requires that atom quantities be specified to
output to dump file. :dd
{No dump local arguments specified} :dt
Self-explanatory. :dd
{No ellipsoids allowed with this atom style} :dt
Self-explanatory. Check data file. :dd
{No fix gravity defined for fix pour} :dt
Cannot add poured particles without gravity to move them. :dd
{No improper style is defined for compute improper/local} :dt
Self-explanatory. :dd
{No impropers allowed with this atom style} :dt
Self-explanatory. Check data file. :dd
{No lines allowed with this atom style} :dt
Self-explanatory. Check data file. :dd
{No matching element in ADP potential file} :dt
The ADP potential file does not contain elements that match the
requested elements. :dd
{No matching element in EAM potential file} :dt
The EAM potential file does not contain elements that match the
requested elements. :dd
+{No overlap of box and region for create_atoms} :dt
+
+Self-explanatory. :dd
+
{No pair hbond/dreiding coefficients set} :dt
Self-explanatory. :dd
{No pair style defined for compute group/group} :dt
Cannot calculate group interactions without a pair style defined. :dd
{No pair style is defined for compute pair/local} :dt
Self-explanatory. :dd
{No pair style is defined for compute property/local} :dt
Self-explanatory. :dd
{No rigid bodies defined} :dt
The fix specification did not end up defining any rigid bodies. :dd
{No triangles allowed with this atom style} :dt
Self-explanatory. Check data file. :dd
{Non digit character between brackets in variable} :dt
Self-explantory. :dd
{Non integer # of swaps in temper command} :dt
Swap frequency in temper command must evenly divide the total # of
timesteps. :dd
{Nprocs not a multiple of N for -reorder} :dt
Self-explanatory. :dd
{Numeric index is out of bounds} :dt
A command with an argument that specifies an integer or range of
integers is using a value that is less than 1 or greater than the
maximum allowed limit. :dd
{One or more atoms belong to multiple rigid bodies} :dt
Two or more rigid bodies defined by the fix rigid command cannot
contain the same atom. :dd
{One or zero atoms in rigid body} :dt
Any rigid body defined by the fix rigid command must contain 2 or more
atoms. :dd
{Only zhi currently implemented for fix append/atoms} :dt
Self-explanatory. :dd
{Out of range atoms - cannot compute PPPM} :dt
One or more atoms are attempting to map their charge to a PPPM grid
point that is not owned by a processor. This is likely for one of two
reasons, both of them bad. First, it may mean that an atom near the
boundary of a processor's sub-domain has moved more than 1/2 the
"neighbor skin distance"_neighbor.html without neighbor lists being
rebuilt and atoms being migrated to new processors. This also means
you may be missing pairwise interactions that need to be computed.
The solution is to change the re-neighboring criteria via the
"neigh_modify"_neigh_modify command. The safest settings are "delay 0
every 1 check yes". Second, it may mean that an atom has moved far
outside a processor's sub-domain or even the entire simulation box.
This indicates bad physics, e.g. due to highly overlapping atoms, too
large a timestep, etc. :dd
{Overlapping large/large in pair colloid} :dt
This potential is infinite when there is an overlap. :dd
{Overlapping small/large in pair colloid} :dt
This potential is inifinte when there is an overlap. :dd
{POEMS fix must come before NPT/NPH fix} :dt
NPT/NPH fix must be defined in input script after all poems fixes,
else the fix contribution to the pressure virial is incorrect. :dd
{PPPM grid is too large} :dt
The global PPPM grid is larger than OFFSET in one or more dimensions.
OFFSET is currently set to 4096. You likely need to decrease the
requested accuracy. :dd
-{PPPM order cannot be greater than %d} :dt
+{PPPM order cannot be < 2 or > than %d} :dt
-Self-explanatory. :dd
+This is a limitation of the PPPM implementation in LAMMPS. :dd
{PPPM order has been reduced to 0} :dt
LAMMPS has attempted to reduce the PPPM order to enable the simulation
to run, but can reduce the order no further. Try increasing the
-accuracy of PPPM by reducing the tolerance size, thus inducing a
+accuracy of PPPM by reducing the tolerance size, thus inducing a
larger PPPM grid. :dd
{PRD command before simulation box is defined} :dt
The prd command cannot be used before a read_data,
read_restart, or create_box command. :dd
{PRD nsteps must be multiple of t_event} :dt
Self-explanatory. :dd
{PRD t_corr must be multiple of t_event} :dt
Self-explanatory. :dd
{PWD environment variable is unset} :dt
This environment variable must be set to use pair_style kim.
See the doc page for pair_style kim. :dd
{Package command after simulation box is defined} :dt
The package command cannot be used afer a read_data, read_restart, or
create_box command. :dd
{Package cuda command without USER-CUDA installed} :dt
The USER-CUDA package must be installed via "make yes-user-cuda"
before LAMMPS is built. :dd
{Pair brownian requires atom style sphere} :dt
Self-explanatory. :dd
{Pair brownian requires extended particles} :dt
One of the particles has radius 0.0. :dd
{Pair brownian requires monodisperse particles} :dt
All particles must be the same finite size. :dd
{Pair brownian/poly requires atom style sphere} :dt
Self-explanatory. :dd
{Pair brownian/poly requires extended particles} :dt
One of the particles has radius 0.0. :dd
{Pair brownian/poly requires newton pair off} :dt
Self-explanatory. :dd
{Pair coeff for hybrid has invalid style} :dt
Style in pair coeff must have been listed in pair_style command. :dd
{Pair coul/wolf requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair cutoff < Respa interior cutoff} :dt
One or more pairwise cutoffs are too short to use with the specified
rRESPA cutoffs. :dd
{Pair dipole/cut requires atom attributes q, mu, torque} :dt
The atom style defined does not have these attributes. :dd
{Pair distance < table inner cutoff} :dt
Two atoms are closer together than the pairwise table allows. :dd
{Pair distance > table outer cutoff} :dt
Two atoms are further apart than the pairwise table allows. :dd
{Pair dpd requires ghost atoms store velocity} :dt
Use the communicate vel yes command to enable this. :dd
{Pair gayberne epsilon a,b,c coeffs are not all set} :dt
Each atom type involved in pair_style gayberne must
have these 3 coefficients set at least once. :dd
{Pair gayberne requires atom style ellipsoid} :dt
Self-explanatory. :dd
{Pair gayberne requires atoms with same type have same shape} :dt
Self-explanatory. :dd
{Pair gayberne/gpu requires atom style ellipsoid} :dt
Self-explanatory. :dd
{Pair gayberne/gpu requires atoms with same type have same shape} :dt
Self-explanatory. :dd
{Pair granular requires atom style sphere} :dt
Self-explanatory. :dd
{Pair granular requires ghost atoms store velocity} :dt
Use the communicate vel yes command to enable this. :dd
{Pair granular with shear history requires newton pair off} :dt
This is a current restriction of the implementation of pair
granular styles with history. :dd
{Pair hybrid sub-style does not support single call} :dt
You are attempting to invoke a single() call on a pair style
that doesn't support it. :dd
{Pair hybrid sub-style is not used} :dt
No pair_coeff command used a sub-style specified in the pair_style
command. :dd
{Pair inner cutoff < Respa interior cutoff} :dt
One or more pairwise cutoffs are too short to use with the specified
rRESPA cutoffs. :dd
{Pair inner cutoff >= Pair outer cutoff} :dt
The specified cutoffs for the pair style are inconsistent. :dd
{Pair line/lj requires atom style line} :dt
Self-explanatory. :dd
{Pair lubricate requires atom style sphere} :dt
Self-explanatory. :dd
{Pair lubricate requires ghost atoms store velocity} :dt
Use the communicate vel yes command to enable this. :dd
{Pair lubricate requires monodisperse particles} :dt
All particles must be the same finite size. :dd
{Pair lubricate/poly requires atom style sphere} :dt
Self-explanatory. :dd
{Pair lubricate/poly requires extended particles} :dt
One of the particles has radius 0.0. :dd
{Pair lubricate/poly requires ghost atoms store velocity} :dt
Use the communicate vel yes command to enable this. :dd
{Pair lubricate/poly requires newton pair off} :dt
Self-explanatory. :dd
{Pair lubricateU requires atom style sphere} :dt
Self-explanatory. :dd
{Pair lubricateU requires ghost atoms store velocity} :dt
Use the communicate vel yes command to enable this. :dd
{Pair lubricateU requires monodisperse particles} :dt
All particles must be the same finite size. :dd
{Pair lubricateU/poly requires ghost atoms store velocity} :dt
Use the communicate vel yes command to enable this. :dd
{Pair lubricateU/poly requires newton pair off} :dt
Self-explanatory. :dd
{Pair peri lattice is not identical in x, y, and z} :dt
The lattice defined by the lattice command must be cubic. :dd
{Pair peri requires a lattice be defined} :dt
Use the lattice command for this purpose. :dd
{Pair peri requires an atom map, see atom_modify} :dt
Even for atomic systems, an atom map is required to find Peridynamic
bonds. Use the atom_modify command to define one. :dd
{Pair resquared epsilon a,b,c coeffs are not all set} :dt
Self-explanatory. :dd
{Pair resquared epsilon and sigma coeffs are not all set} :dt
Self-explanatory. :dd
{Pair resquared requires atom style ellipsoid} :dt
Self-explanatory. :dd
{Pair resquared requires atoms with same type have same shape} :dt
Self-explanatory. :dd
{Pair resquared/gpu requires atom style ellipsoid} :dt
Self-explanatory. :dd
{Pair resquared/gpu requires atoms with same type have same shape} :dt
Self-explanatory. :dd
{Pair style AIREBO requires atom IDs} :dt
This is a requirement to use the AIREBO potential. :dd
{Pair style AIREBO requires newton pair on} :dt
See the newton command. This is a restriction to use the AIREBO
potential. :dd
+{Pair style BOP requires atom IDs} :dt
+
+This is a requirement to use the BOP potential. :dd
+
+{Pair style BOP requires newton pair on} :dt
+
+See the newton command. This is a restriction to use the BOP
+potential. :dd
+
{Pair style COMB requires atom IDs} :dt
This is a requirement to use the AIREBO potential. :dd
{Pair style COMB requires atom attribute q} :dt
Self-explanatory. :dd
{Pair style COMB requires newton pair on} :dt
See the newton command. This is a restriction to use the COMB
potential. :dd
+{Pair style LCBOP requires atom IDs} :dt
+
+This is a requirement to use the LCBOP potential. :dd
+
+{Pair style LCBOP requires newton pair on} :dt
+
+See the newton command. This is a restriction to use the LCBOP
+potential. :dd
+
{Pair style MEAM requires newton pair on} :dt
See the newton command. This is a restriction to use the MEAM
potential. :dd
{Pair style Stillinger-Weber requires atom IDs} :dt
This is a requirement to use the SW potential. :dd
{Pair style Stillinger-Weber requires newton pair on} :dt
See the newton command. This is a restriction to use the SW
potential. :dd
{Pair style Tersoff requires atom IDs} :dt
This is a requirement to use the Tersoff potential. :dd
{Pair style Tersoff requires newton pair on} :dt
See the newton command. This is a restriction to use the Tersoff
potential. :dd
+{Pair style bop requires comm ghost cutoff at least 3x larger than %g} :dt
+
+Use the communicate ghost command to set this. See the pair bop
+doc page for more details. :dd
+
{Pair style born/coul/long requires atom attribute q} :dt
An atom style that defines this attribute must be used. :dd
{Pair style born/coul/wolf requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style buck/coul/cut requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style buck/coul/long requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Pair style buck/coul/long/gpu requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style coul/cut requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Pair style coul/long/gpu requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Pair style does not have extra field requested by compute pair/local} :dt
The pair style does not support the pN value requested by the compute
pair/local command. :dd
{Pair style does not support bond_style quartic} :dt
The pair style does not have a single() function, so it can
not be invoked by bond_style quartic. :dd
{Pair style does not support compute group/group} :dt
The pair_style does not have a single() function, so it cannot be
invokded by the compute group/group command. :dd
{Pair style does not support compute pair/local} :dt
The pair style does not have a single() function, so it can
not be invoked by compute pair/local. :dd
{Pair style does not support compute property/local} :dt
The pair style does not have a single() function, so it can
not be invoked by fix bond/swap. :dd
{Pair style does not support fix bond/swap} :dt
The pair style does not have a single() function, so it can
not be invoked by fix bond/swap. :dd
{Pair style does not support pair_write} :dt
The pair style does not have a single() function, so it can
not be invoked by pair write. :dd
{Pair style does not support rRESPA inner/middle/outer} :dt
You are attempting to use rRESPA options with a pair style that
does not support them. :dd
{Pair style granular with history requires atoms have IDs} :dt
Atoms in the simulation do not have IDs, so history effects
cannot be tracked by the granular pair potential. :dd
{Pair style hbond/dreiding requires an atom map, see atom_modify} :dt
Self-explanatory. :dd
{Pair style hbond/dreiding requires atom IDs} :dt
Self-explanatory. :dd
{Pair style hbond/dreiding requires molecular system} :dt
Self-explanatory. :dd
{Pair style hbond/dreiding requires newton pair on} :dt
See the newton command for details. :dd
{Pair style hybrid cannot have hybrid as an argument} :dt
Self-explanatory. :dd
{Pair style hybrid cannot have none as an argument} :dt
Self-explanatory. :dd
{Pair style is incompatible with KSpace style} :dt
If a pair style with a long-range Coulombic component is selected,
then a kspace style must also be used. :dd
{Pair style kim requires newton pair off} :dt
This is a current restriction of the KIM library. :dd
{Pair style lj/charmm/coul/charmm requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Pair style lj/charmm/coul/long requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Pair style lj/charmm/coul/long/gpu requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/class2/coul/cut requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/class2/coul/long requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/class2/coul/long/gpu requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/cut/coul/cut requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/cut/coul/cut/gpu requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/cut/coul/long requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/cut/coul/long/gpu requires atom attribute q} :dt
The atom style defined does not have this attribute. :dd
{Pair style lj/cut/coul/long/tip4p requires atom IDs} :dt
There are no atom IDs defined in the system and the TIP4P potential
requires them to find O,H atoms with a water molecule. :dd
{Pair style lj/cut/coul/long/tip4p requires atom attribute q} :dt
The atom style defined does not have these attributes. :dd
{Pair style lj/cut/coul/long/tip4p requires newton pair on} :dt
This is because the computation of constraint forces within a water
molecule adds forces to atoms owned by other processors. :dd
{Pair style lj/gromacs/coul/gromacs requires atom attribute q} :dt
An atom_style with this attribute is needed. :dd
{Pair style peri requires atom style peri} :dt
Self-explanatory. :dd
{Pair style reax requires atom IDs} :dt
This is a requirement to use the ReaxFF potential. :dd
{Pair style reax requires newton pair on} :dt
This is a requirement to use the ReaxFF potential. :dd
{Pair table cutoffs must all be equal to use with KSpace} :dt
When using pair style table with a long-range KSpace solver, the
cutoffs for all atom type pairs must all be the same, since the
long-range solver starts at that cutoff. :dd
{Pair table parameters did not set N} :dt
List of pair table parameters must include N setting. :dd
{Pair tersoff/zbl requires metal or real units} :dt
This is a current restriction of this pair potential. :dd
{Pair tri/lj requires atom style tri} :dt
Self-explanatory. :dd
{Pair yukawa/colloid requires atom style sphere} :dt
Self-explantory. :dd
{Pair yukawa/colloid requires atoms with same type have same radius} :dt
Self-explantory. :dd
{Pair_coeff command before pair_style is defined} :dt
Self-explanatory. :dd
{Pair_coeff command before simulation box is defined} :dt
The pair_coeff command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Pair_modify command before pair_style is defined} :dt
Self-explanatory. :dd
{Pair_write command before pair_style is defined} :dt
Self-explanatory. :dd
{Particle on or inside fix wall surface} :dt
Particles must be "exterior" to the wall in order for energy/force to
be calculated. :dd
{Particle on or inside surface of region used in fix wall/region} :dt
Particles must be "exterior" to the region surface in order for
energy/force to be calculated. :dd
{Per-atom compute in equal-style variable formula} :dt
Equal-style variables cannot use per-atom quantities. :dd
{Per-atom energy was not tallied on needed timestep} :dt
You are using a thermo keyword that requires potentials to
have tallied energy, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work. :dd
{Per-atom fix in equal-style variable formula} :dt
Equal-style variables cannot use per-atom quantities. :dd
{Per-atom virial was not tallied on needed timestep} :dt
You are using a thermo keyword that requires potentials to have
tallied the virial, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work. :dd
{Per-processor system is too big} :dt
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer. :dd
{Potential energy ID for fix neb does not exist} :dt
Self-explanatory. :dd
{Potential energy ID for fix nvt/nph/npt does not exist} :dt
A compute for potential energy must be defined. :dd
{Potential file has duplicate entry} :dt
The potential file for a SW or Tersoff potential has more than
one entry for the same 3 ordered elements. :dd
{Potential file is missing an entry} :dt
The potential file for a SW or Tersoff potential does not have a
needed entry. :dd
{Power by 0 in variable formula} :dt
Self-explanatory. :dd
{Pressure ID for fix box/relax does not exist} :dt
The compute ID needed to compute pressure for the fix does not
exist. :dd
{Pressure ID for fix modify does not exist} :dt
Self-explanatory. :dd
{Pressure ID for fix npt/nph does not exist} :dt
Self-explanatory. :dd
{Pressure ID for fix press/berendsen does not exist} :dt
The compute ID needed to compute pressure for the fix does not
exist. :dd
{Pressure ID for thermo does not exist} :dt
The compute ID needed to compute pressure for thermodynamics does not
exist. :dd
{Pressure control can not be used with fix nvt} :dt
Self-explanatory. :dd
{Pressure control can not be used with fix nvt/asphere} :dt
Self-explanatory. :dd
{Pressure control can not be used with fix nvt/sllod} :dt
Self-explanatory. :dd
{Pressure control can not be used with fix nvt/sphere} :dt
Self-explanatory. :dd
{Pressure control must be used with fix nph} :dt
Self-explanatory. :dd
{Pressure control must be used with fix nph/asphere} :dt
Self-explanatory. :dd
{Pressure control must be used with fix nph/sphere} :dt
Self-explanatory. :dd
{Pressure control must be used with fix nphug} :dt
A pressure control keyword (iso, aniso, tri, x, y, or z) must be
provided. :dd
{Pressure control must be used with fix npt} :dt
Self-explanatory. :dd
{Pressure control must be used with fix npt/asphere} :dt
Self-explanatory. :dd
{Pressure control must be used with fix npt/sphere} :dt
Self-explanatory. :dd
{Processor count in z must be 1 for 2d simulation} :dt
Self-explanatory. :dd
{Processor partitions are inconsistent} :dt
The total number of processors in all partitions must match the number
of processors LAMMPS is running on. :dd
{Processors command after simulation box is defined} :dt
The processors command cannot be used after a read_data, read_restart,
or create_box command. :dd
{Processors custom grid file is inconsistent} :dt
The vales in the custom file are not consistent with the number of
processors you are running on or the Px,Py,Pz settings of the
processors command. Or there was not a setting for every processor. :dd
{Processors grid numa and map style are incompatible} :dt
Using numa for gstyle in the processors command requires using
cart for the map option. :dd
{Processors part option and grid style are incompatible} :dt
Cannot use gstyle numa or custom with the part option. :dd
{Processors twogrid requires proc count be a multiple of core count} :dt
Self-explanatory. :dd
{Pstart and Pstop must have the same value} :dt
Self-explanatory. :dd
{R0 < 0 for fix spring command} :dt
Equilibrium spring length is invalid. :dd
+{Read_dump field not found in dump file} :dt
+
+Self-explanatory. :dd
+
+{Read_dump triclinic status does not match simulation} :dt
+
+Both the dump snapshot and the current LAMMPS simulation must
+be using either an orthogonal or triclinic box. :dd
+
+{Read_dump x,y,z fields do not have consistent scaling} :dt
+
+Self-explanatory. :dd
+
{Reax_defs.h setting for NATDEF is too small} :dt
Edit the setting in the ReaxFF library and re-compile the
library and re-build LAMMPS. :dd
{Reax_defs.h setting for NNEIGHMAXDEF is too small} :dt
Edit the setting in the ReaxFF library and re-compile the
library and re-build LAMMPS. :dd
{Receiving partition in processors part command is already a receiver} :dt
Cannot specify a partition to be a receiver twice. :dd
{Region ID for compute reduce/region does not exist} :dt
Self-explanatory. :dd
{Region ID for compute temp/region does not exist} :dt
Self-explanatory. :dd
{Region ID for dump custom does not exist} :dt
Self-explanatory. :dd
{Region ID for fix addforce does not exist} :dt
Self-explanatory. :dd
{Region ID for fix ave/spatial does not exist} :dt
Self-explanatory. :dd
{Region ID for fix aveforce does not exist} :dt
Self-explanatory. :dd
{Region ID for fix deposit does not exist} :dt
Self-explanatory. :dd
{Region ID for fix evaporate does not exist} :dt
Self-explanatory. :dd
{Region ID for fix heat does not exist} :dt
Self-explanatory. :dd
{Region ID for fix setforce does not exist} :dt
Self-explanatory. :dd
{Region ID for fix wall/region does not exist} :dt
Self-explanatory. :dd
{Region ID in variable formula does not exist} :dt
Self-explanatory. :dd
{Region cannot have 0 length rotation vector} :dt
Self-explanatory. :dd
{Region intersect region ID does not exist} :dt
Self-explanatory. :dd
{Region union or intersect cannot be dynamic} :dt
The sub-regions can be dynamic, but not the combined region. :dd
{Region union region ID does not exist} :dt
One or more of the region IDs specified by the region union command
does not exist. :dd
{Replacing a fix, but new style != old style} :dt
A fix ID can be used a 2nd time, but only if the style matches the
previous fix. In this case it is assumed you with to reset a fix's
parameters. This error may mean you are mistakenly re-using a fix ID
when you do not intend to. :dd
{Replicate command before simulation box is defined} :dt
The replicate command cannot be used before a read_data, read_restart,
or create_box command. :dd
{Replicate did not assign all atoms correctly} :dt
Atoms replicated by the replicate command were not assigned correctly
to processors. This is likely due to some atom coordinates being
outside a non-periodic simulation box. :dd
{Replicated molecular system atom IDs are too big} :dt
See the setting for the allowed atom ID size in the src/lmptype.h
file. :dd
{Replicated system is too big} :dt
See the setting for bigint in the src/lmptype.h file. :dd
+{Rerun command before simulation box is defined} :dt
+
+The rerun command cannot be used before a read_data, read_restart, or
+create_box command. :dd
+
+{Rerun dump file does not contain requested snapshot} :dt
+
+Self-explanatory. :dd
+
{Resetting timestep is not allowed with fix move} :dt
This is because fix move is moving atoms based on elapsed time. :dd
{Respa inner cutoffs are invalid} :dt
The first cutoff must be <= the second cutoff. :dd
{Respa levels must be >= 1} :dt
Self-explanatory. :dd
{Respa middle cutoffs are invalid} :dt
The first cutoff must be <= the second cutoff. :dd
+{Restart variable returned a bad timestep} :dt
+
+The variable must return a timestep greater than the current timestep. :dd
+
{Restrain atoms %d %d %d %d missing on proc %d at step %ld} :dt
The 4 atoms in a restrain dihedral specified by the fix restrain
command are not all accessible to a processor. This probably means an
atom has moved too far. :dd
+{Restrain atoms %d %d %d missing on proc %d at step %ld} :dt
+
+The 3 atoms in a restrain angle specified by the fix restrain
+command are not all accessible to a processor. This probably means an
+atom has moved too far. :dd
+
+{Restrain atoms %d %d missing on proc %d at step %ld} :dt
+
+The 2 atoms in a restrain bond specified by the fix restrain
+command are not all accessible to a processor. This probably means an
+atom has moved too far. :dd
+
{Reuse of compute ID} :dt
A compute ID cannot be used twice. :dd
{Reuse of dump ID} :dt
A dump ID cannot be used twice. :dd
{Reuse of region ID} :dt
A region ID cannot be used twice. :dd
{Rigid body has degenerate moment of inertia} :dt
Fix poems will only work with bodies (collections of atoms) that have
non-zero principal moments of inertia. This means they must be 3 or
more non-collinear atoms, even with joint atoms removed. :dd
{Rigid fix must come before NPT/NPH fix} :dt
NPT/NPH fix must be defined in input script after all rigid fixes,
else the rigid fix contribution to the pressure virial is
incorrect. :dd
{Rmask function in equal-style variable formula} :dt
Rmask is per-atom operation. :dd
{Run command before simulation box is defined} :dt
The run command cannot be used before a read_data, read_restart, or
create_box command. :dd
{Run command start value is after start of run} :dt
Self-explanatory. :dd
{Run command stop value is before end of run} :dt
Self-explanatory. :dd
{Run_style command before simulation box is defined} :dt
The run_style command cannot be used before a read_data,
read_restart, or create_box command. :dd
{SRD bin size for fix srd differs from user request} :dt
Fix SRD had to adjust the bin size to fit the simulation box. See the
cubic keyword if you want this message to be an error vs warning. :dd
{SRD bins for fix srd are not cubic enough} :dt
The bin shape is not within tolerance of cubic. See the cubic
keyword if you want this message to be an error vs warning. :dd
{SRD particle %d started inside big particle %d on step %ld bounce %d} :dt
See the inside keyword if you want this message to be an error vs
warning. :dd
{Same dimension twice in fix ave/spatial} :dt
Self-explanatory. :dd
{Sending partition in processors part command is already a sender} :dt
Cannot specify a partition to be a sender twice. :dd
{Set command before simulation box is defined} :dt
The set command cannot be used before a read_data, read_restart,
or create_box command. :dd
{Set command with no atoms existing} :dt
No atoms are yet defined so the set command cannot be used. :dd
{Set region ID does not exist} :dt
Region ID specified in set command does not exist. :dd
{Shake angles have different bond types} :dt
All 3-atom angle-constrained SHAKE clusters specified by the fix shake
command that are the same angle type, must also have the same bond
types for the 2 bonds in the angle. :dd
{Shake atoms %d %d %d %d missing on proc %d at step %ld} :dt
The 4 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far. :dd
{Shake atoms %d %d %d missing on proc %d at step %ld} :dt
The 3 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far. :dd
{Shake atoms %d %d missing on proc %d at step %ld} :dt
The 2 atoms in a single shake cluster specified by the fix shake
command are not all accessible to a processor. This probably means
an atom has moved too far. :dd
{Shake cluster of more than 4 atoms} :dt
A single cluster specified by the fix shake command can have no more
than 4 atoms. :dd
{Shake clusters are connected} :dt
A single cluster specified by the fix shake command must have a single
central atom with up to 3 other atoms bonded to it. :dd
{Shake determinant = 0.0} :dt
The determinant of the matrix being solved for a single cluster
specified by the fix shake command is numerically invalid. :dd
{Shake fix must come before NPT/NPH fix} :dt
NPT fix must be defined in input script after SHAKE fix, else the
SHAKE fix contribution to the pressure virial is incorrect. :dd
{Small, tag, big integers are not sized correctly} :dt
See description of these 3 data types in src/lmptype.h. :dd
{Smallint setting in lmptype.h is invalid} :dt
It has to be the size of an integer. :dd
{Smallint setting in lmptype.h is not compatible} :dt
Smallint stored in restart file is not consistent with LAMMPS version
you are running. :dd
{Specified processors != physical processors} :dt
The 3d grid of processors defined by the processors command does not
match the number of processors LAMMPS is being run on. :dd
{Specified target stress must be uniaxial or hydrostatic} :dt
Self-explanatory. :dd
{Sqrt of negative value in variable formula} :dt
Self-explanatory. :dd
{Substitution for illegal variable} :dt
Input script line contained a variable that could not be substituted
for. :dd
{System in data file is too big} :dt
See the setting for bigint in the src/lmptype.h file. :dd
{TAD nsteps must be multiple of t_event} :dt
Self-explanatory. :dd
{TIP4P hydrogen has incorrect atom type} :dt
The TIP4P pairwise computation found an H atom whose type does not
agree with the specified H type. :dd
{TIP4P hydrogen is missing} :dt
The TIP4P pairwise computation failed to find the correct H atom
within a water molecule. :dd
{TMD target file did not list all group atoms} :dt
The target file for the fix tmd command did not list all atoms in the
fix group. :dd
{Tad command before simulation box is defined} :dt
Self-explanatory. :dd
{Tagint setting in lmptype.h is invalid} :dt
Tagint must be as large or larger than smallint. :dd
{Tagint setting in lmptype.h is not compatible} :dt
Smallint stored in restart file is not consistent with LAMMPS version
you are running. :dd
{Target temperature for fix nvt/npt/nph cannot be 0.0} :dt
Self-explanatory. :dd
{Target temperature for fix rigid/nvt cannot be 0.0} :dt
Self-explanatory. :dd
{Temper command before simulation box is defined} :dt
The temper command cannot be used before a read_data, read_restart, or
create_box command. :dd
{Temperature ID for fix bond/swap does not exist} :dt
Self-explanatory. :dd
{Temperature ID for fix box/relax does not exist} :dt
Self-explanatory. :dd
{Temperature ID for fix nvt/nph/npt does not exist} :dt
Self-explanatory. :dd
{Temperature ID for fix press/berendsen does not exist} :dt
Self-explanatory. :dd
{Temperature ID for fix temp/berendsen does not exist} :dt
Self-explanatory. :dd
{Temperature ID for fix temp/rescale does not exist} :dt
Self-explanatory. :dd
{Temperature control can not be used with fix nph} :dt
Self-explanatory. :dd
{Temperature control can not be used with fix nph/asphere} :dt
Self-explanatory. :dd
{Temperature control can not be used with fix nph/sphere} :dt
Self-explanatory. :dd
{Temperature control must be used with fix nphug} :dt
The temp keyword must be provided. :dd
{Temperature control must be used with fix npt} :dt
Self-explanatory. :dd
{Temperature control must be used with fix npt/asphere} :dt
Self-explanatory. :dd
{Temperature control must be used with fix npt/sphere} :dt
Self-explanatory. :dd
{Temperature control must be used with fix nvt} :dt
Self-explanatory. :dd
{Temperature control must be used with fix nvt/asphere} :dt
Self-explanatory. :dd
{Temperature control must be used with fix nvt/sllod} :dt
Self-explanatory. :dd
{Temperature control must be used with fix nvt/sphere} :dt
Self-explanatory. :dd
{Temperature for fix nvt/sllod does not have a bias} :dt
The specified compute must compute temperature with a bias. :dd
{Tempering could not find thermo_pe compute} :dt
This compute is created by the thermo command. It must have been
explicitly deleted by a uncompute command. :dd
{Tempering fix ID is not defined} :dt
The fix ID specified by the temper command does not exist. :dd
{Tempering temperature fix is not valid} :dt
The fix specified by the temper command is not one that controls
temperature (nvt or langevin). :dd
{The package gpu command is required for gpu styles} :dt
Self-explanatory. :dd
{Thermo and fix not computed at compatible times} :dt
Fixes generate values on specific timesteps. The thermo output
does not match these timesteps. :dd
{Thermo compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Thermo compute does not compute array} :dt
Self-explanatory. :dd
{Thermo compute does not compute scalar} :dt
Self-explanatory. :dd
{Thermo compute does not compute vector} :dt
Self-explanatory. :dd
{Thermo compute vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Thermo custom variable cannot be indexed} :dt
Self-explanatory. :dd
{Thermo custom variable is not equal-style variable} :dt
Only equal-style variables can be output with thermodynamics, not
atom-style variables. :dd
{Thermo every variable returned a bad timestep} :dt
The variable must return a timestep greater than the current timestep. :dd
{Thermo fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Thermo fix does not compute array} :dt
Self-explanatory. :dd
{Thermo fix does not compute scalar} :dt
Self-explanatory. :dd
{Thermo fix does not compute vector} :dt
Self-explanatory. :dd
{Thermo fix vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Thermo keyword in variable requires lattice be defined} :dt
The xlat, ylat, zlat keywords refer to lattice properties. :dd
{Thermo keyword in variable requires thermo to use/init pe} :dt
You are using a thermo keyword in a variable that requires
potential energy to be calculated, but your thermo output
does not use it. Add it to your thermo output. :dd
{Thermo keyword in variable requires thermo to use/init press} :dt
You are using a thermo keyword in a variable that requires pressure to
be calculated, but your thermo output does not use it. Add it to your
thermo output. :dd
{Thermo keyword in variable requires thermo to use/init temp} :dt
You are using a thermo keyword in a variable that requires temperature
to be calculated, but your thermo output does not use it. Add it to
your thermo output. :dd
{Thermo keyword requires lattice be defined} :dt
The xlat, ylat, zlat keywords refer to lattice properties. :dd
{Thermo style does not use press} :dt
Cannot use thermo_modify to set this parameter since the thermo_style
is not computing this quantity. :dd
{Thermo style does not use temp} :dt
Cannot use thermo_modify to set this parameter since the thermo_style
is not computing this quantity. :dd
{Thermo_modify int format does not contain d character} :dt
Self-explanatory. :dd
{Thermo_modify pressure ID does not compute pressure} :dt
The specified compute ID does not compute pressure. :dd
{Thermo_modify temperature ID does not compute temperature} :dt
The specified compute ID does not compute temperature. :dd
{Thermo_style command before simulation box is defined} :dt
The thermo_style command cannot be used before a read_data,
read_restart, or create_box command. :dd
{This variable thermo keyword cannot be used between runs} :dt
Keywords that refer to time (such as cpu, elapsed) do not
make sense in between runs. :dd
{Threshhold for an atom property that isn't allocated} :dt
A dump threshhold has been requested on a quantity that is
not defined by the atom style used in this simulation. :dd
{Timestep must be >= 0} :dt
Specified timestep is invalid. :dd
{Too big a problem to use velocity create loop all} :dt
The system size must fit in a 32-bit integer to use this option. :dd
{Too big a timestep} :dt
Specified timestep is too large. :dd
{Too big a timestep for dump dcd} :dt
The timestep must fit in a 32-bit integer to use this dump style. :dd
{Too big a timestep for dump xtc} :dt
The timestep must fit in a 32-bit integer to use this dump style. :dd
{Too few bits for lookup table} :dt
Table size specified via pair_modify command does not work with your
machine's floating point representation. :dd
+{Too many atom pairs for pair bop} :dt
+
+The number of atomic pairs exceeds the expected number. Check your
+atomic structure to ensure that it is realistic. :dd
+
{Too many atom sorting bins} :dt
This is likely due to an immense simulation box that has blown up
to a large size. :dd
+{Too many atom triplets for pair bop} :dt
+
+The number of three atom groups for angle determinations exceeds the
+expected number. Check your atomic structrure to ensure that it is
+realistic. :dd
+
{Too many atoms for dump dcd} :dt
The system size must fit in a 32-bit integer to use this dump
style. :dd
{Too many atoms for dump xtc} :dt
The system size must fit in a 32-bit integer to use this dump
style. :dd
{Too many atoms to dump sort} :dt
Cannot sort when running with more than 2^31 atoms. :dd
{Too many exponent bits for lookup table} :dt
Table size specified via pair_modify command does not work with your
machine's floating point representation. :dd
{Too many groups} :dt
-The maximum number of atom groups (including the "all" group) is
+The maximum number of atom groups (including the "all" group) is
given by MAX_GROUP in group.cpp and is 32. :dd
{Too many iterations} :dt
-You must use a number of iterations that fit in a 32-bit integer
+You must use a number of iterations that fit in a 32-bit integer
for minimization. :dd
{Too many local+ghost atoms for neighbor list} :dt
The number of nlocal + nghost atoms on a processor
is limited by the size of a 32-bit integer with 2 bits
removed for masking 1-2, 1-3, 1-4 neighbors. :dd
{Too many mantissa bits for lookup table} :dt
Table size specified via pair_modify command does not work with your
machine's floating point representation. :dd
{Too many masses for fix shake} :dt
The fix shake command cannot list more masses than there are atom
types. :dd
{Too many neighbor bins} :dt
This is likely due to an immense simulation box that has blown up
to a large size. :dd
{Too many timesteps} :dt
The cummulative timesteps must fit in a 64-bit integer. :dd
{Too many timesteps for NEB} :dt
-You must use a number of timesteps that fit in a 32-bit integer
+You must use a number of timesteps that fit in a 32-bit integer
for NEB. :dd
{Too many total atoms} :dt
See the setting for bigint in the src/lmptype.h file. :dd
{Too many total bits for bitmapped lookup table} :dt
Table size specified via pair_modify command is too large. Note that
a value of N generates a 2^N size table. :dd
{Too many touching neighbors - boost MAXTOUCH} :dt
A granular simulation has too many neighbors touching one atom. The
MAXTOUCH parameter in fix_shear_history.cpp must be set larger and
LAMMPS must be re-built. :dd
{Too much per-proc info for dump} :dt
Number of local atoms times number of columns must fit in a 32-bit
integer for dump. :dd
{Tree structure in joint connections} :dt
Fix poems cannot (yet) work with coupled bodies whose joints connect
the bodies in a tree structure. :dd
{Triclinic box skew is too large} :dt
The displacement in a skewed direction must be less than half the box
length in that dimension. E.g. the xy tilt must be between -half and
+half of the x box length. :dd
{Tried to convert a double to int, but input_double > INT_MAX} :dt
Self-explanatory. :dd
{Two groups cannot be the same in fix spring couple} :dt
Self-explanatory. :dd
{USER-CUDA mode requires CUDA variant of min style} :dt
CUDA mode is enabled, so the min style must include a cuda suffix. :dd
{USER-CUDA mode requires CUDA variant of run style} :dt
CUDA mode is enabled, so the run style must include a cuda suffix. :dd
{USER-CUDA package requires a cuda enabled atom_style} :dt
Self-explanatory. :dd
{Unable to initialize accelerator for use} :dt
There was a problem initializing an accelerator for the gpu package :dd
{Unbalanced quotes in input line} :dt
No matching end double quote was found following a leading double
quote. :dd
{Unexpected end of -reorder file} :dt
Self-explanatory. :dd
{Unexpected end of custom file} :dt
Self-explanatory. :dd
{Unexpected end of data file} :dt
LAMMPS hit the end of the data file while attempting to read a
section. Something is wrong with the format of the data file. :dd
+{Unexpected end of dump file} :dt
+
+A read operation from the file failed. :dd
+
+{Unexpected end of fix rigid file} :dt
+
+A read operation from the file failed. :dd
+
{Units command after simulation box is defined} :dt
The units command cannot be used after a read_data, read_restart, or
create_box command. :dd
{Universe/uloop variable count < # of partitions} :dt
A universe or uloop style variable must specify a number of values >= to the
number of processor partitions. :dd
{Unknown command: %s} :dt
The command is not known to LAMMPS. Check the input script. :dd
{Unknown error in GPU library} :dt
Self-explanatory. :dd
{Unknown identifier in data file: %s} :dt
A section of the data file cannot be read by LAMMPS. :dd
{Unknown table style in angle style table} :dt
Self-explanatory. :dd
{Unknown table style in bond style table} :dt
Self-explanatory. :dd
{Unknown table style in pair_style command} :dt
Style of table is invalid for use with pair_style table command. :dd
{Unrecognized lattice type in MEAM file 1} :dt
The lattice type in an entry of the MEAM library file is not
valid. :dd
{Unrecognized lattice type in MEAM file 2} :dt
The lattice type in an entry of the MEAM parameter file is not
valid. :dd
{Unrecognized pair style in compute pair command} :dt
Self-explanatory. :dd
{Use of change_box with undefined lattice} :dt
Must use lattice command with displace_box command if units option is
set to lattice. :dd
{Use of compute temp/ramp with undefined lattice} :dt
Must use lattice command with compute temp/ramp command if units
option is set to lattice. :dd
{Use of displace_atoms with undefined lattice} :dt
Must use lattice command with displace_atoms command if units option
is set to lattice. :dd
{Use of fix append/atoms with undefined lattice} :dt
A lattice must be defined before using this fix. :dd
{Use of fix ave/spatial with undefined lattice} :dt
A lattice must be defined to use fix ave/spatial with units = lattice. :dd
{Use of fix deform with undefined lattice} :dt
A lattice must be defined to use fix deform with units = lattice. :dd
{Use of fix deposit with undefined lattice} :dt
Must use lattice command with compute fix deposit command if units
option is set to lattice. :dd
{Use of fix dt/reset with undefined lattice} :dt
Must use lattice command with fix dt/reset command if units option is
set to lattice. :dd
{Use of fix indent with undefined lattice} :dt
The lattice command must be used to define a lattice before using the
fix indent command. :dd
{Use of fix move with undefined lattice} :dt
Must use lattice command with fix move command if units option is
set to lattice. :dd
{Use of fix recenter with undefined lattice} :dt
Must use lattice command with fix recenter command if units option is
set to lattice. :dd
{Use of fix wall with undefined lattice} :dt
Must use lattice command with fix wall command if units option is set
to lattice. :dd
{Use of fix wall/piston with undefined lattice} :dt
A lattice must be defined before using this fix. :dd
{Use of region with undefined lattice} :dt
If units = lattice (the default) for the region command, then a
lattice must first be defined via the lattice command. :dd
{Use of velocity with undefined lattice} :dt
If units = lattice (the default) for the velocity set or velocity ramp
command, then a lattice must first be defined via the lattice command. :dd
{Using fix nvt/sllod with inconsistent fix deform remap option} :dt
Fix nvt/sllod requires that deforming atoms have a velocity profile
provided by "remap v" as a fix deform option. :dd
{Using fix nvt/sllod with no fix deform defined} :dt
Self-explanatory. :dd
{Using fix srd with inconsistent fix deform remap option} :dt
When shearing the box in an SRD simulation, the remap v option for fix
deform needs to be used. :dd
{Using pair lubricate with inconsistent fix deform remap option} :dt
-If fix deform is used, the remap v option is required. :dd
+Must use remap v option with fix deform with this pair style. :dd
{Using pair lubricate/poly with inconsistent fix deform remap option} :dt
If fix deform is used, the remap v option is required. :dd
{Variable evaluation before simulation box is defined} :dt
Cannot evaluate a compute or fix or atom-based value in a variable
before the simulation has been setup. :dd
{Variable for compute ti is invalid style} :dt
Self-explanatory. :dd
{Variable for dump every is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for dump image center is invalid style} :dt
Must be an equal-style variable. :dd
{Variable for dump image persp is invalid style} :dt
Must be an equal-style variable. :dd
{Variable for dump image phi is invalid style} :dt
Must be an equal-style variable. :dd
{Variable for dump image theta is invalid style} :dt
Must be an equal-style variable. :dd
{Variable for dump image zoom is invalid style} :dt
Must be an equal-style variable. :dd
{Variable for fix adapt is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix addforce is invalid style} :dt
Self-explanatory. :dd
{Variable for fix aveforce is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix deform is invalid style} :dt
The variable must be an equal-style variable. :dd
{Variable for fix efield is invalid style} :dt
Only equal-style variables can be used. :dd
+{Variable for fix gravity is invalid style} :dt
+
+Only equal-style variables can be used. :dd
+
{Variable for fix indent is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix indent is not equal style} :dt
Only equal-style variables can be used. :dd
{Variable for fix langevin is invalid style} :dt
It must be an equal-style variable. :dd
{Variable for fix move is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix setforce is invalid style} :dt
Only equal-style variables can be used. :dd
+{Variable for fix temp/berendsen is invalid style} :dt
+
+Only equal-style variables can be used. :dd
+
+{Variable for fix temp/rescale is invalid style} :dt
+
+Only equal-style variables can be used. :dd
+
{Variable for fix wall is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix wall/reflect is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for fix wall/srd is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for region is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for region is not equal style} :dt
Self-explanatory. :dd
+{Variable for restart is invalid style} :dt
+
+Only equal-style variables can be used. :dd
+
{Variable for thermo every is invalid style} :dt
Only equal-style variables can be used. :dd
{Variable for velocity set is invalid style} :dt
Only atom-style variables can be used. :dd
{Variable formula compute array is accessed out-of-range} :dt
Self-explanatory. :dd
{Variable formula compute vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Variable formula fix array is accessed out-of-range} :dt
Self-explanatory. :dd
{Variable formula fix vector is accessed out-of-range} :dt
Self-explanatory. :dd
{Variable name for compute atom/molecule does not exist} :dt
Self-explanatory. :dd
{Variable name for compute reduce does not exist} :dt
Self-explanatory. :dd
{Variable name for compute ti does not exist} :dt
Self-explanatory. :dd
{Variable name for dump every does not exist} :dt
Self-explanatory. :dd
{Variable name for dump image center does not exist} :dt
Self-explanatory. :dd
{Variable name for dump image persp does not exist} :dt
Self-explanatory. :dd
{Variable name for dump image phi does not exist} :dt
Self-explanatory. :dd
{Variable name for dump image theta does not exist} :dt
Self-explanatory. :dd
{Variable name for dump image zoom does not exist} :dt
Self-explanatory. :dd
{Variable name for fix adapt does not exist} :dt
Self-explanatory. :dd
{Variable name for fix addforce does not exist} :dt
Self-explanatory. :dd
{Variable name for fix ave/atom does not exist} :dt
Self-explanatory. :dd
{Variable name for fix ave/correlate does not exist} :dt
Self-explanatory. :dd
{Variable name for fix ave/histo does not exist} :dt
Self-explanatory. :dd
{Variable name for fix ave/spatial does not exist} :dt
Self-explanatory. :dd
{Variable name for fix ave/time does not exist} :dt
Self-explanatory. :dd
{Variable name for fix aveforce does not exist} :dt
Self-explanatory. :dd
{Variable name for fix deform does not exist} :dt
Self-explantory. :dd
{Variable name for fix efield does not exist} :dt
Self-explanatory. :dd
+{Variable name for fix gravity does not exist} :dt
+
+Self-explanatory. :dd
+
{Variable name for fix indent does not exist} :dt
Self-explanatory. :dd
{Variable name for fix langevin does not exist} :dt
Self-explanatory. :dd
{Variable name for fix move does not exist} :dt
Self-explanatory. :dd
{Variable name for fix setforce does not exist} :dt
Self-explanatory. :dd
{Variable name for fix store/state does not exist} :dt
Self-explanatory. :dd
+{Variable name for fix temp/berendsen does not exist} :dt
+
+Self-explanatory. :dd
+
+{Variable name for fix temp/rescale does not exist} :dt
+
+Self-explanatory. :dd
+
{Variable name for fix wall does not exist} :dt
Self-explanatory. :dd
{Variable name for fix wall/reflect does not exist} :dt
Self-explanatory. :dd
{Variable name for fix wall/srd does not exist} :dt
Self-explanatory. :dd
{Variable name for region does not exist} :dt
Self-explanatory. :dd
+{Variable name for restart does not exist} :dt
+
+Self-explanatory. :dd
+
{Variable name for thermo every does not exist} :dt
Self-explanatory. :dd
{Variable name for velocity set does not exist} :dt
Self-explanatory. :dd
{Variable name must be alphanumeric or underscore characters} :dt
Self-explanatory. :dd
{Velocity command before simulation box is defined} :dt
The velocity command cannot be used before a read_data, read_restart,
or create_box command. :dd
{Velocity command with no atoms existing} :dt
A velocity command has been used, but no atoms yet exist. :dd
{Velocity ramp in z for a 2d problem} :dt
Self-explanatory. :dd
{Velocity temperature ID does not compute temperature} :dt
The compute ID given to the velocity command must compute
temperature. :dd
{Verlet/split requires 2 partitions} :dt
See the -partition command-line switch. :dd
{Verlet/split requires Rspace partition layout be multiple of Kspace partition layout in each dim} :dt
This is controlled by the processors command. :dd
{Verlet/split requires Rspace partition size be multiple of Kspace partition size} :dt
This is so there is an equal number of Rspace processors for every
Kspace processor. :dd
{Virial was not tallied on needed timestep} :dt
You are using a thermo keyword that requires potentials to
have tallied the virial, but they didn't on this timestep. See the
variable doc page for ideas on how to make this work. :dd
{Wall defined twice in fix wall command} :dt
Self-explanatory. :dd
{Wall defined twice in fix wall/reflect command} :dt
Self-explanatory. :dd
{Wall defined twice in fix wall/srd command} :dt
Self-explanatory. :dd
+{Water H epsilon must be 0.0 for pair style lj/cut/coul/long/tip4p} :dt
+
+This is because LAMMPS does not compute the Lennard-Jones interactions
+with these particles for efficiency reasons. :dd
+
{World variable count doesn't match # of partitions} :dt
A world-style variable must specify a number of values equal to the
number of processor partitions. :dd
{Write_restart command before simulation box is defined} :dt
The write_restart command cannot be used before a read_data,
read_restart, or create_box command. :dd
{Zero-length lattice orient vector} :dt
Self-explanatory. :dd
:dle
Warnings: :h4,link(warn)
:dlb
{Atom with molecule ID = 0 included in compute molecule group} :dt
The group used in a compute command that operates on moleclues
includes atoms with no molecule ID. This is probably not what you
want. :dd
+{Both groups in compute group/group have a net charge; the Kspace boundary correction to energy will be non-zero} :dt
+
+Self-explantory. :dd
+
{Broken bonds will not alter angles, dihedrals, or impropers} :dt
See the doc page for fix bond/break for more info on this
restriction. :dd
{Building an occasional neighobr list when atoms may have moved too far} :dt
This can cause LAMMPS to crash when the neighbor list is built.
The solution is to check for building the regular neighbor lists
more frequently. :dd
+{Cannot include log terms without 1/r terms; setting flagHI to 1} :dt
+
+Self-explanatory. :dd
+
+{Cannot include log terms without 1/r terms; setting flagHI to 1.} :dt
+
+Self-explanatory. :dd
+
{Compute cna/atom cutoff may be too large to find ghost atom neighbors} :dt
The neighbor cutoff used may not encompass enough ghost atoms
to perform this operation correctly. :dd
{Computing temperature of portions of rigid bodies} :dt
The group defined by the temperature compute does not encompass all
the atoms in one or more rigid bodies, so the change in
degrees-of-freedom for the atoms in those partial rigid bodies will
not be accounted for. :dd
{Created bonds will not create angles, dihedrals, or impropers} :dt
See the doc page for fix bond/create for more info on this
restriction. :dd
{Dihedral problem: %d %ld %d %d %d %d} :dt
Conformation of the 4 listed dihedral atoms is extreme; you may want
to check your simulation geometry. :dd
{Dump dcd/xtc timestamp may be wrong with fix dt/reset} :dt
If the fix changes the timestep, the dump dcd file will not
reflect the change. :dd
{FENE bond too long: %ld %d %d %g} :dt
A FENE bond has stretched dangerously far. It's interaction strength
will be truncated to attempt to prevent the bond from blowing up. :dd
{FENE bond too long: %ld %g} :dt
A FENE bond has stretched dangerously far. It's interaction strength
will be truncated to attempt to prevent the bond from blowing up. :dd
{Fix GCMC may delete atom with non-zero molecule ID} :dt
This is probably an error, since you should not delete only one atom
of a molecule. The GCMC molecule exchange feature does not yet work. :dd
{Fix SRD walls overlap but fix srd overlap not set} :dt
You likely want to set this in your input script. :dd
{Fix bond/swap will ignore defined angles} :dt
See the doc page for fix bond/swap for more info on this
restriction. :dd
{Fix evaporate may delete atom with non-zero molecule ID} :dt
This is probably an error, since you should not delete only one atom
of a molecule. :dd
{Fix move does not update angular momentum} :dt
Atoms store this quantity, but fix move does not (yet) update it. :dd
{Fix move does not update quaternions} :dt
Atoms store this quantity, but fix move does not (yet) update it. :dd
{Fix recenter should come after all other integration fixes} :dt
-Other fixes may change the position of the center-of-mass, so
+Other fixes may change the position of the center-of-mass, so
fix recenter should come last. :dd
+{Fix shake with rRESPA computes invalid pressures} :dt
+
+This is a known bug in LAMMPS that has not yet been fixed. If you use
+SHAKE with rRESPA and perform a constant volume simulation (e.g. using
+fix npt) this only affects the output pressure, not the dynamics of
+the simulation. If you use SHAKE with rRESPA and perform a constant
+pressure simulation (e.g. using fix npt) then you will be
+equilibrating to the wrong volume. :dd
+
{Fix srd SRD moves may trigger frequent reneighboring} :dt
This is because the SRD particles may move long distances. :dd
{Fix srd grid size > 1/4 of big particle diameter} :dt
This may cause accuracy problems. :dd
{Fix srd particle moved outside valid domain} :dt
This may indicate a problem with your simulation parameters. :dd
{Fix srd particles may move > big particle diameter} :dt
This may cause accuracy problems. :dd
{Fix srd viscosity < 0.0 due to low SRD density} :dt
This may cause accuracy problems. :dd
{Fix thermal/conductivity comes before fix ave/spatial} :dt
The order of these 2 fixes in your input script is such that fix
thermal/conductivity comes first. If you are using fix ave/spatial to
measure the temperature profile induced by fix viscosity, then this
may cause a glitch in the profile since you are averaging immediately
after swaps have occurred. Flipping the order of the 2 fixes
typically helps. :dd
{Fix viscosity comes before fix ave/spatial} :dt
The order of these 2 fixes in your input script is such that
fix viscosity comes first. If you are using fix ave/spatial
to measure the velocity profile induced by fix viscosity, then
this may cause a glitch in the profile since you are averaging
immediately after swaps have occurred. Flipping the order
of the 2 fixes typically helps. :dd
{Group for fix_modify temp != fix group} :dt
The fix_modify command is specifying a temperature computation that
computes a temperature on a different group of atoms than the fix
itself operates on. This is probably not what you want to do. :dd
{Improper problem: %d %ld %d %d %d %d} :dt
Conformation of the 4 listed improper atoms is extreme; you may want
to check your simulation geometry. :dd
{Kspace_modify slab param < 2.0 may cause unphysical behavior} :dt
The kspace_modify slab parameter should be larger to insure periodic
grids padded with empty space do not overlap. :dd
{Less insertions than requested} :dt
Less atom insertions occurred on this timestep due to the fix pour
command than were scheduled. This is probably because there were too
many overlaps detected. :dd
{Lost atoms via change_box: original %ld current %ld} :dt
The command options you have used caused atoms to be lost. :dd
{Lost atoms via displace_atoms: original %ld current %ld} :dt
The command options you have used caused atoms to be lost. :dd
{Lost atoms: original %ld current %ld} :dt
Lost atoms are checked for each time thermo output is done. See the
thermo_modify lost command for options. Lost atoms usually indicate
bad dynamics, e.g. atoms have been blown far out of the simulation
box, or moved futher than one processor's sub-domain away before
reneighboring. :dd
{Mismatch between velocity and compute groups} :dt
The temperature computation used by the velocity command will not be
on the same group of atoms that velocities are being set for. :dd
{More than one compute centro/atom} :dt
It is not efficient to use compute centro/atom more than once. :dd
{More than one compute cluster/atom} :dt
It is not efficient to use compute cluster/atom more than once. :dd
{More than one compute cna/atom defined} :dt
It is not efficient to use compute cna/atom more than once. :dd
{More than one compute coord/atom} :dt
It is not efficient to use compute coord/atom more than once. :dd
{More than one compute damage/atom} :dt
It is not efficient to use compute ke/atom more than once. :dd
{More than one compute ke/atom} :dt
It is not efficient to use compute ke/atom more than once. :dd
{More than one fix poems} :dt
It is not efficient to use fix poems more than once. :dd
{More than one fix rigid} :dt
It is not efficient to use fix rigid more than once. :dd
{New thermo_style command, previous thermo_modify settings will be lost} :dt
If a thermo_style command is used after a thermo_modify command, the
settings changed by the thermo_modify command will be reset to their
default values. This is because the thermo_modify commmand acts on
the currently defined thermo style, and a thermo_style command creates
a new style. :dd
{No Kspace calculation with verlet/split} :dt
The 2nd partition performs a kspace calculation so the kspace_style
command must be used. :dd
{No fixes defined, atoms won't move} :dt
If you are not using a fix like nve, nvt, npt then atom velocities and
coordinates will not be updated during timestepping. :dd
{No joints between rigid bodies, use fix rigid instead} :dt
The bodies defined by fix poems are not connected by joints. POEMS
will integrate the body motion, but it would be more efficient to use
fix rigid. :dd
{Not using real units with pair reax} :dt
This is most likely an error, unless you have created your own ReaxFF
parameter file in a different set of units. :dd
{One or more atoms are time integrated more than once} :dt
This is probably an error since you typically do not want to
advance the positions or velocities of an atom more than once
per timestep. :dd
{One or more compute molecules has atoms not in group} :dt
The group used in a compute command that operates on moleclues does
not include all the atoms in some molecules. This is probably not
what you want. :dd
{One or more respa levels compute no forces} :dt
This is computationally inefficient. :dd
{Pair COMB charge %.10f with force %.10f hit max barrier} :dt
Something is possibly wrong with your model. :dd
{Pair COMB charge %.10f with force %.10f hit min barrier} :dt
Something is possibly wrong with your model. :dd
{Pair brownian needs newton pair on for momentum conservation} :dt
Self-explanatory. :dd
{Pair dpd needs newton pair on for momentum conservation} :dt
Self-explanatory. :dd
{Pair dsmc: num_of_collisions > number_of_A} :dt
Collision model in DSMC is breaking down. :dd
{Pair dsmc: num_of_collisions > number_of_B} :dt
Collision model in DSMC is breaking down. :dd
{Particle deposition was unsuccessful} :dt
The fix deposit command was not able to insert as many atoms as
needed. The requested volume fraction may be too high, or other atoms
may be in the insertion region. :dd
{Reducing PPPM order b/c stencil extends beyond neighbor processor} :dt
LAMMPS is attempting this in order to allow the simulation
to run. It should not effect the PPPM accuracy. :dd
{Replacing a fix, but new group != old group} :dt
The ID and style of a fix match for a fix you are changing with a fix
command, but the new group you are specifying does not match the old
group. :dd
{Replicating in a non-periodic dimension} :dt
The parameters for a replicate command will cause a non-periodic
dimension to be replicated; this may cause unwanted behavior. :dd
{Resetting reneighboring criteria during PRD} :dt
A PRD simulation requires that neigh_modify settings be delay = 0,
every = 1, check = yes. Since these settings were not in place,
LAMMPS changed them and will restore them to their original values
after the PRD simulation. :dd
{Resetting reneighboring criteria during TAD} :dt
A TAD simulation requires that neigh_modify settings be delay = 0,
every = 1, check = yes. Since these settings were not in place,
LAMMPS changed them and will restore them to their original values
after the PRD simulation. :dd
{Resetting reneighboring criteria during minimization} :dt
Minimization requires that neigh_modify settings be delay = 0, every =
1, check = yes. Since these settings were not in place, LAMMPS
changed them and will restore them to their original values after the
minimization. :dd
{Restart file used different # of processors} :dt
The restart file was written out by a LAMMPS simulation running on a
different number of processors. Due to round-off, the trajectories of
your restarted simulation may diverge a little more quickly than if
you ran on the same # of processors. :dd
{Restart file used different 3d processor grid} :dt
The restart file was written out by a LAMMPS simulation running on a
different 3d grid of processors. Due to round-off, the trajectories
of your restarted simulation may diverge a little more quickly than if
you ran on the same # of processors. :dd
{Restart file used different boundary settings, using restart file values} :dt
Your input script cannot change these restart file settings. :dd
{Restart file used different newton bond setting, using restart file value} :dt
The restart file value will override the setting in the input script. :dd
{Restart file used different newton pair setting, using input script value} :dt
The input script value will override the setting in the restart file. :dd
{Restart file version does not match LAMMPS version} :dt
This may cause problems when reading the restart file. :dd
{Restrain problem: %d %ld %d %d %d %d} :dt
Conformation of the 4 listed dihedral atoms is extreme; you may want
to check your simulation geometry. :dd
{Running PRD with only one replica} :dt
This is allowed, but you will get no parallel speed-up. :dd
{SRD bin shifting turned on due to small lamda} :dt
This is done to try to preserve accuracy. :dd
{SRD bin size for fix srd differs from user request} :dt
Fix SRD had to adjust the bin size to fit the simulation box. See the
cubic keyword if you want this message to be an error vs warning. :dd
{SRD bins for fix srd are not cubic enough} :dt
The bin shape is not within tolerance of cubic. See the cubic
keyword if you want this message to be an error vs warning. :dd
{SRD particle %d started inside big particle %d on step %ld bounce %d} :dt
See the inside keyword if you want this message to be an error vs
warning. :dd
{Shake determinant < 0.0} :dt
The determinant of the quadratic equation being solved for a single
cluster specified by the fix shake command is numerically suspect. LAMMPS
will set it to 0.0 and continue. :dd
{Should not allow rigid bodies to bounce off relecting walls} :dt
LAMMPS allows this, but their dynamics are not computed correctly. :dd
{System is not charge neutral, net charge = %g} :dt
The total charge on all atoms on the system is not 0.0, which
is not valid for Ewald or PPPM. :dd
{Table inner cutoff >= outer cutoff} :dt
You specified an inner cutoff for a Coulombic table that is longer
than the global cutoff. Probably not what you wanted. :dd
{Temperature for MSST is not for group all} :dt
User-assigned temperature to MSST fix does not compute temperature for
all atoms. Since MSST computes a global pressure, the kinetic energy
contribution from the temperature is assumed to also be for all atoms.
Thus the pressure used by MSST could be inaccurate. :dd
{Temperature for NPT is not for group all} :dt
User-assigned temperature to NPT fix does not compute temperature for
all atoms. Since NPT computes a global pressure, the kinetic energy
contribution from the temperature is assumed to also be for all atoms.
Thus the pressure used by NPT could be inaccurate. :dd
{Temperature for fix modify is not for group all} :dt
The temperature compute is being used with a pressure calculation
which does operate on group all, so this may be inconsistent. :dd
{Temperature for thermo pressure is not for group all} :dt
User-assigned temperature to thermo via the thermo_modify command does
not compute temperature for all atoms. Since thermo computes a global
pressure, the kinetic energy contribution from the temperature is
assumed to also be for all atoms. Thus the pressure printed by thermo
could be inaccurate. :dd
{Too many common neighbors in CNA %d times} :dt
More than the maximum # of neighbors was found multiple times. This
was unexpected. :dd
{Too many inner timesteps in fix ttm} :dt
Self-explanatory. :dd
{Too many neighbors in CNA for %d atoms} :dt
More than the maximum # of neighbors was found multiple times. This
was unexpected. :dd
{Use special bonds = 0,1,1 with bond style fene} :dt
Most FENE models need this setting for the special_bonds command. :dd
{Use special bonds = 0,1,1 with bond style fene/expand} :dt
Most FENE models need this setting for the special_bonds command. :dd
{Using compute temp/deform with inconsistent fix deform remap option} :dt
Fix nvt/sllod assumes deforming atoms have a velocity profile provided
by "remap v" or "remap none" as a fix deform option. :dd
{Using compute temp/deform with no fix deform defined} :dt
This is probably an error, since it makes little sense to use
compute temp/deform in this case. :dd
{Using fix srd with box deformation but no SRD thermostat} :dt
The deformation will heat the SRD particles so this can
be dangerous. :dd
{Using pair tail corrections with nonperiodic system} :dt
This is probably a bogus thing to do, since tail corrections are
computed by integrating the density of a periodic system out to
infinity. :dd
:dle
diff --git a/doc/Section_packages.html b/doc/Section_packages.html
index e16611608..ae604bbf9 100644
--- a/doc/Section_packages.html
+++ b/doc/Section_packages.html
@@ -1,471 +1,471 @@
<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_accelerate.html">Next
Section</A>
</CENTER>
<HR>
<H3>4. Packages
</H3>
<P>This section gives a quick overview of the add-on packages that extend
LAMMPS functionality.
</P>
4.1 <A HREF = "#pkg_1">Standard packages</A><BR>
4.2 <A HREF = "#pkg_2">User packages</A> <BR>
<P>LAMMPS includes many optional packages, which 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" from within the src
directory of the LAMMPS distribution.
</P>
<P>See <A HREF = "Section_start.html#start_3">Section_start 3</A> of the manual for
details on how to include/exclude specific packages as part of the
LAMMPS build process, and for more details about the differences
between standard packages and user packages in LAMMPS.
</P>
<P>Below, the packages currently availabe in LAMMPS are listed. For
standard packages, just a one-line description is given. For user
packages, more details are provided.
</P>
<HR>
<HR>
<H4><A NAME = "pkg_1"></A>4.1 Standard packages
</H4>
<P>The current list of standard packages is as follows:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD >Package</TD><TD > Description</TD><TD > Author(s)</TD><TD > Doc page</TD><TD > Example</TD><TD > Library</TD></TR>
-<TR ALIGN="center"><TD >ASPHERE</TD><TD > aspherical particles</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_14">howto</A></TD><TD > ellipse</TD><TD > -</TD></TR>
+<TR ALIGN="center"><TD >ASPHERE</TD><TD > aspherical particles</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_14">Section_howto</A></TD><TD > ellipse</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >CLASS2</TD><TD > class 2 force fields</TD><TD > -</TD><TD > <A HREF = "pair_class2.html">pair_style lj/class2</A></TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >COLLOID</TD><TD > colloidal particles</TD><TD > -</TD><TD > <A HREF = "atom_style.html">atom_style colloid</A></TD><TD > colloid</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >DIPOLE</TD><TD > point dipole particles</TD><TD > -</TD><TD > <A HREF = "pair_dipole.html">pair_style dipole/cut</A></TD><TD > dipole</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >FLD</TD><TD > Fast Lubrication Dynamics</TD><TD > Kumar & Bybee & Higdon (1)</TD><TD > <A HREF = "pair_lubricateU.html">pair_style lubricateU</A></TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >GPU</TD><TD > GPU-enabled potentials</TD><TD > Mike Brown (ORNL)</TD><TD > <A HREF = "Section_accelerate.html#acc_3">Section accelerate</A></TD><TD > gpu</TD><TD > lib/gpu</TD></TR>
-<TR ALIGN="center"><TD >GRANULAR</TD><TD > granular systems</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_6<A HREF = "pair_kim.html">>howto</A></TD><TD > pour</TD><TD > -</TD></TR>
-<TR ALIGN="center"><TD >KIM</TD><TD > openKIM potentials</TD><TD > Smirichinski & Elliot & Tadmor (3)</TD><TD > pair_style kim</A></TD><TD > kim</TD><TD > lib/kim</TD></TR>
+<TR ALIGN="center"><TD >GRANULAR</TD><TD > granular systems</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_6">Section_howto</A></TD><TD > pour</TD><TD > -</TD></TR>
+<TR ALIGN="center"><TD >KIM</TD><TD > openKIM potentials</TD><TD > Smirichinski & Elliot & Tadmor (3)</TD><TD > <A HREF = "pair_kim.html">pair_style kim</A></TD><TD > kim</TD><TD > lib/kim</TD></TR>
<TR ALIGN="center"><TD >KSPACE</TD><TD > long-range Coulombic solvers</TD><TD > -</TD><TD > <A HREF = "kspace_style.html">kspace_style</A></TD><TD > peptide</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >MANYBODY</TD><TD > many-body potentials</TD><TD > -</TD><TD > <A HREF = "pair_tersoff.html">pair_style tersoff</A></TD><TD > shear</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >MEAM</TD><TD > modified EAM potential</TD><TD > Greg Wagner (Sandia)</TD><TD > <A HREF = "pair_meam.html">pair_style meam</A></TD><TD > meam</TD><TD > lib/meam</TD></TR>
<TR ALIGN="center"><TD >MC</TD><TD > Monte Carlo options</TD><TD > -</TD><TD > <A HREF = "fix_gcmc.html">fix gcmc</A></TD><TD > -</TD><TD > -</TD></TR>
-<TR ALIGN="center"><TD >MOLECULE</TD><TD > molecular system force fields</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_3">howto</A></TD><TD > peptide</TD><TD > -</TD></TR>
+<TR ALIGN="center"><TD >MOLECULE</TD><TD > molecular system force fields</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_3">Section_howto</A></TD><TD > peptide</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >OPT</TD><TD > optimized pair potentials</TD><TD > Fischer & Richie & Natoli (2)</TD><TD > <A HREF = "Section_accelerate.html#acc_1">Section accelerate</A></TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >PERI</TD><TD > Peridynamics models</TD><TD > Mike Parks (Sandia)</TD><TD > <A HREF = "pair_peri.html">pair_style peri</A></TD><TD > peri</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >POEMS</TD><TD > coupled rigid body motion</TD><TD > Rudra Mukherjee (JPL)</TD><TD > <A HREF = "fix_poems.html">fix poems</A></TD><TD > rigid</TD><TD > lib/poems</TD></TR>
<TR ALIGN="center"><TD >REAX</TD><TD > ReaxFF potential</TD><TD > Aidan Thompson (Sandia)</TD><TD > <A HREF = "pair_reax.html">pair_style reax</A></TD><TD > reax</TD><TD > lib/reax</TD></TR>
-<TR ALIGN="center"><TD >REPLICA</TD><TD > multi-replica methods</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_5">howto</A></TD><TD > tad</TD><TD > -</TD></TR>
+<TR ALIGN="center"><TD >REPLICA</TD><TD > multi-replica methods</TD><TD > -</TD><TD > <A HREF = "Section_howto.html#howto_5">Section_howto</A></TD><TD > tad</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >SHOCK</TD><TD > shock loading methods</TD><TD > -</TD><TD > <A HREF = "fix_msst.html">fix msst</A></TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >SRD</TD><TD > stochastic rotation dynamics</TD><TD > -</TD><TD > <A HREF = "fix_srd.html">fix srd</A></TD><TD > srd</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >XTC</TD><TD > dumps in XTC format</TD><TD > -</TD><TD > <A HREF = "dump.html">dump</A></TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >
</TD></TR></TABLE></DIV>
<P>The "Authors" column lists a name(s) if a specific person is
responible for creating and maintaining the package.
</P>
<P>(1) The FLD package was created by Amit Kumar and Michael Bybee from
Jonathan Higdon's group at UIUC.
</P>
<P>(2) The OPT package was created by James Fischer (High Performance
Technologies), David Richie, and Vincent Natoli (Stone Ridge
Technolgy).
</P>
<P>(3) The KIM package was created by Valeriu Smirichinski, Ryan Elliott,
and Ellad Tadmor (U Minn).
</P>
<P>The "Doc page" column links to either a portion of the
<A HREF = "Section_howto.html">Section_howto</A> of the manual, or an input script
command implemented as part of the package.
</P>
<P>The "Example" column is a sub-directory in the examples directory of
the distribution which has an input script that uses the package.
E.g. "peptide" refers to the examples/peptide directory.
</P>
<P>The "Library" column lists an external library which must be built first and which LAMMPS links to when it is built. These are in the lib directory of the distribution. <A HREF = "Section_start.html#start_3_3">This section</A> of the manual gives details on the 2-step build process with external libraries.
</P>
<HR>
<HR>
<H4><A NAME = "pkg_2"></A>4.2 User packages
</H4>
<P>The current list of user-contributed packages is as follows:
</P>
<DIV ALIGN=center><TABLE BORDER=1 >
<TR ALIGN="center"><TD >Package</TD><TD > Description</TD><TD > Author(s)</TD><TD > Doc page</TD><TD > Example</TD><TD > Pic/movie</TD><TD > Library</TD></TR>
<TR ALIGN="center"><TD >USER-MISC</TD><TD > single-file contributions</TD><TD > USER-MISC/README</TD><TD > USER-MISC/README</TD><TD > -</TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-ATC</TD><TD > atom-to-continuum coupling</TD><TD > Jones & Templeton & Zimmerman (2)</TD><TD > <A HREF = "fix_atc.html">fix atc</A></TD><TD > USER/atc</TD><TD > <A HREF = "http://lammps.sandia.gov/pictures.html#atc">atc</A></TD><TD > lib/atc</TD></TR>
<TR ALIGN="center"><TD >USER-AWPMD</TD><TD > wave-packet MD</TD><TD > Ilya Valuev (JIHT)</TD><TD > <A HREF = "pair_awpmd.html">pair_style awpmd/cut</A></TD><TD > USER/awpmd</TD><TD > -</TD><TD > lib/awpmd</TD></TR>
<TR ALIGN="center"><TD >USER-CG-CMM</TD><TD > coarse-graining model</TD><TD > Axel Kohlmeyer (Temple U)</TD><TD > <A HREF = "pair_sdk.html">pair_style lj/sdk</A></TD><TD > USER/cg-cmm</TD><TD > <A HREF = "http://lammps.sandia.gov/pictures.html#cg">cg</A></TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-COLVARS</TD><TD > collective variables</TD><TD > Fiorin & Henin & Kohlmeyer (3)</TD><TD > <A HREF = "fix_colvars.html">fix colvars</A></TD><TD > USER/colvars</TD><TD > <A HREF = "colvars">colvars</A></TD><TD > lib/colvars</TD></TR>
<TR ALIGN="center"><TD >USER-CUDA</TD><TD > NVIDIA GPU styles</TD><TD > Christian Trott (U Tech Ilmenau)</TD><TD > <A HREF = "Section_accelerate.html#acc_4">Section accelerate</A></TD><TD > USER/cuda</TD><TD > -</TD><TD > lib/cuda</TD></TR>
<TR ALIGN="center"><TD >USER-EFF</TD><TD > electron force field</TD><TD > Andres Jaramillo-Botero (Caltech)</TD><TD > <A HREF = "pair_eff.html">pair_style eff/cut</A></TD><TD > USER/eff</TD><TD > <A HREF = "http://lammps.sandia.gov/movies.html#eff">eff</A></TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-EWALDN</TD><TD > Ewald for 1/R^n</TD><TD > Pieter in' t Veld (BASF)</TD><TD > <A HREF = "kspace_style.html">kspace_style</A></TD><TD > -</TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-MOLFILE</TD><TD > <A HREF = "http://www.ks.uiuc.edu/Research/vmd">VMD</A> molfile plug-ins</TD><TD > Axel Kohlmeyer (Temple U)</TD><TD > <A HREF = "dump_molfile.html">dump molfile</A></TD><TD > -</TD><TD > -</TD><TD > lib/molfile</TD></TR>
<TR ALIGN="center"><TD >USER-OMP</TD><TD > OpenMP threaded styles</TD><TD > Axel Kohlmeyer (Temple U)</TD><TD > <A HREF = "Section_accelerate.html#acc_2">Section accelerate</A></TD><TD > -</TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-REAXC</TD><TD > C version of ReaxFF</TD><TD > Metin Aktulga (LBNL)</TD><TD > <A HREF = "pair_reax_c.html">pair_style reaxc</A></TD><TD > reax</TD><TD > -</TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >USER-SPH</TD><TD > smoothed particle hydrodynamics</TD><TD > Georg Ganzenmuller (EMI)</TD><TD > <A HREF = "USER/sph/SPH_LAMMPS_userguide.pdf">userguide.pdf</A></TD><TD > USER/sph</TD><TD > <A HREF = "http://lammps.sandia.gov/movies.html#sph">sph</A></TD><TD > -</TD></TR>
<TR ALIGN="center"><TD >
</TD></TR></TABLE></DIV>
<P>The "Authors" column lists a name(s) if a specific person is
responible for creating and maintaining the package.
</P>
<P>(2) The ATC package was created by Reese Jones, Jeremy Templeton, and
Jon Zimmerman (Sandia).
</P>
<P>(3) The COLVARS package was created by Axel Kohlmeyer (Temple U) using
the colvars module library written by Giacomo Fiorin (Temple U) and
Jerome Henin (LISM, Marseille, France).
</P>
<P>The "Doc page" column links to either a portion of the
<A HREF = "Section_howto.html">Section_howto</A> of the manual, or an input script
command implemented as part of the package, or to additional
documentation provided witht he package.
</P>
<P>The "Example" column is a sub-directory in the examples directory of
the distribution which has an input script that uses the package.
E.g. "peptide" refers to the examples/peptide directory. USER/cuda
refers to the examples/USER/cuda directory.
</P>
<P>The "Library" column lists an external library which must be built
first and which LAMMPS links to when it is built. These are in the
lib directory of the distribution. <A HREF = "Section_start.html#start_3_3">This
section</A> of the manual gives details on
the 2-step build process with external libraries.
</P>
<P>More details on each package, from the USER-blah/README file
is given below.
</P>
<HR>
<H4>USER-MISC package
</H4>
<P>The files in this package are a potpourri of (mostly) unrelated
features contributed to LAMMPS by users. Each feature is a single
pair of files (*.cpp and *.h).
</P>
<P>More information about each feature can be found by reading its doc
page in the LAMMPS doc directory. The doc page which lists all LAMMPS
input script commands is as follows:
</P>
<P><A HREF = "Section_commands.html#cmd_5">Section_commands</A>
</P>
<P>User-contributed features are listed at the bottom of the fix,
compute, pair, etc sections.
</P>
<P>The list of features and author of each is given in the
src/USER-MISC/README file.
</P>
<P>You should contact the author directly if you have specific questions
about the feature or its coding.
</P>
<HR>
<H4>USER-ATC package
</H4>
<P>This package implements a "fix atc" command which can be used in a
LAMMPS input script. This fix can be employed to either do concurrent
coupling of MD with FE-based physics surrogates or on-the-fly
post-processing of atomic information to continuum fields.
</P>
<P>See the doc page for the fix atc command to get started. At the
bottom of the doc page are many links to additional documentation
contained in the doc/USER/atc directory.
</P>
<P>There are example scripts for using this package in examples/USER/atc.
</P>
<P>This package uses an external library in lib/atc which must be
compiled before making LAMMPS. See the lib/atc/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
</P>
<P>The primary people who created this package are Reese Jones (rjones at
sandia.gov), Jeremy Templeton (jatempl at sandia.gov) and Jon
Zimmerman (jzimmer at sandia.gov) at Sandia. Contact them directly if
you have questions.
</P>
<HR>
<H4>USER-AWPMD package
</H4>
<P>This package contains a LAMMPS implementation of the Antisymmetrized
Wave Packet Molecular Dynamics (AWPMD) method.
</P>
<P>See the doc page for the pair_style awpmd/cut command to get started.
</P>
<P>There are example scripts for using this package in examples/USER/awpmd.
</P>
<P>This package uses an external library in lib/awpmd which must be
compiled before making LAMMPS. See the lib/awpmd/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
</P>
<P>The person who created this package is Ilya Valuev at the JIHT in
Russia (valuev at physik.hu-berlin.de). Contact him directly if you
have questions.
</P>
<HR>
<H4>USER-COLVARS package
</H4>
<P>This package implements the "fix colvars" command which can be
used in a LAMMPS input script.
</P>
<P>This fix allows to use "collective variables" to implement
Adaptive Biasing Force, Metadynamics, Steered MD, Umbrella
Sampling and Restraints. This code consists of two parts:
</P>
<UL><LI>A portable collective variable module library written and maintained by Giacomo Fiorin (ICMS, Temple University, Philadelphia, PA, USA) and Jerome Henin (LISM, CNRS, Marseille, France). This code is located in the directory lib/colvars and needs to be compiled first.
<LI>The colvars fix and an interface layer, exchanges information between LAMMPS and the collective variable module.
</UL>
<P>See the doc page of <A HREF = "fix_colvars.html">fix colvars</A> for more details.
</P>
<P>There are example scripts for using this package in
examples/USER/colvars
</P>
<P>This is a very new interface that does not yet support all
features in the module and will see future optimizations
and improvements. The colvars module library is also available
in NAMD has been thoroughly used and tested there. Bugs and
problems are likely due to the interface layers code.
Thus the current version of this package should be considered
beta quality.
</P>
<P>The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
</P>
<HR>
<H4>USER-CG-CMM package
</H4>
<P>This package implements 3 commands which can be used in a LAMMPS input
script:
</P>
<UL><LI>pair_style lj/sdk
<LI>pair_style lj/sdk/coul/long
<LI>angle_style sdk
</UL>
<P>These styles allow coarse grained MD simulations with the
parametrization of Shinoda, DeVane, Klein, Mol Sim, 33, 27 (2007)
(SDK), with extensions to simulate ionic liquids, electrolytes, lipids
and charged amino acids.
</P>
<P>See the doc pages for these commands for details.
</P>
<P>There are example scripts for using this package in
examples/USER/cg-cmm.
</P>
<P>This is the second generation implementation reducing the the clutter
of the previous version. For many systems with electrostatics, it will
be faster to use pair_style hybrid/overlay with lj/sdk and coul/long
instead of the combined lj/sdk/coul/long style. since the number of
charged atom types is usually small. For any other coulomb
interactions this is now required. To exploit this property, the use
of the kspace_style pppm/cg is recommended over regular pppm. For all
new styles, input file backward compatibility is provided. The old
implementation is still available through appending the /old
suffix. These will be discontinued and removed after the new
implementation has been fully validated.
</P>
<P>The current version of this package should be considered beta
quality. The CG potentials work correctly for "normal" situations, but
have not been testing with all kinds of potential parameters and
simulation systems.
</P>
<P>The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
</P>
<HR>
<H4>USER-CUDA package
</H4>
<P>This package provides acceleration of various LAMMPS pair styles, fix
styles, compute styles, and long-range Coulombics via PPPM for NVIDIA
GPUs.
</P>
<P>See this section of the manual to get started:
</P>
<P><A HREF = "Section_accelerate.html#acc_4">Section_accelerate</A>
</P>
<P>There are example scripts for using this package in
examples/USER/cuda.
</P>
<P>This package uses an external library in lib/cuda which must be
compiled before making LAMMPS. See the lib/cuda/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
</P>
<P>The person who created this package is Christian Trott at the
University of Technology Ilmenau, Germany (christian.trott at
tu-ilmenau.de). Contact him directly if you have questions.
</P>
<HR>
<H4>USER-EFF package
</H4>
<P>This package contains a LAMMPS implementation of the electron Force
Field (eFF) currently under development at Caltech, as described in
A. Jaramillo-Botero, J. Su, Q. An, and W.A. Goddard III, JCC,
2010. The eFF potential was first introduced by Su and Goddard, in
2007.
</P>
<P>eFF can be viewed as an approximation to QM wave packet dynamics and
Fermionic molecular dynamics, combining the ability of electronic
structure methods to describe atomic structure, bonding, and chemistry
in materials, and of plasma methods to describe nonequilibrium
dynamics of large systems with a large number of highly excited
electrons. We classify it as a mixed QM-classical approach rather than
a conventional force field method, which introduces QM-based terms (a
spin-dependent repulsion term to account for the Pauli exclusion
principle and the electron wavefunction kinetic energy associated with
the Heisenberg principle) that reduce, along with classical
electrostatic terms between nuclei and electrons, to the sum of a set
of effective pairwise potentials. This makes eFF uniquely suited to
simulate materials over a wide range of temperatures and pressures
where electronically excited and ionized states of matter can occur
and coexist.
</P>
<P>The necessary customizations to the LAMMPS core are in place to
enable the correct handling of explicit electron properties during
minimization and dynamics.
</P>
<P>See the doc page for the pair_style eff/cut command to get started.
</P>
<P>There are example scripts for using this package in
examples/USER/eff.
</P>
<P>There are auxiliary tools for using this package in tools/eff.
</P>
<P>The person who created this package is Andres Jaramillo-Botero at
CalTech (ajaramil at wag.caltech.edu). Contact him directly if you
have questions.
</P>
<HR>
<H4>USER-EWALDN package
</H4>
<P>This package implements 3 commands which can be used in a LAMMPS input
script: pair_style lj/coul, pair_style buck/coul, and kspace_style
ewald/n.
</P>
<P>The "kspace_style ewald/n" command is similar to standard Ewald for
charges, but also enables the Lennard-Jones interaction, or any 1/r^N
interaction to be of infinite extent, instead of being cutoff. LAMMPS
pair potentials for long-range Coulombic interactions, such as
lj/cut/coul/long can be used with ewald/n. The two new pair_style
commands provide the modifications for the short-range LJ and
Buckingham interactions that can also be used with ewald/n.
</P>
<P>Two other advantages of kspace_style ewald/n are that
</P>
<P>a) it can be used with non-orthogonal (triclinic symmetry) simulation
boxes
</P>
<P>b) it can include long-range summations not just for Coulombic
interactions (1/r), but also for dispersion interactions (1/r^6) and
dipole interactions (1/r^3).
</P>
<P>Neither of these options is currently possible for other kspace styles
such as PPPM and ewald.
</P>
<P>See the doc pages for these commands for details.
</P>
<P>The person who created these files is Pieter in' t Veld while at
Sandia. He is now at BASF (pieter.intveld at basf.com). Contact him
directly if you have questions.
</P>
<HR>
<H4>USER-OMP package
</H4>
<P>This package provides OpenMP multi-threading support and
other optimizations of various LAMMPS pair styles, dihedral
styles, and fix styles.
</P>
<P>See this section of the manual to get started:
</P>
<P><A HREF = "Section_accelerate.html#acc_2">Section_accelerate</A>
</P>
<P>The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
</P>
<HR>
<H4>USER-REAXC package
</H4>
<P>This package contains a implementation for LAMMPS of the ReaxFF force
field. ReaxFF uses distance-dependent bond-order functions to
represent the contributions of chemical bonding to the potential
energy. It was originally developed by Adri van Duin and the Goddard
group at CalTech.
</P>
<P>The USER-REAXC version of ReaxFF (pair_style reax/c), implemented in
C, should give identical or very similar results to pair_style reax,
which is a ReaxFF implementation on top of a Fortran library, a
version of which library was originally authored by Adri van Duin.
</P>
<P>The reax/c version should be somewhat faster and more scalable,
particularly with respect to the charge equilibration calculation. It
should also be easier to build and use since there are no complicating
issues with Fortran memory allocation or linking to a Fortran library.
</P>
<P>For technical details about this implemention of ReaxFF, see
this paper:
</P>
<P>Parallel and Scalable Reactive Molecular Dynamics: Numerical Methods
and Algorithmic Techniques, H. M. Aktulga, J. C. Fogarty,
S. A. Pandit, A. Y. Grama, Parallel Computing, in press (2011).
</P>
<P>See the doc page for the pair_style reax/c command for details
of how to use it in LAMMPS.
</P>
<P>The person who created this package is Hasan Metin Aktulga (hmaktulga
at lbl.gov), while at Purdue University. Contact him directly, or
Aidan Thompson at Sandia (athomps at sandia.gov), if you have
questions.
</P>
<HR>
<H4>USER-SPH package
</H4>
<P>This package implements smoothed particle hydrodynamics (SPH) in
LAMMPS. Currently, the package has the following features:
</P>
<P>* Tait, ideal gas, Lennard-Jones equation of states, full support for
complete (i.e. internal-energy dependent) equations of state
* plain or Monaghans XSPH integration of the equations of motion
* density continuity or density summation to propagate the density field
* commands to set internal energy and density of particles from the
input script
* output commands to access internal energy and density for dumping and
thermo output
</P>
<P>See the file doc/USER/sph/SPH_LAMMPS_userguide.pdf to get started.
</P>
<P>There are example scripts for using this package in examples/USER/sph.
</P>
<P>The person who created this package is Georg Ganzenmuller at the
Fraunhofer-Institute for High-Speed Dynamics, Ernst Mach Institute in
Germany (georg.ganzenmueller at emi.fhg.de). Contact him directly if
you have questions.
</P>
</HTML>
diff --git a/doc/Section_packages.txt b/doc/Section_packages.txt
index 8e9556f82..e3575fd5f 100644
--- a/doc/Section_packages.txt
+++ b/doc/Section_packages.txt
@@ -1,456 +1,456 @@
"Previous Section"_Section_commands.html - "LAMMPS WWW Site"_lws -
"LAMMPS Documentation"_ld - "LAMMPS Commands"_lc - "Next
Section"_Section_accelerate.html :c
:link(lws,http://lammps.sandia.gov)
:link(ld,Manual.html)
:link(lc,Section_commands.html#comm)
:line
4. Packages :h3
This section gives a quick overview of the add-on packages that extend
LAMMPS functionality.
4.1 "Standard packages"_#pkg_1
4.2 "User packages"_#pkg_2 :all(b)
LAMMPS includes many optional packages, which 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" from within the src
directory of the LAMMPS distribution.
See "Section_start 3"_Section_start.html#start_3 of the manual for
details on how to include/exclude specific packages as part of the
LAMMPS build process, and for more details about the differences
between standard packages and user packages in LAMMPS.
Below, the packages currently availabe in LAMMPS are listed. For
standard packages, just a one-line description is given. For user
packages, more details are provided.
:line
:line
4.1 Standard packages :h4,link(pkg_1)
The current list of standard packages is as follows:
Package, Description, Author(s), Doc page, Example, Library
-ASPHERE, aspherical particles, -, "howto"_Section_howto.html#howto_14, ellipse, -
+ASPHERE, aspherical particles, -, "Section_howto"_Section_howto.html#howto_14, ellipse, -
CLASS2, class 2 force fields, -, "pair_style lj/class2"_pair_class2.html, -, -
COLLOID, colloidal particles, -, "atom_style colloid"_atom_style.html, colloid, -
DIPOLE, point dipole particles, -, "pair_style dipole/cut"_pair_dipole.html, dipole, -
FLD, Fast Lubrication Dynamics, Kumar & Bybee & Higdon (1), "pair_style lubricateU"_pair_lubricateU.html, -, -
GPU, GPU-enabled potentials, Mike Brown (ORNL), "Section accelerate"_Section_accelerate.html#acc_3, gpu, lib/gpu
-GRANULAR, granular systems, -, "howto"_Section_howto.html#howto_6, pour, -
-KIM, openKIM potentials, Smirichinski & Elliot & Tadmor (3), pair_style kim"_pair_kim.html, kim, lib/kim
+GRANULAR, granular systems, -, "Section_howto"_Section_howto.html#howto_6, pour, -
+KIM, openKIM potentials, Smirichinski & Elliot & Tadmor (3), "pair_style kim"_pair_kim.html, kim, lib/kim
KSPACE, long-range Coulombic solvers, -, "kspace_style"_kspace_style.html, peptide, -
MANYBODY, many-body potentials, -, "pair_style tersoff"_pair_tersoff.html, shear, -
MEAM, modified EAM potential, Greg Wagner (Sandia), "pair_style meam"_pair_meam.html, meam, lib/meam
MC, Monte Carlo options, -, "fix gcmc"_fix_gcmc.html, -, -
-MOLECULE, molecular system force fields, -, "howto"_Section_howto.html#howto_3, peptide, -
+MOLECULE, molecular system force fields, -, "Section_howto"_Section_howto.html#howto_3, peptide, -
OPT, optimized pair potentials, Fischer & Richie & Natoli (2), "Section accelerate"_Section_accelerate.html#acc_1, -, -
PERI, Peridynamics models, Mike Parks (Sandia), "pair_style peri"_pair_peri.html, peri, -
POEMS, coupled rigid body motion, Rudra Mukherjee (JPL), "fix poems"_fix_poems.html, rigid, lib/poems
REAX, ReaxFF potential, Aidan Thompson (Sandia), "pair_style reax"_pair_reax.html, reax, lib/reax
-REPLICA, multi-replica methods, -, "howto"_Section_howto.html#howto_5, tad, -
+REPLICA, multi-replica methods, -, "Section_howto"_Section_howto.html#howto_5, tad, -
SHOCK, shock loading methods, -, "fix msst"_fix_msst.html, -, -
SRD, stochastic rotation dynamics, -, "fix srd"_fix_srd.html, srd, -
XTC, dumps in XTC format, -, "dump"_dump.html, -, -
:tb(ea=c)
The "Authors" column lists a name(s) if a specific person is
responible for creating and maintaining the package.
(1) The FLD package was created by Amit Kumar and Michael Bybee from
Jonathan Higdon's group at UIUC.
(2) The OPT package was created by James Fischer (High Performance
Technologies), David Richie, and Vincent Natoli (Stone Ridge
Technolgy).
(3) The KIM package was created by Valeriu Smirichinski, Ryan Elliott,
and Ellad Tadmor (U Minn).
The "Doc page" column links to either a portion of the
"Section_howto"_Section_howto.html of the manual, or an input script
command implemented as part of the package.
The "Example" column is a sub-directory in the examples directory of
the distribution which has an input script that uses the package.
E.g. "peptide" refers to the examples/peptide directory.
The "Library" column lists an external library which must be built first and which LAMMPS links to when it is built. These are in the lib directory of the distribution. "This section"_Section_start.html#start_3_3 of the manual gives details on the 2-step build process with external libraries.
:line
:line
4.2 User packages :h4,link(pkg_2)
The current list of user-contributed packages is as follows:
Package, Description, Author(s), Doc page, Example, Pic/movie, Library
USER-MISC, single-file contributions, USER-MISC/README, USER-MISC/README, -, -, -
USER-ATC, atom-to-continuum coupling, Jones & Templeton & Zimmerman (2), "fix atc"_fix_atc.html, USER/atc, "atc"_atc, lib/atc
USER-AWPMD, wave-packet MD, Ilya Valuev (JIHT), "pair_style awpmd/cut"_pair_awpmd.html, USER/awpmd, -, lib/awpmd
USER-CG-CMM, coarse-graining model, Axel Kohlmeyer (Temple U), "pair_style lj/sdk"_pair_sdk.html, USER/cg-cmm, "cg"_cg, -
USER-COLVARS, collective variables, Fiorin & Henin & Kohlmeyer (3), "fix colvars"_fix_colvars.html, USER/colvars, "colvars"_colvars, lib/colvars
USER-CUDA, NVIDIA GPU styles, Christian Trott (U Tech Ilmenau), "Section accelerate"_Section_accelerate.html#acc_4, USER/cuda, -, lib/cuda
USER-EFF, electron force field, Andres Jaramillo-Botero (Caltech), "pair_style eff/cut"_pair_eff.html, USER/eff, "eff"_eff, -
USER-EWALDN, Ewald for 1/R^n, Pieter in' t Veld (BASF), "kspace_style"_kspace_style.html, -, -, -
USER-MOLFILE, "VMD"_VMD molfile plug-ins, Axel Kohlmeyer (Temple U), "dump molfile"_dump_molfile.html, -, -, lib/molfile
USER-OMP, OpenMP threaded styles, Axel Kohlmeyer (Temple U), "Section accelerate"_Section_accelerate.html#acc_2, -, -, -
USER-REAXC, C version of ReaxFF, Metin Aktulga (LBNL), "pair_style reaxc"_pair_reax_c.html, reax, -, -
USER-SPH, smoothed particle hydrodynamics, Georg Ganzenmuller (EMI), "userguide.pdf"_USER/sph/SPH_LAMMPS_userguide.pdf, USER/sph, "sph"_sph, -
:tb(ea=c)
:link(atc,http://lammps.sandia.gov/pictures.html#atc)
:link(cg,http://lammps.sandia.gov/pictures.html#cg)
:link(eff,http://lammps.sandia.gov/movies.html#eff)
:link(sph,http://lammps.sandia.gov/movies.html#sph)
:link(VMD,http://www.ks.uiuc.edu/Research/vmd)
The "Authors" column lists a name(s) if a specific person is
responible for creating and maintaining the package.
(2) The ATC package was created by Reese Jones, Jeremy Templeton, and
Jon Zimmerman (Sandia).
(3) The COLVARS package was created by Axel Kohlmeyer (Temple U) using
the colvars module library written by Giacomo Fiorin (Temple U) and
Jerome Henin (LISM, Marseille, France).
The "Doc page" column links to either a portion of the
"Section_howto"_Section_howto.html of the manual, or an input script
command implemented as part of the package, or to additional
documentation provided witht he package.
The "Example" column is a sub-directory in the examples directory of
the distribution which has an input script that uses the package.
E.g. "peptide" refers to the examples/peptide directory. USER/cuda
refers to the examples/USER/cuda directory.
The "Library" column lists an external library which must be built
first and which LAMMPS links to when it is built. These are in the
lib directory of the distribution. "This
section"_Section_start.html#start_3_3 of the manual gives details on
the 2-step build process with external libraries.
More details on each package, from the USER-blah/README file
is given below.
:line
USER-MISC package :h4
The files in this package are a potpourri of (mostly) unrelated
features contributed to LAMMPS by users. Each feature is a single
pair of files (*.cpp and *.h).
More information about each feature can be found by reading its doc
page in the LAMMPS doc directory. The doc page which lists all LAMMPS
input script commands is as follows:
"Section_commands"_Section_commands.html#cmd_5
User-contributed features are listed at the bottom of the fix,
compute, pair, etc sections.
The list of features and author of each is given in the
src/USER-MISC/README file.
You should contact the author directly if you have specific questions
about the feature or its coding.
:line
USER-ATC package :h4
This package implements a "fix atc" command which can be used in a
LAMMPS input script. This fix can be employed to either do concurrent
coupling of MD with FE-based physics surrogates or on-the-fly
post-processing of atomic information to continuum fields.
See the doc page for the fix atc command to get started. At the
bottom of the doc page are many links to additional documentation
contained in the doc/USER/atc directory.
There are example scripts for using this package in examples/USER/atc.
This package uses an external library in lib/atc which must be
compiled before making LAMMPS. See the lib/atc/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
The primary people who created this package are Reese Jones (rjones at
sandia.gov), Jeremy Templeton (jatempl at sandia.gov) and Jon
Zimmerman (jzimmer at sandia.gov) at Sandia. Contact them directly if
you have questions.
:line
USER-AWPMD package :h4
This package contains a LAMMPS implementation of the Antisymmetrized
Wave Packet Molecular Dynamics (AWPMD) method.
See the doc page for the pair_style awpmd/cut command to get started.
There are example scripts for using this package in examples/USER/awpmd.
This package uses an external library in lib/awpmd which must be
compiled before making LAMMPS. See the lib/awpmd/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
The person who created this package is Ilya Valuev at the JIHT in
Russia (valuev at physik.hu-berlin.de). Contact him directly if you
have questions.
:line
USER-COLVARS package :h4
This package implements the "fix colvars" command which can be
used in a LAMMPS input script.
This fix allows to use "collective variables" to implement
Adaptive Biasing Force, Metadynamics, Steered MD, Umbrella
Sampling and Restraints. This code consists of two parts:
A portable collective variable module library written and maintained by Giacomo Fiorin (ICMS, Temple University, Philadelphia, PA, USA) and Jerome Henin (LISM, CNRS, Marseille, France). This code is located in the directory lib/colvars and needs to be compiled first.
The colvars fix and an interface layer, exchanges information between LAMMPS and the collective variable module. :ul
See the doc page of "fix colvars"_fix_colvars.html for more details.
There are example scripts for using this package in
examples/USER/colvars
This is a very new interface that does not yet support all
features in the module and will see future optimizations
and improvements. The colvars module library is also available
in NAMD has been thoroughly used and tested there. Bugs and
problems are likely due to the interface layers code.
Thus the current version of this package should be considered
beta quality.
The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
:line
USER-CG-CMM package :h4
This package implements 3 commands which can be used in a LAMMPS input
script:
pair_style lj/sdk
pair_style lj/sdk/coul/long
angle_style sdk :ul
These styles allow coarse grained MD simulations with the
parametrization of Shinoda, DeVane, Klein, Mol Sim, 33, 27 (2007)
(SDK), with extensions to simulate ionic liquids, electrolytes, lipids
and charged amino acids.
See the doc pages for these commands for details.
There are example scripts for using this package in
examples/USER/cg-cmm.
This is the second generation implementation reducing the the clutter
of the previous version. For many systems with electrostatics, it will
be faster to use pair_style hybrid/overlay with lj/sdk and coul/long
instead of the combined lj/sdk/coul/long style. since the number of
charged atom types is usually small. For any other coulomb
interactions this is now required. To exploit this property, the use
of the kspace_style pppm/cg is recommended over regular pppm. For all
new styles, input file backward compatibility is provided. The old
implementation is still available through appending the /old
suffix. These will be discontinued and removed after the new
implementation has been fully validated.
The current version of this package should be considered beta
quality. The CG potentials work correctly for "normal" situations, but
have not been testing with all kinds of potential parameters and
simulation systems.
The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
:line
USER-CUDA package :h4
This package provides acceleration of various LAMMPS pair styles, fix
styles, compute styles, and long-range Coulombics via PPPM for NVIDIA
GPUs.
See this section of the manual to get started:
"Section_accelerate"_Section_accelerate.html#acc_4
There are example scripts for using this package in
examples/USER/cuda.
This package uses an external library in lib/cuda which must be
compiled before making LAMMPS. See the lib/cuda/README file and the
LAMMPS manual for information on building LAMMPS with external
libraries.
The person who created this package is Christian Trott at the
University of Technology Ilmenau, Germany (christian.trott at
tu-ilmenau.de). Contact him directly if you have questions.
:line
USER-EFF package :h4
This package contains a LAMMPS implementation of the electron Force
Field (eFF) currently under development at Caltech, as described in
A. Jaramillo-Botero, J. Su, Q. An, and W.A. Goddard III, JCC,
2010. The eFF potential was first introduced by Su and Goddard, in
2007.
eFF can be viewed as an approximation to QM wave packet dynamics and
Fermionic molecular dynamics, combining the ability of electronic
structure methods to describe atomic structure, bonding, and chemistry
in materials, and of plasma methods to describe nonequilibrium
dynamics of large systems with a large number of highly excited
electrons. We classify it as a mixed QM-classical approach rather than
a conventional force field method, which introduces QM-based terms (a
spin-dependent repulsion term to account for the Pauli exclusion
principle and the electron wavefunction kinetic energy associated with
the Heisenberg principle) that reduce, along with classical
electrostatic terms between nuclei and electrons, to the sum of a set
of effective pairwise potentials. This makes eFF uniquely suited to
simulate materials over a wide range of temperatures and pressures
where electronically excited and ionized states of matter can occur
and coexist.
The necessary customizations to the LAMMPS core are in place to
enable the correct handling of explicit electron properties during
minimization and dynamics.
See the doc page for the pair_style eff/cut command to get started.
There are example scripts for using this package in
examples/USER/eff.
There are auxiliary tools for using this package in tools/eff.
The person who created this package is Andres Jaramillo-Botero at
CalTech (ajaramil at wag.caltech.edu). Contact him directly if you
have questions.
:line
USER-EWALDN package :h4
This package implements 3 commands which can be used in a LAMMPS input
script: pair_style lj/coul, pair_style buck/coul, and kspace_style
ewald/n.
The "kspace_style ewald/n" command is similar to standard Ewald for
charges, but also enables the Lennard-Jones interaction, or any 1/r^N
interaction to be of infinite extent, instead of being cutoff. LAMMPS
pair potentials for long-range Coulombic interactions, such as
lj/cut/coul/long can be used with ewald/n. The two new pair_style
commands provide the modifications for the short-range LJ and
Buckingham interactions that can also be used with ewald/n.
Two other advantages of kspace_style ewald/n are that
a) it can be used with non-orthogonal (triclinic symmetry) simulation
boxes
b) it can include long-range summations not just for Coulombic
interactions (1/r), but also for dispersion interactions (1/r^6) and
dipole interactions (1/r^3).
Neither of these options is currently possible for other kspace styles
such as PPPM and ewald.
See the doc pages for these commands for details.
The person who created these files is Pieter in' t Veld while at
Sandia. He is now at BASF (pieter.intveld at basf.com). Contact him
directly if you have questions.
:line
USER-OMP package :h4
This package provides OpenMP multi-threading support and
other optimizations of various LAMMPS pair styles, dihedral
styles, and fix styles.
See this section of the manual to get started:
"Section_accelerate"_Section_accelerate.html#acc_2
The person who created this package is Axel Kohlmeyer at Temple U
(akohlmey at gmail.com). Contact him directly if you have questions.
:line
USER-REAXC package :h4
This package contains a implementation for LAMMPS of the ReaxFF force
field. ReaxFF uses distance-dependent bond-order functions to
represent the contributions of chemical bonding to the potential
energy. It was originally developed by Adri van Duin and the Goddard
group at CalTech.
The USER-REAXC version of ReaxFF (pair_style reax/c), implemented in
C, should give identical or very similar results to pair_style reax,
which is a ReaxFF implementation on top of a Fortran library, a
version of which library was originally authored by Adri van Duin.
The reax/c version should be somewhat faster and more scalable,
particularly with respect to the charge equilibration calculation. It
should also be easier to build and use since there are no complicating
issues with Fortran memory allocation or linking to a Fortran library.
For technical details about this implemention of ReaxFF, see
this paper:
Parallel and Scalable Reactive Molecular Dynamics: Numerical Methods
and Algorithmic Techniques, H. M. Aktulga, J. C. Fogarty,
S. A. Pandit, A. Y. Grama, Parallel Computing, in press (2011).
See the doc page for the pair_style reax/c command for details
of how to use it in LAMMPS.
The person who created this package is Hasan Metin Aktulga (hmaktulga
at lbl.gov), while at Purdue University. Contact him directly, or
Aidan Thompson at Sandia (athomps at sandia.gov), if you have
questions.
:line
USER-SPH package :h4
This package implements smoothed particle hydrodynamics (SPH) in
LAMMPS. Currently, the package has the following features:
* Tait, ideal gas, Lennard-Jones equation of states, full support for
complete (i.e. internal-energy dependent) equations of state
* plain or Monaghans XSPH integration of the equations of motion
* density continuity or density summation to propagate the density field
* commands to set internal energy and density of particles from the
input script
* output commands to access internal energy and density for dumping and
thermo output
See the file doc/USER/sph/SPH_LAMMPS_userguide.pdf to get started.
There are example scripts for using this package in examples/USER/sph.
The person who created this package is Georg Ganzenmuller at the
Fraunhofer-Institute for High-Speed Dynamics, Ernst Mach Institute in
Germany (georg.ganzenmueller at emi.fhg.de). Contact him directly if
you have questions.
diff --git a/doc/Section_start.html b/doc/Section_start.html
index e071e8182..eef8e51a8 100644
--- a/doc/Section_start.html
+++ b/doc/Section_start.html
@@ -1,1323 +1,1331 @@
<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 = "#start_1">What's in the LAMMPS distribution</A><BR>
2.2 <A HREF = "#start_2">Making LAMMPS</A><BR>
2.3 <A HREF = "#start_3">Making LAMMPS with optional packages</A><BR>
2.4 <A HREF = "#start_4">Building LAMMPS via the Make.py script</A><BR>
2.5 <A HREF = "#start_5">Building LAMMPS as a library</A><BR>
2.6 <A HREF = "#start_6">Running LAMMPS</A><BR>
2.7 <A HREF = "#start_7">Command-line options</A><BR>
2.8 <A HREF = "#start_8">Screen output</A><BR>
2.9 <A HREF = "#start_9">Tips for users of previous versions</A> <BR>
<HR>
<HR>
<H4><A NAME = "start_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 one of the Windows executables from the download page,
then you just get a single file:
</P>
<PRE>lmp_windows.exe
</PRE>
<P>Skip to the <A HREF = "#start_6">Running LAMMPS</A> sections for info on how to
launch these executables on a Windows box.
</P>
<P>The Windows executables for serial or parallel only include 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 from source code using Microsoft Visual Studio,
as described in the next section.
</P>
<HR>
<H4><A NAME = "start_2"></A>2.2 Making LAMMPS
</H4>
<P>This section has the following sub-sections:
</P>
<UL><LI><A HREF = "#start_2_1">Read this first</A>
<LI><A HREF = "#start_2_2">Steps to build a LAMMPS executable</A>
<LI><A HREF = "#start_2_3">Common errors that can occur when making LAMMPS</A>
<LI><A HREF = "#start_2_4">Additional build tips</A>
<LI><A HREF = "#start_2_5">Building for a Mac</A>
<LI><A HREF = "#start_2_6">Building for Windows</A>
</UL>
<HR>
<A NAME = "start_2_1"></A><B><I>Read this first:</I></B>
<P>Building LAMMPS can be non-trivial. You may need to edit a makefile,
there are compiler options to consider, additional libraries can be
used (MPI, FFT, JPEG), LAMMPS packages may be included or excluded,
some of these packages use auxiliary libraries which need to be
pre-built, etc.
</P>
<P>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 have are often not
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 post a question to the <A HREF = "http://lammps.sandia.gov/mail.html">LAMMPS mail
list</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 can include it in the LAMMPS distribution.
</P>
<HR>
<A NAME = "start_2_2"></A><B><I>Steps to build a LAMMPS executable:</I></B>
<P><B>Step 0</B>
</P>
<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 many 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
or
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>
<P>Note that by default only a few of LAMMPS optional packages are
installed. To build LAMMPS with optional packages, see <A HREF = "#start_3">this
section</A> below.
</P>
<P><B>Step 1</B>
</P>
<P>If Step 0 did not work, you will need to create a low-level Makefile
for your machine, like Makefile.foo. You should make a copy of an
existing src/MAKE/Makefile.* as a starting point. The only portions
of the file you need to edit are the first line, the "compiler/linker
settings" section, and the "LAMMPS-specific settings" section.
</P>
<P><B>Step 2</B>
</P>
<P>Change the first line of src/MAKE/Makefile.foo to list the word "foo"
after the "#", and whatever other options it will set. This is the
line you will see if you just type "make".
</P>
<P><B>Step 3</B>
</P>
<P>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 commercial Intel icc
compiler, which can be downloaded 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, then you'll need to create a Makefile.foo patterned
after Makefile.storm, which uses different rules that do not involve
dependency files. Note that when you build LAMMPS for the first time
on a new platform, a long list of *.d files will be printed out
rapidly. This is not an error; it is the Makefile doing its normal
creation of dependencies.
</P>
<P><B>Step 4</B>
</P>
<P>The "system-specific settings" section has several parts. Note that
if you change any -D setting in this section, you should do a full
re-compile, after typing "make clean" (which will describe different
clean options).
</P>
<P>The LMP_INC variable is used to include options that turn on ifdefs
within the LAMMPS code. The options that are currently recogized are:
</P>
<UL><LI>-DLAMMPS_GZIP
<LI>-DLAMMPS_JPEG
<LI>-DLAMMPS_MEMALIGN
<LI>-DLAMMPS_XDR
<LI>-DLAMMPS_SMALLBIG
<LI>-DLAMMPS_BIGBIG
<LI>-DLAMMPS_SMALLSMALL
<LI>-DLAMMPS_LONGLONG_TO_LONG
<LI>-DPACK_ARRAY
<LI>-DPACK_POINTER
<LI>-DPACK_MEMCPY
</UL>
<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.
</P>
<P>If you use -DLAMMPS_JPEG, the <A HREF = "dump.html">dump image</A> command will be
able to write out JPEG image files. If not, it will only be able to
write out text-based PPM image files. For JPEG files, you must also
link LAMMPS with a JPEG library, as described below.
</P>
<P>Using -DLAMMPS_MEMALIGN=<bytes> enables the use of the
posix_memalign() call instead of malloc() when large chunks or memory
are allocated by LAMMPS. This can help to make more efficient use of
vector instructions of modern CPUS, since dynamically allocated memory
has to be aligned on larger than default byte boundaries (e.g. 16
bytes instead of 8 bytes on x86 type platforms) for optimal
performance.
</P>
<P>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>Use at most one of the -DLAMMPS_SMALLBIG, -DLAMMPS_BIGBIG,
-D-DLAMMPS_SMALLSMALL settings. The default is -DLAMMPS_SMALLBIG.
-These refer to use of 4-byte (small) vs 8-byte (big) integers within
-LAMMPS, as described in src/lmptype.h. The only reason to use the
-BIGBIG setting is to enable simulation of huge molecular systems with
-more than 2 billion atoms. The only reason to use the SMALLSMALL
-setting is if your machine does not support 64-bit integers.
+These settings refer to use of 4-byte (small) vs 8-byte (big) integers
+within LAMMPS, as specified in src/lmptype.h. The only reason to use
+the BIGBIG setting is to enable simulation of huge molecular systems
+with more than 2 billion atoms or to allow moving atoms to wrap back
+through a periodic box more than 512 times. The only reason to use
+the SMALLSMALL setting is if your machine does not support 64-bit
+integers. See the <A HREF = "#start_2_4">Additional build tips</A> section below
+for more details.
</P>
<P>The -DLAMMPS_LONGLONG_TO_LONG setting may be needed if your system or
MPI version does not recognize "long long" data types. In this case a
"long" data type is likely already 64-bits, in which case this setting
will convert to that data type.
</P>
<P>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. See the
<A HREF = "kspace_style.html">kspace_style</A> command for info about PPPM. See
Step 6 below for info about building LAMMPS with an FFT library.
</P>
<P><B>Step 5</B>
</P>
<P>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 should be able to leave these 3
variables blank; the MPI wrapper knows where to find the needed files.
If not, and MPI is installed on your system in the usual place (under
/usr/local), you also may not need to specify these 3 variables. On
some large parallel machines which use "modules" for their
compile/link environements, you may simply need to include the correct
module in your build environment. Or the parallel machine may have a
vendor-provided MPI which the compiler has no trouble finding.
</P>
<P>Failing this, with these 3 variables you can specify where the mpi.h
file (MPI_INC) and the MPI library file (MPI_PATH) are found and the
name of the library file (MPI_LIB).
</P>
<P>If you are installing MPI yourself, we recommend Argonne's MPICH2
or OpenMPI. MPICH can be downloaded from the <A HREF = "http://www.mcs.anl.gov/research/projects/mpich2/">Argonne MPI
site</A>. OpenMPI can
be downloaded from the <A HREF = "http://www.open-mpi.org">OpenMPI site</A>.
Other MPI packages 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 is likely to be faster
than a self-installed MPICH or OpenMPI, so find out how to build
and link with it. If you use MPICH or OpenMPI, 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 to run LAMMPS on a single processor, you can use the
dummy MPI library provided in src/STUBS, since you don't need a true
MPI library installed on your system. See the
src/MAKE/Makefile.serial file for how to specify the 3 MPI variables
in this case. You will also need to build the STUBS library for your
platform before making LAMMPS itself. From the src directory, type
"make stubs", or from the STUBS dir, type "make" and it should 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 provides a CPU timer function called
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><B>Step 6</B>
</P>
<P>The 3 FFT variables allow you to specify an FFT library which LAMMPS
uses (for performing 1d FFTs) when running the particle-particle
particle-mesh (PPPM) option for long-range Coulombics via the
<A HREF = "kspace_style.html">kspace_style</A> command.
</P>
<P>LAMMPS supports various open-source or vendor-supplied FFT libraries
for this purpose. If you leave these 3 variables blank, LAMMPS will
use the open-source <A HREF = "http://kissfft.sf.net">KISS FFT library</A>, which is
included in the LAMMPS distribution. This library is portable to all
platforms and for typical LAMMPS simulations is almost as fast as FFTW
or vendor optimized libraries. If you are not including the KSPACE
package in your build, you can also leave the 3 variables blank.
</P>
<P>Otherwise, select which kinds of FFTs to use as part of the FFT_INC
setting by a switch of the form -DFFT_XXX. Recommended values for XXX
are: MKL, SCSL, FFTW2, and FFTW3. Legacy options are: INTEL, SGI,
ACML, and T3E. For backward compatability, using -DFFT_FFTW will use
the FFTW2 library. Using -DFFT_NONE will use the KISS library
described above.
</P>
<P>You may also need to set the FFT_INC, FFT_PATH, and FFT_LIB variables,
so the compiler and linker can find the needed FFT header and library
files. Note that on some large parallel machines which use "modules"
for their compile/link environements, you may simply need to include
the correct module in your build environment. Or the parallel machine
may have a vendor-provided FFT library which the compiler has no
trouble finding.
</P>
<P>FFTW is a fast, portable library that should also work on any
platform. You can download it from
<A HREF = "http://www.fftw.org">www.fftw.org</A>. Both the legacy version 2.1.X and
the newer 3.X versions are supported as -DFFT_FFTW2 or -DFFT_FFTW3.
Building FFTW for your box should be as simple as ./configure; make.
Note that on some platforms FFTW2 has been pre-installed, and uses
renamed files indicating the precision it was compiled with,
e.g. sfftw.h, or dfftw.h instead of fftw.h. In this case, you can
specify an additional define variable for FFT_INC called -DFFTW_SIZE,
which will select the correct include file. In this case, for FFT_LIB
you must also manually specify the correct library, namely -lsfftw or
-ldfftw.
</P>
<P>The FFT_INC variable also allows for a -DFFT_SINGLE setting that will
use single-precision FFTs with PPPM, which can speed-up long-range
calulations, particularly in parallel or on GPUs. Fourier transform
and related PPPM operations are somewhat insensitive to floating point
truncation errors and thus do not always need to be performed in
double precision. Using the -DFFT_SINGLE setting trades off a little
accuracy for reduced memory use and parallel communication costs for
transposing 3d FFT data. Note that single precision FFTs have only
been tested with the FFTW3, FFTW2, MKL, and KISS FFT options.
</P>
<P><B>Step 7</B>
</P>
<P>The 3 JPG variables allow you to specify a JPEG library which LAMMPS
uses when writing out JPEG files via the <A HREF = "dump_image.html">dump image</A>
command. These can be left blank if you do not use the -DLAMMPS_JPEG
switch discussed above in Step 4, since in that case JPEG output will
be disabled.
</P>
<P>A standard JPEG library usually goes by the name libjpeg.a and has an
associated header file jpeglib.h. Whichever JPEG library you have on
your platform, you'll need to set the appropriate JPG_INC, JPG_PATH,
and JPG_LIB variables, so that the compiler and linker can find it.
</P>
<P>As before, if these header and library files are in the usual place on
your machine, you may not need to set these variables.
</P>
<P><B>Step 8</B>
</P>
<P>Note that by default only a few of LAMMPS optional packages are
installed. To build LAMMPS with optional packages, see <A HREF = "#start_3">this
section</A> below, before proceeding to Step 9.
</P>
<P><B>Step 9</B>
</P>
<P>That's it. Once you have a correct Makefile.foo, you have installed
the optional LAMMPS packages you want to include in your build, and
you have pre-built any other needed libraries (e.g. MPI, FFT, package
libraries), all you need to do from the src directory is type
something like this:
</P>
<PRE>make foo
or
gmake foo
</PRE>
<P>You should get the executable lmp_foo when the build is complete.
</P>
<HR>
<A NAME = "start_2_3"></A><B><I>Errors that can occur when making LAMMPS:</I></B>
<P>IMPORTANT NOTE: If an error occurs when building LAMMPS, the compiler
or linker will state very explicitly what the problem is. The error
message should give you a hint as to which of the steps above has
failed, and what you need to do in order to fix it. Building a code
with a Makefile is a very logical process. The compiler and linker
need to find the appropriate files and those files need to be
compatible with LAMMPS source files. When a make fails, there is
usually a very simple reason, which you or a local expert will need to
fix.
</P>
<P>Here are two non-obvious errors that can occur:
</P>
<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 native 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 a pre-generated
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. Note that you should
include/exclude any desired optional packages before using the "make
makelist" command.
</P>
<P>(2) If you get an error that says something like 'identifier "atoll"
is undefined', then your machine does not support "long long"
integers. Try using the -DLAMMPS_LONGLONG_TO_LONG setting described
above in Step 4.
</P>
<HR>
<A NAME = "start_2_4"></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_target 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) 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 or MPI implementation 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>(3) Changing the LAMMPS size limits via -DLAMMPS_SMALLBIG or
+-DLAMMPS_BIBIG or -DLAMMPS_SMALLSMALL
+</P>
+<P>As explained above, any of these 3 settings can be specified on the
+LMP_INC line in your low-level src/MAKE/Makefile.foo.
+</P>
+<P>The default is -DLAMMPS_SMALLBIG which allows for systems with up to
+2^63 atoms and timesteps (about 9 billion billion). The atom limit is
+for atomic systems that do not require atom IDs. For molecular
+models, which require atom IDs, the limit is 2^31 atoms (about 2
+billion). With this setting, image flags are stored in 32-bit
+integers, which means for 3 dimensions that atoms can only wrap around
+a periodic box at most 512 times. If atoms move through the periodic
+box more than this limit, the image flags will "roll over", e.g. from
+511 to -512, which can cause diagnostics like the mean-squared
+displacement, as calculated by the <A HREF = "compute_msd.html">compute msd</A>
+command, to be faulty.
+</P>
+<P>To allow for larger molecular systems or larger image flags, compile
+with -DLAMMPS_BIGBIG. This enables molecular systems with up to 2^63
+atoms (about 9 billion billion). And image flags will not "roll over"
+until they reach 2^20 = 1048576.
+</P>
+<P>IMPORTANT NOTE: As of 6/2012, the BIGBIG setting does not yet enable
+molecular systems to grow as large as 2^63. Only the image flag roll
+over is currently affected by this compile option.
+</P>
+<P>If your system does not support 8-byte integers, you will need to
+compile with the -DLAMMPS_SMALLSMALL setting. This will restrict your
+total number of atoms (for atomic or molecular models) and timesteps
+to 2^31 (about 2 billion). Image flags will roll over at 2^9 = 512.
</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.
+system sizes. These need to be consistent with the associated C data
+types, or else LAMMPS will generate a run-time error.
</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
+basis is limited by 4-byte integer storage to 2^31 atoms per processor
+(about 2 billion). This 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>
<A NAME = "start_2_5"></A><B><I>Building for a Mac:</I></B>
<P>OS X is BSD Unix, so it should just work. See the
src/MAKE/Makefile.mac file.
</P>
<HR>
<A NAME = "start_2_6"></A><B><I>Building for Windows:</I></B>
<P>The LAMMPS download page has an option to download both a serial and
parallel pre-built Windows exeutable. See the <A HREF = "#start_6">Running
LAMMPS</A> section for instructions for running these
executables on a Windows box.
</P>
<P>The pre-built executables are built with a subset of the available
pacakges; see the download page for the list. If you want
a Windows version with specific packages included and excluded,
you can build it yourself.
</P>
<P>One way to do this is install and use cygwin to build LAMMPS with a
standard Linus make, just as you would on any Linux box; see
src/MAKE/Makefile.cygwin.
</P>
<P>The other way to do this is using Visual Studio and project files.
See the src/WINDOWS directory and its README.txt file for instructions
on both a basic build and a customized build with pacakges you select.
</P>
<HR>
<H4><A NAME = "start_3"></A>2.3 Making LAMMPS with optional packages
</H4>
<P>This section has the following sub-sections:
</P>
<UL><LI><A HREF = "#start_3_1">Package basics</A>
<LI><A HREF = "#start_3_2">Including/excluding packages</A>
<LI><A HREF = "#start_3_3">Packages that require extra libraries</A>
<LI><A HREF = "#start_3_4">Additional Makefile settings for extra libraries</A>
</UL>
<HR>
<A NAME = "start_3_1"></A><B><I>Package basics:</I></B>
<P>The source code for LAMMPS is structured as a 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" from within
the src directory of the LAMMPS distribution.
</P>
<P>If you use a command in a LAMMPS input script that is specific to a
particular package, you must have built LAMMPS with that package, else
you will get an error that the style is invalid or the command is
unknown. Every command's doc page specfies if it is part of a
package. You can also type
</P>
<PRE>lmp_machine -h
</PRE>
<P>to run your executable with the optional <A HREF = "#start_7">-h command-line
switch</A> for "help", which will list the styles and commands
known to your executable.
</P>
<P>There are two kinds of packages in LAMMPS, standard and user packages.
More information about the contents of standard and user packages is
given in <A HREF = "Section_packages.html">Section_packages</A> of the manual. The
difference between standard and user packages 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 have been contributed by users, and always begin with
the user prefix. If they are a single command (single file), they are
typically in the user-misc package. Otherwise, they are a a set of
files grouped together which add a specific functionality to the code.
</P>
<P>User packages don't necessarily meet the requirements of the standard
packages. 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#mod_14">this
section</A> of the documentation.
</P>
<HR>
<A NAME = "start_3_2"></A><B><I>Including/excluding packages:</I></B>
<P>To use or not use a package you must include or exclude it before
building LAMMPS. From the src directory, this is typically as simple
as:
</P>
<PRE>make yes-colloid
make g++
</PRE>
<P>or
</P>
<PRE>make no-manybody
make g++
</PRE>
<P>Some packages have individual files that depend on other packages
being included. LAMMPS checks for this and does the right thing.
I.e. individual files are only included if their dependencies are
already included. Likewise, if a package is excluded, other files
dependent on that package are also excluded.
</P>
<P>The reason to exclude packages is if you will never run certain kinds
of simulations. For some packages, this will keep you from having to
build auxiliary libraries (see below), and will also produce a smaller
executable which may run a bit faster.
</P>
<P>When you download a LAMMPS tarball, these packages are pre-installed
in the src directory: KSPACE, MANYBODY,MOLECULE. When you download
LAMMPS source files from the SVN or Git repositories, no packages are
pre-installed.
</P>
<P>Packages are included or excluded by typing "make yes-name" or "make
no-name", where "name" is the name of the package in lower-case, e.g.
name = kspace for the KSPACE package or name = user-atc for the
USER-ATC 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 all of the package-related make options.
</P>
<P>IMPORTANT NOTE: Inclusion/exclusion of a package works by simply
moving files back and forth between the main src directory and
sub-directories with the package name (e.g. src/KSPACE, src/USER-ATC),
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 package-related 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 sub-directories if the package has been included. It
should be used after a patch is installed, since patches only update
the files in the package sub-directory, but not the src files. Typing
"make package-overwrite" will overwrite files in the package
sub-directories with src files.
</P>
<P>Typing "make package-status" will show which packages are currently
included. Of those that are included, it will list files that are
different in the src directory and package sub-directory. Typing
"make package-diff" lists all differences between these files. Again,
type "make package" to see all of the package-related make options.
</P>
<HR>
<A NAME = "start_3_3"></A><B><I>Packages that require extra libraries:</I></B>
<P>A few of the standard and user packages require additional auxiliary
libraries to be compiled first. If you get a LAMMPS build error about
a missing library, this is likely the reason. The source code or
hooks to these libraries is included in the LAMMPS distribution under
the "lib" directory. Look at the lib/README file for a list of these
or see <A HREF = "Section_packages.html">Section_packages</A> of the doc pages.
</P>
<P>Each lib directory has a README file (e.g. lib/reax/README) with
instructions on how to build that library. Typically this is done
in this manner:
</P>
<PRE>make -f Makefile.g++
</PRE>
<P>in the appropriate directory, e.g. in lib/reax. However, some of the
libraries do not build this way. Again, see the libary README file
for details.
</P>
<P>If you are building the library, you will need to 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 Fortran-based libraries, your system must have
a Fortran compiler, the settings for which will need to be listed in
the Makefile.
</P>
<P>When you have built one of these libraries, there are 2 things to
check:
</P>
<P>(1) The file libname.a should now exist in lib/name.
E.g. lib/reax/libreax.a. This is the library file LAMMPS will link
against. One exception is the lib/cuda library which produces the
file liblammpscuda.a, because there is already a system library
libcuda.a.
</P>
<P>(2) The file Makefile.lammps should exist in lib/name. E.g.
lib/cuda/Makefile.lammps. This file may be auto-generated by the
build of the library, or you may need to make a copy of the
appropriate provided file (e.g. lib/meam/Makefile.lammps.gfortran).
Either way you should insure that the settings in this file are
appropriate for your system.
</P>
<P>There are typically 3 settings in the Makefile.lammps file (unless
some are blank or not needed): a SYSINC, SYSPATH, and SYSLIB setting,
specific to this package. These are settings the LAMMPS build will
import when compiling the LAMMPS package files (not the library
files), and linking to the auxiliary library. They typically list any
other system libraries needed to support the package and where to find
them. An example is the BLAS and LAPACK libraries needed by the
USER-ATC package. Or the system libraries that support calling
Fortran from C++, as the MEAM and REAX packages do.
</P>
<P>(3) One exception to these rules is the lib/linalg directory, which is
simply BLAS and LAPACK files used by the USER-ATC package (and
possibly other packages in the future). If you do not have these
libraries on your system, you can use one of the Makefiles in this
directory (which you may need to modify) to build a dummy BLAS and
LAPACK library. It can then be included in the
lib/atc/Makefile.lammps file as part of the SYSPATH and SYSLIB lines
so that LAMMPS will build properly with the USER-ATC package.
</P>
<P>Note that if the Makefile.lammps settings are not correct for your
box, the LAMMPS build will likely fail.
</P>
<P>There are also a few packages, like KIM and USER-MOLFILE, that use
additional auxiliary libraries which are not provided with LAMMPS. In
these cases, there is no corresponding sub-directory under the lib
directory. You are expected to download and install these libraries
yourself before building LAMMPS with the package installed, if they
are not already on your system.
</P>
<P>However there is still a Makefile.lammps file with settings used when
building LAMMPS with the package installed, as in (2) above. Is is
found in the package directory itself, e.g. src/KIM/Makefile.lammps.
This file contains the same 3 settings described above for SYSINC,
SYSPATH, and SYSLIB. The Makefile.lammps file contains instructions
on how to specify these settings for your system. You need to specify
the settings before building LAMMPS with one of those packages
installed, else the LAMMPS build will likely fail.
</P>
<HR>
<H4><A NAME = "start_4"></A>2.4 Building LAMMPS via the Make.py script
</H4>
<P>The src directory includes a Make.py script, written
in Python, which can be used to automate various steps
of the build process.
</P>
<P>You can run the script from the src directory by typing either:
</P>
<PRE>Make.py
python Make.py
</PRE>
<P>which will give you info about the tool. For the former to work, you
may need to edit the 1st line of the script to point to your local
Python. And you may need to insure the script is executable:
</P>
<PRE>chmod +x Make.py
</PRE>
<P>The following options are supported as switches:
</P>
<UL><LI>-i file1 file2 ...
<LI>-p package1 package2 ...
<LI>-u package1 package2 ...
<LI>-e package1 arg1 arg2 package2 ...
<LI>-o dir
<LI>-b machine
<LI>-s suffix1 suffix2 ...
<LI>-l dir
<LI>-j N
<LI>-h switch1 switch2 ...
</UL>
<P>Help on any switch can be listed by using -h, e.g.
</P>
<PRE>Make.py -h -i -p
</PRE>
<P>At a hi-level, these are the kinds of package management
and build tasks that can be performed easily, using
the Make.py tool:
</P>
<UL><LI>install/uninstall packages and build the associated external libs (use -p and -u and -e)
<LI>install packages needed for one or more input scripts (use -i and -p)
<LI>build LAMMPS, either in the src dir or new dir (use -b)
<LI>create a new dir with only the source code needed for one or more input scripts (use -i and -o)
</UL>
<P>The last bullet can be useful when you wish to build a stripped-down
version of LAMMPS to run a specific script(s). Or when you wish to
move the minimal amount of files to another platform for a remote
LAMMPS build.
</P>
<P>Note that using Make.py is not a substitute for insuring you have a
valid src/MAKE/Makefile.foo for your system, or that external library
Makefiles in any lib/* directories you use are also valid for your
system. But once you have done that, you can use Make.py to quickly
include/exclude the packages and external libraries needed by your
input scripts.
</P>
<HR>
<H4><A NAME = "start_5"></A>2.5 Building LAMMPS as a library
</H4>
<P>LAMMPS itself can be built as a library, which can then be called from
another application or a scripting language. See <A HREF = "Section_howto.html#howto_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. Note that inclusion or exclusion of
any desired optional packages should be done before typing "make
makelib". 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#howto_10">Section_howto 10</A> of the
manual. See <A HREF = "Section_python.html">Section_python</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#howto_19">Section_howto 19</A> of the
manual for a description of the interface and how to extend it for
your needs.
</P>
<HR>
<H4><A NAME = "start_6"></A>2.6 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 or bench 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 a standard Lennard-Jones benchmark on a
Linux box, using mpirun to launch a parallel job:
</P>
<PRE>cd src
make linux
cp lmp_linux ../bench
cd ../bench
mpirun -np 4 lmp_linux < in.lj
</PRE>
<P>See <A HREF = "http://lammps.sandia.gov/bench.html">this page</A> for timings for this and the other benchmarks
on various platforms.
</P>
<HR>
<P>On a Windows box, you can skip making LAMMPS and simply download an
executable, as described above, though the pre-packaged executables
include only certain packages.
</P>
<P>To run a 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">Section_errors</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 = "start_7"></A>2.7 Command-line options
</H4>
<P>At run time, LAMMPS recognizes several optional command-line switches
which may be used in any order. Either the full word or a one-or-two
letter abbreviation can be used:
</P>
<UL><LI>-c or -cuda
<LI>-e or -echo
<LI>-i or -in
<LI>-h or -help
<LI>-l or -log
<LI>-p or -partition
<LI>-pl or -plog
<LI>-ps or -pscreen
<LI>-r or -reorder
<LI>-sc or -screen
<LI>-sf or -suffix
<LI>-v or -var
</UL>
<P>For example, lmp_ibm might be launched as follows:
</P>
<PRE>mpirun -np 16 lmp_ibm -v f tmp.out -l my.log -sc none < in.alloy
mpirun -np 16 lmp_ibm -var f tmp.out -log my.log -screen none < in.alloy
</PRE>
<P>Here are the details on the options:
</P>
<PRE>-cuda on/off
</PRE>
<P>Explicitly enable or disable CUDA support, as provided by the
USER-CUDA package. If LAMMPS is built with this package, as described
above in <A HREF = "#start_3">Section 2.3</A>, then by default LAMMPS will run in
CUDA mode. If this switch is set to "off", then it will not, even if
it was built with the USER-CUDA package, which means you can run
standard LAMMPS or with the GPU package for testing or benchmarking
purposes. The only reason to set the switch to "on", is to check if
LAMMPS was built with the USER-CUDA package, since an error will be
generated if it was not.
</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>-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>-help
</PRE>
<P>Print a list of options compiled into this executable for each LAMMPS
style (atom_style, fix, compute, pair_style, bond_style, etc). This
can help you know if the command you want to use was included via the
appropriate package. LAMMPS will print the info and immediately exit
if this switch is used.
</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.
Option -plog will override the name of the partition log files file.N.
</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>Running with multiple partitions can e useful for running
<A HREF = "Section_howto.html#howto_5">multi-replica simulations</A>, where each
replica runs on on one or a few 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.
</P>
<P>To run multiple independent simulatoins from one input script, using
multiple partitions, see <A HREF = "Section_howto.html#howto_4">Section_howto 4</A>
of the manual. World- and universe-style <A HREF = "variable.html">variables</A>
are useful in this context.
</P>
<PRE>-plog file
</PRE>
<P>Specify the base name for the partition log files, so partition N
writes log information to file.N. If file is none, then no partition
log files are created. This overrides the filename specified in the
-log command-line option. This option is useful when working with
large numbers of partitions, allowing the partition log files to be
suppressed (-plog none) or placed in a sub-directory (-plog
replica_files/log.lammps) If this option is not used the log file for
partition N is log.lammps.N or whatever is specified by the -log
command-line option.
</P>
<PRE>-pscreen file
</PRE>
<P>Specify the base name for the partition screen file, so partition N
writes screen information to file.N. If file is none, then no
partition screen files are created. This overrides the filename
specified in the -screen command-line option. This option is useful
when working with large numbers of partitions, allowing the partition
screen files to be suppressed (-pscreen none) or placed in a
sub-directory (-pscreen replica_files/screen). If this option is not
used the screen file for partition N is screen.N or whatever is
specified by the -screen command-line option.
</P>
<PRE>-reorder nth N
-reorder custom filename
</PRE>
<P>Reorder the processors in the MPI communicator used to instantiate
LAMMPS, in one of several ways. The original MPI communicator ranks
all P processors from 0 to P-1. The mapping of these ranks to
physical processors is done by MPI before LAMMPS begins. It may be
useful in some cases to alter the rank order. E.g. to insure that
cores within each node are ranked in a desired order. Or when using
the <A HREF = "run_style.html">run_style verlet/split</A> command with 2 partitions
to insure that a specific Kspace processor (in the 2nd partition) is
matched up with a specific set of processors in the 1st partition.
See the <A HREF = "Section_accelerate.html">Section_accelerate</A> doc pages for
more details.
</P>
<P>If the keyword <I>nth</I> is used with a setting <I>N</I>, then it means every
Nth processor will be moved to the end of the ranking. This is useful
when using the <A HREF = "run_style.html">run_style verlet/split</A> command with 2
partitions via the -partition command-line switch. The first set of
processors will be in the first partition, the 2nd set in the 2nd
partition. The -reorder command-line switch can alter this so that
the 1st N procs in the 1st partition and one proc in the 2nd partition
will be ordered consecutively, e.g. as the cores on one physical node.
This can boost performance. For example, if you use "-reorder nth 4"
and "-partition 9 3" and you are running on 12 processors, the
processors will be reordered from
</P>
<PRE>0 1 2 3 4 5 6 7 8 9 10 11
</PRE>
<P>to
</P>
<PRE>0 1 2 4 5 6 8 9 10 3 7 11
</PRE>
<P>so that the processors in each partition will be
</P>
<PRE>0 1 2 4 5 6 8 9 10
3 7 11
</PRE>
<P>See the "processors" command for how to insure processors from each
partition could then be grouped optimally for quad-core nodes.
</P>
<P>If the keyword is <I>custom", then a file that specifies a permutation
of the processor ranks is also specified. The format of the reorder
file is as follows. Any number of initial blank or comment lines
(starting with a "#" character) can be present. These should be
followed by P lines of the form:
</P>
<PRE>I J
</PRE>
<P>where P is the number of processors LAMMPS was launched with. Note
that if running in multi-partition mode (see the -partition switch
above) P is the total number of processors in all partitions. The I
and J values describe a permutation of the P processors. Every I and
J should be values from 0 to P-1 inclusive. In the set of P I values,
every proc ID should appear exactly once. Ditto for the set of P J
values. A single I,J pairing means that the physical processor with
rank I in the original MPI communicator will have rank J in the
reordered communicator.
</P>
<P>Note that rank ordering can also be specified by many MPI
implementations, either by environment variables that specify how to
order physical processors, or by config files that specify what
physical processors to assign to each MPI rank. The -reorder switch
simply gives you a portable way to do this without relying on MPI
itself. See the <A HREF = "processors">processors out</A> command for how to output
info on the final assignment of physical processors to the LAMMPS
simulation domain.
</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. Option -pscreen will override the name of the
partition screen files file.N.
</P>
<PRE>-suffix style
</PRE>
<P>Use variants of various styles if they exist. The specified style can
be <I>opt</I>, <I>omp</I>, <I>gpu</I>, or <I>cuda</I>. These refer to optional packages that
LAMMPS can be built with, as described above in <A HREF = "#start_3">Section
2.3</A>. The "opt" style corrsponds to the OPT package, the
"omp" style to the USER-OMP package, the "gpu" style to the GPU
package, and the "cuda" style to the USER-CUDA package.
</P>
<P>As an example, all of the packages provide a <A HREF = "pair_lj.html">pair_style
lj/cut</A> variant, with style names lj/cut/opt, lj/cut/omp,
lj/cut/gpu, or lj/cut/cuda. A variant styles can be specified
explicitly in your input script, e.g. pair_style lj/cut/gpu. If the
-suffix switch is used, you do not need to modify your input script.
The specified suffix (opt,omp,gpu,cuda) is automatically appended
whenever your input script command creates a new
<A HREF = "atom_style.html">atom</A>, <A HREF = "pair_style.html">pair</A>, <A HREF = "fix.html">fix</A>,
<A HREF = "compute.html">compute</A>, or <A HREF = "run_style.html">run</A> style. If the variant
version does not exist, the standard version is created.
</P>
<P>For the GPU package, using this command-line switch also invokes the
default GPU settings, as if the command "package gpu force/neigh 0 0
1" were used at the top of your input script. These settings can be
changed by using the <A HREF = "package.html">package gpu</A> command in your script
if desired.
</P>
<P>For the OMP package, using this command-line switch also invokes the
default OMP settings, as if the command "package omp *" were used at
the top of your input script. These settings can be changed by using
the <A HREF = "package.html">package omp</A> command in your script if desired.
</P>
<P>The <A HREF = "suffix.html">suffix</A> command can also set a suffix and it can also
turn off/on any suffix setting made via the command line.
</P>
<PRE>-var name value1 value2 ...
</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}). An <A HREF = "variable.html">index-style
variable</A> will be created and populated with the
subsequent values, e.g. a set of filenames. Using this command-line
option is equivalent to putting the line "variable name index value1
value2 ..." 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#cmd_2">this
section</A> for more info on using variables
in input scripts.
</P>
<P>NOTE: Currently, the command-line parser looks for arguments that
start with "-" to indicate new switches. Thus you cannot specify
multiple variable values if any of they start with a "-", e.g. a
negative numeric value. It is OK if the first value1 starts with a
"-", since it is automatically skipped.
</P>
<HR>
<H4><A NAME = "start_8"></A>2.8 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 = "start_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">Section_history</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 f361c9f0c..8469a82dc 100644
--- a/doc/Section_start.txt
+++ b/doc/Section_start.txt
@@ -1,1312 +1,1320 @@
"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"_#start_1
2.2 "Making LAMMPS"_#start_2
2.3 "Making LAMMPS with optional packages"_#start_3
2.4 "Building LAMMPS via the Make.py script"_#start_4
2.5 "Building LAMMPS as a library"_#start_5
2.6 "Running LAMMPS"_#start_6
2.7 "Command-line options"_#start_7
2.8 "Screen output"_#start_8
2.9 "Tips for users of previous versions"_#start_9 :all(b)
:line
:line
2.1 What's in the LAMMPS distribution :h4,link(start_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 one of the Windows executables from the download page,
then you just get a single file:
lmp_windows.exe :pre
Skip to the "Running LAMMPS"_#start_6 sections for info on how to
launch these executables on a Windows box.
The Windows executables for serial or parallel only include 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 from source code using Microsoft Visual Studio,
as described in the next section.
:line
2.2 Making LAMMPS :h4,link(start_2)
This section has the following sub-sections:
"Read this first"_#start_2_1
"Steps to build a LAMMPS executable"_#start_2_2
"Common errors that can occur when making LAMMPS"_#start_2_3
"Additional build tips"_#start_2_4
"Building for a Mac"_#start_2_5
"Building for Windows"_#start_2_6 :ul
:line
[{Read this first:}] :link(start_2_1)
Building LAMMPS can be non-trivial. You may need to edit a makefile,
there are compiler options to consider, additional libraries can be
used (MPI, FFT, JPEG), LAMMPS packages may be included or excluded,
some of these packages use auxiliary libraries which need to be
pre-built, 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 have are often not
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 post a question to the "LAMMPS mail
list"_http://lammps.sandia.gov/mail.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 can include it in the LAMMPS distribution.
:line
[{Steps to build a LAMMPS executable:}] :link(start_2_2)
[Step 0]
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 many 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
or
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.
Note that by default only a few of LAMMPS optional packages are
installed. To build LAMMPS with optional packages, see "this
section"_#start_3 below.
[Step 1]
If Step 0 did not work, you will need to create a low-level Makefile
for your machine, like Makefile.foo. You should make a copy of an
existing src/MAKE/Makefile.* as a starting point. The only portions
of the file you need to edit are the first line, the "compiler/linker
settings" section, and the "LAMMPS-specific settings" section.
[Step 2]
Change the first line of src/MAKE/Makefile.foo to list the word "foo"
after the "#", and whatever other options it will set. This is the
line you will see if you just type "make".
[Step 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 commercial Intel icc
compiler, which can be downloaded 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, then you'll need to create a Makefile.foo patterned
after Makefile.storm, which uses different rules that do not involve
dependency files. Note that when you build LAMMPS for the first time
on a new platform, a long list of *.d files will be printed out
rapidly. This is not an error; it is the Makefile doing its normal
creation of dependencies.
[Step 4]
The "system-specific settings" section has several parts. Note that
if you change any -D setting in this section, you should do a full
re-compile, after typing "make clean" (which will describe different
clean options).
The LMP_INC variable is used to include options that turn on ifdefs
within the LAMMPS code. The options that are currently recogized are:
-DLAMMPS_GZIP
-DLAMMPS_JPEG
-DLAMMPS_MEMALIGN
-DLAMMPS_XDR
-DLAMMPS_SMALLBIG
-DLAMMPS_BIGBIG
-DLAMMPS_SMALLSMALL
-DLAMMPS_LONGLONG_TO_LONG
-DPACK_ARRAY
-DPACK_POINTER
-DPACK_MEMCPY :ul
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.
If you use -DLAMMPS_JPEG, the "dump image"_dump.html command will be
able to write out JPEG image files. If not, it will only be able to
write out text-based PPM image files. For JPEG files, you must also
link LAMMPS with a JPEG library, as described below.
Using -DLAMMPS_MEMALIGN=<bytes> enables the use of the
posix_memalign() call instead of malloc() when large chunks or memory
are allocated by LAMMPS. This can help to make more efficient use of
vector instructions of modern CPUS, since dynamically allocated memory
has to be aligned on larger than default byte boundaries (e.g. 16
bytes instead of 8 bytes on x86 type platforms) for optimal
performance.
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.
Use at most one of the -DLAMMPS_SMALLBIG, -DLAMMPS_BIGBIG,
-D-DLAMMPS_SMALLSMALL settings. The default is -DLAMMPS_SMALLBIG.
-These refer to use of 4-byte (small) vs 8-byte (big) integers within
-LAMMPS, as described in src/lmptype.h. The only reason to use the
-BIGBIG setting is to enable simulation of huge molecular systems with
-more than 2 billion atoms. The only reason to use the SMALLSMALL
-setting is if your machine does not support 64-bit integers.
+These settings refer to use of 4-byte (small) vs 8-byte (big) integers
+within LAMMPS, as specified in src/lmptype.h. The only reason to use
+the BIGBIG setting is to enable simulation of huge molecular systems
+with more than 2 billion atoms or to allow moving atoms to wrap back
+through a periodic box more than 512 times. The only reason to use
+the SMALLSMALL setting is if your machine does not support 64-bit
+integers. See the "Additional build tips"_#start_2_4 section below
+for more details.
The -DLAMMPS_LONGLONG_TO_LONG setting may be needed if your system or
MPI version does not recognize "long long" data types. In this case a
"long" data type is likely already 64-bits, in which case this setting
will convert to that data type.
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. See the
"kspace_style"_kspace_style.html command for info about PPPM. See
Step 6 below for info about building LAMMPS with an FFT library.
[Step 5]
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 should be able to leave these 3
variables blank; the MPI wrapper knows where to find the needed files.
If not, and MPI is installed on your system in the usual place (under
/usr/local), you also may not need to specify these 3 variables. On
some large parallel machines which use "modules" for their
compile/link environements, you may simply need to include the correct
module in your build environment. Or the parallel machine may have a
vendor-provided MPI which the compiler has no trouble finding.
Failing this, with these 3 variables you can specify where the mpi.h
file (MPI_INC) and the MPI library file (MPI_PATH) are found and the
name of the library file (MPI_LIB).
If you are installing MPI yourself, we recommend Argonne's MPICH2
or OpenMPI. MPICH can be downloaded from the "Argonne MPI
site"_http://www.mcs.anl.gov/research/projects/mpich2/. OpenMPI can
be downloaded from the "OpenMPI site"_http://www.open-mpi.org.
Other MPI packages 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 is likely to be faster
than a self-installed MPICH or OpenMPI, so find out how to build
and link with it. If you use MPICH or OpenMPI, 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 to run LAMMPS on a single processor, you can use the
dummy MPI library provided in src/STUBS, since you don't need a true
MPI library installed on your system. See the
src/MAKE/Makefile.serial file for how to specify the 3 MPI variables
in this case. You will also need to build the STUBS library for your
platform before making LAMMPS itself. From the src directory, type
"make stubs", or from the STUBS dir, type "make" and it should 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.c provides a CPU timer function called
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.
[Step 6]
The 3 FFT variables allow you to specify an FFT library which LAMMPS
uses (for performing 1d FFTs) when running the particle-particle
particle-mesh (PPPM) option for long-range Coulombics via the
"kspace_style"_kspace_style.html command.
LAMMPS supports various open-source or vendor-supplied FFT libraries
for this purpose. If you leave these 3 variables blank, LAMMPS will
use the open-source "KISS FFT library"_http://kissfft.sf.net, which is
included in the LAMMPS distribution. This library is portable to all
platforms and for typical LAMMPS simulations is almost as fast as FFTW
or vendor optimized libraries. If you are not including the KSPACE
package in your build, you can also leave the 3 variables blank.
Otherwise, select which kinds of FFTs to use as part of the FFT_INC
setting by a switch of the form -DFFT_XXX. Recommended values for XXX
are: MKL, SCSL, FFTW2, and FFTW3. Legacy options are: INTEL, SGI,
ACML, and T3E. For backward compatability, using -DFFT_FFTW will use
the FFTW2 library. Using -DFFT_NONE will use the KISS library
described above.
You may also need to set the FFT_INC, FFT_PATH, and FFT_LIB variables,
so the compiler and linker can find the needed FFT header and library
files. Note that on some large parallel machines which use "modules"
for their compile/link environements, you may simply need to include
the correct module in your build environment. Or the parallel machine
may have a vendor-provided FFT library which the compiler has no
trouble finding.
FFTW is a fast, portable library that should also work on any
platform. You can download it from
"www.fftw.org"_http://www.fftw.org. Both the legacy version 2.1.X and
the newer 3.X versions are supported as -DFFT_FFTW2 or -DFFT_FFTW3.
Building FFTW for your box should be as simple as ./configure; make.
Note that on some platforms FFTW2 has been pre-installed, and uses
renamed files indicating the precision it was compiled with,
e.g. sfftw.h, or dfftw.h instead of fftw.h. In this case, you can
specify an additional define variable for FFT_INC called -DFFTW_SIZE,
which will select the correct include file. In this case, for FFT_LIB
you must also manually specify the correct library, namely -lsfftw or
-ldfftw.
The FFT_INC variable also allows for a -DFFT_SINGLE setting that will
use single-precision FFTs with PPPM, which can speed-up long-range
calulations, particularly in parallel or on GPUs. Fourier transform
and related PPPM operations are somewhat insensitive to floating point
truncation errors and thus do not always need to be performed in
double precision. Using the -DFFT_SINGLE setting trades off a little
accuracy for reduced memory use and parallel communication costs for
transposing 3d FFT data. Note that single precision FFTs have only
been tested with the FFTW3, FFTW2, MKL, and KISS FFT options.
[Step 7]
The 3 JPG variables allow you to specify a JPEG library which LAMMPS
uses when writing out JPEG files via the "dump image"_dump_image.html
command. These can be left blank if you do not use the -DLAMMPS_JPEG
switch discussed above in Step 4, since in that case JPEG output will
be disabled.
A standard JPEG library usually goes by the name libjpeg.a and has an
associated header file jpeglib.h. Whichever JPEG library you have on
your platform, you'll need to set the appropriate JPG_INC, JPG_PATH,
and JPG_LIB variables, so that the compiler and linker can find it.
As before, if these header and library files are in the usual place on
your machine, you may not need to set these variables.
[Step 8]
Note that by default only a few of LAMMPS optional packages are
installed. To build LAMMPS with optional packages, see "this
section"_#start_3 below, before proceeding to Step 9.
[Step 9]
That's it. Once you have a correct Makefile.foo, you have installed
the optional LAMMPS packages you want to include in your build, and
you have pre-built any other needed libraries (e.g. MPI, FFT, package
libraries), all you need to do from the src directory is type
something like this:
make foo
or
gmake foo :pre
You should get the executable lmp_foo when the build is complete.
:line
[{Errors that can occur when making LAMMPS:}] :link(start_2_3)
IMPORTANT NOTE: If an error occurs when building LAMMPS, the compiler
or linker will state very explicitly what the problem is. The error
message should give you a hint as to which of the steps above has
failed, and what you need to do in order to fix it. Building a code
with a Makefile is a very logical process. The compiler and linker
need to find the appropriate files and those files need to be
compatible with LAMMPS source files. When a make fails, there is
usually a very simple reason, which you or a local expert will need to
fix.
Here are two non-obvious errors that can occur:
(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 native 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 a pre-generated
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. Note that you should
include/exclude any desired optional packages before using the "make
makelist" command.
(2) If you get an error that says something like 'identifier "atoll"
is undefined', then your machine does not support "long long"
integers. Try using the -DLAMMPS_LONGLONG_TO_LONG setting described
above in Step 4.
:line
[{Additional build tips:}] :link(start_2_4)
(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_target 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) 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 or MPI implementation 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).
+(3) Changing the LAMMPS size limits via -DLAMMPS_SMALLBIG or
+-DLAMMPS_BIBIG or -DLAMMPS_SMALLSMALL
+
+As explained above, any of these 3 settings can be specified on the
+LMP_INC line in your low-level src/MAKE/Makefile.foo.
+
+The default is -DLAMMPS_SMALLBIG which allows for systems with up to
+2^63 atoms and timesteps (about 9 billion billion). The atom limit is
+for atomic systems that do not require atom IDs. For molecular
+models, which require atom IDs, the limit is 2^31 atoms (about 2
+billion). With this setting, image flags are stored in 32-bit
+integers, which means for 3 dimensions that atoms can only wrap around
+a periodic box at most 512 times. If atoms move through the periodic
+box more than this limit, the image flags will "roll over", e.g. from
+511 to -512, which can cause diagnostics like the mean-squared
+displacement, as calculated by the "compute msd"_compute_msd.html
+command, to be faulty.
+
+To allow for larger molecular systems or larger image flags, compile
+with -DLAMMPS_BIGBIG. This enables molecular systems with up to 2^63
+atoms (about 9 billion billion). And image flags will not "roll over"
+until they reach 2^20 = 1048576.
+
+IMPORTANT NOTE: As of 6/2012, the BIGBIG setting does not yet enable
+molecular systems to grow as large as 2^63. Only the image flag roll
+over is currently affected by this compile option.
+
+If your system does not support 8-byte integers, you will need to
+compile with the -DLAMMPS_SMALLSMALL setting. This will restrict your
+total number of atoms (for atomic or molecular models) and timesteps
+to 2^31 (about 2 billion). Image flags will roll over at 2^9 = 512.
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.
+system sizes. These need to be consistent with the associated C data
+types, or else LAMMPS will generate a run-time error.
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
+basis is limited by 4-byte integer storage to 2^31 atoms per processor
+(about 2 billion). This 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
[{Building for a Mac:}] :link(start_2_5)
OS X is BSD Unix, so it should just work. See the
src/MAKE/Makefile.mac file.
:line
[{Building for Windows:}] :link(start_2_6)
The LAMMPS download page has an option to download both a serial and
parallel pre-built Windows exeutable. See the "Running
LAMMPS"_#start_6 section for instructions for running these
executables on a Windows box.
The pre-built executables are built with a subset of the available
pacakges; see the download page for the list. If you want
a Windows version with specific packages included and excluded,
you can build it yourself.
One way to do this is install and use cygwin to build LAMMPS with a
standard Linus make, just as you would on any Linux box; see
src/MAKE/Makefile.cygwin.
The other way to do this is using Visual Studio and project files.
See the src/WINDOWS directory and its README.txt file for instructions
on both a basic build and a customized build with pacakges you select.
:line
2.3 Making LAMMPS with optional packages :h4,link(start_3)
This section has the following sub-sections:
"Package basics"_#start_3_1
"Including/excluding packages"_#start_3_2
"Packages that require extra libraries"_#start_3_3
"Additional Makefile settings for extra libraries"_#start_3_4 :ul
:line
[{Package basics:}] :link(start_3_1)
The source code for LAMMPS is structured as a 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" from within
the src directory of the LAMMPS distribution.
If you use a command in a LAMMPS input script that is specific to a
particular package, you must have built LAMMPS with that package, else
you will get an error that the style is invalid or the command is
unknown. Every command's doc page specfies if it is part of a
package. You can also type
lmp_machine -h :pre
to run your executable with the optional "-h command-line
switch"_#start_7 for "help", which will list the styles and commands
known to your executable.
There are two kinds of packages in LAMMPS, standard and user packages.
More information about the contents of standard and user packages is
given in "Section_packages"_Section_packages.html of the manual. The
difference between standard and user packages 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 have been contributed by users, and always begin with
the user prefix. If they are a single command (single file), they are
typically in the user-misc package. Otherwise, they are a a set of
files grouped together which add a specific functionality to the code.
User packages don't necessarily meet the requirements of the standard
packages. 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#mod_14 of the documentation.
:line
[{Including/excluding packages:}] :link(start_3_2)
To use or not use a package you must include or exclude it before
building LAMMPS. From the src directory, this is typically as simple
as:
make yes-colloid
make g++ :pre
or
make no-manybody
make g++ :pre
Some packages have individual files that depend on other packages
being included. LAMMPS checks for this and does the right thing.
I.e. individual files are only included if their dependencies are
already included. Likewise, if a package is excluded, other files
dependent on that package are also excluded.
The reason to exclude packages is if you will never run certain kinds
of simulations. For some packages, this will keep you from having to
build auxiliary libraries (see below), and will also produce a smaller
executable which may run a bit faster.
When you download a LAMMPS tarball, these packages are pre-installed
in the src directory: KSPACE, MANYBODY,MOLECULE. When you download
LAMMPS source files from the SVN or Git repositories, no packages are
pre-installed.
Packages are included or excluded by typing "make yes-name" or "make
no-name", where "name" is the name of the package in lower-case, e.g.
name = kspace for the KSPACE package or name = user-atc for the
USER-ATC 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 all of the package-related make options.
IMPORTANT NOTE: Inclusion/exclusion of a package works by simply
moving files back and forth between the main src directory and
sub-directories with the package name (e.g. src/KSPACE, src/USER-ATC),
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 package-related 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 sub-directories if the package has been included. It
should be used after a patch is installed, since patches only update
the files in the package sub-directory, but not the src files. Typing
"make package-overwrite" will overwrite files in the package
sub-directories with src files.
Typing "make package-status" will show which packages are currently
included. Of those that are included, it will list files that are
different in the src directory and package sub-directory. Typing
"make package-diff" lists all differences between these files. Again,
type "make package" to see all of the package-related make options.
:line
[{Packages that require extra libraries:}] :link(start_3_3)
A few of the standard and user packages require additional auxiliary
libraries to be compiled first. If you get a LAMMPS build error about
a missing library, this is likely the reason. The source code or
hooks to these libraries is included in the LAMMPS distribution under
the "lib" directory. Look at the lib/README file for a list of these
or see "Section_packages"_Section_packages.html of the doc pages.
Each lib directory has a README file (e.g. lib/reax/README) with
instructions on how to build that library. Typically this is done
in this manner:
make -f Makefile.g++ :pre
in the appropriate directory, e.g. in lib/reax. However, some of the
libraries do not build this way. Again, see the libary README file
for details.
If you are building the library, you will need to 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 Fortran-based libraries, your system must have
a Fortran compiler, the settings for which will need to be listed in
the Makefile.
When you have built one of these libraries, there are 2 things to
check:
(1) The file libname.a should now exist in lib/name.
E.g. lib/reax/libreax.a. This is the library file LAMMPS will link
against. One exception is the lib/cuda library which produces the
file liblammpscuda.a, because there is already a system library
libcuda.a.
(2) The file Makefile.lammps should exist in lib/name. E.g.
lib/cuda/Makefile.lammps. This file may be auto-generated by the
build of the library, or you may need to make a copy of the
appropriate provided file (e.g. lib/meam/Makefile.lammps.gfortran).
Either way you should insure that the settings in this file are
appropriate for your system.
There are typically 3 settings in the Makefile.lammps file (unless
some are blank or not needed): a SYSINC, SYSPATH, and SYSLIB setting,
specific to this package. These are settings the LAMMPS build will
import when compiling the LAMMPS package files (not the library
files), and linking to the auxiliary library. They typically list any
other system libraries needed to support the package and where to find
them. An example is the BLAS and LAPACK libraries needed by the
USER-ATC package. Or the system libraries that support calling
Fortran from C++, as the MEAM and REAX packages do.
(3) One exception to these rules is the lib/linalg directory, which is
simply BLAS and LAPACK files used by the USER-ATC package (and
possibly other packages in the future). If you do not have these
libraries on your system, you can use one of the Makefiles in this
directory (which you may need to modify) to build a dummy BLAS and
LAPACK library. It can then be included in the
lib/atc/Makefile.lammps file as part of the SYSPATH and SYSLIB lines
so that LAMMPS will build properly with the USER-ATC package.
Note that if the Makefile.lammps settings are not correct for your
box, the LAMMPS build will likely fail.
There are also a few packages, like KIM and USER-MOLFILE, that use
additional auxiliary libraries which are not provided with LAMMPS. In
these cases, there is no corresponding sub-directory under the lib
directory. You are expected to download and install these libraries
yourself before building LAMMPS with the package installed, if they
are not already on your system.
However there is still a Makefile.lammps file with settings used when
building LAMMPS with the package installed, as in (2) above. Is is
found in the package directory itself, e.g. src/KIM/Makefile.lammps.
This file contains the same 3 settings described above for SYSINC,
SYSPATH, and SYSLIB. The Makefile.lammps file contains instructions
on how to specify these settings for your system. You need to specify
the settings before building LAMMPS with one of those packages
installed, else the LAMMPS build will likely fail.
:line
2.4 Building LAMMPS via the Make.py script :h4,link(start_4)
The src directory includes a Make.py script, written
in Python, which can be used to automate various steps
of the build process.
You can run the script from the src directory by typing either:
Make.py
python Make.py :pre
which will give you info about the tool. For the former to work, you
may need to edit the 1st line of the script to point to your local
Python. And you may need to insure the script is executable:
chmod +x Make.py :pre
The following options are supported as switches:
-i file1 file2 ...
-p package1 package2 ...
-u package1 package2 ...
-e package1 arg1 arg2 package2 ...
-o dir
-b machine
-s suffix1 suffix2 ...
-l dir
-j N
-h switch1 switch2 ... :ul
Help on any switch can be listed by using -h, e.g.
Make.py -h -i -p :pre
At a hi-level, these are the kinds of package management
and build tasks that can be performed easily, using
the Make.py tool:
install/uninstall packages and build the associated external libs (use -p and -u and -e)
install packages needed for one or more input scripts (use -i and -p)
build LAMMPS, either in the src dir or new dir (use -b)
create a new dir with only the source code needed for one or more input scripts (use -i and -o) :ul
The last bullet can be useful when you wish to build a stripped-down
version of LAMMPS to run a specific script(s). Or when you wish to
move the minimal amount of files to another platform for a remote
LAMMPS build.
Note that using Make.py is not a substitute for insuring you have a
valid src/MAKE/Makefile.foo for your system, or that external library
Makefiles in any lib/* directories you use are also valid for your
system. But once you have done that, you can use Make.py to quickly
include/exclude the packages and external libraries needed by your
input scripts.
:line
2.5 Building LAMMPS as a library :h4,link(start_5)
LAMMPS itself can be built as a library, which can then be called from
another application or a scripting language. See "this
section"_Section_howto.html#howto_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. Note that inclusion or exclusion of
any desired optional packages should be done before typing "make
makelib". 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 "Section_howto 10"_Section_howto.html#howto_10 of the
manual. See "Section_python"_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 "Section_howto 19"_Section_howto.html#howto_19 of the
manual for a description of the interface and how to extend it for
your needs.
:line
2.6 Running LAMMPS :h4,link(start_6)
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 or bench 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 a standard Lennard-Jones benchmark on a
Linux box, using mpirun to launch a parallel job:
cd src
make linux
cp lmp_linux ../bench
cd ../bench
mpirun -np 4 lmp_linux < in.lj :pre
See "this page"_bench for timings for this and the other benchmarks
on various platforms.
:link(bench,http://lammps.sandia.gov/bench.html)
:line
On a Windows box, you can skip making LAMMPS and simply download an
executable, as described above, though the pre-packaged executables
include only certain packages.
To run a 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 "Section_errors"_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.7 Command-line options :h4,link(start_7)
At run time, LAMMPS recognizes several optional command-line switches
which may be used in any order. Either the full word or a one-or-two
letter abbreviation can be used:
-c or -cuda
-e or -echo
-i or -in
-h or -help
-l or -log
-p or -partition
-pl or -plog
-ps or -pscreen
-r or -reorder
-sc or -screen
-sf or -suffix
-v or -var :ul
For example, lmp_ibm might be launched as follows:
mpirun -np 16 lmp_ibm -v f tmp.out -l my.log -sc none < in.alloy
mpirun -np 16 lmp_ibm -var f tmp.out -log my.log -screen none < in.alloy :pre
Here are the details on the options:
-cuda on/off :pre
Explicitly enable or disable CUDA support, as provided by the
USER-CUDA package. If LAMMPS is built with this package, as described
above in "Section 2.3"_#start_3, then by default LAMMPS will run in
CUDA mode. If this switch is set to "off", then it will not, even if
it was built with the USER-CUDA package, which means you can run
standard LAMMPS or with the GPU package for testing or benchmarking
purposes. The only reason to set the switch to "on", is to check if
LAMMPS was built with the USER-CUDA package, since an error will be
generated if it was not.
-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.
-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.
-help :pre
Print a list of options compiled into this executable for each LAMMPS
style (atom_style, fix, compute, pair_style, bond_style, etc). This
can help you know if the command you want to use was included via the
appropriate package. LAMMPS will print the info and immediately exit
if this switch is used.
-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.
Option -plog will override the name of the partition log files file.N.
-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.
Running with multiple partitions can e useful for running
"multi-replica simulations"_Section_howto.html#howto_5, where each
replica runs on on one or a few 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.
To run multiple independent simulatoins from one input script, using
multiple partitions, see "Section_howto 4"_Section_howto.html#howto_4
of the manual. World- and universe-style "variables"_variable.html
are useful in this context.
-plog file :pre
Specify the base name for the partition log files, so partition N
writes log information to file.N. If file is none, then no partition
log files are created. This overrides the filename specified in the
-log command-line option. This option is useful when working with
large numbers of partitions, allowing the partition log files to be
suppressed (-plog none) or placed in a sub-directory (-plog
replica_files/log.lammps) If this option is not used the log file for
partition N is log.lammps.N or whatever is specified by the -log
command-line option.
-pscreen file :pre
Specify the base name for the partition screen file, so partition N
writes screen information to file.N. If file is none, then no
partition screen files are created. This overrides the filename
specified in the -screen command-line option. This option is useful
when working with large numbers of partitions, allowing the partition
screen files to be suppressed (-pscreen none) or placed in a
sub-directory (-pscreen replica_files/screen). If this option is not
used the screen file for partition N is screen.N or whatever is
specified by the -screen command-line option.
-reorder nth N
-reorder custom filename :pre
Reorder the processors in the MPI communicator used to instantiate
LAMMPS, in one of several ways. The original MPI communicator ranks
all P processors from 0 to P-1. The mapping of these ranks to
physical processors is done by MPI before LAMMPS begins. It may be
useful in some cases to alter the rank order. E.g. to insure that
cores within each node are ranked in a desired order. Or when using
the "run_style verlet/split"_run_style.html command with 2 partitions
to insure that a specific Kspace processor (in the 2nd partition) is
matched up with a specific set of processors in the 1st partition.
See the "Section_accelerate"_Section_accelerate.html doc pages for
more details.
If the keyword {nth} is used with a setting {N}, then it means every
Nth processor will be moved to the end of the ranking. This is useful
when using the "run_style verlet/split"_run_style.html command with 2
partitions via the -partition command-line switch. The first set of
processors will be in the first partition, the 2nd set in the 2nd
partition. The -reorder command-line switch can alter this so that
the 1st N procs in the 1st partition and one proc in the 2nd partition
will be ordered consecutively, e.g. as the cores on one physical node.
This can boost performance. For example, if you use "-reorder nth 4"
and "-partition 9 3" and you are running on 12 processors, the
processors will be reordered from
0 1 2 3 4 5 6 7 8 9 10 11 :pre
to
0 1 2 4 5 6 8 9 10 3 7 11 :pre
so that the processors in each partition will be
0 1 2 4 5 6 8 9 10
3 7 11 :pre
See the "processors" command for how to insure processors from each
partition could then be grouped optimally for quad-core nodes.
If the keyword is {custom", then a file that specifies a permutation
of the processor ranks is also specified. The format of the reorder
file is as follows. Any number of initial blank or comment lines
(starting with a "#" character) can be present. These should be
followed by P lines of the form:
I J :pre
where P is the number of processors LAMMPS was launched with. Note
that if running in multi-partition mode (see the -partition switch
above) P is the total number of processors in all partitions. The I
and J values describe a permutation of the P processors. Every I and
J should be values from 0 to P-1 inclusive. In the set of P I values,
every proc ID should appear exactly once. Ditto for the set of P J
values. A single I,J pairing means that the physical processor with
rank I in the original MPI communicator will have rank J in the
reordered communicator.
Note that rank ordering can also be specified by many MPI
implementations, either by environment variables that specify how to
order physical processors, or by config files that specify what
physical processors to assign to each MPI rank. The -reorder switch
simply gives you a portable way to do this without relying on MPI
itself. See the "processors out"_processors command for how to output
info on the final assignment of physical processors to the LAMMPS
simulation domain.
-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. Option -pscreen will override the name of the
partition screen files file.N.
-suffix style :pre
Use variants of various styles if they exist. The specified style can
be {opt}, {omp}, {gpu}, or {cuda}. These refer to optional packages that
LAMMPS can be built with, as described above in "Section
2.3"_#start_3. The "opt" style corrsponds to the OPT package, the
"omp" style to the USER-OMP package, the "gpu" style to the GPU
package, and the "cuda" style to the USER-CUDA package.
As an example, all of the packages provide a "pair_style
lj/cut"_pair_lj.html variant, with style names lj/cut/opt, lj/cut/omp,
lj/cut/gpu, or lj/cut/cuda. A variant styles can be specified
explicitly in your input script, e.g. pair_style lj/cut/gpu. If the
-suffix switch is used, you do not need to modify your input script.
The specified suffix (opt,omp,gpu,cuda) is automatically appended
whenever your input script command creates a new
"atom"_atom_style.html, "pair"_pair_style.html, "fix"_fix.html,
"compute"_compute.html, or "run"_run_style.html style. If the variant
version does not exist, the standard version is created.
For the GPU package, using this command-line switch also invokes the
default GPU settings, as if the command "package gpu force/neigh 0 0
1" were used at the top of your input script. These settings can be
changed by using the "package gpu"_package.html command in your script
if desired.
For the OMP package, using this command-line switch also invokes the
default OMP settings, as if the command "package omp *" were used at
the top of your input script. These settings can be changed by using
the "package omp"_package.html command in your script if desired.
The "suffix"_suffix.html command can also set a suffix and it can also
turn off/on any suffix setting made via the command line.
-var name value1 value2 ... :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\}). An "index-style
variable"_variable.html will be created and populated with the
subsequent values, e.g. a set of filenames. Using this command-line
option is equivalent to putting the line "variable name index value1
value2 ..." 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#cmd_2 for more info on using variables
in input scripts.
NOTE: Currently, the command-line parser looks for arguments that
start with "-" to indicate new switches. Thus you cannot specify
multiple variable values if any of they start with a "-", e.g. a
negative numeric value. It is OK if the first value1 starts with a
"-", since it is automatically skipped.
:line
2.8 LAMMPS screen output :h4,link(start_8)
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.9 Tips for users of previous LAMMPS versions :h4,link(start_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 "Section_history"_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/fix_rigid.html b/doc/fix_rigid.html
index 4ea4e975c..0bbd9fbdd 100644
--- a/doc/fix_rigid.html
+++ b/doc/fix_rigid.html
@@ -1,455 +1,456 @@
<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>fix rigid command
</H3>
<H3>fix rigid/nve command
</H3>
<H3>fix rigid/nvt command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>fix ID group-ID style bodystyle args keyword values ...
</PRE>
<UL><LI>ID, group-ID are documented in <A HREF = "fix.html">fix</A> command
<LI>style = <I>rigid</I> or <I>rigid/nve</I> or <I>rigid/nvt</I>
<LI>bodystyle = <I>single</I> or <I>molecule</I> or <I>group</I>
<PRE> <I>single</I> args = none
<I>molecule</I> args = none
<I>group</I> args = N groupID1 groupID2 ...
N = # of groups
groupID1, groupID2, ... = list of N group IDs
</PRE>
<LI>zero or more keyword/value pairs may be appended
<LI>keyword = <I>langevin</I> or <I>temp</I> or <I>tparam</I> or <I>force</I> or <I>torque</I> or <I>infile</I>
<PRE> <I>langevin</I> values = Tstart Tstop Tperiod seed
Tstart,Tstop = desired temperature at start/stop of run (temperature units)
Tdamp = temperature damping parameter (time units)
seed = random number seed to use for white noise (positive integer)
<I>temp</I> values = Tstart Tstop Tdamp
Tstart,Tstop = desired temperature at start/stop of run (temperature units)
Tdamp = temperature damping parameter (time units)
<I>tparam</I> values = Tchain Titer Torder
Tchain = length of Nose/Hoover thermostat chain
Titer = number of thermostat iterations performed
Torder = 3 or 5 = Yoshida-Suzuki integration parameters
<I>force</I> values = M xflag yflag zflag
M = which rigid body from 1-Nbody (see asterisk form below)
xflag,yflag,zflag = off/on if component of center-of-mass force is active
<I>torque</I> values = M xflag yflag zflag
M = which rigid body from 1-Nbody (see asterisk form below)
xflag,yflag,zflag = off/on if component of center-of-mass torque is active
<I>infile</I> filename
filename = file with per-body values of mass, center-of-mass, moments of inertia
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>fix 1 clump rigid single
fix 1 clump rigid single force 1 off off on langevin 1.0 1.0 1.0 428984
fix 1 polychains rigid/nvt molecule temp 1.0 1.0 5.0
fix 1 polychains rigid molecule force 1*5 off off off force 6*10 off off on
fix 2 fluid rigid group 3 clump1 clump2 clump3 torque * off off off
</PRE>
<P><B>Description:</B>
</P>
<P>Treat one or more sets of atoms as independent rigid bodies. This
means that each timestep the total force and torque on each rigid body
is computed as the sum of the forces and torques on its constituent
particles and the coordinates, velocities, and orientations of the
atoms in each body are updated so that the body moves and rotates as a
single entity.
</P>
<P>Examples of large rigid bodies are a large colloidal particle, or
portions of a large biomolecule such as a protein.
</P>
<P>Example of small rigid bodies are patchy nanoparticles, such as those
modeled in <A HREF = "#Zhang">this paper</A> by Sharon Glotzer's group, clumps of
granular particles, lipid molecules consiting of one or more point
dipoles connected to other spheroids or ellipsoids, irregular
particles built from line segments (2d) or triangles (3d), and
coarse-grain models of nano or colloidal particles consisting of a
small number of constituent particles. Note that the <A HREF = "fix_shake.html">fix
shake</A> command can also be used to rigidify small
molecules of 2, 3, or 4 atoms, e.g. water molecules. That fix treats
the constituent atoms as point masses.
</P>
<P>These fixes also update the positions and velocities of the atoms in
each rigid body via time integration. The <I>rigid</I> and <I>rigid/nve</I>
styles do this via constant NVE integration. The only difference is
that the <I>rigid</I> style uses an integration technique based on
Richardson iterations. The <I>rigid/nve</I> style uses the methods
described in the paper by <A HREF = "#Miller">Miller</A>, which are thought to
provide better energy conservation than an iterative approach.
</P>
<P>The <I>rigid/nvt</I> style performs constant NVT integration using a
Nose/Hoover thermostat with chains as described originally in
<A HREF = "#Hoover">(Hoover)</A> and <A HREF = "#Martyna">(Martyna)</A>, which thermostats both
the translational and rotational degrees of freedom of the rigid
bodies. The rigid-body algorithm used by <I>rigid/nvt</I> is described in
the paper by <A HREF = "#Kamberaj">Kamberaj</A>.
</P>
<P>IMPORTANT NOTE: You should not update the atoms in rigid bodies via
other time-integration fixes (e.g. nve, nvt, npt), or you will be
integrating their motion more than once each timestep.
</P>
<P>IMPORTANT NOTE: These fixes are overkill if you simply want to hold a
collection of atoms stationary or have them move with a constant
velocity. A simpler way to hold atoms stationary is to not include
those atoms in your time integration fix. E.g. use "fix 1 mobile nve"
instead of "fix 1 all nve", where "mobile" is the group of atoms that
you want to move. You can move atoms with a constant velocity by
assigning them an initial velocity (via the <A HREF = "velocity.html">velocity</A>
command), setting the force on them to 0.0 (via the <A HREF = "fix_setforce.html">fix
setforce</A> command), and integrating them as usual
(e.g. via the <A HREF = "fix_nve.html">fix nve</A> command).
</P>
<HR>
<P>The constituent particles within a rigid body can be point particles
(the default in LAMMPS) or finite-size particles, such as spheres or
ellipsoids or line segments or triangles. See the <A HREF = "atom_style.html">atom_style sphere
and ellipsoid and line and tri</A> commands for more
details on these kinds of particles. Finite-size particles contribute
differently to the moment of inertia of a rigid body than do point
particles. Finite-size particles can also experience torque (e.g. due
to <A HREF = "pair_gran.html">frictional granular interactions</A>) and have an
orientation. These contributions are accounted for by these fixes.
</P>
<P>Forces between particles within a body do not contribute to the
external force or torque on the body. Thus for computational
efficiency, you may wish to turn off pairwise and bond interactions
between particles within each rigid body. The <A HREF = "neigh_modify.html">neigh_modify
exclude</A> and <A HREF = "delete_bonds.html">delete_bonds</A>
commands are used to do this. For finite-size particles this also
means the particles can be highly overlapped when creating the rigid
body.
</P>
<HR>
<P>Each body must have two or more atoms. An atom can belong to at most
one rigid body. Which atoms are in which bodies can be defined via
several options.
</P>
<P>For bodystyle <I>single</I> the entire fix group of atoms is treated as one
rigid body.
</P>
<P>For bodystyle <I>molecule</I>, each set of atoms in the fix group with a
different molecule ID is treated as a rigid body.
</P>
<P>For bodystyle <I>group</I>, each of the listed groups is treated as a
separate rigid body. Only atoms that are also in the fix group are
included in each rigid body.
</P>
<P>IMPORTANT NOTE: To compute the initial center-of-mass position and
other properties of each rigid body, the image flags for each atom in
the body are used to "unwrap" the atom coordinates. Thus you must
insure that these image flags are consistent so that the unwrapping
creates a valid rigid body (one where the atoms are close together),
particularly if the atoms in a single rigid body straddle a periodic
boundary. This means the input data file or restart file must define
the image flags for each atom consistently or that you have used the
<A HREF = "set.html">set</A> command to specify them correctly. If a dimension is
non-periodic then the image flag of each atom must be 0 in that
dimension, else an error is generated.
</P>
<P>By default, each rigid body is acted on by other atoms which induce an
external force and torque on its center of mass, causing it to
translate and rotate. Components of the external center-of-mass force
and torque can be turned off by the <I>force</I> and <I>torque</I> keywords.
This may be useful if you wish a body to rotate but not translate, or
vice versa, or if you wish it to rotate or translate continuously
unaffected by interactions with other particles. Note that if you
expect a rigid body not to move or rotate by using these keywords, you
must insure its initial center-of-mass translational or angular
velocity is 0.0. Otherwise the initial translational or angular
momentum the body has will persist.
</P>
<P>An xflag, yflag, or zflag set to <I>off</I> means turn off the component of
force of torque in that dimension. A setting of <I>on</I> means turn on
the component, which is the default. Which rigid body(s) the settings
apply to is determined by the first argument of the <I>force</I> and
<I>torque</I> keywords. It can be an integer M from 1 to Nbody, where
Nbody is the number of rigid bodies defined. A wild-card asterisk can
be used in place of, or in conjunction with, the M argument to set the
flags for multiple rigid bodies. This takes the form "*" or "*n" or
"n*" or "m*n". If N = the number of rigid bodies, then an asterisk
with no numeric values means all bodies from 1 to N. A leading
asterisk means all bodies from 1 to n (inclusive). A trailing
asterisk means all bodies from n to N (inclusive). A middle asterisk
means all types from m to n (inclusive). Note that you can use the
<I>force</I> or <I>torque</I> keywords as many times as you like. If a
particular rigid body has its component flags set multiple times, the
settings from the final keyword are used.
</P>
<P>For computational efficiency, you may wish to turn off pairwise and
bond interactions within each rigid body, as they no longer contribute
to the motion. The <A HREF = "neigh_modify.html">neigh_modify exclude</A> and
<A HREF = "delete_bonds.html">delete_bonds</A> commands are used to do this.
</P>
<P>For computational efficiency, you should typically define one fix
rigid which includes all the desired rigid bodies. LAMMPS will allow
multiple rigid fixes to be defined, but it is more expensive.
</P>
<HR>
<P>The keyword/value option pairs are used in the following ways.
</P>
<P>The <I>langevin</I> and <I>temp</I> and <I>tparam</I> keywords perform thermostatting
of the rigid bodies, altering both their translational and rotational
degrees of freedom. What is meant by "temperature" of a collection of
rigid bodies and how it can be monitored via the fix output is
discussed below.
</P>
<P>The <I>langevin</I> keyword applies a Langevin thermostat to the constant
NVE time integration performed by either the <I>rigid</I> or <I>rigid/nve</I>
styles. It cannot be used with the <I>rigid/nvt</I> style. The desired
temperature at each timestep is a ramped value during the run from
<I>Tstart</I> to <I>Tstop</I>. The <I>Tdamp</I> parameter is specified in time units
and determines how rapidly the temperature is relaxed. For example, a
value of 100.0 means to relax the temperature in a timespan of
(roughly) 100 time units (tau or fmsec or psec - see the
<A HREF = "units.html">units</A> command). The random # <I>seed</I> must be a positive
integer. The way the Langevin thermostatting operates is explained on
the <A HREF = "fix_langevin.html">fix langevin</A> doc page.
</P>
<P>The <I>temp</I> and <I>tparam</I> keywords apply a Nose/Hoover thermostat to the
NVT time integration performed by the <I>rigid/nvt</I> style. They cannot
be used with the <I>rigid</I> or <I>rigid/nve</I> styles. The desired
temperature at each timestep is a ramped value during the run from
<I>Tstart</I> to <I>Tstop</I>. The <I>Tdamp</I> parameter is specified in time units
and determines how rapidly the temperature is relaxed. For example, a
value of 100.0 means to relax the temperature in a timespan of
(roughly) 100 time units (tau or fmsec or psec - see the
<A HREF = "units.html">units</A> command).
</P>
<P>Nose/Hoover chains are used in conjunction with this thermostat. The
<I>tparam</I> keyword can optionally be used to change the chain settings
used. <I>Tchain</I> is the number of thermostats in the Nose Hoover chain.
This value, along with <I>Tdamp</I> can be varied to dampen undesirable
oscillations in temperature that can occur in a simulation. As a rule
of thumb, increasing the chain length should lead to smaller
oscillations.
</P>
<P>IMPORTANT NOTE: There are alternate ways to thermostat a system of
rigid bodies. You can use <A HREF = "fix_langevin.html">fix langevin</A> to treat
the individual particles in the rigid bodies as effectively immersed
in an implicit solvent, e.g. a Brownian dynamics model. For hybrid
systems with both rigid bodies and solvent particles, you can
thermostat only the solvent particles that surround one or more rigid
bodies by appropriate choice of groups in the compute and fix commands
for temperature and thermostatting. The solvent interactions with the
rigid bodies should then effectively thermostat the rigid body
temperature as well without use of the Langevin or Nose/Hoover options
associated with the fix rigid commands.
</P>
<P>The <I>infile</I> keyword allows a file of rigid body attributes to be read
in from a file, rather then letting LAMMPS compute them. There are 3
such attributes: the total mass of the rigid body, its center-of-mass
position, and its 6 moments of inertia. For rigid bodies consisting
of point particles or non-overlapping finite-size particles, LAMMPS
can compute these values accurately. However, for rigid bodies
consisting of finite-size particles which overlap each other, LAMMPS
will ignore the overlaps when computing these 3 attributes. The
amount of error this induces depends on the amount of overlap. To
avoid this issue, the values can be pre-computed (e.g. using Monte
Carlo integration).
</P>
<P>The format of the file is as follows. Note that The file does not
have to list attributes for every rigid body integrated by fix rigid.
Only bodies which the file specifies will have their computed
attributes overridden. The file can contain
initial blank lines or comment lines starting with "#" which
are ignored. The first non-blank, non-comment line should
list N = the number of lines to follow. The N successive lines
contain the following information:
</P>
<PRE>ID1 masstotal xcm ycm zcm ixx iyy izz ixy ixz iyz
ID2 masstotal xcm ycm zcm ixx iyy izz ixy ixz iyz
...
IDN masstotal xcm ycm zcm ixx iyy izz ixy ixz iyz
</PRE>
<P>The rigid body IDs are all positive integers. For the <I>single</I>
bodystyle, only an ID of 1 can be used. For the <I>group</I> bodystyle,
IDs from 1 to Ng can be used where Ng is the number of specified
groups. For the <I>molecule</I> bodystyle, use the molecule ID for the
atoms in a specific rigid body as the rigid body ID.
</P>
<P>The masstotal and center-of-mass coordinates (xcm,ycm,zcm) are
self-explanatory. The center-of-mass should be consistent with what
is calculated for the position of the rigid body with all its atoms
unwrapped by their respective image flags. If this produces a
center-of-mass that is outside the simulation box, LAMMPS wraps it
back into the box. The 6 moments of inertia (ixx,iyy,izz,ixy,ixz,iyz)
should be the values consistent with the current orientation of the
rigid body around its center of mass. The values are with respect to
-the XYZ coordinate axes, not with respect to the prinicpal axes of the
-rigid body itself. LAMMPS performs the latter calcultion internally.
+the simulation box XYZ axes, not with respect to the prinicpal axes of
+the rigid body itself. LAMMPS performs the latter calculation
+internally.
</P>
<P>IMPORTANT NOTE: The last point means that you cannot restart a
simulation with rigid bodies using the
<A HREF = "read_restart.html">read_restart</A> command and use the same <I>infile</I> of
rigid body attributes as input for the 2nd simulation, if the rigid
bodies have moved or rotated. Instead, you need to produce a new
<I>infile</I> that reflects the correct attributes for each rigid body at
the time of restart. We are thinking about a good way to overcome
this issue.
</P>
<HR>
<P>If you use a <A HREF = "compute.html">temperature compute</A> with a group that
includes particles in rigid bodies, the degrees-of-freedom removed by
each rigid body are accounted for in the temperature (and pressure)
computation, but only if the temperature group includes all the
particles in a particular rigid body.
</P>
<P>A 3d rigid body has 6 degrees of freedom (3 translational, 3
rotational), except for a collection of point particles lying on a
straight line, which has only 5, e.g a dimer. A 2d rigid body has 3
degrees of freedom (2 translational, 1 rotational).
</P>
<P>IMPORTANT NOTE: You may wish to explicitly subtract additional
degrees-of-freedom if you use the <I>force</I> and <I>torque</I> keywords to
eliminate certain motions of one or more rigid bodies. LAMMPS does
not do this automatically.
</P>
<P>The rigid body contribution to the pressure of the system (virial) is
also accounted for by this fix.
</P>
<P>IMPORTANT NOTE: The periodic image flags of atoms in rigid bodies are
altered so that the rigid body can be reconstructed correctly when it
straddles periodic boundaries. The atom image flags are not
incremented/decremented as they would be for non-rigid atoms as the
rigid body crosses periodic boundaries. This means you cannot
interpret them as you normally would. For example, the image flag
values written to a <A HREF = "dump.html">dump file</A> will be different than they
would be if the atoms were not in a rigid body. Likewise the <A HREF = "compute_msd.html">compute
msd</A> will not compute the expected mean-squared
displacement for such atoms if the body moves across periodic
boundaries. It also means that if you have bonds between a pair of
rigid bodies and the bond straddles a periodic boundary, you cannot
use the <A HREF = "replicate.html">replicate</A> command to increase the system
size. Note that this fix does define image flags for each rigid body,
which are incremented when the rigid body crosses a periodic boundary
in the usual way. These image flags have the same meaning as atom
images (see the "dump" command) and can be accessed and output as
described below.
</P>
<HR>
<P><B>Restart, fix_modify, output, run start/stop, minimize info:</B>
</P>
<P>No information about the <I>rigid</I> and <I>rigid/nve</I> fixes are written to
<A HREF = "restart.html">binary restart files</A>. For style <I>rigid/nvt</I> the state
of the Nose/Hoover thermostat is written to <A HREF = "restart.html">binary restart
files</A>. See the <A HREF = "read_restart.html">read_restart</A> command
for info on how to re-specify a fix in an input script that reads a
restart file, so that the operation of the fix continues in an
uninterrupted fashion.
</P>
<P>The <A HREF = "fix_modify.html">fix_modify</A> <I>energy</I> option is supported by the
rigid/nvt fix to add the energy change induced by the thermostatting
to the system's potential energy as part of <A HREF = "thermo_style.html">thermodynamic
output</A>.
</P>
<P>The rigid and rigid/nve fixes computes a global scalar which can be
accessed by various <A HREF = "Section_howto.html#howto_15">output commands</A>.
The scalar value calculated by these fixes is "intensive". The scalar
is the current temperature of the collection of rigid bodies. This is
averaged over all rigid bodies and their translational and rotational
degrees of freedom. The translational energy of a rigid body is 1/2 m
v^2, where m = total mass of the body and v = the velocity of its
center of mass. The rotational energy of a rigid body is 1/2 I w^2,
where I = the moment of inertia tensor of the body and w = its angular
velocity. Degrees of freedom constrained by the <I>force</I> and <I>torque</I>
keywords are removed from this calculation.
</P>
<P>The rigid/nvt fix computes a global scalar which can be accessed by
various <A HREF = "Section_howto.html#howto_15">output commands</A>. The scalar
value calculated by the rigid/nvt fix is "extensive". The scalar is
the cumulative energy change due to the thermostatting the fix
performs.
</P>
<P>All of these fixes compute a global array of values which can be
accessed by various <A HREF = "Section_howto.html#howto_15">output commands</A>.
The number of rows in the array is equal to the number of rigid
bodies. The number of columns is 15. Thus for each rigid body, 15
values are stored: the xyz coords of the center of mass (COM), the xyz
components of the COM velocity, the xyz components of the force acting
on the COM, the xyz components of the torque acting on the COM, and
the xyz image flags of the COM, which have the same meaning as image
flags for atom positions (see the "dump" command). The force and
torque values in the array are not affected by the <I>force</I> and
<I>torque</I> keywords in the fix rigid command; they reflect values before
any changes are made by those keywords.
</P>
<P>The ordering of the rigid bodies (by row in the array) is as follows.
For the <I>single</I> keyword there is just one rigid body. For the
<I>molecule</I> keyword, the bodies are ordered by ascending molecule ID.
For the <I>group</I> keyword, the list of group IDs determines the ordering
of bodies.
</P>
<P>The array values calculated by these fixes are "intensive", meaning
they are independent of the number of atoms in the simulation.
</P>
<P>No parameter of these fixes can be used with the <I>start/stop</I> keywords
of the <A HREF = "run.html">run</A> command. These fixes are not invoked during
<A HREF = "minimize.html">energy minimization</A>.
</P>
<P><B>Restrictions:</B>
</P>
<P>These fixes performs an MPI_Allreduce each timestep that is
proportional in length to the number of rigid bodies. Hence they will
not scale well in parallel if large numbers of rigid bodies are
simulated.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "delete_bonds.html">delete_bonds</A>, <A HREF = "neigh_modify.html">neigh_modify</A>
exclude
</P>
<P><B>Default:</B>
</P>
<P>The option defaults are force * on on on and torque * on on on,
meaning all rigid bodies are acted on by center-of-mass force and
torque. Also Tchain = 10, Titer = 1, Torder = 3.
</P>
<HR>
<A NAME = "Hoover"></A>
<P><B>(Hoover)</B> Hoover, Phys Rev A, 31, 1695 (1985).
</P>
<A NAME = "Kamberaj"></A>
<P><B>(Kamberaj)</B> Kamberaj, Low, Neal, J Chem Phys, 122, 224114 (2005).
</P>
<A NAME = "Martyna"></A>
<P><B>(Martyna)</B> Martyna, Klein, Tuckerman, J Chem Phys, 97, 2635 (1992);
Martyna, Tuckerman, Tobias, Klein, Mol Phys, 87, 1117.
</P>
<A NAME = "Miller"></A>
<P><B>(Miller)</B> Miller, Eleftheriou, Pattnaik, Ndirango, and Newns,
J Chem Phys, 116, 8649 (2002).
</P>
<A NAME = "Zhang"></A>
<P><B>(Zhang)</B> Zhang, Glotzer, Nanoletters, 4, 1407-1413 (2004).
</P>
</HTML>
diff --git a/doc/fix_rigid.txt b/doc/fix_rigid.txt
index 17fcc9e24..0e8f5beea 100644
--- a/doc/fix_rigid.txt
+++ b/doc/fix_rigid.txt
@@ -1,437 +1,438 @@
"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
fix rigid command :h3
fix rigid/nve command :h3
fix rigid/nvt command :h3
[Syntax:]
fix ID group-ID style bodystyle args keyword values ... :pre
ID, group-ID are documented in "fix"_fix.html command :ulb,l
style = {rigid} or {rigid/nve} or {rigid/nvt} :l
bodystyle = {single} or {molecule} or {group} :l
{single} args = none
{molecule} args = none
{group} args = N groupID1 groupID2 ...
N = # of groups
groupID1, groupID2, ... = list of N group IDs :pre
zero or more keyword/value pairs may be appended :l
keyword = {langevin} or {temp} or {tparam} or {force} or {torque} or {infile} :l
{langevin} values = Tstart Tstop Tperiod seed
Tstart,Tstop = desired temperature at start/stop of run (temperature units)
Tdamp = temperature damping parameter (time units)
seed = random number seed to use for white noise (positive integer)
{temp} values = Tstart Tstop Tdamp
Tstart,Tstop = desired temperature at start/stop of run (temperature units)
Tdamp = temperature damping parameter (time units)
{tparam} values = Tchain Titer Torder
Tchain = length of Nose/Hoover thermostat chain
Titer = number of thermostat iterations performed
Torder = 3 or 5 = Yoshida-Suzuki integration parameters
{force} values = M xflag yflag zflag
M = which rigid body from 1-Nbody (see asterisk form below)
xflag,yflag,zflag = off/on if component of center-of-mass force is active
{torque} values = M xflag yflag zflag
M = which rigid body from 1-Nbody (see asterisk form below)
xflag,yflag,zflag = off/on if component of center-of-mass torque is active
{infile} filename
filename = file with per-body values of mass, center-of-mass, moments of inertia :pre
:ule
[Examples:]
fix 1 clump rigid single
fix 1 clump rigid single force 1 off off on langevin 1.0 1.0 1.0 428984
fix 1 polychains rigid/nvt molecule temp 1.0 1.0 5.0
fix 1 polychains rigid molecule force 1*5 off off off force 6*10 off off on
fix 2 fluid rigid group 3 clump1 clump2 clump3 torque * off off off :pre
[Description:]
Treat one or more sets of atoms as independent rigid bodies. This
means that each timestep the total force and torque on each rigid body
is computed as the sum of the forces and torques on its constituent
particles and the coordinates, velocities, and orientations of the
atoms in each body are updated so that the body moves and rotates as a
single entity.
Examples of large rigid bodies are a large colloidal particle, or
portions of a large biomolecule such as a protein.
Example of small rigid bodies are patchy nanoparticles, such as those
modeled in "this paper"_#Zhang by Sharon Glotzer's group, clumps of
granular particles, lipid molecules consiting of one or more point
dipoles connected to other spheroids or ellipsoids, irregular
particles built from line segments (2d) or triangles (3d), and
coarse-grain models of nano or colloidal particles consisting of a
small number of constituent particles. Note that the "fix
shake"_fix_shake.html command can also be used to rigidify small
molecules of 2, 3, or 4 atoms, e.g. water molecules. That fix treats
the constituent atoms as point masses.
These fixes also update the positions and velocities of the atoms in
each rigid body via time integration. The {rigid} and {rigid/nve}
styles do this via constant NVE integration. The only difference is
that the {rigid} style uses an integration technique based on
Richardson iterations. The {rigid/nve} style uses the methods
described in the paper by "Miller"_#Miller, which are thought to
provide better energy conservation than an iterative approach.
The {rigid/nvt} style performs constant NVT integration using a
Nose/Hoover thermostat with chains as described originally in
"(Hoover)"_#Hoover and "(Martyna)"_#Martyna, which thermostats both
the translational and rotational degrees of freedom of the rigid
bodies. The rigid-body algorithm used by {rigid/nvt} is described in
the paper by "Kamberaj"_#Kamberaj.
IMPORTANT NOTE: You should not update the atoms in rigid bodies via
other time-integration fixes (e.g. nve, nvt, npt), or you will be
integrating their motion more than once each timestep.
IMPORTANT NOTE: These fixes are overkill if you simply want to hold a
collection of atoms stationary or have them move with a constant
velocity. A simpler way to hold atoms stationary is to not include
those atoms in your time integration fix. E.g. use "fix 1 mobile nve"
instead of "fix 1 all nve", where "mobile" is the group of atoms that
you want to move. You can move atoms with a constant velocity by
assigning them an initial velocity (via the "velocity"_velocity.html
command), setting the force on them to 0.0 (via the "fix
setforce"_fix_setforce.html command), and integrating them as usual
(e.g. via the "fix nve"_fix_nve.html command).
:line
The constituent particles within a rigid body can be point particles
(the default in LAMMPS) or finite-size particles, such as spheres or
ellipsoids or line segments or triangles. See the "atom_style sphere
and ellipsoid and line and tri"_atom_style.html commands for more
details on these kinds of particles. Finite-size particles contribute
differently to the moment of inertia of a rigid body than do point
particles. Finite-size particles can also experience torque (e.g. due
to "frictional granular interactions"_pair_gran.html) and have an
orientation. These contributions are accounted for by these fixes.
Forces between particles within a body do not contribute to the
external force or torque on the body. Thus for computational
efficiency, you may wish to turn off pairwise and bond interactions
between particles within each rigid body. The "neigh_modify
exclude"_neigh_modify.html and "delete_bonds"_delete_bonds.html
commands are used to do this. For finite-size particles this also
means the particles can be highly overlapped when creating the rigid
body.
:line
Each body must have two or more atoms. An atom can belong to at most
one rigid body. Which atoms are in which bodies can be defined via
several options.
For bodystyle {single} the entire fix group of atoms is treated as one
rigid body.
For bodystyle {molecule}, each set of atoms in the fix group with a
different molecule ID is treated as a rigid body.
For bodystyle {group}, each of the listed groups is treated as a
separate rigid body. Only atoms that are also in the fix group are
included in each rigid body.
IMPORTANT NOTE: To compute the initial center-of-mass position and
other properties of each rigid body, the image flags for each atom in
the body are used to "unwrap" the atom coordinates. Thus you must
insure that these image flags are consistent so that the unwrapping
creates a valid rigid body (one where the atoms are close together),
particularly if the atoms in a single rigid body straddle a periodic
boundary. This means the input data file or restart file must define
the image flags for each atom consistently or that you have used the
"set"_set.html command to specify them correctly. If a dimension is
non-periodic then the image flag of each atom must be 0 in that
dimension, else an error is generated.
By default, each rigid body is acted on by other atoms which induce an
external force and torque on its center of mass, causing it to
translate and rotate. Components of the external center-of-mass force
and torque can be turned off by the {force} and {torque} keywords.
This may be useful if you wish a body to rotate but not translate, or
vice versa, or if you wish it to rotate or translate continuously
unaffected by interactions with other particles. Note that if you
expect a rigid body not to move or rotate by using these keywords, you
must insure its initial center-of-mass translational or angular
velocity is 0.0. Otherwise the initial translational or angular
momentum the body has will persist.
An xflag, yflag, or zflag set to {off} means turn off the component of
force of torque in that dimension. A setting of {on} means turn on
the component, which is the default. Which rigid body(s) the settings
apply to is determined by the first argument of the {force} and
{torque} keywords. It can be an integer M from 1 to Nbody, where
Nbody is the number of rigid bodies defined. A wild-card asterisk can
be used in place of, or in conjunction with, the M argument to set the
flags for multiple rigid bodies. This takes the form "*" or "*n" or
"n*" or "m*n". If N = the number of rigid bodies, then an asterisk
with no numeric values means all bodies from 1 to N. A leading
asterisk means all bodies from 1 to n (inclusive). A trailing
asterisk means all bodies from n to N (inclusive). A middle asterisk
means all types from m to n (inclusive). Note that you can use the
{force} or {torque} keywords as many times as you like. If a
particular rigid body has its component flags set multiple times, the
settings from the final keyword are used.
For computational efficiency, you may wish to turn off pairwise and
bond interactions within each rigid body, as they no longer contribute
to the motion. The "neigh_modify exclude"_neigh_modify.html and
"delete_bonds"_delete_bonds.html commands are used to do this.
For computational efficiency, you should typically define one fix
rigid which includes all the desired rigid bodies. LAMMPS will allow
multiple rigid fixes to be defined, but it is more expensive.
:line
The keyword/value option pairs are used in the following ways.
The {langevin} and {temp} and {tparam} keywords perform thermostatting
of the rigid bodies, altering both their translational and rotational
degrees of freedom. What is meant by "temperature" of a collection of
rigid bodies and how it can be monitored via the fix output is
discussed below.
The {langevin} keyword applies a Langevin thermostat to the constant
NVE time integration performed by either the {rigid} or {rigid/nve}
styles. It cannot be used with the {rigid/nvt} style. The desired
temperature at each timestep is a ramped value during the run from
{Tstart} to {Tstop}. The {Tdamp} parameter is specified in time units
and determines how rapidly the temperature is relaxed. For example, a
value of 100.0 means to relax the temperature in a timespan of
(roughly) 100 time units (tau or fmsec or psec - see the
"units"_units.html command). The random # {seed} must be a positive
integer. The way the Langevin thermostatting operates is explained on
the "fix langevin"_fix_langevin.html doc page.
The {temp} and {tparam} keywords apply a Nose/Hoover thermostat to the
NVT time integration performed by the {rigid/nvt} style. They cannot
be used with the {rigid} or {rigid/nve} styles. The desired
temperature at each timestep is a ramped value during the run from
{Tstart} to {Tstop}. The {Tdamp} parameter is specified in time units
and determines how rapidly the temperature is relaxed. For example, a
value of 100.0 means to relax the temperature in a timespan of
(roughly) 100 time units (tau or fmsec or psec - see the
"units"_units.html command).
Nose/Hoover chains are used in conjunction with this thermostat. The
{tparam} keyword can optionally be used to change the chain settings
used. {Tchain} is the number of thermostats in the Nose Hoover chain.
This value, along with {Tdamp} can be varied to dampen undesirable
oscillations in temperature that can occur in a simulation. As a rule
of thumb, increasing the chain length should lead to smaller
oscillations.
IMPORTANT NOTE: There are alternate ways to thermostat a system of
rigid bodies. You can use "fix langevin"_fix_langevin.html to treat
the individual particles in the rigid bodies as effectively immersed
in an implicit solvent, e.g. a Brownian dynamics model. For hybrid
systems with both rigid bodies and solvent particles, you can
thermostat only the solvent particles that surround one or more rigid
bodies by appropriate choice of groups in the compute and fix commands
for temperature and thermostatting. The solvent interactions with the
rigid bodies should then effectively thermostat the rigid body
temperature as well without use of the Langevin or Nose/Hoover options
associated with the fix rigid commands.
The {infile} keyword allows a file of rigid body attributes to be read
in from a file, rather then letting LAMMPS compute them. There are 3
such attributes: the total mass of the rigid body, its center-of-mass
position, and its 6 moments of inertia. For rigid bodies consisting
of point particles or non-overlapping finite-size particles, LAMMPS
can compute these values accurately. However, for rigid bodies
consisting of finite-size particles which overlap each other, LAMMPS
will ignore the overlaps when computing these 3 attributes. The
amount of error this induces depends on the amount of overlap. To
avoid this issue, the values can be pre-computed (e.g. using Monte
Carlo integration).
The format of the file is as follows. Note that The file does not
have to list attributes for every rigid body integrated by fix rigid.
Only bodies which the file specifies will have their computed
attributes overridden. The file can contain
initial blank lines or comment lines starting with "#" which
are ignored. The first non-blank, non-comment line should
list N = the number of lines to follow. The N successive lines
contain the following information:
ID1 masstotal xcm ycm zcm ixx iyy izz ixy ixz iyz
ID2 masstotal xcm ycm zcm ixx iyy izz ixy ixz iyz
...
IDN masstotal xcm ycm zcm ixx iyy izz ixy ixz iyz :pre
The rigid body IDs are all positive integers. For the {single}
bodystyle, only an ID of 1 can be used. For the {group} bodystyle,
IDs from 1 to Ng can be used where Ng is the number of specified
groups. For the {molecule} bodystyle, use the molecule ID for the
atoms in a specific rigid body as the rigid body ID.
The masstotal and center-of-mass coordinates (xcm,ycm,zcm) are
self-explanatory. The center-of-mass should be consistent with what
is calculated for the position of the rigid body with all its atoms
unwrapped by their respective image flags. If this produces a
center-of-mass that is outside the simulation box, LAMMPS wraps it
back into the box. The 6 moments of inertia (ixx,iyy,izz,ixy,ixz,iyz)
should be the values consistent with the current orientation of the
rigid body around its center of mass. The values are with respect to
-the XYZ coordinate axes, not with respect to the prinicpal axes of the
-rigid body itself. LAMMPS performs the latter calcultion internally.
+the simulation box XYZ axes, not with respect to the prinicpal axes of
+the rigid body itself. LAMMPS performs the latter calculation
+internally.
IMPORTANT NOTE: The last point means that you cannot restart a
simulation with rigid bodies using the
"read_restart"_read_restart.html command and use the same {infile} of
rigid body attributes as input for the 2nd simulation, if the rigid
bodies have moved or rotated. Instead, you need to produce a new
{infile} that reflects the correct attributes for each rigid body at
the time of restart. We are thinking about a good way to overcome
this issue.
:line
If you use a "temperature compute"_compute.html with a group that
includes particles in rigid bodies, the degrees-of-freedom removed by
each rigid body are accounted for in the temperature (and pressure)
computation, but only if the temperature group includes all the
particles in a particular rigid body.
A 3d rigid body has 6 degrees of freedom (3 translational, 3
rotational), except for a collection of point particles lying on a
straight line, which has only 5, e.g a dimer. A 2d rigid body has 3
degrees of freedom (2 translational, 1 rotational).
IMPORTANT NOTE: You may wish to explicitly subtract additional
degrees-of-freedom if you use the {force} and {torque} keywords to
eliminate certain motions of one or more rigid bodies. LAMMPS does
not do this automatically.
The rigid body contribution to the pressure of the system (virial) is
also accounted for by this fix.
IMPORTANT NOTE: The periodic image flags of atoms in rigid bodies are
altered so that the rigid body can be reconstructed correctly when it
straddles periodic boundaries. The atom image flags are not
incremented/decremented as they would be for non-rigid atoms as the
rigid body crosses periodic boundaries. This means you cannot
interpret them as you normally would. For example, the image flag
values written to a "dump file"_dump.html will be different than they
would be if the atoms were not in a rigid body. Likewise the "compute
msd"_compute_msd.html will not compute the expected mean-squared
displacement for such atoms if the body moves across periodic
boundaries. It also means that if you have bonds between a pair of
rigid bodies and the bond straddles a periodic boundary, you cannot
use the "replicate"_replicate.html command to increase the system
size. Note that this fix does define image flags for each rigid body,
which are incremented when the rigid body crosses a periodic boundary
in the usual way. These image flags have the same meaning as atom
images (see the "dump" command) and can be accessed and output as
described below.
:line
[Restart, fix_modify, output, run start/stop, minimize info:]
No information about the {rigid} and {rigid/nve} fixes are written to
"binary restart files"_restart.html. For style {rigid/nvt} the state
of the Nose/Hoover thermostat is written to "binary restart
files"_restart.html. See the "read_restart"_read_restart.html command
for info on how to re-specify a fix in an input script that reads a
restart file, so that the operation of the fix continues in an
uninterrupted fashion.
The "fix_modify"_fix_modify.html {energy} option is supported by the
rigid/nvt fix to add the energy change induced by the thermostatting
to the system's potential energy as part of "thermodynamic
output"_thermo_style.html.
The rigid and rigid/nve fixes computes a global scalar which can be
accessed by various "output commands"_Section_howto.html#howto_15.
The scalar value calculated by these fixes is "intensive". The scalar
is the current temperature of the collection of rigid bodies. This is
averaged over all rigid bodies and their translational and rotational
degrees of freedom. The translational energy of a rigid body is 1/2 m
v^2, where m = total mass of the body and v = the velocity of its
center of mass. The rotational energy of a rigid body is 1/2 I w^2,
where I = the moment of inertia tensor of the body and w = its angular
velocity. Degrees of freedom constrained by the {force} and {torque}
keywords are removed from this calculation.
The rigid/nvt fix computes a global scalar which can be accessed by
various "output commands"_Section_howto.html#howto_15. The scalar
value calculated by the rigid/nvt fix is "extensive". The scalar is
the cumulative energy change due to the thermostatting the fix
performs.
All of these fixes compute a global array of values which can be
accessed by various "output commands"_Section_howto.html#howto_15.
The number of rows in the array is equal to the number of rigid
bodies. The number of columns is 15. Thus for each rigid body, 15
values are stored: the xyz coords of the center of mass (COM), the xyz
components of the COM velocity, the xyz components of the force acting
on the COM, the xyz components of the torque acting on the COM, and
the xyz image flags of the COM, which have the same meaning as image
flags for atom positions (see the "dump" command). The force and
torque values in the array are not affected by the {force} and
{torque} keywords in the fix rigid command; they reflect values before
any changes are made by those keywords.
The ordering of the rigid bodies (by row in the array) is as follows.
For the {single} keyword there is just one rigid body. For the
{molecule} keyword, the bodies are ordered by ascending molecule ID.
For the {group} keyword, the list of group IDs determines the ordering
of bodies.
The array values calculated by these fixes are "intensive", meaning
they are independent of the number of atoms in the simulation.
No parameter of these fixes can be used with the {start/stop} keywords
of the "run"_run.html command. These fixes are not invoked during
"energy minimization"_minimize.html.
[Restrictions:]
These fixes performs an MPI_Allreduce each timestep that is
proportional in length to the number of rigid bodies. Hence they will
not scale well in parallel if large numbers of rigid bodies are
simulated.
[Related commands:]
"delete_bonds"_delete_bonds.html, "neigh_modify"_neigh_modify.html
exclude
[Default:]
The option defaults are force * on on on and torque * on on on,
meaning all rigid bodies are acted on by center-of-mass force and
torque. Also Tchain = 10, Titer = 1, Torder = 3.
:line
:link(Hoover)
[(Hoover)] Hoover, Phys Rev A, 31, 1695 (1985).
:link(Kamberaj)
[(Kamberaj)] Kamberaj, Low, Neal, J Chem Phys, 122, 224114 (2005).
:link(Martyna)
[(Martyna)] Martyna, Klein, Tuckerman, J Chem Phys, 97, 2635 (1992);
Martyna, Tuckerman, Tobias, Klein, Mol Phys, 87, 1117.
:link(Miller)
[(Miller)] Miller, Eleftheriou, Pattnaik, Ndirango, and Newns,
J Chem Phys, 116, 8649 (2002).
:link(Zhang)
[(Zhang)] Zhang, Glotzer, Nanoletters, 4, 1407-1413 (2004).
diff --git a/doc/min_modify.html b/doc/min_modify.html
index ced08b2c6..e052b633a 100644
--- a/doc/min_modify.html
+++ b/doc/min_modify.html
@@ -1,79 +1,79 @@
<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>min_modify command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>min_modify keyword values ...
</PRE>
<UL><LI>one or more keyword/value pairs may be listed
<PRE>keyword = <I>dmax</I> or <I>line</I>
<I>dmax</I> value = max
max = maximum distance for line search to move (distance units)
- <I>line</I> value = <I>backtrack</I> or <I>quadratic</I>or <I>forcezero</I>
+ <I>line</I> value = <I>backtrack</I> or <I>quadratic</I> or <I>forcezero</I>
backtrack,quadratic,forcezero = style of linesearch to use
</PRE>
</UL>
<P><B>Examples:</B>
</P>
<PRE>min_modify dmax 0.2
</PRE>
<P><B>Description:</B>
</P>
<P>This command sets parameters that affect the energy minimization
algorithms selected by the <A HREF = "min_style.html">min_style</A> command. The
various settings may affect the convergence rate and overall number of
force evaluations required by a minimization, so users can experiment
with these parameters to tune their minimizations.
</P>
<P>The <I>cg</I> and <I>sd</I> minimization styles have an outer iteration and an
inner iteration which is steps along a one-dimensional line search in
a particular search direction. The <I>dmax</I> parameter is how far any
atom can move in a single line search in any dimension (x, y, or z).
For the <I>quickmin</I> and <I>fire</I> minimization styles, the <I>dmax</I> setting
is how far any atom can move in a single iteration (timestep). Thus a
value of 0.1 in real <A HREF = "units.html">units</A> means no atom will move
further than 0.1 Angstroms in a single outer iteration. This prevents
highly overlapped atoms from being moved long distances (e.g. through
another atom) due to large forces.
</P>
<P>The choice of line search algorithm for the <I>cg</I> and <I>sd</I> minimization
styles can be selected via the <I>line</I> keyword. The default
backtracking search is robust and should always find a local energy
minimum. However, it will "converge" when it can no longer reduce the
energy of the system. Individual atom forces may still be larger than
desired at this point, because the energy change is measured as the
difference of two large values (energy before and energy after) and
that difference may be smaller than machine epsilon even if atoms
could move in the gradient direction to reduce forces further.
</P>
<P>By contrast, the <I>quadratic</I> line search algorithm tries to
reduce the forces to zero, while guaranteeing that the energy
changes is not positive (uphill). For some systems, it may also
be more efficient than the backtracking algorithm by
requiring fewer energy/force evaluations. The <I>forcezero</I>
line search algorithm is similar to <I>quadratic</I>.
It may be more efficient than <I>quadratic</I> on some systems.
</P>
<P><B>Restrictions:</B> none
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "min_style.html">min_style</A>, <A HREF = "minimize.html">minimize</A>
</P>
<P><B>Default:</B>
</P>
<P>The option defaults are dmax = 0.1 and line = backtrack.
</P>
</HTML>
diff --git a/doc/min_modify.txt b/doc/min_modify.txt
index 3cca32a85..27bab8f96 100644
--- a/doc/min_modify.txt
+++ b/doc/min_modify.txt
@@ -1,72 +1,72 @@
"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
min_modify command :h3
[Syntax:]
min_modify keyword values ... :pre
one or more keyword/value pairs may be listed :ulb,l
keyword = {dmax} or {line}
{dmax} value = max
max = maximum distance for line search to move (distance units)
- {line} value = {backtrack} or {quadratic}or {forcezero}
+ {line} value = {backtrack} or {quadratic} or {forcezero}
backtrack,quadratic,forcezero = style of linesearch to use :pre
:ule
[Examples:]
min_modify dmax 0.2 :pre
[Description:]
This command sets parameters that affect the energy minimization
algorithms selected by the "min_style"_min_style.html command. The
various settings may affect the convergence rate and overall number of
force evaluations required by a minimization, so users can experiment
with these parameters to tune their minimizations.
The {cg} and {sd} minimization styles have an outer iteration and an
inner iteration which is steps along a one-dimensional line search in
a particular search direction. The {dmax} parameter is how far any
atom can move in a single line search in any dimension (x, y, or z).
For the {quickmin} and {fire} minimization styles, the {dmax} setting
is how far any atom can move in a single iteration (timestep). Thus a
value of 0.1 in real "units"_units.html means no atom will move
further than 0.1 Angstroms in a single outer iteration. This prevents
highly overlapped atoms from being moved long distances (e.g. through
another atom) due to large forces.
The choice of line search algorithm for the {cg} and {sd} minimization
styles can be selected via the {line} keyword. The default
backtracking search is robust and should always find a local energy
minimum. However, it will "converge" when it can no longer reduce the
energy of the system. Individual atom forces may still be larger than
desired at this point, because the energy change is measured as the
difference of two large values (energy before and energy after) and
that difference may be smaller than machine epsilon even if atoms
could move in the gradient direction to reduce forces further.
By contrast, the {quadratic} line search algorithm tries to
reduce the forces to zero, while guaranteeing that the energy
changes is not positive (uphill). For some systems, it may also
be more efficient than the backtracking algorithm by
requiring fewer energy/force evaluations. The {forcezero}
line search algorithm is similar to {quadratic}.
It may be more efficient than {quadratic} on some systems.
[Restrictions:] none
[Related commands:]
"min_style"_min_style.html, "minimize"_minimize.html
[Default:]
The option defaults are dmax = 0.1 and line = backtrack.
diff --git a/doc/pair_airebo.html b/doc/pair_airebo.html
index 42502af09..2cb34a219 100644
--- a/doc/pair_airebo.html
+++ b/doc/pair_airebo.html
@@ -1,197 +1,199 @@
<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>pair_style airebo command
</H3>
<H3>pair_style airebo/omp command
</H3>
<H3>pair_style rebo command
</H3>
<H3>pair_style rebo/omp command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style cutoff LJ_flag TORSION_flag
</PRE>
<UL><LI>style = <I>airebo</I> or <I>rebo</I>
<LI>cutoff = LJ cutoff (sigma scale factor) (AIREBO only)
<LI>LJ_flag = 0/1 to turn off/on the LJ term (AIREBO only, optional)
<LI>TORSION_flag = 0/1 to turn off/on the torsion term (AIREBO only, optional)
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style airebo 3.0
pair_style airebo 2.5 1 0
pair_coeff * * ../potentials/CH.airebo H C
</PRE>
<PRE>pair_style rebo
pair_coeff * * ../potentials/CH.airebo H C
</PRE>
<P><B>Description:</B>
</P>
<P>The <I>airebo</I> pair style computes the Adaptive Intermolecular Reactive
Empirical Bond Order (AIREBO) Potential of <A HREF = "#Stuart">(Stuart)</A> for a
system of carbon and/or hydrogen atoms. Note that this is the initial
formulation of AIREBO from 2000, not the later formulation. The
<I>rebo</I> pair style computes the Reactive Empirical Bond Order (REBO)
Potential of <A HREF = "#Brenner">(Brenner)</A>. Note that this is the so-called
2nd generation REBO from 2002, not the original REBO from 1990. As
discussed below, 2nd generation REBO is closely related to the intial
AIREBO; it is just a subset of the potential energy terms.
</P>
<P>The AIREBO potential consists of three terms:
</P>
<CENTER><IMG SRC = "Eqs/pair_airebo.jpg">
</CENTER>
<P>By default, all three terms are included. For the <I>airebo</I> style, if
the two optional flag arguments to the pair_style command are
included, the LJ and torsional terms can be turned off. Note that
both or neither of the flags must be included. If both of the LJ an
torsional terms are turned off, it becomes the 2nd-generation REBO
potential, with a small caveat on the spline fitting procedure
mentioned below. This can be specified directly as pair_style rebo
with no additional arguments.
</P>
<P>The detailed formulas for this potential are given in
<A HREF = "#Stuart">(Stuart)</A>; here we provide only a brief description.
</P>
<P>The E_REBO term has the same functional form as the hydrocarbon REBO
potential developed in <A HREF = "#Brenner">(Brenner)</A>. The coefficients for
E_REBO in AIREBO are essentially the same as Brenner's potential, but
a few fitted spline values are slightly different. For most cases the
E_REBO term in AIREBO will produce the same energies, forces and
statistical averages as the original REBO potential from which it was
derived. The E_REBO term in the AIREBO potential gives the model its
reactive capabilities and only describes short-ranged C-C, C-H and H-H
interactions (r < 2 Angstroms). These interactions have strong
coordination-dependence through a bond order parameter, which adjusts
the attraction between the I,J atoms based on the position of other
nearby atoms and thus has 3- and 4-body dependence.
</P>
<P>The E_LJ term adds longer-ranged interactions (2 < r < cutoff) using a
form similar to the standard <A HREF = "pair_lj.html">Lennard Jones potential</A>.
The E_LJ term in AIREBO contains a series of switching functions so
that the short-ranged LJ repulsion (1/r^12) does not interfere with
the energetics captured by the E_REBO term. The extent of the E_LJ
interactions is determined by the <I>cutoff</I> argument to the pair_style
command which is a scale factor. For each type pair (C-C, C-H, H-H)
the cutoff is obtained by multiplying the scale factor by the sigma
value defined in the potential file for that type pair. In the
standard AIREBO potential, sigma_CC = 3.4 Angstroms, so with a scale
factor of 3.0 (the argument in pair_style), the resulting E_LJ cutoff
would be 10.2 Angstroms.
</P>
<P>The E_TORSION term is an explicit 4-body potential that describes
various dihedral angle preferences in hydrocarbon configurations.
</P>
+<HR>
+
<P>Only a single pair_coeff command is used with the <I>airebo</I> or <I>rebo</I>
style which specifies an AIREBO potential file with parameters for C
and H. Note that the <I>rebo</I> style in LAMMPS uses the same
AIREBO-formatted potential file. These are mapped to LAMMPS atom
types by specifying N additional arguments after the filename in the
pair_coeff command, where N is the number of LAMMPS atom types:
</P>
<UL><LI>filename
<LI>N element names = mapping of AIREBO elements to atom types
</UL>
<P>As an example, if your LAMMPS simulation has 4 atom types and you want
the 1st 3 to be C, and the 4th to be H, you would use the following
pair_coeff command:
</P>
<PRE>pair_coeff * * CH.airebo C C C H
</PRE>
<P>The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three C arguments map LAMMPS atom types 1,2,3 to the C
element in the AIREBO file. The final H argument maps LAMMPS atom
type 4 to the H element in the SW file. If a mapping value is
specified as NULL, the mapping is not performed. This can be used
when a <I>airebo</I> potential is used as part of the <I>hybrid</I> pair style.
The NULL values are placeholders for atom types that will be used with
other potentials.
</P>
<P>The parameters/coefficients for the AIREBO potentials are listed in
the CH.airebo file to agree with the original <A HREF = "#Stuart">(Stuart)</A>
paper. Thus the parameters are specific to this potential and the way
it was fit, so modifying the file should be done cautiously.
</P>
<HR>
<P>Styles with a <I>cuda</I>, <I>gpu</I>, <I>omp</I>, or <I>opt</I> suffix are functionally
the same as the corresponding style without the suffix. They have
been optimized to run faster, depending on your available hardware, as
discussed in <A HREF = "Section_accelerate.html">Section_accelerate</A> of the
manual. The accelerated styles take the same arguments and should
produce the same results, except for round-off and precision issues.
</P>
<P>These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A>
section for more info.
</P>
<P>You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the <A HREF = "Section_start.html#start_7">-suffix command-line
switch</A> when you invoke LAMMPS, or you can
use the <A HREF = "suffix.html">suffix</A> command in your input script.
</P>
<P>See <A HREF = "Section_accelerate.html">Section_accelerate</A> of the manual for
more instructions on how to use the accelerated styles effectively.
</P>
<HR>
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
</P>
<P>These pair styles do not support the <A HREF = "pair_modify.html">pair_modify</A>
mix, shift, table, and tail options.
</P>
<P>These pair styles do not write their information to <A HREF = "restart.html">binary restart
files</A>, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
</P>
<P>These pair styles can only be used via the <I>pair</I> keyword of the
<A HREF = "run_style.html">run_style respa</A> command. They do not support the
<I>inner</I>, <I>middle</I>, <I>outer</I> keywords.
</P>
<P><B>Restrictions:</B>
</P>
<P>These pair styles are part of the MANYBODY package. They are only
enabled if LAMMPS was built with that package (which it is by
default). See the <A HREF = "Section_start.html#start_3">Making LAMMPS</A> section
for more info.
</P>
<P>These pair potentials require the <A HREF = "newton.html">newton</A> setting to be
"on" for pair interactions.
</P>
<P>The CH.airebo potential file provided with LAMMPS (see the potentials
directory) is parameterized for metal <A HREF = "units.html">units</A>. You can use
the AIREBO or REBO potential with any LAMMPS units, but you would need
to create your own AIREBO potential file with coefficients listed in
the appropriate units if your simulation doesn't use "metal" units.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>
</P>
<P><B>Default:</B> none
</P>
<HR>
<A NAME = "Stuart"></A>
<P><B>(Stuart)</B> Stuart, Tutein, Harrison, J Chem Phys, 112, 6472-6486
(2000).
</P>
<A NAME = "Brenner"></A>
<P><B>(Brenner)</B> Brenner, Shenderova, Harrison, Stuart, Ni, Sinnott, J
Physics: Condensed Matter, 14, 783-802 (2002).
</P>
</HTML>
diff --git a/doc/pair_airebo.txt b/doc/pair_airebo.txt
index 0d76804a0..59313a27a 100644
--- a/doc/pair_airebo.txt
+++ b/doc/pair_airebo.txt
@@ -1,187 +1,189 @@
"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
pair_style airebo command :h3
pair_style airebo/omp command :h3
pair_style rebo command :h3
pair_style rebo/omp command :h3
[Syntax:]
pair_style style cutoff LJ_flag TORSION_flag :pre
style = {airebo} or {rebo}
cutoff = LJ cutoff (sigma scale factor) (AIREBO only)
LJ_flag = 0/1 to turn off/on the LJ term (AIREBO only, optional)
TORSION_flag = 0/1 to turn off/on the torsion term (AIREBO only, optional) :ul
[Examples:]
pair_style airebo 3.0
pair_style airebo 2.5 1 0
pair_coeff * * ../potentials/CH.airebo H C :pre
pair_style rebo
pair_coeff * * ../potentials/CH.airebo H C :pre
[Description:]
The {airebo} pair style computes the Adaptive Intermolecular Reactive
Empirical Bond Order (AIREBO) Potential of "(Stuart)"_#Stuart for a
system of carbon and/or hydrogen atoms. Note that this is the initial
formulation of AIREBO from 2000, not the later formulation. The
{rebo} pair style computes the Reactive Empirical Bond Order (REBO)
Potential of "(Brenner)"_#Brenner. Note that this is the so-called
2nd generation REBO from 2002, not the original REBO from 1990. As
discussed below, 2nd generation REBO is closely related to the intial
AIREBO; it is just a subset of the potential energy terms.
The AIREBO potential consists of three terms:
:c,image(Eqs/pair_airebo.jpg)
By default, all three terms are included. For the {airebo} style, if
the two optional flag arguments to the pair_style command are
included, the LJ and torsional terms can be turned off. Note that
both or neither of the flags must be included. If both of the LJ an
torsional terms are turned off, it becomes the 2nd-generation REBO
potential, with a small caveat on the spline fitting procedure
mentioned below. This can be specified directly as pair_style rebo
with no additional arguments.
The detailed formulas for this potential are given in
"(Stuart)"_#Stuart; here we provide only a brief description.
The E_REBO term has the same functional form as the hydrocarbon REBO
potential developed in "(Brenner)"_#Brenner. The coefficients for
E_REBO in AIREBO are essentially the same as Brenner's potential, but
a few fitted spline values are slightly different. For most cases the
E_REBO term in AIREBO will produce the same energies, forces and
statistical averages as the original REBO potential from which it was
derived. The E_REBO term in the AIREBO potential gives the model its
reactive capabilities and only describes short-ranged C-C, C-H and H-H
interactions (r < 2 Angstroms). These interactions have strong
coordination-dependence through a bond order parameter, which adjusts
the attraction between the I,J atoms based on the position of other
nearby atoms and thus has 3- and 4-body dependence.
The E_LJ term adds longer-ranged interactions (2 < r < cutoff) using a
form similar to the standard "Lennard Jones potential"_pair_lj.html.
The E_LJ term in AIREBO contains a series of switching functions so
that the short-ranged LJ repulsion (1/r^12) does not interfere with
the energetics captured by the E_REBO term. The extent of the E_LJ
interactions is determined by the {cutoff} argument to the pair_style
command which is a scale factor. For each type pair (C-C, C-H, H-H)
the cutoff is obtained by multiplying the scale factor by the sigma
value defined in the potential file for that type pair. In the
standard AIREBO potential, sigma_CC = 3.4 Angstroms, so with a scale
factor of 3.0 (the argument in pair_style), the resulting E_LJ cutoff
would be 10.2 Angstroms.
The E_TORSION term is an explicit 4-body potential that describes
various dihedral angle preferences in hydrocarbon configurations.
+:line
+
Only a single pair_coeff command is used with the {airebo} or {rebo}
style which specifies an AIREBO potential file with parameters for C
and H. Note that the {rebo} style in LAMMPS uses the same
AIREBO-formatted potential file. These are mapped to LAMMPS atom
types by specifying N additional arguments after the filename in the
pair_coeff command, where N is the number of LAMMPS atom types:
filename
N element names = mapping of AIREBO elements to atom types :ul
As an example, if your LAMMPS simulation has 4 atom types and you want
the 1st 3 to be C, and the 4th to be H, you would use the following
pair_coeff command:
pair_coeff * * CH.airebo C C C H :pre
The 1st 2 arguments must be * * so as to span all LAMMPS atom types.
The first three C arguments map LAMMPS atom types 1,2,3 to the C
element in the AIREBO file. The final H argument maps LAMMPS atom
type 4 to the H element in the SW file. If a mapping value is
specified as NULL, the mapping is not performed. This can be used
when a {airebo} potential is used as part of the {hybrid} pair style.
The NULL values are placeholders for atom types that will be used with
other potentials.
The parameters/coefficients for the AIREBO potentials are listed in
the CH.airebo file to agree with the original "(Stuart)"_#Stuart
paper. Thus the parameters are specific to this potential and the way
it was fit, so modifying the file should be done cautiously.
:line
Styles with a {cuda}, {gpu}, {omp}, or {opt} suffix are functionally
the same as the corresponding style without the suffix. They have
been optimized to run faster, depending on your available hardware, as
discussed in "Section_accelerate"_Section_accelerate.html of the
manual. The accelerated styles take the same arguments and should
produce the same results, except for round-off and precision issues.
These accelerated styles are part of the USER-CUDA, GPU, USER-OMP and OPT
packages, respectively. They are only enabled if LAMMPS was built with
those packages. See the "Making LAMMPS"_Section_start.html#start_3
section for more info.
You can specify the accelerated styles explicitly in your input script
by including their suffix, or you can use the "-suffix command-line
switch"_Section_start.html#start_7 when you invoke LAMMPS, or you can
use the "suffix"_suffix.html command in your input script.
See "Section_accelerate"_Section_accelerate.html of the manual for
more instructions on how to use the accelerated styles effectively.
:line
[Mixing, shift, table, tail correction, restart, rRESPA info]:
These pair styles do not support the "pair_modify"_pair_modify.html
mix, shift, table, and tail options.
These pair styles do not write their information to "binary restart
files"_restart.html, since it is stored in potential files. Thus, you
need to re-specify the pair_style and pair_coeff commands in an input
script that reads a restart file.
These pair styles can only be used via the {pair} keyword of the
"run_style respa"_run_style.html command. They do not support the
{inner}, {middle}, {outer} keywords.
[Restrictions:]
These pair styles are part of the MANYBODY package. They are only
enabled if LAMMPS was built with that package (which it is by
default). See the "Making LAMMPS"_Section_start.html#start_3 section
for more info.
These pair potentials require the "newton"_newton.html setting to be
"on" for pair interactions.
The CH.airebo potential file provided with LAMMPS (see the potentials
directory) is parameterized for metal "units"_units.html. You can use
the AIREBO or REBO potential with any LAMMPS units, but you would need
to create your own AIREBO potential file with coefficients listed in
the appropriate units if your simulation doesn't use "metal" units.
[Related commands:]
"pair_coeff"_pair_coeff.html
[Default:] none
:line
:link(Stuart)
[(Stuart)] Stuart, Tutein, Harrison, J Chem Phys, 112, 6472-6486
(2000).
:link(Brenner)
[(Brenner)] Brenner, Shenderova, Harrison, Stuart, Ni, Sinnott, J
Physics: Condensed Matter, 14, 783-802 (2002).
diff --git a/doc/pair_coeff.html b/doc/pair_coeff.html
index 1f47c40b3..942428e17 100644
--- a/doc/pair_coeff.html
+++ b/doc/pair_coeff.html
@@ -1,186 +1,187 @@
<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>pair_coeff command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_coeff I J args
</PRE>
<UL><LI>I,J = atom types (see asterisk form below)
<LI>args = coefficients for one or more pairs of atom types
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_coeff 1 2 1.0 1.0 2.5
pair_coeff 2 * 1.0 1.0
pair_coeff 3* 1*2 1.0 1.0 2.5
pair_coeff * * 1.0 1.0
pair_coeff * * nialhjea 1 1 2
pair_coeff * 3 morse.table ENTRY1
pair_coeff 1 2 lj/cut 1.0 1.0 2.5 (for pair_style hybrid)
</PRE>
<P><B>Description:</B>
</P>
<P>Specify the pairwise force field coefficients for one or more pairs of
atom types. The number and meaning of the coefficients depends on the
pair style. Pair coefficients can also be set in the data file read
by the <A HREF = "read_data.html">read_data</A> command or in a restart file.
</P>
<P>I and J can be specified in one of two ways. Explicit numeric values
can be used for each, as in the 1st example above. I <= J is
required. LAMMPS sets the coefficients for the symmetric J,I
interaction to the same values.
</P>
<P>A wildcard asterisk can be used in place of or in conjunction with the
I,J arguments to set the coefficients for multiple pairs of atom
types. This takes the form "*" or "*n" or "n*" or "m*n". If N = the
number of atom types, then an asterisk with no numeric values means all
types from 1 to N. A leading asterisk means all types from 1 to n
(inclusive). A trailing asterisk means all types from n to N
(inclusive). A middle asterisk means all types from m to n
(inclusive). Note that only type pairs with I <= J are considered; if
asterisks imply type pairs where J < I, they are ignored.
</P>
<P>Note that a pair_coeff command can override a previous setting for the
same I,J pair. For example, these commands set the coeffs for all I,J
pairs, then overwrite the coeffs for just the I,J = 2,3 pair:
</P>
<PRE>pair_coeff * * 1.0 1.0 2.5
pair_coeff 2 3 2.0 1.0 1.12
</PRE>
<P>A line in a data file that specifies pair coefficients uses the exact
same format as the arguments of the pair_coeff command in an input
script, with the exception of the I,J type arguments. In each line of
the "Pair Coeffs" section of a data file, only a single type I is
specified, which sets the coefficients for type I interacting with
type I. This is because the section has exactly N lines, where N =
the number of atom types. For this reason, the wild-card asterisk
should also not be used as part of the I argument. Thus in a data
file, the line corresponding to the 1st example above would be listed
as
</P>
<PRE>2 1.0 1.0 2.5
</PRE>
<P>For many potentials, if coefficients for type pairs with I != J are
not set explicitly by a pair_coeff command, the values are inferred
from the I,I and J,J settings by mixing rules; see the
<A HREF = "pair_modify.html">pair_modify</A> command for a discussion. Details on
this option as it pertains to individual potentials are described on
the doc page for the potential.
</P>
<HR>
<P>Here is an alphabetic list of pair styles defined in LAMMPS. Click on
the style to display the formula it computes, arguments specified in
the pair_style command, and coefficients specified by the associated
<A HREF = "pair_coeff.html">pair_coeff</A> command.
</P>
<P>Note that there are also additional pair styles submitted by users
which are included in the LAMMPS distribution. The list of these with
links to the individual styles are given in the pair section of <A HREF = "Section_commands.html#cmd_5">this
page</A>.
</P>
<P>There are also additional accelerated pair styles included in the
LAMMPS distribution for faster performance on CPUs and GPUs. The list
of these with links to the individual styles are given in the pair
section of <A HREF = "Section_commands.html#cmd_5">this page</A>.
</P>
<UL><LI><A HREF = "pair_hybrid.html">pair_style hybrid</A> - multiple styles of pairwise interactions
<LI><A HREF = "pair_hybrid.html">pair_style hybrid/overlay</A> - multiple styles of superposed pairwise interactions
</UL>
<UL><LI><A HREF = "pair_adp.html">pair_style adp</A> - angular dependent potential (ADP) of Mishin
<LI><A HREF = "pair_airebo.html">pair_style airebo</A> - AIREBO potential of Stuart
+<LI><A HREF = "pair_bop.html">pair_style bop</A> - BOP potential of Pettifor
<LI><A HREF = "pair_born.html">pair_style born</A> - Born-Mayer-Huggins potential
<LI><A HREF = "pair_born.html">pair_style born/coul/long</A> - Born-Mayer-Huggins with long-range Coulombics
<LI><A HREF = "pair_born.html">pair_style born/coul/wolf</A> - Born-Mayer-Huggins with Coulombics via Wolf potential
<LI><A HREF = "pair_brownian.html">pair_style brownian</A> - Brownian potential for Fast Lubrication Dynamics
<LI><A HREF = "pair_brownian.html">pair_style brownian/poly</A> - Brownian potential for Fast Lubrication Dynamics with polydispersity
<LI><A HREF = "pair_buck.html">pair_style buck</A> - Buckingham potential
<LI><A HREF = "pair_buck.html">pair_style buck/coul/cut</A> - Buckingham with cutoff Coulomb
<LI><A HREF = "pair_buck.html">pair_style buck/coul/long</A> - Buckingham with long-range Coulomb
<LI><A HREF = "pair_colloid.html">pair_style colloid</A> - integrated colloidal potential
<LI><A HREF = "pair_comb.html">pair_style comb</A> - charge-optimized many-body (COMB) potential
<LI><A HREF = "pair_coul.html">pair_style coul/cut</A> - cutoff Coulombic potential
<LI><A HREF = "pair_coul.html">pair_style coul/debye</A> - cutoff Coulombic potential with Debye screening
<LI><A HREF = "pair_coul.html">pair_style coul/long</A> - long-range Coulombic potential
<LI><A HREF = "pair_coul.html">pair_style coul/wolf</A> - Coulombics via Wolf potential
<LI><A HREF = "pair_dipole.html">pair_style dipole/cut</A> - point dipoles with cutoff
<LI><A HREF = "pair_dpd.html">pair_style dpd</A> - dissipative particle dynamics (DPD)
<LI><A HREF = "pair_dpd.html">pair_style dpd/tstat</A> - DPD thermostatting
<LI><A HREF = "pair_dsmc.html">pair_style dsmc</A> - Direct Simulation Monte Carlo (DSMC)
<LI><A HREF = "pair_eam.html">pair_style eam</A> - embedded atom method (EAM)
<LI><A HREF = "pair_eam.html">pair_style eam/alloy</A> - alloy EAM
<LI><A HREF = "pair_eam.html">pair_style eam/fs</A> - Finnis-Sinclair EAM
<LI><A HREF = "pair_eim.html">pair_style eim</A> - embedded ion method (EIM)
<LI><A HREF = "pair_gauss.html">pair_style gauss</A> - Gaussian potential
<LI><A HREF = "pair_gayberne.html">pair_style gayberne</A> - Gay-Berne ellipsoidal potential
<LI><A HREF = "pair_gran.html">pair_style gran/hertz/history</A> - granular potential with Hertzian interactions
<LI><A HREF = "pair_gran.html">pair_style gran/hooke</A> - granular potential with history effects
<LI><A HREF = "pair_gran.html">pair_style gran/hooke/history</A> - granular potential without history effects
<LI><A HREF = "pair_hbond_dreiding.html">pair_style hbond/dreiding/lj</A> - DREIDING hydrogen bonding LJ potential
<LI><A HREF = "pair_hbond_dreiding.html">pair_style hbond/dreiding/morse</A> - DREIDING hydrogen bonding Morse potential
<LI><A HREF = "pair_lcbop.html">pair_style lcbop</A> - long-range bond-order potential (LCBOP)
<LI><A HREF = "pair_line_lj.html">pair_style line/lj</A> - LJ potential between line segments
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/charmm</A> - CHARMM potential with cutoff Coulomb
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/charmm/implicit</A> - CHARMM for implicit solvent
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/long</A> - CHARMM with long-range Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2</A> - COMPASS (class 2) force field with no Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2/coul/cut</A> - COMPASS with cutoff Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2/coul/long</A> - COMPASS with long-range Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut</A> - cutoff Lennard-Jones potential with no Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/cut</A> - LJ with cutoff Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/debye</A> - LJ with Debye screening added to Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/long</A> - LJ with long-range Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/long/tip4p</A> - LJ with long-range Coulomb for TIP4P water
<LI><A HREF = "pair_lj_expand.html">pair_style lj/expand</A> - Lennard-Jones for variable size particles
<LI><A HREF = "pair_gromacs.html">pair_style lj/gromacs</A> - GROMACS-style Lennard-Jones potential
<LI><A HREF = "pair_gromacs.html">pair_style lj/gromacs/coul/gromacs</A> - GROMACS-style LJ and Coulombic potential
<LI><A HREF = "pair_lj_smooth.html">pair_style lj/smooth</A> - smoothed Lennard-Jones potential
<LI><A HREF = "pair_lj_smooth_linear.html">pair_style lj/smooth/linear</A> - linear smoothed Lennard-Jones potential
<LI><A HREF = "pair_lj96.html">pair_style lj96/cut</A> - Lennard-Jones 9/6 potential
<LI><A HREF = "pair_lubricate.html">pair_style lubricate</A> - hydrodynamic lubrication forces
<LI><A HREF = "pair_lubricate.html">pair_style lubricate/poly</A> - hydrodynamic lubrication forces with polydispersity
<LI><A HREF = "pair_lubricateU.html">pair_style lubricateU</A> - hydrodynamic lubrication forces for Fast Lubrication Dynamics
<LI><A HREF = "pair_lubricateU.html">pair_style lubricateU/poly</A> - hydrodynamic lubrication forces for Fast Lubrication Dynamics with polydispersity
<LI><A HREF = "pair_meam.html">pair_style meam</A> - modified embedded atom method (MEAM)
<LI><A HREF = "pair_morse.html">pair_style morse</A> - Morse potential
<LI><A HREF = "pair_peri.html">pair_style peri/lps</A> - peridynamic LPS potential
<LI><A HREF = "pair_peri.html">pair_style peri/pmb</A> - peridynamic PMB potential
<LI><A HREF = "pair_reax.html">pair_style reax</A> - ReaxFF potential
<LI><A HREF = "pair_airebo.html">pair_style rebo</A> - 2nd-generation REBO potential of Brenner
<LI><A HREF = "pair_resquared.html">pair_style resquared</A> - Everaers RE-Squared ellipsoidal potential
<LI><A HREF = "pair_soft.html">pair_style soft</A> - Soft (cosine) potential
<LI><A HREF = "pair_sw.html">pair_style sw</A> - Stillinger-Weber 3-body potential
<LI><A HREF = "pair_table.html">pair_style table</A> - tabulated pair potential
<LI><A HREF = "pair_tersoff.html">pair_style tersoff</A> - Tersoff 3-body potential
<LI><A HREF = "pair_tersoff_zbl.html">pair_style tersoff/zbl</A> - Tersoff/ZBL 3-body potential
<LI><A HREF = "pair_tri_lj.html">pair_style tri/lj</A> - LJ potential between triangles
<LI><A HREF = "pair_yukawa.html">pair_style yukawa</A> - Yukawa potential
<LI><A HREF = "pair_yukawa_colloid.html">pair_style yukawa/colloid</A> - screened Yukawa potential for finite-size particles
</UL>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This command must come after the simulation box is defined by a
<A HREF = "read_data.html">read_data</A>, <A HREF = "read_restart.html">read_restart</A>, or
<A HREF = "create_box.html">create_box</A> command.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_style.html">pair_style</A>, <A HREF = "pair_modify.html">pair_modify</A>,
<A HREF = "read_data.html">read_data</A>, <A HREF = "read_restart.html">read_restart</A>,
<A HREF = "pair_write.html">pair_write</A>
</P>
<P><B>Default:</B> none
</P>
</HTML>
diff --git a/doc/pair_coeff.txt b/doc/pair_coeff.txt
index e67abefef..73a0b234a 100644
--- a/doc/pair_coeff.txt
+++ b/doc/pair_coeff.txt
@@ -1,181 +1,182 @@
"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
pair_coeff command :h3
[Syntax:]
pair_coeff I J args :pre
I,J = atom types (see asterisk form below)
args = coefficients for one or more pairs of atom types :ul
[Examples:]
pair_coeff 1 2 1.0 1.0 2.5
pair_coeff 2 * 1.0 1.0
pair_coeff 3* 1*2 1.0 1.0 2.5
pair_coeff * * 1.0 1.0
pair_coeff * * nialhjea 1 1 2
pair_coeff * 3 morse.table ENTRY1
pair_coeff 1 2 lj/cut 1.0 1.0 2.5 (for pair_style hybrid) :pre
[Description:]
Specify the pairwise force field coefficients for one or more pairs of
atom types. The number and meaning of the coefficients depends on the
pair style. Pair coefficients can also be set in the data file read
by the "read_data"_read_data.html command or in a restart file.
I and J can be specified in one of two ways. Explicit numeric values
can be used for each, as in the 1st example above. I <= J is
required. LAMMPS sets the coefficients for the symmetric J,I
interaction to the same values.
A wildcard asterisk can be used in place of or in conjunction with the
I,J arguments to set the coefficients for multiple pairs of atom
types. This takes the form "*" or "*n" or "n*" or "m*n". If N = the
number of atom types, then an asterisk with no numeric values means all
types from 1 to N. A leading asterisk means all types from 1 to n
(inclusive). A trailing asterisk means all types from n to N
(inclusive). A middle asterisk means all types from m to n
(inclusive). Note that only type pairs with I <= J are considered; if
asterisks imply type pairs where J < I, they are ignored.
Note that a pair_coeff command can override a previous setting for the
same I,J pair. For example, these commands set the coeffs for all I,J
pairs, then overwrite the coeffs for just the I,J = 2,3 pair:
pair_coeff * * 1.0 1.0 2.5
pair_coeff 2 3 2.0 1.0 1.12 :pre
A line in a data file that specifies pair coefficients uses the exact
same format as the arguments of the pair_coeff command in an input
script, with the exception of the I,J type arguments. In each line of
the "Pair Coeffs" section of a data file, only a single type I is
specified, which sets the coefficients for type I interacting with
type I. This is because the section has exactly N lines, where N =
the number of atom types. For this reason, the wild-card asterisk
should also not be used as part of the I argument. Thus in a data
file, the line corresponding to the 1st example above would be listed
as
2 1.0 1.0 2.5 :pre
For many potentials, if coefficients for type pairs with I != J are
not set explicitly by a pair_coeff command, the values are inferred
from the I,I and J,J settings by mixing rules; see the
"pair_modify"_pair_modify.html command for a discussion. Details on
this option as it pertains to individual potentials are described on
the doc page for the potential.
:line
Here is an alphabetic list of pair styles defined in LAMMPS. Click on
the style to display the formula it computes, arguments specified in
the pair_style command, and coefficients specified by the associated
"pair_coeff"_pair_coeff.html command.
Note that there are also additional pair styles submitted by users
which are included in the LAMMPS distribution. The list of these with
links to the individual styles are given in the pair section of "this
page"_Section_commands.html#cmd_5.
There are also additional accelerated pair styles included in the
LAMMPS distribution for faster performance on CPUs and GPUs. The list
of these with links to the individual styles are given in the pair
section of "this page"_Section_commands.html#cmd_5.
"pair_style hybrid"_pair_hybrid.html - multiple styles of pairwise interactions
"pair_style hybrid/overlay"_pair_hybrid.html - multiple styles of superposed pairwise interactions :ul
"pair_style adp"_pair_adp.html - angular dependent potential (ADP) of Mishin
"pair_style airebo"_pair_airebo.html - AIREBO potential of Stuart
+"pair_style bop"_pair_bop.html - BOP potential of Pettifor
"pair_style born"_pair_born.html - Born-Mayer-Huggins potential
"pair_style born/coul/long"_pair_born.html - Born-Mayer-Huggins with long-range Coulombics
"pair_style born/coul/wolf"_pair_born.html - Born-Mayer-Huggins with Coulombics via Wolf potential
"pair_style brownian"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics
"pair_style brownian/poly"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics with polydispersity
"pair_style buck"_pair_buck.html - Buckingham potential
"pair_style buck/coul/cut"_pair_buck.html - Buckingham with cutoff Coulomb
"pair_style buck/coul/long"_pair_buck.html - Buckingham with long-range Coulomb
"pair_style colloid"_pair_colloid.html - integrated colloidal potential
"pair_style comb"_pair_comb.html - charge-optimized many-body (COMB) potential
"pair_style coul/cut"_pair_coul.html - cutoff Coulombic potential
"pair_style coul/debye"_pair_coul.html - cutoff Coulombic potential with Debye screening
"pair_style coul/long"_pair_coul.html - long-range Coulombic potential
"pair_style coul/wolf"_pair_coul.html - Coulombics via Wolf potential
"pair_style dipole/cut"_pair_dipole.html - point dipoles with cutoff
"pair_style dpd"_pair_dpd.html - dissipative particle dynamics (DPD)
"pair_style dpd/tstat"_pair_dpd.html - DPD thermostatting
"pair_style dsmc"_pair_dsmc.html - Direct Simulation Monte Carlo (DSMC)
"pair_style eam"_pair_eam.html - embedded atom method (EAM)
"pair_style eam/alloy"_pair_eam.html - alloy EAM
"pair_style eam/fs"_pair_eam.html - Finnis-Sinclair EAM
"pair_style eim"_pair_eim.html - embedded ion method (EIM)
"pair_style gauss"_pair_gauss.html - Gaussian potential
"pair_style gayberne"_pair_gayberne.html - Gay-Berne ellipsoidal potential
"pair_style gran/hertz/history"_pair_gran.html - granular potential with Hertzian interactions
"pair_style gran/hooke"_pair_gran.html - granular potential with history effects
"pair_style gran/hooke/history"_pair_gran.html - granular potential without history effects
"pair_style hbond/dreiding/lj"_pair_hbond_dreiding.html - DREIDING hydrogen bonding LJ potential
"pair_style hbond/dreiding/morse"_pair_hbond_dreiding.html - DREIDING hydrogen bonding Morse potential
"pair_style lcbop"_pair_lcbop.html - long-range bond-order potential (LCBOP)
"pair_style line/lj"_pair_line_lj.html - LJ potential between line segments
"pair_style lj/charmm/coul/charmm"_pair_charmm.html - CHARMM potential with cutoff Coulomb
"pair_style lj/charmm/coul/charmm/implicit"_pair_charmm.html - CHARMM for implicit solvent
"pair_style lj/charmm/coul/long"_pair_charmm.html - CHARMM with long-range Coulomb
"pair_style lj/class2"_pair_class2.html - COMPASS (class 2) force field with no Coulomb
"pair_style lj/class2/coul/cut"_pair_class2.html - COMPASS with cutoff Coulomb
"pair_style lj/class2/coul/long"_pair_class2.html - COMPASS with long-range Coulomb
"pair_style lj/cut"_pair_lj.html - cutoff Lennard-Jones potential with no Coulomb
"pair_style lj/cut/coul/cut"_pair_lj.html - LJ with cutoff Coulomb
"pair_style lj/cut/coul/debye"_pair_lj.html - LJ with Debye screening added to Coulomb
"pair_style lj/cut/coul/long"_pair_lj.html - LJ with long-range Coulomb
"pair_style lj/cut/coul/long/tip4p"_pair_lj.html - LJ with long-range Coulomb for TIP4P water
"pair_style lj/expand"_pair_lj_expand.html - Lennard-Jones for variable size particles
"pair_style lj/gromacs"_pair_gromacs.html - GROMACS-style Lennard-Jones potential
"pair_style lj/gromacs/coul/gromacs"_pair_gromacs.html - GROMACS-style LJ and Coulombic potential
"pair_style lj/smooth"_pair_lj_smooth.html - smoothed Lennard-Jones potential
"pair_style lj/smooth/linear"_pair_lj_smooth_linear.html - linear smoothed Lennard-Jones potential
"pair_style lj96/cut"_pair_lj96.html - Lennard-Jones 9/6 potential
"pair_style lubricate"_pair_lubricate.html - hydrodynamic lubrication forces
"pair_style lubricate/poly"_pair_lubricate.html - hydrodynamic lubrication forces with polydispersity
"pair_style lubricateU"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication Dynamics
"pair_style lubricateU/poly"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication Dynamics with polydispersity
"pair_style meam"_pair_meam.html - modified embedded atom method (MEAM)
"pair_style morse"_pair_morse.html - Morse potential
"pair_style peri/lps"_pair_peri.html - peridynamic LPS potential
"pair_style peri/pmb"_pair_peri.html - peridynamic PMB potential
"pair_style reax"_pair_reax.html - ReaxFF potential
"pair_style rebo"_pair_airebo.html - 2nd-generation REBO potential of Brenner
"pair_style resquared"_pair_resquared.html - Everaers RE-Squared ellipsoidal potential
"pair_style soft"_pair_soft.html - Soft (cosine) potential
"pair_style sw"_pair_sw.html - Stillinger-Weber 3-body potential
"pair_style table"_pair_table.html - tabulated pair potential
"pair_style tersoff"_pair_tersoff.html - Tersoff 3-body potential
"pair_style tersoff/zbl"_pair_tersoff_zbl.html - Tersoff/ZBL 3-body potential
"pair_style tri/lj"_pair_tri_lj.html - LJ potential between triangles
"pair_style yukawa"_pair_yukawa.html - Yukawa potential
"pair_style yukawa/colloid"_pair_yukawa_colloid.html - screened Yukawa potential for finite-size particles :ul
:line
[Restrictions:]
This command must come after the simulation box is defined by a
"read_data"_read_data.html, "read_restart"_read_restart.html, or
"create_box"_create_box.html command.
[Related commands:]
"pair_style"_pair_style.html, "pair_modify"_pair_modify.html,
"read_data"_read_data.html, "read_restart"_read_restart.html,
"pair_write"_pair_write.html
[Default:] none
diff --git a/doc/pair_style.html b/doc/pair_style.html
index 6f3f4c965..699bf7235 100644
--- a/doc/pair_style.html
+++ b/doc/pair_style.html
@@ -1,196 +1,197 @@
<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>pair_style command
</H3>
<P><B>Syntax:</B>
</P>
<PRE>pair_style style args
</PRE>
<UL><LI>style = one of the styles from the list below
<LI>args = arguments used by a particular style
</UL>
<P><B>Examples:</B>
</P>
<PRE>pair_style lj/cut 2.5
pair_style eam/alloy
pair_style hybrid lj/charmm/coul/long 10.0 eam
pair_style table linear 1000
pair_style none
</PRE>
<P><B>Description:</B>
</P>
<P>Set the formula(s) LAMMPS uses to compute pairwise interactions. In
LAMMPS, pair potentials are defined between pairs of atoms that are
within a cutoff distance and the set of active interactions typically
changes over time. See the <A HREF = "bond_style.html">bond_style</A> command to
define potentials between pairs of bonded atoms, which typically
remain in place for the duration of a simulation.
</P>
<P>In LAMMPS, pairwise force fields encompass a variety of interactions,
some of which include many-body effects, e.g. EAM, Stillinger-Weber,
Tersoff, REBO potentials. They are still classified as "pairwise"
potentials because the set of interacting atoms changes with time
(unlike molecular bonds) and thus a neighbor list is used to find
nearby interacting atoms.
</P>
<P>Hybrid models where specified pairs of atom types interact via
different pair potentials can be setup using the <I>hybrid</I> pair style.
</P>
<P>The coefficients associated with a pair style are typically set for
each pair of atom types, and are specified by the
<A HREF = "pair_coeff.html">pair_coeff</A> command or read from a file by the
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
commands.
</P>
<P>The <A HREF = "pair_modify.html">pair_modify</A> command sets options for mixing of
type I-J interaction coefficients and adding energy offsets or tail
corrections to Lennard-Jones potentials. Details on these options as
they pertain to individual potentials are described on the doc page
for the potential. Likewise, info on whether the potential
information is stored in a <A HREF = "write_restart.html">restart file</A> is listed
on the potential doc page.
</P>
<P>In the formulas listed for each pair style, <I>E</I> is the energy of a
pairwise interaction between two atoms separated by a distance <I>r</I>.
The force between the atoms is the negative derivative of this
expression.
</P>
<P>If the pair_style command has a cutoff argument, it sets global
cutoffs for all pairs of atom types. The distance(s) can be smaller
or larger than the dimensions of the simulation box.
</P>
<P>Typically, the global cutoff value can be overridden for a specific
pair of atom types by the <A HREF = "pair_coeff.html">pair_coeff</A> command. The
pair style settings (including global cutoffs) can be changed by a
subsequent pair_style command using the same style. This will reset
the cutoffs for all atom type pairs, including those previously set
explicitly by a <A HREF = "pair_coeff.html">pair_coeff</A> command. The exceptions
to this are that pair_style <I>table</I> and <I>hybrid</I> settings cannot be
reset. A new pair_style command for these styles will wipe out all
previously specified pair_coeff values.
</P>
<HR>
<P>Here is an alphabetic list of pair styles defined in LAMMPS. Click on
the style to display the formula it computes, arguments specified in
the pair_style command, and coefficients specified by the associated
<A HREF = "pair_coeff.html">pair_coeff</A> command.
</P>
<P>Note that there are also additional pair styles submitted by users
which are included in the LAMMPS distribution. The list of these with
links to the individual styles are given in the pair section of <A HREF = "Section_commands.html#cmd_5">this
page</A>.
</P>
<P>There are also additional accelerated pair styles included in the
LAMMPS distribution for faster performance on CPUs and GPUs. The list
of these with links to the individual styles are given in the pair
section of <A HREF = "Section_commands.html#cmd_5">this page</A>.
</P>
<UL><LI><A HREF = "pair_none.html">pair_style none</A> - turn off pairwise interactions
<LI><A HREF = "pair_hybrid.html">pair_style hybrid</A> - multiple styles of pairwise interactions
<LI><A HREF = "pair_hybrid.html">pair_style hybrid/overlay</A> - multiple styles of superposed pairwise interactions
</UL>
<UL><LI><A HREF = "pair_adp.html">pair_style adp</A> - angular dependent potential (ADP) of Mishin
<LI><A HREF = "pair_airebo.html">pair_style airebo</A> - AIREBO potential of Stuart
+<LI><A HREF = "pair_bop.html">pair_style bop</A> - BOP potential of Pettifor
<LI><A HREF = "pair_born.html">pair_style born</A> - Born-Mayer-Huggins potential
<LI><A HREF = "pair_born.html">pair_style born/coul/long</A> - Born-Mayer-Huggins with long-range Coulombics
<LI><A HREF = "pair_born.html">pair_style born/coul/wolf</A> - Born-Mayer-Huggins with Coulombics via Wolf potential
<LI><A HREF = "pair_brownian.html">pair_style brownian</A> - Brownian potential for Fast Lubrication Dynamics
<LI><A HREF = "pair_brownian.html">pair_style brownian/poly</A> - Brownian potential for Fast Lubrication Dynamics with polydispersity
<LI><A HREF = "pair_buck.html">pair_style buck</A> - Buckingham potential
<LI><A HREF = "pair_buck.html">pair_style buck/coul/cut</A> - Buckingham with cutoff Coulomb
<LI><A HREF = "pair_buck.html">pair_style buck/coul/long</A> - Buckingham with long-range Coulomb
<LI><A HREF = "pair_colloid.html">pair_style colloid</A> - integrated colloidal potential
<LI><A HREF = "pair_comb.html">pair_style comb</A> - charge-optimized many-body (COMB) potential
<LI><A HREF = "pair_coul.html">pair_style coul/cut</A> - cutoff Coulombic potential
<LI><A HREF = "pair_coul.html">pair_style coul/debye</A> - cutoff Coulombic potential with Debye screening
<LI><A HREF = "pair_coul.html">pair_style coul/long</A> - long-range Coulombic potential
<LI><A HREF = "pair_coul.html">pair_style coul/wolf</A> - Coulombics via Wolf potential
<LI><A HREF = "pair_dipole.html">pair_style dipole/cut</A> - point dipoles with cutoff
<LI><A HREF = "pair_dpd.html">pair_style dpd</A> - dissipative particle dynamics (DPD)
<LI><A HREF = "pair_dpd.html">pair_style dpd/tstat</A> - DPD thermostatting
<LI><A HREF = "pair_dsmc.html">pair_style dsmc</A> - Direct Simulation Monte Carlo (DSMC)
<LI><A HREF = "pair_eam.html">pair_style eam</A> - embedded atom method (EAM)
<LI><A HREF = "pair_eam.html">pair_style eam/alloy</A> - alloy EAM
<LI><A HREF = "pair_eam.html">pair_style eam/fs</A> - Finnis-Sinclair EAM
<LI><A HREF = "pair_eim.html">pair_style eim</A> - embedded ion method (EIM)
<LI><A HREF = "pair_gauss.html">pair_style gauss</A> - Gaussian potential
<LI><A HREF = "pair_gayberne.html">pair_style gayberne</A> - Gay-Berne ellipsoidal potential
<LI><A HREF = "pair_gran.html">pair_style gran/hertz/history</A> - granular potential with Hertzian interactions
<LI><A HREF = "pair_gran.html">pair_style gran/hooke</A> - granular potential with history effects
<LI><A HREF = "pair_gran.html">pair_style gran/hooke/history</A> - granular potential without history effects
<LI><A HREF = "pair_hbond_dreiding.html">pair_style hbond/dreiding/lj</A> - DREIDING hydrogen bonding LJ potential
<LI><A HREF = "pair_hbond_dreiding.html">pair_style hbond/dreiding/morse</A> - DREIDING hydrogen bonding Morse potential
<LI><A HREF = "pair_lcbop.html">pair_style lcbop</A> - long-range bond-order potential (LCBOP)
<LI><A HREF = "pair_line_lj.html">pair_style line/lj</A> - LJ potential between line segments
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/charmm</A> - CHARMM potential with cutoff Coulomb
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/charmm/implicit</A> - CHARMM for implicit solvent
<LI><A HREF = "pair_charmm.html">pair_style lj/charmm/coul/long</A> - CHARMM with long-range Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2</A> - COMPASS (class 2) force field with no Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2/coul/cut</A> - COMPASS with cutoff Coulomb
<LI><A HREF = "pair_class2.html">pair_style lj/class2/coul/long</A> - COMPASS with long-range Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut</A> - cutoff Lennard-Jones potential with no Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/cut</A> - LJ with cutoff Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/debye</A> - LJ with Debye screening added to Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/long</A> - LJ with long-range Coulomb
<LI><A HREF = "pair_lj.html">pair_style lj/cut/coul/long/tip4p</A> - LJ with long-range Coulomb for TIP4P water
<LI><A HREF = "pair_lj_expand.html">pair_style lj/expand</A> - Lennard-Jones for variable size particles
<LI><A HREF = "pair_gromacs.html">pair_style lj/gromacs</A> - GROMACS-style Lennard-Jones potential
<LI><A HREF = "pair_gromacs.html">pair_style lj/gromacs/coul/gromacs</A> - GROMACS-style LJ and Coulombic potential
<LI><A HREF = "pair_lj_smooth.html">pair_style lj/smooth</A> - smoothed Lennard-Jones potential
<LI><A HREF = "pair_lj_smooth_linear.html">pair_style lj/smooth/linear</A> - linear smoothed Lennard-Jones potential
<LI><A HREF = "pair_lj96.html">pair_style lj96/cut</A> - Lennard-Jones 9/6 potential
<LI><A HREF = "pair_lubricate.html">pair_style lubricate</A> - hydrodynamic lubrication forces
<LI><A HREF = "pair_lubricate.html">pair_style lubricate/poly</A> - hydrodynamic lubrication forces with polydispersity
<LI><A HREF = "pair_lubricateU.html">pair_style lubricateU</A> - hydrodynamic lubrication forces for Fast Lubrication Dynamics
<LI><A HREF = "pair_lubricateU.html">pair_style lubricateU/poly</A> - hydrodynamic lubrication forces for Fast Lubrication with polydispersity
<LI><A HREF = "pair_meam.html">pair_style meam</A> - modified embedded atom method (MEAM)
<LI><A HREF = "pair_morse.html">pair_style morse</A> - Morse potential
<LI><A HREF = "pair_peri.html">pair_style peri/lps</A> - peridynamic LPS potential
<LI><A HREF = "pair_peri.html">pair_style peri/pmb</A> - peridynamic PMB potential
<LI><A HREF = "pair_reax.html">pair_style reax</A> - ReaxFF potential
<LI><A HREF = "pair_airebo.html">pair_style rebo</A> - 2nd generation REBO potential of Brenner
<LI><A HREF = "pair_resquared.html">pair_style resquared</A> - Everaers RE-Squared ellipsoidal potential
<LI><A HREF = "pair_soft.html">pair_style soft</A> - Soft (cosine) potential
<LI><A HREF = "pair_sw.html">pair_style sw</A> - Stillinger-Weber 3-body potential
<LI><A HREF = "pair_table.html">pair_style table</A> - tabulated pair potential
<LI><A HREF = "pair_tersoff.html">pair_style tersoff</A> - Tersoff 3-body potential
<LI><A HREF = "pair_tersoff_zbl.html">pair_style tersoff/zbl</A> - Tersoff/ZBL 3-body potential
<LI><A HREF = "pair_tri_lj.html">pair_style tri/lj</A> - LJ potential between triangles
<LI><A HREF = "pair_yukawa.html">pair_style yukawa</A> - Yukawa potential
<LI><A HREF = "pair_yukawa_colloid.html">pair_style yukawa/colloid</A> - screened Yukawa potential for finite-size particles
</UL>
<HR>
<P><B>Restrictions:</B>
</P>
<P>This command must be used before any coefficients are set by the
<A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "read_data.html">read_data</A>, or
<A HREF = "read_restart.html">read_restart</A> commands.
</P>
<P>Some pair styles are part of specific packages. They are only enabled
if LAMMPS was built with that package. See the <A HREF = "Section_start.html#start_3">Making
LAMMPS</A> section for more info on packages.
The doc pages for individual pair potentials tell if it is part of a
package.
</P>
<P><B>Related commands:</B>
</P>
<P><A HREF = "pair_coeff.html">pair_coeff</A>, <A HREF = "read_data.html">read_data</A>,
<A HREF = "pair_modify.html">pair_modify</A>, <A HREF = "kspace_style.html">kspace_style</A>,
<A HREF = "dielectric.html">dielectric</A>, <A HREF = "pair_write.html">pair_write</A>
</P>
<P><B>Default:</B>
</P>
<PRE>pair_style none
</PRE>
</HTML>
diff --git a/doc/pair_style.txt b/doc/pair_style.txt
index bf353ef1d..ee0d38300 100644
--- a/doc/pair_style.txt
+++ b/doc/pair_style.txt
@@ -1,191 +1,192 @@
"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
pair_style command :h3
[Syntax:]
pair_style style args :pre
style = one of the styles from the list below
args = arguments used by a particular style :ul
[Examples:]
pair_style lj/cut 2.5
pair_style eam/alloy
pair_style hybrid lj/charmm/coul/long 10.0 eam
pair_style table linear 1000
pair_style none :pre
[Description:]
Set the formula(s) LAMMPS uses to compute pairwise interactions. In
LAMMPS, pair potentials are defined between pairs of atoms that are
within a cutoff distance and the set of active interactions typically
changes over time. See the "bond_style"_bond_style.html command to
define potentials between pairs of bonded atoms, which typically
remain in place for the duration of a simulation.
In LAMMPS, pairwise force fields encompass a variety of interactions,
some of which include many-body effects, e.g. EAM, Stillinger-Weber,
Tersoff, REBO potentials. They are still classified as "pairwise"
potentials because the set of interacting atoms changes with time
(unlike molecular bonds) and thus a neighbor list is used to find
nearby interacting atoms.
Hybrid models where specified pairs of atom types interact via
different pair potentials can be setup using the {hybrid} pair style.
The coefficients associated with a pair style are typically set for
each pair of atom types, and are specified by the
"pair_coeff"_pair_coeff.html command or read from a file by the
"read_data"_read_data.html or "read_restart"_read_restart.html
commands.
The "pair_modify"_pair_modify.html command sets options for mixing of
type I-J interaction coefficients and adding energy offsets or tail
corrections to Lennard-Jones potentials. Details on these options as
they pertain to individual potentials are described on the doc page
for the potential. Likewise, info on whether the potential
information is stored in a "restart file"_write_restart.html is listed
on the potential doc page.
In the formulas listed for each pair style, {E} is the energy of a
pairwise interaction between two atoms separated by a distance {r}.
The force between the atoms is the negative derivative of this
expression.
If the pair_style command has a cutoff argument, it sets global
cutoffs for all pairs of atom types. The distance(s) can be smaller
or larger than the dimensions of the simulation box.
Typically, the global cutoff value can be overridden for a specific
pair of atom types by the "pair_coeff"_pair_coeff.html command. The
pair style settings (including global cutoffs) can be changed by a
subsequent pair_style command using the same style. This will reset
the cutoffs for all atom type pairs, including those previously set
explicitly by a "pair_coeff"_pair_coeff.html command. The exceptions
to this are that pair_style {table} and {hybrid} settings cannot be
reset. A new pair_style command for these styles will wipe out all
previously specified pair_coeff values.
:line
Here is an alphabetic list of pair styles defined in LAMMPS. Click on
the style to display the formula it computes, arguments specified in
the pair_style command, and coefficients specified by the associated
"pair_coeff"_pair_coeff.html command.
Note that there are also additional pair styles submitted by users
which are included in the LAMMPS distribution. The list of these with
links to the individual styles are given in the pair section of "this
page"_Section_commands.html#cmd_5.
There are also additional accelerated pair styles included in the
LAMMPS distribution for faster performance on CPUs and GPUs. The list
of these with links to the individual styles are given in the pair
section of "this page"_Section_commands.html#cmd_5.
"pair_style none"_pair_none.html - turn off pairwise interactions
"pair_style hybrid"_pair_hybrid.html - multiple styles of pairwise interactions
"pair_style hybrid/overlay"_pair_hybrid.html - multiple styles of superposed pairwise interactions :ul
"pair_style adp"_pair_adp.html - angular dependent potential (ADP) of Mishin
"pair_style airebo"_pair_airebo.html - AIREBO potential of Stuart
+"pair_style bop"_pair_bop.html - BOP potential of Pettifor
"pair_style born"_pair_born.html - Born-Mayer-Huggins potential
"pair_style born/coul/long"_pair_born.html - Born-Mayer-Huggins with long-range Coulombics
"pair_style born/coul/wolf"_pair_born.html - Born-Mayer-Huggins with Coulombics via Wolf potential
"pair_style brownian"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics
"pair_style brownian/poly"_pair_brownian.html - Brownian potential for Fast Lubrication Dynamics with polydispersity
"pair_style buck"_pair_buck.html - Buckingham potential
"pair_style buck/coul/cut"_pair_buck.html - Buckingham with cutoff Coulomb
"pair_style buck/coul/long"_pair_buck.html - Buckingham with long-range Coulomb
"pair_style colloid"_pair_colloid.html - integrated colloidal potential
"pair_style comb"_pair_comb.html - charge-optimized many-body (COMB) potential
"pair_style coul/cut"_pair_coul.html - cutoff Coulombic potential
"pair_style coul/debye"_pair_coul.html - cutoff Coulombic potential with Debye screening
"pair_style coul/long"_pair_coul.html - long-range Coulombic potential
"pair_style coul/wolf"_pair_coul.html - Coulombics via Wolf potential
"pair_style dipole/cut"_pair_dipole.html - point dipoles with cutoff
"pair_style dpd"_pair_dpd.html - dissipative particle dynamics (DPD)
"pair_style dpd/tstat"_pair_dpd.html - DPD thermostatting
"pair_style dsmc"_pair_dsmc.html - Direct Simulation Monte Carlo (DSMC)
"pair_style eam"_pair_eam.html - embedded atom method (EAM)
"pair_style eam/alloy"_pair_eam.html - alloy EAM
"pair_style eam/fs"_pair_eam.html - Finnis-Sinclair EAM
"pair_style eim"_pair_eim.html - embedded ion method (EIM)
"pair_style gauss"_pair_gauss.html - Gaussian potential
"pair_style gayberne"_pair_gayberne.html - Gay-Berne ellipsoidal potential
"pair_style gran/hertz/history"_pair_gran.html - granular potential with Hertzian interactions
"pair_style gran/hooke"_pair_gran.html - granular potential with history effects
"pair_style gran/hooke/history"_pair_gran.html - granular potential without history effects
"pair_style hbond/dreiding/lj"_pair_hbond_dreiding.html - DREIDING hydrogen bonding LJ potential
"pair_style hbond/dreiding/morse"_pair_hbond_dreiding.html - DREIDING hydrogen bonding Morse potential
"pair_style lcbop"_pair_lcbop.html - long-range bond-order potential (LCBOP)
"pair_style line/lj"_pair_line_lj.html - LJ potential between line segments
"pair_style lj/charmm/coul/charmm"_pair_charmm.html - CHARMM potential with cutoff Coulomb
"pair_style lj/charmm/coul/charmm/implicit"_pair_charmm.html - CHARMM for implicit solvent
"pair_style lj/charmm/coul/long"_pair_charmm.html - CHARMM with long-range Coulomb
"pair_style lj/class2"_pair_class2.html - COMPASS (class 2) force field with no Coulomb
"pair_style lj/class2/coul/cut"_pair_class2.html - COMPASS with cutoff Coulomb
"pair_style lj/class2/coul/long"_pair_class2.html - COMPASS with long-range Coulomb
"pair_style lj/cut"_pair_lj.html - cutoff Lennard-Jones potential with no Coulomb
"pair_style lj/cut/coul/cut"_pair_lj.html - LJ with cutoff Coulomb
"pair_style lj/cut/coul/debye"_pair_lj.html - LJ with Debye screening added to Coulomb
"pair_style lj/cut/coul/long"_pair_lj.html - LJ with long-range Coulomb
"pair_style lj/cut/coul/long/tip4p"_pair_lj.html - LJ with long-range Coulomb for TIP4P water
"pair_style lj/expand"_pair_lj_expand.html - Lennard-Jones for variable size particles
"pair_style lj/gromacs"_pair_gromacs.html - GROMACS-style Lennard-Jones potential
"pair_style lj/gromacs/coul/gromacs"_pair_gromacs.html - GROMACS-style LJ and Coulombic potential
"pair_style lj/smooth"_pair_lj_smooth.html - smoothed Lennard-Jones potential
"pair_style lj/smooth/linear"_pair_lj_smooth_linear.html - linear smoothed Lennard-Jones potential
"pair_style lj96/cut"_pair_lj96.html - Lennard-Jones 9/6 potential
"pair_style lubricate"_pair_lubricate.html - hydrodynamic lubrication forces
"pair_style lubricate/poly"_pair_lubricate.html - hydrodynamic lubrication forces with polydispersity
"pair_style lubricateU"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication Dynamics
"pair_style lubricateU/poly"_pair_lubricateU.html - hydrodynamic lubrication forces for Fast Lubrication with polydispersity
"pair_style meam"_pair_meam.html - modified embedded atom method (MEAM)
"pair_style morse"_pair_morse.html - Morse potential
"pair_style peri/lps"_pair_peri.html - peridynamic LPS potential
"pair_style peri/pmb"_pair_peri.html - peridynamic PMB potential
"pair_style reax"_pair_reax.html - ReaxFF potential
"pair_style rebo"_pair_airebo.html - 2nd generation REBO potential of Brenner
"pair_style resquared"_pair_resquared.html - Everaers RE-Squared ellipsoidal potential
"pair_style soft"_pair_soft.html - Soft (cosine) potential
"pair_style sw"_pair_sw.html - Stillinger-Weber 3-body potential
"pair_style table"_pair_table.html - tabulated pair potential
"pair_style tersoff"_pair_tersoff.html - Tersoff 3-body potential
"pair_style tersoff/zbl"_pair_tersoff_zbl.html - Tersoff/ZBL 3-body potential
"pair_style tri/lj"_pair_tri_lj.html - LJ potential between triangles
"pair_style yukawa"_pair_yukawa.html - Yukawa potential
"pair_style yukawa/colloid"_pair_yukawa_colloid.html - screened Yukawa potential for finite-size particles :ul
:line
[Restrictions:]
This command must be used before any coefficients are set by the
"pair_coeff"_pair_coeff.html, "read_data"_read_data.html, or
"read_restart"_read_restart.html commands.
Some pair styles are part of specific packages. They are only enabled
if LAMMPS was built with that package. See the "Making
LAMMPS"_Section_start.html#start_3 section for more info on packages.
The doc pages for individual pair potentials tell if it is part of a
package.
[Related commands:]
"pair_coeff"_pair_coeff.html, "read_data"_read_data.html,
"pair_modify"_pair_modify.html, "kspace_style"_kspace_style.html,
"dielectric"_dielectric.html, "pair_write"_pair_write.html
[Default:]
pair_style none :pre
diff --git a/lib/cuda/Makefile.defaults b/lib/cuda/Makefile.defaults
index 9bccd1aeb..16445cca1 100644
--- a/lib/cuda/Makefile.defaults
+++ b/lib/cuda/Makefile.defaults
@@ -1,16 +1,19 @@
#precision setting: 1 single, 2 double, 4 mixed
precision ?= 4
+#verbose setting: 0 no, 1 yes
+verbose ?= 1
+
#GPU architecture (compute capability): 13, 20, 21
arch ?= 20
#Using cufft (should not be changed)
cufft ?= 1
#Using dbg mode
dbg ?= 0
#On mac machines set this to 0 in order to avoid usage of linux specific precision timer
prec_timer ?= 1
diff --git a/potentials/AlSiMgCuFe.meam b/potentials/AlSiMgCuFe.meam
new file mode 100644
index 000000000..492b2ac63
--- /dev/null
+++ b/potentials/AlSiMgCuFe.meam
@@ -0,0 +1,126 @@
+# MEAM Al, Si, Mg, Cu, Fe alloy potential
+# use with AlS SiS MgS CuS FeS from library.meam
+# http://dx.doi.org/10.1103/PhysRevB.85.245102
+
+ Cmin(1,1,1) = 0.8
+ repuls(1,1) = 0.1
+ Cmin(3,3,3) = 0.8
+ Cmin(4,4,4) = 0.8
+ Cmin(5,5,5) = 0.68
+ repuls(5,5) = 0.3
+ Cmax(5,5,5) = 1.9
+
+ nn2(1,1)=1
+ nn2(1,2)=1
+ nn2(1,3)=1
+ nn2(1,4)=1
+ nn2(1,5)=1
+ nn2(2,2)=1
+ nn2(2,3)=1
+ nn2(2,4)=1
+ nn2(2,5)=1
+ nn2(3,3)=1
+ nn2(3,4)=1
+ nn2(3,5)=1
+ nn2(4,4)=1
+ nn2(4,5)=1
+ nn2(5,5)=1
+
+ lattce(1,2)='b1'
+ delta(1,2)=+0.28
+ alpha(1,2)=4.56
+ re(1,2)=2.62
+ Cmin(1,1,2) = 0.50
+ Cmin(2,2,1) = 2.00
+ Cmin(1,2,1) = 2.00
+ Cmin(1,2,2) = 2.00
+
+ lattce(1,3)='b1'
+ delta(1,3)=+0.23
+ alpha(1,3)=4.52
+ re(1,3)=2.87
+ Cmin(1,1,3) = 2.00
+ Cmin(3,3,1) = 0.00
+ Cmin(1,3,1) = 2.00
+ Cmin(1,3,3) = 0.00
+
+ lattce(1,4)='b1'
+ delta(1,4)=+0.19
+ alpha(1,4)=4.65
+ re(1,4)=2.53
+ Cmin(1,1,4) = 0.00
+ Cmin(4,4,1) = 2.00
+ Cmin(1,4,1) = 2.00
+ Cmin(1,4,4) = 2.00
+
+ lattce(1,5)='b1'
+ delta(1,5)=+0.26
+ alpha(1,5)=4.64
+ re(1,5)=2.45
+ Cmin(1,1,5) = 0.90
+ Cmin(5,5,1) = 0.10
+ Cmin(1,5,1) = 2.00
+ Cmin(1,5,5) = 2.00
+
+ lattce(2,3)='b1'
+ delta(2,3)=+0.2
+ alpha(2,3)=4.73
+ re(2,3)=2.75
+ Cmin(2,2,3) = 1.00
+ Cmin(3,3,2) = 1.00
+ Cmin(2,3,2) = 2.00
+ Cmin(2,3,3) = 2.00
+
+ lattce(2,4)='b1'
+ delta(2,4)=+0.14
+ alpha(2,4)=4.74
+ re(2,4)=2.46
+ Cmin(2,2,4) = 0.00
+ Cmin(4,4,2) = 0.00
+ Cmin(2,4,2) = 2.00
+ Cmin(2,4,4) = 2.00
+
+ lattce(2,5)='b1'
+ delta(2,5)=-0.07
+ alpha(2,5)=5.17
+ re(2,5)=2.39
+ Cmin(2,2,5) = 1.00
+ Cmin(5,5,2) = 1.00
+ Cmin(2,5,2) = 2.00
+ Cmin(2,5,5) = 0.00
+ attrac(2,5) = 0.1
+ repuls(2,5) = 0.1
+
+ lattce(3,4)='b1'
+ delta(3,4)=+0.23
+ alpha(3,4)=4.70
+ re(3,4)=2.63
+ Cmin(3,3,4) = 2.00
+ Cmin(4,4,3) = 0.00
+ Cmin(3,4,3) = 2.00
+ Cmin(3,4,4) = 2.00
+
+ lattce(3,5)='b1'
+ delta(3,5)=+0.6
+ alpha(3,5)=4.96
+ re(3,5)=2.61
+ Cmin(3,3,5) = 0.65
+ Cmin(5,5,3) = 0.00
+ Cmin(3,5,3) = 2.00
+ Cmin(3,5,5) = 2.00
+
+ lattce(4,5)='b1'
+ delta(4,5)=+0.63
+ alpha(4,5)=5.21
+ re(4,5)=2.42
+ Cmin(5,5,4)=0.00
+
+ attrac(5,2) = 0.1
+ repuls(5,2) = 0.1
+
+ rc = 5.0
+ ialloy=1
+ augt1=0
+ delr=0.25658351
+ emb_lin_neg=1
+ bkgd_dyn=1
diff --git a/potentials/CdTe.bop b/potentials/CdTe.bop
new file mode 100644
index 000000000..c6bf28f5c
--- /dev/null
+++ b/potentials/CdTe.bop
@@ -0,0 +1,44 @@
+elements:
+ 2
+ 48 1.124118e+02 Cd
+ 52 1.276030e+02 Te
+
+global:
+ 1.00e-05 1.00e-05 1.00e-05 1.00e-05 1.00e-05 1.00e-03 1.00e-05
+ 2 9.900000e-01 1.000000e-02
+ 2.0 0.625 1
+ 1.573798e+01 1.137622e+00 2.087779e+00
+ 2.218068e+01 2.689731e+00
+ 2.000000e+00 0.000000e+00
+
+ptrs:
+ 0.000000e+00 1.000000e+00 4.200000e-01
+ 0.000000e+00 1.000000e+00 4.606863e-01
+
+pairs:
+ 3.127600e+00 3.127600e+00 3.730300e+00 4.333000e+00
+ 3.263155e+00 1.553883e+00 2.800000e+00
+ 1.863695e-01 2.383177e-01 9.759853e-02
+ 0.000000e+00 5.611298e-01 0.000000e+00
+ 1.000000e+00 1.000000e+00 0.000000e+00
+ 4.318628e-01 1.500000e+01 1.000000e+06
+ 3.127600e+00 3.127600e+00 4.013800e+00 4.900000e+00
+ 2.587831e+00 1.287478e+00 2.811251e+00
+ 6.314400e-01 8.252896e-01 3.174259e-02
+ 0.000000e+00 1.286955e+00 0.000000e+00
+ 1.000000e+00 1.000000e+00 0.000000e+00
+ 5.000000e-01 0.000000e+00 1.000000e+06
+ 3.162600e+00 3.162600e+00 3.804600e+00 4.446500e+00
+ 2.458846e+00 1.223306e+00 2.799998e+00
+ 8.769118e-01 7.826353e-01 5.312050e-01
+ 0.000000e+00 1.014809e+00 0.000000e+00
+ 1.000000e+00 1.000000e+00 0.000000e+00
+ 3.312269e-01 -2.860190e+00 1.000000e+06
+
+tris:
+ 3.968701e-01 8.810195e-01 -2.778897e-01
+ -1.007128e-01 10.000000e-01 1.007128e-01
+ 2.007322e-01 6.000000e-01 1.992678e-01
+ 2.095238e-01 6.000000e-01 1.904762e-01
+ 3.928496e-03 9.999272e-01 -3.855665e-03
+ 1.171817e-01 8.348116e-01 4.800670e-02
diff --git a/potentials/CdTe.bop.table b/potentials/CdTe.bop.table
new file mode 100644
index 000000000..44e682f00
--- /dev/null
+++ b/potentials/CdTe.bop.table
@@ -0,0 +1,4832 @@
+ 2
+ 48 0.11241180E+03 Cd
+ 52 0.12760300E+03 Te
+ 2000 2000
+ 0.10E-04 0.10E-04 0.10E-04 0.10E-04 0.10E-04 0.10E-02 0.10E-04
+ 0.42000000E+00
+ 0.46068630E+00
+ 0.43330000E+01
+ 0.56112980E+00 0.00000000E+00 0.10000000E+01 0.10000000E+01
+ 0.00000000E+00 0.00000000E+00
+ 0.43186280E+00 0.15000000E+02 0.10000000E+07
+ 0.44465000E+01
+ 0.10148090E+01 0.00000000E+00 0.10000000E+01 0.10000000E+01
+ 0.00000000E+00 0.00000000E+00
+ 0.33122690E+00 -0.28601900E+01 0.10000000E+07
+ 0.49000000E+01
+ 0.12869550E+01 0.00000000E+00 0.10000000E+01 0.10000000E+01
+ 0.00000000E+00 0.00000000E+00
+ 0.50000000E+00 0.00000000E+00 0.10000000E+07
+ 0.39687010E+00 0.88101950E+00 -0.27788970E+00
+ -0.10071280E+00 0.10000000E+01 0.10071280E+00
+ 0.20952380E+00 0.60000000E+00 0.19047620E+00
+ 0.39284960E-02 0.99992720E+00 -0.38556650E-02
+ -0.10071280E+00 0.10000000E+01 0.10071280E+00
+ 0.20073220E+00 0.60000000E+00 0.19926780E+00
+ 0.39284960E-02 0.99992720E+00 -0.38556650E-02
+ 0.11718170E+00 0.83481160E+00 0.48006700E-01
+ 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06
+ 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06
+ 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06
+ 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06
+ 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06
+ 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06
+ 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06
+ 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06
+ 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06 0.37236414E+06
+ 0.37236414E+06 0.37236414E+06 0.35044271E+06 0.32717105E+06 0.30587762E+06
+ 0.28635889E+06 0.26843578E+06 0.25195028E+06 0.23676268E+06 0.22274912E+06
+ 0.20979957E+06 0.19781604E+06 0.18671109E+06 0.17640656E+06 0.16683242E+06
+ 0.15792578E+06 0.14963014E+06 0.14189457E+06 0.13467311E+06 0.12792424E+06
+ 0.12161035E+06 0.11569735E+06 0.11015428E+06 0.10495298E+06 0.10006781E+06
+ 0.95475381E+05 0.91154339E+05 0.87085159E+05 0.83249960E+05 0.79632356E+05
+ 0.76217307E+05 0.72990993E+05 0.69940704E+05 0.67054733E+05 0.64322291E+05
+ 0.61733417E+05 0.59278915E+05 0.56950278E+05 0.54739633E+05 0.52639687E+05
+ 0.50643676E+05 0.48745323E+05 0.46938796E+05 0.45218674E+05 0.43579912E+05
+ 0.42017812E+05 0.40527994E+05 0.39106374E+05 0.37749140E+05 0.36452730E+05
+ 0.35213814E+05 0.34029276E+05 0.32896201E+05 0.31811857E+05 0.30773682E+05
+ 0.29779273E+05 0.28826376E+05 0.27912873E+05 0.27036771E+05 0.26196199E+05
+ 0.25389395E+05 0.24614700E+05 0.23870552E+05 0.23155477E+05 0.22468085E+05
+ 0.21807067E+05 0.21171183E+05 0.20559266E+05 0.19970209E+05 0.19402967E+05
+ 0.18856552E+05 0.18330028E+05 0.17822510E+05 0.17333156E+05 0.16861172E+05
+ 0.16405802E+05 0.15966332E+05 0.15542080E+05 0.15132402E+05 0.14736685E+05
+ 0.14354347E+05 0.13984833E+05 0.13627616E+05 0.13282196E+05 0.12948096E+05
+ 0.12624860E+05 0.12312056E+05 0.12009273E+05 0.11716116E+05 0.11432210E+05
+ 0.11157198E+05 0.10890739E+05 0.10632507E+05 0.10382190E+05 0.10139491E+05
+ 0.99041265E+04 0.96758242E+04 0.94543246E+04 0.92393793E+04 0.90307506E+04
+ 0.88282110E+04 0.86315426E+04 0.84405368E+04 0.82549938E+04 0.80747220E+04
+ 0.78995378E+04 0.77292653E+04 0.75637356E+04 0.74027867E+04 0.72462631E+04
+ 0.70940158E+04 0.69459014E+04 0.68017824E+04 0.66615266E+04 0.65250071E+04
+ 0.63921017E+04 0.62626932E+04 0.61366686E+04 0.60139195E+04 0.58943415E+04
+ 0.57778341E+04 0.56643006E+04 0.55536478E+04 0.54457861E+04 0.53406292E+04
+ 0.52380938E+04 0.51380999E+04 0.50405700E+04 0.49454298E+04 0.48526073E+04
+ 0.47620334E+04 0.46736412E+04 0.45873662E+04 0.45031463E+04 0.44209212E+04
+ 0.43406332E+04 0.42622262E+04 0.41856460E+04 0.41108406E+04 0.40377594E+04
+ 0.39663536E+04 0.38965762E+04 0.38283815E+04 0.37617256E+04 0.36965657E+04
+ 0.36328608E+04 0.35705709E+04 0.35096574E+04 0.34500831E+04 0.33918118E+04
+ 0.33348085E+04 0.32790394E+04 0.32244716E+04 0.31710735E+04 0.31188142E+04
+ 0.30676640E+04 0.30175939E+04 0.29685760E+04 0.29205830E+04 0.28735888E+04
+ 0.28275679E+04 0.27824953E+04 0.27383473E+04 0.26951004E+04 0.26527322E+04
+ 0.26112207E+04 0.25705447E+04 0.25306834E+04 0.24916170E+04 0.24533258E+04
+ 0.24157912E+04 0.23789946E+04 0.23429183E+04 0.23075450E+04 0.22728578E+04
+ 0.22388405E+04 0.22054771E+04 0.21727523E+04 0.21406509E+04 0.21091585E+04
+ 0.20782609E+04 0.20479442E+04 0.20181951E+04 0.19890006E+04 0.19603478E+04
+ 0.19322246E+04 0.19046188E+04 0.18775188E+04 0.18509132E+04 0.18247910E+04
+ 0.17991414E+04 0.17739538E+04 0.17492181E+04 0.17249242E+04 0.17010626E+04
+ 0.16776238E+04 0.16545986E+04 0.16319780E+04 0.16097533E+04 0.15879160E+04
+ 0.15664577E+04 0.15453706E+04 0.15246465E+04 0.15042780E+04 0.14842575E+04
+ 0.14645776E+04 0.14452313E+04 0.14262117E+04 0.14075120E+04 0.13891255E+04
+ 0.13710458E+04 0.13532667E+04 0.13357820E+04 0.13185858E+04 0.13016721E+04
+ 0.12850354E+04 0.12686699E+04 0.12525704E+04 0.12367315E+04 0.12211480E+04
+ 0.12058148E+04 0.11907271E+04 0.11758800E+04 0.11612688E+04 0.11468889E+04
+ 0.11327358E+04 0.11188052E+04 0.11050927E+04 0.10915941E+04 0.10783053E+04
+ 0.10652225E+04 0.10523415E+04 0.10396586E+04 0.10271702E+04 0.10148724E+04
+ 0.10027618E+04 0.99083481E+03 0.97908807E+03 0.96751823E+03 0.95612200E+03
+ 0.94489621E+03 0.93383772E+03 0.92294347E+03 0.91221048E+03 0.90163580E+03
+ 0.89121659E+03 0.88095004E+03 0.87083339E+03 0.86086398E+03 0.85103917E+03
+ 0.84135639E+03 0.83181312E+03 0.82240689E+03 0.81313530E+03 0.80399598E+03
+ 0.79498662E+03 0.78610494E+03 0.77734874E+03 0.76871584E+03 0.76020410E+03
+ 0.75181145E+03 0.74353585E+03 0.73537528E+03 0.72732780E+03 0.71939147E+03
+ 0.71156443E+03 0.70384481E+03 0.69623083E+03 0.68872070E+03 0.68131268E+03
+ 0.67400509E+03 0.66679624E+03 0.65968451E+03 0.65266828E+03 0.64574600E+03
+ 0.63891611E+03 0.63217711E+03 0.62552752E+03 0.61896587E+03 0.61249075E+03
+ 0.60610076E+03 0.59979453E+03 0.59357071E+03 0.58742798E+03 0.58136506E+03
+ 0.57538066E+03 0.56947354E+03 0.56364249E+03 0.55788630E+03 0.55220379E+03
+ 0.54659381E+03 0.54105523E+03 0.53558694E+03 0.53018783E+03 0.52485685E+03
+ 0.51959293E+03 0.51439505E+03 0.50926219E+03 0.50419335E+03 0.49918756E+03
+ 0.49424386E+03 0.48936131E+03 0.48453897E+03 0.47977595E+03 0.47507134E+03
+ 0.47042428E+03 0.46583389E+03 0.46129935E+03 0.45681980E+03 0.45239444E+03
+ 0.44802247E+03 0.44370310E+03 0.43943555E+03 0.43521907E+03 0.43105290E+03
+ 0.42693631E+03 0.42286859E+03 0.41884902E+03 0.41487690E+03 0.41095155E+03
+ 0.40707230E+03 0.40323848E+03 0.39944945E+03 0.39570456E+03 0.39200319E+03
+ 0.38834471E+03 0.38472853E+03 0.38115404E+03 0.37762066E+03 0.37412781E+03
+ 0.37067491E+03 0.36726142E+03 0.36388678E+03 0.36055046E+03 0.35725192E+03
+ 0.35399063E+03 0.35076609E+03 0.34757780E+03 0.34442524E+03 0.34130794E+03
+ 0.33822541E+03 0.33517717E+03 0.33216277E+03 0.32918175E+03 0.32623365E+03
+ 0.32331803E+03 0.32043445E+03 0.31758249E+03 0.31476171E+03 0.31197171E+03
+ 0.30921208E+03 0.30648241E+03 0.30378230E+03 0.30111137E+03 0.29846923E+03
+ 0.29585550E+03 0.29326982E+03 0.29071180E+03 0.28818110E+03 0.28567735E+03
+ 0.28320021E+03 0.28074933E+03 0.27832438E+03 0.27592501E+03 0.27355091E+03
+ 0.27120174E+03 0.26887719E+03 0.26657694E+03 0.26430068E+03 0.26204812E+03
+ 0.25981894E+03 0.25761285E+03 0.25542957E+03 0.25326880E+03 0.25113027E+03
+ 0.24901368E+03 0.24691878E+03 0.24484529E+03 0.24279294E+03 0.24076148E+03
+ 0.23875063E+03 0.23676016E+03 0.23478980E+03 0.23283931E+03 0.23090845E+03
+ 0.22899698E+03 0.22710465E+03 0.22523125E+03 0.22337653E+03 0.22154027E+03
+ 0.21972225E+03 0.21792225E+03 0.21614004E+03 0.21437543E+03 0.21262819E+03
+ 0.21089812E+03 0.20918501E+03 0.20748867E+03 0.20580888E+03 0.20414547E+03
+ 0.20249822E+03 0.20086696E+03 0.19925150E+03 0.19765164E+03 0.19606721E+03
+ 0.19449802E+03 0.19294390E+03 0.19140468E+03 0.18988017E+03 0.18837021E+03
+ 0.18687464E+03 0.18539328E+03 0.18392596E+03 0.18247254E+03 0.18103285E+03
+ 0.17960673E+03 0.17819403E+03 0.17679460E+03 0.17540828E+03 0.17403493E+03
+ 0.17267440E+03 0.17132654E+03 0.16999121E+03 0.16866827E+03 0.16735759E+03
+ 0.16605902E+03 0.16477243E+03 0.16349769E+03 0.16223466E+03 0.16098321E+03
+ 0.15974322E+03 0.15851456E+03 0.15729710E+03 0.15609072E+03 0.15489530E+03
+ 0.15371072E+03 0.15253686E+03 0.15137361E+03 0.15022084E+03 0.14907844E+03
+ 0.14794631E+03 0.14682432E+03 0.14571237E+03 0.14461036E+03 0.14351817E+03
+ 0.14243570E+03 0.14136285E+03 0.14029950E+03 0.13924557E+03 0.13820095E+03
+ 0.13716554E+03 0.13613924E+03 0.13512196E+03 0.13411360E+03 0.13311407E+03
+ 0.13212327E+03 0.13114112E+03 0.13016752E+03 0.12920238E+03 0.12824561E+03
+ 0.12729713E+03 0.12635685E+03 0.12542469E+03 0.12450056E+03 0.12358438E+03
+ 0.12267606E+03 0.12177553E+03 0.12088270E+03 0.11999750E+03 0.11911984E+03
+ 0.11824966E+03 0.11738687E+03 0.11653140E+03 0.11568318E+03 0.11484213E+03
+ 0.11400817E+03 0.11318124E+03 0.11236127E+03 0.11154818E+03 0.11074191E+03
+ 0.10994239E+03 0.10914954E+03 0.10836332E+03 0.10758364E+03 0.10681044E+03
+ 0.10604366E+03 0.10528323E+03 0.10452910E+03 0.10378119E+03 0.10303946E+03
+ 0.10230383E+03 0.10157424E+03 0.10085065E+03 0.10013298E+03 0.99421188E+02
+ 0.98715207E+02 0.98014984E+02 0.97320461E+02 0.96631585E+02 0.95948300E+02
+ 0.95270552E+02 0.94598288E+02 0.93931454E+02 0.93270000E+02 0.92613872E+02
+ 0.91963020E+02 0.91317394E+02 0.90676943E+02 0.90041619E+02 0.89411372E+02
+ 0.88786155E+02 0.88165919E+02 0.87550618E+02 0.86940204E+02 0.86334632E+02
+ 0.85733857E+02 0.85137832E+02 0.84546514E+02 0.83959859E+02 0.83377822E+02
+ 0.82800361E+02 0.82227433E+02 0.81658996E+02 0.81095009E+02 0.80535429E+02
+ 0.79980217E+02 0.79429331E+02 0.78882733E+02 0.78340382E+02 0.77802240E+02
+ 0.77268268E+02 0.76738428E+02 0.76212681E+02 0.75690991E+02 0.75173321E+02
+ 0.74659634E+02 0.74149894E+02 0.73644065E+02 0.73142112E+02 0.72644000E+02
+ 0.72149693E+02 0.71659159E+02 0.71172363E+02 0.70689271E+02 0.70209850E+02
+ 0.69734068E+02 0.69261891E+02 0.68793289E+02 0.68328228E+02 0.67866678E+02
+ 0.67408607E+02 0.66953985E+02 0.66502780E+02 0.66054964E+02 0.65610506E+02
+ 0.65169376E+02 0.64731545E+02 0.64296985E+02 0.63865666E+02 0.63437561E+02
+ 0.63012641E+02 0.62590879E+02 0.62172246E+02 0.61756717E+02 0.61344263E+02
+ 0.60934859E+02 0.60528478E+02 0.60125094E+02 0.59724681E+02 0.59327213E+02
+ 0.58932666E+02 0.58541014E+02 0.58152232E+02 0.57766296E+02 0.57383182E+02
+ 0.57002865E+02 0.56625322E+02 0.56250529E+02 0.55878463E+02 0.55509100E+02
+ 0.55142419E+02 0.54778396E+02 0.54417008E+02 0.54058235E+02 0.53702053E+02
+ 0.53348440E+02 0.52997377E+02 0.52648840E+02 0.52302810E+02 0.51959264E+02
+ 0.51618183E+02 0.51279546E+02 0.50943332E+02 0.50609522E+02 0.50278096E+02
+ 0.49949033E+02 0.49622315E+02 0.49297922E+02 0.48975835E+02 0.48656035E+02
+ 0.48338503E+02 0.48023221E+02 0.47710171E+02 0.47399333E+02 0.47090690E+02
+ 0.46784225E+02 0.46479919E+02 0.46177755E+02 0.45877715E+02 0.45579783E+02
+ 0.45283941E+02 0.44990173E+02 0.44698461E+02 0.44408790E+02 0.44121142E+02
+ 0.43835502E+02 0.43551854E+02 0.43270181E+02 0.42990467E+02 0.42712698E+02
+ 0.42436858E+02 0.42162931E+02 0.41890901E+02 0.41620755E+02 0.41352477E+02
+ 0.41086052E+02 0.40821466E+02 0.40558705E+02 0.40297753E+02 0.40038596E+02
+ 0.39781221E+02 0.39525614E+02 0.39271760E+02 0.39019646E+02 0.38769258E+02
+ 0.38520584E+02 0.38273609E+02 0.38028320E+02 0.37784704E+02 0.37542749E+02
+ 0.37302441E+02 0.37063767E+02 0.36826716E+02 0.36591274E+02 0.36357429E+02
+ 0.36125169E+02 0.35894482E+02 0.35665355E+02 0.35437776E+02 0.35211735E+02
+ 0.34987218E+02 0.34764214E+02 0.34542713E+02 0.34322702E+02 0.34104170E+02
+ 0.33887105E+02 0.33671497E+02 0.33457335E+02 0.33244608E+02 0.33033305E+02
+ 0.32823414E+02 0.32614926E+02 0.32407830E+02 0.32202116E+02 0.31997772E+02
+ 0.31794790E+02 0.31593158E+02 0.31392867E+02 0.31193906E+02 0.30996266E+02
+ 0.30799936E+02 0.30604908E+02 0.30411171E+02 0.30218715E+02 0.30027533E+02
+ 0.29837613E+02 0.29648946E+02 0.29461524E+02 0.29275337E+02 0.29090376E+02
+ 0.28906632E+02 0.28724096E+02 0.28542759E+02 0.28362612E+02 0.28183648E+02
+ 0.28005856E+02 0.27829229E+02 0.27653758E+02 0.27479435E+02 0.27306251E+02
+ 0.27134198E+02 0.26963267E+02 0.26793451E+02 0.26624742E+02 0.26457132E+02
+ 0.26290612E+02 0.26125175E+02 0.25960813E+02 0.25797518E+02 0.25635283E+02
+ 0.25474099E+02 0.25313960E+02 0.25154858E+02 0.24996786E+02 0.24839736E+02
+ 0.24683701E+02 0.24528673E+02 0.24374646E+02 0.24221612E+02 0.24069565E+02
+ 0.23918496E+02 0.23768401E+02 0.23619270E+02 0.23471099E+02 0.23323879E+02
+ 0.23177605E+02 0.23032269E+02 0.22887865E+02 0.22744386E+02 0.22601826E+02
+ 0.22460179E+02 0.22319438E+02 0.22179596E+02 0.22040648E+02 0.21902587E+02
+ 0.21765407E+02 0.21629102E+02 0.21493665E+02 0.21359092E+02 0.21225375E+02
+ 0.21092508E+02 0.20960487E+02 0.20829305E+02 0.20698956E+02 0.20569434E+02
+ 0.20440734E+02 0.20312851E+02 0.20185777E+02 0.20059509E+02 0.19934040E+02
+ 0.19809365E+02 0.19685479E+02 0.19562375E+02 0.19440049E+02 0.19318496E+02
+ 0.19197710E+02 0.19077685E+02 0.18958417E+02 0.18839901E+02 0.18722131E+02
+ 0.18605103E+02 0.18488811E+02 0.18373250E+02 0.18258415E+02 0.18144302E+02
+ 0.18030906E+02 0.17918221E+02 0.17806244E+02 0.17694968E+02 0.17584390E+02
+ 0.17474505E+02 0.17365308E+02 0.17256794E+02 0.17148959E+02 0.17041799E+02
+ 0.16935308E+02 0.16829483E+02 0.16724319E+02 0.16619811E+02 0.16515956E+02
+ 0.16412748E+02 0.16310184E+02 0.16208258E+02 0.16106968E+02 0.16006309E+02
+ 0.15906276E+02 0.15806866E+02 0.15708074E+02 0.15609896E+02 0.15512328E+02
+ 0.15415367E+02 0.15319007E+02 0.15223246E+02 0.15128079E+02 0.15033502E+02
+ 0.14939512E+02 0.14846104E+02 0.14753276E+02 0.14661022E+02 0.14569339E+02
+ 0.14478224E+02 0.14387673E+02 0.14297681E+02 0.14208247E+02 0.14119365E+02
+ 0.14031032E+02 0.13943245E+02 0.13856000E+02 0.13769294E+02 0.13683122E+02
+ 0.13597483E+02 0.13512371E+02 0.13427784E+02 0.13343719E+02 0.13260172E+02
+ 0.13177139E+02 0.13094618E+02 0.13012605E+02 0.12931096E+02 0.12850089E+02
+ 0.12769580E+02 0.12689567E+02 0.12610045E+02 0.12531012E+02 0.12452465E+02
+ 0.12374400E+02 0.12296815E+02 0.12219706E+02 0.12143070E+02 0.12066905E+02
+ 0.11991207E+02 0.11915973E+02 0.11841201E+02 0.11766887E+02 0.11693028E+02
+ 0.11619623E+02 0.11546667E+02 0.11474157E+02 0.11402092E+02 0.11330469E+02
+ 0.11259283E+02 0.11188534E+02 0.11118217E+02 0.11048330E+02 0.10978871E+02
+ 0.10909837E+02 0.10841225E+02 0.10773032E+02 0.10705256E+02 0.10637894E+02
+ 0.10570944E+02 0.10504403E+02 0.10438268E+02 0.10372537E+02 0.10307208E+02
+ 0.10242277E+02 0.10177743E+02 0.10113602E+02 0.10049853E+02 0.99864932E+01
+ 0.99235197E+01 0.98609302E+01 0.97987224E+01 0.97368940E+01 0.96754426E+01
+ 0.96143658E+01 0.95536613E+01 0.94933268E+01 0.94333599E+01 0.93737585E+01
+ 0.93145203E+01 0.92556429E+01 0.91971242E+01 0.91389620E+01 0.90811539E+01
+ 0.90236980E+01 0.89665918E+01 0.89098334E+01 0.88534206E+01 0.87973512E+01
+ 0.87416231E+01 0.86862342E+01 0.86311824E+01 0.85764657E+01 0.85220820E+01
+ 0.84680292E+01 0.84143053E+01 0.83609083E+01 0.83078362E+01 0.82550869E+01
+ 0.82026586E+01 0.81505492E+01 0.80987569E+01 0.80472795E+01 0.79961153E+01
+ 0.79452623E+01 0.78947186E+01 0.78444824E+01 0.77945517E+01 0.77449246E+01
+ 0.76955994E+01 0.76465742E+01 0.75978471E+01 0.75494164E+01 0.75012803E+01
+ 0.74534368E+01 0.74058844E+01 0.73586212E+01 0.73116454E+01 0.72649553E+01
+ 0.72185492E+01 0.71724254E+01 0.71265820E+01 0.70810176E+01 0.70357302E+01
+ 0.69907184E+01 0.69459804E+01 0.69015145E+01 0.68573191E+01 0.68133926E+01
+ 0.67697333E+01 0.67263397E+01 0.66832101E+01 0.66403429E+01 0.65977366E+01
+ 0.65553896E+01 0.65133003E+01 0.64714672E+01 0.64298887E+01 0.63885633E+01
+ 0.63474895E+01 0.63066658E+01 0.62660906E+01 0.62257625E+01 0.61856799E+01
+ 0.61458415E+01 0.61062457E+01 0.60668911E+01 0.60277763E+01 0.59888998E+01
+ 0.59502601E+01 0.59118559E+01 0.58736858E+01 0.58357483E+01 0.57980420E+01
+ 0.57605657E+01 0.57233178E+01 0.56862971E+01 0.56495022E+01 0.56129317E+01
+ 0.55765843E+01 0.55404586E+01 0.55045534E+01 0.54688673E+01 0.54333990E+01
+ 0.53981473E+01 0.53631107E+01 0.53282881E+01 0.52936782E+01 0.52592797E+01
+ 0.52250913E+01 0.51911118E+01 0.51573400E+01 0.51237746E+01 0.50904143E+01
+ 0.50572581E+01 0.50243046E+01 0.49915527E+01 0.49590011E+01 0.49266486E+01
+ 0.48944942E+01 0.48625366E+01 0.48307746E+01 0.47992071E+01 0.47678329E+01
+ 0.47366509E+01 0.47056599E+01 0.46748589E+01 0.46442466E+01 0.46138220E+01
+ 0.45835840E+01 0.45535314E+01 0.45236632E+01 0.44939782E+01 0.44644754E+01
+ 0.44351536E+01 0.44060120E+01 0.43770492E+01 0.43482644E+01 0.43196565E+01
+ 0.42912243E+01 0.42629669E+01 0.42348832E+01 0.42069723E+01 0.41792330E+01
+ 0.41516644E+01 0.41242655E+01 0.40970352E+01 0.40699726E+01 0.40430767E+01
+ 0.40163465E+01 0.39897810E+01 0.39633792E+01 0.39371402E+01 0.39110630E+01
+ 0.38851467E+01 0.38593903E+01 0.38337929E+01 0.38083535E+01 0.37830712E+01
+ 0.37579451E+01 0.37329743E+01 0.37081578E+01 0.36834947E+01 0.36589841E+01
+ 0.36346252E+01 0.36104170E+01 0.35863586E+01 0.35624492E+01 0.35386879E+01
+ 0.35150739E+01 0.34916061E+01 0.34682838E+01 0.34451062E+01 0.34220724E+01
+ 0.33991814E+01 0.33764326E+01 0.33538250E+01 0.33313578E+01 0.33090302E+01
+ 0.32868414E+01 0.32647906E+01 0.32428769E+01 0.32210995E+01 0.31994576E+01
+ 0.31779505E+01 0.31565773E+01 0.31353373E+01 0.31142296E+01 0.30932536E+01
+ 0.30724083E+01 0.30516931E+01 0.30311071E+01 0.30106497E+01 0.29903201E+01
+ 0.29701174E+01 0.29500410E+01 0.29300901E+01 0.29102640E+01 0.28905619E+01
+ 0.28709832E+01 0.28515270E+01 0.28321927E+01 0.28129796E+01 0.27938868E+01
+ 0.27749138E+01 0.27560599E+01 0.27373242E+01 0.27187061E+01 0.27002050E+01
+ 0.26818201E+01 0.26635508E+01 0.26453963E+01 0.26273561E+01 0.26094293E+01
+ 0.25916154E+01 0.25739137E+01 0.25563236E+01 0.25388443E+01 0.25214752E+01
+ 0.25042156E+01 0.24870650E+01 0.24700227E+01 0.24530880E+01 0.24362603E+01
+ 0.24195390E+01 0.24029234E+01 0.23864129E+01 0.23700069E+01 0.23537048E+01
+ 0.23375060E+01 0.23214098E+01 0.23054157E+01 0.22895231E+01 0.22737312E+01
+ 0.22580397E+01 0.22424478E+01 0.22269549E+01 0.22115606E+01 0.21962641E+01
+ 0.21810650E+01 0.21659626E+01 0.21509564E+01 0.21360458E+01 0.21212303E+01
+ 0.21065092E+01 0.20918821E+01 0.20773483E+01 0.20629073E+01 0.20485586E+01
+ 0.20343016E+01 0.20201357E+01 0.20060605E+01 0.19920754E+01 0.19781798E+01
+ 0.19643733E+01 0.19506552E+01 0.19370252E+01 0.19234825E+01 0.19100268E+01
+ 0.18966576E+01 0.18833742E+01 0.18701762E+01 0.18570631E+01 0.18440344E+01
+ 0.18310896E+01 0.18182281E+01 0.18054495E+01 0.17927533E+01 0.17801390E+01
+ 0.17676061E+01 0.17551542E+01 0.17427827E+01 0.17304911E+01 0.17182791E+01
+ 0.17061460E+01 0.16940915E+01 0.16821151E+01 0.16702163E+01 0.16583946E+01
+ 0.16466496E+01 0.16349809E+01 0.16233879E+01 0.16118702E+01 0.16004274E+01
+ 0.15890590E+01 0.15777646E+01 0.15665437E+01 0.15553959E+01 0.15443208E+01
+ 0.15333179E+01 0.15223868E+01 0.15115270E+01 0.15007382E+01 0.14900199E+01
+ 0.14793716E+01 0.14687930E+01 0.14582837E+01 0.14478432E+01 0.14374711E+01
+ 0.14271670E+01 0.14169304E+01 0.14067611E+01 0.13966586E+01 0.13866224E+01
+ 0.13766522E+01 0.13667476E+01 0.13569082E+01 0.13471336E+01 0.13374234E+01
+ 0.13277772E+01 0.13181947E+01 0.13086753E+01 0.12992189E+01 0.12898249E+01
+ 0.12804931E+01 0.12712229E+01 0.12620142E+01 0.12528664E+01 0.12437792E+01
+ 0.12347523E+01 0.12257853E+01 0.12168778E+01 0.12080294E+01 0.11992399E+01
+ 0.11905088E+01 0.11818358E+01 0.11732205E+01 0.11646626E+01 0.11561618E+01
+ 0.11477176E+01 0.11393298E+01 0.11309980E+01 0.11227219E+01 0.11145011E+01
+ 0.11063353E+01 0.10982241E+01 0.10901673E+01 0.10821644E+01 0.10742152E+01
+ 0.10663193E+01 0.10584765E+01 0.10506863E+01 0.10429484E+01 0.10352627E+01
+ 0.10276286E+01 0.10200459E+01 0.10125143E+01 0.10050335E+01 0.99760317E+00
+ 0.99022297E+00 0.98289262E+00 0.97561181E+00 0.96838024E+00 0.96119760E+00
+ 0.95406359E+00 0.94697791E+00 0.93994026E+00 0.93295035E+00 0.92600789E+00
+ 0.91911258E+00 0.91226413E+00 0.90546225E+00 0.89870665E+00 0.89199706E+00
+ 0.88533317E+00 0.87871472E+00 0.87214142E+00 0.86561298E+00 0.85912914E+00
+ 0.85268961E+00 0.84629413E+00 0.83994241E+00 0.83363419E+00 0.82736920E+00
+ 0.82114716E+00 0.81496781E+00 0.80883089E+00 0.80273613E+00 0.79668326E+00
+ 0.79067204E+00 0.78470219E+00 0.77877346E+00 0.77288559E+00 0.76703833E+00
+ 0.76123142E+00 0.75546461E+00 0.74973766E+00 0.74405031E+00 0.73840230E+00
+ 0.73279341E+00 0.72722338E+00 0.72169196E+00 0.71619892E+00 0.71074402E+00
+ 0.70532701E+00 0.69994765E+00 0.69460572E+00 0.68930097E+00 0.68403317E+00
+ 0.67880208E+00 0.67360748E+00 0.66844914E+00 0.66332682E+00 0.65824030E+00
+ 0.65318936E+00 0.64817376E+00 0.64319329E+00 0.63824771E+00 0.63333682E+00
+ 0.62846039E+00 0.62361820E+00 0.61881003E+00 0.61403568E+00 0.60929491E+00
+ 0.60458753E+00 0.59991331E+00 0.59527205E+00 0.59066354E+00 0.58608757E+00
+ 0.58154392E+00 0.57703240E+00 0.57255280E+00 0.56810491E+00 0.56368854E+00
+ 0.55930347E+00 0.55494952E+00 0.55062647E+00 0.54633414E+00 0.54207232E+00
+ 0.53784083E+00 0.53363946E+00 0.52946801E+00 0.52532631E+00 0.52121416E+00
+ 0.51713136E+00 0.51307773E+00 0.50905308E+00 0.50505722E+00 0.50108997E+00
+ 0.49715114E+00 0.49324055E+00 0.48935802E+00 0.48550336E+00 0.48167639E+00
+ 0.47787694E+00 0.47410482E+00 0.47035987E+00 0.46664189E+00 0.46295072E+00
+ 0.45928618E+00 0.45564810E+00 0.45203631E+00 0.44845063E+00 0.44489090E+00
+ 0.44135694E+00 0.43784859E+00 0.43436568E+00 0.43090805E+00 0.42747552E+00
+ 0.42406793E+00 0.42068513E+00 0.41732694E+00 0.41399322E+00 0.41068378E+00
+ 0.40739848E+00 0.40413716E+00 0.40089966E+00 0.39768583E+00 0.39449550E+00
+ 0.39132852E+00 0.38818474E+00 0.38506400E+00 0.38196616E+00 0.37889105E+00
+ 0.37583854E+00 0.37280847E+00 0.36980069E+00 0.36681506E+00 0.36385142E+00
+ 0.36090964E+00 0.35798956E+00 0.35509104E+00 0.35221394E+00 0.34935812E+00
+ 0.34652343E+00 0.34370974E+00 0.34091690E+00 0.33814477E+00 0.33539322E+00
+ 0.33266210E+00 0.32995129E+00 0.32726064E+00 0.32459002E+00 0.32193929E+00
+ 0.31930833E+00 0.31669699E+00 0.31410516E+00 0.31153269E+00 0.30897945E+00
+ 0.30644532E+00 0.30393017E+00 0.30143387E+00 0.29895629E+00 0.29649730E+00
+ 0.29405678E+00 0.29163461E+00 0.28923066E+00 0.28684480E+00 0.28447692E+00
+ 0.28212689E+00 0.27979460E+00 0.27747991E+00 0.27518271E+00 0.27290288E+00
+ 0.27064031E+00 0.26839487E+00 0.26616645E+00 0.26395493E+00 0.26176020E+00
+ 0.25958214E+00 0.25742064E+00 0.25527558E+00 0.25314685E+00 0.25103434E+00
+ 0.24893794E+00 0.24685754E+00 0.24479303E+00 0.24274429E+00 0.24071122E+00
+ 0.23869372E+00 0.23669166E+00 0.23470496E+00 0.23273349E+00 0.23077717E+00
+ 0.22883587E+00 0.22690950E+00 0.22499795E+00 0.22310113E+00 0.22121892E+00
+ 0.21935123E+00 0.21749795E+00 0.21565900E+00 0.21383425E+00 0.21202363E+00
+ 0.21022702E+00 0.20844434E+00 0.20667547E+00 0.20492034E+00 0.20317883E+00
+ 0.20145086E+00 0.19973633E+00 0.19803515E+00 0.19634722E+00 0.19467245E+00
+ 0.19301074E+00 0.19136202E+00 0.18972617E+00 0.18810312E+00 0.18649277E+00
+ 0.18489503E+00 0.18330982E+00 0.18173704E+00 0.18017661E+00 0.17862844E+00
+ 0.17709244E+00 0.17556853E+00 0.17405662E+00 0.17255663E+00 0.17106846E+00
+ 0.16959205E+00 0.16812729E+00 0.16667412E+00 0.16523244E+00 0.16380218E+00
+ 0.16238325E+00 0.16097558E+00 0.15957908E+00 0.15819366E+00 0.15681927E+00
+ 0.15545580E+00 0.15410319E+00 0.15276136E+00 0.15143023E+00 0.15010972E+00
+ 0.14879975E+00 0.14750026E+00 0.14621116E+00 0.14493238E+00 0.14366384E+00
+ 0.14240548E+00 0.14115721E+00 0.13991897E+00 0.13869067E+00 0.13747226E+00
+ 0.13626365E+00 0.13506478E+00 0.13387557E+00 0.13269596E+00 0.13152588E+00
+ 0.13036524E+00 0.12921400E+00 0.12807207E+00 0.12693939E+00 0.12581590E+00
+ 0.12470152E+00 0.12359618E+00 0.12249983E+00 0.12141239E+00 0.12033380E+00
+ 0.11926400E+00 0.11820292E+00 0.11715049E+00 0.11610666E+00 0.11507135E+00
+ 0.11404451E+00 0.11302607E+00 0.11201598E+00 0.11101416E+00 0.11002056E+00
+ 0.10903511E+00 0.10805776E+00 0.10708845E+00 0.10612712E+00 0.10517370E+00
+ 0.10422814E+00 0.10329037E+00 0.10236035E+00 0.10143801E+00 0.10052330E+00
+ 0.99616157E-01 0.98716525E-01 0.97824348E-01 0.96939571E-01 0.96062139E-01
+ 0.95191995E-01 0.94329085E-01 0.93473355E-01 0.92624750E-01 0.91783217E-01
+ 0.90948702E-01 0.90121153E-01 0.89300516E-01 0.88486740E-01 0.87679772E-01
+ 0.86879561E-01 0.86086055E-01 0.85299204E-01 0.84518957E-01 0.83745264E-01
+ 0.82978075E-01 0.82217339E-01 0.81463009E-01 0.80715035E-01 0.79973369E-01
+ 0.79237962E-01 0.78508766E-01 0.77785734E-01 0.77068818E-01 0.76357972E-01
+ 0.75653150E-01 0.74954303E-01 0.74261388E-01 0.73574357E-01 0.72893166E-01
+ 0.72217769E-01 0.71548122E-01 0.70884181E-01 0.70225901E-01 0.69573238E-01
+ 0.68926148E-01 0.68284590E-01 0.67648519E-01 0.67017893E-01 0.66392669E-01
+ 0.65772806E-01 0.65158262E-01 0.64548995E-01 0.63944964E-01 0.63346128E-01
+ 0.62752447E-01 0.62163879E-01 0.61580386E-01 0.61001927E-01 0.60428463E-01
+ 0.59859955E-01 0.59296363E-01 0.58737648E-01 0.58183774E-01 0.57634700E-01
+ 0.57090390E-01 0.56550805E-01 0.56015909E-01 0.55485664E-01 0.54960034E-01
+ 0.54438981E-01 0.53922470E-01 0.53410464E-01 0.52902928E-01 0.52399825E-01
+ 0.51901122E-01 0.51406782E-01 0.50916770E-01 0.50431053E-01 0.49949596E-01
+ 0.49472364E-01 0.48999325E-01 0.48530444E-01 0.48065687E-01 0.47605022E-01
+ 0.47148417E-01 0.46695837E-01 0.46247251E-01 0.45802627E-01 0.45361932E-01
+ 0.44925136E-01 0.44492205E-01 0.44063110E-01 0.43637818E-01 0.43216300E-01
+ 0.42798524E-01 0.42384460E-01 0.41974078E-01 0.41567348E-01 0.41164240E-01
+ 0.40764725E-01 0.40368772E-01 0.39976355E-01 0.39587442E-01 0.39202006E-01
+ 0.38820017E-01 0.38441449E-01 0.38066272E-01 0.37694459E-01 0.37325983E-01
+ 0.36960815E-01 0.36598928E-01 0.36240295E-01 0.35884890E-01 0.35532686E-01
+ 0.35183656E-01 0.34837773E-01 0.34495013E-01 0.34155348E-01 0.33818754E-01
+ 0.33485204E-01 0.33154674E-01 0.32827138E-01 0.32502571E-01 0.32180948E-01
+ 0.31862245E-01 0.31546437E-01 0.31233501E-01 0.30923411E-01 0.30616144E-01
+ 0.30311677E-01 0.30009986E-01 0.29711047E-01 0.29414837E-01 0.29121334E-01
+ 0.28830514E-01 0.28542355E-01 0.28256834E-01 0.27973928E-01 0.27693617E-01
+ 0.27415877E-01 0.27140687E-01 0.26868025E-01 0.26597869E-01 0.26330199E-01
+ 0.26064993E-01 0.25802229E-01 0.25541888E-01 0.25283948E-01 0.25028389E-01
+ 0.24775190E-01 0.24524331E-01 0.24275792E-01 0.24029553E-01 0.23785594E-01
+ 0.23543896E-01 0.23304439E-01 0.23067203E-01 0.22832170E-01 0.22599320E-01
+ 0.22368634E-01 0.22140094E-01 0.21913681E-01 0.21689376E-01 0.21467161E-01
+ 0.21247019E-01 0.21028930E-01 0.20812876E-01 0.20598841E-01 0.20386806E-01
+ 0.20176754E-01 0.19968667E-01 0.19762529E-01 0.19558321E-01 0.19356027E-01
+ 0.19155630E-01 0.18957114E-01 0.18760461E-01 0.18565656E-01 0.18372681E-01
+ 0.18181521E-01 0.17992160E-01 0.17804581E-01 0.17618769E-01 0.17434707E-01
+ 0.17252381E-01 0.17071775E-01 0.16892873E-01 0.16715660E-01 0.16540121E-01
+ 0.16366241E-01 0.16194006E-01 0.16023399E-01 0.15854407E-01 0.15687015E-01
+ 0.15521209E-01 0.15356974E-01 0.15194296E-01 0.15033161E-01 0.14873555E-01
+ 0.14715464E-01 0.14558875E-01 0.14403773E-01 0.14250144E-01 0.14097977E-01
+ 0.13947257E-01 0.13797970E-01 0.13650105E-01 0.13503647E-01 0.13358585E-01
+ 0.13214904E-01 0.13072593E-01 0.12931638E-01 0.12792027E-01 0.12653749E-01
+ 0.12516789E-01 0.12381137E-01 0.12246780E-01 0.12113706E-01 0.11981903E-01
+ 0.11851360E-01 0.11722063E-01 0.11594003E-01 0.11467167E-01 0.11341544E-01
+ 0.11217122E-01 0.11093891E-01 0.10971838E-01 0.10850953E-01 0.10731226E-01
+ 0.10612644E-01 0.10495197E-01 0.10378875E-01 0.10263667E-01 0.10149562E-01
+ 0.10036550E-01 0.99246196E-02 0.98137616E-02 0.97039655E-02 0.95952210E-02
+ 0.94875183E-02 0.93808472E-02 0.92751979E-02 0.91705606E-02 0.90669256E-02
+ 0.89642833E-02 0.88626240E-02 0.87619384E-02 0.86622170E-02 0.85634505E-02
+ 0.84656297E-02 0.83687454E-02 0.82727886E-02 0.81777502E-02 0.80836213E-02
+ 0.79903931E-02 0.78980567E-02 0.78066036E-02 0.77160251E-02 0.76263126E-02
+ 0.75374577E-02 0.74494520E-02 0.73622871E-02 0.72759548E-02 0.71904470E-02
+ 0.71057555E-02 0.70218724E-02 0.69387895E-02 0.68564992E-02 0.67749935E-02
+ 0.66942647E-02 0.66143051E-02 0.65351072E-02 0.64566634E-02 0.63789662E-02
+ 0.63020083E-02 0.62257823E-02 0.61502811E-02 0.60754973E-02 0.60014238E-02
+ 0.59280538E-02 0.58553800E-02 0.57833957E-02 0.57120940E-02 0.56414681E-02
+ 0.55715114E-02 0.55022171E-02 0.54335786E-02 0.53655896E-02 0.52982434E-02
+ 0.52315339E-02 0.51654545E-02 0.50999992E-02 0.50351617E-02 0.49709358E-02
+ 0.49073156E-02 0.48442951E-02 0.47818683E-02 0.47200294E-02 0.46587726E-02
+ 0.45980921E-02 0.45379824E-02 0.44784377E-02 0.44194527E-02 0.43610217E-02
+ 0.43031395E-02 0.42458007E-02 0.41889999E-02 0.41327320E-02 0.40769919E-02
+ 0.40217745E-02 0.39670747E-02 0.39128876E-02 0.38592083E-02 0.38060320E-02
+ 0.37533539E-02 0.37011694E-02 0.36494738E-02 0.35982625E-02 0.35475310E-02
+ 0.34972750E-02 0.34474900E-02 0.33981718E-02 0.33493160E-02 0.33009186E-02
+ 0.32529753E-02 0.32054823E-02 0.31584354E-02 0.31118308E-02 0.30656646E-02
+ 0.30199330E-02 0.29746324E-02 0.29297590E-02 0.28853093E-02 0.28412798E-02
+ 0.27976669E-02 0.27544674E-02 0.27116779E-02 0.26692952E-02 0.26273159E-02
+ 0.25857372E-02 0.25445557E-02 0.25037687E-02 0.24633732E-02 0.24233662E-02
+ 0.23837451E-02 0.23445070E-02 0.23056494E-02 0.22671697E-02 0.22290653E-02
+ 0.21913337E-02 0.21539726E-02 0.21169797E-02 0.20803527E-02 0.20440894E-02
+ 0.20081877E-02 0.19726455E-02 0.19374608E-02 0.19026318E-02 0.18681564E-02
+ 0.18340331E-02 0.18002599E-02 0.17668353E-02 0.17337576E-02 0.17010253E-02
+ 0.16686369E-02 0.16365911E-02 0.16048863E-02 0.15735214E-02 0.15424951E-02
+ 0.15118062E-02 0.14814536E-02 0.14514362E-02 0.14217531E-02 0.13924033E-02
+ 0.13633859E-02 0.13347000E-02 0.13063449E-02 0.12783198E-02 0.12506240E-02
+ 0.12232569E-02 0.11962179E-02 0.11695065E-02 0.11431221E-02 0.11170642E-02
+ 0.10913325E-02 0.10659266E-02 0.10408460E-02 0.10160905E-02 0.99165985E-03
+ 0.96755368E-03 0.94377180E-03 0.92031400E-03 0.89718009E-03 0.87436990E-03
+ 0.85188327E-03 0.82972007E-03 0.80788015E-03 0.78636340E-03 0.76516969E-03
+ 0.74429890E-03 0.72375091E-03 0.70352559E-03 0.68362280E-03 0.66404239E-03
+ 0.64478418E-03 0.62584799E-03 0.60723360E-03 0.58894078E-03 0.57096924E-03
+ 0.55331867E-03 0.53598874E-03 0.51897903E-03 0.50228912E-03 0.48591850E-03
+ 0.46986662E-03 0.45413289E-03 0.43871661E-03 0.42361705E-03 0.40883340E-03
+ 0.39436476E-03 0.38021016E-03 0.36636855E-03 0.35283878E-03 0.33961963E-03
+ 0.32670975E-03 0.31410772E-03 0.30181202E-03 0.28982100E-03 0.27813293E-03
+ 0.26674595E-03 0.25565810E-03 0.24486728E-03 0.23437130E-03 0.22416784E-03
+ 0.21425445E-03 0.20462856E-03 0.19528747E-03 0.18622838E-03 0.17744834E-03
+ 0.16894426E-03 0.16071296E-03 0.15275111E-03 0.14505525E-03 0.13762181E-03
+ 0.13044709E-03 0.12352726E-03 0.11685839E-03 0.11043642E-03 0.10425717E-03
+ 0.98316362E-04 0.92609607E-04 0.87132410E-04 0.81880180E-04 0.76848230E-04
+ 0.72031786E-04 0.67425991E-04 0.63025911E-04 0.58826538E-04 0.54822803E-04
+ 0.51009579E-04 0.47381685E-04 0.43933900E-04 0.40660966E-04 0.37557597E-04
+ 0.34618485E-04 0.31838314E-04 0.29211760E-04 0.26733505E-04 0.24398243E-04
+ 0.22200690E-04 0.20135590E-04 0.18197725E-04 0.16381922E-04 0.14683062E-04
+ 0.13096087E-04 0.11616008E-04 0.10237913E-04 0.89569732E-05 0.77684493E-05
+ 0.66676997E-05 0.56501858E-05 0.47114772E-05 0.38472578E-05 0.30533303E-05
+ 0.23256206E-05 0.16601819E-05 0.10531979E-05 0.50098619E-06 0.00000000E+00
+ 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05
+ 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05
+ 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05
+ 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05
+ 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05
+ 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05
+ 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05
+ 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05
+ 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05 0.50528773E+05
+ 0.50409310E+05 0.47756885E+05 0.45296626E+05 0.43010952E+05 0.40884215E+05
+ 0.38902450E+05 0.37053162E+05 0.35325154E+05 0.33708362E+05 0.32193728E+05
+ 0.30773080E+05 0.29439033E+05 0.28184899E+05 0.27004612E+05 0.25892661E+05
+ 0.24844029E+05 0.23854144E+05 0.22918830E+05 0.22034271E+05 0.21196970E+05
+ 0.20403722E+05 0.19651584E+05 0.18937850E+05 0.18260029E+05 0.17615825E+05
+ 0.17003119E+05 0.16419954E+05 0.15864517E+05 0.15335134E+05 0.14830248E+05
+ 0.14348419E+05 0.13888307E+05 0.13448665E+05 0.13028335E+05 0.12626237E+05
+ 0.12241364E+05 0.11872777E+05 0.11519597E+05 0.11181004E+05 0.10856231E+05
+ 0.10544560E+05 0.10245315E+05 0.99578671E+04 0.96816222E+04 0.94160240E+04
+ 0.91605492E+04 0.89147058E+04 0.86780308E+04 0.84500880E+04 0.82304665E+04
+ 0.80187787E+04 0.78146589E+04 0.76177620E+04 0.74277616E+04 0.72443495E+04
+ 0.70672342E+04 0.68961395E+04 0.67308043E+04 0.65709810E+04 0.64164348E+04
+ 0.62669434E+04 0.61222956E+04 0.59822908E+04 0.58467387E+04 0.57154585E+04
+ 0.55882780E+04 0.54650336E+04 0.53455698E+04 0.52297383E+04 0.51173980E+04
+ 0.50084143E+04 0.49026590E+04 0.48000100E+04 0.47003504E+04 0.46035691E+04
+ 0.45095597E+04 0.44182208E+04 0.43294552E+04 0.42431702E+04 0.41592773E+04
+ 0.40776916E+04 0.39983318E+04 0.39211204E+04 0.38459828E+04 0.37728479E+04
+ 0.37016473E+04 0.36323156E+04 0.35647899E+04 0.34990101E+04 0.34349184E+04
+ 0.33724594E+04 0.33115797E+04 0.32522284E+04 0.31943562E+04 0.31379160E+04
+ 0.30828624E+04 0.30291517E+04 0.29767422E+04 0.29255932E+04 0.28756662E+04
+ 0.28269236E+04 0.27793294E+04 0.27328491E+04 0.26874492E+04 0.26430976E+04
+ 0.25997632E+04 0.25574162E+04 0.25160277E+04 0.24755699E+04 0.24360161E+04
+ 0.23973403E+04 0.23595175E+04 0.23225238E+04 0.22863356E+04 0.22509307E+04
+ 0.22162872E+04 0.21823842E+04 0.21492014E+04 0.21167191E+04 0.20849185E+04
+ 0.20537811E+04 0.20232893E+04 0.19934259E+04 0.19641742E+04 0.19355182E+04
+ 0.19074424E+04 0.18799317E+04 0.18529715E+04 0.18265476E+04 0.18006465E+04
+ 0.17752548E+04 0.17503597E+04 0.17259487E+04 0.17020097E+04 0.16785311E+04
+ 0.16555015E+04 0.16329099E+04 0.16107455E+04 0.15889981E+04 0.15676575E+04
+ 0.15467140E+04 0.15261581E+04 0.15059806E+04 0.14861726E+04 0.14667254E+04
+ 0.14476305E+04 0.14288798E+04 0.14104653E+04 0.13923793E+04 0.13746142E+04
+ 0.13571628E+04 0.13400178E+04 0.13231725E+04 0.13066201E+04 0.12903541E+04
+ 0.12743680E+04 0.12586558E+04 0.12432113E+04 0.12280288E+04 0.12131025E+04
+ 0.11984269E+04 0.11839966E+04 0.11698062E+04 0.11558508E+04 0.11421252E+04
+ 0.11286247E+04 0.11153445E+04 0.11022799E+04 0.10894265E+04 0.10767799E+04
+ 0.10643358E+04 0.10520901E+04 0.10400386E+04 0.10281775E+04 0.10165029E+04
+ 0.10050110E+04 0.99369808E+03 0.98256064E+03 0.97159515E+03 0.96079820E+03
+ 0.95016647E+03 0.93969671E+03 0.92938574E+03 0.91923048E+03 0.90922790E+03
+ 0.89937505E+03 0.88966906E+03 0.88010710E+03 0.87068644E+03 0.86140439E+03
+ 0.85225833E+03 0.84324570E+03 0.83436399E+03 0.82561077E+03 0.81698364E+03
+ 0.80848027E+03 0.80009838E+03 0.79183574E+03 0.78369016E+03 0.77565952E+03
+ 0.76774173E+03 0.75993475E+03 0.75223659E+03 0.74464530E+03 0.73715896E+03
+ 0.72977573E+03 0.72249376E+03 0.71531128E+03 0.70822653E+03 0.70123782E+03
+ 0.69434345E+03 0.68754180E+03 0.68083127E+03 0.67421027E+03 0.66767729E+03
+ 0.66123080E+03 0.65486935E+03 0.64859149E+03 0.64239579E+03 0.63628090E+03
+ 0.63024543E+03 0.62428808E+03 0.61840754E+03 0.61260253E+03 0.60687182E+03
+ 0.60121416E+03 0.59562838E+03 0.59011329E+03 0.58466774E+03 0.57929061E+03
+ 0.57398078E+03 0.56873718E+03 0.56355874E+03 0.55844443E+03 0.55339321E+03
+ 0.54840409E+03 0.54347609E+03 0.53860824E+03 0.53379960E+03 0.52904924E+03
+ 0.52435625E+03 0.51971975E+03 0.51513885E+03 0.51061271E+03 0.50614047E+03
+ 0.50172131E+03 0.49735442E+03 0.49303900E+03 0.48877428E+03 0.48455949E+03
+ 0.48039388E+03 0.47627670E+03 0.47220724E+03 0.46818477E+03 0.46420861E+03
+ 0.46027807E+03 0.45639247E+03 0.45255115E+03 0.44875347E+03 0.44499878E+03
+ 0.44128646E+03 0.43761589E+03 0.43398647E+03 0.43039761E+03 0.42684872E+03
+ 0.42333923E+03 0.41986857E+03 0.41643620E+03 0.41304157E+03 0.40968414E+03
+ 0.40636340E+03 0.40307882E+03 0.39982990E+03 0.39661613E+03 0.39343704E+03
+ 0.39029214E+03 0.38718095E+03 0.38410302E+03 0.38105787E+03 0.37804507E+03
+ 0.37506417E+03 0.37211474E+03 0.36919635E+03 0.36630857E+03 0.36345100E+03
+ 0.36062323E+03 0.35782485E+03 0.35505549E+03 0.35231474E+03 0.34960222E+03
+ 0.34691757E+03 0.34426042E+03 0.34163039E+03 0.33902715E+03 0.33645032E+03
+ 0.33389958E+03 0.33137458E+03 0.32887498E+03 0.32640046E+03 0.32395069E+03
+ 0.32152535E+03 0.31912414E+03 0.31674673E+03 0.31439284E+03 0.31206215E+03
+ 0.30975437E+03 0.30746922E+03 0.30520641E+03 0.30296566E+03 0.30074669E+03
+ 0.29854922E+03 0.29637300E+03 0.29421775E+03 0.29208321E+03 0.28996914E+03
+ 0.28787527E+03 0.28580136E+03 0.28374717E+03 0.28171244E+03 0.27969695E+03
+ 0.27770047E+03 0.27572275E+03 0.27376357E+03 0.27182272E+03 0.26989996E+03
+ 0.26799509E+03 0.26610788E+03 0.26423813E+03 0.26238563E+03 0.26055018E+03
+ 0.25873156E+03 0.25692960E+03 0.25514407E+03 0.25337481E+03 0.25162161E+03
+ 0.24988428E+03 0.24816265E+03 0.24645652E+03 0.24476573E+03 0.24309009E+03
+ 0.24142942E+03 0.23978356E+03 0.23815234E+03 0.23653558E+03 0.23493313E+03
+ 0.23334482E+03 0.23177049E+03 0.23020998E+03 0.22866314E+03 0.22712981E+03
+ 0.22560984E+03 0.22410307E+03 0.22260938E+03 0.22112860E+03 0.21966059E+03
+ 0.21820521E+03 0.21676233E+03 0.21533180E+03 0.21391349E+03 0.21250726E+03
+ 0.21111298E+03 0.20973053E+03 0.20835977E+03 0.20700057E+03 0.20565281E+03
+ 0.20431637E+03 0.20299112E+03 0.20167695E+03 0.20037373E+03 0.19908135E+03
+ 0.19779969E+03 0.19652864E+03 0.19526808E+03 0.19401790E+03 0.19277800E+03
+ 0.19154826E+03 0.19032858E+03 0.18911885E+03 0.18791897E+03 0.18672883E+03
+ 0.18554834E+03 0.18437739E+03 0.18321588E+03 0.18206372E+03 0.18092081E+03
+ 0.17978706E+03 0.17866236E+03 0.17754663E+03 0.17643977E+03 0.17534170E+03
+ 0.17425233E+03 0.17317156E+03 0.17209931E+03 0.17103550E+03 0.16998003E+03
+ 0.16893283E+03 0.16789380E+03 0.16686288E+03 0.16583998E+03 0.16482501E+03
+ 0.16381790E+03 0.16281858E+03 0.16182696E+03 0.16084296E+03 0.15986652E+03
+ 0.15889756E+03 0.15793600E+03 0.15698178E+03 0.15603481E+03 0.15509504E+03
+ 0.15416238E+03 0.15323678E+03 0.15231816E+03 0.15140645E+03 0.15050159E+03
+ 0.14960352E+03 0.14871216E+03 0.14782746E+03 0.14694934E+03 0.14607776E+03
+ 0.14521263E+03 0.14435391E+03 0.14350153E+03 0.14265544E+03 0.14181557E+03
+ 0.14098186E+03 0.14015426E+03 0.13933271E+03 0.13851715E+03 0.13770753E+03
+ 0.13690379E+03 0.13610588E+03 0.13531374E+03 0.13452732E+03 0.13374657E+03
+ 0.13297144E+03 0.13220186E+03 0.13143780E+03 0.13067920E+03 0.12992602E+03
+ 0.12917819E+03 0.12843568E+03 0.12769844E+03 0.12696641E+03 0.12623955E+03
+ 0.12551782E+03 0.12480117E+03 0.12408954E+03 0.12338291E+03 0.12268122E+03
+ 0.12198443E+03 0.12129249E+03 0.12060536E+03 0.11992300E+03 0.11924538E+03
+ 0.11857243E+03 0.11790413E+03 0.11724043E+03 0.11658130E+03 0.11592669E+03
+ 0.11527656E+03 0.11463088E+03 0.11398960E+03 0.11335269E+03 0.11272010E+03
+ 0.11209181E+03 0.11146778E+03 0.11084796E+03 0.11023233E+03 0.10962084E+03
+ 0.10901346E+03 0.10841016E+03 0.10781090E+03 0.10721564E+03 0.10662436E+03
+ 0.10603701E+03 0.10545357E+03 0.10487400E+03 0.10429828E+03 0.10372636E+03
+ 0.10315821E+03 0.10259381E+03 0.10203312E+03 0.10147611E+03 0.10092276E+03
+ 0.10037302E+03 0.99826872E+02 0.99284287E+02 0.98745233E+02 0.98209681E+02
+ 0.97677602E+02 0.97148968E+02 0.96623751E+02 0.96101922E+02 0.95583454E+02
+ 0.95068320E+02 0.94556492E+02 0.94047943E+02 0.93542648E+02 0.93040579E+02
+ 0.92541710E+02 0.92046017E+02 0.91553473E+02 0.91064052E+02 0.90577731E+02
+ 0.90094484E+02 0.89614287E+02 0.89137115E+02 0.88662944E+02 0.88191751E+02
+ 0.87723511E+02 0.87258203E+02 0.86795801E+02 0.86336285E+02 0.85879630E+02
+ 0.85425814E+02 0.84974816E+02 0.84526612E+02 0.84081183E+02 0.83638504E+02
+ 0.83198557E+02 0.82761318E+02 0.82326767E+02 0.81894884E+02 0.81465648E+02
+ 0.81039038E+02 0.80615035E+02 0.80193618E+02 0.79774767E+02 0.79358463E+02
+ 0.78944686E+02 0.78533418E+02 0.78124638E+02 0.77718329E+02 0.77314471E+02
+ 0.76913047E+02 0.76514036E+02 0.76117422E+02 0.75723187E+02 0.75331312E+02
+ 0.74941780E+02 0.74554573E+02 0.74169674E+02 0.73787066E+02 0.73406732E+02
+ 0.73028654E+02 0.72652816E+02 0.72279202E+02 0.71907796E+02 0.71538579E+02
+ 0.71171538E+02 0.70806655E+02 0.70443916E+02 0.70083303E+02 0.69724802E+02
+ 0.69368398E+02 0.69014074E+02 0.68661816E+02 0.68311610E+02 0.67963439E+02
+ 0.67617289E+02 0.67273147E+02 0.66930996E+02 0.66590824E+02 0.66252615E+02
+ 0.65916356E+02 0.65582032E+02 0.65249631E+02 0.64919138E+02 0.64590539E+02
+ 0.64263822E+02 0.63938972E+02 0.63615977E+02 0.63294823E+02 0.62975498E+02
+ 0.62657989E+02 0.62342282E+02 0.62028365E+02 0.61716227E+02 0.61405853E+02
+ 0.61097232E+02 0.60790352E+02 0.60485201E+02 0.60181766E+02 0.59880036E+02
+ 0.59579998E+02 0.59281642E+02 0.58984955E+02 0.58689926E+02 0.58396544E+02
+ 0.58104797E+02 0.57814675E+02 0.57526165E+02 0.57239258E+02 0.56953941E+02
+ 0.56670205E+02 0.56388038E+02 0.56107430E+02 0.55828370E+02 0.55550848E+02
+ 0.55274854E+02 0.55000377E+02 0.54727406E+02 0.54455933E+02 0.54185946E+02
+ 0.53917436E+02 0.53650393E+02 0.53384807E+02 0.53120669E+02 0.52857968E+02
+ 0.52596696E+02 0.52336843E+02 0.52078399E+02 0.51821355E+02 0.51565702E+02
+ 0.51311430E+02 0.51058532E+02 0.50806997E+02 0.50556816E+02 0.50307982E+02
+ 0.50060484E+02 0.49814315E+02 0.49569465E+02 0.49325927E+02 0.49083691E+02
+ 0.48842749E+02 0.48603093E+02 0.48364714E+02 0.48127605E+02 0.47891756E+02
+ 0.47657161E+02 0.47423810E+02 0.47191697E+02 0.46960812E+02 0.46731148E+02
+ 0.46502698E+02 0.46275454E+02 0.46049407E+02 0.45824551E+02 0.45600877E+02
+ 0.45378379E+02 0.45157049E+02 0.44936880E+02 0.44717863E+02 0.44499993E+02
+ 0.44283261E+02 0.44067661E+02 0.43853186E+02 0.43639828E+02 0.43427581E+02
+ 0.43216438E+02 0.43006391E+02 0.42797434E+02 0.42589560E+02 0.42382763E+02
+ 0.42177036E+02 0.41972372E+02 0.41768765E+02 0.41566208E+02 0.41364695E+02
+ 0.41164219E+02 0.40964774E+02 0.40766353E+02 0.40568952E+02 0.40372562E+02
+ 0.40177179E+02 0.39982795E+02 0.39789405E+02 0.39597003E+02 0.39405584E+02
+ 0.39215140E+02 0.39025666E+02 0.38837156E+02 0.38649605E+02 0.38463006E+02
+ 0.38277354E+02 0.38092644E+02 0.37908869E+02 0.37726024E+02 0.37544104E+02
+ 0.37363103E+02 0.37183016E+02 0.37003836E+02 0.36825560E+02 0.36648180E+02
+ 0.36471693E+02 0.36296093E+02 0.36121374E+02 0.35947532E+02 0.35774561E+02
+ 0.35602456E+02 0.35431212E+02 0.35260825E+02 0.35091288E+02 0.34922598E+02
+ 0.34754749E+02 0.34587736E+02 0.34421554E+02 0.34256199E+02 0.34091666E+02
+ 0.33927950E+02 0.33765047E+02 0.33602951E+02 0.33441658E+02 0.33281163E+02
+ 0.33121463E+02 0.32962551E+02 0.32804425E+02 0.32647078E+02 0.32490508E+02
+ 0.32334709E+02 0.32179676E+02 0.32025407E+02 0.31871896E+02 0.31719139E+02
+ 0.31567131E+02 0.31415869E+02 0.31265349E+02 0.31115565E+02 0.30966515E+02
+ 0.30818193E+02 0.30670596E+02 0.30523720E+02 0.30377561E+02 0.30232114E+02
+ 0.30087376E+02 0.29943343E+02 0.29800010E+02 0.29657375E+02 0.29515432E+02
+ 0.29374179E+02 0.29233611E+02 0.29093724E+02 0.28954516E+02 0.28815981E+02
+ 0.28678117E+02 0.28540920E+02 0.28404386E+02 0.28268511E+02 0.28133292E+02
+ 0.27998725E+02 0.27864806E+02 0.27731533E+02 0.27598902E+02 0.27466908E+02
+ 0.27335549E+02 0.27204821E+02 0.27074721E+02 0.26945246E+02 0.26816391E+02
+ 0.26688154E+02 0.26560531E+02 0.26433520E+02 0.26307116E+02 0.26181316E+02
+ 0.26056118E+02 0.25931517E+02 0.25807512E+02 0.25684098E+02 0.25561272E+02
+ 0.25439032E+02 0.25317373E+02 0.25196294E+02 0.25075791E+02 0.24955861E+02
+ 0.24836501E+02 0.24717708E+02 0.24599479E+02 0.24481810E+02 0.24364700E+02
+ 0.24248145E+02 0.24132141E+02 0.24016687E+02 0.23901780E+02 0.23787415E+02
+ 0.23673592E+02 0.23560306E+02 0.23447555E+02 0.23335337E+02 0.23223648E+02
+ 0.23112485E+02 0.23001847E+02 0.22891730E+02 0.22782131E+02 0.22673048E+02
+ 0.22564479E+02 0.22456420E+02 0.22348869E+02 0.22241823E+02 0.22135280E+02
+ 0.22029237E+02 0.21923691E+02 0.21818641E+02 0.21714082E+02 0.21610014E+02
+ 0.21506434E+02 0.21403338E+02 0.21300724E+02 0.21198591E+02 0.21096935E+02
+ 0.20995755E+02 0.20895047E+02 0.20794810E+02 0.20695040E+02 0.20595736E+02
+ 0.20496895E+02 0.20398516E+02 0.20300594E+02 0.20203130E+02 0.20106119E+02
+ 0.20009559E+02 0.19913450E+02 0.19817787E+02 0.19722569E+02 0.19627794E+02
+ 0.19533460E+02 0.19439564E+02 0.19346104E+02 0.19253078E+02 0.19160483E+02
+ 0.19068319E+02 0.18976581E+02 0.18885270E+02 0.18794381E+02 0.18703914E+02
+ 0.18613866E+02 0.18524235E+02 0.18435019E+02 0.18346216E+02 0.18257823E+02
+ 0.18169840E+02 0.18082264E+02 0.17995092E+02 0.17908323E+02 0.17821956E+02
+ 0.17735987E+02 0.17650415E+02 0.17565238E+02 0.17480455E+02 0.17396063E+02
+ 0.17312060E+02 0.17228444E+02 0.17145214E+02 0.17062368E+02 0.16979904E+02
+ 0.16897819E+02 0.16816113E+02 0.16734783E+02 0.16653828E+02 0.16573245E+02
+ 0.16493033E+02 0.16413190E+02 0.16333715E+02 0.16254605E+02 0.16175859E+02
+ 0.16097475E+02 0.16019451E+02 0.15941786E+02 0.15864478E+02 0.15787526E+02
+ 0.15710926E+02 0.15634679E+02 0.15558781E+02 0.15483232E+02 0.15408030E+02
+ 0.15333173E+02 0.15258660E+02 0.15184488E+02 0.15110657E+02 0.15037164E+02
+ 0.14964009E+02 0.14891189E+02 0.14818702E+02 0.14746549E+02 0.14674725E+02
+ 0.14603231E+02 0.14532065E+02 0.14461225E+02 0.14390709E+02 0.14320517E+02
+ 0.14250646E+02 0.14181095E+02 0.14111862E+02 0.14042947E+02 0.13974347E+02
+ 0.13906061E+02 0.13838088E+02 0.13770426E+02 0.13703073E+02 0.13636029E+02
+ 0.13569292E+02 0.13502860E+02 0.13436732E+02 0.13370907E+02 0.13305383E+02
+ 0.13240159E+02 0.13175233E+02 0.13110604E+02 0.13046270E+02 0.12982231E+02
+ 0.12918485E+02 0.12855031E+02 0.12791867E+02 0.12728991E+02 0.12666403E+02
+ 0.12604102E+02 0.12542085E+02 0.12480352E+02 0.12418901E+02 0.12357732E+02
+ 0.12296842E+02 0.12236230E+02 0.12175896E+02 0.12115837E+02 0.12056053E+02
+ 0.11996543E+02 0.11937305E+02 0.11878337E+02 0.11819640E+02 0.11761211E+02
+ 0.11703049E+02 0.11645153E+02 0.11587521E+02 0.11530154E+02 0.11473049E+02
+ 0.11416205E+02 0.11359621E+02 0.11303296E+02 0.11247229E+02 0.11191418E+02
+ 0.11135862E+02 0.11080561E+02 0.11025513E+02 0.10970717E+02 0.10916171E+02
+ 0.10861875E+02 0.10807828E+02 0.10754028E+02 0.10700475E+02 0.10647166E+02
+ 0.10594102E+02 0.10541281E+02 0.10488702E+02 0.10436363E+02 0.10384264E+02
+ 0.10332404E+02 0.10280782E+02 0.10229396E+02 0.10178245E+02 0.10127329E+02
+ 0.10076647E+02 0.10026197E+02 0.99759777E+01 0.99259890E+01 0.98762296E+01
+ 0.98266984E+01 0.97773945E+01 0.97283167E+01 0.96794642E+01 0.96308358E+01
+ 0.95824307E+01 0.95342477E+01 0.94862860E+01 0.94385446E+01 0.93910224E+01
+ 0.93437185E+01 0.92966320E+01 0.92497618E+01 0.92031071E+01 0.91566668E+01
+ 0.91104400E+01 0.90644258E+01 0.90186232E+01 0.89730313E+01 0.89276492E+01
+ 0.88824760E+01 0.88375106E+01 0.87927523E+01 0.87482001E+01 0.87038530E+01
+ 0.86597103E+01 0.86157709E+01 0.85720340E+01 0.85284987E+01 0.84851642E+01
+ 0.84420295E+01 0.83990937E+01 0.83563560E+01 0.83138156E+01 0.82714715E+01
+ 0.82293229E+01 0.81873689E+01 0.81456087E+01 0.81040414E+01 0.80626663E+01
+ 0.80214823E+01 0.79804888E+01 0.79396849E+01 0.78990698E+01 0.78586425E+01
+ 0.78184024E+01 0.77783485E+01 0.77384802E+01 0.76987965E+01 0.76592966E+01
+ 0.76199799E+01 0.75808454E+01 0.75418923E+01 0.75031199E+01 0.74645275E+01
+ 0.74261141E+01 0.73878791E+01 0.73498216E+01 0.73119409E+01 0.72742362E+01
+ 0.72367067E+01 0.71993518E+01 0.71621705E+01 0.71251623E+01 0.70883262E+01
+ 0.70516616E+01 0.70151678E+01 0.69788439E+01 0.69426893E+01 0.69067032E+01
+ 0.68708849E+01 0.68352336E+01 0.67997487E+01 0.67644294E+01 0.67292749E+01
+ 0.66942847E+01 0.66594579E+01 0.66247938E+01 0.65902919E+01 0.65559512E+01
+ 0.65217713E+01 0.64877513E+01 0.64538905E+01 0.64201883E+01 0.63866441E+01
+ 0.63532570E+01 0.63200264E+01 0.62869517E+01 0.62540322E+01 0.62212672E+01
+ 0.61886560E+01 0.61561980E+01 0.61238925E+01 0.60917389E+01 0.60597365E+01
+ 0.60278846E+01 0.59961826E+01 0.59646298E+01 0.59332256E+01 0.59019694E+01
+ 0.58708605E+01 0.58398983E+01 0.58090822E+01 0.57784115E+01 0.57478855E+01
+ 0.57175038E+01 0.56872655E+01 0.56571702E+01 0.56272172E+01 0.55974059E+01
+ 0.55677357E+01 0.55382060E+01 0.55088161E+01 0.54795655E+01 0.54504536E+01
+ 0.54214797E+01 0.53926433E+01 0.53639438E+01 0.53353805E+01 0.53069530E+01
+ 0.52786605E+01 0.52505026E+01 0.52224787E+01 0.51945881E+01 0.51668303E+01
+ 0.51392048E+01 0.51117109E+01 0.50843481E+01 0.50571158E+01 0.50300134E+01
+ 0.50030405E+01 0.49761964E+01 0.49494805E+01 0.49228924E+01 0.48964315E+01
+ 0.48700972E+01 0.48438890E+01 0.48178063E+01 0.47918486E+01 0.47660154E+01
+ 0.47403061E+01 0.47147202E+01 0.46892571E+01 0.46639163E+01 0.46386974E+01
+ 0.46135997E+01 0.45886227E+01 0.45637660E+01 0.45390289E+01 0.45144111E+01
+ 0.44899119E+01 0.44655308E+01 0.44412674E+01 0.44171212E+01 0.43930916E+01
+ 0.43691781E+01 0.43453802E+01 0.43216974E+01 0.42981293E+01 0.42746753E+01
+ 0.42513349E+01 0.42281077E+01 0.42049931E+01 0.41819907E+01 0.41591000E+01
+ 0.41363205E+01 0.41136516E+01 0.40910930E+01 0.40686442E+01 0.40463047E+01
+ 0.40240739E+01 0.40019515E+01 0.39799370E+01 0.39580298E+01 0.39362296E+01
+ 0.39145359E+01 0.38929481E+01 0.38714659E+01 0.38500888E+01 0.38288163E+01
+ 0.38076480E+01 0.37865835E+01 0.37656221E+01 0.37447636E+01 0.37240075E+01
+ 0.37033534E+01 0.36828007E+01 0.36623490E+01 0.36419980E+01 0.36217471E+01
+ 0.36015959E+01 0.35815441E+01 0.35615911E+01 0.35417365E+01 0.35219800E+01
+ 0.35023210E+01 0.34827592E+01 0.34632941E+01 0.34439252E+01 0.34246523E+01
+ 0.34054749E+01 0.33863925E+01 0.33674047E+01 0.33485111E+01 0.33297114E+01
+ 0.33110050E+01 0.32923917E+01 0.32738709E+01 0.32554423E+01 0.32371054E+01
+ 0.32188599E+01 0.32007054E+01 0.31826415E+01 0.31646677E+01 0.31467837E+01
+ 0.31289891E+01 0.31112835E+01 0.30936664E+01 0.30761376E+01 0.30586966E+01
+ 0.30413431E+01 0.30240765E+01 0.30068967E+01 0.29898031E+01 0.29727955E+01
+ 0.29558733E+01 0.29390363E+01 0.29222841E+01 0.29056163E+01 0.28890325E+01
+ 0.28725324E+01 0.28561156E+01 0.28397816E+01 0.28235303E+01 0.28073611E+01
+ 0.27912737E+01 0.27752678E+01 0.27593430E+01 0.27434990E+01 0.27277353E+01
+ 0.27120517E+01 0.26964477E+01 0.26809230E+01 0.26654773E+01 0.26501102E+01
+ 0.26348214E+01 0.26196105E+01 0.26044772E+01 0.25894211E+01 0.25744419E+01
+ 0.25595392E+01 0.25447128E+01 0.25299621E+01 0.25152871E+01 0.25006871E+01
+ 0.24861621E+01 0.24717115E+01 0.24573352E+01 0.24430326E+01 0.24288036E+01
+ 0.24146478E+01 0.24005649E+01 0.23865545E+01 0.23726162E+01 0.23587499E+01
+ 0.23449552E+01 0.23312317E+01 0.23175791E+01 0.23039971E+01 0.22904854E+01
+ 0.22770436E+01 0.22636716E+01 0.22503688E+01 0.22371351E+01 0.22239701E+01
+ 0.22108736E+01 0.21978451E+01 0.21848844E+01 0.21719912E+01 0.21591652E+01
+ 0.21464060E+01 0.21337134E+01 0.21210871E+01 0.21085268E+01 0.20960322E+01
+ 0.20836029E+01 0.20712387E+01 0.20589393E+01 0.20467043E+01 0.20345336E+01
+ 0.20224267E+01 0.20103835E+01 0.19984036E+01 0.19864868E+01 0.19746326E+01
+ 0.19628410E+01 0.19511115E+01 0.19394439E+01 0.19278379E+01 0.19162933E+01
+ 0.19048097E+01 0.18933868E+01 0.18820245E+01 0.18707223E+01 0.18594801E+01
+ 0.18482976E+01 0.18371744E+01 0.18261104E+01 0.18151052E+01 0.18041585E+01
+ 0.17932702E+01 0.17824399E+01 0.17716673E+01 0.17609523E+01 0.17502945E+01
+ 0.17396936E+01 0.17291495E+01 0.17186618E+01 0.17082303E+01 0.16978547E+01
+ 0.16875348E+01 0.16772703E+01 0.16670609E+01 0.16569064E+01 0.16468065E+01
+ 0.16367611E+01 0.16267697E+01 0.16168323E+01 0.16069484E+01 0.15971180E+01
+ 0.15873406E+01 0.15776162E+01 0.15679444E+01 0.15583249E+01 0.15487576E+01
+ 0.15392422E+01 0.15297785E+01 0.15203662E+01 0.15110050E+01 0.15016948E+01
+ 0.14924353E+01 0.14832262E+01 0.14740673E+01 0.14649584E+01 0.14558993E+01
+ 0.14468896E+01 0.14379293E+01 0.14290180E+01 0.14201555E+01 0.14113416E+01
+ 0.14025760E+01 0.13938585E+01 0.13851890E+01 0.13765671E+01 0.13679927E+01
+ 0.13594654E+01 0.13509852E+01 0.13425518E+01 0.13341648E+01 0.13258242E+01
+ 0.13175298E+01 0.13092812E+01 0.13010782E+01 0.12929207E+01 0.12848085E+01
+ 0.12767412E+01 0.12687188E+01 0.12607409E+01 0.12528074E+01 0.12449181E+01
+ 0.12370727E+01 0.12292710E+01 0.12215129E+01 0.12137981E+01 0.12061264E+01
+ 0.11984976E+01 0.11909115E+01 0.11833678E+01 0.11758665E+01 0.11684072E+01
+ 0.11609898E+01 0.11536141E+01 0.11462798E+01 0.11389868E+01 0.11317349E+01
+ 0.11245238E+01 0.11173534E+01 0.11102235E+01 0.11031339E+01 0.10960843E+01
+ 0.10890746E+01 0.10821046E+01 0.10751741E+01 0.10682829E+01 0.10614308E+01
+ 0.10546176E+01 0.10478432E+01 0.10411073E+01 0.10344097E+01 0.10277503E+01
+ 0.10211289E+01 0.10145452E+01 0.10079992E+01 0.10014906E+01 0.99501919E+00
+ 0.98858484E+00 0.98218735E+00 0.97582655E+00 0.96950225E+00 0.96321427E+00
+ 0.95696242E+00 0.95074654E+00 0.94456644E+00 0.93842195E+00 0.93231288E+00
+ 0.92623907E+00 0.92020033E+00 0.91419649E+00 0.90822738E+00 0.90229282E+00
+ 0.89639265E+00 0.89052668E+00 0.88469475E+00 0.87889669E+00 0.87313233E+00
+ 0.86740150E+00 0.86170403E+00 0.85603975E+00 0.85040850E+00 0.84481011E+00
+ 0.83924441E+00 0.83371124E+00 0.82821044E+00 0.82274184E+00 0.81730529E+00
+ 0.81190060E+00 0.80652764E+00 0.80118623E+00 0.79587621E+00 0.79059744E+00
+ 0.78534973E+00 0.78013295E+00 0.77494693E+00 0.76979152E+00 0.76466655E+00
+ 0.75957188E+00 0.75450735E+00 0.74947281E+00 0.74446809E+00 0.73949306E+00
+ 0.73454755E+00 0.72963142E+00 0.72474451E+00 0.71988667E+00 0.71505777E+00
+ 0.71025764E+00 0.70548613E+00 0.70074311E+00 0.69602842E+00 0.69134192E+00
+ 0.68668345E+00 0.68205289E+00 0.67745008E+00 0.67287487E+00 0.66832713E+00
+ 0.66380671E+00 0.65931347E+00 0.65484727E+00 0.65040797E+00 0.64599543E+00
+ 0.64160950E+00 0.63725005E+00 0.63291695E+00 0.62861004E+00 0.62432921E+00
+ 0.62007430E+00 0.61584518E+00 0.61164172E+00 0.60746379E+00 0.60331124E+00
+ 0.59918395E+00 0.59508178E+00 0.59100460E+00 0.58695228E+00 0.58292469E+00
+ 0.57892169E+00 0.57494315E+00 0.57098895E+00 0.56705896E+00 0.56315304E+00
+ 0.55927108E+00 0.55541294E+00 0.55157849E+00 0.54776761E+00 0.54398018E+00
+ 0.54021607E+00 0.53647515E+00 0.53275730E+00 0.52906240E+00 0.52539032E+00
+ 0.52174094E+00 0.51811414E+00 0.51450980E+00 0.51092780E+00 0.50736802E+00
+ 0.50383033E+00 0.50031462E+00 0.49682077E+00 0.49334866E+00 0.48989817E+00
+ 0.48646919E+00 0.48306161E+00 0.47967529E+00 0.47631014E+00 0.47296602E+00
+ 0.46964284E+00 0.46634047E+00 0.46305880E+00 0.45979772E+00 0.45655712E+00
+ 0.45333688E+00 0.45013690E+00 0.44695705E+00 0.44379724E+00 0.44065735E+00
+ 0.43753727E+00 0.43443689E+00 0.43135611E+00 0.42829482E+00 0.42525290E+00
+ 0.42223025E+00 0.41922677E+00 0.41624235E+00 0.41327689E+00 0.41033027E+00
+ 0.40740239E+00 0.40449316E+00 0.40160246E+00 0.39873020E+00 0.39587626E+00
+ 0.39304056E+00 0.39022298E+00 0.38742343E+00 0.38464180E+00 0.38187799E+00
+ 0.37913191E+00 0.37640345E+00 0.37369252E+00 0.37099901E+00 0.36832283E+00
+ 0.36566389E+00 0.36302208E+00 0.36039730E+00 0.35778947E+00 0.35519848E+00
+ 0.35262424E+00 0.35006666E+00 0.34752563E+00 0.34500107E+00 0.34249289E+00
+ 0.34000098E+00 0.33752526E+00 0.33506563E+00 0.33262200E+00 0.33019429E+00
+ 0.32778239E+00 0.32538623E+00 0.32300570E+00 0.32064072E+00 0.31829120E+00
+ 0.31595704E+00 0.31363818E+00 0.31133450E+00 0.30904593E+00 0.30677238E+00
+ 0.30451376E+00 0.30226998E+00 0.30004096E+00 0.29782662E+00 0.29562686E+00
+ 0.29344161E+00 0.29127077E+00 0.28911427E+00 0.28697202E+00 0.28484394E+00
+ 0.28272994E+00 0.28062994E+00 0.27854387E+00 0.27647163E+00 0.27441314E+00
+ 0.27236834E+00 0.27033712E+00 0.26831943E+00 0.26631516E+00 0.26432425E+00
+ 0.26234662E+00 0.26038219E+00 0.25843087E+00 0.25649260E+00 0.25456729E+00
+ 0.25265487E+00 0.25075525E+00 0.24886837E+00 0.24699415E+00 0.24513251E+00
+ 0.24328337E+00 0.24144667E+00 0.23962232E+00 0.23781025E+00 0.23601039E+00
+ 0.23422267E+00 0.23244700E+00 0.23068333E+00 0.22893157E+00 0.22719165E+00
+ 0.22546350E+00 0.22374706E+00 0.22204224E+00 0.22034898E+00 0.21866721E+00
+ 0.21699686E+00 0.21533785E+00 0.21369012E+00 0.21205360E+00 0.21042823E+00
+ 0.20881392E+00 0.20721061E+00 0.20561825E+00 0.20403675E+00 0.20246605E+00
+ 0.20090608E+00 0.19935679E+00 0.19781809E+00 0.19628993E+00 0.19477224E+00
+ 0.19326495E+00 0.19176801E+00 0.19028134E+00 0.18880488E+00 0.18733857E+00
+ 0.18588234E+00 0.18443613E+00 0.18299988E+00 0.18157352E+00 0.18015700E+00
+ 0.17875024E+00 0.17735319E+00 0.17596579E+00 0.17458797E+00 0.17321968E+00
+ 0.17186085E+00 0.17051142E+00 0.16917134E+00 0.16784054E+00 0.16651896E+00
+ 0.16520655E+00 0.16390324E+00 0.16260898E+00 0.16132371E+00 0.16004737E+00
+ 0.15877991E+00 0.15752125E+00 0.15627136E+00 0.15503017E+00 0.15379762E+00
+ 0.15257366E+00 0.15135824E+00 0.15015129E+00 0.14895276E+00 0.14776259E+00
+ 0.14658074E+00 0.14540714E+00 0.14424175E+00 0.14308450E+00 0.14193534E+00
+ 0.14079423E+00 0.13966110E+00 0.13853590E+00 0.13741859E+00 0.13630910E+00
+ 0.13520739E+00 0.13411340E+00 0.13302708E+00 0.13194838E+00 0.13087725E+00
+ 0.12981363E+00 0.12875749E+00 0.12770876E+00 0.12666739E+00 0.12563334E+00
+ 0.12460655E+00 0.12358698E+00 0.12257458E+00 0.12156929E+00 0.12057107E+00
+ 0.11957988E+00 0.11859565E+00 0.11761834E+00 0.11664792E+00 0.11568431E+00
+ 0.11472749E+00 0.11377740E+00 0.11283400E+00 0.11189724E+00 0.11096706E+00
+ 0.11004344E+00 0.10912631E+00 0.10821564E+00 0.10731138E+00 0.10641348E+00
+ 0.10552189E+00 0.10463659E+00 0.10375750E+00 0.10288461E+00 0.10201785E+00
+ 0.10115718E+00 0.10030257E+00 0.99453968E-01 0.98611328E-01 0.97774609E-01
+ 0.96943768E-01 0.96118763E-01 0.95299550E-01 0.94486087E-01 0.93678333E-01
+ 0.92876245E-01 0.92079781E-01 0.91288900E-01 0.90503561E-01 0.89723723E-01
+ 0.88949344E-01 0.88180384E-01 0.87416802E-01 0.86658559E-01 0.85905614E-01
+ 0.85157927E-01 0.84415459E-01 0.83678170E-01 0.82946021E-01 0.82218973E-01
+ 0.81496986E-01 0.80780023E-01 0.80068045E-01 0.79361013E-01 0.78658890E-01
+ 0.77961638E-01 0.77269219E-01 0.76581595E-01 0.75898729E-01 0.75220585E-01
+ 0.74547126E-01 0.73878314E-01 0.73214113E-01 0.72554488E-01 0.71899401E-01
+ 0.71248818E-01 0.70602702E-01 0.69961018E-01 0.69323731E-01 0.68690806E-01
+ 0.68062207E-01 0.67437901E-01 0.66817852E-01 0.66202027E-01 0.65590391E-01
+ 0.64982910E-01 0.64379552E-01 0.63780281E-01 0.63185066E-01 0.62593873E-01
+ 0.62006669E-01 0.61423421E-01 0.60844097E-01 0.60268666E-01 0.59697094E-01
+ 0.59129350E-01 0.58565403E-01 0.58005220E-01 0.57448771E-01 0.56896025E-01
+ 0.56346952E-01 0.55801519E-01 0.55259698E-01 0.54721457E-01 0.54186768E-01
+ 0.53655600E-01 0.53127924E-01 0.52603711E-01 0.52082932E-01 0.51565557E-01
+ 0.51051559E-01 0.50540909E-01 0.50033579E-01 0.49529541E-01 0.49028768E-01
+ 0.48531231E-01 0.48036905E-01 0.47545762E-01 0.47057775E-01 0.46572918E-01
+ 0.46091165E-01 0.45612490E-01 0.45136868E-01 0.44664273E-01 0.44194679E-01
+ 0.43728063E-01 0.43264399E-01 0.42803664E-01 0.42345833E-01 0.41890883E-01
+ 0.41438789E-01 0.40989530E-01 0.40543082E-01 0.40099422E-01 0.39658529E-01
+ 0.39220380E-01 0.38784953E-01 0.38352228E-01 0.37922184E-01 0.37494799E-01
+ 0.37070053E-01 0.36647927E-01 0.36228400E-01 0.35811453E-01 0.35397068E-01
+ 0.34985225E-01 0.34575906E-01 0.34169093E-01 0.33764770E-01 0.33362918E-01
+ 0.32963520E-01 0.32566561E-01 0.32172023E-01 0.31779893E-01 0.31390153E-01
+ 0.31002790E-01 0.30617789E-01 0.30235136E-01 0.29854817E-01 0.29476819E-01
+ 0.29101129E-01 0.28727736E-01 0.28356626E-01 0.27987790E-01 0.27621215E-01
+ 0.27256892E-01 0.26894810E-01 0.26534960E-01 0.26177333E-01 0.25821920E-01
+ 0.25468712E-01 0.25117704E-01 0.24768887E-01 0.24422255E-01 0.24077801E-01
+ 0.23735521E-01 0.23395410E-01 0.23057462E-01 0.22721674E-01 0.22388043E-01
+ 0.22056566E-01 0.21727240E-01 0.21400063E-01 0.21075035E-01 0.20752155E-01
+ 0.20431423E-01 0.20112839E-01 0.19796405E-01 0.19482121E-01 0.19169991E-01
+ 0.18860017E-01 0.18552202E-01 0.18246551E-01 0.17943067E-01 0.17641757E-01
+ 0.17342625E-01 0.17045678E-01 0.16750923E-01 0.16458366E-01 0.16168017E-01
+ 0.15879884E-01 0.15593974E-01 0.15310299E-01 0.15028869E-01 0.14749693E-01
+ 0.14472783E-01 0.14198152E-01 0.13925810E-01 0.13655771E-01 0.13388049E-01
+ 0.13122656E-01 0.12859607E-01 0.12598916E-01 0.12340599E-01 0.12084671E-01
+ 0.11831148E-01 0.11580046E-01 0.11331381E-01 0.11085171E-01 0.10841432E-01
+ 0.10600182E-01 0.10361440E-01 0.10125222E-01 0.98915469E-02 0.96604334E-02
+ 0.94318998E-02 0.92059648E-02 0.89826471E-02 0.87619655E-02 0.85439387E-02
+ 0.83285856E-02 0.81159249E-02 0.79059752E-02 0.76987549E-02 0.74942825E-02
+ 0.72925759E-02 0.70936531E-02 0.68975315E-02 0.67042284E-02 0.65137604E-02
+ 0.63261440E-02 0.61413949E-02 0.59595286E-02 0.57805596E-02 0.56045021E-02
+ 0.54313695E-02 0.52611743E-02 0.50939285E-02 0.49296430E-02 0.47683280E-02
+ 0.46099927E-02 0.44546452E-02 0.43022927E-02 0.41529412E-02 0.40065957E-02
+ 0.38632598E-02 0.37229361E-02 0.35856257E-02 0.34513286E-02 0.33200432E-02
+ 0.31917666E-02 0.30664946E-02 0.29442212E-02 0.28249390E-02 0.27086393E-02
+ 0.25953115E-02 0.24849435E-02 0.23775215E-02 0.22730301E-02 0.21714524E-02
+ 0.20727694E-02 0.19769608E-02 0.18840044E-02 0.17938763E-02 0.17065509E-02
+ 0.16220009E-02 0.15401973E-02 0.14611096E-02 0.13847052E-02 0.13109504E-02
+ 0.12398095E-02 0.11712453E-02 0.11052191E-02 0.10416907E-02 0.98061856E-03
+ 0.92195948E-03 0.86566907E-03 0.81170163E-03 0.76001021E-03 0.71054671E-03
+ 0.66326194E-03 0.61810569E-03 0.57502681E-03 0.53397332E-03 0.49489244E-03
+ 0.45773073E-03 0.42243417E-03 0.38894821E-03 0.35721793E-03 0.32718808E-03
+ 0.29880323E-03 0.27200781E-03 0.24674624E-03 0.22296306E-03 0.20060295E-03
+ 0.17961090E-03 0.15993225E-03 0.14151285E-03 0.12429906E-03 0.10823794E-03
+ 0.93277267E-04 0.79365628E-04 0.66452530E-04 0.54488447E-04 0.43424905E-04
+ 0.33214542E-04 0.23811174E-04 0.15169849E-04 0.72469031E-05 0.00000000E+00
+ 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05
+ 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05
+ 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05
+ 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05
+ 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05
+ 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05
+ 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05
+ 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05 0.62792166E+05
+ 0.62792166E+05 0.61986382E+05 0.58238277E+05 0.54797131E+05 0.51631518E+05
+ 0.48713845E+05 0.46019812E+05 0.43527957E+05 0.41219277E+05 0.39076902E+05
+ 0.37085813E+05 0.35232615E+05 0.33505328E+05 0.31893216E+05 0.30386639E+05
+ 0.28976921E+05 0.27656239E+05 0.26417527E+05 0.25254390E+05 0.24161031E+05
+ 0.23132185E+05 0.22163064E+05 0.21249304E+05 0.20386926E+05 0.19572291E+05
+ 0.18802071E+05 0.18073216E+05 0.17382927E+05 0.16728633E+05 0.16107968E+05
+ 0.15518752E+05 0.14958977E+05 0.14426788E+05 0.13920469E+05 0.13438433E+05
+ 0.12979212E+05 0.12541443E+05 0.12123860E+05 0.11725288E+05 0.11344634E+05
+ 0.10980882E+05 0.10633082E+05 0.10300352E+05 0.99818665E+04 0.96768543E+04
+ 0.93845954E+04 0.91044157E+04 0.88356841E+04 0.85778091E+04 0.83302361E+04
+ 0.80924446E+04 0.78639458E+04 0.76442802E+04 0.74330159E+04 0.72297463E+04
+ 0.70340885E+04 0.68456818E+04 0.66641860E+04 0.64892803E+04 0.63206617E+04
+ 0.61580441E+04 0.60011570E+04 0.58497448E+04 0.57035653E+04 0.55623896E+04
+ 0.54260007E+04 0.52941930E+04 0.51667715E+04 0.50435512E+04 0.49243567E+04
+ 0.48090212E+04 0.46973864E+04 0.45893017E+04 0.44846241E+04 0.43832175E+04
+ 0.42849521E+04 0.41897047E+04 0.40973576E+04 0.40077990E+04 0.39209220E+04
+ 0.38366248E+04 0.37548101E+04 0.36753854E+04 0.35982619E+04 0.35233552E+04
+ 0.34505843E+04 0.33798720E+04 0.33111445E+04 0.32443309E+04 0.31793637E+04
+ 0.31161781E+04 0.30547120E+04 0.29949062E+04 0.29367036E+04 0.28800497E+04
+ 0.28248922E+04 0.27711809E+04 0.27188677E+04 0.26679063E+04 0.26182524E+04
+ 0.25698633E+04 0.25226983E+04 0.24767179E+04 0.24318843E+04 0.23881612E+04
+ 0.23455137E+04 0.23039082E+04 0.22633123E+04 0.22236949E+04 0.21850260E+04
+ 0.21472768E+04 0.21104195E+04 0.20744272E+04 0.20392743E+04 0.20049358E+04
+ 0.19713878E+04 0.19386070E+04 0.19065713E+04 0.18752591E+04 0.18446496E+04
+ 0.18147228E+04 0.17854593E+04 0.17568404E+04 0.17288481E+04 0.17014650E+04
+ 0.16746741E+04 0.16484592E+04 0.16228045E+04 0.15976949E+04 0.15731156E+04
+ 0.15490523E+04 0.15254913E+04 0.15024193E+04 0.14798232E+04 0.14576908E+04
+ 0.14360097E+04 0.14147684E+04 0.13939555E+04 0.13735600E+04 0.13535713E+04
+ 0.13339789E+04 0.13147730E+04 0.12959439E+04 0.12774820E+04 0.12593784E+04
+ 0.12416241E+04 0.12242107E+04 0.12071296E+04 0.11903730E+04 0.11739329E+04
+ 0.11578018E+04 0.11419722E+04 0.11264370E+04 0.11111892E+04 0.10962220E+04
+ 0.10815289E+04 0.10671035E+04 0.10529395E+04 0.10390310E+04 0.10253721E+04
+ 0.10119570E+04 0.99878025E+03 0.98583644E+03 0.97312033E+03 0.96062682E+03
+ 0.94835094E+03 0.93628787E+03 0.92443291E+03 0.91278149E+03 0.90132916E+03
+ 0.89007159E+03 0.87900456E+03 0.86812396E+03 0.85742580E+03 0.84690618E+03
+ 0.83656130E+03 0.82638747E+03 0.81638108E+03 0.80653863E+03 0.79685670E+03
+ 0.78733195E+03 0.77796112E+03 0.76874106E+03 0.75966867E+03 0.75074094E+03
+ 0.74195494E+03 0.73330779E+03 0.72479669E+03 0.71641894E+03 0.70817185E+03
+ 0.70005284E+03 0.69205937E+03 0.68418897E+03 0.67643923E+03 0.66880778E+03
+ 0.66129233E+03 0.65389063E+03 0.64660049E+03 0.63941977E+03 0.63234636E+03
+ 0.62537824E+03 0.61851340E+03 0.61174989E+03 0.60508580E+03 0.59851928E+03
+ 0.59204850E+03 0.58567169E+03 0.57938710E+03 0.57319304E+03 0.56708784E+03
+ 0.56106988E+03 0.55513757E+03 0.54928936E+03 0.54352373E+03 0.53783919E+03
+ 0.53223428E+03 0.52670760E+03 0.52125774E+03 0.51588334E+03 0.51058307E+03
+ 0.50535564E+03 0.50019975E+03 0.49511418E+03 0.49009768E+03 0.48514908E+03
+ 0.48026719E+03 0.47545087E+03 0.47069900E+03 0.46601047E+03 0.46138422E+03
+ 0.45681919E+03 0.45231434E+03 0.44786866E+03 0.44348117E+03 0.43915089E+03
+ 0.43487687E+03 0.43065818E+03 0.42649391E+03 0.42238316E+03 0.41832505E+03
+ 0.41431874E+03 0.41036336E+03 0.40645810E+03 0.40260215E+03 0.39879472E+03
+ 0.39503502E+03 0.39132229E+03 0.38765579E+03 0.38403479E+03 0.38045855E+03
+ 0.37692639E+03 0.37343759E+03 0.36999150E+03 0.36658743E+03 0.36322474E+03
+ 0.35990279E+03 0.35662094E+03 0.35337858E+03 0.35017510E+03 0.34700992E+03
+ 0.34388244E+03 0.34079209E+03 0.33773832E+03 0.33472056E+03 0.33173829E+03
+ 0.32879096E+03 0.32587805E+03 0.32299906E+03 0.32015348E+03 0.31734081E+03
+ 0.31456057E+03 0.31181229E+03 0.30909549E+03 0.30640972E+03 0.30375452E+03
+ 0.30112945E+03 0.29853408E+03 0.29596797E+03 0.29343071E+03 0.29092189E+03
+ 0.28844109E+03 0.28598792E+03 0.28356199E+03 0.28116290E+03 0.27879029E+03
+ 0.27644378E+03 0.27412301E+03 0.27182761E+03 0.26955723E+03 0.26731152E+03
+ 0.26509015E+03 0.26289278E+03 0.26071907E+03 0.25856870E+03 0.25644135E+03
+ 0.25433671E+03 0.25225448E+03 0.25019434E+03 0.24815599E+03 0.24613915E+03
+ 0.24414353E+03 0.24216883E+03 0.24021479E+03 0.23828112E+03 0.23636756E+03
+ 0.23447384E+03 0.23259969E+03 0.23074487E+03 0.22890911E+03 0.22709217E+03
+ 0.22529380E+03 0.22351376E+03 0.22175181E+03 0.22000772E+03 0.21828126E+03
+ 0.21657220E+03 0.21488032E+03 0.21320539E+03 0.21154721E+03 0.20990555E+03
+ 0.20828021E+03 0.20667099E+03 0.20507768E+03 0.20350007E+03 0.20193798E+03
+ 0.20039121E+03 0.19885956E+03 0.19734285E+03 0.19584090E+03 0.19435352E+03
+ 0.19288053E+03 0.19142175E+03 0.18997702E+03 0.18854615E+03 0.18712898E+03
+ 0.18572534E+03 0.18433508E+03 0.18295802E+03 0.18159400E+03 0.18024288E+03
+ 0.17890449E+03 0.17757868E+03 0.17626531E+03 0.17496422E+03 0.17367527E+03
+ 0.17239831E+03 0.17113321E+03 0.16987981E+03 0.16863800E+03 0.16740762E+03
+ 0.16618855E+03 0.16498065E+03 0.16378380E+03 0.16259786E+03 0.16142271E+03
+ 0.16025823E+03 0.15910429E+03 0.15796076E+03 0.15682754E+03 0.15570451E+03
+ 0.15459154E+03 0.15348852E+03 0.15239535E+03 0.15131190E+03 0.15023808E+03
+ 0.14917376E+03 0.14811885E+03 0.14707324E+03 0.14603682E+03 0.14500949E+03
+ 0.14399116E+03 0.14298172E+03 0.14198107E+03 0.14098911E+03 0.14000576E+03
+ 0.13903092E+03 0.13806448E+03 0.13710637E+03 0.13615649E+03 0.13521475E+03
+ 0.13428106E+03 0.13335534E+03 0.13243750E+03 0.13152745E+03 0.13062511E+03
+ 0.12973040E+03 0.12884324E+03 0.12796354E+03 0.12709123E+03 0.12622623E+03
+ 0.12536846E+03 0.12451785E+03 0.12367431E+03 0.12283778E+03 0.12200818E+03
+ 0.12118544E+03 0.12036948E+03 0.11956025E+03 0.11875766E+03 0.11796164E+03
+ 0.11717214E+03 0.11638908E+03 0.11561240E+03 0.11484202E+03 0.11407790E+03
+ 0.11331995E+03 0.11256813E+03 0.11182236E+03 0.11108259E+03 0.11034875E+03
+ 0.10962078E+03 0.10889864E+03 0.10818225E+03 0.10747155E+03 0.10676650E+03
+ 0.10606704E+03 0.10537311E+03 0.10468465E+03 0.10400161E+03 0.10332394E+03
+ 0.10265158E+03 0.10198449E+03 0.10132261E+03 0.10066588E+03 0.10001426E+03
+ 0.99367702E+02 0.98726151E+02 0.98089561E+02 0.97457883E+02 0.96831070E+02
+ 0.96209074E+02 0.95591850E+02 0.94979350E+02 0.94371531E+02 0.93768346E+02
+ 0.93169752E+02 0.92575706E+02 0.91986162E+02 0.91401080E+02 0.90820416E+02
+ 0.90244130E+02 0.89672178E+02 0.89104522E+02 0.88541120E+02 0.87981932E+02
+ 0.87426920E+02 0.86876043E+02 0.86329264E+02 0.85786545E+02 0.85247847E+02
+ 0.84713134E+02 0.84182369E+02 0.83655516E+02 0.83132538E+02 0.82613399E+02
+ 0.82098066E+02 0.81586502E+02 0.81078674E+02 0.80574548E+02 0.80074089E+02
+ 0.79577265E+02 0.79084043E+02 0.78594391E+02 0.78108275E+02 0.77625665E+02
+ 0.77146529E+02 0.76670836E+02 0.76198555E+02 0.75729655E+02 0.75264107E+02
+ 0.74801881E+02 0.74342948E+02 0.73887277E+02 0.73434841E+02 0.72985612E+02
+ 0.72539560E+02 0.72096658E+02 0.71656878E+02 0.71220194E+02 0.70786577E+02
+ 0.70356003E+02 0.69928443E+02 0.69503872E+02 0.69082264E+02 0.68663594E+02
+ 0.68247836E+02 0.67834965E+02 0.67424957E+02 0.67017786E+02 0.66613429E+02
+ 0.66211862E+02 0.65813061E+02 0.65417002E+02 0.65023662E+02 0.64633018E+02
+ 0.64245048E+02 0.63859729E+02 0.63477038E+02 0.63096954E+02 0.62719454E+02
+ 0.62344518E+02 0.61972123E+02 0.61602248E+02 0.61234873E+02 0.60869977E+02
+ 0.60507539E+02 0.60147539E+02 0.59789957E+02 0.59434773E+02 0.59081967E+02
+ 0.58731520E+02 0.58383412E+02 0.58037624E+02 0.57694138E+02 0.57352934E+02
+ 0.57013995E+02 0.56677301E+02 0.56342835E+02 0.56010578E+02 0.55680513E+02
+ 0.55352622E+02 0.55026888E+02 0.54703292E+02 0.54381820E+02 0.54062452E+02
+ 0.53745173E+02 0.53429966E+02 0.53116814E+02 0.52805701E+02 0.52496611E+02
+ 0.52189528E+02 0.51884436E+02 0.51581320E+02 0.51280164E+02 0.50980952E+02
+ 0.50683670E+02 0.50388302E+02 0.50094833E+02 0.49803249E+02 0.49513535E+02
+ 0.49225676E+02 0.48939658E+02 0.48655467E+02 0.48373089E+02 0.48092510E+02
+ 0.47813715E+02 0.47536692E+02 0.47261427E+02 0.46987905E+02 0.46716115E+02
+ 0.46446043E+02 0.46177675E+02 0.45910999E+02 0.45646002E+02 0.45382671E+02
+ 0.45120994E+02 0.44860958E+02 0.44602551E+02 0.44345761E+02 0.44090575E+02
+ 0.43836981E+02 0.43584969E+02 0.43334525E+02 0.43085638E+02 0.42838297E+02
+ 0.42592490E+02 0.42348205E+02 0.42105432E+02 0.41864160E+02 0.41624376E+02
+ 0.41386071E+02 0.41149234E+02 0.40913853E+02 0.40679919E+02 0.40447419E+02
+ 0.40216345E+02 0.39986686E+02 0.39758431E+02 0.39531570E+02 0.39306093E+02
+ 0.39081990E+02 0.38859252E+02 0.38637868E+02 0.38417828E+02 0.38199124E+02
+ 0.37981745E+02 0.37765681E+02 0.37550925E+02 0.37337465E+02 0.37125293E+02
+ 0.36914401E+02 0.36704777E+02 0.36496415E+02 0.36289305E+02 0.36083437E+02
+ 0.35878804E+02 0.35675396E+02 0.35473205E+02 0.35272222E+02 0.35072440E+02
+ 0.34873849E+02 0.34676441E+02 0.34480208E+02 0.34285141E+02 0.34091234E+02
+ 0.33898477E+02 0.33706863E+02 0.33516384E+02 0.33327031E+02 0.33138798E+02
+ 0.32951676E+02 0.32765658E+02 0.32580737E+02 0.32396904E+02 0.32214152E+02
+ 0.32032475E+02 0.31851864E+02 0.31672312E+02 0.31493813E+02 0.31316358E+02
+ 0.31139942E+02 0.30964557E+02 0.30790195E+02 0.30616851E+02 0.30444517E+02
+ 0.30273186E+02 0.30102853E+02 0.29933509E+02 0.29765148E+02 0.29597765E+02
+ 0.29431352E+02 0.29265903E+02 0.29101411E+02 0.28937870E+02 0.28775275E+02
+ 0.28613618E+02 0.28452893E+02 0.28293094E+02 0.28134216E+02 0.27976252E+02
+ 0.27819196E+02 0.27663042E+02 0.27507784E+02 0.27353416E+02 0.27199933E+02
+ 0.27047329E+02 0.26895598E+02 0.26744735E+02 0.26594733E+02 0.26445587E+02
+ 0.26297293E+02 0.26149843E+02 0.26003233E+02 0.25857457E+02 0.25712510E+02
+ 0.25568387E+02 0.25425082E+02 0.25282591E+02 0.25140907E+02 0.25000026E+02
+ 0.24859942E+02 0.24720651E+02 0.24582148E+02 0.24444427E+02 0.24307484E+02
+ 0.24171313E+02 0.24035910E+02 0.23901270E+02 0.23767388E+02 0.23634259E+02
+ 0.23501879E+02 0.23370243E+02 0.23239346E+02 0.23109184E+02 0.22979752E+02
+ 0.22851045E+02 0.22723059E+02 0.22595789E+02 0.22469232E+02 0.22343382E+02
+ 0.22218235E+02 0.22093787E+02 0.21970034E+02 0.21846970E+02 0.21724593E+02
+ 0.21602898E+02 0.21481880E+02 0.21361535E+02 0.21241860E+02 0.21122850E+02
+ 0.21004501E+02 0.20886809E+02 0.20769770E+02 0.20653380E+02 0.20537635E+02
+ 0.20422531E+02 0.20308065E+02 0.20194232E+02 0.20081029E+02 0.19968452E+02
+ 0.19856496E+02 0.19745159E+02 0.19634437E+02 0.19524325E+02 0.19414820E+02
+ 0.19305919E+02 0.19197618E+02 0.19089914E+02 0.18982802E+02 0.18876279E+02
+ 0.18770342E+02 0.18664987E+02 0.18560211E+02 0.18456011E+02 0.18352382E+02
+ 0.18249322E+02 0.18146827E+02 0.18044894E+02 0.17943519E+02 0.17842700E+02
+ 0.17742432E+02 0.17642714E+02 0.17543540E+02 0.17444909E+02 0.17346817E+02
+ 0.17249261E+02 0.17152238E+02 0.17055745E+02 0.16959778E+02 0.16864335E+02
+ 0.16769412E+02 0.16675007E+02 0.16581116E+02 0.16487736E+02 0.16394866E+02
+ 0.16302500E+02 0.16210638E+02 0.16119275E+02 0.16028409E+02 0.15938037E+02
+ 0.15848156E+02 0.15758763E+02 0.15669856E+02 0.15581432E+02 0.15493488E+02
+ 0.15406021E+02 0.15319029E+02 0.15232508E+02 0.15146456E+02 0.15060871E+02
+ 0.14975750E+02 0.14891090E+02 0.14806888E+02 0.14723142E+02 0.14639850E+02
+ 0.14557008E+02 0.14474615E+02 0.14392667E+02 0.14311162E+02 0.14230098E+02
+ 0.14149473E+02 0.14069283E+02 0.13989526E+02 0.13910200E+02 0.13831303E+02
+ 0.13752831E+02 0.13674784E+02 0.13597157E+02 0.13519950E+02 0.13443159E+02
+ 0.13366782E+02 0.13290817E+02 0.13215262E+02 0.13140114E+02 0.13065372E+02
+ 0.12991032E+02 0.12917093E+02 0.12843552E+02 0.12770407E+02 0.12697657E+02
+ 0.12625298E+02 0.12553329E+02 0.12481748E+02 0.12410552E+02 0.12339739E+02
+ 0.12269307E+02 0.12199254E+02 0.12129579E+02 0.12060278E+02 0.11991350E+02
+ 0.11922793E+02 0.11854605E+02 0.11786784E+02 0.11719327E+02 0.11652233E+02
+ 0.11585500E+02 0.11519126E+02 0.11453108E+02 0.11387446E+02 0.11322137E+02
+ 0.11257178E+02 0.11192569E+02 0.11128307E+02 0.11064391E+02 0.11000818E+02
+ 0.10937587E+02 0.10874696E+02 0.10812143E+02 0.10749926E+02 0.10688043E+02
+ 0.10626493E+02 0.10565273E+02 0.10504383E+02 0.10443820E+02 0.10383583E+02
+ 0.10323669E+02 0.10264077E+02 0.10204805E+02 0.10145852E+02 0.10087216E+02
+ 0.10028895E+02 0.99708877E+01 0.99131920E+01 0.98558064E+01 0.97987294E+01
+ 0.97419592E+01 0.96854942E+01 0.96293328E+01 0.95734733E+01 0.95179143E+01
+ 0.94626540E+01 0.94076909E+01 0.93530234E+01 0.92986500E+01 0.92445690E+01
+ 0.91907790E+01 0.91372784E+01 0.90840657E+01 0.90311393E+01 0.89784978E+01
+ 0.89261396E+01 0.88740633E+01 0.88222673E+01 0.87707502E+01 0.87195105E+01
+ 0.86685468E+01 0.86178576E+01 0.85674414E+01 0.85172969E+01 0.84674226E+01
+ 0.84178171E+01 0.83684789E+01 0.83194068E+01 0.82705992E+01 0.82220548E+01
+ 0.81737722E+01 0.81257501E+01 0.80779871E+01 0.80304819E+01 0.79832330E+01
+ 0.79362392E+01 0.78894991E+01 0.78430114E+01 0.77967748E+01 0.77507880E+01
+ 0.77050497E+01 0.76595585E+01 0.76143133E+01 0.75693127E+01 0.75245555E+01
+ 0.74800403E+01 0.74357660E+01 0.73917313E+01 0.73479349E+01 0.73043756E+01
+ 0.72610522E+01 0.72179635E+01 0.71751082E+01 0.71324852E+01 0.70900931E+01
+ 0.70479310E+01 0.70059974E+01 0.69642914E+01 0.69228116E+01 0.68815570E+01
+ 0.68405263E+01 0.67997185E+01 0.67591323E+01 0.67187666E+01 0.66786203E+01
+ 0.66386923E+01 0.65989814E+01 0.65594865E+01 0.65202065E+01 0.64811403E+01
+ 0.64422868E+01 0.64036449E+01 0.63652135E+01 0.63269915E+01 0.62889779E+01
+ 0.62511716E+01 0.62135715E+01 0.61761765E+01 0.61389857E+01 0.61019979E+01
+ 0.60652122E+01 0.60286274E+01 0.59922426E+01 0.59560567E+01 0.59200688E+01
+ 0.58842777E+01 0.58486825E+01 0.58132822E+01 0.57780758E+01 0.57430623E+01
+ 0.57082407E+01 0.56736100E+01 0.56391693E+01 0.56049176E+01 0.55708539E+01
+ 0.55369772E+01 0.55032866E+01 0.54697812E+01 0.54364599E+01 0.54033219E+01
+ 0.53703663E+01 0.53375920E+01 0.53049982E+01 0.52725840E+01 0.52403484E+01
+ 0.52082904E+01 0.51764093E+01 0.51447041E+01 0.51131740E+01 0.50818179E+01
+ 0.50506350E+01 0.50196246E+01 0.49887855E+01 0.49581171E+01 0.49276184E+01
+ 0.48972885E+01 0.48671266E+01 0.48371319E+01 0.48073034E+01 0.47776404E+01
+ 0.47481420E+01 0.47188074E+01 0.46896356E+01 0.46606260E+01 0.46317776E+01
+ 0.46030897E+01 0.45745614E+01 0.45461919E+01 0.45179804E+01 0.44899261E+01
+ 0.44620282E+01 0.44342859E+01 0.44066984E+01 0.43792649E+01 0.43519847E+01
+ 0.43248569E+01 0.42978808E+01 0.42710556E+01 0.42443805E+01 0.42178548E+01
+ 0.41914777E+01 0.41652484E+01 0.41391662E+01 0.41132304E+01 0.40874402E+01
+ 0.40617948E+01 0.40362935E+01 0.40109357E+01 0.39857204E+01 0.39606471E+01
+ 0.39357150E+01 0.39109234E+01 0.38862715E+01 0.38617587E+01 0.38373842E+01
+ 0.38131474E+01 0.37890475E+01 0.37650838E+01 0.37412556E+01 0.37175623E+01
+ 0.36940032E+01 0.36705775E+01 0.36472846E+01 0.36241238E+01 0.36010944E+01
+ 0.35781958E+01 0.35554273E+01 0.35327882E+01 0.35102779E+01 0.34878957E+01
+ 0.34656409E+01 0.34435129E+01 0.34215111E+01 0.33996348E+01 0.33778833E+01
+ 0.33562561E+01 0.33347524E+01 0.33133717E+01 0.32921133E+01 0.32709766E+01
+ 0.32499610E+01 0.32290658E+01 0.32082905E+01 0.31876343E+01 0.31670968E+01
+ 0.31466773E+01 0.31263751E+01 0.31061897E+01 0.30861206E+01 0.30661670E+01
+ 0.30463284E+01 0.30266042E+01 0.30069938E+01 0.29874966E+01 0.29681121E+01
+ 0.29488396E+01 0.29296786E+01 0.29106286E+01 0.28916888E+01 0.28728589E+01
+ 0.28541381E+01 0.28355260E+01 0.28170220E+01 0.27986255E+01 0.27803359E+01
+ 0.27621528E+01 0.27440755E+01 0.27261036E+01 0.27082364E+01 0.26904735E+01
+ 0.26728142E+01 0.26552581E+01 0.26378046E+01 0.26204532E+01 0.26032034E+01
+ 0.25860546E+01 0.25690062E+01 0.25520579E+01 0.25352091E+01 0.25184591E+01
+ 0.25018077E+01 0.24852541E+01 0.24687980E+01 0.24524387E+01 0.24361759E+01
+ 0.24200090E+01 0.24039374E+01 0.23879608E+01 0.23720786E+01 0.23562902E+01
+ 0.23405954E+01 0.23249934E+01 0.23094839E+01 0.22940664E+01 0.22787403E+01
+ 0.22635053E+01 0.22483608E+01 0.22333063E+01 0.22183415E+01 0.22034657E+01
+ 0.21886786E+01 0.21739797E+01 0.21593685E+01 0.21448445E+01 0.21304074E+01
+ 0.21160566E+01 0.21017917E+01 0.20876122E+01 0.20735178E+01 0.20595078E+01
+ 0.20455820E+01 0.20317398E+01 0.20179808E+01 0.20043046E+01 0.19907107E+01
+ 0.19771987E+01 0.19637682E+01 0.19504187E+01 0.19371499E+01 0.19239612E+01
+ 0.19108522E+01 0.18978226E+01 0.18848719E+01 0.18719996E+01 0.18592055E+01
+ 0.18464890E+01 0.18338497E+01 0.18212873E+01 0.18088013E+01 0.17963913E+01
+ 0.17840570E+01 0.17717978E+01 0.17596135E+01 0.17475035E+01 0.17354676E+01
+ 0.17235052E+01 0.17116161E+01 0.16997998E+01 0.16880560E+01 0.16763842E+01
+ 0.16647841E+01 0.16532552E+01 0.16417972E+01 0.16304098E+01 0.16190925E+01
+ 0.16078449E+01 0.15966667E+01 0.15855576E+01 0.15745170E+01 0.15635447E+01
+ 0.15526404E+01 0.15418035E+01 0.15310338E+01 0.15203309E+01 0.15096945E+01
+ 0.14991241E+01 0.14886195E+01 0.14781802E+01 0.14678059E+01 0.14574963E+01
+ 0.14472509E+01 0.14370696E+01 0.14269518E+01 0.14168973E+01 0.14069057E+01
+ 0.13969767E+01 0.13871099E+01 0.13773050E+01 0.13675617E+01 0.13578796E+01
+ 0.13482583E+01 0.13386976E+01 0.13291971E+01 0.13197565E+01 0.13103754E+01
+ 0.13010536E+01 0.12917907E+01 0.12825863E+01 0.12734402E+01 0.12643521E+01
+ 0.12553215E+01 0.12463483E+01 0.12374320E+01 0.12285724E+01 0.12197691E+01
+ 0.12110219E+01 0.12023304E+01 0.11936944E+01 0.11851134E+01 0.11765873E+01
+ 0.11681156E+01 0.11596982E+01 0.11513346E+01 0.11430246E+01 0.11347680E+01
+ 0.11265643E+01 0.11184134E+01 0.11103148E+01 0.11022684E+01 0.10942738E+01
+ 0.10863307E+01 0.10784389E+01 0.10705980E+01 0.10628078E+01 0.10550680E+01
+ 0.10473783E+01 0.10397384E+01 0.10321480E+01 0.10246070E+01 0.10171149E+01
+ 0.10096715E+01 0.10022765E+01 0.99492969E+00 0.98763077E+00 0.98037946E+00
+ 0.97317550E+00 0.96601861E+00 0.95890853E+00 0.95184499E+00 0.94482773E+00
+ 0.93785648E+00 0.93093098E+00 0.92405097E+00 0.91721619E+00 0.91042638E+00
+ 0.90368129E+00 0.89698065E+00 0.89032422E+00 0.88371174E+00 0.87714296E+00
+ 0.87061763E+00 0.86413549E+00 0.85769630E+00 0.85129982E+00 0.84494579E+00
+ 0.83863397E+00 0.83236412E+00 0.82613599E+00 0.81994934E+00 0.81380394E+00
+ 0.80769954E+00 0.80163591E+00 0.79561281E+00 0.78963000E+00 0.78368726E+00
+ 0.77778433E+00 0.77192101E+00 0.76609705E+00 0.76031222E+00 0.75456630E+00
+ 0.74885906E+00 0.74319026E+00 0.73755970E+00 0.73196714E+00 0.72641236E+00
+ 0.72089513E+00 0.71541525E+00 0.70997248E+00 0.70456661E+00 0.69919742E+00
+ 0.69386470E+00 0.68856822E+00 0.68330779E+00 0.67808317E+00 0.67289417E+00
+ 0.66774056E+00 0.66262215E+00 0.65753871E+00 0.65249005E+00 0.64747595E+00
+ 0.64249622E+00 0.63755063E+00 0.63263900E+00 0.62776112E+00 0.62291679E+00
+ 0.61810580E+00 0.61332796E+00 0.60858306E+00 0.60387092E+00 0.59919133E+00
+ 0.59454410E+00 0.58992903E+00 0.58534593E+00 0.58079461E+00 0.57627488E+00
+ 0.57178654E+00 0.56732940E+00 0.56290328E+00 0.55850799E+00 0.55414334E+00
+ 0.54980914E+00 0.54550522E+00 0.54123138E+00 0.53698744E+00 0.53277323E+00
+ 0.52858856E+00 0.52443324E+00 0.52030711E+00 0.51620998E+00 0.51214167E+00
+ 0.50810201E+00 0.50409082E+00 0.50010793E+00 0.49615316E+00 0.49222635E+00
+ 0.48832731E+00 0.48445588E+00 0.48061188E+00 0.47679515E+00 0.47300552E+00
+ 0.46924283E+00 0.46550689E+00 0.46179756E+00 0.45811466E+00 0.45445803E+00
+ 0.45082750E+00 0.44722292E+00 0.44364411E+00 0.44009093E+00 0.43656321E+00
+ 0.43306080E+00 0.42958352E+00 0.42613123E+00 0.42270378E+00 0.41930099E+00
+ 0.41592273E+00 0.41256882E+00 0.40923913E+00 0.40593350E+00 0.40265178E+00
+ 0.39939381E+00 0.39615945E+00 0.39294854E+00 0.38976095E+00 0.38659651E+00
+ 0.38345509E+00 0.38033653E+00 0.37724070E+00 0.37416744E+00 0.37111662E+00
+ 0.36808809E+00 0.36508171E+00 0.36209733E+00 0.35913482E+00 0.35619404E+00
+ 0.35327484E+00 0.35037709E+00 0.34750066E+00 0.34464539E+00 0.34181116E+00
+ 0.33899784E+00 0.33620528E+00 0.33343336E+00 0.33068193E+00 0.32795087E+00
+ 0.32524005E+00 0.32254933E+00 0.31987858E+00 0.31722768E+00 0.31459649E+00
+ 0.31198489E+00 0.30939275E+00 0.30681994E+00 0.30426634E+00 0.30173181E+00
+ 0.29921625E+00 0.29671951E+00 0.29424148E+00 0.29178204E+00 0.28934105E+00
+ 0.28691841E+00 0.28451399E+00 0.28212768E+00 0.27975934E+00 0.27740886E+00
+ 0.27507613E+00 0.27276103E+00 0.27046344E+00 0.26818324E+00 0.26592032E+00
+ 0.26367456E+00 0.26144585E+00 0.25923408E+00 0.25703913E+00 0.25486089E+00
+ 0.25269925E+00 0.25055410E+00 0.24842533E+00 0.24631283E+00 0.24421648E+00
+ 0.24213619E+00 0.24007183E+00 0.23802331E+00 0.23599052E+00 0.23397336E+00
+ 0.23197171E+00 0.22998547E+00 0.22801454E+00 0.22605881E+00 0.22411819E+00
+ 0.22219256E+00 0.22028183E+00 0.21838589E+00 0.21650465E+00 0.21463800E+00
+ 0.21278585E+00 0.21094809E+00 0.20912464E+00 0.20731538E+00 0.20552022E+00
+ 0.20373906E+00 0.20197182E+00 0.20021839E+00 0.19847868E+00 0.19675259E+00
+ 0.19504003E+00 0.19334091E+00 0.19165513E+00 0.18998261E+00 0.18832324E+00
+ 0.18667694E+00 0.18504362E+00 0.18342319E+00 0.18181555E+00 0.18022062E+00
+ 0.17863832E+00 0.17706854E+00 0.17551121E+00 0.17396623E+00 0.17243353E+00
+ 0.17091301E+00 0.16940459E+00 0.16790819E+00 0.16642372E+00 0.16495109E+00
+ 0.16349022E+00 0.16204103E+00 0.16060344E+00 0.15917737E+00 0.15776273E+00
+ 0.15635944E+00 0.15496742E+00 0.15358659E+00 0.15221688E+00 0.15085820E+00
+ 0.14951048E+00 0.14817363E+00 0.14684758E+00 0.14553225E+00 0.14422757E+00
+ 0.14293345E+00 0.14164983E+00 0.14037663E+00 0.13911377E+00 0.13786118E+00
+ 0.13661878E+00 0.13538650E+00 0.13416427E+00 0.13295202E+00 0.13174967E+00
+ 0.13055715E+00 0.12937440E+00 0.12820133E+00 0.12703788E+00 0.12588398E+00
+ 0.12473956E+00 0.12360455E+00 0.12247888E+00 0.12136248E+00 0.12025529E+00
+ 0.11915724E+00 0.11806827E+00 0.11698829E+00 0.11591726E+00 0.11485509E+00
+ 0.11380174E+00 0.11275713E+00 0.11172120E+00 0.11069388E+00 0.10967511E+00
+ 0.10866483E+00 0.10766298E+00 0.10666948E+00 0.10568429E+00 0.10470733E+00
+ 0.10373856E+00 0.10277789E+00 0.10182529E+00 0.10088068E+00 0.99944001E-01
+ 0.99015202E-01 0.98094221E-01 0.97180998E-01 0.96275476E-01 0.95377596E-01
+ 0.94487302E-01 0.93604536E-01 0.92729241E-01 0.91861361E-01 0.91000840E-01
+ 0.90147622E-01 0.89301652E-01 0.88462875E-01 0.87631237E-01 0.86806683E-01
+ 0.85989159E-01 0.85178612E-01 0.84374989E-01 0.83578236E-01 0.82788302E-01
+ 0.82005134E-01 0.81228680E-01 0.80458889E-01 0.79695711E-01 0.78939093E-01
+ 0.78188986E-01 0.77445339E-01 0.76708103E-01 0.75977228E-01 0.75252665E-01
+ 0.74534366E-01 0.73822282E-01 0.73116364E-01 0.72416565E-01 0.71722837E-01
+ 0.71035134E-01 0.70353408E-01 0.69677612E-01 0.69007702E-01 0.68343629E-01
+ 0.67685350E-01 0.67032818E-01 0.66385988E-01 0.65744816E-01 0.65109258E-01
+ 0.64479269E-01 0.63854805E-01 0.63235824E-01 0.62622281E-01 0.62014134E-01
+ 0.61411340E-01 0.60813856E-01 0.60221642E-01 0.59634654E-01 0.59052852E-01
+ 0.58476194E-01 0.57904639E-01 0.57338147E-01 0.56776678E-01 0.56220190E-01
+ 0.55668645E-01 0.55122003E-01 0.54580225E-01 0.54043271E-01 0.53511103E-01
+ 0.52983682E-01 0.52460971E-01 0.51942931E-01 0.51429525E-01 0.50920715E-01
+ 0.50416465E-01 0.49916737E-01 0.49421494E-01 0.48930701E-01 0.48444321E-01
+ 0.47962318E-01 0.47484658E-01 0.47011303E-01 0.46542220E-01 0.46077374E-01
+ 0.45616730E-01 0.45160253E-01 0.44707909E-01 0.44259665E-01 0.43815487E-01
+ 0.43375342E-01 0.42939196E-01 0.42507017E-01 0.42078771E-01 0.41654427E-01
+ 0.41233952E-01 0.40817314E-01 0.40404481E-01 0.39995423E-01 0.39590107E-01
+ 0.39188502E-01 0.38790578E-01 0.38396304E-01 0.38005650E-01 0.37618585E-01
+ 0.37235080E-01 0.36855105E-01 0.36478630E-01 0.36105625E-01 0.35736063E-01
+ 0.35369913E-01 0.35007148E-01 0.34647738E-01 0.34291656E-01 0.33938874E-01
+ 0.33589363E-01 0.33243096E-01 0.32900045E-01 0.32560184E-01 0.32223485E-01
+ 0.31889922E-01 0.31559468E-01 0.31232095E-01 0.30907779E-01 0.30586494E-01
+ 0.30268212E-01 0.29952909E-01 0.29640559E-01 0.29331137E-01 0.29024618E-01
+ 0.28720977E-01 0.28420189E-01 0.28122229E-01 0.27827074E-01 0.27534699E-01
+ 0.27245080E-01 0.26958194E-01 0.26674017E-01 0.26392525E-01 0.26113695E-01
+ 0.25837504E-01 0.25563929E-01 0.25292948E-01 0.25024537E-01 0.24758675E-01
+ 0.24495339E-01 0.24234508E-01 0.23976159E-01 0.23720271E-01 0.23466821E-01
+ 0.23215790E-01 0.22967155E-01 0.22720896E-01 0.22476991E-01 0.22235421E-01
+ 0.21996163E-01 0.21759199E-01 0.21524508E-01 0.21292069E-01 0.21061863E-01
+ 0.20833871E-01 0.20608071E-01 0.20384446E-01 0.20162975E-01 0.19943640E-01
+ 0.19726421E-01 0.19511301E-01 0.19298259E-01 0.19087277E-01 0.18878338E-01
+ 0.18671422E-01 0.18466513E-01 0.18263590E-01 0.18062638E-01 0.17863638E-01
+ 0.17666573E-01 0.17471425E-01 0.17278177E-01 0.17086812E-01 0.16897313E-01
+ 0.16709662E-01 0.16523845E-01 0.16339843E-01 0.16157640E-01 0.15977221E-01
+ 0.15798568E-01 0.15621667E-01 0.15446500E-01 0.15273052E-01 0.15101308E-01
+ 0.14931252E-01 0.14762868E-01 0.14596142E-01 0.14431058E-01 0.14267601E-01
+ 0.14105757E-01 0.13945510E-01 0.13786846E-01 0.13629750E-01 0.13474208E-01
+ 0.13320205E-01 0.13167729E-01 0.13016763E-01 0.12867295E-01 0.12719311E-01
+ 0.12572797E-01 0.12427739E-01 0.12284124E-01 0.12141939E-01 0.12001170E-01
+ 0.11861805E-01 0.11723829E-01 0.11587231E-01 0.11451998E-01 0.11318116E-01
+ 0.11185574E-01 0.11054358E-01 0.10924457E-01 0.10795858E-01 0.10668549E-01
+ 0.10542518E-01 0.10417753E-01 0.10294243E-01 0.10171975E-01 0.10050937E-01
+ 0.99311196E-02 0.98125096E-02 0.96950963E-02 0.95788683E-02 0.94638146E-02
+ 0.93499240E-02 0.92371858E-02 0.91255890E-02 0.90151229E-02 0.89057769E-02
+ 0.87975405E-02 0.86904031E-02 0.85843544E-02 0.84793842E-02 0.83754823E-02
+ 0.82726385E-02 0.81708430E-02 0.80700858E-02 0.79703571E-02 0.78716472E-02
+ 0.77739465E-02 0.76772453E-02 0.75815344E-02 0.74868042E-02 0.73930455E-02
+ 0.73002492E-02 0.72084061E-02 0.71175071E-02 0.70275434E-02 0.69385061E-02
+ 0.68503865E-02 0.67631757E-02 0.66768653E-02 0.65914467E-02 0.65069114E-02
+ 0.64232511E-02 0.63404575E-02 0.62585224E-02 0.61774376E-02 0.60971952E-02
+ 0.60177870E-02 0.59392054E-02 0.58614423E-02 0.57844902E-02 0.57083412E-02
+ 0.56329879E-02 0.55584226E-02 0.54846381E-02 0.54116268E-02 0.53393815E-02
+ 0.52678950E-02 0.51971601E-02 0.51271697E-02 0.50579168E-02 0.49893946E-02
+ 0.49215960E-02 0.48545144E-02 0.47881429E-02 0.47224750E-02 0.46575040E-02
+ 0.45932234E-02 0.45296267E-02 0.44667076E-02 0.44044596E-02 0.43428767E-02
+ 0.42819525E-02 0.42216809E-02 0.41620559E-02 0.41030715E-02 0.40447216E-02
+ 0.39870005E-02 0.39299024E-02 0.38734214E-02 0.38175519E-02 0.37622882E-02
+ 0.37076249E-02 0.36535563E-02 0.36000770E-02 0.35471817E-02 0.34948649E-02
+ 0.34431215E-02 0.33919462E-02 0.33413338E-02 0.32912793E-02 0.32417777E-02
+ 0.31928238E-02 0.31444128E-02 0.30965398E-02 0.30492000E-02 0.30023886E-02
+ 0.29561009E-02 0.29103322E-02 0.28650780E-02 0.28203336E-02 0.27760945E-02
+ 0.27323564E-02 0.26891147E-02 0.26463653E-02 0.26041036E-02 0.25623255E-02
+ 0.25210268E-02 0.24802033E-02 0.24398510E-02 0.23999657E-02 0.23605434E-02
+ 0.23215802E-02 0.22830721E-02 0.22450153E-02 0.22074059E-02 0.21702402E-02
+ 0.21335144E-02 0.20972248E-02 0.20613677E-02 0.20259396E-02 0.19909368E-02
+ 0.19563559E-02 0.19221932E-02 0.18884455E-02 0.18551092E-02 0.18221811E-02
+ 0.17896577E-02 0.17575358E-02 0.17258121E-02 0.16944834E-02 0.16635465E-02
+ 0.16329982E-02 0.16028355E-02 0.15730553E-02 0.15436545E-02 0.15146301E-02
+ 0.14859791E-02 0.14576986E-02 0.14297856E-02 0.14022373E-02 0.13750509E-02
+ 0.13482234E-02 0.13217522E-02 0.12956343E-02 0.12698672E-02 0.12444480E-02
+ 0.12193741E-02 0.11946429E-02 0.11702516E-02 0.11461977E-02 0.11224786E-02
+ 0.10990917E-02 0.10760344E-02 0.10533043E-02 0.10308989E-02 0.10088156E-02
+ 0.98705198E-03 0.96560563E-03 0.94447410E-03 0.92365498E-03 0.90314588E-03
+ 0.88294442E-03 0.86304824E-03 0.84345498E-03 0.82416231E-03 0.80516791E-03
+ 0.78646945E-03 0.76806465E-03 0.74995122E-03 0.73212686E-03 0.71458931E-03
+ 0.69733631E-03 0.68036559E-03 0.66367491E-03 0.64726203E-03 0.63112470E-03
+ 0.61526069E-03 0.59966778E-03 0.58434372E-03 0.56928630E-03 0.55449329E-03
+ 0.53996248E-03 0.52569162E-03 0.51167851E-03 0.49792092E-03 0.48441662E-03
+ 0.47116338E-03 0.45815897E-03 0.44540115E-03 0.43288768E-03 0.42061633E-03
+ 0.40858483E-03 0.39679093E-03 0.38523236E-03 0.37390687E-03 0.36281216E-03
+ 0.35194595E-03 0.34130595E-03 0.33088986E-03 0.32069535E-03 0.31072012E-03
+ 0.30096181E-03 0.29141811E-03 0.28208663E-03 0.27296504E-03 0.26405094E-03
+ 0.25534195E-03 0.24683568E-03 0.23852971E-03 0.23042161E-03 0.22250897E-03
+ 0.21478932E-03 0.20726022E-03 0.19991920E-03 0.19276377E-03 0.18579144E-03
+ 0.17899971E-03 0.17238607E-03 0.16594798E-03 0.15968292E-03 0.15358833E-03
+ 0.14766167E-03 0.14190036E-03 0.13630183E-03 0.13086349E-03 0.12558277E-03
+ 0.12045705E-03 0.11548373E-03 0.11066021E-03 0.10598386E-03 0.10145206E-03
+ 0.97062192E-04 0.92811624E-04 0.88697726E-04 0.84717866E-04 0.80869413E-04
+ 0.77149734E-04 0.73556200E-04 0.70086184E-04 0.66737063E-04 0.63506217E-04
+ 0.60391034E-04 0.57388907E-04 0.54497240E-04 0.51713444E-04 0.49034941E-04
+ 0.46459166E-04 0.43983564E-04 0.41605598E-04 0.39322743E-04 0.37132494E-04
+ 0.35032362E-04 0.33019876E-04 0.31092589E-04 0.29248072E-04 0.27483921E-04
+ 0.25797757E-04 0.24187223E-04 0.22649993E-04 0.21183765E-04 0.19786268E-04
+ 0.18455261E-04 0.17188533E-04 0.15983905E-04 0.14839234E-04 0.13752408E-04
+ 0.12721352E-04 0.11744026E-04 0.10818429E-04 0.99425949E-05 0.91145990E-05
+ 0.83325543E-05 0.75946143E-05 0.68989732E-05 0.62438661E-05 0.56275702E-05
+ 0.50484045E-05 0.45047309E-05 0.39949538E-05 0.35175209E-05 0.30709234E-05
+ 0.26536956E-05 0.22644158E-05 0.19017056E-05 0.15642301E-05 0.12506980E-05
+ 0.95986098E-06 0.69051399E-06 0.44149456E-06 0.21168260E-06 0.00000000E+00
+ 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03
+ 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03
+ 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03
+ 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03
+ 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03
+ 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03
+ 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03
+ 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03
+ 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03 0.23974391E+03
+ 0.23974391E+03 0.23974391E+03 0.23291613E+03 0.22541822E+03 0.21830884E+03
+ 0.21156053E+03 0.20514827E+03 0.19904921E+03 0.19324246E+03 0.18770888E+03
+ 0.18243091E+03 0.17739242E+03 0.17257854E+03 0.16797557E+03 0.16357088E+03
+ 0.15935277E+03 0.15531042E+03 0.15143380E+03 0.14771361E+03 0.14414119E+03
+ 0.14070850E+03 0.13740805E+03 0.13423286E+03 0.13117640E+03 0.12823258E+03
+ 0.12539571E+03 0.12266045E+03 0.12002181E+03 0.11747510E+03 0.11501593E+03
+ 0.11264016E+03 0.11034390E+03 0.10812350E+03 0.10597552E+03 0.10389671E+03
+ 0.10188400E+03 0.99934506E+02 0.98045499E+02 0.96214397E+02 0.94438757E+02
+ 0.92716268E+02 0.91044740E+02 0.89422099E+02 0.87846376E+02 0.86315704E+02
+ 0.84828309E+02 0.83382506E+02 0.81976693E+02 0.80609347E+02 0.79279018E+02
+ 0.77984324E+02 0.76723950E+02 0.75496643E+02 0.74301206E+02 0.73136500E+02
+ 0.72001433E+02 0.70894968E+02 0.69816109E+02 0.68763906E+02 0.67737452E+02
+ 0.66735876E+02 0.65758348E+02 0.64804069E+02 0.63872278E+02 0.62962243E+02
+ 0.62073262E+02 0.61204663E+02 0.60355801E+02 0.59526057E+02 0.58714836E+02
+ 0.57921567E+02 0.57145701E+02 0.56386711E+02 0.55644090E+02 0.54917350E+02
+ 0.54206022E+02 0.53509654E+02 0.52827812E+02 0.52160076E+02 0.51506043E+02
+ 0.50865324E+02 0.50237545E+02 0.49622344E+02 0.49019373E+02 0.48428295E+02
+ 0.47848787E+02 0.47280534E+02 0.46723235E+02 0.46176597E+02 0.45640338E+02
+ 0.45114185E+02 0.44597876E+02 0.44091154E+02 0.43593774E+02 0.43105496E+02
+ 0.42626092E+02 0.42155336E+02 0.41693014E+02 0.41238916E+02 0.40792839E+02
+ 0.40354588E+02 0.39923971E+02 0.39500805E+02 0.39084911E+02 0.38676116E+02
+ 0.38274253E+02 0.37879157E+02 0.37490672E+02 0.37108644E+02 0.36732923E+02
+ 0.36363367E+02 0.35999834E+02 0.35642189E+02 0.35290299E+02 0.34944036E+02
+ 0.34603275E+02 0.34267894E+02 0.33937777E+02 0.33612808E+02 0.33292876E+02
+ 0.32977872E+02 0.32667692E+02 0.32362232E+02 0.32061394E+02 0.31765080E+02
+ 0.31473195E+02 0.31185648E+02 0.30902348E+02 0.30623210E+02 0.30348149E+02
+ 0.30077080E+02 0.29809925E+02 0.29546604E+02 0.29287041E+02 0.29031161E+02
+ 0.28778893E+02 0.28530164E+02 0.28284907E+02 0.28043053E+02 0.27804538E+02
+ 0.27569296E+02 0.27337266E+02 0.27108387E+02 0.26882598E+02 0.26659843E+02
+ 0.26440064E+02 0.26223206E+02 0.26009215E+02 0.25798039E+02 0.25589625E+02
+ 0.25383924E+02 0.25180887E+02 0.24980465E+02 0.24782611E+02 0.24587280E+02
+ 0.24394427E+02 0.24204008E+02 0.24015981E+02 0.23830303E+02 0.23646934E+02
+ 0.23465833E+02 0.23286962E+02 0.23110283E+02 0.22935757E+02 0.22763349E+02
+ 0.22593023E+02 0.22424743E+02 0.22258475E+02 0.22094186E+02 0.21931843E+02
+ 0.21771414E+02 0.21612867E+02 0.21456171E+02 0.21301297E+02 0.21148215E+02
+ 0.20996896E+02 0.20847311E+02 0.20699433E+02 0.20553235E+02 0.20408690E+02
+ 0.20265772E+02 0.20124455E+02 0.19984715E+02 0.19846526E+02 0.19709866E+02
+ 0.19574709E+02 0.19441033E+02 0.19308816E+02 0.19178035E+02 0.19048668E+02
+ 0.18920694E+02 0.18794093E+02 0.18668842E+02 0.18544923E+02 0.18422316E+02
+ 0.18301001E+02 0.18180958E+02 0.18062170E+02 0.17944619E+02 0.17828285E+02
+ 0.17713152E+02 0.17599201E+02 0.17486417E+02 0.17374782E+02 0.17264281E+02
+ 0.17154896E+02 0.17046612E+02 0.16939414E+02 0.16833286E+02 0.16728213E+02
+ 0.16624181E+02 0.16521176E+02 0.16419182E+02 0.16318187E+02 0.16218176E+02
+ 0.16119136E+02 0.16021053E+02 0.15923916E+02 0.15827711E+02 0.15732425E+02
+ 0.15638046E+02 0.15544562E+02 0.15451962E+02 0.15360233E+02 0.15269364E+02
+ 0.15179343E+02 0.15090160E+02 0.15001804E+02 0.14914263E+02 0.14827528E+02
+ 0.14741587E+02 0.14656432E+02 0.14572050E+02 0.14488434E+02 0.14405572E+02
+ 0.14323456E+02 0.14242075E+02 0.14161421E+02 0.14081485E+02 0.14002258E+02
+ 0.13923730E+02 0.13845893E+02 0.13768739E+02 0.13692258E+02 0.13616444E+02
+ 0.13541287E+02 0.13466780E+02 0.13392915E+02 0.13319683E+02 0.13247078E+02
+ 0.13175091E+02 0.13103716E+02 0.13032945E+02 0.12962771E+02 0.12893186E+02
+ 0.12824184E+02 0.12755758E+02 0.12687901E+02 0.12620606E+02 0.12553868E+02
+ 0.12487678E+02 0.12422032E+02 0.12356922E+02 0.12292343E+02 0.12228289E+02
+ 0.12164752E+02 0.12101729E+02 0.12039212E+02 0.11977195E+02 0.11915675E+02
+ 0.11854643E+02 0.11794096E+02 0.11734028E+02 0.11674433E+02 0.11615306E+02
+ 0.11556642E+02 0.11498436E+02 0.11440683E+02 0.11383377E+02 0.11326515E+02
+ 0.11270090E+02 0.11214098E+02 0.11158536E+02 0.11103397E+02 0.11048677E+02
+ 0.10994372E+02 0.10940478E+02 0.10886990E+02 0.10833903E+02 0.10781213E+02
+ 0.10728917E+02 0.10677010E+02 0.10625488E+02 0.10574347E+02 0.10523582E+02
+ 0.10473191E+02 0.10423168E+02 0.10373511E+02 0.10324215E+02 0.10275277E+02
+ 0.10226693E+02 0.10178460E+02 0.10130573E+02 0.10083029E+02 0.10035826E+02
+ 0.99889583E+01 0.99424239E+01 0.98962191E+01 0.98503405E+01 0.98047850E+01
+ 0.97595492E+01 0.97146300E+01 0.96700243E+01 0.96257289E+01 0.95817407E+01
+ 0.95380568E+01 0.94946741E+01 0.94515896E+01 0.94088006E+01 0.93663040E+01
+ 0.93240971E+01 0.92821770E+01 0.92405409E+01 0.91991862E+01 0.91581101E+01
+ 0.91173099E+01 0.90767830E+01 0.90365268E+01 0.89965388E+01 0.89568163E+01
+ 0.89173568E+01 0.88781580E+01 0.88392172E+01 0.88005322E+01 0.87621005E+01
+ 0.87239197E+01 0.86859875E+01 0.86483017E+01 0.86108598E+01 0.85736597E+01
+ 0.85366991E+01 0.84999759E+01 0.84634878E+01 0.84272327E+01 0.83912085E+01
+ 0.83554131E+01 0.83198444E+01 0.82845003E+01 0.82493789E+01 0.82144781E+01
+ 0.81797959E+01 0.81453304E+01 0.81110797E+01 0.80770418E+01 0.80432148E+01
+ 0.80095969E+01 0.79761862E+01 0.79429810E+01 0.79099793E+01 0.78771794E+01
+ 0.78445796E+01 0.78121780E+01 0.77799730E+01 0.77479629E+01 0.77161459E+01
+ 0.76845204E+01 0.76530848E+01 0.76218373E+01 0.75907765E+01 0.75599007E+01
+ 0.75292082E+01 0.74986977E+01 0.74683674E+01 0.74382159E+01 0.74082417E+01
+ 0.73784433E+01 0.73488192E+01 0.73193679E+01 0.72900879E+01 0.72609780E+01
+ 0.72320365E+01 0.72032622E+01 0.71746537E+01 0.71462095E+01 0.71179284E+01
+ 0.70898089E+01 0.70618497E+01 0.70340497E+01 0.70064073E+01 0.69789214E+01
+ 0.69515906E+01 0.69244138E+01 0.68973896E+01 0.68705169E+01 0.68437944E+01
+ 0.68172209E+01 0.67907952E+01 0.67645161E+01 0.67383825E+01 0.67123931E+01
+ 0.66865469E+01 0.66608428E+01 0.66352795E+01 0.66098560E+01 0.65845711E+01
+ 0.65594239E+01 0.65344131E+01 0.65095378E+01 0.64847969E+01 0.64601893E+01
+ 0.64357140E+01 0.64113699E+01 0.63871561E+01 0.63630716E+01 0.63391153E+01
+ 0.63152863E+01 0.62915836E+01 0.62680062E+01 0.62445532E+01 0.62212236E+01
+ 0.61980165E+01 0.61749309E+01 0.61519660E+01 0.61291208E+01 0.61063945E+01
+ 0.60837860E+01 0.60612947E+01 0.60389195E+01 0.60166596E+01 0.59945141E+01
+ 0.59724822E+01 0.59505631E+01 0.59287560E+01 0.59070599E+01 0.58854740E+01
+ 0.58639977E+01 0.58426300E+01 0.58213702E+01 0.58002174E+01 0.57791710E+01
+ 0.57582300E+01 0.57373939E+01 0.57166617E+01 0.56960328E+01 0.56755064E+01
+ 0.56550817E+01 0.56347581E+01 0.56145348E+01 0.55944111E+01 0.55743863E+01
+ 0.55544596E+01 0.55346305E+01 0.55148981E+01 0.54952619E+01 0.54757211E+01
+ 0.54562750E+01 0.54369230E+01 0.54176645E+01 0.53984987E+01 0.53794251E+01
+ 0.53604430E+01 0.53415517E+01 0.53227506E+01 0.53040392E+01 0.52854167E+01
+ 0.52668825E+01 0.52484362E+01 0.52300770E+01 0.52118043E+01 0.51936176E+01
+ 0.51755163E+01 0.51574998E+01 0.51395675E+01 0.51217188E+01 0.51039532E+01
+ 0.50862702E+01 0.50686691E+01 0.50511494E+01 0.50337106E+01 0.50163521E+01
+ 0.49990734E+01 0.49818740E+01 0.49647533E+01 0.49477108E+01 0.49307460E+01
+ 0.49138583E+01 0.48970474E+01 0.48803125E+01 0.48636534E+01 0.48470693E+01
+ 0.48305600E+01 0.48141248E+01 0.47977634E+01 0.47814751E+01 0.47652596E+01
+ 0.47491163E+01 0.47330449E+01 0.47170448E+01 0.47011155E+01 0.46852567E+01
+ 0.46694679E+01 0.46537485E+01 0.46380983E+01 0.46225166E+01 0.46070032E+01
+ 0.45915575E+01 0.45761792E+01 0.45608678E+01 0.45456229E+01 0.45304440E+01
+ 0.45153308E+01 0.45002828E+01 0.44852996E+01 0.44703809E+01 0.44555261E+01
+ 0.44407350E+01 0.44260072E+01 0.44113421E+01 0.43967395E+01 0.43821990E+01
+ 0.43677201E+01 0.43533025E+01 0.43389459E+01 0.43246498E+01 0.43104138E+01
+ 0.42962377E+01 0.42821210E+01 0.42680634E+01 0.42540645E+01 0.42401239E+01
+ 0.42262414E+01 0.42124166E+01 0.41986490E+01 0.41849384E+01 0.41712845E+01
+ 0.41576868E+01 0.41441451E+01 0.41306590E+01 0.41172281E+01 0.41038523E+01
+ 0.40905310E+01 0.40772641E+01 0.40640512E+01 0.40508919E+01 0.40377859E+01
+ 0.40247330E+01 0.40117329E+01 0.39987851E+01 0.39858895E+01 0.39730456E+01
+ 0.39602533E+01 0.39475122E+01 0.39348219E+01 0.39221823E+01 0.39095930E+01
+ 0.38970538E+01 0.38845643E+01 0.38721242E+01 0.38597333E+01 0.38473913E+01
+ 0.38350979E+01 0.38228529E+01 0.38106559E+01 0.37985067E+01 0.37864050E+01
+ 0.37743506E+01 0.37623431E+01 0.37503824E+01 0.37384681E+01 0.37266000E+01
+ 0.37147778E+01 0.37030013E+01 0.36912703E+01 0.36795844E+01 0.36679434E+01
+ 0.36563471E+01 0.36447952E+01 0.36332875E+01 0.36218237E+01 0.36104036E+01
+ 0.35990269E+01 0.35876935E+01 0.35764030E+01 0.35651553E+01 0.35539501E+01
+ 0.35427871E+01 0.35316662E+01 0.35205871E+01 0.35095496E+01 0.34985535E+01
+ 0.34875985E+01 0.34766844E+01 0.34658110E+01 0.34549781E+01 0.34441855E+01
+ 0.34334329E+01 0.34227201E+01 0.34120470E+01 0.34014133E+01 0.33908188E+01
+ 0.33802633E+01 0.33697465E+01 0.33592684E+01 0.33488286E+01 0.33384270E+01
+ 0.33280634E+01 0.33177376E+01 0.33074493E+01 0.32971985E+01 0.32869848E+01
+ 0.32768081E+01 0.32666683E+01 0.32565650E+01 0.32464982E+01 0.32364676E+01
+ 0.32264731E+01 0.32165144E+01 0.32065914E+01 0.31967040E+01 0.31868518E+01
+ 0.31770348E+01 0.31672527E+01 0.31575054E+01 0.31477927E+01 0.31381145E+01
+ 0.31284705E+01 0.31188606E+01 0.31092846E+01 0.30997423E+01 0.30902336E+01
+ 0.30807583E+01 0.30713163E+01 0.30619073E+01 0.30525312E+01 0.30431879E+01
+ 0.30338772E+01 0.30245988E+01 0.30153527E+01 0.30061388E+01 0.29969567E+01
+ 0.29878065E+01 0.29786879E+01 0.29696007E+01 0.29605449E+01 0.29515202E+01
+ 0.29425265E+01 0.29335638E+01 0.29246317E+01 0.29157302E+01 0.29068591E+01
+ 0.28980182E+01 0.28892075E+01 0.28804268E+01 0.28716759E+01 0.28629547E+01
+ 0.28542631E+01 0.28456009E+01 0.28369679E+01 0.28283641E+01 0.28197892E+01
+ 0.28112432E+01 0.28027260E+01 0.27942373E+01 0.27857770E+01 0.27773451E+01
+ 0.27689414E+01 0.27605657E+01 0.27522179E+01 0.27438979E+01 0.27356056E+01
+ 0.27273408E+01 0.27191034E+01 0.27108933E+01 0.27027103E+01 0.26945544E+01
+ 0.26864253E+01 0.26783230E+01 0.26702474E+01 0.26621983E+01 0.26541756E+01
+ 0.26461792E+01 0.26382090E+01 0.26302648E+01 0.26223466E+01 0.26144541E+01
+ 0.26065874E+01 0.25987462E+01 0.25909305E+01 0.25831402E+01 0.25753751E+01
+ 0.25676351E+01 0.25599201E+01 0.25522301E+01 0.25445648E+01 0.25369242E+01
+ 0.25293081E+01 0.25217165E+01 0.25141493E+01 0.25066063E+01 0.24990875E+01
+ 0.24915927E+01 0.24841218E+01 0.24766747E+01 0.24692514E+01 0.24618516E+01
+ 0.24544754E+01 0.24471226E+01 0.24397930E+01 0.24324867E+01 0.24252035E+01
+ 0.24179433E+01 0.24107060E+01 0.24034915E+01 0.23962997E+01 0.23891306E+01
+ 0.23819839E+01 0.23748596E+01 0.23677577E+01 0.23606780E+01 0.23536205E+01
+ 0.23465849E+01 0.23395714E+01 0.23325796E+01 0.23256097E+01 0.23186614E+01
+ 0.23117347E+01 0.23048294E+01 0.22979456E+01 0.22910831E+01 0.22842418E+01
+ 0.22774216E+01 0.22706225E+01 0.22638443E+01 0.22570870E+01 0.22503504E+01
+ 0.22436346E+01 0.22369394E+01 0.22302647E+01 0.22236105E+01 0.22169766E+01
+ 0.22103630E+01 0.22037695E+01 0.21971962E+01 0.21906429E+01 0.21841096E+01
+ 0.21775961E+01 0.21711024E+01 0.21646285E+01 0.21581741E+01 0.21517393E+01
+ 0.21453240E+01 0.21389280E+01 0.21325514E+01 0.21261940E+01 0.21198558E+01
+ 0.21135366E+01 0.21072365E+01 0.21009553E+01 0.20946930E+01 0.20884494E+01
+ 0.20822245E+01 0.20760183E+01 0.20698307E+01 0.20636615E+01 0.20575107E+01
+ 0.20513783E+01 0.20452642E+01 0.20391683E+01 0.20330905E+01 0.20270308E+01
+ 0.20209890E+01 0.20149652E+01 0.20089592E+01 0.20029710E+01 0.19970006E+01
+ 0.19910478E+01 0.19851125E+01 0.19791948E+01 0.19732945E+01 0.19674116E+01
+ 0.19615460E+01 0.19556977E+01 0.19498666E+01 0.19440525E+01 0.19382556E+01
+ 0.19324756E+01 0.19267125E+01 0.19209663E+01 0.19152369E+01 0.19095242E+01
+ 0.19038282E+01 0.18981489E+01 0.18924860E+01 0.18868397E+01 0.18812098E+01
+ 0.18755962E+01 0.18699990E+01 0.18644180E+01 0.18588532E+01 0.18533045E+01
+ 0.18477719E+01 0.18422553E+01 0.18367546E+01 0.18312698E+01 0.18258009E+01
+ 0.18203477E+01 0.18149103E+01 0.18094885E+01 0.18040824E+01 0.17986918E+01
+ 0.17933166E+01 0.17879569E+01 0.17826126E+01 0.17772837E+01 0.17719700E+01
+ 0.17666715E+01 0.17613882E+01 0.17561200E+01 0.17508668E+01 0.17456287E+01
+ 0.17404055E+01 0.17351972E+01 0.17300037E+01 0.17248250E+01 0.17196611E+01
+ 0.17145119E+01 0.17093773E+01 0.17042573E+01 0.16991518E+01 0.16940608E+01
+ 0.16889843E+01 0.16839221E+01 0.16788743E+01 0.16738408E+01 0.16688214E+01
+ 0.16638163E+01 0.16588253E+01 0.16538484E+01 0.16488856E+01 0.16439367E+01
+ 0.16390018E+01 0.16340808E+01 0.16291737E+01 0.16242803E+01 0.16194007E+01
+ 0.16145348E+01 0.16096826E+01 0.16048440E+01 0.16000190E+01 0.15952075E+01
+ 0.15904094E+01 0.15856249E+01 0.15808537E+01 0.15760958E+01 0.15713513E+01
+ 0.15666200E+01 0.15619019E+01 0.15571970E+01 0.15525052E+01 0.15478266E+01
+ 0.15431609E+01 0.15385083E+01 0.15338686E+01 0.15292418E+01 0.15246279E+01
+ 0.15200268E+01 0.15154385E+01 0.15108629E+01 0.15063001E+01 0.15017499E+01
+ 0.14972123E+01 0.14926874E+01 0.14881749E+01 0.14836750E+01 0.14791875E+01
+ 0.14747124E+01 0.14702497E+01 0.14657994E+01 0.14613613E+01 0.14569356E+01
+ 0.14525220E+01 0.14481206E+01 0.14437314E+01 0.14393542E+01 0.14349892E+01
+ 0.14306362E+01 0.14262951E+01 0.14219660E+01 0.14176489E+01 0.14133436E+01
+ 0.14090501E+01 0.14047685E+01 0.14004986E+01 0.13962405E+01 0.13919940E+01
+ 0.13877592E+01 0.13835360E+01 0.13793245E+01 0.13751244E+01 0.13709359E+01
+ 0.13667589E+01 0.13625933E+01 0.13584391E+01 0.13542963E+01 0.13501648E+01
+ 0.13460447E+01 0.13419358E+01 0.13378381E+01 0.13337517E+01 0.13296764E+01
+ 0.13256122E+01 0.13215592E+01 0.13175172E+01 0.13134862E+01 0.13094663E+01
+ 0.13054573E+01 0.13014592E+01 0.12974721E+01 0.12934958E+01 0.12895304E+01
+ 0.12855757E+01 0.12816318E+01 0.12776987E+01 0.12737763E+01 0.12698645E+01
+ 0.12659634E+01 0.12620730E+01 0.12581931E+01 0.12543237E+01 0.12504649E+01
+ 0.12466165E+01 0.12427786E+01 0.12389512E+01 0.12351341E+01 0.12313274E+01
+ 0.12275311E+01 0.12237450E+01 0.12199692E+01 0.12162037E+01 0.12124484E+01
+ 0.12087033E+01 0.12049683E+01 0.12012435E+01 0.11975287E+01 0.11938241E+01
+ 0.11901295E+01 0.11864449E+01 0.11827702E+01 0.11791056E+01 0.11754508E+01
+ 0.11718060E+01 0.11681710E+01 0.11645459E+01 0.11609306E+01 0.11573251E+01
+ 0.11537293E+01 0.11501433E+01 0.11465669E+01 0.11430003E+01 0.11394433E+01
+ 0.11358959E+01 0.11323581E+01 0.11288299E+01 0.11253113E+01 0.11218021E+01
+ 0.11183025E+01 0.11148123E+01 0.11113315E+01 0.11078602E+01 0.11043982E+01
+ 0.11009456E+01 0.10975023E+01 0.10940684E+01 0.10906437E+01 0.10872283E+01
+ 0.10838221E+01 0.10804251E+01 0.10770373E+01 0.10736586E+01 0.10702891E+01
+ 0.10669287E+01 0.10635774E+01 0.10602351E+01 0.10569018E+01 0.10535776E+01
+ 0.10502623E+01 0.10469560E+01 0.10436587E+01 0.10403702E+01 0.10370907E+01
+ 0.10338199E+01 0.10305581E+01 0.10273050E+01 0.10240608E+01 0.10208253E+01
+ 0.10175985E+01 0.10143805E+01 0.10111711E+01 0.10079705E+01 0.10047785E+01
+ 0.10015951E+01 0.99842029E+00 0.99525409E+00 0.99209646E+00 0.98894736E+00
+ 0.98580677E+00 0.98267468E+00 0.97955105E+00 0.97643588E+00 0.97332913E+00
+ 0.97023078E+00 0.96714081E+00 0.96405920E+00 0.96098593E+00 0.95792098E+00
+ 0.95486432E+00 0.95181593E+00 0.94877579E+00 0.94574388E+00 0.94272018E+00
+ 0.93970467E+00 0.93669732E+00 0.93369811E+00 0.93070703E+00 0.92772406E+00
+ 0.92474916E+00 0.92178232E+00 0.91882353E+00 0.91587275E+00 0.91292997E+00
+ 0.90999517E+00 0.90706833E+00 0.90414943E+00 0.90123844E+00 0.89833535E+00
+ 0.89544014E+00 0.89255279E+00 0.88967327E+00 0.88680157E+00 0.88393767E+00
+ 0.88108154E+00 0.87823317E+00 0.87539254E+00 0.87255963E+00 0.86973442E+00
+ 0.86691689E+00 0.86410701E+00 0.86130478E+00 0.85851017E+00 0.85572317E+00
+ 0.85294375E+00 0.85017189E+00 0.84740758E+00 0.84465079E+00 0.84190152E+00
+ 0.83915973E+00 0.83642542E+00 0.83369855E+00 0.83097912E+00 0.82826711E+00
+ 0.82556249E+00 0.82286525E+00 0.82017537E+00 0.81749283E+00 0.81481762E+00
+ 0.81214971E+00 0.80948909E+00 0.80683574E+00 0.80418964E+00 0.80155078E+00
+ 0.79891913E+00 0.79629468E+00 0.79367741E+00 0.79106730E+00 0.78846434E+00
+ 0.78586850E+00 0.78327978E+00 0.78069815E+00 0.77812360E+00 0.77555610E+00
+ 0.77299565E+00 0.77044222E+00 0.76789579E+00 0.76535636E+00 0.76282390E+00
+ 0.76029840E+00 0.75777983E+00 0.75526819E+00 0.75276345E+00 0.75026561E+00
+ 0.74777463E+00 0.74529051E+00 0.74281323E+00 0.74034277E+00 0.73787912E+00
+ 0.73542226E+00 0.73297217E+00 0.73052884E+00 0.72809224E+00 0.72566238E+00
+ 0.72323922E+00 0.72082275E+00 0.71841296E+00 0.71600983E+00 0.71361335E+00
+ 0.71122349E+00 0.70884025E+00 0.70646360E+00 0.70409353E+00 0.70173003E+00
+ 0.69937308E+00 0.69702266E+00 0.69467876E+00 0.69234137E+00 0.69001046E+00
+ 0.68768602E+00 0.68536804E+00 0.68305650E+00 0.68075139E+00 0.67845269E+00
+ 0.67616038E+00 0.67387446E+00 0.67159490E+00 0.66932169E+00 0.66705481E+00
+ 0.66479426E+00 0.66254001E+00 0.66029205E+00 0.65805036E+00 0.65581494E+00
+ 0.65358577E+00 0.65136282E+00 0.64914609E+00 0.64693557E+00 0.64473123E+00
+ 0.64253306E+00 0.64034105E+00 0.63815519E+00 0.63597546E+00 0.63380184E+00
+ 0.63163432E+00 0.62947289E+00 0.62731753E+00 0.62516823E+00 0.62302497E+00
+ 0.62088774E+00 0.61875653E+00 0.61663131E+00 0.61451209E+00 0.61239884E+00
+ 0.61029155E+00 0.60819020E+00 0.60609479E+00 0.60400529E+00 0.60192170E+00
+ 0.59984400E+00 0.59777217E+00 0.59570621E+00 0.59364610E+00 0.59159182E+00
+ 0.58954336E+00 0.58750071E+00 0.58546386E+00 0.58343279E+00 0.58140749E+00
+ 0.57938794E+00 0.57737413E+00 0.57536605E+00 0.57336368E+00 0.57136702E+00
+ 0.56937604E+00 0.56739074E+00 0.56541110E+00 0.56343711E+00 0.56146876E+00
+ 0.55950603E+00 0.55754890E+00 0.55559738E+00 0.55365143E+00 0.55171106E+00
+ 0.54977624E+00 0.54784697E+00 0.54592323E+00 0.54400501E+00 0.54209230E+00
+ 0.54018508E+00 0.53828334E+00 0.53638707E+00 0.53449625E+00 0.53261088E+00
+ 0.53073094E+00 0.52885642E+00 0.52698730E+00 0.52512357E+00 0.52326523E+00
+ 0.52141225E+00 0.51956463E+00 0.51772235E+00 0.51588540E+00 0.51405377E+00
+ 0.51222744E+00 0.51040641E+00 0.50859067E+00 0.50678019E+00 0.50497497E+00
+ 0.50317499E+00 0.50138025E+00 0.49959073E+00 0.49780641E+00 0.49602730E+00
+ 0.49425337E+00 0.49248461E+00 0.49072101E+00 0.48896257E+00 0.48720926E+00
+ 0.48546107E+00 0.48371800E+00 0.48198003E+00 0.48024715E+00 0.47851935E+00
+ 0.47679662E+00 0.47507894E+00 0.47336630E+00 0.47165870E+00 0.46995611E+00
+ 0.46825854E+00 0.46656596E+00 0.46487836E+00 0.46319574E+00 0.46151808E+00
+ 0.45984537E+00 0.45817760E+00 0.45651476E+00 0.45485684E+00 0.45320382E+00
+ 0.45155570E+00 0.44991245E+00 0.44827408E+00 0.44664057E+00 0.44501191E+00
+ 0.44338808E+00 0.44176908E+00 0.44015490E+00 0.43854552E+00 0.43694093E+00
+ 0.43534113E+00 0.43374609E+00 0.43215582E+00 0.43057029E+00 0.42898950E+00
+ 0.42741344E+00 0.42584210E+00 0.42427546E+00 0.42271351E+00 0.42115624E+00
+ 0.41960365E+00 0.41805572E+00 0.41651244E+00 0.41497380E+00 0.41343979E+00
+ 0.41191039E+00 0.41038561E+00 0.40886542E+00 0.40734981E+00 0.40583878E+00
+ 0.40433232E+00 0.40283041E+00 0.40133305E+00 0.39984021E+00 0.39835190E+00
+ 0.39686810E+00 0.39538880E+00 0.39391400E+00 0.39244367E+00 0.39097781E+00
+ 0.38951641E+00 0.38805947E+00 0.38660696E+00 0.38515887E+00 0.38371521E+00
+ 0.38227595E+00 0.38084110E+00 0.37941062E+00 0.37798453E+00 0.37656280E+00
+ 0.37514543E+00 0.37373240E+00 0.37232371E+00 0.37091934E+00 0.36951930E+00
+ 0.36812355E+00 0.36673210E+00 0.36534494E+00 0.36396205E+00 0.36258343E+00
+ 0.36120906E+00 0.35983893E+00 0.35847305E+00 0.35711138E+00 0.35575393E+00
+ 0.35440069E+00 0.35305164E+00 0.35170678E+00 0.35036609E+00 0.34902957E+00
+ 0.34769721E+00 0.34636899E+00 0.34504490E+00 0.34372494E+00 0.34240910E+00
+ 0.34109737E+00 0.33978973E+00 0.33848618E+00 0.33718671E+00 0.33589130E+00
+ 0.33459996E+00 0.33331266E+00 0.33202940E+00 0.33075017E+00 0.32947496E+00
+ 0.32820376E+00 0.32693656E+00 0.32567336E+00 0.32441413E+00 0.32315888E+00
+ 0.32190759E+00 0.32066025E+00 0.31941685E+00 0.31817739E+00 0.31694186E+00
+ 0.31571024E+00 0.31448252E+00 0.31325870E+00 0.31203877E+00 0.31082272E+00
+ 0.30961054E+00 0.30840221E+00 0.30719774E+00 0.30599710E+00 0.30480030E+00
+ 0.30360732E+00 0.30241815E+00 0.30123279E+00 0.30005122E+00 0.29887344E+00
+ 0.29769943E+00 0.29652919E+00 0.29536271E+00 0.29419997E+00 0.29304098E+00
+ 0.29188572E+00 0.29073417E+00 0.28958634E+00 0.28844222E+00 0.28730179E+00
+ 0.28616504E+00 0.28503197E+00 0.28390257E+00 0.28277683E+00 0.28165474E+00
+ 0.28053628E+00 0.27942146E+00 0.27831027E+00 0.27720268E+00 0.27609870E+00
+ 0.27499832E+00 0.27390153E+00 0.27280831E+00 0.27171867E+00 0.27063258E+00
+ 0.26955005E+00 0.26847106E+00 0.26739560E+00 0.26632368E+00 0.26525526E+00
+ 0.26419036E+00 0.26312896E+00 0.26207105E+00 0.26101662E+00 0.25996566E+00
+ 0.25891817E+00 0.25787414E+00 0.25683356E+00 0.25579641E+00 0.25476270E+00
+ 0.25373240E+00 0.25270553E+00 0.25168205E+00 0.25066198E+00 0.24964529E+00
+ 0.24863198E+00 0.24762204E+00 0.24661547E+00 0.24561225E+00 0.24461238E+00
+ 0.24361584E+00 0.24262263E+00 0.24163275E+00 0.24064617E+00 0.23966290E+00
+ 0.23868293E+00 0.23770624E+00 0.23673283E+00 0.23576270E+00 0.23479582E+00
+ 0.23383220E+00 0.23287183E+00 0.23191469E+00 0.23096078E+00 0.23001009E+00
+ 0.22906262E+00 0.22811835E+00 0.22717727E+00 0.22623939E+00 0.22530468E+00
+ 0.22437315E+00 0.22344478E+00 0.22251957E+00 0.22159750E+00 0.22067857E+00
+ 0.21976278E+00 0.21885011E+00 0.21794055E+00 0.21703410E+00 0.21613075E+00
+ 0.21523049E+00 0.21433331E+00 0.21343921E+00 0.21254818E+00 0.21166020E+00
+ 0.21077528E+00 0.20989340E+00 0.20901455E+00 0.20813873E+00 0.20726594E+00
+ 0.20639615E+00 0.20552936E+00 0.20466558E+00 0.20380478E+00 0.20294696E+00
+ 0.20209211E+00 0.20124022E+00 0.20039130E+00 0.19954532E+00 0.19870228E+00
+ 0.19786218E+00 0.19702500E+00 0.19619074E+00 0.19535938E+00 0.19453093E+00
+ 0.19370538E+00 0.19288271E+00 0.19206292E+00 0.19124600E+00 0.19043195E+00
+ 0.18962075E+00 0.18881240E+00 0.18800689E+00 0.18720421E+00 0.18640436E+00
+ 0.18560732E+00 0.18481310E+00 0.18402168E+00 0.18323305E+00 0.18244721E+00
+ 0.18166415E+00 0.18088387E+00 0.18010635E+00 0.17933158E+00 0.17855957E+00
+ 0.17779029E+00 0.17702375E+00 0.17625994E+00 0.17549885E+00 0.17474047E+00
+ 0.17398480E+00 0.17323182E+00 0.17248153E+00 0.17173393E+00 0.17098900E+00
+ 0.17024674E+00 0.16950714E+00 0.16877019E+00 0.16803589E+00 0.16730422E+00
+ 0.16657519E+00 0.16584878E+00 0.16512498E+00 0.16440380E+00 0.16368521E+00
+ 0.16296922E+00 0.16225582E+00 0.16154500E+00 0.16083675E+00 0.16013106E+00
+ 0.15942794E+00 0.15872736E+00 0.15802932E+00 0.15733383E+00 0.15664086E+00
+ 0.15595041E+00 0.15526248E+00 0.15457705E+00 0.15389413E+00 0.15321370E+00
+ 0.15253575E+00 0.15186028E+00 0.15118729E+00 0.15051676E+00 0.14984868E+00
+ 0.14918306E+00 0.14851987E+00 0.14785913E+00 0.14720081E+00 0.14654491E+00
+ 0.14589143E+00 0.14524036E+00 0.14459169E+00 0.14394541E+00 0.14330151E+00
+ 0.14266000E+00 0.14202085E+00 0.14138408E+00 0.14074966E+00 0.14011759E+00
+ 0.13948786E+00 0.13886048E+00 0.13823542E+00 0.13761269E+00 0.13699227E+00
+ 0.13637416E+00 0.13575835E+00 0.13514484E+00 0.13453361E+00 0.13392467E+00
+ 0.13331800E+00 0.13271360E+00 0.13211146E+00 0.13151157E+00 0.13091393E+00
+ 0.13031853E+00 0.12972536E+00 0.12913441E+00 0.12854569E+00 0.12795917E+00
+ 0.12737487E+00 0.12679275E+00 0.12621284E+00 0.12563510E+00 0.12505954E+00
+ 0.12448615E+00 0.12391493E+00 0.12334586E+00 0.12277895E+00 0.12221417E+00
+ 0.12165153E+00 0.12109102E+00 0.12053264E+00 0.11997636E+00 0.11942220E+00
+ 0.11887014E+00 0.11832017E+00 0.11777230E+00 0.11722650E+00 0.11668278E+00
+ 0.11614112E+00 0.11560153E+00 0.11506398E+00 0.11452849E+00 0.11399504E+00
+ 0.11346362E+00 0.11293422E+00 0.11240685E+00 0.11188149E+00 0.11135813E+00
+ 0.11083677E+00 0.11031741E+00 0.10980003E+00 0.10928463E+00 0.10877120E+00
+ 0.10825973E+00 0.10775023E+00 0.10724267E+00 0.10673706E+00 0.10623339E+00
+ 0.10573165E+00 0.10523183E+00 0.10473392E+00 0.10423793E+00 0.10374384E+00
+ 0.10325165E+00 0.10276134E+00 0.10227292E+00 0.10178638E+00 0.10130170E+00
+ 0.10081888E+00 0.10033792E+00 0.99858808E-01 0.99381536E-01 0.98906098E-01
+ 0.98432487E-01 0.97960696E-01 0.97490719E-01 0.97022547E-01 0.96556176E-01
+ 0.96091596E-01 0.95628802E-01 0.95167787E-01 0.94708543E-01 0.94251063E-01
+ 0.93795341E-01 0.93341369E-01 0.92889141E-01 0.92438648E-01 0.91989886E-01
+ 0.91542845E-01 0.91097519E-01 0.90653902E-01 0.90211986E-01 0.89771763E-01
+ 0.89333227E-01 0.88896371E-01 0.88461187E-01 0.88027668E-01 0.87595808E-01
+ 0.87165598E-01 0.86737032E-01 0.86310103E-01 0.85884802E-01 0.85461124E-01
+ 0.85039060E-01 0.84618604E-01 0.84199748E-01 0.83782485E-01 0.83366807E-01
+ 0.82952707E-01 0.82540178E-01 0.82129212E-01 0.81719802E-01 0.81311940E-01
+ 0.80905619E-01 0.80500832E-01 0.80097571E-01 0.79695828E-01 0.79295596E-01
+ 0.78896867E-01 0.78499634E-01 0.78103889E-01 0.77709624E-01 0.77316833E-01
+ 0.76925506E-01 0.76535636E-01 0.76147217E-01 0.75760239E-01 0.75374695E-01
+ 0.74990577E-01 0.74607877E-01 0.74226588E-01 0.73846702E-01 0.73468210E-01
+ 0.73091104E-01 0.72715377E-01 0.72341021E-01 0.71968027E-01 0.71596387E-01
+ 0.71226094E-01 0.70857139E-01 0.70489513E-01 0.70123209E-01 0.69758219E-01
+ 0.69394533E-01 0.69032144E-01 0.68671043E-01 0.68311222E-01 0.67952673E-01
+ 0.67595386E-01 0.67239354E-01 0.66884568E-01 0.66531018E-01 0.66178697E-01
+ 0.65827596E-01 0.65477707E-01 0.65129019E-01 0.64781525E-01 0.64435215E-01
+ 0.64090082E-01 0.63746114E-01 0.63403305E-01 0.63061645E-01 0.62721124E-01
+ 0.62381734E-01 0.62043465E-01 0.61706308E-01 0.61370254E-01 0.61035294E-01
+ 0.60701418E-01 0.60368617E-01 0.60036881E-01 0.59706201E-01 0.59376567E-01
+ 0.59047970E-01 0.58720400E-01 0.58393847E-01 0.58068302E-01 0.57743755E-01
+ 0.57420196E-01 0.57097615E-01 0.56776002E-01 0.56455347E-01 0.56135640E-01
+ 0.55816871E-01 0.55499031E-01 0.55182107E-01 0.54866091E-01 0.54550973E-01
+ 0.54236740E-01 0.53923385E-01 0.53610895E-01 0.53299260E-01 0.52988470E-01
+ 0.52678515E-01 0.52369383E-01 0.52061064E-01 0.51753547E-01 0.51446821E-01
+ 0.51140876E-01 0.50835700E-01 0.50531283E-01 0.50227614E-01 0.49924681E-01
+ 0.49622474E-01 0.49320981E-01 0.49020191E-01 0.48720093E-01 0.48420677E-01
+ 0.48121929E-01 0.47823840E-01 0.47526398E-01 0.47229592E-01 0.46933409E-01
+ 0.46637839E-01 0.46342870E-01 0.46048490E-01 0.45754689E-01 0.45461454E-01
+ 0.45168774E-01 0.44876638E-01 0.44585033E-01 0.44293948E-01 0.44003372E-01
+ 0.43713292E-01 0.43423697E-01 0.43134576E-01 0.42845917E-01 0.42557707E-01
+ 0.42269936E-01 0.41982592E-01 0.41695663E-01 0.41409137E-01 0.41123004E-01
+ 0.40837251E-01 0.40551866E-01 0.40266839E-01 0.39982158E-01 0.39697811E-01
+ 0.39413787E-01 0.39130075E-01 0.38846663E-01 0.38563541E-01 0.38280697E-01
+ 0.37998120E-01 0.37715800E-01 0.37433724E-01 0.37151884E-01 0.36870267E-01
+ 0.36588864E-01 0.36307664E-01 0.36026657E-01 0.35745833E-01 0.35465181E-01
+ 0.35184692E-01 0.34904357E-01 0.34624165E-01 0.34344107E-01 0.34064175E-01
+ 0.33784360E-01 0.33504652E-01 0.33225043E-01 0.32945526E-01 0.32666091E-01
+ 0.32386733E-01 0.32107442E-01 0.31828212E-01 0.31549036E-01 0.31269907E-01
+ 0.30990820E-01 0.30711769E-01 0.30432747E-01 0.30153750E-01 0.29874773E-01
+ 0.29595812E-01 0.29316863E-01 0.29037922E-01 0.28758986E-01 0.28480053E-01
+ 0.28201120E-01 0.27922186E-01 0.27643250E-01 0.27364311E-01 0.27085369E-01
+ 0.26806425E-01 0.26527480E-01 0.26248535E-01 0.25969593E-01 0.25690658E-01
+ 0.25411731E-01 0.25132819E-01 0.24853925E-01 0.24575057E-01 0.24296219E-01
+ 0.24017420E-01 0.23738668E-01 0.23459971E-01 0.23181338E-01 0.22902782E-01
+ 0.22624312E-01 0.22345941E-01 0.22067683E-01 0.21789550E-01 0.21511559E-01
+ 0.21233726E-01 0.20956066E-01 0.20678598E-01 0.20401341E-01 0.20124315E-01
+ 0.19847541E-01 0.19571041E-01 0.19294837E-01 0.19018955E-01 0.18743419E-01
+ 0.18468256E-01 0.18193494E-01 0.17919161E-01 0.17645286E-01 0.17371902E-01
+ 0.17099040E-01 0.16826733E-01 0.16555016E-01 0.16283924E-01 0.16013495E-01
+ 0.15743766E-01 0.15474777E-01 0.15206568E-01 0.14939180E-01 0.14672656E-01
+ 0.14407041E-01 0.14142378E-01 0.13878715E-01 0.13616098E-01 0.13354575E-01
+ 0.13094196E-01 0.12835012E-01 0.12577073E-01 0.12320432E-01 0.12065143E-01
+ 0.11811259E-01 0.11558835E-01 0.11307928E-01 0.11058594E-01 0.10810890E-01
+ 0.10564875E-01 0.10320606E-01 0.10078145E-01 0.98375490E-02 0.95988795E-02
+ 0.93621966E-02 0.91275611E-02 0.88950340E-02 0.86646764E-02 0.84365493E-02
+ 0.82107137E-02 0.79872307E-02 0.77661607E-02 0.75475643E-02 0.73315012E-02
+ 0.71180309E-02 0.69072119E-02 0.66991023E-02 0.64937590E-02 0.62912383E-02
+ 0.60915951E-02 0.58948831E-02 0.57011549E-02 0.55104615E-02 0.53228523E-02
+ 0.51383750E-02 0.49570757E-02 0.47789983E-02 0.46041849E-02 0.44326752E-02
+ 0.42645069E-02 0.40997151E-02 0.39383324E-02 0.37803890E-02 0.36259121E-02
+ 0.34749263E-02 0.33274532E-02 0.31835115E-02 0.30431166E-02 0.29062809E-02
+ 0.27730135E-02 0.26433203E-02 0.25172037E-02 0.23946626E-02 0.22756928E-02
+ 0.21602862E-02 0.20484313E-02 0.19401132E-02 0.18353133E-02 0.17340096E-02
+ 0.16361764E-02 0.15417845E-02 0.14508015E-02 0.13631912E-02 0.12789144E-02
+ 0.11979283E-02 0.11201871E-02 0.10456417E-02 0.97424019E-03 0.90592753E-03
+ 0.84064603E-03 0.77833529E-03 0.71893240E-03 0.66237211E-03 0.60858692E-03
+ 0.55750733E-03 0.50906196E-03 0.46317774E-03 0.41978011E-03 0.37879322E-03
+ 0.34014007E-03 0.30374279E-03 0.26952277E-03 0.23740090E-03 0.20729778E-03
+ 0.17913386E-03 0.15282974E-03 0.12830627E-03 0.10548479E-03 0.84287317E-04
+ 0.64636727E-04 0.46456913E-04 0.29672970E-04 0.14211347E-04 0.00000000E+00
+ 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03
+ 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03
+ 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03
+ 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03
+ 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03
+ 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03
+ 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03
+ 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03
+ 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03 0.18374826E+03
+ 0.18353199E+03 0.17866225E+03 0.17402229E+03 0.16959671E+03 0.16537144E+03
+ 0.16133361E+03 0.15747138E+03 0.15377390E+03 0.15023116E+03 0.14683396E+03
+ 0.14357377E+03 0.14044274E+03 0.13743356E+03 0.13453948E+03 0.13175422E+03
+ 0.12907195E+03 0.12648724E+03 0.12399502E+03 0.12159057E+03 0.11926947E+03
+ 0.11702760E+03 0.11486110E+03 0.11276634E+03 0.11073994E+03 0.10877869E+03
+ 0.10687962E+03 0.10503989E+03 0.10325686E+03 0.10152802E+03 0.99851023E+02
+ 0.98223640E+02 0.96643769E+02 0.95109424E+02 0.93618727E+02 0.92169899E+02
+ 0.90761256E+02 0.89391200E+02 0.88058216E+02 0.86760866E+02 0.85497786E+02
+ 0.84267676E+02 0.83069302E+02 0.81901491E+02 0.80763123E+02 0.79653135E+02
+ 0.78570509E+02 0.77514279E+02 0.76483520E+02 0.75477351E+02 0.74494929E+02
+ 0.73535450E+02 0.72598143E+02 0.71682273E+02 0.70787135E+02 0.69912055E+02
+ 0.69056387E+02 0.68219512E+02 0.67400837E+02 0.66599793E+02 0.65815833E+02
+ 0.65048434E+02 0.64297092E+02 0.63561325E+02 0.62840667E+02 0.62134673E+02
+ 0.61442912E+02 0.60764973E+02 0.60100456E+02 0.59448981E+02 0.58810178E+02
+ 0.58183692E+02 0.57569182E+02 0.56966317E+02 0.56374780E+02 0.55794264E+02
+ 0.55224473E+02 0.54665122E+02 0.54115935E+02 0.53576646E+02 0.53046998E+02
+ 0.52526742E+02 0.52015638E+02 0.51513453E+02 0.51019964E+02 0.50534954E+02
+ 0.50058211E+02 0.49589533E+02 0.49128724E+02 0.48675591E+02 0.48229951E+02
+ 0.47791625E+02 0.47360440E+02 0.46936227E+02 0.46518824E+02 0.46108073E+02
+ 0.45703821E+02 0.45305919E+02 0.44914223E+02 0.44528594E+02 0.44148895E+02
+ 0.43774996E+02 0.43406767E+02 0.43044084E+02 0.42686827E+02 0.42334879E+02
+ 0.41988125E+02 0.41646454E+02 0.41309759E+02 0.40977935E+02 0.40650879E+02
+ 0.40328494E+02 0.40010681E+02 0.39697348E+02 0.39388403E+02 0.39083757E+02
+ 0.38783324E+02 0.38487018E+02 0.38194759E+02 0.37906465E+02 0.37622059E+02
+ 0.37341465E+02 0.37064610E+02 0.36791420E+02 0.36521825E+02 0.36255758E+02
+ 0.35993150E+02 0.35733937E+02 0.35478056E+02 0.35225443E+02 0.34976039E+02
+ 0.34729784E+02 0.34486621E+02 0.34246493E+02 0.34009346E+02 0.33775125E+02
+ 0.33543779E+02 0.33315255E+02 0.33089505E+02 0.32866478E+02 0.32646129E+02
+ 0.32428409E+02 0.32213273E+02 0.32000676E+02 0.31790576E+02 0.31582929E+02
+ 0.31377694E+02 0.31174830E+02 0.30974298E+02 0.30776057E+02 0.30580071E+02
+ 0.30386302E+02 0.30194713E+02 0.30005269E+02 0.29817934E+02 0.29632676E+02
+ 0.29449459E+02 0.29268252E+02 0.29089021E+02 0.28911737E+02 0.28736368E+02
+ 0.28562883E+02 0.28391254E+02 0.28221452E+02 0.28053447E+02 0.27887214E+02
+ 0.27722723E+02 0.27559948E+02 0.27398865E+02 0.27239446E+02 0.27081666E+02
+ 0.26925502E+02 0.26770929E+02 0.26617923E+02 0.26466461E+02 0.26316520E+02
+ 0.26168079E+02 0.26021114E+02 0.25875606E+02 0.25731532E+02 0.25588871E+02
+ 0.25447605E+02 0.25307712E+02 0.25169174E+02 0.25031970E+02 0.24896083E+02
+ 0.24761494E+02 0.24628184E+02 0.24496136E+02 0.24365332E+02 0.24235756E+02
+ 0.24107389E+02 0.23980217E+02 0.23854222E+02 0.23729389E+02 0.23605701E+02
+ 0.23483144E+02 0.23361702E+02 0.23241361E+02 0.23122105E+02 0.23003921E+02
+ 0.22886794E+02 0.22770711E+02 0.22655657E+02 0.22541620E+02 0.22428586E+02
+ 0.22316542E+02 0.22205475E+02 0.22095374E+02 0.21986225E+02 0.21878017E+02
+ 0.21770737E+02 0.21664374E+02 0.21558917E+02 0.21454354E+02 0.21350673E+02
+ 0.21247865E+02 0.21145917E+02 0.21044820E+02 0.20944564E+02 0.20845137E+02
+ 0.20746530E+02 0.20648732E+02 0.20551734E+02 0.20455527E+02 0.20360101E+02
+ 0.20265446E+02 0.20171553E+02 0.20078413E+02 0.19986018E+02 0.19894358E+02
+ 0.19803425E+02 0.19713211E+02 0.19623706E+02 0.19534903E+02 0.19446794E+02
+ 0.19359370E+02 0.19272625E+02 0.19186549E+02 0.19101135E+02 0.19016376E+02
+ 0.18932264E+02 0.18848793E+02 0.18765954E+02 0.18683741E+02 0.18602147E+02
+ 0.18521164E+02 0.18440787E+02 0.18361008E+02 0.18281820E+02 0.18203218E+02
+ 0.18125194E+02 0.18047743E+02 0.17970859E+02 0.17894534E+02 0.17818764E+02
+ 0.17743541E+02 0.17668861E+02 0.17594717E+02 0.17521104E+02 0.17448016E+02
+ 0.17375447E+02 0.17303392E+02 0.17231846E+02 0.17160803E+02 0.17090258E+02
+ 0.17020205E+02 0.16950641E+02 0.16881559E+02 0.16812954E+02 0.16744822E+02
+ 0.16677158E+02 0.16609957E+02 0.16543215E+02 0.16476926E+02 0.16411086E+02
+ 0.16345690E+02 0.16280735E+02 0.16216215E+02 0.16152126E+02 0.16088464E+02
+ 0.16025225E+02 0.15962405E+02 0.15899999E+02 0.15838003E+02 0.15776413E+02
+ 0.15715226E+02 0.15654437E+02 0.15594042E+02 0.15534038E+02 0.15474421E+02
+ 0.15415187E+02 0.15356332E+02 0.15297853E+02 0.15239746E+02 0.15182008E+02
+ 0.15124635E+02 0.15067623E+02 0.15010970E+02 0.14954672E+02 0.14898725E+02
+ 0.14843126E+02 0.14787872E+02 0.14732960E+02 0.14678387E+02 0.14624148E+02
+ 0.14570243E+02 0.14516666E+02 0.14463416E+02 0.14410488E+02 0.14357882E+02
+ 0.14305592E+02 0.14253617E+02 0.14201954E+02 0.14150599E+02 0.14099550E+02
+ 0.14048805E+02 0.13998360E+02 0.13948213E+02 0.13898361E+02 0.13848802E+02
+ 0.13799533E+02 0.13750551E+02 0.13701854E+02 0.13653439E+02 0.13605305E+02
+ 0.13557447E+02 0.13509865E+02 0.13462556E+02 0.13415516E+02 0.13368745E+02
+ 0.13322239E+02 0.13275997E+02 0.13230015E+02 0.13184293E+02 0.13138827E+02
+ 0.13093615E+02 0.13048656E+02 0.13003947E+02 0.12959486E+02 0.12915271E+02
+ 0.12871300E+02 0.12827570E+02 0.12784080E+02 0.12740828E+02 0.12697812E+02
+ 0.12655030E+02 0.12612480E+02 0.12570159E+02 0.12528067E+02 0.12486201E+02
+ 0.12444560E+02 0.12403141E+02 0.12361942E+02 0.12320963E+02 0.12280201E+02
+ 0.12239654E+02 0.12199321E+02 0.12159199E+02 0.12119288E+02 0.12079586E+02
+ 0.12040090E+02 0.12000800E+02 0.11961713E+02 0.11922829E+02 0.11884144E+02
+ 0.11845659E+02 0.11807370E+02 0.11769278E+02 0.11731379E+02 0.11693673E+02
+ 0.11656159E+02 0.11618834E+02 0.11581697E+02 0.11544747E+02 0.11507982E+02
+ 0.11471401E+02 0.11435002E+02 0.11398785E+02 0.11362747E+02 0.11326887E+02
+ 0.11291204E+02 0.11255697E+02 0.11220364E+02 0.11185204E+02 0.11150216E+02
+ 0.11115398E+02 0.11080749E+02 0.11046268E+02 0.11011953E+02 0.10977804E+02
+ 0.10943819E+02 0.10909996E+02 0.10876335E+02 0.10842835E+02 0.10809494E+02
+ 0.10776311E+02 0.10743285E+02 0.10710415E+02 0.10677699E+02 0.10645137E+02
+ 0.10612727E+02 0.10580469E+02 0.10548360E+02 0.10516401E+02 0.10484590E+02
+ 0.10452926E+02 0.10421408E+02 0.10390034E+02 0.10358805E+02 0.10327718E+02
+ 0.10296773E+02 0.10265969E+02 0.10235305E+02 0.10204779E+02 0.10174392E+02
+ 0.10144141E+02 0.10114026E+02 0.10084046E+02 0.10054200E+02 0.10024488E+02
+ 0.99949070E+01 0.99654576E+01 0.99361385E+01 0.99069489E+01 0.98778878E+01
+ 0.98489543E+01 0.98201476E+01 0.97914668E+01 0.97629111E+01 0.97344796E+01
+ 0.97061714E+01 0.96779858E+01 0.96499218E+01 0.96219787E+01 0.95941556E+01
+ 0.95664518E+01 0.95388664E+01 0.95113987E+01 0.94840478E+01 0.94568130E+01
+ 0.94296935E+01 0.94026885E+01 0.93757974E+01 0.93490192E+01 0.93223534E+01
+ 0.92957990E+01 0.92693555E+01 0.92430221E+01 0.92167980E+01 0.91906826E+01
+ 0.91646751E+01 0.91387749E+01 0.91129812E+01 0.90872934E+01 0.90617107E+01
+ 0.90362325E+01 0.90108581E+01 0.89855869E+01 0.89604181E+01 0.89353512E+01
+ 0.89103855E+01 0.88855203E+01 0.88607550E+01 0.88360890E+01 0.88115216E+01
+ 0.87870523E+01 0.87626803E+01 0.87384051E+01 0.87142261E+01 0.86901426E+01
+ 0.86661542E+01 0.86422601E+01 0.86184598E+01 0.85947527E+01 0.85711382E+01
+ 0.85476158E+01 0.85241849E+01 0.85008450E+01 0.84775954E+01 0.84544356E+01
+ 0.84313650E+01 0.84083832E+01 0.83854896E+01 0.83626836E+01 0.83399647E+01
+ 0.83173324E+01 0.82947861E+01 0.82723254E+01 0.82499497E+01 0.82276585E+01
+ 0.82054513E+01 0.81833275E+01 0.81612868E+01 0.81393286E+01 0.81174524E+01
+ 0.80956577E+01 0.80739441E+01 0.80523110E+01 0.80307580E+01 0.80092846E+01
+ 0.79878903E+01 0.79665747E+01 0.79453374E+01 0.79241777E+01 0.79030954E+01
+ 0.78820900E+01 0.78611609E+01 0.78403078E+01 0.78195303E+01 0.77988278E+01
+ 0.77782000E+01 0.77576464E+01 0.77371666E+01 0.77167601E+01 0.76964266E+01
+ 0.76761657E+01 0.76559768E+01 0.76358597E+01 0.76158139E+01 0.75958390E+01
+ 0.75759346E+01 0.75561003E+01 0.75363356E+01 0.75166403E+01 0.74970140E+01
+ 0.74774561E+01 0.74579664E+01 0.74385445E+01 0.74191900E+01 0.73999025E+01
+ 0.73806817E+01 0.73615271E+01 0.73424384E+01 0.73234153E+01 0.73044574E+01
+ 0.72855643E+01 0.72667357E+01 0.72479713E+01 0.72292705E+01 0.72106333E+01
+ 0.71920591E+01 0.71735476E+01 0.71550985E+01 0.71367115E+01 0.71183862E+01
+ 0.71001223E+01 0.70819195E+01 0.70637774E+01 0.70456957E+01 0.70276741E+01
+ 0.70097122E+01 0.69918098E+01 0.69739665E+01 0.69561821E+01 0.69384561E+01
+ 0.69207884E+01 0.69031785E+01 0.68856262E+01 0.68681312E+01 0.68506932E+01
+ 0.68333118E+01 0.68159869E+01 0.67987180E+01 0.67815049E+01 0.67643474E+01
+ 0.67472450E+01 0.67301976E+01 0.67132049E+01 0.66962665E+01 0.66793822E+01
+ 0.66625517E+01 0.66457748E+01 0.66290511E+01 0.66123804E+01 0.65957624E+01
+ 0.65791969E+01 0.65626836E+01 0.65462222E+01 0.65298124E+01 0.65134540E+01
+ 0.64971468E+01 0.64808905E+01 0.64646848E+01 0.64485294E+01 0.64324242E+01
+ 0.64163689E+01 0.64003632E+01 0.63844068E+01 0.63684996E+01 0.63526413E+01
+ 0.63368316E+01 0.63210703E+01 0.63053572E+01 0.62896920E+01 0.62740745E+01
+ 0.62585045E+01 0.62429817E+01 0.62275059E+01 0.62120769E+01 0.61966944E+01
+ 0.61813583E+01 0.61660682E+01 0.61508240E+01 0.61356255E+01 0.61204724E+01
+ 0.61053645E+01 0.60903016E+01 0.60752834E+01 0.60603099E+01 0.60453807E+01
+ 0.60304956E+01 0.60156545E+01 0.60008571E+01 0.59861032E+01 0.59713926E+01
+ 0.59567252E+01 0.59421006E+01 0.59275188E+01 0.59129794E+01 0.58984824E+01
+ 0.58840275E+01 0.58696145E+01 0.58552432E+01 0.58409134E+01 0.58266250E+01
+ 0.58123777E+01 0.57981713E+01 0.57840057E+01 0.57698807E+01 0.57557961E+01
+ 0.57417517E+01 0.57277473E+01 0.57137828E+01 0.56998579E+01 0.56859724E+01
+ 0.56721263E+01 0.56583193E+01 0.56445513E+01 0.56308220E+01 0.56171313E+01
+ 0.56034791E+01 0.55898650E+01 0.55762891E+01 0.55627511E+01 0.55492508E+01
+ 0.55357881E+01 0.55223627E+01 0.55089747E+01 0.54956237E+01 0.54823096E+01
+ 0.54690322E+01 0.54557915E+01 0.54425872E+01 0.54294191E+01 0.54162872E+01
+ 0.54031912E+01 0.53901310E+01 0.53771064E+01 0.53641173E+01 0.53511636E+01
+ 0.53382450E+01 0.53253615E+01 0.53125128E+01 0.52996989E+01 0.52869196E+01
+ 0.52741746E+01 0.52614640E+01 0.52487875E+01 0.52361450E+01 0.52235363E+01
+ 0.52109614E+01 0.51984200E+01 0.51859121E+01 0.51734374E+01 0.51609958E+01
+ 0.51485873E+01 0.51362116E+01 0.51238687E+01 0.51115583E+01 0.50992804E+01
+ 0.50870349E+01 0.50748215E+01 0.50626401E+01 0.50504907E+01 0.50383731E+01
+ 0.50262871E+01 0.50142327E+01 0.50022097E+01 0.49902179E+01 0.49782573E+01
+ 0.49663277E+01 0.49544290E+01 0.49425611E+01 0.49307238E+01 0.49189170E+01
+ 0.49071407E+01 0.48953946E+01 0.48836786E+01 0.48719927E+01 0.48603367E+01
+ 0.48487105E+01 0.48371140E+01 0.48255470E+01 0.48140095E+01 0.48025013E+01
+ 0.47910223E+01 0.47795724E+01 0.47681514E+01 0.47567594E+01 0.47453961E+01
+ 0.47340614E+01 0.47227552E+01 0.47114775E+01 0.47002281E+01 0.46890069E+01
+ 0.46778137E+01 0.46666486E+01 0.46555113E+01 0.46444018E+01 0.46333199E+01
+ 0.46222656E+01 0.46112387E+01 0.46002392E+01 0.45892669E+01 0.45783218E+01
+ 0.45674037E+01 0.45565125E+01 0.45456481E+01 0.45348105E+01 0.45239995E+01
+ 0.45132150E+01 0.45024570E+01 0.44917252E+01 0.44810197E+01 0.44703404E+01
+ 0.44596871E+01 0.44490597E+01 0.44384582E+01 0.44278824E+01 0.44173322E+01
+ 0.44068077E+01 0.43963085E+01 0.43858348E+01 0.43753864E+01 0.43649631E+01
+ 0.43545649E+01 0.43441918E+01 0.43338435E+01 0.43235201E+01 0.43132214E+01
+ 0.43029474E+01 0.42926979E+01 0.42824729E+01 0.42722722E+01 0.42620959E+01
+ 0.42519438E+01 0.42418158E+01 0.42317118E+01 0.42216318E+01 0.42115756E+01
+ 0.42015433E+01 0.41915346E+01 0.41815496E+01 0.41715881E+01 0.41616500E+01
+ 0.41517353E+01 0.41418439E+01 0.41319758E+01 0.41221307E+01 0.41123087E+01
+ 0.41025096E+01 0.40927335E+01 0.40829802E+01 0.40732495E+01 0.40635416E+01
+ 0.40538562E+01 0.40441933E+01 0.40345529E+01 0.40249348E+01 0.40153390E+01
+ 0.40057653E+01 0.39962138E+01 0.39866844E+01 0.39771769E+01 0.39676913E+01
+ 0.39582276E+01 0.39487856E+01 0.39393653E+01 0.39299666E+01 0.39205894E+01
+ 0.39112337E+01 0.39018994E+01 0.38925864E+01 0.38832947E+01 0.38740242E+01
+ 0.38647748E+01 0.38555464E+01 0.38463390E+01 0.38371526E+01 0.38279870E+01
+ 0.38188421E+01 0.38097180E+01 0.38006145E+01 0.37915316E+01 0.37824692E+01
+ 0.37734272E+01 0.37644057E+01 0.37554044E+01 0.37464234E+01 0.37374626E+01
+ 0.37285219E+01 0.37196013E+01 0.37107006E+01 0.37018199E+01 0.36929591E+01
+ 0.36841181E+01 0.36752968E+01 0.36664952E+01 0.36577132E+01 0.36489508E+01
+ 0.36402079E+01 0.36314845E+01 0.36227804E+01 0.36140957E+01 0.36054302E+01
+ 0.35967839E+01 0.35881568E+01 0.35795487E+01 0.35709597E+01 0.35623896E+01
+ 0.35538385E+01 0.35453062E+01 0.35367928E+01 0.35282981E+01 0.35198220E+01
+ 0.35113646E+01 0.35029258E+01 0.34945055E+01 0.34861036E+01 0.34777202E+01
+ 0.34693551E+01 0.34610084E+01 0.34526798E+01 0.34443695E+01 0.34360773E+01
+ 0.34278032E+01 0.34195472E+01 0.34113091E+01 0.34030889E+01 0.33948867E+01
+ 0.33867022E+01 0.33785356E+01 0.33703866E+01 0.33622553E+01 0.33541417E+01
+ 0.33460456E+01 0.33379671E+01 0.33299060E+01 0.33218623E+01 0.33138360E+01
+ 0.33058271E+01 0.32978354E+01 0.32898609E+01 0.32819036E+01 0.32739635E+01
+ 0.32660404E+01 0.32581344E+01 0.32502453E+01 0.32423732E+01 0.32345179E+01
+ 0.32266796E+01 0.32188580E+01 0.32110531E+01 0.32032650E+01 0.31954936E+01
+ 0.31877387E+01 0.31800004E+01 0.31722787E+01 0.31645734E+01 0.31568845E+01
+ 0.31492121E+01 0.31415560E+01 0.31339162E+01 0.31262926E+01 0.31186853E+01
+ 0.31110941E+01 0.31035191E+01 0.30959601E+01 0.30884172E+01 0.30808903E+01
+ 0.30733793E+01 0.30658843E+01 0.30584051E+01 0.30509418E+01 0.30434942E+01
+ 0.30360624E+01 0.30286463E+01 0.30212459E+01 0.30138611E+01 0.30064918E+01
+ 0.29991382E+01 0.29918000E+01 0.29844773E+01 0.29771700E+01 0.29698781E+01
+ 0.29626015E+01 0.29553403E+01 0.29480943E+01 0.29408635E+01 0.29336480E+01
+ 0.29264475E+01 0.29192622E+01 0.29120920E+01 0.29049368E+01 0.28977966E+01
+ 0.28906714E+01 0.28835611E+01 0.28764657E+01 0.28693851E+01 0.28623193E+01
+ 0.28552684E+01 0.28482321E+01 0.28412106E+01 0.28342037E+01 0.28272115E+01
+ 0.28202338E+01 0.28132707E+01 0.28063222E+01 0.27993881E+01 0.27924685E+01
+ 0.27855633E+01 0.27786725E+01 0.27717960E+01 0.27649338E+01 0.27580860E+01
+ 0.27512523E+01 0.27444329E+01 0.27376277E+01 0.27308366E+01 0.27240596E+01
+ 0.27172967E+01 0.27105479E+01 0.27038130E+01 0.26970921E+01 0.26903852E+01
+ 0.26836922E+01 0.26770131E+01 0.26703478E+01 0.26636963E+01 0.26570586E+01
+ 0.26504347E+01 0.26438245E+01 0.26372280E+01 0.26306451E+01 0.26240758E+01
+ 0.26175202E+01 0.26109781E+01 0.26044495E+01 0.25979345E+01 0.25914329E+01
+ 0.25849448E+01 0.25784700E+01 0.25720087E+01 0.25655606E+01 0.25591260E+01
+ 0.25527046E+01 0.25462964E+01 0.25399015E+01 0.25335198E+01 0.25271512E+01
+ 0.25207958E+01 0.25144535E+01 0.25081243E+01 0.25018082E+01 0.24955050E+01
+ 0.24892149E+01 0.24829378E+01 0.24766735E+01 0.24704222E+01 0.24641838E+01
+ 0.24579582E+01 0.24517455E+01 0.24455455E+01 0.24393584E+01 0.24331839E+01
+ 0.24270222E+01 0.24208732E+01 0.24147369E+01 0.24086131E+01 0.24025020E+01
+ 0.23964035E+01 0.23903175E+01 0.23842441E+01 0.23781831E+01 0.23721347E+01
+ 0.23660986E+01 0.23600750E+01 0.23540639E+01 0.23480650E+01 0.23420785E+01
+ 0.23361044E+01 0.23301425E+01 0.23241929E+01 0.23182556E+01 0.23123304E+01
+ 0.23064175E+01 0.23005167E+01 0.22946281E+01 0.22887516E+01 0.22828871E+01
+ 0.22770348E+01 0.22711945E+01 0.22653662E+01 0.22595499E+01 0.22537455E+01
+ 0.22479531E+01 0.22421727E+01 0.22364041E+01 0.22306474E+01 0.22249026E+01
+ 0.22191696E+01 0.22134483E+01 0.22077389E+01 0.22020412E+01 0.21963553E+01
+ 0.21906810E+01 0.21850185E+01 0.21793676E+01 0.21737283E+01 0.21681007E+01
+ 0.21624846E+01 0.21568802E+01 0.21512872E+01 0.21457058E+01 0.21401359E+01
+ 0.21345775E+01 0.21290306E+01 0.21234951E+01 0.21179709E+01 0.21124582E+01
+ 0.21069569E+01 0.21014669E+01 0.20959882E+01 0.20905208E+01 0.20850647E+01
+ 0.20796199E+01 0.20741863E+01 0.20687640E+01 0.20633528E+01 0.20579528E+01
+ 0.20525640E+01 0.20471862E+01 0.20418196E+01 0.20364641E+01 0.20311197E+01
+ 0.20257863E+01 0.20204640E+01 0.20151526E+01 0.20098523E+01 0.20045629E+01
+ 0.19992844E+01 0.19940169E+01 0.19887603E+01 0.19835145E+01 0.19782797E+01
+ 0.19730557E+01 0.19678425E+01 0.19626401E+01 0.19574485E+01 0.19522676E+01
+ 0.19470975E+01 0.19419382E+01 0.19367895E+01 0.19316515E+01 0.19265242E+01
+ 0.19214076E+01 0.19163016E+01 0.19112061E+01 0.19061213E+01 0.19010471E+01
+ 0.18959834E+01 0.18909302E+01 0.18858875E+01 0.18808554E+01 0.18758337E+01
+ 0.18708225E+01 0.18658217E+01 0.18608313E+01 0.18558514E+01 0.18508818E+01
+ 0.18459226E+01 0.18409737E+01 0.18360352E+01 0.18311070E+01 0.18261890E+01
+ 0.18212814E+01 0.18163840E+01 0.18114968E+01 0.18066199E+01 0.18017531E+01
+ 0.17968966E+01 0.17920502E+01 0.17872139E+01 0.17823878E+01 0.17775718E+01
+ 0.17727659E+01 0.17679701E+01 0.17631843E+01 0.17584086E+01 0.17536429E+01
+ 0.17488872E+01 0.17441415E+01 0.17394058E+01 0.17346801E+01 0.17299642E+01
+ 0.17252583E+01 0.17205624E+01 0.17158762E+01 0.17112000E+01 0.17065336E+01
+ 0.17018771E+01 0.16972304E+01 0.16925935E+01 0.16879664E+01 0.16833490E+01
+ 0.16787414E+01 0.16741436E+01 0.16695554E+01 0.16649770E+01 0.16604083E+01
+ 0.16558492E+01 0.16512998E+01 0.16467601E+01 0.16422299E+01 0.16377094E+01
+ 0.16331985E+01 0.16286971E+01 0.16242053E+01 0.16197230E+01 0.16152503E+01
+ 0.16107871E+01 0.16063334E+01 0.16018892E+01 0.15974544E+01 0.15930291E+01
+ 0.15886132E+01 0.15842067E+01 0.15798097E+01 0.15754220E+01 0.15710437E+01
+ 0.15666747E+01 0.15623151E+01 0.15579649E+01 0.15536239E+01 0.15492922E+01
+ 0.15449698E+01 0.15406567E+01 0.15363528E+01 0.15320582E+01 0.15277728E+01
+ 0.15234966E+01 0.15192295E+01 0.15149717E+01 0.15107230E+01 0.15064835E+01
+ 0.15022530E+01 0.14980317E+01 0.14938195E+01 0.14896164E+01 0.14854224E+01
+ 0.14812374E+01 0.14770615E+01 0.14728945E+01 0.14687366E+01 0.14645877E+01
+ 0.14604478E+01 0.14563169E+01 0.14521949E+01 0.14480818E+01 0.14439777E+01
+ 0.14398825E+01 0.14357962E+01 0.14317187E+01 0.14276502E+01 0.14235904E+01
+ 0.14195396E+01 0.14154975E+01 0.14114643E+01 0.14074399E+01 0.14034242E+01
+ 0.13994174E+01 0.13954192E+01 0.13914299E+01 0.13874492E+01 0.13834773E+01
+ 0.13795140E+01 0.13755595E+01 0.13716136E+01 0.13676764E+01 0.13637478E+01
+ 0.13598279E+01 0.13559166E+01 0.13520139E+01 0.13481198E+01 0.13442342E+01
+ 0.13403573E+01 0.13364888E+01 0.13326290E+01 0.13287776E+01 0.13249347E+01
+ 0.13211004E+01 0.13172745E+01 0.13134571E+01 0.13096482E+01 0.13058477E+01
+ 0.13020556E+01 0.12982720E+01 0.12944967E+01 0.12907299E+01 0.12869714E+01
+ 0.12832213E+01 0.12794795E+01 0.12757461E+01 0.12720210E+01 0.12683042E+01
+ 0.12645957E+01 0.12608955E+01 0.12572036E+01 0.12535199E+01 0.12498445E+01
+ 0.12461773E+01 0.12425183E+01 0.12388676E+01 0.12352250E+01 0.12315906E+01
+ 0.12279644E+01 0.12243464E+01 0.12207365E+01 0.12171347E+01 0.12135411E+01
+ 0.12099555E+01 0.12063781E+01 0.12028087E+01 0.11992474E+01 0.11956942E+01
+ 0.11921490E+01 0.11886118E+01 0.11850826E+01 0.11815615E+01 0.11780483E+01
+ 0.11745432E+01 0.11710460E+01 0.11675567E+01 0.11640754E+01 0.11606021E+01
+ 0.11571366E+01 0.11536791E+01 0.11502294E+01 0.11467877E+01 0.11433538E+01
+ 0.11399277E+01 0.11365096E+01 0.11330992E+01 0.11296967E+01 0.11263019E+01
+ 0.11229150E+01 0.11195359E+01 0.11161645E+01 0.11128009E+01 0.11094450E+01
+ 0.11060969E+01 0.11027565E+01 0.10994238E+01 0.10960988E+01 0.10927815E+01
+ 0.10894719E+01 0.10861699E+01 0.10828756E+01 0.10795889E+01 0.10763099E+01
+ 0.10730385E+01 0.10697747E+01 0.10665184E+01 0.10632698E+01 0.10600287E+01
+ 0.10567952E+01 0.10535692E+01 0.10503508E+01 0.10471399E+01 0.10439365E+01
+ 0.10407405E+01 0.10375521E+01 0.10343712E+01 0.10311977E+01 0.10280317E+01
+ 0.10248731E+01 0.10217219E+01 0.10185782E+01 0.10154418E+01 0.10123129E+01
+ 0.10091913E+01 0.10060771E+01 0.10029703E+01 0.99987077E+00 0.99677861E+00
+ 0.99369378E+00 0.99061626E+00 0.98754604E+00 0.98448311E+00 0.98142746E+00
+ 0.97837908E+00 0.97533795E+00 0.97230406E+00 0.96927741E+00 0.96625798E+00
+ 0.96324576E+00 0.96024073E+00 0.95724289E+00 0.95425223E+00 0.95126873E+00
+ 0.94829239E+00 0.94532318E+00 0.94236111E+00 0.93940615E+00 0.93645830E+00
+ 0.93351755E+00 0.93058388E+00 0.92765729E+00 0.92473776E+00 0.92182528E+00
+ 0.91891984E+00 0.91602143E+00 0.91313003E+00 0.91024565E+00 0.90736825E+00
+ 0.90449785E+00 0.90163441E+00 0.89877794E+00 0.89592842E+00 0.89308583E+00
+ 0.89025018E+00 0.88742144E+00 0.88459961E+00 0.88178468E+00 0.87897662E+00
+ 0.87617545E+00 0.87338113E+00 0.87059366E+00 0.86781304E+00 0.86503924E+00
+ 0.86227226E+00 0.85951209E+00 0.85675872E+00 0.85401212E+00 0.85127231E+00
+ 0.84853925E+00 0.84581295E+00 0.84309339E+00 0.84038056E+00 0.83767445E+00
+ 0.83497505E+00 0.83228234E+00 0.82959632E+00 0.82691698E+00 0.82424430E+00
+ 0.82157827E+00 0.81891889E+00 0.81626614E+00 0.81362001E+00 0.81098049E+00
+ 0.80834757E+00 0.80572124E+00 0.80310149E+00 0.80048830E+00 0.79788168E+00
+ 0.79528159E+00 0.79268804E+00 0.79010102E+00 0.78752051E+00 0.78494650E+00
+ 0.78237898E+00 0.77981794E+00 0.77726338E+00 0.77471527E+00 0.77217361E+00
+ 0.76963839E+00 0.76710959E+00 0.76458722E+00 0.76207125E+00 0.75956167E+00
+ 0.75705848E+00 0.75456166E+00 0.75207120E+00 0.74958710E+00 0.74710934E+00
+ 0.74463791E+00 0.74217280E+00 0.73971400E+00 0.73726149E+00 0.73481528E+00
+ 0.73237534E+00 0.72994168E+00 0.72751426E+00 0.72509310E+00 0.72267816E+00
+ 0.72026946E+00 0.71786697E+00 0.71547068E+00 0.71308058E+00 0.71069666E+00
+ 0.70831892E+00 0.70594734E+00 0.70358191E+00 0.70122261E+00 0.69886945E+00
+ 0.69652241E+00 0.69418147E+00 0.69184663E+00 0.68951788E+00 0.68719521E+00
+ 0.68487860E+00 0.68256804E+00 0.68026354E+00 0.67796506E+00 0.67567261E+00
+ 0.67338617E+00 0.67110574E+00 0.66883129E+00 0.66656283E+00 0.66430034E+00
+ 0.66204381E+00 0.65979323E+00 0.65754859E+00 0.65530988E+00 0.65307709E+00
+ 0.65085020E+00 0.64862921E+00 0.64641411E+00 0.64420489E+00 0.64200153E+00
+ 0.63980403E+00 0.63761237E+00 0.63542654E+00 0.63324654E+00 0.63107236E+00
+ 0.62890397E+00 0.62674138E+00 0.62458457E+00 0.62243354E+00 0.62028826E+00
+ 0.61814873E+00 0.61601495E+00 0.61388689E+00 0.61176455E+00 0.60964792E+00
+ 0.60753699E+00 0.60543174E+00 0.60333218E+00 0.60123827E+00 0.59915003E+00
+ 0.59706743E+00 0.59499046E+00 0.59291912E+00 0.59085340E+00 0.58879327E+00
+ 0.58673874E+00 0.58468979E+00 0.58264642E+00 0.58060860E+00 0.57857634E+00
+ 0.57654961E+00 0.57452842E+00 0.57251274E+00 0.57050258E+00 0.56849791E+00
+ 0.56649872E+00 0.56450502E+00 0.56251678E+00 0.56053400E+00 0.55855666E+00
+ 0.55658476E+00 0.55461828E+00 0.55265722E+00 0.55070155E+00 0.54875128E+00
+ 0.54680640E+00 0.54486688E+00 0.54293272E+00 0.54100392E+00 0.53908045E+00
+ 0.53716231E+00 0.53524949E+00 0.53334198E+00 0.53143976E+00 0.52954283E+00
+ 0.52765117E+00 0.52576478E+00 0.52388364E+00 0.52200775E+00 0.52013709E+00
+ 0.51827165E+00 0.51641142E+00 0.51455639E+00 0.51270655E+00 0.51086189E+00
+ 0.50902240E+00 0.50718806E+00 0.50535887E+00 0.50353482E+00 0.50171589E+00
+ 0.49990207E+00 0.49809336E+00 0.49628974E+00 0.49449120E+00 0.49269773E+00
+ 0.49090932E+00 0.48912596E+00 0.48734763E+00 0.48557433E+00 0.48380605E+00
+ 0.48204277E+00 0.48028449E+00 0.47853119E+00 0.47678286E+00 0.47503948E+00
+ 0.47330106E+00 0.47156758E+00 0.46983902E+00 0.46811538E+00 0.46639664E+00
+ 0.46468280E+00 0.46297384E+00 0.46126975E+00 0.45957052E+00 0.45787614E+00
+ 0.45618659E+00 0.45450187E+00 0.45282196E+00 0.45114686E+00 0.44947655E+00
+ 0.44781102E+00 0.44615026E+00 0.44449425E+00 0.44284299E+00 0.44119646E+00
+ 0.43955466E+00 0.43791756E+00 0.43628517E+00 0.43465746E+00 0.43303443E+00
+ 0.43141606E+00 0.42980235E+00 0.42819327E+00 0.42658882E+00 0.42498899E+00
+ 0.42339377E+00 0.42180313E+00 0.42021708E+00 0.41863560E+00 0.41705867E+00
+ 0.41548629E+00 0.41391844E+00 0.41235510E+00 0.41079628E+00 0.40924195E+00
+ 0.40769211E+00 0.40614674E+00 0.40460582E+00 0.40306935E+00 0.40153732E+00
+ 0.40000970E+00 0.39848649E+00 0.39696768E+00 0.39545326E+00 0.39394320E+00
+ 0.39243750E+00 0.39093614E+00 0.38943911E+00 0.38794641E+00 0.38645801E+00
+ 0.38497390E+00 0.38349407E+00 0.38201850E+00 0.38054719E+00 0.37908012E+00
+ 0.37761728E+00 0.37615864E+00 0.37470421E+00 0.37325396E+00 0.37180788E+00
+ 0.37036596E+00 0.36892819E+00 0.36749454E+00 0.36606501E+00 0.36463959E+00
+ 0.36321825E+00 0.36180098E+00 0.36038778E+00 0.35897862E+00 0.35757349E+00
+ 0.35617238E+00 0.35477527E+00 0.35338215E+00 0.35199300E+00 0.35060780E+00
+ 0.34922655E+00 0.34784923E+00 0.34647582E+00 0.34510631E+00 0.34374068E+00
+ 0.34237892E+00 0.34102100E+00 0.33966693E+00 0.33831667E+00 0.33697022E+00
+ 0.33562755E+00 0.33428866E+00 0.33295353E+00 0.33162213E+00 0.33029446E+00
+ 0.32897049E+00 0.32765022E+00 0.32633362E+00 0.32502067E+00 0.32371137E+00
+ 0.32240569E+00 0.32110361E+00 0.31980513E+00 0.31851021E+00 0.31721885E+00
+ 0.31593103E+00 0.31464672E+00 0.31336592E+00 0.31208859E+00 0.31081473E+00
+ 0.30954432E+00 0.30827733E+00 0.30701376E+00 0.30575357E+00 0.30449675E+00
+ 0.30324328E+00 0.30199315E+00 0.30074633E+00 0.29950280E+00 0.29826255E+00
+ 0.29702555E+00 0.29579179E+00 0.29456124E+00 0.29333388E+00 0.29210969E+00
+ 0.29088866E+00 0.28967075E+00 0.28845596E+00 0.28724426E+00 0.28603562E+00
+ 0.28483003E+00 0.28362746E+00 0.28242789E+00 0.28123131E+00 0.28003768E+00
+ 0.27884698E+00 0.27765920E+00 0.27647430E+00 0.27529227E+00 0.27411309E+00
+ 0.27293672E+00 0.27176314E+00 0.27059234E+00 0.26942428E+00 0.26825894E+00
+ 0.26709631E+00 0.26593634E+00 0.26477902E+00 0.26362432E+00 0.26247222E+00
+ 0.26132268E+00 0.26017569E+00 0.25903122E+00 0.25788924E+00 0.25674972E+00
+ 0.25561264E+00 0.25447797E+00 0.25334569E+00 0.25221575E+00 0.25108814E+00
+ 0.24996283E+00 0.24883979E+00 0.24771899E+00 0.24660040E+00 0.24548400E+00
+ 0.24436974E+00 0.24325761E+00 0.24214757E+00 0.24103959E+00 0.23993364E+00
+ 0.23882969E+00 0.23772771E+00 0.23662766E+00 0.23552952E+00 0.23443325E+00
+ 0.23333883E+00 0.23224621E+00 0.23115536E+00 0.23006626E+00 0.22897886E+00
+ 0.22789314E+00 0.22680905E+00 0.22572658E+00 0.22464567E+00 0.22356629E+00
+ 0.22248842E+00 0.22141201E+00 0.22033703E+00 0.21926344E+00 0.21819120E+00
+ 0.21712028E+00 0.21605065E+00 0.21498226E+00 0.21391507E+00 0.21284906E+00
+ 0.21178417E+00 0.21072037E+00 0.20965763E+00 0.20859590E+00 0.20753514E+00
+ 0.20647532E+00 0.20541640E+00 0.20435832E+00 0.20330106E+00 0.20224458E+00
+ 0.20118882E+00 0.20013376E+00 0.19907935E+00 0.19802554E+00 0.19697230E+00
+ 0.19591958E+00 0.19486734E+00 0.19381555E+00 0.19276414E+00 0.19171309E+00
+ 0.19066235E+00 0.18961188E+00 0.18856162E+00 0.18751155E+00 0.18646161E+00
+ 0.18541176E+00 0.18436196E+00 0.18331216E+00 0.18226232E+00 0.18121239E+00
+ 0.18016233E+00 0.17911209E+00 0.17806163E+00 0.17701091E+00 0.17595988E+00
+ 0.17490849E+00 0.17385671E+00 0.17280448E+00 0.17175176E+00 0.17069851E+00
+ 0.16964468E+00 0.16859023E+00 0.16753511E+00 0.16647929E+00 0.16542271E+00
+ 0.16436533E+00 0.16330711E+00 0.16224801E+00 0.16118799E+00 0.16012699E+00
+ 0.15906498E+00 0.15800192E+00 0.15693777E+00 0.15587249E+00 0.15480603E+00
+ 0.15373835E+00 0.15266942E+00 0.15159920E+00 0.15052765E+00 0.14945474E+00
+ 0.14838042E+00 0.14730466E+00 0.14622743E+00 0.14514869E+00 0.14406842E+00
+ 0.14298657E+00 0.14190311E+00 0.14081803E+00 0.13973128E+00 0.13864284E+00
+ 0.13755269E+00 0.13646080E+00 0.13536714E+00 0.13427170E+00 0.13317445E+00
+ 0.13207537E+00 0.13097445E+00 0.12987167E+00 0.12876702E+00 0.12766048E+00
+ 0.12655204E+00 0.12544170E+00 0.12432945E+00 0.12321529E+00 0.12209920E+00
+ 0.12098120E+00 0.11986129E+00 0.11873946E+00 0.11761574E+00 0.11649012E+00
+ 0.11536263E+00 0.11423327E+00 0.11310206E+00 0.11196904E+00 0.11083421E+00
+ 0.10969761E+00 0.10855927E+00 0.10741923E+00 0.10627751E+00 0.10513417E+00
+ 0.10398924E+00 0.10284278E+00 0.10169483E+00 0.10054545E+00 0.99394707E-01
+ 0.98242654E-01 0.97089363E-01 0.95934906E-01 0.94779358E-01 0.93622800E-01
+ 0.92465316E-01 0.91306996E-01 0.90147934E-01 0.88988228E-01 0.87827981E-01
+ 0.86667301E-01 0.85506301E-01 0.84345099E-01 0.83183818E-01 0.82022585E-01
+ 0.80861534E-01 0.79700801E-01 0.78540532E-01 0.77380873E-01 0.76221978E-01
+ 0.75064008E-01 0.73907124E-01 0.72751498E-01 0.71597304E-01 0.70444722E-01
+ 0.69293937E-01 0.68145140E-01 0.66998527E-01 0.65854300E-01 0.64712663E-01
+ 0.63573829E-01 0.62438014E-01 0.61305439E-01 0.60176331E-01 0.59050921E-01
+ 0.57929443E-01 0.56812139E-01 0.55699252E-01 0.54591032E-01 0.53487732E-01
+ 0.52389607E-01 0.51296920E-01 0.50209933E-01 0.49128914E-01 0.48054134E-01
+ 0.46985866E-01 0.45924385E-01 0.44869970E-01 0.43822901E-01 0.42783458E-01
+ 0.41751927E-01 0.40728590E-01 0.39713733E-01 0.38707641E-01 0.37710598E-01
+ 0.36722891E-01 0.35744802E-01 0.34776614E-01 0.33818609E-01 0.32871064E-01
+ 0.31934257E-01 0.31008460E-01 0.30093944E-01 0.29190973E-01 0.28299809E-01
+ 0.27420708E-01 0.26553922E-01 0.25699694E-01 0.24858263E-01 0.24029861E-01
+ 0.23214710E-01 0.22413028E-01 0.21625020E-01 0.20850886E-01 0.20090814E-01
+ 0.19344982E-01 0.18613559E-01 0.17896702E-01 0.17194557E-01 0.16507257E-01
+ 0.15834923E-01 0.15177666E-01 0.14535581E-01 0.13908750E-01 0.13297242E-01
+ 0.12701111E-01 0.12120398E-01 0.11555129E-01 0.11005313E-01 0.10470947E-01
+ 0.99520121E-02 0.94484729E-02 0.89602798E-02 0.84873675E-02 0.80296556E-02
+ 0.75870481E-02 0.71594341E-02 0.67466875E-02 0.63486676E-02 0.59652187E-02
+ 0.55961711E-02 0.52413411E-02 0.49005311E-02 0.45735305E-02 0.42601159E-02
+ 0.39600516E-02 0.36730901E-02 0.33989729E-02 0.31374308E-02 0.28881848E-02
+ 0.26509466E-02 0.24254195E-02 0.22112990E-02 0.20082734E-02 0.18160252E-02
+ 0.16342311E-02 0.14625634E-02 0.13006905E-02 0.11482780E-02 0.10049892E-02
+ 0.87048637E-03 0.74443115E-03 0.62648565E-03 0.51631316E-03 0.41357893E-03
+ 0.31795099E-03 0.22910086E-03 0.14670429E-03 0.70441929E-04 0.00000000E+00
+ 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03
+ 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03
+ 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03
+ 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03
+ 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03
+ 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03
+ 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03
+ 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03 0.25420062E+03
+ 0.25420062E+03 0.25257244E+03 0.24485527E+03 0.23754720E+03 0.23061776E+03
+ 0.22403937E+03 0.21778703E+03 0.21183801E+03 0.20617158E+03 0.20076885E+03
+ 0.19561254E+03 0.19068679E+03 0.18597707E+03 0.18147002E+03 0.17715334E+03
+ 0.17301568E+03 0.16904654E+03 0.16523625E+03 0.16157581E+03 0.15805689E+03
+ 0.15467177E+03 0.15141324E+03 0.14827461E+03 0.14524964E+03 0.14233250E+03
+ 0.13951775E+03 0.13680030E+03 0.13417539E+03 0.13163855E+03 0.12918559E+03
+ 0.12681259E+03 0.12451584E+03 0.12229188E+03 0.12013742E+03 0.11804940E+03
+ 0.11602490E+03 0.11406118E+03 0.11215564E+03 0.11030585E+03 0.10850948E+03
+ 0.10676435E+03 0.10506837E+03 0.10341959E+03 0.10181613E+03 0.10025622E+03
+ 0.98738185E+02 0.97260422E+02 0.95821412E+02 0.94419711E+02 0.93053941E+02
+ 0.91722793E+02 0.90425018E+02 0.89159424E+02 0.87924876E+02 0.86720289E+02
+ 0.85544628E+02 0.84396904E+02 0.83276170E+02 0.82181524E+02 0.81112099E+02
+ 0.80067068E+02 0.79045637E+02 0.78047046E+02 0.77070569E+02 0.76115505E+02
+ 0.75181187E+02 0.74266970E+02 0.73372238E+02 0.72496399E+02 0.71638883E+02
+ 0.70799144E+02 0.69976655E+02 0.69170910E+02 0.68381423E+02 0.67607726E+02
+ 0.66849367E+02 0.66105913E+02 0.65376944E+02 0.64662058E+02 0.63960866E+02
+ 0.63272992E+02 0.62598077E+02 0.61935770E+02 0.61285734E+02 0.60647646E+02
+ 0.60021190E+02 0.59406064E+02 0.58801975E+02 0.58208638E+02 0.57625781E+02
+ 0.57053139E+02 0.56490455E+02 0.55937481E+02 0.55393978E+02 0.54859714E+02
+ 0.54334462E+02 0.53818007E+02 0.53310137E+02 0.52810647E+02 0.52319340E+02
+ 0.51836022E+02 0.51360509E+02 0.50892620E+02 0.50432178E+02 0.49979015E+02
+ 0.49532966E+02 0.49093869E+02 0.48661571E+02 0.48235919E+02 0.47816768E+02
+ 0.47403975E+02 0.46997401E+02 0.46596912E+02 0.46202377E+02 0.45813669E+02
+ 0.45430666E+02 0.45053245E+02 0.44681291E+02 0.44314690E+02 0.43953332E+02
+ 0.43597107E+02 0.43245913E+02 0.42899646E+02 0.42558207E+02 0.42221500E+02
+ 0.41889429E+02 0.41561905E+02 0.41238836E+02 0.40920135E+02 0.40605719E+02
+ 0.40295503E+02 0.39989407E+02 0.39687353E+02 0.39389263E+02 0.39095063E+02
+ 0.38804679E+02 0.38518040E+02 0.38235077E+02 0.37955722E+02 0.37679908E+02
+ 0.37407571E+02 0.37138648E+02 0.36873076E+02 0.36610796E+02 0.36351750E+02
+ 0.36095878E+02 0.35843126E+02 0.35593438E+02 0.35346760E+02 0.35103042E+02
+ 0.34862230E+02 0.34624275E+02 0.34389129E+02 0.34156743E+02 0.33927070E+02
+ 0.33700065E+02 0.33475683E+02 0.33253881E+02 0.33034614E+02 0.32817842E+02
+ 0.32603523E+02 0.32391618E+02 0.32182086E+02 0.31974890E+02 0.31769991E+02
+ 0.31567354E+02 0.31366941E+02 0.31168718E+02 0.30972649E+02 0.30778701E+02
+ 0.30586841E+02 0.30397036E+02 0.30209254E+02 0.30023464E+02 0.29839636E+02
+ 0.29657738E+02 0.29477743E+02 0.29299620E+02 0.29123342E+02 0.28948881E+02
+ 0.28776210E+02 0.28605303E+02 0.28436132E+02 0.28268673E+02 0.28102899E+02
+ 0.27938788E+02 0.27776314E+02 0.27615453E+02 0.27456183E+02 0.27298480E+02
+ 0.27142323E+02 0.26987688E+02 0.26834555E+02 0.26682902E+02 0.26532709E+02
+ 0.26383954E+02 0.26236618E+02 0.26090682E+02 0.25946125E+02 0.25802929E+02
+ 0.25661075E+02 0.25520545E+02 0.25381321E+02 0.25243384E+02 0.25106719E+02
+ 0.24971307E+02 0.24837132E+02 0.24704177E+02 0.24572427E+02 0.24441865E+02
+ 0.24312475E+02 0.24184242E+02 0.24057152E+02 0.23931189E+02 0.23806338E+02
+ 0.23682586E+02 0.23559917E+02 0.23438319E+02 0.23317778E+02 0.23198279E+02
+ 0.23079810E+02 0.22962359E+02 0.22845911E+02 0.22730455E+02 0.22615978E+02
+ 0.22502468E+02 0.22389913E+02 0.22278301E+02 0.22167621E+02 0.22057861E+02
+ 0.21949010E+02 0.21841057E+02 0.21733991E+02 0.21627801E+02 0.21522478E+02
+ 0.21418009E+02 0.21314386E+02 0.21211598E+02 0.21109636E+02 0.21008489E+02
+ 0.20908147E+02 0.20808603E+02 0.20709845E+02 0.20611866E+02 0.20514655E+02
+ 0.20418205E+02 0.20322506E+02 0.20227549E+02 0.20133327E+02 0.20039831E+02
+ 0.19947052E+02 0.19854983E+02 0.19763615E+02 0.19672941E+02 0.19582952E+02
+ 0.19493642E+02 0.19405002E+02 0.19317026E+02 0.19229705E+02 0.19143033E+02
+ 0.19057002E+02 0.18971605E+02 0.18886836E+02 0.18802688E+02 0.18719154E+02
+ 0.18636227E+02 0.18553901E+02 0.18472169E+02 0.18391025E+02 0.18310463E+02
+ 0.18230476E+02 0.18151058E+02 0.18072204E+02 0.17993908E+02 0.17916163E+02
+ 0.17838964E+02 0.17762305E+02 0.17686180E+02 0.17610584E+02 0.17535512E+02
+ 0.17460958E+02 0.17386917E+02 0.17313383E+02 0.17240352E+02 0.17167818E+02
+ 0.17095776E+02 0.17024222E+02 0.16953149E+02 0.16882554E+02 0.16812432E+02
+ 0.16742778E+02 0.16673587E+02 0.16604854E+02 0.16536576E+02 0.16468748E+02
+ 0.16401365E+02 0.16334422E+02 0.16267916E+02 0.16201843E+02 0.16136197E+02
+ 0.16070976E+02 0.16006174E+02 0.15941788E+02 0.15877814E+02 0.15814248E+02
+ 0.15751086E+02 0.15688324E+02 0.15625958E+02 0.15563985E+02 0.15502400E+02
+ 0.15441201E+02 0.15380383E+02 0.15319943E+02 0.15259878E+02 0.15200184E+02
+ 0.15140857E+02 0.15081894E+02 0.15023292E+02 0.14965048E+02 0.14907158E+02
+ 0.14849618E+02 0.14792427E+02 0.14735579E+02 0.14679074E+02 0.14622906E+02
+ 0.14567074E+02 0.14511574E+02 0.14456403E+02 0.14401559E+02 0.14347038E+02
+ 0.14292838E+02 0.14238955E+02 0.14185387E+02 0.14132131E+02 0.14079184E+02
+ 0.14026544E+02 0.13974208E+02 0.13922174E+02 0.13870437E+02 0.13818997E+02
+ 0.13767851E+02 0.13716995E+02 0.13666428E+02 0.13616146E+02 0.13566148E+02
+ 0.13516432E+02 0.13466993E+02 0.13417832E+02 0.13368944E+02 0.13320327E+02
+ 0.13271980E+02 0.13223900E+02 0.13176085E+02 0.13128533E+02 0.13081241E+02
+ 0.13034207E+02 0.12987429E+02 0.12940905E+02 0.12894633E+02 0.12848611E+02
+ 0.12802836E+02 0.12757308E+02 0.12712022E+02 0.12666979E+02 0.12622175E+02
+ 0.12577609E+02 0.12533279E+02 0.12489183E+02 0.12445319E+02 0.12401684E+02
+ 0.12358279E+02 0.12315100E+02 0.12272145E+02 0.12229413E+02 0.12186903E+02
+ 0.12144612E+02 0.12102538E+02 0.12060681E+02 0.12019037E+02 0.11977607E+02
+ 0.11936387E+02 0.11895376E+02 0.11854573E+02 0.11813976E+02 0.11773583E+02
+ 0.11733393E+02 0.11693405E+02 0.11653616E+02 0.11614025E+02 0.11574631E+02
+ 0.11535432E+02 0.11496426E+02 0.11457613E+02 0.11418990E+02 0.11380557E+02
+ 0.11342312E+02 0.11304253E+02 0.11266379E+02 0.11228688E+02 0.11191180E+02
+ 0.11153853E+02 0.11116706E+02 0.11079736E+02 0.11042944E+02 0.11006327E+02
+ 0.10969884E+02 0.10933615E+02 0.10897517E+02 0.10861590E+02 0.10825832E+02
+ 0.10790241E+02 0.10754818E+02 0.10719560E+02 0.10684467E+02 0.10649537E+02
+ 0.10614769E+02 0.10580162E+02 0.10545714E+02 0.10511425E+02 0.10477293E+02
+ 0.10443318E+02 0.10409498E+02 0.10375832E+02 0.10342319E+02 0.10308958E+02
+ 0.10275748E+02 0.10242687E+02 0.10209775E+02 0.10177011E+02 0.10144394E+02
+ 0.10111922E+02 0.10079595E+02 0.10047412E+02 0.10015371E+02 0.99834717E+01
+ 0.99517133E+01 0.99200945E+01 0.98886145E+01 0.98572723E+01 0.98260669E+01
+ 0.97949976E+01 0.97640632E+01 0.97332629E+01 0.97025958E+01 0.96720610E+01
+ 0.96416576E+01 0.96113847E+01 0.95812415E+01 0.95512270E+01 0.95213404E+01
+ 0.94915810E+01 0.94619477E+01 0.94324399E+01 0.94030565E+01 0.93737970E+01
+ 0.93446603E+01 0.93156458E+01 0.92867526E+01 0.92579799E+01 0.92293269E+01
+ 0.92007929E+01 0.91723770E+01 0.91440786E+01 0.91158969E+01 0.90878310E+01
+ 0.90598803E+01 0.90320440E+01 0.90043214E+01 0.89767117E+01 0.89492143E+01
+ 0.89218284E+01 0.88945533E+01 0.88673884E+01 0.88403328E+01 0.88133860E+01
+ 0.87865471E+01 0.87598157E+01 0.87331909E+01 0.87066722E+01 0.86802588E+01
+ 0.86539500E+01 0.86277454E+01 0.86016441E+01 0.85756456E+01 0.85497492E+01
+ 0.85239543E+01 0.84982603E+01 0.84726666E+01 0.84471724E+01 0.84217773E+01
+ 0.83964807E+01 0.83712818E+01 0.83461802E+01 0.83211752E+01 0.82962663E+01
+ 0.82714529E+01 0.82467343E+01 0.82221101E+01 0.81975797E+01 0.81731425E+01
+ 0.81487979E+01 0.81245454E+01 0.81003845E+01 0.80763146E+01 0.80523351E+01
+ 0.80284456E+01 0.80046455E+01 0.79809343E+01 0.79573114E+01 0.79337764E+01
+ 0.79103287E+01 0.78869678E+01 0.78636932E+01 0.78405045E+01 0.78174010E+01
+ 0.77943824E+01 0.77714481E+01 0.77485977E+01 0.77258306E+01 0.77031464E+01
+ 0.76805447E+01 0.76580249E+01 0.76355865E+01 0.76132292E+01 0.75909524E+01
+ 0.75687558E+01 0.75466388E+01 0.75246010E+01 0.75026419E+01 0.74807611E+01
+ 0.74589583E+01 0.74372328E+01 0.74155844E+01 0.73940126E+01 0.73725169E+01
+ 0.73510969E+01 0.73297523E+01 0.73084825E+01 0.72872873E+01 0.72661661E+01
+ 0.72451186E+01 0.72241444E+01 0.72032430E+01 0.71824141E+01 0.71616573E+01
+ 0.71409722E+01 0.71203584E+01 0.70998155E+01 0.70793431E+01 0.70589409E+01
+ 0.70386085E+01 0.70183455E+01 0.69981515E+01 0.69780262E+01 0.69579692E+01
+ 0.69379801E+01 0.69180586E+01 0.68982044E+01 0.68784170E+01 0.68586961E+01
+ 0.68390414E+01 0.68194525E+01 0.67999291E+01 0.67804708E+01 0.67610773E+01
+ 0.67417483E+01 0.67224835E+01 0.67032824E+01 0.66841448E+01 0.66650703E+01
+ 0.66460586E+01 0.66271095E+01 0.66082225E+01 0.65893973E+01 0.65706338E+01
+ 0.65519314E+01 0.65332900E+01 0.65147091E+01 0.64961886E+01 0.64777281E+01
+ 0.64593273E+01 0.64409858E+01 0.64227035E+01 0.64044800E+01 0.63863150E+01
+ 0.63682082E+01 0.63501594E+01 0.63321682E+01 0.63142344E+01 0.62963577E+01
+ 0.62785377E+01 0.62607743E+01 0.62430671E+01 0.62254159E+01 0.62078204E+01
+ 0.61902803E+01 0.61727954E+01 0.61553653E+01 0.61379899E+01 0.61206689E+01
+ 0.61034019E+01 0.60861888E+01 0.60690293E+01 0.60519230E+01 0.60348699E+01
+ 0.60178696E+01 0.60009218E+01 0.59840264E+01 0.59671830E+01 0.59503915E+01
+ 0.59336515E+01 0.59169629E+01 0.59003254E+01 0.58837387E+01 0.58672027E+01
+ 0.58507170E+01 0.58342815E+01 0.58178959E+01 0.58015600E+01 0.57852736E+01
+ 0.57690364E+01 0.57528482E+01 0.57367087E+01 0.57206179E+01 0.57045753E+01
+ 0.56885809E+01 0.56726344E+01 0.56567356E+01 0.56408842E+01 0.56250801E+01
+ 0.56093230E+01 0.55936127E+01 0.55779491E+01 0.55623318E+01 0.55467608E+01
+ 0.55312357E+01 0.55157565E+01 0.55003228E+01 0.54849345E+01 0.54695914E+01
+ 0.54542933E+01 0.54390399E+01 0.54238312E+01 0.54086668E+01 0.53935467E+01
+ 0.53784706E+01 0.53634382E+01 0.53484496E+01 0.53335043E+01 0.53186023E+01
+ 0.53037434E+01 0.52889273E+01 0.52741540E+01 0.52594231E+01 0.52447346E+01
+ 0.52300883E+01 0.52154839E+01 0.52009213E+01 0.51864003E+01 0.51719208E+01
+ 0.51574825E+01 0.51430854E+01 0.51287291E+01 0.51144136E+01 0.51001387E+01
+ 0.50859042E+01 0.50717100E+01 0.50575558E+01 0.50434415E+01 0.50293670E+01
+ 0.50153321E+01 0.50013366E+01 0.49873803E+01 0.49734632E+01 0.49595850E+01
+ 0.49457456E+01 0.49319448E+01 0.49181824E+01 0.49044584E+01 0.48907725E+01
+ 0.48771247E+01 0.48635147E+01 0.48499424E+01 0.48364076E+01 0.48229102E+01
+ 0.48094501E+01 0.47960271E+01 0.47826411E+01 0.47692919E+01 0.47559793E+01
+ 0.47427032E+01 0.47294636E+01 0.47162601E+01 0.47030928E+01 0.46899614E+01
+ 0.46768658E+01 0.46638059E+01 0.46507816E+01 0.46377926E+01 0.46248389E+01
+ 0.46119204E+01 0.45990368E+01 0.45861881E+01 0.45733741E+01 0.45605947E+01
+ 0.45478498E+01 0.45351392E+01 0.45224629E+01 0.45098206E+01 0.44972122E+01
+ 0.44846377E+01 0.44720968E+01 0.44595895E+01 0.44471157E+01 0.44346752E+01
+ 0.44222679E+01 0.44098936E+01 0.43975523E+01 0.43852438E+01 0.43729681E+01
+ 0.43607249E+01 0.43485142E+01 0.43363358E+01 0.43241897E+01 0.43120757E+01
+ 0.42999937E+01 0.42879435E+01 0.42759252E+01 0.42639385E+01 0.42519833E+01
+ 0.42400596E+01 0.42281672E+01 0.42163060E+01 0.42044759E+01 0.41926767E+01
+ 0.41809085E+01 0.41691710E+01 0.41574641E+01 0.41457878E+01 0.41341420E+01
+ 0.41225265E+01 0.41109412E+01 0.40993861E+01 0.40878609E+01 0.40763657E+01
+ 0.40649003E+01 0.40534646E+01 0.40420585E+01 0.40306820E+01 0.40193348E+01
+ 0.40080169E+01 0.39967283E+01 0.39854687E+01 0.39742382E+01 0.39630365E+01
+ 0.39518637E+01 0.39407196E+01 0.39296041E+01 0.39185172E+01 0.39074586E+01
+ 0.38964284E+01 0.38854265E+01 0.38744526E+01 0.38635069E+01 0.38525891E+01
+ 0.38416991E+01 0.38308370E+01 0.38200025E+01 0.38091956E+01 0.37984163E+01
+ 0.37876643E+01 0.37769397E+01 0.37662423E+01 0.37555721E+01 0.37449289E+01
+ 0.37343127E+01 0.37237234E+01 0.37131609E+01 0.37026251E+01 0.36921159E+01
+ 0.36816333E+01 0.36711771E+01 0.36607474E+01 0.36503439E+01 0.36399667E+01
+ 0.36296155E+01 0.36192905E+01 0.36089914E+01 0.35987181E+01 0.35884707E+01
+ 0.35782491E+01 0.35680530E+01 0.35578826E+01 0.35477376E+01 0.35376180E+01
+ 0.35275238E+01 0.35174548E+01 0.35074110E+01 0.34973923E+01 0.34873987E+01
+ 0.34774300E+01 0.34674861E+01 0.34575671E+01 0.34476728E+01 0.34378031E+01
+ 0.34279580E+01 0.34181375E+01 0.34083413E+01 0.33985695E+01 0.33888220E+01
+ 0.33790987E+01 0.33693996E+01 0.33597245E+01 0.33500735E+01 0.33404463E+01
+ 0.33308431E+01 0.33212636E+01 0.33117078E+01 0.33021757E+01 0.32926672E+01
+ 0.32831822E+01 0.32737206E+01 0.32642825E+01 0.32548676E+01 0.32454760E+01
+ 0.32361076E+01 0.32267623E+01 0.32174400E+01 0.32081407E+01 0.31988644E+01
+ 0.31896109E+01 0.31803802E+01 0.31711722E+01 0.31619869E+01 0.31528242E+01
+ 0.31436840E+01 0.31345663E+01 0.31254710E+01 0.31163980E+01 0.31073474E+01
+ 0.30983189E+01 0.30893127E+01 0.30803285E+01 0.30713664E+01 0.30624263E+01
+ 0.30535081E+01 0.30446117E+01 0.30357372E+01 0.30268844E+01 0.30180533E+01
+ 0.30092438E+01 0.30004559E+01 0.29916895E+01 0.29829445E+01 0.29742210E+01
+ 0.29655188E+01 0.29568379E+01 0.29481782E+01 0.29395397E+01 0.29309223E+01
+ 0.29223259E+01 0.29137506E+01 0.29051962E+01 0.28966627E+01 0.28881500E+01
+ 0.28796582E+01 0.28711870E+01 0.28627366E+01 0.28543067E+01 0.28458975E+01
+ 0.28375087E+01 0.28291404E+01 0.28207926E+01 0.28124650E+01 0.28041578E+01
+ 0.27958709E+01 0.27876042E+01 0.27793576E+01 0.27711311E+01 0.27629247E+01
+ 0.27547382E+01 0.27465718E+01 0.27384252E+01 0.27302985E+01 0.27221916E+01
+ 0.27141044E+01 0.27060369E+01 0.26979891E+01 0.26899609E+01 0.26819523E+01
+ 0.26739631E+01 0.26659934E+01 0.26580432E+01 0.26501123E+01 0.26422007E+01
+ 0.26343084E+01 0.26264353E+01 0.26185814E+01 0.26107466E+01 0.26029309E+01
+ 0.25951343E+01 0.25873566E+01 0.25795979E+01 0.25718581E+01 0.25641371E+01
+ 0.25564350E+01 0.25487516E+01 0.25410869E+01 0.25334409E+01 0.25258136E+01
+ 0.25182048E+01 0.25106146E+01 0.25030429E+01 0.24954896E+01 0.24879547E+01
+ 0.24804383E+01 0.24729401E+01 0.24654602E+01 0.24579986E+01 0.24505552E+01
+ 0.24431299E+01 0.24357227E+01 0.24283337E+01 0.24209626E+01 0.24136095E+01
+ 0.24062744E+01 0.23989572E+01 0.23916579E+01 0.23843763E+01 0.23771126E+01
+ 0.23698666E+01 0.23626383E+01 0.23554277E+01 0.23482347E+01 0.23410593E+01
+ 0.23339014E+01 0.23267610E+01 0.23196381E+01 0.23125327E+01 0.23054446E+01
+ 0.22983738E+01 0.22913204E+01 0.22842842E+01 0.22772653E+01 0.22702636E+01
+ 0.22632790E+01 0.22563115E+01 0.22493611E+01 0.22424278E+01 0.22355114E+01
+ 0.22286120E+01 0.22217296E+01 0.22148640E+01 0.22080154E+01 0.22011835E+01
+ 0.21943684E+01 0.21875700E+01 0.21807884E+01 0.21740234E+01 0.21672751E+01
+ 0.21605434E+01 0.21538282E+01 0.21471295E+01 0.21404474E+01 0.21337817E+01
+ 0.21271325E+01 0.21204996E+01 0.21138831E+01 0.21072829E+01 0.21006989E+01
+ 0.20941313E+01 0.20875798E+01 0.20810445E+01 0.20745254E+01 0.20680224E+01
+ 0.20615354E+01 0.20550645E+01 0.20486096E+01 0.20421707E+01 0.20357477E+01
+ 0.20293406E+01 0.20229494E+01 0.20165741E+01 0.20102145E+01 0.20038708E+01
+ 0.19975427E+01 0.19912304E+01 0.19849338E+01 0.19786528E+01 0.19723874E+01
+ 0.19661376E+01 0.19599034E+01 0.19536846E+01 0.19474814E+01 0.19412936E+01
+ 0.19351212E+01 0.19289642E+01 0.19228226E+01 0.19166963E+01 0.19105853E+01
+ 0.19044895E+01 0.18984090E+01 0.18923437E+01 0.18862935E+01 0.18802585E+01
+ 0.18742386E+01 0.18682338E+01 0.18622440E+01 0.18562693E+01 0.18503095E+01
+ 0.18443647E+01 0.18384348E+01 0.18325198E+01 0.18266197E+01 0.18207344E+01
+ 0.18148639E+01 0.18090082E+01 0.18031673E+01 0.17973410E+01 0.17915295E+01
+ 0.17857326E+01 0.17799503E+01 0.17741827E+01 0.17684296E+01 0.17626910E+01
+ 0.17569670E+01 0.17512575E+01 0.17455624E+01 0.17398817E+01 0.17342155E+01
+ 0.17285636E+01 0.17229260E+01 0.17173028E+01 0.17116938E+01 0.17060992E+01
+ 0.17005187E+01 0.16949524E+01 0.16894004E+01 0.16838624E+01 0.16783386E+01
+ 0.16728289E+01 0.16673332E+01 0.16618516E+01 0.16563840E+01 0.16509303E+01
+ 0.16454906E+01 0.16400649E+01 0.16346530E+01 0.16292550E+01 0.16238709E+01
+ 0.16185006E+01 0.16131440E+01 0.16078013E+01 0.16024722E+01 0.15971569E+01
+ 0.15918553E+01 0.15865673E+01 0.15812930E+01 0.15760322E+01 0.15707851E+01
+ 0.15655515E+01 0.15603314E+01 0.15551248E+01 0.15499317E+01 0.15447521E+01
+ 0.15395858E+01 0.15344330E+01 0.15292935E+01 0.15241674E+01 0.15190546E+01
+ 0.15139551E+01 0.15088689E+01 0.15037959E+01 0.14987361E+01 0.14936896E+01
+ 0.14886562E+01 0.14836359E+01 0.14786288E+01 0.14736347E+01 0.14686537E+01
+ 0.14636858E+01 0.14587308E+01 0.14537889E+01 0.14488599E+01 0.14439439E+01
+ 0.14390408E+01 0.14341506E+01 0.14292732E+01 0.14244087E+01 0.14195571E+01
+ 0.14147182E+01 0.14098921E+01 0.14050787E+01 0.14002780E+01 0.13954901E+01
+ 0.13907148E+01 0.13859522E+01 0.13812022E+01 0.13764648E+01 0.13717400E+01
+ 0.13670277E+01 0.13623280E+01 0.13576408E+01 0.13529661E+01 0.13483038E+01
+ 0.13436539E+01 0.13390165E+01 0.13343915E+01 0.13297788E+01 0.13251784E+01
+ 0.13205904E+01 0.13160147E+01 0.13114512E+01 0.13069000E+01 0.13023611E+01
+ 0.12978343E+01 0.12933197E+01 0.12888172E+01 0.12843269E+01 0.12798487E+01
+ 0.12753826E+01 0.12709285E+01 0.12664865E+01 0.12620565E+01 0.12576385E+01
+ 0.12532325E+01 0.12488384E+01 0.12444563E+01 0.12400860E+01 0.12357276E+01
+ 0.12313811E+01 0.12270465E+01 0.12227236E+01 0.12184125E+01 0.12141132E+01
+ 0.12098257E+01 0.12055499E+01 0.12012857E+01 0.11970333E+01 0.11927925E+01
+ 0.11885634E+01 0.11843458E+01 0.11801399E+01 0.11759455E+01 0.11717627E+01
+ 0.11675914E+01 0.11634316E+01 0.11592833E+01 0.11551464E+01 0.11510210E+01
+ 0.11469070E+01 0.11428044E+01 0.11387131E+01 0.11346332E+01 0.11305647E+01
+ 0.11265074E+01 0.11224615E+01 0.11184268E+01 0.11144033E+01 0.11103911E+01
+ 0.11063900E+01 0.11024002E+01 0.10984215E+01 0.10944539E+01 0.10904974E+01
+ 0.10865521E+01 0.10826178E+01 0.10786946E+01 0.10747823E+01 0.10708811E+01
+ 0.10669909E+01 0.10631117E+01 0.10592434E+01 0.10553860E+01 0.10515395E+01
+ 0.10477039E+01 0.10438792E+01 0.10400653E+01 0.10362622E+01 0.10324699E+01
+ 0.10286884E+01 0.10249177E+01 0.10211577E+01 0.10174084E+01 0.10136698E+01
+ 0.10099418E+01 0.10062246E+01 0.10025179E+01 0.99882189E+00 0.99513644E+00
+ 0.99146157E+00 0.98779724E+00 0.98414344E+00 0.98050016E+00 0.97686736E+00
+ 0.97324502E+00 0.96963314E+00 0.96603168E+00 0.96244062E+00 0.95885995E+00
+ 0.95528965E+00 0.95172969E+00 0.94818006E+00 0.94464073E+00 0.94111169E+00
+ 0.93759291E+00 0.93408437E+00 0.93058606E+00 0.92709795E+00 0.92362003E+00
+ 0.92015227E+00 0.91669465E+00 0.91324716E+00 0.90980976E+00 0.90638246E+00
+ 0.90296521E+00 0.89955801E+00 0.89616083E+00 0.89277366E+00 0.88939647E+00
+ 0.88602925E+00 0.88267196E+00 0.87932461E+00 0.87598715E+00 0.87265958E+00
+ 0.86934188E+00 0.86603402E+00 0.86273599E+00 0.85944776E+00 0.85616932E+00
+ 0.85290065E+00 0.84964172E+00 0.84639252E+00 0.84315303E+00 0.83992322E+00
+ 0.83670309E+00 0.83349260E+00 0.83029174E+00 0.82710050E+00 0.82391884E+00
+ 0.82074675E+00 0.81758422E+00 0.81443122E+00 0.81128773E+00 0.80815374E+00
+ 0.80502922E+00 0.80191415E+00 0.79880852E+00 0.79571231E+00 0.79262550E+00
+ 0.78954806E+00 0.78647998E+00 0.78342124E+00 0.78037182E+00 0.77733170E+00
+ 0.77430087E+00 0.77127929E+00 0.76826697E+00 0.76526386E+00 0.76226996E+00
+ 0.75928525E+00 0.75630970E+00 0.75334331E+00 0.75038604E+00 0.74743788E+00
+ 0.74449882E+00 0.74156883E+00 0.73864789E+00 0.73573598E+00 0.73283309E+00
+ 0.72993920E+00 0.72705429E+00 0.72417834E+00 0.72131132E+00 0.71845323E+00
+ 0.71560404E+00 0.71276373E+00 0.70993229E+00 0.70710970E+00 0.70429593E+00
+ 0.70149098E+00 0.69869481E+00 0.69590741E+00 0.69312877E+00 0.69035886E+00
+ 0.68759767E+00 0.68484518E+00 0.68210136E+00 0.67936621E+00 0.67663969E+00
+ 0.67392180E+00 0.67121251E+00 0.66851181E+00 0.66581967E+00 0.66313609E+00
+ 0.66046103E+00 0.65779449E+00 0.65513644E+00 0.65248686E+00 0.64984575E+00
+ 0.64721306E+00 0.64458880E+00 0.64197295E+00 0.63936547E+00 0.63676636E+00
+ 0.63417559E+00 0.63159316E+00 0.62901903E+00 0.62645320E+00 0.62389564E+00
+ 0.62134633E+00 0.61880526E+00 0.61627241E+00 0.61374776E+00 0.61123130E+00
+ 0.60872299E+00 0.60622284E+00 0.60373081E+00 0.60124689E+00 0.59877106E+00
+ 0.59630331E+00 0.59384361E+00 0.59139195E+00 0.58894831E+00 0.58651267E+00
+ 0.58408501E+00 0.58166532E+00 0.57925358E+00 0.57684977E+00 0.57445386E+00
+ 0.57206586E+00 0.56968572E+00 0.56731345E+00 0.56494901E+00 0.56259240E+00
+ 0.56024359E+00 0.55790257E+00 0.55556931E+00 0.55324381E+00 0.55092604E+00
+ 0.54861599E+00 0.54631363E+00 0.54401895E+00 0.54173193E+00 0.53945256E+00
+ 0.53718081E+00 0.53491667E+00 0.53266012E+00 0.53041115E+00 0.52816973E+00
+ 0.52593585E+00 0.52370949E+00 0.52149063E+00 0.51927925E+00 0.51707535E+00
+ 0.51487889E+00 0.51268987E+00 0.51050826E+00 0.50833404E+00 0.50616721E+00
+ 0.50400774E+00 0.50185561E+00 0.49971081E+00 0.49757332E+00 0.49544312E+00
+ 0.49332020E+00 0.49120453E+00 0.48909611E+00 0.48699490E+00 0.48490090E+00
+ 0.48281409E+00 0.48073445E+00 0.47866196E+00 0.47659660E+00 0.47453837E+00
+ 0.47248723E+00 0.47044318E+00 0.46840620E+00 0.46637626E+00 0.46435335E+00
+ 0.46233746E+00 0.46032857E+00 0.45832666E+00 0.45633171E+00 0.45434370E+00
+ 0.45236263E+00 0.45038846E+00 0.44842119E+00 0.44646080E+00 0.44450726E+00
+ 0.44256057E+00 0.44062070E+00 0.43868764E+00 0.43676138E+00 0.43484188E+00
+ 0.43292915E+00 0.43102315E+00 0.42912388E+00 0.42723131E+00 0.42534544E+00
+ 0.42346623E+00 0.42159368E+00 0.41972777E+00 0.41786848E+00 0.41601579E+00
+ 0.41416969E+00 0.41233016E+00 0.41049719E+00 0.40867075E+00 0.40685083E+00
+ 0.40503742E+00 0.40323049E+00 0.40143002E+00 0.39963602E+00 0.39784844E+00
+ 0.39606729E+00 0.39429254E+00 0.39252417E+00 0.39076217E+00 0.38900652E+00
+ 0.38725721E+00 0.38551421E+00 0.38377752E+00 0.38204711E+00 0.38032297E+00
+ 0.37860508E+00 0.37689343E+00 0.37518799E+00 0.37348876E+00 0.37179571E+00
+ 0.37010882E+00 0.36842809E+00 0.36675350E+00 0.36508502E+00 0.36342264E+00
+ 0.36176635E+00 0.36011613E+00 0.35847196E+00 0.35683382E+00 0.35520171E+00
+ 0.35357559E+00 0.35195546E+00 0.35034131E+00 0.34873310E+00 0.34713083E+00
+ 0.34553448E+00 0.34394404E+00 0.34235948E+00 0.34078080E+00 0.33920796E+00
+ 0.33764097E+00 0.33607980E+00 0.33452443E+00 0.33297485E+00 0.33143105E+00
+ 0.32989300E+00 0.32836069E+00 0.32683410E+00 0.32531322E+00 0.32379803E+00
+ 0.32228852E+00 0.32078467E+00 0.31928646E+00 0.31779387E+00 0.31630689E+00
+ 0.31482551E+00 0.31334970E+00 0.31187946E+00 0.31041476E+00 0.30895559E+00
+ 0.30750193E+00 0.30605377E+00 0.30461108E+00 0.30317386E+00 0.30174209E+00
+ 0.30031576E+00 0.29889483E+00 0.29747931E+00 0.29606917E+00 0.29466439E+00
+ 0.29326497E+00 0.29187089E+00 0.29048212E+00 0.28909865E+00 0.28772048E+00
+ 0.28634757E+00 0.28497992E+00 0.28361751E+00 0.28226032E+00 0.28090834E+00
+ 0.27956155E+00 0.27821993E+00 0.27688347E+00 0.27555216E+00 0.27422597E+00
+ 0.27290490E+00 0.27158891E+00 0.27027801E+00 0.26897218E+00 0.26767139E+00
+ 0.26637563E+00 0.26508489E+00 0.26379914E+00 0.26251838E+00 0.26124259E+00
+ 0.25997176E+00 0.25870585E+00 0.25744487E+00 0.25618880E+00 0.25493761E+00
+ 0.25369130E+00 0.25244984E+00 0.25121323E+00 0.24998144E+00 0.24875446E+00
+ 0.24753227E+00 0.24631487E+00 0.24510222E+00 0.24389433E+00 0.24269116E+00
+ 0.24149271E+00 0.24029896E+00 0.23910989E+00 0.23792550E+00 0.23674575E+00
+ 0.23557064E+00 0.23440016E+00 0.23323427E+00 0.23207298E+00 0.23091626E+00
+ 0.22976411E+00 0.22861649E+00 0.22747340E+00 0.22633482E+00 0.22520074E+00
+ 0.22407114E+00 0.22294600E+00 0.22182531E+00 0.22070906E+00 0.21959722E+00
+ 0.21848979E+00 0.21738674E+00 0.21628806E+00 0.21519374E+00 0.21410376E+00
+ 0.21301810E+00 0.21193675E+00 0.21085969E+00 0.20978691E+00 0.20871839E+00
+ 0.20765412E+00 0.20659408E+00 0.20553825E+00 0.20448663E+00 0.20343919E+00
+ 0.20239591E+00 0.20135679E+00 0.20032181E+00 0.19929095E+00 0.19826419E+00
+ 0.19724153E+00 0.19622294E+00 0.19520841E+00 0.19419793E+00 0.19319148E+00
+ 0.19218903E+00 0.19119059E+00 0.19019613E+00 0.18920563E+00 0.18821909E+00
+ 0.18723648E+00 0.18625780E+00 0.18528302E+00 0.18431212E+00 0.18334511E+00
+ 0.18238195E+00 0.18142263E+00 0.18046714E+00 0.17951547E+00 0.17856759E+00
+ 0.17762349E+00 0.17668316E+00 0.17574657E+00 0.17481373E+00 0.17388460E+00
+ 0.17295918E+00 0.17203744E+00 0.17111938E+00 0.17020498E+00 0.16929421E+00
+ 0.16838708E+00 0.16748356E+00 0.16658363E+00 0.16568729E+00 0.16479451E+00
+ 0.16390528E+00 0.16301958E+00 0.16213740E+00 0.16125873E+00 0.16038355E+00
+ 0.15951183E+00 0.15864358E+00 0.15777877E+00 0.15691738E+00 0.15605941E+00
+ 0.15520483E+00 0.15435363E+00 0.15350580E+00 0.15266132E+00 0.15182017E+00
+ 0.15098234E+00 0.15014782E+00 0.14931658E+00 0.14848862E+00 0.14766391E+00
+ 0.14684245E+00 0.14602421E+00 0.14520919E+00 0.14439736E+00 0.14358871E+00
+ 0.14278323E+00 0.14198090E+00 0.14118170E+00 0.14038563E+00 0.13959265E+00
+ 0.13880277E+00 0.13801596E+00 0.13723221E+00 0.13645151E+00 0.13567383E+00
+ 0.13489916E+00 0.13412749E+00 0.13335881E+00 0.13259309E+00 0.13183032E+00
+ 0.13107049E+00 0.13031358E+00 0.12955957E+00 0.12880846E+00 0.12806022E+00
+ 0.12731485E+00 0.12657232E+00 0.12583261E+00 0.12509573E+00 0.12436164E+00
+ 0.12363034E+00 0.12290181E+00 0.12217603E+00 0.12145299E+00 0.12073268E+00
+ 0.12001507E+00 0.11930016E+00 0.11858793E+00 0.11787837E+00 0.11717145E+00
+ 0.11646716E+00 0.11576550E+00 0.11506644E+00 0.11436997E+00 0.11367607E+00
+ 0.11298474E+00 0.11229595E+00 0.11160969E+00 0.11092594E+00 0.11024469E+00
+ 0.10956593E+00 0.10888964E+00 0.10821581E+00 0.10754442E+00 0.10687545E+00
+ 0.10620890E+00 0.10554474E+00 0.10488297E+00 0.10422356E+00 0.10356651E+00
+ 0.10291180E+00 0.10225942E+00 0.10160934E+00 0.10096156E+00 0.10031607E+00
+ 0.99672837E-01 0.99031862E-01 0.98393126E-01 0.97756615E-01 0.97122316E-01
+ 0.96490214E-01 0.95860295E-01 0.95232546E-01 0.94606951E-01 0.93983499E-01
+ 0.93362174E-01 0.92742963E-01 0.92125853E-01 0.91510830E-01 0.90897880E-01
+ 0.90286990E-01 0.89678146E-01 0.89071336E-01 0.88466546E-01 0.87863763E-01
+ 0.87262973E-01 0.86664164E-01 0.86067323E-01 0.85472437E-01 0.84879493E-01
+ 0.84288479E-01 0.83699382E-01 0.83112189E-01 0.82526888E-01 0.81943467E-01
+ 0.81361914E-01 0.80782216E-01 0.80204362E-01 0.79628339E-01 0.79054136E-01
+ 0.78481742E-01 0.77911144E-01 0.77342331E-01 0.76775293E-01 0.76210017E-01
+ 0.75646493E-01 0.75084711E-01 0.74524658E-01 0.73966325E-01 0.73409701E-01
+ 0.72854776E-01 0.72301539E-01 0.71749981E-01 0.71200092E-01 0.70651862E-01
+ 0.70105281E-01 0.69560341E-01 0.69017031E-01 0.68475344E-01 0.67935270E-01
+ 0.67396800E-01 0.66859926E-01 0.66324640E-01 0.65790934E-01 0.65258799E-01
+ 0.64728229E-01 0.64199216E-01 0.63671753E-01 0.63145832E-01 0.62621447E-01
+ 0.62098591E-01 0.61577258E-01 0.61057443E-01 0.60539138E-01 0.60022340E-01
+ 0.59507041E-01 0.58993238E-01 0.58480925E-01 0.57970099E-01 0.57460754E-01
+ 0.56952887E-01 0.56446495E-01 0.55941573E-01 0.55438119E-01 0.54936130E-01
+ 0.54435603E-01 0.53936537E-01 0.53438929E-01 0.52942779E-01 0.52448084E-01
+ 0.51954845E-01 0.51463060E-01 0.50972729E-01 0.50483853E-01 0.49996433E-01
+ 0.49510468E-01 0.49025961E-01 0.48542913E-01 0.48061326E-01 0.47581202E-01
+ 0.47102545E-01 0.46625357E-01 0.46149642E-01 0.45675405E-01 0.45202649E-01
+ 0.44731380E-01 0.44261602E-01 0.43793321E-01 0.43326544E-01 0.42861277E-01
+ 0.42397527E-01 0.41935302E-01 0.41474608E-01 0.41015456E-01 0.40557852E-01
+ 0.40101807E-01 0.39647331E-01 0.39194433E-01 0.38743124E-01 0.38293415E-01
+ 0.37845318E-01 0.37398845E-01 0.36954008E-01 0.36510820E-01 0.36069295E-01
+ 0.35629448E-01 0.35191291E-01 0.34754841E-01 0.34320112E-01 0.33887121E-01
+ 0.33455885E-01 0.33026419E-01 0.32598742E-01 0.32172871E-01 0.31748824E-01
+ 0.31326621E-01 0.30906281E-01 0.30487824E-01 0.30071270E-01 0.29656640E-01
+ 0.29243954E-01 0.28833236E-01 0.28424506E-01 0.28017787E-01 0.27613104E-01
+ 0.27210478E-01 0.26809934E-01 0.26411497E-01 0.26015191E-01 0.25621041E-01
+ 0.25229073E-01 0.24839313E-01 0.24451787E-01 0.24066522E-01 0.23683546E-01
+ 0.23302884E-01 0.22924566E-01 0.22548619E-01 0.22175072E-01 0.21803953E-01
+ 0.21435291E-01 0.21069115E-01 0.20705455E-01 0.20344340E-01 0.19985801E-01
+ 0.19629866E-01 0.19276566E-01 0.18925932E-01 0.18577994E-01 0.18232781E-01
+ 0.17890326E-01 0.17550657E-01 0.17213806E-01 0.16879804E-01 0.16548680E-01
+ 0.16220465E-01 0.15895190E-01 0.15572884E-01 0.15253578E-01 0.14937302E-01
+ 0.14624084E-01 0.14313955E-01 0.14006944E-01 0.13703079E-01 0.13402389E-01
+ 0.13104901E-01 0.12810644E-01 0.12519645E-01 0.12231930E-01 0.11947525E-01
+ 0.11666456E-01 0.11388748E-01 0.11114425E-01 0.10843512E-01 0.10576031E-01
+ 0.10312003E-01 0.10051452E-01 0.97943967E-02 0.95408577E-02 0.92908537E-02
+ 0.90444027E-02 0.88015217E-02 0.85622266E-02 0.83265324E-02 0.80944530E-02
+ 0.78660012E-02 0.76411886E-02 0.74200257E-02 0.72025216E-02 0.69886844E-02
+ 0.67785209E-02 0.65720364E-02 0.63692351E-02 0.61701198E-02 0.59746917E-02
+ 0.57829508E-02 0.55948957E-02 0.54105234E-02 0.52298296E-02 0.50528082E-02
+ 0.48794520E-02 0.47097520E-02 0.45436977E-02 0.43812771E-02 0.42224765E-02
+ 0.40672810E-02 0.39156737E-02 0.37676363E-02 0.36231491E-02 0.34821905E-02
+ 0.33447375E-02 0.32107656E-02 0.30802487E-02 0.29531591E-02 0.28294677E-02
+ 0.27091436E-02 0.25921548E-02 0.24784677E-02 0.23680470E-02 0.22608563E-02
+ 0.21568578E-02 0.20560121E-02 0.19582788E-02 0.18636160E-02 0.17719805E-02
+ 0.16833282E-02 0.15976135E-02 0.15147900E-02 0.14348101E-02 0.13576251E-02
+ 0.12831856E-02 0.12114409E-02 0.11423400E-02 0.10758306E-02 0.10118600E-02
+ 0.95037475E-03 0.89132078E-03 0.83464352E-03 0.78028791E-03 0.72819850E-03
+ 0.67831951E-03 0.63059487E-03 0.58496835E-03 0.54138356E-03 0.49978405E-03
+ 0.46011338E-03 0.42231518E-03 0.38633324E-03 0.35211151E-03 0.31959426E-03
+ 0.28872607E-03 0.25945191E-03 0.23171724E-03 0.20546801E-03 0.18065078E-03
+ 0.15721273E-03 0.13510173E-03 0.11426639E-03 0.94656136E-04 0.76221215E-04
+ 0.58912771E-04 0.42682877E-04 0.27484576E-04 0.13271919E-04 0.00000000E+00
+ 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02
+ 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02
+ 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02
+ 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02
+ 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02
+ 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02
+ 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02
+ 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02
+ 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02 0.98182606E+02
+ 0.98182606E+02 0.98182606E+02 0.95386420E+02 0.92315792E+02 0.89404279E+02
+ 0.86640635E+02 0.84014613E+02 0.81516857E+02 0.79138812E+02 0.76872640E+02
+ 0.74711148E+02 0.72647728E+02 0.70676293E+02 0.68791236E+02 0.66987376E+02
+ 0.65259928E+02 0.63604460E+02 0.62016864E+02 0.60493329E+02 0.59030312E+02
+ 0.57624520E+02 0.56272883E+02 0.54972542E+02 0.53720825E+02 0.52515239E+02
+ 0.51353452E+02 0.50233279E+02 0.49152673E+02 0.48109717E+02 0.47102609E+02
+ 0.46129657E+02 0.45189268E+02 0.44279946E+02 0.43400280E+02 0.42548941E+02
+ 0.41724674E+02 0.40926297E+02 0.40152690E+02 0.39402796E+02 0.38675616E+02
+ 0.37970203E+02 0.37285660E+02 0.36621138E+02 0.35975830E+02 0.35348972E+02
+ 0.34739838E+02 0.34147736E+02 0.33572012E+02 0.33012041E+02 0.32467230E+02
+ 0.31937012E+02 0.31420850E+02 0.30918230E+02 0.30428661E+02 0.29951677E+02
+ 0.29486832E+02 0.29033700E+02 0.28591874E+02 0.28160964E+02 0.27740599E+02
+ 0.27330422E+02 0.26930094E+02 0.26539287E+02 0.26157690E+02 0.25785002E+02
+ 0.25420936E+02 0.25065218E+02 0.24717583E+02 0.24377777E+02 0.24045556E+02
+ 0.23720688E+02 0.23402947E+02 0.23092117E+02 0.22787990E+02 0.22490368E+02
+ 0.22199057E+02 0.21913872E+02 0.21634636E+02 0.21361178E+02 0.21093331E+02
+ 0.20830936E+02 0.20573841E+02 0.20321897E+02 0.20074962E+02 0.19832897E+02
+ 0.19595570E+02 0.19362853E+02 0.19134622E+02 0.18910756E+02 0.18691142E+02
+ 0.18475666E+02 0.18264221E+02 0.18056702E+02 0.17853010E+02 0.17653045E+02
+ 0.17456714E+02 0.17263925E+02 0.17074590E+02 0.16888622E+02 0.16705940E+02
+ 0.16526462E+02 0.16350111E+02 0.16176811E+02 0.16006490E+02 0.15839076E+02
+ 0.15674500E+02 0.15512696E+02 0.15353599E+02 0.15197147E+02 0.15043278E+02
+ 0.14891933E+02 0.14743055E+02 0.14596588E+02 0.14452478E+02 0.14310672E+02
+ 0.14171120E+02 0.14033771E+02 0.13898578E+02 0.13765493E+02 0.13634471E+02
+ 0.13505467E+02 0.13378439E+02 0.13253343E+02 0.13130141E+02 0.13008791E+02
+ 0.12889255E+02 0.12771495E+02 0.12655475E+02 0.12541160E+02 0.12428513E+02
+ 0.12317502E+02 0.12208094E+02 0.12100256E+02 0.11993956E+02 0.11889166E+02
+ 0.11785854E+02 0.11683992E+02 0.11583551E+02 0.11484505E+02 0.11386825E+02
+ 0.11290486E+02 0.11195463E+02 0.11101730E+02 0.11009262E+02 0.10918037E+02
+ 0.10828031E+02 0.10739221E+02 0.10651585E+02 0.10565101E+02 0.10479750E+02
+ 0.10395509E+02 0.10312358E+02 0.10230279E+02 0.10149252E+02 0.10069258E+02
+ 0.99902786E+01 0.99122961E+01 0.98352930E+01 0.97592522E+01 0.96841568E+01
+ 0.96099905E+01 0.95367373E+01 0.94643815E+01 0.93929079E+01 0.93223014E+01
+ 0.92525474E+01 0.91836315E+01 0.91155396E+01 0.90482582E+01 0.89817737E+01
+ 0.89160729E+01 0.88511429E+01 0.87869713E+01 0.87235455E+01 0.86608536E+01
+ 0.85988836E+01 0.85376240E+01 0.84770635E+01 0.84171908E+01 0.83579950E+01
+ 0.82994656E+01 0.82415920E+01 0.81843640E+01 0.81277714E+01 0.80718046E+01
+ 0.80164537E+01 0.79617094E+01 0.79075623E+01 0.78540034E+01 0.78010237E+01
+ 0.77486144E+01 0.76967670E+01 0.76454732E+01 0.75947245E+01 0.75445129E+01
+ 0.74948305E+01 0.74456694E+01 0.73970221E+01 0.73488809E+01 0.73012386E+01
+ 0.72540880E+01 0.72074218E+01 0.71612331E+01 0.71155152E+01 0.70702613E+01
+ 0.70254648E+01 0.69811192E+01 0.69372181E+01 0.68937555E+01 0.68507250E+01
+ 0.68081207E+01 0.67659367E+01 0.67241671E+01 0.66828063E+01 0.66418487E+01
+ 0.66012887E+01 0.65611210E+01 0.65213402E+01 0.64819411E+01 0.64429185E+01
+ 0.64042675E+01 0.63659830E+01 0.63280602E+01 0.62904943E+01 0.62532805E+01
+ 0.62164144E+01 0.61798911E+01 0.61437064E+01 0.61078559E+01 0.60723350E+01
+ 0.60371397E+01 0.60022658E+01 0.59677090E+01 0.59334654E+01 0.58995309E+01
+ 0.58659017E+01 0.58325739E+01 0.57995437E+01 0.57668073E+01 0.57343612E+01
+ 0.57022016E+01 0.56703250E+01 0.56387279E+01 0.56074068E+01 0.55763584E+01
+ 0.55455794E+01 0.55150664E+01 0.54848162E+01 0.54548256E+01 0.54250915E+01
+ 0.53956108E+01 0.53663804E+01 0.53373974E+01 0.53086588E+01 0.52801617E+01
+ 0.52519033E+01 0.52238807E+01 0.51960911E+01 0.51685319E+01 0.51412003E+01
+ 0.51140937E+01 0.50872095E+01 0.50605451E+01 0.50340979E+01 0.50078656E+01
+ 0.49818455E+01 0.49560353E+01 0.49304326E+01 0.49050350E+01 0.48798403E+01
+ 0.48548461E+01 0.48300502E+01 0.48054503E+01 0.47810443E+01 0.47568301E+01
+ 0.47328054E+01 0.47089682E+01 0.46853164E+01 0.46618480E+01 0.46385609E+01
+ 0.46154533E+01 0.45925230E+01 0.45697683E+01 0.45471872E+01 0.45247778E+01
+ 0.45025383E+01 0.44804669E+01 0.44585617E+01 0.44368211E+01 0.44152431E+01
+ 0.43938262E+01 0.43725686E+01 0.43514687E+01 0.43305247E+01 0.43097350E+01
+ 0.42890981E+01 0.42686124E+01 0.42482762E+01 0.42280881E+01 0.42080464E+01
+ 0.41881497E+01 0.41683966E+01 0.41487855E+01 0.41293149E+01 0.41099835E+01
+ 0.40907899E+01 0.40717326E+01 0.40528103E+01 0.40340216E+01 0.40153652E+01
+ 0.39968398E+01 0.39784439E+01 0.39601765E+01 0.39420361E+01 0.39240216E+01
+ 0.39061317E+01 0.38883651E+01 0.38707207E+01 0.38531972E+01 0.38357936E+01
+ 0.38185085E+01 0.38013409E+01 0.37842897E+01 0.37673536E+01 0.37505317E+01
+ 0.37338227E+01 0.37172257E+01 0.37007395E+01 0.36843632E+01 0.36680956E+01
+ 0.36519357E+01 0.36358826E+01 0.36199351E+01 0.36040924E+01 0.35883534E+01
+ 0.35727172E+01 0.35571828E+01 0.35417492E+01 0.35264156E+01 0.35111810E+01
+ 0.34960445E+01 0.34810052E+01 0.34660622E+01 0.34512146E+01 0.34364616E+01
+ 0.34218022E+01 0.34072357E+01 0.33927612E+01 0.33783779E+01 0.33640849E+01
+ 0.33498815E+01 0.33357668E+01 0.33217401E+01 0.33078005E+01 0.32939473E+01
+ 0.32801797E+01 0.32664970E+01 0.32528984E+01 0.32393832E+01 0.32259506E+01
+ 0.32126000E+01 0.31993305E+01 0.31861416E+01 0.31730324E+01 0.31600024E+01
+ 0.31470507E+01 0.31341769E+01 0.31213801E+01 0.31086597E+01 0.30960151E+01
+ 0.30834456E+01 0.30709505E+01 0.30585294E+01 0.30461814E+01 0.30339060E+01
+ 0.30217026E+01 0.30095706E+01 0.29975094E+01 0.29855183E+01 0.29735969E+01
+ 0.29617445E+01 0.29499605E+01 0.29382444E+01 0.29265956E+01 0.29150136E+01
+ 0.29034978E+01 0.28920477E+01 0.28806627E+01 0.28693423E+01 0.28580859E+01
+ 0.28468931E+01 0.28357634E+01 0.28246962E+01 0.28136909E+01 0.28027472E+01
+ 0.27918645E+01 0.27810424E+01 0.27702803E+01 0.27595778E+01 0.27489343E+01
+ 0.27383495E+01 0.27278228E+01 0.27173539E+01 0.27069421E+01 0.26965872E+01
+ 0.26862886E+01 0.26760459E+01 0.26658587E+01 0.26557265E+01 0.26456490E+01
+ 0.26356256E+01 0.26256559E+01 0.26157396E+01 0.26058763E+01 0.25960654E+01
+ 0.25863067E+01 0.25765997E+01 0.25669440E+01 0.25573393E+01 0.25477851E+01
+ 0.25382810E+01 0.25288268E+01 0.25194219E+01 0.25100661E+01 0.25007590E+01
+ 0.24915001E+01 0.24822892E+01 0.24731258E+01 0.24640097E+01 0.24549405E+01
+ 0.24459177E+01 0.24369412E+01 0.24280104E+01 0.24191252E+01 0.24102852E+01
+ 0.24014899E+01 0.23927392E+01 0.23840326E+01 0.23753699E+01 0.23667507E+01
+ 0.23581748E+01 0.23496417E+01 0.23411512E+01 0.23327031E+01 0.23242968E+01
+ 0.23159323E+01 0.23076092E+01 0.22993271E+01 0.22910858E+01 0.22828850E+01
+ 0.22747244E+01 0.22666038E+01 0.22585228E+01 0.22504811E+01 0.22424785E+01
+ 0.22345148E+01 0.22265895E+01 0.22187026E+01 0.22108536E+01 0.22030423E+01
+ 0.21952686E+01 0.21875320E+01 0.21798324E+01 0.21721694E+01 0.21645429E+01
+ 0.21569526E+01 0.21493983E+01 0.21418796E+01 0.21343964E+01 0.21269484E+01
+ 0.21195353E+01 0.21121570E+01 0.21048132E+01 0.20975036E+01 0.20902280E+01
+ 0.20829863E+01 0.20757781E+01 0.20686032E+01 0.20614615E+01 0.20543526E+01
+ 0.20472765E+01 0.20402328E+01 0.20332213E+01 0.20262419E+01 0.20192942E+01
+ 0.20123782E+01 0.20054936E+01 0.19986402E+01 0.19918177E+01 0.19850260E+01
+ 0.19782650E+01 0.19715342E+01 0.19648337E+01 0.19581632E+01 0.19515224E+01
+ 0.19449112E+01 0.19383295E+01 0.19317769E+01 0.19252534E+01 0.19187587E+01
+ 0.19122927E+01 0.19058551E+01 0.18994459E+01 0.18930647E+01 0.18867115E+01
+ 0.18803860E+01 0.18740881E+01 0.18678176E+01 0.18615743E+01 0.18553581E+01
+ 0.18491688E+01 0.18430061E+01 0.18368701E+01 0.18307604E+01 0.18246769E+01
+ 0.18186195E+01 0.18125880E+01 0.18065822E+01 0.18006019E+01 0.17946471E+01
+ 0.17887176E+01 0.17828131E+01 0.17769336E+01 0.17710789E+01 0.17652489E+01
+ 0.17594433E+01 0.17536621E+01 0.17479051E+01 0.17421721E+01 0.17364630E+01
+ 0.17307777E+01 0.17251159E+01 0.17194777E+01 0.17138628E+01 0.17082711E+01
+ 0.17027024E+01 0.16971566E+01 0.16916337E+01 0.16861333E+01 0.16806555E+01
+ 0.16752000E+01 0.16697668E+01 0.16643557E+01 0.16589665E+01 0.16535993E+01
+ 0.16482537E+01 0.16429297E+01 0.16376272E+01 0.16323460E+01 0.16270861E+01
+ 0.16218472E+01 0.16166293E+01 0.16114323E+01 0.16062560E+01 0.16011003E+01
+ 0.15959650E+01 0.15908502E+01 0.15857556E+01 0.15806812E+01 0.15756267E+01
+ 0.15705922E+01 0.15655775E+01 0.15605824E+01 0.15556069E+01 0.15506509E+01
+ 0.15457143E+01 0.15407968E+01 0.15358985E+01 0.15310193E+01 0.15261589E+01
+ 0.15213174E+01 0.15164945E+01 0.15116903E+01 0.15069045E+01 0.15021372E+01
+ 0.14973881E+01 0.14926573E+01 0.14879445E+01 0.14832497E+01 0.14785729E+01
+ 0.14739138E+01 0.14692724E+01 0.14646486E+01 0.14600423E+01 0.14554534E+01
+ 0.14508818E+01 0.14463274E+01 0.14417902E+01 0.14372700E+01 0.14327668E+01
+ 0.14282803E+01 0.14238107E+01 0.14193577E+01 0.14149213E+01 0.14105014E+01
+ 0.14060978E+01 0.14017106E+01 0.13973397E+01 0.13929848E+01 0.13886460E+01
+ 0.13843232E+01 0.13800163E+01 0.13757252E+01 0.13714497E+01 0.13671900E+01
+ 0.13629457E+01 0.13587170E+01 0.13545036E+01 0.13503056E+01 0.13461228E+01
+ 0.13419551E+01 0.13378025E+01 0.13336649E+01 0.13295423E+01 0.13254344E+01
+ 0.13213413E+01 0.13172630E+01 0.13131992E+01 0.13091500E+01 0.13051152E+01
+ 0.13010948E+01 0.12970888E+01 0.12930969E+01 0.12891193E+01 0.12851557E+01
+ 0.12812062E+01 0.12772707E+01 0.12733490E+01 0.12694411E+01 0.12655470E+01
+ 0.12616666E+01 0.12577998E+01 0.12539465E+01 0.12501067E+01 0.12462803E+01
+ 0.12424673E+01 0.12386675E+01 0.12348810E+01 0.12311076E+01 0.12273472E+01
+ 0.12235999E+01 0.12198656E+01 0.12161441E+01 0.12124354E+01 0.12087396E+01
+ 0.12050564E+01 0.12013858E+01 0.11977279E+01 0.11940824E+01 0.11904494E+01
+ 0.11868288E+01 0.11832206E+01 0.11796246E+01 0.11760408E+01 0.11724692E+01
+ 0.11689097E+01 0.11653623E+01 0.11618268E+01 0.11583033E+01 0.11547916E+01
+ 0.11512918E+01 0.11478037E+01 0.11443273E+01 0.11408626E+01 0.11374094E+01
+ 0.11339678E+01 0.11305377E+01 0.11271191E+01 0.11237118E+01 0.11203158E+01
+ 0.11169311E+01 0.11135576E+01 0.11101953E+01 0.11068442E+01 0.11035040E+01
+ 0.11001749E+01 0.10968568E+01 0.10935496E+01 0.10902532E+01 0.10869677E+01
+ 0.10836929E+01 0.10804289E+01 0.10771755E+01 0.10739327E+01 0.10707005E+01
+ 0.10674788E+01 0.10642676E+01 0.10610669E+01 0.10578765E+01 0.10546964E+01
+ 0.10515266E+01 0.10483671E+01 0.10452178E+01 0.10420786E+01 0.10389496E+01
+ 0.10358306E+01 0.10327216E+01 0.10296226E+01 0.10265335E+01 0.10234543E+01
+ 0.10203849E+01 0.10173253E+01 0.10142755E+01 0.10112354E+01 0.10082050E+01
+ 0.10051842E+01 0.10021730E+01 0.99917134E+00 0.99617917E+00 0.99319647E+00
+ 0.99022319E+00 0.98725929E+00 0.98430473E+00 0.98135947E+00 0.97842347E+00
+ 0.97549669E+00 0.97257908E+00 0.96967063E+00 0.96677127E+00 0.96388098E+00
+ 0.96099971E+00 0.95812743E+00 0.95526410E+00 0.95240969E+00 0.94956414E+00
+ 0.94672743E+00 0.94389953E+00 0.94108038E+00 0.93826996E+00 0.93546824E+00
+ 0.93267516E+00 0.92989070E+00 0.92711483E+00 0.92434750E+00 0.92158868E+00
+ 0.91883834E+00 0.91609644E+00 0.91336295E+00 0.91063782E+00 0.90792104E+00
+ 0.90521256E+00 0.90251235E+00 0.89982037E+00 0.89713660E+00 0.89446099E+00
+ 0.89179352E+00 0.88913416E+00 0.88648286E+00 0.88383960E+00 0.88120435E+00
+ 0.87857707E+00 0.87595774E+00 0.87334631E+00 0.87074276E+00 0.86814705E+00
+ 0.86555917E+00 0.86297906E+00 0.86040671E+00 0.85784209E+00 0.85528515E+00
+ 0.85273588E+00 0.85019424E+00 0.84766020E+00 0.84513374E+00 0.84261481E+00
+ 0.84010340E+00 0.83759947E+00 0.83510300E+00 0.83261395E+00 0.83013230E+00
+ 0.82765802E+00 0.82519108E+00 0.82273145E+00 0.82027910E+00 0.81783401E+00
+ 0.81539615E+00 0.81296548E+00 0.81054199E+00 0.80812564E+00 0.80571641E+00
+ 0.80331428E+00 0.80091920E+00 0.79853116E+00 0.79615014E+00 0.79377609E+00
+ 0.79140901E+00 0.78904885E+00 0.78669560E+00 0.78434924E+00 0.78200972E+00
+ 0.77967703E+00 0.77735115E+00 0.77503204E+00 0.77271969E+00 0.77041406E+00
+ 0.76811514E+00 0.76582289E+00 0.76353730E+00 0.76125834E+00 0.75898598E+00
+ 0.75672020E+00 0.75446098E+00 0.75220828E+00 0.74996210E+00 0.74772240E+00
+ 0.74548917E+00 0.74326237E+00 0.74104198E+00 0.73882799E+00 0.73662036E+00
+ 0.73441908E+00 0.73222413E+00 0.73003547E+00 0.72785309E+00 0.72567696E+00
+ 0.72350707E+00 0.72134338E+00 0.71918589E+00 0.71703456E+00 0.71488937E+00
+ 0.71275031E+00 0.71061735E+00 0.70849047E+00 0.70636965E+00 0.70425486E+00
+ 0.70214609E+00 0.70004331E+00 0.69794651E+00 0.69585566E+00 0.69377074E+00
+ 0.69169174E+00 0.68961862E+00 0.68755138E+00 0.68548999E+00 0.68343442E+00
+ 0.68138467E+00 0.67934071E+00 0.67730251E+00 0.67527007E+00 0.67324336E+00
+ 0.67122236E+00 0.66920705E+00 0.66719742E+00 0.66519344E+00 0.66319509E+00
+ 0.66120236E+00 0.65921522E+00 0.65723366E+00 0.65525766E+00 0.65328720E+00
+ 0.65132226E+00 0.64936282E+00 0.64740887E+00 0.64546039E+00 0.64351735E+00
+ 0.64157974E+00 0.63964754E+00 0.63772074E+00 0.63579931E+00 0.63388324E+00
+ 0.63197252E+00 0.63006711E+00 0.62816701E+00 0.62627220E+00 0.62438266E+00
+ 0.62249837E+00 0.62061932E+00 0.61874549E+00 0.61687686E+00 0.61501342E+00
+ 0.61315514E+00 0.61130202E+00 0.60945404E+00 0.60761117E+00 0.60577340E+00
+ 0.60394072E+00 0.60211311E+00 0.60029056E+00 0.59847304E+00 0.59666054E+00
+ 0.59485305E+00 0.59305055E+00 0.59125302E+00 0.58946045E+00 0.58767282E+00
+ 0.58589012E+00 0.58411233E+00 0.58233943E+00 0.58057142E+00 0.57880826E+00
+ 0.57704996E+00 0.57529650E+00 0.57354785E+00 0.57180401E+00 0.57006495E+00
+ 0.56833068E+00 0.56660116E+00 0.56487638E+00 0.56315634E+00 0.56144101E+00
+ 0.55973038E+00 0.55802444E+00 0.55632318E+00 0.55462657E+00 0.55293460E+00
+ 0.55124727E+00 0.54956455E+00 0.54788643E+00 0.54621290E+00 0.54454394E+00
+ 0.54287954E+00 0.54121969E+00 0.53956437E+00 0.53791357E+00 0.53626727E+00
+ 0.53462547E+00 0.53298814E+00 0.53135528E+00 0.52972687E+00 0.52810289E+00
+ 0.52648334E+00 0.52486821E+00 0.52325747E+00 0.52165111E+00 0.52004913E+00
+ 0.51845151E+00 0.51685823E+00 0.51526929E+00 0.51368467E+00 0.51210436E+00
+ 0.51052834E+00 0.50895661E+00 0.50738914E+00 0.50582594E+00 0.50426698E+00
+ 0.50271225E+00 0.50116175E+00 0.49961545E+00 0.49807335E+00 0.49653543E+00
+ 0.49500169E+00 0.49347210E+00 0.49194667E+00 0.49042537E+00 0.48890819E+00
+ 0.48739513E+00 0.48588617E+00 0.48438129E+00 0.48288050E+00 0.48138377E+00
+ 0.47989109E+00 0.47840246E+00 0.47691786E+00 0.47543727E+00 0.47396070E+00
+ 0.47248812E+00 0.47101953E+00 0.46955492E+00 0.46809426E+00 0.46663756E+00
+ 0.46518480E+00 0.46373597E+00 0.46229106E+00 0.46085006E+00 0.45941295E+00
+ 0.45797973E+00 0.45655039E+00 0.45512491E+00 0.45370329E+00 0.45228551E+00
+ 0.45087156E+00 0.44946143E+00 0.44805512E+00 0.44665261E+00 0.44525388E+00
+ 0.44385894E+00 0.44246777E+00 0.44108036E+00 0.43969670E+00 0.43831677E+00
+ 0.43694058E+00 0.43556810E+00 0.43419933E+00 0.43283427E+00 0.43147289E+00
+ 0.43011518E+00 0.42876115E+00 0.42741078E+00 0.42606405E+00 0.42472096E+00
+ 0.42338151E+00 0.42204567E+00 0.42071344E+00 0.41938481E+00 0.41805978E+00
+ 0.41673832E+00 0.41542043E+00 0.41410611E+00 0.41279534E+00 0.41148811E+00
+ 0.41018442E+00 0.40888424E+00 0.40758759E+00 0.40629444E+00 0.40500478E+00
+ 0.40371862E+00 0.40243593E+00 0.40115670E+00 0.39988094E+00 0.39860863E+00
+ 0.39733976E+00 0.39607432E+00 0.39481231E+00 0.39355371E+00 0.39229851E+00
+ 0.39104671E+00 0.38979830E+00 0.38855327E+00 0.38731161E+00 0.38607331E+00
+ 0.38483837E+00 0.38360676E+00 0.38237849E+00 0.38115355E+00 0.37993193E+00
+ 0.37871362E+00 0.37749861E+00 0.37628689E+00 0.37507845E+00 0.37387329E+00
+ 0.37267140E+00 0.37147277E+00 0.37027739E+00 0.36908525E+00 0.36789634E+00
+ 0.36671066E+00 0.36552820E+00 0.36434895E+00 0.36317290E+00 0.36200004E+00
+ 0.36083037E+00 0.35966387E+00 0.35850054E+00 0.35734038E+00 0.35618337E+00
+ 0.35502950E+00 0.35387877E+00 0.35273117E+00 0.35158669E+00 0.35044532E+00
+ 0.34930706E+00 0.34817190E+00 0.34703983E+00 0.34591084E+00 0.34478493E+00
+ 0.34366208E+00 0.34254229E+00 0.34142556E+00 0.34031186E+00 0.33920121E+00
+ 0.33809358E+00 0.33698898E+00 0.33588739E+00 0.33478881E+00 0.33369323E+00
+ 0.33260063E+00 0.33151103E+00 0.33042440E+00 0.32934074E+00 0.32826004E+00
+ 0.32718230E+00 0.32610750E+00 0.32503565E+00 0.32396673E+00 0.32290073E+00
+ 0.32183766E+00 0.32077750E+00 0.31972024E+00 0.31866588E+00 0.31761441E+00
+ 0.31656582E+00 0.31552011E+00 0.31447727E+00 0.31343730E+00 0.31240018E+00
+ 0.31136590E+00 0.31033447E+00 0.30930588E+00 0.30828011E+00 0.30725716E+00
+ 0.30623703E+00 0.30521971E+00 0.30420518E+00 0.30319345E+00 0.30218451E+00
+ 0.30117835E+00 0.30017496E+00 0.29917434E+00 0.29817648E+00 0.29718137E+00
+ 0.29618901E+00 0.29519940E+00 0.29421251E+00 0.29322835E+00 0.29224692E+00
+ 0.29126820E+00 0.29029219E+00 0.28931887E+00 0.28834826E+00 0.28738033E+00
+ 0.28641509E+00 0.28545252E+00 0.28449262E+00 0.28353538E+00 0.28258080E+00
+ 0.28162887E+00 0.28067959E+00 0.27973294E+00 0.27878892E+00 0.27784753E+00
+ 0.27690876E+00 0.27597260E+00 0.27503905E+00 0.27410810E+00 0.27317975E+00
+ 0.27225398E+00 0.27133079E+00 0.27041018E+00 0.26949215E+00 0.26857667E+00
+ 0.26766375E+00 0.26675339E+00 0.26584557E+00 0.26494029E+00 0.26403754E+00
+ 0.26313733E+00 0.26223963E+00 0.26134445E+00 0.26045178E+00 0.25956162E+00
+ 0.25867395E+00 0.25778878E+00 0.25690609E+00 0.25602588E+00 0.25514815E+00
+ 0.25427289E+00 0.25340009E+00 0.25252975E+00 0.25166186E+00 0.25079642E+00
+ 0.24993342E+00 0.24907285E+00 0.24821472E+00 0.24735900E+00 0.24650571E+00
+ 0.24565482E+00 0.24480635E+00 0.24396027E+00 0.24311659E+00 0.24227530E+00
+ 0.24143639E+00 0.24059986E+00 0.23976571E+00 0.23893392E+00 0.23810450E+00
+ 0.23727743E+00 0.23645271E+00 0.23563034E+00 0.23481031E+00 0.23399261E+00
+ 0.23317725E+00 0.23236420E+00 0.23155348E+00 0.23074507E+00 0.22993897E+00
+ 0.22913517E+00 0.22833366E+00 0.22753445E+00 0.22673753E+00 0.22594288E+00
+ 0.22515052E+00 0.22436042E+00 0.22357259E+00 0.22278702E+00 0.22200370E+00
+ 0.22122264E+00 0.22044381E+00 0.21966723E+00 0.21889288E+00 0.21812077E+00
+ 0.21735087E+00 0.21658319E+00 0.21581773E+00 0.21505448E+00 0.21429343E+00
+ 0.21353458E+00 0.21277792E+00 0.21202345E+00 0.21127116E+00 0.21052105E+00
+ 0.20977311E+00 0.20902734E+00 0.20828374E+00 0.20754229E+00 0.20680300E+00
+ 0.20606585E+00 0.20533085E+00 0.20459798E+00 0.20386725E+00 0.20313865E+00
+ 0.20241217E+00 0.20168781E+00 0.20096556E+00 0.20024542E+00 0.19952738E+00
+ 0.19881145E+00 0.19809761E+00 0.19738585E+00 0.19667619E+00 0.19596860E+00
+ 0.19526308E+00 0.19455964E+00 0.19385826E+00 0.19315894E+00 0.19246168E+00
+ 0.19176647E+00 0.19107331E+00 0.19038219E+00 0.18969310E+00 0.18900605E+00
+ 0.18832102E+00 0.18763802E+00 0.18695703E+00 0.18627806E+00 0.18560110E+00
+ 0.18492614E+00 0.18425318E+00 0.18358222E+00 0.18291324E+00 0.18224625E+00
+ 0.18158125E+00 0.18091822E+00 0.18025716E+00 0.17959807E+00 0.17894094E+00
+ 0.17828577E+00 0.17763255E+00 0.17698128E+00 0.17633196E+00 0.17568458E+00
+ 0.17503913E+00 0.17439562E+00 0.17375403E+00 0.17311436E+00 0.17247662E+00
+ 0.17184078E+00 0.17120685E+00 0.17057483E+00 0.16994471E+00 0.16931649E+00
+ 0.16869015E+00 0.16806570E+00 0.16744314E+00 0.16682245E+00 0.16620364E+00
+ 0.16558669E+00 0.16497162E+00 0.16435840E+00 0.16374704E+00 0.16313753E+00
+ 0.16252986E+00 0.16192405E+00 0.16132007E+00 0.16071792E+00 0.16011761E+00
+ 0.15951912E+00 0.15892245E+00 0.15832760E+00 0.15773457E+00 0.15714334E+00
+ 0.15655392E+00 0.15596630E+00 0.15538048E+00 0.15479645E+00 0.15421421E+00
+ 0.15363375E+00 0.15305507E+00 0.15247817E+00 0.15190304E+00 0.15132967E+00
+ 0.15075807E+00 0.15018823E+00 0.14962015E+00 0.14905381E+00 0.14848922E+00
+ 0.14792637E+00 0.14736527E+00 0.14680589E+00 0.14624825E+00 0.14569233E+00
+ 0.14513813E+00 0.14458566E+00 0.14403489E+00 0.14348584E+00 0.14293849E+00
+ 0.14239285E+00 0.14184890E+00 0.14130665E+00 0.14076608E+00 0.14022721E+00
+ 0.13969001E+00 0.13915449E+00 0.13862065E+00 0.13808847E+00 0.13755796E+00
+ 0.13702912E+00 0.13650193E+00 0.13597639E+00 0.13545251E+00 0.13493027E+00
+ 0.13440968E+00 0.13389072E+00 0.13337340E+00 0.13285770E+00 0.13234364E+00
+ 0.13183119E+00 0.13132037E+00 0.13081116E+00 0.13030356E+00 0.12979757E+00
+ 0.12929319E+00 0.12879040E+00 0.12828921E+00 0.12778961E+00 0.12729160E+00
+ 0.12679517E+00 0.12630032E+00 0.12580705E+00 0.12531536E+00 0.12482523E+00
+ 0.12433667E+00 0.12384966E+00 0.12336422E+00 0.12288033E+00 0.12239799E+00
+ 0.12191720E+00 0.12143795E+00 0.12096024E+00 0.12048406E+00 0.12000942E+00
+ 0.11953630E+00 0.11906471E+00 0.11859464E+00 0.11812608E+00 0.11765904E+00
+ 0.11719351E+00 0.11672948E+00 0.11626696E+00 0.11580593E+00 0.11534640E+00
+ 0.11488836E+00 0.11443180E+00 0.11397673E+00 0.11352314E+00 0.11307103E+00
+ 0.11262039E+00 0.11217122E+00 0.11172351E+00 0.11127727E+00 0.11083248E+00
+ 0.11038915E+00 0.10994727E+00 0.10950684E+00 0.10906785E+00 0.10863030E+00
+ 0.10819419E+00 0.10775951E+00 0.10732627E+00 0.10689444E+00 0.10646405E+00
+ 0.10603507E+00 0.10560750E+00 0.10518135E+00 0.10475661E+00 0.10433327E+00
+ 0.10391133E+00 0.10349079E+00 0.10307165E+00 0.10265390E+00 0.10223753E+00
+ 0.10182255E+00 0.10140895E+00 0.10099673E+00 0.10058588E+00 0.10017640E+00
+ 0.99768284E-01 0.99361534E-01 0.98956145E-01 0.98552112E-01 0.98149433E-01
+ 0.97748103E-01 0.97348119E-01 0.96949478E-01 0.96552176E-01 0.96156211E-01
+ 0.95761578E-01 0.95368274E-01 0.94976297E-01 0.94585641E-01 0.94196305E-01
+ 0.93808285E-01 0.93421577E-01 0.93036178E-01 0.92652085E-01 0.92269294E-01
+ 0.91887802E-01 0.91507606E-01 0.91128702E-01 0.90751087E-01 0.90374758E-01
+ 0.89999711E-01 0.89625944E-01 0.89253452E-01 0.88882232E-01 0.88512282E-01
+ 0.88143598E-01 0.87776176E-01 0.87410014E-01 0.87045107E-01 0.86681454E-01
+ 0.86319050E-01 0.85957892E-01 0.85597977E-01 0.85239303E-01 0.84881864E-01
+ 0.84525659E-01 0.84170684E-01 0.83816936E-01 0.83464411E-01 0.83113107E-01
+ 0.82763020E-01 0.82414147E-01 0.82066485E-01 0.81720031E-01 0.81374781E-01
+ 0.81030732E-01 0.80687881E-01 0.80346224E-01 0.80005760E-01 0.79666484E-01
+ 0.79328393E-01 0.78991485E-01 0.78655755E-01 0.78321202E-01 0.77987821E-01
+ 0.77655610E-01 0.77324565E-01 0.76994684E-01 0.76665962E-01 0.76338398E-01
+ 0.76011988E-01 0.75686728E-01 0.75362616E-01 0.75039649E-01 0.74717824E-01
+ 0.74397137E-01 0.74077585E-01 0.73759165E-01 0.73441875E-01 0.73125710E-01
+ 0.72810669E-01 0.72496748E-01 0.72183943E-01 0.71872253E-01 0.71561673E-01
+ 0.71252200E-01 0.70943833E-01 0.70636567E-01 0.70330400E-01 0.70025328E-01
+ 0.69721348E-01 0.69418459E-01 0.69116655E-01 0.68815935E-01 0.68516296E-01
+ 0.68217734E-01 0.67920246E-01 0.67623830E-01 0.67328482E-01 0.67034199E-01
+ 0.66740979E-01 0.66448819E-01 0.66157715E-01 0.65867664E-01 0.65578664E-01
+ 0.65290711E-01 0.65003803E-01 0.64717937E-01 0.64433109E-01 0.64149316E-01
+ 0.63866557E-01 0.63584827E-01 0.63304124E-01 0.63024445E-01 0.62745787E-01
+ 0.62468147E-01 0.62191522E-01 0.61915909E-01 0.61641305E-01 0.61367708E-01
+ 0.61095113E-01 0.60823520E-01 0.60552924E-01 0.60283322E-01 0.60014712E-01
+ 0.59747092E-01 0.59480457E-01 0.59214805E-01 0.58950133E-01 0.58686438E-01
+ 0.58423718E-01 0.58161969E-01 0.57901189E-01 0.57641374E-01 0.57382522E-01
+ 0.57124630E-01 0.56867696E-01 0.56611715E-01 0.56356686E-01 0.56102605E-01
+ 0.55849470E-01 0.55597278E-01 0.55346025E-01 0.55095710E-01 0.54846329E-01
+ 0.54597879E-01 0.54350358E-01 0.54103762E-01 0.53858089E-01 0.53613336E-01
+ 0.53369501E-01 0.53126579E-01 0.52884569E-01 0.52643468E-01 0.52403272E-01
+ 0.52163980E-01 0.51925587E-01 0.51688092E-01 0.51451491E-01 0.51215782E-01
+ 0.50980962E-01 0.50747028E-01 0.50513978E-01 0.50281807E-01 0.50050514E-01
+ 0.49820096E-01 0.49590550E-01 0.49361873E-01 0.49134063E-01 0.48907116E-01
+ 0.48681029E-01 0.48455801E-01 0.48231428E-01 0.48007907E-01 0.47785235E-01
+ 0.47563411E-01 0.47342430E-01 0.47122290E-01 0.46902989E-01 0.46684523E-01
+ 0.46466889E-01 0.46250086E-01 0.46034110E-01 0.45818958E-01 0.45604627E-01
+ 0.45391115E-01 0.45178419E-01 0.44966536E-01 0.44755463E-01 0.44545198E-01
+ 0.44335737E-01 0.44127079E-01 0.43919219E-01 0.43712156E-01 0.43505885E-01
+ 0.43300406E-01 0.43095714E-01 0.42891808E-01 0.42688683E-01 0.42486338E-01
+ 0.42284770E-01 0.42083975E-01 0.41883951E-01 0.41684695E-01 0.41486204E-01
+ 0.41288476E-01 0.41091508E-01 0.40895296E-01 0.40699838E-01 0.40505131E-01
+ 0.40311173E-01 0.40117960E-01 0.39925489E-01 0.39733759E-01 0.39542765E-01
+ 0.39352505E-01 0.39162977E-01 0.38974176E-01 0.38786102E-01 0.38598750E-01
+ 0.38412117E-01 0.38226201E-01 0.38041000E-01 0.37856509E-01 0.37672727E-01
+ 0.37489650E-01 0.37307275E-01 0.37125600E-01 0.36944621E-01 0.36764336E-01
+ 0.36584742E-01 0.36405836E-01 0.36227615E-01 0.36050075E-01 0.35873215E-01
+ 0.35697031E-01 0.35521519E-01 0.35346679E-01 0.35172505E-01 0.34998995E-01
+ 0.34826147E-01 0.34653957E-01 0.34482423E-01 0.34311540E-01 0.34141307E-01
+ 0.33971720E-01 0.33802777E-01 0.33634473E-01 0.33466807E-01 0.33299775E-01
+ 0.33133374E-01 0.32967601E-01 0.32802453E-01 0.32637927E-01 0.32474019E-01
+ 0.32310727E-01 0.32148048E-01 0.31985978E-01 0.31824514E-01 0.31663654E-01
+ 0.31503394E-01 0.31343730E-01 0.31184660E-01 0.31026180E-01 0.30868288E-01
+ 0.30710980E-01 0.30554252E-01 0.30398103E-01 0.30242527E-01 0.30087523E-01
+ 0.29933086E-01 0.29779215E-01 0.29625904E-01 0.29473151E-01 0.29320953E-01
+ 0.29169307E-01 0.29018208E-01 0.28867654E-01 0.28717641E-01 0.28568166E-01
+ 0.28419225E-01 0.28270816E-01 0.28122934E-01 0.27975576E-01 0.27828739E-01
+ 0.27682419E-01 0.27536612E-01 0.27391316E-01 0.27246527E-01 0.27102240E-01
+ 0.26958454E-01 0.26815163E-01 0.26672364E-01 0.26530055E-01 0.26388230E-01
+ 0.26246887E-01 0.26106022E-01 0.25965631E-01 0.25825710E-01 0.25686256E-01
+ 0.25547265E-01 0.25408734E-01 0.25270657E-01 0.25133033E-01 0.24995856E-01
+ 0.24859124E-01 0.24722831E-01 0.24586975E-01 0.24451551E-01 0.24316556E-01
+ 0.24181985E-01 0.24047835E-01 0.23914101E-01 0.23780781E-01 0.23647868E-01
+ 0.23515361E-01 0.23383254E-01 0.23251543E-01 0.23120225E-01 0.22989295E-01
+ 0.22858750E-01 0.22728584E-01 0.22598794E-01 0.22469375E-01 0.22340324E-01
+ 0.22211637E-01 0.22083308E-01 0.21955333E-01 0.21827709E-01 0.21700431E-01
+ 0.21573495E-01 0.21446895E-01 0.21320629E-01 0.21194691E-01 0.21069078E-01
+ 0.20943783E-01 0.20818805E-01 0.20694136E-01 0.20569774E-01 0.20445714E-01
+ 0.20321950E-01 0.20198480E-01 0.20075297E-01 0.19952398E-01 0.19829777E-01
+ 0.19707431E-01 0.19585354E-01 0.19463542E-01 0.19341991E-01 0.19220695E-01
+ 0.19099649E-01 0.18978850E-01 0.18858293E-01 0.18737972E-01 0.18617883E-01
+ 0.18498022E-01 0.18378383E-01 0.18258961E-01 0.18139753E-01 0.18020753E-01
+ 0.17901956E-01 0.17783358E-01 0.17664954E-01 0.17546739E-01 0.17428708E-01
+ 0.17310857E-01 0.17193181E-01 0.17075674E-01 0.16958333E-01 0.16841152E-01
+ 0.16724128E-01 0.16607254E-01 0.16490526E-01 0.16373940E-01 0.16257491E-01
+ 0.16141175E-01 0.16024986E-01 0.15908920E-01 0.15792973E-01 0.15677139E-01
+ 0.15561415E-01 0.15445796E-01 0.15330277E-01 0.15214855E-01 0.15099524E-01
+ 0.14984281E-01 0.14869121E-01 0.14754040E-01 0.14639033E-01 0.14524098E-01
+ 0.14409229E-01 0.14294423E-01 0.14179675E-01 0.14064983E-01 0.13950342E-01
+ 0.13835749E-01 0.13721200E-01 0.13606691E-01 0.13492220E-01 0.13377783E-01
+ 0.13263377E-01 0.13148999E-01 0.13034645E-01 0.12920314E-01 0.12806002E-01
+ 0.12691707E-01 0.12577427E-01 0.12463159E-01 0.12348901E-01 0.12234651E-01
+ 0.12120408E-01 0.12006170E-01 0.11891934E-01 0.11777702E-01 0.11663470E-01
+ 0.11549238E-01 0.11435006E-01 0.11320773E-01 0.11206539E-01 0.11092303E-01
+ 0.10978067E-01 0.10863830E-01 0.10749594E-01 0.10635358E-01 0.10521125E-01
+ 0.10406896E-01 0.10292673E-01 0.10178458E-01 0.10064252E-01 0.99500595E-02
+ 0.98358826E-02 0.97217247E-02 0.96075896E-02 0.94934810E-02 0.93794033E-02
+ 0.92653613E-02 0.91513598E-02 0.90374042E-02 0.89235004E-02 0.88096544E-02
+ 0.86958728E-02 0.85821624E-02 0.84685307E-02 0.83549854E-02 0.82415346E-02
+ 0.81281869E-02 0.80149514E-02 0.79018375E-02 0.77888552E-02 0.76760147E-02
+ 0.75633269E-02 0.74508032E-02 0.73384551E-02 0.72262950E-02 0.71143356E-02
+ 0.70025900E-02 0.68910718E-02 0.67797951E-02 0.66687747E-02 0.65580255E-02
+ 0.64475632E-02 0.63374037E-02 0.62275637E-02 0.61180601E-02 0.60089104E-02
+ 0.59001325E-02 0.57917450E-02 0.56837666E-02 0.55762167E-02 0.54691150E-02
+ 0.53624818E-02 0.52563377E-02 0.51507037E-02 0.50456012E-02 0.49410522E-02
+ 0.48370787E-02 0.47337034E-02 0.46309490E-02 0.45288389E-02 0.44273965E-02
+ 0.43266456E-02 0.42266102E-02 0.41273145E-02 0.40287831E-02 0.39310405E-02
+ 0.38341115E-02 0.37380209E-02 0.36427938E-02 0.35484552E-02 0.34550300E-02
+ 0.33625433E-02 0.32710200E-02 0.31804850E-02 0.30909630E-02 0.30024784E-02
+ 0.29150556E-02 0.28287187E-02 0.27434913E-02 0.26593968E-02 0.25764583E-02
+ 0.24946981E-02 0.24141385E-02 0.23348007E-02 0.22567058E-02 0.21798740E-02
+ 0.21043248E-02 0.20300771E-02 0.19571488E-02 0.18855573E-02 0.18153187E-02
+ 0.17464486E-02 0.16789612E-02 0.16128700E-02 0.15481872E-02 0.14849241E-02
+ 0.14230907E-02 0.13626959E-02 0.13037472E-02 0.12462511E-02 0.11902126E-02
+ 0.11356355E-02 0.10825221E-02 0.10308734E-02 0.98068902E-03 0.93196716E-03
+ 0.88470455E-03 0.83889650E-03 0.79453686E-03 0.75161805E-03 0.71013100E-03
+ 0.67006525E-03 0.63140884E-03 0.59414845E-03 0.55826932E-03 0.52375533E-03
+ 0.49058900E-03 0.45875154E-03 0.42822289E-03 0.39898174E-03 0.37100558E-03
+ 0.34427076E-03 0.31875257E-03 0.29442524E-03 0.27126203E-03 0.24923532E-03
+ 0.22831664E-03 0.20847675E-03 0.18968573E-03 0.17191305E-03 0.15512763E-03
+ 0.13929797E-03 0.12439214E-03 0.11037798E-03 0.97223073E-04 0.84894904E-04
+ 0.73360904E-04 0.62588545E-04 0.52545417E-04 0.43199310E-04 0.34518285E-04
+ 0.26470755E-04 0.19025555E-04 0.12152007E-04 0.58199898E-05 0.00000000E+00
+ 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03
+ 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03
+ 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03
+ 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03
+ 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03
+ 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03
+ 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03
+ 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03
+ 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03 0.12471708E+03
+ 0.12457030E+03 0.12126502E+03 0.11811569E+03 0.11511188E+03 0.11224403E+03
+ 0.10950339E+03 0.10688194E+03 0.10437232E+03 0.10196773E+03 0.99661915E+02
+ 0.97449101E+02 0.95323945E+02 0.93281498E+02 0.91317174E+02 0.89426712E+02
+ 0.87606152E+02 0.85851807E+02 0.84160239E+02 0.82528243E+02 0.80952825E+02
+ 0.79431181E+02 0.77960692E+02 0.76538900E+02 0.75163499E+02 0.73832327E+02
+ 0.72543350E+02 0.71294656E+02 0.70084442E+02 0.68911014E+02 0.67772771E+02
+ 0.66668202E+02 0.65595882E+02 0.64554463E+02 0.63542669E+02 0.62559294E+02
+ 0.61603192E+02 0.60673282E+02 0.59768534E+02 0.58887973E+02 0.58030671E+02
+ 0.57195747E+02 0.56382365E+02 0.55589726E+02 0.54817071E+02 0.54063679E+02
+ 0.53328859E+02 0.52611954E+02 0.51912338E+02 0.51229412E+02 0.50562604E+02
+ 0.49911368E+02 0.49275181E+02 0.48653545E+02 0.48045980E+02 0.47452029E+02
+ 0.46871254E+02 0.46303235E+02 0.45747568E+02 0.45203868E+02 0.44671764E+02
+ 0.44150901E+02 0.43640936E+02 0.43141542E+02 0.42652404E+02 0.42173218E+02
+ 0.41703693E+02 0.41243549E+02 0.40792516E+02 0.40350334E+02 0.39916754E+02
+ 0.39491534E+02 0.39074441E+02 0.38665254E+02 0.38263755E+02 0.37869736E+02
+ 0.37482997E+02 0.37103343E+02 0.36730589E+02 0.36364552E+02 0.36005059E+02
+ 0.35651941E+02 0.35305035E+02 0.34964183E+02 0.34629233E+02 0.34300037E+02
+ 0.33976454E+02 0.33658344E+02 0.33345574E+02 0.33038016E+02 0.32735543E+02
+ 0.32438034E+02 0.32145371E+02 0.31857442E+02 0.31574134E+02 0.31295341E+02
+ 0.31020960E+02 0.30750888E+02 0.30485029E+02 0.30223288E+02 0.29965571E+02
+ 0.29711791E+02 0.29461860E+02 0.29215693E+02 0.28973209E+02 0.28734328E+02
+ 0.28498972E+02 0.28267067E+02 0.28038539E+02 0.27813317E+02 0.27591332E+02
+ 0.27372516E+02 0.27156805E+02 0.26944133E+02 0.26734440E+02 0.26527665E+02
+ 0.26323749E+02 0.26122635E+02 0.25924267E+02 0.25728591E+02 0.25535554E+02
+ 0.25345104E+02 0.25157191E+02 0.24971767E+02 0.24788782E+02 0.24608192E+02
+ 0.24429950E+02 0.24254012E+02 0.24080335E+02 0.23908877E+02 0.23739597E+02
+ 0.23572454E+02 0.23407410E+02 0.23244426E+02 0.23083465E+02 0.22924490E+02
+ 0.22767466E+02 0.22612359E+02 0.22459133E+02 0.22307756E+02 0.22158196E+02
+ 0.22010421E+02 0.21864400E+02 0.21720103E+02 0.21577500E+02 0.21436562E+02
+ 0.21297261E+02 0.21159569E+02 0.21023460E+02 0.20888906E+02 0.20755883E+02
+ 0.20624364E+02 0.20494325E+02 0.20365742E+02 0.20238591E+02 0.20112849E+02
+ 0.19988492E+02 0.19865500E+02 0.19743850E+02 0.19623520E+02 0.19504490E+02
+ 0.19386739E+02 0.19270248E+02 0.19154996E+02 0.19040965E+02 0.18928136E+02
+ 0.18816490E+02 0.18706008E+02 0.18596674E+02 0.18488471E+02 0.18381380E+02
+ 0.18275385E+02 0.18170470E+02 0.18066619E+02 0.17963816E+02 0.17862045E+02
+ 0.17761292E+02 0.17661542E+02 0.17562779E+02 0.17464991E+02 0.17368162E+02
+ 0.17272279E+02 0.17177328E+02 0.17083297E+02 0.16990171E+02 0.16897939E+02
+ 0.16806588E+02 0.16716106E+02 0.16626480E+02 0.16537698E+02 0.16449749E+02
+ 0.16362622E+02 0.16276305E+02 0.16190788E+02 0.16106059E+02 0.16022107E+02
+ 0.15938923E+02 0.15856495E+02 0.15774815E+02 0.15693872E+02 0.15613655E+02
+ 0.15534157E+02 0.15455367E+02 0.15377275E+02 0.15299874E+02 0.15223153E+02
+ 0.15147104E+02 0.15071719E+02 0.14996989E+02 0.14922905E+02 0.14849460E+02
+ 0.14776645E+02 0.14704453E+02 0.14632875E+02 0.14561904E+02 0.14491532E+02
+ 0.14421752E+02 0.14352556E+02 0.14283938E+02 0.14215890E+02 0.14148405E+02
+ 0.14081476E+02 0.14015097E+02 0.13949261E+02 0.13883961E+02 0.13819192E+02
+ 0.13754946E+02 0.13691217E+02 0.13628000E+02 0.13565287E+02 0.13503074E+02
+ 0.13441355E+02 0.13380122E+02 0.13319372E+02 0.13259098E+02 0.13199295E+02
+ 0.13139957E+02 0.13081079E+02 0.13022656E+02 0.12964683E+02 0.12907154E+02
+ 0.12850064E+02 0.12793408E+02 0.12737182E+02 0.12681381E+02 0.12626000E+02
+ 0.12571034E+02 0.12516479E+02 0.12462330E+02 0.12408582E+02 0.12355232E+02
+ 0.12302274E+02 0.12249705E+02 0.12197520E+02 0.12145716E+02 0.12094288E+02
+ 0.12043231E+02 0.11992543E+02 0.11942218E+02 0.11892254E+02 0.11842646E+02
+ 0.11793391E+02 0.11744485E+02 0.11695924E+02 0.11647704E+02 0.11599822E+02
+ 0.11552275E+02 0.11505059E+02 0.11458170E+02 0.11411606E+02 0.11365362E+02
+ 0.11319436E+02 0.11273824E+02 0.11228523E+02 0.11183530E+02 0.11138842E+02
+ 0.11094455E+02 0.11050367E+02 0.11006575E+02 0.10963076E+02 0.10919866E+02
+ 0.10876943E+02 0.10834305E+02 0.10791947E+02 0.10749868E+02 0.10708065E+02
+ 0.10666535E+02 0.10625275E+02 0.10584282E+02 0.10543555E+02 0.10503091E+02
+ 0.10462886E+02 0.10422939E+02 0.10383247E+02 0.10343808E+02 0.10304619E+02
+ 0.10265678E+02 0.10226982E+02 0.10188529E+02 0.10150317E+02 0.10112344E+02
+ 0.10074607E+02 0.10037104E+02 0.99998327E+01 0.99627915E+01 0.99259780E+01
+ 0.98893900E+01 0.98530255E+01 0.98168824E+01 0.97809587E+01 0.97452523E+01
+ 0.97097614E+01 0.96744839E+01 0.96394179E+01 0.96045615E+01 0.95699128E+01
+ 0.95354700E+01 0.95012311E+01 0.94671944E+01 0.94333580E+01 0.93997202E+01
+ 0.93662793E+01 0.93330334E+01 0.92999809E+01 0.92671201E+01 0.92344492E+01
+ 0.92019666E+01 0.91696707E+01 0.91375599E+01 0.91056324E+01 0.90738869E+01
+ 0.90423216E+01 0.90109351E+01 0.89797257E+01 0.89486920E+01 0.89178325E+01
+ 0.88871457E+01 0.88566301E+01 0.88262843E+01 0.87961069E+01 0.87660963E+01
+ 0.87362513E+01 0.87065704E+01 0.86770523E+01 0.86476955E+01 0.86184988E+01
+ 0.85894609E+01 0.85605803E+01 0.85318558E+01 0.85032862E+01 0.84748702E+01
+ 0.84466064E+01 0.84184937E+01 0.83905308E+01 0.83627164E+01 0.83350495E+01
+ 0.83075288E+01 0.82801531E+01 0.82529213E+01 0.82258321E+01 0.81988845E+01
+ 0.81720773E+01 0.81454095E+01 0.81188798E+01 0.80924872E+01 0.80662306E+01
+ 0.80401090E+01 0.80141212E+01 0.79882663E+01 0.79625431E+01 0.79369507E+01
+ 0.79114880E+01 0.78861541E+01 0.78609478E+01 0.78358683E+01 0.78109146E+01
+ 0.77860856E+01 0.77613805E+01 0.77367982E+01 0.77123379E+01 0.76879986E+01
+ 0.76637793E+01 0.76396793E+01 0.76156975E+01 0.75918330E+01 0.75680851E+01
+ 0.75444528E+01 0.75209352E+01 0.74975315E+01 0.74742408E+01 0.74510623E+01
+ 0.74279952E+01 0.74050385E+01 0.73821916E+01 0.73594536E+01 0.73368237E+01
+ 0.73143011E+01 0.72918850E+01 0.72695747E+01 0.72473693E+01 0.72252681E+01
+ 0.72032703E+01 0.71813753E+01 0.71595821E+01 0.71378902E+01 0.71162988E+01
+ 0.70948071E+01 0.70734145E+01 0.70521202E+01 0.70309235E+01 0.70098238E+01
+ 0.69888203E+01 0.69679124E+01 0.69470993E+01 0.69263805E+01 0.69057552E+01
+ 0.68852229E+01 0.68647828E+01 0.68444342E+01 0.68241767E+01 0.68040094E+01
+ 0.67839319E+01 0.67639434E+01 0.67440434E+01 0.67242313E+01 0.67045064E+01
+ 0.66848681E+01 0.66653159E+01 0.66458492E+01 0.66264673E+01 0.66071697E+01
+ 0.65879558E+01 0.65688251E+01 0.65497770E+01 0.65308109E+01 0.65119264E+01
+ 0.64931227E+01 0.64743994E+01 0.64557560E+01 0.64371919E+01 0.64187066E+01
+ 0.64002995E+01 0.63819702E+01 0.63637181E+01 0.63455428E+01 0.63274436E+01
+ 0.63094201E+01 0.62914719E+01 0.62735984E+01 0.62557991E+01 0.62380735E+01
+ 0.62204213E+01 0.62028418E+01 0.61853346E+01 0.61678992E+01 0.61505353E+01
+ 0.61332422E+01 0.61160197E+01 0.60988671E+01 0.60817841E+01 0.60647702E+01
+ 0.60478250E+01 0.60309480E+01 0.60141389E+01 0.59973971E+01 0.59807222E+01
+ 0.59641139E+01 0.59475717E+01 0.59310952E+01 0.59146840E+01 0.58983376E+01
+ 0.58820557E+01 0.58658378E+01 0.58496837E+01 0.58335927E+01 0.58175647E+01
+ 0.58015991E+01 0.57856957E+01 0.57698539E+01 0.57540735E+01 0.57383541E+01
+ 0.57226952E+01 0.57070965E+01 0.56915577E+01 0.56760784E+01 0.56606582E+01
+ 0.56452968E+01 0.56299938E+01 0.56147488E+01 0.55995615E+01 0.55844316E+01
+ 0.55693587E+01 0.55543425E+01 0.55393826E+01 0.55244787E+01 0.55096305E+01
+ 0.54948376E+01 0.54800997E+01 0.54654165E+01 0.54507876E+01 0.54362128E+01
+ 0.54216916E+01 0.54072239E+01 0.53928093E+01 0.53784475E+01 0.53641381E+01
+ 0.53498809E+01 0.53356755E+01 0.53215217E+01 0.53074192E+01 0.52933676E+01
+ 0.52793667E+01 0.52654161E+01 0.52515157E+01 0.52376650E+01 0.52238639E+01
+ 0.52101120E+01 0.51964091E+01 0.51827548E+01 0.51691489E+01 0.51555912E+01
+ 0.51420813E+01 0.51286190E+01 0.51152039E+01 0.51018360E+01 0.50885148E+01
+ 0.50752401E+01 0.50620117E+01 0.50488293E+01 0.50356926E+01 0.50226015E+01
+ 0.50095555E+01 0.49965546E+01 0.49835984E+01 0.49706867E+01 0.49578192E+01
+ 0.49449957E+01 0.49322160E+01 0.49194798E+01 0.49067869E+01 0.48941371E+01
+ 0.48815300E+01 0.48689656E+01 0.48564435E+01 0.48439635E+01 0.48315254E+01
+ 0.48191290E+01 0.48067740E+01 0.47944603E+01 0.47821875E+01 0.47699556E+01
+ 0.47577642E+01 0.47456131E+01 0.47335022E+01 0.47214312E+01 0.47093999E+01
+ 0.46974081E+01 0.46854556E+01 0.46735422E+01 0.46616676E+01 0.46498318E+01
+ 0.46380344E+01 0.46262752E+01 0.46145542E+01 0.46028710E+01 0.45912255E+01
+ 0.45796175E+01 0.45680467E+01 0.45565131E+01 0.45450164E+01 0.45335563E+01
+ 0.45221328E+01 0.45107457E+01 0.44993947E+01 0.44880796E+01 0.44768003E+01
+ 0.44655567E+01 0.44543484E+01 0.44431754E+01 0.44320375E+01 0.44209344E+01
+ 0.44098661E+01 0.43988323E+01 0.43878329E+01 0.43768676E+01 0.43659364E+01
+ 0.43550390E+01 0.43441753E+01 0.43333451E+01 0.43225482E+01 0.43117846E+01
+ 0.43010539E+01 0.42903561E+01 0.42796910E+01 0.42690585E+01 0.42584583E+01
+ 0.42478903E+01 0.42373544E+01 0.42268503E+01 0.42163781E+01 0.42059374E+01
+ 0.41955281E+01 0.41851502E+01 0.41748034E+01 0.41644875E+01 0.41542025E+01
+ 0.41439482E+01 0.41337244E+01 0.41235310E+01 0.41133679E+01 0.41032349E+01
+ 0.40931318E+01 0.40830585E+01 0.40730150E+01 0.40630009E+01 0.40530163E+01
+ 0.40430609E+01 0.40331347E+01 0.40232374E+01 0.40133690E+01 0.40035293E+01
+ 0.39937182E+01 0.39839355E+01 0.39741811E+01 0.39644550E+01 0.39547568E+01
+ 0.39450866E+01 0.39354442E+01 0.39258295E+01 0.39162423E+01 0.39066826E+01
+ 0.38971501E+01 0.38876447E+01 0.38781665E+01 0.38687151E+01 0.38592905E+01
+ 0.38498926E+01 0.38405213E+01 0.38311764E+01 0.38218578E+01 0.38125654E+01
+ 0.38032990E+01 0.37940587E+01 0.37848442E+01 0.37756554E+01 0.37664922E+01
+ 0.37573545E+01 0.37482423E+01 0.37391553E+01 0.37300934E+01 0.37210566E+01
+ 0.37120448E+01 0.37030578E+01 0.36940955E+01 0.36851578E+01 0.36762446E+01
+ 0.36673559E+01 0.36584914E+01 0.36496511E+01 0.36408349E+01 0.36320427E+01
+ 0.36232744E+01 0.36145298E+01 0.36058090E+01 0.35971117E+01 0.35884378E+01
+ 0.35797873E+01 0.35711601E+01 0.35625561E+01 0.35539751E+01 0.35454172E+01
+ 0.35368821E+01 0.35283697E+01 0.35198801E+01 0.35114130E+01 0.35029685E+01
+ 0.34945463E+01 0.34861465E+01 0.34777688E+01 0.34694133E+01 0.34610798E+01
+ 0.34527683E+01 0.34444786E+01 0.34362106E+01 0.34279644E+01 0.34197397E+01
+ 0.34115365E+01 0.34033546E+01 0.33951941E+01 0.33870549E+01 0.33789367E+01
+ 0.33708397E+01 0.33627636E+01 0.33547083E+01 0.33466739E+01 0.33386602E+01
+ 0.33306671E+01 0.33226946E+01 0.33147425E+01 0.33068108E+01 0.32988995E+01
+ 0.32910083E+01 0.32831373E+01 0.32752863E+01 0.32674554E+01 0.32596443E+01
+ 0.32518530E+01 0.32440815E+01 0.32363297E+01 0.32285975E+01 0.32208848E+01
+ 0.32131915E+01 0.32055176E+01 0.31978629E+01 0.31902275E+01 0.31826112E+01
+ 0.31750140E+01 0.31674358E+01 0.31598765E+01 0.31523360E+01 0.31448143E+01
+ 0.31373113E+01 0.31298270E+01 0.31223612E+01 0.31149138E+01 0.31074850E+01
+ 0.31000744E+01 0.30926821E+01 0.30853081E+01 0.30779521E+01 0.30706143E+01
+ 0.30632945E+01 0.30559925E+01 0.30487085E+01 0.30414423E+01 0.30341938E+01
+ 0.30269630E+01 0.30197497E+01 0.30125541E+01 0.30053759E+01 0.29982151E+01
+ 0.29910717E+01 0.29839455E+01 0.29768366E+01 0.29697448E+01 0.29626701E+01
+ 0.29556125E+01 0.29485718E+01 0.29415481E+01 0.29345411E+01 0.29275510E+01
+ 0.29205776E+01 0.29136209E+01 0.29066808E+01 0.28997572E+01 0.28928502E+01
+ 0.28859595E+01 0.28790852E+01 0.28722273E+01 0.28653856E+01 0.28585601E+01
+ 0.28517507E+01 0.28449575E+01 0.28381802E+01 0.28314190E+01 0.28246736E+01
+ 0.28179442E+01 0.28112305E+01 0.28045326E+01 0.27978503E+01 0.27911838E+01
+ 0.27845328E+01 0.27778973E+01 0.27712773E+01 0.27646728E+01 0.27580836E+01
+ 0.27515098E+01 0.27449512E+01 0.27384079E+01 0.27318797E+01 0.27253666E+01
+ 0.27188686E+01 0.27123857E+01 0.27059177E+01 0.26994646E+01 0.26930263E+01
+ 0.26866029E+01 0.26801943E+01 0.26738003E+01 0.26674211E+01 0.26610564E+01
+ 0.26547063E+01 0.26483708E+01 0.26420497E+01 0.26357431E+01 0.26294508E+01
+ 0.26231729E+01 0.26169092E+01 0.26106598E+01 0.26044246E+01 0.25982035E+01
+ 0.25919966E+01 0.25858037E+01 0.25796248E+01 0.25734599E+01 0.25673089E+01
+ 0.25611717E+01 0.25550485E+01 0.25489389E+01 0.25428432E+01 0.25367611E+01
+ 0.25306927E+01 0.25246380E+01 0.25185968E+01 0.25125691E+01 0.25065549E+01
+ 0.25005541E+01 0.24945668E+01 0.24885928E+01 0.24826321E+01 0.24766848E+01
+ 0.24707506E+01 0.24648297E+01 0.24589219E+01 0.24530272E+01 0.24471456E+01
+ 0.24412770E+01 0.24354215E+01 0.24295788E+01 0.24237491E+01 0.24179323E+01
+ 0.24121283E+01 0.24063372E+01 0.24005587E+01 0.23947930E+01 0.23890400E+01
+ 0.23832997E+01 0.23775719E+01 0.23718567E+01 0.23661540E+01 0.23604639E+01
+ 0.23547862E+01 0.23491209E+01 0.23434680E+01 0.23378275E+01 0.23321992E+01
+ 0.23265833E+01 0.23209796E+01 0.23153881E+01 0.23098087E+01 0.23042415E+01
+ 0.22986864E+01 0.22931434E+01 0.22876124E+01 0.22820934E+01 0.22765863E+01
+ 0.22710912E+01 0.22656080E+01 0.22601366E+01 0.22546771E+01 0.22492293E+01
+ 0.22437933E+01 0.22383691E+01 0.22329565E+01 0.22275556E+01 0.22221663E+01
+ 0.22167886E+01 0.22114224E+01 0.22060678E+01 0.22007247E+01 0.21953931E+01
+ 0.21900728E+01 0.21847640E+01 0.21794666E+01 0.21741805E+01 0.21689057E+01
+ 0.21636422E+01 0.21583899E+01 0.21531488E+01 0.21479190E+01 0.21427002E+01
+ 0.21374927E+01 0.21322962E+01 0.21271107E+01 0.21219363E+01 0.21167729E+01
+ 0.21116205E+01 0.21064790E+01 0.21013485E+01 0.20962288E+01 0.20911200E+01
+ 0.20860220E+01 0.20809348E+01 0.20758584E+01 0.20707928E+01 0.20657378E+01
+ 0.20606936E+01 0.20556600E+01 0.20506370E+01 0.20456247E+01 0.20406229E+01
+ 0.20356316E+01 0.20306509E+01 0.20256807E+01 0.20207210E+01 0.20157717E+01
+ 0.20108328E+01 0.20059043E+01 0.20009862E+01 0.19960784E+01 0.19911809E+01
+ 0.19862937E+01 0.19814168E+01 0.19765500E+01 0.19716935E+01 0.19668472E+01
+ 0.19620110E+01 0.19571850E+01 0.19523691E+01 0.19475632E+01 0.19427674E+01
+ 0.19379816E+01 0.19332058E+01 0.19284401E+01 0.19236842E+01 0.19189383E+01
+ 0.19142023E+01 0.19094762E+01 0.19047599E+01 0.19000535E+01 0.18953569E+01
+ 0.18906701E+01 0.18859930E+01 0.18813257E+01 0.18766681E+01 0.18720202E+01
+ 0.18673819E+01 0.18627533E+01 0.18581343E+01 0.18535250E+01 0.18489252E+01
+ 0.18443349E+01 0.18397542E+01 0.18351830E+01 0.18306213E+01 0.18260690E+01
+ 0.18215262E+01 0.18169928E+01 0.18124688E+01 0.18079542E+01 0.18034490E+01
+ 0.17989531E+01 0.17944665E+01 0.17899891E+01 0.17855211E+01 0.17810623E+01
+ 0.17766127E+01 0.17721723E+01 0.17677411E+01 0.17633191E+01 0.17589062E+01
+ 0.17545025E+01 0.17501078E+01 0.17457223E+01 0.17413457E+01 0.17369783E+01
+ 0.17326198E+01 0.17282703E+01 0.17239299E+01 0.17195984E+01 0.17152758E+01
+ 0.17109621E+01 0.17066574E+01 0.17023615E+01 0.16980745E+01 0.16937963E+01
+ 0.16895269E+01 0.16852664E+01 0.16810146E+01 0.16767716E+01 0.16725373E+01
+ 0.16683118E+01 0.16640950E+01 0.16598868E+01 0.16556873E+01 0.16514965E+01
+ 0.16473143E+01 0.16431407E+01 0.16389758E+01 0.16348194E+01 0.16306715E+01
+ 0.16265322E+01 0.16224014E+01 0.16182791E+01 0.16141653E+01 0.16100600E+01
+ 0.16059631E+01 0.16018747E+01 0.15977946E+01 0.15937230E+01 0.15896597E+01
+ 0.15856049E+01 0.15815583E+01 0.15775201E+01 0.15734902E+01 0.15694685E+01
+ 0.15654552E+01 0.15614501E+01 0.15574533E+01 0.15534646E+01 0.15494842E+01
+ 0.15455120E+01 0.15415480E+01 0.15375921E+01 0.15336443E+01 0.15297047E+01
+ 0.15257732E+01 0.15218497E+01 0.15179344E+01 0.15140271E+01 0.15101279E+01
+ 0.15062366E+01 0.15023534E+01 0.14984782E+01 0.14946110E+01 0.14907517E+01
+ 0.14869004E+01 0.14830570E+01 0.14792215E+01 0.14753939E+01 0.14715742E+01
+ 0.14677624E+01 0.14639584E+01 0.14601623E+01 0.14563740E+01 0.14525935E+01
+ 0.14488207E+01 0.14450558E+01 0.14412986E+01 0.14375492E+01 0.14338075E+01
+ 0.14300735E+01 0.14263473E+01 0.14226287E+01 0.14189178E+01 0.14152145E+01
+ 0.14115189E+01 0.14078309E+01 0.14041505E+01 0.14004777E+01 0.13968126E+01
+ 0.13931549E+01 0.13895049E+01 0.13858624E+01 0.13822274E+01 0.13785999E+01
+ 0.13749799E+01 0.13713674E+01 0.13677624E+01 0.13641648E+01 0.13605747E+01
+ 0.13569920E+01 0.13534168E+01 0.13498489E+01 0.13462884E+01 0.13427353E+01
+ 0.13391896E+01 0.13356512E+01 0.13321201E+01 0.13285964E+01 0.13250799E+01
+ 0.13215708E+01 0.13180689E+01 0.13145743E+01 0.13110870E+01 0.13076069E+01
+ 0.13041340E+01 0.13006684E+01 0.12972099E+01 0.12937586E+01 0.12903145E+01
+ 0.12868776E+01 0.12834478E+01 0.12800252E+01 0.12766097E+01 0.12732012E+01
+ 0.12697999E+01 0.12664057E+01 0.12630186E+01 0.12596385E+01 0.12562654E+01
+ 0.12528994E+01 0.12495404E+01 0.12461884E+01 0.12428435E+01 0.12395055E+01
+ 0.12361745E+01 0.12328504E+01 0.12295333E+01 0.12262231E+01 0.12229199E+01
+ 0.12196235E+01 0.12163341E+01 0.12130516E+01 0.12097759E+01 0.12065071E+01
+ 0.12032451E+01 0.11999900E+01 0.11967417E+01 0.11935003E+01 0.11902656E+01
+ 0.11870377E+01 0.11838167E+01 0.11806023E+01 0.11773948E+01 0.11741940E+01
+ 0.11709999E+01 0.11678125E+01 0.11646319E+01 0.11614580E+01 0.11582907E+01
+ 0.11551301E+01 0.11519762E+01 0.11488290E+01 0.11456884E+01 0.11425544E+01
+ 0.11394271E+01 0.11363063E+01 0.11331922E+01 0.11300846E+01 0.11269836E+01
+ 0.11238892E+01 0.11208014E+01 0.11177201E+01 0.11146453E+01 0.11115770E+01
+ 0.11085153E+01 0.11054600E+01 0.11024113E+01 0.10993690E+01 0.10963332E+01
+ 0.10933038E+01 0.10902809E+01 0.10872644E+01 0.10842544E+01 0.10812507E+01
+ 0.10782535E+01 0.10752627E+01 0.10722782E+01 0.10693001E+01 0.10663284E+01
+ 0.10633630E+01 0.10604040E+01 0.10574513E+01 0.10545049E+01 0.10515649E+01
+ 0.10486311E+01 0.10457036E+01 0.10427824E+01 0.10398675E+01 0.10369588E+01
+ 0.10340563E+01 0.10311601E+01 0.10282702E+01 0.10253864E+01 0.10225089E+01
+ 0.10196375E+01 0.10167724E+01 0.10139134E+01 0.10110606E+01 0.10082139E+01
+ 0.10053734E+01 0.10025390E+01 0.99971078E+00 0.99688865E+00 0.99407263E+00
+ 0.99126271E+00 0.98845887E+00 0.98566111E+00 0.98286942E+00 0.98008379E+00
+ 0.97730421E+00 0.97453067E+00 0.97176315E+00 0.96900166E+00 0.96624617E+00
+ 0.96349669E+00 0.96075320E+00 0.95801569E+00 0.95528415E+00 0.95255858E+00
+ 0.94983895E+00 0.94712527E+00 0.94441753E+00 0.94171571E+00 0.93901980E+00
+ 0.93632980E+00 0.93364570E+00 0.93096748E+00 0.92829515E+00 0.92562868E+00
+ 0.92296807E+00 0.92031330E+00 0.91766438E+00 0.91502130E+00 0.91238403E+00
+ 0.90975258E+00 0.90712693E+00 0.90450707E+00 0.90189300E+00 0.89928471E+00
+ 0.89668219E+00 0.89408542E+00 0.89149440E+00 0.88890912E+00 0.88632958E+00
+ 0.88375575E+00 0.88118764E+00 0.87862523E+00 0.87606852E+00 0.87351750E+00
+ 0.87097215E+00 0.86843247E+00 0.86589845E+00 0.86337008E+00 0.86084735E+00
+ 0.85833026E+00 0.85581879E+00 0.85331293E+00 0.85081268E+00 0.84831803E+00
+ 0.84582897E+00 0.84334549E+00 0.84086758E+00 0.83839523E+00 0.83592844E+00
+ 0.83346719E+00 0.83101148E+00 0.82856130E+00 0.82611664E+00 0.82367749E+00
+ 0.82124384E+00 0.81881569E+00 0.81639302E+00 0.81397583E+00 0.81156410E+00
+ 0.80915784E+00 0.80675702E+00 0.80436165E+00 0.80197172E+00 0.79958720E+00
+ 0.79720811E+00 0.79483443E+00 0.79246614E+00 0.79010325E+00 0.78774574E+00
+ 0.78539360E+00 0.78304684E+00 0.78070543E+00 0.77836937E+00 0.77603865E+00
+ 0.77371327E+00 0.77139321E+00 0.76907847E+00 0.76676904E+00 0.76446490E+00
+ 0.76216606E+00 0.75987251E+00 0.75758423E+00 0.75530121E+00 0.75302346E+00
+ 0.75075095E+00 0.74848369E+00 0.74622167E+00 0.74396487E+00 0.74171329E+00
+ 0.73946691E+00 0.73722575E+00 0.73498977E+00 0.73275898E+00 0.73053337E+00
+ 0.72831293E+00 0.72609765E+00 0.72388752E+00 0.72168254E+00 0.71948269E+00
+ 0.71728798E+00 0.71509838E+00 0.71291390E+00 0.71073453E+00 0.70856025E+00
+ 0.70639106E+00 0.70422696E+00 0.70206793E+00 0.69991396E+00 0.69776505E+00
+ 0.69562119E+00 0.69348237E+00 0.69134859E+00 0.68921983E+00 0.68709609E+00
+ 0.68497736E+00 0.68286364E+00 0.68075490E+00 0.67865116E+00 0.67655239E+00
+ 0.67445860E+00 0.67236976E+00 0.67028589E+00 0.66820696E+00 0.66613297E+00
+ 0.66406391E+00 0.66199978E+00 0.65994056E+00 0.65788626E+00 0.65583685E+00
+ 0.65379234E+00 0.65175271E+00 0.64971796E+00 0.64768808E+00 0.64566306E+00
+ 0.64364290E+00 0.64162759E+00 0.63961711E+00 0.63761147E+00 0.63561065E+00
+ 0.63361465E+00 0.63162345E+00 0.62963706E+00 0.62765546E+00 0.62567865E+00
+ 0.62370661E+00 0.62173935E+00 0.61977685E+00 0.61781910E+00 0.61586610E+00
+ 0.61391785E+00 0.61197432E+00 0.61003552E+00 0.60810144E+00 0.60617207E+00
+ 0.60424740E+00 0.60232743E+00 0.60041214E+00 0.59850154E+00 0.59659560E+00
+ 0.59469433E+00 0.59279772E+00 0.59090576E+00 0.58901844E+00 0.58713576E+00
+ 0.58525770E+00 0.58338427E+00 0.58151544E+00 0.57965123E+00 0.57779161E+00
+ 0.57593658E+00 0.57408613E+00 0.57224026E+00 0.57039895E+00 0.56856221E+00
+ 0.56673002E+00 0.56490238E+00 0.56307927E+00 0.56126069E+00 0.55944664E+00
+ 0.55763711E+00 0.55583208E+00 0.55403156E+00 0.55223553E+00 0.55044398E+00
+ 0.54865692E+00 0.54687433E+00 0.54509620E+00 0.54332253E+00 0.54155331E+00
+ 0.53978853E+00 0.53802819E+00 0.53627227E+00 0.53452078E+00 0.53277370E+00
+ 0.53103103E+00 0.52929275E+00 0.52755887E+00 0.52582937E+00 0.52410424E+00
+ 0.52238349E+00 0.52066710E+00 0.51895506E+00 0.51724738E+00 0.51554403E+00
+ 0.51384502E+00 0.51215033E+00 0.51045996E+00 0.50877390E+00 0.50709215E+00
+ 0.50541469E+00 0.50374153E+00 0.50207264E+00 0.50040803E+00 0.49874769E+00
+ 0.49709161E+00 0.49543979E+00 0.49379221E+00 0.49214887E+00 0.49050976E+00
+ 0.48887488E+00 0.48724421E+00 0.48561776E+00 0.48399551E+00 0.48237745E+00
+ 0.48076358E+00 0.47915390E+00 0.47754839E+00 0.47594705E+00 0.47434986E+00
+ 0.47275683E+00 0.47116795E+00 0.46958320E+00 0.46800259E+00 0.46642610E+00
+ 0.46485373E+00 0.46328546E+00 0.46172130E+00 0.46016124E+00 0.45860526E+00
+ 0.45705337E+00 0.45550555E+00 0.45396180E+00 0.45242210E+00 0.45088646E+00
+ 0.44935487E+00 0.44782731E+00 0.44630379E+00 0.44478429E+00 0.44326880E+00
+ 0.44175733E+00 0.44024986E+00 0.43874638E+00 0.43724690E+00 0.43575139E+00
+ 0.43425986E+00 0.43277230E+00 0.43128870E+00 0.42980904E+00 0.42833334E+00
+ 0.42686157E+00 0.42539374E+00 0.42392983E+00 0.42246984E+00 0.42101375E+00
+ 0.41956157E+00 0.41811329E+00 0.41666889E+00 0.41522838E+00 0.41379174E+00
+ 0.41235897E+00 0.41093006E+00 0.40950500E+00 0.40808379E+00 0.40666641E+00
+ 0.40525287E+00 0.40384316E+00 0.40243726E+00 0.40103517E+00 0.39963688E+00
+ 0.39824239E+00 0.39685169E+00 0.39546477E+00 0.39408163E+00 0.39270225E+00
+ 0.39132663E+00 0.38995477E+00 0.38858665E+00 0.38722227E+00 0.38586163E+00
+ 0.38450470E+00 0.38315150E+00 0.38180201E+00 0.38045621E+00 0.37911412E+00
+ 0.37777571E+00 0.37644099E+00 0.37510993E+00 0.37378255E+00 0.37245883E+00
+ 0.37113876E+00 0.36982233E+00 0.36850954E+00 0.36720039E+00 0.36589486E+00
+ 0.36459294E+00 0.36329463E+00 0.36199993E+00 0.36070882E+00 0.35942130E+00
+ 0.35813736E+00 0.35685699E+00 0.35558019E+00 0.35430695E+00 0.35303726E+00
+ 0.35177111E+00 0.35050850E+00 0.34924942E+00 0.34799386E+00 0.34674182E+00
+ 0.34549329E+00 0.34424825E+00 0.34300671E+00 0.34176865E+00 0.34053407E+00
+ 0.33930297E+00 0.33807532E+00 0.33685114E+00 0.33563040E+00 0.33441310E+00
+ 0.33319924E+00 0.33198880E+00 0.33078178E+00 0.32957818E+00 0.32837797E+00
+ 0.32718117E+00 0.32598775E+00 0.32479772E+00 0.32361106E+00 0.32242776E+00
+ 0.32124783E+00 0.32007125E+00 0.31889801E+00 0.31772811E+00 0.31656153E+00
+ 0.31539828E+00 0.31423834E+00 0.31308171E+00 0.31192837E+00 0.31077833E+00
+ 0.30963157E+00 0.30848809E+00 0.30734787E+00 0.30621091E+00 0.30507721E+00
+ 0.30394674E+00 0.30281952E+00 0.30169552E+00 0.30057475E+00 0.29945719E+00
+ 0.29834283E+00 0.29723167E+00 0.29612370E+00 0.29501891E+00 0.29391730E+00
+ 0.29281885E+00 0.29172356E+00 0.29063142E+00 0.28954242E+00 0.28845655E+00
+ 0.28737381E+00 0.28629418E+00 0.28521767E+00 0.28414425E+00 0.28307393E+00
+ 0.28200669E+00 0.28094253E+00 0.27988144E+00 0.27882340E+00 0.27776842E+00
+ 0.27671648E+00 0.27566758E+00 0.27462170E+00 0.27357884E+00 0.27253898E+00
+ 0.27150213E+00 0.27046827E+00 0.26943740E+00 0.26840950E+00 0.26738456E+00
+ 0.26636258E+00 0.26534355E+00 0.26432746E+00 0.26331431E+00 0.26230407E+00
+ 0.26129675E+00 0.26029233E+00 0.25929081E+00 0.25829217E+00 0.25729641E+00
+ 0.25630352E+00 0.25531349E+00 0.25432631E+00 0.25334197E+00 0.25236046E+00
+ 0.25138177E+00 0.25040590E+00 0.24943283E+00 0.24846255E+00 0.24749506E+00
+ 0.24653034E+00 0.24556839E+00 0.24460919E+00 0.24365274E+00 0.24269903E+00
+ 0.24174804E+00 0.24079977E+00 0.23985420E+00 0.23891133E+00 0.23797114E+00
+ 0.23703364E+00 0.23609879E+00 0.23516661E+00 0.23423707E+00 0.23331016E+00
+ 0.23238588E+00 0.23146421E+00 0.23054515E+00 0.22962867E+00 0.22871478E+00
+ 0.22780347E+00 0.22689471E+00 0.22598850E+00 0.22508483E+00 0.22418369E+00
+ 0.22328506E+00 0.22238894E+00 0.22149531E+00 0.22060416E+00 0.21971549E+00
+ 0.21882927E+00 0.21794550E+00 0.21706417E+00 0.21618526E+00 0.21530877E+00
+ 0.21443467E+00 0.21356296E+00 0.21269363E+00 0.21182666E+00 0.21096204E+00
+ 0.21009976E+00 0.20923981E+00 0.20838217E+00 0.20752683E+00 0.20667378E+00
+ 0.20582300E+00 0.20497449E+00 0.20412823E+00 0.20328420E+00 0.20244239E+00
+ 0.20160279E+00 0.20076538E+00 0.19993016E+00 0.19909710E+00 0.19826620E+00
+ 0.19743744E+00 0.19661080E+00 0.19578627E+00 0.19496384E+00 0.19414349E+00
+ 0.19332521E+00 0.19250898E+00 0.19169479E+00 0.19088262E+00 0.19007246E+00
+ 0.18926429E+00 0.18845809E+00 0.18765386E+00 0.18685157E+00 0.18605121E+00
+ 0.18525276E+00 0.18445621E+00 0.18366154E+00 0.18286873E+00 0.18207777E+00
+ 0.18128864E+00 0.18050133E+00 0.17971581E+00 0.17893207E+00 0.17815010E+00
+ 0.17736986E+00 0.17659136E+00 0.17581456E+00 0.17503945E+00 0.17426602E+00
+ 0.17349424E+00 0.17272409E+00 0.17195556E+00 0.17118863E+00 0.17042328E+00
+ 0.16965949E+00 0.16889724E+00 0.16813651E+00 0.16737728E+00 0.16661953E+00
+ 0.16586324E+00 0.16510839E+00 0.16435497E+00 0.16360294E+00 0.16285229E+00
+ 0.16210299E+00 0.16135503E+00 0.16060839E+00 0.15986304E+00 0.15911896E+00
+ 0.15837613E+00 0.15763453E+00 0.15689413E+00 0.15615491E+00 0.15541685E+00
+ 0.15467993E+00 0.15394412E+00 0.15320940E+00 0.15247575E+00 0.15174313E+00
+ 0.15101154E+00 0.15028094E+00 0.14955130E+00 0.14882262E+00 0.14809485E+00
+ 0.14736798E+00 0.14664197E+00 0.14591681E+00 0.14519247E+00 0.14446893E+00
+ 0.14374615E+00 0.14302411E+00 0.14230278E+00 0.14158215E+00 0.14086217E+00
+ 0.14014283E+00 0.13942409E+00 0.13870594E+00 0.13798833E+00 0.13727126E+00
+ 0.13655467E+00 0.13583856E+00 0.13512289E+00 0.13440763E+00 0.13369275E+00
+ 0.13297823E+00 0.13226404E+00 0.13155014E+00 0.13083652E+00 0.13012313E+00
+ 0.12940995E+00 0.12869695E+00 0.12798410E+00 0.12727138E+00 0.12655874E+00
+ 0.12584617E+00 0.12513363E+00 0.12442109E+00 0.12370852E+00 0.12299589E+00
+ 0.12228317E+00 0.12157034E+00 0.12085735E+00 0.12014419E+00 0.11943081E+00
+ 0.11871719E+00 0.11800331E+00 0.11728912E+00 0.11657460E+00 0.11585971E+00
+ 0.11514444E+00 0.11442874E+00 0.11371259E+00 0.11299596E+00 0.11227882E+00
+ 0.11156114E+00 0.11084289E+00 0.11012403E+00 0.10940455E+00 0.10868441E+00
+ 0.10796359E+00 0.10724205E+00 0.10651977E+00 0.10579672E+00 0.10507287E+00
+ 0.10434819E+00 0.10362267E+00 0.10289627E+00 0.10216897E+00 0.10144074E+00
+ 0.10071156E+00 0.99981400E-01 0.99250242E-01 0.98518061E-01 0.97784834E-01
+ 0.97050540E-01 0.96315159E-01 0.95578669E-01 0.94841051E-01 0.94102286E-01
+ 0.93362357E-01 0.92621247E-01 0.91878939E-01 0.91135419E-01 0.90390673E-01
+ 0.89644687E-01 0.88897450E-01 0.88148950E-01 0.87399179E-01 0.86648128E-01
+ 0.85895790E-01 0.85142159E-01 0.84387231E-01 0.83631004E-01 0.82873475E-01
+ 0.82114645E-01 0.81354515E-01 0.80593090E-01 0.79830374E-01 0.79066374E-01
+ 0.78301099E-01 0.77534559E-01 0.76766767E-01 0.75997737E-01 0.75227487E-01
+ 0.74456034E-01 0.73683399E-01 0.72909606E-01 0.72134680E-01 0.71358648E-01
+ 0.70581541E-01 0.69803392E-01 0.69024235E-01 0.68244108E-01 0.67463051E-01
+ 0.66681108E-01 0.65898325E-01 0.65114750E-01 0.64330435E-01 0.63545434E-01
+ 0.62759804E-01 0.61973608E-01 0.61186907E-01 0.60399769E-01 0.59612264E-01
+ 0.58824466E-01 0.58036450E-01 0.57248297E-01 0.56460091E-01 0.55671917E-01
+ 0.54883866E-01 0.54096032E-01 0.53308512E-01 0.52521406E-01 0.51734820E-01
+ 0.50948860E-01 0.50163638E-01 0.49379270E-01 0.48595873E-01 0.47813571E-01
+ 0.47032489E-01 0.46252756E-01 0.45474505E-01 0.44697873E-01 0.43923000E-01
+ 0.43150029E-01 0.42379107E-01 0.41610385E-01 0.40844015E-01 0.40080155E-01
+ 0.39318965E-01 0.38560607E-01 0.37805247E-01 0.37053055E-01 0.36304203E-01
+ 0.35558863E-01 0.34817213E-01 0.34079433E-01 0.33345704E-01 0.32616209E-01
+ 0.31891134E-01 0.31170665E-01 0.30454993E-01 0.29744306E-01 0.29038796E-01
+ 0.28338656E-01 0.27644077E-01 0.26955254E-01 0.26272380E-01 0.25595649E-01
+ 0.24925254E-01 0.24261387E-01 0.23604240E-01 0.22954004E-01 0.22310869E-01
+ 0.21675022E-01 0.21046647E-01 0.20425929E-01 0.19813048E-01 0.19208180E-01
+ 0.18611501E-01 0.18023179E-01 0.17443381E-01 0.16872269E-01 0.16310000E-01
+ 0.15756726E-01 0.15212593E-01 0.14677742E-01 0.14152307E-01 0.13636416E-01
+ 0.13130191E-01 0.12633746E-01 0.12147187E-01 0.11670614E-01 0.11204117E-01
+ 0.10747778E-01 0.10301672E-01 0.98658640E-02 0.94404095E-02 0.90253551E-02
+ 0.86207381E-02 0.82265856E-02 0.78429150E-02 0.74697338E-02 0.71070390E-02
+ 0.67548175E-02 0.64130458E-02 0.60816902E-02 0.57607062E-02 0.54500393E-02
+ 0.51496245E-02 0.48593862E-02 0.45792391E-02 0.43090875E-02 0.40488258E-02
+ 0.37983389E-02 0.35575019E-02 0.33261809E-02 0.31042329E-02 0.28915063E-02
+ 0.26878409E-02 0.24930690E-02 0.23070150E-02 0.21294962E-02 0.19603233E-02
+ 0.17993005E-02 0.16462265E-02 0.15008946E-02 0.13630932E-02 0.12326069E-02
+ 0.11092162E-02 0.99269863E-03 0.88282921E-03 0.77938090E-03 0.68212524E-03
+ 0.59083293E-03 0.50527436E-03 0.42522016E-03 0.35044181E-03 0.28071209E-03
+ 0.21580569E-03 0.15549966E-03 0.99573903E-04 0.47811675E-04 0.00000000E+00
+ 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01
+ 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01
+ 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01
+ 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01
+ 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01
+ 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01
+ 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01
+ 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01 0.97771570E+01
+ 0.97771570E+01 0.97145336E+01 0.94177130E+01 0.91366271E+01 0.88701043E+01
+ 0.86170840E+01 0.83766043E+01 0.81477908E+01 0.79298467E+01 0.77220450E+01
+ 0.75237208E+01 0.73342648E+01 0.71531180E+01 0.69797664E+01 0.68137366E+01
+ 0.66545921E+01 0.65019299E+01 0.63553768E+01 0.62145876E+01 0.60792419E+01
+ 0.59490420E+01 0.58237113E+01 0.57029923E+01 0.55866448E+01 0.54744447E+01
+ 0.53661828E+01 0.52616633E+01 0.51607029E+01 0.50631300E+01 0.49687835E+01
+ 0.48775121E+01 0.47891738E+01 0.47036349E+01 0.46207695E+01 0.45404591E+01
+ 0.44625920E+01 0.43870626E+01 0.43137713E+01 0.42426239E+01 0.41735314E+01
+ 0.41064094E+01 0.40411782E+01 0.39777620E+01 0.39160891E+01 0.38560914E+01
+ 0.37977041E+01 0.37408659E+01 0.36855181E+01 0.36316054E+01 0.35790747E+01
+ 0.35278756E+01 0.34779601E+01 0.34292823E+01 0.33817987E+01 0.33354674E+01
+ 0.32902487E+01 0.32461045E+01 0.32029985E+01 0.31608958E+01 0.31197632E+01
+ 0.30795688E+01 0.30402821E+01 0.30018740E+01 0.29643164E+01 0.29275824E+01
+ 0.28916463E+01 0.28564833E+01 0.28220698E+01 0.27883830E+01 0.27554009E+01
+ 0.27231025E+01 0.26914676E+01 0.26604768E+01 0.26301113E+01 0.26003530E+01
+ 0.25711848E+01 0.25425898E+01 0.25145519E+01 0.24870557E+01 0.24600862E+01
+ 0.24336289E+01 0.24076701E+01 0.23821962E+01 0.23571943E+01 0.23326519E+01
+ 0.23085569E+01 0.22848977E+01 0.22616630E+01 0.22388419E+01 0.22164238E+01
+ 0.21943987E+01 0.21727565E+01 0.21514878E+01 0.21305834E+01 0.21100343E+01
+ 0.20898319E+01 0.20699679E+01 0.20504340E+01 0.20312224E+01 0.20123255E+01
+ 0.19937360E+01 0.19754467E+01 0.19574505E+01 0.19397409E+01 0.19223111E+01
+ 0.19051550E+01 0.18882663E+01 0.18716391E+01 0.18552675E+01 0.18391460E+01
+ 0.18232690E+01 0.18076312E+01 0.17922274E+01 0.17770527E+01 0.17621021E+01
+ 0.17473709E+01 0.17328544E+01 0.17185481E+01 0.17044478E+01 0.16905491E+01
+ 0.16768479E+01 0.16633401E+01 0.16500218E+01 0.16368893E+01 0.16239387E+01
+ 0.16111665E+01 0.15985692E+01 0.15861432E+01 0.15738852E+01 0.15617920E+01
+ 0.15498604E+01 0.15380872E+01 0.15264695E+01 0.15150042E+01 0.15036886E+01
+ 0.14925197E+01 0.14814949E+01 0.14706115E+01 0.14598668E+01 0.14492584E+01
+ 0.14387837E+01 0.14284402E+01 0.14182257E+01 0.14081378E+01 0.13981743E+01
+ 0.13883328E+01 0.13786114E+01 0.13690078E+01 0.13595200E+01 0.13501460E+01
+ 0.13408838E+01 0.13317315E+01 0.13226872E+01 0.13137491E+01 0.13049154E+01
+ 0.12961842E+01 0.12875540E+01 0.12790229E+01 0.12705894E+01 0.12622518E+01
+ 0.12540086E+01 0.12458582E+01 0.12377991E+01 0.12298299E+01 0.12219490E+01
+ 0.12141551E+01 0.12064467E+01 0.11988226E+01 0.11912813E+01 0.11838216E+01
+ 0.11764423E+01 0.11691419E+01 0.11619194E+01 0.11547734E+01 0.11477030E+01
+ 0.11407068E+01 0.11337837E+01 0.11269327E+01 0.11201526E+01 0.11134425E+01
+ 0.11068011E+01 0.11002276E+01 0.10937209E+01 0.10872800E+01 0.10809040E+01
+ 0.10745919E+01 0.10683427E+01 0.10621556E+01 0.10560297E+01 0.10499641E+01
+ 0.10439579E+01 0.10380103E+01 0.10321205E+01 0.10262875E+01 0.10205107E+01
+ 0.10147893E+01 0.10091224E+01 0.10035093E+01 0.99794933E+00 0.99244167E+00
+ 0.98698564E+00 0.98158052E+00 0.97622563E+00 0.97092027E+00 0.96566379E+00
+ 0.96045553E+00 0.95529485E+00 0.95018110E+00 0.94511366E+00 0.94009193E+00
+ 0.93511529E+00 0.93018317E+00 0.92529497E+00 0.92045012E+00 0.91564807E+00
+ 0.91088826E+00 0.90617015E+00 0.90149319E+00 0.89685688E+00 0.89226068E+00
+ 0.88770410E+00 0.88318662E+00 0.87870777E+00 0.87426706E+00 0.86986400E+00
+ 0.86549814E+00 0.86116900E+00 0.85687615E+00 0.85261913E+00 0.84839750E+00
+ 0.84421084E+00 0.84005871E+00 0.83594070E+00 0.83185640E+00 0.82780540E+00
+ 0.82378730E+00 0.81980171E+00 0.81584824E+00 0.81192652E+00 0.80803616E+00
+ 0.80417680E+00 0.80034808E+00 0.79654963E+00 0.79278111E+00 0.78904216E+00
+ 0.78533245E+00 0.78165164E+00 0.77799939E+00 0.77437538E+00 0.77077929E+00
+ 0.76721080E+00 0.76366960E+00 0.76015538E+00 0.75666783E+00 0.75320667E+00
+ 0.74977158E+00 0.74636228E+00 0.74297849E+00 0.73961993E+00 0.73628631E+00
+ 0.73297736E+00 0.72969281E+00 0.72643240E+00 0.72319586E+00 0.71998293E+00
+ 0.71679337E+00 0.71362691E+00 0.71048330E+00 0.70736231E+00 0.70426370E+00
+ 0.70118722E+00 0.69813264E+00 0.69509972E+00 0.69208825E+00 0.68909800E+00
+ 0.68612873E+00 0.68318024E+00 0.68025231E+00 0.67734473E+00 0.67445728E+00
+ 0.67158976E+00 0.66874196E+00 0.66591368E+00 0.66310472E+00 0.66031489E+00
+ 0.65754399E+00 0.65479183E+00 0.65205821E+00 0.64934297E+00 0.64664590E+00
+ 0.64396683E+00 0.64130558E+00 0.63866198E+00 0.63603584E+00 0.63342699E+00
+ 0.63083527E+00 0.62826051E+00 0.62570254E+00 0.62316120E+00 0.62063632E+00
+ 0.61812774E+00 0.61563532E+00 0.61315889E+00 0.61069829E+00 0.60825339E+00
+ 0.60582402E+00 0.60341004E+00 0.60101130E+00 0.59862766E+00 0.59625898E+00
+ 0.59390511E+00 0.59156591E+00 0.58924126E+00 0.58693101E+00 0.58463502E+00
+ 0.58235317E+00 0.58008533E+00 0.57783136E+00 0.57559114E+00 0.57336454E+00
+ 0.57115144E+00 0.56895171E+00 0.56676524E+00 0.56459189E+00 0.56243156E+00
+ 0.56028412E+00 0.55814946E+00 0.55602747E+00 0.55391802E+00 0.55182102E+00
+ 0.54973634E+00 0.54766388E+00 0.54560353E+00 0.54355518E+00 0.54151873E+00
+ 0.53949408E+00 0.53748111E+00 0.53547973E+00 0.53348983E+00 0.53151132E+00
+ 0.52954410E+00 0.52758807E+00 0.52564313E+00 0.52370919E+00 0.52178616E+00
+ 0.51987393E+00 0.51797242E+00 0.51608154E+00 0.51420119E+00 0.51233130E+00
+ 0.51047176E+00 0.50862249E+00 0.50678341E+00 0.50495442E+00 0.50313546E+00
+ 0.50132642E+00 0.49952724E+00 0.49773782E+00 0.49595809E+00 0.49418796E+00
+ 0.49242737E+00 0.49067622E+00 0.48893445E+00 0.48720197E+00 0.48547871E+00
+ 0.48376459E+00 0.48205955E+00 0.48036351E+00 0.47867639E+00 0.47699812E+00
+ 0.47532863E+00 0.47366786E+00 0.47201573E+00 0.47037217E+00 0.46873711E+00
+ 0.46711050E+00 0.46549225E+00 0.46388231E+00 0.46228061E+00 0.46068708E+00
+ 0.45910167E+00 0.45752430E+00 0.45595492E+00 0.45439346E+00 0.45283986E+00
+ 0.45129406E+00 0.44975600E+00 0.44822562E+00 0.44670286E+00 0.44518767E+00
+ 0.44367998E+00 0.44217974E+00 0.44068689E+00 0.43920138E+00 0.43772314E+00
+ 0.43625213E+00 0.43478830E+00 0.43333157E+00 0.43188191E+00 0.43043927E+00
+ 0.42900358E+00 0.42757479E+00 0.42615286E+00 0.42473774E+00 0.42332937E+00
+ 0.42192770E+00 0.42053268E+00 0.41914428E+00 0.41776243E+00 0.41638709E+00
+ 0.41501821E+00 0.41365575E+00 0.41229965E+00 0.41094988E+00 0.40960638E+00
+ 0.40826912E+00 0.40693804E+00 0.40561311E+00 0.40429427E+00 0.40298149E+00
+ 0.40167472E+00 0.40037391E+00 0.39907904E+00 0.39779005E+00 0.39650690E+00
+ 0.39522956E+00 0.39395797E+00 0.39269211E+00 0.39143193E+00 0.39017739E+00
+ 0.38892845E+00 0.38768507E+00 0.38644722E+00 0.38521485E+00 0.38398794E+00
+ 0.38276643E+00 0.38155030E+00 0.38033950E+00 0.37913401E+00 0.37793378E+00
+ 0.37673877E+00 0.37554896E+00 0.37436431E+00 0.37318478E+00 0.37201034E+00
+ 0.37084095E+00 0.36967659E+00 0.36851721E+00 0.36736278E+00 0.36621327E+00
+ 0.36506865E+00 0.36392889E+00 0.36279395E+00 0.36166379E+00 0.36053840E+00
+ 0.35941774E+00 0.35830177E+00 0.35719047E+00 0.35608380E+00 0.35498174E+00
+ 0.35388426E+00 0.35279132E+00 0.35170289E+00 0.35061895E+00 0.34953947E+00
+ 0.34846442E+00 0.34739377E+00 0.34632750E+00 0.34526557E+00 0.34420795E+00
+ 0.34315462E+00 0.34210556E+00 0.34106073E+00 0.34002011E+00 0.33898367E+00
+ 0.33795139E+00 0.33692323E+00 0.33589918E+00 0.33487920E+00 0.33386328E+00
+ 0.33285139E+00 0.33184349E+00 0.33083958E+00 0.32983961E+00 0.32884358E+00
+ 0.32785145E+00 0.32686319E+00 0.32587880E+00 0.32489823E+00 0.32392148E+00
+ 0.32294851E+00 0.32197930E+00 0.32101383E+00 0.32005208E+00 0.31909402E+00
+ 0.31813964E+00 0.31718891E+00 0.31624180E+00 0.31529830E+00 0.31435839E+00
+ 0.31342204E+00 0.31248923E+00 0.31155995E+00 0.31063416E+00 0.30971185E+00
+ 0.30879301E+00 0.30787760E+00 0.30696561E+00 0.30605702E+00 0.30515180E+00
+ 0.30424995E+00 0.30335144E+00 0.30245624E+00 0.30156435E+00 0.30067573E+00
+ 0.29979038E+00 0.29890828E+00 0.29802939E+00 0.29715372E+00 0.29628123E+00
+ 0.29541191E+00 0.29454575E+00 0.29368272E+00 0.29282280E+00 0.29196599E+00
+ 0.29111225E+00 0.29026158E+00 0.28941395E+00 0.28856935E+00 0.28772777E+00
+ 0.28688918E+00 0.28605357E+00 0.28522092E+00 0.28439121E+00 0.28356444E+00
+ 0.28274057E+00 0.28191961E+00 0.28110152E+00 0.28028631E+00 0.27947393E+00
+ 0.27866440E+00 0.27785768E+00 0.27705376E+00 0.27625264E+00 0.27545428E+00
+ 0.27465868E+00 0.27386583E+00 0.27307570E+00 0.27228828E+00 0.27150356E+00
+ 0.27072153E+00 0.26994217E+00 0.26916546E+00 0.26839139E+00 0.26761995E+00
+ 0.26685112E+00 0.26608490E+00 0.26532126E+00 0.26456019E+00 0.26380167E+00
+ 0.26304571E+00 0.26229227E+00 0.26154136E+00 0.26079294E+00 0.26004703E+00
+ 0.25930359E+00 0.25856261E+00 0.25782409E+00 0.25708802E+00 0.25635437E+00
+ 0.25562313E+00 0.25489430E+00 0.25416787E+00 0.25344381E+00 0.25272212E+00
+ 0.25200278E+00 0.25128578E+00 0.25057112E+00 0.24985878E+00 0.24914874E+00
+ 0.24844100E+00 0.24773555E+00 0.24703237E+00 0.24633145E+00 0.24563278E+00
+ 0.24493635E+00 0.24424215E+00 0.24355017E+00 0.24286039E+00 0.24217281E+00
+ 0.24148741E+00 0.24080419E+00 0.24012313E+00 0.23944422E+00 0.23876745E+00
+ 0.23809282E+00 0.23742031E+00 0.23674991E+00 0.23608161E+00 0.23541540E+00
+ 0.23475127E+00 0.23408922E+00 0.23342922E+00 0.23277127E+00 0.23211537E+00
+ 0.23146150E+00 0.23080965E+00 0.23015981E+00 0.22951197E+00 0.22886613E+00
+ 0.22822227E+00 0.22758039E+00 0.22694047E+00 0.22630251E+00 0.22566649E+00
+ 0.22503241E+00 0.22440027E+00 0.22377004E+00 0.22314172E+00 0.22251531E+00
+ 0.22189078E+00 0.22126815E+00 0.22064739E+00 0.22002849E+00 0.21941146E+00
+ 0.21879628E+00 0.21818294E+00 0.21757143E+00 0.21696175E+00 0.21635388E+00
+ 0.21574783E+00 0.21514358E+00 0.21454111E+00 0.21394044E+00 0.21334154E+00
+ 0.21274441E+00 0.21214904E+00 0.21155542E+00 0.21096355E+00 0.21037342E+00
+ 0.20978502E+00 0.20919834E+00 0.20861338E+00 0.20803012E+00 0.20744856E+00
+ 0.20686870E+00 0.20629052E+00 0.20571402E+00 0.20513919E+00 0.20456602E+00
+ 0.20399451E+00 0.20342465E+00 0.20285644E+00 0.20228985E+00 0.20172490E+00
+ 0.20116156E+00 0.20059985E+00 0.20003973E+00 0.19948122E+00 0.19892431E+00
+ 0.19836898E+00 0.19781523E+00 0.19726305E+00 0.19671244E+00 0.19616340E+00
+ 0.19561591E+00 0.19506996E+00 0.19452556E+00 0.19398269E+00 0.19344135E+00
+ 0.19290153E+00 0.19236323E+00 0.19182644E+00 0.19129116E+00 0.19075737E+00
+ 0.19022507E+00 0.18969426E+00 0.18916493E+00 0.18863707E+00 0.18811068E+00
+ 0.18758575E+00 0.18706228E+00 0.18654025E+00 0.18601968E+00 0.18550054E+00
+ 0.18498283E+00 0.18446655E+00 0.18395169E+00 0.18343824E+00 0.18292621E+00
+ 0.18241558E+00 0.18190635E+00 0.18139852E+00 0.18089207E+00 0.18038701E+00
+ 0.17988332E+00 0.17938101E+00 0.17888006E+00 0.17838047E+00 0.17788224E+00
+ 0.17738537E+00 0.17688983E+00 0.17639564E+00 0.17590279E+00 0.17541126E+00
+ 0.17492106E+00 0.17443218E+00 0.17394462E+00 0.17345837E+00 0.17297342E+00
+ 0.17248977E+00 0.17200742E+00 0.17152636E+00 0.17104659E+00 0.17056810E+00
+ 0.17009088E+00 0.16961494E+00 0.16914026E+00 0.16866685E+00 0.16819469E+00
+ 0.16772379E+00 0.16725414E+00 0.16678573E+00 0.16631856E+00 0.16585263E+00
+ 0.16538793E+00 0.16492445E+00 0.16446220E+00 0.16400116E+00 0.16354134E+00
+ 0.16308272E+00 0.16262531E+00 0.16216910E+00 0.16171409E+00 0.16126026E+00
+ 0.16080763E+00 0.16035618E+00 0.15990590E+00 0.15945681E+00 0.15900888E+00
+ 0.15856212E+00 0.15811652E+00 0.15767208E+00 0.15722880E+00 0.15678667E+00
+ 0.15634568E+00 0.15590584E+00 0.15546713E+00 0.15502956E+00 0.15459312E+00
+ 0.15415781E+00 0.15372362E+00 0.15329055E+00 0.15285860E+00 0.15242776E+00
+ 0.15199803E+00 0.15156940E+00 0.15114187E+00 0.15071544E+00 0.15029010E+00
+ 0.14986585E+00 0.14944269E+00 0.14902061E+00 0.14859961E+00 0.14817969E+00
+ 0.14776084E+00 0.14734305E+00 0.14692633E+00 0.14651067E+00 0.14609607E+00
+ 0.14568253E+00 0.14527003E+00 0.14485859E+00 0.14444818E+00 0.14403882E+00
+ 0.14363050E+00 0.14322321E+00 0.14281695E+00 0.14241172E+00 0.14200751E+00
+ 0.14160432E+00 0.14120216E+00 0.14080100E+00 0.14040086E+00 0.14000173E+00
+ 0.13960360E+00 0.13920647E+00 0.13881034E+00 0.13841521E+00 0.13802107E+00
+ 0.13762792E+00 0.13723576E+00 0.13684458E+00 0.13645438E+00 0.13606516E+00
+ 0.13567691E+00 0.13528963E+00 0.13490332E+00 0.13451798E+00 0.13413360E+00
+ 0.13375018E+00 0.13336772E+00 0.13298621E+00 0.13260565E+00 0.13222604E+00
+ 0.13184737E+00 0.13146965E+00 0.13109287E+00 0.13071702E+00 0.13034211E+00
+ 0.12996813E+00 0.12959508E+00 0.12922295E+00 0.12885175E+00 0.12848147E+00
+ 0.12811210E+00 0.12774365E+00 0.12737612E+00 0.12700949E+00 0.12664377E+00
+ 0.12627895E+00 0.12591504E+00 0.12555202E+00 0.12518991E+00 0.12482868E+00
+ 0.12446835E+00 0.12410891E+00 0.12375035E+00 0.12339268E+00 0.12303589E+00
+ 0.12267998E+00 0.12232494E+00 0.12197078E+00 0.12161749E+00 0.12126507E+00
+ 0.12091352E+00 0.12056283E+00 0.12021301E+00 0.11986404E+00 0.11951593E+00
+ 0.11916867E+00 0.11882227E+00 0.11847672E+00 0.11813202E+00 0.11778816E+00
+ 0.11744514E+00 0.11710297E+00 0.11676163E+00 0.11642113E+00 0.11608147E+00
+ 0.11574263E+00 0.11540463E+00 0.11506745E+00 0.11473110E+00 0.11439557E+00
+ 0.11406087E+00 0.11372698E+00 0.11339391E+00 0.11306165E+00 0.11273020E+00
+ 0.11239957E+00 0.11206974E+00 0.11174072E+00 0.11141250E+00 0.11108508E+00
+ 0.11075846E+00 0.11043264E+00 0.11010762E+00 0.10978339E+00 0.10945995E+00
+ 0.10913730E+00 0.10881543E+00 0.10849435E+00 0.10817406E+00 0.10785454E+00
+ 0.10753581E+00 0.10721785E+00 0.10690067E+00 0.10658426E+00 0.10626862E+00
+ 0.10595375E+00 0.10563965E+00 0.10532631E+00 0.10501374E+00 0.10470193E+00
+ 0.10439087E+00 0.10408058E+00 0.10377104E+00 0.10346226E+00 0.10315423E+00
+ 0.10284695E+00 0.10254041E+00 0.10223463E+00 0.10192959E+00 0.10162529E+00
+ 0.10132173E+00 0.10101891E+00 0.10071683E+00 0.10041549E+00 0.10011488E+00
+ 0.99815002E-01 0.99515855E-01 0.99217436E-01 0.98919745E-01 0.98622778E-01
+ 0.98326535E-01 0.98031014E-01 0.97736213E-01 0.97442130E-01 0.97148764E-01
+ 0.96856113E-01 0.96564175E-01 0.96272949E-01 0.95982432E-01 0.95692624E-01
+ 0.95403522E-01 0.95115125E-01 0.94827432E-01 0.94540440E-01 0.94254148E-01
+ 0.93968554E-01 0.93683657E-01 0.93399456E-01 0.93115948E-01 0.92833131E-01
+ 0.92551005E-01 0.92269568E-01 0.91988818E-01 0.91708754E-01 0.91429373E-01
+ 0.91150675E-01 0.90872658E-01 0.90595321E-01 0.90318661E-01 0.90042677E-01
+ 0.89767369E-01 0.89492733E-01 0.89218769E-01 0.88945476E-01 0.88672851E-01
+ 0.88400894E-01 0.88129602E-01 0.87858974E-01 0.87589009E-01 0.87319706E-01
+ 0.87051062E-01 0.86783077E-01 0.86515749E-01 0.86249076E-01 0.85983057E-01
+ 0.85717690E-01 0.85452975E-01 0.85188910E-01 0.84925493E-01 0.84662723E-01
+ 0.84400598E-01 0.84139117E-01 0.83878279E-01 0.83618083E-01 0.83358526E-01
+ 0.83099607E-01 0.82841326E-01 0.82583681E-01 0.82326670E-01 0.82070292E-01
+ 0.81814545E-01 0.81559429E-01 0.81304942E-01 0.81051083E-01 0.80797849E-01
+ 0.80545241E-01 0.80293257E-01 0.80041894E-01 0.79791153E-01 0.79541031E-01
+ 0.79291528E-01 0.79042641E-01 0.78794371E-01 0.78546715E-01 0.78299672E-01
+ 0.78053241E-01 0.77807420E-01 0.77562209E-01 0.77317606E-01 0.77073610E-01
+ 0.76830219E-01 0.76587432E-01 0.76345248E-01 0.76103667E-01 0.75862685E-01
+ 0.75622303E-01 0.75382519E-01 0.75143332E-01 0.74904740E-01 0.74666743E-01
+ 0.74429338E-01 0.74192526E-01 0.73956304E-01 0.73720672E-01 0.73485628E-01
+ 0.73251171E-01 0.73017300E-01 0.72784013E-01 0.72551310E-01 0.72319190E-01
+ 0.72087650E-01 0.71856691E-01 0.71626310E-01 0.71396507E-01 0.71167280E-01
+ 0.70938628E-01 0.70710551E-01 0.70483046E-01 0.70256114E-01 0.70029752E-01
+ 0.69803959E-01 0.69578735E-01 0.69354078E-01 0.69129987E-01 0.68906461E-01
+ 0.68683499E-01 0.68461100E-01 0.68239262E-01 0.68017985E-01 0.67797267E-01
+ 0.67577107E-01 0.67357504E-01 0.67138458E-01 0.66919966E-01 0.66702028E-01
+ 0.66484643E-01 0.66267810E-01 0.66051527E-01 0.65835794E-01 0.65620609E-01
+ 0.65405971E-01 0.65191880E-01 0.64978333E-01 0.64765331E-01 0.64552872E-01
+ 0.64340955E-01 0.64129579E-01 0.63918742E-01 0.63708445E-01 0.63498685E-01
+ 0.63289462E-01 0.63080774E-01 0.62872621E-01 0.62665002E-01 0.62457915E-01
+ 0.62251360E-01 0.62045335E-01 0.61839839E-01 0.61634872E-01 0.61430432E-01
+ 0.61226519E-01 0.61023131E-01 0.60820267E-01 0.60617927E-01 0.60416109E-01
+ 0.60214812E-01 0.60014036E-01 0.59813778E-01 0.59614040E-01 0.59414818E-01
+ 0.59216113E-01 0.59017922E-01 0.58820247E-01 0.58623084E-01 0.58426434E-01
+ 0.58230295E-01 0.58034667E-01 0.57839548E-01 0.57644937E-01 0.57450834E-01
+ 0.57257237E-01 0.57064146E-01 0.56871559E-01 0.56679476E-01 0.56487895E-01
+ 0.56296816E-01 0.56106238E-01 0.55916159E-01 0.55726580E-01 0.55537498E-01
+ 0.55348913E-01 0.55160823E-01 0.54973229E-01 0.54786129E-01 0.54599522E-01
+ 0.54413407E-01 0.54227783E-01 0.54042650E-01 0.53858006E-01 0.53673850E-01
+ 0.53490182E-01 0.53307000E-01 0.53124304E-01 0.52942093E-01 0.52760365E-01
+ 0.52579121E-01 0.52398358E-01 0.52218076E-01 0.52038275E-01 0.51858952E-01
+ 0.51680108E-01 0.51501742E-01 0.51323851E-01 0.51146437E-01 0.50969497E-01
+ 0.50793031E-01 0.50617038E-01 0.50441516E-01 0.50266466E-01 0.50091886E-01
+ 0.49917776E-01 0.49744133E-01 0.49570959E-01 0.49398251E-01 0.49226008E-01
+ 0.49054231E-01 0.48882917E-01 0.48712067E-01 0.48541679E-01 0.48371752E-01
+ 0.48202286E-01 0.48033279E-01 0.47864731E-01 0.47696641E-01 0.47529008E-01
+ 0.47361831E-01 0.47195109E-01 0.47028842E-01 0.46863028E-01 0.46697667E-01
+ 0.46532758E-01 0.46368299E-01 0.46204291E-01 0.46040732E-01 0.45877621E-01
+ 0.45714958E-01 0.45552742E-01 0.45390971E-01 0.45229646E-01 0.45068764E-01
+ 0.44908326E-01 0.44748330E-01 0.44588776E-01 0.44429663E-01 0.44270989E-01
+ 0.44112755E-01 0.43954959E-01 0.43797600E-01 0.43640678E-01 0.43484191E-01
+ 0.43328140E-01 0.43172522E-01 0.43017338E-01 0.42862587E-01 0.42708266E-01
+ 0.42554377E-01 0.42400918E-01 0.42247887E-01 0.42095285E-01 0.41943111E-01
+ 0.41791363E-01 0.41640041E-01 0.41489144E-01 0.41338671E-01 0.41188622E-01
+ 0.41038995E-01 0.40889790E-01 0.40741006E-01 0.40592642E-01 0.40444697E-01
+ 0.40297171E-01 0.40150063E-01 0.40003371E-01 0.39857096E-01 0.39711236E-01
+ 0.39565790E-01 0.39420758E-01 0.39276139E-01 0.39131933E-01 0.38988137E-01
+ 0.38844752E-01 0.38701777E-01 0.38559210E-01 0.38417052E-01 0.38275301E-01
+ 0.38133957E-01 0.37993018E-01 0.37852485E-01 0.37712355E-01 0.37572629E-01
+ 0.37433305E-01 0.37294384E-01 0.37155863E-01 0.37017743E-01 0.36880022E-01
+ 0.36742699E-01 0.36605775E-01 0.36469248E-01 0.36333117E-01 0.36197381E-01
+ 0.36062041E-01 0.35927094E-01 0.35792541E-01 0.35658380E-01 0.35524611E-01
+ 0.35391233E-01 0.35258244E-01 0.35125646E-01 0.34993435E-01 0.34861613E-01
+ 0.34730178E-01 0.34599129E-01 0.34468465E-01 0.34338187E-01 0.34208292E-01
+ 0.34078780E-01 0.33949651E-01 0.33820904E-01 0.33692538E-01 0.33564552E-01
+ 0.33436945E-01 0.33309717E-01 0.33182867E-01 0.33056394E-01 0.32930297E-01
+ 0.32804576E-01 0.32679230E-01 0.32554258E-01 0.32429660E-01 0.32305434E-01
+ 0.32181580E-01 0.32058097E-01 0.31934984E-01 0.31812241E-01 0.31689867E-01
+ 0.31567861E-01 0.31446223E-01 0.31324951E-01 0.31204045E-01 0.31083504E-01
+ 0.30963328E-01 0.30843515E-01 0.30724065E-01 0.30604978E-01 0.30486251E-01
+ 0.30367886E-01 0.30249880E-01 0.30132234E-01 0.30014946E-01 0.29898016E-01
+ 0.29781443E-01 0.29665226E-01 0.29549365E-01 0.29433858E-01 0.29318706E-01
+ 0.29203907E-01 0.29089460E-01 0.28975365E-01 0.28861622E-01 0.28748229E-01
+ 0.28635185E-01 0.28522491E-01 0.28410145E-01 0.28298146E-01 0.28186494E-01
+ 0.28075188E-01 0.27964228E-01 0.27853612E-01 0.27743339E-01 0.27633410E-01
+ 0.27523824E-01 0.27414579E-01 0.27305675E-01 0.27197112E-01 0.27088887E-01
+ 0.26981002E-01 0.26873455E-01 0.26766245E-01 0.26659372E-01 0.26552835E-01
+ 0.26446633E-01 0.26340765E-01 0.26235232E-01 0.26130031E-01 0.26025163E-01
+ 0.25920626E-01 0.25816421E-01 0.25712545E-01 0.25608999E-01 0.25505782E-01
+ 0.25402893E-01 0.25300332E-01 0.25198097E-01 0.25096188E-01 0.24994604E-01
+ 0.24893345E-01 0.24792410E-01 0.24691798E-01 0.24591508E-01 0.24491540E-01
+ 0.24391893E-01 0.24292567E-01 0.24193560E-01 0.24094872E-01 0.23996502E-01
+ 0.23898449E-01 0.23800714E-01 0.23703295E-01 0.23606191E-01 0.23509401E-01
+ 0.23412926E-01 0.23316764E-01 0.23220915E-01 0.23125377E-01 0.23030151E-01
+ 0.22935236E-01 0.22840630E-01 0.22746333E-01 0.22652345E-01 0.22558664E-01
+ 0.22465291E-01 0.22372224E-01 0.22279463E-01 0.22187006E-01 0.22094854E-01
+ 0.22003006E-01 0.21911460E-01 0.21820217E-01 0.21729275E-01 0.21638634E-01
+ 0.21548294E-01 0.21458252E-01 0.21368510E-01 0.21279066E-01 0.21189919E-01
+ 0.21101068E-01 0.21012514E-01 0.20924255E-01 0.20836291E-01 0.20748621E-01
+ 0.20661244E-01 0.20574160E-01 0.20487368E-01 0.20400867E-01 0.20314657E-01
+ 0.20228737E-01 0.20143106E-01 0.20057763E-01 0.19972708E-01 0.19887941E-01
+ 0.19803460E-01 0.19719265E-01 0.19635355E-01 0.19551730E-01 0.19468388E-01
+ 0.19385330E-01 0.19302554E-01 0.19220060E-01 0.19137847E-01 0.19055914E-01
+ 0.18974262E-01 0.18892888E-01 0.18811793E-01 0.18730976E-01 0.18650436E-01
+ 0.18570172E-01 0.18490184E-01 0.18410471E-01 0.18331033E-01 0.18251868E-01
+ 0.18172976E-01 0.18094357E-01 0.18016010E-01 0.17937934E-01 0.17860128E-01
+ 0.17782592E-01 0.17705326E-01 0.17628327E-01 0.17551597E-01 0.17475133E-01
+ 0.17398937E-01 0.17323005E-01 0.17247340E-01 0.17171938E-01 0.17096801E-01
+ 0.17021926E-01 0.16947314E-01 0.16872964E-01 0.16798876E-01 0.16725047E-01
+ 0.16651479E-01 0.16578170E-01 0.16505119E-01 0.16432327E-01 0.16359792E-01
+ 0.16287513E-01 0.16215490E-01 0.16143723E-01 0.16072210E-01 0.16000951E-01
+ 0.15929946E-01 0.15859193E-01 0.15788693E-01 0.15718444E-01 0.15648445E-01
+ 0.15578697E-01 0.15509198E-01 0.15439948E-01 0.15370946E-01 0.15302192E-01
+ 0.15233685E-01 0.15165423E-01 0.15097408E-01 0.15029637E-01 0.14962111E-01
+ 0.14894828E-01 0.14827788E-01 0.14760991E-01 0.14694436E-01 0.14628121E-01
+ 0.14562047E-01 0.14496213E-01 0.14430618E-01 0.14365261E-01 0.14300142E-01
+ 0.14235261E-01 0.14170616E-01 0.14106207E-01 0.14042033E-01 0.13978094E-01
+ 0.13914389E-01 0.13850918E-01 0.13787679E-01 0.13724673E-01 0.13661898E-01
+ 0.13599354E-01 0.13537040E-01 0.13474955E-01 0.13413100E-01 0.13351473E-01
+ 0.13290074E-01 0.13228901E-01 0.13167955E-01 0.13107235E-01 0.13046741E-01
+ 0.12986470E-01 0.12926424E-01 0.12866601E-01 0.12807000E-01 0.12747622E-01
+ 0.12688465E-01 0.12629529E-01 0.12570813E-01 0.12512316E-01 0.12454038E-01
+ 0.12395979E-01 0.12338137E-01 0.12280512E-01 0.12223104E-01 0.12165911E-01
+ 0.12108934E-01 0.12052171E-01 0.11995622E-01 0.11939286E-01 0.11883163E-01
+ 0.11827251E-01 0.11771552E-01 0.11716063E-01 0.11660784E-01 0.11605715E-01
+ 0.11550854E-01 0.11496202E-01 0.11441758E-01 0.11387520E-01 0.11333490E-01
+ 0.11279665E-01 0.11226045E-01 0.11172629E-01 0.11119418E-01 0.11066410E-01
+ 0.11013605E-01 0.10961002E-01 0.10908600E-01 0.10856399E-01 0.10804399E-01
+ 0.10752598E-01 0.10700997E-01 0.10649593E-01 0.10598388E-01 0.10547379E-01
+ 0.10496568E-01 0.10445952E-01 0.10395532E-01 0.10345306E-01 0.10295275E-01
+ 0.10245437E-01 0.10195792E-01 0.10146339E-01 0.10097078E-01 0.10048008E-01
+ 0.99991286E-02 0.99504391E-02 0.99019388E-02 0.98536271E-02 0.98055035E-02
+ 0.97575673E-02 0.97098180E-02 0.96622548E-02 0.96148773E-02 0.95676848E-02
+ 0.95206767E-02 0.94738523E-02 0.94272112E-02 0.93807526E-02 0.93344761E-02
+ 0.92883808E-02 0.92424664E-02 0.91967321E-02 0.91511773E-02 0.91058015E-02
+ 0.90606041E-02 0.90155844E-02 0.89707418E-02 0.89260758E-02 0.88815857E-02
+ 0.88372709E-02 0.87931309E-02 0.87491650E-02 0.87053726E-02 0.86617531E-02
+ 0.86183060E-02 0.85750305E-02 0.85319262E-02 0.84889924E-02 0.84462285E-02
+ 0.84036340E-02 0.83612081E-02 0.83189504E-02 0.82768601E-02 0.82349368E-02
+ 0.81931798E-02 0.81515886E-02 0.81101624E-02 0.80689008E-02 0.80278030E-02
+ 0.79868686E-02 0.79460970E-02 0.79054874E-02 0.78650394E-02 0.78247523E-02
+ 0.77846255E-02 0.77446585E-02 0.77048506E-02 0.76652013E-02 0.76257099E-02
+ 0.75863758E-02 0.75471985E-02 0.75081773E-02 0.74693117E-02 0.74306011E-02
+ 0.73920448E-02 0.73536423E-02 0.73153930E-02 0.72772962E-02 0.72393514E-02
+ 0.72015580E-02 0.71639154E-02 0.71264230E-02 0.70890802E-02 0.70518864E-02
+ 0.70148410E-02 0.69779435E-02 0.69411931E-02 0.69045894E-02 0.68681317E-02
+ 0.68318194E-02 0.67956520E-02 0.67596289E-02 0.67237494E-02 0.66880129E-02
+ 0.66524190E-02 0.66169669E-02 0.65816561E-02 0.65464859E-02 0.65114559E-02
+ 0.64765654E-02 0.64418138E-02 0.64072005E-02 0.63727249E-02 0.63383865E-02
+ 0.63041846E-02 0.62701186E-02 0.62361880E-02 0.62023922E-02 0.61687305E-02
+ 0.61352024E-02 0.61018073E-02 0.60685446E-02 0.60354136E-02 0.60024139E-02
+ 0.59695448E-02 0.59368058E-02 0.59041961E-02 0.58717154E-02 0.58393628E-02
+ 0.58071380E-02 0.57750402E-02 0.57430688E-02 0.57112234E-02 0.56795033E-02
+ 0.56479079E-02 0.56164365E-02 0.55850888E-02 0.55538639E-02 0.55227615E-02
+ 0.54917807E-02 0.54609212E-02 0.54301822E-02 0.53995632E-02 0.53690637E-02
+ 0.53386829E-02 0.53084204E-02 0.52782755E-02 0.52482477E-02 0.52183363E-02
+ 0.51885408E-02 0.51588606E-02 0.51292951E-02 0.50998437E-02 0.50705059E-02
+ 0.50412810E-02 0.50121684E-02 0.49831676E-02 0.49542781E-02 0.49254991E-02
+ 0.48968301E-02 0.48682706E-02 0.48398200E-02 0.48114776E-02 0.47832429E-02
+ 0.47551153E-02 0.47270942E-02 0.46991791E-02 0.46713693E-02 0.46436644E-02
+ 0.46160636E-02 0.45885665E-02 0.45611724E-02 0.45338808E-02 0.45066910E-02
+ 0.44796026E-02 0.44526150E-02 0.44257275E-02 0.43989396E-02 0.43722507E-02
+ 0.43456603E-02 0.43191677E-02 0.42927725E-02 0.42664740E-02 0.42402716E-02
+ 0.42141649E-02 0.41881532E-02 0.41622359E-02 0.41364126E-02 0.41106826E-02
+ 0.40850454E-02 0.40595004E-02 0.40340470E-02 0.40086848E-02 0.39834131E-02
+ 0.39582313E-02 0.39331390E-02 0.39081356E-02 0.38832205E-02 0.38583932E-02
+ 0.38336531E-02 0.38089996E-02 0.37844323E-02 0.37599506E-02 0.37355540E-02
+ 0.37112419E-02 0.36870137E-02 0.36628689E-02 0.36388071E-02 0.36148276E-02
+ 0.35909300E-02 0.35671137E-02 0.35433782E-02 0.35197229E-02 0.34961474E-02
+ 0.34726512E-02 0.34492336E-02 0.34258943E-02 0.34026326E-02 0.33794481E-02
+ 0.33563403E-02 0.33333087E-02 0.33103528E-02 0.32874721E-02 0.32646661E-02
+ 0.32419343E-02 0.32192762E-02 0.31966914E-02 0.31741793E-02 0.31517396E-02
+ 0.31293716E-02 0.31070751E-02 0.30848494E-02 0.30626943E-02 0.30406091E-02
+ 0.30185934E-02 0.29966469E-02 0.29747690E-02 0.29529594E-02 0.29312175E-02
+ 0.29095431E-02 0.28879356E-02 0.28663946E-02 0.28449198E-02 0.28235107E-02
+ 0.28021670E-02 0.27808882E-02 0.27596740E-02 0.27385239E-02 0.27174377E-02
+ 0.26964149E-02 0.26754552E-02 0.26545583E-02 0.26337237E-02 0.26129511E-02
+ 0.25922403E-02 0.25715909E-02 0.25510025E-02 0.25304749E-02 0.25100078E-02
+ 0.24896008E-02 0.24692537E-02 0.24489662E-02 0.24287380E-02 0.24085689E-02
+ 0.23884587E-02 0.23684070E-02 0.23484137E-02 0.23284784E-02 0.23086011E-02
+ 0.22887816E-02 0.22690195E-02 0.22493147E-02 0.22296671E-02 0.22100765E-02
+ 0.21905428E-02 0.21710657E-02 0.21516452E-02 0.21322812E-02 0.21129735E-02
+ 0.20937220E-02 0.20745268E-02 0.20553876E-02 0.20363045E-02 0.20172774E-02
+ 0.19983062E-02 0.19793910E-02 0.19605317E-02 0.19417284E-02 0.19229811E-02
+ 0.19042897E-02 0.18856544E-02 0.18670752E-02 0.18485523E-02 0.18300856E-02
+ 0.18116753E-02 0.17933215E-02 0.17750244E-02 0.17567841E-02 0.17386008E-02
+ 0.17204747E-02 0.17024059E-02 0.16843947E-02 0.16664414E-02 0.16485461E-02
+ 0.16307092E-02 0.16129309E-02 0.15952115E-02 0.15775514E-02 0.15599509E-02
+ 0.15424104E-02 0.15249301E-02 0.15075106E-02 0.14901522E-02 0.14728553E-02
+ 0.14556204E-02 0.14384480E-02 0.14213385E-02 0.14042925E-02 0.13873104E-02
+ 0.13703928E-02 0.13535403E-02 0.13367534E-02 0.13200327E-02 0.13033788E-02
+ 0.12867925E-02 0.12702742E-02 0.12538247E-02 0.12374447E-02 0.12211349E-02
+ 0.12048960E-02 0.11887287E-02 0.11726338E-02 0.11566122E-02 0.11406645E-02
+ 0.11247916E-02 0.11089944E-02 0.10932737E-02 0.10776304E-02 0.10620653E-02
+ 0.10465793E-02 0.10311735E-02 0.10158486E-02 0.10006058E-02 0.98544583E-03
+ 0.97036982E-03 0.95537873E-03 0.94047357E-03 0.92565537E-03 0.91092518E-03
+ 0.89628404E-03 0.88173303E-03 0.86727322E-03 0.85290571E-03 0.83863159E-03
+ 0.82445198E-03 0.81036800E-03 0.79638078E-03 0.78249145E-03 0.76870117E-03
+ 0.75501108E-03 0.74142234E-03 0.72793612E-03 0.71455358E-03 0.70127590E-03
+ 0.68810424E-03 0.67503979E-03 0.66208371E-03 0.64923718E-03 0.63650137E-03
+ 0.62387746E-03 0.61136660E-03 0.59896996E-03 0.58668870E-03 0.57452395E-03
+ 0.56247687E-03 0.55054858E-03 0.53874020E-03 0.52705283E-03 0.51548757E-03
+ 0.50404550E-03 0.49272768E-03 0.48153515E-03 0.47046894E-03 0.45953006E-03
+ 0.44871949E-03 0.43803819E-03 0.42748709E-03 0.41706712E-03 0.40677915E-03
+ 0.39662404E-03 0.38660261E-03 0.37671566E-03 0.36696395E-03 0.35734821E-03
+ 0.34786912E-03 0.33852734E-03 0.32932349E-03 0.32025813E-03 0.31133181E-03
+ 0.30254501E-03 0.29389819E-03 0.28539174E-03 0.27702602E-03 0.26880133E-03
+ 0.26071795E-03 0.25277607E-03 0.24497585E-03 0.23731740E-03 0.22980077E-03
+ 0.22242597E-03 0.21519292E-03 0.20810153E-03 0.20115161E-03 0.19434296E-03
+ 0.18767527E-03 0.18114820E-03 0.17476136E-03 0.16851428E-03 0.16240643E-03
+ 0.15643725E-03 0.15060607E-03 0.14491220E-03 0.13935488E-03 0.13393328E-03
+ 0.12864652E-03 0.12349364E-03 0.11847365E-03 0.11358549E-03 0.10882802E-03
+ 0.10420007E-03 0.99700406E-04 0.95327728E-04 0.91080688E-04 0.86957882E-04
+ 0.82957852E-04 0.79079090E-04 0.75320035E-04 0.71679078E-04 0.68154561E-04
+ 0.64744783E-04 0.61447995E-04 0.58262408E-04 0.55186190E-04 0.52217473E-04
+ 0.49354351E-04 0.46594883E-04 0.43937097E-04 0.41378989E-04 0.38918529E-04
+ 0.36553661E-04 0.34282306E-04 0.32102364E-04 0.30011719E-04 0.28008237E-04
+ 0.26089773E-04 0.24254170E-04 0.22499266E-04 0.20822892E-04 0.19222876E-04
+ 0.17697049E-04 0.16243241E-04 0.14859290E-04 0.13543042E-04 0.12292351E-04
+ 0.11105087E-04 0.99791342E-05 0.89123930E-05 0.79027858E-05 0.69482564E-05
+ 0.60467735E-05 0.51963320E-05 0.43949557E-05 0.36406989E-05 0.29316482E-05
+ 0.22659245E-05 0.16416844E-05 0.10571218E-05 0.51046941E-06 0.00000000E+00
+ 0.22206215E-01 0.22672190E-01 0.23138164E-01 0.23604139E-01 0.24070113E-01
+ 0.24536088E-01 0.25002062E-01 0.25468037E-01 0.25934011E-01 0.26399986E-01
+ 0.26865960E-01 0.27331935E-01 0.27797909E-01 0.28263884E-01 0.28729858E-01
+ 0.29195832E-01 0.29661807E-01 0.30127781E-01 0.30593756E-01 0.31059730E-01
+ 0.31525705E-01 0.31991679E-01 0.32457654E-01 0.32923628E-01 0.33389603E-01
+ 0.33855577E-01 0.34321552E-01 0.34787526E-01 0.35253501E-01 0.35719475E-01
+ 0.36185450E-01 0.36651424E-01 0.37117399E-01 0.37583373E-01 0.38049348E-01
+ 0.38515322E-01 0.38981297E-01 0.39447271E-01 0.39913246E-01 0.40379220E-01
+ 0.40845194E-01 0.41311169E-01 0.41777143E-01 0.42243118E-01 0.42709092E-01
+ 0.43175067E-01 0.43641041E-01 0.44107016E-01 0.44572990E-01 0.45038965E-01
+ 0.45504939E-01 0.45970914E-01 0.46436888E-01 0.46902863E-01 0.47368837E-01
+ 0.47834812E-01 0.48300786E-01 0.48766761E-01 0.49232735E-01 0.49698710E-01
+ 0.50164684E-01 0.50630659E-01 0.51096633E-01 0.51562607E-01 0.52028582E-01
+ 0.52494556E-01 0.52960531E-01 0.53426505E-01 0.53892480E-01 0.54358454E-01
+ 0.54824429E-01 0.55290403E-01 0.55756378E-01 0.56222352E-01 0.56688327E-01
+ 0.57154301E-01 0.57620276E-01 0.58086250E-01 0.58552225E-01 0.59018199E-01
+ 0.59484174E-01 0.59950148E-01 0.60416123E-01 0.60882097E-01 0.61348072E-01
+ 0.61814046E-01 0.62280021E-01 0.62745995E-01 0.63211969E-01 0.63677944E-01
+ 0.64143918E-01 0.64609893E-01 0.65075867E-01 0.65541842E-01 0.66007816E-01
+ 0.66473791E-01 0.66939765E-01 0.67405740E-01 0.67871714E-01 0.68337689E-01
+ 0.68803663E-01 0.69269638E-01 0.69735612E-01 0.70201587E-01 0.70667561E-01
+ 0.71133536E-01 0.71599510E-01 0.72065485E-01 0.72531459E-01 0.72997434E-01
+ 0.73463408E-01 0.73929383E-01 0.74395357E-01 0.74861331E-01 0.75327306E-01
+ 0.75793280E-01 0.76259255E-01 0.76725229E-01 0.77191204E-01 0.77657178E-01
+ 0.78123153E-01 0.78589127E-01 0.79055102E-01 0.79521076E-01 0.79987051E-01
+ 0.80453025E-01 0.80919000E-01 0.81384974E-01 0.81850949E-01 0.82316923E-01
+ 0.82782898E-01 0.83248872E-01 0.83714847E-01 0.84180821E-01 0.84646796E-01
+ 0.85112770E-01 0.85578744E-01 0.86044719E-01 0.86510693E-01 0.86976668E-01
+ 0.87442642E-01 0.87908617E-01 0.88374591E-01 0.88840566E-01 0.89306540E-01
+ 0.89772515E-01 0.90238489E-01 0.90704464E-01 0.91170438E-01 0.91636413E-01
+ 0.92102387E-01 0.92568362E-01 0.93034336E-01 0.93500311E-01 0.93966285E-01
+ 0.94432260E-01 0.94898234E-01 0.95364209E-01 0.95830183E-01 0.96296158E-01
+ 0.96762132E-01 0.97228106E-01 0.97694081E-01 0.98160055E-01 0.98626030E-01
+ 0.99092004E-01 0.99557979E-01 0.10002395E+00 0.10048993E+00 0.10095590E+00
+ 0.10142188E+00 0.10188785E+00 0.10235383E+00 0.10281980E+00 0.10328577E+00
+ 0.10375175E+00 0.10421772E+00 0.10468370E+00 0.10514967E+00 0.10561565E+00
+ 0.10608162E+00 0.10654760E+00 0.10701357E+00 0.10747955E+00 0.10794552E+00
+ 0.10841149E+00 0.10887747E+00 0.10934344E+00 0.10980942E+00 0.11027539E+00
+ 0.11074137E+00 0.11120734E+00 0.11167332E+00 0.11213929E+00 0.11260526E+00
+ 0.11307124E+00 0.11353721E+00 0.11400319E+00 0.11446916E+00 0.11493514E+00
+ 0.11540111E+00 0.11586709E+00 0.11633306E+00 0.11679903E+00 0.11726501E+00
+ 0.11773098E+00 0.11819696E+00 0.11866293E+00 0.11912891E+00 0.11959488E+00
+ 0.12006086E+00 0.12052683E+00 0.12099280E+00 0.12145878E+00 0.12192475E+00
+ 0.12239073E+00 0.12285670E+00 0.12332268E+00 0.12378865E+00 0.12425463E+00
+ 0.12472060E+00 0.12518658E+00 0.12565255E+00 0.12611852E+00 0.12658450E+00
+ 0.12705047E+00 0.12751645E+00 0.12798242E+00 0.12844840E+00 0.12891437E+00
+ 0.12938035E+00 0.12984632E+00 0.13031229E+00 0.13077827E+00 0.13124424E+00
+ 0.13171022E+00 0.13217619E+00 0.13264217E+00 0.13310814E+00 0.13357412E+00
+ 0.13404009E+00 0.13450606E+00 0.13497204E+00 0.13543801E+00 0.13590399E+00
+ 0.13636996E+00 0.13683594E+00 0.13730191E+00 0.13776789E+00 0.13823386E+00
+ 0.13869984E+00 0.13916581E+00 0.13963178E+00 0.14009776E+00 0.14056373E+00
+ 0.14102971E+00 0.14149568E+00 0.14196166E+00 0.14242763E+00 0.14289361E+00
+ 0.14335958E+00 0.14382555E+00 0.14429153E+00 0.14475750E+00 0.14522348E+00
+ 0.14568945E+00 0.14615543E+00 0.14662140E+00 0.14708738E+00 0.14755335E+00
+ 0.14801932E+00 0.14848530E+00 0.14895127E+00 0.14941725E+00 0.14988322E+00
+ 0.15034920E+00 0.15081517E+00 0.15128115E+00 0.15174712E+00 0.15221310E+00
+ 0.15267907E+00 0.15314504E+00 0.15361102E+00 0.15407699E+00 0.15454297E+00
+ 0.15500894E+00 0.15547492E+00 0.15594089E+00 0.15640687E+00 0.15687284E+00
+ 0.15733881E+00 0.15780479E+00 0.15827076E+00 0.15873674E+00 0.15920271E+00
+ 0.15966869E+00 0.16013466E+00 0.16060064E+00 0.16106661E+00 0.16153258E+00
+ 0.16199856E+00 0.16246453E+00 0.16293051E+00 0.16339648E+00 0.16386246E+00
+ 0.16432843E+00 0.16479441E+00 0.16526038E+00 0.16572635E+00 0.16619233E+00
+ 0.16665830E+00 0.16712428E+00 0.16759025E+00 0.16805623E+00 0.16852220E+00
+ 0.16898818E+00 0.16945415E+00 0.16992013E+00 0.17038610E+00 0.17085207E+00
+ 0.17131805E+00 0.17178402E+00 0.17225000E+00 0.17271597E+00 0.17318195E+00
+ 0.17364792E+00 0.17411390E+00 0.17457987E+00 0.17504584E+00 0.17551182E+00
+ 0.17597779E+00 0.17644377E+00 0.17690974E+00 0.17737572E+00 0.17784169E+00
+ 0.17830767E+00 0.17877364E+00 0.17923961E+00 0.17970559E+00 0.18017156E+00
+ 0.18063754E+00 0.18110351E+00 0.18156949E+00 0.18203546E+00 0.18250144E+00
+ 0.18296741E+00 0.18343339E+00 0.18389936E+00 0.18436533E+00 0.18483131E+00
+ 0.18529728E+00 0.18576326E+00 0.18622923E+00 0.18669521E+00 0.18716118E+00
+ 0.18762716E+00 0.18809313E+00 0.18855910E+00 0.18902508E+00 0.18949105E+00
+ 0.18995703E+00 0.19042300E+00 0.19088898E+00 0.19135495E+00 0.19182093E+00
+ 0.19228690E+00 0.19275287E+00 0.19321885E+00 0.19368482E+00 0.19415080E+00
+ 0.19461677E+00 0.19508275E+00 0.19554872E+00 0.19601470E+00 0.19648067E+00
+ 0.19694665E+00 0.19741262E+00 0.19787859E+00 0.19834457E+00 0.19881054E+00
+ 0.19927652E+00 0.19974249E+00 0.20020847E+00 0.20067444E+00 0.20114042E+00
+ 0.20160639E+00 0.20207236E+00 0.20253834E+00 0.20300431E+00 0.20347029E+00
+ 0.20393626E+00 0.20440224E+00 0.20486821E+00 0.20533419E+00 0.20580016E+00
+ 0.20626613E+00 0.20673211E+00 0.20719808E+00 0.20766406E+00 0.20813003E+00
+ 0.20859601E+00 0.20906198E+00 0.20952796E+00 0.20999393E+00 0.21045990E+00
+ 0.21092588E+00 0.21139185E+00 0.21185783E+00 0.21232380E+00 0.21278978E+00
+ 0.21325575E+00 0.21372173E+00 0.21418770E+00 0.21465368E+00 0.21511965E+00
+ 0.21558562E+00 0.21605160E+00 0.21651757E+00 0.21698355E+00 0.21744952E+00
+ 0.21791550E+00 0.21838147E+00 0.21884745E+00 0.21931342E+00 0.21977939E+00
+ 0.22024537E+00 0.22071134E+00 0.22117732E+00 0.22164329E+00 0.22210927E+00
+ 0.22257524E+00 0.22304122E+00 0.22350719E+00 0.22397316E+00 0.22443914E+00
+ 0.22490511E+00 0.22537109E+00 0.22583706E+00 0.22630304E+00 0.22676901E+00
+ 0.22723499E+00 0.22770096E+00 0.22816694E+00 0.22863291E+00 0.22909888E+00
+ 0.22956486E+00 0.23003083E+00 0.23049681E+00 0.23096278E+00 0.23142876E+00
+ 0.23189473E+00 0.23236071E+00 0.23282668E+00 0.23329265E+00 0.23375863E+00
+ 0.23422460E+00 0.23469058E+00 0.23515655E+00 0.23562253E+00 0.23608850E+00
+ 0.23655448E+00 0.23702045E+00 0.23748642E+00 0.23795240E+00 0.23841837E+00
+ 0.23888435E+00 0.23935032E+00 0.23981630E+00 0.24028227E+00 0.24074825E+00
+ 0.24121422E+00 0.24168020E+00 0.24214617E+00 0.24261214E+00 0.24307812E+00
+ 0.24354409E+00 0.24401007E+00 0.24447604E+00 0.24494202E+00 0.24540799E+00
+ 0.24587397E+00 0.24633994E+00 0.24680591E+00 0.24727189E+00 0.24773786E+00
+ 0.24820384E+00 0.24866981E+00 0.24913579E+00 0.24960176E+00 0.25006774E+00
+ 0.25053371E+00 0.25099968E+00 0.25146566E+00 0.25193163E+00 0.25239761E+00
+ 0.25286358E+00 0.25332956E+00 0.25379553E+00 0.25426151E+00 0.25472748E+00
+ 0.25519345E+00 0.25565943E+00 0.25612540E+00 0.25659138E+00 0.25705735E+00
+ 0.25752333E+00 0.25798930E+00 0.25845528E+00 0.25892125E+00 0.25938723E+00
+ 0.25985320E+00 0.26031917E+00 0.26078515E+00 0.26125112E+00 0.26171710E+00
+ 0.26218307E+00 0.26264905E+00 0.26311502E+00 0.26358100E+00 0.26404697E+00
+ 0.26451294E+00 0.26497892E+00 0.26544489E+00 0.26591087E+00 0.26637684E+00
+ 0.26684282E+00 0.26730879E+00 0.26777477E+00 0.26824074E+00 0.26870671E+00
+ 0.26917269E+00 0.26963866E+00 0.27010464E+00 0.27057061E+00 0.27103659E+00
+ 0.27150256E+00 0.27196854E+00 0.27243451E+00 0.27290049E+00 0.27336646E+00
+ 0.27383243E+00 0.27429841E+00 0.27476438E+00 0.27523036E+00 0.27569633E+00
+ 0.27616231E+00 0.27662828E+00 0.27709426E+00 0.27756023E+00 0.27802620E+00
+ 0.27849218E+00 0.27895815E+00 0.27942413E+00 0.27989010E+00 0.28035608E+00
+ 0.28082205E+00 0.28128803E+00 0.28175400E+00 0.28221997E+00 0.28268595E+00
+ 0.28315192E+00 0.28361790E+00 0.28408387E+00 0.28454985E+00 0.28501582E+00
+ 0.28548180E+00 0.28594777E+00 0.28641375E+00 0.28687972E+00 0.28734569E+00
+ 0.28781167E+00 0.28827764E+00 0.28874362E+00 0.28920959E+00 0.28967557E+00
+ 0.29014154E+00 0.29060752E+00 0.29107349E+00 0.29153946E+00 0.29200544E+00
+ 0.29247141E+00 0.29293739E+00 0.29340336E+00 0.29386934E+00 0.29433531E+00
+ 0.29480129E+00 0.29526726E+00 0.29573323E+00 0.29619921E+00 0.29666518E+00
+ 0.29713116E+00 0.29759713E+00 0.29806311E+00 0.29852908E+00 0.29899506E+00
+ 0.29946103E+00 0.29992701E+00 0.30039298E+00 0.30085895E+00 0.30132493E+00
+ 0.30179090E+00 0.30225688E+00 0.30272285E+00 0.30318883E+00 0.30365480E+00
+ 0.30412078E+00 0.30458675E+00 0.30505272E+00 0.30551870E+00 0.30598467E+00
+ 0.30645065E+00 0.30691662E+00 0.30738260E+00 0.30784857E+00 0.30831455E+00
+ 0.30878052E+00 0.30924649E+00 0.30971247E+00 0.31017844E+00 0.31064442E+00
+ 0.31111039E+00 0.31157637E+00 0.31204234E+00 0.31250832E+00 0.31297429E+00
+ 0.31344026E+00 0.31390624E+00 0.31437221E+00 0.31483819E+00 0.31530416E+00
+ 0.31577014E+00 0.31623611E+00 0.31670209E+00 0.31716806E+00 0.31763404E+00
+ 0.31810001E+00 0.31856598E+00 0.31903196E+00 0.31949793E+00 0.31996391E+00
+ 0.32042988E+00 0.32089586E+00 0.32136183E+00 0.32182781E+00 0.32229378E+00
+ 0.32275975E+00 0.32322573E+00 0.32369170E+00 0.32415768E+00 0.32462365E+00
+ 0.32508963E+00 0.32555560E+00 0.32602158E+00 0.32648755E+00 0.32695352E+00
+ 0.32741950E+00 0.32788547E+00 0.32835145E+00 0.32881742E+00 0.32928340E+00
+ 0.32974937E+00 0.33021535E+00 0.33068132E+00 0.33114730E+00 0.33161327E+00
+ 0.33207924E+00 0.33254522E+00 0.33301119E+00 0.33347717E+00 0.33394314E+00
+ 0.33440912E+00 0.33487509E+00 0.33534107E+00 0.33580704E+00 0.33627301E+00
+ 0.33673899E+00 0.33720496E+00 0.33767094E+00 0.33813691E+00 0.33860289E+00
+ 0.33906886E+00 0.33953484E+00 0.34000081E+00 0.34046678E+00 0.34093276E+00
+ 0.34139873E+00 0.34186471E+00 0.34233068E+00 0.34279666E+00 0.34326263E+00
+ 0.34372861E+00 0.34419458E+00 0.34466056E+00 0.34512653E+00 0.34559250E+00
+ 0.34605848E+00 0.34652445E+00 0.34699043E+00 0.34745640E+00 0.34792238E+00
+ 0.34838835E+00 0.34885433E+00 0.34932030E+00 0.34978627E+00 0.35025225E+00
+ 0.35071822E+00 0.35118420E+00 0.35165017E+00 0.35211615E+00 0.35258212E+00
+ 0.35304810E+00 0.35351407E+00 0.35398004E+00 0.35444602E+00 0.35491199E+00
+ 0.35537797E+00 0.35584394E+00 0.35630992E+00 0.35677589E+00 0.35724187E+00
+ 0.35770784E+00 0.35817381E+00 0.35863979E+00 0.35910576E+00 0.35957174E+00
+ 0.36003771E+00 0.36050369E+00 0.36096966E+00 0.36143564E+00 0.36190161E+00
+ 0.36236759E+00 0.36283356E+00 0.36329953E+00 0.36376551E+00 0.36423148E+00
+ 0.36469746E+00 0.36516343E+00 0.36562941E+00 0.36609538E+00 0.36656136E+00
+ 0.36702733E+00 0.36749330E+00 0.36795928E+00 0.36842525E+00 0.36889123E+00
+ 0.36935720E+00 0.36982318E+00 0.37028915E+00 0.37075513E+00 0.37122110E+00
+ 0.37168707E+00 0.37215305E+00 0.37261902E+00 0.37308500E+00 0.37355097E+00
+ 0.37401695E+00 0.37448292E+00 0.37494890E+00 0.37541487E+00 0.37588085E+00
+ 0.37634682E+00 0.37681279E+00 0.37727877E+00 0.37774474E+00 0.37821072E+00
+ 0.37867669E+00 0.37914267E+00 0.37960864E+00 0.38007462E+00 0.38054059E+00
+ 0.38100656E+00 0.38147254E+00 0.38193851E+00 0.38240449E+00 0.38287046E+00
+ 0.38333644E+00 0.38380241E+00 0.38426839E+00 0.38473436E+00 0.38520033E+00
+ 0.38566631E+00 0.38613228E+00 0.38659826E+00 0.38706423E+00 0.38753021E+00
+ 0.38799618E+00 0.38846216E+00 0.38892813E+00 0.38939411E+00 0.38986008E+00
+ 0.39032605E+00 0.39079203E+00 0.39125800E+00 0.39172398E+00 0.39218995E+00
+ 0.39265593E+00 0.39312190E+00 0.39358788E+00 0.39405385E+00 0.39451982E+00
+ 0.39498580E+00 0.39545177E+00 0.39591775E+00 0.39638372E+00 0.39684970E+00
+ 0.39731567E+00 0.39778165E+00 0.39824762E+00 0.39871359E+00 0.39917957E+00
+ 0.39964554E+00 0.40011152E+00 0.40057749E+00 0.40104347E+00 0.40150944E+00
+ 0.40197542E+00 0.40244139E+00 0.40290736E+00 0.40337334E+00 0.40383931E+00
+ 0.40430529E+00 0.40477126E+00 0.40523724E+00 0.40570321E+00 0.40616919E+00
+ 0.40663516E+00 0.40710114E+00 0.40756711E+00 0.40803308E+00 0.40849906E+00
+ 0.40896503E+00 0.40943101E+00 0.40989698E+00 0.41036296E+00 0.41082893E+00
+ 0.41129491E+00 0.41176088E+00 0.41222685E+00 0.41269283E+00 0.41315880E+00
+ 0.41362478E+00 0.41409075E+00 0.41455673E+00 0.41502270E+00 0.41548868E+00
+ 0.41595465E+00 0.41642062E+00 0.41688660E+00 0.41735257E+00 0.41781855E+00
+ 0.41828452E+00 0.41875050E+00 0.41921647E+00 0.41968245E+00 0.42014842E+00
+ 0.42061440E+00 0.42108037E+00 0.42154634E+00 0.42201232E+00 0.42247829E+00
+ 0.42294427E+00 0.42341024E+00 0.42387622E+00 0.42434219E+00 0.42480817E+00
+ 0.42527414E+00 0.42574011E+00 0.42620609E+00 0.42667206E+00 0.42713804E+00
+ 0.42760401E+00 0.42806999E+00 0.42853596E+00 0.42900194E+00 0.42946791E+00
+ 0.42993388E+00 0.43039986E+00 0.43086583E+00 0.43133181E+00 0.43179778E+00
+ 0.43226376E+00 0.43272973E+00 0.43319571E+00 0.43366168E+00 0.43412766E+00
+ 0.43459363E+00 0.43505960E+00 0.43552558E+00 0.43599155E+00 0.43645753E+00
+ 0.43692350E+00 0.43738948E+00 0.43785545E+00 0.43832143E+00 0.43878740E+00
+ 0.43925337E+00 0.43971935E+00 0.44018532E+00 0.44065130E+00 0.44111727E+00
+ 0.44158325E+00 0.44204922E+00 0.44251520E+00 0.44298117E+00 0.44344714E+00
+ 0.44391312E+00 0.44437909E+00 0.44484507E+00 0.44531104E+00 0.44577702E+00
+ 0.44624299E+00 0.44670897E+00 0.44717494E+00 0.44764091E+00 0.44810689E+00
+ 0.44857286E+00 0.44903884E+00 0.44950481E+00 0.44997079E+00 0.45043676E+00
+ 0.45090274E+00 0.45136871E+00 0.45183469E+00 0.45230066E+00 0.45276663E+00
+ 0.45323261E+00 0.45369858E+00 0.45416456E+00 0.45463053E+00 0.45509651E+00
+ 0.45556248E+00 0.45602846E+00 0.45649443E+00 0.45696040E+00 0.45742638E+00
+ 0.45789235E+00 0.45835833E+00 0.45882430E+00 0.45929028E+00 0.45975625E+00
+ 0.46022223E+00 0.46068820E+00 0.46115417E+00 0.46162015E+00 0.46208612E+00
+ 0.46255210E+00 0.46301807E+00 0.46348405E+00 0.46395002E+00 0.46441600E+00
+ 0.46488197E+00 0.46534795E+00 0.46581392E+00 0.46627989E+00 0.46674587E+00
+ 0.46721184E+00 0.46767782E+00 0.46814379E+00 0.46860977E+00 0.46907574E+00
+ 0.46954172E+00 0.47000769E+00 0.47047366E+00 0.47093964E+00 0.47140561E+00
+ 0.47187159E+00 0.47233756E+00 0.47280354E+00 0.47326951E+00 0.47373549E+00
+ 0.47420146E+00 0.47466743E+00 0.47513341E+00 0.47559938E+00 0.47606536E+00
+ 0.47653133E+00 0.47699731E+00 0.47746328E+00 0.47792926E+00 0.47839523E+00
+ 0.47886121E+00 0.47932718E+00 0.47979315E+00 0.48025913E+00 0.48072510E+00
+ 0.48119108E+00 0.48165705E+00 0.48212303E+00 0.48258900E+00 0.48305498E+00
+ 0.48352095E+00 0.48398692E+00 0.48445290E+00 0.48491887E+00 0.48538485E+00
+ 0.48585082E+00 0.48631680E+00 0.48678277E+00 0.48724875E+00 0.48771472E+00
+ 0.48818069E+00 0.48864667E+00 0.48911264E+00 0.48957862E+00 0.49004459E+00
+ 0.49051057E+00 0.49097654E+00 0.49144252E+00 0.49190849E+00 0.49237446E+00
+ 0.49284044E+00 0.49330641E+00 0.49377239E+00 0.49423836E+00 0.49470434E+00
+ 0.49517031E+00 0.49563629E+00 0.49610226E+00 0.49656824E+00 0.49703421E+00
+ 0.49750018E+00 0.49796616E+00 0.49843213E+00 0.49889811E+00 0.49936408E+00
+ 0.49983006E+00 0.50029603E+00 0.50076201E+00 0.50122798E+00 0.50169395E+00
+ 0.50215993E+00 0.50262590E+00 0.50309188E+00 0.50355785E+00 0.50402383E+00
+ 0.50448980E+00 0.50495578E+00 0.50542175E+00 0.50588772E+00 0.50635370E+00
+ 0.50681967E+00 0.50728565E+00 0.50775162E+00 0.50821760E+00 0.50868357E+00
+ 0.50914955E+00 0.50961552E+00 0.51008150E+00 0.51054747E+00 0.51101344E+00
+ 0.51147942E+00 0.51194539E+00 0.51241137E+00 0.51287734E+00 0.51334332E+00
+ 0.51380929E+00 0.51427527E+00 0.51474124E+00 0.51520721E+00 0.51567319E+00
+ 0.51613916E+00 0.51660514E+00 0.51707111E+00 0.51753709E+00 0.51800306E+00
+ 0.51846904E+00 0.51893501E+00 0.51940098E+00 0.51986696E+00 0.52033293E+00
+ 0.52079891E+00 0.52126488E+00 0.52173086E+00 0.52219683E+00 0.52266281E+00
+ 0.52312878E+00 0.52359476E+00 0.52406073E+00 0.52452670E+00 0.52499268E+00
+ 0.52545865E+00 0.52592463E+00 0.52639060E+00 0.52685658E+00 0.52732255E+00
+ 0.52778853E+00 0.52825450E+00 0.52872047E+00 0.52918645E+00 0.52965242E+00
+ 0.53011840E+00 0.53058437E+00 0.53105035E+00 0.53151632E+00 0.53198230E+00
+ 0.53244827E+00 0.53291424E+00 0.53338022E+00 0.53384619E+00 0.53431217E+00
+ 0.53477814E+00 0.53524412E+00 0.53571009E+00 0.53617607E+00 0.53664204E+00
+ 0.53710801E+00 0.53757399E+00 0.53803996E+00 0.53850594E+00 0.53897191E+00
+ 0.53943789E+00 0.53990386E+00 0.54036984E+00 0.54083581E+00 0.54130179E+00
+ 0.54176776E+00 0.54223373E+00 0.54269971E+00 0.54316568E+00 0.54363166E+00
+ 0.54409763E+00 0.54456361E+00 0.54502958E+00 0.54549556E+00 0.54596153E+00
+ 0.54642750E+00 0.54689348E+00 0.54735945E+00 0.54782543E+00 0.54829140E+00
+ 0.54875738E+00 0.54922335E+00 0.54968933E+00 0.55015530E+00 0.55062127E+00
+ 0.55108725E+00 0.55155322E+00 0.55201920E+00 0.55248517E+00 0.55295115E+00
+ 0.55341712E+00 0.55388310E+00 0.55434907E+00 0.55481505E+00 0.55528102E+00
+ 0.55574699E+00 0.55621297E+00 0.55667894E+00 0.55714492E+00 0.55761089E+00
+ 0.55807687E+00 0.55854284E+00 0.55900882E+00 0.55947479E+00 0.55994076E+00
+ 0.56040674E+00 0.56087271E+00 0.56133869E+00 0.56180466E+00 0.56227064E+00
+ 0.56273661E+00 0.56320259E+00 0.56366856E+00 0.56413453E+00 0.56460051E+00
+ 0.56506648E+00 0.56553246E+00 0.56599843E+00 0.56646441E+00 0.56693038E+00
+ 0.56739636E+00 0.56786233E+00 0.56832830E+00 0.56879428E+00 0.56926025E+00
+ 0.56972623E+00 0.57019220E+00 0.57065818E+00 0.57112415E+00 0.57159013E+00
+ 0.57205610E+00 0.57252208E+00 0.57298805E+00 0.57345402E+00 0.57392000E+00
+ 0.57438597E+00 0.57485195E+00 0.57531792E+00 0.57578390E+00 0.57624987E+00
+ 0.57671585E+00 0.57718182E+00 0.57764779E+00 0.57811377E+00 0.57857974E+00
+ 0.57904572E+00 0.57951169E+00 0.57997767E+00 0.58044364E+00 0.58090962E+00
+ 0.58137559E+00 0.58184156E+00 0.58230754E+00 0.58277351E+00 0.58323949E+00
+ 0.58370546E+00 0.58417144E+00 0.58463741E+00 0.58510339E+00 0.58556936E+00
+ 0.58603534E+00 0.58650131E+00 0.58696728E+00 0.58743326E+00 0.58789923E+00
+ 0.58836521E+00 0.58883118E+00 0.58929716E+00 0.58976313E+00 0.59022911E+00
+ 0.59069508E+00 0.59116105E+00 0.59162703E+00 0.59209300E+00 0.59255898E+00
+ 0.59302495E+00 0.59349093E+00 0.59395690E+00 0.59442288E+00 0.59488885E+00
+ 0.59535482E+00 0.59582080E+00 0.59628677E+00 0.59675275E+00 0.59721872E+00
+ 0.59768470E+00 0.59815067E+00 0.59861665E+00 0.59908262E+00 0.59954860E+00
+ 0.60001457E+00 0.60048054E+00 0.60094652E+00 0.60141249E+00 0.60187847E+00
+ 0.60234444E+00 0.60281042E+00 0.60327639E+00 0.60374237E+00 0.60420834E+00
+ 0.60467431E+00 0.60514029E+00 0.60560626E+00 0.60607224E+00 0.60653821E+00
+ 0.60700419E+00 0.60747016E+00 0.60793614E+00 0.60840211E+00 0.60886808E+00
+ 0.60933406E+00 0.60980003E+00 0.61026601E+00 0.61073198E+00 0.61119796E+00
+ 0.61166393E+00 0.61212991E+00 0.61259588E+00 0.61306185E+00 0.61352783E+00
+ 0.61399380E+00 0.61445978E+00 0.61492575E+00 0.61539173E+00 0.61585770E+00
+ 0.61632368E+00 0.61678965E+00 0.61725563E+00 0.61772160E+00 0.61818757E+00
+ 0.61865355E+00 0.61911952E+00 0.61958550E+00 0.62005147E+00 0.62051745E+00
+ 0.62098342E+00 0.62144940E+00 0.62191537E+00 0.62238134E+00 0.62284732E+00
+ 0.62331329E+00 0.62377927E+00 0.62424524E+00 0.62471122E+00 0.62517719E+00
+ 0.62564317E+00 0.62610914E+00 0.62657511E+00 0.62704109E+00 0.62750706E+00
+ 0.62797304E+00 0.62843901E+00 0.62890499E+00 0.62937096E+00 0.62983694E+00
+ 0.63030291E+00 0.63076889E+00 0.63123486E+00 0.63170083E+00 0.63216681E+00
+ 0.63263278E+00 0.63309876E+00 0.63356473E+00 0.63403071E+00 0.63449668E+00
+ 0.63496266E+00 0.63542863E+00 0.63589460E+00 0.63636058E+00 0.63682655E+00
+ 0.63729253E+00 0.63775850E+00 0.63822448E+00 0.63869045E+00 0.63915643E+00
+ 0.63962240E+00 0.64008837E+00 0.64055435E+00 0.64102032E+00 0.64148630E+00
+ 0.64195227E+00 0.64241825E+00 0.64288422E+00 0.64335020E+00 0.64381617E+00
+ 0.64428214E+00 0.64474812E+00 0.64521409E+00 0.64568007E+00 0.64614604E+00
+ 0.64661202E+00 0.64707799E+00 0.64754397E+00 0.64800994E+00 0.64847592E+00
+ 0.64894189E+00 0.64940786E+00 0.64987384E+00 0.65033981E+00 0.65080579E+00
+ 0.65127176E+00 0.65173774E+00 0.65220371E+00 0.65266969E+00 0.65313566E+00
+ 0.65360163E+00 0.65406761E+00 0.65453358E+00 0.65499956E+00 0.65546553E+00
+ 0.65593151E+00 0.65639748E+00 0.65686346E+00 0.65732943E+00 0.65779540E+00
+ 0.65826138E+00 0.65872735E+00 0.65919333E+00 0.65965930E+00 0.66012528E+00
+ 0.66059125E+00 0.66105723E+00 0.66152320E+00 0.66198918E+00 0.66245515E+00
+ 0.66292112E+00 0.66338710E+00 0.66385307E+00 0.66431905E+00 0.66478502E+00
+ 0.66525100E+00 0.66571697E+00 0.66618295E+00 0.66664892E+00 0.66711489E+00
+ 0.66758087E+00 0.66804684E+00 0.66851282E+00 0.66897879E+00 0.66944477E+00
+ 0.66991074E+00 0.67037672E+00 0.67084269E+00 0.67130866E+00 0.67177464E+00
+ 0.67224061E+00 0.67270659E+00 0.67317256E+00 0.67363854E+00 0.67410451E+00
+ 0.67457049E+00 0.67503646E+00 0.67550244E+00 0.67596841E+00 0.67643438E+00
+ 0.67690036E+00 0.67736633E+00 0.67783231E+00 0.67829828E+00 0.67876426E+00
+ 0.67923023E+00 0.67969621E+00 0.68016218E+00 0.68062815E+00 0.68109413E+00
+ 0.68156010E+00 0.68202608E+00 0.68249205E+00 0.68295803E+00 0.68342400E+00
+ 0.68388998E+00 0.68435595E+00 0.68482192E+00 0.68528790E+00 0.68575387E+00
+ 0.68621985E+00 0.68668582E+00 0.68715180E+00 0.68761777E+00 0.68808375E+00
+ 0.68854972E+00 0.68901569E+00 0.68948167E+00 0.68994764E+00 0.69041362E+00
+ 0.69087959E+00 0.69134557E+00 0.69181154E+00 0.69227752E+00 0.69274349E+00
+ 0.69320947E+00 0.69367544E+00 0.69414141E+00 0.69460739E+00 0.69507336E+00
+ 0.69553934E+00 0.69600531E+00 0.69647129E+00 0.69693726E+00 0.69740324E+00
+ 0.69786921E+00 0.69833518E+00 0.69880116E+00 0.69926713E+00 0.69973311E+00
+ 0.70019908E+00 0.70066506E+00 0.70113103E+00 0.70159701E+00 0.70206298E+00
+ 0.70252895E+00 0.70299493E+00 0.70346090E+00 0.70392688E+00 0.70439285E+00
+ 0.70485883E+00 0.70532480E+00 0.70579078E+00 0.70625675E+00 0.70672272E+00
+ 0.70718870E+00 0.70765467E+00 0.70812065E+00 0.70858662E+00 0.70905260E+00
+ 0.70951857E+00 0.70998455E+00 0.71045052E+00 0.71091650E+00 0.71138247E+00
+ 0.71184844E+00 0.71231442E+00 0.71278039E+00 0.71324637E+00 0.71371234E+00
+ 0.71417832E+00 0.71464429E+00 0.71511027E+00 0.71557624E+00 0.71604221E+00
+ 0.71650819E+00 0.71697416E+00 0.71744014E+00 0.71790611E+00 0.71837209E+00
+ 0.71883806E+00 0.71930404E+00 0.71977001E+00 0.72023598E+00 0.72070196E+00
+ 0.72116793E+00 0.72163391E+00 0.72209988E+00 0.72256586E+00 0.72303183E+00
+ 0.72349781E+00 0.72396378E+00 0.72442976E+00 0.72489573E+00 0.72536170E+00
+ 0.72582768E+00 0.72629365E+00 0.72675963E+00 0.72722560E+00 0.72769158E+00
+ 0.72815755E+00 0.72862353E+00 0.72908950E+00 0.72955547E+00 0.73002145E+00
+ 0.73048742E+00 0.73095340E+00 0.73141937E+00 0.73188535E+00 0.73235132E+00
+ 0.73281730E+00 0.73328327E+00 0.73374924E+00 0.73421522E+00 0.73468119E+00
+ 0.73514717E+00 0.73561314E+00 0.73607912E+00 0.73654509E+00 0.73701107E+00
+ 0.73747704E+00 0.73794301E+00 0.73840899E+00 0.73887496E+00 0.73934094E+00
+ 0.73980691E+00 0.74027289E+00 0.74073886E+00 0.74120484E+00 0.74167081E+00
+ 0.74213679E+00 0.74260276E+00 0.74306873E+00 0.74353471E+00 0.74400068E+00
+ 0.74446666E+00 0.74493263E+00 0.74539861E+00 0.74586458E+00 0.74633056E+00
+ 0.74679653E+00 0.74726250E+00 0.74772848E+00 0.74819445E+00 0.74866043E+00
+ 0.74912640E+00 0.74959238E+00 0.75005835E+00 0.75052433E+00 0.75099030E+00
+ 0.75145627E+00 0.75192225E+00 0.75238822E+00 0.75285420E+00 0.75332017E+00
+ 0.75378615E+00 0.75425212E+00 0.75471810E+00 0.75518407E+00 0.75565004E+00
+ 0.75611602E+00 0.75658199E+00 0.75704797E+00 0.75751394E+00 0.75797992E+00
+ 0.75844589E+00 0.75891187E+00 0.75937784E+00 0.75984382E+00 0.76030979E+00
+ 0.76077576E+00 0.76124174E+00 0.76170771E+00 0.76217369E+00 0.76263966E+00
+ 0.76310564E+00 0.76357161E+00 0.76403759E+00 0.76450356E+00 0.76496953E+00
+ 0.76543551E+00 0.76590148E+00 0.76636746E+00 0.76683343E+00 0.76729941E+00
+ 0.76776538E+00 0.76823136E+00 0.76869733E+00 0.76916330E+00 0.76962928E+00
+ 0.77009525E+00 0.77056123E+00 0.77102720E+00 0.77149318E+00 0.77195915E+00
+ 0.77242513E+00 0.77289110E+00 0.77335707E+00 0.77382305E+00 0.77428902E+00
+ 0.77475500E+00 0.77522097E+00 0.77568695E+00 0.77615292E+00 0.77661890E+00
+ 0.77708487E+00 0.77755085E+00 0.77801682E+00 0.77848279E+00 0.77894877E+00
+ 0.77941474E+00 0.77988072E+00 0.78034669E+00 0.78081267E+00 0.78127864E+00
+ 0.78174462E+00 0.78221059E+00 0.78267656E+00 0.78314254E+00 0.78360851E+00
+ 0.78407449E+00 0.78454046E+00 0.78500644E+00 0.78547241E+00 0.78593839E+00
+ 0.78640436E+00 0.78687033E+00 0.78733631E+00 0.78780228E+00 0.78826826E+00
+ 0.78873423E+00 0.78920021E+00 0.78966618E+00 0.79013216E+00 0.79059813E+00
+ 0.79106410E+00 0.79153008E+00 0.79199605E+00 0.79246203E+00 0.79292800E+00
+ 0.79339398E+00 0.79385995E+00 0.79432593E+00 0.79479190E+00 0.79525787E+00
+ 0.79572385E+00 0.79618982E+00 0.79665580E+00 0.79712177E+00 0.79758775E+00
+ 0.79805372E+00 0.79851970E+00 0.79898567E+00 0.79945165E+00 0.79991762E+00
+ 0.80038359E+00 0.80084957E+00 0.80131554E+00 0.80178152E+00 0.80224749E+00
+ 0.80271347E+00 0.80317944E+00 0.80364542E+00 0.80411139E+00 0.80457736E+00
+ 0.80504334E+00 0.80550931E+00 0.80597529E+00 0.80644126E+00 0.80690724E+00
+ 0.80737321E+00 0.80783919E+00 0.80830516E+00 0.80877113E+00 0.80923711E+00
+ 0.80970308E+00 0.81016906E+00 0.81063503E+00 0.81110101E+00 0.81156698E+00
+ 0.81203296E+00 0.81249893E+00 0.81296490E+00 0.81343088E+00 0.81389685E+00
+ 0.81436283E+00 0.81482880E+00 0.81529478E+00 0.81576075E+00 0.81622673E+00
+ 0.81669270E+00 0.81715867E+00 0.81762465E+00 0.81809062E+00 0.81855660E+00
+ 0.81902257E+00 0.81948855E+00 0.81995452E+00 0.82042050E+00 0.82088647E+00
+ 0.82135244E+00 0.82181842E+00 0.82228439E+00 0.82275037E+00 0.82321634E+00
+ 0.82368232E+00 0.82414829E+00 0.82461427E+00 0.82508024E+00 0.82554621E+00
+ 0.82601219E+00 0.82647816E+00 0.82694414E+00 0.82741011E+00 0.82787609E+00
+ 0.82834206E+00 0.82880804E+00 0.82927401E+00 0.82973998E+00 0.83020596E+00
+ 0.83067193E+00 0.83113791E+00 0.83160388E+00 0.83206986E+00 0.83253583E+00
+ 0.83300181E+00 0.83346778E+00 0.83393375E+00 0.83439973E+00 0.83486570E+00
+ 0.83533168E+00 0.83579765E+00 0.83626363E+00 0.83672960E+00 0.83719557E+00
+ 0.83766155E+00 0.83812752E+00 0.83859350E+00 0.83905947E+00 0.83952545E+00
+ 0.83999142E+00 0.84045740E+00 0.84092337E+00 0.84138934E+00 0.84185532E+00
+ 0.84232129E+00 0.84278727E+00 0.84325324E+00 0.84371922E+00 0.84418519E+00
+ 0.84465116E+00 0.84511714E+00 0.84558311E+00 0.84604909E+00 0.84651506E+00
+ 0.84698104E+00 0.84744701E+00 0.84791298E+00 0.84837896E+00 0.84884493E+00
+ 0.84931091E+00 0.84977688E+00 0.85024286E+00 0.85070883E+00 0.85117480E+00
+ 0.85164078E+00 0.85210675E+00 0.85257273E+00 0.85303870E+00 0.85350467E+00
+ 0.85397065E+00 0.85443662E+00 0.85490259E+00 0.85536857E+00 0.85583454E+00
+ 0.85630052E+00 0.85676649E+00 0.85723246E+00 0.85769843E+00 0.85816441E+00
+ 0.85863038E+00 0.85909635E+00 0.85956232E+00 0.86002829E+00 0.86049426E+00
+ 0.86096023E+00 0.86142619E+00 0.86189215E+00 0.86235810E+00 0.86282402E+00
+ 0.86328984E+00 0.86372164E+00 0.86372532E+00 0.86372546E+00 0.86372550E+00
+ 0.86372553E+00 0.86372554E+00 0.86372555E+00 0.86372556E+00 0.86372556E+00
+ 0.86372557E+00 0.86372557E+00 0.86372557E+00 0.86372558E+00 0.86372558E+00
+ 0.86372558E+00 0.86372558E+00 0.86372558E+00 0.86372558E+00 0.86372558E+00
+ 0.86372558E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00
+ 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00
+ 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00
+ 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00
+ 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00
+ 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00
+ 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00
+ 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00 0.86372559E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00 0.86372560E+00
+ 0.10909710E+00 0.10944794E+00 0.10979877E+00 0.11014961E+00 0.11050045E+00
+ 0.11085128E+00 0.11120212E+00 0.11155295E+00 0.11190379E+00 0.11225463E+00
+ 0.11260546E+00 0.11295630E+00 0.11330713E+00 0.11365797E+00 0.11400880E+00
+ 0.11435964E+00 0.11471048E+00 0.11506131E+00 0.11541215E+00 0.11576298E+00
+ 0.11611382E+00 0.11646466E+00 0.11681549E+00 0.11716633E+00 0.11751716E+00
+ 0.11786800E+00 0.11821883E+00 0.11856967E+00 0.11892051E+00 0.11927134E+00
+ 0.11962218E+00 0.11997301E+00 0.12032385E+00 0.12067469E+00 0.12102552E+00
+ 0.12137636E+00 0.12172719E+00 0.12207803E+00 0.12242886E+00 0.12277970E+00
+ 0.12313054E+00 0.12348137E+00 0.12383221E+00 0.12418304E+00 0.12453388E+00
+ 0.12488472E+00 0.12523555E+00 0.12558639E+00 0.12593722E+00 0.12628806E+00
+ 0.12663889E+00 0.12698973E+00 0.12734057E+00 0.12769140E+00 0.12804224E+00
+ 0.12839307E+00 0.12874391E+00 0.12909475E+00 0.12944558E+00 0.12979642E+00
+ 0.13014725E+00 0.13049809E+00 0.13084893E+00 0.13119976E+00 0.13155060E+00
+ 0.13190143E+00 0.13225227E+00 0.13260310E+00 0.13295394E+00 0.13330478E+00
+ 0.13365561E+00 0.13400645E+00 0.13435728E+00 0.13470812E+00 0.13505896E+00
+ 0.13540979E+00 0.13576063E+00 0.13611146E+00 0.13646230E+00 0.13681313E+00
+ 0.13716397E+00 0.13751481E+00 0.13786564E+00 0.13821648E+00 0.13856731E+00
+ 0.13891815E+00 0.13926899E+00 0.13961982E+00 0.13997066E+00 0.14032149E+00
+ 0.14067233E+00 0.14102316E+00 0.14137400E+00 0.14172484E+00 0.14207567E+00
+ 0.14242651E+00 0.14277734E+00 0.14312818E+00 0.14347902E+00 0.14382985E+00
+ 0.14418069E+00 0.14453152E+00 0.14488236E+00 0.14523319E+00 0.14558403E+00
+ 0.14593487E+00 0.14628570E+00 0.14663654E+00 0.14698737E+00 0.14733821E+00
+ 0.14768905E+00 0.14803988E+00 0.14839072E+00 0.14874155E+00 0.14909239E+00
+ 0.14944322E+00 0.14979406E+00 0.15014490E+00 0.15049573E+00 0.15084657E+00
+ 0.15119740E+00 0.15154824E+00 0.15189908E+00 0.15224991E+00 0.15260075E+00
+ 0.15295158E+00 0.15330242E+00 0.15365325E+00 0.15400409E+00 0.15435493E+00
+ 0.15470576E+00 0.15505660E+00 0.15540743E+00 0.15575827E+00 0.15610911E+00
+ 0.15645994E+00 0.15681078E+00 0.15716161E+00 0.15751245E+00 0.15786328E+00
+ 0.15821412E+00 0.15856496E+00 0.15891579E+00 0.15926663E+00 0.15961746E+00
+ 0.15996830E+00 0.16031914E+00 0.16066997E+00 0.16102081E+00 0.16137164E+00
+ 0.16172248E+00 0.16207331E+00 0.16242415E+00 0.16277499E+00 0.16312582E+00
+ 0.16347666E+00 0.16382749E+00 0.16417833E+00 0.16452917E+00 0.16488000E+00
+ 0.16523084E+00 0.16558167E+00 0.16593251E+00 0.16628334E+00 0.16663418E+00
+ 0.16698502E+00 0.16733585E+00 0.16768669E+00 0.16803752E+00 0.16838836E+00
+ 0.16873920E+00 0.16909003E+00 0.16944087E+00 0.16979170E+00 0.17014254E+00
+ 0.17049337E+00 0.17084421E+00 0.17119505E+00 0.17154588E+00 0.17189672E+00
+ 0.17224755E+00 0.17259839E+00 0.17294923E+00 0.17330006E+00 0.17365090E+00
+ 0.17400173E+00 0.17435257E+00 0.17470340E+00 0.17505424E+00 0.17540508E+00
+ 0.17575591E+00 0.17610675E+00 0.17645758E+00 0.17680842E+00 0.17715926E+00
+ 0.17751009E+00 0.17786093E+00 0.17821176E+00 0.17856260E+00 0.17891343E+00
+ 0.17926427E+00 0.17961511E+00 0.17996594E+00 0.18031678E+00 0.18066761E+00
+ 0.18101845E+00 0.18136929E+00 0.18172012E+00 0.18207096E+00 0.18242179E+00
+ 0.18277263E+00 0.18312346E+00 0.18347430E+00 0.18382514E+00 0.18417597E+00
+ 0.18452681E+00 0.18487764E+00 0.18522848E+00 0.18557932E+00 0.18593015E+00
+ 0.18628099E+00 0.18663182E+00 0.18698266E+00 0.18733350E+00 0.18768433E+00
+ 0.18803517E+00 0.18838600E+00 0.18873684E+00 0.18908767E+00 0.18943851E+00
+ 0.18978935E+00 0.19014018E+00 0.19049102E+00 0.19084185E+00 0.19119269E+00
+ 0.19154353E+00 0.19189436E+00 0.19224520E+00 0.19259603E+00 0.19294687E+00
+ 0.19329770E+00 0.19364854E+00 0.19399938E+00 0.19435021E+00 0.19470105E+00
+ 0.19505188E+00 0.19540272E+00 0.19575356E+00 0.19610439E+00 0.19645523E+00
+ 0.19680606E+00 0.19715690E+00 0.19750773E+00 0.19785857E+00 0.19820941E+00
+ 0.19856024E+00 0.19891108E+00 0.19926191E+00 0.19961275E+00 0.19996359E+00
+ 0.20031442E+00 0.20066526E+00 0.20101609E+00 0.20136693E+00 0.20171776E+00
+ 0.20206860E+00 0.20241944E+00 0.20277027E+00 0.20312111E+00 0.20347194E+00
+ 0.20382278E+00 0.20417362E+00 0.20452445E+00 0.20487529E+00 0.20522612E+00
+ 0.20557696E+00 0.20592779E+00 0.20627863E+00 0.20662947E+00 0.20698030E+00
+ 0.20733114E+00 0.20768197E+00 0.20803281E+00 0.20838365E+00 0.20873448E+00
+ 0.20908532E+00 0.20943615E+00 0.20978699E+00 0.21013782E+00 0.21048866E+00
+ 0.21083950E+00 0.21119033E+00 0.21154117E+00 0.21189200E+00 0.21224284E+00
+ 0.21259368E+00 0.21294451E+00 0.21329535E+00 0.21364618E+00 0.21399702E+00
+ 0.21434785E+00 0.21469869E+00 0.21504953E+00 0.21540036E+00 0.21575120E+00
+ 0.21610203E+00 0.21645287E+00 0.21680371E+00 0.21715454E+00 0.21750538E+00
+ 0.21785621E+00 0.21820705E+00 0.21855788E+00 0.21890872E+00 0.21925956E+00
+ 0.21961039E+00 0.21996123E+00 0.22031206E+00 0.22066290E+00 0.22101374E+00
+ 0.22136457E+00 0.22171541E+00 0.22206624E+00 0.22241708E+00 0.22276791E+00
+ 0.22311875E+00 0.22346959E+00 0.22382042E+00 0.22417126E+00 0.22452209E+00
+ 0.22487293E+00 0.22522377E+00 0.22557460E+00 0.22592544E+00 0.22627627E+00
+ 0.22662711E+00 0.22697794E+00 0.22732878E+00 0.22767962E+00 0.22803045E+00
+ 0.22838129E+00 0.22873212E+00 0.22908296E+00 0.22943380E+00 0.22978463E+00
+ 0.23013547E+00 0.23048630E+00 0.23083714E+00 0.23118797E+00 0.23153881E+00
+ 0.23188965E+00 0.23224048E+00 0.23259132E+00 0.23294215E+00 0.23329299E+00
+ 0.23364383E+00 0.23399466E+00 0.23434550E+00 0.23469633E+00 0.23504717E+00
+ 0.23539800E+00 0.23574884E+00 0.23609968E+00 0.23645051E+00 0.23680135E+00
+ 0.23715218E+00 0.23750302E+00 0.23785386E+00 0.23820469E+00 0.23855553E+00
+ 0.23890636E+00 0.23925720E+00 0.23960803E+00 0.23995887E+00 0.24030971E+00
+ 0.24066054E+00 0.24101138E+00 0.24136221E+00 0.24171305E+00 0.24206389E+00
+ 0.24241472E+00 0.24276556E+00 0.24311639E+00 0.24346723E+00 0.24381806E+00
+ 0.24416890E+00 0.24451974E+00 0.24487057E+00 0.24522141E+00 0.24557224E+00
+ 0.24592308E+00 0.24627392E+00 0.24662475E+00 0.24697559E+00 0.24732642E+00
+ 0.24767726E+00 0.24802810E+00 0.24837893E+00 0.24872977E+00 0.24908060E+00
+ 0.24943144E+00 0.24978227E+00 0.25013311E+00 0.25048395E+00 0.25083478E+00
+ 0.25118562E+00 0.25153645E+00 0.25188729E+00 0.25223813E+00 0.25258896E+00
+ 0.25293980E+00 0.25329063E+00 0.25364147E+00 0.25399230E+00 0.25434314E+00
+ 0.25469398E+00 0.25504481E+00 0.25539565E+00 0.25574648E+00 0.25609732E+00
+ 0.25644816E+00 0.25679899E+00 0.25714983E+00 0.25750066E+00 0.25785150E+00
+ 0.25820233E+00 0.25855317E+00 0.25890401E+00 0.25925484E+00 0.25960568E+00
+ 0.25995651E+00 0.26030735E+00 0.26065819E+00 0.26100902E+00 0.26135986E+00
+ 0.26171069E+00 0.26206153E+00 0.26241236E+00 0.26276320E+00 0.26311404E+00
+ 0.26346487E+00 0.26381571E+00 0.26416654E+00 0.26451738E+00 0.26486822E+00
+ 0.26521905E+00 0.26556989E+00 0.26592072E+00 0.26627156E+00 0.26662239E+00
+ 0.26697323E+00 0.26732407E+00 0.26767490E+00 0.26802574E+00 0.26837657E+00
+ 0.26872741E+00 0.26907825E+00 0.26942908E+00 0.26977992E+00 0.27013075E+00
+ 0.27048159E+00 0.27083242E+00 0.27118326E+00 0.27153410E+00 0.27188493E+00
+ 0.27223577E+00 0.27258660E+00 0.27293744E+00 0.27328828E+00 0.27363911E+00
+ 0.27398995E+00 0.27434078E+00 0.27469162E+00 0.27504245E+00 0.27539329E+00
+ 0.27574413E+00 0.27609496E+00 0.27644580E+00 0.27679663E+00 0.27714747E+00
+ 0.27749831E+00 0.27784914E+00 0.27819998E+00 0.27855081E+00 0.27890165E+00
+ 0.27925248E+00 0.27960332E+00 0.27995416E+00 0.28030499E+00 0.28065583E+00
+ 0.28100666E+00 0.28135750E+00 0.28170834E+00 0.28205917E+00 0.28241001E+00
+ 0.28276084E+00 0.28311168E+00 0.28346251E+00 0.28381335E+00 0.28416419E+00
+ 0.28451502E+00 0.28486586E+00 0.28521669E+00 0.28556753E+00 0.28591837E+00
+ 0.28626920E+00 0.28662004E+00 0.28697087E+00 0.28732171E+00 0.28767254E+00
+ 0.28802338E+00 0.28837422E+00 0.28872505E+00 0.28907589E+00 0.28942672E+00
+ 0.28977756E+00 0.29012840E+00 0.29047923E+00 0.29083007E+00 0.29118090E+00
+ 0.29153174E+00 0.29188257E+00 0.29223341E+00 0.29258425E+00 0.29293508E+00
+ 0.29328592E+00 0.29363675E+00 0.29398759E+00 0.29433843E+00 0.29468926E+00
+ 0.29504010E+00 0.29539093E+00 0.29574177E+00 0.29609260E+00 0.29644344E+00
+ 0.29679428E+00 0.29714511E+00 0.29749595E+00 0.29784678E+00 0.29819762E+00
+ 0.29854846E+00 0.29889929E+00 0.29925013E+00 0.29960096E+00 0.29995180E+00
+ 0.30030263E+00 0.30065347E+00 0.30100431E+00 0.30135514E+00 0.30170598E+00
+ 0.30205681E+00 0.30240765E+00 0.30275849E+00 0.30310932E+00 0.30346016E+00
+ 0.30381099E+00 0.30416183E+00 0.30451267E+00 0.30486350E+00 0.30521434E+00
+ 0.30556517E+00 0.30591601E+00 0.30626684E+00 0.30661768E+00 0.30696852E+00
+ 0.30731935E+00 0.30767019E+00 0.30802102E+00 0.30837186E+00 0.30872270E+00
+ 0.30907353E+00 0.30942437E+00 0.30977520E+00 0.31012604E+00 0.31047687E+00
+ 0.31082771E+00 0.31117855E+00 0.31152938E+00 0.31188022E+00 0.31223105E+00
+ 0.31258189E+00 0.31293273E+00 0.31328356E+00 0.31363440E+00 0.31398523E+00
+ 0.31433607E+00 0.31468690E+00 0.31503774E+00 0.31538858E+00 0.31573941E+00
+ 0.31609025E+00 0.31644108E+00 0.31679192E+00 0.31714276E+00 0.31749359E+00
+ 0.31784443E+00 0.31819526E+00 0.31854610E+00 0.31889693E+00 0.31924777E+00
+ 0.31959861E+00 0.31994944E+00 0.32030028E+00 0.32065111E+00 0.32100195E+00
+ 0.32135279E+00 0.32170362E+00 0.32205446E+00 0.32240529E+00 0.32275613E+00
+ 0.32310696E+00 0.32345780E+00 0.32380864E+00 0.32415947E+00 0.32451031E+00
+ 0.32486114E+00 0.32521198E+00 0.32556282E+00 0.32591365E+00 0.32626449E+00
+ 0.32661532E+00 0.32696616E+00 0.32731699E+00 0.32766783E+00 0.32801867E+00
+ 0.32836950E+00 0.32872034E+00 0.32907117E+00 0.32942201E+00 0.32977285E+00
+ 0.33012368E+00 0.33047452E+00 0.33082535E+00 0.33117619E+00 0.33152702E+00
+ 0.33187786E+00 0.33222870E+00 0.33257953E+00 0.33293037E+00 0.33328120E+00
+ 0.33363204E+00 0.33398288E+00 0.33433371E+00 0.33468455E+00 0.33503538E+00
+ 0.33538622E+00 0.33573705E+00 0.33608789E+00 0.33643873E+00 0.33678956E+00
+ 0.33714040E+00 0.33749123E+00 0.33784207E+00 0.33819291E+00 0.33854374E+00
+ 0.33889458E+00 0.33924541E+00 0.33959625E+00 0.33994708E+00 0.34029792E+00
+ 0.34064876E+00 0.34099959E+00 0.34135043E+00 0.34170126E+00 0.34205210E+00
+ 0.34240294E+00 0.34275377E+00 0.34310461E+00 0.34345544E+00 0.34380628E+00
+ 0.34415711E+00 0.34450795E+00 0.34485879E+00 0.34520962E+00 0.34556046E+00
+ 0.34591129E+00 0.34626213E+00 0.34661297E+00 0.34696380E+00 0.34731464E+00
+ 0.34766547E+00 0.34801631E+00 0.34836714E+00 0.34871798E+00 0.34906882E+00
+ 0.34941965E+00 0.34977049E+00 0.35012132E+00 0.35047216E+00 0.35082300E+00
+ 0.35117383E+00 0.35152467E+00 0.35187550E+00 0.35222634E+00 0.35257717E+00
+ 0.35292801E+00 0.35327885E+00 0.35362968E+00 0.35398052E+00 0.35433135E+00
+ 0.35468219E+00 0.35503303E+00 0.35538386E+00 0.35573470E+00 0.35608553E+00
+ 0.35643637E+00 0.35678720E+00 0.35713804E+00 0.35748888E+00 0.35783971E+00
+ 0.35819055E+00 0.35854138E+00 0.35889222E+00 0.35924306E+00 0.35959389E+00
+ 0.35994473E+00 0.36029556E+00 0.36064640E+00 0.36099723E+00 0.36134807E+00
+ 0.36169891E+00 0.36204974E+00 0.36240058E+00 0.36275141E+00 0.36310225E+00
+ 0.36345309E+00 0.36380392E+00 0.36415476E+00 0.36450559E+00 0.36485643E+00
+ 0.36520726E+00 0.36555810E+00 0.36590894E+00 0.36625977E+00 0.36661061E+00
+ 0.36696144E+00 0.36731228E+00 0.36766312E+00 0.36801395E+00 0.36836479E+00
+ 0.36871562E+00 0.36906646E+00 0.36941730E+00 0.36976813E+00 0.37011897E+00
+ 0.37046980E+00 0.37082064E+00 0.37117147E+00 0.37152231E+00 0.37187315E+00
+ 0.37222398E+00 0.37257482E+00 0.37292565E+00 0.37327649E+00 0.37362733E+00
+ 0.37397816E+00 0.37432900E+00 0.37467983E+00 0.37503067E+00 0.37538150E+00
+ 0.37573234E+00 0.37608318E+00 0.37643401E+00 0.37678485E+00 0.37713568E+00
+ 0.37748652E+00 0.37783736E+00 0.37818819E+00 0.37853903E+00 0.37888986E+00
+ 0.37924070E+00 0.37959153E+00 0.37994237E+00 0.38029321E+00 0.38064404E+00
+ 0.38099488E+00 0.38134571E+00 0.38169655E+00 0.38204739E+00 0.38239822E+00
+ 0.38274906E+00 0.38309989E+00 0.38345073E+00 0.38380156E+00 0.38415240E+00
+ 0.38450324E+00 0.38485407E+00 0.38520491E+00 0.38555574E+00 0.38590658E+00
+ 0.38625742E+00 0.38660825E+00 0.38695909E+00 0.38730992E+00 0.38766076E+00
+ 0.38801159E+00 0.38836243E+00 0.38871327E+00 0.38906410E+00 0.38941494E+00
+ 0.38976577E+00 0.39011661E+00 0.39046745E+00 0.39081828E+00 0.39116912E+00
+ 0.39151995E+00 0.39187079E+00 0.39222162E+00 0.39257246E+00 0.39292330E+00
+ 0.39327413E+00 0.39362497E+00 0.39397580E+00 0.39432664E+00 0.39467748E+00
+ 0.39502831E+00 0.39537915E+00 0.39572998E+00 0.39608082E+00 0.39643165E+00
+ 0.39678249E+00 0.39713333E+00 0.39748416E+00 0.39783500E+00 0.39818583E+00
+ 0.39853667E+00 0.39888751E+00 0.39923834E+00 0.39958918E+00 0.39994001E+00
+ 0.40029085E+00 0.40064168E+00 0.40099252E+00 0.40134336E+00 0.40169419E+00
+ 0.40204503E+00 0.40239586E+00 0.40274670E+00 0.40309754E+00 0.40344837E+00
+ 0.40379921E+00 0.40415004E+00 0.40450088E+00 0.40485171E+00 0.40520255E+00
+ 0.40555339E+00 0.40590422E+00 0.40625506E+00 0.40660589E+00 0.40695673E+00
+ 0.40730757E+00 0.40765840E+00 0.40800924E+00 0.40836007E+00 0.40871091E+00
+ 0.40906174E+00 0.40941258E+00 0.40976342E+00 0.41011425E+00 0.41046509E+00
+ 0.41081592E+00 0.41116676E+00 0.41151760E+00 0.41186843E+00 0.41221927E+00
+ 0.41257010E+00 0.41292094E+00 0.41327177E+00 0.41362261E+00 0.41397345E+00
+ 0.41432428E+00 0.41467512E+00 0.41502595E+00 0.41537679E+00 0.41572763E+00
+ 0.41607846E+00 0.41642930E+00 0.41678013E+00 0.41713097E+00 0.41748180E+00
+ 0.41783264E+00 0.41818348E+00 0.41853431E+00 0.41888515E+00 0.41923598E+00
+ 0.41958682E+00 0.41993766E+00 0.42028849E+00 0.42063933E+00 0.42099016E+00
+ 0.42134100E+00 0.42169183E+00 0.42204267E+00 0.42239351E+00 0.42274434E+00
+ 0.42309518E+00 0.42344601E+00 0.42379685E+00 0.42414769E+00 0.42449852E+00
+ 0.42484936E+00 0.42520019E+00 0.42555103E+00 0.42590186E+00 0.42625270E+00
+ 0.42660354E+00 0.42695437E+00 0.42730521E+00 0.42765604E+00 0.42800688E+00
+ 0.42835772E+00 0.42870855E+00 0.42905939E+00 0.42941022E+00 0.42976106E+00
+ 0.43011190E+00 0.43046273E+00 0.43081357E+00 0.43116440E+00 0.43151524E+00
+ 0.43186607E+00 0.43221691E+00 0.43256775E+00 0.43291858E+00 0.43326942E+00
+ 0.43362025E+00 0.43397109E+00 0.43432193E+00 0.43467276E+00 0.43502360E+00
+ 0.43537443E+00 0.43572527E+00 0.43607610E+00 0.43642694E+00 0.43677778E+00
+ 0.43712861E+00 0.43747945E+00 0.43783028E+00 0.43818112E+00 0.43853196E+00
+ 0.43888279E+00 0.43923363E+00 0.43958446E+00 0.43993530E+00 0.44028613E+00
+ 0.44063697E+00 0.44098781E+00 0.44133864E+00 0.44168948E+00 0.44204031E+00
+ 0.44239115E+00 0.44274199E+00 0.44309282E+00 0.44344366E+00 0.44379449E+00
+ 0.44414533E+00 0.44449616E+00 0.44484700E+00 0.44519784E+00 0.44554867E+00
+ 0.44589951E+00 0.44625034E+00 0.44660118E+00 0.44695202E+00 0.44730285E+00
+ 0.44765369E+00 0.44800452E+00 0.44835536E+00 0.44870619E+00 0.44905703E+00
+ 0.44940787E+00 0.44975870E+00 0.45010954E+00 0.45046037E+00 0.45081121E+00
+ 0.45116205E+00 0.45151288E+00 0.45186372E+00 0.45221455E+00 0.45256539E+00
+ 0.45291622E+00 0.45326706E+00 0.45361790E+00 0.45396873E+00 0.45431957E+00
+ 0.45467040E+00 0.45502124E+00 0.45537208E+00 0.45572291E+00 0.45607375E+00
+ 0.45642458E+00 0.45677542E+00 0.45712625E+00 0.45747709E+00 0.45782793E+00
+ 0.45817876E+00 0.45852960E+00 0.45888043E+00 0.45923127E+00 0.45958211E+00
+ 0.45993294E+00 0.46028378E+00 0.46063461E+00 0.46098545E+00 0.46133628E+00
+ 0.46168712E+00 0.46203796E+00 0.46238879E+00 0.46273963E+00 0.46309046E+00
+ 0.46344130E+00 0.46379214E+00 0.46414297E+00 0.46449381E+00 0.46484464E+00
+ 0.46519548E+00 0.46554631E+00 0.46589715E+00 0.46624799E+00 0.46659882E+00
+ 0.46694966E+00 0.46730049E+00 0.46765133E+00 0.46800217E+00 0.46835300E+00
+ 0.46870384E+00 0.46905467E+00 0.46940551E+00 0.46975634E+00 0.47010718E+00
+ 0.47045802E+00 0.47080885E+00 0.47115969E+00 0.47151052E+00 0.47186136E+00
+ 0.47221220E+00 0.47256303E+00 0.47291387E+00 0.47326470E+00 0.47361554E+00
+ 0.47396637E+00 0.47431721E+00 0.47466805E+00 0.47501888E+00 0.47536972E+00
+ 0.47572055E+00 0.47607139E+00 0.47642223E+00 0.47677306E+00 0.47712390E+00
+ 0.47747473E+00 0.47782557E+00 0.47817640E+00 0.47852724E+00 0.47887808E+00
+ 0.47922891E+00 0.47957975E+00 0.47993058E+00 0.48028142E+00 0.48063226E+00
+ 0.48098309E+00 0.48133393E+00 0.48168476E+00 0.48203560E+00 0.48238643E+00
+ 0.48273727E+00 0.48308811E+00 0.48343894E+00 0.48378978E+00 0.48414061E+00
+ 0.48449145E+00 0.48484229E+00 0.48519312E+00 0.48554396E+00 0.48589479E+00
+ 0.48624563E+00 0.48659646E+00 0.48694730E+00 0.48729814E+00 0.48764897E+00
+ 0.48799981E+00 0.48835064E+00 0.48870148E+00 0.48905232E+00 0.48940315E+00
+ 0.48975399E+00 0.49010482E+00 0.49045566E+00 0.49080649E+00 0.49115733E+00
+ 0.49150817E+00 0.49185900E+00 0.49220984E+00 0.49256067E+00 0.49291151E+00
+ 0.49326235E+00 0.49361318E+00 0.49396402E+00 0.49431485E+00 0.49466569E+00
+ 0.49501652E+00 0.49536736E+00 0.49571820E+00 0.49606903E+00 0.49641987E+00
+ 0.49677070E+00 0.49712154E+00 0.49747238E+00 0.49782321E+00 0.49817405E+00
+ 0.49852488E+00 0.49887572E+00 0.49922655E+00 0.49957739E+00 0.49992823E+00
+ 0.50027906E+00 0.50062990E+00 0.50098073E+00 0.50133157E+00 0.50168241E+00
+ 0.50203324E+00 0.50238408E+00 0.50273491E+00 0.50308575E+00 0.50343659E+00
+ 0.50378742E+00 0.50413826E+00 0.50448909E+00 0.50483993E+00 0.50519076E+00
+ 0.50554160E+00 0.50589244E+00 0.50624327E+00 0.50659411E+00 0.50694494E+00
+ 0.50729578E+00 0.50764662E+00 0.50799745E+00 0.50834829E+00 0.50869912E+00
+ 0.50904996E+00 0.50940079E+00 0.50975163E+00 0.51010247E+00 0.51045330E+00
+ 0.51080414E+00 0.51115497E+00 0.51150581E+00 0.51185665E+00 0.51220748E+00
+ 0.51255832E+00 0.51290915E+00 0.51325999E+00 0.51361082E+00 0.51396166E+00
+ 0.51431250E+00 0.51466333E+00 0.51501417E+00 0.51536500E+00 0.51571584E+00
+ 0.51606668E+00 0.51641751E+00 0.51676835E+00 0.51711918E+00 0.51747002E+00
+ 0.51782085E+00 0.51817169E+00 0.51852253E+00 0.51887336E+00 0.51922420E+00
+ 0.51957503E+00 0.51992587E+00 0.52027671E+00 0.52062754E+00 0.52097838E+00
+ 0.52132921E+00 0.52168005E+00 0.52203088E+00 0.52238172E+00 0.52273256E+00
+ 0.52308339E+00 0.52343423E+00 0.52378506E+00 0.52413590E+00 0.52448674E+00
+ 0.52483757E+00 0.52518841E+00 0.52553924E+00 0.52589008E+00 0.52624091E+00
+ 0.52659175E+00 0.52694259E+00 0.52729342E+00 0.52764426E+00 0.52799509E+00
+ 0.52834593E+00 0.52869677E+00 0.52904760E+00 0.52939844E+00 0.52974927E+00
+ 0.53010011E+00 0.53045094E+00 0.53080178E+00 0.53115262E+00 0.53150345E+00
+ 0.53185429E+00 0.53220512E+00 0.53255596E+00 0.53290680E+00 0.53325763E+00
+ 0.53360847E+00 0.53395930E+00 0.53431014E+00 0.53466097E+00 0.53501181E+00
+ 0.53536265E+00 0.53571348E+00 0.53606432E+00 0.53641515E+00 0.53676599E+00
+ 0.53711683E+00 0.53746766E+00 0.53781850E+00 0.53816933E+00 0.53852017E+00
+ 0.53887100E+00 0.53922184E+00 0.53957268E+00 0.53992351E+00 0.54027435E+00
+ 0.54062518E+00 0.54097602E+00 0.54132686E+00 0.54167769E+00 0.54202853E+00
+ 0.54237936E+00 0.54273020E+00 0.54308103E+00 0.54343187E+00 0.54378271E+00
+ 0.54413354E+00 0.54448438E+00 0.54483521E+00 0.54518605E+00 0.54553689E+00
+ 0.54588772E+00 0.54623856E+00 0.54658939E+00 0.54694023E+00 0.54729106E+00
+ 0.54764190E+00 0.54799274E+00 0.54834357E+00 0.54869441E+00 0.54904524E+00
+ 0.54939608E+00 0.54974692E+00 0.55009775E+00 0.55044859E+00 0.55079942E+00
+ 0.55115026E+00 0.55150109E+00 0.55185193E+00 0.55220277E+00 0.55255360E+00
+ 0.55290444E+00 0.55325527E+00 0.55360611E+00 0.55395695E+00 0.55430778E+00
+ 0.55465862E+00 0.55500945E+00 0.55536029E+00 0.55571112E+00 0.55606196E+00
+ 0.55641280E+00 0.55676363E+00 0.55711447E+00 0.55746530E+00 0.55781614E+00
+ 0.55816698E+00 0.55851781E+00 0.55886865E+00 0.55921948E+00 0.55957032E+00
+ 0.55992115E+00 0.56027199E+00 0.56062283E+00 0.56097366E+00 0.56132450E+00
+ 0.56167533E+00 0.56202617E+00 0.56237701E+00 0.56272784E+00 0.56307868E+00
+ 0.56342951E+00 0.56378035E+00 0.56413118E+00 0.56448202E+00 0.56483286E+00
+ 0.56518369E+00 0.56553453E+00 0.56588536E+00 0.56623620E+00 0.56658704E+00
+ 0.56693787E+00 0.56728871E+00 0.56763954E+00 0.56799038E+00 0.56834121E+00
+ 0.56869205E+00 0.56904289E+00 0.56939372E+00 0.56974456E+00 0.57009539E+00
+ 0.57044623E+00 0.57079707E+00 0.57114790E+00 0.57149874E+00 0.57184957E+00
+ 0.57220041E+00 0.57255124E+00 0.57290208E+00 0.57325292E+00 0.57360375E+00
+ 0.57395459E+00 0.57430542E+00 0.57465626E+00 0.57500710E+00 0.57535793E+00
+ 0.57570877E+00 0.57605960E+00 0.57641044E+00 0.57676127E+00 0.57711211E+00
+ 0.57746295E+00 0.57781378E+00 0.57816462E+00 0.57851545E+00 0.57886629E+00
+ 0.57921713E+00 0.57956796E+00 0.57991880E+00 0.58026963E+00 0.58062047E+00
+ 0.58097130E+00 0.58132214E+00 0.58167298E+00 0.58202381E+00 0.58237465E+00
+ 0.58272548E+00 0.58307632E+00 0.58342716E+00 0.58377799E+00 0.58412883E+00
+ 0.58447966E+00 0.58483050E+00 0.58518133E+00 0.58553217E+00 0.58588301E+00
+ 0.58623384E+00 0.58658468E+00 0.58693551E+00 0.58728635E+00 0.58763719E+00
+ 0.58798802E+00 0.58833886E+00 0.58868969E+00 0.58904053E+00 0.58939136E+00
+ 0.58974220E+00 0.59009304E+00 0.59044387E+00 0.59079471E+00 0.59114554E+00
+ 0.59149638E+00 0.59184722E+00 0.59219805E+00 0.59254889E+00 0.59289972E+00
+ 0.59325056E+00 0.59360139E+00 0.59395223E+00 0.59430307E+00 0.59465390E+00
+ 0.59500474E+00 0.59535557E+00 0.59570641E+00 0.59605725E+00 0.59640808E+00
+ 0.59675892E+00 0.59710975E+00 0.59746059E+00 0.59781142E+00 0.59816226E+00
+ 0.59851310E+00 0.59886393E+00 0.59921477E+00 0.59956560E+00 0.59991644E+00
+ 0.60026728E+00 0.60061811E+00 0.60096895E+00 0.60131978E+00 0.60167062E+00
+ 0.60202145E+00 0.60237229E+00 0.60272313E+00 0.60307396E+00 0.60342480E+00
+ 0.60377563E+00 0.60412647E+00 0.60447731E+00 0.60482814E+00 0.60517898E+00
+ 0.60552981E+00 0.60588065E+00 0.60623148E+00 0.60658232E+00 0.60693316E+00
+ 0.60728399E+00 0.60763483E+00 0.60798566E+00 0.60833650E+00 0.60868734E+00
+ 0.60903817E+00 0.60938901E+00 0.60973984E+00 0.61009068E+00 0.61044151E+00
+ 0.61079235E+00 0.61114319E+00 0.61149402E+00 0.61184486E+00 0.61219569E+00
+ 0.61254653E+00 0.61289736E+00 0.61324820E+00 0.61359904E+00 0.61394987E+00
+ 0.61430071E+00 0.61465154E+00 0.61500238E+00 0.61535322E+00 0.61570405E+00
+ 0.61605489E+00 0.61640572E+00 0.61675656E+00 0.61710739E+00 0.61745823E+00
+ 0.61780907E+00 0.61815990E+00 0.61851074E+00 0.61886157E+00 0.61921241E+00
+ 0.61956325E+00 0.61991408E+00 0.62026492E+00 0.62061575E+00 0.62096659E+00
+ 0.62131742E+00 0.62166826E+00 0.62201910E+00 0.62236993E+00 0.62272077E+00
+ 0.62307160E+00 0.62342244E+00 0.62377328E+00 0.62412411E+00 0.62447495E+00
+ 0.62482578E+00 0.62517662E+00 0.62552745E+00 0.62587829E+00 0.62622913E+00
+ 0.62657996E+00 0.62693080E+00 0.62728163E+00 0.62763247E+00 0.62798330E+00
+ 0.62833414E+00 0.62868498E+00 0.62903581E+00 0.62938665E+00 0.62973748E+00
+ 0.63008832E+00 0.63043916E+00 0.63078999E+00 0.63114083E+00 0.63149166E+00
+ 0.63184250E+00 0.63219333E+00 0.63254417E+00 0.63289501E+00 0.63324584E+00
+ 0.63359668E+00 0.63394751E+00 0.63429835E+00 0.63464919E+00 0.63500002E+00
+ 0.63535086E+00 0.63570169E+00 0.63605253E+00 0.63640336E+00 0.63675420E+00
+ 0.63710504E+00 0.63745587E+00 0.63780671E+00 0.63815754E+00 0.63850838E+00
+ 0.63885921E+00 0.63921005E+00 0.63956089E+00 0.63991172E+00 0.64026256E+00
+ 0.64061339E+00 0.64096423E+00 0.64131506E+00 0.64166590E+00 0.64201674E+00
+ 0.64236757E+00 0.64271841E+00 0.64306924E+00 0.64342008E+00 0.64377091E+00
+ 0.64412175E+00 0.64447259E+00 0.64482342E+00 0.64517426E+00 0.64552509E+00
+ 0.64587593E+00 0.64622676E+00 0.64657760E+00 0.64692844E+00 0.64727927E+00
+ 0.64763011E+00 0.64798094E+00 0.64833178E+00 0.64868261E+00 0.64903345E+00
+ 0.64938429E+00 0.64973512E+00 0.65008596E+00 0.65043679E+00 0.65078763E+00
+ 0.65113846E+00 0.65148930E+00 0.65184013E+00 0.65219097E+00 0.65254180E+00
+ 0.65289264E+00 0.65324348E+00 0.65359431E+00 0.65394515E+00 0.65429598E+00
+ 0.65464682E+00 0.65499765E+00 0.65534849E+00 0.65569932E+00 0.65605016E+00
+ 0.65640099E+00 0.65675183E+00 0.65710266E+00 0.65745349E+00 0.65780433E+00
+ 0.65815516E+00 0.65850600E+00 0.65885683E+00 0.65920766E+00 0.65955849E+00
+ 0.65990932E+00 0.66026015E+00 0.66061098E+00 0.66096180E+00 0.66131261E+00
+ 0.66166339E+00 0.66201411E+00 0.66236386E+00 0.66245334E+00 0.66245360E+00
+ 0.66245367E+00 0.66245371E+00 0.66245373E+00 0.66245374E+00 0.66245375E+00
+ 0.66245376E+00 0.66245376E+00 0.66245376E+00 0.66245377E+00 0.66245377E+00
+ 0.66245377E+00 0.66245377E+00 0.66245378E+00 0.66245378E+00 0.66245378E+00
+ 0.66245378E+00 0.66245378E+00 0.66245378E+00 0.66245378E+00 0.66245378E+00
+ 0.66245378E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00
+ 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00
+ 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00
+ 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00
+ 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00
+ 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00
+ 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00
+ 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00
+ 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00 0.66245379E+00
+ 0.66245379E+00 0.66245379E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00 0.66245380E+00
+ -0.14142132E-09 0.50025000E-03 0.10005001E-02 0.15007503E-02 0.20010004E-02
+ 0.25012506E-02 0.30015007E-02 0.35017509E-02 0.40020010E-02 0.45022511E-02
+ 0.50025013E-02 0.55027514E-02 0.60030016E-02 0.65032517E-02 0.70035018E-02
+ 0.75037520E-02 0.80040021E-02 0.85042523E-02 0.90045024E-02 0.95047526E-02
+ 0.10005003E-01 0.10505253E-01 0.11005503E-01 0.11505753E-01 0.12006003E-01
+ 0.12506253E-01 0.13006504E-01 0.13506754E-01 0.14007004E-01 0.14507254E-01
+ 0.15007504E-01 0.15507754E-01 0.16008004E-01 0.16508255E-01 0.17008505E-01
+ 0.17508755E-01 0.18009005E-01 0.18509255E-01 0.19009505E-01 0.19509755E-01
+ 0.20010006E-01 0.20510256E-01 0.21010506E-01 0.21510756E-01 0.22011006E-01
+ 0.22511256E-01 0.23011506E-01 0.23511757E-01 0.24012007E-01 0.24512257E-01
+ 0.25012507E-01 0.25512757E-01 0.26013007E-01 0.26513257E-01 0.27013508E-01
+ 0.27513758E-01 0.28014008E-01 0.28514258E-01 0.29014508E-01 0.29514758E-01
+ 0.30015008E-01 0.30515259E-01 0.31015509E-01 0.31515759E-01 0.32016009E-01
+ 0.32516259E-01 0.33016509E-01 0.33516759E-01 0.34017010E-01 0.34517260E-01
+ 0.35017510E-01 0.35517760E-01 0.36018010E-01 0.36518260E-01 0.37018510E-01
+ 0.37518761E-01 0.38019011E-01 0.38519261E-01 0.39019511E-01 0.39519761E-01
+ 0.40020011E-01 0.40520261E-01 0.41020512E-01 0.41520762E-01 0.42021012E-01
+ 0.42521262E-01 0.43021512E-01 0.43521762E-01 0.44022012E-01 0.44522262E-01
+ 0.45022513E-01 0.45522763E-01 0.46023013E-01 0.46523263E-01 0.47023513E-01
+ 0.47523763E-01 0.48024013E-01 0.48524264E-01 0.49024514E-01 0.49524764E-01
+ 0.50025014E-01 0.50525264E-01 0.51025514E-01 0.51525764E-01 0.52026015E-01
+ 0.52526265E-01 0.53026515E-01 0.53526765E-01 0.54027015E-01 0.54527265E-01
+ 0.55027515E-01 0.55527766E-01 0.56028016E-01 0.56528266E-01 0.57028516E-01
+ 0.57528766E-01 0.58029016E-01 0.58529266E-01 0.59029517E-01 0.59529767E-01
+ 0.60030017E-01 0.60530267E-01 0.61030517E-01 0.61530767E-01 0.62031017E-01
+ 0.62531268E-01 0.63031518E-01 0.63531768E-01 0.64032018E-01 0.64532268E-01
+ 0.65032518E-01 0.65532768E-01 0.66033019E-01 0.66533269E-01 0.67033519E-01
+ 0.67533769E-01 0.68034019E-01 0.68534269E-01 0.69034519E-01 0.69534770E-01
+ 0.70035020E-01 0.70535270E-01 0.71035520E-01 0.71535770E-01 0.72036020E-01
+ 0.72536270E-01 0.73036521E-01 0.73536771E-01 0.74037021E-01 0.74537271E-01
+ 0.75037521E-01 0.75537771E-01 0.76038021E-01 0.76538272E-01 0.77038522E-01
+ 0.77538772E-01 0.78039022E-01 0.78539272E-01 0.79039522E-01 0.79539772E-01
+ 0.80040023E-01 0.80540273E-01 0.81040523E-01 0.81540773E-01 0.82041023E-01
+ 0.82541273E-01 0.83041523E-01 0.83541774E-01 0.84042024E-01 0.84542274E-01
+ 0.85042524E-01 0.85542774E-01 0.86043024E-01 0.86543274E-01 0.87043525E-01
+ 0.87543775E-01 0.88044025E-01 0.88544275E-01 0.89044525E-01 0.89544775E-01
+ 0.90045025E-01 0.90545276E-01 0.91045526E-01 0.91545776E-01 0.92046026E-01
+ 0.92546276E-01 0.93046526E-01 0.93546776E-01 0.94047027E-01 0.94547277E-01
+ 0.95047527E-01 0.95547777E-01 0.96048027E-01 0.96548277E-01 0.97048527E-01
+ 0.97548778E-01 0.98049028E-01 0.98549278E-01 0.99049528E-01 0.99549778E-01
+ 0.10005003E+00 0.10055028E+00 0.10105053E+00 0.10155078E+00 0.10205103E+00
+ 0.10255128E+00 0.10305153E+00 0.10355178E+00 0.10405203E+00 0.10455228E+00
+ 0.10505253E+00 0.10555278E+00 0.10605303E+00 0.10655328E+00 0.10705353E+00
+ 0.10755378E+00 0.10805403E+00 0.10855428E+00 0.10905453E+00 0.10955478E+00
+ 0.11005503E+00 0.11055528E+00 0.11105553E+00 0.11155578E+00 0.11205603E+00
+ 0.11255628E+00 0.11305653E+00 0.11355678E+00 0.11405703E+00 0.11455728E+00
+ 0.11505753E+00 0.11555778E+00 0.11605803E+00 0.11655828E+00 0.11705853E+00
+ 0.11755878E+00 0.11805903E+00 0.11855928E+00 0.11905953E+00 0.11955978E+00
+ 0.12006003E+00 0.12056028E+00 0.12106053E+00 0.12156078E+00 0.12206103E+00
+ 0.12256128E+00 0.12306153E+00 0.12356178E+00 0.12406204E+00 0.12456229E+00
+ 0.12506254E+00 0.12556279E+00 0.12606304E+00 0.12656329E+00 0.12706354E+00
+ 0.12756379E+00 0.12806404E+00 0.12856429E+00 0.12906454E+00 0.12956479E+00
+ 0.13006504E+00 0.13056529E+00 0.13106554E+00 0.13156579E+00 0.13206604E+00
+ 0.13256629E+00 0.13306654E+00 0.13356679E+00 0.13406704E+00 0.13456729E+00
+ 0.13506754E+00 0.13556779E+00 0.13606804E+00 0.13656829E+00 0.13706854E+00
+ 0.13756879E+00 0.13806904E+00 0.13856929E+00 0.13906954E+00 0.13956979E+00
+ 0.14007004E+00 0.14057029E+00 0.14107054E+00 0.14157079E+00 0.14207104E+00
+ 0.14257129E+00 0.14307154E+00 0.14357179E+00 0.14407204E+00 0.14457229E+00
+ 0.14507254E+00 0.14557279E+00 0.14607304E+00 0.14657329E+00 0.14707354E+00
+ 0.14757379E+00 0.14807404E+00 0.14857429E+00 0.14907454E+00 0.14957479E+00
+ 0.15007504E+00 0.15057529E+00 0.15107554E+00 0.15157579E+00 0.15207604E+00
+ 0.15257629E+00 0.15307654E+00 0.15357679E+00 0.15407704E+00 0.15457729E+00
+ 0.15507754E+00 0.15557779E+00 0.15607804E+00 0.15657829E+00 0.15707854E+00
+ 0.15757879E+00 0.15807904E+00 0.15857929E+00 0.15907955E+00 0.15957980E+00
+ 0.16008005E+00 0.16058030E+00 0.16108055E+00 0.16158080E+00 0.16208105E+00
+ 0.16258130E+00 0.16308155E+00 0.16358180E+00 0.16408205E+00 0.16458230E+00
+ 0.16508255E+00 0.16558280E+00 0.16608305E+00 0.16658330E+00 0.16708355E+00
+ 0.16758380E+00 0.16808405E+00 0.16858430E+00 0.16908455E+00 0.16958480E+00
+ 0.17008505E+00 0.17058530E+00 0.17108555E+00 0.17158580E+00 0.17208605E+00
+ 0.17258630E+00 0.17308655E+00 0.17358680E+00 0.17408705E+00 0.17458730E+00
+ 0.17508755E+00 0.17558780E+00 0.17608805E+00 0.17658830E+00 0.17708855E+00
+ 0.17758880E+00 0.17808905E+00 0.17858930E+00 0.17908955E+00 0.17958980E+00
+ 0.18009005E+00 0.18059030E+00 0.18109055E+00 0.18159080E+00 0.18209105E+00
+ 0.18259130E+00 0.18309155E+00 0.18359180E+00 0.18409205E+00 0.18459230E+00
+ 0.18509255E+00 0.18559280E+00 0.18609305E+00 0.18659330E+00 0.18709355E+00
+ 0.18759380E+00 0.18809405E+00 0.18859430E+00 0.18909455E+00 0.18959480E+00
+ 0.19009505E+00 0.19059530E+00 0.19109555E+00 0.19159580E+00 0.19209605E+00
+ 0.19259630E+00 0.19309655E+00 0.19359680E+00 0.19409705E+00 0.19459731E+00
+ 0.19509756E+00 0.19559781E+00 0.19609806E+00 0.19659831E+00 0.19709856E+00
+ 0.19759881E+00 0.19809906E+00 0.19859931E+00 0.19909956E+00 0.19959981E+00
+ 0.20010006E+00 0.20060031E+00 0.20110056E+00 0.20160081E+00 0.20210106E+00
+ 0.20260131E+00 0.20310156E+00 0.20360181E+00 0.20410206E+00 0.20460231E+00
+ 0.20510256E+00 0.20560281E+00 0.20610306E+00 0.20660331E+00 0.20710356E+00
+ 0.20760381E+00 0.20810406E+00 0.20860431E+00 0.20910456E+00 0.20960481E+00
+ 0.21010506E+00 0.21060531E+00 0.21110556E+00 0.21160581E+00 0.21210606E+00
+ 0.21260631E+00 0.21310656E+00 0.21360681E+00 0.21410706E+00 0.21460731E+00
+ 0.21510756E+00 0.21560781E+00 0.21610806E+00 0.21660831E+00 0.21710856E+00
+ 0.21760881E+00 0.21810906E+00 0.21860931E+00 0.21910956E+00 0.21960981E+00
+ 0.22011006E+00 0.22061031E+00 0.22111056E+00 0.22161081E+00 0.22211106E+00
+ 0.22261131E+00 0.22311156E+00 0.22361181E+00 0.22411206E+00 0.22461231E+00
+ 0.22511256E+00 0.22561281E+00 0.22611306E+00 0.22661331E+00 0.22711356E+00
+ 0.22761381E+00 0.22811406E+00 0.22861431E+00 0.22911456E+00 0.22961482E+00
+ 0.23011507E+00 0.23061532E+00 0.23111557E+00 0.23161582E+00 0.23211607E+00
+ 0.23261632E+00 0.23311657E+00 0.23361682E+00 0.23411707E+00 0.23461732E+00
+ 0.23511757E+00 0.23561782E+00 0.23611807E+00 0.23661832E+00 0.23711857E+00
+ 0.23761882E+00 0.23811907E+00 0.23861932E+00 0.23911957E+00 0.23961982E+00
+ 0.24012007E+00 0.24062032E+00 0.24112057E+00 0.24162082E+00 0.24212107E+00
+ 0.24262132E+00 0.24312157E+00 0.24362182E+00 0.24412207E+00 0.24462232E+00
+ 0.24512257E+00 0.24562282E+00 0.24612307E+00 0.24662332E+00 0.24712357E+00
+ 0.24762382E+00 0.24812407E+00 0.24862432E+00 0.24912457E+00 0.24962482E+00
+ 0.25012507E+00 0.25062532E+00 0.25112557E+00 0.25162582E+00 0.25212607E+00
+ 0.25262632E+00 0.25312657E+00 0.25362682E+00 0.25412707E+00 0.25462732E+00
+ 0.25512757E+00 0.25562782E+00 0.25612807E+00 0.25662832E+00 0.25712857E+00
+ 0.25762882E+00 0.25812907E+00 0.25862932E+00 0.25912957E+00 0.25962982E+00
+ 0.26013007E+00 0.26063032E+00 0.26113057E+00 0.26163082E+00 0.26213107E+00
+ 0.26263132E+00 0.26313157E+00 0.26363182E+00 0.26413207E+00 0.26463232E+00
+ 0.26513258E+00 0.26563283E+00 0.26613308E+00 0.26663333E+00 0.26713358E+00
+ 0.26763383E+00 0.26813408E+00 0.26863433E+00 0.26913458E+00 0.26963483E+00
+ 0.27013508E+00 0.27063533E+00 0.27113558E+00 0.27163583E+00 0.27213608E+00
+ 0.27263633E+00 0.27313658E+00 0.27363683E+00 0.27413708E+00 0.27463733E+00
+ 0.27513758E+00 0.27563783E+00 0.27613808E+00 0.27663833E+00 0.27713858E+00
+ 0.27763883E+00 0.27813908E+00 0.27863933E+00 0.27913958E+00 0.27963983E+00
+ 0.28014008E+00 0.28064033E+00 0.28114058E+00 0.28164083E+00 0.28214108E+00
+ 0.28264133E+00 0.28314158E+00 0.28364183E+00 0.28414208E+00 0.28464233E+00
+ 0.28514258E+00 0.28564283E+00 0.28614308E+00 0.28664333E+00 0.28714358E+00
+ 0.28764383E+00 0.28814408E+00 0.28864433E+00 0.28914458E+00 0.28964483E+00
+ 0.29014508E+00 0.29064533E+00 0.29114558E+00 0.29164583E+00 0.29214608E+00
+ 0.29264633E+00 0.29314658E+00 0.29364683E+00 0.29414708E+00 0.29464733E+00
+ 0.29514758E+00 0.29564783E+00 0.29614808E+00 0.29664833E+00 0.29714858E+00
+ 0.29764883E+00 0.29814908E+00 0.29864933E+00 0.29914958E+00 0.29964983E+00
+ 0.30015009E+00 0.30065034E+00 0.30115059E+00 0.30165084E+00 0.30215109E+00
+ 0.30265134E+00 0.30315159E+00 0.30365184E+00 0.30415209E+00 0.30465234E+00
+ 0.30515259E+00 0.30565284E+00 0.30615309E+00 0.30665334E+00 0.30715359E+00
+ 0.30765384E+00 0.30815409E+00 0.30865434E+00 0.30915459E+00 0.30965484E+00
+ 0.31015509E+00 0.31065534E+00 0.31115559E+00 0.31165584E+00 0.31215609E+00
+ 0.31265634E+00 0.31315659E+00 0.31365684E+00 0.31415709E+00 0.31465734E+00
+ 0.31515759E+00 0.31565784E+00 0.31615809E+00 0.31665834E+00 0.31715859E+00
+ 0.31765884E+00 0.31815909E+00 0.31865934E+00 0.31915959E+00 0.31965984E+00
+ 0.32016009E+00 0.32066034E+00 0.32116059E+00 0.32166084E+00 0.32216109E+00
+ 0.32266134E+00 0.32316159E+00 0.32366184E+00 0.32416209E+00 0.32466234E+00
+ 0.32516259E+00 0.32566284E+00 0.32616309E+00 0.32666334E+00 0.32716359E+00
+ 0.32766384E+00 0.32816409E+00 0.32866434E+00 0.32916459E+00 0.32966484E+00
+ 0.33016509E+00 0.33066534E+00 0.33116559E+00 0.33166584E+00 0.33216609E+00
+ 0.33266634E+00 0.33316659E+00 0.33366684E+00 0.33416709E+00 0.33466734E+00
+ 0.33516759E+00 0.33566785E+00 0.33616810E+00 0.33666835E+00 0.33716860E+00
+ 0.33766885E+00 0.33816910E+00 0.33866935E+00 0.33916960E+00 0.33966985E+00
+ 0.34017010E+00 0.34067035E+00 0.34117060E+00 0.34167085E+00 0.34217110E+00
+ 0.34267135E+00 0.34317160E+00 0.34367185E+00 0.34417210E+00 0.34467235E+00
+ 0.34517260E+00 0.34567285E+00 0.34617310E+00 0.34667335E+00 0.34717360E+00
+ 0.34767385E+00 0.34817410E+00 0.34867435E+00 0.34917460E+00 0.34967485E+00
+ 0.35017510E+00 0.35067535E+00 0.35117560E+00 0.35167585E+00 0.35217610E+00
+ 0.35267635E+00 0.35317660E+00 0.35367685E+00 0.35417710E+00 0.35467735E+00
+ 0.35517760E+00 0.35567785E+00 0.35617810E+00 0.35667835E+00 0.35717860E+00
+ 0.35767885E+00 0.35817910E+00 0.35867935E+00 0.35917960E+00 0.35967985E+00
+ 0.36018010E+00 0.36068035E+00 0.36118060E+00 0.36168085E+00 0.36218110E+00
+ 0.36268135E+00 0.36318160E+00 0.36368185E+00 0.36418210E+00 0.36468235E+00
+ 0.36518260E+00 0.36568285E+00 0.36618310E+00 0.36668335E+00 0.36718360E+00
+ 0.36768385E+00 0.36818410E+00 0.36868435E+00 0.36918460E+00 0.36968485E+00
+ 0.37018510E+00 0.37068536E+00 0.37118561E+00 0.37168586E+00 0.37218611E+00
+ 0.37268636E+00 0.37318661E+00 0.37368686E+00 0.37418711E+00 0.37468736E+00
+ 0.37518761E+00 0.37568786E+00 0.37618811E+00 0.37668836E+00 0.37718861E+00
+ 0.37768886E+00 0.37818911E+00 0.37868936E+00 0.37918961E+00 0.37968986E+00
+ 0.38019011E+00 0.38069036E+00 0.38119061E+00 0.38169086E+00 0.38219111E+00
+ 0.38269136E+00 0.38319161E+00 0.38369186E+00 0.38419211E+00 0.38469236E+00
+ 0.38519261E+00 0.38569286E+00 0.38619311E+00 0.38669336E+00 0.38719361E+00
+ 0.38769386E+00 0.38819411E+00 0.38869436E+00 0.38919461E+00 0.38969486E+00
+ 0.39019511E+00 0.39069536E+00 0.39119561E+00 0.39169586E+00 0.39219611E+00
+ 0.39269636E+00 0.39319661E+00 0.39369686E+00 0.39419711E+00 0.39469736E+00
+ 0.39519761E+00 0.39569786E+00 0.39619811E+00 0.39669836E+00 0.39719861E+00
+ 0.39769886E+00 0.39819911E+00 0.39869936E+00 0.39919961E+00 0.39969986E+00
+ 0.40020011E+00 0.40070036E+00 0.40120061E+00 0.40170086E+00 0.40220111E+00
+ 0.40270136E+00 0.40320161E+00 0.40370186E+00 0.40420211E+00 0.40470236E+00
+ 0.40520261E+00 0.40570286E+00 0.40620312E+00 0.40670337E+00 0.40720362E+00
+ 0.40770387E+00 0.40820412E+00 0.40870437E+00 0.40920462E+00 0.40970487E+00
+ 0.41020512E+00 0.41070537E+00 0.41120562E+00 0.41170587E+00 0.41220612E+00
+ 0.41270637E+00 0.41320662E+00 0.41370687E+00 0.41420712E+00 0.41470737E+00
+ 0.41520762E+00 0.41570787E+00 0.41620812E+00 0.41670837E+00 0.41720862E+00
+ 0.41770887E+00 0.41820912E+00 0.41870937E+00 0.41920962E+00 0.41970987E+00
+ 0.42021012E+00 0.42071037E+00 0.42121062E+00 0.42171087E+00 0.42221112E+00
+ 0.42271137E+00 0.42321162E+00 0.42371187E+00 0.42421212E+00 0.42471237E+00
+ 0.42521262E+00 0.42571287E+00 0.42621312E+00 0.42671337E+00 0.42721362E+00
+ 0.42771387E+00 0.42821412E+00 0.42871437E+00 0.42921462E+00 0.42971487E+00
+ 0.43021512E+00 0.43071537E+00 0.43121562E+00 0.43171587E+00 0.43221612E+00
+ 0.43271637E+00 0.43321662E+00 0.43371687E+00 0.43421712E+00 0.43471737E+00
+ 0.43521762E+00 0.43571787E+00 0.43621812E+00 0.43671837E+00 0.43721862E+00
+ 0.43771887E+00 0.43821912E+00 0.43871937E+00 0.43921962E+00 0.43971987E+00
+ 0.44022012E+00 0.44072037E+00 0.44122063E+00 0.44172088E+00 0.44222113E+00
+ 0.44272138E+00 0.44322163E+00 0.44372188E+00 0.44422213E+00 0.44472238E+00
+ 0.44522263E+00 0.44572288E+00 0.44622313E+00 0.44672338E+00 0.44722363E+00
+ 0.44772388E+00 0.44822413E+00 0.44872438E+00 0.44922463E+00 0.44972488E+00
+ 0.45022513E+00 0.45072538E+00 0.45122563E+00 0.45172588E+00 0.45222613E+00
+ 0.45272638E+00 0.45322663E+00 0.45372688E+00 0.45422713E+00 0.45472738E+00
+ 0.45522763E+00 0.45572788E+00 0.45622813E+00 0.45672838E+00 0.45722863E+00
+ 0.45772888E+00 0.45822913E+00 0.45872938E+00 0.45922963E+00 0.45972988E+00
+ 0.46023013E+00 0.46073038E+00 0.46123063E+00 0.46173088E+00 0.46223113E+00
+ 0.46273138E+00 0.46323163E+00 0.46373188E+00 0.46423213E+00 0.46473238E+00
+ 0.46523263E+00 0.46573288E+00 0.46623313E+00 0.46673338E+00 0.46723363E+00
+ 0.46773388E+00 0.46823413E+00 0.46873438E+00 0.46923463E+00 0.46973488E+00
+ 0.47023513E+00 0.47073538E+00 0.47123563E+00 0.47173588E+00 0.47223613E+00
+ 0.47273638E+00 0.47323663E+00 0.47373688E+00 0.47423713E+00 0.47473738E+00
+ 0.47523763E+00 0.47573788E+00 0.47623813E+00 0.47673839E+00 0.47723864E+00
+ 0.47773889E+00 0.47823914E+00 0.47873939E+00 0.47923964E+00 0.47973989E+00
+ 0.48024014E+00 0.48074039E+00 0.48124064E+00 0.48174089E+00 0.48224114E+00
+ 0.48274139E+00 0.48324164E+00 0.48374189E+00 0.48424214E+00 0.48474239E+00
+ 0.48524264E+00 0.48574289E+00 0.48624314E+00 0.48674339E+00 0.48724364E+00
+ 0.48774389E+00 0.48824414E+00 0.48874439E+00 0.48924464E+00 0.48974489E+00
+ 0.49024514E+00 0.49074539E+00 0.49124564E+00 0.49174589E+00 0.49224614E+00
+ 0.49274639E+00 0.49324664E+00 0.49374689E+00 0.49424714E+00 0.49474739E+00
+ 0.49524764E+00 0.49574789E+00 0.49624814E+00 0.49674839E+00 0.49724864E+00
+ 0.49774889E+00 0.49824914E+00 0.49874939E+00 0.49924964E+00 0.49974989E+00
+ 0.50025014E+00 0.50075039E+00 0.50125064E+00 0.50175089E+00 0.50225114E+00
+ 0.50275139E+00 0.50325164E+00 0.50375189E+00 0.50425214E+00 0.50475239E+00
+ 0.50525264E+00 0.50575289E+00 0.50625314E+00 0.50675339E+00 0.50725364E+00
+ 0.50775389E+00 0.50825414E+00 0.50875439E+00 0.50925464E+00 0.50975489E+00
+ 0.51025514E+00 0.51075539E+00 0.51125564E+00 0.51175590E+00 0.51225615E+00
+ 0.51275640E+00 0.51325665E+00 0.51375690E+00 0.51425715E+00 0.51475740E+00
+ 0.51525765E+00 0.51575790E+00 0.51625815E+00 0.51675840E+00 0.51725865E+00
+ 0.51775890E+00 0.51825915E+00 0.51875940E+00 0.51925965E+00 0.51975990E+00
+ 0.52026015E+00 0.52076040E+00 0.52126065E+00 0.52176090E+00 0.52226115E+00
+ 0.52276140E+00 0.52326165E+00 0.52376190E+00 0.52426215E+00 0.52476240E+00
+ 0.52526265E+00 0.52576290E+00 0.52626315E+00 0.52676340E+00 0.52726365E+00
+ 0.52776390E+00 0.52826415E+00 0.52876440E+00 0.52926465E+00 0.52976490E+00
+ 0.53026515E+00 0.53076540E+00 0.53126565E+00 0.53176590E+00 0.53226615E+00
+ 0.53276640E+00 0.53326665E+00 0.53376690E+00 0.53426715E+00 0.53476740E+00
+ 0.53526765E+00 0.53576790E+00 0.53626815E+00 0.53676840E+00 0.53726865E+00
+ 0.53776890E+00 0.53826915E+00 0.53876940E+00 0.53926965E+00 0.53976990E+00
+ 0.54027015E+00 0.54077040E+00 0.54127065E+00 0.54177090E+00 0.54227115E+00
+ 0.54277140E+00 0.54327165E+00 0.54377190E+00 0.54427215E+00 0.54477240E+00
+ 0.54527265E+00 0.54577290E+00 0.54627315E+00 0.54677340E+00 0.54727366E+00
+ 0.54777391E+00 0.54827416E+00 0.54877441E+00 0.54927466E+00 0.54977491E+00
+ 0.55027516E+00 0.55077541E+00 0.55127566E+00 0.55177591E+00 0.55227616E+00
+ 0.55277641E+00 0.55327666E+00 0.55377691E+00 0.55427716E+00 0.55477741E+00
+ 0.55527766E+00 0.55577791E+00 0.55627816E+00 0.55677841E+00 0.55727866E+00
+ 0.55777891E+00 0.55827916E+00 0.55877941E+00 0.55927966E+00 0.55977991E+00
+ 0.56028016E+00 0.56078041E+00 0.56128066E+00 0.56178091E+00 0.56228116E+00
+ 0.56278141E+00 0.56328166E+00 0.56378191E+00 0.56428216E+00 0.56478241E+00
+ 0.56528266E+00 0.56578291E+00 0.56628316E+00 0.56678341E+00 0.56728366E+00
+ 0.56778391E+00 0.56828416E+00 0.56878441E+00 0.56928466E+00 0.56978491E+00
+ 0.57028516E+00 0.57078541E+00 0.57128566E+00 0.57178591E+00 0.57228616E+00
+ 0.57278641E+00 0.57328666E+00 0.57378691E+00 0.57428716E+00 0.57478741E+00
+ 0.57528766E+00 0.57578791E+00 0.57628816E+00 0.57678841E+00 0.57728866E+00
+ 0.57778891E+00 0.57828916E+00 0.57878941E+00 0.57928966E+00 0.57978991E+00
+ 0.58029016E+00 0.58079041E+00 0.58129066E+00 0.58179091E+00 0.58229117E+00
+ 0.58279142E+00 0.58329167E+00 0.58379192E+00 0.58429217E+00 0.58479242E+00
+ 0.58529267E+00 0.58579292E+00 0.58629317E+00 0.58679342E+00 0.58729367E+00
+ 0.58779392E+00 0.58829417E+00 0.58879442E+00 0.58929467E+00 0.58979492E+00
+ 0.59029517E+00 0.59079542E+00 0.59129567E+00 0.59179592E+00 0.59229617E+00
+ 0.59279642E+00 0.59329667E+00 0.59379692E+00 0.59429717E+00 0.59479742E+00
+ 0.59529767E+00 0.59579792E+00 0.59629817E+00 0.59679842E+00 0.59729867E+00
+ 0.59779892E+00 0.59829917E+00 0.59879942E+00 0.59929967E+00 0.59979992E+00
+ 0.60030017E+00 0.60080042E+00 0.60130067E+00 0.60180092E+00 0.60230117E+00
+ 0.60280142E+00 0.60330167E+00 0.60380192E+00 0.60430217E+00 0.60480242E+00
+ 0.60530267E+00 0.60580292E+00 0.60630317E+00 0.60680342E+00 0.60730367E+00
+ 0.60780392E+00 0.60830417E+00 0.60880442E+00 0.60930467E+00 0.60980492E+00
+ 0.61030517E+00 0.61080542E+00 0.61130567E+00 0.61180592E+00 0.61230617E+00
+ 0.61280642E+00 0.61330667E+00 0.61380692E+00 0.61430717E+00 0.61480742E+00
+ 0.61530767E+00 0.61580792E+00 0.61630817E+00 0.61680842E+00 0.61730867E+00
+ 0.61780893E+00 0.61830918E+00 0.61880943E+00 0.61930968E+00 0.61980993E+00
+ 0.62031018E+00 0.62081043E+00 0.62131068E+00 0.62181093E+00 0.62231118E+00
+ 0.62281143E+00 0.62331168E+00 0.62381193E+00 0.62431218E+00 0.62481243E+00
+ 0.62531268E+00 0.62581293E+00 0.62631318E+00 0.62681343E+00 0.62731368E+00
+ 0.62781393E+00 0.62831418E+00 0.62881443E+00 0.62931468E+00 0.62981493E+00
+ 0.63031518E+00 0.63081543E+00 0.63131568E+00 0.63181593E+00 0.63231618E+00
+ 0.63281643E+00 0.63331668E+00 0.63381693E+00 0.63431718E+00 0.63481743E+00
+ 0.63531768E+00 0.63581793E+00 0.63631818E+00 0.63681843E+00 0.63731868E+00
+ 0.63781893E+00 0.63831918E+00 0.63881943E+00 0.63931968E+00 0.63981993E+00
+ 0.64032018E+00 0.64082043E+00 0.64132068E+00 0.64182093E+00 0.64232118E+00
+ 0.64282143E+00 0.64332168E+00 0.64382193E+00 0.64432218E+00 0.64482243E+00
+ 0.64532268E+00 0.64582293E+00 0.64632318E+00 0.64682343E+00 0.64732368E+00
+ 0.64782393E+00 0.64832418E+00 0.64882443E+00 0.64932468E+00 0.64982493E+00
+ 0.65032518E+00 0.65082543E+00 0.65132568E+00 0.65182593E+00 0.65232618E+00
+ 0.65282643E+00 0.65332669E+00 0.65382694E+00 0.65432719E+00 0.65482744E+00
+ 0.65532769E+00 0.65582794E+00 0.65632819E+00 0.65682844E+00 0.65732869E+00
+ 0.65782894E+00 0.65832919E+00 0.65882944E+00 0.65932969E+00 0.65982994E+00
+ 0.66033019E+00 0.66083044E+00 0.66133069E+00 0.66183094E+00 0.66233119E+00
+ 0.66283144E+00 0.66333169E+00 0.66383194E+00 0.66433219E+00 0.66483244E+00
+ 0.66533269E+00 0.66583294E+00 0.66633319E+00 0.66683344E+00 0.66733369E+00
+ 0.66783394E+00 0.66833419E+00 0.66883444E+00 0.66933469E+00 0.66983494E+00
+ 0.67033519E+00 0.67083544E+00 0.67133569E+00 0.67183594E+00 0.67233619E+00
+ 0.67283644E+00 0.67333669E+00 0.67383694E+00 0.67433719E+00 0.67483744E+00
+ 0.67533769E+00 0.67583794E+00 0.67633819E+00 0.67683844E+00 0.67733869E+00
+ 0.67783894E+00 0.67833919E+00 0.67883944E+00 0.67933969E+00 0.67983994E+00
+ 0.68034019E+00 0.68084044E+00 0.68134069E+00 0.68184094E+00 0.68234119E+00
+ 0.68284144E+00 0.68334169E+00 0.68384194E+00 0.68434219E+00 0.68484244E+00
+ 0.68534269E+00 0.68584294E+00 0.68634319E+00 0.68684344E+00 0.68734369E+00
+ 0.68784394E+00 0.68834420E+00 0.68884445E+00 0.68934470E+00 0.68984495E+00
+ 0.69034520E+00 0.69084545E+00 0.69134570E+00 0.69184595E+00 0.69234620E+00
+ 0.69284645E+00 0.69334670E+00 0.69384695E+00 0.69434720E+00 0.69484745E+00
+ 0.69534770E+00 0.69584795E+00 0.69634820E+00 0.69684845E+00 0.69734870E+00
+ 0.69784895E+00 0.69834920E+00 0.69884945E+00 0.69934970E+00 0.69984995E+00
+ 0.70035020E+00 0.70085045E+00 0.70135070E+00 0.70185095E+00 0.70235120E+00
+ 0.70285145E+00 0.70335170E+00 0.70385195E+00 0.70435220E+00 0.70485245E+00
+ 0.70535270E+00 0.70585295E+00 0.70635320E+00 0.70685345E+00 0.70735370E+00
+ 0.70785395E+00 0.70835420E+00 0.70885445E+00 0.70935470E+00 0.70985495E+00
+ 0.71035520E+00 0.71085545E+00 0.71135570E+00 0.71185595E+00 0.71235620E+00
+ 0.71285645E+00 0.71335670E+00 0.71385695E+00 0.71435720E+00 0.71485745E+00
+ 0.71535770E+00 0.71585795E+00 0.71635820E+00 0.71685845E+00 0.71735870E+00
+ 0.71785895E+00 0.71835920E+00 0.71885945E+00 0.71935970E+00 0.71985995E+00
+ 0.72036020E+00 0.72086045E+00 0.72136070E+00 0.72186095E+00 0.72236120E+00
+ 0.72286145E+00 0.72336170E+00 0.72386196E+00 0.72436221E+00 0.72486246E+00
+ 0.72536271E+00 0.72586296E+00 0.72636321E+00 0.72686346E+00 0.72736371E+00
+ 0.72786396E+00 0.72836421E+00 0.72886446E+00 0.72936471E+00 0.72986496E+00
+ 0.73036521E+00 0.73086546E+00 0.73136571E+00 0.73186596E+00 0.73236621E+00
+ 0.73286646E+00 0.73336671E+00 0.73386696E+00 0.73436721E+00 0.73486746E+00
+ 0.73536771E+00 0.73586796E+00 0.73636821E+00 0.73686846E+00 0.73736871E+00
+ 0.73786896E+00 0.73836921E+00 0.73886946E+00 0.73936971E+00 0.73986996E+00
+ 0.74037021E+00 0.74087046E+00 0.74137071E+00 0.74187096E+00 0.74237121E+00
+ 0.74287146E+00 0.74337171E+00 0.74387196E+00 0.74437221E+00 0.74487246E+00
+ 0.74537271E+00 0.74587296E+00 0.74637321E+00 0.74687346E+00 0.74737371E+00
+ 0.74787396E+00 0.74837421E+00 0.74887446E+00 0.74937471E+00 0.74987496E+00
+ 0.75037521E+00 0.75087546E+00 0.75137571E+00 0.75187596E+00 0.75237621E+00
+ 0.75287646E+00 0.75337671E+00 0.75387696E+00 0.75437721E+00 0.75487746E+00
+ 0.75537771E+00 0.75587796E+00 0.75637821E+00 0.75687846E+00 0.75737871E+00
+ 0.75787896E+00 0.75837921E+00 0.75887946E+00 0.75937972E+00 0.75987997E+00
+ 0.76038022E+00 0.76088047E+00 0.76138072E+00 0.76188097E+00 0.76238122E+00
+ 0.76288147E+00 0.76338172E+00 0.76388197E+00 0.76438222E+00 0.76488247E+00
+ 0.76538272E+00 0.76588297E+00 0.76638322E+00 0.76688347E+00 0.76738372E+00
+ 0.76788397E+00 0.76838422E+00 0.76888447E+00 0.76938472E+00 0.76988497E+00
+ 0.77038522E+00 0.77088547E+00 0.77138572E+00 0.77188597E+00 0.77238622E+00
+ 0.77288647E+00 0.77338672E+00 0.77388697E+00 0.77438722E+00 0.77488747E+00
+ 0.77538772E+00 0.77588797E+00 0.77638822E+00 0.77688847E+00 0.77738872E+00
+ 0.77788897E+00 0.77838922E+00 0.77888947E+00 0.77938972E+00 0.77988997E+00
+ 0.78039022E+00 0.78089047E+00 0.78139072E+00 0.78189097E+00 0.78239122E+00
+ 0.78289147E+00 0.78339172E+00 0.78389197E+00 0.78439222E+00 0.78489247E+00
+ 0.78539272E+00 0.78589297E+00 0.78639322E+00 0.78689347E+00 0.78739372E+00
+ 0.78789397E+00 0.78839422E+00 0.78889447E+00 0.78939472E+00 0.78989497E+00
+ 0.79039522E+00 0.79089547E+00 0.79139572E+00 0.79189597E+00 0.79239622E+00
+ 0.79289647E+00 0.79339672E+00 0.79389697E+00 0.79439722E+00 0.79489748E+00
+ 0.79539773E+00 0.79589798E+00 0.79639823E+00 0.79689848E+00 0.79739873E+00
+ 0.79789898E+00 0.79839923E+00 0.79889948E+00 0.79939973E+00 0.79989998E+00
+ 0.80040023E+00 0.80090048E+00 0.80140073E+00 0.80190098E+00 0.80240123E+00
+ 0.80290148E+00 0.80340173E+00 0.80390198E+00 0.80440223E+00 0.80490248E+00
+ 0.80540273E+00 0.80590298E+00 0.80640323E+00 0.80690348E+00 0.80740373E+00
+ 0.80790398E+00 0.80840423E+00 0.80890448E+00 0.80940473E+00 0.80990498E+00
+ 0.81040523E+00 0.81090548E+00 0.81140573E+00 0.81190598E+00 0.81240623E+00
+ 0.81290648E+00 0.81340673E+00 0.81390698E+00 0.81440723E+00 0.81490748E+00
+ 0.81540773E+00 0.81590798E+00 0.81640823E+00 0.81690848E+00 0.81740873E+00
+ 0.81790898E+00 0.81840923E+00 0.81890948E+00 0.81940973E+00 0.81990998E+00
+ 0.82041023E+00 0.82091048E+00 0.82141073E+00 0.82191098E+00 0.82241123E+00
+ 0.82291148E+00 0.82341173E+00 0.82391198E+00 0.82441223E+00 0.82491248E+00
+ 0.82541273E+00 0.82591298E+00 0.82641323E+00 0.82691348E+00 0.82741373E+00
+ 0.82791398E+00 0.82841423E+00 0.82891448E+00 0.82941473E+00 0.82991498E+00
+ 0.83041523E+00 0.83091549E+00 0.83141574E+00 0.83191599E+00 0.83241624E+00
+ 0.83291649E+00 0.83341674E+00 0.83391699E+00 0.83441724E+00 0.83491749E+00
+ 0.83541774E+00 0.83591799E+00 0.83641824E+00 0.83691849E+00 0.83741874E+00
+ 0.83791899E+00 0.83841924E+00 0.83891949E+00 0.83941974E+00 0.83991999E+00
+ 0.84042024E+00 0.84092049E+00 0.84142074E+00 0.84192099E+00 0.84242124E+00
+ 0.84292149E+00 0.84342174E+00 0.84392199E+00 0.84442224E+00 0.84492249E+00
+ 0.84542274E+00 0.84592299E+00 0.84642324E+00 0.84692349E+00 0.84742374E+00
+ 0.84792399E+00 0.84842424E+00 0.84892449E+00 0.84942474E+00 0.84992499E+00
+ 0.85042524E+00 0.85092549E+00 0.85142574E+00 0.85192599E+00 0.85242624E+00
+ 0.85292649E+00 0.85342674E+00 0.85392699E+00 0.85442724E+00 0.85492749E+00
+ 0.85542774E+00 0.85592799E+00 0.85642824E+00 0.85692849E+00 0.85742874E+00
+ 0.85792899E+00 0.85842924E+00 0.85892949E+00 0.85942974E+00 0.85992999E+00
+ 0.86043024E+00 0.86093049E+00 0.86143074E+00 0.86193099E+00 0.86243124E+00
+ 0.86293149E+00 0.86343174E+00 0.86393199E+00 0.86443224E+00 0.86493249E+00
+ 0.86543274E+00 0.86593299E+00 0.86643325E+00 0.86693350E+00 0.86743375E+00
+ 0.86793400E+00 0.86843425E+00 0.86893450E+00 0.86943475E+00 0.86993500E+00
+ 0.87043525E+00 0.87093550E+00 0.87143575E+00 0.87193600E+00 0.87243625E+00
+ 0.87293650E+00 0.87343675E+00 0.87393700E+00 0.87443725E+00 0.87493750E+00
+ 0.87543775E+00 0.87593800E+00 0.87643825E+00 0.87693850E+00 0.87743875E+00
+ 0.87793900E+00 0.87843925E+00 0.87893950E+00 0.87943975E+00 0.87994000E+00
+ 0.88044025E+00 0.88094050E+00 0.88144075E+00 0.88194100E+00 0.88244125E+00
+ 0.88294150E+00 0.88344175E+00 0.88394200E+00 0.88444225E+00 0.88494250E+00
+ 0.88544275E+00 0.88594300E+00 0.88644325E+00 0.88694350E+00 0.88744375E+00
+ 0.88794400E+00 0.88844425E+00 0.88894450E+00 0.88944475E+00 0.88994500E+00
+ 0.89044525E+00 0.89094550E+00 0.89144575E+00 0.89194600E+00 0.89244625E+00
+ 0.89294650E+00 0.89344675E+00 0.89394700E+00 0.89444725E+00 0.89494750E+00
+ 0.89544775E+00 0.89594800E+00 0.89644825E+00 0.89694850E+00 0.89744875E+00
+ 0.89794900E+00 0.89844925E+00 0.89894950E+00 0.89944975E+00 0.89995000E+00
+ 0.90045025E+00 0.90095050E+00 0.90145075E+00 0.90195100E+00 0.90245125E+00
+ 0.90295150E+00 0.90345176E+00 0.90395201E+00 0.90445226E+00 0.90495251E+00
+ 0.90545276E+00 0.90595301E+00 0.90645326E+00 0.90695351E+00 0.90745376E+00
+ 0.90795401E+00 0.90845426E+00 0.90895451E+00 0.90945476E+00 0.90995501E+00
+ 0.91045526E+00 0.91095551E+00 0.91145576E+00 0.91195601E+00 0.91245626E+00
+ 0.91295651E+00 0.91345676E+00 0.91395701E+00 0.91445726E+00 0.91495751E+00
+ 0.91545776E+00 0.91595801E+00 0.91645826E+00 0.91695851E+00 0.91745876E+00
+ 0.91795901E+00 0.91845926E+00 0.91895951E+00 0.91945976E+00 0.91996001E+00
+ 0.92046026E+00 0.92096051E+00 0.92146076E+00 0.92196101E+00 0.92246126E+00
+ 0.92296151E+00 0.92346176E+00 0.92396201E+00 0.92446226E+00 0.92496251E+00
+ 0.92546276E+00 0.92596301E+00 0.92646326E+00 0.92696351E+00 0.92746376E+00
+ 0.92796401E+00 0.92846426E+00 0.92896451E+00 0.92946476E+00 0.92996501E+00
+ 0.93046526E+00 0.93096551E+00 0.93146576E+00 0.93196601E+00 0.93246626E+00
+ 0.93296651E+00 0.93346676E+00 0.93396701E+00 0.93446726E+00 0.93496751E+00
+ 0.93546776E+00 0.93596801E+00 0.93646826E+00 0.93696851E+00 0.93746876E+00
+ 0.93796901E+00 0.93846926E+00 0.93896951E+00 0.93946976E+00 0.93997001E+00
+ 0.94047026E+00 0.94097051E+00 0.94147076E+00 0.94197102E+00 0.94247127E+00
+ 0.94297152E+00 0.94347177E+00 0.94397202E+00 0.94447227E+00 0.94497252E+00
+ 0.94547277E+00 0.94597302E+00 0.94647327E+00 0.94697352E+00 0.94747377E+00
+ 0.94797402E+00 0.94847427E+00 0.94897452E+00 0.94947477E+00 0.94997502E+00
+ 0.95047527E+00 0.95097552E+00 0.95147577E+00 0.95197602E+00 0.95247627E+00
+ 0.95297652E+00 0.95347677E+00 0.95397702E+00 0.95447727E+00 0.95497752E+00
+ 0.95547777E+00 0.95597802E+00 0.95647827E+00 0.95697852E+00 0.95747877E+00
+ 0.95797902E+00 0.95847927E+00 0.95897952E+00 0.95947977E+00 0.95998002E+00
+ 0.96048027E+00 0.96098052E+00 0.96148077E+00 0.96198102E+00 0.96248127E+00
+ 0.96298152E+00 0.96348177E+00 0.96398202E+00 0.96448227E+00 0.96498252E+00
+ 0.96548277E+00 0.96598302E+00 0.96648327E+00 0.96698352E+00 0.96748377E+00
+ 0.96798402E+00 0.96848427E+00 0.96898452E+00 0.96948477E+00 0.96998502E+00
+ 0.97048527E+00 0.97098552E+00 0.97148577E+00 0.97198602E+00 0.97248627E+00
+ 0.97298652E+00 0.97348677E+00 0.97398702E+00 0.97448727E+00 0.97498752E+00
+ 0.97548777E+00 0.97598802E+00 0.97648827E+00 0.97698852E+00 0.97748877E+00
+ 0.97798902E+00 0.97848927E+00 0.97898952E+00 0.97948977E+00 0.97999002E+00
+ 0.98049027E+00 0.98099052E+00 0.98149077E+00 0.98199102E+00 0.98249127E+00
+ 0.98299152E+00 0.98349177E+00 0.98399202E+00 0.98449227E+00 0.98499252E+00
+ 0.98549277E+00 0.98599302E+00 0.98649327E+00 0.98699352E+00 0.98749377E+00
+ 0.98799402E+00 0.98849427E+00 0.98899452E+00 0.98949477E+00 0.98999502E+00
+ 0.99049527E+00 0.99099552E+00 0.99149576E+00 0.99199601E+00 0.99249626E+00
+ 0.99299651E+00 0.99349676E+00 0.99399701E+00 0.99449726E+00 0.99499750E+00
+ 0.99549775E+00 0.99599800E+00 0.99649824E+00 0.99699849E+00 0.99749873E+00
+ 0.99799896E+00 0.99849919E+00 0.99899939E+00 0.99949950E+00 0.99998812E+00
+ 0.10000000E+01
+ 0.10000000E+01
+ 0.00000000E+00
+ 0.00000000E+00
+ 0.00000000E+00
diff --git a/potentials/GaAs.bop b/potentials/GaAs.bop
new file mode 100644
index 000000000..e4ae5fba2
--- /dev/null
+++ b/potentials/GaAs.bop
@@ -0,0 +1,44 @@
+elements:
+ 2
+ 31 0.697230E+02 Ga
+ 33 0.749216E+02 As
+
+global:
+ 0.10E-04 0.10E-04 0.10E-04 0.10E-04 0.10E-04 0.10E-04 0.10E-04
+ 3 -0.164498E+01 0.164498E+01
+ 1.0 0.625 1
+ 0.157380E+02 0.113762E+01 0.208778E+01
+ 0.221807E+02 0.268973E+01
+ 0.200000E+01 0.000000E+00
+
+ptrs:
+ 0.000000E+00 0.100000E+01 0.720160E+00
+ 0.000000E+00 0.100000E+01 0.427095E+00
+
+pairs:
+ 0.242350E+01 0.242350E+01 0.300000E+01 0.370000E+01
+ 0.145090E+01 0.725450E+00 0.262344E+01
+ 0.155200E+01 0.152326E+01 0.975201E-01
+ 0.000000E+00 0.151928E+01 0.000000E+00
+ 0.100000E+01 0.100000E+01 0.000000E+00
+ 0.445550E+00 0.256485E+02 0.100000E-04
+ 0.238000E+01 0.238000E+01 0.300000E+01 0.370000E+01
+ 0.196519E+01 0.982590E+00 0.262343E+01
+ 0.210000E+01 0.179589E+01 0.323325E+00
+ 0.000000E+00 0.853384E+00 0.000000E+00
+ 0.100000E+01 0.100000E+01 0.000000E+00
+ 0.500000E+00 0.000000E+00 0.100000E-04
+ 0.212000E+01 0.212000E+01 0.300000E+01 0.365000E+01
+ 0.130585E+01 0.652930E+00 0.263039E+01
+ 0.398000E+01 0.308774E+01 0.926321E+00
+ 0.000000E+00 0.360162E+01 0.000000E+00
+ 0.100000E+01 0.100000E+01 0.000000E+00
+ 0.655795E+00 -0.760039E+00 0.100000E-04
+
+tris:
+ 0.921519E-01 0.720160E+00 0.187688E+00
+ 0.537305E-01 0.720160E+00 0.226109E+00
+ 0.256222E+00 0.668583E+00 0.751959E-01
+ 0.234227E+00 0.765773E+00 0.000000E+00
+ -0.318731E-01 0.749790E+00 0.282083E+00
+ -0.211787E-01 0.766727E+00 0.254452E+00
diff --git a/potentials/GaAs.bop.table b/potentials/GaAs.bop.table
new file mode 100644
index 000000000..fd0e4ad21
--- /dev/null
+++ b/potentials/GaAs.bop.table
@@ -0,0 +1,4832 @@
+ 2
+ 31 0.69723000E+02 Ga
+ 33 0.74921593E+02 As
+ 2000 2000
+ 0.10E-04 0.10E-04 0.10E-04 0.10E-04 0.10E-04 0.10E-04 0.10E-04
+ 0.72016037E+00
+ 0.42709517E+00
+ 0.37000000E+01
+ 0.15192792E+01 0.00000000E+00 0.10000000E+01 0.10000000E+01
+ 0.00000000E+00 0.00000000E+00
+ 0.44555014E+00 0.25648508E+02 0.10E-04
+ 0.36500001E+01
+ 0.36016219E+01 0.00000000E+00 0.10000000E+01 0.10000000E+01
+ 0.00000000E+00 0.00000000E+00
+ 0.65579468E+00 -0.76003909E+00 0.10E-04
+ 0.37000000E+01
+ 0.85338426E+00 0.00000000E+00 0.10000000E+01 0.10000000E+01
+ 0.00000000E+00 0.00000000E+00
+ 0.50000000E+00 0.00000000E+00 0.10E-04
+ 9.21518535E-02 7.20160363E-01 1.87687783E-01
+ 5.37304525E-02 7.20160376E-01 2.26109172E-01
+ 2.34227480E-01 7.65772520E-01 0.00000000E+00
+ -3.18730636E-02 7.49789590E-01 2.82083474E-01
+ 5.37304525E-02 7.20160376E-01 2.26109172E-01
+ 2.56221496E-01 6.68582598E-01 7.51959058E-02
+ -3.18730636E-02 7.49789590E-01 2.82083474E-01
+ -2.11787351E-02 7.66726837E-01 2.54451898E-01
+ 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03
+ 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03
+ 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03
+ 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03
+ 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03
+ 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03
+ 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03
+ 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03
+ 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03
+ 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03
+ 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03 0.67538417E+03
+ 0.65810775E+03 0.64111474E+03 0.62484927E+03 0.60926821E+03 0.59433169E+03
+ 0.58000277E+03 0.56624722E+03 0.55303323E+03 0.54033125E+03 0.52811376E+03
+ 0.51635513E+03 0.50503146E+03 0.49412041E+03 0.48360111E+03 0.47345405E+03
+ 0.46366091E+03 0.45420457E+03 0.44506892E+03 0.43623885E+03 0.42770015E+03
+ 0.41943947E+03 0.41144420E+03 0.40370250E+03 0.39620317E+03 0.38893566E+03
+ 0.38189000E+03 0.37505675E+03 0.36842702E+03 0.36199235E+03 0.35574475E+03
+ 0.34967665E+03 0.34378088E+03 0.33805059E+03 0.33247934E+03 0.32706095E+03
+ 0.32178960E+03 0.31665971E+03 0.31166599E+03 0.30680340E+03 0.30206714E+03
+ 0.29745263E+03 0.29295550E+03 0.28857159E+03 0.28429692E+03 0.28012768E+03
+ 0.27606026E+03 0.27209117E+03 0.26821711E+03 0.26443488E+03 0.26074146E+03
+ 0.25713392E+03 0.25360948E+03 0.25016546E+03 0.24679931E+03 0.24350855E+03
+ 0.24029083E+03 0.23714388E+03 0.23406552E+03 0.23105367E+03 0.22810632E+03
+ 0.22522153E+03 0.22239744E+03 0.21963228E+03 0.21692431E+03 0.21427188E+03
+ 0.21167341E+03 0.20912734E+03 0.20663221E+03 0.20418659E+03 0.20178909E+03
+ 0.19943840E+03 0.19713323E+03 0.19487236E+03 0.19265458E+03 0.19047875E+03
+ 0.18834375E+03 0.18624851E+03 0.18419200E+03 0.18217321E+03 0.18019116E+03
+ 0.17824493E+03 0.17633360E+03 0.17445630E+03 0.17261218E+03 0.17080041E+03
+ 0.16902020E+03 0.16727078E+03 0.16555140E+03 0.16386133E+03 0.16219988E+03
+ 0.16056637E+03 0.15896013E+03 0.15738052E+03 0.15582693E+03 0.15429876E+03
+ 0.15279541E+03 0.15131633E+03 0.14986096E+03 0.14842877E+03 0.14701924E+03
+ 0.14563187E+03 0.14426616E+03 0.14292165E+03 0.14159786E+03 0.14029436E+03
+ 0.13901070E+03 0.13774645E+03 0.13650121E+03 0.13527458E+03 0.13406615E+03
+ 0.13287556E+03 0.13170243E+03 0.13054640E+03 0.12940712E+03 0.12828425E+03
+ 0.12717746E+03 0.12608641E+03 0.12501081E+03 0.12395033E+03 0.12290468E+03
+ 0.12187357E+03 0.12085670E+03 0.11985382E+03 0.11886464E+03 0.11788889E+03
+ 0.11692633E+03 0.11597670E+03 0.11503976E+03 0.11411527E+03 0.11320299E+03
+ 0.11230269E+03 0.11141417E+03 0.11053718E+03 0.10967154E+03 0.10881702E+03
+ 0.10797343E+03 0.10714058E+03 0.10631825E+03 0.10550628E+03 0.10470447E+03
+ 0.10391265E+03 0.10313064E+03 0.10235826E+03 0.10159536E+03 0.10084176E+03
+ 0.10009731E+03 0.99361849E+02 0.98635221E+02 0.97917279E+02 0.97207876E+02
+ 0.96506867E+02 0.95814114E+02 0.95129477E+02 0.94452822E+02 0.93784019E+02
+ 0.93122937E+02 0.92469451E+02 0.91823438E+02 0.91184775E+02 0.90553345E+02
+ 0.89929032E+02 0.89311723E+02 0.88701305E+02 0.88097670E+02 0.87500711E+02
+ 0.86910324E+02 0.86326406E+02 0.85748856E+02 0.85177576E+02 0.84612469E+02
+ 0.84053442E+02 0.83500401E+02 0.82953255E+02 0.82411915E+02 0.81876293E+02
+ 0.81346305E+02 0.80821865E+02 0.80302892E+02 0.79789305E+02 0.79281023E+02
+ 0.78777970E+02 0.78280068E+02 0.77787244E+02 0.77299422E+02 0.76816533E+02
+ 0.76338503E+02 0.75865264E+02 0.75396748E+02 0.74932887E+02 0.74473616E+02
+ 0.74018871E+02 0.73568587E+02 0.73122702E+02 0.72681156E+02 0.72243888E+02
+ 0.71810839E+02 0.71381951E+02 0.70957168E+02 0.70536433E+02 0.70119691E+02
+ 0.69706889E+02 0.69297974E+02 0.68892892E+02 0.68491594E+02 0.68094028E+02
+ 0.67700145E+02 0.67309897E+02 0.66923235E+02 0.66540114E+02 0.66160485E+02
+ 0.65784305E+02 0.65411527E+02 0.65042110E+02 0.64676008E+02 0.64313180E+02
+ 0.63953583E+02 0.63597178E+02 0.63243922E+02 0.62893778E+02 0.62546704E+02
+ 0.62202663E+02 0.61861618E+02 0.61523530E+02 0.61188363E+02 0.60856081E+02
+ 0.60526648E+02 0.60200030E+02 0.59876192E+02 0.59555100E+02 0.59236721E+02
+ 0.58921022E+02 0.58607970E+02 0.58297535E+02 0.57989684E+02 0.57684388E+02
+ 0.57381614E+02 0.57081334E+02 0.56783519E+02 0.56488138E+02 0.56195164E+02
+ 0.55904569E+02 0.55616324E+02 0.55330403E+02 0.55046779E+02 0.54765425E+02
+ 0.54486314E+02 0.54209423E+02 0.53934724E+02 0.53662194E+02 0.53391807E+02
+ 0.53123539E+02 0.52857367E+02 0.52593267E+02 0.52331216E+02 0.52071191E+02
+ 0.51813169E+02 0.51557129E+02 0.51303047E+02 0.51050904E+02 0.50800677E+02
+ 0.50552346E+02 0.50305890E+02 0.50061288E+02 0.49818521E+02 0.49577568E+02
+ 0.49338411E+02 0.49101029E+02 0.48865404E+02 0.48631517E+02 0.48399350E+02
+ 0.48168885E+02 0.47940103E+02 0.47712986E+02 0.47487518E+02 0.47263681E+02
+ 0.47041458E+02 0.46820832E+02 0.46601786E+02 0.46384305E+02 0.46168372E+02
+ 0.45953971E+02 0.45741087E+02 0.45529704E+02 0.45319806E+02 0.45111380E+02
+ 0.44904409E+02 0.44698879E+02 0.44494776E+02 0.44292084E+02 0.44090792E+02
+ 0.43890883E+02 0.43692345E+02 0.43495163E+02 0.43299325E+02 0.43104817E+02
+ 0.42911627E+02 0.42719740E+02 0.42529145E+02 0.42339829E+02 0.42151779E+02
+ 0.41964983E+02 0.41779429E+02 0.41595106E+02 0.41412001E+02 0.41230102E+02
+ 0.41049398E+02 0.40869878E+02 0.40691531E+02 0.40514344E+02 0.40338308E+02
+ 0.40163412E+02 0.39989644E+02 0.39816995E+02 0.39645454E+02 0.39475010E+02
+ 0.39305653E+02 0.39137373E+02 0.38970161E+02 0.38804006E+02 0.38638899E+02
+ 0.38474830E+02 0.38311789E+02 0.38149768E+02 0.37988757E+02 0.37828747E+02
+ 0.37669728E+02 0.37511692E+02 0.37354631E+02 0.37198534E+02 0.37043394E+02
+ 0.36889203E+02 0.36735950E+02 0.36583630E+02 0.36432232E+02 0.36281749E+02
+ 0.36132174E+02 0.35983497E+02 0.35835711E+02 0.35688809E+02 0.35542782E+02
+ 0.35397623E+02 0.35253325E+02 0.35109879E+02 0.34967279E+02 0.34825518E+02
+ 0.34684588E+02 0.34544482E+02 0.34405193E+02 0.34266715E+02 0.34129039E+02
+ 0.33992160E+02 0.33856071E+02 0.33720764E+02 0.33586235E+02 0.33452475E+02
+ 0.33319479E+02 0.33187240E+02 0.33055752E+02 0.32925008E+02 0.32795004E+02
+ 0.32665731E+02 0.32537185E+02 0.32409359E+02 0.32282248E+02 0.32155846E+02
+ 0.32030146E+02 0.31905144E+02 0.31780833E+02 0.31657208E+02 0.31534263E+02
+ 0.31411994E+02 0.31290394E+02 0.31169458E+02 0.31049181E+02 0.30929557E+02
+ 0.30810582E+02 0.30692250E+02 0.30574556E+02 0.30457496E+02 0.30341063E+02
+ 0.30225254E+02 0.30110063E+02 0.29995485E+02 0.29881516E+02 0.29768151E+02
+ 0.29655386E+02 0.29543215E+02 0.29431634E+02 0.29320638E+02 0.29210224E+02
+ 0.29100386E+02 0.28991120E+02 0.28882422E+02 0.28774287E+02 0.28666711E+02
+ 0.28559691E+02 0.28453221E+02 0.28347297E+02 0.28241916E+02 0.28137074E+02
+ 0.28032765E+02 0.27928987E+02 0.27825736E+02 0.27723007E+02 0.27620796E+02
+ 0.27519100E+02 0.27417916E+02 0.27317238E+02 0.27217064E+02 0.27117389E+02
+ 0.27018211E+02 0.26919525E+02 0.26821328E+02 0.26723616E+02 0.26626387E+02
+ 0.26529635E+02 0.26433359E+02 0.26337553E+02 0.26242216E+02 0.26147344E+02
+ 0.26052933E+02 0.25958980E+02 0.25865482E+02 0.25772436E+02 0.25679838E+02
+ 0.25587685E+02 0.25495974E+02 0.25404703E+02 0.25313867E+02 0.25223464E+02
+ 0.25133491E+02 0.25043944E+02 0.24954822E+02 0.24866120E+02 0.24777836E+02
+ 0.24689968E+02 0.24602511E+02 0.24515465E+02 0.24428824E+02 0.24342588E+02
+ 0.24256752E+02 0.24171315E+02 0.24086273E+02 0.24001624E+02 0.23917366E+02
+ 0.23833495E+02 0.23750009E+02 0.23666905E+02 0.23584181E+02 0.23501835E+02
+ 0.23419863E+02 0.23338263E+02 0.23257033E+02 0.23176171E+02 0.23095673E+02
+ 0.23015538E+02 0.22935763E+02 0.22856346E+02 0.22777283E+02 0.22698574E+02
+ 0.22620216E+02 0.22542206E+02 0.22464542E+02 0.22387222E+02 0.22310244E+02
+ 0.22233605E+02 0.22157303E+02 0.22081337E+02 0.22005703E+02 0.21930400E+02
+ 0.21855426E+02 0.21780778E+02 0.21706455E+02 0.21632454E+02 0.21558774E+02
+ 0.21485412E+02 0.21412366E+02 0.21339635E+02 0.21267216E+02 0.21195107E+02
+ 0.21123307E+02 0.21051813E+02 0.20980624E+02 0.20909738E+02 0.20839152E+02
+ 0.20768866E+02 0.20698876E+02 0.20629182E+02 0.20559781E+02 0.20490672E+02
+ 0.20421853E+02 0.20353322E+02 0.20285077E+02 0.20217116E+02 0.20149439E+02
+ 0.20082043E+02 0.20014926E+02 0.19948086E+02 0.19881523E+02 0.19815234E+02
+ 0.19749218E+02 0.19683473E+02 0.19617998E+02 0.19552790E+02 0.19487849E+02
+ 0.19423173E+02 0.19358759E+02 0.19294607E+02 0.19230715E+02 0.19167082E+02
+ 0.19103706E+02 0.19040585E+02 0.18977718E+02 0.18915103E+02 0.18852739E+02
+ 0.18790625E+02 0.18728760E+02 0.18667140E+02 0.18605766E+02 0.18544636E+02
+ 0.18483748E+02 0.18423101E+02 0.18362694E+02 0.18302525E+02 0.18242593E+02
+ 0.18182897E+02 0.18123434E+02 0.18064205E+02 0.18005207E+02 0.17946439E+02
+ 0.17887900E+02 0.17829589E+02 0.17771505E+02 0.17713645E+02 0.17656009E+02
+ 0.17598596E+02 0.17541404E+02 0.17484432E+02 0.17427679E+02 0.17371144E+02
+ 0.17314825E+02 0.17258722E+02 0.17202832E+02 0.17147156E+02 0.17091691E+02
+ 0.17036437E+02 0.16981393E+02 0.16926556E+02 0.16871927E+02 0.16817504E+02
+ 0.16763285E+02 0.16709271E+02 0.16655459E+02 0.16601849E+02 0.16548440E+02
+ 0.16495229E+02 0.16442218E+02 0.16389403E+02 0.16336785E+02 0.16284362E+02
+ 0.16232134E+02 0.16180098E+02 0.16128255E+02 0.16076602E+02 0.16025140E+02
+ 0.15973867E+02 0.15922782E+02 0.15871885E+02 0.15821173E+02 0.15770647E+02
+ 0.15720305E+02 0.15670146E+02 0.15620170E+02 0.15570375E+02 0.15520760E+02
+ 0.15471325E+02 0.15422068E+02 0.15372990E+02 0.15324088E+02 0.15275362E+02
+ 0.15226810E+02 0.15178433E+02 0.15130229E+02 0.15082198E+02 0.15034338E+02
+ 0.14986648E+02 0.14939129E+02 0.14891778E+02 0.14844595E+02 0.14797579E+02
+ 0.14750730E+02 0.14704046E+02 0.14657527E+02 0.14611172E+02 0.14564979E+02
+ 0.14518949E+02 0.14473081E+02 0.14427373E+02 0.14381825E+02 0.14336436E+02
+ 0.14291206E+02 0.14246133E+02 0.14201217E+02 0.14156457E+02 0.14111852E+02
+ 0.14067401E+02 0.14023104E+02 0.13978961E+02 0.13934969E+02 0.13891129E+02
+ 0.13847440E+02 0.13803901E+02 0.13760511E+02 0.13717270E+02 0.13674177E+02
+ 0.13631231E+02 0.13588432E+02 0.13545779E+02 0.13503270E+02 0.13460907E+02
+ 0.13418687E+02 0.13376610E+02 0.13334675E+02 0.13292883E+02 0.13251231E+02
+ 0.13209720E+02 0.13168349E+02 0.13127117E+02 0.13086023E+02 0.13045067E+02
+ 0.13004249E+02 0.12963567E+02 0.12923021E+02 0.12882610E+02 0.12842335E+02
+ 0.12802193E+02 0.12762185E+02 0.12722310E+02 0.12682567E+02 0.12642955E+02
+ 0.12603475E+02 0.12564125E+02 0.12524906E+02 0.12485815E+02 0.12446854E+02
+ 0.12408020E+02 0.12369314E+02 0.12330736E+02 0.12292283E+02 0.12253957E+02
+ 0.12215756E+02 0.12177680E+02 0.12139728E+02 0.12101899E+02 0.12064194E+02
+ 0.12026612E+02 0.11989151E+02 0.11951812E+02 0.11914594E+02 0.11877497E+02
+ 0.11840519E+02 0.11803661E+02 0.11766922E+02 0.11730302E+02 0.11693799E+02
+ 0.11657414E+02 0.11621145E+02 0.11584993E+02 0.11548957E+02 0.11513036E+02
+ 0.11477230E+02 0.11441539E+02 0.11405961E+02 0.11370497E+02 0.11335146E+02
+ 0.11299907E+02 0.11264780E+02 0.11229765E+02 0.11194861E+02 0.11160068E+02
+ 0.11125384E+02 0.11090811E+02 0.11056346E+02 0.11021991E+02 0.10987743E+02
+ 0.10953604E+02 0.10919572E+02 0.10885647E+02 0.10851828E+02 0.10818116E+02
+ 0.10784509E+02 0.10751008E+02 0.10717611E+02 0.10684319E+02 0.10651131E+02
+ 0.10618046E+02 0.10585064E+02 0.10552185E+02 0.10519409E+02 0.10486734E+02
+ 0.10454160E+02 0.10421688E+02 0.10389317E+02 0.10357045E+02 0.10324874E+02
+ 0.10292801E+02 0.10260828E+02 0.10228954E+02 0.10197178E+02 0.10165500E+02
+ 0.10133919E+02 0.10102435E+02 0.10071048E+02 0.10039758E+02 0.10008563E+02
+ 0.99774643E+01 0.99464605E+01 0.99155516E+01 0.98847371E+01 0.98540168E+01
+ 0.98233903E+01 0.97928571E+01 0.97624169E+01 0.97320695E+01 0.97018143E+01
+ 0.96716511E+01 0.96415795E+01 0.96115992E+01 0.95817098E+01 0.95519110E+01
+ 0.95222023E+01 0.94925836E+01 0.94630544E+01 0.94336144E+01 0.94042632E+01
+ 0.93750006E+01 0.93458262E+01 0.93167397E+01 0.92877407E+01 0.92588289E+01
+ 0.92300040E+01 0.92012656E+01 0.91726135E+01 0.91440473E+01 0.91155667E+01
+ 0.90871714E+01 0.90588611E+01 0.90306354E+01 0.90024941E+01 0.89744368E+01
+ 0.89464633E+01 0.89185732E+01 0.88907662E+01 0.88630420E+01 0.88354003E+01
+ 0.88078409E+01 0.87803634E+01 0.87529675E+01 0.87256529E+01 0.86984194E+01
+ 0.86712666E+01 0.86441942E+01 0.86172021E+01 0.85902898E+01 0.85634571E+01
+ 0.85367038E+01 0.85100294E+01 0.84834338E+01 0.84569167E+01 0.84304778E+01
+ 0.84041168E+01 0.83778335E+01 0.83516275E+01 0.83254986E+01 0.82994466E+01
+ 0.82734711E+01 0.82475719E+01 0.82217488E+01 0.81960014E+01 0.81703295E+01
+ 0.81447328E+01 0.81192111E+01 0.80937642E+01 0.80683917E+01 0.80430934E+01
+ 0.80178691E+01 0.79927184E+01 0.79676412E+01 0.79426372E+01 0.79177062E+01
+ 0.78928478E+01 0.78680619E+01 0.78433482E+01 0.78187064E+01 0.77941364E+01
+ 0.77696378E+01 0.77452105E+01 0.77208542E+01 0.76965686E+01 0.76723535E+01
+ 0.76482088E+01 0.76241340E+01 0.76001291E+01 0.75761938E+01 0.75523278E+01
+ 0.75285309E+01 0.75048029E+01 0.74811436E+01 0.74575527E+01 0.74340301E+01
+ 0.74105754E+01 0.73871884E+01 0.73638691E+01 0.73406170E+01 0.73174320E+01
+ 0.72943140E+01 0.72712625E+01 0.72482776E+01 0.72253588E+01 0.72025061E+01
+ 0.71797192E+01 0.71569978E+01 0.71343419E+01 0.71117511E+01 0.70892253E+01
+ 0.70667642E+01 0.70443677E+01 0.70220355E+01 0.69997674E+01 0.69775633E+01
+ 0.69554229E+01 0.69333460E+01 0.69113324E+01 0.68893819E+01 0.68674944E+01
+ 0.68456696E+01 0.68239073E+01 0.68022073E+01 0.67805695E+01 0.67589936E+01
+ 0.67374795E+01 0.67160268E+01 0.66946356E+01 0.66733055E+01 0.66520364E+01
+ 0.66308281E+01 0.66096804E+01 0.65885931E+01 0.65675660E+01 0.65465989E+01
+ 0.65256917E+01 0.65048442E+01 0.64840562E+01 0.64633274E+01 0.64426578E+01
+ 0.64220471E+01 0.64014952E+01 0.63810019E+01 0.63605670E+01 0.63401902E+01
+ 0.63198716E+01 0.62996108E+01 0.62794077E+01 0.62592622E+01 0.62391739E+01
+ 0.62191429E+01 0.61991689E+01 0.61792517E+01 0.61593911E+01 0.61395871E+01
+ 0.61198394E+01 0.61001478E+01 0.60805123E+01 0.60609325E+01 0.60414084E+01
+ 0.60219398E+01 0.60025266E+01 0.59831685E+01 0.59638653E+01 0.59446171E+01
+ 0.59254235E+01 0.59062844E+01 0.58871997E+01 0.58681692E+01 0.58491927E+01
+ 0.58302701E+01 0.58114012E+01 0.57925859E+01 0.57738240E+01 0.57551153E+01
+ 0.57364598E+01 0.57178571E+01 0.56993073E+01 0.56808101E+01 0.56623654E+01
+ 0.56439731E+01 0.56256329E+01 0.56073448E+01 0.55891085E+01 0.55709240E+01
+ 0.55527911E+01 0.55347096E+01 0.55166794E+01 0.54987003E+01 0.54807722E+01
+ 0.54628950E+01 0.54450686E+01 0.54272926E+01 0.54095671E+01 0.53918919E+01
+ 0.53742668E+01 0.53566917E+01 0.53391665E+01 0.53216910E+01 0.53042650E+01
+ 0.52868885E+01 0.52695613E+01 0.52522833E+01 0.52350542E+01 0.52178741E+01
+ 0.52007427E+01 0.51836599E+01 0.51666256E+01 0.51496396E+01 0.51327018E+01
+ 0.51158122E+01 0.50989704E+01 0.50821764E+01 0.50654302E+01 0.50487314E+01
+ 0.50320801E+01 0.50154761E+01 0.49989192E+01 0.49824093E+01 0.49659463E+01
+ 0.49495301E+01 0.49331605E+01 0.49168374E+01 0.49005607E+01 0.48843303E+01
+ 0.48681459E+01 0.48520076E+01 0.48359152E+01 0.48198685E+01 0.48038674E+01
+ 0.47879118E+01 0.47720016E+01 0.47561367E+01 0.47403169E+01 0.47245421E+01
+ 0.47088122E+01 0.46931270E+01 0.46774866E+01 0.46618906E+01 0.46463390E+01
+ 0.46308318E+01 0.46153687E+01 0.45999497E+01 0.45845745E+01 0.45692433E+01
+ 0.45539557E+01 0.45387117E+01 0.45235111E+01 0.45083539E+01 0.44932400E+01
+ 0.44781691E+01 0.44631413E+01 0.44481564E+01 0.44332142E+01 0.44183147E+01
+ 0.44034578E+01 0.43886433E+01 0.43738711E+01 0.43591411E+01 0.43444533E+01
+ 0.43298074E+01 0.43152034E+01 0.43006412E+01 0.42861207E+01 0.42716417E+01
+ 0.42572041E+01 0.42428079E+01 0.42284529E+01 0.42141391E+01 0.41998662E+01
+ 0.41856342E+01 0.41714431E+01 0.41572926E+01 0.41431828E+01 0.41291134E+01
+ 0.41150844E+01 0.41010956E+01 0.40871470E+01 0.40732385E+01 0.40593699E+01
+ 0.40455412E+01 0.40317523E+01 0.40180030E+01 0.40042932E+01 0.39906229E+01
+ 0.39769919E+01 0.39634002E+01 0.39498476E+01 0.39363340E+01 0.39228594E+01
+ 0.39094236E+01 0.38960266E+01 0.38826682E+01 0.38693483E+01 0.38560669E+01
+ 0.38428238E+01 0.38296190E+01 0.38164523E+01 0.38033236E+01 0.37902329E+01
+ 0.37771801E+01 0.37641650E+01 0.37511876E+01 0.37382478E+01 0.37253454E+01
+ 0.37124804E+01 0.36996527E+01 0.36868621E+01 0.36741087E+01 0.36613922E+01
+ 0.36487127E+01 0.36360700E+01 0.36234639E+01 0.36108945E+01 0.35983617E+01
+ 0.35858652E+01 0.35734052E+01 0.35609813E+01 0.35485937E+01 0.35362421E+01
+ 0.35239265E+01 0.35116467E+01 0.34994028E+01 0.34871946E+01 0.34750220E+01
+ 0.34628849E+01 0.34507833E+01 0.34387170E+01 0.34266860E+01 0.34146902E+01
+ 0.34027294E+01 0.33908037E+01 0.33789128E+01 0.33670568E+01 0.33552355E+01
+ 0.33434488E+01 0.33316968E+01 0.33199791E+01 0.33082959E+01 0.32966470E+01
+ 0.32850323E+01 0.32734517E+01 0.32619052E+01 0.32503926E+01 0.32389140E+01
+ 0.32274691E+01 0.32160579E+01 0.32046803E+01 0.31933363E+01 0.31820257E+01
+ 0.31707485E+01 0.31595046E+01 0.31482939E+01 0.31371163E+01 0.31259718E+01
+ 0.31148602E+01 0.31037815E+01 0.30927356E+01 0.30817224E+01 0.30707419E+01
+ 0.30597939E+01 0.30488783E+01 0.30379952E+01 0.30271444E+01 0.30163258E+01
+ 0.30055393E+01 0.29947849E+01 0.29840626E+01 0.29733721E+01 0.29627135E+01
+ 0.29520866E+01 0.29414914E+01 0.29309278E+01 0.29203957E+01 0.29098950E+01
+ 0.28994257E+01 0.28889877E+01 0.28785809E+01 0.28682053E+01 0.28578607E+01
+ 0.28475470E+01 0.28372643E+01 0.28270124E+01 0.28167913E+01 0.28066008E+01
+ 0.27964409E+01 0.27863115E+01 0.27762126E+01 0.27661441E+01 0.27561058E+01
+ 0.27460978E+01 0.27361199E+01 0.27261721E+01 0.27162543E+01 0.27063664E+01
+ 0.26965084E+01 0.26866801E+01 0.26768816E+01 0.26671127E+01 0.26573733E+01
+ 0.26476634E+01 0.26379829E+01 0.26283318E+01 0.26187099E+01 0.26091172E+01
+ 0.25995537E+01 0.25900192E+01 0.25805137E+01 0.25710370E+01 0.25615893E+01
+ 0.25521702E+01 0.25427799E+01 0.25334182E+01 0.25240851E+01 0.25147804E+01
+ 0.25055041E+01 0.24962562E+01 0.24870366E+01 0.24778451E+01 0.24686818E+01
+ 0.24595466E+01 0.24504393E+01 0.24413600E+01 0.24323085E+01 0.24232849E+01
+ 0.24142889E+01 0.24053206E+01 0.23963799E+01 0.23874666E+01 0.23785809E+01
+ 0.23697225E+01 0.23608914E+01 0.23520875E+01 0.23433109E+01 0.23345613E+01
+ 0.23258388E+01 0.23171432E+01 0.23084746E+01 0.22998328E+01 0.22912178E+01
+ 0.22826295E+01 0.22740678E+01 0.22655327E+01 0.22570241E+01 0.22485420E+01
+ 0.22400862E+01 0.22316568E+01 0.22232536E+01 0.22148766E+01 0.22065257E+01
+ 0.21982008E+01 0.21899020E+01 0.21816291E+01 0.21733820E+01 0.21651607E+01
+ 0.21569652E+01 0.21487953E+01 0.21406511E+01 0.21325324E+01 0.21244391E+01
+ 0.21163713E+01 0.21083288E+01 0.21003117E+01 0.20923197E+01 0.20843529E+01
+ 0.20764112E+01 0.20684946E+01 0.20606029E+01 0.20527361E+01 0.20448942E+01
+ 0.20370771E+01 0.20292847E+01 0.20215169E+01 0.20137738E+01 0.20060552E+01
+ 0.19983611E+01 0.19906914E+01 0.19830461E+01 0.19754251E+01 0.19678283E+01
+ 0.19602557E+01 0.19527072E+01 0.19451827E+01 0.19376823E+01 0.19302058E+01
+ 0.19227531E+01 0.19153243E+01 0.19079192E+01 0.19005379E+01 0.18931802E+01
+ 0.18858460E+01 0.18785354E+01 0.18712482E+01 0.18639844E+01 0.18567440E+01
+ 0.18495268E+01 0.18423329E+01 0.18351622E+01 0.18280145E+01 0.18208899E+01
+ 0.18137883E+01 0.18067096E+01 0.17996538E+01 0.17926208E+01 0.17856106E+01
+ 0.17786231E+01 0.17716582E+01 0.17647159E+01 0.17577961E+01 0.17508988E+01
+ 0.17440239E+01 0.17371714E+01 0.17303412E+01 0.17235332E+01 0.17167474E+01
+ 0.17099838E+01 0.17032422E+01 0.16965227E+01 0.16898251E+01 0.16831494E+01
+ 0.16764956E+01 0.16698635E+01 0.16632532E+01 0.16566646E+01 0.16500976E+01
+ 0.16435522E+01 0.16370284E+01 0.16305259E+01 0.16240449E+01 0.16175853E+01
+ 0.16111469E+01 0.16047298E+01 0.15983339E+01 0.15919591E+01 0.15856054E+01
+ 0.15792727E+01 0.15729611E+01 0.15666703E+01 0.15604004E+01 0.15541513E+01
+ 0.15479229E+01 0.15417153E+01 0.15355283E+01 0.15293619E+01 0.15232161E+01
+ 0.15170907E+01 0.15109858E+01 0.15049013E+01 0.14988371E+01 0.14927932E+01
+ 0.14867695E+01 0.14807660E+01 0.14747826E+01 0.14688193E+01 0.14628760E+01
+ 0.14569527E+01 0.14510493E+01 0.14451657E+01 0.14393020E+01 0.14334580E+01
+ 0.14276337E+01 0.14218291E+01 0.14160441E+01 0.14102786E+01 0.14045327E+01
+ 0.13988062E+01 0.13930991E+01 0.13874113E+01 0.13817428E+01 0.13760936E+01
+ 0.13704636E+01 0.13648527E+01 0.13592609E+01 0.13536882E+01 0.13481345E+01
+ 0.13425997E+01 0.13370838E+01 0.13315867E+01 0.13261085E+01 0.13206489E+01
+ 0.13152081E+01 0.13097860E+01 0.13043824E+01 0.12989974E+01 0.12936308E+01
+ 0.12882827E+01 0.12829531E+01 0.12776417E+01 0.12723487E+01 0.12670739E+01
+ 0.12618173E+01 0.12565789E+01 0.12513586E+01 0.12461564E+01 0.12409721E+01
+ 0.12358058E+01 0.12306575E+01 0.12255270E+01 0.12204143E+01 0.12153194E+01
+ 0.12102422E+01 0.12051826E+01 0.12001407E+01 0.11951164E+01 0.11901096E+01
+ 0.11851203E+01 0.11801485E+01 0.11751940E+01 0.11702569E+01 0.11653370E+01
+ 0.11604345E+01 0.11555491E+01 0.11506808E+01 0.11458297E+01 0.11409957E+01
+ 0.11361786E+01 0.11313785E+01 0.11265954E+01 0.11218291E+01 0.11170797E+01
+ 0.11123470E+01 0.11076311E+01 0.11029319E+01 0.10982493E+01 0.10935833E+01
+ 0.10889339E+01 0.10843010E+01 0.10796845E+01 0.10750845E+01 0.10705008E+01
+ 0.10659335E+01 0.10613824E+01 0.10568476E+01 0.10523290E+01 0.10478265E+01
+ 0.10433402E+01 0.10388699E+01 0.10344156E+01 0.10299773E+01 0.10255549E+01
+ 0.10211484E+01 0.10167577E+01 0.10123828E+01 0.10080237E+01 0.10036803E+01
+ 0.99935251E+00 0.99504036E+00 0.99074379E+00 0.98646275E+00 0.98219720E+00
+ 0.97794709E+00 0.97371237E+00 0.96949302E+00 0.96528898E+00 0.96110021E+00
+ 0.95692666E+00 0.95276830E+00 0.94862508E+00 0.94449696E+00 0.94038389E+00
+ 0.93628584E+00 0.93220276E+00 0.92813460E+00 0.92408133E+00 0.92004290E+00
+ 0.91601928E+00 0.91201041E+00 0.90801626E+00 0.90403678E+00 0.90007194E+00
+ 0.89612168E+00 0.89218598E+00 0.88826478E+00 0.88435805E+00 0.88046574E+00
+ 0.87658782E+00 0.87272423E+00 0.86887495E+00 0.86503993E+00 0.86121912E+00
+ 0.85741249E+00 0.85361999E+00 0.84984159E+00 0.84607725E+00 0.84232691E+00
+ 0.83859055E+00 0.83486813E+00 0.83115959E+00 0.82746490E+00 0.82378403E+00
+ 0.82011692E+00 0.81646355E+00 0.81282387E+00 0.80919783E+00 0.80558541E+00
+ 0.80198656E+00 0.79840123E+00 0.79482940E+00 0.79127102E+00 0.78772605E+00
+ 0.78419446E+00 0.78067619E+00 0.77717122E+00 0.77367951E+00 0.77020101E+00
+ 0.76673568E+00 0.76328350E+00 0.75984441E+00 0.75641838E+00 0.75300537E+00
+ 0.74960534E+00 0.74621826E+00 0.74284408E+00 0.73948276E+00 0.73613428E+00
+ 0.73279858E+00 0.72947564E+00 0.72616541E+00 0.72286785E+00 0.71958293E+00
+ 0.71631061E+00 0.71305085E+00 0.70980361E+00 0.70656886E+00 0.70334656E+00
+ 0.70013666E+00 0.69693914E+00 0.69375396E+00 0.69058107E+00 0.68742045E+00
+ 0.68427205E+00 0.68113583E+00 0.67801177E+00 0.67489982E+00 0.67179994E+00
+ 0.66871211E+00 0.66563627E+00 0.66257240E+00 0.65952046E+00 0.65648042E+00
+ 0.65345222E+00 0.65043585E+00 0.64743127E+00 0.64443843E+00 0.64145730E+00
+ 0.63848784E+00 0.63553003E+00 0.63258382E+00 0.62964917E+00 0.62672606E+00
+ 0.62381444E+00 0.62091429E+00 0.61802556E+00 0.61514822E+00 0.61228223E+00
+ 0.60942756E+00 0.60658418E+00 0.60375204E+00 0.60093111E+00 0.59812137E+00
+ 0.59532277E+00 0.59253527E+00 0.58975885E+00 0.58699347E+00 0.58423909E+00
+ 0.58149568E+00 0.57876321E+00 0.57604164E+00 0.57333093E+00 0.57063106E+00
+ 0.56794198E+00 0.56526367E+00 0.56259609E+00 0.55993920E+00 0.55729297E+00
+ 0.55465738E+00 0.55203237E+00 0.54941793E+00 0.54681401E+00 0.54422059E+00
+ 0.54163762E+00 0.53906509E+00 0.53650294E+00 0.53395116E+00 0.53140970E+00
+ 0.52887853E+00 0.52635762E+00 0.52384695E+00 0.52134646E+00 0.51885614E+00
+ 0.51637594E+00 0.51390585E+00 0.51144581E+00 0.50899581E+00 0.50655580E+00
+ 0.50412576E+00 0.50170565E+00 0.49929545E+00 0.49689511E+00 0.49450461E+00
+ 0.49212392E+00 0.48975299E+00 0.48739181E+00 0.48504034E+00 0.48269855E+00
+ 0.48036640E+00 0.47804386E+00 0.47573091E+00 0.47342751E+00 0.47113362E+00
+ 0.46884923E+00 0.46657429E+00 0.46430878E+00 0.46205266E+00 0.45980591E+00
+ 0.45756849E+00 0.45534037E+00 0.45312152E+00 0.45091191E+00 0.44871150E+00
+ 0.44652028E+00 0.44433821E+00 0.44216525E+00 0.44000138E+00 0.43784657E+00
+ 0.43570078E+00 0.43356399E+00 0.43143616E+00 0.42931727E+00 0.42720728E+00
+ 0.42510617E+00 0.42301391E+00 0.42093046E+00 0.41885580E+00 0.41678990E+00
+ 0.41473272E+00 0.41268424E+00 0.41064443E+00 0.40861325E+00 0.40659069E+00
+ 0.40457670E+00 0.40257127E+00 0.40057436E+00 0.39858594E+00 0.39660598E+00
+ 0.39463446E+00 0.39267134E+00 0.39071660E+00 0.38877021E+00 0.38683214E+00
+ 0.38490236E+00 0.38298077E+00 0.38106472E+00 0.37915289E+00 0.37724529E+00
+ 0.37534191E+00 0.37344277E+00 0.37154787E+00 0.36965721E+00 0.36777080E+00
+ 0.36588864E+00 0.36401074E+00 0.36213710E+00 0.36026772E+00 0.35840262E+00
+ 0.35654179E+00 0.35468524E+00 0.35283297E+00 0.35098499E+00 0.34914130E+00
+ 0.34730192E+00 0.34546683E+00 0.34363605E+00 0.34180958E+00 0.33998743E+00
+ 0.33816960E+00 0.33635609E+00 0.33454692E+00 0.33274207E+00 0.33094157E+00
+ 0.32914541E+00 0.32735359E+00 0.32556613E+00 0.32378302E+00 0.32200428E+00
+ 0.32022990E+00 0.31845989E+00 0.31669426E+00 0.31493300E+00 0.31317613E+00
+ 0.31142365E+00 0.30967556E+00 0.30793187E+00 0.30619258E+00 0.30445770E+00
+ 0.30272722E+00 0.30100117E+00 0.29927953E+00 0.29756232E+00 0.29584954E+00
+ 0.29414119E+00 0.29243728E+00 0.29073782E+00 0.28904280E+00 0.28735223E+00
+ 0.28566612E+00 0.28398447E+00 0.28230729E+00 0.28063457E+00 0.27896634E+00
+ 0.27730258E+00 0.27564330E+00 0.27398851E+00 0.27233822E+00 0.27069242E+00
+ 0.26905113E+00 0.26741434E+00 0.26578207E+00 0.26415430E+00 0.26253106E+00
+ 0.26091235E+00 0.25929816E+00 0.25768851E+00 0.25608339E+00 0.25448282E+00
+ 0.25288680E+00 0.25129532E+00 0.24970841E+00 0.24812605E+00 0.24654826E+00
+ 0.24497505E+00 0.24340640E+00 0.24184234E+00 0.24028286E+00 0.23872796E+00
+ 0.23717766E+00 0.23563196E+00 0.23409086E+00 0.23255437E+00 0.23102248E+00
+ 0.22949522E+00 0.22797257E+00 0.22645455E+00 0.22494115E+00 0.22343240E+00
+ 0.22192827E+00 0.22042880E+00 0.21893397E+00 0.21744379E+00 0.21595826E+00
+ 0.21447740E+00 0.21300121E+00 0.21152968E+00 0.21006283E+00 0.20860066E+00
+ 0.20714317E+00 0.20569037E+00 0.20424227E+00 0.20279886E+00 0.20136015E+00
+ 0.19992615E+00 0.19849686E+00 0.19707228E+00 0.19565243E+00 0.19423730E+00
+ 0.19282690E+00 0.19142123E+00 0.19002031E+00 0.18862412E+00 0.18723268E+00
+ 0.18584600E+00 0.18446407E+00 0.18308690E+00 0.18171449E+00 0.18034686E+00
+ 0.17898400E+00 0.17762592E+00 0.17627263E+00 0.17492412E+00 0.17358041E+00
+ 0.17224149E+00 0.17090737E+00 0.16957807E+00 0.16825357E+00 0.16693389E+00
+ 0.16561902E+00 0.16430899E+00 0.16300378E+00 0.16170340E+00 0.16040787E+00
+ 0.15911717E+00 0.15783133E+00 0.15655033E+00 0.15527419E+00 0.15400292E+00
+ 0.15273650E+00 0.15147496E+00 0.15021829E+00 0.14896651E+00 0.14771960E+00
+ 0.14647759E+00 0.14524046E+00 0.14400824E+00 0.14278091E+00 0.14155849E+00
+ 0.14034099E+00 0.13912840E+00 0.13792073E+00 0.13671798E+00 0.13552016E+00
+ 0.13432728E+00 0.13313933E+00 0.13195633E+00 0.13077827E+00 0.12960517E+00
+ 0.12843702E+00 0.12727383E+00 0.12611561E+00 0.12496236E+00 0.12381408E+00
+ 0.12267079E+00 0.12153247E+00 0.12039915E+00 0.11927081E+00 0.11814748E+00
+ 0.11702914E+00 0.11591581E+00 0.11480750E+00 0.11370420E+00 0.11260591E+00
+ 0.11151266E+00 0.11042443E+00 0.10934123E+00 0.10826308E+00 0.10718996E+00
+ 0.10612190E+00 0.10505888E+00 0.10400093E+00 0.10294803E+00 0.10190020E+00
+ 0.10085743E+00 0.99819747E-01 0.98787138E-01 0.97759613E-01 0.96737177E-01
+ 0.95719833E-01 0.94707586E-01 0.93700440E-01 0.92698402E-01 0.91701474E-01
+ 0.90709661E-01 0.89722968E-01 0.88741400E-01 0.87764961E-01 0.86793655E-01
+ 0.85827487E-01 0.84866462E-01 0.83910585E-01 0.82959858E-01 0.82014289E-01
+ 0.81073880E-01 0.80138636E-01 0.79208562E-01 0.78283663E-01 0.77363943E-01
+ 0.76449406E-01 0.75540058E-01 0.74635901E-01 0.73736943E-01 0.72843185E-01
+ 0.71954634E-01 0.71071294E-01 0.70193170E-01 0.69320265E-01 0.68452584E-01
+ 0.67590133E-01 0.66732915E-01 0.65880935E-01 0.65034197E-01 0.64192707E-01
+ 0.63356468E-01 0.62525486E-01 0.61699765E-01 0.60879308E-01 0.60064122E-01
+ 0.59254210E-01 0.58449577E-01 0.57650227E-01 0.56856166E-01 0.56067397E-01
+ 0.55283925E-01 0.54505755E-01 0.53732891E-01 0.52965338E-01 0.52203100E-01
+ 0.51446181E-01 0.50694588E-01 0.49948323E-01 0.49207392E-01 0.48471798E-01
+ 0.47741547E-01 0.47016644E-01 0.46297092E-01 0.45582896E-01 0.44874061E-01
+ 0.44170591E-01 0.43472491E-01 0.42779765E-01 0.42092418E-01 0.41410455E-01
+ 0.40733879E-01 0.40062696E-01 0.39396910E-01 0.38736526E-01 0.38081548E-01
+ 0.37431981E-01 0.36787829E-01 0.36149096E-01 0.35515788E-01 0.34887909E-01
+ 0.34265463E-01 0.33648456E-01 0.33036890E-01 0.32430772E-01 0.31830106E-01
+ 0.31234895E-01 0.30645145E-01 0.30060861E-01 0.29482046E-01 0.28908705E-01
+ 0.28340844E-01 0.27778466E-01 0.27221575E-01 0.26670177E-01 0.26124277E-01
+ 0.25583877E-01 0.25048984E-01 0.24519602E-01 0.23995734E-01 0.23477387E-01
+ 0.22964564E-01 0.22457269E-01 0.21955508E-01 0.21459285E-01 0.20968604E-01
+ 0.20483470E-01 0.20003888E-01 0.19529862E-01 0.19061397E-01 0.18598497E-01
+ 0.18141166E-01 0.17689410E-01 0.17243232E-01 0.16802638E-01 0.16367632E-01
+ 0.15938218E-01 0.15514401E-01 0.15096186E-01 0.14683577E-01 0.14276578E-01
+ 0.13875195E-01 0.13479431E-01 0.13089291E-01 0.12704780E-01 0.12325903E-01
+ 0.11952663E-01 0.11585066E-01 0.11223116E-01 0.10866817E-01 0.10516175E-01
+ 0.10171193E-01 0.98318756E-02 0.94982283E-02 0.91702552E-02 0.88479609E-02
+ 0.85313499E-02 0.82204267E-02 0.79151960E-02 0.76156621E-02 0.73218297E-02
+ 0.70337034E-02 0.67512876E-02 0.64745869E-02 0.62036059E-02 0.59383490E-02
+ 0.56788209E-02 0.54250261E-02 0.51769690E-02 0.49346544E-02 0.46980867E-02
+ 0.44672704E-02 0.42422101E-02 0.40229103E-02 0.38093757E-02 0.36016106E-02
+ 0.33996197E-02 0.32034076E-02 0.30129787E-02 0.28283376E-02 0.26494888E-02
+ 0.24764369E-02 0.23091865E-02 0.21477420E-02 0.19921080E-02 0.18422891E-02
+ 0.16982898E-02 0.15601146E-02 0.14277682E-02 0.13012549E-02 0.11805795E-02
+ 0.10657463E-02 0.95676006E-03 0.85362519E-03 0.75634627E-03 0.66492784E-03
+ 0.57937444E-03 0.49969063E-03 0.42588094E-03 0.35794991E-03 0.29590210E-03
+ 0.23974203E-03 0.18947427E-03 0.14510334E-03 0.10663380E-03 0.74070178E-04
+ 0.47417029E-04 0.26678894E-04 0.11860315E-04 0.29658360E-05 0.00000000E+00
+ 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03
+ 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03
+ 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03
+ 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03
+ 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03
+ 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03
+ 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03
+ 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03
+ 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03
+ 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03
+ 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03 0.79216962E+03
+ 0.78778870E+03 0.76945282E+03 0.75185631E+03 0.73495714E+03 0.71871634E+03
+ 0.70309772E+03 0.68806765E+03 0.67359482E+03 0.65965006E+03 0.64620616E+03
+ 0.63323770E+03 0.62072093E+03 0.60863360E+03 0.59695489E+03 0.58566526E+03
+ 0.57474637E+03 0.56418100E+03 0.55395295E+03 0.54404698E+03 0.53444871E+03
+ 0.52514463E+03 0.51612195E+03 0.50736862E+03 0.49887325E+03 0.49062505E+03
+ 0.48261383E+03 0.47482995E+03 0.46726424E+03 0.45990804E+03 0.45275311E+03
+ 0.44579163E+03 0.43901620E+03 0.43241974E+03 0.42599554E+03 0.41973722E+03
+ 0.41363869E+03 0.40769416E+03 0.40189809E+03 0.39624523E+03 0.39073054E+03
+ 0.38534922E+03 0.38009668E+03 0.37496855E+03 0.36996063E+03 0.36506890E+03
+ 0.36028955E+03 0.35561888E+03 0.35105340E+03 0.34658971E+03 0.34222459E+03
+ 0.33795495E+03 0.33377780E+03 0.32969030E+03 0.32568970E+03 0.32177337E+03
+ 0.31793878E+03 0.31418350E+03 0.31050518E+03 0.30690159E+03 0.30337056E+03
+ 0.29990999E+03 0.29651790E+03 0.29319233E+03 0.28993144E+03 0.28673343E+03
+ 0.28359656E+03 0.28051916E+03 0.27749964E+03 0.27453643E+03 0.27162803E+03
+ 0.26877299E+03 0.26596993E+03 0.26321747E+03 0.26051432E+03 0.25785922E+03
+ 0.25525095E+03 0.25268831E+03 0.25017018E+03 0.24769545E+03 0.24526304E+03
+ 0.24287192E+03 0.24052109E+03 0.23820958E+03 0.23593644E+03 0.23370077E+03
+ 0.23150167E+03 0.22933829E+03 0.22720981E+03 0.22511541E+03 0.22305431E+03
+ 0.22102576E+03 0.21902901E+03 0.21706336E+03 0.21512810E+03 0.21322257E+03
+ 0.21134610E+03 0.20949807E+03 0.20767786E+03 0.20588485E+03 0.20411848E+03
+ 0.20237817E+03 0.20066337E+03 0.19897355E+03 0.19730817E+03 0.19566674E+03
+ 0.19404876E+03 0.19245374E+03 0.19088123E+03 0.18933075E+03 0.18780187E+03
+ 0.18629416E+03 0.18480719E+03 0.18334056E+03 0.18189386E+03 0.18046670E+03
+ 0.17905871E+03 0.17766951E+03 0.17629874E+03 0.17494605E+03 0.17361110E+03
+ 0.17229355E+03 0.17099307E+03 0.16970935E+03 0.16844208E+03 0.16719094E+03
+ 0.16595565E+03 0.16473592E+03 0.16353146E+03 0.16234199E+03 0.16116725E+03
+ 0.16000698E+03 0.15886091E+03 0.15772880E+03 0.15661040E+03 0.15550547E+03
+ 0.15441377E+03 0.15333509E+03 0.15226918E+03 0.15121584E+03 0.15017485E+03
+ 0.14914601E+03 0.14812909E+03 0.14712391E+03 0.14613028E+03 0.14514799E+03
+ 0.14417686E+03 0.14321670E+03 0.14226735E+03 0.14132861E+03 0.14040032E+03
+ 0.13948232E+03 0.13857443E+03 0.13767649E+03 0.13678835E+03 0.13590985E+03
+ 0.13504083E+03 0.13418116E+03 0.13333068E+03 0.13248926E+03 0.13165674E+03
+ 0.13083300E+03 0.13001790E+03 0.12921131E+03 0.12841310E+03 0.12762315E+03
+ 0.12684132E+03 0.12606749E+03 0.12530156E+03 0.12454340E+03 0.12379289E+03
+ 0.12304993E+03 0.12231440E+03 0.12158620E+03 0.12086521E+03 0.12015134E+03
+ 0.11944448E+03 0.11874454E+03 0.11805141E+03 0.11736499E+03 0.11668520E+03
+ 0.11601193E+03 0.11534510E+03 0.11468462E+03 0.11403040E+03 0.11338235E+03
+ 0.11274039E+03 0.11210443E+03 0.11147439E+03 0.11085020E+03 0.11023177E+03
+ 0.10961902E+03 0.10901188E+03 0.10841027E+03 0.10781412E+03 0.10722336E+03
+ 0.10663791E+03 0.10605771E+03 0.10548268E+03 0.10491276E+03 0.10434789E+03
+ 0.10378799E+03 0.10323300E+03 0.10268287E+03 0.10213752E+03 0.10159689E+03
+ 0.10106093E+03 0.10052958E+03 0.10000278E+03 0.99480469E+02 0.98962593E+02
+ 0.98449096E+02 0.97939925E+02 0.97435026E+02 0.96934346E+02 0.96437833E+02
+ 0.95945436E+02 0.95457104E+02 0.94972790E+02 0.94492443E+02 0.94016016E+02
+ 0.93543462E+02 0.93074735E+02 0.92609788E+02 0.92148577E+02 0.91691057E+02
+ 0.91237185E+02 0.90786918E+02 0.90340214E+02 0.89897032E+02 0.89457329E+02
+ 0.89021066E+02 0.88588202E+02 0.88158700E+02 0.87732520E+02 0.87309624E+02
+ 0.86889975E+02 0.86473536E+02 0.86060270E+02 0.85650142E+02 0.85243117E+02
+ 0.84839159E+02 0.84438235E+02 0.84040310E+02 0.83645352E+02 0.83253327E+02
+ 0.82864204E+02 0.82477951E+02 0.82094535E+02 0.81713926E+02 0.81336094E+02
+ 0.80961009E+02 0.80588641E+02 0.80218960E+02 0.79851937E+02 0.79487546E+02
+ 0.79125756E+02 0.78766541E+02 0.78409874E+02 0.78055727E+02 0.77704074E+02
+ 0.77354889E+02 0.77008146E+02 0.76663820E+02 0.76321885E+02 0.75982317E+02
+ 0.75645091E+02 0.75310184E+02 0.74977571E+02 0.74647228E+02 0.74319134E+02
+ 0.73993265E+02 0.73669598E+02 0.73348112E+02 0.73028784E+02 0.72711592E+02
+ 0.72396516E+02 0.72083534E+02 0.71772625E+02 0.71463769E+02 0.71156946E+02
+ 0.70852135E+02 0.70549317E+02 0.70248472E+02 0.69949581E+02 0.69652625E+02
+ 0.69357585E+02 0.69064443E+02 0.68773180E+02 0.68483778E+02 0.68196220E+02
+ 0.67910488E+02 0.67626564E+02 0.67344431E+02 0.67064073E+02 0.66785472E+02
+ 0.66508611E+02 0.66233476E+02 0.65960049E+02 0.65688314E+02 0.65418256E+02
+ 0.65149859E+02 0.64883108E+02 0.64617988E+02 0.64354483E+02 0.64092579E+02
+ 0.63832261E+02 0.63573515E+02 0.63316326E+02 0.63060680E+02 0.62806563E+02
+ 0.62553962E+02 0.62302863E+02 0.62053252E+02 0.61805116E+02 0.61558442E+02
+ 0.61313217E+02 0.61069428E+02 0.60827062E+02 0.60586107E+02 0.60346551E+02
+ 0.60108380E+02 0.59871584E+02 0.59636149E+02 0.59402065E+02 0.59169319E+02
+ 0.58937900E+02 0.58707796E+02 0.58478996E+02 0.58251490E+02 0.58025265E+02
+ 0.57800311E+02 0.57576617E+02 0.57354173E+02 0.57132967E+02 0.56912990E+02
+ 0.56694230E+02 0.56476679E+02 0.56260325E+02 0.56045159E+02 0.55831170E+02
+ 0.55618350E+02 0.55406688E+02 0.55196174E+02 0.54986800E+02 0.54778556E+02
+ 0.54571433E+02 0.54365421E+02 0.54160511E+02 0.53956695E+02 0.53753964E+02
+ 0.53552308E+02 0.53351720E+02 0.53152190E+02 0.52953710E+02 0.52756272E+02
+ 0.52559867E+02 0.52364487E+02 0.52170124E+02 0.51976770E+02 0.51784417E+02
+ 0.51593058E+02 0.51402683E+02 0.51213286E+02 0.51024858E+02 0.50837394E+02
+ 0.50650883E+02 0.50465321E+02 0.50280698E+02 0.50097008E+02 0.49914244E+02
+ 0.49732398E+02 0.49551464E+02 0.49371435E+02 0.49192303E+02 0.49014061E+02
+ 0.48836704E+02 0.48660224E+02 0.48484615E+02 0.48309870E+02 0.48135983E+02
+ 0.47962947E+02 0.47790756E+02 0.47619404E+02 0.47448883E+02 0.47279190E+02
+ 0.47110316E+02 0.46942256E+02 0.46775004E+02 0.46608555E+02 0.46442901E+02
+ 0.46278038E+02 0.46113960E+02 0.45950661E+02 0.45788135E+02 0.45626377E+02
+ 0.45465380E+02 0.45305141E+02 0.45145653E+02 0.44986911E+02 0.44828909E+02
+ 0.44671643E+02 0.44515106E+02 0.44359295E+02 0.44204203E+02 0.44049826E+02
+ 0.43896158E+02 0.43743196E+02 0.43590932E+02 0.43439364E+02 0.43288486E+02
+ 0.43138293E+02 0.42988780E+02 0.42839943E+02 0.42691777E+02 0.42544278E+02
+ 0.42397440E+02 0.42251259E+02 0.42105732E+02 0.41960853E+02 0.41816618E+02
+ 0.41673022E+02 0.41530062E+02 0.41387732E+02 0.41246029E+02 0.41104949E+02
+ 0.40964487E+02 0.40824640E+02 0.40685402E+02 0.40546770E+02 0.40408741E+02
+ 0.40271309E+02 0.40134471E+02 0.39998224E+02 0.39862563E+02 0.39727484E+02
+ 0.39592984E+02 0.39459058E+02 0.39325704E+02 0.39192917E+02 0.39060694E+02
+ 0.38929030E+02 0.38797924E+02 0.38667369E+02 0.38537365E+02 0.38407906E+02
+ 0.38278989E+02 0.38150611E+02 0.38022768E+02 0.37895458E+02 0.37768676E+02
+ 0.37642419E+02 0.37516684E+02 0.37391468E+02 0.37266767E+02 0.37142579E+02
+ 0.37018899E+02 0.36895725E+02 0.36773054E+02 0.36650883E+02 0.36529208E+02
+ 0.36408026E+02 0.36287335E+02 0.36167131E+02 0.36047412E+02 0.35928174E+02
+ 0.35809414E+02 0.35691130E+02 0.35573319E+02 0.35455977E+02 0.35339103E+02
+ 0.35222692E+02 0.35106743E+02 0.34991253E+02 0.34876218E+02 0.34761636E+02
+ 0.34647505E+02 0.34533822E+02 0.34420584E+02 0.34307788E+02 0.34195432E+02
+ 0.34083514E+02 0.33972030E+02 0.33860978E+02 0.33750356E+02 0.33640161E+02
+ 0.33530391E+02 0.33421042E+02 0.33312114E+02 0.33203603E+02 0.33095506E+02
+ 0.32987822E+02 0.32880549E+02 0.32773683E+02 0.32667222E+02 0.32561165E+02
+ 0.32455509E+02 0.32350251E+02 0.32245389E+02 0.32140922E+02 0.32036846E+02
+ 0.31933160E+02 0.31829862E+02 0.31726949E+02 0.31624419E+02 0.31522270E+02
+ 0.31420500E+02 0.31319107E+02 0.31218089E+02 0.31117443E+02 0.31017168E+02
+ 0.30917261E+02 0.30817721E+02 0.30718546E+02 0.30619733E+02 0.30521281E+02
+ 0.30423187E+02 0.30325450E+02 0.30228068E+02 0.30131039E+02 0.30034360E+02
+ 0.29938031E+02 0.29842049E+02 0.29746412E+02 0.29651119E+02 0.29556168E+02
+ 0.29461556E+02 0.29367283E+02 0.29273346E+02 0.29179743E+02 0.29086473E+02
+ 0.28993535E+02 0.28900925E+02 0.28808643E+02 0.28716687E+02 0.28625055E+02
+ 0.28533746E+02 0.28442758E+02 0.28352089E+02 0.28261737E+02 0.28171701E+02
+ 0.28081980E+02 0.27992571E+02 0.27903473E+02 0.27814685E+02 0.27726205E+02
+ 0.27638031E+02 0.27550162E+02 0.27462597E+02 0.27375333E+02 0.27288369E+02
+ 0.27201705E+02 0.27115337E+02 0.27029266E+02 0.26943488E+02 0.26858004E+02
+ 0.26772811E+02 0.26687908E+02 0.26603293E+02 0.26518966E+02 0.26434925E+02
+ 0.26351167E+02 0.26267693E+02 0.26184501E+02 0.26101588E+02 0.26018955E+02
+ 0.25936599E+02 0.25854519E+02 0.25772714E+02 0.25691183E+02 0.25609923E+02
+ 0.25528935E+02 0.25448216E+02 0.25367766E+02 0.25287583E+02 0.25207666E+02
+ 0.25128013E+02 0.25048623E+02 0.24969496E+02 0.24890630E+02 0.24812023E+02
+ 0.24733674E+02 0.24655583E+02 0.24577748E+02 0.24500168E+02 0.24422841E+02
+ 0.24345767E+02 0.24268944E+02 0.24192372E+02 0.24116048E+02 0.24039973E+02
+ 0.23964144E+02 0.23888561E+02 0.23813222E+02 0.23738127E+02 0.23663274E+02
+ 0.23588662E+02 0.23514291E+02 0.23440159E+02 0.23366264E+02 0.23292607E+02
+ 0.23219185E+02 0.23145999E+02 0.23073046E+02 0.23000326E+02 0.22927838E+02
+ 0.22855580E+02 0.22783553E+02 0.22711754E+02 0.22640182E+02 0.22568838E+02
+ 0.22497719E+02 0.22426825E+02 0.22356155E+02 0.22285707E+02 0.22215482E+02
+ 0.22145477E+02 0.22075692E+02 0.22006127E+02 0.21936779E+02 0.21867649E+02
+ 0.21798734E+02 0.21730036E+02 0.21661551E+02 0.21593280E+02 0.21525222E+02
+ 0.21457375E+02 0.21389740E+02 0.21322314E+02 0.21255097E+02 0.21188089E+02
+ 0.21121288E+02 0.21054693E+02 0.20988304E+02 0.20922120E+02 0.20856139E+02
+ 0.20790362E+02 0.20724787E+02 0.20659414E+02 0.20594241E+02 0.20529268E+02
+ 0.20464494E+02 0.20399918E+02 0.20335540E+02 0.20271358E+02 0.20207372E+02
+ 0.20143581E+02 0.20079985E+02 0.20016581E+02 0.19953371E+02 0.19890352E+02
+ 0.19827525E+02 0.19764888E+02 0.19702441E+02 0.19640182E+02 0.19578112E+02
+ 0.19516230E+02 0.19454534E+02 0.19393024E+02 0.19331699E+02 0.19270559E+02
+ 0.19209603E+02 0.19148830E+02 0.19088239E+02 0.19027830E+02 0.18967602E+02
+ 0.18907554E+02 0.18847686E+02 0.18787997E+02 0.18728486E+02 0.18669153E+02
+ 0.18609997E+02 0.18551017E+02 0.18492212E+02 0.18433583E+02 0.18375128E+02
+ 0.18316846E+02 0.18258738E+02 0.18200801E+02 0.18143037E+02 0.18085443E+02
+ 0.18028020E+02 0.17970767E+02 0.17913683E+02 0.17856768E+02 0.17800020E+02
+ 0.17743440E+02 0.17687026E+02 0.17630779E+02 0.17574697E+02 0.17518780E+02
+ 0.17463027E+02 0.17407439E+02 0.17352013E+02 0.17296749E+02 0.17241648E+02
+ 0.17186708E+02 0.17131929E+02 0.17077310E+02 0.17022851E+02 0.16968551E+02
+ 0.16914409E+02 0.16860425E+02 0.16806599E+02 0.16752930E+02 0.16699417E+02
+ 0.16646059E+02 0.16592857E+02 0.16539810E+02 0.16486917E+02 0.16434177E+02
+ 0.16381591E+02 0.16329157E+02 0.16276875E+02 0.16224744E+02 0.16172765E+02
+ 0.16120936E+02 0.16069257E+02 0.16017727E+02 0.15966347E+02 0.15915115E+02
+ 0.15864030E+02 0.15813094E+02 0.15762304E+02 0.15711660E+02 0.15661163E+02
+ 0.15610811E+02 0.15560604E+02 0.15510541E+02 0.15460623E+02 0.15410848E+02
+ 0.15361216E+02 0.15311727E+02 0.15262379E+02 0.15213174E+02 0.15164109E+02
+ 0.15115186E+02 0.15066402E+02 0.15017759E+02 0.14969255E+02 0.14920889E+02
+ 0.14872663E+02 0.14824574E+02 0.14776622E+02 0.14728808E+02 0.14681131E+02
+ 0.14633589E+02 0.14586184E+02 0.14538914E+02 0.14491779E+02 0.14444778E+02
+ 0.14397911E+02 0.14351179E+02 0.14304579E+02 0.14258112E+02 0.14211777E+02
+ 0.14165575E+02 0.14119504E+02 0.14073564E+02 0.14027755E+02 0.13982076E+02
+ 0.13936527E+02 0.13891108E+02 0.13845818E+02 0.13800657E+02 0.13755623E+02
+ 0.13710718E+02 0.13665941E+02 0.13621290E+02 0.13576766E+02 0.13532369E+02
+ 0.13488098E+02 0.13443952E+02 0.13399931E+02 0.13356035E+02 0.13312264E+02
+ 0.13268617E+02 0.13225094E+02 0.13181693E+02 0.13138416E+02 0.13095262E+02
+ 0.13052229E+02 0.13009319E+02 0.12966530E+02 0.12923862E+02 0.12881315E+02
+ 0.12838889E+02 0.12796582E+02 0.12754395E+02 0.12712328E+02 0.12670380E+02
+ 0.12628550E+02 0.12586838E+02 0.12545245E+02 0.12503769E+02 0.12462411E+02
+ 0.12421169E+02 0.12380044E+02 0.12339035E+02 0.12298143E+02 0.12257365E+02
+ 0.12216703E+02 0.12176156E+02 0.12135724E+02 0.12095406E+02 0.12055202E+02
+ 0.12015111E+02 0.11975134E+02 0.11935270E+02 0.11895518E+02 0.11855879E+02
+ 0.11816351E+02 0.11776936E+02 0.11737632E+02 0.11698438E+02 0.11659356E+02
+ 0.11620384E+02 0.11581522E+02 0.11542770E+02 0.11504128E+02 0.11465595E+02
+ 0.11427170E+02 0.11388855E+02 0.11350647E+02 0.11312548E+02 0.11274556E+02
+ 0.11236672E+02 0.11198895E+02 0.11161224E+02 0.11123661E+02 0.11086203E+02
+ 0.11048851E+02 0.11011606E+02 0.10974465E+02 0.10937429E+02 0.10900499E+02
+ 0.10863672E+02 0.10826950E+02 0.10790332E+02 0.10753818E+02 0.10717407E+02
+ 0.10681099E+02 0.10644894E+02 0.10608792E+02 0.10572791E+02 0.10536893E+02
+ 0.10501097E+02 0.10465401E+02 0.10429808E+02 0.10394315E+02 0.10358922E+02
+ 0.10323630E+02 0.10288439E+02 0.10253347E+02 0.10218354E+02 0.10183461E+02
+ 0.10148667E+02 0.10113972E+02 0.10079375E+02 0.10044877E+02 0.10010476E+02
+ 0.99761736E+01 0.99419685E+01 0.99078606E+01 0.98738498E+01 0.98399356E+01
+ 0.98061180E+01 0.97723966E+01 0.97387712E+01 0.97052416E+01 0.96718074E+01
+ 0.96384685E+01 0.96052246E+01 0.95720754E+01 0.95390208E+01 0.95060604E+01
+ 0.94731941E+01 0.94404216E+01 0.94077426E+01 0.93751569E+01 0.93426643E+01
+ 0.93102645E+01 0.92779573E+01 0.92457424E+01 0.92136197E+01 0.91815889E+01
+ 0.91496497E+01 0.91178020E+01 0.90860454E+01 0.90543798E+01 0.90228049E+01
+ 0.89913206E+01 0.89599265E+01 0.89286225E+01 0.88974082E+01 0.88662836E+01
+ 0.88352483E+01 0.88043022E+01 0.87734450E+01 0.87426765E+01 0.87119965E+01
+ 0.86814047E+01 0.86509010E+01 0.86204851E+01 0.85901567E+01 0.85599158E+01
+ 0.85297620E+01 0.84996952E+01 0.84697150E+01 0.84398215E+01 0.84100142E+01
+ 0.83802929E+01 0.83506576E+01 0.83211079E+01 0.82916437E+01 0.82622647E+01
+ 0.82329707E+01 0.82037616E+01 0.81746370E+01 0.81455969E+01 0.81166410E+01
+ 0.80877690E+01 0.80589809E+01 0.80302763E+01 0.80016551E+01 0.79731170E+01
+ 0.79446619E+01 0.79162896E+01 0.78879999E+01 0.78597925E+01 0.78316673E+01
+ 0.78036240E+01 0.77756625E+01 0.77477825E+01 0.77199839E+01 0.76922665E+01
+ 0.76646301E+01 0.76370744E+01 0.76095993E+01 0.75822046E+01 0.75548900E+01
+ 0.75276555E+01 0.75005007E+01 0.74734256E+01 0.74464299E+01 0.74195134E+01
+ 0.73926760E+01 0.73659173E+01 0.73392374E+01 0.73126359E+01 0.72861127E+01
+ 0.72596675E+01 0.72333003E+01 0.72070108E+01 0.71807988E+01 0.71546641E+01
+ 0.71286066E+01 0.71026261E+01 0.70767224E+01 0.70508952E+01 0.70251445E+01
+ 0.69994700E+01 0.69738716E+01 0.69483490E+01 0.69229021E+01 0.68975308E+01
+ 0.68722348E+01 0.68470139E+01 0.68218680E+01 0.67967969E+01 0.67718004E+01
+ 0.67468783E+01 0.67220305E+01 0.66972568E+01 0.66725570E+01 0.66479309E+01
+ 0.66233784E+01 0.65988993E+01 0.65744933E+01 0.65501604E+01 0.65259004E+01
+ 0.65017130E+01 0.64775982E+01 0.64535557E+01 0.64295854E+01 0.64056870E+01
+ 0.63818606E+01 0.63581057E+01 0.63344224E+01 0.63108103E+01 0.62872695E+01
+ 0.62637996E+01 0.62404005E+01 0.62170721E+01 0.61938141E+01 0.61706265E+01
+ 0.61475090E+01 0.61244615E+01 0.61014838E+01 0.60785757E+01 0.60557372E+01
+ 0.60329679E+01 0.60102679E+01 0.59876368E+01 0.59650745E+01 0.59425809E+01
+ 0.59201558E+01 0.58977991E+01 0.58755106E+01 0.58532900E+01 0.58311374E+01
+ 0.58090524E+01 0.57870350E+01 0.57650849E+01 0.57432021E+01 0.57213863E+01
+ 0.56996375E+01 0.56779553E+01 0.56563398E+01 0.56347907E+01 0.56133079E+01
+ 0.55918912E+01 0.55705405E+01 0.55492556E+01 0.55280363E+01 0.55068825E+01
+ 0.54857940E+01 0.54647708E+01 0.54438126E+01 0.54229192E+01 0.54020906E+01
+ 0.53813265E+01 0.53606269E+01 0.53399915E+01 0.53194203E+01 0.52989130E+01
+ 0.52784695E+01 0.52580897E+01 0.52377734E+01 0.52175205E+01 0.51973307E+01
+ 0.51772040E+01 0.51571403E+01 0.51371393E+01 0.51172009E+01 0.50973249E+01
+ 0.50775113E+01 0.50577599E+01 0.50380704E+01 0.50184429E+01 0.49988770E+01
+ 0.49793728E+01 0.49599300E+01 0.49405484E+01 0.49212281E+01 0.49019687E+01
+ 0.48827701E+01 0.48636323E+01 0.48445550E+01 0.48255381E+01 0.48065815E+01
+ 0.47876851E+01 0.47688486E+01 0.47500720E+01 0.47313550E+01 0.47126977E+01
+ 0.46940997E+01 0.46755610E+01 0.46570815E+01 0.46386609E+01 0.46202992E+01
+ 0.46019962E+01 0.45837518E+01 0.45655658E+01 0.45474381E+01 0.45293685E+01
+ 0.45113569E+01 0.44934033E+01 0.44755073E+01 0.44576689E+01 0.44398880E+01
+ 0.44221644E+01 0.44044980E+01 0.43868886E+01 0.43693362E+01 0.43518405E+01
+ 0.43344014E+01 0.43170188E+01 0.42996926E+01 0.42824226E+01 0.42652087E+01
+ 0.42480507E+01 0.42309485E+01 0.42139020E+01 0.41969111E+01 0.41799756E+01
+ 0.41630953E+01 0.41462702E+01 0.41295001E+01 0.41127849E+01 0.40961244E+01
+ 0.40795185E+01 0.40629671E+01 0.40464701E+01 0.40300272E+01 0.40136385E+01
+ 0.39973036E+01 0.39810226E+01 0.39647953E+01 0.39486215E+01 0.39325012E+01
+ 0.39164341E+01 0.39004202E+01 0.38844593E+01 0.38685514E+01 0.38526962E+01
+ 0.38368936E+01 0.38211436E+01 0.38054459E+01 0.37898005E+01 0.37742072E+01
+ 0.37586659E+01 0.37431765E+01 0.37277388E+01 0.37123527E+01 0.36970181E+01
+ 0.36817349E+01 0.36665029E+01 0.36513220E+01 0.36361921E+01 0.36211130E+01
+ 0.36060847E+01 0.35911069E+01 0.35761797E+01 0.35613028E+01 0.35464761E+01
+ 0.35316995E+01 0.35169728E+01 0.35022960E+01 0.34876690E+01 0.34730915E+01
+ 0.34585635E+01 0.34440849E+01 0.34296555E+01 0.34152752E+01 0.34009438E+01
+ 0.33866614E+01 0.33724276E+01 0.33582425E+01 0.33441058E+01 0.33300176E+01
+ 0.33159775E+01 0.33019856E+01 0.32880417E+01 0.32741457E+01 0.32602975E+01
+ 0.32464968E+01 0.32327437E+01 0.32190380E+01 0.32053796E+01 0.31917683E+01
+ 0.31782040E+01 0.31646867E+01 0.31512162E+01 0.31377923E+01 0.31244150E+01
+ 0.31110841E+01 0.30977996E+01 0.30845612E+01 0.30713690E+01 0.30582227E+01
+ 0.30451222E+01 0.30320675E+01 0.30190584E+01 0.30060948E+01 0.29931765E+01
+ 0.29803035E+01 0.29674757E+01 0.29546929E+01 0.29419549E+01 0.29292618E+01
+ 0.29166134E+01 0.29040095E+01 0.28914500E+01 0.28789349E+01 0.28664640E+01
+ 0.28540372E+01 0.28416544E+01 0.28293154E+01 0.28170202E+01 0.28047686E+01
+ 0.27925606E+01 0.27803959E+01 0.27682746E+01 0.27561964E+01 0.27441613E+01
+ 0.27321692E+01 0.27202199E+01 0.27083133E+01 0.26964494E+01 0.26846279E+01
+ 0.26728488E+01 0.26611120E+01 0.26494174E+01 0.26377649E+01 0.26261542E+01
+ 0.26145854E+01 0.26030583E+01 0.25915729E+01 0.25801289E+01 0.25687263E+01
+ 0.25573650E+01 0.25460448E+01 0.25347657E+01 0.25235276E+01 0.25123303E+01
+ 0.25011737E+01 0.24900577E+01 0.24789822E+01 0.24679471E+01 0.24569523E+01
+ 0.24459977E+01 0.24350831E+01 0.24242085E+01 0.24133738E+01 0.24025788E+01
+ 0.23918234E+01 0.23811075E+01 0.23704311E+01 0.23597940E+01 0.23491961E+01
+ 0.23386373E+01 0.23281174E+01 0.23176365E+01 0.23071943E+01 0.22967908E+01
+ 0.22864259E+01 0.22760994E+01 0.22658113E+01 0.22555614E+01 0.22453496E+01
+ 0.22351759E+01 0.22250401E+01 0.22149422E+01 0.22048819E+01 0.21948593E+01
+ 0.21848742E+01 0.21749264E+01 0.21650160E+01 0.21551428E+01 0.21453067E+01
+ 0.21355075E+01 0.21257452E+01 0.21160198E+01 0.21063310E+01 0.20966787E+01
+ 0.20870630E+01 0.20774836E+01 0.20679404E+01 0.20584335E+01 0.20489626E+01
+ 0.20395276E+01 0.20301285E+01 0.20207652E+01 0.20114375E+01 0.20021454E+01
+ 0.19928887E+01 0.19836673E+01 0.19744812E+01 0.19653303E+01 0.19562144E+01
+ 0.19471335E+01 0.19380874E+01 0.19290760E+01 0.19200993E+01 0.19111571E+01
+ 0.19022494E+01 0.18933761E+01 0.18845369E+01 0.18757320E+01 0.18669610E+01
+ 0.18582241E+01 0.18495209E+01 0.18408516E+01 0.18322159E+01 0.18236137E+01
+ 0.18150450E+01 0.18065097E+01 0.17980076E+01 0.17895387E+01 0.17811029E+01
+ 0.17727000E+01 0.17643300E+01 0.17559928E+01 0.17476883E+01 0.17394163E+01
+ 0.17311769E+01 0.17229698E+01 0.17147950E+01 0.17066525E+01 0.16985420E+01
+ 0.16904636E+01 0.16824170E+01 0.16744023E+01 0.16664193E+01 0.16584680E+01
+ 0.16505482E+01 0.16426598E+01 0.16348027E+01 0.16269769E+01 0.16191823E+01
+ 0.16114188E+01 0.16036862E+01 0.15959844E+01 0.15883135E+01 0.15806733E+01
+ 0.15730636E+01 0.15654845E+01 0.15579358E+01 0.15504173E+01 0.15429292E+01
+ 0.15354711E+01 0.15280431E+01 0.15206451E+01 0.15132769E+01 0.15059385E+01
+ 0.14986297E+01 0.14913506E+01 0.14841009E+01 0.14768806E+01 0.14696897E+01
+ 0.14625280E+01 0.14553954E+01 0.14482918E+01 0.14412172E+01 0.14341715E+01
+ 0.14271545E+01 0.14201662E+01 0.14132066E+01 0.14062754E+01 0.13993726E+01
+ 0.13924982E+01 0.13856520E+01 0.13788339E+01 0.13720439E+01 0.13652819E+01
+ 0.13585478E+01 0.13518415E+01 0.13451628E+01 0.13385118E+01 0.13318884E+01
+ 0.13252923E+01 0.13187237E+01 0.13121823E+01 0.13056681E+01 0.12991810E+01
+ 0.12927209E+01 0.12862877E+01 0.12798814E+01 0.12735019E+01 0.12671490E+01
+ 0.12608227E+01 0.12545229E+01 0.12482495E+01 0.12420024E+01 0.12357816E+01
+ 0.12295869E+01 0.12234183E+01 0.12172757E+01 0.12111590E+01 0.12050681E+01
+ 0.11990030E+01 0.11929635E+01 0.11869496E+01 0.11809612E+01 0.11749982E+01
+ 0.11690605E+01 0.11631480E+01 0.11572607E+01 0.11513985E+01 0.11455612E+01
+ 0.11397489E+01 0.11339614E+01 0.11281986E+01 0.11224605E+01 0.11167470E+01
+ 0.11110580E+01 0.11053934E+01 0.10997531E+01 0.10941371E+01 0.10885453E+01
+ 0.10829775E+01 0.10774338E+01 0.10719140E+01 0.10664181E+01 0.10609459E+01
+ 0.10554974E+01 0.10500726E+01 0.10446713E+01 0.10392934E+01 0.10339389E+01
+ 0.10286077E+01 0.10232997E+01 0.10180149E+01 0.10127531E+01 0.10075144E+01
+ 0.10022985E+01 0.99710542E+00 0.99193511E+00 0.98678748E+00 0.98166244E+00
+ 0.97655992E+00 0.97147984E+00 0.96642212E+00 0.96138669E+00 0.95637347E+00
+ 0.95138239E+00 0.94641336E+00 0.94146631E+00 0.93654116E+00 0.93163785E+00
+ 0.92675629E+00 0.92189641E+00 0.91705813E+00 0.91224137E+00 0.90744607E+00
+ 0.90267215E+00 0.89791953E+00 0.89318814E+00 0.88847791E+00 0.88378875E+00
+ 0.87912060E+00 0.87447339E+00 0.86984703E+00 0.86524146E+00 0.86065660E+00
+ 0.85609237E+00 0.85154872E+00 0.84702556E+00 0.84252281E+00 0.83804042E+00
+ 0.83357830E+00 0.82913639E+00 0.82471460E+00 0.82031288E+00 0.81593114E+00
+ 0.81156932E+00 0.80722734E+00 0.80290514E+00 0.79860264E+00 0.79431978E+00
+ 0.79005647E+00 0.78581265E+00 0.78158826E+00 0.77738321E+00 0.77319745E+00
+ 0.76903089E+00 0.76488348E+00 0.76075514E+00 0.75664580E+00 0.75255539E+00
+ 0.74848384E+00 0.74443109E+00 0.74039706E+00 0.73638170E+00 0.73238492E+00
+ 0.72840666E+00 0.72444685E+00 0.72050543E+00 0.71658232E+00 0.71267747E+00
+ 0.70879079E+00 0.70492224E+00 0.70107172E+00 0.69723919E+00 0.69342458E+00
+ 0.68962781E+00 0.68584882E+00 0.68208754E+00 0.67834392E+00 0.67461787E+00
+ 0.67090935E+00 0.66721827E+00 0.66354458E+00 0.65988821E+00 0.65624910E+00
+ 0.65262718E+00 0.64902238E+00 0.64543464E+00 0.64186390E+00 0.63831009E+00
+ 0.63477315E+00 0.63125302E+00 0.62774962E+00 0.62426290E+00 0.62079279E+00
+ 0.61733924E+00 0.61390217E+00 0.61048152E+00 0.60707723E+00 0.60368925E+00
+ 0.60031749E+00 0.59696191E+00 0.59362244E+00 0.59029902E+00 0.58699159E+00
+ 0.58370008E+00 0.58042444E+00 0.57716460E+00 0.57392049E+00 0.57069207E+00
+ 0.56747927E+00 0.56428203E+00 0.56110028E+00 0.55793397E+00 0.55478304E+00
+ 0.55164742E+00 0.54852706E+00 0.54542190E+00 0.54233188E+00 0.53925693E+00
+ 0.53619700E+00 0.53315204E+00 0.53012197E+00 0.52710674E+00 0.52410630E+00
+ 0.52112058E+00 0.51814953E+00 0.51519308E+00 0.51225119E+00 0.50932379E+00
+ 0.50641082E+00 0.50351223E+00 0.50062795E+00 0.49775794E+00 0.49490214E+00
+ 0.49206048E+00 0.48923291E+00 0.48641938E+00 0.48361983E+00 0.48083419E+00
+ 0.47806243E+00 0.47530447E+00 0.47256027E+00 0.46982976E+00 0.46711290E+00
+ 0.46440963E+00 0.46171988E+00 0.45904362E+00 0.45638077E+00 0.45373130E+00
+ 0.45109513E+00 0.44847223E+00 0.44586253E+00 0.44326598E+00 0.44068252E+00
+ 0.43811211E+00 0.43555469E+00 0.43301020E+00 0.43047859E+00 0.42795981E+00
+ 0.42545381E+00 0.42296053E+00 0.42047992E+00 0.41801193E+00 0.41555650E+00
+ 0.41311359E+00 0.41068314E+00 0.40826509E+00 0.40585940E+00 0.40346602E+00
+ 0.40108489E+00 0.39871596E+00 0.39635919E+00 0.39401451E+00 0.39168189E+00
+ 0.38936126E+00 0.38705258E+00 0.38475580E+00 0.38247087E+00 0.38019773E+00
+ 0.37793634E+00 0.37568665E+00 0.37344861E+00 0.37122216E+00 0.36900727E+00
+ 0.36680387E+00 0.36461193E+00 0.36243138E+00 0.36026219E+00 0.35810234E+00
+ 0.35594974E+00 0.35380437E+00 0.35166624E+00 0.34953534E+00 0.34741166E+00
+ 0.34529519E+00 0.34318592E+00 0.34108386E+00 0.33898899E+00 0.33690130E+00
+ 0.33482080E+00 0.33274747E+00 0.33068131E+00 0.32862231E+00 0.32657046E+00
+ 0.32452576E+00 0.32248820E+00 0.32045778E+00 0.31843448E+00 0.31641830E+00
+ 0.31440924E+00 0.31240728E+00 0.31041243E+00 0.30842467E+00 0.30644400E+00
+ 0.30447041E+00 0.30250389E+00 0.30054444E+00 0.29859206E+00 0.29664673E+00
+ 0.29470844E+00 0.29277720E+00 0.29085299E+00 0.28893582E+00 0.28702566E+00
+ 0.28512252E+00 0.28322638E+00 0.28133725E+00 0.27945512E+00 0.27757997E+00
+ 0.27571181E+00 0.27385062E+00 0.27199640E+00 0.27014914E+00 0.26830884E+00
+ 0.26647549E+00 0.26464908E+00 0.26282960E+00 0.26101706E+00 0.25921143E+00
+ 0.25741273E+00 0.25562093E+00 0.25383604E+00 0.25205804E+00 0.25028693E+00
+ 0.24852271E+00 0.24676536E+00 0.24501488E+00 0.24327126E+00 0.24153451E+00
+ 0.23980460E+00 0.23808153E+00 0.23636530E+00 0.23465591E+00 0.23295333E+00
+ 0.23125757E+00 0.22956863E+00 0.22788648E+00 0.22621114E+00 0.22454258E+00
+ 0.22288081E+00 0.22122582E+00 0.21957759E+00 0.21793614E+00 0.21630143E+00
+ 0.21467348E+00 0.21305228E+00 0.21143781E+00 0.20983007E+00 0.20822906E+00
+ 0.20663476E+00 0.20504718E+00 0.20346630E+00 0.20189212E+00 0.20032463E+00
+ 0.19876383E+00 0.19720970E+00 0.19566225E+00 0.19412146E+00 0.19258733E+00
+ 0.19105985E+00 0.18953902E+00 0.18802482E+00 0.18651726E+00 0.18501632E+00
+ 0.18352200E+00 0.18203430E+00 0.18055319E+00 0.17907869E+00 0.17761078E+00
+ 0.17614946E+00 0.17469472E+00 0.17324654E+00 0.17180494E+00 0.17036989E+00
+ 0.16894140E+00 0.16751945E+00 0.16610404E+00 0.16469517E+00 0.16329282E+00
+ 0.16189699E+00 0.16050768E+00 0.15912487E+00 0.15774856E+00 0.15637874E+00
+ 0.15501542E+00 0.15365857E+00 0.15230819E+00 0.15096428E+00 0.14962684E+00
+ 0.14829584E+00 0.14697129E+00 0.14565319E+00 0.14434152E+00 0.14303627E+00
+ 0.14173745E+00 0.14044503E+00 0.13915903E+00 0.13787943E+00 0.13660622E+00
+ 0.13533940E+00 0.13407896E+00 0.13282490E+00 0.13157720E+00 0.13033586E+00
+ 0.12910088E+00 0.12787225E+00 0.12664996E+00 0.12543400E+00 0.12422437E+00
+ 0.12302106E+00 0.12182407E+00 0.12063339E+00 0.11944900E+00 0.11827092E+00
+ 0.11709912E+00 0.11593360E+00 0.11477436E+00 0.11362139E+00 0.11247468E+00
+ 0.11133422E+00 0.11020002E+00 0.10907205E+00 0.10795033E+00 0.10683483E+00
+ 0.10572555E+00 0.10462249E+00 0.10352564E+00 0.10243499E+00 0.10135054E+00
+ 0.10027228E+00 0.99200196E-01 0.98134293E-01 0.97074559E-01 0.96020988E-01
+ 0.94973573E-01 0.93932308E-01 0.92897187E-01 0.91868202E-01 0.90845347E-01
+ 0.89828616E-01 0.88818002E-01 0.87813497E-01 0.86815097E-01 0.85822793E-01
+ 0.84836579E-01 0.83856450E-01 0.82882397E-01 0.81914416E-01 0.80952498E-01
+ 0.79996637E-01 0.79046828E-01 0.78103062E-01 0.77165334E-01 0.76233637E-01
+ 0.75307964E-01 0.74388309E-01 0.73474665E-01 0.72567026E-01 0.71665384E-01
+ 0.70769734E-01 0.69880068E-01 0.68996381E-01 0.68118665E-01 0.67246914E-01
+ 0.66381121E-01 0.65521280E-01 0.64667384E-01 0.63819427E-01 0.62977401E-01
+ 0.62141300E-01 0.61311119E-01 0.60486849E-01 0.59668484E-01 0.58856019E-01
+ 0.58049446E-01 0.57248758E-01 0.56453949E-01 0.55665013E-01 0.54881942E-01
+ 0.54104731E-01 0.53333372E-01 0.52567859E-01 0.51808186E-01 0.51054345E-01
+ 0.50306331E-01 0.49564136E-01 0.48827754E-01 0.48097178E-01 0.47372402E-01
+ 0.46653420E-01 0.45940223E-01 0.45232807E-01 0.44531164E-01 0.43835288E-01
+ 0.43145172E-01 0.42460809E-01 0.41782193E-01 0.41109318E-01 0.40442176E-01
+ 0.39780761E-01 0.39125067E-01 0.38475086E-01 0.37830813E-01 0.37192241E-01
+ 0.36559362E-01 0.35932171E-01 0.35310661E-01 0.34694825E-01 0.34084657E-01
+ 0.33480149E-01 0.32881296E-01 0.32288091E-01 0.31700527E-01 0.31118598E-01
+ 0.30542297E-01 0.29971617E-01 0.29406552E-01 0.28847095E-01 0.28293239E-01
+ 0.27744979E-01 0.27202307E-01 0.26665216E-01 0.26133701E-01 0.25607754E-01
+ 0.25087370E-01 0.24572540E-01 0.24063260E-01 0.23559521E-01 0.23061318E-01
+ 0.22568644E-01 0.22081492E-01 0.21599856E-01 0.21123729E-01 0.20653104E-01
+ 0.20187975E-01 0.19728336E-01 0.19274179E-01 0.18825498E-01 0.18382287E-01
+ 0.17944538E-01 0.17512246E-01 0.17085404E-01 0.16664004E-01 0.16248041E-01
+ 0.15837508E-01 0.15432398E-01 0.15032704E-01 0.14638421E-01 0.14249540E-01
+ 0.13866057E-01 0.13487964E-01 0.13115254E-01 0.12747922E-01 0.12385960E-01
+ 0.12029361E-01 0.11678120E-01 0.11332229E-01 0.10991682E-01 0.10656473E-01
+ 0.10326594E-01 0.10002040E-01 0.96828025E-02 0.93688763E-02 0.90602545E-02
+ 0.87569303E-02 0.84588972E-02 0.81661487E-02 0.78786780E-02 0.75964786E-02
+ 0.73195439E-02 0.70478672E-02 0.67814420E-02 0.65202617E-02 0.62643196E-02
+ 0.60136091E-02 0.57681237E-02 0.55278568E-02 0.52928016E-02 0.50629517E-02
+ 0.48383004E-02 0.46188411E-02 0.44045673E-02 0.41954722E-02 0.39915493E-02
+ 0.37927920E-02 0.35991937E-02 0.34107478E-02 0.32274476E-02 0.30492866E-02
+ 0.28762582E-02 0.27083557E-02 0.25455725E-02 0.23879022E-02 0.22353379E-02
+ 0.20878732E-02 0.19455014E-02 0.18082159E-02 0.16760102E-02 0.15488775E-02
+ 0.14268114E-02 0.13098051E-02 0.11978522E-02 0.10909459E-02 0.98907970E-03
+ 0.89224699E-03 0.80044114E-03 0.71365556E-03 0.63188364E-03 0.55511876E-03
+ 0.48335434E-03 0.41658375E-03 0.35480040E-03 0.29799767E-03 0.24616897E-03
+ 0.19930769E-03 0.15740722E-03 0.12046096E-03 0.88462293E-04 0.61404624E-04
+ 0.39281344E-04 0.22085848E-04 0.98115285E-05 0.24517812E-05 0.00000000E+00
+ 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04
+ 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04
+ 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04
+ 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04
+ 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04
+ 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04
+ 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04
+ 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04
+ 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04
+ 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04
+ 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04 0.75983097E+04
+ 0.73362408E+04 0.70808388E+04 0.68386082E+04 0.66086560E+04 0.63901640E+04
+ 0.61823808E+04 0.59846159E+04 0.57962336E+04 0.56166479E+04 0.54453180E+04
+ 0.52817441E+04 0.51254635E+04 0.49760477E+04 0.48330995E+04 0.46962496E+04
+ 0.45651550E+04 0.44394966E+04 0.43189770E+04 0.42033189E+04 0.40922636E+04
+ 0.39855692E+04 0.38830097E+04 0.37843735E+04 0.36894624E+04 0.35980906E+04
+ 0.35100838E+04 0.34252781E+04 0.33435198E+04 0.32646641E+04 0.31885748E+04
+ 0.31151236E+04 0.30441895E+04 0.29756585E+04 0.29094228E+04 0.28453808E+04
+ 0.27834363E+04 0.27234985E+04 0.26654813E+04 0.26093033E+04 0.25548872E+04
+ 0.25021599E+04 0.24510521E+04 0.24014978E+04 0.23534346E+04 0.23068029E+04
+ 0.22615463E+04 0.22176111E+04 0.21749461E+04 0.21335028E+04 0.20932346E+04
+ 0.20540976E+04 0.20160494E+04 0.19790501E+04 0.19430612E+04 0.19080461E+04
+ 0.18739700E+04 0.18407993E+04 0.18085023E+04 0.17770484E+04 0.17464083E+04
+ 0.17165542E+04 0.16874592E+04 0.16590979E+04 0.16314455E+04 0.16044787E+04
+ 0.15781748E+04 0.15525122E+04 0.15274701E+04 0.15030287E+04 0.14791687E+04
+ 0.14558719E+04 0.14331205E+04 0.14108977E+04 0.13891870E+04 0.13679729E+04
+ 0.13472401E+04 0.13269743E+04 0.13071615E+04 0.12877881E+04 0.12688412E+04
+ 0.12503085E+04 0.12321777E+04 0.12144373E+04 0.11970762E+04 0.11800836E+04
+ 0.11634491E+04 0.11471626E+04 0.11312144E+04 0.11155953E+04 0.11002962E+04
+ 0.10853083E+04 0.10706232E+04 0.10562329E+04 0.10421293E+04 0.10283050E+04
+ 0.10147526E+04 0.10014649E+04 0.98843512E+03 0.97565652E+03 0.96312268E+03
+ 0.95082737E+03 0.93876453E+03 0.92692832E+03 0.91531307E+03 0.90391329E+03
+ 0.89272365E+03 0.88173900E+03 0.87095434E+03 0.86036480E+03 0.84996571E+03
+ 0.83975248E+03 0.82972070E+03 0.81986607E+03 0.81018443E+03 0.80067172E+03
+ 0.79132402E+03 0.78213752E+03 0.77310851E+03 0.76423339E+03 0.75550867E+03
+ 0.74693094E+03 0.73849692E+03 0.73020338E+03 0.72204721E+03 0.71402538E+03
+ 0.70613494E+03 0.69837300E+03 0.69073680E+03 0.68322360E+03 0.67583076E+03
+ 0.66855572E+03 0.66139597E+03 0.65434907E+03 0.64741265E+03 0.64058440E+03
+ 0.63386207E+03 0.62724347E+03 0.62072645E+03 0.61430894E+03 0.60798892E+03
+ 0.60176439E+03 0.59563345E+03 0.58959421E+03 0.58364484E+03 0.57778355E+03
+ 0.57200860E+03 0.56631830E+03 0.56071099E+03 0.55518505E+03 0.54973891E+03
+ 0.54437102E+03 0.53907988E+03 0.53386403E+03 0.52872204E+03 0.52365252E+03
+ 0.51865408E+03 0.51372541E+03 0.50886520E+03 0.50407219E+03 0.49934513E+03
+ 0.49468280E+03 0.49008403E+03 0.48554765E+03 0.48107254E+03 0.47665758E+03
+ 0.47230170E+03 0.46800384E+03 0.46376297E+03 0.45957807E+03 0.45544816E+03
+ 0.45137228E+03 0.44734947E+03 0.44337881E+03 0.43945941E+03 0.43559036E+03
+ 0.43177082E+03 0.42799992E+03 0.42427685E+03 0.42060079E+03 0.41697095E+03
+ 0.41338654E+03 0.40984681E+03 0.40635102E+03 0.40289842E+03 0.39948832E+03
+ 0.39612000E+03 0.39279279E+03 0.38950601E+03 0.38625901E+03 0.38305113E+03
+ 0.37988175E+03 0.37675025E+03 0.37365602E+03 0.37059848E+03 0.36757703E+03
+ 0.36459111E+03 0.36164015E+03 0.35872361E+03 0.35584096E+03 0.35299165E+03
+ 0.35017519E+03 0.34739105E+03 0.34463875E+03 0.34191779E+03 0.33922769E+03
+ 0.33656800E+03 0.33393824E+03 0.33133797E+03 0.32876673E+03 0.32622411E+03
+ 0.32370967E+03 0.32122299E+03 0.31876366E+03 0.31633128E+03 0.31392545E+03
+ 0.31154579E+03 0.30919190E+03 0.30686343E+03 0.30455999E+03 0.30228124E+03
+ 0.30002680E+03 0.29779635E+03 0.29558952E+03 0.29340600E+03 0.29124544E+03
+ 0.28910753E+03 0.28699194E+03 0.28489837E+03 0.28282650E+03 0.28077603E+03
+ 0.27874668E+03 0.27673813E+03 0.27475012E+03 0.27278235E+03 0.27083456E+03
+ 0.26890646E+03 0.26699780E+03 0.26510830E+03 0.26323771E+03 0.26138578E+03
+ 0.25955225E+03 0.25773689E+03 0.25593944E+03 0.25415968E+03 0.25239736E+03
+ 0.25065227E+03 0.24892416E+03 0.24721283E+03 0.24551804E+03 0.24383960E+03
+ 0.24217728E+03 0.24053087E+03 0.23890018E+03 0.23728500E+03 0.23568514E+03
+ 0.23410039E+03 0.23253057E+03 0.23097548E+03 0.22943495E+03 0.22790878E+03
+ 0.22639680E+03 0.22489884E+03 0.22341471E+03 0.22194424E+03 0.22048728E+03
+ 0.21904364E+03 0.21761316E+03 0.21619570E+03 0.21479107E+03 0.21339914E+03
+ 0.21201974E+03 0.21065272E+03 0.20929794E+03 0.20795524E+03 0.20662449E+03
+ 0.20530553E+03 0.20399824E+03 0.20270246E+03 0.20141807E+03 0.20014492E+03
+ 0.19888289E+03 0.19763185E+03 0.19639167E+03 0.19516221E+03 0.19394337E+03
+ 0.19273500E+03 0.19153700E+03 0.19034924E+03 0.18917160E+03 0.18800397E+03
+ 0.18684624E+03 0.18569829E+03 0.18456001E+03 0.18343128E+03 0.18231202E+03
+ 0.18120209E+03 0.18010141E+03 0.17900987E+03 0.17792736E+03 0.17685379E+03
+ 0.17578906E+03 0.17473306E+03 0.17368571E+03 0.17264690E+03 0.17161654E+03
+ 0.17059455E+03 0.16958083E+03 0.16857528E+03 0.16757782E+03 0.16658837E+03
+ 0.16560684E+03 0.16463313E+03 0.16366718E+03 0.16270889E+03 0.16175818E+03
+ 0.16081497E+03 0.15987919E+03 0.15895075E+03 0.15802958E+03 0.15711559E+03
+ 0.15620872E+03 0.15530890E+03 0.15441604E+03 0.15353007E+03 0.15265092E+03
+ 0.15177853E+03 0.15091282E+03 0.15005372E+03 0.14920117E+03 0.14835510E+03
+ 0.14751544E+03 0.14668212E+03 0.14585509E+03 0.14503428E+03 0.14421962E+03
+ 0.14341106E+03 0.14260853E+03 0.14181197E+03 0.14102132E+03 0.14023653E+03
+ 0.13945753E+03 0.13868427E+03 0.13791669E+03 0.13715474E+03 0.13639836E+03
+ 0.13564749E+03 0.13490208E+03 0.13416207E+03 0.13342743E+03 0.13269808E+03
+ 0.13197399E+03 0.13125510E+03 0.13054135E+03 0.12983271E+03 0.12912912E+03
+ 0.12843053E+03 0.12773690E+03 0.12704818E+03 0.12636432E+03 0.12568527E+03
+ 0.12501100E+03 0.12434145E+03 0.12367658E+03 0.12301634E+03 0.12236070E+03
+ 0.12170962E+03 0.12106303E+03 0.12042092E+03 0.11978323E+03 0.11914992E+03
+ 0.11852096E+03 0.11789630E+03 0.11727591E+03 0.11665974E+03 0.11604776E+03
+ 0.11543992E+03 0.11483620E+03 0.11423655E+03 0.11364093E+03 0.11304932E+03
+ 0.11246167E+03 0.11187794E+03 0.11129811E+03 0.11072214E+03 0.11015000E+03
+ 0.10958164E+03 0.10901704E+03 0.10845617E+03 0.10789898E+03 0.10734545E+03
+ 0.10679555E+03 0.10624924E+03 0.10570649E+03 0.10516728E+03 0.10463156E+03
+ 0.10409932E+03 0.10357052E+03 0.10304512E+03 0.10252311E+03 0.10200445E+03
+ 0.10148911E+03 0.10097707E+03 0.10046829E+03 0.99962750E+02 0.99460423E+02
+ 0.98961279E+02 0.98465293E+02 0.97972436E+02 0.97482683E+02 0.96996008E+02
+ 0.96512385E+02 0.96031788E+02 0.95554192E+02 0.95079572E+02 0.94607903E+02
+ 0.94139162E+02 0.93673322E+02 0.93210362E+02 0.92750256E+02 0.92292981E+02
+ 0.91838515E+02 0.91386834E+02 0.90937916E+02 0.90491737E+02 0.90048276E+02
+ 0.89607511E+02 0.89169419E+02 0.88733980E+02 0.88301172E+02 0.87870973E+02
+ 0.87443363E+02 0.87018321E+02 0.86595826E+02 0.86175859E+02 0.85758399E+02
+ 0.85343426E+02 0.84930921E+02 0.84520864E+02 0.84113235E+02 0.83708016E+02
+ 0.83305188E+02 0.82904732E+02 0.82506629E+02 0.82110862E+02 0.81717411E+02
+ 0.81326259E+02 0.80937389E+02 0.80550782E+02 0.80166421E+02 0.79784289E+02
+ 0.79404369E+02 0.79026643E+02 0.78651095E+02 0.78277709E+02 0.77906467E+02
+ 0.77537354E+02 0.77170353E+02 0.76805449E+02 0.76442625E+02 0.76081866E+02
+ 0.75723157E+02 0.75366481E+02 0.75011825E+02 0.74659172E+02 0.74308507E+02
+ 0.73959817E+02 0.73613086E+02 0.73268300E+02 0.72925444E+02 0.72584505E+02
+ 0.72245467E+02 0.71908318E+02 0.71573042E+02 0.71239628E+02 0.70908060E+02
+ 0.70578326E+02 0.70250411E+02 0.69924304E+02 0.69599991E+02 0.69277458E+02
+ 0.68956694E+02 0.68637685E+02 0.68320418E+02 0.68004882E+02 0.67691064E+02
+ 0.67378951E+02 0.67068532E+02 0.66759794E+02 0.66452725E+02 0.66147314E+02
+ 0.65843549E+02 0.65541419E+02 0.65240911E+02 0.64942015E+02 0.64644718E+02
+ 0.64349011E+02 0.64054881E+02 0.63762319E+02 0.63471312E+02 0.63181851E+02
+ 0.62893924E+02 0.62607520E+02 0.62322630E+02 0.62039243E+02 0.61757349E+02
+ 0.61476937E+02 0.61197997E+02 0.60920520E+02 0.60644494E+02 0.60369911E+02
+ 0.60096760E+02 0.59825033E+02 0.59554718E+02 0.59285807E+02 0.59018290E+02
+ 0.58752159E+02 0.58487402E+02 0.58224012E+02 0.57961980E+02 0.57701295E+02
+ 0.57441949E+02 0.57183934E+02 0.56927241E+02 0.56671860E+02 0.56417783E+02
+ 0.56165001E+02 0.55913507E+02 0.55663291E+02 0.55414345E+02 0.55166661E+02
+ 0.54920230E+02 0.54675045E+02 0.54431097E+02 0.54188378E+02 0.53946881E+02
+ 0.53706597E+02 0.53467518E+02 0.53229638E+02 0.52992947E+02 0.52757439E+02
+ 0.52523106E+02 0.52289940E+02 0.52057934E+02 0.51827081E+02 0.51597373E+02
+ 0.51368803E+02 0.51141363E+02 0.50915048E+02 0.50689848E+02 0.50465759E+02
+ 0.50242771E+02 0.50020880E+02 0.49800077E+02 0.49580356E+02 0.49361710E+02
+ 0.49144133E+02 0.48927617E+02 0.48712157E+02 0.48497746E+02 0.48284376E+02
+ 0.48072043E+02 0.47860739E+02 0.47650458E+02 0.47441194E+02 0.47232941E+02
+ 0.47025692E+02 0.46819441E+02 0.46614183E+02 0.46409911E+02 0.46206619E+02
+ 0.46004302E+02 0.45802952E+02 0.45602566E+02 0.45403136E+02 0.45204657E+02
+ 0.45007124E+02 0.44810530E+02 0.44614870E+02 0.44420139E+02 0.44226330E+02
+ 0.44033439E+02 0.43841461E+02 0.43650388E+02 0.43460217E+02 0.43270942E+02
+ 0.43082557E+02 0.42895058E+02 0.42708439E+02 0.42522695E+02 0.42337821E+02
+ 0.42153812E+02 0.41970663E+02 0.41788368E+02 0.41606924E+02 0.41426324E+02
+ 0.41246564E+02 0.41067640E+02 0.40889546E+02 0.40712277E+02 0.40535829E+02
+ 0.40360198E+02 0.40185377E+02 0.40011364E+02 0.39838153E+02 0.39665739E+02
+ 0.39494119E+02 0.39323287E+02 0.39153240E+02 0.38983972E+02 0.38815479E+02
+ 0.38647757E+02 0.38480802E+02 0.38314609E+02 0.38149174E+02 0.37984493E+02
+ 0.37820562E+02 0.37657376E+02 0.37494931E+02 0.37333223E+02 0.37172248E+02
+ 0.37012002E+02 0.36852482E+02 0.36693682E+02 0.36535599E+02 0.36378229E+02
+ 0.36221568E+02 0.36065612E+02 0.35910358E+02 0.35755801E+02 0.35601938E+02
+ 0.35448765E+02 0.35296278E+02 0.35144473E+02 0.34993347E+02 0.34842896E+02
+ 0.34693117E+02 0.34544006E+02 0.34395558E+02 0.34247772E+02 0.34100642E+02
+ 0.33954167E+02 0.33808341E+02 0.33663162E+02 0.33518626E+02 0.33374730E+02
+ 0.33231470E+02 0.33088843E+02 0.32946846E+02 0.32805475E+02 0.32664727E+02
+ 0.32524599E+02 0.32385087E+02 0.32246189E+02 0.32107901E+02 0.31970219E+02
+ 0.31833141E+02 0.31696664E+02 0.31560784E+02 0.31425498E+02 0.31290803E+02
+ 0.31156697E+02 0.31023176E+02 0.30890237E+02 0.30757876E+02 0.30626092E+02
+ 0.30494881E+02 0.30364240E+02 0.30234167E+02 0.30104658E+02 0.29975710E+02
+ 0.29847321E+02 0.29719488E+02 0.29592207E+02 0.29465477E+02 0.29339294E+02
+ 0.29213656E+02 0.29088559E+02 0.28964002E+02 0.28839981E+02 0.28716493E+02
+ 0.28593537E+02 0.28471109E+02 0.28349207E+02 0.28227828E+02 0.28106969E+02
+ 0.27986628E+02 0.27866802E+02 0.27747489E+02 0.27628687E+02 0.27510392E+02
+ 0.27392602E+02 0.27275314E+02 0.27158527E+02 0.27042238E+02 0.26926444E+02
+ 0.26811143E+02 0.26696332E+02 0.26582009E+02 0.26468172E+02 0.26354818E+02
+ 0.26241945E+02 0.26129551E+02 0.26017633E+02 0.25906189E+02 0.25795217E+02
+ 0.25684714E+02 0.25574678E+02 0.25465107E+02 0.25355998E+02 0.25247350E+02
+ 0.25139161E+02 0.25031427E+02 0.24924147E+02 0.24817318E+02 0.24710940E+02
+ 0.24605008E+02 0.24499522E+02 0.24394479E+02 0.24289877E+02 0.24185713E+02
+ 0.24081987E+02 0.23978696E+02 0.23875837E+02 0.23773409E+02 0.23671409E+02
+ 0.23569836E+02 0.23468688E+02 0.23367963E+02 0.23267658E+02 0.23167772E+02
+ 0.23068303E+02 0.22969248E+02 0.22870607E+02 0.22772376E+02 0.22674555E+02
+ 0.22577140E+02 0.22480131E+02 0.22383526E+02 0.22287322E+02 0.22191518E+02
+ 0.22096111E+02 0.22001101E+02 0.21906485E+02 0.21812261E+02 0.21718428E+02
+ 0.21624984E+02 0.21531927E+02 0.21439256E+02 0.21346967E+02 0.21255061E+02
+ 0.21163535E+02 0.21072387E+02 0.20981616E+02 0.20891219E+02 0.20801196E+02
+ 0.20711545E+02 0.20622263E+02 0.20533350E+02 0.20444803E+02 0.20356621E+02
+ 0.20268803E+02 0.20181346E+02 0.20094249E+02 0.20007511E+02 0.19921129E+02
+ 0.19835103E+02 0.19749431E+02 0.19664110E+02 0.19579140E+02 0.19494520E+02
+ 0.19410246E+02 0.19326319E+02 0.19242736E+02 0.19159495E+02 0.19076597E+02
+ 0.18994038E+02 0.18911817E+02 0.18829933E+02 0.18748385E+02 0.18667171E+02
+ 0.18586289E+02 0.18505738E+02 0.18425517E+02 0.18345624E+02 0.18266058E+02
+ 0.18186817E+02 0.18107899E+02 0.18029305E+02 0.17951031E+02 0.17873078E+02
+ 0.17795442E+02 0.17718124E+02 0.17641121E+02 0.17564432E+02 0.17488056E+02
+ 0.17411992E+02 0.17336238E+02 0.17260792E+02 0.17185655E+02 0.17110823E+02
+ 0.17036297E+02 0.16962074E+02 0.16888153E+02 0.16814534E+02 0.16741214E+02
+ 0.16668193E+02 0.16595469E+02 0.16523041E+02 0.16450907E+02 0.16379067E+02
+ 0.16307520E+02 0.16236263E+02 0.16165296E+02 0.16094617E+02 0.16024226E+02
+ 0.15954121E+02 0.15884301E+02 0.15814765E+02 0.15745511E+02 0.15676539E+02
+ 0.15607847E+02 0.15539433E+02 0.15471298E+02 0.15403439E+02 0.15335856E+02
+ 0.15268547E+02 0.15201512E+02 0.15134748E+02 0.15068256E+02 0.15002033E+02
+ 0.14936079E+02 0.14870393E+02 0.14804974E+02 0.14739819E+02 0.14674929E+02
+ 0.14610303E+02 0.14545938E+02 0.14481835E+02 0.14417991E+02 0.14354407E+02
+ 0.14291080E+02 0.14228010E+02 0.14165196E+02 0.14102637E+02 0.14040331E+02
+ 0.13978278E+02 0.13916477E+02 0.13854926E+02 0.13793625E+02 0.13732572E+02
+ 0.13671767E+02 0.13611208E+02 0.13550895E+02 0.13490827E+02 0.13431002E+02
+ 0.13371419E+02 0.13312079E+02 0.13252978E+02 0.13194118E+02 0.13135496E+02
+ 0.13077112E+02 0.13018965E+02 0.12961053E+02 0.12903376E+02 0.12845933E+02
+ 0.12788724E+02 0.12731746E+02 0.12674999E+02 0.12618483E+02 0.12562195E+02
+ 0.12506136E+02 0.12450305E+02 0.12394700E+02 0.12339321E+02 0.12284166E+02
+ 0.12229235E+02 0.12174527E+02 0.12120042E+02 0.12065777E+02 0.12011733E+02
+ 0.11957908E+02 0.11904301E+02 0.11850913E+02 0.11797741E+02 0.11744785E+02
+ 0.11692044E+02 0.11639518E+02 0.11587205E+02 0.11535104E+02 0.11483215E+02
+ 0.11431537E+02 0.11380069E+02 0.11328811E+02 0.11277760E+02 0.11226918E+02
+ 0.11176282E+02 0.11125852E+02 0.11075627E+02 0.11025607E+02 0.10975790E+02
+ 0.10926176E+02 0.10876764E+02 0.10827553E+02 0.10778543E+02 0.10729732E+02
+ 0.10681120E+02 0.10632706E+02 0.10584489E+02 0.10536469E+02 0.10488645E+02
+ 0.10441015E+02 0.10393580E+02 0.10346338E+02 0.10299289E+02 0.10252432E+02
+ 0.10205766E+02 0.10159291E+02 0.10113005E+02 0.10066909E+02 0.10021001E+02
+ 0.99752798E+01 0.99297459E+01 0.98843981E+01 0.98392357E+01 0.97942579E+01
+ 0.97494641E+01 0.97048536E+01 0.96604256E+01 0.96161794E+01 0.95721144E+01
+ 0.95282298E+01 0.94845249E+01 0.94409991E+01 0.93976517E+01 0.93544819E+01
+ 0.93114892E+01 0.92686727E+01 0.92260319E+01 0.91835661E+01 0.91412745E+01
+ 0.90991566E+01 0.90572116E+01 0.90154390E+01 0.89738379E+01 0.89324079E+01
+ 0.88911482E+01 0.88500581E+01 0.88091371E+01 0.87683844E+01 0.87277995E+01
+ 0.86873817E+01 0.86471304E+01 0.86070448E+01 0.85671245E+01 0.85273687E+01
+ 0.84877768E+01 0.84483483E+01 0.84090824E+01 0.83699786E+01 0.83310363E+01
+ 0.82922548E+01 0.82536335E+01 0.82151718E+01 0.81768691E+01 0.81387249E+01
+ 0.81007384E+01 0.80629091E+01 0.80252364E+01 0.79877198E+01 0.79503585E+01
+ 0.79131521E+01 0.78760999E+01 0.78392014E+01 0.78024559E+01 0.77658630E+01
+ 0.77294219E+01 0.76931322E+01 0.76569932E+01 0.76210044E+01 0.75851653E+01
+ 0.75494752E+01 0.75139336E+01 0.74785399E+01 0.74432936E+01 0.74081941E+01
+ 0.73732409E+01 0.73384334E+01 0.73037710E+01 0.72692533E+01 0.72348795E+01
+ 0.72006493E+01 0.71665621E+01 0.71326173E+01 0.70988144E+01 0.70651529E+01
+ 0.70316322E+01 0.69982517E+01 0.69650111E+01 0.69319097E+01 0.68989469E+01
+ 0.68661224E+01 0.68334355E+01 0.68008858E+01 0.67684727E+01 0.67361957E+01
+ 0.67040543E+01 0.66720480E+01 0.66401763E+01 0.66084387E+01 0.65768346E+01
+ 0.65453635E+01 0.65140251E+01 0.64828187E+01 0.64517438E+01 0.64208000E+01
+ 0.63899868E+01 0.63593037E+01 0.63287502E+01 0.62983257E+01 0.62680299E+01
+ 0.62378622E+01 0.62078222E+01 0.61779093E+01 0.61481231E+01 0.61184632E+01
+ 0.60889289E+01 0.60595199E+01 0.60302357E+01 0.60010758E+01 0.59720398E+01
+ 0.59431272E+01 0.59143374E+01 0.58856702E+01 0.58571249E+01 0.58287011E+01
+ 0.58003985E+01 0.57722164E+01 0.57441545E+01 0.57162123E+01 0.56883894E+01
+ 0.56606853E+01 0.56330996E+01 0.56056317E+01 0.55782814E+01 0.55510480E+01
+ 0.55239313E+01 0.54969307E+01 0.54700458E+01 0.54432762E+01 0.54166214E+01
+ 0.53900810E+01 0.53636546E+01 0.53373417E+01 0.53111420E+01 0.52850549E+01
+ 0.52590801E+01 0.52332172E+01 0.52074656E+01 0.51818250E+01 0.51562950E+01
+ 0.51308752E+01 0.51055651E+01 0.50803644E+01 0.50552725E+01 0.50302891E+01
+ 0.50054139E+01 0.49806463E+01 0.49559860E+01 0.49314325E+01 0.49069856E+01
+ 0.48826446E+01 0.48584094E+01 0.48342794E+01 0.48102542E+01 0.47863335E+01
+ 0.47625169E+01 0.47388040E+01 0.47151943E+01 0.46916875E+01 0.46682832E+01
+ 0.46449810E+01 0.46217806E+01 0.45986815E+01 0.45756833E+01 0.45527857E+01
+ 0.45299883E+01 0.45072907E+01 0.44846925E+01 0.44621933E+01 0.44397928E+01
+ 0.44174907E+01 0.43952864E+01 0.43731797E+01 0.43511702E+01 0.43292574E+01
+ 0.43074411E+01 0.42857209E+01 0.42640964E+01 0.42425672E+01 0.42211330E+01
+ 0.41997934E+01 0.41785481E+01 0.41573967E+01 0.41363388E+01 0.41153740E+01
+ 0.40945021E+01 0.40737227E+01 0.40530353E+01 0.40324398E+01 0.40119356E+01
+ 0.39915225E+01 0.39712001E+01 0.39509681E+01 0.39308261E+01 0.39107738E+01
+ 0.38908107E+01 0.38709367E+01 0.38511513E+01 0.38314543E+01 0.38118452E+01
+ 0.37923237E+01 0.37728895E+01 0.37535422E+01 0.37342816E+01 0.37151073E+01
+ 0.36960189E+01 0.36770162E+01 0.36580987E+01 0.36392662E+01 0.36205183E+01
+ 0.36018548E+01 0.35832752E+01 0.35647793E+01 0.35463668E+01 0.35280372E+01
+ 0.35097904E+01 0.34916259E+01 0.34735435E+01 0.34555428E+01 0.34376236E+01
+ 0.34197854E+01 0.34020280E+01 0.33843512E+01 0.33667545E+01 0.33492376E+01
+ 0.33318003E+01 0.33144422E+01 0.32971631E+01 0.32799626E+01 0.32628404E+01
+ 0.32457962E+01 0.32288297E+01 0.32119406E+01 0.31951287E+01 0.31783935E+01
+ 0.31617348E+01 0.31451524E+01 0.31286458E+01 0.31122149E+01 0.30958593E+01
+ 0.30795786E+01 0.30633728E+01 0.30472413E+01 0.30311840E+01 0.30152005E+01
+ 0.29992906E+01 0.29834540E+01 0.29676904E+01 0.29519995E+01 0.29363809E+01
+ 0.29208345E+01 0.29053600E+01 0.28899570E+01 0.28746253E+01 0.28593646E+01
+ 0.28441746E+01 0.28290550E+01 0.28140056E+01 0.27990261E+01 0.27841162E+01
+ 0.27692756E+01 0.27545041E+01 0.27398014E+01 0.27251672E+01 0.27106012E+01
+ 0.26961032E+01 0.26816729E+01 0.26673101E+01 0.26530144E+01 0.26387855E+01
+ 0.26246234E+01 0.26105276E+01 0.25964978E+01 0.25825340E+01 0.25686357E+01
+ 0.25548027E+01 0.25410348E+01 0.25273316E+01 0.25136930E+01 0.25001187E+01
+ 0.24866084E+01 0.24731619E+01 0.24597788E+01 0.24464590E+01 0.24332022E+01
+ 0.24200082E+01 0.24068767E+01 0.23938073E+01 0.23808000E+01 0.23678545E+01
+ 0.23549704E+01 0.23421475E+01 0.23293857E+01 0.23166846E+01 0.23040441E+01
+ 0.22914637E+01 0.22789435E+01 0.22664829E+01 0.22540820E+01 0.22417403E+01
+ 0.22294576E+01 0.22172338E+01 0.22050686E+01 0.21929616E+01 0.21809128E+01
+ 0.21689219E+01 0.21569885E+01 0.21451126E+01 0.21332938E+01 0.21215320E+01
+ 0.21098268E+01 0.20981781E+01 0.20865857E+01 0.20750492E+01 0.20635685E+01
+ 0.20521434E+01 0.20407735E+01 0.20294588E+01 0.20181989E+01 0.20069937E+01
+ 0.19958428E+01 0.19847462E+01 0.19737035E+01 0.19627145E+01 0.19517791E+01
+ 0.19408970E+01 0.19300680E+01 0.19192918E+01 0.19085683E+01 0.18978971E+01
+ 0.18872782E+01 0.18767113E+01 0.18661962E+01 0.18557326E+01 0.18453204E+01
+ 0.18349593E+01 0.18246491E+01 0.18143897E+01 0.18041807E+01 0.17940220E+01
+ 0.17839134E+01 0.17738547E+01 0.17638456E+01 0.17538860E+01 0.17439756E+01
+ 0.17341142E+01 0.17243017E+01 0.17145379E+01 0.17048224E+01 0.16951552E+01
+ 0.16855359E+01 0.16759646E+01 0.16664408E+01 0.16569644E+01 0.16475352E+01
+ 0.16381531E+01 0.16288178E+01 0.16195291E+01 0.16102868E+01 0.16010907E+01
+ 0.15919407E+01 0.15828365E+01 0.15737780E+01 0.15647649E+01 0.15557970E+01
+ 0.15468742E+01 0.15379963E+01 0.15291631E+01 0.15203743E+01 0.15116298E+01
+ 0.15029295E+01 0.14942731E+01 0.14856604E+01 0.14770912E+01 0.14685654E+01
+ 0.14600828E+01 0.14516431E+01 0.14432463E+01 0.14348921E+01 0.14265803E+01
+ 0.14183108E+01 0.14100833E+01 0.14018978E+01 0.13937539E+01 0.13856516E+01
+ 0.13775906E+01 0.13695708E+01 0.13615920E+01 0.13536539E+01 0.13457566E+01
+ 0.13378997E+01 0.13300830E+01 0.13223065E+01 0.13145700E+01 0.13068731E+01
+ 0.12992159E+01 0.12915981E+01 0.12840195E+01 0.12764800E+01 0.12689794E+01
+ 0.12615176E+01 0.12540943E+01 0.12467094E+01 0.12393627E+01 0.12320541E+01
+ 0.12247833E+01 0.12175503E+01 0.12103548E+01 0.12031968E+01 0.11960759E+01
+ 0.11889921E+01 0.11819453E+01 0.11749351E+01 0.11679615E+01 0.11610244E+01
+ 0.11541235E+01 0.11472586E+01 0.11404297E+01 0.11336366E+01 0.11268791E+01
+ 0.11201570E+01 0.11134702E+01 0.11068186E+01 0.11002019E+01 0.10936201E+01
+ 0.10870729E+01 0.10805602E+01 0.10740819E+01 0.10676378E+01 0.10612277E+01
+ 0.10548516E+01 0.10485092E+01 0.10422003E+01 0.10359250E+01 0.10296829E+01
+ 0.10234739E+01 0.10172980E+01 0.10111549E+01 0.10050444E+01 0.99896655E+00
+ 0.99292107E+00 0.98690784E+00 0.98092672E+00 0.97497756E+00 0.96906021E+00
+ 0.96317453E+00 0.95732037E+00 0.95149760E+00 0.94570606E+00 0.93994562E+00
+ 0.93421613E+00 0.92851745E+00 0.92284945E+00 0.91721197E+00 0.91160489E+00
+ 0.90602805E+00 0.90048133E+00 0.89496458E+00 0.88947767E+00 0.88402045E+00
+ 0.87859279E+00 0.87319456E+00 0.86782562E+00 0.86248583E+00 0.85717506E+00
+ 0.85189317E+00 0.84664004E+00 0.84141551E+00 0.83621948E+00 0.83105179E+00
+ 0.82591232E+00 0.82080095E+00 0.81571752E+00 0.81066193E+00 0.80563403E+00
+ 0.80063370E+00 0.79566081E+00 0.79071522E+00 0.78579682E+00 0.78090548E+00
+ 0.77604106E+00 0.77120344E+00 0.76639249E+00 0.76160810E+00 0.75685013E+00
+ 0.75211845E+00 0.74741296E+00 0.74273351E+00 0.73808000E+00 0.73345229E+00
+ 0.72885026E+00 0.72427379E+00 0.71972276E+00 0.71519706E+00 0.71069655E+00
+ 0.70622112E+00 0.70177065E+00 0.69734502E+00 0.69294412E+00 0.68856781E+00
+ 0.68421600E+00 0.67988855E+00 0.67558535E+00 0.67130629E+00 0.66705125E+00
+ 0.66282012E+00 0.65861277E+00 0.65442910E+00 0.65026899E+00 0.64613233E+00
+ 0.64201900E+00 0.63792889E+00 0.63386190E+00 0.62981790E+00 0.62579679E+00
+ 0.62179845E+00 0.61782278E+00 0.61386966E+00 0.60993898E+00 0.60603065E+00
+ 0.60214453E+00 0.59828054E+00 0.59443856E+00 0.59061848E+00 0.58682020E+00
+ 0.58304360E+00 0.57928859E+00 0.57555506E+00 0.57184289E+00 0.56815200E+00
+ 0.56448226E+00 0.56083359E+00 0.55720587E+00 0.55359900E+00 0.55001287E+00
+ 0.54644740E+00 0.54290246E+00 0.53937797E+00 0.53587382E+00 0.53238991E+00
+ 0.52892613E+00 0.52548240E+00 0.52205861E+00 0.51865465E+00 0.51527044E+00
+ 0.51190587E+00 0.50856085E+00 0.50523527E+00 0.50192904E+00 0.49864207E+00
+ 0.49537425E+00 0.49212549E+00 0.48889570E+00 0.48568478E+00 0.48249263E+00
+ 0.47931916E+00 0.47616428E+00 0.47302789E+00 0.46990990E+00 0.46681021E+00
+ 0.46372874E+00 0.46066539E+00 0.45762007E+00 0.45459269E+00 0.45158315E+00
+ 0.44859137E+00 0.44561726E+00 0.44266072E+00 0.43972167E+00 0.43680001E+00
+ 0.43389567E+00 0.43100854E+00 0.42813855E+00 0.42528560E+00 0.42244960E+00
+ 0.41963048E+00 0.41682814E+00 0.41404249E+00 0.41127346E+00 0.40852095E+00
+ 0.40578488E+00 0.40306517E+00 0.40036173E+00 0.39767447E+00 0.39500332E+00
+ 0.39234819E+00 0.38970899E+00 0.38708565E+00 0.38447808E+00 0.38188620E+00
+ 0.37930993E+00 0.37674918E+00 0.37420388E+00 0.37167394E+00 0.36915929E+00
+ 0.36665985E+00 0.36417553E+00 0.36170625E+00 0.35925195E+00 0.35681253E+00
+ 0.35438792E+00 0.35197804E+00 0.34958282E+00 0.34720218E+00 0.34483604E+00
+ 0.34248432E+00 0.34014695E+00 0.33782386E+00 0.33551496E+00 0.33322018E+00
+ 0.33093945E+00 0.32867269E+00 0.32641983E+00 0.32418079E+00 0.32195550E+00
+ 0.31974389E+00 0.31754589E+00 0.31536141E+00 0.31319040E+00 0.31103277E+00
+ 0.30888845E+00 0.30675738E+00 0.30463949E+00 0.30253470E+00 0.30044293E+00
+ 0.29836414E+00 0.29629823E+00 0.29424514E+00 0.29220481E+00 0.29017716E+00
+ 0.28816213E+00 0.28615965E+00 0.28416965E+00 0.28219205E+00 0.28022681E+00
+ 0.27827384E+00 0.27633308E+00 0.27440446E+00 0.27248793E+00 0.27058341E+00
+ 0.26869083E+00 0.26681014E+00 0.26494126E+00 0.26308413E+00 0.26123869E+00
+ 0.25940488E+00 0.25758257E+00 0.25576969E+00 0.25396521E+00 0.25216910E+00
+ 0.25038134E+00 0.24860192E+00 0.24683082E+00 0.24506801E+00 0.24331348E+00
+ 0.24156721E+00 0.23982918E+00 0.23809938E+00 0.23637777E+00 0.23466435E+00
+ 0.23295909E+00 0.23126198E+00 0.22957299E+00 0.22789211E+00 0.22621932E+00
+ 0.22455459E+00 0.22289792E+00 0.22124927E+00 0.21960864E+00 0.21797600E+00
+ 0.21635133E+00 0.21473462E+00 0.21312584E+00 0.21152498E+00 0.20993201E+00
+ 0.20834693E+00 0.20676970E+00 0.20520031E+00 0.20363874E+00 0.20208497E+00
+ 0.20053899E+00 0.19900077E+00 0.19747029E+00 0.19594754E+00 0.19443250E+00
+ 0.19292514E+00 0.19142545E+00 0.18993341E+00 0.18844900E+00 0.18697220E+00
+ 0.18550299E+00 0.18404136E+00 0.18258728E+00 0.18114073E+00 0.17970170E+00
+ 0.17827016E+00 0.17684610E+00 0.17542950E+00 0.17402034E+00 0.17261860E+00
+ 0.17122426E+00 0.16983731E+00 0.16845771E+00 0.16708546E+00 0.16572054E+00
+ 0.16436292E+00 0.16301258E+00 0.16166952E+00 0.16033370E+00 0.15900511E+00
+ 0.15768374E+00 0.15636955E+00 0.15506253E+00 0.15376267E+00 0.15246995E+00
+ 0.15118433E+00 0.14990582E+00 0.14863438E+00 0.14737000E+00 0.14611265E+00
+ 0.14486233E+00 0.14361901E+00 0.14238267E+00 0.14115329E+00 0.13993085E+00
+ 0.13871534E+00 0.13750673E+00 0.13630501E+00 0.13511016E+00 0.13392215E+00
+ 0.13274098E+00 0.13156661E+00 0.13039903E+00 0.12923823E+00 0.12808418E+00
+ 0.12693686E+00 0.12579625E+00 0.12466234E+00 0.12353511E+00 0.12241454E+00
+ 0.12130060E+00 0.12019328E+00 0.11909256E+00 0.11799843E+00 0.11691085E+00
+ 0.11582982E+00 0.11475531E+00 0.11368730E+00 0.11262579E+00 0.11157073E+00
+ 0.11052213E+00 0.10947995E+00 0.10844418E+00 0.10741481E+00 0.10639180E+00
+ 0.10537515E+00 0.10436483E+00 0.10336082E+00 0.10236311E+00 0.10137167E+00
+ 0.10038649E+00 0.99407546E-01 0.98434822E-01 0.97468297E-01 0.96507953E-01
+ 0.95553770E-01 0.94605729E-01 0.93663811E-01 0.92727998E-01 0.91798269E-01
+ 0.90874606E-01 0.89956991E-01 0.89045403E-01 0.88139823E-01 0.87240234E-01
+ 0.86346615E-01 0.85458947E-01 0.84577212E-01 0.83701390E-01 0.82831462E-01
+ 0.81967410E-01 0.81109213E-01 0.80256854E-01 0.79410313E-01 0.78569570E-01
+ 0.77734608E-01 0.76905406E-01 0.76081946E-01 0.75264208E-01 0.74452174E-01
+ 0.73645825E-01 0.72845140E-01 0.72050103E-01 0.71260692E-01 0.70476890E-01
+ 0.69698676E-01 0.68926033E-01 0.68158940E-01 0.67397380E-01 0.66641332E-01
+ 0.65890778E-01 0.65145699E-01 0.64406075E-01 0.63671888E-01 0.62943118E-01
+ 0.62219747E-01 0.61501754E-01 0.60789122E-01 0.60081832E-01 0.59379863E-01
+ 0.58683197E-01 0.57991815E-01 0.57305698E-01 0.56624827E-01 0.55949183E-01
+ 0.55278746E-01 0.54613497E-01 0.53953419E-01 0.53298490E-01 0.52648693E-01
+ 0.52004008E-01 0.51364416E-01 0.50729899E-01 0.50100436E-01 0.49476010E-01
+ 0.48856600E-01 0.48242189E-01 0.47632755E-01 0.47028282E-01 0.46428749E-01
+ 0.45834138E-01 0.45244429E-01 0.44659604E-01 0.44079643E-01 0.43504527E-01
+ 0.42934237E-01 0.42368755E-01 0.41808060E-01 0.41252135E-01 0.40700959E-01
+ 0.40154514E-01 0.39612781E-01 0.39075740E-01 0.38543373E-01 0.38015660E-01
+ 0.37492583E-01 0.36974123E-01 0.36460259E-01 0.35950974E-01 0.35446248E-01
+ 0.34946062E-01 0.34450397E-01 0.33959234E-01 0.33472554E-01 0.32990337E-01
+ 0.32512565E-01 0.32039219E-01 0.31570280E-01 0.31105727E-01 0.30645544E-01
+ 0.30189709E-01 0.29738205E-01 0.29291012E-01 0.28848111E-01 0.28409484E-01
+ 0.27975110E-01 0.27544971E-01 0.27119048E-01 0.26697322E-01 0.26279773E-01
+ 0.25866383E-01 0.25457132E-01 0.25052002E-01 0.24650973E-01 0.24254027E-01
+ 0.23861144E-01 0.23472305E-01 0.23087491E-01 0.22706683E-01 0.22329862E-01
+ 0.21957009E-01 0.21588105E-01 0.21223130E-01 0.20862066E-01 0.20504894E-01
+ 0.20151594E-01 0.19802148E-01 0.19456536E-01 0.19114739E-01 0.18776738E-01
+ 0.18442515E-01 0.18112050E-01 0.17785323E-01 0.17462317E-01 0.17143011E-01
+ 0.16827387E-01 0.16515426E-01 0.16207109E-01 0.15902416E-01 0.15601328E-01
+ 0.15303827E-01 0.15009894E-01 0.14719508E-01 0.14432652E-01 0.14149306E-01
+ 0.13869450E-01 0.13593067E-01 0.13320137E-01 0.13050641E-01 0.12784559E-01
+ 0.12521873E-01 0.12262563E-01 0.12006611E-01 0.11753998E-01 0.11504704E-01
+ 0.11258710E-01 0.11015997E-01 0.10776547E-01 0.10540340E-01 0.10307356E-01
+ 0.10077578E-01 0.98509857E-02 0.96275600E-02 0.94072820E-02 0.91901327E-02
+ 0.89760930E-02 0.87651437E-02 0.85572659E-02 0.83524404E-02 0.81506483E-02
+ 0.79518703E-02 0.77560875E-02 0.75632807E-02 0.73734309E-02 0.71865190E-02
+ 0.70025260E-02 0.68214328E-02 0.66432202E-02 0.64678693E-02 0.62953609E-02
+ 0.61256759E-02 0.59587954E-02 0.57947003E-02 0.56333713E-02 0.54747896E-02
+ 0.53189360E-02 0.51657914E-02 0.50153367E-02 0.48675530E-02 0.47224211E-02
+ 0.45799219E-02 0.44400364E-02 0.43027455E-02 0.41680301E-02 0.40358712E-02
+ 0.39062496E-02 0.37791464E-02 0.36545423E-02 0.35324185E-02 0.34127557E-02
+ 0.32955349E-02 0.31807371E-02 0.30683431E-02 0.29583340E-02 0.28506905E-02
+ 0.27453937E-02 0.26424245E-02 0.25417638E-02 0.24433924E-02 0.23472915E-02
+ 0.22534418E-02 0.21618243E-02 0.20724200E-02 0.19852097E-02 0.19001745E-02
+ 0.18172951E-02 0.17365525E-02 0.16579278E-02 0.15814017E-02 0.15069552E-02
+ 0.14345693E-02 0.13642249E-02 0.12959029E-02 0.12295842E-02 0.11652497E-02
+ 0.11028805E-02 0.10424573E-02 0.98396118E-03 0.92737302E-03 0.87267375E-03
+ 0.81984429E-03 0.76886557E-03 0.71971853E-03 0.67238408E-03 0.62684315E-03
+ 0.58307667E-03 0.54106556E-03 0.50079076E-03 0.46223319E-03 0.42537377E-03
+ 0.39019344E-03 0.35667312E-03 0.32479373E-03 0.29453621E-03 0.26588147E-03
+ 0.23881046E-03 0.21330409E-03 0.18934329E-03 0.16690898E-03 0.14598210E-03
+ 0.12654357E-03 0.10857432E-03 0.92055273E-04 0.76967357E-04 0.63291499E-04
+ 0.51008626E-04 0.40099664E-04 0.30545541E-04 0.22327182E-04 0.15425516E-04
+ 0.98214683E-05 0.54959661E-05 0.24299361E-05 0.60430516E-06 0.00000000E+00
+ 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02
+ 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02
+ 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02
+ 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02
+ 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02
+ 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02
+ 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02
+ 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02
+ 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02
+ 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02
+ 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02 0.31776346E+02
+ 0.31367291E+02 0.30959675E+02 0.30564419E+02 0.30180941E+02 0.29808694E+02
+ 0.29447169E+02 0.29095884E+02 0.28754388E+02 0.28422256E+02 0.28099090E+02
+ 0.27784511E+02 0.27478165E+02 0.27179716E+02 0.26888846E+02 0.26605255E+02
+ 0.26328660E+02 0.26058791E+02 0.25795393E+02 0.25538223E+02 0.25287053E+02
+ 0.25041662E+02 0.24801845E+02 0.24567402E+02 0.24338146E+02 0.24113897E+02
+ 0.23894484E+02 0.23679744E+02 0.23469522E+02 0.23263669E+02 0.23062042E+02
+ 0.22864506E+02 0.22670932E+02 0.22481194E+02 0.22295173E+02 0.22112755E+02
+ 0.21933832E+02 0.21758298E+02 0.21586052E+02 0.21416998E+02 0.21251043E+02
+ 0.21088098E+02 0.20928078E+02 0.20770899E+02 0.20616483E+02 0.20464754E+02
+ 0.20315638E+02 0.20169064E+02 0.20024964E+02 0.19883273E+02 0.19743928E+02
+ 0.19606867E+02 0.19472031E+02 0.19339364E+02 0.19208811E+02 0.19080318E+02
+ 0.18953836E+02 0.18829313E+02 0.18706702E+02 0.18585958E+02 0.18467035E+02
+ 0.18349890E+02 0.18234481E+02 0.18120768E+02 0.18008711E+02 0.17898272E+02
+ 0.17789415E+02 0.17682103E+02 0.17576303E+02 0.17471980E+02 0.17369102E+02
+ 0.17267637E+02 0.17167555E+02 0.17068825E+02 0.16971420E+02 0.16875311E+02
+ 0.16780470E+02 0.16686871E+02 0.16594489E+02 0.16503299E+02 0.16413275E+02
+ 0.16324395E+02 0.16236636E+02 0.16149975E+02 0.16064390E+02 0.15979860E+02
+ 0.15896365E+02 0.15813884E+02 0.15732399E+02 0.15651889E+02 0.15572337E+02
+ 0.15493724E+02 0.15416032E+02 0.15339246E+02 0.15263347E+02 0.15188320E+02
+ 0.15114148E+02 0.15040816E+02 0.14968310E+02 0.14896614E+02 0.14825713E+02
+ 0.14755595E+02 0.14686244E+02 0.14617649E+02 0.14549795E+02 0.14482669E+02
+ 0.14416261E+02 0.14350556E+02 0.14285543E+02 0.14221212E+02 0.14157549E+02
+ 0.14094545E+02 0.14032188E+02 0.13970468E+02 0.13909375E+02 0.13848897E+02
+ 0.13789026E+02 0.13729751E+02 0.13671063E+02 0.13612953E+02 0.13555412E+02
+ 0.13498430E+02 0.13442000E+02 0.13386112E+02 0.13330758E+02 0.13275930E+02
+ 0.13221620E+02 0.13167820E+02 0.13114523E+02 0.13061721E+02 0.13009406E+02
+ 0.12957571E+02 0.12906210E+02 0.12855315E+02 0.12804879E+02 0.12754896E+02
+ 0.12705360E+02 0.12656263E+02 0.12607600E+02 0.12559365E+02 0.12511550E+02
+ 0.12464152E+02 0.12417163E+02 0.12370577E+02 0.12324391E+02 0.12278596E+02
+ 0.12233190E+02 0.12188166E+02 0.12143518E+02 0.12099242E+02 0.12055334E+02
+ 0.12011787E+02 0.11968597E+02 0.11925760E+02 0.11883270E+02 0.11841124E+02
+ 0.11799316E+02 0.11757843E+02 0.11716699E+02 0.11675881E+02 0.11635385E+02
+ 0.11595206E+02 0.11555340E+02 0.11515784E+02 0.11476533E+02 0.11437584E+02
+ 0.11398933E+02 0.11360576E+02 0.11322509E+02 0.11284729E+02 0.11247233E+02
+ 0.11210017E+02 0.11173077E+02 0.11136410E+02 0.11100014E+02 0.11063884E+02
+ 0.11028017E+02 0.10992411E+02 0.10957062E+02 0.10921967E+02 0.10887123E+02
+ 0.10852528E+02 0.10818178E+02 0.10784070E+02 0.10750202E+02 0.10716571E+02
+ 0.10683175E+02 0.10650010E+02 0.10617073E+02 0.10584363E+02 0.10551877E+02
+ 0.10519612E+02 0.10487566E+02 0.10455736E+02 0.10424121E+02 0.10392716E+02
+ 0.10361521E+02 0.10330533E+02 0.10299749E+02 0.10269168E+02 0.10238787E+02
+ 0.10208604E+02 0.10178617E+02 0.10148824E+02 0.10119223E+02 0.10089811E+02
+ 0.10060587E+02 0.10031548E+02 0.10002694E+02 0.99740211E+01 0.99455282E+01
+ 0.99172134E+01 0.98890747E+01 0.98611104E+01 0.98333187E+01 0.98056978E+01
+ 0.97782459E+01 0.97509613E+01 0.97238424E+01 0.96968874E+01 0.96700947E+01
+ 0.96434626E+01 0.96169896E+01 0.95906741E+01 0.95645145E+01 0.95385092E+01
+ 0.95126567E+01 0.94869555E+01 0.94614042E+01 0.94360013E+01 0.94107452E+01
+ 0.93856347E+01 0.93606682E+01 0.93358445E+01 0.93111620E+01 0.92866196E+01
+ 0.92622157E+01 0.92379492E+01 0.92138187E+01 0.91898229E+01 0.91659606E+01
+ 0.91422304E+01 0.91186312E+01 0.90951618E+01 0.90718209E+01 0.90486073E+01
+ 0.90255199E+01 0.90025575E+01 0.89797189E+01 0.89570031E+01 0.89344088E+01
+ 0.89119351E+01 0.88895807E+01 0.88673446E+01 0.88452258E+01 0.88232232E+01
+ 0.88013358E+01 0.87795625E+01 0.87579023E+01 0.87363542E+01 0.87149172E+01
+ 0.86935903E+01 0.86723726E+01 0.86512631E+01 0.86302609E+01 0.86093650E+01
+ 0.85885745E+01 0.85678886E+01 0.85473061E+01 0.85268264E+01 0.85064485E+01
+ 0.84861716E+01 0.84659947E+01 0.84459171E+01 0.84259378E+01 0.84060561E+01
+ 0.83862711E+01 0.83665820E+01 0.83469881E+01 0.83274885E+01 0.83080824E+01
+ 0.82887690E+01 0.82695476E+01 0.82504175E+01 0.82313778E+01 0.82124278E+01
+ 0.81935669E+01 0.81747942E+01 0.81561090E+01 0.81375107E+01 0.81189985E+01
+ 0.81005717E+01 0.80822297E+01 0.80639717E+01 0.80457971E+01 0.80277052E+01
+ 0.80096954E+01 0.79917670E+01 0.79739193E+01 0.79561518E+01 0.79384637E+01
+ 0.79208545E+01 0.79033236E+01 0.78858703E+01 0.78684940E+01 0.78511941E+01
+ 0.78339701E+01 0.78168213E+01 0.77997472E+01 0.77827471E+01 0.77658206E+01
+ 0.77489670E+01 0.77321858E+01 0.77154765E+01 0.76988385E+01 0.76822712E+01
+ 0.76657741E+01 0.76493468E+01 0.76329886E+01 0.76166990E+01 0.76004776E+01
+ 0.75843238E+01 0.75682371E+01 0.75522171E+01 0.75362631E+01 0.75203748E+01
+ 0.75045517E+01 0.74887932E+01 0.74730990E+01 0.74574685E+01 0.74419012E+01
+ 0.74263967E+01 0.74109546E+01 0.73955744E+01 0.73802556E+01 0.73649978E+01
+ 0.73498006E+01 0.73346635E+01 0.73195861E+01 0.73045680E+01 0.72896088E+01
+ 0.72747079E+01 0.72598651E+01 0.72450799E+01 0.72303519E+01 0.72156807E+01
+ 0.72010659E+01 0.71865070E+01 0.71720038E+01 0.71575558E+01 0.71431627E+01
+ 0.71288240E+01 0.71145394E+01 0.71003085E+01 0.70861309E+01 0.70720063E+01
+ 0.70579343E+01 0.70439146E+01 0.70299467E+01 0.70160304E+01 0.70021652E+01
+ 0.69883509E+01 0.69745871E+01 0.69608734E+01 0.69472095E+01 0.69335952E+01
+ 0.69200299E+01 0.69065135E+01 0.68930456E+01 0.68796258E+01 0.68662539E+01
+ 0.68529295E+01 0.68396523E+01 0.68264221E+01 0.68132384E+01 0.68001010E+01
+ 0.67870096E+01 0.67739639E+01 0.67609635E+01 0.67480083E+01 0.67350978E+01
+ 0.67222319E+01 0.67094102E+01 0.66966324E+01 0.66838982E+01 0.66712074E+01
+ 0.66585598E+01 0.66459549E+01 0.66333925E+01 0.66208725E+01 0.66083944E+01
+ 0.65959581E+01 0.65835632E+01 0.65712095E+01 0.65588968E+01 0.65466248E+01
+ 0.65343932E+01 0.65222017E+01 0.65100503E+01 0.64979384E+01 0.64858661E+01
+ 0.64738329E+01 0.64618386E+01 0.64498831E+01 0.64379660E+01 0.64260871E+01
+ 0.64142462E+01 0.64024431E+01 0.63906775E+01 0.63789492E+01 0.63672580E+01
+ 0.63556037E+01 0.63439859E+01 0.63324045E+01 0.63208594E+01 0.63093501E+01
+ 0.62978767E+01 0.62864387E+01 0.62750361E+01 0.62636685E+01 0.62523359E+01
+ 0.62410380E+01 0.62297745E+01 0.62185453E+01 0.62073502E+01 0.61961889E+01
+ 0.61850613E+01 0.61739672E+01 0.61629064E+01 0.61518786E+01 0.61408837E+01
+ 0.61299215E+01 0.61189919E+01 0.61080945E+01 0.60972293E+01 0.60863960E+01
+ 0.60755944E+01 0.60648244E+01 0.60540859E+01 0.60433785E+01 0.60327021E+01
+ 0.60220566E+01 0.60114418E+01 0.60008575E+01 0.59903035E+01 0.59797797E+01
+ 0.59692858E+01 0.59588218E+01 0.59483874E+01 0.59379825E+01 0.59276069E+01
+ 0.59172605E+01 0.59069430E+01 0.58966543E+01 0.58863944E+01 0.58761629E+01
+ 0.58659597E+01 0.58557848E+01 0.58456379E+01 0.58355188E+01 0.58254275E+01
+ 0.58153638E+01 0.58053274E+01 0.57953183E+01 0.57853364E+01 0.57753814E+01
+ 0.57654532E+01 0.57555517E+01 0.57456768E+01 0.57358282E+01 0.57260059E+01
+ 0.57162097E+01 0.57064394E+01 0.56966950E+01 0.56869762E+01 0.56772830E+01
+ 0.56676152E+01 0.56579727E+01 0.56483553E+01 0.56387629E+01 0.56291954E+01
+ 0.56196526E+01 0.56101344E+01 0.56006408E+01 0.55911714E+01 0.55817263E+01
+ 0.55723053E+01 0.55629082E+01 0.55535350E+01 0.55441856E+01 0.55348597E+01
+ 0.55255573E+01 0.55162782E+01 0.55070224E+01 0.54977896E+01 0.54885799E+01
+ 0.54793930E+01 0.54702289E+01 0.54610875E+01 0.54519685E+01 0.54428720E+01
+ 0.54337977E+01 0.54247457E+01 0.54157157E+01 0.54067076E+01 0.53977214E+01
+ 0.53887570E+01 0.53798141E+01 0.53708928E+01 0.53619929E+01 0.53531142E+01
+ 0.53442568E+01 0.53354205E+01 0.53266051E+01 0.53178106E+01 0.53090369E+01
+ 0.53002839E+01 0.52915514E+01 0.52828394E+01 0.52741478E+01 0.52654764E+01
+ 0.52568252E+01 0.52481940E+01 0.52395828E+01 0.52309915E+01 0.52224200E+01
+ 0.52138682E+01 0.52053359E+01 0.51968231E+01 0.51883297E+01 0.51798556E+01
+ 0.51714008E+01 0.51629650E+01 0.51545483E+01 0.51461504E+01 0.51377715E+01
+ 0.51294113E+01 0.51210697E+01 0.51127467E+01 0.51044422E+01 0.50961561E+01
+ 0.50878883E+01 0.50796387E+01 0.50714073E+01 0.50631939E+01 0.50549985E+01
+ 0.50468210E+01 0.50386613E+01 0.50305192E+01 0.50223949E+01 0.50142880E+01
+ 0.50061987E+01 0.49981267E+01 0.49900721E+01 0.49820346E+01 0.49740144E+01
+ 0.49660112E+01 0.49580250E+01 0.49500557E+01 0.49421032E+01 0.49341675E+01
+ 0.49262485E+01 0.49183461E+01 0.49104602E+01 0.49025908E+01 0.48947378E+01
+ 0.48869011E+01 0.48790806E+01 0.48712763E+01 0.48634881E+01 0.48557159E+01
+ 0.48479596E+01 0.48402193E+01 0.48324947E+01 0.48247859E+01 0.48170927E+01
+ 0.48094151E+01 0.48017531E+01 0.47941065E+01 0.47864753E+01 0.47788595E+01
+ 0.47712589E+01 0.47636735E+01 0.47561032E+01 0.47485480E+01 0.47410077E+01
+ 0.47334824E+01 0.47259720E+01 0.47184764E+01 0.47109955E+01 0.47035292E+01
+ 0.46960776E+01 0.46886405E+01 0.46812179E+01 0.46738098E+01 0.46664160E+01
+ 0.46590365E+01 0.46516712E+01 0.46443201E+01 0.46369831E+01 0.46296602E+01
+ 0.46223513E+01 0.46150564E+01 0.46077753E+01 0.46005080E+01 0.45932545E+01
+ 0.45860148E+01 0.45787886E+01 0.45715761E+01 0.45643771E+01 0.45571916E+01
+ 0.45500195E+01 0.45428608E+01 0.45357154E+01 0.45285833E+01 0.45214644E+01
+ 0.45143586E+01 0.45072660E+01 0.45001864E+01 0.44931198E+01 0.44860661E+01
+ 0.44790253E+01 0.44719974E+01 0.44649822E+01 0.44579798E+01 0.44509901E+01
+ 0.44440130E+01 0.44370484E+01 0.44300965E+01 0.44231570E+01 0.44162299E+01
+ 0.44093152E+01 0.44024129E+01 0.43955228E+01 0.43886450E+01 0.43817793E+01
+ 0.43749258E+01 0.43680845E+01 0.43612551E+01 0.43544378E+01 0.43476324E+01
+ 0.43408389E+01 0.43340573E+01 0.43272874E+01 0.43205294E+01 0.43137831E+01
+ 0.43070485E+01 0.43003255E+01 0.42936141E+01 0.42869142E+01 0.42802259E+01
+ 0.42735490E+01 0.42668835E+01 0.42602294E+01 0.42535866E+01 0.42469551E+01
+ 0.42403349E+01 0.42337258E+01 0.42271279E+01 0.42205412E+01 0.42139655E+01
+ 0.42074009E+01 0.42008472E+01 0.41943045E+01 0.41877727E+01 0.41812518E+01
+ 0.41747417E+01 0.41682425E+01 0.41617539E+01 0.41552761E+01 0.41488090E+01
+ 0.41423525E+01 0.41359066E+01 0.41294713E+01 0.41230465E+01 0.41166322E+01
+ 0.41102283E+01 0.41038348E+01 0.40974517E+01 0.40910790E+01 0.40847165E+01
+ 0.40783644E+01 0.40720224E+01 0.40656906E+01 0.40593690E+01 0.40530575E+01
+ 0.40467561E+01 0.40404647E+01 0.40341833E+01 0.40279120E+01 0.40216505E+01
+ 0.40153990E+01 0.40091574E+01 0.40029255E+01 0.39967035E+01 0.39904913E+01
+ 0.39842888E+01 0.39780960E+01 0.39719129E+01 0.39657394E+01 0.39595755E+01
+ 0.39534213E+01 0.39472765E+01 0.39411413E+01 0.39350155E+01 0.39288992E+01
+ 0.39227923E+01 0.39166947E+01 0.39106066E+01 0.39045277E+01 0.38984582E+01
+ 0.38923979E+01 0.38863468E+01 0.38803049E+01 0.38742722E+01 0.38682486E+01
+ 0.38622342E+01 0.38562288E+01 0.38502325E+01 0.38442451E+01 0.38382668E+01
+ 0.38322975E+01 0.38263370E+01 0.38203855E+01 0.38144429E+01 0.38085090E+01
+ 0.38025841E+01 0.37966679E+01 0.37907604E+01 0.37848617E+01 0.37789717E+01
+ 0.37730904E+01 0.37672178E+01 0.37613538E+01 0.37554983E+01 0.37496515E+01
+ 0.37438131E+01 0.37379834E+01 0.37321621E+01 0.37263492E+01 0.37205448E+01
+ 0.37147488E+01 0.37089612E+01 0.37031820E+01 0.36974111E+01 0.36916486E+01
+ 0.36858943E+01 0.36801482E+01 0.36744104E+01 0.36686809E+01 0.36629595E+01
+ 0.36572463E+01 0.36515412E+01 0.36458442E+01 0.36401553E+01 0.36344745E+01
+ 0.36288017E+01 0.36231370E+01 0.36174803E+01 0.36118315E+01 0.36061906E+01
+ 0.36005577E+01 0.35949328E+01 0.35893156E+01 0.35837064E+01 0.35781050E+01
+ 0.35725114E+01 0.35669255E+01 0.35613475E+01 0.35557772E+01 0.35502146E+01
+ 0.35446597E+01 0.35391126E+01 0.35335730E+01 0.35280411E+01 0.35225169E+01
+ 0.35170002E+01 0.35114911E+01 0.35059895E+01 0.35004955E+01 0.34950090E+01
+ 0.34895300E+01 0.34840584E+01 0.34785943E+01 0.34731377E+01 0.34676884E+01
+ 0.34622466E+01 0.34568121E+01 0.34513849E+01 0.34459651E+01 0.34405526E+01
+ 0.34351474E+01 0.34297495E+01 0.34243588E+01 0.34189753E+01 0.34135991E+01
+ 0.34082300E+01 0.34028682E+01 0.33975135E+01 0.33921659E+01 0.33868255E+01
+ 0.33814921E+01 0.33761659E+01 0.33708467E+01 0.33655345E+01 0.33602294E+01
+ 0.33549313E+01 0.33496402E+01 0.33443561E+01 0.33390789E+01 0.33338086E+01
+ 0.33285453E+01 0.33232889E+01 0.33180394E+01 0.33127968E+01 0.33075610E+01
+ 0.33023320E+01 0.32971099E+01 0.32918946E+01 0.32866861E+01 0.32814843E+01
+ 0.32762893E+01 0.32711010E+01 0.32659195E+01 0.32607446E+01 0.32555765E+01
+ 0.32504150E+01 0.32452602E+01 0.32401120E+01 0.32349704E+01 0.32298355E+01
+ 0.32247072E+01 0.32195854E+01 0.32144702E+01 0.32093615E+01 0.32042594E+01
+ 0.31991638E+01 0.31940747E+01 0.31889921E+01 0.31839160E+01 0.31788463E+01
+ 0.31737831E+01 0.31687263E+01 0.31636759E+01 0.31586319E+01 0.31535943E+01
+ 0.31485631E+01 0.31435382E+01 0.31385197E+01 0.31335075E+01 0.31285016E+01
+ 0.31235020E+01 0.31185087E+01 0.31135217E+01 0.31085409E+01 0.31035664E+01
+ 0.30985981E+01 0.30936361E+01 0.30886802E+01 0.30837306E+01 0.30787871E+01
+ 0.30738498E+01 0.30689186E+01 0.30639936E+01 0.30590747E+01 0.30541619E+01
+ 0.30492552E+01 0.30443547E+01 0.30394602E+01 0.30345717E+01 0.30296893E+01
+ 0.30248130E+01 0.30199426E+01 0.30150783E+01 0.30102200E+01 0.30053677E+01
+ 0.30005213E+01 0.29956809E+01 0.29908465E+01 0.29860180E+01 0.29811955E+01
+ 0.29763788E+01 0.29715681E+01 0.29667633E+01 0.29619643E+01 0.29571713E+01
+ 0.29523840E+01 0.29476027E+01 0.29428271E+01 0.29380574E+01 0.29332935E+01
+ 0.29285355E+01 0.29237832E+01 0.29190367E+01 0.29142959E+01 0.29095610E+01
+ 0.29048317E+01 0.29001082E+01 0.28953905E+01 0.28906784E+01 0.28859721E+01
+ 0.28812715E+01 0.28765765E+01 0.28718872E+01 0.28672036E+01 0.28625257E+01
+ 0.28578534E+01 0.28531867E+01 0.28485256E+01 0.28438702E+01 0.28392204E+01
+ 0.28345761E+01 0.28299375E+01 0.28253044E+01 0.28206769E+01 0.28160549E+01
+ 0.28114385E+01 0.28068276E+01 0.28022223E+01 0.27976225E+01 0.27930281E+01
+ 0.27884393E+01 0.27838560E+01 0.27792781E+01 0.27747057E+01 0.27701388E+01
+ 0.27655773E+01 0.27610213E+01 0.27564707E+01 0.27519255E+01 0.27473858E+01
+ 0.27428514E+01 0.27383225E+01 0.27337989E+01 0.27292808E+01 0.27247679E+01
+ 0.27202605E+01 0.27157584E+01 0.27112617E+01 0.27067703E+01 0.27022842E+01
+ 0.26978035E+01 0.26933280E+01 0.26888579E+01 0.26843930E+01 0.26799335E+01
+ 0.26754792E+01 0.26710302E+01 0.26665865E+01 0.26621480E+01 0.26577148E+01
+ 0.26532868E+01 0.26488640E+01 0.26444465E+01 0.26400342E+01 0.26356271E+01
+ 0.26312252E+01 0.26268285E+01 0.26224369E+01 0.26180506E+01 0.26136694E+01
+ 0.26092934E+01 0.26049225E+01 0.26005568E+01 0.25961962E+01 0.25918408E+01
+ 0.25874905E+01 0.25831453E+01 0.25788052E+01 0.25744702E+01 0.25701403E+01
+ 0.25658155E+01 0.25614958E+01 0.25571812E+01 0.25528716E+01 0.25485671E+01
+ 0.25442677E+01 0.25399733E+01 0.25356839E+01 0.25313996E+01 0.25271203E+01
+ 0.25228460E+01 0.25185768E+01 0.25143125E+01 0.25100533E+01 0.25057990E+01
+ 0.25015498E+01 0.24973055E+01 0.24930662E+01 0.24888319E+01 0.24846025E+01
+ 0.24803781E+01 0.24761586E+01 0.24719441E+01 0.24677345E+01 0.24635298E+01
+ 0.24593301E+01 0.24551353E+01 0.24509454E+01 0.24467604E+01 0.24425803E+01
+ 0.24384051E+01 0.24342348E+01 0.24300694E+01 0.24259089E+01 0.24217532E+01
+ 0.24176024E+01 0.24134565E+01 0.24093154E+01 0.24051791E+01 0.24010477E+01
+ 0.23969212E+01 0.23927994E+01 0.23886825E+01 0.23845704E+01 0.23804631E+01
+ 0.23763607E+01 0.23722630E+01 0.23681702E+01 0.23640821E+01 0.23599988E+01
+ 0.23559203E+01 0.23518466E+01 0.23477776E+01 0.23437134E+01 0.23396540E+01
+ 0.23355994E+01 0.23315494E+01 0.23275043E+01 0.23234638E+01 0.23194281E+01
+ 0.23153972E+01 0.23113709E+01 0.23073494E+01 0.23033326E+01 0.22993205E+01
+ 0.22953131E+01 0.22913104E+01 0.22873124E+01 0.22833191E+01 0.22793304E+01
+ 0.22753465E+01 0.22713672E+01 0.22673926E+01 0.22634227E+01 0.22594574E+01
+ 0.22554968E+01 0.22515409E+01 0.22475896E+01 0.22436429E+01 0.22397009E+01
+ 0.22357635E+01 0.22318307E+01 0.22279025E+01 0.22239790E+01 0.22200601E+01
+ 0.22161458E+01 0.22122361E+01 0.22083311E+01 0.22044306E+01 0.22005347E+01
+ 0.21966434E+01 0.21927567E+01 0.21888745E+01 0.21849970E+01 0.21811240E+01
+ 0.21772556E+01 0.21733917E+01 0.21695324E+01 0.21656777E+01 0.21618275E+01
+ 0.21579819E+01 0.21541408E+01 0.21503042E+01 0.21464722E+01 0.21426447E+01
+ 0.21388218E+01 0.21350033E+01 0.21311894E+01 0.21273800E+01 0.21235751E+01
+ 0.21197748E+01 0.21159789E+01 0.21121875E+01 0.21084007E+01 0.21046183E+01
+ 0.21008404E+01 0.20970670E+01 0.20932981E+01 0.20895336E+01 0.20857736E+01
+ 0.20820181E+01 0.20782671E+01 0.20745205E+01 0.20707784E+01 0.20670407E+01
+ 0.20633075E+01 0.20595788E+01 0.20558545E+01 0.20521346E+01 0.20484192E+01
+ 0.20447082E+01 0.20410016E+01 0.20372995E+01 0.20336018E+01 0.20299085E+01
+ 0.20262196E+01 0.20225351E+01 0.20188551E+01 0.20151795E+01 0.20115082E+01
+ 0.20078414E+01 0.20041789E+01 0.20005209E+01 0.19968672E+01 0.19932180E+01
+ 0.19895731E+01 0.19859326E+01 0.19822965E+01 0.19786647E+01 0.19750373E+01
+ 0.19714143E+01 0.19677957E+01 0.19641814E+01 0.19605715E+01 0.19569659E+01
+ 0.19533647E+01 0.19497678E+01 0.19461753E+01 0.19425871E+01 0.19390033E+01
+ 0.19354238E+01 0.19318486E+01 0.19282778E+01 0.19247113E+01 0.19211491E+01
+ 0.19175913E+01 0.19140377E+01 0.19104885E+01 0.19069436E+01 0.19034030E+01
+ 0.18998667E+01 0.18963347E+01 0.18928070E+01 0.18892837E+01 0.18857646E+01
+ 0.18822498E+01 0.18787393E+01 0.18752331E+01 0.18717311E+01 0.18682335E+01
+ 0.18647401E+01 0.18612510E+01 0.18577662E+01 0.18542857E+01 0.18508094E+01
+ 0.18473374E+01 0.18438697E+01 0.18404062E+01 0.18369469E+01 0.18334920E+01
+ 0.18300413E+01 0.18265948E+01 0.18231526E+01 0.18197146E+01 0.18162809E+01
+ 0.18128514E+01 0.18094261E+01 0.18060051E+01 0.18025883E+01 0.17991757E+01
+ 0.17957674E+01 0.17923633E+01 0.17889634E+01 0.17855677E+01 0.17821763E+01
+ 0.17787890E+01 0.17754060E+01 0.17720272E+01 0.17686526E+01 0.17652822E+01
+ 0.17619160E+01 0.17585540E+01 0.17551962E+01 0.17518426E+01 0.17484931E+01
+ 0.17451479E+01 0.17418069E+01 0.17384700E+01 0.17351373E+01 0.17318088E+01
+ 0.17284845E+01 0.17251644E+01 0.17218484E+01 0.17185366E+01 0.17152290E+01
+ 0.17119255E+01 0.17086262E+01 0.17053311E+01 0.17020401E+01 0.16987533E+01
+ 0.16954706E+01 0.16921921E+01 0.16889178E+01 0.16856476E+01 0.16823815E+01
+ 0.16791196E+01 0.16758618E+01 0.16726082E+01 0.16693586E+01 0.16661133E+01
+ 0.16628720E+01 0.16596349E+01 0.16564020E+01 0.16531731E+01 0.16499484E+01
+ 0.16467278E+01 0.16435113E+01 0.16402989E+01 0.16370907E+01 0.16338865E+01
+ 0.16306865E+01 0.16274906E+01 0.16242987E+01 0.16211110E+01 0.16179274E+01
+ 0.16147479E+01 0.16115725E+01 0.16084012E+01 0.16052340E+01 0.16020708E+01
+ 0.15989118E+01 0.15957569E+01 0.15926060E+01 0.15894592E+01 0.15863165E+01
+ 0.15831779E+01 0.15800433E+01 0.15769129E+01 0.15737865E+01 0.15706642E+01
+ 0.15675459E+01 0.15644317E+01 0.15613216E+01 0.15582155E+01 0.15551135E+01
+ 0.15520156E+01 0.15489217E+01 0.15458319E+01 0.15427461E+01 0.15396644E+01
+ 0.15365867E+01 0.15335131E+01 0.15304435E+01 0.15273780E+01 0.15243165E+01
+ 0.15212591E+01 0.15182056E+01 0.15151563E+01 0.15121109E+01 0.15090696E+01
+ 0.15060323E+01 0.15029991E+01 0.14999698E+01 0.14969446E+01 0.14939234E+01
+ 0.14909063E+01 0.14878931E+01 0.14848840E+01 0.14818789E+01 0.14788777E+01
+ 0.14758806E+01 0.14728876E+01 0.14698985E+01 0.14669134E+01 0.14639323E+01
+ 0.14609552E+01 0.14579822E+01 0.14550131E+01 0.14520480E+01 0.14490869E+01
+ 0.14461298E+01 0.14431767E+01 0.14402276E+01 0.14372824E+01 0.14343413E+01
+ 0.14314041E+01 0.14284709E+01 0.14255417E+01 0.14226165E+01 0.14196952E+01
+ 0.14167779E+01 0.14138646E+01 0.14109553E+01 0.14080499E+01 0.14051484E+01
+ 0.14022510E+01 0.13993575E+01 0.13964680E+01 0.13935824E+01 0.13907007E+01
+ 0.13878231E+01 0.13849494E+01 0.13820796E+01 0.13792138E+01 0.13763519E+01
+ 0.13734940E+01 0.13706400E+01 0.13677899E+01 0.13649438E+01 0.13621017E+01
+ 0.13592634E+01 0.13564291E+01 0.13535988E+01 0.13507723E+01 0.13479498E+01
+ 0.13451312E+01 0.13423166E+01 0.13395058E+01 0.13366990E+01 0.13338961E+01
+ 0.13310971E+01 0.13283020E+01 0.13255109E+01 0.13227236E+01 0.13199403E+01
+ 0.13171609E+01 0.13143853E+01 0.13116137E+01 0.13088460E+01 0.13060822E+01
+ 0.13033223E+01 0.13005663E+01 0.12978141E+01 0.12950659E+01 0.12923216E+01
+ 0.12895811E+01 0.12868445E+01 0.12841118E+01 0.12813831E+01 0.12786581E+01
+ 0.12759371E+01 0.12732199E+01 0.12705067E+01 0.12677973E+01 0.12650917E+01
+ 0.12623901E+01 0.12596923E+01 0.12569983E+01 0.12543083E+01 0.12516221E+01
+ 0.12489397E+01 0.12462612E+01 0.12435866E+01 0.12409159E+01 0.12382489E+01
+ 0.12355859E+01 0.12329267E+01 0.12302713E+01 0.12276198E+01 0.12249721E+01
+ 0.12223283E+01 0.12196883E+01 0.12170522E+01 0.12144199E+01 0.12117914E+01
+ 0.12091667E+01 0.12065459E+01 0.12039289E+01 0.12013158E+01 0.11987065E+01
+ 0.11961010E+01 0.11934993E+01 0.11909014E+01 0.11883074E+01 0.11857172E+01
+ 0.11831307E+01 0.11805481E+01 0.11779694E+01 0.11753944E+01 0.11728232E+01
+ 0.11702558E+01 0.11676923E+01 0.11651325E+01 0.11625766E+01 0.11600244E+01
+ 0.11574760E+01 0.11549315E+01 0.11523907E+01 0.11498537E+01 0.11473205E+01
+ 0.11447911E+01 0.11422654E+01 0.11397436E+01 0.11372255E+01 0.11347112E+01
+ 0.11322007E+01 0.11296939E+01 0.11271910E+01 0.11246918E+01 0.11221963E+01
+ 0.11197047E+01 0.11172168E+01 0.11147327E+01 0.11122523E+01 0.11097757E+01
+ 0.11073028E+01 0.11048337E+01 0.11023683E+01 0.10999068E+01 0.10974489E+01
+ 0.10949948E+01 0.10925444E+01 0.10900978E+01 0.10876550E+01 0.10852158E+01
+ 0.10827804E+01 0.10803488E+01 0.10779208E+01 0.10754966E+01 0.10730762E+01
+ 0.10706594E+01 0.10682464E+01 0.10658371E+01 0.10634316E+01 0.10610297E+01
+ 0.10586316E+01 0.10562372E+01 0.10538465E+01 0.10514595E+01 0.10490762E+01
+ 0.10466966E+01 0.10443208E+01 0.10419486E+01 0.10395801E+01 0.10372154E+01
+ 0.10348543E+01 0.10324969E+01 0.10301432E+01 0.10277932E+01 0.10254469E+01
+ 0.10231043E+01 0.10207654E+01 0.10184302E+01 0.10160986E+01 0.10137707E+01
+ 0.10114465E+01 0.10091260E+01 0.10068091E+01 0.10044959E+01 0.10021864E+01
+ 0.99988051E+00 0.99757832E+00 0.99527979E+00 0.99298491E+00 0.99069370E+00
+ 0.98840614E+00 0.98612223E+00 0.98384197E+00 0.98156537E+00 0.97929241E+00
+ 0.97702309E+00 0.97475742E+00 0.97249539E+00 0.97023700E+00 0.96798224E+00
+ 0.96573112E+00 0.96348363E+00 0.96123977E+00 0.95899954E+00 0.95676293E+00
+ 0.95452995E+00 0.95230058E+00 0.95007484E+00 0.94785271E+00 0.94563420E+00
+ 0.94341930E+00 0.94120801E+00 0.93900033E+00 0.93679626E+00 0.93459579E+00
+ 0.93239892E+00 0.93020565E+00 0.92801597E+00 0.92582989E+00 0.92364741E+00
+ 0.92146851E+00 0.91929320E+00 0.91712148E+00 0.91495334E+00 0.91278879E+00
+ 0.91062781E+00 0.90847041E+00 0.90631658E+00 0.90416633E+00 0.90201964E+00
+ 0.89987653E+00 0.89773698E+00 0.89560099E+00 0.89346857E+00 0.89133970E+00
+ 0.88921439E+00 0.88709263E+00 0.88497442E+00 0.88285977E+00 0.88074866E+00
+ 0.87864110E+00 0.87653708E+00 0.87443660E+00 0.87233965E+00 0.87024624E+00
+ 0.86815637E+00 0.86607003E+00 0.86398721E+00 0.86190792E+00 0.85983216E+00
+ 0.85775992E+00 0.85569119E+00 0.85362598E+00 0.85156429E+00 0.84950611E+00
+ 0.84745144E+00 0.84540028E+00 0.84335262E+00 0.84130846E+00 0.83926780E+00
+ 0.83723064E+00 0.83519698E+00 0.83316681E+00 0.83114013E+00 0.82911693E+00
+ 0.82709723E+00 0.82508100E+00 0.82306826E+00 0.82105900E+00 0.81905321E+00
+ 0.81705089E+00 0.81505205E+00 0.81305667E+00 0.81106476E+00 0.80907631E+00
+ 0.80709133E+00 0.80510980E+00 0.80313173E+00 0.80115711E+00 0.79918594E+00
+ 0.79721823E+00 0.79525395E+00 0.79329313E+00 0.79133574E+00 0.78938179E+00
+ 0.78743128E+00 0.78548420E+00 0.78354055E+00 0.78160033E+00 0.77966354E+00
+ 0.77773017E+00 0.77580022E+00 0.77387369E+00 0.77195058E+00 0.77003088E+00
+ 0.76811459E+00 0.76620171E+00 0.76429223E+00 0.76238616E+00 0.76048348E+00
+ 0.75858421E+00 0.75668806E+00 0.75478518E+00 0.75287069E+00 0.75094468E+00
+ 0.74900724E+00 0.74705844E+00 0.74509839E+00 0.74312717E+00 0.74114487E+00
+ 0.73915157E+00 0.73714737E+00 0.73513236E+00 0.73310662E+00 0.73107024E+00
+ 0.72902330E+00 0.72696591E+00 0.72489814E+00 0.72282009E+00 0.72073184E+00
+ 0.71863349E+00 0.71652511E+00 0.71440680E+00 0.71227865E+00 0.71014075E+00
+ 0.70799318E+00 0.70583603E+00 0.70366939E+00 0.70149335E+00 0.69930800E+00
+ 0.69711343E+00 0.69490972E+00 0.69269697E+00 0.69047526E+00 0.68824467E+00
+ 0.68600531E+00 0.68375725E+00 0.68150059E+00 0.67923542E+00 0.67696181E+00
+ 0.67467987E+00 0.67238968E+00 0.67009132E+00 0.66778489E+00 0.66547048E+00
+ 0.66314817E+00 0.66081805E+00 0.65848021E+00 0.65613474E+00 0.65378173E+00
+ 0.65142126E+00 0.64905343E+00 0.64667832E+00 0.64429602E+00 0.64190662E+00
+ 0.63951021E+00 0.63710688E+00 0.63469671E+00 0.63227979E+00 0.62985621E+00
+ 0.62742607E+00 0.62498944E+00 0.62254643E+00 0.62009710E+00 0.61764156E+00
+ 0.61517990E+00 0.61271219E+00 0.61023854E+00 0.60775902E+00 0.60527373E+00
+ 0.60278275E+00 0.60028618E+00 0.59778410E+00 0.59527660E+00 0.59276377E+00
+ 0.59024569E+00 0.58772246E+00 0.58519417E+00 0.58266089E+00 0.58012273E+00
+ 0.57757977E+00 0.57503210E+00 0.57247980E+00 0.56992297E+00 0.56736169E+00
+ 0.56479605E+00 0.56222614E+00 0.55965205E+00 0.55707387E+00 0.55449169E+00
+ 0.55190559E+00 0.54931566E+00 0.54672199E+00 0.54412467E+00 0.54152379E+00
+ 0.53891944E+00 0.53631170E+00 0.53370066E+00 0.53108642E+00 0.52846905E+00
+ 0.52584866E+00 0.52322532E+00 0.52059913E+00 0.51797017E+00 0.51533853E+00
+ 0.51270431E+00 0.51006758E+00 0.50742845E+00 0.50478699E+00 0.50214329E+00
+ 0.49949745E+00 0.49684955E+00 0.49419968E+00 0.49154792E+00 0.48889438E+00
+ 0.48623913E+00 0.48358226E+00 0.48092387E+00 0.47826404E+00 0.47560286E+00
+ 0.47294041E+00 0.47027680E+00 0.46761209E+00 0.46494639E+00 0.46227979E+00
+ 0.45961236E+00 0.45694420E+00 0.45427540E+00 0.45160604E+00 0.44893622E+00
+ 0.44626602E+00 0.44359553E+00 0.44092484E+00 0.43825404E+00 0.43558322E+00
+ 0.43291246E+00 0.43024185E+00 0.42757148E+00 0.42490145E+00 0.42223183E+00
+ 0.41956273E+00 0.41689421E+00 0.41422638E+00 0.41155933E+00 0.40889313E+00
+ 0.40622788E+00 0.40356368E+00 0.40090059E+00 0.39823873E+00 0.39557816E+00
+ 0.39291899E+00 0.39026130E+00 0.38760518E+00 0.38495071E+00 0.38229799E+00
+ 0.37964710E+00 0.37699814E+00 0.37435118E+00 0.37170633E+00 0.36906367E+00
+ 0.36642328E+00 0.36378525E+00 0.36114968E+00 0.35851665E+00 0.35588625E+00
+ 0.35325857E+00 0.35063370E+00 0.34801172E+00 0.34539272E+00 0.34277680E+00
+ 0.34016404E+00 0.33755453E+00 0.33494836E+00 0.33234561E+00 0.32974638E+00
+ 0.32715075E+00 0.32455881E+00 0.32197066E+00 0.31938637E+00 0.31680604E+00
+ 0.31422975E+00 0.31165760E+00 0.30908967E+00 0.30652605E+00 0.30396683E+00
+ 0.30141210E+00 0.29886195E+00 0.29631646E+00 0.29377572E+00 0.29123982E+00
+ 0.28870886E+00 0.28618291E+00 0.28366207E+00 0.28114643E+00 0.27863607E+00
+ 0.27613108E+00 0.27363156E+00 0.27113758E+00 0.26864924E+00 0.26616663E+00
+ 0.26368983E+00 0.26121894E+00 0.25875403E+00 0.25629521E+00 0.25384256E+00
+ 0.25139616E+00 0.24895611E+00 0.24652249E+00 0.24409540E+00 0.24167491E+00
+ 0.23926113E+00 0.23685413E+00 0.23445401E+00 0.23206085E+00 0.22967475E+00
+ 0.22729579E+00 0.22492406E+00 0.22255965E+00 0.22020264E+00 0.21785313E+00
+ 0.21551121E+00 0.21317695E+00 0.21085046E+00 0.20853182E+00 0.20622111E+00
+ 0.20391843E+00 0.20162387E+00 0.19933751E+00 0.19705944E+00 0.19478975E+00
+ 0.19252853E+00 0.19027587E+00 0.18803185E+00 0.18579656E+00 0.18357010E+00
+ 0.18135255E+00 0.17914400E+00 0.17694454E+00 0.17475425E+00 0.17257323E+00
+ 0.17040156E+00 0.16823933E+00 0.16608663E+00 0.16394355E+00 0.16181018E+00
+ 0.15968661E+00 0.15757291E+00 0.15546919E+00 0.15337553E+00 0.15129202E+00
+ 0.14921875E+00 0.14715581E+00 0.14510328E+00 0.14306125E+00 0.14102981E+00
+ 0.13900906E+00 0.13699907E+00 0.13499994E+00 0.13301175E+00 0.13103460E+00
+ 0.12906857E+00 0.12711375E+00 0.12517024E+00 0.12323811E+00 0.12131745E+00
+ 0.11940836E+00 0.11751092E+00 0.11562523E+00 0.11375136E+00 0.11188942E+00
+ 0.11003948E+00 0.10820164E+00 0.10637598E+00 0.10456259E+00 0.10276156E+00
+ 0.10097298E+00 0.99196944E-01 0.97433531E-01 0.95682832E-01 0.93944936E-01
+ 0.92219932E-01 0.90507909E-01 0.88808953E-01 0.87123155E-01 0.85450602E-01
+ 0.83791383E-01 0.82145587E-01 0.80513301E-01 0.78894615E-01 0.77289616E-01
+ 0.75698394E-01 0.74121036E-01 0.72557631E-01 0.71008268E-01 0.69473035E-01
+ 0.67952021E-01 0.66445314E-01 0.64953002E-01 0.63475174E-01 0.62011918E-01
+ 0.60563323E-01 0.59129478E-01 0.57710470E-01 0.56306388E-01 0.54917321E-01
+ 0.53543357E-01 0.52184585E-01 0.50841093E-01 0.49512969E-01 0.48200303E-01
+ 0.46903181E-01 0.45621694E-01 0.44355929E-01 0.43105975E-01 0.41871920E-01
+ 0.40653853E-01 0.39451862E-01 0.38266035E-01 0.37096462E-01 0.35943231E-01
+ 0.34806429E-01 0.33686146E-01 0.32582470E-01 0.31495489E-01 0.30425292E-01
+ 0.29371968E-01 0.28335604E-01 0.27316290E-01 0.26314113E-01 0.25329163E-01
+ 0.24361527E-01 0.23411294E-01 0.22478553E-01 0.21563392E-01 0.20665899E-01
+ 0.19786163E-01 0.18924273E-01 0.18080316E-01 0.17254382E-01 0.16446559E-01
+ 0.15656935E-01 0.14885598E-01 0.14132638E-01 0.13398143E-01 0.12682200E-01
+ 0.11984899E-01 0.11306328E-01 0.10646576E-01 0.10005730E-01 0.93838802E-02
+ 0.87811139E-02 0.81975200E-02 0.76331868E-02 0.70882029E-02 0.65626567E-02
+ 0.60566366E-02 0.55702312E-02 0.51035288E-02 0.46566180E-02 0.42295871E-02
+ 0.38225248E-02 0.34355193E-02 0.30686593E-02 0.27220330E-02 0.23957291E-02
+ 0.20898360E-02 0.18044420E-02 0.15396358E-02 0.12955057E-02 0.10721402E-02
+ 0.86962779E-03 0.68805689E-03 0.52751599E-03 0.38809353E-03 0.26987798E-03
+ 0.17295780E-03 0.97421455E-04 0.43357398E-04 0.10854093E-04 0.00000000E+00
+ 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02
+ 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02
+ 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02
+ 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02
+ 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02
+ 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02
+ 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02
+ 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02
+ 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02
+ 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02
+ 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02 0.43562903E+02
+ 0.43442278E+02 0.42933735E+02 0.42439970E+02 0.41960302E+02 0.41494097E+02
+ 0.41040758E+02 0.40599722E+02 0.40170462E+02 0.39752480E+02 0.39345306E+02
+ 0.38948500E+02 0.38561642E+02 0.38184337E+02 0.37816211E+02 0.37456911E+02
+ 0.37106100E+02 0.36763461E+02 0.36428691E+02 0.36101504E+02 0.35781627E+02
+ 0.35468801E+02 0.35162778E+02 0.34863324E+02 0.34570214E+02 0.34283234E+02
+ 0.34002182E+02 0.33726861E+02 0.33457086E+02 0.33192680E+02 0.32933472E+02
+ 0.32679298E+02 0.32430005E+02 0.32185442E+02 0.31945465E+02 0.31709939E+02
+ 0.31478731E+02 0.31251715E+02 0.31028771E+02 0.30809780E+02 0.30594631E+02
+ 0.30383218E+02 0.30175435E+02 0.29971184E+02 0.29770368E+02 0.29572896E+02
+ 0.29378678E+02 0.29187628E+02 0.28999664E+02 0.28814705E+02 0.28632676E+02
+ 0.28453501E+02 0.28277109E+02 0.28103431E+02 0.27932400E+02 0.27763951E+02
+ 0.27598022E+02 0.27434552E+02 0.27273482E+02 0.27114757E+02 0.26958321E+02
+ 0.26804121E+02 0.26652107E+02 0.26502227E+02 0.26354435E+02 0.26208683E+02
+ 0.26064926E+02 0.25923120E+02 0.25783222E+02 0.25645192E+02 0.25508988E+02
+ 0.25374573E+02 0.25241908E+02 0.25110956E+02 0.24981682E+02 0.24854051E+02
+ 0.24728030E+02 0.24603586E+02 0.24480686E+02 0.24359300E+02 0.24239398E+02
+ 0.24120950E+02 0.24003929E+02 0.23888305E+02 0.23774053E+02 0.23661145E+02
+ 0.23549557E+02 0.23439263E+02 0.23330239E+02 0.23222461E+02 0.23115906E+02
+ 0.23010552E+02 0.22906377E+02 0.22803359E+02 0.22701478E+02 0.22600712E+02
+ 0.22501043E+02 0.22402450E+02 0.22304916E+02 0.22208421E+02 0.22112947E+02
+ 0.22018478E+02 0.21924995E+02 0.21832481E+02 0.21740922E+02 0.21650299E+02
+ 0.21560599E+02 0.21471805E+02 0.21383902E+02 0.21296877E+02 0.21210714E+02
+ 0.21125400E+02 0.21040921E+02 0.20957263E+02 0.20874414E+02 0.20792361E+02
+ 0.20711091E+02 0.20630592E+02 0.20550852E+02 0.20471859E+02 0.20393602E+02
+ 0.20316070E+02 0.20239251E+02 0.20163135E+02 0.20087711E+02 0.20012968E+02
+ 0.19938898E+02 0.19865489E+02 0.19792732E+02 0.19720618E+02 0.19649137E+02
+ 0.19578279E+02 0.19508037E+02 0.19438401E+02 0.19369362E+02 0.19300913E+02
+ 0.19233044E+02 0.19165748E+02 0.19099016E+02 0.19032841E+02 0.18967215E+02
+ 0.18902131E+02 0.18837580E+02 0.18773557E+02 0.18710053E+02 0.18647062E+02
+ 0.18584576E+02 0.18522590E+02 0.18461096E+02 0.18400088E+02 0.18339559E+02
+ 0.18279504E+02 0.18219916E+02 0.18160789E+02 0.18102116E+02 0.18043893E+02
+ 0.17986114E+02 0.17928772E+02 0.17871862E+02 0.17815380E+02 0.17759318E+02
+ 0.17703673E+02 0.17648439E+02 0.17593611E+02 0.17539183E+02 0.17485152E+02
+ 0.17431511E+02 0.17378257E+02 0.17325385E+02 0.17272890E+02 0.17220767E+02
+ 0.17169012E+02 0.17117621E+02 0.17066589E+02 0.17015913E+02 0.16965587E+02
+ 0.16915609E+02 0.16865972E+02 0.16816675E+02 0.16767713E+02 0.16719082E+02
+ 0.16670778E+02 0.16622797E+02 0.16575136E+02 0.16527791E+02 0.16480759E+02
+ 0.16434036E+02 0.16387619E+02 0.16341504E+02 0.16295688E+02 0.16250167E+02
+ 0.16204938E+02 0.16159999E+02 0.16115346E+02 0.16070975E+02 0.16026884E+02
+ 0.15983070E+02 0.15939529E+02 0.15896260E+02 0.15853258E+02 0.15810521E+02
+ 0.15768046E+02 0.15725831E+02 0.15683873E+02 0.15642169E+02 0.15600715E+02
+ 0.15559511E+02 0.15518553E+02 0.15477839E+02 0.15437365E+02 0.15397131E+02
+ 0.15357132E+02 0.15317367E+02 0.15277834E+02 0.15238530E+02 0.15199452E+02
+ 0.15160599E+02 0.15121969E+02 0.15083558E+02 0.15045365E+02 0.15007388E+02
+ 0.14969624E+02 0.14932072E+02 0.14894729E+02 0.14857593E+02 0.14820663E+02
+ 0.14783936E+02 0.14747410E+02 0.14711084E+02 0.14674955E+02 0.14639022E+02
+ 0.14603282E+02 0.14567735E+02 0.14532377E+02 0.14497208E+02 0.14462225E+02
+ 0.14427427E+02 0.14392812E+02 0.14358378E+02 0.14324124E+02 0.14290048E+02
+ 0.14256148E+02 0.14222422E+02 0.14188870E+02 0.14155489E+02 0.14122279E+02
+ 0.14089236E+02 0.14056361E+02 0.14023650E+02 0.13991104E+02 0.13958720E+02
+ 0.13926497E+02 0.13894433E+02 0.13862528E+02 0.13830779E+02 0.13799185E+02
+ 0.13767745E+02 0.13736458E+02 0.13705322E+02 0.13674336E+02 0.13643499E+02
+ 0.13612809E+02 0.13582264E+02 0.13551865E+02 0.13521609E+02 0.13491495E+02
+ 0.13461523E+02 0.13431690E+02 0.13401996E+02 0.13372439E+02 0.13343019E+02
+ 0.13313734E+02 0.13284583E+02 0.13255565E+02 0.13226678E+02 0.13197923E+02
+ 0.13169296E+02 0.13140799E+02 0.13112429E+02 0.13084185E+02 0.13056067E+02
+ 0.13028073E+02 0.13000202E+02 0.12972454E+02 0.12944827E+02 0.12917320E+02
+ 0.12889933E+02 0.12862664E+02 0.12835512E+02 0.12808477E+02 0.12781558E+02
+ 0.12754753E+02 0.12728062E+02 0.12701484E+02 0.12675018E+02 0.12648663E+02
+ 0.12622417E+02 0.12596282E+02 0.12570254E+02 0.12544335E+02 0.12518522E+02
+ 0.12492815E+02 0.12467213E+02 0.12441716E+02 0.12416321E+02 0.12391030E+02
+ 0.12365841E+02 0.12340752E+02 0.12315764E+02 0.12290876E+02 0.12266086E+02
+ 0.12241395E+02 0.12216801E+02 0.12192303E+02 0.12167902E+02 0.12143595E+02
+ 0.12119383E+02 0.12095265E+02 0.12071240E+02 0.12047307E+02 0.12023466E+02
+ 0.11999715E+02 0.11976055E+02 0.11952485E+02 0.11929004E+02 0.11905611E+02
+ 0.11882306E+02 0.11859088E+02 0.11835956E+02 0.11812910E+02 0.11789949E+02
+ 0.11767073E+02 0.11744281E+02 0.11721572E+02 0.11698946E+02 0.11676402E+02
+ 0.11653940E+02 0.11631558E+02 0.11609257E+02 0.11587036E+02 0.11564894E+02
+ 0.11542831E+02 0.11520846E+02 0.11498939E+02 0.11477109E+02 0.11455355E+02
+ 0.11433678E+02 0.11412076E+02 0.11390548E+02 0.11369096E+02 0.11347717E+02
+ 0.11326412E+02 0.11305179E+02 0.11284019E+02 0.11262931E+02 0.11241914E+02
+ 0.11220968E+02 0.11200093E+02 0.11179288E+02 0.11158552E+02 0.11137885E+02
+ 0.11117287E+02 0.11096757E+02 0.11076294E+02 0.11055899E+02 0.11035571E+02
+ 0.11015308E+02 0.10995112E+02 0.10974981E+02 0.10954915E+02 0.10934914E+02
+ 0.10914977E+02 0.10895103E+02 0.10875293E+02 0.10855546E+02 0.10835861E+02
+ 0.10816239E+02 0.10796678E+02 0.10777178E+02 0.10757739E+02 0.10738361E+02
+ 0.10719042E+02 0.10699784E+02 0.10680584E+02 0.10661444E+02 0.10642362E+02
+ 0.10623339E+02 0.10604373E+02 0.10585465E+02 0.10566614E+02 0.10547819E+02
+ 0.10529081E+02 0.10510399E+02 0.10491772E+02 0.10473201E+02 0.10454685E+02
+ 0.10436224E+02 0.10417817E+02 0.10399463E+02 0.10381164E+02 0.10362917E+02
+ 0.10344724E+02 0.10326583E+02 0.10308494E+02 0.10290458E+02 0.10272473E+02
+ 0.10254540E+02 0.10236657E+02 0.10218825E+02 0.10201044E+02 0.10183313E+02
+ 0.10165631E+02 0.10147999E+02 0.10130417E+02 0.10112883E+02 0.10095398E+02
+ 0.10077961E+02 0.10060572E+02 0.10043231E+02 0.10025937E+02 0.10008691E+02
+ 0.99914914E+01 0.99743385E+01 0.99572320E+01 0.99401715E+01 0.99231569E+01
+ 0.99061877E+01 0.98892639E+01 0.98723851E+01 0.98555510E+01 0.98387614E+01
+ 0.98220160E+01 0.98053146E+01 0.97886569E+01 0.97720427E+01 0.97554717E+01
+ 0.97389436E+01 0.97224583E+01 0.97060154E+01 0.96896148E+01 0.96732562E+01
+ 0.96569393E+01 0.96406639E+01 0.96244298E+01 0.96082368E+01 0.95920846E+01
+ 0.95759729E+01 0.95599016E+01 0.95438704E+01 0.95278792E+01 0.95119276E+01
+ 0.94960155E+01 0.94801426E+01 0.94643087E+01 0.94485137E+01 0.94327572E+01
+ 0.94170391E+01 0.94013592E+01 0.93857172E+01 0.93701130E+01 0.93545463E+01
+ 0.93390170E+01 0.93235248E+01 0.93080695E+01 0.92926509E+01 0.92772689E+01
+ 0.92619232E+01 0.92466137E+01 0.92313401E+01 0.92161022E+01 0.92008999E+01
+ 0.91857329E+01 0.91706012E+01 0.91555044E+01 0.91404424E+01 0.91254150E+01
+ 0.91104221E+01 0.90954634E+01 0.90805388E+01 0.90656481E+01 0.90507911E+01
+ 0.90359676E+01 0.90211775E+01 0.90064206E+01 0.89916967E+01 0.89770056E+01
+ 0.89623472E+01 0.89477213E+01 0.89331277E+01 0.89185663E+01 0.89040369E+01
+ 0.88895393E+01 0.88750734E+01 0.88606390E+01 0.88462360E+01 0.88318641E+01
+ 0.88175233E+01 0.88032133E+01 0.87889341E+01 0.87746854E+01 0.87604671E+01
+ 0.87462791E+01 0.87321211E+01 0.87179931E+01 0.87038949E+01 0.86898264E+01
+ 0.86757873E+01 0.86617777E+01 0.86477972E+01 0.86338457E+01 0.86199232E+01
+ 0.86060295E+01 0.85921644E+01 0.85783278E+01 0.85645196E+01 0.85507395E+01
+ 0.85369876E+01 0.85232636E+01 0.85095674E+01 0.84958988E+01 0.84822578E+01
+ 0.84686442E+01 0.84550579E+01 0.84414987E+01 0.84279665E+01 0.84144612E+01
+ 0.84009826E+01 0.83875307E+01 0.83741052E+01 0.83607062E+01 0.83473333E+01
+ 0.83339866E+01 0.83206659E+01 0.83073711E+01 0.82941020E+01 0.82808585E+01
+ 0.82676406E+01 0.82544480E+01 0.82412807E+01 0.82281386E+01 0.82150215E+01
+ 0.82019294E+01 0.81888620E+01 0.81758193E+01 0.81628012E+01 0.81498076E+01
+ 0.81368384E+01 0.81238933E+01 0.81109725E+01 0.80980756E+01 0.80852026E+01
+ 0.80723535E+01 0.80595280E+01 0.80467262E+01 0.80339478E+01 0.80211928E+01
+ 0.80084611E+01 0.79957525E+01 0.79830670E+01 0.79704045E+01 0.79577648E+01
+ 0.79451479E+01 0.79325537E+01 0.79199820E+01 0.79074328E+01 0.78949059E+01
+ 0.78824013E+01 0.78699189E+01 0.78574585E+01 0.78450201E+01 0.78326036E+01
+ 0.78202089E+01 0.78078359E+01 0.77954844E+01 0.77831545E+01 0.77708460E+01
+ 0.77585587E+01 0.77462928E+01 0.77340479E+01 0.77218241E+01 0.77096213E+01
+ 0.76974393E+01 0.76852781E+01 0.76731376E+01 0.76610177E+01 0.76489183E+01
+ 0.76368394E+01 0.76247808E+01 0.76127425E+01 0.76007243E+01 0.75887263E+01
+ 0.75767483E+01 0.75647902E+01 0.75528519E+01 0.75409334E+01 0.75290346E+01
+ 0.75171554E+01 0.75052958E+01 0.74934556E+01 0.74816347E+01 0.74698332E+01
+ 0.74580508E+01 0.74462876E+01 0.74345435E+01 0.74228183E+01 0.74111120E+01
+ 0.73994246E+01 0.73877559E+01 0.73761059E+01 0.73644745E+01 0.73528617E+01
+ 0.73412673E+01 0.73296913E+01 0.73181336E+01 0.73065942E+01 0.72950730E+01
+ 0.72835698E+01 0.72720847E+01 0.72606176E+01 0.72491683E+01 0.72377369E+01
+ 0.72263232E+01 0.72149272E+01 0.72035489E+01 0.71921881E+01 0.71808448E+01
+ 0.71695189E+01 0.71582104E+01 0.71469192E+01 0.71356452E+01 0.71243884E+01
+ 0.71131486E+01 0.71019260E+01 0.70907202E+01 0.70795314E+01 0.70683595E+01
+ 0.70572043E+01 0.70460659E+01 0.70349441E+01 0.70238389E+01 0.70127503E+01
+ 0.70016781E+01 0.69906224E+01 0.69795831E+01 0.69685600E+01 0.69575532E+01
+ 0.69465626E+01 0.69355881E+01 0.69246297E+01 0.69136873E+01 0.69027609E+01
+ 0.68918503E+01 0.68809557E+01 0.68700768E+01 0.68592136E+01 0.68483661E+01
+ 0.68375343E+01 0.68267181E+01 0.68159173E+01 0.68051320E+01 0.67943622E+01
+ 0.67836077E+01 0.67728685E+01 0.67621446E+01 0.67514358E+01 0.67407423E+01
+ 0.67300638E+01 0.67194004E+01 0.67087520E+01 0.66981185E+01 0.66875000E+01
+ 0.66768962E+01 0.66663073E+01 0.66557332E+01 0.66451738E+01 0.66346290E+01
+ 0.66240988E+01 0.66135832E+01 0.66030821E+01 0.65925955E+01 0.65821233E+01
+ 0.65716655E+01 0.65612220E+01 0.65507928E+01 0.65403778E+01 0.65299770E+01
+ 0.65195904E+01 0.65092179E+01 0.64988594E+01 0.64885149E+01 0.64781845E+01
+ 0.64678679E+01 0.64575652E+01 0.64472764E+01 0.64370014E+01 0.64267401E+01
+ 0.64164926E+01 0.64062587E+01 0.63960385E+01 0.63858318E+01 0.63756387E+01
+ 0.63654591E+01 0.63552930E+01 0.63451403E+01 0.63350010E+01 0.63248750E+01
+ 0.63147624E+01 0.63046630E+01 0.62945768E+01 0.62845039E+01 0.62744441E+01
+ 0.62643974E+01 0.62543638E+01 0.62443432E+01 0.62343357E+01 0.62243411E+01
+ 0.62143594E+01 0.62043906E+01 0.61944347E+01 0.61844916E+01 0.61745612E+01
+ 0.61646437E+01 0.61547388E+01 0.61448466E+01 0.61349671E+01 0.61251001E+01
+ 0.61152458E+01 0.61054039E+01 0.60955746E+01 0.60857578E+01 0.60759533E+01
+ 0.60661613E+01 0.60563817E+01 0.60466144E+01 0.60368593E+01 0.60271166E+01
+ 0.60173861E+01 0.60076678E+01 0.59979617E+01 0.59882677E+01 0.59785858E+01
+ 0.59689160E+01 0.59592583E+01 0.59496125E+01 0.59399788E+01 0.59303570E+01
+ 0.59207471E+01 0.59111492E+01 0.59015630E+01 0.58919888E+01 0.58824263E+01
+ 0.58728756E+01 0.58633366E+01 0.58538094E+01 0.58442939E+01 0.58347900E+01
+ 0.58252977E+01 0.58158171E+01 0.58063480E+01 0.57968905E+01 0.57874445E+01
+ 0.57780099E+01 0.57685869E+01 0.57591753E+01 0.57497751E+01 0.57403862E+01
+ 0.57310088E+01 0.57216426E+01 0.57122878E+01 0.57029442E+01 0.56936119E+01
+ 0.56842909E+01 0.56749810E+01 0.56656823E+01 0.56563947E+01 0.56471183E+01
+ 0.56378530E+01 0.56285987E+01 0.56193555E+01 0.56101233E+01 0.56009022E+01
+ 0.55916920E+01 0.55824927E+01 0.55733044E+01 0.55641270E+01 0.55549604E+01
+ 0.55458048E+01 0.55366599E+01 0.55275259E+01 0.55184027E+01 0.55092902E+01
+ 0.55001885E+01 0.54910975E+01 0.54820172E+01 0.54729476E+01 0.54638886E+01
+ 0.54548403E+01 0.54458026E+01 0.54367755E+01 0.54277589E+01 0.54187529E+01
+ 0.54097574E+01 0.54007725E+01 0.53917980E+01 0.53828340E+01 0.53738804E+01
+ 0.53649372E+01 0.53560045E+01 0.53470821E+01 0.53381701E+01 0.53292685E+01
+ 0.53203772E+01 0.53114961E+01 0.53026254E+01 0.52937649E+01 0.52849147E+01
+ 0.52760747E+01 0.52672449E+01 0.52584253E+01 0.52496159E+01 0.52408166E+01
+ 0.52320275E+01 0.52232485E+01 0.52144796E+01 0.52057207E+01 0.51969719E+01
+ 0.51882332E+01 0.51795045E+01 0.51707858E+01 0.51620771E+01 0.51533784E+01
+ 0.51446896E+01 0.51360108E+01 0.51273419E+01 0.51186829E+01 0.51100338E+01
+ 0.51013946E+01 0.50927652E+01 0.50841457E+01 0.50755359E+01 0.50669360E+01
+ 0.50583459E+01 0.50497656E+01 0.50411951E+01 0.50326342E+01 0.50240831E+01
+ 0.50155418E+01 0.50070101E+01 0.49984881E+01 0.49899758E+01 0.49814731E+01
+ 0.49729801E+01 0.49644967E+01 0.49560229E+01 0.49475587E+01 0.49391041E+01
+ 0.49306590E+01 0.49222235E+01 0.49137976E+01 0.49053811E+01 0.48969742E+01
+ 0.48885768E+01 0.48801888E+01 0.48718104E+01 0.48634413E+01 0.48550817E+01
+ 0.48467316E+01 0.48383909E+01 0.48300595E+01 0.48217376E+01 0.48134250E+01
+ 0.48051218E+01 0.47968279E+01 0.47885434E+01 0.47802682E+01 0.47720023E+01
+ 0.47637457E+01 0.47554984E+01 0.47472604E+01 0.47390316E+01 0.47308121E+01
+ 0.47226019E+01 0.47144008E+01 0.47062090E+01 0.46980264E+01 0.46898529E+01
+ 0.46816887E+01 0.46735336E+01 0.46653877E+01 0.46572509E+01 0.46491232E+01
+ 0.46410047E+01 0.46328953E+01 0.46247950E+01 0.46167038E+01 0.46086216E+01
+ 0.46005486E+01 0.45924845E+01 0.45844296E+01 0.45763837E+01 0.45683468E+01
+ 0.45603189E+01 0.45523000E+01 0.45442901E+01 0.45362892E+01 0.45282973E+01
+ 0.45203143E+01 0.45123403E+01 0.45043753E+01 0.44964192E+01 0.44884720E+01
+ 0.44805337E+01 0.44726044E+01 0.44646839E+01 0.44567723E+01 0.44488696E+01
+ 0.44409758E+01 0.44330908E+01 0.44252147E+01 0.44173475E+01 0.44094890E+01
+ 0.44016394E+01 0.43937986E+01 0.43859666E+01 0.43781434E+01 0.43703290E+01
+ 0.43625234E+01 0.43547266E+01 0.43469385E+01 0.43391592E+01 0.43313886E+01
+ 0.43236268E+01 0.43158737E+01 0.43081293E+01 0.43003937E+01 0.42926667E+01
+ 0.42849484E+01 0.42772389E+01 0.42695380E+01 0.42618458E+01 0.42541623E+01
+ 0.42464874E+01 0.42388212E+01 0.42311636E+01 0.42235147E+01 0.42158744E+01
+ 0.42082427E+01 0.42006196E+01 0.41930052E+01 0.41853993E+01 0.41778021E+01
+ 0.41702134E+01 0.41626333E+01 0.41550618E+01 0.41474988E+01 0.41399444E+01
+ 0.41323986E+01 0.41248613E+01 0.41173326E+01 0.41098124E+01 0.41023007E+01
+ 0.40947975E+01 0.40873028E+01 0.40798167E+01 0.40723391E+01 0.40648699E+01
+ 0.40574092E+01 0.40499571E+01 0.40425134E+01 0.40350781E+01 0.40276514E+01
+ 0.40202330E+01 0.40128232E+01 0.40054218E+01 0.39980288E+01 0.39906442E+01
+ 0.39832681E+01 0.39759004E+01 0.39685412E+01 0.39611903E+01 0.39538479E+01
+ 0.39465138E+01 0.39391881E+01 0.39318709E+01 0.39245620E+01 0.39172615E+01
+ 0.39099693E+01 0.39026856E+01 0.38954102E+01 0.38881431E+01 0.38808844E+01
+ 0.38736341E+01 0.38663921E+01 0.38591584E+01 0.38519331E+01 0.38447160E+01
+ 0.38375074E+01 0.38303070E+01 0.38231149E+01 0.38159312E+01 0.38087557E+01
+ 0.38015886E+01 0.37944297E+01 0.37872791E+01 0.37801368E+01 0.37730028E+01
+ 0.37658771E+01 0.37587596E+01 0.37516504E+01 0.37445495E+01 0.37374568E+01
+ 0.37303724E+01 0.37232962E+01 0.37162283E+01 0.37091686E+01 0.37021171E+01
+ 0.36950739E+01 0.36880389E+01 0.36810121E+01 0.36739935E+01 0.36669832E+01
+ 0.36599810E+01 0.36529871E+01 0.36460014E+01 0.36390238E+01 0.36320545E+01
+ 0.36250933E+01 0.36181404E+01 0.36111956E+01 0.36042590E+01 0.35973306E+01
+ 0.35904103E+01 0.35834983E+01 0.35765943E+01 0.35696986E+01 0.35628110E+01
+ 0.35559315E+01 0.35490602E+01 0.35421971E+01 0.35353421E+01 0.35284952E+01
+ 0.35216565E+01 0.35148259E+01 0.35080034E+01 0.35011891E+01 0.34943828E+01
+ 0.34875847E+01 0.34807947E+01 0.34740129E+01 0.34672391E+01 0.34604734E+01
+ 0.34537159E+01 0.34469664E+01 0.34402250E+01 0.34334918E+01 0.34267666E+01
+ 0.34200495E+01 0.34133405E+01 0.34066395E+01 0.33999467E+01 0.33932619E+01
+ 0.33865852E+01 0.33799166E+01 0.33732560E+01 0.33666035E+01 0.33599590E+01
+ 0.33533226E+01 0.33466943E+01 0.33400740E+01 0.33334618E+01 0.33268576E+01
+ 0.33202614E+01 0.33136733E+01 0.33070933E+01 0.33005212E+01 0.32939572E+01
+ 0.32874012E+01 0.32808533E+01 0.32743134E+01 0.32677815E+01 0.32612576E+01
+ 0.32547417E+01 0.32482339E+01 0.32417340E+01 0.32352422E+01 0.32287584E+01
+ 0.32222825E+01 0.32158147E+01 0.32093549E+01 0.32029030E+01 0.31964592E+01
+ 0.31900234E+01 0.31835955E+01 0.31771756E+01 0.31707638E+01 0.31643598E+01
+ 0.31579639E+01 0.31515760E+01 0.31451960E+01 0.31388240E+01 0.31324600E+01
+ 0.31261039E+01 0.31197558E+01 0.31134157E+01 0.31070835E+01 0.31007593E+01
+ 0.30944430E+01 0.30881347E+01 0.30818343E+01 0.30755419E+01 0.30692575E+01
+ 0.30629810E+01 0.30567124E+01 0.30504518E+01 0.30441991E+01 0.30379543E+01
+ 0.30317175E+01 0.30254886E+01 0.30192676E+01 0.30130546E+01 0.30068495E+01
+ 0.30006523E+01 0.29944631E+01 0.29882817E+01 0.29821083E+01 0.29759428E+01
+ 0.29697852E+01 0.29636355E+01 0.29574937E+01 0.29513599E+01 0.29452339E+01
+ 0.29391159E+01 0.29330057E+01 0.29269035E+01 0.29208091E+01 0.29147226E+01
+ 0.29086441E+01 0.29025734E+01 0.28965106E+01 0.28904557E+01 0.28844087E+01
+ 0.28783696E+01 0.28723383E+01 0.28663150E+01 0.28602995E+01 0.28542919E+01
+ 0.28482921E+01 0.28423002E+01 0.28363163E+01 0.28303401E+01 0.28243719E+01
+ 0.28184115E+01 0.28124589E+01 0.28065143E+01 0.28005775E+01 0.27946485E+01
+ 0.27887274E+01 0.27828141E+01 0.27769088E+01 0.27710112E+01 0.27651215E+01
+ 0.27592397E+01 0.27533657E+01 0.27474995E+01 0.27416412E+01 0.27357907E+01
+ 0.27299480E+01 0.27241132E+01 0.27182862E+01 0.27124671E+01 0.27066558E+01
+ 0.27008523E+01 0.26950566E+01 0.26892688E+01 0.26834887E+01 0.26777165E+01
+ 0.26719522E+01 0.26661956E+01 0.26604468E+01 0.26547059E+01 0.26489728E+01
+ 0.26432475E+01 0.26375300E+01 0.26318203E+01 0.26261184E+01 0.26204243E+01
+ 0.26147380E+01 0.26090595E+01 0.26033888E+01 0.25977258E+01 0.25920707E+01
+ 0.25864234E+01 0.25807839E+01 0.25751521E+01 0.25695282E+01 0.25639120E+01
+ 0.25583036E+01 0.25527030E+01 0.25471101E+01 0.25415251E+01 0.25359478E+01
+ 0.25303783E+01 0.25248165E+01 0.25192625E+01 0.25137163E+01 0.25081779E+01
+ 0.25026472E+01 0.24971243E+01 0.24916091E+01 0.24861017E+01 0.24806021E+01
+ 0.24751102E+01 0.24696260E+01 0.24641496E+01 0.24586810E+01 0.24532201E+01
+ 0.24477669E+01 0.24423215E+01 0.24368838E+01 0.24314539E+01 0.24260317E+01
+ 0.24206172E+01 0.24152105E+01 0.24098115E+01 0.24044202E+01 0.23990367E+01
+ 0.23936608E+01 0.23882928E+01 0.23829324E+01 0.23775797E+01 0.23722348E+01
+ 0.23668975E+01 0.23615680E+01 0.23562462E+01 0.23509321E+01 0.23456257E+01
+ 0.23403270E+01 0.23350361E+01 0.23297528E+01 0.23244772E+01 0.23192093E+01
+ 0.23139491E+01 0.23086966E+01 0.23034518E+01 0.22982147E+01 0.22929853E+01
+ 0.22877635E+01 0.22825494E+01 0.22773430E+01 0.22721443E+01 0.22669533E+01
+ 0.22617699E+01 0.22565942E+01 0.22514262E+01 0.22462659E+01 0.22411132E+01
+ 0.22359681E+01 0.22308308E+01 0.22257011E+01 0.22205790E+01 0.22154646E+01
+ 0.22103579E+01 0.22052588E+01 0.22001673E+01 0.21950835E+01 0.21900073E+01
+ 0.21849388E+01 0.21798779E+01 0.21748247E+01 0.21697790E+01 0.21647411E+01
+ 0.21597107E+01 0.21546880E+01 0.21496729E+01 0.21446654E+01 0.21396655E+01
+ 0.21346733E+01 0.21296886E+01 0.21247116E+01 0.21197422E+01 0.21147804E+01
+ 0.21098262E+01 0.21048796E+01 0.20999406E+01 0.20950092E+01 0.20900854E+01
+ 0.20851692E+01 0.20802606E+01 0.20753596E+01 0.20704661E+01 0.20655802E+01
+ 0.20607020E+01 0.20558313E+01 0.20509681E+01 0.20461126E+01 0.20412646E+01
+ 0.20364242E+01 0.20315913E+01 0.20267660E+01 0.20219483E+01 0.20171381E+01
+ 0.20123355E+01 0.20075405E+01 0.20027529E+01 0.19979730E+01 0.19932005E+01
+ 0.19884357E+01 0.19836783E+01 0.19789285E+01 0.19741862E+01 0.19694515E+01
+ 0.19647243E+01 0.19600046E+01 0.19552924E+01 0.19505878E+01 0.19458906E+01
+ 0.19412010E+01 0.19365189E+01 0.19318443E+01 0.19271772E+01 0.19225176E+01
+ 0.19178655E+01 0.19132209E+01 0.19085838E+01 0.19039542E+01 0.18993321E+01
+ 0.18947174E+01 0.18901103E+01 0.18855106E+01 0.18809184E+01 0.18763337E+01
+ 0.18717564E+01 0.18671866E+01 0.18626243E+01 0.18580694E+01 0.18535220E+01
+ 0.18489821E+01 0.18444496E+01 0.18399245E+01 0.18354069E+01 0.18308968E+01
+ 0.18263940E+01 0.18218987E+01 0.18174109E+01 0.18129305E+01 0.18084575E+01
+ 0.18039919E+01 0.17995337E+01 0.17950830E+01 0.17906397E+01 0.17862038E+01
+ 0.17817753E+01 0.17773542E+01 0.17729405E+01 0.17685341E+01 0.17641352E+01
+ 0.17597437E+01 0.17553596E+01 0.17509828E+01 0.17466135E+01 0.17422515E+01
+ 0.17378969E+01 0.17335496E+01 0.17292097E+01 0.17248772E+01 0.17205521E+01
+ 0.17162343E+01 0.17119238E+01 0.17076207E+01 0.17033250E+01 0.16990366E+01
+ 0.16947555E+01 0.16904818E+01 0.16862154E+01 0.16819563E+01 0.16777045E+01
+ 0.16734601E+01 0.16692230E+01 0.16649932E+01 0.16607707E+01 0.16565555E+01
+ 0.16523476E+01 0.16481470E+01 0.16439538E+01 0.16397678E+01 0.16355891E+01
+ 0.16314176E+01 0.16272535E+01 0.16230966E+01 0.16189470E+01 0.16148047E+01
+ 0.16106696E+01 0.16065418E+01 0.16024213E+01 0.15983080E+01 0.15942019E+01
+ 0.15901031E+01 0.15860116E+01 0.15819273E+01 0.15778502E+01 0.15737803E+01
+ 0.15697177E+01 0.15656623E+01 0.15616141E+01 0.15575731E+01 0.15535393E+01
+ 0.15495127E+01 0.15454934E+01 0.15414812E+01 0.15374762E+01 0.15334784E+01
+ 0.15294878E+01 0.15255044E+01 0.15215281E+01 0.15175590E+01 0.15135971E+01
+ 0.15096424E+01 0.15056948E+01 0.15017544E+01 0.14978211E+01 0.14938949E+01
+ 0.14899759E+01 0.14860641E+01 0.14821593E+01 0.14782618E+01 0.14743713E+01
+ 0.14704879E+01 0.14666117E+01 0.14627426E+01 0.14588805E+01 0.14550256E+01
+ 0.14511778E+01 0.14473371E+01 0.14435034E+01 0.14396769E+01 0.14358574E+01
+ 0.14320450E+01 0.14282397E+01 0.14244414E+01 0.14206502E+01 0.14168661E+01
+ 0.14130890E+01 0.14093189E+01 0.14055559E+01 0.14018000E+01 0.13980510E+01
+ 0.13943091E+01 0.13905743E+01 0.13868464E+01 0.13831256E+01 0.13794117E+01
+ 0.13757049E+01 0.13720051E+01 0.13683122E+01 0.13646264E+01 0.13609476E+01
+ 0.13572757E+01 0.13536108E+01 0.13499529E+01 0.13463019E+01 0.13426579E+01
+ 0.13390209E+01 0.13353908E+01 0.13317676E+01 0.13281514E+01 0.13245422E+01
+ 0.13209398E+01 0.13173444E+01 0.13137559E+01 0.13101744E+01 0.13065997E+01
+ 0.13030320E+01 0.12994711E+01 0.12959172E+01 0.12923701E+01 0.12888299E+01
+ 0.12852966E+01 0.12817702E+01 0.12782507E+01 0.12747380E+01 0.12712322E+01
+ 0.12677332E+01 0.12642411E+01 0.12607558E+01 0.12572774E+01 0.12538058E+01
+ 0.12503410E+01 0.12468831E+01 0.12434319E+01 0.12399876E+01 0.12365501E+01
+ 0.12331194E+01 0.12296955E+01 0.12262784E+01 0.12228680E+01 0.12194645E+01
+ 0.12160677E+01 0.12126777E+01 0.12092944E+01 0.12059179E+01 0.12025482E+01
+ 0.11991852E+01 0.11958290E+01 0.11924794E+01 0.11891367E+01 0.11858006E+01
+ 0.11824713E+01 0.11791486E+01 0.11758327E+01 0.11725235E+01 0.11692210E+01
+ 0.11659251E+01 0.11626360E+01 0.11593535E+01 0.11560777E+01 0.11528086E+01
+ 0.11495462E+01 0.11462904E+01 0.11430412E+01 0.11397987E+01 0.11365628E+01
+ 0.11333336E+01 0.11301110E+01 0.11268950E+01 0.11236856E+01 0.11204829E+01
+ 0.11172867E+01 0.11140972E+01 0.11109142E+01 0.11077378E+01 0.11045680E+01
+ 0.11014048E+01 0.10982481E+01 0.10950981E+01 0.10919545E+01 0.10888175E+01
+ 0.10856871E+01 0.10825632E+01 0.10794458E+01 0.10763350E+01 0.10732306E+01
+ 0.10701328E+01 0.10670415E+01 0.10639567E+01 0.10608784E+01 0.10578066E+01
+ 0.10547413E+01 0.10516824E+01 0.10486300E+01 0.10455841E+01 0.10425446E+01
+ 0.10395116E+01 0.10364851E+01 0.10334650E+01 0.10304513E+01 0.10274440E+01
+ 0.10244432E+01 0.10214487E+01 0.10184607E+01 0.10154791E+01 0.10125039E+01
+ 0.10095350E+01 0.10065726E+01 0.10036165E+01 0.10006668E+01 0.99772347E+00
+ 0.99478649E+00 0.99185586E+00 0.98893157E+00 0.98601362E+00 0.98310200E+00
+ 0.98019671E+00 0.97729773E+00 0.97440507E+00 0.97151871E+00 0.96863865E+00
+ 0.96576489E+00 0.96289740E+00 0.96003620E+00 0.95718127E+00 0.95433261E+00
+ 0.95149020E+00 0.94865405E+00 0.94582414E+00 0.94300047E+00 0.94018304E+00
+ 0.93737183E+00 0.93456684E+00 0.93176806E+00 0.92897549E+00 0.92617997E+00
+ 0.92337193E+00 0.92055148E+00 0.91771873E+00 0.91487380E+00 0.91201681E+00
+ 0.90914787E+00 0.90626709E+00 0.90337459E+00 0.90047049E+00 0.89755489E+00
+ 0.89462792E+00 0.89168969E+00 0.88874032E+00 0.88577991E+00 0.88280859E+00
+ 0.87982648E+00 0.87683367E+00 0.87383030E+00 0.87081647E+00 0.86779230E+00
+ 0.86475790E+00 0.86171340E+00 0.85865890E+00 0.85559452E+00 0.85252037E+00
+ 0.84943658E+00 0.84634325E+00 0.84324050E+00 0.84012845E+00 0.83700721E+00
+ 0.83387689E+00 0.83073761E+00 0.82758949E+00 0.82443264E+00 0.82126718E+00
+ 0.81809321E+00 0.81491086E+00 0.81172025E+00 0.80852147E+00 0.80531466E+00
+ 0.80209992E+00 0.79887738E+00 0.79564714E+00 0.79240932E+00 0.78916404E+00
+ 0.78591140E+00 0.78265154E+00 0.77938455E+00 0.77611056E+00 0.77282968E+00
+ 0.76954203E+00 0.76624772E+00 0.76294686E+00 0.75963958E+00 0.75632598E+00
+ 0.75300618E+00 0.74968030E+00 0.74634845E+00 0.74301075E+00 0.73966731E+00
+ 0.73631824E+00 0.73296367E+00 0.72960370E+00 0.72623845E+00 0.72286804E+00
+ 0.71949258E+00 0.71611219E+00 0.71272698E+00 0.70933706E+00 0.70594256E+00
+ 0.70254359E+00 0.69914025E+00 0.69573267E+00 0.69232097E+00 0.68890525E+00
+ 0.68548563E+00 0.68206223E+00 0.67863516E+00 0.67520454E+00 0.67177048E+00
+ 0.66833309E+00 0.66489250E+00 0.66144882E+00 0.65800216E+00 0.65455263E+00
+ 0.65110036E+00 0.64764545E+00 0.64418803E+00 0.64072820E+00 0.63726609E+00
+ 0.63380180E+00 0.63033545E+00 0.62686717E+00 0.62339705E+00 0.61992522E+00
+ 0.61645180E+00 0.61297689E+00 0.60950061E+00 0.60602308E+00 0.60254442E+00
+ 0.59906473E+00 0.59558413E+00 0.59210274E+00 0.58862068E+00 0.58513805E+00
+ 0.58165498E+00 0.57817157E+00 0.57468794E+00 0.57120422E+00 0.56772050E+00
+ 0.56423692E+00 0.56075357E+00 0.55727059E+00 0.55378807E+00 0.55030615E+00
+ 0.54682493E+00 0.54334452E+00 0.53986505E+00 0.53638663E+00 0.53290937E+00
+ 0.52943339E+00 0.52595880E+00 0.52248572E+00 0.51901426E+00 0.51554454E+00
+ 0.51207668E+00 0.50861078E+00 0.50514697E+00 0.50168535E+00 0.49822605E+00
+ 0.49476918E+00 0.49131485E+00 0.48786318E+00 0.48441428E+00 0.48096827E+00
+ 0.47752526E+00 0.47408538E+00 0.47064872E+00 0.46721542E+00 0.46378558E+00
+ 0.46035931E+00 0.45693674E+00 0.45351798E+00 0.45010315E+00 0.44669235E+00
+ 0.44328571E+00 0.43988333E+00 0.43648534E+00 0.43309185E+00 0.42970298E+00
+ 0.42631883E+00 0.42293952E+00 0.41956518E+00 0.41619591E+00 0.41283183E+00
+ 0.40947305E+00 0.40611969E+00 0.40277187E+00 0.39942969E+00 0.39609328E+00
+ 0.39276275E+00 0.38943821E+00 0.38611979E+00 0.38280758E+00 0.37950172E+00
+ 0.37620231E+00 0.37290947E+00 0.36962332E+00 0.36634396E+00 0.36307152E+00
+ 0.35980611E+00 0.35654784E+00 0.35329684E+00 0.35005321E+00 0.34681706E+00
+ 0.34358853E+00 0.34036771E+00 0.33715473E+00 0.33394969E+00 0.33075273E+00
+ 0.32756394E+00 0.32438345E+00 0.32121136E+00 0.31804781E+00 0.31489289E+00
+ 0.31174673E+00 0.30860943E+00 0.30548113E+00 0.30236192E+00 0.29925193E+00
+ 0.29615127E+00 0.29306005E+00 0.28997840E+00 0.28690642E+00 0.28384423E+00
+ 0.28079194E+00 0.27774968E+00 0.27471755E+00 0.27169567E+00 0.26868416E+00
+ 0.26568313E+00 0.26269269E+00 0.25971296E+00 0.25674406E+00 0.25378611E+00
+ 0.25083920E+00 0.24790347E+00 0.24497902E+00 0.24206598E+00 0.23916444E+00
+ 0.23627455E+00 0.23339639E+00 0.23053010E+00 0.22767578E+00 0.22483356E+00
+ 0.22200354E+00 0.21918584E+00 0.21638058E+00 0.21358786E+00 0.21080782E+00
+ 0.20804055E+00 0.20528619E+00 0.20254483E+00 0.19981660E+00 0.19710161E+00
+ 0.19439998E+00 0.19171182E+00 0.18903724E+00 0.18637637E+00 0.18372931E+00
+ 0.18109618E+00 0.17847711E+00 0.17587219E+00 0.17328155E+00 0.17070530E+00
+ 0.16814355E+00 0.16559643E+00 0.16306405E+00 0.16054652E+00 0.15804395E+00
+ 0.15555647E+00 0.15308418E+00 0.15062720E+00 0.14818565E+00 0.14575965E+00
+ 0.14334930E+00 0.14095472E+00 0.13857603E+00 0.13621334E+00 0.13386677E+00
+ 0.13153643E+00 0.12922244E+00 0.12692491E+00 0.12464395E+00 0.12237969E+00
+ 0.12013224E+00 0.11790171E+00 0.11568821E+00 0.11349187E+00 0.11131280E+00
+ 0.10915111E+00 0.10700691E+00 0.10488033E+00 0.10277147E+00 0.10068046E+00
+ 0.98607407E-01 0.96552425E-01 0.94515631E-01 0.92497139E-01 0.90497065E-01
+ 0.88515523E-01 0.86552630E-01 0.84608499E-01 0.82683246E-01 0.80776986E-01
+ 0.78889833E-01 0.77021904E-01 0.75173312E-01 0.73344173E-01 0.71534603E-01
+ 0.69744715E-01 0.67974625E-01 0.66224449E-01 0.64494300E-01 0.62784295E-01
+ 0.61094547E-01 0.59425173E-01 0.57776288E-01 0.56148005E-01 0.54540441E-01
+ 0.52953710E-01 0.51387927E-01 0.49843208E-01 0.48319667E-01 0.46817419E-01
+ 0.45336580E-01 0.43877265E-01 0.42439588E-01 0.41023664E-01 0.39629610E-01
+ 0.38257538E-01 0.36907566E-01 0.35579807E-01 0.34274377E-01 0.32991390E-01
+ 0.31730962E-01 0.30493209E-01 0.29278243E-01 0.28086182E-01 0.26917140E-01
+ 0.25771231E-01 0.24648572E-01 0.23549276E-01 0.22473460E-01 0.21421238E-01
+ 0.20392724E-01 0.19388035E-01 0.18407285E-01 0.17450589E-01 0.16518062E-01
+ 0.15609819E-01 0.14725976E-01 0.13866647E-01 0.13031947E-01 0.12221992E-01
+ 0.11436896E-01 0.10676774E-01 0.99417419E-02 0.92319142E-02 0.85474059E-02
+ 0.78883322E-02 0.72548081E-02 0.66469485E-02 0.60648686E-02 0.55086833E-02
+ 0.49785076E-02 0.44744567E-02 0.39966456E-02 0.35451892E-02 0.31202025E-02
+ 0.27218008E-02 0.23500988E-02 0.20052118E-02 0.16872547E-02 0.13963426E-02
+ 0.11325904E-02 0.89611322E-03 0.68702610E-03 0.50544405E-03 0.35148211E-03
+ 0.22525530E-03 0.12687865E-03 0.56467198E-04 0.14135971E-04 0.00000000E+00
+ 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03
+ 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03
+ 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03
+ 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03
+ 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03
+ 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03
+ 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03
+ 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03
+ 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03
+ 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03
+ 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03 0.10802410E+03
+ 0.10614487E+03 0.10428086E+03 0.10248166E+03 0.10074393E+03 0.99064572E+02
+ 0.97440674E+02 0.95869526E+02 0.94348590E+02 0.92875488E+02 0.91447991E+02
+ 0.90064005E+02 0.88721562E+02 0.87418814E+02 0.86154019E+02 0.84925535E+02
+ 0.83731815E+02 0.82571398E+02 0.81442903E+02 0.80345027E+02 0.79276535E+02
+ 0.78236257E+02 0.77223086E+02 0.76235972E+02 0.75273917E+02 0.74335976E+02
+ 0.73421249E+02 0.72528881E+02 0.71658058E+02 0.70808006E+02 0.69977987E+02
+ 0.69167297E+02 0.68375266E+02 0.67601254E+02 0.66844650E+02 0.66104870E+02
+ 0.65381357E+02 0.64673577E+02 0.63981019E+02 0.63303196E+02 0.62639639E+02
+ 0.61989900E+02 0.61353550E+02 0.60730177E+02 0.60119386E+02 0.59520797E+02
+ 0.58934046E+02 0.58358783E+02 0.57794673E+02 0.57241392E+02 0.56698629E+02
+ 0.56166085E+02 0.55643473E+02 0.55130516E+02 0.54626946E+02 0.54132507E+02
+ 0.53646950E+02 0.53170038E+02 0.52701539E+02 0.52241232E+02 0.51788901E+02
+ 0.51344340E+02 0.50907349E+02 0.50477735E+02 0.50055311E+02 0.49639897E+02
+ 0.49231318E+02 0.48829406E+02 0.48433997E+02 0.48044934E+02 0.47662063E+02
+ 0.47285238E+02 0.46914315E+02 0.46549154E+02 0.46189622E+02 0.45835589E+02
+ 0.45486927E+02 0.45143515E+02 0.44805233E+02 0.44471967E+02 0.44143605E+02
+ 0.43820039E+02 0.43501162E+02 0.43186873E+02 0.42877073E+02 0.42571664E+02
+ 0.42270554E+02 0.41973652E+02 0.41680868E+02 0.41392117E+02 0.41107315E+02
+ 0.40826381E+02 0.40549236E+02 0.40275802E+02 0.40006005E+02 0.39739772E+02
+ 0.39477032E+02 0.39217715E+02 0.38961755E+02 0.38709086E+02 0.38459645E+02
+ 0.38213368E+02 0.37970195E+02 0.37730067E+02 0.37492927E+02 0.37258719E+02
+ 0.37027387E+02 0.36798879E+02 0.36573141E+02 0.36350125E+02 0.36129779E+02
+ 0.35912055E+02 0.35696907E+02 0.35484288E+02 0.35274153E+02 0.35066459E+02
+ 0.34861161E+02 0.34658220E+02 0.34457592E+02 0.34259240E+02 0.34063122E+02
+ 0.33869202E+02 0.33677442E+02 0.33487805E+02 0.33300256E+02 0.33114760E+02
+ 0.32931283E+02 0.32749791E+02 0.32570252E+02 0.32392634E+02 0.32216906E+02
+ 0.32043037E+02 0.31870997E+02 0.31700757E+02 0.31532289E+02 0.31365563E+02
+ 0.31200554E+02 0.31037234E+02 0.30875576E+02 0.30715556E+02 0.30557147E+02
+ 0.30400325E+02 0.30245066E+02 0.30091346E+02 0.29939141E+02 0.29788430E+02
+ 0.29639189E+02 0.29491397E+02 0.29345032E+02 0.29200074E+02 0.29056501E+02
+ 0.28914294E+02 0.28773432E+02 0.28633896E+02 0.28495667E+02 0.28358727E+02
+ 0.28223057E+02 0.28088638E+02 0.27955454E+02 0.27823486E+02 0.27692719E+02
+ 0.27563134E+02 0.27434717E+02 0.27307450E+02 0.27181318E+02 0.27056305E+02
+ 0.26932397E+02 0.26809577E+02 0.26687832E+02 0.26567148E+02 0.26447509E+02
+ 0.26328902E+02 0.26211313E+02 0.26094729E+02 0.25979136E+02 0.25864523E+02
+ 0.25750875E+02 0.25638181E+02 0.25526427E+02 0.25415603E+02 0.25305696E+02
+ 0.25196694E+02 0.25088586E+02 0.24981361E+02 0.24875007E+02 0.24769514E+02
+ 0.24664870E+02 0.24561066E+02 0.24458090E+02 0.24355934E+02 0.24254585E+02
+ 0.24154036E+02 0.24054275E+02 0.23955294E+02 0.23857083E+02 0.23759632E+02
+ 0.23662933E+02 0.23566976E+02 0.23471754E+02 0.23377256E+02 0.23283475E+02
+ 0.23190401E+02 0.23098028E+02 0.23006346E+02 0.22915348E+02 0.22825025E+02
+ 0.22735370E+02 0.22646376E+02 0.22558034E+02 0.22470337E+02 0.22383278E+02
+ 0.22296850E+02 0.22211045E+02 0.22125856E+02 0.22041277E+02 0.21957301E+02
+ 0.21873922E+02 0.21791131E+02 0.21708924E+02 0.21627293E+02 0.21546232E+02
+ 0.21465736E+02 0.21385797E+02 0.21306410E+02 0.21227569E+02 0.21149269E+02
+ 0.21071502E+02 0.20994264E+02 0.20917549E+02 0.20841351E+02 0.20765665E+02
+ 0.20690486E+02 0.20615807E+02 0.20541625E+02 0.20467933E+02 0.20394727E+02
+ 0.20322002E+02 0.20249752E+02 0.20177974E+02 0.20106661E+02 0.20035809E+02
+ 0.19965414E+02 0.19895470E+02 0.19825974E+02 0.19756921E+02 0.19688306E+02
+ 0.19620125E+02 0.19552373E+02 0.19485047E+02 0.19418142E+02 0.19351654E+02
+ 0.19285579E+02 0.19219913E+02 0.19154651E+02 0.19089790E+02 0.19025326E+02
+ 0.18961256E+02 0.18897574E+02 0.18834278E+02 0.18771364E+02 0.18708828E+02
+ 0.18646667E+02 0.18584876E+02 0.18523453E+02 0.18462395E+02 0.18401696E+02
+ 0.18341355E+02 0.18281368E+02 0.18221731E+02 0.18162442E+02 0.18103496E+02
+ 0.18044892E+02 0.17986625E+02 0.17928693E+02 0.17871092E+02 0.17813820E+02
+ 0.17756873E+02 0.17700249E+02 0.17643945E+02 0.17587957E+02 0.17532284E+02
+ 0.17476921E+02 0.17421867E+02 0.17367118E+02 0.17312672E+02 0.17258526E+02
+ 0.17204677E+02 0.17151124E+02 0.17097863E+02 0.17044891E+02 0.16992207E+02
+ 0.16939807E+02 0.16887689E+02 0.16835851E+02 0.16784291E+02 0.16733005E+02
+ 0.16681992E+02 0.16631249E+02 0.16580774E+02 0.16530565E+02 0.16480619E+02
+ 0.16430934E+02 0.16381509E+02 0.16332339E+02 0.16283425E+02 0.16234763E+02
+ 0.16186351E+02 0.16138187E+02 0.16090270E+02 0.16042597E+02 0.15995166E+02
+ 0.15947975E+02 0.15901022E+02 0.15854305E+02 0.15807823E+02 0.15761573E+02
+ 0.15715554E+02 0.15669763E+02 0.15624198E+02 0.15578859E+02 0.15533743E+02
+ 0.15488848E+02 0.15444173E+02 0.15399715E+02 0.15355474E+02 0.15311446E+02
+ 0.15267632E+02 0.15224028E+02 0.15180634E+02 0.15137447E+02 0.15094466E+02
+ 0.15051690E+02 0.15009117E+02 0.14966744E+02 0.14924572E+02 0.14882597E+02
+ 0.14840820E+02 0.14799237E+02 0.14757848E+02 0.14716651E+02 0.14675644E+02
+ 0.14634827E+02 0.14594197E+02 0.14553754E+02 0.14513496E+02 0.14473421E+02
+ 0.14433528E+02 0.14393816E+02 0.14354284E+02 0.14314929E+02 0.14275751E+02
+ 0.14236749E+02 0.14197921E+02 0.14159266E+02 0.14120782E+02 0.14082468E+02
+ 0.14044324E+02 0.14006347E+02 0.13968537E+02 0.13930892E+02 0.13893412E+02
+ 0.13856094E+02 0.13818938E+02 0.13781943E+02 0.13745108E+02 0.13708430E+02
+ 0.13671910E+02 0.13635546E+02 0.13599337E+02 0.13563282E+02 0.13527379E+02
+ 0.13491628E+02 0.13456028E+02 0.13420577E+02 0.13385275E+02 0.13350120E+02
+ 0.13315112E+02 0.13280249E+02 0.13245530E+02 0.13210955E+02 0.13176522E+02
+ 0.13142231E+02 0.13108080E+02 0.13074068E+02 0.13040195E+02 0.13006460E+02
+ 0.12972861E+02 0.12939398E+02 0.12906070E+02 0.12872875E+02 0.12839813E+02
+ 0.12806884E+02 0.12774085E+02 0.12741417E+02 0.12708879E+02 0.12676468E+02
+ 0.12644186E+02 0.12612030E+02 0.12580000E+02 0.12548096E+02 0.12516315E+02
+ 0.12484659E+02 0.12453124E+02 0.12421712E+02 0.12390421E+02 0.12359250E+02
+ 0.12328199E+02 0.12297266E+02 0.12266451E+02 0.12235754E+02 0.12205173E+02
+ 0.12174707E+02 0.12144357E+02 0.12114121E+02 0.12083998E+02 0.12053988E+02
+ 0.12024089E+02 0.11994303E+02 0.11964626E+02 0.11935060E+02 0.11905603E+02
+ 0.11876254E+02 0.11847013E+02 0.11817880E+02 0.11788853E+02 0.11759931E+02
+ 0.11731115E+02 0.11702403E+02 0.11673795E+02 0.11645291E+02 0.11616889E+02
+ 0.11588588E+02 0.11560390E+02 0.11532291E+02 0.11504293E+02 0.11476395E+02
+ 0.11448595E+02 0.11420893E+02 0.11393289E+02 0.11365782E+02 0.11338372E+02
+ 0.11311057E+02 0.11283838E+02 0.11256713E+02 0.11229683E+02 0.11202746E+02
+ 0.11175902E+02 0.11149151E+02 0.11122492E+02 0.11095924E+02 0.11069447E+02
+ 0.11043060E+02 0.11016763E+02 0.10990555E+02 0.10964436E+02 0.10938405E+02
+ 0.10912462E+02 0.10886606E+02 0.10860836E+02 0.10835153E+02 0.10809556E+02
+ 0.10784043E+02 0.10758616E+02 0.10733272E+02 0.10708013E+02 0.10682836E+02
+ 0.10657742E+02 0.10632731E+02 0.10607801E+02 0.10582953E+02 0.10558185E+02
+ 0.10533498E+02 0.10508891E+02 0.10484364E+02 0.10459915E+02 0.10435545E+02
+ 0.10411254E+02 0.10387040E+02 0.10362903E+02 0.10338843E+02 0.10314860E+02
+ 0.10290953E+02 0.10267121E+02 0.10243365E+02 0.10219683E+02 0.10196076E+02
+ 0.10172543E+02 0.10149083E+02 0.10125697E+02 0.10102383E+02 0.10079141E+02
+ 0.10055972E+02 0.10032874E+02 0.10009847E+02 0.99868913E+01 0.99640058E+01
+ 0.99411904E+01 0.99184447E+01 0.98957683E+01 0.98731608E+01 0.98506218E+01
+ 0.98281511E+01 0.98057482E+01 0.97834128E+01 0.97611445E+01 0.97389430E+01
+ 0.97168079E+01 0.96947388E+01 0.96727355E+01 0.96507976E+01 0.96289248E+01
+ 0.96071166E+01 0.95853728E+01 0.95636930E+01 0.95420769E+01 0.95205242E+01
+ 0.94990346E+01 0.94776077E+01 0.94562431E+01 0.94349407E+01 0.94137000E+01
+ 0.93925208E+01 0.93714027E+01 0.93503455E+01 0.93293487E+01 0.93084122E+01
+ 0.92875356E+01 0.92667186E+01 0.92459609E+01 0.92252623E+01 0.92046223E+01
+ 0.91840408E+01 0.91635174E+01 0.91430519E+01 0.91226439E+01 0.91022932E+01
+ 0.90819995E+01 0.90617625E+01 0.90415819E+01 0.90214575E+01 0.90013890E+01
+ 0.89813760E+01 0.89614185E+01 0.89415159E+01 0.89216682E+01 0.89018751E+01
+ 0.88821362E+01 0.88624513E+01 0.88428201E+01 0.88232425E+01 0.88037181E+01
+ 0.87842467E+01 0.87648280E+01 0.87454617E+01 0.87261478E+01 0.87068858E+01
+ 0.86876755E+01 0.86685167E+01 0.86494092E+01 0.86303527E+01 0.86113469E+01
+ 0.85923917E+01 0.85734868E+01 0.85546319E+01 0.85358269E+01 0.85170714E+01
+ 0.84983654E+01 0.84797085E+01 0.84611004E+01 0.84425411E+01 0.84240303E+01
+ 0.84055676E+01 0.83871530E+01 0.83687862E+01 0.83504670E+01 0.83321952E+01
+ 0.83139705E+01 0.82957928E+01 0.82776618E+01 0.82595773E+01 0.82415391E+01
+ 0.82235470E+01 0.82056008E+01 0.81877003E+01 0.81698453E+01 0.81520356E+01
+ 0.81342710E+01 0.81165512E+01 0.80988762E+01 0.80812456E+01 0.80636593E+01
+ 0.80461171E+01 0.80286189E+01 0.80111643E+01 0.79937533E+01 0.79763856E+01
+ 0.79590611E+01 0.79417795E+01 0.79245407E+01 0.79073445E+01 0.78901907E+01
+ 0.78730791E+01 0.78560095E+01 0.78389819E+01 0.78219959E+01 0.78050514E+01
+ 0.77881483E+01 0.77712863E+01 0.77544653E+01 0.77376851E+01 0.77209455E+01
+ 0.77042464E+01 0.76875877E+01 0.76709690E+01 0.76543903E+01 0.76378514E+01
+ 0.76213522E+01 0.76048924E+01 0.75884719E+01 0.75720906E+01 0.75557482E+01
+ 0.75394447E+01 0.75231798E+01 0.75069534E+01 0.74907654E+01 0.74746155E+01
+ 0.74585037E+01 0.74424298E+01 0.74263936E+01 0.74103950E+01 0.73944338E+01
+ 0.73785099E+01 0.73626231E+01 0.73467733E+01 0.73309604E+01 0.73151841E+01
+ 0.72994443E+01 0.72837409E+01 0.72680738E+01 0.72524428E+01 0.72368478E+01
+ 0.72212886E+01 0.72057650E+01 0.71902770E+01 0.71748244E+01 0.71594071E+01
+ 0.71440249E+01 0.71286777E+01 0.71133654E+01 0.70980878E+01 0.70828447E+01
+ 0.70676362E+01 0.70524619E+01 0.70373219E+01 0.70222159E+01 0.70071439E+01
+ 0.69921056E+01 0.69771011E+01 0.69621301E+01 0.69471925E+01 0.69322882E+01
+ 0.69174171E+01 0.69025790E+01 0.68877739E+01 0.68730016E+01 0.68582620E+01
+ 0.68435549E+01 0.68288802E+01 0.68142379E+01 0.67996278E+01 0.67850498E+01
+ 0.67705037E+01 0.67559895E+01 0.67415071E+01 0.67270562E+01 0.67126369E+01
+ 0.66982489E+01 0.66838922E+01 0.66695667E+01 0.66552722E+01 0.66410087E+01
+ 0.66267760E+01 0.66125741E+01 0.65984027E+01 0.65842618E+01 0.65701514E+01
+ 0.65560712E+01 0.65420212E+01 0.65280013E+01 0.65140113E+01 0.65000512E+01
+ 0.64861209E+01 0.64722202E+01 0.64583491E+01 0.64445074E+01 0.64306951E+01
+ 0.64169120E+01 0.64031581E+01 0.63894332E+01 0.63757373E+01 0.63620702E+01
+ 0.63484318E+01 0.63348222E+01 0.63212410E+01 0.63076883E+01 0.62941640E+01
+ 0.62806680E+01 0.62672001E+01 0.62537603E+01 0.62403485E+01 0.62269645E+01
+ 0.62136084E+01 0.62002800E+01 0.61869792E+01 0.61737059E+01 0.61604600E+01
+ 0.61472415E+01 0.61340502E+01 0.61208861E+01 0.61077491E+01 0.60946390E+01
+ 0.60815559E+01 0.60684995E+01 0.60554699E+01 0.60424670E+01 0.60294905E+01
+ 0.60165406E+01 0.60036170E+01 0.59907197E+01 0.59778487E+01 0.59650037E+01
+ 0.59521849E+01 0.59393919E+01 0.59266249E+01 0.59138837E+01 0.59011682E+01
+ 0.58884783E+01 0.58758140E+01 0.58631752E+01 0.58505618E+01 0.58379737E+01
+ 0.58254109E+01 0.58128732E+01 0.58003606E+01 0.57878731E+01 0.57754105E+01
+ 0.57629727E+01 0.57505597E+01 0.57381715E+01 0.57258078E+01 0.57134688E+01
+ 0.57011542E+01 0.56888641E+01 0.56765982E+01 0.56643567E+01 0.56521393E+01
+ 0.56399461E+01 0.56277770E+01 0.56156318E+01 0.56035105E+01 0.55914131E+01
+ 0.55793394E+01 0.55672895E+01 0.55552631E+01 0.55432604E+01 0.55312811E+01
+ 0.55193253E+01 0.55073928E+01 0.54954836E+01 0.54835977E+01 0.54717349E+01
+ 0.54598952E+01 0.54480785E+01 0.54362848E+01 0.54245139E+01 0.54127660E+01
+ 0.54010407E+01 0.53893382E+01 0.53776583E+01 0.53660010E+01 0.53543663E+01
+ 0.53427539E+01 0.53311640E+01 0.53195964E+01 0.53080510E+01 0.52965278E+01
+ 0.52850268E+01 0.52735479E+01 0.52620910E+01 0.52506560E+01 0.52392430E+01
+ 0.52278518E+01 0.52164824E+01 0.52051347E+01 0.51938086E+01 0.51825042E+01
+ 0.51712213E+01 0.51599600E+01 0.51487200E+01 0.51375014E+01 0.51263042E+01
+ 0.51151282E+01 0.51039734E+01 0.50928398E+01 0.50817273E+01 0.50706358E+01
+ 0.50595653E+01 0.50485157E+01 0.50374871E+01 0.50264792E+01 0.50154921E+01
+ 0.50045257E+01 0.49935800E+01 0.49826549E+01 0.49717504E+01 0.49608664E+01
+ 0.49500028E+01 0.49391596E+01 0.49283368E+01 0.49175343E+01 0.49067520E+01
+ 0.48959899E+01 0.48852480E+01 0.48745262E+01 0.48638244E+01 0.48531426E+01
+ 0.48424808E+01 0.48318388E+01 0.48212168E+01 0.48106145E+01 0.48000319E+01
+ 0.47894691E+01 0.47789260E+01 0.47684024E+01 0.47578984E+01 0.47474139E+01
+ 0.47369489E+01 0.47265033E+01 0.47160771E+01 0.47056702E+01 0.46952826E+01
+ 0.46849142E+01 0.46745650E+01 0.46642350E+01 0.46539241E+01 0.46436322E+01
+ 0.46333593E+01 0.46231054E+01 0.46128704E+01 0.46026543E+01 0.45924571E+01
+ 0.45822786E+01 0.45721189E+01 0.45619779E+01 0.45518555E+01 0.45417518E+01
+ 0.45316666E+01 0.45216000E+01 0.45115518E+01 0.45015221E+01 0.44915108E+01
+ 0.44815179E+01 0.44715433E+01 0.44615870E+01 0.44516490E+01 0.44417291E+01
+ 0.44318274E+01 0.44219439E+01 0.44120784E+01 0.44022310E+01 0.43924015E+01
+ 0.43825900E+01 0.43727965E+01 0.43630208E+01 0.43532630E+01 0.43435230E+01
+ 0.43338008E+01 0.43240963E+01 0.43144094E+01 0.43047403E+01 0.42950887E+01
+ 0.42854548E+01 0.42758384E+01 0.42662394E+01 0.42566580E+01 0.42470940E+01
+ 0.42375474E+01 0.42280181E+01 0.42185062E+01 0.42090115E+01 0.41995341E+01
+ 0.41900739E+01 0.41806309E+01 0.41712050E+01 0.41617963E+01 0.41524046E+01
+ 0.41430299E+01 0.41336722E+01 0.41243316E+01 0.41150078E+01 0.41057010E+01
+ 0.40964110E+01 0.40871378E+01 0.40778814E+01 0.40686418E+01 0.40594190E+01
+ 0.40502128E+01 0.40410233E+01 0.40318504E+01 0.40226941E+01 0.40135544E+01
+ 0.40044312E+01 0.39953245E+01 0.39862342E+01 0.39771604E+01 0.39681030E+01
+ 0.39590620E+01 0.39500373E+01 0.39410289E+01 0.39320368E+01 0.39230609E+01
+ 0.39141013E+01 0.39051578E+01 0.38962305E+01 0.38873193E+01 0.38784242E+01
+ 0.38695451E+01 0.38606821E+01 0.38518351E+01 0.38430040E+01 0.38341889E+01
+ 0.38253897E+01 0.38166063E+01 0.38078388E+01 0.37990871E+01 0.37903513E+01
+ 0.37816311E+01 0.37729267E+01 0.37642380E+01 0.37555650E+01 0.37469077E+01
+ 0.37382659E+01 0.37296397E+01 0.37210291E+01 0.37124340E+01 0.37038545E+01
+ 0.36952904E+01 0.36867417E+01 0.36782085E+01 0.36696906E+01 0.36611881E+01
+ 0.36527010E+01 0.36442292E+01 0.36357726E+01 0.36273313E+01 0.36189052E+01
+ 0.36104944E+01 0.36020987E+01 0.35937181E+01 0.35853527E+01 0.35770024E+01
+ 0.35686671E+01 0.35603469E+01 0.35520417E+01 0.35437515E+01 0.35354763E+01
+ 0.35272160E+01 0.35189706E+01 0.35107401E+01 0.35025244E+01 0.34943236E+01
+ 0.34861376E+01 0.34779664E+01 0.34698100E+01 0.34616683E+01 0.34535413E+01
+ 0.34454290E+01 0.34373314E+01 0.34292484E+01 0.34211800E+01 0.34131262E+01
+ 0.34050870E+01 0.33970623E+01 0.33890521E+01 0.33810564E+01 0.33730752E+01
+ 0.33651084E+01 0.33571561E+01 0.33492182E+01 0.33412946E+01 0.33333854E+01
+ 0.33254905E+01 0.33176099E+01 0.33097436E+01 0.33018916E+01 0.32940537E+01
+ 0.32862302E+01 0.32784208E+01 0.32706255E+01 0.32628444E+01 0.32550775E+01
+ 0.32473246E+01 0.32395858E+01 0.32318611E+01 0.32241504E+01 0.32164537E+01
+ 0.32087710E+01 0.32011022E+01 0.31934474E+01 0.31858066E+01 0.31781796E+01
+ 0.31705665E+01 0.31629673E+01 0.31553819E+01 0.31478103E+01 0.31402526E+01
+ 0.31327085E+01 0.31251783E+01 0.31176618E+01 0.31101590E+01 0.31026698E+01
+ 0.30951944E+01 0.30877326E+01 0.30802844E+01 0.30728498E+01 0.30654288E+01
+ 0.30580214E+01 0.30506275E+01 0.30432471E+01 0.30358803E+01 0.30285269E+01
+ 0.30211870E+01 0.30138605E+01 0.30065474E+01 0.29992478E+01 0.29919615E+01
+ 0.29846886E+01 0.29774291E+01 0.29701828E+01 0.29629499E+01 0.29557303E+01
+ 0.29485239E+01 0.29413307E+01 0.29341508E+01 0.29269841E+01 0.29198306E+01
+ 0.29126903E+01 0.29055631E+01 0.28984490E+01 0.28913480E+01 0.28842602E+01
+ 0.28771854E+01 0.28701236E+01 0.28630749E+01 0.28560392E+01 0.28490166E+01
+ 0.28420068E+01 0.28350101E+01 0.28280263E+01 0.28210554E+01 0.28140974E+01
+ 0.28071523E+01 0.28002201E+01 0.27933007E+01 0.27863942E+01 0.27795005E+01
+ 0.27726195E+01 0.27657514E+01 0.27588960E+01 0.27520533E+01 0.27452234E+01
+ 0.27384062E+01 0.27316016E+01 0.27248098E+01 0.27180306E+01 0.27112640E+01
+ 0.27045101E+01 0.26977687E+01 0.26910399E+01 0.26843237E+01 0.26776201E+01
+ 0.26709290E+01 0.26642503E+01 0.26575842E+01 0.26509306E+01 0.26442894E+01
+ 0.26376607E+01 0.26310444E+01 0.26244405E+01 0.26178490E+01 0.26112699E+01
+ 0.26047032E+01 0.25981488E+01 0.25916067E+01 0.25850769E+01 0.25785594E+01
+ 0.25720542E+01 0.25655613E+01 0.25590806E+01 0.25526121E+01 0.25461559E+01
+ 0.25397118E+01 0.25332799E+01 0.25268602E+01 0.25204526E+01 0.25140572E+01
+ 0.25076739E+01 0.25013026E+01 0.24949435E+01 0.24885964E+01 0.24822613E+01
+ 0.24759383E+01 0.24696273E+01 0.24633283E+01 0.24570413E+01 0.24507663E+01
+ 0.24445032E+01 0.24382521E+01 0.24320128E+01 0.24257855E+01 0.24195701E+01
+ 0.24133665E+01 0.24071748E+01 0.24009950E+01 0.23948270E+01 0.23886707E+01
+ 0.23825263E+01 0.23763937E+01 0.23702728E+01 0.23641637E+01 0.23580663E+01
+ 0.23519807E+01 0.23459067E+01 0.23398444E+01 0.23337938E+01 0.23277549E+01
+ 0.23217276E+01 0.23157119E+01 0.23097079E+01 0.23037154E+01 0.22977345E+01
+ 0.22917652E+01 0.22858075E+01 0.22798613E+01 0.22739266E+01 0.22680034E+01
+ 0.22620917E+01 0.22561915E+01 0.22503028E+01 0.22444255E+01 0.22385596E+01
+ 0.22327052E+01 0.22268622E+01 0.22210305E+01 0.22152103E+01 0.22094014E+01
+ 0.22036038E+01 0.21978176E+01 0.21920427E+01 0.21862791E+01 0.21805267E+01
+ 0.21747857E+01 0.21690559E+01 0.21633374E+01 0.21576301E+01 0.21519340E+01
+ 0.21462491E+01 0.21405754E+01 0.21349129E+01 0.21292615E+01 0.21236213E+01
+ 0.21179922E+01 0.21123742E+01 0.21067673E+01 0.21011716E+01 0.20955869E+01
+ 0.20900132E+01 0.20844506E+01 0.20788990E+01 0.20733585E+01 0.20678289E+01
+ 0.20623104E+01 0.20568028E+01 0.20513062E+01 0.20458205E+01 0.20403458E+01
+ 0.20348820E+01 0.20294291E+01 0.20239870E+01 0.20185559E+01 0.20131356E+01
+ 0.20077262E+01 0.20023276E+01 0.19969399E+01 0.19915629E+01 0.19861968E+01
+ 0.19808414E+01 0.19754968E+01 0.19701630E+01 0.19648399E+01 0.19595275E+01
+ 0.19542258E+01 0.19489349E+01 0.19436546E+01 0.19383850E+01 0.19331261E+01
+ 0.19278778E+01 0.19226402E+01 0.19174131E+01 0.19121967E+01 0.19069909E+01
+ 0.19017956E+01 0.18966109E+01 0.18914368E+01 0.18862732E+01 0.18811201E+01
+ 0.18759776E+01 0.18708455E+01 0.18657239E+01 0.18606128E+01 0.18555122E+01
+ 0.18504220E+01 0.18453423E+01 0.18402729E+01 0.18352140E+01 0.18301655E+01
+ 0.18251273E+01 0.18200995E+01 0.18150821E+01 0.18100750E+01 0.18050782E+01
+ 0.18000918E+01 0.17951156E+01 0.17901497E+01 0.17851942E+01 0.17802488E+01
+ 0.17753137E+01 0.17703889E+01 0.17654743E+01 0.17605699E+01 0.17556757E+01
+ 0.17507916E+01 0.17459178E+01 0.17410541E+01 0.17362005E+01 0.17313571E+01
+ 0.17265238E+01 0.17217006E+01 0.17168875E+01 0.17120845E+01 0.17072915E+01
+ 0.17025086E+01 0.16977358E+01 0.16929730E+01 0.16882201E+01 0.16834773E+01
+ 0.16787445E+01 0.16740217E+01 0.16693088E+01 0.16646059E+01 0.16599129E+01
+ 0.16552298E+01 0.16505567E+01 0.16458934E+01 0.16412401E+01 0.16365966E+01
+ 0.16319630E+01 0.16273392E+01 0.16227253E+01 0.16181212E+01 0.16135269E+01
+ 0.16089424E+01 0.16043677E+01 0.15998027E+01 0.15952476E+01 0.15907021E+01
+ 0.15861665E+01 0.15816405E+01 0.15771242E+01 0.15726177E+01 0.15681208E+01
+ 0.15636336E+01 0.15591561E+01 0.15546882E+01 0.15502299E+01 0.15457813E+01
+ 0.15413422E+01 0.15369128E+01 0.15324930E+01 0.15280827E+01 0.15236820E+01
+ 0.15192908E+01 0.15149092E+01 0.15105371E+01 0.15061745E+01 0.15018214E+01
+ 0.14974778E+01 0.14931436E+01 0.14888189E+01 0.14845037E+01 0.14801979E+01
+ 0.14759015E+01 0.14716145E+01 0.14673370E+01 0.14630688E+01 0.14588100E+01
+ 0.14545605E+01 0.14503204E+01 0.14460896E+01 0.14418682E+01 0.14376560E+01
+ 0.14334532E+01 0.14292596E+01 0.14250753E+01 0.14209003E+01 0.14167345E+01
+ 0.14125780E+01 0.14084307E+01 0.14042926E+01 0.14001637E+01 0.13960440E+01
+ 0.13919334E+01 0.13878320E+01 0.13837398E+01 0.13796567E+01 0.13755827E+01
+ 0.13715179E+01 0.13674621E+01 0.13634154E+01 0.13593778E+01 0.13553493E+01
+ 0.13513298E+01 0.13473194E+01 0.13433180E+01 0.13393256E+01 0.13353422E+01
+ 0.13313678E+01 0.13274023E+01 0.13234459E+01 0.13194983E+01 0.13155598E+01
+ 0.13116301E+01 0.13077094E+01 0.13037976E+01 0.12998946E+01 0.12960006E+01
+ 0.12921154E+01 0.12882391E+01 0.12843716E+01 0.12805129E+01 0.12766631E+01
+ 0.12728220E+01 0.12689898E+01 0.12651663E+01 0.12613516E+01 0.12575457E+01
+ 0.12537485E+01 0.12499600E+01 0.12461803E+01 0.12424093E+01 0.12386469E+01
+ 0.12348933E+01 0.12311483E+01 0.12274120E+01 0.12236843E+01 0.12199653E+01
+ 0.12162549E+01 0.12125531E+01 0.12088599E+01 0.12051753E+01 0.12014992E+01
+ 0.11978317E+01 0.11941728E+01 0.11905224E+01 0.11868806E+01 0.11832472E+01
+ 0.11796224E+01 0.11760060E+01 0.11723981E+01 0.11687987E+01 0.11652077E+01
+ 0.11616252E+01 0.11580511E+01 0.11544854E+01 0.11509281E+01 0.11473793E+01
+ 0.11438388E+01 0.11403066E+01 0.11367828E+01 0.11332674E+01 0.11297603E+01
+ 0.11262615E+01 0.11227710E+01 0.11192889E+01 0.11158150E+01 0.11123493E+01
+ 0.11088920E+01 0.11054429E+01 0.11020020E+01 0.10985693E+01 0.10951449E+01
+ 0.10917286E+01 0.10883205E+01 0.10849207E+01 0.10815289E+01 0.10781454E+01
+ 0.10747699E+01 0.10714026E+01 0.10680434E+01 0.10646923E+01 0.10613493E+01
+ 0.10580144E+01 0.10546875E+01 0.10513687E+01 0.10480579E+01 0.10447552E+01
+ 0.10414605E+01 0.10381738E+01 0.10348951E+01 0.10316243E+01 0.10283616E+01
+ 0.10251068E+01 0.10218599E+01 0.10186210E+01 0.10153900E+01 0.10121669E+01
+ 0.10089517E+01 0.10057443E+01 0.10025449E+01 0.99935332E+00 0.99616959E+00
+ 0.99299370E+00 0.98982563E+00 0.98666538E+00 0.98351293E+00 0.98036827E+00
+ 0.97723138E+00 0.97410226E+00 0.97098090E+00 0.96786727E+00 0.96476138E+00
+ 0.96166320E+00 0.95857273E+00 0.95548995E+00 0.95241485E+00 0.94934743E+00
+ 0.94628766E+00 0.94323553E+00 0.94019104E+00 0.93715418E+00 0.93412492E+00
+ 0.93110326E+00 0.92808918E+00 0.92508268E+00 0.92208374E+00 0.91909235E+00
+ 0.91610850E+00 0.91313217E+00 0.91016336E+00 0.90720205E+00 0.90424823E+00
+ 0.90130189E+00 0.89836301E+00 0.89543159E+00 0.89250761E+00 0.88959106E+00
+ 0.88668193E+00 0.88378021E+00 0.88088588E+00 0.87799893E+00 0.87511935E+00
+ 0.87224714E+00 0.86938227E+00 0.86652473E+00 0.86367452E+00 0.86083162E+00
+ 0.85799601E+00 0.85516770E+00 0.85234666E+00 0.84953288E+00 0.84672636E+00
+ 0.84392707E+00 0.84113502E+00 0.83835017E+00 0.83557254E+00 0.83280209E+00
+ 0.83003883E+00 0.82728273E+00 0.82453379E+00 0.82179199E+00 0.81905733E+00
+ 0.81632979E+00 0.81360935E+00 0.81089601E+00 0.80818976E+00 0.80549058E+00
+ 0.80279847E+00 0.80011340E+00 0.79743537E+00 0.79476437E+00 0.79210038E+00
+ 0.78944339E+00 0.78679339E+00 0.78415037E+00 0.78151432E+00 0.77888522E+00
+ 0.77626307E+00 0.77364784E+00 0.77103954E+00 0.76843814E+00 0.76584364E+00
+ 0.76325602E+00 0.76067527E+00 0.75810139E+00 0.75553435E+00 0.75297415E+00
+ 0.75042078E+00 0.74787421E+00 0.74533445E+00 0.74280148E+00 0.74027528E+00
+ 0.73775586E+00 0.73524318E+00 0.73273725E+00 0.73023805E+00 0.72774556E+00
+ 0.72525978E+00 0.72278070E+00 0.72030830E+00 0.71784258E+00 0.71538351E+00
+ 0.71293109E+00 0.71048531E+00 0.70804615E+00 0.70561361E+00 0.70318766E+00
+ 0.70076831E+00 0.69835553E+00 0.69594932E+00 0.69354966E+00 0.69115655E+00
+ 0.68876996E+00 0.68638990E+00 0.68401634E+00 0.68164928E+00 0.67928870E+00
+ 0.67693459E+00 0.67458695E+00 0.67224575E+00 0.66991099E+00 0.66758266E+00
+ 0.66526074E+00 0.66294522E+00 0.66063609E+00 0.65833334E+00 0.65603696E+00
+ 0.65374694E+00 0.65146325E+00 0.64918590E+00 0.64691487E+00 0.64465015E+00
+ 0.64239173E+00 0.64013959E+00 0.63789372E+00 0.63565412E+00 0.63342077E+00
+ 0.63119366E+00 0.62897261E+00 0.62675165E+00 0.62452781E+00 0.62230114E+00
+ 0.62007168E+00 0.61783949E+00 0.61560460E+00 0.61336706E+00 0.61112693E+00
+ 0.60888425E+00 0.60663906E+00 0.60439140E+00 0.60214134E+00 0.59988891E+00
+ 0.59763416E+00 0.59537713E+00 0.59311788E+00 0.59085645E+00 0.58859289E+00
+ 0.58632723E+00 0.58405954E+00 0.58178985E+00 0.57951822E+00 0.57724468E+00
+ 0.57496929E+00 0.57269209E+00 0.57041313E+00 0.56813246E+00 0.56585012E+00
+ 0.56356615E+00 0.56128061E+00 0.55899354E+00 0.55670499E+00 0.55441500E+00
+ 0.55212363E+00 0.54983091E+00 0.54753689E+00 0.54524163E+00 0.54294516E+00
+ 0.54064754E+00 0.53834880E+00 0.53604901E+00 0.53374819E+00 0.53144641E+00
+ 0.52914370E+00 0.52684012E+00 0.52453570E+00 0.52223050E+00 0.51992457E+00
+ 0.51761794E+00 0.51531067E+00 0.51300280E+00 0.51069438E+00 0.50838545E+00
+ 0.50607607E+00 0.50376627E+00 0.50145611E+00 0.49914563E+00 0.49683488E+00
+ 0.49452390E+00 0.49221274E+00 0.48990146E+00 0.48759008E+00 0.48527867E+00
+ 0.48296726E+00 0.48065591E+00 0.47834466E+00 0.47603355E+00 0.47372264E+00
+ 0.47141197E+00 0.46910158E+00 0.46679153E+00 0.46448185E+00 0.46217261E+00
+ 0.45986383E+00 0.45755558E+00 0.45524789E+00 0.45294081E+00 0.45063439E+00
+ 0.44832868E+00 0.44602371E+00 0.44371955E+00 0.44141623E+00 0.43911381E+00
+ 0.43681232E+00 0.43451181E+00 0.43221234E+00 0.42991395E+00 0.42761668E+00
+ 0.42532058E+00 0.42302569E+00 0.42073208E+00 0.41843977E+00 0.41614882E+00
+ 0.41385927E+00 0.41157117E+00 0.40928457E+00 0.40699951E+00 0.40471604E+00
+ 0.40243421E+00 0.40015406E+00 0.39787564E+00 0.39559900E+00 0.39332418E+00
+ 0.39105122E+00 0.38878019E+00 0.38651111E+00 0.38424404E+00 0.38197903E+00
+ 0.37971612E+00 0.37745536E+00 0.37519680E+00 0.37294047E+00 0.37068643E+00
+ 0.36843473E+00 0.36618541E+00 0.36393851E+00 0.36169409E+00 0.35945219E+00
+ 0.35721286E+00 0.35497614E+00 0.35274208E+00 0.35051073E+00 0.34828213E+00
+ 0.34605633E+00 0.34383337E+00 0.34161331E+00 0.33939619E+00 0.33718206E+00
+ 0.33497096E+00 0.33276293E+00 0.33055803E+00 0.32835631E+00 0.32615780E+00
+ 0.32396256E+00 0.32177063E+00 0.31958206E+00 0.31739689E+00 0.31521518E+00
+ 0.31303696E+00 0.31086229E+00 0.30869121E+00 0.30652377E+00 0.30436001E+00
+ 0.30219998E+00 0.30004373E+00 0.29789130E+00 0.29574274E+00 0.29359810E+00
+ 0.29145742E+00 0.28932075E+00 0.28718814E+00 0.28505964E+00 0.28293528E+00
+ 0.28081512E+00 0.27869920E+00 0.27658757E+00 0.27448027E+00 0.27237736E+00
+ 0.27027888E+00 0.26818487E+00 0.26609538E+00 0.26401047E+00 0.26193016E+00
+ 0.25985452E+00 0.25778359E+00 0.25571741E+00 0.25365604E+00 0.25159951E+00
+ 0.24954787E+00 0.24750118E+00 0.24545947E+00 0.24342280E+00 0.24139121E+00
+ 0.23936474E+00 0.23734345E+00 0.23532738E+00 0.23331657E+00 0.23131108E+00
+ 0.22931095E+00 0.22731623E+00 0.22532695E+00 0.22334318E+00 0.22136495E+00
+ 0.21939232E+00 0.21742532E+00 0.21546401E+00 0.21350843E+00 0.21155863E+00
+ 0.20961466E+00 0.20767655E+00 0.20574437E+00 0.20381815E+00 0.20189794E+00
+ 0.19998379E+00 0.19807574E+00 0.19617385E+00 0.19427815E+00 0.19238870E+00
+ 0.19050553E+00 0.18862871E+00 0.18675827E+00 0.18489425E+00 0.18303672E+00
+ 0.18118571E+00 0.17934126E+00 0.17750344E+00 0.17567228E+00 0.17384782E+00
+ 0.17203012E+00 0.17021923E+00 0.16841518E+00 0.16661803E+00 0.16482783E+00
+ 0.16304461E+00 0.16126842E+00 0.15949932E+00 0.15773735E+00 0.15598255E+00
+ 0.15423497E+00 0.15249467E+00 0.15076167E+00 0.14903604E+00 0.14731781E+00
+ 0.14560704E+00 0.14390377E+00 0.14220805E+00 0.14051992E+00 0.13883943E+00
+ 0.13716663E+00 0.13550156E+00 0.13384427E+00 0.13219481E+00 0.13055322E+00
+ 0.12891955E+00 0.12729384E+00 0.12567615E+00 0.12406652E+00 0.12246500E+00
+ 0.12087162E+00 0.11928645E+00 0.11770952E+00 0.11614088E+00 0.11458058E+00
+ 0.11302867E+00 0.11148519E+00 0.10995019E+00 0.10842371E+00 0.10690580E+00
+ 0.10539651E+00 0.10389588E+00 0.10240397E+00 0.10092081E+00 0.99446458E-01
+ 0.97980955E-01 0.96524350E-01 0.95076687E-01 0.93638015E-01 0.92208380E-01
+ 0.90787828E-01 0.89376406E-01 0.87974160E-01 0.86581136E-01 0.85197383E-01
+ 0.83822945E-01 0.82457870E-01 0.81102203E-01 0.79755993E-01 0.78419284E-01
+ 0.77092124E-01 0.75774559E-01 0.74466636E-01 0.73168402E-01 0.71879902E-01
+ 0.70601183E-01 0.69332293E-01 0.68073277E-01 0.66824181E-01 0.65585054E-01
+ 0.64355940E-01 0.63136888E-01 0.61927942E-01 0.60729150E-01 0.59540559E-01
+ 0.58362214E-01 0.57194162E-01 0.56036451E-01 0.54889126E-01 0.53752234E-01
+ 0.52625821E-01 0.51509935E-01 0.50404621E-01 0.49309926E-01 0.48225897E-01
+ 0.47152580E-01 0.46090022E-01 0.45038270E-01 0.43997369E-01 0.42967367E-01
+ 0.41948309E-01 0.40940244E-01 0.39943216E-01 0.38957273E-01 0.37982461E-01
+ 0.37018826E-01 0.36066416E-01 0.35125277E-01 0.34195455E-01 0.33276997E-01
+ 0.32369949E-01 0.31474359E-01 0.30590271E-01 0.29717734E-01 0.28856794E-01
+ 0.28007496E-01 0.27169888E-01 0.26344017E-01 0.25529928E-01 0.24727668E-01
+ 0.23937284E-01 0.23158823E-01 0.22392331E-01 0.21637854E-01 0.20895439E-01
+ 0.20165133E-01 0.19446981E-01 0.18741032E-01 0.18047330E-01 0.17365924E-01
+ 0.16696859E-01 0.16040181E-01 0.15395938E-01 0.14764176E-01 0.14144941E-01
+ 0.13538280E-01 0.12944240E-01 0.12362867E-01 0.11794207E-01 0.11238308E-01
+ 0.10695215E-01 0.10164976E-01 0.96476363E-02 0.91432431E-02 0.86518428E-02
+ 0.81734819E-02 0.77082070E-02 0.72560647E-02 0.68171014E-02 0.63913637E-02
+ 0.59788982E-02 0.55797513E-02 0.51939698E-02 0.48216000E-02 0.44626885E-02
+ 0.41172819E-02 0.37854268E-02 0.34671696E-02 0.31625569E-02 0.28716352E-02
+ 0.25944512E-02 0.23310512E-02 0.20814820E-02 0.18457900E-02 0.16240218E-02
+ 0.14162238E-02 0.12224427E-02 0.10427251E-02 0.87711733E-03 0.72566609E-03
+ 0.58841787E-03 0.46541923E-03 0.35671670E-03 0.26235684E-03 0.18238618E-03
+ 0.11685127E-03 0.65798657E-04 0.29274877E-04 0.73264764E-05 0.00000000E+00
+ 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01
+ 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01
+ 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01
+ 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01
+ 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01
+ 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01
+ 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01
+ 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01
+ 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01
+ 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01
+ 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01 0.20343409E+01
+ 0.20081530E+01 0.19820572E+01 0.19567526E+01 0.19322021E+01 0.19083707E+01
+ 0.18852256E+01 0.18627361E+01 0.18408734E+01 0.18196101E+01 0.17989208E+01
+ 0.17787813E+01 0.17591688E+01 0.17400619E+01 0.17214402E+01 0.17032846E+01
+ 0.16855768E+01 0.16682996E+01 0.16514367E+01 0.16349726E+01 0.16188925E+01
+ 0.16031824E+01 0.15878291E+01 0.15728200E+01 0.15581428E+01 0.15437863E+01
+ 0.15297394E+01 0.15159916E+01 0.15025330E+01 0.14893542E+01 0.14764459E+01
+ 0.14637996E+01 0.14514068E+01 0.14392596E+01 0.14273505E+01 0.14156720E+01
+ 0.14042172E+01 0.13929794E+01 0.13819521E+01 0.13711292E+01 0.13605047E+01
+ 0.13500728E+01 0.13398282E+01 0.13297656E+01 0.13198798E+01 0.13101660E+01
+ 0.13006194E+01 0.12912357E+01 0.12820104E+01 0.12729392E+01 0.12640182E+01
+ 0.12552435E+01 0.12466112E+01 0.12381178E+01 0.12297597E+01 0.12215336E+01
+ 0.12134361E+01 0.12054640E+01 0.11976144E+01 0.11898843E+01 0.11822708E+01
+ 0.11747711E+01 0.11673825E+01 0.11601025E+01 0.11529286E+01 0.11458582E+01
+ 0.11388891E+01 0.11320190E+01 0.11252456E+01 0.11185667E+01 0.11119804E+01
+ 0.11054846E+01 0.10990773E+01 0.10927565E+01 0.10865206E+01 0.10803676E+01
+ 0.10742959E+01 0.10683036E+01 0.10623893E+01 0.10565512E+01 0.10507878E+01
+ 0.10450977E+01 0.10394793E+01 0.10339312E+01 0.10284520E+01 0.10230403E+01
+ 0.10176949E+01 0.10124145E+01 0.10071977E+01 0.10020434E+01 0.99695043E+00
+ 0.99191758E+00 0.98694374E+00 0.98202781E+00 0.97716872E+00 0.97236543E+00
+ 0.96761692E+00 0.96292219E+00 0.95828028E+00 0.95369025E+00 0.94915117E+00
+ 0.94466214E+00 0.94022228E+00 0.93583074E+00 0.93148668E+00 0.92718928E+00
+ 0.92293774E+00 0.91873129E+00 0.91456916E+00 0.91045061E+00 0.90637490E+00
+ 0.90234134E+00 0.89834922E+00 0.89439786E+00 0.89048660E+00 0.88661478E+00
+ 0.88278179E+00 0.87898698E+00 0.87522976E+00 0.87150952E+00 0.86782569E+00
+ 0.86417770E+00 0.86056499E+00 0.85698700E+00 0.85344321E+00 0.84993310E+00
+ 0.84645615E+00 0.84301185E+00 0.83959972E+00 0.83621928E+00 0.83287005E+00
+ 0.82955156E+00 0.82626338E+00 0.82300504E+00 0.81977613E+00 0.81657620E+00
+ 0.81340484E+00 0.81026165E+00 0.80714621E+00 0.80405814E+00 0.80099705E+00
+ 0.79796255E+00 0.79495428E+00 0.79197187E+00 0.78901496E+00 0.78608320E+00
+ 0.78317624E+00 0.78029375E+00 0.77743539E+00 0.77460084E+00 0.77178978E+00
+ 0.76900189E+00 0.76623686E+00 0.76349439E+00 0.76077419E+00 0.75807595E+00
+ 0.75539939E+00 0.75274423E+00 0.75011020E+00 0.74749702E+00 0.74490441E+00
+ 0.74233213E+00 0.73977991E+00 0.73724749E+00 0.73473463E+00 0.73224108E+00
+ 0.72976660E+00 0.72731095E+00 0.72487390E+00 0.72245522E+00 0.72005469E+00
+ 0.71767208E+00 0.71530717E+00 0.71295975E+00 0.71062961E+00 0.70831654E+00
+ 0.70602034E+00 0.70374080E+00 0.70147774E+00 0.69923094E+00 0.69700023E+00
+ 0.69478541E+00 0.69258630E+00 0.69040271E+00 0.68823447E+00 0.68608140E+00
+ 0.68394333E+00 0.68182008E+00 0.67971148E+00 0.67761737E+00 0.67553759E+00
+ 0.67347197E+00 0.67142036E+00 0.66938259E+00 0.66735852E+00 0.66534799E+00
+ 0.66335086E+00 0.66136698E+00 0.65939619E+00 0.65743837E+00 0.65549336E+00
+ 0.65356103E+00 0.65164125E+00 0.64973387E+00 0.64783877E+00 0.64595581E+00
+ 0.64408487E+00 0.64222582E+00 0.64037853E+00 0.63854288E+00 0.63671875E+00
+ 0.63490602E+00 0.63310456E+00 0.63131427E+00 0.62953503E+00 0.62776672E+00
+ 0.62600923E+00 0.62426246E+00 0.62252629E+00 0.62080061E+00 0.61908533E+00
+ 0.61738033E+00 0.61568551E+00 0.61400078E+00 0.61232602E+00 0.61066114E+00
+ 0.60900605E+00 0.60736065E+00 0.60572484E+00 0.60409853E+00 0.60248162E+00
+ 0.60087403E+00 0.59927566E+00 0.59768643E+00 0.59610624E+00 0.59453502E+00
+ 0.59297267E+00 0.59141911E+00 0.58987426E+00 0.58833804E+00 0.58681036E+00
+ 0.58529114E+00 0.58378030E+00 0.58227778E+00 0.58078348E+00 0.57929733E+00
+ 0.57781926E+00 0.57634919E+00 0.57488705E+00 0.57343277E+00 0.57198627E+00
+ 0.57054749E+00 0.56911635E+00 0.56769278E+00 0.56627672E+00 0.56486810E+00
+ 0.56346686E+00 0.56207292E+00 0.56068622E+00 0.55930669E+00 0.55793428E+00
+ 0.55656893E+00 0.55521056E+00 0.55385912E+00 0.55251454E+00 0.55117677E+00
+ 0.54984575E+00 0.54852142E+00 0.54720373E+00 0.54589260E+00 0.54458800E+00
+ 0.54328985E+00 0.54199812E+00 0.54071273E+00 0.53943365E+00 0.53816081E+00
+ 0.53689416E+00 0.53563366E+00 0.53437924E+00 0.53313086E+00 0.53188847E+00
+ 0.53065202E+00 0.52942146E+00 0.52819673E+00 0.52697780E+00 0.52576461E+00
+ 0.52455712E+00 0.52335528E+00 0.52215905E+00 0.52096837E+00 0.51978321E+00
+ 0.51860352E+00 0.51742925E+00 0.51626036E+00 0.51509681E+00 0.51393856E+00
+ 0.51278556E+00 0.51163777E+00 0.51049515E+00 0.50935766E+00 0.50822526E+00
+ 0.50709791E+00 0.50597557E+00 0.50485820E+00 0.50374576E+00 0.50263821E+00
+ 0.50153552E+00 0.50043764E+00 0.49934455E+00 0.49825619E+00 0.49717255E+00
+ 0.49609357E+00 0.49501923E+00 0.49394949E+00 0.49288431E+00 0.49182366E+00
+ 0.49076751E+00 0.48971582E+00 0.48866856E+00 0.48762569E+00 0.48658719E+00
+ 0.48555301E+00 0.48452313E+00 0.48349752E+00 0.48247614E+00 0.48145896E+00
+ 0.48044595E+00 0.47943709E+00 0.47843233E+00 0.47743165E+00 0.47643503E+00
+ 0.47544242E+00 0.47445381E+00 0.47346916E+00 0.47248844E+00 0.47151163E+00
+ 0.47053869E+00 0.46956961E+00 0.46860435E+00 0.46764288E+00 0.46668518E+00
+ 0.46573122E+00 0.46478097E+00 0.46383441E+00 0.46289151E+00 0.46195225E+00
+ 0.46101661E+00 0.46008454E+00 0.45915604E+00 0.45823107E+00 0.45730961E+00
+ 0.45639164E+00 0.45547713E+00 0.45456606E+00 0.45365840E+00 0.45275413E+00
+ 0.45185324E+00 0.45095568E+00 0.45006145E+00 0.44917052E+00 0.44828286E+00
+ 0.44739846E+00 0.44651730E+00 0.44563934E+00 0.44476457E+00 0.44389297E+00
+ 0.44302451E+00 0.44215918E+00 0.44129696E+00 0.44043782E+00 0.43958174E+00
+ 0.43872870E+00 0.43787869E+00 0.43703168E+00 0.43618765E+00 0.43534659E+00
+ 0.43450847E+00 0.43367328E+00 0.43284099E+00 0.43201159E+00 0.43118505E+00
+ 0.43036136E+00 0.42954051E+00 0.42872247E+00 0.42790722E+00 0.42709475E+00
+ 0.42628504E+00 0.42547806E+00 0.42467381E+00 0.42387227E+00 0.42307342E+00
+ 0.42227724E+00 0.42148371E+00 0.42069282E+00 0.41990455E+00 0.41911889E+00
+ 0.41833581E+00 0.41755531E+00 0.41677737E+00 0.41600196E+00 0.41522908E+00
+ 0.41445871E+00 0.41369083E+00 0.41292543E+00 0.41216249E+00 0.41140200E+00
+ 0.41064394E+00 0.40988829E+00 0.40913505E+00 0.40838420E+00 0.40763572E+00
+ 0.40688960E+00 0.40614583E+00 0.40540438E+00 0.40466525E+00 0.40392842E+00
+ 0.40319388E+00 0.40246162E+00 0.40173162E+00 0.40100386E+00 0.40027834E+00
+ 0.39955504E+00 0.39883394E+00 0.39811504E+00 0.39739832E+00 0.39668377E+00
+ 0.39597138E+00 0.39526113E+00 0.39455300E+00 0.39384700E+00 0.39314310E+00
+ 0.39244130E+00 0.39174157E+00 0.39104392E+00 0.39034832E+00 0.38965476E+00
+ 0.38896324E+00 0.38827374E+00 0.38758625E+00 0.38690076E+00 0.38621725E+00
+ 0.38553572E+00 0.38485615E+00 0.38417854E+00 0.38350287E+00 0.38282912E+00
+ 0.38215730E+00 0.38148739E+00 0.38081937E+00 0.38015324E+00 0.37948899E+00
+ 0.37882660E+00 0.37816607E+00 0.37750739E+00 0.37685054E+00 0.37619551E+00
+ 0.37554230E+00 0.37489090E+00 0.37424128E+00 0.37359346E+00 0.37294740E+00
+ 0.37230312E+00 0.37166058E+00 0.37101980E+00 0.37038075E+00 0.36974342E+00
+ 0.36910781E+00 0.36847391E+00 0.36784171E+00 0.36721120E+00 0.36658237E+00
+ 0.36595521E+00 0.36532971E+00 0.36470587E+00 0.36408367E+00 0.36346310E+00
+ 0.36284416E+00 0.36222684E+00 0.36161113E+00 0.36099702E+00 0.36038450E+00
+ 0.35977357E+00 0.35916421E+00 0.35855642E+00 0.35795019E+00 0.35734550E+00
+ 0.35674237E+00 0.35614076E+00 0.35554068E+00 0.35494212E+00 0.35434507E+00
+ 0.35374953E+00 0.35315548E+00 0.35256291E+00 0.35197183E+00 0.35138221E+00
+ 0.35079407E+00 0.35020738E+00 0.34962213E+00 0.34903833E+00 0.34845597E+00
+ 0.34787503E+00 0.34729551E+00 0.34671740E+00 0.34614070E+00 0.34556540E+00
+ 0.34499149E+00 0.34441896E+00 0.34384781E+00 0.34327804E+00 0.34270962E+00
+ 0.34214256E+00 0.34157686E+00 0.34101249E+00 0.34044946E+00 0.33988776E+00
+ 0.33932739E+00 0.33876833E+00 0.33821058E+00 0.33765414E+00 0.33709899E+00
+ 0.33654514E+00 0.33599257E+00 0.33544127E+00 0.33489125E+00 0.33434250E+00
+ 0.33379500E+00 0.33324876E+00 0.33270377E+00 0.33216002E+00 0.33161750E+00
+ 0.33107621E+00 0.33053615E+00 0.32999731E+00 0.32945967E+00 0.32892325E+00
+ 0.32838802E+00 0.32785399E+00 0.32732115E+00 0.32678949E+00 0.32625901E+00
+ 0.32572970E+00 0.32520155E+00 0.32467457E+00 0.32414875E+00 0.32362407E+00
+ 0.32310054E+00 0.32257815E+00 0.32205689E+00 0.32153677E+00 0.32101776E+00
+ 0.32049988E+00 0.31998311E+00 0.31946744E+00 0.31895288E+00 0.31843942E+00
+ 0.31792705E+00 0.31741577E+00 0.31690557E+00 0.31639645E+00 0.31588840E+00
+ 0.31538142E+00 0.31487550E+00 0.31437064E+00 0.31386684E+00 0.31336408E+00
+ 0.31286237E+00 0.31236170E+00 0.31186206E+00 0.31136346E+00 0.31086588E+00
+ 0.31036932E+00 0.30987377E+00 0.30937924E+00 0.30888572E+00 0.30839320E+00
+ 0.30790168E+00 0.30741115E+00 0.30692161E+00 0.30643306E+00 0.30594548E+00
+ 0.30545889E+00 0.30497327E+00 0.30448861E+00 0.30400492E+00 0.30352219E+00
+ 0.30304042E+00 0.30255959E+00 0.30207972E+00 0.30160079E+00 0.30112279E+00
+ 0.30064574E+00 0.30016961E+00 0.29969441E+00 0.29922014E+00 0.29874678E+00
+ 0.29827434E+00 0.29780281E+00 0.29733219E+00 0.29686247E+00 0.29639366E+00
+ 0.29592574E+00 0.29545871E+00 0.29499257E+00 0.29452731E+00 0.29406294E+00
+ 0.29359945E+00 0.29313683E+00 0.29267508E+00 0.29221419E+00 0.29175417E+00
+ 0.29129501E+00 0.29083671E+00 0.29037925E+00 0.28992265E+00 0.28946689E+00
+ 0.28901198E+00 0.28855790E+00 0.28810466E+00 0.28765225E+00 0.28720067E+00
+ 0.28674992E+00 0.28629998E+00 0.28585087E+00 0.28540257E+00 0.28495508E+00
+ 0.28450841E+00 0.28406253E+00 0.28361746E+00 0.28317319E+00 0.28272972E+00
+ 0.28228703E+00 0.28184514E+00 0.28140404E+00 0.28096371E+00 0.28052417E+00
+ 0.28008541E+00 0.27964742E+00 0.27921020E+00 0.27877375E+00 0.27833806E+00
+ 0.27790314E+00 0.27746898E+00 0.27703557E+00 0.27660291E+00 0.27617101E+00
+ 0.27573986E+00 0.27530945E+00 0.27487978E+00 0.27445085E+00 0.27402266E+00
+ 0.27359520E+00 0.27316847E+00 0.27274247E+00 0.27231719E+00 0.27189264E+00
+ 0.27146881E+00 0.27104570E+00 0.27062330E+00 0.27020161E+00 0.26978063E+00
+ 0.26936036E+00 0.26894079E+00 0.26852192E+00 0.26810375E+00 0.26768628E+00
+ 0.26726950E+00 0.26685341E+00 0.26643801E+00 0.26602330E+00 0.26560927E+00
+ 0.26519592E+00 0.26478325E+00 0.26437126E+00 0.26395994E+00 0.26354929E+00
+ 0.26313931E+00 0.26273000E+00 0.26232135E+00 0.26191336E+00 0.26150603E+00
+ 0.26109936E+00 0.26069334E+00 0.26028798E+00 0.25988327E+00 0.25947920E+00
+ 0.25907578E+00 0.25867300E+00 0.25827087E+00 0.25786937E+00 0.25746851E+00
+ 0.25706828E+00 0.25666869E+00 0.25626972E+00 0.25587139E+00 0.25547367E+00
+ 0.25507659E+00 0.25468012E+00 0.25428427E+00 0.25388904E+00 0.25349443E+00
+ 0.25310043E+00 0.25270704E+00 0.25231425E+00 0.25192208E+00 0.25153051E+00
+ 0.25113954E+00 0.25074917E+00 0.25035941E+00 0.24997023E+00 0.24958166E+00
+ 0.24919367E+00 0.24880628E+00 0.24841947E+00 0.24803326E+00 0.24764762E+00
+ 0.24726258E+00 0.24687811E+00 0.24649422E+00 0.24611091E+00 0.24572817E+00
+ 0.24534601E+00 0.24496442E+00 0.24458340E+00 0.24420295E+00 0.24382306E+00
+ 0.24344374E+00 0.24306498E+00 0.24268678E+00 0.24230914E+00 0.24193206E+00
+ 0.24155554E+00 0.24117957E+00 0.24080415E+00 0.24042928E+00 0.24005496E+00
+ 0.23968119E+00 0.23930796E+00 0.23893528E+00 0.23856314E+00 0.23819154E+00
+ 0.23782047E+00 0.23744995E+00 0.23707996E+00 0.23671050E+00 0.23634158E+00
+ 0.23597319E+00 0.23560532E+00 0.23523799E+00 0.23487118E+00 0.23450489E+00
+ 0.23413912E+00 0.23377388E+00 0.23340916E+00 0.23304495E+00 0.23268126E+00
+ 0.23231809E+00 0.23195543E+00 0.23159328E+00 0.23123164E+00 0.23087051E+00
+ 0.23050989E+00 0.23014978E+00 0.22979016E+00 0.22943106E+00 0.22907245E+00
+ 0.22871434E+00 0.22835674E+00 0.22799963E+00 0.22764301E+00 0.22728689E+00
+ 0.22693127E+00 0.22657613E+00 0.22622149E+00 0.22586733E+00 0.22551367E+00
+ 0.22516048E+00 0.22480779E+00 0.22445558E+00 0.22410385E+00 0.22375260E+00
+ 0.22340183E+00 0.22305153E+00 0.22270172E+00 0.22235238E+00 0.22200352E+00
+ 0.22165512E+00 0.22130721E+00 0.22095976E+00 0.22061278E+00 0.22026627E+00
+ 0.21992022E+00 0.21957464E+00 0.21922953E+00 0.21888487E+00 0.21854068E+00
+ 0.21819696E+00 0.21785369E+00 0.21751087E+00 0.21716852E+00 0.21682662E+00
+ 0.21648518E+00 0.21614419E+00 0.21580365E+00 0.21546356E+00 0.21512392E+00
+ 0.21478474E+00 0.21444600E+00 0.21410770E+00 0.21376986E+00 0.21343245E+00
+ 0.21309549E+00 0.21275897E+00 0.21242290E+00 0.21208726E+00 0.21175206E+00
+ 0.21141730E+00 0.21108298E+00 0.21074909E+00 0.21041564E+00 0.21008262E+00
+ 0.20975003E+00 0.20941787E+00 0.20908615E+00 0.20875485E+00 0.20842398E+00
+ 0.20809354E+00 0.20776353E+00 0.20743394E+00 0.20710477E+00 0.20677603E+00
+ 0.20644771E+00 0.20611981E+00 0.20579233E+00 0.20546527E+00 0.20513863E+00
+ 0.20481241E+00 0.20448660E+00 0.20416121E+00 0.20383623E+00 0.20351167E+00
+ 0.20318752E+00 0.20286378E+00 0.20254045E+00 0.20221753E+00 0.20189502E+00
+ 0.20157292E+00 0.20125122E+00 0.20092993E+00 0.20060905E+00 0.20028857E+00
+ 0.19996849E+00 0.19964882E+00 0.19932955E+00 0.19901068E+00 0.19869221E+00
+ 0.19837413E+00 0.19805646E+00 0.19773918E+00 0.19742230E+00 0.19710582E+00
+ 0.19678973E+00 0.19647403E+00 0.19615873E+00 0.19584382E+00 0.19552930E+00
+ 0.19521517E+00 0.19490143E+00 0.19458808E+00 0.19427512E+00 0.19396255E+00
+ 0.19365036E+00 0.19333856E+00 0.19302714E+00 0.19271611E+00 0.19240546E+00
+ 0.19209520E+00 0.19178531E+00 0.19147581E+00 0.19116669E+00 0.19085794E+00
+ 0.19054958E+00 0.19024159E+00 0.18993399E+00 0.18962675E+00 0.18931990E+00
+ 0.18901342E+00 0.18870731E+00 0.18840158E+00 0.18809622E+00 0.18779123E+00
+ 0.18748662E+00 0.18718237E+00 0.18687850E+00 0.18657499E+00 0.18627186E+00
+ 0.18596909E+00 0.18566669E+00 0.18536466E+00 0.18506299E+00 0.18476168E+00
+ 0.18446075E+00 0.18416017E+00 0.18385996E+00 0.18356012E+00 0.18326063E+00
+ 0.18296151E+00 0.18266274E+00 0.18236434E+00 0.18206630E+00 0.18176861E+00
+ 0.18147128E+00 0.18117431E+00 0.18087770E+00 0.18058145E+00 0.18028554E+00
+ 0.17999000E+00 0.17969481E+00 0.17939997E+00 0.17910549E+00 0.17881136E+00
+ 0.17851758E+00 0.17822415E+00 0.17793107E+00 0.17763834E+00 0.17734597E+00
+ 0.17705394E+00 0.17676226E+00 0.17647093E+00 0.17617994E+00 0.17588930E+00
+ 0.17559901E+00 0.17530907E+00 0.17501947E+00 0.17473021E+00 0.17444130E+00
+ 0.17415273E+00 0.17386450E+00 0.17357662E+00 0.17328908E+00 0.17300187E+00
+ 0.17271501E+00 0.17242849E+00 0.17214231E+00 0.17185647E+00 0.17157097E+00
+ 0.17128580E+00 0.17100098E+00 0.17071649E+00 0.17043233E+00 0.17014851E+00
+ 0.16986503E+00 0.16958188E+00 0.16929907E+00 0.16901659E+00 0.16873444E+00
+ 0.16845263E+00 0.16817115E+00 0.16789000E+00 0.16760919E+00 0.16732870E+00
+ 0.16704854E+00 0.16676872E+00 0.16648922E+00 0.16621006E+00 0.16593122E+00
+ 0.16565271E+00 0.16537453E+00 0.16509667E+00 0.16481914E+00 0.16454194E+00
+ 0.16426507E+00 0.16398852E+00 0.16371229E+00 0.16343639E+00 0.16316081E+00
+ 0.16288556E+00 0.16261063E+00 0.16233602E+00 0.16206174E+00 0.16178778E+00
+ 0.16151413E+00 0.16124081E+00 0.16096781E+00 0.16069513E+00 0.16042278E+00
+ 0.16015073E+00 0.15987901E+00 0.15960761E+00 0.15933653E+00 0.15906576E+00
+ 0.15879531E+00 0.15852518E+00 0.15825536E+00 0.15798586E+00 0.15771668E+00
+ 0.15744781E+00 0.15717925E+00 0.15691101E+00 0.15664309E+00 0.15637548E+00
+ 0.15610818E+00 0.15584119E+00 0.15557452E+00 0.15530816E+00 0.15504211E+00
+ 0.15477637E+00 0.15451095E+00 0.15424583E+00 0.15398103E+00 0.15371653E+00
+ 0.15345235E+00 0.15318847E+00 0.15292490E+00 0.15266165E+00 0.15239870E+00
+ 0.15213605E+00 0.15187372E+00 0.15161169E+00 0.15134997E+00 0.15108856E+00
+ 0.15082745E+00 0.15056665E+00 0.15030615E+00 0.15004596E+00 0.14978607E+00
+ 0.14952649E+00 0.14926721E+00 0.14900823E+00 0.14874956E+00 0.14849120E+00
+ 0.14823313E+00 0.14797537E+00 0.14771791E+00 0.14746075E+00 0.14720389E+00
+ 0.14694734E+00 0.14669108E+00 0.14643513E+00 0.14617947E+00 0.14592412E+00
+ 0.14566906E+00 0.14541431E+00 0.14515985E+00 0.14490569E+00 0.14465184E+00
+ 0.14439828E+00 0.14414501E+00 0.14389205E+00 0.14363938E+00 0.14338701E+00
+ 0.14313493E+00 0.14288315E+00 0.14263167E+00 0.14238049E+00 0.14212960E+00
+ 0.14187900E+00 0.14162870E+00 0.14137869E+00 0.14112898E+00 0.14087957E+00
+ 0.14063044E+00 0.14038161E+00 0.14013308E+00 0.13988483E+00 0.13963688E+00
+ 0.13938922E+00 0.13914186E+00 0.13889478E+00 0.13864800E+00 0.13840151E+00
+ 0.13815531E+00 0.13790940E+00 0.13766378E+00 0.13741845E+00 0.13717342E+00
+ 0.13692867E+00 0.13668421E+00 0.13644004E+00 0.13619616E+00 0.13595257E+00
+ 0.13570927E+00 0.13546625E+00 0.13522353E+00 0.13498109E+00 0.13473894E+00
+ 0.13449708E+00 0.13425550E+00 0.13401421E+00 0.13377321E+00 0.13353249E+00
+ 0.13329206E+00 0.13305192E+00 0.13281206E+00 0.13257249E+00 0.13233320E+00
+ 0.13209420E+00 0.13185548E+00 0.13161705E+00 0.13137890E+00 0.13114104E+00
+ 0.13090346E+00 0.13066616E+00 0.13042915E+00 0.13019242E+00 0.12995597E+00
+ 0.12971981E+00 0.12948393E+00 0.12924833E+00 0.12901301E+00 0.12877798E+00
+ 0.12854322E+00 0.12830875E+00 0.12807456E+00 0.12784065E+00 0.12760702E+00
+ 0.12737368E+00 0.12714061E+00 0.12690782E+00 0.12667532E+00 0.12644309E+00
+ 0.12621114E+00 0.12597947E+00 0.12574808E+00 0.12551698E+00 0.12528614E+00
+ 0.12505559E+00 0.12482532E+00 0.12459532E+00 0.12436561E+00 0.12413617E+00
+ 0.12390701E+00 0.12367812E+00 0.12344951E+00 0.12322118E+00 0.12299313E+00
+ 0.12276536E+00 0.12253786E+00 0.12231063E+00 0.12208369E+00 0.12185701E+00
+ 0.12163062E+00 0.12140450E+00 0.12117865E+00 0.12095309E+00 0.12072779E+00
+ 0.12050277E+00 0.12027803E+00 0.12005356E+00 0.11982936E+00 0.11960544E+00
+ 0.11938179E+00 0.11915842E+00 0.11893532E+00 0.11871249E+00 0.11848994E+00
+ 0.11826766E+00 0.11804565E+00 0.11782392E+00 0.11760246E+00 0.11738127E+00
+ 0.11716035E+00 0.11693971E+00 0.11671933E+00 0.11649923E+00 0.11627940E+00
+ 0.11605984E+00 0.11584056E+00 0.11562154E+00 0.11540280E+00 0.11518432E+00
+ 0.11496612E+00 0.11474819E+00 0.11453052E+00 0.11431313E+00 0.11409601E+00
+ 0.11387915E+00 0.11366257E+00 0.11344626E+00 0.11323021E+00 0.11301444E+00
+ 0.11279893E+00 0.11258369E+00 0.11236872E+00 0.11215402E+00 0.11193959E+00
+ 0.11172543E+00 0.11151153E+00 0.11129790E+00 0.11108454E+00 0.11087145E+00
+ 0.11065863E+00 0.11044607E+00 0.11023378E+00 0.11002176E+00 0.10981000E+00
+ 0.10959851E+00 0.10938729E+00 0.10917633E+00 0.10896564E+00 0.10875522E+00
+ 0.10854506E+00 0.10833517E+00 0.10812554E+00 0.10791618E+00 0.10770708E+00
+ 0.10749825E+00 0.10728969E+00 0.10708139E+00 0.10687335E+00 0.10666558E+00
+ 0.10645808E+00 0.10625084E+00 0.10604386E+00 0.10583715E+00 0.10563070E+00
+ 0.10542451E+00 0.10521859E+00 0.10501293E+00 0.10480754E+00 0.10460241E+00
+ 0.10439754E+00 0.10419293E+00 0.10398859E+00 0.10378451E+00 0.10358070E+00
+ 0.10337714E+00 0.10317385E+00 0.10297082E+00 0.10276805E+00 0.10256555E+00
+ 0.10236330E+00 0.10216132E+00 0.10195960E+00 0.10175814E+00 0.10155695E+00
+ 0.10135601E+00 0.10115533E+00 0.10095492E+00 0.10075477E+00 0.10055487E+00
+ 0.10035524E+00 0.10015587E+00 0.99956756E-01 0.99757905E-01 0.99559313E-01
+ 0.99360981E-01 0.99162909E-01 0.98965097E-01 0.98767544E-01 0.98570250E-01
+ 0.98373216E-01 0.98176441E-01 0.97979924E-01 0.97783667E-01 0.97587668E-01
+ 0.97391928E-01 0.97196447E-01 0.97001223E-01 0.96806258E-01 0.96611551E-01
+ 0.96417102E-01 0.96222911E-01 0.96028978E-01 0.95835302E-01 0.95641884E-01
+ 0.95448723E-01 0.95255819E-01 0.95063173E-01 0.94870783E-01 0.94678651E-01
+ 0.94486775E-01 0.94295155E-01 0.94103792E-01 0.93912686E-01 0.93721836E-01
+ 0.93531241E-01 0.93340903E-01 0.93150821E-01 0.92960995E-01 0.92771424E-01
+ 0.92582108E-01 0.92393048E-01 0.92204244E-01 0.92015694E-01 0.91827400E-01
+ 0.91639360E-01 0.91451576E-01 0.91264046E-01 0.91076770E-01 0.90889749E-01
+ 0.90702982E-01 0.90516470E-01 0.90330211E-01 0.90144207E-01 0.89958456E-01
+ 0.89772959E-01 0.89587716E-01 0.89402726E-01 0.89217989E-01 0.89033506E-01
+ 0.88849276E-01 0.88665298E-01 0.88481574E-01 0.88298103E-01 0.88114884E-01
+ 0.87931917E-01 0.87749203E-01 0.87566742E-01 0.87384532E-01 0.87202575E-01
+ 0.87020869E-01 0.86839415E-01 0.86658213E-01 0.86477263E-01 0.86296564E-01
+ 0.86116116E-01 0.85935920E-01 0.85755975E-01 0.85576280E-01 0.85396837E-01
+ 0.85217644E-01 0.85038702E-01 0.84860011E-01 0.84681570E-01 0.84503379E-01
+ 0.84325438E-01 0.84147748E-01 0.83970307E-01 0.83793116E-01 0.83616175E-01
+ 0.83439483E-01 0.83263041E-01 0.83086848E-01 0.82910904E-01 0.82735210E-01
+ 0.82559764E-01 0.82384568E-01 0.82209620E-01 0.82034920E-01 0.81860470E-01
+ 0.81686267E-01 0.81512313E-01 0.81338607E-01 0.81165149E-01 0.80991939E-01
+ 0.80818977E-01 0.80646262E-01 0.80473795E-01 0.80301576E-01 0.80129604E-01
+ 0.79957879E-01 0.79786401E-01 0.79615170E-01 0.79444186E-01 0.79273448E-01
+ 0.79102958E-01 0.78932713E-01 0.78762716E-01 0.78592964E-01 0.78423459E-01
+ 0.78254199E-01 0.78085186E-01 0.77916418E-01 0.77747896E-01 0.77579619E-01
+ 0.77411588E-01 0.77243802E-01 0.77076261E-01 0.76908966E-01 0.76741915E-01
+ 0.76575109E-01 0.76408548E-01 0.76242231E-01 0.76076159E-01 0.75910332E-01
+ 0.75744748E-01 0.75579409E-01 0.75414313E-01 0.75249461E-01 0.75084853E-01
+ 0.74920489E-01 0.74756368E-01 0.74592491E-01 0.74428857E-01 0.74265466E-01
+ 0.74102318E-01 0.73939412E-01 0.73776750E-01 0.73614330E-01 0.73452153E-01
+ 0.73290218E-01 0.73128525E-01 0.72967075E-01 0.72805866E-01 0.72644900E-01
+ 0.72484175E-01 0.72323692E-01 0.72163450E-01 0.72003450E-01 0.71843691E-01
+ 0.71684173E-01 0.71524896E-01 0.71365861E-01 0.71207066E-01 0.71048511E-01
+ 0.70890197E-01 0.70732124E-01 0.70574291E-01 0.70416697E-01 0.70259344E-01
+ 0.70102231E-01 0.69945358E-01 0.69788724E-01 0.69632330E-01 0.69476175E-01
+ 0.69320260E-01 0.69164583E-01 0.69009146E-01 0.68853948E-01 0.68698988E-01
+ 0.68544267E-01 0.68389784E-01 0.68235540E-01 0.68081534E-01 0.67927766E-01
+ 0.67774237E-01 0.67620945E-01 0.67467890E-01 0.67315074E-01 0.67162495E-01
+ 0.67010153E-01 0.66858048E-01 0.66706181E-01 0.66554550E-01 0.66403156E-01
+ 0.66251999E-01 0.66101079E-01 0.65950395E-01 0.65799947E-01 0.65649735E-01
+ 0.65499760E-01 0.65350020E-01 0.65200516E-01 0.65051248E-01 0.64902215E-01
+ 0.64753418E-01 0.64604856E-01 0.64456529E-01 0.64308437E-01 0.64160580E-01
+ 0.64012957E-01 0.63865569E-01 0.63718416E-01 0.63571496E-01 0.63424811E-01
+ 0.63278360E-01 0.63132143E-01 0.62986160E-01 0.62840410E-01 0.62694894E-01
+ 0.62549611E-01 0.62404561E-01 0.62259745E-01 0.62115161E-01 0.61970810E-01
+ 0.61826692E-01 0.61682806E-01 0.61539153E-01 0.61395732E-01 0.61252543E-01
+ 0.61109586E-01 0.60966861E-01 0.60824368E-01 0.60682106E-01 0.60540075E-01
+ 0.60398276E-01 0.60256708E-01 0.60115371E-01 0.59974265E-01 0.59833389E-01
+ 0.59692744E-01 0.59552330E-01 0.59412146E-01 0.59272192E-01 0.59132467E-01
+ 0.58992973E-01 0.58853709E-01 0.58714674E-01 0.58575868E-01 0.58437292E-01
+ 0.58298945E-01 0.58160827E-01 0.58022937E-01 0.57885277E-01 0.57747845E-01
+ 0.57610641E-01 0.57473666E-01 0.57336919E-01 0.57200400E-01 0.57064108E-01
+ 0.56928045E-01 0.56792208E-01 0.56656600E-01 0.56521218E-01 0.56386064E-01
+ 0.56251136E-01 0.56116435E-01 0.55981961E-01 0.55847714E-01 0.55713693E-01
+ 0.55579898E-01 0.55446329E-01 0.55312986E-01 0.55179868E-01 0.55046977E-01
+ 0.54914310E-01 0.54781869E-01 0.54649653E-01 0.54517663E-01 0.54385897E-01
+ 0.54254355E-01 0.54123039E-01 0.53991946E-01 0.53861078E-01 0.53730434E-01
+ 0.53600014E-01 0.53469817E-01 0.53339845E-01 0.53210095E-01 0.53080569E-01
+ 0.52951266E-01 0.52822186E-01 0.52693329E-01 0.52564695E-01 0.52436283E-01
+ 0.52308094E-01 0.52180126E-01 0.52052381E-01 0.51924858E-01 0.51797556E-01
+ 0.51670476E-01 0.51543618E-01 0.51416980E-01 0.51290564E-01 0.51164369E-01
+ 0.51038394E-01 0.50912641E-01 0.50787107E-01 0.50661794E-01 0.50536701E-01
+ 0.50411828E-01 0.50287175E-01 0.50162742E-01 0.50038528E-01 0.49914533E-01
+ 0.49790758E-01 0.49667201E-01 0.49543863E-01 0.49420745E-01 0.49297844E-01
+ 0.49175162E-01 0.49052698E-01 0.48930452E-01 0.48808424E-01 0.48686614E-01
+ 0.48565021E-01 0.48443629E-01 0.48321805E-01 0.48199239E-01 0.48075934E-01
+ 0.47951898E-01 0.47827135E-01 0.47701651E-01 0.47575452E-01 0.47448544E-01
+ 0.47320932E-01 0.47192622E-01 0.47063620E-01 0.46933930E-01 0.46803560E-01
+ 0.46672514E-01 0.46540799E-01 0.46408419E-01 0.46275381E-01 0.46141690E-01
+ 0.46007352E-01 0.45872372E-01 0.45736757E-01 0.45600511E-01 0.45463641E-01
+ 0.45326153E-01 0.45188051E-01 0.45049341E-01 0.44910030E-01 0.44770123E-01
+ 0.44629625E-01 0.44488542E-01 0.44346880E-01 0.44204645E-01 0.44061842E-01
+ 0.43918476E-01 0.43774554E-01 0.43630081E-01 0.43485063E-01 0.43339506E-01
+ 0.43193415E-01 0.43046795E-01 0.42899653E-01 0.42751994E-01 0.42603824E-01
+ 0.42455148E-01 0.42305972E-01 0.42156303E-01 0.42006144E-01 0.41855503E-01
+ 0.41704384E-01 0.41552794E-01 0.41400738E-01 0.41248222E-01 0.41095251E-01
+ 0.40941832E-01 0.40787969E-01 0.40633668E-01 0.40478936E-01 0.40323777E-01
+ 0.40168198E-01 0.40012203E-01 0.39855800E-01 0.39698993E-01 0.39541788E-01
+ 0.39384190E-01 0.39226206E-01 0.39067841E-01 0.38909101E-01 0.38749991E-01
+ 0.38590518E-01 0.38430685E-01 0.38270501E-01 0.38109969E-01 0.37949096E-01
+ 0.37787887E-01 0.37626349E-01 0.37464486E-01 0.37302304E-01 0.37139809E-01
+ 0.36977007E-01 0.36813904E-01 0.36650504E-01 0.36486814E-01 0.36322839E-01
+ 0.36158586E-01 0.35994059E-01 0.35829264E-01 0.35664207E-01 0.35498894E-01
+ 0.35333330E-01 0.35167522E-01 0.35001473E-01 0.34835192E-01 0.34668682E-01
+ 0.34501949E-01 0.34335000E-01 0.34167840E-01 0.34000475E-01 0.33832909E-01
+ 0.33665150E-01 0.33497202E-01 0.33329072E-01 0.33160764E-01 0.32992286E-01
+ 0.32823641E-01 0.32654836E-01 0.32485877E-01 0.32316769E-01 0.32147518E-01
+ 0.31978130E-01 0.31808609E-01 0.31638963E-01 0.31469196E-01 0.31299315E-01
+ 0.31129324E-01 0.30959230E-01 0.30789038E-01 0.30618754E-01 0.30448384E-01
+ 0.30277932E-01 0.30107406E-01 0.29936810E-01 0.29766150E-01 0.29595432E-01
+ 0.29424662E-01 0.29253845E-01 0.29082987E-01 0.28912093E-01 0.28741169E-01
+ 0.28570221E-01 0.28399255E-01 0.28228276E-01 0.28057290E-01 0.27886302E-01
+ 0.27715318E-01 0.27544344E-01 0.27373386E-01 0.27202449E-01 0.27031538E-01
+ 0.26860660E-01 0.26689820E-01 0.26519024E-01 0.26348278E-01 0.26177586E-01
+ 0.26006956E-01 0.25836391E-01 0.25665899E-01 0.25495485E-01 0.25325154E-01
+ 0.25154912E-01 0.24984765E-01 0.24814718E-01 0.24644778E-01 0.24474949E-01
+ 0.24305238E-01 0.24135650E-01 0.23966190E-01 0.23796865E-01 0.23627680E-01
+ 0.23458640E-01 0.23289752E-01 0.23121022E-01 0.22952453E-01 0.22784054E-01
+ 0.22615828E-01 0.22447782E-01 0.22279921E-01 0.22112252E-01 0.21944779E-01
+ 0.21777508E-01 0.21610446E-01 0.21443597E-01 0.21276968E-01 0.21110563E-01
+ 0.20944389E-01 0.20778452E-01 0.20612757E-01 0.20447309E-01 0.20282115E-01
+ 0.20117179E-01 0.19952509E-01 0.19788108E-01 0.19623984E-01 0.19460141E-01
+ 0.19296586E-01 0.19133323E-01 0.18970359E-01 0.18807700E-01 0.18645350E-01
+ 0.18483316E-01 0.18321604E-01 0.18160218E-01 0.17999165E-01 0.17838450E-01
+ 0.17678080E-01 0.17518058E-01 0.17358392E-01 0.17199087E-01 0.17040149E-01
+ 0.16881583E-01 0.16723395E-01 0.16565590E-01 0.16408175E-01 0.16251155E-01
+ 0.16094535E-01 0.15938321E-01 0.15782519E-01 0.15627135E-01 0.15472175E-01
+ 0.15317643E-01 0.15163545E-01 0.15009888E-01 0.14856677E-01 0.14703917E-01
+ 0.14551614E-01 0.14399775E-01 0.14248404E-01 0.14097507E-01 0.13947090E-01
+ 0.13797158E-01 0.13647718E-01 0.13498774E-01 0.13350334E-01 0.13202401E-01
+ 0.13054982E-01 0.12908082E-01 0.12761708E-01 0.12615865E-01 0.12470558E-01
+ 0.12325793E-01 0.12181576E-01 0.12037913E-01 0.11894809E-01 0.11752269E-01
+ 0.11610300E-01 0.11468908E-01 0.11328097E-01 0.11187873E-01 0.11048243E-01
+ 0.10909211E-01 0.10770784E-01 0.10632967E-01 0.10495766E-01 0.10359186E-01
+ 0.10223233E-01 0.10087914E-01 0.99532321E-02 0.98191948E-02 0.96858072E-02
+ 0.95530751E-02 0.94210040E-02 0.92895998E-02 0.91588679E-02 0.90288141E-02
+ 0.88994441E-02 0.87707635E-02 0.86427779E-02 0.85154931E-02 0.83889147E-02
+ 0.82630483E-02 0.81378997E-02 0.80134745E-02 0.78897783E-02 0.77668168E-02
+ 0.76445957E-02 0.75231207E-02 0.74023973E-02 0.72824314E-02 0.71632284E-02
+ 0.70447942E-02 0.69271343E-02 0.68102545E-02 0.66941603E-02 0.65788575E-02
+ 0.64643517E-02 0.63506485E-02 0.62377537E-02 0.61256729E-02 0.60144118E-02
+ 0.59039760E-02 0.57943712E-02 0.56856031E-02 0.55776772E-02 0.54705994E-02
+ 0.53643752E-02 0.52590103E-02 0.51545104E-02 0.50508811E-02 0.49481281E-02
+ 0.48462571E-02 0.47452737E-02 0.46451836E-02 0.45459924E-02 0.44477059E-02
+ 0.43503296E-02 0.42538693E-02 0.41583306E-02 0.40637191E-02 0.39700406E-02
+ 0.38773007E-02 0.37855050E-02 0.36946593E-02 0.36047691E-02 0.35158402E-02
+ 0.34278782E-02 0.33408888E-02 0.32548776E-02 0.31698503E-02 0.30858126E-02
+ 0.30027701E-02 0.29207285E-02 0.28396935E-02 0.27596707E-02 0.26806657E-02
+ 0.26026843E-02 0.25257321E-02 0.24498148E-02 0.23749380E-02 0.23011074E-02
+ 0.22283287E-02 0.21566075E-02 0.20859495E-02 0.20163603E-02 0.19478457E-02
+ 0.18804112E-02 0.18140626E-02 0.17488054E-02 0.16846455E-02 0.16215884E-02
+ 0.15596397E-02 0.14988052E-02 0.14390906E-02 0.13805014E-02 0.13230434E-02
+ 0.12667222E-02 0.12115434E-02 0.11575128E-02 0.11046360E-02 0.10529187E-02
+ 0.10023665E-02 0.95298504E-03 0.90478007E-03 0.85775722E-03 0.81192215E-03
+ 0.76728052E-03 0.72383800E-03 0.68160024E-03 0.64057293E-03 0.60076170E-03
+ 0.56217224E-03 0.52481020E-03 0.48868125E-03 0.45379105E-03 0.42014526E-03
+ 0.38774955E-03 0.35660958E-03 0.32673101E-03 0.29811951E-03 0.27078073E-03
+ 0.24472035E-03 0.21994403E-03 0.19645743E-03 0.17426621E-03 0.15337603E-03
+ 0.13379257E-03 0.11552147E-03 0.98568418E-04 0.82939061E-04 0.68639067E-04
+ 0.55674099E-04 0.44049820E-04 0.33771894E-04 0.24845983E-04 0.17277752E-04
+ 0.11072863E-04 0.62369807E-05 0.27757669E-05 0.69488562E-06 0.00000000E+00
+ 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02
+ 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02
+ 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02
+ 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02
+ 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02
+ 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02
+ 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02
+ 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02
+ 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02
+ 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02
+ 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02 0.13068872E+02
+ 0.13032684E+02 0.12880121E+02 0.12731991E+02 0.12588091E+02 0.12448230E+02
+ 0.12312228E+02 0.12179917E+02 0.12051139E+02 0.11925744E+02 0.11803592E+02
+ 0.11684550E+02 0.11568493E+02 0.11455301E+02 0.11344864E+02 0.11237074E+02
+ 0.11131830E+02 0.11029039E+02 0.10928608E+02 0.10830452E+02 0.10734489E+02
+ 0.10640641E+02 0.10548834E+02 0.10458997E+02 0.10371064E+02 0.10284971E+02
+ 0.10200655E+02 0.10118059E+02 0.10037126E+02 0.99578044E+01 0.98800419E+01
+ 0.98037899E+01 0.97290018E+01 0.96556328E+01 0.95836400E+01 0.95129821E+01
+ 0.94436197E+01 0.93755150E+01 0.93086315E+01 0.92429343E+01 0.91783898E+01
+ 0.91149657E+01 0.90526309E+01 0.89913556E+01 0.89311109E+01 0.88718691E+01
+ 0.88136037E+01 0.87562887E+01 0.86998994E+01 0.86444119E+01 0.85898031E+01
+ 0.85360507E+01 0.84831332E+01 0.84310298E+01 0.83797204E+01 0.83291857E+01
+ 0.82794069E+01 0.82303659E+01 0.81820450E+01 0.81344274E+01 0.80874966E+01
+ 0.80412367E+01 0.79956323E+01 0.79506685E+01 0.79063308E+01 0.78626051E+01
+ 0.78194780E+01 0.77769362E+01 0.77349669E+01 0.76935578E+01 0.76526968E+01
+ 0.76123721E+01 0.75725726E+01 0.75332871E+01 0.74945049E+01 0.74562157E+01
+ 0.74184093E+01 0.73810759E+01 0.73442060E+01 0.73077903E+01 0.72718196E+01
+ 0.72362854E+01 0.72011788E+01 0.71664918E+01 0.71322161E+01 0.70983438E+01
+ 0.70648673E+01 0.70317791E+01 0.69990719E+01 0.69667386E+01 0.69347722E+01
+ 0.69031660E+01 0.68719134E+01 0.68410080E+01 0.68104435E+01 0.67802139E+01
+ 0.67503131E+01 0.67207354E+01 0.66914751E+01 0.66625265E+01 0.66338845E+01
+ 0.66055435E+01 0.65774986E+01 0.65497447E+01 0.65222767E+01 0.64950900E+01
+ 0.64681799E+01 0.64415417E+01 0.64151710E+01 0.63890633E+01 0.63632144E+01
+ 0.63376202E+01 0.63122764E+01 0.62871791E+01 0.62623244E+01 0.62377085E+01
+ 0.62133275E+01 0.61891777E+01 0.61652557E+01 0.61415579E+01 0.61180808E+01
+ 0.60948211E+01 0.60717754E+01 0.60489406E+01 0.60263134E+01 0.60038907E+01
+ 0.59816696E+01 0.59596469E+01 0.59378199E+01 0.59161856E+01 0.58947412E+01
+ 0.58734841E+01 0.58524114E+01 0.58315205E+01 0.58108089E+01 0.57902740E+01
+ 0.57699134E+01 0.57497245E+01 0.57297050E+01 0.57098525E+01 0.56901647E+01
+ 0.56706394E+01 0.56512743E+01 0.56320672E+01 0.56130161E+01 0.55941187E+01
+ 0.55753731E+01 0.55567772E+01 0.55383290E+01 0.55200266E+01 0.55018680E+01
+ 0.54838514E+01 0.54659750E+01 0.54482368E+01 0.54306351E+01 0.54131682E+01
+ 0.53958343E+01 0.53786318E+01 0.53615589E+01 0.53446141E+01 0.53277957E+01
+ 0.53111022E+01 0.52945319E+01 0.52780834E+01 0.52617552E+01 0.52455457E+01
+ 0.52294536E+01 0.52134774E+01 0.51976157E+01 0.51818671E+01 0.51662303E+01
+ 0.51507039E+01 0.51352866E+01 0.51199770E+01 0.51047741E+01 0.50896764E+01
+ 0.50746828E+01 0.50597919E+01 0.50450028E+01 0.50303141E+01 0.50157247E+01
+ 0.50012334E+01 0.49868393E+01 0.49725410E+01 0.49583376E+01 0.49442280E+01
+ 0.49302111E+01 0.49162859E+01 0.49024514E+01 0.48887065E+01 0.48750502E+01
+ 0.48614817E+01 0.48479999E+01 0.48346039E+01 0.48212927E+01 0.48080654E+01
+ 0.47949211E+01 0.47818590E+01 0.47688781E+01 0.47559775E+01 0.47431565E+01
+ 0.47304141E+01 0.47177496E+01 0.47051620E+01 0.46926507E+01 0.46802148E+01
+ 0.46678536E+01 0.46555661E+01 0.46433518E+01 0.46312098E+01 0.46191394E+01
+ 0.46071398E+01 0.45952104E+01 0.45833504E+01 0.45715591E+01 0.45598359E+01
+ 0.45481800E+01 0.45365907E+01 0.45250675E+01 0.45136096E+01 0.45022164E+01
+ 0.44908873E+01 0.44796216E+01 0.44684188E+01 0.44572781E+01 0.44461990E+01
+ 0.44351809E+01 0.44242232E+01 0.44133253E+01 0.44024867E+01 0.43917067E+01
+ 0.43809848E+01 0.43703206E+01 0.43597133E+01 0.43491625E+01 0.43386676E+01
+ 0.43282282E+01 0.43178437E+01 0.43075136E+01 0.42972373E+01 0.42870144E+01
+ 0.42768444E+01 0.42667269E+01 0.42566612E+01 0.42466470E+01 0.42366837E+01
+ 0.42267710E+01 0.42169083E+01 0.42070953E+01 0.41973313E+01 0.41876161E+01
+ 0.41779492E+01 0.41683301E+01 0.41587584E+01 0.41492338E+01 0.41397557E+01
+ 0.41303238E+01 0.41209376E+01 0.41115968E+01 0.41023010E+01 0.40930498E+01
+ 0.40838427E+01 0.40746795E+01 0.40655596E+01 0.40564829E+01 0.40474488E+01
+ 0.40384570E+01 0.40295072E+01 0.40205989E+01 0.40117320E+01 0.40029059E+01
+ 0.39941203E+01 0.39853750E+01 0.39766695E+01 0.39680036E+01 0.39593769E+01
+ 0.39507891E+01 0.39422398E+01 0.39337288E+01 0.39252557E+01 0.39168202E+01
+ 0.39084220E+01 0.39000608E+01 0.38917363E+01 0.38834482E+01 0.38751962E+01
+ 0.38669800E+01 0.38587993E+01 0.38506539E+01 0.38425434E+01 0.38344675E+01
+ 0.38264261E+01 0.38184188E+01 0.38104453E+01 0.38025055E+01 0.37945989E+01
+ 0.37867254E+01 0.37788847E+01 0.37710765E+01 0.37633006E+01 0.37555567E+01
+ 0.37478446E+01 0.37401641E+01 0.37325148E+01 0.37248966E+01 0.37173092E+01
+ 0.37097523E+01 0.37022258E+01 0.36947294E+01 0.36872629E+01 0.36798261E+01
+ 0.36724186E+01 0.36650404E+01 0.36576911E+01 0.36503706E+01 0.36430787E+01
+ 0.36358151E+01 0.36285796E+01 0.36213720E+01 0.36141922E+01 0.36070398E+01
+ 0.35999147E+01 0.35928168E+01 0.35857457E+01 0.35787013E+01 0.35716835E+01
+ 0.35646919E+01 0.35577264E+01 0.35507869E+01 0.35438732E+01 0.35369849E+01
+ 0.35301221E+01 0.35232844E+01 0.35164718E+01 0.35096839E+01 0.35029207E+01
+ 0.34961820E+01 0.34894676E+01 0.34827773E+01 0.34761110E+01 0.34694685E+01
+ 0.34628496E+01 0.34562541E+01 0.34496819E+01 0.34431328E+01 0.34366068E+01
+ 0.34301035E+01 0.34236228E+01 0.34171647E+01 0.34107288E+01 0.34043152E+01
+ 0.33979236E+01 0.33915538E+01 0.33852058E+01 0.33788794E+01 0.33725744E+01
+ 0.33662906E+01 0.33600280E+01 0.33537864E+01 0.33475657E+01 0.33413656E+01
+ 0.33351862E+01 0.33290271E+01 0.33228884E+01 0.33167698E+01 0.33106713E+01
+ 0.33045926E+01 0.32985337E+01 0.32924945E+01 0.32864747E+01 0.32804743E+01
+ 0.32744932E+01 0.32685311E+01 0.32625881E+01 0.32566639E+01 0.32507585E+01
+ 0.32448717E+01 0.32390034E+01 0.32331535E+01 0.32273218E+01 0.32215083E+01
+ 0.32157128E+01 0.32099352E+01 0.32041755E+01 0.31984334E+01 0.31927088E+01
+ 0.31870018E+01 0.31813120E+01 0.31756396E+01 0.31699842E+01 0.31643459E+01
+ 0.31587244E+01 0.31531198E+01 0.31475319E+01 0.31419605E+01 0.31364057E+01
+ 0.31308672E+01 0.31253451E+01 0.31198391E+01 0.31143492E+01 0.31088753E+01
+ 0.31034172E+01 0.30979750E+01 0.30925485E+01 0.30871375E+01 0.30817420E+01
+ 0.30763620E+01 0.30709972E+01 0.30656477E+01 0.30603133E+01 0.30549939E+01
+ 0.30496895E+01 0.30443999E+01 0.30391251E+01 0.30338650E+01 0.30286194E+01
+ 0.30233884E+01 0.30181717E+01 0.30129694E+01 0.30077813E+01 0.30026074E+01
+ 0.29974475E+01 0.29923017E+01 0.29871697E+01 0.29820516E+01 0.29769472E+01
+ 0.29718564E+01 0.29667793E+01 0.29617156E+01 0.29566654E+01 0.29516285E+01
+ 0.29466049E+01 0.29415945E+01 0.29365972E+01 0.29316129E+01 0.29266416E+01
+ 0.29216832E+01 0.29167376E+01 0.29118047E+01 0.29068846E+01 0.29019770E+01
+ 0.28970819E+01 0.28921993E+01 0.28873291E+01 0.28824711E+01 0.28776255E+01
+ 0.28727920E+01 0.28679706E+01 0.28631612E+01 0.28583639E+01 0.28535784E+01
+ 0.28488048E+01 0.28440429E+01 0.28392927E+01 0.28345542E+01 0.28298273E+01
+ 0.28251118E+01 0.28204079E+01 0.28157153E+01 0.28110340E+01 0.28063640E+01
+ 0.28017052E+01 0.27970575E+01 0.27924210E+01 0.27877954E+01 0.27831808E+01
+ 0.27785771E+01 0.27739842E+01 0.27694021E+01 0.27648308E+01 0.27602701E+01
+ 0.27557200E+01 0.27511805E+01 0.27466514E+01 0.27421328E+01 0.27376246E+01
+ 0.27331267E+01 0.27286391E+01 0.27241618E+01 0.27196945E+01 0.27152374E+01
+ 0.27107904E+01 0.27063534E+01 0.27019263E+01 0.26975091E+01 0.26931018E+01
+ 0.26887043E+01 0.26843165E+01 0.26799384E+01 0.26755700E+01 0.26712112E+01
+ 0.26668619E+01 0.26625221E+01 0.26581918E+01 0.26538709E+01 0.26495593E+01
+ 0.26452571E+01 0.26409641E+01 0.26366803E+01 0.26324057E+01 0.26281402E+01
+ 0.26238838E+01 0.26196364E+01 0.26153980E+01 0.26111686E+01 0.26069480E+01
+ 0.26027363E+01 0.25985334E+01 0.25943393E+01 0.25901538E+01 0.25859771E+01
+ 0.25818090E+01 0.25776494E+01 0.25734984E+01 0.25693560E+01 0.25652220E+01
+ 0.25610964E+01 0.25569792E+01 0.25528703E+01 0.25487697E+01 0.25446774E+01
+ 0.25405934E+01 0.25365175E+01 0.25324497E+01 0.25283900E+01 0.25243385E+01
+ 0.25202949E+01 0.25162593E+01 0.25122317E+01 0.25082119E+01 0.25042001E+01
+ 0.25001961E+01 0.24961999E+01 0.24922114E+01 0.24882307E+01 0.24842577E+01
+ 0.24802923E+01 0.24763345E+01 0.24723843E+01 0.24684417E+01 0.24645066E+01
+ 0.24605789E+01 0.24566587E+01 0.24527459E+01 0.24488405E+01 0.24449424E+01
+ 0.24410516E+01 0.24371681E+01 0.24332918E+01 0.24294228E+01 0.24255609E+01
+ 0.24217061E+01 0.24178585E+01 0.24140179E+01 0.24101844E+01 0.24063579E+01
+ 0.24025384E+01 0.23987258E+01 0.23949202E+01 0.23911214E+01 0.23873295E+01
+ 0.23835445E+01 0.23797662E+01 0.23759947E+01 0.23722299E+01 0.23684719E+01
+ 0.23647205E+01 0.23609758E+01 0.23572377E+01 0.23535061E+01 0.23497812E+01
+ 0.23460628E+01 0.23423509E+01 0.23386454E+01 0.23349464E+01 0.23312539E+01
+ 0.23275677E+01 0.23238879E+01 0.23202145E+01 0.23165473E+01 0.23128865E+01
+ 0.23092319E+01 0.23055835E+01 0.23019414E+01 0.22983054E+01 0.22946756E+01
+ 0.22910519E+01 0.22874343E+01 0.22838228E+01 0.22802174E+01 0.22766180E+01
+ 0.22730246E+01 0.22694371E+01 0.22658557E+01 0.22622801E+01 0.22587105E+01
+ 0.22551467E+01 0.22515888E+01 0.22480368E+01 0.22444905E+01 0.22409500E+01
+ 0.22374153E+01 0.22338864E+01 0.22303631E+01 0.22268456E+01 0.22233337E+01
+ 0.22198275E+01 0.22163269E+01 0.22128319E+01 0.22093424E+01 0.22058586E+01
+ 0.22023803E+01 0.21989075E+01 0.21954402E+01 0.21919783E+01 0.21885220E+01
+ 0.21850710E+01 0.21816255E+01 0.21781854E+01 0.21747506E+01 0.21713211E+01
+ 0.21678970E+01 0.21644783E+01 0.21610648E+01 0.21576565E+01 0.21542535E+01
+ 0.21508558E+01 0.21474632E+01 0.21440758E+01 0.21406936E+01 0.21373166E+01
+ 0.21339447E+01 0.21305779E+01 0.21272162E+01 0.21238595E+01 0.21205079E+01
+ 0.21171614E+01 0.21138198E+01 0.21104833E+01 0.21071518E+01 0.21038252E+01
+ 0.21005035E+01 0.20971868E+01 0.20938750E+01 0.20905681E+01 0.20872660E+01
+ 0.20839689E+01 0.20806765E+01 0.20773890E+01 0.20741063E+01 0.20708283E+01
+ 0.20675552E+01 0.20642868E+01 0.20610231E+01 0.20577642E+01 0.20545099E+01
+ 0.20512604E+01 0.20480155E+01 0.20447753E+01 0.20415397E+01 0.20383087E+01
+ 0.20350824E+01 0.20318606E+01 0.20286434E+01 0.20254308E+01 0.20222228E+01
+ 0.20190192E+01 0.20158202E+01 0.20126257E+01 0.20094356E+01 0.20062501E+01
+ 0.20030690E+01 0.19998923E+01 0.19967200E+01 0.19935522E+01 0.19903888E+01
+ 0.19872297E+01 0.19840750E+01 0.19809247E+01 0.19777787E+01 0.19746371E+01
+ 0.19714997E+01 0.19683667E+01 0.19652379E+01 0.19621134E+01 0.19589932E+01
+ 0.19558772E+01 0.19527654E+01 0.19496579E+01 0.19465546E+01 0.19434554E+01
+ 0.19403604E+01 0.19372696E+01 0.19341830E+01 0.19311005E+01 0.19280221E+01
+ 0.19249478E+01 0.19218777E+01 0.19188116E+01 0.19157496E+01 0.19126917E+01
+ 0.19096378E+01 0.19065880E+01 0.19035422E+01 0.19005004E+01 0.18974626E+01
+ 0.18944288E+01 0.18913990E+01 0.18883731E+01 0.18853512E+01 0.18823333E+01
+ 0.18793193E+01 0.18763092E+01 0.18733030E+01 0.18703008E+01 0.18673024E+01
+ 0.18643079E+01 0.18613173E+01 0.18583305E+01 0.18553475E+01 0.18523684E+01
+ 0.18493932E+01 0.18464217E+01 0.18434541E+01 0.18404902E+01 0.18375301E+01
+ 0.18345738E+01 0.18316213E+01 0.18286725E+01 0.18257274E+01 0.18227861E+01
+ 0.18198485E+01 0.18169146E+01 0.18139844E+01 0.18110579E+01 0.18081351E+01
+ 0.18052159E+01 0.18023004E+01 0.17993886E+01 0.17964804E+01 0.17935758E+01
+ 0.17906749E+01 0.17877775E+01 0.17848838E+01 0.17819937E+01 0.17791072E+01
+ 0.17762242E+01 0.17733448E+01 0.17704690E+01 0.17675967E+01 0.17647280E+01
+ 0.17618627E+01 0.17590011E+01 0.17561429E+01 0.17532882E+01 0.17504371E+01
+ 0.17475894E+01 0.17447452E+01 0.17419045E+01 0.17390672E+01 0.17362334E+01
+ 0.17334031E+01 0.17305761E+01 0.17277526E+01 0.17249326E+01 0.17221159E+01
+ 0.17193027E+01 0.17164929E+01 0.17136864E+01 0.17108833E+01 0.17080836E+01
+ 0.17052873E+01 0.17024944E+01 0.16997048E+01 0.16969185E+01 0.16941356E+01
+ 0.16913560E+01 0.16885797E+01 0.16858067E+01 0.16830371E+01 0.16802707E+01
+ 0.16775076E+01 0.16747479E+01 0.16719914E+01 0.16692382E+01 0.16664882E+01
+ 0.16637415E+01 0.16609980E+01 0.16582578E+01 0.16555209E+01 0.16527871E+01
+ 0.16500566E+01 0.16473293E+01 0.16446052E+01 0.16418843E+01 0.16391667E+01
+ 0.16364522E+01 0.16337408E+01 0.16310327E+01 0.16283277E+01 0.16256259E+01
+ 0.16229273E+01 0.16202318E+01 0.16175395E+01 0.16148503E+01 0.16121642E+01
+ 0.16094812E+01 0.16068014E+01 0.16041247E+01 0.16014511E+01 0.15987806E+01
+ 0.15961132E+01 0.15934489E+01 0.15907877E+01 0.15881295E+01 0.15854745E+01
+ 0.15828225E+01 0.15801735E+01 0.15775277E+01 0.15748848E+01 0.15722451E+01
+ 0.15696083E+01 0.15669746E+01 0.15643439E+01 0.15617163E+01 0.15590916E+01
+ 0.15564700E+01 0.15538514E+01 0.15512358E+01 0.15486232E+01 0.15460136E+01
+ 0.15434069E+01 0.15408033E+01 0.15382026E+01 0.15356049E+01 0.15330102E+01
+ 0.15304184E+01 0.15278296E+01 0.15252438E+01 0.15226608E+01 0.15200809E+01
+ 0.15175038E+01 0.15149297E+01 0.15123586E+01 0.15097903E+01 0.15072250E+01
+ 0.15046626E+01 0.15021031E+01 0.14995465E+01 0.14969928E+01 0.14944420E+01
+ 0.14918941E+01 0.14893491E+01 0.14868069E+01 0.14842677E+01 0.14817313E+01
+ 0.14791978E+01 0.14766671E+01 0.14741393E+01 0.14716144E+01 0.14690923E+01
+ 0.14665731E+01 0.14640567E+01 0.14615432E+01 0.14590325E+01 0.14565246E+01
+ 0.14540195E+01 0.14515173E+01 0.14490179E+01 0.14465213E+01 0.14440276E+01
+ 0.14415366E+01 0.14390484E+01 0.14365631E+01 0.14340805E+01 0.14316008E+01
+ 0.14291238E+01 0.14266496E+01 0.14241782E+01 0.14217095E+01 0.14192437E+01
+ 0.14167806E+01 0.14143203E+01 0.14118628E+01 0.14094080E+01 0.14069559E+01
+ 0.14045067E+01 0.14020601E+01 0.13996164E+01 0.13971753E+01 0.13947370E+01
+ 0.13923015E+01 0.13898686E+01 0.13874385E+01 0.13850112E+01 0.13825865E+01
+ 0.13801646E+01 0.13777454E+01 0.13753289E+01 0.13729151E+01 0.13705041E+01
+ 0.13680957E+01 0.13656901E+01 0.13632871E+01 0.13608868E+01 0.13584892E+01
+ 0.13560944E+01 0.13537022E+01 0.13513126E+01 0.13489258E+01 0.13465417E+01
+ 0.13441602E+01 0.13417814E+01 0.13394052E+01 0.13370317E+01 0.13346609E+01
+ 0.13322928E+01 0.13299273E+01 0.13275645E+01 0.13252043E+01 0.13228468E+01
+ 0.13204919E+01 0.13181396E+01 0.13157900E+01 0.13134431E+01 0.13110988E+01
+ 0.13087571E+01 0.13064180E+01 0.13040816E+01 0.13017478E+01 0.12994166E+01
+ 0.12970881E+01 0.12947622E+01 0.12924388E+01 0.12901181E+01 0.12878001E+01
+ 0.12854846E+01 0.12831717E+01 0.12808615E+01 0.12785538E+01 0.12762487E+01
+ 0.12739463E+01 0.12716464E+01 0.12693491E+01 0.12670544E+01 0.12647624E+01
+ 0.12624729E+01 0.12601859E+01 0.12579016E+01 0.12556198E+01 0.12533407E+01
+ 0.12510641E+01 0.12487900E+01 0.12465186E+01 0.12442497E+01 0.12419834E+01
+ 0.12397196E+01 0.12374584E+01 0.12351998E+01 0.12329438E+01 0.12306902E+01
+ 0.12284393E+01 0.12261909E+01 0.12239451E+01 0.12217018E+01 0.12194610E+01
+ 0.12172228E+01 0.12149872E+01 0.12127541E+01 0.12105235E+01 0.12082955E+01
+ 0.12060700E+01 0.12038470E+01 0.12016266E+01 0.11994087E+01 0.11971933E+01
+ 0.11949805E+01 0.11927702E+01 0.11905624E+01 0.11883571E+01 0.11861544E+01
+ 0.11839542E+01 0.11817565E+01 0.11795613E+01 0.11773686E+01 0.11751785E+01
+ 0.11729908E+01 0.11708057E+01 0.11686231E+01 0.11664430E+01 0.11642654E+01
+ 0.11620903E+01 0.11599177E+01 0.11577476E+01 0.11555800E+01 0.11534149E+01
+ 0.11512523E+01 0.11490921E+01 0.11469345E+01 0.11447794E+01 0.11426268E+01
+ 0.11404766E+01 0.11383290E+01 0.11361838E+01 0.11340411E+01 0.11319009E+01
+ 0.11297632E+01 0.11276279E+01 0.11254952E+01 0.11233649E+01 0.11212371E+01
+ 0.11191118E+01 0.11169889E+01 0.11148685E+01 0.11127506E+01 0.11106352E+01
+ 0.11085222E+01 0.11064117E+01 0.11043037E+01 0.11021981E+01 0.11000950E+01
+ 0.10979944E+01 0.10958962E+01 0.10938005E+01 0.10917072E+01 0.10896164E+01
+ 0.10875280E+01 0.10854422E+01 0.10833587E+01 0.10812777E+01 0.10791992E+01
+ 0.10771231E+01 0.10750495E+01 0.10729783E+01 0.10709096E+01 0.10688433E+01
+ 0.10667795E+01 0.10647181E+01 0.10626592E+01 0.10606027E+01 0.10585486E+01
+ 0.10564970E+01 0.10544478E+01 0.10524011E+01 0.10503568E+01 0.10483149E+01
+ 0.10462755E+01 0.10442385E+01 0.10422039E+01 0.10401718E+01 0.10381421E+01
+ 0.10361148E+01 0.10340900E+01 0.10320675E+01 0.10300476E+01 0.10280300E+01
+ 0.10260149E+01 0.10240022E+01 0.10219919E+01 0.10199840E+01 0.10179786E+01
+ 0.10159756E+01 0.10139750E+01 0.10119768E+01 0.10099811E+01 0.10079877E+01
+ 0.10059968E+01 0.10040083E+01 0.10020222E+01 0.10000386E+01 0.99805731E+00
+ 0.99607847E+00 0.99410204E+00 0.99212802E+00 0.99015640E+00 0.98818720E+00
+ 0.98622041E+00 0.98425603E+00 0.98229405E+00 0.98033448E+00 0.97837731E+00
+ 0.97642255E+00 0.97447020E+00 0.97252024E+00 0.97057269E+00 0.96862754E+00
+ 0.96668480E+00 0.96474445E+00 0.96280650E+00 0.96087095E+00 0.95893780E+00
+ 0.95700705E+00 0.95507869E+00 0.95315273E+00 0.95122916E+00 0.94930799E+00
+ 0.94738921E+00 0.94547283E+00 0.94355884E+00 0.94164723E+00 0.93973802E+00
+ 0.93783121E+00 0.93592678E+00 0.93402473E+00 0.93212508E+00 0.93022782E+00
+ 0.92833294E+00 0.92644044E+00 0.92455034E+00 0.92266261E+00 0.92077728E+00
+ 0.91889432E+00 0.91701375E+00 0.91513556E+00 0.91325975E+00 0.91138633E+00
+ 0.90951528E+00 0.90764661E+00 0.90578033E+00 0.90391642E+00 0.90205489E+00
+ 0.90019573E+00 0.89833895E+00 0.89648455E+00 0.89463252E+00 0.89278287E+00
+ 0.89093559E+00 0.88909069E+00 0.88724816E+00 0.88540800E+00 0.88357021E+00
+ 0.88173479E+00 0.87990175E+00 0.87807107E+00 0.87624276E+00 0.87441683E+00
+ 0.87259326E+00 0.87077205E+00 0.86895322E+00 0.86713675E+00 0.86532264E+00
+ 0.86351090E+00 0.86170153E+00 0.85989452E+00 0.85808987E+00 0.85628759E+00
+ 0.85448767E+00 0.85269011E+00 0.85089491E+00 0.84910207E+00 0.84731159E+00
+ 0.84552347E+00 0.84373771E+00 0.84195431E+00 0.84017327E+00 0.83839458E+00
+ 0.83661825E+00 0.83484428E+00 0.83307266E+00 0.83130339E+00 0.82953648E+00
+ 0.82777193E+00 0.82600973E+00 0.82424988E+00 0.82249238E+00 0.82073723E+00
+ 0.81898444E+00 0.81723400E+00 0.81548590E+00 0.81374016E+00 0.81199676E+00
+ 0.81025571E+00 0.80851701E+00 0.80678066E+00 0.80504665E+00 0.80331499E+00
+ 0.80158568E+00 0.79985871E+00 0.79813408E+00 0.79641180E+00 0.79469186E+00
+ 0.79297427E+00 0.79125902E+00 0.78954611E+00 0.78783554E+00 0.78612731E+00
+ 0.78442142E+00 0.78271787E+00 0.78101666E+00 0.77931778E+00 0.77762125E+00
+ 0.77592705E+00 0.77423519E+00 0.77254567E+00 0.77085848E+00 0.76917362E+00
+ 0.76749110E+00 0.76581092E+00 0.76413307E+00 0.76245755E+00 0.76078436E+00
+ 0.75911350E+00 0.75744498E+00 0.75577879E+00 0.75411492E+00 0.75245339E+00
+ 0.75079419E+00 0.74913731E+00 0.74748276E+00 0.74583054E+00 0.74418064E+00
+ 0.74253308E+00 0.74088783E+00 0.73924491E+00 0.73760432E+00 0.73596605E+00
+ 0.73433010E+00 0.73269648E+00 0.73106518E+00 0.72943620E+00 0.72780954E+00
+ 0.72618520E+00 0.72456318E+00 0.72294348E+00 0.72132609E+00 0.71971103E+00
+ 0.71809828E+00 0.71648785E+00 0.71487974E+00 0.71327394E+00 0.71167046E+00
+ 0.71006929E+00 0.70847043E+00 0.70687389E+00 0.70527966E+00 0.70368775E+00
+ 0.70209814E+00 0.70051085E+00 0.69892586E+00 0.69734319E+00 0.69576282E+00
+ 0.69418476E+00 0.69260901E+00 0.69103557E+00 0.68946443E+00 0.68789560E+00
+ 0.68632908E+00 0.68476486E+00 0.68320294E+00 0.68164333E+00 0.68008601E+00
+ 0.67853100E+00 0.67697830E+00 0.67542789E+00 0.67387978E+00 0.67233398E+00
+ 0.67079047E+00 0.66924926E+00 0.66771034E+00 0.66617373E+00 0.66463941E+00
+ 0.66310738E+00 0.66157765E+00 0.66005022E+00 0.65852507E+00 0.65700222E+00
+ 0.65548167E+00 0.65396340E+00 0.65244743E+00 0.65093374E+00 0.64942234E+00
+ 0.64791324E+00 0.64640642E+00 0.64490188E+00 0.64339964E+00 0.64189968E+00
+ 0.64040201E+00 0.63890662E+00 0.63741351E+00 0.63592269E+00 0.63443414E+00
+ 0.63294788E+00 0.63146391E+00 0.62998221E+00 0.62850279E+00 0.62702565E+00
+ 0.62555079E+00 0.62407820E+00 0.62260789E+00 0.62113986E+00 0.61967410E+00
+ 0.61821061E+00 0.61674940E+00 0.61529046E+00 0.61383380E+00 0.61237940E+00
+ 0.61092728E+00 0.60947742E+00 0.60802984E+00 0.60658452E+00 0.60514147E+00
+ 0.60370068E+00 0.60226216E+00 0.60082591E+00 0.59939192E+00 0.59796019E+00
+ 0.59653072E+00 0.59510352E+00 0.59367858E+00 0.59225589E+00 0.59083547E+00
+ 0.58941731E+00 0.58800140E+00 0.58658775E+00 0.58517635E+00 0.58376721E+00
+ 0.58236033E+00 0.58095569E+00 0.57955331E+00 0.57815318E+00 0.57675531E+00
+ 0.57535968E+00 0.57396630E+00 0.57257517E+00 0.57118629E+00 0.56979965E+00
+ 0.56841526E+00 0.56703311E+00 0.56565321E+00 0.56427555E+00 0.56290013E+00
+ 0.56152695E+00 0.56015601E+00 0.55878731E+00 0.55742085E+00 0.55605663E+00
+ 0.55469465E+00 0.55333490E+00 0.55197738E+00 0.55062210E+00 0.54926905E+00
+ 0.54791823E+00 0.54656965E+00 0.54522329E+00 0.54387916E+00 0.54253726E+00
+ 0.54119759E+00 0.53986014E+00 0.53852492E+00 0.53719192E+00 0.53586115E+00
+ 0.53453260E+00 0.53320627E+00 0.53188216E+00 0.53056026E+00 0.52924059E+00
+ 0.52792314E+00 0.52660790E+00 0.52529487E+00 0.52398406E+00 0.52267546E+00
+ 0.52136908E+00 0.52006491E+00 0.51876294E+00 0.51746319E+00 0.51616564E+00
+ 0.51487030E+00 0.51357717E+00 0.51228624E+00 0.51099751E+00 0.50971099E+00
+ 0.50842667E+00 0.50714455E+00 0.50586463E+00 0.50458690E+00 0.50331138E+00
+ 0.50203805E+00 0.50076691E+00 0.49949797E+00 0.49823123E+00 0.49696667E+00
+ 0.49570431E+00 0.49444413E+00 0.49318615E+00 0.49193035E+00 0.49067674E+00
+ 0.48942531E+00 0.48817606E+00 0.48692900E+00 0.48568412E+00 0.48444143E+00
+ 0.48320091E+00 0.48196256E+00 0.48072640E+00 0.47949241E+00 0.47826060E+00
+ 0.47703096E+00 0.47580349E+00 0.47457819E+00 0.47335507E+00 0.47213411E+00
+ 0.47091532E+00 0.46969869E+00 0.46848424E+00 0.46727194E+00 0.46606181E+00
+ 0.46485384E+00 0.46364803E+00 0.46244437E+00 0.46124288E+00 0.46004354E+00
+ 0.45884636E+00 0.45765133E+00 0.45645846E+00 0.45526773E+00 0.45407916E+00
+ 0.45289273E+00 0.45170846E+00 0.45052633E+00 0.44934634E+00 0.44816850E+00
+ 0.44699280E+00 0.44581924E+00 0.44464782E+00 0.44347854E+00 0.44231140E+00
+ 0.44114639E+00 0.43998352E+00 0.43882278E+00 0.43766418E+00 0.43650770E+00
+ 0.43535336E+00 0.43420114E+00 0.43305105E+00 0.43190308E+00 0.43075724E+00
+ 0.42961352E+00 0.42847192E+00 0.42733244E+00 0.42619508E+00 0.42505984E+00
+ 0.42392671E+00 0.42279570E+00 0.42166680E+00 0.42054001E+00 0.41941533E+00
+ 0.41829276E+00 0.41717229E+00 0.41605394E+00 0.41493768E+00 0.41382353E+00
+ 0.41271149E+00 0.41160154E+00 0.41049369E+00 0.40938794E+00 0.40828428E+00
+ 0.40718272E+00 0.40608325E+00 0.40498587E+00 0.40389059E+00 0.40279739E+00
+ 0.40170627E+00 0.40061725E+00 0.39953030E+00 0.39844544E+00 0.39736266E+00
+ 0.39628197E+00 0.39520334E+00 0.39412680E+00 0.39305233E+00 0.39197993E+00
+ 0.39090961E+00 0.38984135E+00 0.38877517E+00 0.38771105E+00 0.38664900E+00
+ 0.38558901E+00 0.38453108E+00 0.38347522E+00 0.38242141E+00 0.38136967E+00
+ 0.38031998E+00 0.37927234E+00 0.37822676E+00 0.37718323E+00 0.37614175E+00
+ 0.37510232E+00 0.37406493E+00 0.37302960E+00 0.37199630E+00 0.37096505E+00
+ 0.36993583E+00 0.36890866E+00 0.36788352E+00 0.36686042E+00 0.36583935E+00
+ 0.36482032E+00 0.36380332E+00 0.36278834E+00 0.36177539E+00 0.36076447E+00
+ 0.35975557E+00 0.35874870E+00 0.35774384E+00 0.35674101E+00 0.35574019E+00
+ 0.35474139E+00 0.35374460E+00 0.35274983E+00 0.35175706E+00 0.35076631E+00
+ 0.34977756E+00 0.34879081E+00 0.34780607E+00 0.34682334E+00 0.34584260E+00
+ 0.34486386E+00 0.34388712E+00 0.34291238E+00 0.34193962E+00 0.34096886E+00
+ 0.34000009E+00 0.33903331E+00 0.33806852E+00 0.33710570E+00 0.33614488E+00
+ 0.33518603E+00 0.33422916E+00 0.33327427E+00 0.33232136E+00 0.33137042E+00
+ 0.33042145E+00 0.32947446E+00 0.32852943E+00 0.32758637E+00 0.32664527E+00
+ 0.32570614E+00 0.32476897E+00 0.32383376E+00 0.32290050E+00 0.32196920E+00
+ 0.32103986E+00 0.32011247E+00 0.31918703E+00 0.31826354E+00 0.31734199E+00
+ 0.31642239E+00 0.31550474E+00 0.31458902E+00 0.31367525E+00 0.31276341E+00
+ 0.31185350E+00 0.31094553E+00 0.31003950E+00 0.30913539E+00 0.30823321E+00
+ 0.30733296E+00 0.30643463E+00 0.30553823E+00 0.30464374E+00 0.30375117E+00
+ 0.30286052E+00 0.30197179E+00 0.30108497E+00 0.30020006E+00 0.29931705E+00
+ 0.29843596E+00 0.29755677E+00 0.29667948E+00 0.29580410E+00 0.29493061E+00
+ 0.29405902E+00 0.29318933E+00 0.29232153E+00 0.29145563E+00 0.29059161E+00
+ 0.28972948E+00 0.28886923E+00 0.28801087E+00 0.28715439E+00 0.28629979E+00
+ 0.28544707E+00 0.28459623E+00 0.28374725E+00 0.28290015E+00 0.28205492E+00
+ 0.28121156E+00 0.28037006E+00 0.27953043E+00 0.27869266E+00 0.27785400E+00
+ 0.27701159E+00 0.27616545E+00 0.27531563E+00 0.27446215E+00 0.27360505E+00
+ 0.27274437E+00 0.27188014E+00 0.27101239E+00 0.27014116E+00 0.26926648E+00
+ 0.26838839E+00 0.26750692E+00 0.26662211E+00 0.26573398E+00 0.26484259E+00
+ 0.26394795E+00 0.26305011E+00 0.26214910E+00 0.26124495E+00 0.26033770E+00
+ 0.25942738E+00 0.25851403E+00 0.25759768E+00 0.25667837E+00 0.25575612E+00
+ 0.25483098E+00 0.25390299E+00 0.25297216E+00 0.25203854E+00 0.25110217E+00
+ 0.25016308E+00 0.24922129E+00 0.24827686E+00 0.24732980E+00 0.24638016E+00
+ 0.24542797E+00 0.24447327E+00 0.24351608E+00 0.24255645E+00 0.24159441E+00
+ 0.24062999E+00 0.23966322E+00 0.23869415E+00 0.23772280E+00 0.23674922E+00
+ 0.23577343E+00 0.23479547E+00 0.23381537E+00 0.23283318E+00 0.23184891E+00
+ 0.23086262E+00 0.22987432E+00 0.22888407E+00 0.22789188E+00 0.22689780E+00
+ 0.22590186E+00 0.22490410E+00 0.22390454E+00 0.22290323E+00 0.22190020E+00
+ 0.22089548E+00 0.21988911E+00 0.21888112E+00 0.21787154E+00 0.21686042E+00
+ 0.21584778E+00 0.21483367E+00 0.21381810E+00 0.21280113E+00 0.21178278E+00
+ 0.21076308E+00 0.20974208E+00 0.20871981E+00 0.20769630E+00 0.20667158E+00
+ 0.20564570E+00 0.20461868E+00 0.20359056E+00 0.20256137E+00 0.20153115E+00
+ 0.20049994E+00 0.19946776E+00 0.19843465E+00 0.19740065E+00 0.19636580E+00
+ 0.19533011E+00 0.19429364E+00 0.19325642E+00 0.19221847E+00 0.19117983E+00
+ 0.19014055E+00 0.18910064E+00 0.18806016E+00 0.18701912E+00 0.18597757E+00
+ 0.18493555E+00 0.18389307E+00 0.18285019E+00 0.18180693E+00 0.18076333E+00
+ 0.17971943E+00 0.17867525E+00 0.17763083E+00 0.17658621E+00 0.17554142E+00
+ 0.17449650E+00 0.17345148E+00 0.17240639E+00 0.17136127E+00 0.17031616E+00
+ 0.16927108E+00 0.16822608E+00 0.16718118E+00 0.16613643E+00 0.16509185E+00
+ 0.16404748E+00 0.16300336E+00 0.16195952E+00 0.16091599E+00 0.15987282E+00
+ 0.15883002E+00 0.15778765E+00 0.15674572E+00 0.15570428E+00 0.15466337E+00
+ 0.15362301E+00 0.15258324E+00 0.15154410E+00 0.15050561E+00 0.14946782E+00
+ 0.14843076E+00 0.14739446E+00 0.14635896E+00 0.14532429E+00 0.14429049E+00
+ 0.14325758E+00 0.14222562E+00 0.14119462E+00 0.14016463E+00 0.13913568E+00
+ 0.13810780E+00 0.13708103E+00 0.13605540E+00 0.13503095E+00 0.13400771E+00
+ 0.13298572E+00 0.13196501E+00 0.13094561E+00 0.12992756E+00 0.12891090E+00
+ 0.12789565E+00 0.12688186E+00 0.12586956E+00 0.12485878E+00 0.12384955E+00
+ 0.12284192E+00 0.12183591E+00 0.12083156E+00 0.11982891E+00 0.11882799E+00
+ 0.11782883E+00 0.11683147E+00 0.11583594E+00 0.11484228E+00 0.11385052E+00
+ 0.11286070E+00 0.11187285E+00 0.11088700E+00 0.10990319E+00 0.10892146E+00
+ 0.10794184E+00 0.10696436E+00 0.10598906E+00 0.10501597E+00 0.10404512E+00
+ 0.10307656E+00 0.10211032E+00 0.10114642E+00 0.10018491E+00 0.99225822E-01
+ 0.98269186E-01 0.97315038E-01 0.96363413E-01 0.95414346E-01 0.94467870E-01
+ 0.93524022E-01 0.92582834E-01 0.91644342E-01 0.90708580E-01 0.89775582E-01
+ 0.88845384E-01 0.87918019E-01 0.86993522E-01 0.86071928E-01 0.85153271E-01
+ 0.84237586E-01 0.83324907E-01 0.82415268E-01 0.81508704E-01 0.80605251E-01
+ 0.79704941E-01 0.78807810E-01 0.77913892E-01 0.77023222E-01 0.76135834E-01
+ 0.75251763E-01 0.74371043E-01 0.73493709E-01 0.72619795E-01 0.71749336E-01
+ 0.70882366E-01 0.70018920E-01 0.69159032E-01 0.68302737E-01 0.67450070E-01
+ 0.66601064E-01 0.65755754E-01 0.64914175E-01 0.64076362E-01 0.63242348E-01
+ 0.62412169E-01 0.61585858E-01 0.60763451E-01 0.59944982E-01 0.59130485E-01
+ 0.58319996E-01 0.57513547E-01 0.56711175E-01 0.55912912E-01 0.55118795E-01
+ 0.54328857E-01 0.53543134E-01 0.52761658E-01 0.51984466E-01 0.51211591E-01
+ 0.50443068E-01 0.49678932E-01 0.48919217E-01 0.48163957E-01 0.47413187E-01
+ 0.46666942E-01 0.45925255E-01 0.45188163E-01 0.44455698E-01 0.43727896E-01
+ 0.43004791E-01 0.42286418E-01 0.41572811E-01 0.40864004E-01 0.40160032E-01
+ 0.39460930E-01 0.38766733E-01 0.38077474E-01 0.37393188E-01 0.36713909E-01
+ 0.36039673E-01 0.35370514E-01 0.34706465E-01 0.34047563E-01 0.33393840E-01
+ 0.32745333E-01 0.32102074E-01 0.31464100E-01 0.30831443E-01 0.30204140E-01
+ 0.29582223E-01 0.28965729E-01 0.28354690E-01 0.27749143E-01 0.27149121E-01
+ 0.26554658E-01 0.25965790E-01 0.25382551E-01 0.24804975E-01 0.24233097E-01
+ 0.23666951E-01 0.23106572E-01 0.22551994E-01 0.22003253E-01 0.21460382E-01
+ 0.20923415E-01 0.20392388E-01 0.19867335E-01 0.19348291E-01 0.18835289E-01
+ 0.18328365E-01 0.17827553E-01 0.17332887E-01 0.16844402E-01 0.16362133E-01
+ 0.15886114E-01 0.15416379E-01 0.14952963E-01 0.14495901E-01 0.14045226E-01
+ 0.13600975E-01 0.13163180E-01 0.12731877E-01 0.12307100E-01 0.11888883E-01
+ 0.11477262E-01 0.11072270E-01 0.10673942E-01 0.10282313E-01 0.98974174E-02
+ 0.95192891E-02 0.91479629E-02 0.87834734E-02 0.84258550E-02 0.80751423E-02
+ 0.77313697E-02 0.73945719E-02 0.70647832E-02 0.67420383E-02 0.64263715E-02
+ 0.61178175E-02 0.58164107E-02 0.55221856E-02 0.52351768E-02 0.49554187E-02
+ 0.46829460E-02 0.44177929E-02 0.41599942E-02 0.39095843E-02 0.36665977E-02
+ 0.34310688E-02 0.32030323E-02 0.29825227E-02 0.27695744E-02 0.25642219E-02
+ 0.23664998E-02 0.21764425E-02 0.19940846E-02 0.18194606E-02 0.16526050E-02
+ 0.14935524E-02 0.13423371E-02 0.11989937E-02 0.10635568E-02 0.93606080E-03
+ 0.81654026E-03 0.70502968E-03 0.60156357E-03 0.50617643E-03 0.41890278E-03
+ 0.33977713E-03 0.26883398E-03 0.20610784E-03 0.15163322E-03 0.10544464E-03
+ 0.67576591E-04 0.38063596E-04 0.16940160E-04 0.42407915E-05 0.00000000E+00
+ 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02
+ 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02
+ 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02
+ 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02
+ 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02
+ 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02
+ 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02
+ 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02
+ 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02
+ 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02
+ 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02 0.19448198E+02
+ 0.19109869E+02 0.18774281E+02 0.18450360E+02 0.18137507E+02 0.17835162E+02
+ 0.17542803E+02 0.17259940E+02 0.16986117E+02 0.16720906E+02 0.16463906E+02
+ 0.16214739E+02 0.15973051E+02 0.15738510E+02 0.15510802E+02 0.15289631E+02
+ 0.15074718E+02 0.14865802E+02 0.14662632E+02 0.14464975E+02 0.14272609E+02
+ 0.14085321E+02 0.13902914E+02 0.13725199E+02 0.13551995E+02 0.13383132E+02
+ 0.13218448E+02 0.13057790E+02 0.12901011E+02 0.12747971E+02 0.12598538E+02
+ 0.12452585E+02 0.12309991E+02 0.12170641E+02 0.12034425E+02 0.11901238E+02
+ 0.11770980E+02 0.11643554E+02 0.11518869E+02 0.11396837E+02 0.11277373E+02
+ 0.11160397E+02 0.11045831E+02 0.10933602E+02 0.10823637E+02 0.10715870E+02
+ 0.10610234E+02 0.10506666E+02 0.10405106E+02 0.10305496E+02 0.10207779E+02
+ 0.10111902E+02 0.10017813E+02 0.99254625E+01 0.98348019E+01 0.97457852E+01
+ 0.96583677E+01 0.95725064E+01 0.94881599E+01 0.94052881E+01 0.93238525E+01
+ 0.92438157E+01 0.91651417E+01 0.90877958E+01 0.90117444E+01 0.89369550E+01
+ 0.88633961E+01 0.87910376E+01 0.87198499E+01 0.86498046E+01 0.85808743E+01
+ 0.85130323E+01 0.84462528E+01 0.83805109E+01 0.83157823E+01 0.82520435E+01
+ 0.81892720E+01 0.81274455E+01 0.80665428E+01 0.80065430E+01 0.79474261E+01
+ 0.78891725E+01 0.78317633E+01 0.77751801E+01 0.77194050E+01 0.76644206E+01
+ 0.76102100E+01 0.75567569E+01 0.75040454E+01 0.74520599E+01 0.74007854E+01
+ 0.73502072E+01 0.73003112E+01 0.72510833E+01 0.72025102E+01 0.71545788E+01
+ 0.71072762E+01 0.70605899E+01 0.70145080E+01 0.69690186E+01 0.69241101E+01
+ 0.68797714E+01 0.68359917E+01 0.67927601E+01 0.67500665E+01 0.67079006E+01
+ 0.66662526E+01 0.66251129E+01 0.65844721E+01 0.65443211E+01 0.65046510E+01
+ 0.64654530E+01 0.64267186E+01 0.63884396E+01 0.63506078E+01 0.63132154E+01
+ 0.62762546E+01 0.62397178E+01 0.62035977E+01 0.61678871E+01 0.61325790E+01
+ 0.60976665E+01 0.60631428E+01 0.60290014E+01 0.59952359E+01 0.59618400E+01
+ 0.59288075E+01 0.58961325E+01 0.58638091E+01 0.58318315E+01 0.58001941E+01
+ 0.57688915E+01 0.57379181E+01 0.57072689E+01 0.56769385E+01 0.56469220E+01
+ 0.56172145E+01 0.55878110E+01 0.55587068E+01 0.55298974E+01 0.55013782E+01
+ 0.54731446E+01 0.54451924E+01 0.54175173E+01 0.53901151E+01 0.53629816E+01
+ 0.53361130E+01 0.53095051E+01 0.52831543E+01 0.52570566E+01 0.52312083E+01
+ 0.52056059E+01 0.51802458E+01 0.51551243E+01 0.51302382E+01 0.51055841E+01
+ 0.50811585E+01 0.50569584E+01 0.50329804E+01 0.50092216E+01 0.49856788E+01
+ 0.49623490E+01 0.49392292E+01 0.49163166E+01 0.48936084E+01 0.48711016E+01
+ 0.48487936E+01 0.48266818E+01 0.48047633E+01 0.47830358E+01 0.47614965E+01
+ 0.47401429E+01 0.47189728E+01 0.46979835E+01 0.46771727E+01 0.46565382E+01
+ 0.46360775E+01 0.46157885E+01 0.45956689E+01 0.45757166E+01 0.45559294E+01
+ 0.45363051E+01 0.45168419E+01 0.44975375E+01 0.44783900E+01 0.44593974E+01
+ 0.44405578E+01 0.44218694E+01 0.44033301E+01 0.43849382E+01 0.43666919E+01
+ 0.43485894E+01 0.43306289E+01 0.43128088E+01 0.42951272E+01 0.42775826E+01
+ 0.42601733E+01 0.42428977E+01 0.42257542E+01 0.42087413E+01 0.41918573E+01
+ 0.41751008E+01 0.41584703E+01 0.41419643E+01 0.41255813E+01 0.41093200E+01
+ 0.40931790E+01 0.40771567E+01 0.40612520E+01 0.40454635E+01 0.40297897E+01
+ 0.40142295E+01 0.39987816E+01 0.39834446E+01 0.39682174E+01 0.39530987E+01
+ 0.39380874E+01 0.39231821E+01 0.39083819E+01 0.38936854E+01 0.38790916E+01
+ 0.38645994E+01 0.38502075E+01 0.38359151E+01 0.38217209E+01 0.38076240E+01
+ 0.37936232E+01 0.37797176E+01 0.37659061E+01 0.37521878E+01 0.37385616E+01
+ 0.37250266E+01 0.37115819E+01 0.36982264E+01 0.36849593E+01 0.36717796E+01
+ 0.36586864E+01 0.36456789E+01 0.36327562E+01 0.36199173E+01 0.36071614E+01
+ 0.35944878E+01 0.35818955E+01 0.35693837E+01 0.35569516E+01 0.35445985E+01
+ 0.35323235E+01 0.35201258E+01 0.35080047E+01 0.34959594E+01 0.34839892E+01
+ 0.34720933E+01 0.34602710E+01 0.34485215E+01 0.34368443E+01 0.34252385E+01
+ 0.34137035E+01 0.34022385E+01 0.33908430E+01 0.33795162E+01 0.33682575E+01
+ 0.33570662E+01 0.33459417E+01 0.33348834E+01 0.33238906E+01 0.33129628E+01
+ 0.33020992E+01 0.32912994E+01 0.32805626E+01 0.32698884E+01 0.32592761E+01
+ 0.32487252E+01 0.32382351E+01 0.32278053E+01 0.32174351E+01 0.32071241E+01
+ 0.31968716E+01 0.31866773E+01 0.31765405E+01 0.31664607E+01 0.31564374E+01
+ 0.31464702E+01 0.31365584E+01 0.31267017E+01 0.31168995E+01 0.31071513E+01
+ 0.30974566E+01 0.30878151E+01 0.30782262E+01 0.30686894E+01 0.30592043E+01
+ 0.30497705E+01 0.30403874E+01 0.30310548E+01 0.30217720E+01 0.30125388E+01
+ 0.30033546E+01 0.29942191E+01 0.29851318E+01 0.29760923E+01 0.29671003E+01
+ 0.29581552E+01 0.29492568E+01 0.29404046E+01 0.29315982E+01 0.29228373E+01
+ 0.29141215E+01 0.29054503E+01 0.28968235E+01 0.28882406E+01 0.28797013E+01
+ 0.28712053E+01 0.28627521E+01 0.28543414E+01 0.28459729E+01 0.28376463E+01
+ 0.28293611E+01 0.28211171E+01 0.28129139E+01 0.28047512E+01 0.27966287E+01
+ 0.27885460E+01 0.27805029E+01 0.27724989E+01 0.27645338E+01 0.27566074E+01
+ 0.27487192E+01 0.27408690E+01 0.27330565E+01 0.27252813E+01 0.27175433E+01
+ 0.27098420E+01 0.27021773E+01 0.26945487E+01 0.26869562E+01 0.26793993E+01
+ 0.26718778E+01 0.26643914E+01 0.26569398E+01 0.26495229E+01 0.26421403E+01
+ 0.26347917E+01 0.26274769E+01 0.26201957E+01 0.26129478E+01 0.26057329E+01
+ 0.25985507E+01 0.25914012E+01 0.25842839E+01 0.25771987E+01 0.25701453E+01
+ 0.25631235E+01 0.25561330E+01 0.25491737E+01 0.25422452E+01 0.25353474E+01
+ 0.25284801E+01 0.25216429E+01 0.25148357E+01 0.25080583E+01 0.25013105E+01
+ 0.24945920E+01 0.24879026E+01 0.24812422E+01 0.24746105E+01 0.24680072E+01
+ 0.24614323E+01 0.24548854E+01 0.24483665E+01 0.24418753E+01 0.24354115E+01
+ 0.24289751E+01 0.24225658E+01 0.24161834E+01 0.24098277E+01 0.24034986E+01
+ 0.23971958E+01 0.23909193E+01 0.23846687E+01 0.23784439E+01 0.23722448E+01
+ 0.23660711E+01 0.23599227E+01 0.23537994E+01 0.23477011E+01 0.23416275E+01
+ 0.23355785E+01 0.23295539E+01 0.23235536E+01 0.23175774E+01 0.23116252E+01
+ 0.23056967E+01 0.22997918E+01 0.22939103E+01 0.22880522E+01 0.22822172E+01
+ 0.22764052E+01 0.22706160E+01 0.22648495E+01 0.22591055E+01 0.22533840E+01
+ 0.22476846E+01 0.22420073E+01 0.22363520E+01 0.22307185E+01 0.22251066E+01
+ 0.22195162E+01 0.22139473E+01 0.22083995E+01 0.22028729E+01 0.21973672E+01
+ 0.21918823E+01 0.21864181E+01 0.21809745E+01 0.21755513E+01 0.21701484E+01
+ 0.21647657E+01 0.21594030E+01 0.21540602E+01 0.21487372E+01 0.21434339E+01
+ 0.21381501E+01 0.21328857E+01 0.21276406E+01 0.21224147E+01 0.21172078E+01
+ 0.21120198E+01 0.21068507E+01 0.21017003E+01 0.20965684E+01 0.20914550E+01
+ 0.20863600E+01 0.20812832E+01 0.20762245E+01 0.20711838E+01 0.20661610E+01
+ 0.20611561E+01 0.20561688E+01 0.20511991E+01 0.20462469E+01 0.20413120E+01
+ 0.20363944E+01 0.20314939E+01 0.20266106E+01 0.20217441E+01 0.20168945E+01
+ 0.20120617E+01 0.20072455E+01 0.20024459E+01 0.19976627E+01 0.19928959E+01
+ 0.19881453E+01 0.19834109E+01 0.19786925E+01 0.19739902E+01 0.19693037E+01
+ 0.19646330E+01 0.19599780E+01 0.19553386E+01 0.19507147E+01 0.19461062E+01
+ 0.19415131E+01 0.19369352E+01 0.19323725E+01 0.19278248E+01 0.19232922E+01
+ 0.19187744E+01 0.19142714E+01 0.19097832E+01 0.19053096E+01 0.19008506E+01
+ 0.18964060E+01 0.18919759E+01 0.18875600E+01 0.18831584E+01 0.18787710E+01
+ 0.18743976E+01 0.18700383E+01 0.18656928E+01 0.18613612E+01 0.18570434E+01
+ 0.18527392E+01 0.18484487E+01 0.18441717E+01 0.18399081E+01 0.18356580E+01
+ 0.18314211E+01 0.18271976E+01 0.18229871E+01 0.18187898E+01 0.18146055E+01
+ 0.18104342E+01 0.18062758E+01 0.18021301E+01 0.17979972E+01 0.17938770E+01
+ 0.17897695E+01 0.17856744E+01 0.17815918E+01 0.17775217E+01 0.17734639E+01
+ 0.17694183E+01 0.17653850E+01 0.17613638E+01 0.17573548E+01 0.17533577E+01
+ 0.17493726E+01 0.17453994E+01 0.17414380E+01 0.17374884E+01 0.17335505E+01
+ 0.17296242E+01 0.17257096E+01 0.17218064E+01 0.17179148E+01 0.17140345E+01
+ 0.17101656E+01 0.17063080E+01 0.17024616E+01 0.16986264E+01 0.16948023E+01
+ 0.16909893E+01 0.16871873E+01 0.16833963E+01 0.16796161E+01 0.16758468E+01
+ 0.16720882E+01 0.16683404E+01 0.16646033E+01 0.16608768E+01 0.16571609E+01
+ 0.16534555E+01 0.16497605E+01 0.16460760E+01 0.16424018E+01 0.16387380E+01
+ 0.16350844E+01 0.16314410E+01 0.16278078E+01 0.16241847E+01 0.16205716E+01
+ 0.16169686E+01 0.16133755E+01 0.16097923E+01 0.16062190E+01 0.16026556E+01
+ 0.15991018E+01 0.15955579E+01 0.15920236E+01 0.15884989E+01 0.15849838E+01
+ 0.15814782E+01 0.15779822E+01 0.15744956E+01 0.15710184E+01 0.15675505E+01
+ 0.15640920E+01 0.15606427E+01 0.15572027E+01 0.15537718E+01 0.15503501E+01
+ 0.15469375E+01 0.15435339E+01 0.15401394E+01 0.15367538E+01 0.15333772E+01
+ 0.15300094E+01 0.15266505E+01 0.15233004E+01 0.15199590E+01 0.15166264E+01
+ 0.15133025E+01 0.15099872E+01 0.15066805E+01 0.15033824E+01 0.15000928E+01
+ 0.14968117E+01 0.14935391E+01 0.14902749E+01 0.14870190E+01 0.14837715E+01
+ 0.14805323E+01 0.14773013E+01 0.14740786E+01 0.14708640E+01 0.14676577E+01
+ 0.14644594E+01 0.14612692E+01 0.14580871E+01 0.14549129E+01 0.14517468E+01
+ 0.14485886E+01 0.14454382E+01 0.14422958E+01 0.14391612E+01 0.14360344E+01
+ 0.14329154E+01 0.14298040E+01 0.14267004E+01 0.14236045E+01 0.14205162E+01
+ 0.14174355E+01 0.14143624E+01 0.14112968E+01 0.14082387E+01 0.14051881E+01
+ 0.14021449E+01 0.13991092E+01 0.13960808E+01 0.13930598E+01 0.13900460E+01
+ 0.13870396E+01 0.13840404E+01 0.13810485E+01 0.13780637E+01 0.13750861E+01
+ 0.13721157E+01 0.13691523E+01 0.13661961E+01 0.13632468E+01 0.13603046E+01
+ 0.13573694E+01 0.13544411E+01 0.13515198E+01 0.13486054E+01 0.13456978E+01
+ 0.13427972E+01 0.13399033E+01 0.13370162E+01 0.13341359E+01 0.13312623E+01
+ 0.13283954E+01 0.13255352E+01 0.13226817E+01 0.13198348E+01 0.13169945E+01
+ 0.13141608E+01 0.13113336E+01 0.13085130E+01 0.13056988E+01 0.13028912E+01
+ 0.13000899E+01 0.12972951E+01 0.12945068E+01 0.12917247E+01 0.12889491E+01
+ 0.12861797E+01 0.12834167E+01 0.12806599E+01 0.12779094E+01 0.12751651E+01
+ 0.12724270E+01 0.12696951E+01 0.12669694E+01 0.12642498E+01 0.12615362E+01
+ 0.12588288E+01 0.12561275E+01 0.12534322E+01 0.12507429E+01 0.12480596E+01
+ 0.12453822E+01 0.12427108E+01 0.12400454E+01 0.12373858E+01 0.12347322E+01
+ 0.12320844E+01 0.12294424E+01 0.12268063E+01 0.12241759E+01 0.12215514E+01
+ 0.12189326E+01 0.12163195E+01 0.12137121E+01 0.12111105E+01 0.12085145E+01
+ 0.12059241E+01 0.12033394E+01 0.12007603E+01 0.11981868E+01 0.11956188E+01
+ 0.11930564E+01 0.11904996E+01 0.11879482E+01 0.11854024E+01 0.11828620E+01
+ 0.11803271E+01 0.11777975E+01 0.11752735E+01 0.11727548E+01 0.11702415E+01
+ 0.11677335E+01 0.11652309E+01 0.11627336E+01 0.11602416E+01 0.11577549E+01
+ 0.11552734E+01 0.11527972E+01 0.11503263E+01 0.11478605E+01 0.11453999E+01
+ 0.11429445E+01 0.11404943E+01 0.11380492E+01 0.11356093E+01 0.11331744E+01
+ 0.11307446E+01 0.11283199E+01 0.11259003E+01 0.11234857E+01 0.11210761E+01
+ 0.11186715E+01 0.11162719E+01 0.11138773E+01 0.11114876E+01 0.11091029E+01
+ 0.11067231E+01 0.11043482E+01 0.11019782E+01 0.10996131E+01 0.10972528E+01
+ 0.10948973E+01 0.10925467E+01 0.10902009E+01 0.10878599E+01 0.10855237E+01
+ 0.10831923E+01 0.10808656E+01 0.10785436E+01 0.10762263E+01 0.10739138E+01
+ 0.10716059E+01 0.10693028E+01 0.10670042E+01 0.10647104E+01 0.10624211E+01
+ 0.10601365E+01 0.10578565E+01 0.10555810E+01 0.10533102E+01 0.10510438E+01
+ 0.10487821E+01 0.10465249E+01 0.10442721E+01 0.10420239E+01 0.10397802E+01
+ 0.10375410E+01 0.10353062E+01 0.10330759E+01 0.10308500E+01 0.10286285E+01
+ 0.10264114E+01 0.10241988E+01 0.10219905E+01 0.10197866E+01 0.10175870E+01
+ 0.10153918E+01 0.10132009E+01 0.10110144E+01 0.10088321E+01 0.10066541E+01
+ 0.10044804E+01 0.10023110E+01 0.10001458E+01 0.99798491E+00 0.99582822E+00
+ 0.99367574E+00 0.99152747E+00 0.98938339E+00 0.98724349E+00 0.98510777E+00
+ 0.98297620E+00 0.98084877E+00 0.97872548E+00 0.97660631E+00 0.97449126E+00
+ 0.97238030E+00 0.97027343E+00 0.96817063E+00 0.96607190E+00 0.96397723E+00
+ 0.96188659E+00 0.95979999E+00 0.95771740E+00 0.95563882E+00 0.95356424E+00
+ 0.95149365E+00 0.94942703E+00 0.94736438E+00 0.94530568E+00 0.94325093E+00
+ 0.94120010E+00 0.93915320E+00 0.93711021E+00 0.93507112E+00 0.93303592E+00
+ 0.93100460E+00 0.92897715E+00 0.92695355E+00 0.92493381E+00 0.92291791E+00
+ 0.92090583E+00 0.91889757E+00 0.91689312E+00 0.91489247E+00 0.91289561E+00
+ 0.91090252E+00 0.90891320E+00 0.90692765E+00 0.90494584E+00 0.90296777E+00
+ 0.90099343E+00 0.89902281E+00 0.89705591E+00 0.89509270E+00 0.89313319E+00
+ 0.89117736E+00 0.88922520E+00 0.88727670E+00 0.88533186E+00 0.88339067E+00
+ 0.88145311E+00 0.87951918E+00 0.87758887E+00 0.87566217E+00 0.87373906E+00
+ 0.87181955E+00 0.86990362E+00 0.86799127E+00 0.86608248E+00 0.86417725E+00
+ 0.86227556E+00 0.86037741E+00 0.85848280E+00 0.85659170E+00 0.85470412E+00
+ 0.85282004E+00 0.85093946E+00 0.84906237E+00 0.84718876E+00 0.84531862E+00
+ 0.84345194E+00 0.84158872E+00 0.83972894E+00 0.83787261E+00 0.83601970E+00
+ 0.83417022E+00 0.83232415E+00 0.83048149E+00 0.82864222E+00 0.82680635E+00
+ 0.82497386E+00 0.82314475E+00 0.82131900E+00 0.81949662E+00 0.81767758E+00
+ 0.81586189E+00 0.81404954E+00 0.81224051E+00 0.81043481E+00 0.80863242E+00
+ 0.80683334E+00 0.80503756E+00 0.80324507E+00 0.80145587E+00 0.79966994E+00
+ 0.79788728E+00 0.79610788E+00 0.79433174E+00 0.79255885E+00 0.79078920E+00
+ 0.78902279E+00 0.78725960E+00 0.78549963E+00 0.78374288E+00 0.78198933E+00
+ 0.78023898E+00 0.77849182E+00 0.77674784E+00 0.77500705E+00 0.77326943E+00
+ 0.77153497E+00 0.76980367E+00 0.76807552E+00 0.76635052E+00 0.76462866E+00
+ 0.76290992E+00 0.76119432E+00 0.75948183E+00 0.75777245E+00 0.75606618E+00
+ 0.75436301E+00 0.75266293E+00 0.75096593E+00 0.74927202E+00 0.74758118E+00
+ 0.74589340E+00 0.74420869E+00 0.74252703E+00 0.74084843E+00 0.73917286E+00
+ 0.73750033E+00 0.73583083E+00 0.73416435E+00 0.73250089E+00 0.73084045E+00
+ 0.72918300E+00 0.72752856E+00 0.72587712E+00 0.72422866E+00 0.72258318E+00
+ 0.72094068E+00 0.71930115E+00 0.71766458E+00 0.71603097E+00 0.71440032E+00
+ 0.71277261E+00 0.71114784E+00 0.70952601E+00 0.70790711E+00 0.70629113E+00
+ 0.70467808E+00 0.70306793E+00 0.70146069E+00 0.69985636E+00 0.69825492E+00
+ 0.69665637E+00 0.69506071E+00 0.69346793E+00 0.69187802E+00 0.69029098E+00
+ 0.68870681E+00 0.68712549E+00 0.68554703E+00 0.68397142E+00 0.68239865E+00
+ 0.68082871E+00 0.67926161E+00 0.67769734E+00 0.67613588E+00 0.67457725E+00
+ 0.67302142E+00 0.67146840E+00 0.66991818E+00 0.66837076E+00 0.66682613E+00
+ 0.66528429E+00 0.66374522E+00 0.66220894E+00 0.66067542E+00 0.65914467E+00
+ 0.65761668E+00 0.65609145E+00 0.65456897E+00 0.65304923E+00 0.65153224E+00
+ 0.65001798E+00 0.64850646E+00 0.64699766E+00 0.64549158E+00 0.64398823E+00
+ 0.64248758E+00 0.64098965E+00 0.63949441E+00 0.63800188E+00 0.63651204E+00
+ 0.63502489E+00 0.63354043E+00 0.63205864E+00 0.63057954E+00 0.62910310E+00
+ 0.62762933E+00 0.62615822E+00 0.62468977E+00 0.62322397E+00 0.62176082E+00
+ 0.62030032E+00 0.61884245E+00 0.61738723E+00 0.61593463E+00 0.61448466E+00
+ 0.61303731E+00 0.61159258E+00 0.61015046E+00 0.60871095E+00 0.60727405E+00
+ 0.60583975E+00 0.60440804E+00 0.60297893E+00 0.60155240E+00 0.60012846E+00
+ 0.59870710E+00 0.59728831E+00 0.59587210E+00 0.59445845E+00 0.59304736E+00
+ 0.59163884E+00 0.59023287E+00 0.58882945E+00 0.58742857E+00 0.58603024E+00
+ 0.58463445E+00 0.58324119E+00 0.58185046E+00 0.58046226E+00 0.57907658E+00
+ 0.57769342E+00 0.57631277E+00 0.57493463E+00 0.57355901E+00 0.57218588E+00
+ 0.57081525E+00 0.56944712E+00 0.56808148E+00 0.56671832E+00 0.56535765E+00
+ 0.56399946E+00 0.56264375E+00 0.56129051E+00 0.55993973E+00 0.55859142E+00
+ 0.55724557E+00 0.55590218E+00 0.55456124E+00 0.55322275E+00 0.55188670E+00
+ 0.55055310E+00 0.54922194E+00 0.54789321E+00 0.54656691E+00 0.54524304E+00
+ 0.54392159E+00 0.54260257E+00 0.54128596E+00 0.53997176E+00 0.53865997E+00
+ 0.53735059E+00 0.53604361E+00 0.53473903E+00 0.53343684E+00 0.53213705E+00
+ 0.53083964E+00 0.52954462E+00 0.52825198E+00 0.52696172E+00 0.52567383E+00
+ 0.52438831E+00 0.52310516E+00 0.52182438E+00 0.52054595E+00 0.51926988E+00
+ 0.51799616E+00 0.51672480E+00 0.51545578E+00 0.51418910E+00 0.51292477E+00
+ 0.51166277E+00 0.51040310E+00 0.50914577E+00 0.50789076E+00 0.50663808E+00
+ 0.50538771E+00 0.50413966E+00 0.50289393E+00 0.50165050E+00 0.50040939E+00
+ 0.49917057E+00 0.49793406E+00 0.49669984E+00 0.49546792E+00 0.49423829E+00
+ 0.49301095E+00 0.49178589E+00 0.49056311E+00 0.48934261E+00 0.48812439E+00
+ 0.48690844E+00 0.48569475E+00 0.48448333E+00 0.48327418E+00 0.48206728E+00
+ 0.48086264E+00 0.47966025E+00 0.47846011E+00 0.47726222E+00 0.47606657E+00
+ 0.47487316E+00 0.47368200E+00 0.47249306E+00 0.47130636E+00 0.47012188E+00
+ 0.46893963E+00 0.46775960E+00 0.46658180E+00 0.46540620E+00 0.46423282E+00
+ 0.46306166E+00 0.46189270E+00 0.46072594E+00 0.45956138E+00 0.45839903E+00
+ 0.45723887E+00 0.45608090E+00 0.45492512E+00 0.45377153E+00 0.45262012E+00
+ 0.45147089E+00 0.45032384E+00 0.44917896E+00 0.44803626E+00 0.44689573E+00
+ 0.44575736E+00 0.44462115E+00 0.44348711E+00 0.44235522E+00 0.44122549E+00
+ 0.44009791E+00 0.43897248E+00 0.43784920E+00 0.43672806E+00 0.43560906E+00
+ 0.43449220E+00 0.43337747E+00 0.43226488E+00 0.43115441E+00 0.43004608E+00
+ 0.42893986E+00 0.42783577E+00 0.42673379E+00 0.42563393E+00 0.42453619E+00
+ 0.42344055E+00 0.42234702E+00 0.42125559E+00 0.42016627E+00 0.41907904E+00
+ 0.41799392E+00 0.41691088E+00 0.41582994E+00 0.41475108E+00 0.41367431E+00
+ 0.41259962E+00 0.41152702E+00 0.41045649E+00 0.40938803E+00 0.40832165E+00
+ 0.40725733E+00 0.40619508E+00 0.40513490E+00 0.40407678E+00 0.40302071E+00
+ 0.40196671E+00 0.40091475E+00 0.39986485E+00 0.39881699E+00 0.39777118E+00
+ 0.39672741E+00 0.39568569E+00 0.39464600E+00 0.39360834E+00 0.39257272E+00
+ 0.39153912E+00 0.39050756E+00 0.38947802E+00 0.38845050E+00 0.38742500E+00
+ 0.38640152E+00 0.38538005E+00 0.38436059E+00 0.38334314E+00 0.38232770E+00
+ 0.38131426E+00 0.38030283E+00 0.37929339E+00 0.37828595E+00 0.37728050E+00
+ 0.37627705E+00 0.37527558E+00 0.37427610E+00 0.37327860E+00 0.37228309E+00
+ 0.37128955E+00 0.37029799E+00 0.36930840E+00 0.36832078E+00 0.36733514E+00
+ 0.36635146E+00 0.36536974E+00 0.36438998E+00 0.36341218E+00 0.36243634E+00
+ 0.36146245E+00 0.36049051E+00 0.35952052E+00 0.35855248E+00 0.35758638E+00
+ 0.35662223E+00 0.35566001E+00 0.35469972E+00 0.35374138E+00 0.35278496E+00
+ 0.35183047E+00 0.35087791E+00 0.34992727E+00 0.34897856E+00 0.34803176E+00
+ 0.34708688E+00 0.34614392E+00 0.34520287E+00 0.34426372E+00 0.34332649E+00
+ 0.34239116E+00 0.34145773E+00 0.34052620E+00 0.33959657E+00 0.33866883E+00
+ 0.33774299E+00 0.33681903E+00 0.33589697E+00 0.33497679E+00 0.33405849E+00
+ 0.33314207E+00 0.33222754E+00 0.33131487E+00 0.33040409E+00 0.32949517E+00
+ 0.32858812E+00 0.32768294E+00 0.32677962E+00 0.32587817E+00 0.32497857E+00
+ 0.32408083E+00 0.32318494E+00 0.32229091E+00 0.32139873E+00 0.32050839E+00
+ 0.31961990E+00 0.31873326E+00 0.31784845E+00 0.31696548E+00 0.31608435E+00
+ 0.31520505E+00 0.31432758E+00 0.31345194E+00 0.31257813E+00 0.31170614E+00
+ 0.31083597E+00 0.30996762E+00 0.30910109E+00 0.30823638E+00 0.30737348E+00
+ 0.30651238E+00 0.30565310E+00 0.30479562E+00 0.30393994E+00 0.30308607E+00
+ 0.30223399E+00 0.30138371E+00 0.30053523E+00 0.29968853E+00 0.29884363E+00
+ 0.29800051E+00 0.29715917E+00 0.29631962E+00 0.29548185E+00 0.29464586E+00
+ 0.29381164E+00 0.29297920E+00 0.29214853E+00 0.29131962E+00 0.29049249E+00
+ 0.28966711E+00 0.28884350E+00 0.28802165E+00 0.28720156E+00 0.28638322E+00
+ 0.28556663E+00 0.28475180E+00 0.28393871E+00 0.28312737E+00 0.28231777E+00
+ 0.28150991E+00 0.28070380E+00 0.27989942E+00 0.27909677E+00 0.27829586E+00
+ 0.27749667E+00 0.27669922E+00 0.27590349E+00 0.27510948E+00 0.27431720E+00
+ 0.27352663E+00 0.27273778E+00 0.27195064E+00 0.27116522E+00 0.27038151E+00
+ 0.26959950E+00 0.26881920E+00 0.26804060E+00 0.26726370E+00 0.26648851E+00
+ 0.26571500E+00 0.26494320E+00 0.26417308E+00 0.26340465E+00 0.26263791E+00
+ 0.26187286E+00 0.26110949E+00 0.26034780E+00 0.25958778E+00 0.25882945E+00
+ 0.25807279E+00 0.25731780E+00 0.25656448E+00 0.25581282E+00 0.25506283E+00
+ 0.25431451E+00 0.25356784E+00 0.25282284E+00 0.25207949E+00 0.25133779E+00
+ 0.25059774E+00 0.24985935E+00 0.24912260E+00 0.24838750E+00 0.24765404E+00
+ 0.24692222E+00 0.24619204E+00 0.24546349E+00 0.24473658E+00 0.24401130E+00
+ 0.24328765E+00 0.24256563E+00 0.24184523E+00 0.24112645E+00 0.24040930E+00
+ 0.23969376E+00 0.23897984E+00 0.23826754E+00 0.23755685E+00 0.23684776E+00
+ 0.23614028E+00 0.23543441E+00 0.23473014E+00 0.23402748E+00 0.23332641E+00
+ 0.23262694E+00 0.23192906E+00 0.23123277E+00 0.23053807E+00 0.22984496E+00
+ 0.22915344E+00 0.22846350E+00 0.22777514E+00 0.22708836E+00 0.22640315E+00
+ 0.22571952E+00 0.22503747E+00 0.22435698E+00 0.22367806E+00 0.22300070E+00
+ 0.22232491E+00 0.22165068E+00 0.22097801E+00 0.22030690E+00 0.21963734E+00
+ 0.21896933E+00 0.21830288E+00 0.21763797E+00 0.21697461E+00 0.21631279E+00
+ 0.21565251E+00 0.21499377E+00 0.21433657E+00 0.21368090E+00 0.21302677E+00
+ 0.21237417E+00 0.21172309E+00 0.21107355E+00 0.21042552E+00 0.20977902E+00
+ 0.20913404E+00 0.20849057E+00 0.20784862E+00 0.20720819E+00 0.20656926E+00
+ 0.20593184E+00 0.20529593E+00 0.20466153E+00 0.20402862E+00 0.20339722E+00
+ 0.20276731E+00 0.20213890E+00 0.20151199E+00 0.20088656E+00 0.20026262E+00
+ 0.19964017E+00 0.19901921E+00 0.19839973E+00 0.19778173E+00 0.19716520E+00
+ 0.19655015E+00 0.19593658E+00 0.19532448E+00 0.19471385E+00 0.19410468E+00
+ 0.19349698E+00 0.19289075E+00 0.19228597E+00 0.19168265E+00 0.19108079E+00
+ 0.19048039E+00 0.18988143E+00 0.18928393E+00 0.18868787E+00 0.18809326E+00
+ 0.18750010E+00 0.18690837E+00 0.18631809E+00 0.18572924E+00 0.18514182E+00
+ 0.18455584E+00 0.18397129E+00 0.18338817E+00 0.18280647E+00 0.18222620E+00
+ 0.18164735E+00 0.18106991E+00 0.18049390E+00 0.17991930E+00 0.17934612E+00
+ 0.17877434E+00 0.17820398E+00 0.17763502E+00 0.17706747E+00 0.17650131E+00
+ 0.17593656E+00 0.17537321E+00 0.17481125E+00 0.17425069E+00 0.17369152E+00
+ 0.17313373E+00 0.17257734E+00 0.17202233E+00 0.17146870E+00 0.17091646E+00
+ 0.17036559E+00 0.16981610E+00 0.16926798E+00 0.16872123E+00 0.16817586E+00
+ 0.16763185E+00 0.16708921E+00 0.16654793E+00 0.16600802E+00 0.16546946E+00
+ 0.16493226E+00 0.16439641E+00 0.16386192E+00 0.16332878E+00 0.16279699E+00
+ 0.16226654E+00 0.16173744E+00 0.16120968E+00 0.16068326E+00 0.16015817E+00
+ 0.15963443E+00 0.15911201E+00 0.15859093E+00 0.15807118E+00 0.15755275E+00
+ 0.15703565E+00 0.15651987E+00 0.15600541E+00 0.15549227E+00 0.15498045E+00
+ 0.15446994E+00 0.15396074E+00 0.15345285E+00 0.15294627E+00 0.15244100E+00
+ 0.15193702E+00 0.15143435E+00 0.15093298E+00 0.15043291E+00 0.14993413E+00
+ 0.14943664E+00 0.14894045E+00 0.14844554E+00 0.14795192E+00 0.14745958E+00
+ 0.14696853E+00 0.14647875E+00 0.14599025E+00 0.14550303E+00 0.14501708E+00
+ 0.14453241E+00 0.14404900E+00 0.14356686E+00 0.14308598E+00 0.14260637E+00
+ 0.14212801E+00 0.14165092E+00 0.14117508E+00 0.14070050E+00 0.14022717E+00
+ 0.13975509E+00 0.13928425E+00 0.13881466E+00 0.13834632E+00 0.13787922E+00
+ 0.13741335E+00 0.13694873E+00 0.13648534E+00 0.13602318E+00 0.13556225E+00
+ 0.13510255E+00 0.13464408E+00 0.13418683E+00 0.13373080E+00 0.13327600E+00
+ 0.13282241E+00 0.13237004E+00 0.13191888E+00 0.13146894E+00 0.13102020E+00
+ 0.13057267E+00 0.13012635E+00 0.12968123E+00 0.12923731E+00 0.12879459E+00
+ 0.12835307E+00 0.12791274E+00 0.12747360E+00 0.12703566E+00 0.12659890E+00
+ 0.12616333E+00 0.12572895E+00 0.12529574E+00 0.12486372E+00 0.12443287E+00
+ 0.12400320E+00 0.12357470E+00 0.12314738E+00 0.12272122E+00 0.12229624E+00
+ 0.12187241E+00 0.12144975E+00 0.12102825E+00 0.12060791E+00 0.12018873E+00
+ 0.11977070E+00 0.11935383E+00 0.11893810E+00 0.11852352E+00 0.11811009E+00
+ 0.11769781E+00 0.11728666E+00 0.11687666E+00 0.11646779E+00 0.11606006E+00
+ 0.11565346E+00 0.11524800E+00 0.11484366E+00 0.11444045E+00 0.11403837E+00
+ 0.11363741E+00 0.11323754E+00 0.11283769E+00 0.11243732E+00 0.11203644E+00
+ 0.11163506E+00 0.11123318E+00 0.11083082E+00 0.11042799E+00 0.11002468E+00
+ 0.10962092E+00 0.10921670E+00 0.10881205E+00 0.10840695E+00 0.10800144E+00
+ 0.10759550E+00 0.10718916E+00 0.10678241E+00 0.10637527E+00 0.10596775E+00
+ 0.10555985E+00 0.10515158E+00 0.10474296E+00 0.10433398E+00 0.10392467E+00
+ 0.10351501E+00 0.10310504E+00 0.10269474E+00 0.10228414E+00 0.10187324E+00
+ 0.10146204E+00 0.10105056E+00 0.10063881E+00 0.10022679E+00 0.99814508E-01
+ 0.99401979E-01 0.98989207E-01 0.98576203E-01 0.98162973E-01 0.97749527E-01
+ 0.97335873E-01 0.96922019E-01 0.96507973E-01 0.96093744E-01 0.95679341E-01
+ 0.95264771E-01 0.94850044E-01 0.94435167E-01 0.94020149E-01 0.93604998E-01
+ 0.93189722E-01 0.92774331E-01 0.92358832E-01 0.91943234E-01 0.91527545E-01
+ 0.91111773E-01 0.90695927E-01 0.90280016E-01 0.89864047E-01 0.89448029E-01
+ 0.89031970E-01 0.88615880E-01 0.88199765E-01 0.87783635E-01 0.87367498E-01
+ 0.86951362E-01 0.86535236E-01 0.86119128E-01 0.85703047E-01 0.85287000E-01
+ 0.84870996E-01 0.84455044E-01 0.84039152E-01 0.83623328E-01 0.83207581E-01
+ 0.82791919E-01 0.82376351E-01 0.81960884E-01 0.81545528E-01 0.81130290E-01
+ 0.80715179E-01 0.80300204E-01 0.79885372E-01 0.79470693E-01 0.79056174E-01
+ 0.78641824E-01 0.78227651E-01 0.77813664E-01 0.77399870E-01 0.76986280E-01
+ 0.76572900E-01 0.76159739E-01 0.75746805E-01 0.75334108E-01 0.74921655E-01
+ 0.74509455E-01 0.74097515E-01 0.73685845E-01 0.73274453E-01 0.72863347E-01
+ 0.72452536E-01 0.72042028E-01 0.71631831E-01 0.71221954E-01 0.70812404E-01
+ 0.70403192E-01 0.69994324E-01 0.69585809E-01 0.69177656E-01 0.68769873E-01
+ 0.68362469E-01 0.67955451E-01 0.67548828E-01 0.67142609E-01 0.66736802E-01
+ 0.66331414E-01 0.65926456E-01 0.65521935E-01 0.65117859E-01 0.64714237E-01
+ 0.64311077E-01 0.63908387E-01 0.63506177E-01 0.63104454E-01 0.62703226E-01
+ 0.62302503E-01 0.61902292E-01 0.61502601E-01 0.61103440E-01 0.60704817E-01
+ 0.60306740E-01 0.59909217E-01 0.59512256E-01 0.59115867E-01 0.58720057E-01
+ 0.58324836E-01 0.57930210E-01 0.57536189E-01 0.57142781E-01 0.56749994E-01
+ 0.56357837E-01 0.55966319E-01 0.55575446E-01 0.55185229E-01 0.54795675E-01
+ 0.54406793E-01 0.54018590E-01 0.53631076E-01 0.53244259E-01 0.52858147E-01
+ 0.52472749E-01 0.52088073E-01 0.51704126E-01 0.51320919E-01 0.50938459E-01
+ 0.50556754E-01 0.50175813E-01 0.49795644E-01 0.49416256E-01 0.49037656E-01
+ 0.48659854E-01 0.48282858E-01 0.47906676E-01 0.47531316E-01 0.47156788E-01
+ 0.46783098E-01 0.46410256E-01 0.46038271E-01 0.45667149E-01 0.45296900E-01
+ 0.44927533E-01 0.44559055E-01 0.44191475E-01 0.43824801E-01 0.43459042E-01
+ 0.43094206E-01 0.42730301E-01 0.42367336E-01 0.42005319E-01 0.41644259E-01
+ 0.41284164E-01 0.40925042E-01 0.40566902E-01 0.40209752E-01 0.39853600E-01
+ 0.39498455E-01 0.39144326E-01 0.38791220E-01 0.38439146E-01 0.38088112E-01
+ 0.37738127E-01 0.37389200E-01 0.37041337E-01 0.36694549E-01 0.36348843E-01
+ 0.36004227E-01 0.35660711E-01 0.35318302E-01 0.34977008E-01 0.34636839E-01
+ 0.34297802E-01 0.33959907E-01 0.33623160E-01 0.33287571E-01 0.32953149E-01
+ 0.32619900E-01 0.32287835E-01 0.31956961E-01 0.31627286E-01 0.31298819E-01
+ 0.30971569E-01 0.30645543E-01 0.30320750E-01 0.29997199E-01 0.29674898E-01
+ 0.29353855E-01 0.29034078E-01 0.28715577E-01 0.28398359E-01 0.28082432E-01
+ 0.27767806E-01 0.27454488E-01 0.27142487E-01 0.26831811E-01 0.26522469E-01
+ 0.26214470E-01 0.25907820E-01 0.25602529E-01 0.25298606E-01 0.24996057E-01
+ 0.24694893E-01 0.24395121E-01 0.24096750E-01 0.23799788E-01 0.23504243E-01
+ 0.23210124E-01 0.22917440E-01 0.22626198E-01 0.22336406E-01 0.22048075E-01
+ 0.21761211E-01 0.21475822E-01 0.21191919E-01 0.20909508E-01 0.20628599E-01
+ 0.20349199E-01 0.20071317E-01 0.19794962E-01 0.19520141E-01 0.19246863E-01
+ 0.18975137E-01 0.18704971E-01 0.18436373E-01 0.18169352E-01 0.17903915E-01
+ 0.17640073E-01 0.17377832E-01 0.17117201E-01 0.16858188E-01 0.16600803E-01
+ 0.16345053E-01 0.16090946E-01 0.15838492E-01 0.15587698E-01 0.15338573E-01
+ 0.15091125E-01 0.14845363E-01 0.14601294E-01 0.14358928E-01 0.14118273E-01
+ 0.13879337E-01 0.13642128E-01 0.13406655E-01 0.13172926E-01 0.12940950E-01
+ 0.12710735E-01 0.12482290E-01 0.12255622E-01 0.12030740E-01 0.11807653E-01
+ 0.11586369E-01 0.11366896E-01 0.11149242E-01 0.10933417E-01 0.10719428E-01
+ 0.10507284E-01 0.10296993E-01 0.10088563E-01 0.98820037E-02 0.96773225E-02
+ 0.94745280E-02 0.92736285E-02 0.90746326E-02 0.88775484E-02 0.86823845E-02
+ 0.84891491E-02 0.82978507E-02 0.81084977E-02 0.79210983E-02 0.77356611E-02
+ 0.75521944E-02 0.73707066E-02 0.71912059E-02 0.70137009E-02 0.68382000E-02
+ 0.66647114E-02 0.64932435E-02 0.63238048E-02 0.61564036E-02 0.59910484E-02
+ 0.58277474E-02 0.56665091E-02 0.55073418E-02 0.53502539E-02 0.51952538E-02
+ 0.50423499E-02 0.48915506E-02 0.47428642E-02 0.45962991E-02 0.44518637E-02
+ 0.43095664E-02 0.41694156E-02 0.40314196E-02 0.38955868E-02 0.37619256E-02
+ 0.36304443E-02 0.35011515E-02 0.33740553E-02 0.32491643E-02 0.31264867E-02
+ 0.30060311E-02 0.28878057E-02 0.27718189E-02 0.26580791E-02 0.25465947E-02
+ 0.24373741E-02 0.23304256E-02 0.22257577E-02 0.21233787E-02 0.20232969E-02
+ 0.19255208E-02 0.18300588E-02 0.17369192E-02 0.16461104E-02 0.15576408E-02
+ 0.14715188E-02 0.13877527E-02 0.13063509E-02 0.12273218E-02 0.11506738E-02
+ 0.10764153E-02 0.10045546E-02 0.93510013E-03 0.86806026E-03 0.80344337E-03
+ 0.74125785E-03 0.68151206E-03 0.62421439E-03 0.56937323E-03 0.51699694E-03
+ 0.46709390E-03 0.41967251E-03 0.37474113E-03 0.33230815E-03 0.29238194E-03
+ 0.25497089E-03 0.22008337E-03 0.18772777E-03 0.15791246E-03 0.13064582E-03
+ 0.10593624E-03 0.83792089E-04 0.64221751E-04 0.47233605E-04 0.32836029E-04
+ 0.21037404E-04 0.11846109E-04 0.52705237E-05 0.13190275E-05 0.00000000E+00
+ 0.13096464E-01 0.13579127E-01 0.14061790E-01 0.14544453E-01 0.15027115E-01
+ 0.15509778E-01 0.15992441E-01 0.16475104E-01 0.16957766E-01 0.17440429E-01
+ 0.17923092E-01 0.18405755E-01 0.18888417E-01 0.19371080E-01 0.19853743E-01
+ 0.20336406E-01 0.20819068E-01 0.21301731E-01 0.21784394E-01 0.22267057E-01
+ 0.22749719E-01 0.23232382E-01 0.23715045E-01 0.24197708E-01 0.24680370E-01
+ 0.25163033E-01 0.25645696E-01 0.26128359E-01 0.26611021E-01 0.27093684E-01
+ 0.27576347E-01 0.28059010E-01 0.28541672E-01 0.29024335E-01 0.29506998E-01
+ 0.29989661E-01 0.30472323E-01 0.30954986E-01 0.31437649E-01 0.31920312E-01
+ 0.32402974E-01 0.32885637E-01 0.33368300E-01 0.33850963E-01 0.34333625E-01
+ 0.34816288E-01 0.35298951E-01 0.35781614E-01 0.36264276E-01 0.36746939E-01
+ 0.37229602E-01 0.37712265E-01 0.38194927E-01 0.38677590E-01 0.39160253E-01
+ 0.39642916E-01 0.40125578E-01 0.40608241E-01 0.41090904E-01 0.41573567E-01
+ 0.42056229E-01 0.42538892E-01 0.43021555E-01 0.43504218E-01 0.43986880E-01
+ 0.44469543E-01 0.44952206E-01 0.45434869E-01 0.45917531E-01 0.46400194E-01
+ 0.46882857E-01 0.47365520E-01 0.47848182E-01 0.48330845E-01 0.48813508E-01
+ 0.49296171E-01 0.49778833E-01 0.50261496E-01 0.50744159E-01 0.51226822E-01
+ 0.51709484E-01 0.52192147E-01 0.52674810E-01 0.53157473E-01 0.53640135E-01
+ 0.54122798E-01 0.54605461E-01 0.55088124E-01 0.55570786E-01 0.56053449E-01
+ 0.56536112E-01 0.57018775E-01 0.57501437E-01 0.57984100E-01 0.58466763E-01
+ 0.58949426E-01 0.59432088E-01 0.59914751E-01 0.60397414E-01 0.60880077E-01
+ 0.61362740E-01 0.61845402E-01 0.62328065E-01 0.62810728E-01 0.63293391E-01
+ 0.63776053E-01 0.64258716E-01 0.64741379E-01 0.65224042E-01 0.65706704E-01
+ 0.66189367E-01 0.66672030E-01 0.67154693E-01 0.67637355E-01 0.68120018E-01
+ 0.68602681E-01 0.69085344E-01 0.69568006E-01 0.70050669E-01 0.70533332E-01
+ 0.71015995E-01 0.71498657E-01 0.71981320E-01 0.72463983E-01 0.72946646E-01
+ 0.73429308E-01 0.73911971E-01 0.74394634E-01 0.74877297E-01 0.75359959E-01
+ 0.75842622E-01 0.76325285E-01 0.76807948E-01 0.77290610E-01 0.77773273E-01
+ 0.78255936E-01 0.78738599E-01 0.79221261E-01 0.79703924E-01 0.80186587E-01
+ 0.80669250E-01 0.81151912E-01 0.81634575E-01 0.82117238E-01 0.82599901E-01
+ 0.83082563E-01 0.83565226E-01 0.84047889E-01 0.84530552E-01 0.85013214E-01
+ 0.85495877E-01 0.85978540E-01 0.86461203E-01 0.86943865E-01 0.87426528E-01
+ 0.87909191E-01 0.88391854E-01 0.88874516E-01 0.89357179E-01 0.89839842E-01
+ 0.90322505E-01 0.90805167E-01 0.91287830E-01 0.91770493E-01 0.92253156E-01
+ 0.92735818E-01 0.93218481E-01 0.93701144E-01 0.94183807E-01 0.94666469E-01
+ 0.95149132E-01 0.95631795E-01 0.96114458E-01 0.96597120E-01 0.97079783E-01
+ 0.97562446E-01 0.98045109E-01 0.98527771E-01 0.99010434E-01 0.99493097E-01
+ 0.99975760E-01 0.10045842E+00 0.10094109E+00 0.10142375E+00 0.10190641E+00
+ 0.10238907E+00 0.10287174E+00 0.10335440E+00 0.10383706E+00 0.10431972E+00
+ 0.10480239E+00 0.10528505E+00 0.10576771E+00 0.10625038E+00 0.10673304E+00
+ 0.10721570E+00 0.10769836E+00 0.10818103E+00 0.10866369E+00 0.10914635E+00
+ 0.10962901E+00 0.11011168E+00 0.11059434E+00 0.11107700E+00 0.11155967E+00
+ 0.11204233E+00 0.11252499E+00 0.11300765E+00 0.11349032E+00 0.11397298E+00
+ 0.11445564E+00 0.11493830E+00 0.11542097E+00 0.11590363E+00 0.11638629E+00
+ 0.11686896E+00 0.11735162E+00 0.11783428E+00 0.11831694E+00 0.11879961E+00
+ 0.11928227E+00 0.11976493E+00 0.12024760E+00 0.12073026E+00 0.12121292E+00
+ 0.12169558E+00 0.12217825E+00 0.12266091E+00 0.12314357E+00 0.12362623E+00
+ 0.12410890E+00 0.12459156E+00 0.12507422E+00 0.12555689E+00 0.12603955E+00
+ 0.12652221E+00 0.12700487E+00 0.12748754E+00 0.12797020E+00 0.12845286E+00
+ 0.12893552E+00 0.12941819E+00 0.12990085E+00 0.13038351E+00 0.13086618E+00
+ 0.13134884E+00 0.13183150E+00 0.13231416E+00 0.13279683E+00 0.13327949E+00
+ 0.13376215E+00 0.13424482E+00 0.13472748E+00 0.13521014E+00 0.13569280E+00
+ 0.13617547E+00 0.13665813E+00 0.13714079E+00 0.13762345E+00 0.13810612E+00
+ 0.13858878E+00 0.13907144E+00 0.13955411E+00 0.14003677E+00 0.14051943E+00
+ 0.14100209E+00 0.14148476E+00 0.14196742E+00 0.14245008E+00 0.14293274E+00
+ 0.14341541E+00 0.14389807E+00 0.14438073E+00 0.14486340E+00 0.14534606E+00
+ 0.14582872E+00 0.14631138E+00 0.14679405E+00 0.14727671E+00 0.14775937E+00
+ 0.14824203E+00 0.14872470E+00 0.14920736E+00 0.14969002E+00 0.15017269E+00
+ 0.15065535E+00 0.15113801E+00 0.15162067E+00 0.15210334E+00 0.15258600E+00
+ 0.15306866E+00 0.15355133E+00 0.15403399E+00 0.15451665E+00 0.15499931E+00
+ 0.15548198E+00 0.15596464E+00 0.15644730E+00 0.15692996E+00 0.15741263E+00
+ 0.15789529E+00 0.15837795E+00 0.15886062E+00 0.15934328E+00 0.15982594E+00
+ 0.16030860E+00 0.16079127E+00 0.16127393E+00 0.16175659E+00 0.16223925E+00
+ 0.16272192E+00 0.16320458E+00 0.16368724E+00 0.16416991E+00 0.16465257E+00
+ 0.16513523E+00 0.16561789E+00 0.16610056E+00 0.16658322E+00 0.16706588E+00
+ 0.16754854E+00 0.16803121E+00 0.16851387E+00 0.16899653E+00 0.16947920E+00
+ 0.16996186E+00 0.17044452E+00 0.17092718E+00 0.17140985E+00 0.17189251E+00
+ 0.17237517E+00 0.17285784E+00 0.17334050E+00 0.17382316E+00 0.17430582E+00
+ 0.17478849E+00 0.17527115E+00 0.17575381E+00 0.17623647E+00 0.17671914E+00
+ 0.17720180E+00 0.17768446E+00 0.17816713E+00 0.17864979E+00 0.17913245E+00
+ 0.17961511E+00 0.18009778E+00 0.18058044E+00 0.18106310E+00 0.18154576E+00
+ 0.18202843E+00 0.18251109E+00 0.18299375E+00 0.18347642E+00 0.18395908E+00
+ 0.18444174E+00 0.18492440E+00 0.18540707E+00 0.18588973E+00 0.18637239E+00
+ 0.18685505E+00 0.18733772E+00 0.18782038E+00 0.18830304E+00 0.18878571E+00
+ 0.18926837E+00 0.18975103E+00 0.19023369E+00 0.19071636E+00 0.19119902E+00
+ 0.19168168E+00 0.19216435E+00 0.19264701E+00 0.19312967E+00 0.19361233E+00
+ 0.19409500E+00 0.19457766E+00 0.19506032E+00 0.19554298E+00 0.19602565E+00
+ 0.19650831E+00 0.19699097E+00 0.19747364E+00 0.19795630E+00 0.19843896E+00
+ 0.19892162E+00 0.19940429E+00 0.19988695E+00 0.20036961E+00 0.20085227E+00
+ 0.20133494E+00 0.20181760E+00 0.20230026E+00 0.20278293E+00 0.20326559E+00
+ 0.20374825E+00 0.20423091E+00 0.20471358E+00 0.20519624E+00 0.20567890E+00
+ 0.20616157E+00 0.20664423E+00 0.20712689E+00 0.20760955E+00 0.20809222E+00
+ 0.20857488E+00 0.20905754E+00 0.20954020E+00 0.21002287E+00 0.21050553E+00
+ 0.21098819E+00 0.21147086E+00 0.21195352E+00 0.21243618E+00 0.21291884E+00
+ 0.21340151E+00 0.21388417E+00 0.21436683E+00 0.21484949E+00 0.21533216E+00
+ 0.21581482E+00 0.21629748E+00 0.21678015E+00 0.21726281E+00 0.21774547E+00
+ 0.21822813E+00 0.21871080E+00 0.21919346E+00 0.21967612E+00 0.22015878E+00
+ 0.22064145E+00 0.22112411E+00 0.22160677E+00 0.22208944E+00 0.22257210E+00
+ 0.22305476E+00 0.22353742E+00 0.22402009E+00 0.22450275E+00 0.22498541E+00
+ 0.22546808E+00 0.22595074E+00 0.22643340E+00 0.22691606E+00 0.22739873E+00
+ 0.22788139E+00 0.22836405E+00 0.22884671E+00 0.22932938E+00 0.22981204E+00
+ 0.23029470E+00 0.23077737E+00 0.23126003E+00 0.23174269E+00 0.23222535E+00
+ 0.23270802E+00 0.23319068E+00 0.23367334E+00 0.23415600E+00 0.23463867E+00
+ 0.23512133E+00 0.23560399E+00 0.23608666E+00 0.23656932E+00 0.23705198E+00
+ 0.23753464E+00 0.23801731E+00 0.23849997E+00 0.23898263E+00 0.23946529E+00
+ 0.23994796E+00 0.24043062E+00 0.24091328E+00 0.24139595E+00 0.24187861E+00
+ 0.24236127E+00 0.24284393E+00 0.24332660E+00 0.24380926E+00 0.24429192E+00
+ 0.24477459E+00 0.24525725E+00 0.24573991E+00 0.24622257E+00 0.24670524E+00
+ 0.24718790E+00 0.24767056E+00 0.24815322E+00 0.24863589E+00 0.24911855E+00
+ 0.24960121E+00 0.25008388E+00 0.25056654E+00 0.25104920E+00 0.25153186E+00
+ 0.25201453E+00 0.25249719E+00 0.25297985E+00 0.25346251E+00 0.25394518E+00
+ 0.25442784E+00 0.25491050E+00 0.25539317E+00 0.25587583E+00 0.25635849E+00
+ 0.25684115E+00 0.25732382E+00 0.25780648E+00 0.25828914E+00 0.25877180E+00
+ 0.25925447E+00 0.25973713E+00 0.26021979E+00 0.26070246E+00 0.26118512E+00
+ 0.26166778E+00 0.26215044E+00 0.26263311E+00 0.26311577E+00 0.26359843E+00
+ 0.26408110E+00 0.26456376E+00 0.26504642E+00 0.26552908E+00 0.26601175E+00
+ 0.26649441E+00 0.26697707E+00 0.26745973E+00 0.26794240E+00 0.26842506E+00
+ 0.26890772E+00 0.26939039E+00 0.26987305E+00 0.27035571E+00 0.27083837E+00
+ 0.27132104E+00 0.27180370E+00 0.27228636E+00 0.27276902E+00 0.27325169E+00
+ 0.27373435E+00 0.27421701E+00 0.27469968E+00 0.27518234E+00 0.27566500E+00
+ 0.27614766E+00 0.27663033E+00 0.27711299E+00 0.27759565E+00 0.27807832E+00
+ 0.27856098E+00 0.27904364E+00 0.27952630E+00 0.28000897E+00 0.28049163E+00
+ 0.28097429E+00 0.28145695E+00 0.28193962E+00 0.28242228E+00 0.28290494E+00
+ 0.28338761E+00 0.28387027E+00 0.28435293E+00 0.28483559E+00 0.28531826E+00
+ 0.28580092E+00 0.28628358E+00 0.28676624E+00 0.28724891E+00 0.28773157E+00
+ 0.28821423E+00 0.28869690E+00 0.28917956E+00 0.28966222E+00 0.29014488E+00
+ 0.29062755E+00 0.29111021E+00 0.29159287E+00 0.29207553E+00 0.29255820E+00
+ 0.29304086E+00 0.29352352E+00 0.29400619E+00 0.29448885E+00 0.29497151E+00
+ 0.29545417E+00 0.29593684E+00 0.29641950E+00 0.29690216E+00 0.29738483E+00
+ 0.29786749E+00 0.29835015E+00 0.29883281E+00 0.29931548E+00 0.29979814E+00
+ 0.30028080E+00 0.30076346E+00 0.30124613E+00 0.30172879E+00 0.30221145E+00
+ 0.30269412E+00 0.30317678E+00 0.30365944E+00 0.30414210E+00 0.30462477E+00
+ 0.30510743E+00 0.30559009E+00 0.30607275E+00 0.30655542E+00 0.30703808E+00
+ 0.30752074E+00 0.30800341E+00 0.30848607E+00 0.30896873E+00 0.30945139E+00
+ 0.30993406E+00 0.31041672E+00 0.31089938E+00 0.31138204E+00 0.31186471E+00
+ 0.31234737E+00 0.31283003E+00 0.31331270E+00 0.31379536E+00 0.31427802E+00
+ 0.31476068E+00 0.31524335E+00 0.31572601E+00 0.31620867E+00 0.31669134E+00
+ 0.31717400E+00 0.31765666E+00 0.31813932E+00 0.31862199E+00 0.31910465E+00
+ 0.31958731E+00 0.32006997E+00 0.32055264E+00 0.32103530E+00 0.32151796E+00
+ 0.32200063E+00 0.32248329E+00 0.32296595E+00 0.32344861E+00 0.32393128E+00
+ 0.32441394E+00 0.32489660E+00 0.32537926E+00 0.32586193E+00 0.32634459E+00
+ 0.32682725E+00 0.32730992E+00 0.32779258E+00 0.32827524E+00 0.32875790E+00
+ 0.32924057E+00 0.32972323E+00 0.33020589E+00 0.33068856E+00 0.33117122E+00
+ 0.33165388E+00 0.33213654E+00 0.33261921E+00 0.33310187E+00 0.33358453E+00
+ 0.33406719E+00 0.33454986E+00 0.33503252E+00 0.33551518E+00 0.33599785E+00
+ 0.33648051E+00 0.33696317E+00 0.33744583E+00 0.33792850E+00 0.33841116E+00
+ 0.33889382E+00 0.33937648E+00 0.33985915E+00 0.34034181E+00 0.34082447E+00
+ 0.34130714E+00 0.34178980E+00 0.34227246E+00 0.34275512E+00 0.34323779E+00
+ 0.34372045E+00 0.34420311E+00 0.34468577E+00 0.34516844E+00 0.34565110E+00
+ 0.34613376E+00 0.34661643E+00 0.34709909E+00 0.34758175E+00 0.34806441E+00
+ 0.34854708E+00 0.34902974E+00 0.34951240E+00 0.34999507E+00 0.35047773E+00
+ 0.35096039E+00 0.35144305E+00 0.35192572E+00 0.35240838E+00 0.35289104E+00
+ 0.35337370E+00 0.35385637E+00 0.35433903E+00 0.35482169E+00 0.35530436E+00
+ 0.35578702E+00 0.35626968E+00 0.35675234E+00 0.35723501E+00 0.35771767E+00
+ 0.35820033E+00 0.35868299E+00 0.35916566E+00 0.35964832E+00 0.36013098E+00
+ 0.36061365E+00 0.36109631E+00 0.36157897E+00 0.36206163E+00 0.36254430E+00
+ 0.36302696E+00 0.36350962E+00 0.36399228E+00 0.36447495E+00 0.36495761E+00
+ 0.36544027E+00 0.36592294E+00 0.36640560E+00 0.36688826E+00 0.36737092E+00
+ 0.36785359E+00 0.36833625E+00 0.36881891E+00 0.36930158E+00 0.36978424E+00
+ 0.37026690E+00 0.37074956E+00 0.37123223E+00 0.37171489E+00 0.37219755E+00
+ 0.37268021E+00 0.37316288E+00 0.37364554E+00 0.37412820E+00 0.37461087E+00
+ 0.37509353E+00 0.37557619E+00 0.37605885E+00 0.37654152E+00 0.37702418E+00
+ 0.37750684E+00 0.37798950E+00 0.37847217E+00 0.37895483E+00 0.37943749E+00
+ 0.37992016E+00 0.38040282E+00 0.38088548E+00 0.38136814E+00 0.38185081E+00
+ 0.38233347E+00 0.38281613E+00 0.38329879E+00 0.38378146E+00 0.38426412E+00
+ 0.38474678E+00 0.38522945E+00 0.38571211E+00 0.38619477E+00 0.38667743E+00
+ 0.38716010E+00 0.38764276E+00 0.38812542E+00 0.38860809E+00 0.38909075E+00
+ 0.38957341E+00 0.39005607E+00 0.39053874E+00 0.39102140E+00 0.39150406E+00
+ 0.39198672E+00 0.39246939E+00 0.39295205E+00 0.39343471E+00 0.39391738E+00
+ 0.39440004E+00 0.39488270E+00 0.39536536E+00 0.39584803E+00 0.39633069E+00
+ 0.39681335E+00 0.39729601E+00 0.39777868E+00 0.39826134E+00 0.39874400E+00
+ 0.39922667E+00 0.39970933E+00 0.40019199E+00 0.40067465E+00 0.40115732E+00
+ 0.40163998E+00 0.40212264E+00 0.40260531E+00 0.40308797E+00 0.40357063E+00
+ 0.40405329E+00 0.40453596E+00 0.40501862E+00 0.40550128E+00 0.40598394E+00
+ 0.40646661E+00 0.40694927E+00 0.40743193E+00 0.40791460E+00 0.40839726E+00
+ 0.40887992E+00 0.40936258E+00 0.40984525E+00 0.41032791E+00 0.41081057E+00
+ 0.41129323E+00 0.41177590E+00 0.41225856E+00 0.41274122E+00 0.41322389E+00
+ 0.41370655E+00 0.41418921E+00 0.41467187E+00 0.41515454E+00 0.41563720E+00
+ 0.41611986E+00 0.41660252E+00 0.41708519E+00 0.41756785E+00 0.41805051E+00
+ 0.41853318E+00 0.41901584E+00 0.41949850E+00 0.41998116E+00 0.42046383E+00
+ 0.42094649E+00 0.42142915E+00 0.42191182E+00 0.42239448E+00 0.42287714E+00
+ 0.42335980E+00 0.42384247E+00 0.42432513E+00 0.42480779E+00 0.42529045E+00
+ 0.42577312E+00 0.42625578E+00 0.42673844E+00 0.42722111E+00 0.42770377E+00
+ 0.42818643E+00 0.42866909E+00 0.42915176E+00 0.42963442E+00 0.43011708E+00
+ 0.43059974E+00 0.43108241E+00 0.43156507E+00 0.43204773E+00 0.43253040E+00
+ 0.43301306E+00 0.43349572E+00 0.43397838E+00 0.43446105E+00 0.43494371E+00
+ 0.43542637E+00 0.43590903E+00 0.43639170E+00 0.43687436E+00 0.43735702E+00
+ 0.43783969E+00 0.43832235E+00 0.43880501E+00 0.43928767E+00 0.43977034E+00
+ 0.44025300E+00 0.44073566E+00 0.44121833E+00 0.44170099E+00 0.44218365E+00
+ 0.44266631E+00 0.44314898E+00 0.44363164E+00 0.44411430E+00 0.44459696E+00
+ 0.44507963E+00 0.44556229E+00 0.44604495E+00 0.44652762E+00 0.44701028E+00
+ 0.44749294E+00 0.44797560E+00 0.44845827E+00 0.44894093E+00 0.44942359E+00
+ 0.44990625E+00 0.45038892E+00 0.45087158E+00 0.45135424E+00 0.45183691E+00
+ 0.45231957E+00 0.45280223E+00 0.45328489E+00 0.45376756E+00 0.45425022E+00
+ 0.45473288E+00 0.45521554E+00 0.45569821E+00 0.45618087E+00 0.45666353E+00
+ 0.45714620E+00 0.45762886E+00 0.45811152E+00 0.45859418E+00 0.45907685E+00
+ 0.45955951E+00 0.46004217E+00 0.46052484E+00 0.46100750E+00 0.46149016E+00
+ 0.46197282E+00 0.46245549E+00 0.46293815E+00 0.46342081E+00 0.46390347E+00
+ 0.46438614E+00 0.46486880E+00 0.46535146E+00 0.46583413E+00 0.46631679E+00
+ 0.46679945E+00 0.46728211E+00 0.46776478E+00 0.46824744E+00 0.46873010E+00
+ 0.46921276E+00 0.46969543E+00 0.47017809E+00 0.47066075E+00 0.47114342E+00
+ 0.47162608E+00 0.47210874E+00 0.47259140E+00 0.47307407E+00 0.47355673E+00
+ 0.47403939E+00 0.47452206E+00 0.47500472E+00 0.47548738E+00 0.47597004E+00
+ 0.47645271E+00 0.47693537E+00 0.47741803E+00 0.47790069E+00 0.47838336E+00
+ 0.47886602E+00 0.47934868E+00 0.47983135E+00 0.48031401E+00 0.48079667E+00
+ 0.48127933E+00 0.48176200E+00 0.48224466E+00 0.48272732E+00 0.48320998E+00
+ 0.48369265E+00 0.48417531E+00 0.48465797E+00 0.48514064E+00 0.48562330E+00
+ 0.48610596E+00 0.48658862E+00 0.48707129E+00 0.48755395E+00 0.48803661E+00
+ 0.48851927E+00 0.48900194E+00 0.48948460E+00 0.48996726E+00 0.49044993E+00
+ 0.49093259E+00 0.49141525E+00 0.49189791E+00 0.49238058E+00 0.49286324E+00
+ 0.49334590E+00 0.49382857E+00 0.49431123E+00 0.49479389E+00 0.49527655E+00
+ 0.49575922E+00 0.49624188E+00 0.49672454E+00 0.49720720E+00 0.49768987E+00
+ 0.49817253E+00 0.49865519E+00 0.49913786E+00 0.49962052E+00 0.50010318E+00
+ 0.50058584E+00 0.50106851E+00 0.50155117E+00 0.50203383E+00 0.50251649E+00
+ 0.50299916E+00 0.50348182E+00 0.50396448E+00 0.50444715E+00 0.50492981E+00
+ 0.50541247E+00 0.50589513E+00 0.50637780E+00 0.50686046E+00 0.50734312E+00
+ 0.50782578E+00 0.50830845E+00 0.50879111E+00 0.50927377E+00 0.50975644E+00
+ 0.51023910E+00 0.51072176E+00 0.51120442E+00 0.51168709E+00 0.51216975E+00
+ 0.51265241E+00 0.51313508E+00 0.51361774E+00 0.51410040E+00 0.51458306E+00
+ 0.51506573E+00 0.51554839E+00 0.51603105E+00 0.51651371E+00 0.51699638E+00
+ 0.51747904E+00 0.51796170E+00 0.51844437E+00 0.51892703E+00 0.51940969E+00
+ 0.51989235E+00 0.52037502E+00 0.52085768E+00 0.52134034E+00 0.52182300E+00
+ 0.52230567E+00 0.52278833E+00 0.52327099E+00 0.52375366E+00 0.52423632E+00
+ 0.52471898E+00 0.52520164E+00 0.52568431E+00 0.52616697E+00 0.52664963E+00
+ 0.52713230E+00 0.52761496E+00 0.52809762E+00 0.52858028E+00 0.52906295E+00
+ 0.52954561E+00 0.53002827E+00 0.53051093E+00 0.53099360E+00 0.53147626E+00
+ 0.53195892E+00 0.53244159E+00 0.53292425E+00 0.53340691E+00 0.53388957E+00
+ 0.53437224E+00 0.53485490E+00 0.53533756E+00 0.53582022E+00 0.53630289E+00
+ 0.53678555E+00 0.53726821E+00 0.53775088E+00 0.53823354E+00 0.53871620E+00
+ 0.53919886E+00 0.53968153E+00 0.54016419E+00 0.54064685E+00 0.54112951E+00
+ 0.54161218E+00 0.54209484E+00 0.54257750E+00 0.54306017E+00 0.54354283E+00
+ 0.54402549E+00 0.54450815E+00 0.54499082E+00 0.54547348E+00 0.54595614E+00
+ 0.54643881E+00 0.54692147E+00 0.54740413E+00 0.54788679E+00 0.54836946E+00
+ 0.54885212E+00 0.54933478E+00 0.54981744E+00 0.55030011E+00 0.55078277E+00
+ 0.55126543E+00 0.55174810E+00 0.55223076E+00 0.55271342E+00 0.55319608E+00
+ 0.55367875E+00 0.55416141E+00 0.55464407E+00 0.55512673E+00 0.55560940E+00
+ 0.55609206E+00 0.55657472E+00 0.55705739E+00 0.55754005E+00 0.55802271E+00
+ 0.55850537E+00 0.55898804E+00 0.55947070E+00 0.55995336E+00 0.56043602E+00
+ 0.56091869E+00 0.56140135E+00 0.56188401E+00 0.56236668E+00 0.56284934E+00
+ 0.56333200E+00 0.56381466E+00 0.56429733E+00 0.56477999E+00 0.56526265E+00
+ 0.56574532E+00 0.56622798E+00 0.56671064E+00 0.56719330E+00 0.56767597E+00
+ 0.56815863E+00 0.56864129E+00 0.56912395E+00 0.56960662E+00 0.57008928E+00
+ 0.57057194E+00 0.57105461E+00 0.57153727E+00 0.57201993E+00 0.57250259E+00
+ 0.57298526E+00 0.57346792E+00 0.57395058E+00 0.57443324E+00 0.57491591E+00
+ 0.57539857E+00 0.57588123E+00 0.57636390E+00 0.57684656E+00 0.57732922E+00
+ 0.57781188E+00 0.57829455E+00 0.57877721E+00 0.57925987E+00 0.57974253E+00
+ 0.58022520E+00 0.58070786E+00 0.58119052E+00 0.58167319E+00 0.58215585E+00
+ 0.58263851E+00 0.58312117E+00 0.58360384E+00 0.58408650E+00 0.58456916E+00
+ 0.58505183E+00 0.58553449E+00 0.58601715E+00 0.58649981E+00 0.58698248E+00
+ 0.58746514E+00 0.58794780E+00 0.58843046E+00 0.58891313E+00 0.58939579E+00
+ 0.58987845E+00 0.59036112E+00 0.59084378E+00 0.59132644E+00 0.59180910E+00
+ 0.59229177E+00 0.59277443E+00 0.59325709E+00 0.59373975E+00 0.59422242E+00
+ 0.59470508E+00 0.59518774E+00 0.59567041E+00 0.59615307E+00 0.59663573E+00
+ 0.59711839E+00 0.59760106E+00 0.59808372E+00 0.59856638E+00 0.59904905E+00
+ 0.59953171E+00 0.60001437E+00 0.60049703E+00 0.60097970E+00 0.60146236E+00
+ 0.60194502E+00 0.60242768E+00 0.60291035E+00 0.60339301E+00 0.60387567E+00
+ 0.60435834E+00 0.60484100E+00 0.60532366E+00 0.60580632E+00 0.60628899E+00
+ 0.60677165E+00 0.60725431E+00 0.60773697E+00 0.60821964E+00 0.60870230E+00
+ 0.60918496E+00 0.60966763E+00 0.61015029E+00 0.61063295E+00 0.61111561E+00
+ 0.61159828E+00 0.61208094E+00 0.61256360E+00 0.61304626E+00 0.61352893E+00
+ 0.61401159E+00 0.61449425E+00 0.61497692E+00 0.61545958E+00 0.61594224E+00
+ 0.61642852E+00 0.61691694E+00 0.61740533E+00 0.61789368E+00 0.61838201E+00
+ 0.61887030E+00 0.61935856E+00 0.61984679E+00 0.62033499E+00 0.62082316E+00
+ 0.62131129E+00 0.62179939E+00 0.62228745E+00 0.62277549E+00 0.62326349E+00
+ 0.62375146E+00 0.62423939E+00 0.62472729E+00 0.62521516E+00 0.62570299E+00
+ 0.62619079E+00 0.62667856E+00 0.62716629E+00 0.62765399E+00 0.62814165E+00
+ 0.62862928E+00 0.62911687E+00 0.62960443E+00 0.63009196E+00 0.63057945E+00
+ 0.63106690E+00 0.63155432E+00 0.63204170E+00 0.63252905E+00 0.63301636E+00
+ 0.63350363E+00 0.63399087E+00 0.63447807E+00 0.63496524E+00 0.63545237E+00
+ 0.63593946E+00 0.63642652E+00 0.63691354E+00 0.63740052E+00 0.63788746E+00
+ 0.63837437E+00 0.63886124E+00 0.63934807E+00 0.63983486E+00 0.64032162E+00
+ 0.64080833E+00 0.64129501E+00 0.64178165E+00 0.64226825E+00 0.64275481E+00
+ 0.64324134E+00 0.64372782E+00 0.64421426E+00 0.64470067E+00 0.64518703E+00
+ 0.64567335E+00 0.64615964E+00 0.64664588E+00 0.64713208E+00 0.64761824E+00
+ 0.64810437E+00 0.64859045E+00 0.64907648E+00 0.64956248E+00 0.65004844E+00
+ 0.65053435E+00 0.65102022E+00 0.65150605E+00 0.65199184E+00 0.65247759E+00
+ 0.65296329E+00 0.65344895E+00 0.65393456E+00 0.65442014E+00 0.65490567E+00
+ 0.65539115E+00 0.65587659E+00 0.65636199E+00 0.65684734E+00 0.65733265E+00
+ 0.65781792E+00 0.65830314E+00 0.65878831E+00 0.65927344E+00 0.65975852E+00
+ 0.66024356E+00 0.66072856E+00 0.66121350E+00 0.66169840E+00 0.66218325E+00
+ 0.66266806E+00 0.66315282E+00 0.66363753E+00 0.66412220E+00 0.66460682E+00
+ 0.66509139E+00 0.66557591E+00 0.66606038E+00 0.66654481E+00 0.66702918E+00
+ 0.66751351E+00 0.66799779E+00 0.66848202E+00 0.66896620E+00 0.66945033E+00
+ 0.66993441E+00 0.67041843E+00 0.67090241E+00 0.67138634E+00 0.67187022E+00
+ 0.67235404E+00 0.67283782E+00 0.67332154E+00 0.67380521E+00 0.67428883E+00
+ 0.67477240E+00 0.67525591E+00 0.67573937E+00 0.67622278E+00 0.67670613E+00
+ 0.67718943E+00 0.67767268E+00 0.67815587E+00 0.67863901E+00 0.67912209E+00
+ 0.67960512E+00 0.68008809E+00 0.68057101E+00 0.68105387E+00 0.68153668E+00
+ 0.68201943E+00 0.68250212E+00 0.68298475E+00 0.68346733E+00 0.68394985E+00
+ 0.68443232E+00 0.68491472E+00 0.68539707E+00 0.68587936E+00 0.68636159E+00
+ 0.68684376E+00 0.68732587E+00 0.68780792E+00 0.68828991E+00 0.68877184E+00
+ 0.68925371E+00 0.68973552E+00 0.69021727E+00 0.69069896E+00 0.69118058E+00
+ 0.69166215E+00 0.69214365E+00 0.69262509E+00 0.69310646E+00 0.69358777E+00
+ 0.69406902E+00 0.69455020E+00 0.69503132E+00 0.69551238E+00 0.69599337E+00
+ 0.69647429E+00 0.69695515E+00 0.69743594E+00 0.69791667E+00 0.69839733E+00
+ 0.69887792E+00 0.69935845E+00 0.69983891E+00 0.70031930E+00 0.70079962E+00
+ 0.70127987E+00 0.70176005E+00 0.70224017E+00 0.70272021E+00 0.70320019E+00
+ 0.70368009E+00 0.70415992E+00 0.70463969E+00 0.70511938E+00 0.70559899E+00
+ 0.70607854E+00 0.70655801E+00 0.70703741E+00 0.70751674E+00 0.70799599E+00
+ 0.70847517E+00 0.70895427E+00 0.70943330E+00 0.70991225E+00 0.71039113E+00
+ 0.71086993E+00 0.71134865E+00 0.71182730E+00 0.71230587E+00 0.71278436E+00
+ 0.71326277E+00 0.71374111E+00 0.71421936E+00 0.71469753E+00 0.71517563E+00
+ 0.71565364E+00 0.71613158E+00 0.71660943E+00 0.71708720E+00 0.71756489E+00
+ 0.71804249E+00 0.71852001E+00 0.71899745E+00 0.71947481E+00 0.71995207E+00
+ 0.72042926E+00 0.72090636E+00 0.72138337E+00 0.72186030E+00 0.72233714E+00
+ 0.72281389E+00 0.72329055E+00 0.72376713E+00 0.72424361E+00 0.72472001E+00
+ 0.72519632E+00 0.72567254E+00 0.72614866E+00 0.72662470E+00 0.72710064E+00
+ 0.72757649E+00 0.72805225E+00 0.72852791E+00 0.72900348E+00 0.72947895E+00
+ 0.72995433E+00 0.73042962E+00 0.73090480E+00 0.73137989E+00 0.73185489E+00
+ 0.73232978E+00 0.73280458E+00 0.73327928E+00 0.73375388E+00 0.73422837E+00
+ 0.73470277E+00 0.73517707E+00 0.73565126E+00 0.73612535E+00 0.73659934E+00
+ 0.73707322E+00 0.73754700E+00 0.73802068E+00 0.73849424E+00 0.73896771E+00
+ 0.73944106E+00 0.73991431E+00 0.74038745E+00 0.74086048E+00 0.74133340E+00
+ 0.74180621E+00 0.74227891E+00 0.74275150E+00 0.74322398E+00 0.74369634E+00
+ 0.74416859E+00 0.74464073E+00 0.74511275E+00 0.74558465E+00 0.74605644E+00
+ 0.74652811E+00 0.74699967E+00 0.74747110E+00 0.74794242E+00 0.74841361E+00
+ 0.74888469E+00 0.74935564E+00 0.74982647E+00 0.75029718E+00 0.75076776E+00
+ 0.75123822E+00 0.75170856E+00 0.75217877E+00 0.75264885E+00 0.75311880E+00
+ 0.75358863E+00 0.75405832E+00 0.75452789E+00 0.75499733E+00 0.75546663E+00
+ 0.75593580E+00 0.75640483E+00 0.75687374E+00 0.75734250E+00 0.75781114E+00
+ 0.75827963E+00 0.75874799E+00 0.75921620E+00 0.75968428E+00 0.76015222E+00
+ 0.76062001E+00 0.76108767E+00 0.76155517E+00 0.76202254E+00 0.76248976E+00
+ 0.76295683E+00 0.76342376E+00 0.76389054E+00 0.76435717E+00 0.76482365E+00
+ 0.76528997E+00 0.76575615E+00 0.76622217E+00 0.76668804E+00 0.76715375E+00
+ 0.76761931E+00 0.76808471E+00 0.76854995E+00 0.76901503E+00 0.76947995E+00
+ 0.76994471E+00 0.77040931E+00 0.77087374E+00 0.77133801E+00 0.77180211E+00
+ 0.77226605E+00 0.77272981E+00 0.77319341E+00 0.77365683E+00 0.77412009E+00
+ 0.77458317E+00 0.77504607E+00 0.77550880E+00 0.77597135E+00 0.77643373E+00
+ 0.77689593E+00 0.77735794E+00 0.77781977E+00 0.77828142E+00 0.77874289E+00
+ 0.77920417E+00 0.77966526E+00 0.78012617E+00 0.78058688E+00 0.78104740E+00
+ 0.78150773E+00 0.78196787E+00 0.78242781E+00 0.78288756E+00 0.78334710E+00
+ 0.78380645E+00 0.78426559E+00 0.78472454E+00 0.78518327E+00 0.78564181E+00
+ 0.78610013E+00 0.78655825E+00 0.78701616E+00 0.78747385E+00 0.78793133E+00
+ 0.78838860E+00 0.78884565E+00 0.78930248E+00 0.78975910E+00 0.79021549E+00
+ 0.79067165E+00 0.79112760E+00 0.79158331E+00 0.79203880E+00 0.79249406E+00
+ 0.79294908E+00 0.79340388E+00 0.79385843E+00 0.79431275E+00 0.79476684E+00
+ 0.79522067E+00 0.79567427E+00 0.79612762E+00 0.79658073E+00 0.79703359E+00
+ 0.79748620E+00 0.79793855E+00 0.79839065E+00 0.79884249E+00 0.79929408E+00
+ 0.79974540E+00 0.80019647E+00 0.80064726E+00 0.80109779E+00 0.80154806E+00
+ 0.80199805E+00 0.80244776E+00 0.80289721E+00 0.80334637E+00 0.80379525E+00
+ 0.80424386E+00 0.80469217E+00 0.80514020E+00 0.80558794E+00 0.80603539E+00
+ 0.80648255E+00 0.80692941E+00 0.80737597E+00 0.80782222E+00 0.80826818E+00
+ 0.80871383E+00 0.80915916E+00 0.80960419E+00 0.81004890E+00 0.81049330E+00
+ 0.81093737E+00 0.81138113E+00 0.81182456E+00 0.81226765E+00 0.81271042E+00
+ 0.81315286E+00 0.81359496E+00 0.81403672E+00 0.81447814E+00 0.81491921E+00
+ 0.81535993E+00 0.81580030E+00 0.81624032E+00 0.81667998E+00 0.81711928E+00
+ 0.81755821E+00 0.81799678E+00 0.81843498E+00 0.81887280E+00 0.81931025E+00
+ 0.81974732E+00 0.82018400E+00 0.82062030E+00 0.82105620E+00 0.82149171E+00
+ 0.82192682E+00 0.82236153E+00 0.82279584E+00 0.82322973E+00 0.82366322E+00
+ 0.82409628E+00 0.82452893E+00 0.82496115E+00 0.82539294E+00 0.82582431E+00
+ 0.82625523E+00 0.82668571E+00 0.82711575E+00 0.82754535E+00 0.82797448E+00
+ 0.82840316E+00 0.82883138E+00 0.82925914E+00 0.82968642E+00 0.83011323E+00
+ 0.83053956E+00 0.83096540E+00 0.83139075E+00 0.83181561E+00 0.83223998E+00
+ 0.83266384E+00 0.83308719E+00 0.83351002E+00 0.83393234E+00 0.83435414E+00
+ 0.83477540E+00 0.83519613E+00 0.83561633E+00 0.83603598E+00 0.83645507E+00
+ 0.83687361E+00 0.83729160E+00 0.83770901E+00 0.83812585E+00 0.83854211E+00
+ 0.83895779E+00 0.83937287E+00 0.83978736E+00 0.84020125E+00 0.84061453E+00
+ 0.84102719E+00 0.84143923E+00 0.84185064E+00 0.84226141E+00 0.84267155E+00
+ 0.84308103E+00 0.84348987E+00 0.84389803E+00 0.84430553E+00 0.84471235E+00
+ 0.84511849E+00 0.84552394E+00 0.84592869E+00 0.84633273E+00 0.84673605E+00
+ 0.84713866E+00 0.84754054E+00 0.84794167E+00 0.84834207E+00 0.84874170E+00
+ 0.84914058E+00 0.84953869E+00 0.84993601E+00 0.85033255E+00 0.85072829E+00
+ 0.85112322E+00 0.85151734E+00 0.85191063E+00 0.85230310E+00 0.85269471E+00
+ 0.85308548E+00 0.85347538E+00 0.85386441E+00 0.85425255E+00 0.85463980E+00
+ 0.85502615E+00 0.85541159E+00 0.85579610E+00 0.85617967E+00 0.85656230E+00
+ 0.85694397E+00 0.85732467E+00 0.85770439E+00 0.85808312E+00 0.85846084E+00
+ 0.85883754E+00 0.85921322E+00 0.85958786E+00 0.85996144E+00 0.86033395E+00
+ 0.86070539E+00 0.86107573E+00 0.86144496E+00 0.86181308E+00 0.86218006E+00
+ 0.86254589E+00 0.86291056E+00 0.86327405E+00 0.86363635E+00 0.86399744E+00
+ 0.86435732E+00 0.86471595E+00 0.86507333E+00 0.86542944E+00 0.86578426E+00
+ 0.86613778E+00 0.86648998E+00 0.86684085E+00 0.86719036E+00 0.86753850E+00
+ 0.86788525E+00 0.86823060E+00 0.86857452E+00 0.86891699E+00 0.86925800E+00
+ 0.86959753E+00 0.86993555E+00 0.87027205E+00 0.87060701E+00 0.87094040E+00
+ 0.87127221E+00 0.87160241E+00 0.87193098E+00 0.87225791E+00 0.87258315E+00
+ 0.87290671E+00 0.87322854E+00 0.87354863E+00 0.87386695E+00 0.87418349E+00
+ 0.87449820E+00 0.87481108E+00 0.87512208E+00 0.87543120E+00 0.87573839E+00
+ 0.87604364E+00 0.87634691E+00 0.87664818E+00 0.87694742E+00 0.87724461E+00
+ 0.87753970E+00 0.87783267E+00 0.87812350E+00 0.87841215E+00 0.87869859E+00
+ 0.87898278E+00 0.87926470E+00 0.87954432E+00 0.87982159E+00 0.88009649E+00
+ 0.88036899E+00 0.88063904E+00 0.88090661E+00 0.88117167E+00 0.88143417E+00
+ 0.88169409E+00 0.88195138E+00 0.88220601E+00 0.88245794E+00 0.88270713E+00
+ 0.88295354E+00 0.88319712E+00 0.88343784E+00 0.88367566E+00 0.88391054E+00
+ 0.88414243E+00 0.88437128E+00 0.88459706E+00 0.88481973E+00 0.88503923E+00
+ 0.88525552E+00 0.88546856E+00 0.88567831E+00 0.88588471E+00 0.88608771E+00
+ 0.88628728E+00 0.88648337E+00 0.88667592E+00 0.88686489E+00 0.88705023E+00
+ 0.88723190E+00 0.88740984E+00 0.88758401E+00 0.88775436E+00 0.88792084E+00
+ 0.88808340E+00 0.88824201E+00 0.88839660E+00 0.88854714E+00 0.88869358E+00
+ 0.88883587E+00 0.88897397E+00 0.88910784E+00 0.88923744E+00 0.88936273E+00
+ 0.88948366E+00 0.88960022E+00 0.88971235E+00 0.88982003E+00 0.88992324E+00
+ 0.89002195E+00 0.89011614E+00 0.89020579E+00 0.89029089E+00 0.89037143E+00
+ 0.89044742E+00 0.89051886E+00 0.89058577E+00 0.89064815E+00 0.89070605E+00
+ 0.89075950E+00 0.89080856E+00 0.89085328E+00 0.89089374E+00 0.89093002E+00
+ 0.89096224E+00 0.89099051E+00 0.89101498E+00 0.89103581E+00 0.89105319E+00
+ 0.89106733E+00 0.89107847E+00 0.89108688E+00 0.89109288E+00 0.89109680E+00
+ 0.89109904E+00 0.89110004E+00 0.89110028E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00 0.89110029E+00
+ 0.93300278E-01 0.93668512E-01 0.94036746E-01 0.94404980E-01 0.94773213E-01
+ 0.95141447E-01 0.95509681E-01 0.95877915E-01 0.96246148E-01 0.96614382E-01
+ 0.96982616E-01 0.97350850E-01 0.97719083E-01 0.98087317E-01 0.98455551E-01
+ 0.98823785E-01 0.99192018E-01 0.99560252E-01 0.99928486E-01 0.10029672E+00
+ 0.10066495E+00 0.10103319E+00 0.10140142E+00 0.10176965E+00 0.10213789E+00
+ 0.10250612E+00 0.10287436E+00 0.10324259E+00 0.10361082E+00 0.10397906E+00
+ 0.10434729E+00 0.10471552E+00 0.10508376E+00 0.10545199E+00 0.10582023E+00
+ 0.10618846E+00 0.10655669E+00 0.10692493E+00 0.10729316E+00 0.10766139E+00
+ 0.10802963E+00 0.10839786E+00 0.10876610E+00 0.10913433E+00 0.10950256E+00
+ 0.10987080E+00 0.11023903E+00 0.11060726E+00 0.11097550E+00 0.11134373E+00
+ 0.11171197E+00 0.11208020E+00 0.11244843E+00 0.11281667E+00 0.11318490E+00
+ 0.11355313E+00 0.11392137E+00 0.11428960E+00 0.11465784E+00 0.11502607E+00
+ 0.11539430E+00 0.11576254E+00 0.11613077E+00 0.11649900E+00 0.11686724E+00
+ 0.11723547E+00 0.11760371E+00 0.11797194E+00 0.11834017E+00 0.11870841E+00
+ 0.11907664E+00 0.11944487E+00 0.11981311E+00 0.12018134E+00 0.12054958E+00
+ 0.12091781E+00 0.12128604E+00 0.12165428E+00 0.12202251E+00 0.12239074E+00
+ 0.12275898E+00 0.12312721E+00 0.12349545E+00 0.12386368E+00 0.12423191E+00
+ 0.12460015E+00 0.12496838E+00 0.12533662E+00 0.12570485E+00 0.12607308E+00
+ 0.12644132E+00 0.12680955E+00 0.12717778E+00 0.12754602E+00 0.12791425E+00
+ 0.12828249E+00 0.12865072E+00 0.12901895E+00 0.12938719E+00 0.12975542E+00
+ 0.13012365E+00 0.13049189E+00 0.13086012E+00 0.13122836E+00 0.13159659E+00
+ 0.13196482E+00 0.13233306E+00 0.13270129E+00 0.13306952E+00 0.13343776E+00
+ 0.13380599E+00 0.13417423E+00 0.13454246E+00 0.13491069E+00 0.13527893E+00
+ 0.13564716E+00 0.13601539E+00 0.13638363E+00 0.13675186E+00 0.13712010E+00
+ 0.13748833E+00 0.13785656E+00 0.13822480E+00 0.13859303E+00 0.13896126E+00
+ 0.13932950E+00 0.13969773E+00 0.14006597E+00 0.14043420E+00 0.14080243E+00
+ 0.14117067E+00 0.14153890E+00 0.14190713E+00 0.14227537E+00 0.14264360E+00
+ 0.14301184E+00 0.14338007E+00 0.14374830E+00 0.14411654E+00 0.14448477E+00
+ 0.14485300E+00 0.14522124E+00 0.14558947E+00 0.14595771E+00 0.14632594E+00
+ 0.14669417E+00 0.14706241E+00 0.14743064E+00 0.14779887E+00 0.14816711E+00
+ 0.14853534E+00 0.14890358E+00 0.14927181E+00 0.14964004E+00 0.15000828E+00
+ 0.15037651E+00 0.15074474E+00 0.15111298E+00 0.15148121E+00 0.15184945E+00
+ 0.15221768E+00 0.15258591E+00 0.15295415E+00 0.15332238E+00 0.15369061E+00
+ 0.15405885E+00 0.15442708E+00 0.15479532E+00 0.15516355E+00 0.15553178E+00
+ 0.15590002E+00 0.15626825E+00 0.15663648E+00 0.15700472E+00 0.15737295E+00
+ 0.15774119E+00 0.15810942E+00 0.15847765E+00 0.15884589E+00 0.15921412E+00
+ 0.15958235E+00 0.15995059E+00 0.16031882E+00 0.16068706E+00 0.16105529E+00
+ 0.16142352E+00 0.16179176E+00 0.16215999E+00 0.16252822E+00 0.16289646E+00
+ 0.16326469E+00 0.16363293E+00 0.16400116E+00 0.16436939E+00 0.16473763E+00
+ 0.16510586E+00 0.16547409E+00 0.16584233E+00 0.16621056E+00 0.16657880E+00
+ 0.16694703E+00 0.16731526E+00 0.16768350E+00 0.16805173E+00 0.16841996E+00
+ 0.16878820E+00 0.16915643E+00 0.16952467E+00 0.16989290E+00 0.17026113E+00
+ 0.17062937E+00 0.17099760E+00 0.17136583E+00 0.17173407E+00 0.17210230E+00
+ 0.17247054E+00 0.17283877E+00 0.17320700E+00 0.17357524E+00 0.17394347E+00
+ 0.17431170E+00 0.17467994E+00 0.17504817E+00 0.17541641E+00 0.17578464E+00
+ 0.17615287E+00 0.17652111E+00 0.17688934E+00 0.17725757E+00 0.17762581E+00
+ 0.17799404E+00 0.17836228E+00 0.17873051E+00 0.17909874E+00 0.17946698E+00
+ 0.17983521E+00 0.18020344E+00 0.18057168E+00 0.18093991E+00 0.18130815E+00
+ 0.18167638E+00 0.18204461E+00 0.18241285E+00 0.18278108E+00 0.18314931E+00
+ 0.18351755E+00 0.18388578E+00 0.18425402E+00 0.18462225E+00 0.18499048E+00
+ 0.18535872E+00 0.18572695E+00 0.18609518E+00 0.18646342E+00 0.18683165E+00
+ 0.18719989E+00 0.18756812E+00 0.18793635E+00 0.18830459E+00 0.18867282E+00
+ 0.18904105E+00 0.18940929E+00 0.18977752E+00 0.19014576E+00 0.19051399E+00
+ 0.19088222E+00 0.19125046E+00 0.19161869E+00 0.19198692E+00 0.19235516E+00
+ 0.19272339E+00 0.19309163E+00 0.19345986E+00 0.19382809E+00 0.19419633E+00
+ 0.19456456E+00 0.19493279E+00 0.19530103E+00 0.19566926E+00 0.19603750E+00
+ 0.19640573E+00 0.19677396E+00 0.19714220E+00 0.19751043E+00 0.19787866E+00
+ 0.19824690E+00 0.19861513E+00 0.19898337E+00 0.19935160E+00 0.19971983E+00
+ 0.20008807E+00 0.20045630E+00 0.20082453E+00 0.20119277E+00 0.20156100E+00
+ 0.20192924E+00 0.20229747E+00 0.20266570E+00 0.20303394E+00 0.20340217E+00
+ 0.20377041E+00 0.20413864E+00 0.20450687E+00 0.20487511E+00 0.20524334E+00
+ 0.20561157E+00 0.20597981E+00 0.20634804E+00 0.20671628E+00 0.20708451E+00
+ 0.20745274E+00 0.20782098E+00 0.20818921E+00 0.20855744E+00 0.20892568E+00
+ 0.20929391E+00 0.20966215E+00 0.21003038E+00 0.21039861E+00 0.21076685E+00
+ 0.21113508E+00 0.21150331E+00 0.21187155E+00 0.21223978E+00 0.21260802E+00
+ 0.21297625E+00 0.21334448E+00 0.21371272E+00 0.21408095E+00 0.21444918E+00
+ 0.21481742E+00 0.21518565E+00 0.21555389E+00 0.21592212E+00 0.21629035E+00
+ 0.21665859E+00 0.21702682E+00 0.21739505E+00 0.21776329E+00 0.21813152E+00
+ 0.21849976E+00 0.21886799E+00 0.21923622E+00 0.21960446E+00 0.21997269E+00
+ 0.22034092E+00 0.22070916E+00 0.22107739E+00 0.22144563E+00 0.22181386E+00
+ 0.22218209E+00 0.22255033E+00 0.22291856E+00 0.22328679E+00 0.22365503E+00
+ 0.22402326E+00 0.22439150E+00 0.22475973E+00 0.22512796E+00 0.22549620E+00
+ 0.22586443E+00 0.22623266E+00 0.22660090E+00 0.22696913E+00 0.22733737E+00
+ 0.22770560E+00 0.22807383E+00 0.22844207E+00 0.22881030E+00 0.22917853E+00
+ 0.22954677E+00 0.22991500E+00 0.23028324E+00 0.23065147E+00 0.23101970E+00
+ 0.23138794E+00 0.23175617E+00 0.23212440E+00 0.23249264E+00 0.23286087E+00
+ 0.23322911E+00 0.23359734E+00 0.23396557E+00 0.23433381E+00 0.23470204E+00
+ 0.23507027E+00 0.23543851E+00 0.23580674E+00 0.23617498E+00 0.23654321E+00
+ 0.23691144E+00 0.23727968E+00 0.23764791E+00 0.23801614E+00 0.23838438E+00
+ 0.23875261E+00 0.23912085E+00 0.23948908E+00 0.23985731E+00 0.24022555E+00
+ 0.24059378E+00 0.24096201E+00 0.24133025E+00 0.24169848E+00 0.24206672E+00
+ 0.24243495E+00 0.24280318E+00 0.24317142E+00 0.24353965E+00 0.24390788E+00
+ 0.24427612E+00 0.24464435E+00 0.24501259E+00 0.24538082E+00 0.24574905E+00
+ 0.24611729E+00 0.24648552E+00 0.24685375E+00 0.24722199E+00 0.24759022E+00
+ 0.24795846E+00 0.24832669E+00 0.24869492E+00 0.24906316E+00 0.24943139E+00
+ 0.24979962E+00 0.25016786E+00 0.25053609E+00 0.25090433E+00 0.25127256E+00
+ 0.25164079E+00 0.25200903E+00 0.25237726E+00 0.25274549E+00 0.25311373E+00
+ 0.25348196E+00 0.25385020E+00 0.25421843E+00 0.25458666E+00 0.25495490E+00
+ 0.25532313E+00 0.25569136E+00 0.25605960E+00 0.25642783E+00 0.25679607E+00
+ 0.25716430E+00 0.25753253E+00 0.25790077E+00 0.25826900E+00 0.25863723E+00
+ 0.25900547E+00 0.25937370E+00 0.25974194E+00 0.26011017E+00 0.26047840E+00
+ 0.26084664E+00 0.26121487E+00 0.26158310E+00 0.26195134E+00 0.26231957E+00
+ 0.26268781E+00 0.26305604E+00 0.26342427E+00 0.26379251E+00 0.26416074E+00
+ 0.26452897E+00 0.26489721E+00 0.26526544E+00 0.26563368E+00 0.26600191E+00
+ 0.26637014E+00 0.26673838E+00 0.26710661E+00 0.26747484E+00 0.26784308E+00
+ 0.26821131E+00 0.26857955E+00 0.26894778E+00 0.26931601E+00 0.26968425E+00
+ 0.27005248E+00 0.27042071E+00 0.27078895E+00 0.27115718E+00 0.27152542E+00
+ 0.27189365E+00 0.27226188E+00 0.27263012E+00 0.27299835E+00 0.27336658E+00
+ 0.27373482E+00 0.27410305E+00 0.27447129E+00 0.27483952E+00 0.27520775E+00
+ 0.27557599E+00 0.27594422E+00 0.27631245E+00 0.27668069E+00 0.27704892E+00
+ 0.27741716E+00 0.27778539E+00 0.27815362E+00 0.27852186E+00 0.27889009E+00
+ 0.27925832E+00 0.27962656E+00 0.27999479E+00 0.28036303E+00 0.28073126E+00
+ 0.28109949E+00 0.28146773E+00 0.28183596E+00 0.28220419E+00 0.28257243E+00
+ 0.28294066E+00 0.28330890E+00 0.28367713E+00 0.28404536E+00 0.28441360E+00
+ 0.28478183E+00 0.28515007E+00 0.28551830E+00 0.28588653E+00 0.28625477E+00
+ 0.28662300E+00 0.28699123E+00 0.28735947E+00 0.28772770E+00 0.28809594E+00
+ 0.28846417E+00 0.28883240E+00 0.28920064E+00 0.28956887E+00 0.28993710E+00
+ 0.29030534E+00 0.29067357E+00 0.29104181E+00 0.29141004E+00 0.29177827E+00
+ 0.29214651E+00 0.29251474E+00 0.29288297E+00 0.29325121E+00 0.29361944E+00
+ 0.29398768E+00 0.29435591E+00 0.29472414E+00 0.29509238E+00 0.29546061E+00
+ 0.29582884E+00 0.29619708E+00 0.29656531E+00 0.29693355E+00 0.29730178E+00
+ 0.29767001E+00 0.29803825E+00 0.29840648E+00 0.29877471E+00 0.29914295E+00
+ 0.29951118E+00 0.29987942E+00 0.30024765E+00 0.30061588E+00 0.30098412E+00
+ 0.30135235E+00 0.30172058E+00 0.30208882E+00 0.30245705E+00 0.30282529E+00
+ 0.30319352E+00 0.30356175E+00 0.30392999E+00 0.30429822E+00 0.30466645E+00
+ 0.30503469E+00 0.30540292E+00 0.30577116E+00 0.30613939E+00 0.30650762E+00
+ 0.30687586E+00 0.30724409E+00 0.30761232E+00 0.30798056E+00 0.30834879E+00
+ 0.30871703E+00 0.30908526E+00 0.30945349E+00 0.30982173E+00 0.31018996E+00
+ 0.31055819E+00 0.31092643E+00 0.31129466E+00 0.31166290E+00 0.31203113E+00
+ 0.31239936E+00 0.31276760E+00 0.31313583E+00 0.31350406E+00 0.31387230E+00
+ 0.31424053E+00 0.31460877E+00 0.31497700E+00 0.31534523E+00 0.31571347E+00
+ 0.31608170E+00 0.31644993E+00 0.31681817E+00 0.31718640E+00 0.31755464E+00
+ 0.31792287E+00 0.31829110E+00 0.31865934E+00 0.31902757E+00 0.31939580E+00
+ 0.31976404E+00 0.32013227E+00 0.32050051E+00 0.32086874E+00 0.32123697E+00
+ 0.32160521E+00 0.32197344E+00 0.32234167E+00 0.32270991E+00 0.32307814E+00
+ 0.32344638E+00 0.32381461E+00 0.32418284E+00 0.32455108E+00 0.32491931E+00
+ 0.32528754E+00 0.32565578E+00 0.32602401E+00 0.32639225E+00 0.32676048E+00
+ 0.32712871E+00 0.32749695E+00 0.32786518E+00 0.32823341E+00 0.32860165E+00
+ 0.32896988E+00 0.32933812E+00 0.32970635E+00 0.33007458E+00 0.33044282E+00
+ 0.33081105E+00 0.33117928E+00 0.33154752E+00 0.33191575E+00 0.33228399E+00
+ 0.33265222E+00 0.33302045E+00 0.33338869E+00 0.33375692E+00 0.33412515E+00
+ 0.33449339E+00 0.33486162E+00 0.33522986E+00 0.33559809E+00 0.33596632E+00
+ 0.33633456E+00 0.33670279E+00 0.33707102E+00 0.33743926E+00 0.33780749E+00
+ 0.33817573E+00 0.33854396E+00 0.33891219E+00 0.33928043E+00 0.33964866E+00
+ 0.34001689E+00 0.34038513E+00 0.34075336E+00 0.34112160E+00 0.34148983E+00
+ 0.34185806E+00 0.34222630E+00 0.34259453E+00 0.34296276E+00 0.34333100E+00
+ 0.34369923E+00 0.34406747E+00 0.34443570E+00 0.34480393E+00 0.34517217E+00
+ 0.34554040E+00 0.34590863E+00 0.34627687E+00 0.34664510E+00 0.34701334E+00
+ 0.34738157E+00 0.34774980E+00 0.34811804E+00 0.34848627E+00 0.34885450E+00
+ 0.34922274E+00 0.34959097E+00 0.34995921E+00 0.35032744E+00 0.35069567E+00
+ 0.35106391E+00 0.35143214E+00 0.35180037E+00 0.35216861E+00 0.35253684E+00
+ 0.35290508E+00 0.35327331E+00 0.35364154E+00 0.35400978E+00 0.35437801E+00
+ 0.35474624E+00 0.35511448E+00 0.35548271E+00 0.35585095E+00 0.35621918E+00
+ 0.35658741E+00 0.35695565E+00 0.35732388E+00 0.35769211E+00 0.35806035E+00
+ 0.35842858E+00 0.35879682E+00 0.35916505E+00 0.35953328E+00 0.35990152E+00
+ 0.36026975E+00 0.36063798E+00 0.36100622E+00 0.36137445E+00 0.36174269E+00
+ 0.36211092E+00 0.36247915E+00 0.36284739E+00 0.36321562E+00 0.36358385E+00
+ 0.36395209E+00 0.36432032E+00 0.36468856E+00 0.36505679E+00 0.36542502E+00
+ 0.36579326E+00 0.36616149E+00 0.36652973E+00 0.36689796E+00 0.36726619E+00
+ 0.36763443E+00 0.36800266E+00 0.36837089E+00 0.36873913E+00 0.36910736E+00
+ 0.36947560E+00 0.36984383E+00 0.37021206E+00 0.37058030E+00 0.37094853E+00
+ 0.37131676E+00 0.37168500E+00 0.37205323E+00 0.37242147E+00 0.37278970E+00
+ 0.37315793E+00 0.37352617E+00 0.37389440E+00 0.37426263E+00 0.37463087E+00
+ 0.37499910E+00 0.37536734E+00 0.37573557E+00 0.37610380E+00 0.37647204E+00
+ 0.37684027E+00 0.37720850E+00 0.37757674E+00 0.37794497E+00 0.37831321E+00
+ 0.37868144E+00 0.37904967E+00 0.37941791E+00 0.37978614E+00 0.38015437E+00
+ 0.38052261E+00 0.38089084E+00 0.38125908E+00 0.38162731E+00 0.38199554E+00
+ 0.38236378E+00 0.38273201E+00 0.38310024E+00 0.38346848E+00 0.38383671E+00
+ 0.38420495E+00 0.38457318E+00 0.38494141E+00 0.38530965E+00 0.38567788E+00
+ 0.38604611E+00 0.38641435E+00 0.38678258E+00 0.38715082E+00 0.38751905E+00
+ 0.38788728E+00 0.38825552E+00 0.38862375E+00 0.38899198E+00 0.38936022E+00
+ 0.38972845E+00 0.39009669E+00 0.39046492E+00 0.39083315E+00 0.39120139E+00
+ 0.39156962E+00 0.39193785E+00 0.39230609E+00 0.39267432E+00 0.39304256E+00
+ 0.39341079E+00 0.39377902E+00 0.39414726E+00 0.39451549E+00 0.39488372E+00
+ 0.39525196E+00 0.39562019E+00 0.39598843E+00 0.39635666E+00 0.39672489E+00
+ 0.39709313E+00 0.39746136E+00 0.39782959E+00 0.39819783E+00 0.39856606E+00
+ 0.39893430E+00 0.39930253E+00 0.39967076E+00 0.40003900E+00 0.40040723E+00
+ 0.40077546E+00 0.40114370E+00 0.40151193E+00 0.40188017E+00 0.40224840E+00
+ 0.40261663E+00 0.40298487E+00 0.40335310E+00 0.40372133E+00 0.40408957E+00
+ 0.40445780E+00 0.40482604E+00 0.40519427E+00 0.40556250E+00 0.40593074E+00
+ 0.40629897E+00 0.40666720E+00 0.40703544E+00 0.40740367E+00 0.40777191E+00
+ 0.40814014E+00 0.40850837E+00 0.40887661E+00 0.40924484E+00 0.40961307E+00
+ 0.40998131E+00 0.41034954E+00 0.41071778E+00 0.41108601E+00 0.41145424E+00
+ 0.41182248E+00 0.41219071E+00 0.41255894E+00 0.41292718E+00 0.41329541E+00
+ 0.41366365E+00 0.41403188E+00 0.41440011E+00 0.41476835E+00 0.41513658E+00
+ 0.41550481E+00 0.41587305E+00 0.41624128E+00 0.41660952E+00 0.41697775E+00
+ 0.41734598E+00 0.41771422E+00 0.41808245E+00 0.41845068E+00 0.41881892E+00
+ 0.41918715E+00 0.41955539E+00 0.41992362E+00 0.42029185E+00 0.42066009E+00
+ 0.42102832E+00 0.42139655E+00 0.42176479E+00 0.42213302E+00 0.42250126E+00
+ 0.42286949E+00 0.42323772E+00 0.42360596E+00 0.42397419E+00 0.42434242E+00
+ 0.42471066E+00 0.42507889E+00 0.42544713E+00 0.42581536E+00 0.42618359E+00
+ 0.42655183E+00 0.42692006E+00 0.42728829E+00 0.42765653E+00 0.42802476E+00
+ 0.42839300E+00 0.42876123E+00 0.42912946E+00 0.42949770E+00 0.42986593E+00
+ 0.43023416E+00 0.43060240E+00 0.43097063E+00 0.43133887E+00 0.43170710E+00
+ 0.43207533E+00 0.43244357E+00 0.43281180E+00 0.43318003E+00 0.43354827E+00
+ 0.43391650E+00 0.43428474E+00 0.43465297E+00 0.43502120E+00 0.43538944E+00
+ 0.43575767E+00 0.43612590E+00 0.43649414E+00 0.43686237E+00 0.43723061E+00
+ 0.43759884E+00 0.43796707E+00 0.43833531E+00 0.43870354E+00 0.43907177E+00
+ 0.43944001E+00 0.43980824E+00 0.44017648E+00 0.44054471E+00 0.44091294E+00
+ 0.44128118E+00 0.44164941E+00 0.44201764E+00 0.44238588E+00 0.44275411E+00
+ 0.44312235E+00 0.44349058E+00 0.44385881E+00 0.44422705E+00 0.44459528E+00
+ 0.44496351E+00 0.44533175E+00 0.44569998E+00 0.44606822E+00 0.44643645E+00
+ 0.44680468E+00 0.44717292E+00 0.44754115E+00 0.44790939E+00 0.44827762E+00
+ 0.44864585E+00 0.44901409E+00 0.44938232E+00 0.44975055E+00 0.45011879E+00
+ 0.45048702E+00 0.45085526E+00 0.45122349E+00 0.45159172E+00 0.45195996E+00
+ 0.45232819E+00 0.45269642E+00 0.45306466E+00 0.45343289E+00 0.45380113E+00
+ 0.45416936E+00 0.45453759E+00 0.45490583E+00 0.45527406E+00 0.45564229E+00
+ 0.45601053E+00 0.45637876E+00 0.45674700E+00 0.45711523E+00 0.45748346E+00
+ 0.45785170E+00 0.45821993E+00 0.45858816E+00 0.45895640E+00 0.45932463E+00
+ 0.45969287E+00 0.46006110E+00 0.46042933E+00 0.46079757E+00 0.46116580E+00
+ 0.46153403E+00 0.46190227E+00 0.46227050E+00 0.46263874E+00 0.46300697E+00
+ 0.46337520E+00 0.46374344E+00 0.46411167E+00 0.46447990E+00 0.46484814E+00
+ 0.46521637E+00 0.46558461E+00 0.46595284E+00 0.46632107E+00 0.46668931E+00
+ 0.46705754E+00 0.46742577E+00 0.46779401E+00 0.46816224E+00 0.46853048E+00
+ 0.46889871E+00 0.46926694E+00 0.46963518E+00 0.47000341E+00 0.47037164E+00
+ 0.47073988E+00 0.47110811E+00 0.47147635E+00 0.47184458E+00 0.47221281E+00
+ 0.47258105E+00 0.47294928E+00 0.47331751E+00 0.47368575E+00 0.47405398E+00
+ 0.47442222E+00 0.47479045E+00 0.47515868E+00 0.47552692E+00 0.47589515E+00
+ 0.47626338E+00 0.47663162E+00 0.47699985E+00 0.47736809E+00 0.47773632E+00
+ 0.47810455E+00 0.47847279E+00 0.47884102E+00 0.47920925E+00 0.47957749E+00
+ 0.47994572E+00 0.48031396E+00 0.48068219E+00 0.48105042E+00 0.48141866E+00
+ 0.48178689E+00 0.48215512E+00 0.48252336E+00 0.48289159E+00 0.48325983E+00
+ 0.48362806E+00 0.48399629E+00 0.48436453E+00 0.48473276E+00 0.48510099E+00
+ 0.48546923E+00 0.48583746E+00 0.48620570E+00 0.48657393E+00 0.48694216E+00
+ 0.48731040E+00 0.48767863E+00 0.48804686E+00 0.48841510E+00 0.48878333E+00
+ 0.48915157E+00 0.48951980E+00 0.48988803E+00 0.49025627E+00 0.49062450E+00
+ 0.49099273E+00 0.49136097E+00 0.49172920E+00 0.49209744E+00 0.49246567E+00
+ 0.49283390E+00 0.49320214E+00 0.49357037E+00 0.49393860E+00 0.49430684E+00
+ 0.49467507E+00 0.49504331E+00 0.49541154E+00 0.49577977E+00 0.49614801E+00
+ 0.49651624E+00 0.49688447E+00 0.49725271E+00 0.49762094E+00 0.49798918E+00
+ 0.49835741E+00 0.49872564E+00 0.49909388E+00 0.49946211E+00 0.49983034E+00
+ 0.50019858E+00 0.50056681E+00 0.50093505E+00 0.50130328E+00 0.50167151E+00
+ 0.50203975E+00 0.50240798E+00 0.50277621E+00 0.50314445E+00 0.50351268E+00
+ 0.50388092E+00 0.50424915E+00 0.50461738E+00 0.50498562E+00 0.50535385E+00
+ 0.50572208E+00 0.50609032E+00 0.50645855E+00 0.50682679E+00 0.50719502E+00
+ 0.50756325E+00 0.50793149E+00 0.50829972E+00 0.50866795E+00 0.50903619E+00
+ 0.50940442E+00 0.50977266E+00 0.51014089E+00 0.51050912E+00 0.51087736E+00
+ 0.51124559E+00 0.51161382E+00 0.51198206E+00 0.51235029E+00 0.51271853E+00
+ 0.51308676E+00 0.51345499E+00 0.51382323E+00 0.51419146E+00 0.51455969E+00
+ 0.51492793E+00 0.51529616E+00 0.51566440E+00 0.51603263E+00 0.51640086E+00
+ 0.51676910E+00 0.51713733E+00 0.51750556E+00 0.51787380E+00 0.51824203E+00
+ 0.51861027E+00 0.51897850E+00 0.51934673E+00 0.51971497E+00 0.52008320E+00
+ 0.52045143E+00 0.52081967E+00 0.52118790E+00 0.52155614E+00 0.52192437E+00
+ 0.52229260E+00 0.52266084E+00 0.52302907E+00 0.52339730E+00 0.52376554E+00
+ 0.52413377E+00 0.52450201E+00 0.52487024E+00 0.52523847E+00 0.52560671E+00
+ 0.52597494E+00 0.52634318E+00 0.52671141E+00 0.52707964E+00 0.52744788E+00
+ 0.52781611E+00 0.52818434E+00 0.52855258E+00 0.52892081E+00 0.52928905E+00
+ 0.52965728E+00 0.53002551E+00 0.53039375E+00 0.53076198E+00 0.53113021E+00
+ 0.53149845E+00 0.53186668E+00 0.53223492E+00 0.53260315E+00 0.53297138E+00
+ 0.53333962E+00 0.53370785E+00 0.53407608E+00 0.53444432E+00 0.53481255E+00
+ 0.53518079E+00 0.53554902E+00 0.53591725E+00 0.53628549E+00 0.53665372E+00
+ 0.53702195E+00 0.53739019E+00 0.53775842E+00 0.53812666E+00 0.53849489E+00
+ 0.53886312E+00 0.53923136E+00 0.53959959E+00 0.53996782E+00 0.54033606E+00
+ 0.54070429E+00 0.54107253E+00 0.54144076E+00 0.54180899E+00 0.54217723E+00
+ 0.54254546E+00 0.54291369E+00 0.54328193E+00 0.54365016E+00 0.54401840E+00
+ 0.54438663E+00 0.54475486E+00 0.54512310E+00 0.54549133E+00 0.54585956E+00
+ 0.54622780E+00 0.54659603E+00 0.54696427E+00 0.54733250E+00 0.54770073E+00
+ 0.54806897E+00 0.54843720E+00 0.54880543E+00 0.54917367E+00 0.54954190E+00
+ 0.54991014E+00 0.55027837E+00 0.55064660E+00 0.55101484E+00 0.55138307E+00
+ 0.55175130E+00 0.55211954E+00 0.55248777E+00 0.55285601E+00 0.55322424E+00
+ 0.55361718E+00 0.55402474E+00 0.55443207E+00 0.55483916E+00 0.55524602E+00
+ 0.55565264E+00 0.55605902E+00 0.55646516E+00 0.55687106E+00 0.55727671E+00
+ 0.55768213E+00 0.55808730E+00 0.55849223E+00 0.55889691E+00 0.55930134E+00
+ 0.55970553E+00 0.56010947E+00 0.56051316E+00 0.56091660E+00 0.56131979E+00
+ 0.56172273E+00 0.56212541E+00 0.56252784E+00 0.56293002E+00 0.56333194E+00
+ 0.56373361E+00 0.56413501E+00 0.56453616E+00 0.56493705E+00 0.56533767E+00
+ 0.56573804E+00 0.56613814E+00 0.56653798E+00 0.56693755E+00 0.56733686E+00
+ 0.56773590E+00 0.56813468E+00 0.56853318E+00 0.56893142E+00 0.56932938E+00
+ 0.56972707E+00 0.57012449E+00 0.57052164E+00 0.57091851E+00 0.57131510E+00
+ 0.57171142E+00 0.57210746E+00 0.57250321E+00 0.57289869E+00 0.57329389E+00
+ 0.57368880E+00 0.57408343E+00 0.57447777E+00 0.57487183E+00 0.57526560E+00
+ 0.57565908E+00 0.57605227E+00 0.57644518E+00 0.57683778E+00 0.57723010E+00
+ 0.57762212E+00 0.57801385E+00 0.57840528E+00 0.57879641E+00 0.57918725E+00
+ 0.57957778E+00 0.57996801E+00 0.58035794E+00 0.58074757E+00 0.58113689E+00
+ 0.58152590E+00 0.58191461E+00 0.58230301E+00 0.58269110E+00 0.58307887E+00
+ 0.58346634E+00 0.58385349E+00 0.58424032E+00 0.58462684E+00 0.58501305E+00
+ 0.58539893E+00 0.58578449E+00 0.58616973E+00 0.58655465E+00 0.58693925E+00
+ 0.58732352E+00 0.58770746E+00 0.58809107E+00 0.58847436E+00 0.58885731E+00
+ 0.58923993E+00 0.58962222E+00 0.59000418E+00 0.59038579E+00 0.59076707E+00
+ 0.59114801E+00 0.59152861E+00 0.59190887E+00 0.59228879E+00 0.59266836E+00
+ 0.59304758E+00 0.59342646E+00 0.59380498E+00 0.59418316E+00 0.59456098E+00
+ 0.59493845E+00 0.59531557E+00 0.59569233E+00 0.59606873E+00 0.59644477E+00
+ 0.59682046E+00 0.59719577E+00 0.59757073E+00 0.59794532E+00 0.59831954E+00
+ 0.59869339E+00 0.59906688E+00 0.59943999E+00 0.59981273E+00 0.60018509E+00
+ 0.60055707E+00 0.60092868E+00 0.60129991E+00 0.60167076E+00 0.60204122E+00
+ 0.60241130E+00 0.60278099E+00 0.60315030E+00 0.60351921E+00 0.60388774E+00
+ 0.60425587E+00 0.60462360E+00 0.60499094E+00 0.60535788E+00 0.60572442E+00
+ 0.60609056E+00 0.60645630E+00 0.60682163E+00 0.60718656E+00 0.60755107E+00
+ 0.60791518E+00 0.60827887E+00 0.60864215E+00 0.60900501E+00 0.60936746E+00
+ 0.60972948E+00 0.61009109E+00 0.61045227E+00 0.61081303E+00 0.61117336E+00
+ 0.61153326E+00 0.61189273E+00 0.61225176E+00 0.61261037E+00 0.61296853E+00
+ 0.61332626E+00 0.61368355E+00 0.61404039E+00 0.61439679E+00 0.61475275E+00
+ 0.61510825E+00 0.61546331E+00 0.61581791E+00 0.61617206E+00 0.61652576E+00
+ 0.61687899E+00 0.61723177E+00 0.61758408E+00 0.61793593E+00 0.61828731E+00
+ 0.61863822E+00 0.61898866E+00 0.61933863E+00 0.61968812E+00 0.62003714E+00
+ 0.62038567E+00 0.62073373E+00 0.62108130E+00 0.62142838E+00 0.62177498E+00
+ 0.62212108E+00 0.62246670E+00 0.62281181E+00 0.62315644E+00 0.62350056E+00
+ 0.62384418E+00 0.62418729E+00 0.62452990E+00 0.62487200E+00 0.62521359E+00
+ 0.62555466E+00 0.62589522E+00 0.62623526E+00 0.62657479E+00 0.62691378E+00
+ 0.62725225E+00 0.62759020E+00 0.62792761E+00 0.62826449E+00 0.62860084E+00
+ 0.62893665E+00 0.62927191E+00 0.62960664E+00 0.62994082E+00 0.63027445E+00
+ 0.63060753E+00 0.63094006E+00 0.63127203E+00 0.63160344E+00 0.63193430E+00
+ 0.63226458E+00 0.63259431E+00 0.63292346E+00 0.63325204E+00 0.63358005E+00
+ 0.63390748E+00 0.63423433E+00 0.63456060E+00 0.63488629E+00 0.63521138E+00
+ 0.63553589E+00 0.63585980E+00 0.63618311E+00 0.63650582E+00 0.63682794E+00
+ 0.63714945E+00 0.63747034E+00 0.63779063E+00 0.63811031E+00 0.63842937E+00
+ 0.63874780E+00 0.63906562E+00 0.63938281E+00 0.63969937E+00 0.64001530E+00
+ 0.64033059E+00 0.64064525E+00 0.64095927E+00 0.64127264E+00 0.64158536E+00
+ 0.64189744E+00 0.64220886E+00 0.64251962E+00 0.64282972E+00 0.64313916E+00
+ 0.64344794E+00 0.64375604E+00 0.64406347E+00 0.64437023E+00 0.64467631E+00
+ 0.64498170E+00 0.64528641E+00 0.64559043E+00 0.64589375E+00 0.64619638E+00
+ 0.64649831E+00 0.64679953E+00 0.64710005E+00 0.64739986E+00 0.64769896E+00
+ 0.64799734E+00 0.64829500E+00 0.64859193E+00 0.64888814E+00 0.64918361E+00
+ 0.64947835E+00 0.64977235E+00 0.65006561E+00 0.65035812E+00 0.65064989E+00
+ 0.65094090E+00 0.65123115E+00 0.65152064E+00 0.65180937E+00 0.65209733E+00
+ 0.65238451E+00 0.65267092E+00 0.65295655E+00 0.65324140E+00 0.65352546E+00
+ 0.65380873E+00 0.65409120E+00 0.65437287E+00 0.65465374E+00 0.65493379E+00
+ 0.65521304E+00 0.65549147E+00 0.65576909E+00 0.65604587E+00 0.65632183E+00
+ 0.65659696E+00 0.65687125E+00 0.65714470E+00 0.65741731E+00 0.65768906E+00
+ 0.65795996E+00 0.65823001E+00 0.65849919E+00 0.65876750E+00 0.65903495E+00
+ 0.65930152E+00 0.65956721E+00 0.65983201E+00 0.66009593E+00 0.66035896E+00
+ 0.66062108E+00 0.66088231E+00 0.66114262E+00 0.66140203E+00 0.66166052E+00
+ 0.66191809E+00 0.66217474E+00 0.66243045E+00 0.66268523E+00 0.66293908E+00
+ 0.66319197E+00 0.66344392E+00 0.66369492E+00 0.66394496E+00 0.66419403E+00
+ 0.66444214E+00 0.66468927E+00 0.66493543E+00 0.66518060E+00 0.66542479E+00
+ 0.66566798E+00 0.66591018E+00 0.66615137E+00 0.66639156E+00 0.66663073E+00
+ 0.66686888E+00 0.66710602E+00 0.66734212E+00 0.66757719E+00 0.66781122E+00
+ 0.66804421E+00 0.66827615E+00 0.66850704E+00 0.66873687E+00 0.66896563E+00
+ 0.66919332E+00 0.66941994E+00 0.66964548E+00 0.66986993E+00 0.67009329E+00
+ 0.67031555E+00 0.67053671E+00 0.67075676E+00 0.67097570E+00 0.67119352E+00
+ 0.67141022E+00 0.67162579E+00 0.67184022E+00 0.67205351E+00 0.67226566E+00
+ 0.67247665E+00 0.67268648E+00 0.67289516E+00 0.67310266E+00 0.67330899E+00
+ 0.67351414E+00 0.67371810E+00 0.67392087E+00 0.67412244E+00 0.67432281E+00
+ 0.67452197E+00 0.67471992E+00 0.67491665E+00 0.67511215E+00 0.67530642E+00
+ 0.67549945E+00 0.67569123E+00 0.67588177E+00 0.67607105E+00 0.67625907E+00
+ 0.67644582E+00 0.67663131E+00 0.67681551E+00 0.67699842E+00 0.67718005E+00
+ 0.67736038E+00 0.67753941E+00 0.67771713E+00 0.67789354E+00 0.67806862E+00
+ 0.67824238E+00 0.67841481E+00 0.67858591E+00 0.67875565E+00 0.67892405E+00
+ 0.67909110E+00 0.67925678E+00 0.67942110E+00 0.67958405E+00 0.67974561E+00
+ 0.67990580E+00 0.68006459E+00 0.68022199E+00 0.68037799E+00 0.68053258E+00
+ 0.68068576E+00 0.68083752E+00 0.68098786E+00 0.68113677E+00 0.68128424E+00
+ 0.68143027E+00 0.68157486E+00 0.68171800E+00 0.68185968E+00 0.68199991E+00
+ 0.68213866E+00 0.68227594E+00 0.68241175E+00 0.68254607E+00 0.68267891E+00
+ 0.68281025E+00 0.68294010E+00 0.68306844E+00 0.68319528E+00 0.68332061E+00
+ 0.68344442E+00 0.68356671E+00 0.68368747E+00 0.68380671E+00 0.68392441E+00
+ 0.68404058E+00 0.68415520E+00 0.68426828E+00 0.68437981E+00 0.68448979E+00
+ 0.68459821E+00 0.68470507E+00 0.68481036E+00 0.68491409E+00 0.68501625E+00
+ 0.68511684E+00 0.68521586E+00 0.68531329E+00 0.68540915E+00 0.68550342E+00
+ 0.68559611E+00 0.68568721E+00 0.68577673E+00 0.68586466E+00 0.68595100E+00
+ 0.68603574E+00 0.68611890E+00 0.68620046E+00 0.68628043E+00 0.68635880E+00
+ 0.68643559E+00 0.68651078E+00 0.68658438E+00 0.68665640E+00 0.68672682E+00
+ 0.68679566E+00 0.68686291E+00 0.68692858E+00 0.68699267E+00 0.68705519E+00
+ 0.68711613E+00 0.68717551E+00 0.68723332E+00 0.68728957E+00 0.68734427E+00
+ 0.68739742E+00 0.68744903E+00 0.68749910E+00 0.68754765E+00 0.68759467E+00
+ 0.68764018E+00 0.68768419E+00 0.68772670E+00 0.68776773E+00 0.68780729E+00
+ 0.68784538E+00 0.68788203E+00 0.68791723E+00 0.68795101E+00 0.68798338E+00
+ 0.68801436E+00 0.68804395E+00 0.68807219E+00 0.68809907E+00 0.68812463E+00
+ 0.68814888E+00 0.68817184E+00 0.68819353E+00 0.68821398E+00 0.68823321E+00
+ 0.68825123E+00 0.68826809E+00 0.68828379E+00 0.68829838E+00 0.68831188E+00
+ 0.68832432E+00 0.68833573E+00 0.68834615E+00 0.68835560E+00 0.68836413E+00
+ 0.68837177E+00 0.68837856E+00 0.68838455E+00 0.68838977E+00 0.68839426E+00
+ 0.68839808E+00 0.68840128E+00 0.68840389E+00 0.68840598E+00 0.68840759E+00
+ 0.68840879E+00 0.68840962E+00 0.68841016E+00 0.68841047E+00 0.68841060E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00 0.68841064E+00
+ 0.00000000E+00 0.50025014E-03 0.10005003E-02 0.15007504E-02 0.20010006E-02
+ 0.25012507E-02 0.30015009E-02 0.35017510E-02 0.40020011E-02 0.45022513E-02
+ 0.50025014E-02 0.55027516E-02 0.60030017E-02 0.65032518E-02 0.70035020E-02
+ 0.75037521E-02 0.80040023E-02 0.85042524E-02 0.90045026E-02 0.95047527E-02
+ 0.10005003E-01 0.10505253E-01 0.11005503E-01 0.11505753E-01 0.12006003E-01
+ 0.12506254E-01 0.13006504E-01 0.13506754E-01 0.14007004E-01 0.14507254E-01
+ 0.15007504E-01 0.15507754E-01 0.16008005E-01 0.16508255E-01 0.17008505E-01
+ 0.17508755E-01 0.18009005E-01 0.18509255E-01 0.19009505E-01 0.19509756E-01
+ 0.20010006E-01 0.20510256E-01 0.21010506E-01 0.21510756E-01 0.22011006E-01
+ 0.22511256E-01 0.23011507E-01 0.23511757E-01 0.24012007E-01 0.24512257E-01
+ 0.25012507E-01 0.25512757E-01 0.26013007E-01 0.26513258E-01 0.27013508E-01
+ 0.27513758E-01 0.28014008E-01 0.28514258E-01 0.29014508E-01 0.29514758E-01
+ 0.30015009E-01 0.30515259E-01 0.31015509E-01 0.31515759E-01 0.32016009E-01
+ 0.32516259E-01 0.33016509E-01 0.33516760E-01 0.34017010E-01 0.34517260E-01
+ 0.35017510E-01 0.35517760E-01 0.36018010E-01 0.36518260E-01 0.37018511E-01
+ 0.37518761E-01 0.38019011E-01 0.38519261E-01 0.39019511E-01 0.39519761E-01
+ 0.40020011E-01 0.40520262E-01 0.41020512E-01 0.41520762E-01 0.42021012E-01
+ 0.42521262E-01 0.43021512E-01 0.43521762E-01 0.44022013E-01 0.44522263E-01
+ 0.45022513E-01 0.45522763E-01 0.46023013E-01 0.46523263E-01 0.47023513E-01
+ 0.47523763E-01 0.48024014E-01 0.48524264E-01 0.49024514E-01 0.49524764E-01
+ 0.50025014E-01 0.50525264E-01 0.51025514E-01 0.51525765E-01 0.52026015E-01
+ 0.52526265E-01 0.53026515E-01 0.53526765E-01 0.54027015E-01 0.54527265E-01
+ 0.55027516E-01 0.55527766E-01 0.56028016E-01 0.56528266E-01 0.57028516E-01
+ 0.57528766E-01 0.58029016E-01 0.58529267E-01 0.59029517E-01 0.59529767E-01
+ 0.60030017E-01 0.60530267E-01 0.61030517E-01 0.61530767E-01 0.62031018E-01
+ 0.62531268E-01 0.63031518E-01 0.63531768E-01 0.64032018E-01 0.64532268E-01
+ 0.65032518E-01 0.65532769E-01 0.66033019E-01 0.66533269E-01 0.67033519E-01
+ 0.67533769E-01 0.68034019E-01 0.68534269E-01 0.69034520E-01 0.69534770E-01
+ 0.70035020E-01 0.70535270E-01 0.71035520E-01 0.71535770E-01 0.72036020E-01
+ 0.72536271E-01 0.73036521E-01 0.73536771E-01 0.74037021E-01 0.74537271E-01
+ 0.75037521E-01 0.75537771E-01 0.76038022E-01 0.76538272E-01 0.77038522E-01
+ 0.77538772E-01 0.78039022E-01 0.78539272E-01 0.79039522E-01 0.79539773E-01
+ 0.80040023E-01 0.80540273E-01 0.81040523E-01 0.81540773E-01 0.82041023E-01
+ 0.82541273E-01 0.83041524E-01 0.83541774E-01 0.84042024E-01 0.84542274E-01
+ 0.85042524E-01 0.85542774E-01 0.86043024E-01 0.86543275E-01 0.87043525E-01
+ 0.87543775E-01 0.88044025E-01 0.88544275E-01 0.89044525E-01 0.89544775E-01
+ 0.90045026E-01 0.90545276E-01 0.91045526E-01 0.91545776E-01 0.92046026E-01
+ 0.92546276E-01 0.93046526E-01 0.93546777E-01 0.94047027E-01 0.94547277E-01
+ 0.95047527E-01 0.95547777E-01 0.96048027E-01 0.96548277E-01 0.97048528E-01
+ 0.97548778E-01 0.98049028E-01 0.98549278E-01 0.99049528E-01 0.99549778E-01
+ 0.10005003E+00 0.10055028E+00 0.10105053E+00 0.10155078E+00 0.10205103E+00
+ 0.10255128E+00 0.10305153E+00 0.10355178E+00 0.10405203E+00 0.10455228E+00
+ 0.10505253E+00 0.10555278E+00 0.10605303E+00 0.10655328E+00 0.10705353E+00
+ 0.10755378E+00 0.10805403E+00 0.10855428E+00 0.10905453E+00 0.10955478E+00
+ 0.11005503E+00 0.11055528E+00 0.11105553E+00 0.11155578E+00 0.11205603E+00
+ 0.11255628E+00 0.11305653E+00 0.11355678E+00 0.11405703E+00 0.11455728E+00
+ 0.11505753E+00 0.11555778E+00 0.11605803E+00 0.11655828E+00 0.11705853E+00
+ 0.11755878E+00 0.11805903E+00 0.11855928E+00 0.11905953E+00 0.11955978E+00
+ 0.12006003E+00 0.12056028E+00 0.12106053E+00 0.12156078E+00 0.12206103E+00
+ 0.12256128E+00 0.12306153E+00 0.12356179E+00 0.12406204E+00 0.12456229E+00
+ 0.12506254E+00 0.12556279E+00 0.12606304E+00 0.12656329E+00 0.12706354E+00
+ 0.12756379E+00 0.12806404E+00 0.12856429E+00 0.12906454E+00 0.12956479E+00
+ 0.13006504E+00 0.13056529E+00 0.13106554E+00 0.13156579E+00 0.13206604E+00
+ 0.13256629E+00 0.13306654E+00 0.13356679E+00 0.13406704E+00 0.13456729E+00
+ 0.13506754E+00 0.13556779E+00 0.13606804E+00 0.13656829E+00 0.13706854E+00
+ 0.13756879E+00 0.13806904E+00 0.13856929E+00 0.13906954E+00 0.13956979E+00
+ 0.14007004E+00 0.14057029E+00 0.14107054E+00 0.14157079E+00 0.14207104E+00
+ 0.14257129E+00 0.14307154E+00 0.14357179E+00 0.14407204E+00 0.14457229E+00
+ 0.14507254E+00 0.14557279E+00 0.14607304E+00 0.14657329E+00 0.14707354E+00
+ 0.14757379E+00 0.14807404E+00 0.14857429E+00 0.14907454E+00 0.14957479E+00
+ 0.15007504E+00 0.15057529E+00 0.15107554E+00 0.15157579E+00 0.15207604E+00
+ 0.15257629E+00 0.15307654E+00 0.15357679E+00 0.15407704E+00 0.15457729E+00
+ 0.15507754E+00 0.15557779E+00 0.15607804E+00 0.15657829E+00 0.15707854E+00
+ 0.15757879E+00 0.15807904E+00 0.15857930E+00 0.15907955E+00 0.15957980E+00
+ 0.16008005E+00 0.16058030E+00 0.16108055E+00 0.16158080E+00 0.16208105E+00
+ 0.16258130E+00 0.16308155E+00 0.16358180E+00 0.16408205E+00 0.16458230E+00
+ 0.16508255E+00 0.16558280E+00 0.16608305E+00 0.16658330E+00 0.16708355E+00
+ 0.16758380E+00 0.16808405E+00 0.16858430E+00 0.16908455E+00 0.16958480E+00
+ 0.17008505E+00 0.17058530E+00 0.17108555E+00 0.17158580E+00 0.17208605E+00
+ 0.17258630E+00 0.17308655E+00 0.17358680E+00 0.17408705E+00 0.17458730E+00
+ 0.17508755E+00 0.17558780E+00 0.17608805E+00 0.17658830E+00 0.17708855E+00
+ 0.17758880E+00 0.17808905E+00 0.17858930E+00 0.17908955E+00 0.17958980E+00
+ 0.18009005E+00 0.18059030E+00 0.18109055E+00 0.18159080E+00 0.18209105E+00
+ 0.18259130E+00 0.18309155E+00 0.18359180E+00 0.18409205E+00 0.18459230E+00
+ 0.18509255E+00 0.18559280E+00 0.18609305E+00 0.18659330E+00 0.18709355E+00
+ 0.18759380E+00 0.18809405E+00 0.18859430E+00 0.18909455E+00 0.18959480E+00
+ 0.19009505E+00 0.19059530E+00 0.19109555E+00 0.19159580E+00 0.19209605E+00
+ 0.19259630E+00 0.19309655E+00 0.19359680E+00 0.19409706E+00 0.19459731E+00
+ 0.19509756E+00 0.19559781E+00 0.19609806E+00 0.19659831E+00 0.19709856E+00
+ 0.19759881E+00 0.19809906E+00 0.19859931E+00 0.19909956E+00 0.19959981E+00
+ 0.20010006E+00 0.20060031E+00 0.20110056E+00 0.20160081E+00 0.20210106E+00
+ 0.20260131E+00 0.20310156E+00 0.20360181E+00 0.20410206E+00 0.20460231E+00
+ 0.20510256E+00 0.20560281E+00 0.20610306E+00 0.20660331E+00 0.20710356E+00
+ 0.20760381E+00 0.20810406E+00 0.20860431E+00 0.20910456E+00 0.20960481E+00
+ 0.21010506E+00 0.21060531E+00 0.21110556E+00 0.21160581E+00 0.21210606E+00
+ 0.21260631E+00 0.21310656E+00 0.21360681E+00 0.21410706E+00 0.21460731E+00
+ 0.21510756E+00 0.21560781E+00 0.21610806E+00 0.21660831E+00 0.21710856E+00
+ 0.21760881E+00 0.21810906E+00 0.21860931E+00 0.21910956E+00 0.21960981E+00
+ 0.22011006E+00 0.22061031E+00 0.22111056E+00 0.22161081E+00 0.22211106E+00
+ 0.22261131E+00 0.22311156E+00 0.22361181E+00 0.22411206E+00 0.22461231E+00
+ 0.22511256E+00 0.22561281E+00 0.22611306E+00 0.22661331E+00 0.22711356E+00
+ 0.22761381E+00 0.22811406E+00 0.22861431E+00 0.22911457E+00 0.22961482E+00
+ 0.23011507E+00 0.23061532E+00 0.23111557E+00 0.23161582E+00 0.23211607E+00
+ 0.23261632E+00 0.23311657E+00 0.23361682E+00 0.23411707E+00 0.23461732E+00
+ 0.23511757E+00 0.23561782E+00 0.23611807E+00 0.23661832E+00 0.23711857E+00
+ 0.23761882E+00 0.23811907E+00 0.23861932E+00 0.23911957E+00 0.23961982E+00
+ 0.24012007E+00 0.24062032E+00 0.24112057E+00 0.24162082E+00 0.24212107E+00
+ 0.24262132E+00 0.24312157E+00 0.24362182E+00 0.24412207E+00 0.24462232E+00
+ 0.24512257E+00 0.24562282E+00 0.24612307E+00 0.24662332E+00 0.24712357E+00
+ 0.24762382E+00 0.24812407E+00 0.24862432E+00 0.24912457E+00 0.24962482E+00
+ 0.25012507E+00 0.25062532E+00 0.25112557E+00 0.25162582E+00 0.25212607E+00
+ 0.25262632E+00 0.25312657E+00 0.25362682E+00 0.25412707E+00 0.25462732E+00
+ 0.25512757E+00 0.25562782E+00 0.25612807E+00 0.25662832E+00 0.25712857E+00
+ 0.25762882E+00 0.25812907E+00 0.25862932E+00 0.25912957E+00 0.25962982E+00
+ 0.26013007E+00 0.26063032E+00 0.26113057E+00 0.26163082E+00 0.26213107E+00
+ 0.26263132E+00 0.26313157E+00 0.26363182E+00 0.26413208E+00 0.26463233E+00
+ 0.26513258E+00 0.26563283E+00 0.26613308E+00 0.26663333E+00 0.26713358E+00
+ 0.26763383E+00 0.26813408E+00 0.26863433E+00 0.26913458E+00 0.26963483E+00
+ 0.27013508E+00 0.27063533E+00 0.27113558E+00 0.27163583E+00 0.27213608E+00
+ 0.27263633E+00 0.27313658E+00 0.27363683E+00 0.27413708E+00 0.27463733E+00
+ 0.27513758E+00 0.27563783E+00 0.27613808E+00 0.27663833E+00 0.27713858E+00
+ 0.27763883E+00 0.27813908E+00 0.27863933E+00 0.27913958E+00 0.27963983E+00
+ 0.28014008E+00 0.28064033E+00 0.28114058E+00 0.28164083E+00 0.28214108E+00
+ 0.28264133E+00 0.28314158E+00 0.28364183E+00 0.28414208E+00 0.28464233E+00
+ 0.28514258E+00 0.28564283E+00 0.28614308E+00 0.28664333E+00 0.28714358E+00
+ 0.28764383E+00 0.28814408E+00 0.28864433E+00 0.28914458E+00 0.28964483E+00
+ 0.29014508E+00 0.29064533E+00 0.29114558E+00 0.29164583E+00 0.29214608E+00
+ 0.29264633E+00 0.29314658E+00 0.29364683E+00 0.29414708E+00 0.29464733E+00
+ 0.29514758E+00 0.29564783E+00 0.29614808E+00 0.29664833E+00 0.29714858E+00
+ 0.29764883E+00 0.29814908E+00 0.29864933E+00 0.29914958E+00 0.29964984E+00
+ 0.30015009E+00 0.30065034E+00 0.30115059E+00 0.30165084E+00 0.30215109E+00
+ 0.30265134E+00 0.30315159E+00 0.30365184E+00 0.30415209E+00 0.30465234E+00
+ 0.30515259E+00 0.30565284E+00 0.30615309E+00 0.30665334E+00 0.30715359E+00
+ 0.30765384E+00 0.30815409E+00 0.30865434E+00 0.30915459E+00 0.30965484E+00
+ 0.31015509E+00 0.31065534E+00 0.31115559E+00 0.31165584E+00 0.31215609E+00
+ 0.31265634E+00 0.31315659E+00 0.31365684E+00 0.31415709E+00 0.31465734E+00
+ 0.31515759E+00 0.31565784E+00 0.31615809E+00 0.31665834E+00 0.31715859E+00
+ 0.31765884E+00 0.31815909E+00 0.31865934E+00 0.31915959E+00 0.31965984E+00
+ 0.32016009E+00 0.32066034E+00 0.32116059E+00 0.32166084E+00 0.32216109E+00
+ 0.32266134E+00 0.32316159E+00 0.32366184E+00 0.32416209E+00 0.32466234E+00
+ 0.32516259E+00 0.32566284E+00 0.32616309E+00 0.32666334E+00 0.32716359E+00
+ 0.32766384E+00 0.32816409E+00 0.32866434E+00 0.32916459E+00 0.32966484E+00
+ 0.33016509E+00 0.33066534E+00 0.33116559E+00 0.33166584E+00 0.33216609E+00
+ 0.33266634E+00 0.33316659E+00 0.33366684E+00 0.33416709E+00 0.33466735E+00
+ 0.33516760E+00 0.33566785E+00 0.33616810E+00 0.33666835E+00 0.33716860E+00
+ 0.33766885E+00 0.33816910E+00 0.33866935E+00 0.33916960E+00 0.33966985E+00
+ 0.34017010E+00 0.34067035E+00 0.34117060E+00 0.34167085E+00 0.34217110E+00
+ 0.34267135E+00 0.34317160E+00 0.34367185E+00 0.34417210E+00 0.34467235E+00
+ 0.34517260E+00 0.34567285E+00 0.34617310E+00 0.34667335E+00 0.34717360E+00
+ 0.34767385E+00 0.34817410E+00 0.34867435E+00 0.34917460E+00 0.34967485E+00
+ 0.35017510E+00 0.35067535E+00 0.35117560E+00 0.35167585E+00 0.35217610E+00
+ 0.35267635E+00 0.35317660E+00 0.35367685E+00 0.35417710E+00 0.35467735E+00
+ 0.35517760E+00 0.35567785E+00 0.35617810E+00 0.35667835E+00 0.35717860E+00
+ 0.35767885E+00 0.35817910E+00 0.35867935E+00 0.35917960E+00 0.35967985E+00
+ 0.36018010E+00 0.36068035E+00 0.36118060E+00 0.36168085E+00 0.36218110E+00
+ 0.36268135E+00 0.36318160E+00 0.36368185E+00 0.36418210E+00 0.36468235E+00
+ 0.36518260E+00 0.36568285E+00 0.36618310E+00 0.36668335E+00 0.36718360E+00
+ 0.36768385E+00 0.36818410E+00 0.36868435E+00 0.36918460E+00 0.36968485E+00
+ 0.37018511E+00 0.37068536E+00 0.37118561E+00 0.37168586E+00 0.37218611E+00
+ 0.37268636E+00 0.37318661E+00 0.37368686E+00 0.37418711E+00 0.37468736E+00
+ 0.37518761E+00 0.37568786E+00 0.37618811E+00 0.37668836E+00 0.37718861E+00
+ 0.37768886E+00 0.37818911E+00 0.37868936E+00 0.37918961E+00 0.37968986E+00
+ 0.38019011E+00 0.38069036E+00 0.38119061E+00 0.38169086E+00 0.38219111E+00
+ 0.38269136E+00 0.38319161E+00 0.38369186E+00 0.38419211E+00 0.38469236E+00
+ 0.38519261E+00 0.38569286E+00 0.38619311E+00 0.38669336E+00 0.38719361E+00
+ 0.38769386E+00 0.38819411E+00 0.38869436E+00 0.38919461E+00 0.38969486E+00
+ 0.39019511E+00 0.39069536E+00 0.39119561E+00 0.39169586E+00 0.39219611E+00
+ 0.39269636E+00 0.39319661E+00 0.39369686E+00 0.39419711E+00 0.39469736E+00
+ 0.39519761E+00 0.39569786E+00 0.39619811E+00 0.39669836E+00 0.39719861E+00
+ 0.39769886E+00 0.39819911E+00 0.39869936E+00 0.39919961E+00 0.39969986E+00
+ 0.40020011E+00 0.40070036E+00 0.40120061E+00 0.40170086E+00 0.40220111E+00
+ 0.40270136E+00 0.40320161E+00 0.40370186E+00 0.40420211E+00 0.40470236E+00
+ 0.40520262E+00 0.40570287E+00 0.40620312E+00 0.40670337E+00 0.40720362E+00
+ 0.40770387E+00 0.40820412E+00 0.40870437E+00 0.40920462E+00 0.40970487E+00
+ 0.41020512E+00 0.41070537E+00 0.41120562E+00 0.41170587E+00 0.41220612E+00
+ 0.41270637E+00 0.41320662E+00 0.41370687E+00 0.41420712E+00 0.41470737E+00
+ 0.41520762E+00 0.41570787E+00 0.41620812E+00 0.41670837E+00 0.41720862E+00
+ 0.41770887E+00 0.41820912E+00 0.41870937E+00 0.41920962E+00 0.41970987E+00
+ 0.42021012E+00 0.42071037E+00 0.42121062E+00 0.42171087E+00 0.42221112E+00
+ 0.42271137E+00 0.42321162E+00 0.42371187E+00 0.42421212E+00 0.42471237E+00
+ 0.42521262E+00 0.42571287E+00 0.42621312E+00 0.42671337E+00 0.42721362E+00
+ 0.42771387E+00 0.42821412E+00 0.42871437E+00 0.42921462E+00 0.42971487E+00
+ 0.43021512E+00 0.43071537E+00 0.43121562E+00 0.43171587E+00 0.43221612E+00
+ 0.43271637E+00 0.43321662E+00 0.43371687E+00 0.43421712E+00 0.43471737E+00
+ 0.43521762E+00 0.43571787E+00 0.43621812E+00 0.43671837E+00 0.43721862E+00
+ 0.43771887E+00 0.43821912E+00 0.43871937E+00 0.43921962E+00 0.43971987E+00
+ 0.44022013E+00 0.44072038E+00 0.44122063E+00 0.44172088E+00 0.44222113E+00
+ 0.44272138E+00 0.44322163E+00 0.44372188E+00 0.44422213E+00 0.44472238E+00
+ 0.44522263E+00 0.44572288E+00 0.44622313E+00 0.44672338E+00 0.44722363E+00
+ 0.44772388E+00 0.44822413E+00 0.44872438E+00 0.44922463E+00 0.44972488E+00
+ 0.45022513E+00 0.45072538E+00 0.45122563E+00 0.45172588E+00 0.45222613E+00
+ 0.45272638E+00 0.45322663E+00 0.45372688E+00 0.45422713E+00 0.45472738E+00
+ 0.45522763E+00 0.45572788E+00 0.45622813E+00 0.45672838E+00 0.45722863E+00
+ 0.45772888E+00 0.45822913E+00 0.45872938E+00 0.45922963E+00 0.45972988E+00
+ 0.46023013E+00 0.46073038E+00 0.46123063E+00 0.46173088E+00 0.46223113E+00
+ 0.46273138E+00 0.46323163E+00 0.46373188E+00 0.46423213E+00 0.46473238E+00
+ 0.46523263E+00 0.46573288E+00 0.46623313E+00 0.46673338E+00 0.46723363E+00
+ 0.46773388E+00 0.46823413E+00 0.46873438E+00 0.46923463E+00 0.46973488E+00
+ 0.47023513E+00 0.47073538E+00 0.47123563E+00 0.47173588E+00 0.47223613E+00
+ 0.47273638E+00 0.47323663E+00 0.47373688E+00 0.47423713E+00 0.47473738E+00
+ 0.47523763E+00 0.47573789E+00 0.47623814E+00 0.47673839E+00 0.47723864E+00
+ 0.47773889E+00 0.47823914E+00 0.47873939E+00 0.47923964E+00 0.47973989E+00
+ 0.48024014E+00 0.48074039E+00 0.48124064E+00 0.48174089E+00 0.48224114E+00
+ 0.48274139E+00 0.48324164E+00 0.48374189E+00 0.48424214E+00 0.48474239E+00
+ 0.48524264E+00 0.48574289E+00 0.48624314E+00 0.48674339E+00 0.48724364E+00
+ 0.48774389E+00 0.48824414E+00 0.48874439E+00 0.48924464E+00 0.48974489E+00
+ 0.49024514E+00 0.49074539E+00 0.49124564E+00 0.49174589E+00 0.49224614E+00
+ 0.49274639E+00 0.49324664E+00 0.49374689E+00 0.49424714E+00 0.49474739E+00
+ 0.49524764E+00 0.49574789E+00 0.49624814E+00 0.49674839E+00 0.49724864E+00
+ 0.49774889E+00 0.49824914E+00 0.49874939E+00 0.49924964E+00 0.49974989E+00
+ 0.50025014E+00 0.50075039E+00 0.50125064E+00 0.50175089E+00 0.50225114E+00
+ 0.50275139E+00 0.50325164E+00 0.50375189E+00 0.50425214E+00 0.50475239E+00
+ 0.50525264E+00 0.50575289E+00 0.50625314E+00 0.50675339E+00 0.50725364E+00
+ 0.50775389E+00 0.50825414E+00 0.50875439E+00 0.50925464E+00 0.50975489E+00
+ 0.51025514E+00 0.51075540E+00 0.51125565E+00 0.51175590E+00 0.51225615E+00
+ 0.51275640E+00 0.51325665E+00 0.51375690E+00 0.51425715E+00 0.51475740E+00
+ 0.51525765E+00 0.51575790E+00 0.51625815E+00 0.51675840E+00 0.51725865E+00
+ 0.51775890E+00 0.51825915E+00 0.51875940E+00 0.51925965E+00 0.51975990E+00
+ 0.52026015E+00 0.52076040E+00 0.52126065E+00 0.52176090E+00 0.52226115E+00
+ 0.52276140E+00 0.52326165E+00 0.52376190E+00 0.52426215E+00 0.52476240E+00
+ 0.52526265E+00 0.52576290E+00 0.52626315E+00 0.52676340E+00 0.52726365E+00
+ 0.52776390E+00 0.52826415E+00 0.52876440E+00 0.52926465E+00 0.52976490E+00
+ 0.53026515E+00 0.53076540E+00 0.53126565E+00 0.53176590E+00 0.53226615E+00
+ 0.53276640E+00 0.53326665E+00 0.53376690E+00 0.53426715E+00 0.53476740E+00
+ 0.53526765E+00 0.53576790E+00 0.53626815E+00 0.53676840E+00 0.53726865E+00
+ 0.53776890E+00 0.53826915E+00 0.53876940E+00 0.53926965E+00 0.53976990E+00
+ 0.54027015E+00 0.54077040E+00 0.54127065E+00 0.54177090E+00 0.54227115E+00
+ 0.54277140E+00 0.54327165E+00 0.54377190E+00 0.54427215E+00 0.54477240E+00
+ 0.54527265E+00 0.54577290E+00 0.54627316E+00 0.54677341E+00 0.54727366E+00
+ 0.54777391E+00 0.54827416E+00 0.54877441E+00 0.54927466E+00 0.54977491E+00
+ 0.55027516E+00 0.55077541E+00 0.55127566E+00 0.55177591E+00 0.55227616E+00
+ 0.55277641E+00 0.55327666E+00 0.55377691E+00 0.55427716E+00 0.55477741E+00
+ 0.55527766E+00 0.55577791E+00 0.55627816E+00 0.55677841E+00 0.55727866E+00
+ 0.55777891E+00 0.55827916E+00 0.55877941E+00 0.55927966E+00 0.55977991E+00
+ 0.56028016E+00 0.56078041E+00 0.56128066E+00 0.56178091E+00 0.56228116E+00
+ 0.56278141E+00 0.56328166E+00 0.56378191E+00 0.56428216E+00 0.56478241E+00
+ 0.56528266E+00 0.56578291E+00 0.56628316E+00 0.56678341E+00 0.56728366E+00
+ 0.56778391E+00 0.56828416E+00 0.56878441E+00 0.56928466E+00 0.56978491E+00
+ 0.57028516E+00 0.57078541E+00 0.57128566E+00 0.57178591E+00 0.57228616E+00
+ 0.57278641E+00 0.57328666E+00 0.57378691E+00 0.57428716E+00 0.57478741E+00
+ 0.57528766E+00 0.57578791E+00 0.57628816E+00 0.57678841E+00 0.57728866E+00
+ 0.57778891E+00 0.57828916E+00 0.57878941E+00 0.57928966E+00 0.57978991E+00
+ 0.58029016E+00 0.58079041E+00 0.58129067E+00 0.58179092E+00 0.58229117E+00
+ 0.58279142E+00 0.58329167E+00 0.58379192E+00 0.58429217E+00 0.58479242E+00
+ 0.58529267E+00 0.58579292E+00 0.58629317E+00 0.58679342E+00 0.58729367E+00
+ 0.58779392E+00 0.58829417E+00 0.58879442E+00 0.58929467E+00 0.58979492E+00
+ 0.59029517E+00 0.59079542E+00 0.59129567E+00 0.59179592E+00 0.59229617E+00
+ 0.59279642E+00 0.59329667E+00 0.59379692E+00 0.59429717E+00 0.59479742E+00
+ 0.59529767E+00 0.59579792E+00 0.59629817E+00 0.59679842E+00 0.59729867E+00
+ 0.59779892E+00 0.59829917E+00 0.59879942E+00 0.59929967E+00 0.59979992E+00
+ 0.60030017E+00 0.60080042E+00 0.60130067E+00 0.60180092E+00 0.60230117E+00
+ 0.60280142E+00 0.60330167E+00 0.60380192E+00 0.60430217E+00 0.60480242E+00
+ 0.60530267E+00 0.60580292E+00 0.60630317E+00 0.60680342E+00 0.60730367E+00
+ 0.60780392E+00 0.60830417E+00 0.60880442E+00 0.60930467E+00 0.60980492E+00
+ 0.61030517E+00 0.61080542E+00 0.61130567E+00 0.61180592E+00 0.61230617E+00
+ 0.61280642E+00 0.61330667E+00 0.61380692E+00 0.61430717E+00 0.61480742E+00
+ 0.61530767E+00 0.61580792E+00 0.61630818E+00 0.61680843E+00 0.61730868E+00
+ 0.61780893E+00 0.61830918E+00 0.61880943E+00 0.61930968E+00 0.61980993E+00
+ 0.62031018E+00 0.62081043E+00 0.62131068E+00 0.62181093E+00 0.62231118E+00
+ 0.62281143E+00 0.62331168E+00 0.62381193E+00 0.62431218E+00 0.62481243E+00
+ 0.62531268E+00 0.62581293E+00 0.62631318E+00 0.62681343E+00 0.62731368E+00
+ 0.62781393E+00 0.62831418E+00 0.62881443E+00 0.62931468E+00 0.62981493E+00
+ 0.63031518E+00 0.63081543E+00 0.63131568E+00 0.63181593E+00 0.63231618E+00
+ 0.63281643E+00 0.63331668E+00 0.63381693E+00 0.63431718E+00 0.63481743E+00
+ 0.63531768E+00 0.63581793E+00 0.63631818E+00 0.63681843E+00 0.63731868E+00
+ 0.63781893E+00 0.63831918E+00 0.63881943E+00 0.63931968E+00 0.63981993E+00
+ 0.64032018E+00 0.64082043E+00 0.64132068E+00 0.64182093E+00 0.64232118E+00
+ 0.64282143E+00 0.64332168E+00 0.64382193E+00 0.64432218E+00 0.64482243E+00
+ 0.64532268E+00 0.64582293E+00 0.64632318E+00 0.64682343E+00 0.64732368E+00
+ 0.64782393E+00 0.64832418E+00 0.64882443E+00 0.64932469E+00 0.64982494E+00
+ 0.65032519E+00 0.65082544E+00 0.65132569E+00 0.65182594E+00 0.65232619E+00
+ 0.65282644E+00 0.65332669E+00 0.65382694E+00 0.65432719E+00 0.65482744E+00
+ 0.65532769E+00 0.65582794E+00 0.65632819E+00 0.65682844E+00 0.65732869E+00
+ 0.65782894E+00 0.65832919E+00 0.65882944E+00 0.65932969E+00 0.65982994E+00
+ 0.66033019E+00 0.66083044E+00 0.66133069E+00 0.66183094E+00 0.66233119E+00
+ 0.66283144E+00 0.66333169E+00 0.66383194E+00 0.66433219E+00 0.66483244E+00
+ 0.66533269E+00 0.66583294E+00 0.66633319E+00 0.66683344E+00 0.66733369E+00
+ 0.66783394E+00 0.66833419E+00 0.66883444E+00 0.66933469E+00 0.66983494E+00
+ 0.67033519E+00 0.67083544E+00 0.67133569E+00 0.67183594E+00 0.67233619E+00
+ 0.67283644E+00 0.67333669E+00 0.67383694E+00 0.67433719E+00 0.67483744E+00
+ 0.67533769E+00 0.67583794E+00 0.67633819E+00 0.67683844E+00 0.67733869E+00
+ 0.67783894E+00 0.67833919E+00 0.67883944E+00 0.67933969E+00 0.67983994E+00
+ 0.68034019E+00 0.68084045E+00 0.68134070E+00 0.68184095E+00 0.68234120E+00
+ 0.68284145E+00 0.68334170E+00 0.68384195E+00 0.68434220E+00 0.68484245E+00
+ 0.68534270E+00 0.68584295E+00 0.68634320E+00 0.68684345E+00 0.68734370E+00
+ 0.68784395E+00 0.68834420E+00 0.68884445E+00 0.68934470E+00 0.68984495E+00
+ 0.69034520E+00 0.69084545E+00 0.69134570E+00 0.69184595E+00 0.69234620E+00
+ 0.69284645E+00 0.69334670E+00 0.69384695E+00 0.69434720E+00 0.69484745E+00
+ 0.69534770E+00 0.69584795E+00 0.69634820E+00 0.69684845E+00 0.69734870E+00
+ 0.69784895E+00 0.69834920E+00 0.69884945E+00 0.69934970E+00 0.69984995E+00
+ 0.70035020E+00 0.70085045E+00 0.70135070E+00 0.70185095E+00 0.70235120E+00
+ 0.70285145E+00 0.70335170E+00 0.70385195E+00 0.70435220E+00 0.70485245E+00
+ 0.70535270E+00 0.70585295E+00 0.70635320E+00 0.70685345E+00 0.70735370E+00
+ 0.70785395E+00 0.70835420E+00 0.70885445E+00 0.70935470E+00 0.70985495E+00
+ 0.71035520E+00 0.71085545E+00 0.71135570E+00 0.71185595E+00 0.71235620E+00
+ 0.71285646E+00 0.71335671E+00 0.71385696E+00 0.71435721E+00 0.71485746E+00
+ 0.71535771E+00 0.71585796E+00 0.71635821E+00 0.71685846E+00 0.71735871E+00
+ 0.71785896E+00 0.71835921E+00 0.71885946E+00 0.71935971E+00 0.71985996E+00
+ 0.72036021E+00 0.72086046E+00 0.72136071E+00 0.72186096E+00 0.72236121E+00
+ 0.72286146E+00 0.72336171E+00 0.72386196E+00 0.72436221E+00 0.72486246E+00
+ 0.72536271E+00 0.72586296E+00 0.72636321E+00 0.72686346E+00 0.72736371E+00
+ 0.72786396E+00 0.72836421E+00 0.72886446E+00 0.72936471E+00 0.72986496E+00
+ 0.73036521E+00 0.73086546E+00 0.73136571E+00 0.73186596E+00 0.73236621E+00
+ 0.73286646E+00 0.73336671E+00 0.73386696E+00 0.73436721E+00 0.73486746E+00
+ 0.73536771E+00 0.73586796E+00 0.73636821E+00 0.73686846E+00 0.73736871E+00
+ 0.73786896E+00 0.73836921E+00 0.73886946E+00 0.73936971E+00 0.73986996E+00
+ 0.74037021E+00 0.74087046E+00 0.74137071E+00 0.74187096E+00 0.74237121E+00
+ 0.74287146E+00 0.74337171E+00 0.74387196E+00 0.74437221E+00 0.74487247E+00
+ 0.74537272E+00 0.74587297E+00 0.74637322E+00 0.74687347E+00 0.74737372E+00
+ 0.74787397E+00 0.74837422E+00 0.74887447E+00 0.74937472E+00 0.74987497E+00
+ 0.75037522E+00 0.75087547E+00 0.75137572E+00 0.75187597E+00 0.75237622E+00
+ 0.75287647E+00 0.75337672E+00 0.75387697E+00 0.75437722E+00 0.75487747E+00
+ 0.75537772E+00 0.75587797E+00 0.75637822E+00 0.75687847E+00 0.75737872E+00
+ 0.75787897E+00 0.75837922E+00 0.75887947E+00 0.75937972E+00 0.75987997E+00
+ 0.76038022E+00 0.76088047E+00 0.76138072E+00 0.76188097E+00 0.76238122E+00
+ 0.76288147E+00 0.76338172E+00 0.76388197E+00 0.76438222E+00 0.76488247E+00
+ 0.76538272E+00 0.76588297E+00 0.76638322E+00 0.76688347E+00 0.76738372E+00
+ 0.76788397E+00 0.76838422E+00 0.76888447E+00 0.76938472E+00 0.76988497E+00
+ 0.77038522E+00 0.77088547E+00 0.77138572E+00 0.77188597E+00 0.77238622E+00
+ 0.77288647E+00 0.77338672E+00 0.77388697E+00 0.77438722E+00 0.77488747E+00
+ 0.77538772E+00 0.77588797E+00 0.77638823E+00 0.77688848E+00 0.77738873E+00
+ 0.77788898E+00 0.77838923E+00 0.77888948E+00 0.77938973E+00 0.77988998E+00
+ 0.78039023E+00 0.78089048E+00 0.78139073E+00 0.78189098E+00 0.78239123E+00
+ 0.78289148E+00 0.78339173E+00 0.78389198E+00 0.78439223E+00 0.78489248E+00
+ 0.78539273E+00 0.78589298E+00 0.78639323E+00 0.78689348E+00 0.78739373E+00
+ 0.78789398E+00 0.78839423E+00 0.78889448E+00 0.78939473E+00 0.78989498E+00
+ 0.79039523E+00 0.79089548E+00 0.79139573E+00 0.79189598E+00 0.79239623E+00
+ 0.79289648E+00 0.79339673E+00 0.79389698E+00 0.79439723E+00 0.79489748E+00
+ 0.79539773E+00 0.79589798E+00 0.79639823E+00 0.79689848E+00 0.79739873E+00
+ 0.79789898E+00 0.79839923E+00 0.79889948E+00 0.79939973E+00 0.79989998E+00
+ 0.80040023E+00 0.80090048E+00 0.80140073E+00 0.80190098E+00 0.80240123E+00
+ 0.80290148E+00 0.80340173E+00 0.80390198E+00 0.80440223E+00 0.80490248E+00
+ 0.80540273E+00 0.80590298E+00 0.80640323E+00 0.80690348E+00 0.80740373E+00
+ 0.80790398E+00 0.80840424E+00 0.80890449E+00 0.80940474E+00 0.80990499E+00
+ 0.81040524E+00 0.81090549E+00 0.81140574E+00 0.81190599E+00 0.81240624E+00
+ 0.81290649E+00 0.81340674E+00 0.81390699E+00 0.81440724E+00 0.81490749E+00
+ 0.81540774E+00 0.81590799E+00 0.81640824E+00 0.81690849E+00 0.81740874E+00
+ 0.81790899E+00 0.81840924E+00 0.81890949E+00 0.81940974E+00 0.81990999E+00
+ 0.82041024E+00 0.82091049E+00 0.82141074E+00 0.82191099E+00 0.82241124E+00
+ 0.82291149E+00 0.82341174E+00 0.82391199E+00 0.82441224E+00 0.82491249E+00
+ 0.82541274E+00 0.82591299E+00 0.82641324E+00 0.82691349E+00 0.82741374E+00
+ 0.82791399E+00 0.82841424E+00 0.82891449E+00 0.82941474E+00 0.82991499E+00
+ 0.83041524E+00 0.83091549E+00 0.83141574E+00 0.83191599E+00 0.83241624E+00
+ 0.83291649E+00 0.83341674E+00 0.83391699E+00 0.83441724E+00 0.83491749E+00
+ 0.83541774E+00 0.83591799E+00 0.83641824E+00 0.83691849E+00 0.83741874E+00
+ 0.83791899E+00 0.83841924E+00 0.83891949E+00 0.83941974E+00 0.83991999E+00
+ 0.84042025E+00 0.84092050E+00 0.84142075E+00 0.84192100E+00 0.84242125E+00
+ 0.84292150E+00 0.84342175E+00 0.84392200E+00 0.84442225E+00 0.84492250E+00
+ 0.84542275E+00 0.84592300E+00 0.84642325E+00 0.84692350E+00 0.84742375E+00
+ 0.84792400E+00 0.84842425E+00 0.84892450E+00 0.84942475E+00 0.84992500E+00
+ 0.85042525E+00 0.85092550E+00 0.85142575E+00 0.85192600E+00 0.85242625E+00
+ 0.85292650E+00 0.85342675E+00 0.85392700E+00 0.85442725E+00 0.85492750E+00
+ 0.85542775E+00 0.85592800E+00 0.85642825E+00 0.85692850E+00 0.85742875E+00
+ 0.85792900E+00 0.85842925E+00 0.85892950E+00 0.85942975E+00 0.85993000E+00
+ 0.86043025E+00 0.86093050E+00 0.86143075E+00 0.86193100E+00 0.86243125E+00
+ 0.86293150E+00 0.86343175E+00 0.86393200E+00 0.86443225E+00 0.86493250E+00
+ 0.86543275E+00 0.86593300E+00 0.86643325E+00 0.86693350E+00 0.86743375E+00
+ 0.86793400E+00 0.86843425E+00 0.86893450E+00 0.86943475E+00 0.86993500E+00
+ 0.87043525E+00 0.87093550E+00 0.87143575E+00 0.87193600E+00 0.87243626E+00
+ 0.87293651E+00 0.87343676E+00 0.87393701E+00 0.87443726E+00 0.87493751E+00
+ 0.87543776E+00 0.87593801E+00 0.87643826E+00 0.87693851E+00 0.87743876E+00
+ 0.87793901E+00 0.87843926E+00 0.87893951E+00 0.87943976E+00 0.87994001E+00
+ 0.88044026E+00 0.88094051E+00 0.88144076E+00 0.88194101E+00 0.88244126E+00
+ 0.88294151E+00 0.88344176E+00 0.88394201E+00 0.88444226E+00 0.88494251E+00
+ 0.88544276E+00 0.88594301E+00 0.88644326E+00 0.88694351E+00 0.88744376E+00
+ 0.88794401E+00 0.88844426E+00 0.88894451E+00 0.88944476E+00 0.88994501E+00
+ 0.89044526E+00 0.89094551E+00 0.89144576E+00 0.89194601E+00 0.89244626E+00
+ 0.89294651E+00 0.89344676E+00 0.89394701E+00 0.89444726E+00 0.89494751E+00
+ 0.89544776E+00 0.89594801E+00 0.89644826E+00 0.89694851E+00 0.89744876E+00
+ 0.89794901E+00 0.89844926E+00 0.89894951E+00 0.89944976E+00 0.89995001E+00
+ 0.90045026E+00 0.90095051E+00 0.90145076E+00 0.90195101E+00 0.90245126E+00
+ 0.90295151E+00 0.90345176E+00 0.90395202E+00 0.90445227E+00 0.90495252E+00
+ 0.90545277E+00 0.90595302E+00 0.90645327E+00 0.90695352E+00 0.90745377E+00
+ 0.90795402E+00 0.90845427E+00 0.90895452E+00 0.90945477E+00 0.90995502E+00
+ 0.91045527E+00 0.91095552E+00 0.91145577E+00 0.91195602E+00 0.91245627E+00
+ 0.91295652E+00 0.91345677E+00 0.91395702E+00 0.91445727E+00 0.91495752E+00
+ 0.91545777E+00 0.91595802E+00 0.91645827E+00 0.91695852E+00 0.91745877E+00
+ 0.91795902E+00 0.91845927E+00 0.91895952E+00 0.91945977E+00 0.91996002E+00
+ 0.92046027E+00 0.92096052E+00 0.92146077E+00 0.92196102E+00 0.92246127E+00
+ 0.92296152E+00 0.92346177E+00 0.92396202E+00 0.92446227E+00 0.92496252E+00
+ 0.92546277E+00 0.92596302E+00 0.92646327E+00 0.92696352E+00 0.92746377E+00
+ 0.92796402E+00 0.92846427E+00 0.92896452E+00 0.92946477E+00 0.92996502E+00
+ 0.93046527E+00 0.93096552E+00 0.93146577E+00 0.93196602E+00 0.93246627E+00
+ 0.93296652E+00 0.93346677E+00 0.93396702E+00 0.93446727E+00 0.93496752E+00
+ 0.93546777E+00 0.93596803E+00 0.93646828E+00 0.93696853E+00 0.93746878E+00
+ 0.93796903E+00 0.93846928E+00 0.93896953E+00 0.93946978E+00 0.93997003E+00
+ 0.94047028E+00 0.94097053E+00 0.94147078E+00 0.94197103E+00 0.94247128E+00
+ 0.94297153E+00 0.94347178E+00 0.94397203E+00 0.94447228E+00 0.94497253E+00
+ 0.94547278E+00 0.94597303E+00 0.94647328E+00 0.94697353E+00 0.94747378E+00
+ 0.94797403E+00 0.94847428E+00 0.94897453E+00 0.94947478E+00 0.94997503E+00
+ 0.95047528E+00 0.95097553E+00 0.95147578E+00 0.95197603E+00 0.95247628E+00
+ 0.95297653E+00 0.95347678E+00 0.95397703E+00 0.95447728E+00 0.95497753E+00
+ 0.95547778E+00 0.95597803E+00 0.95647828E+00 0.95697853E+00 0.95747878E+00
+ 0.95797903E+00 0.95847928E+00 0.95897953E+00 0.95947978E+00 0.95998003E+00
+ 0.96048028E+00 0.96098053E+00 0.96148078E+00 0.96198103E+00 0.96248128E+00
+ 0.96298153E+00 0.96348178E+00 0.96398203E+00 0.96448228E+00 0.96498253E+00
+ 0.96548278E+00 0.96598303E+00 0.96648328E+00 0.96698353E+00 0.96748378E+00
+ 0.96798404E+00 0.96848429E+00 0.96898454E+00 0.96948479E+00 0.96998504E+00
+ 0.97048529E+00 0.97098554E+00 0.97148579E+00 0.97198604E+00 0.97248629E+00
+ 0.97298654E+00 0.97348679E+00 0.97398704E+00 0.97448729E+00 0.97498754E+00
+ 0.97548779E+00 0.97598804E+00 0.97648829E+00 0.97698854E+00 0.97748879E+00
+ 0.97798904E+00 0.97848929E+00 0.97898954E+00 0.97948979E+00 0.97999004E+00
+ 0.98049029E+00 0.98099054E+00 0.98149079E+00 0.98199104E+00 0.98249129E+00
+ 0.98299154E+00 0.98349179E+00 0.98399204E+00 0.98449229E+00 0.98499254E+00
+ 0.98549279E+00 0.98599304E+00 0.98649329E+00 0.98699354E+00 0.98749379E+00
+ 0.98799404E+00 0.98849429E+00 0.98899454E+00 0.98949479E+00 0.98999504E+00
+ 0.99049529E+00 0.99099554E+00 0.99149579E+00 0.99199604E+00 0.99249629E+00
+ 0.99299654E+00 0.99349679E+00 0.99399704E+00 0.99449729E+00 0.99499754E+00
+ 0.99549779E+00 0.99599804E+00 0.99649829E+00 0.99699854E+00 0.99749879E+00
+ 0.99799904E+00 0.99849929E+00 0.99899954E+00 0.99949980E+00 0.10000000E+01
+ 0.10000000E+01
+ 0.10000000E+01
+ 0.00000000E+00
+ 0.00000000E+00
+ 0.00000000E+00
diff --git a/potentials/README b/potentials/README
index 25c2335af..e2f19a1c2 100644
--- a/potentials/README
+++ b/potentials/README
@@ -1,27 +1,29 @@
This directory contains potential files for different elements and
alloys, as used by LAMMPS for various pair styles. See the
description of the "pair_style" and "pair_coeff" commands for details
of the file formats and the various styles in LAMMPS that read these
files.
The prefix of each file indicates the element(s) it is parameterized
for. An additional lower-case identification tag may be appended.
Si = Silicon
SiC = Silicon and Carbon
Au_u3 = Gold universal 3
For many of the files, comments in the header section give origin and
citation information.
The suffix of each file indicates the pair style it is used with:
-airebo AI-REBO (Brenner) potential
+airebo AI-REBO and REBO potentials
+bop BOP potential, analytic form
+bop.table BOP potential, tabulated form
eam embedded atom method (EAM) single element, DYNAMO funcfl format
eam.alloy EAM multi-element alloy, DYNAMO setfl format
eam.fs Finnis-Sinclair EAM format (single element or alloy)
meam modified EAM (MEAM) library and individual elements/alloys
meam.spline modified EAM (MEAM) spline potential
reax ReaxFF potential (see README.reax for more info)
sw Stillinger-Weber potential
tersoff Tersoff potential
diff --git a/potentials/library.meam b/potentials/library.meam
index 7dae0e829..273aab8d5 100644
--- a/potentials/library.meam
+++ b/potentials/library.meam
@@ -1,162 +1,177 @@
# meam data from vax files fcc,bcc,dia 11/4/92
# elt lat z ielement atwt
# alpha b0 b1 b2 b3 alat esub asub
# t0 t1 t2 t3 rozero ibar
+'AlS' 'fcc' 12. 13 26.9815
+4.64 2.04 3.00 6.0 1.50 4.05 3.353 1.07
+1.0 +4.50 -2.30 8.01 1.0 -5
+'SiS' 'dia' 4. 14 28.086
+4.87 4.4 5.5 5.5 5.5 5.431 4.63 1.
+1.0 2.05 4.47 -1.80 2.2 -5
+'MgS' 'hcp' 12. 12 24.305
+5.52 4.0 3.0 0.2 1.2 3.194 1.51 0.80
+1.0 10.04 9.49 -4.3 0.63 -5
+'CuS' 'fcc' 12. 29 63.54
+5.11 3.634 2.20 6 2.20 3.62 3.54 1.07
+1.0 4.91 2.49 2.95 1.10 -5
+'FeS' 'bcc' 8 26 55.847
+5.0270 3.500 2 1.00 1 2.851 4.28 0.5550
+1 -1.6 12.5 -1.40 1.0 -5
'Sn5' 'dia' 4. 50 118.
5.09 5.00 16.0 04.0 5.0 6.483 3.14 1.00
1.0 2.00 5.756 -0.30 1. 0
'Sn' 'dia' 4. 50 118.
5.09 5.42 8.0 5.0 6.0 6.483 3.14 1.12
1.0 3.0 5.707 +0.30 1. 0
'Cu' 'fcc' 12. 29 63.54
5.10570729 3.634 2.20 6 2.20 3.62 3.54 1.07
1.0 3.13803254 2.49438711 2.95269237 1. 0
'Ag' 'fcc' 12. 47 107.870
5.89222008 4.456 2.20 6 2.20 4.08 2.85 1.06
1.0 5.54097609 2.45015783 1.28843988 1. 0
'Au' 'fcc' 12. 79 196.967
6.34090112 5.449 2.20 6 2.20 4.07 3.93 1.04
1.0 1.58956328 1.50776392 2.60609758 1. 0
'Ni1' 'fcc' 12. 28 58.71
4.99 2.45 2.20 6 2.20 3.52 4.45 1.10
1.0 3.57 1.60 3.70 1.0 0
'Ni2' 'fcc' 12. 28 58.71
4.99 2.45 2.20 6 2.20 3.52 4.45 1.10
1.0 3.57 1.60 3.70 1.0 3
'Ni3' 'fcc' 12. 28 58.71
4.99 2.45 1.50 6 1.50 3.52 4.45 1.10
1.0 3.57 1.60 3.70 1.0 3
'Ni4' 'fcc' 12. 28 58.71
4.99 2.45 1.50 6 1.50 3.52 4.45 1.10
1.0 3.57 1.60 3.70 1.0 0
'Ni' 'fcc' 12. 28 58.71
4.99 2.64 1.50 4.50 1.50 3.52 4.45 1.10
1.0 1.692 4.987 3.683 1.0 1
'Nix' 'fcc' 12. 28 58.71
4.99 2.64 1.50 4.50 1.50 3.52 4.45 1.10
1.0 0.00 0.000 3.683 1.0 1
'Ni' 'fcc' 12. 28 58.71
4.99 3.25 0.80 4 1.50 3.52 4.45 1.07
1.0 -4.052 13.14 3.786 1.0 1
'Pd' 'fcc' 12. 46 106.4
6.43230473 4.975 2.20 6 2.20 3.89 3.91 1.01
1.0 2.33573516 1.38343023 4.47989049 1. 0
'Pt' 'fcc' 12. 78 195.09
6.44221724 4.673 2.20 6 2.20 3.92 5.77 1.04
1.0 2.73335406 -1.3759593 3.29322278 1. 0
'Al' 'fcc' 12. 13 26.9815
4.61 2.21 2.20 6.0 2.20 4.05 3.58 1.07
1.0 -1.78 -2.21 8.01 0.6 0
'Al' 'fcc' 12. 13 26.9815
4.69 1.56 4.00 5.5 0.60 4.05 3.36 1.09
1.0 -0.251 -3.450 8.298 0.6 1
'Al' 'fcc' 12. 13 26.9815
4.69 1.58 1.00 6.0 0.60 4.05 3.36 1.09
1.0 -0.808 -2.614 8.298 0.6 1
'Pb' 'fcc' 12. 82 207.19
6.0564428 5.306 2.20 6 2.20 4.95 2.04 1.01
1.0 2.74022352 3.06323991 1.2 1. 0
'Rh' 'fcc' 12. 45 102.905
6.0045385 1.131 1.00 2 1.00 3.8 5.75 1.05
1.0 2.9900 4.60231784 4.8 1. 0
'Ir' 'fcc' 12. 77 192.2
6.52315787 1.13 1.00 2 1.00 3.84 6.93 1.05
1.0 1.50000 8.09942666 4.8 1. 0
'Li' 'bcc' 8. 3 6.939
2.97244804 1.425 1.00 1.00169907 1.00 3.509 1.65 0.87
1.0 0.26395017 0.44431129 -0.2 1. 0
'Na' 'bcc' 8. 11 22.9898
3.64280541 2.313 1.00 1.00173951 1.00 4.291 1.13 0.9
1.0 3.55398839 0.68807569 -0.2 1. 0
'K' 'bcc' 8. 19 39.102
3.90128376 2.687 1.00 1.00186667 1.00 5.344 0.94 0.92
1.0 5.09756981 0.69413264 -0.2 1. 0
'V' 'bcc' 8. 23 50.942
4.83265262 4.113 1.00 1.00095022 1.00 3.04 5.3 1
1.0 4.20161301 4.09946561 -1 1. 0
'Nb' 'bcc' 8. 41 92.906
4.79306197 4.374 1.00 1.00101441 1.00 3.301 7.47 1
1.0 3.75762849 3.82514598 -1 1. 0
'Ta' 'bcc' 8. 73 180.948
4.89528669 3.709 1.00 1.00099783 1.00 3.303 8.09 0.99
1.0 6.08617812 3.35255804 -2.9 1. 0
'Cr' 'bcc' 8. 24 51.996
5.12169218 3.224 1.00 1.00048646 1.00 2.885 4.1 0.94
1.0 -0.207535 12.2600006 -1.9 1. 0
'Mo' 'bcc' 8. 42 95.94
5.84872871 4.481 1.00 1.00065204 1.00 3.15 6.81 0.99
1.0 3.47727181 9.48582009 -2.9 1. 0
'W' 'bcc' 8. 74 183.85
5.62777409 3.978 1.00 1.00065894 1.00 3.165 8.66 0.98
1.0 3.16353338 8.24586928 -2.7 1. 0
'WL' 'bcc' 8 74 183.85
5.6831 6.54 1 1 1 3.1639 8.66 0.4
1 -0.6 0.3 -8.7 1 3
'Fe' 'bcc' 8. 26 55.847
5.07292627 2.935 1.00 1.00080073 1.00 2.866 4.29 0.89
1.0 5.13579244 4.12042448 -2.7 1. 0
'Si' 'dia' 4. 14 28.086
4.87 4.8 4.8 4.8 4.8 5.431 4.63 1.
1.0 3.30 5.105 -0.80 1. 1
'Si97' 'dia' 4. 14 28.086
4.87 4.4 5.5 5.5 5.5 5.431 4.63 1.
1.0 3.13 4.47 -1.80 2.05 0
'Si92' 'dia' 4. 14 28.086
4.87 4.4 5.5 5.5 5.5 5.431 4.63 1.
1.0 3.13 4.47 -1.80 2.35 0
'Six' 'dia' 4 14 28.086
4.87 4.4 5.5 5.5 5.5 5.431 4.63 1.0
1.0 2.05 4.47 -1.8 2.05 0
'Sixb' 'dia' 4 14 28.086
4.87 4.4 5.5 5.5 5.5 5.431 4.63 1.0
1.0 2.05 4.47 -1.8 2.5 0
'Mg' 'hcp' 12. 12 24.305
5.45 2.70 0.0 0.35 3.0 3.20 1.55 1.11
1.0 8.00 04.1 -02.0 1.0 0
'C' 'dia' 4. 6 12.0111
4.38 4.10 4.200 5.00 3.00 3.567 7.37 1.000
1.0 5.0 9.34 -1.00 2.25 1
'C' 'dia' 4. 6 12.0111
4.38 5.20 3.87 4.00 4.50 3.567 7.37 1.278
1.0 15. 2.09 -6.00 2.5 1
'C' 'dia' 4. 6 12.0111
4.38 4.50 4.00 3.50 4.80 3.567 7.37 1.00
1.0 10.5 1.54 -8.75 3.2 1
'C' 'dia' 4. 6 12.0111
4.38 3.30 2.80 1.50 3.20 3.567 7.37 1.00
1.0 10.3 1.54 -8.80 2.5 1
'C' 'dia' 4. 6 12.0111
4.38 4.60 3.45 4.00 4.20 3.567 7.37 1.061
1.0 15.0 1.74 -8.00 2.5 1
'C' 'dia' 4. 6 12.0111
4.38 4.50 4.00 3.50 4.80 3.567 7.37 1.00
1.0 10.5 1.54 -8.75 3.2 1
'h' 'dim' 1. 1 1.0079
2.96 2.70 3.5 3.4 3.4 0.74 2.235 2.27
1.0 0.19 0.00 0.00 20.00 0
'h' 'dim' 1. 1 1.0079
2.96 2.00 4.0 4.0 0.0 0.74 2.235 1.00
1.0 -0.60 -0.80 -0.0 01.0 1
'H' 'dim' 1. 1 1.0079
2.96 2.96 3.0 3.0 3.0 0.74 2.235 2.50
1.0 0.20 -0.10 0.0 0.5 0
'H' 'dim' 1. 1 1.0079
2.96 2.0 3.0 4.0 0.0 0.74 2.225 1.00
1.0 -0.5 -1.00 0.0 0.15 1
'H' 'dim' 1. 1 1.0079
2.96 2.00 2.0 2.0 2.0 0.74 2.235 1.00
1.0 -0.60 -0.80 -0.0 01.0 2
'Hni' 'dim' 1. 1 1.0079
2.96 2.96 3.0 3.0 3.0 0.74 2.235 2.50
1.0 0.2 -0.1 0.0 0.5 0
'Hni' 'dim' 1. 1 1.0079
2.96 2.96 3.0 2.0 3.0 0.74 2.235 36.4
1.0 0.2 6.0 0.0 22.8 0
'Vac' 'fcc' 12. 1 1.
0 0 0.0 0 0.0 1E+08 0 1
0 0 0 0 1. 0
'zz' 'zzz' 99. 1 1.
0 0 0.0 0 0.0 0. 0. 0.
0 0 0 0 1. 0
diff --git a/src/CLASS2/angle_class2.cpp b/src/CLASS2/angle_class2.cpp
index 4129216ed..8b0ba3c23 100644
--- a/src/CLASS2/angle_class2.cpp
+++ b/src/CLASS2/angle_class2.cpp
@@ -1,448 +1,446 @@
/* ----------------------------------------------------------------------
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 "angle_class2.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleClass2::AngleClass2(LAMMPS *lmp) : Angle(lmp) {}
/* ---------------------------------------------------------------------- */
AngleClass2::~AngleClass2()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(setflag_a);
memory->destroy(setflag_bb);
memory->destroy(setflag_ba);
memory->destroy(theta0);
memory->destroy(k2);
memory->destroy(k3);
memory->destroy(k4);
memory->destroy(bb_k);
memory->destroy(bb_r1);
memory->destroy(bb_r2);
memory->destroy(ba_k1);
memory->destroy(ba_k2);
memory->destroy(ba_r1);
memory->destroy(ba_r2);
}
}
/* ---------------------------------------------------------------------- */
void AngleClass2::compute(int eflag, int vflag)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double dtheta,dtheta2,dtheta3,dtheta4,de_angle;
double dr1,dr2,tk1,tk2,aa1,aa2,aa11,aa12,aa21,aa22;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22,b1,b2;
double vx11,vx12,vy11,vy12,vz11,vz12,vx21,vx22,vy21,vy22,vz21,vz22;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
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;
s = 1.0/s;
// force & energy for angle term
dtheta = acos(c) - theta0[type];
dtheta2 = dtheta*dtheta;
dtheta3 = dtheta2*dtheta;
dtheta4 = dtheta3*dtheta;
de_angle = 2.0*k2[type]*dtheta + 3.0*k3[type]*dtheta2 +
4.0*k4[type]*dtheta3;
a = -de_angle*s;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
if (eflag) eangle = k2[type]*dtheta2 + k3[type]*dtheta3 + k4[type]*dtheta4;
// force & energy for bond-bond term
dr1 = r1 - bb_r1[type];
dr2 = r2 - bb_r2[type];
tk1 = bb_k[type] * dr1;
tk2 = bb_k[type] * dr2;
f1[0] -= delx1*tk2/r1;
f1[1] -= dely1*tk2/r1;
f1[2] -= delz1*tk2/r1;
f3[0] -= delx2*tk1/r2;
f3[1] -= dely2*tk1/r2;
f3[2] -= delz2*tk1/r2;
if (eflag) eangle += bb_k[type]*dr1*dr2;
// force & energy for bond-angle term
aa1 = s * dr1 * ba_k1[type];
aa2 = s * dr2 * ba_k2[type];
aa11 = aa1 * c / rsq1;
aa12 = -aa1 / (r1 * r2);
aa21 = aa2 * c / rsq1;
aa22 = -aa2 / (r1 * r2);
vx11 = (aa11 * delx1) + (aa12 * delx2);
vx12 = (aa21 * delx1) + (aa22 * delx2);
vy11 = (aa11 * dely1) + (aa12 * dely2);
vy12 = (aa21 * dely1) + (aa22 * dely2);
vz11 = (aa11 * delz1) + (aa12 * delz2);
vz12 = (aa21 * delz1) + (aa22 * delz2);
aa11 = aa1 * c / rsq2;
aa21 = aa2 * c / rsq2;
vx21 = (aa11 * delx2) + (aa12 * delx1);
vx22 = (aa21 * delx2) + (aa22 * delx1);
vy21 = (aa11 * dely2) + (aa12 * dely1);
vy22 = (aa21 * dely2) + (aa22 * dely1);
vz21 = (aa11 * delz2) + (aa12 * delz1);
vz22 = (aa21 * delz2) + (aa22 * delz1);
b1 = ba_k1[type] * dtheta / r1;
b2 = ba_k2[type] * dtheta / r2;
f1[0] -= vx11 + b1*delx1 + vx12;
f1[1] -= vy11 + b1*dely1 + vy12;
f1[2] -= vz11 + b1*delz1 + vz12;
f3[0] -= vx21 + b2*delx2 + vx22;
f3[1] -= vy21 + b2*dely2 + vy22;
f3[2] -= vz21 + b2*delz2 + vz22;
if (eflag) eangle += ba_k1[type]*dr1*dtheta + ba_k2[type]*dr2*dtheta;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
}
}
/* ---------------------------------------------------------------------- */
void AngleClass2::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(theta0,n+1,"angle:theta0");
memory->create(k2,n+1,"angle:k2");
memory->create(k3,n+1,"angle:k3");
memory->create(k4,n+1,"angle:k4");
memory->create(bb_k,n+1,"angle:bb_k");
memory->create(bb_r1,n+1,"angle:bb_r1");
memory->create(bb_r2,n+1,"angle:bb_r2");
memory->create(ba_k1,n+1,"angle:ba_k1");
memory->create(ba_k2,n+1,"angle:ba_k2");
memory->create(ba_r1,n+1,"angle:ba_r1");
memory->create(ba_r2,n+1,"angle:ba_r2");
memory->create(setflag,n+1,"angle:setflag");
memory->create(setflag_a,n+1,"angle:setflag_a");
memory->create(setflag_bb,n+1,"angle:setflag_bb");
memory->create(setflag_ba,n+1,"angle:setflag_ba");
for (int i = 1; i <= n; i++)
setflag[i] = setflag_a[i] = setflag_bb[i] = setflag_ba[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
arg1 = "bb" -> BondBond coeffs
arg1 = "ba" -> BondAngle coeffs
else -> Angle coeffs
------------------------------------------------------------------------- */
void AngleClass2::coeff(int narg, char **arg)
{
if (narg < 2) error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
int count = 0;
if (strcmp(arg[1],"bb") == 0) {
if (narg != 5) error->all(FLERR,"Incorrect args for angle coefficients");
double bb_k_one = force->numeric(arg[2]);
double bb_r1_one = force->numeric(arg[3]);
double bb_r2_one = force->numeric(arg[4]);
for (int i = ilo; i <= ihi; i++) {
bb_k[i] = bb_k_one;
bb_r1[i] = bb_r1_one;
bb_r2[i] = bb_r2_one;
setflag_bb[i] = 1;
count++;
}
} else if (strcmp(arg[1],"ba") == 0) {
if (narg != 6) error->all(FLERR,"Incorrect args for angle coefficients");
double ba_k1_one = force->numeric(arg[2]);
double ba_k2_one = force->numeric(arg[3]);
double ba_r1_one = force->numeric(arg[4]);
double ba_r2_one = force->numeric(arg[5]);
for (int i = ilo; i <= ihi; i++) {
ba_k1[i] = ba_k1_one;
ba_k2[i] = ba_k2_one;
ba_r1[i] = ba_r1_one;
ba_r2[i] = ba_r2_one;
setflag_ba[i] = 1;
count++;
}
} else {
if (narg != 5) error->all(FLERR,"Incorrect args for angle coefficients");
double theta0_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]);
// convert theta0 from degrees to radians
for (int i = ilo; i <= ihi; i++) {
theta0[i] = theta0_one/180.0 * MY_PI;
k2[i] = k2_one;
k3[i] = k3_one;
k4[i] = k4_one;
setflag_a[i] = 1;
count++;
}
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
for (int i = ilo; i <= ihi; i++)
if (setflag_a[i] == 1 && setflag_bb[i] == 1 && setflag_ba[i] == 1)
setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double AngleClass2::equilibrium_angle(int i)
{
return theta0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleClass2::write_restart(FILE *fp)
{
fwrite(&theta0[1],sizeof(double),atom->nangletypes,fp);
fwrite(&k2[1],sizeof(double),atom->nangletypes,fp);
fwrite(&k3[1],sizeof(double),atom->nangletypes,fp);
fwrite(&k4[1],sizeof(double),atom->nangletypes,fp);
fwrite(&bb_k[1],sizeof(double),atom->nangletypes,fp);
fwrite(&bb_r1[1],sizeof(double),atom->nangletypes,fp);
fwrite(&bb_r2[1],sizeof(double),atom->nangletypes,fp);
fwrite(&ba_k1[1],sizeof(double),atom->nangletypes,fp);
fwrite(&ba_k2[1],sizeof(double),atom->nangletypes,fp);
fwrite(&ba_r1[1],sizeof(double),atom->nangletypes,fp);
fwrite(&ba_r2[1],sizeof(double),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleClass2::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&theta0[1],sizeof(double),atom->nangletypes,fp);
fread(&k2[1],sizeof(double),atom->nangletypes,fp);
fread(&k3[1],sizeof(double),atom->nangletypes,fp);
fread(&k4[1],sizeof(double),atom->nangletypes,fp);
fread(&bb_k[1],sizeof(double),atom->nangletypes,fp);
fread(&bb_r1[1],sizeof(double),atom->nangletypes,fp);
fread(&bb_r2[1],sizeof(double),atom->nangletypes,fp);
fread(&ba_k1[1],sizeof(double),atom->nangletypes,fp);
fread(&ba_k2[1],sizeof(double),atom->nangletypes,fp);
fread(&ba_r1[1],sizeof(double),atom->nangletypes,fp);
fread(&ba_r2[1],sizeof(double),atom->nangletypes,fp);
}
MPI_Bcast(&theta0[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&k2[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&k3[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&k4[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&bb_k[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&bb_r1[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&bb_r2[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&ba_k1[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&ba_k2[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&ba_r1[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&ba_r2[1],atom->nangletypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double AngleClass2::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
s = 1.0/s;
double dtheta = acos(c) - theta0[type];
double dtheta2 = dtheta*dtheta;
double dtheta3 = dtheta2*dtheta;
double dtheta4 = dtheta3*dtheta;
double energy = k2[type]*dtheta2 + k3[type]*dtheta3 + k4[type]*dtheta4;
double dr1 = r1 - bb_r1[type];
double dr2 = r2 - bb_r2[type];
energy += bb_k[type]*dr1*dr2;
energy += ba_k1[type]*dr1*dtheta + ba_k2[type]*dr2*dtheta;
return energy;
}
diff --git a/src/CLASS2/bond_class2.cpp b/src/CLASS2/bond_class2.cpp
index 2234227ab..08c9ee3e9 100644
--- a/src/CLASS2/bond_class2.cpp
+++ b/src/CLASS2/bond_class2.cpp
@@ -1,209 +1,208 @@
/* ----------------------------------------------------------------------
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 "stdlib.h"
#include "bond_class2.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondClass2::BondClass2(LAMMPS *lmp) : Bond(lmp) {}
/* ---------------------------------------------------------------------- */
BondClass2::~BondClass2()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(r0);
memory->destroy(k2);
memory->destroy(k3);
memory->destroy(k4);
}
}
/* ---------------------------------------------------------------------- */
void BondClass2::compute(int eflag, int vflag)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,dr2,dr3,dr4,de_bond;
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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
dr = r - r0[type];
dr2 = dr*dr;
dr3 = dr2*dr;
dr4 = dr3*dr;
// force & energy
de_bond = 2.0*k2[type]*dr + 3.0*k3[type]*dr2 + 4.0*k4[type]*dr3;
if (r > 0.0) fbond = -de_bond/r;
else fbond = 0.0;
if (eflag) ebond = k2[type]*dr2 + k3[type]*dr3 + k4[type]*dr4;
// 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 BondClass2::allocate()
{
allocated = 1;
int n = atom->nbondtypes;
memory->create(r0,n+1,"bond:r0");
memory->create(k2,n+1,"bond:k2");
memory->create(k3,n+1,"bond:k3");
memory->create(k4,n+1,"bond:k4");
memory->create(setflag,n+1,"bond:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs from one line in input script or data file
------------------------------------------------------------------------- */
void BondClass2::coeff(int narg, char **arg)
{
if (narg != 5) error->all(FLERR,"Incorrect args for bond coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nbondtypes,ilo,ihi);
double r0_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]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
r0[i] = r0_one;
k2[i] = k2_one;
k3[i] = k3_one;
k4[i] = k4_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients");
}
/* ----------------------------------------------------------------------
return an equilbrium bond length
------------------------------------------------------------------------- */
double BondClass2::equilibrium_distance(int i)
{
return r0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void BondClass2::write_restart(FILE *fp)
{
fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&k2[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&k3[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&k4[1],sizeof(double),atom->nbondtypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void BondClass2::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&r0[1],sizeof(double),atom->nbondtypes,fp);
fread(&k2[1],sizeof(double),atom->nbondtypes,fp);
fread(&k3[1],sizeof(double),atom->nbondtypes,fp);
fread(&k4[1],sizeof(double),atom->nbondtypes,fp);
}
MPI_Bcast(&r0[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&k2[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&k3[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&k4[1],atom->nbondtypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double BondClass2::single(int type, double rsq, int i, int j)
{
double r = sqrt(rsq);
double dr = r - r0[type];
double dr2 = dr*dr;
double dr3 = dr2*dr;
double dr4 = dr3*dr;
return (k2[type]*dr2 + k3[type]*dr3 + k4[type]*dr4);
}
diff --git a/src/CLASS2/dihedral_class2.cpp b/src/CLASS2/dihedral_class2.cpp
index dcf204a37..ea13d09bc 100644
--- a/src/CLASS2/dihedral_class2.cpp
+++ b/src/CLASS2/dihedral_class2.cpp
@@ -1,906 +1,902 @@
/* ----------------------------------------------------------------------
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 "atom.h"
#include "neighbor.h"
#include "update.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.0000001
/* ---------------------------------------------------------------------- */
DihedralClass2::DihedralClass2(LAMMPS *lmp) : Dihedral(lmp) {}
/* ---------------------------------------------------------------------- */
DihedralClass2::~DihedralClass2()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(setflag_d);
memory->destroy(setflag_mbt);
memory->destroy(setflag_ebt);
memory->destroy(setflag_at);
memory->destroy(setflag_aat);
memory->destroy(setflag_bb13t);
memory->destroy(k1);
memory->destroy(k2);
memory->destroy(k3);
memory->destroy(phi1);
memory->destroy(phi2);
memory->destroy(phi3);
memory->destroy(mbt_f1);
memory->destroy(mbt_f2);
memory->destroy(mbt_f3);
memory->destroy(mbt_r0);
memory->destroy(ebt_f1_1);
memory->destroy(ebt_f2_1);
memory->destroy(ebt_f3_1);
memory->destroy(ebt_r0_1);
memory->destroy(ebt_f1_2);
memory->destroy(ebt_f2_2);
memory->destroy(ebt_f3_2);
memory->destroy(ebt_r0_2);
memory->destroy(at_f1_1);
memory->destroy(at_f2_1);
memory->destroy(at_f3_1);
memory->destroy(at_theta0_1);
memory->destroy(at_f1_2);
memory->destroy(at_f2_2);
memory->destroy(at_f3_2);
memory->destroy(at_theta0_2);
memory->destroy(aat_k);
memory->destroy(aat_theta0_1);
memory->destroy(aat_theta0_2);
memory->destroy(bb13t_k);
memory->destroy(bb13t_r10);
memory->destroy(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 " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
memory->create(k1,n+1,"dihedral:k1");
memory->create(k2,n+1,"dihedral:k2");
memory->create(k3,n+1,"dihedral:k3");
memory->create(phi1,n+1,"dihedral:phi1");
memory->create(phi2,n+1,"dihedral:phi2");
memory->create(phi3,n+1,"dihedral:phi3");
memory->create(mbt_f1,n+1,"dihedral:mbt_f1");
memory->create(mbt_f2,n+1,"dihedral:mbt_f2");
memory->create(mbt_f3,n+1,"dihedral:mbt_f3");
memory->create(mbt_r0,n+1,"dihedral:mbt_r0");
memory->create(ebt_f1_1,n+1,"dihedral:ebt_f1_1");
memory->create(ebt_f2_1,n+1,"dihedral:ebt_f2_1");
memory->create(ebt_f3_1,n+1,"dihedral:ebt_f3_1");
memory->create(ebt_r0_1,n+1,"dihedral:ebt_r0_1");
memory->create(ebt_f1_2,n+1,"dihedral:ebt_f1_2");
memory->create(ebt_f2_2,n+1,"dihedral:ebt_f2_2");
memory->create(ebt_f3_2,n+1,"dihedral:ebt_f3_2");
memory->create(ebt_r0_2,n+1,"dihedral:ebt_r0_2");
memory->create(at_f1_1,n+1,"dihedral:at_f1_1");
memory->create(at_f2_1,n+1,"dihedral:at_f2_1");
memory->create(at_f3_1,n+1,"dihedral:at_f3_1");
memory->create(at_theta0_1,n+1,"dihedral:at_theta0_1");
memory->create(at_f1_2,n+1,"dihedral:at_f1_2");
memory->create(at_f2_2,n+1,"dihedral:at_f2_2");
memory->create(at_f3_2,n+1,"dihedral:at_f3_2");
memory->create(at_theta0_2,n+1,"dihedral:at_theta0_2");
memory->create(aat_k,n+1,"dihedral:aat_k");
memory->create(aat_theta0_1,n+1,"dihedral:aat_theta0_1");
memory->create(aat_theta0_2,n+1,"dihedral:aat_theta0_2");
memory->create(bb13t_k,n+1,"dihedral:bb13t_k");
memory->create(bb13t_r10,n+1,"dihedral:bb13t_r10");
memory->create(bb13t_r30,n+1,"dihedral:bb13t_r30");
memory->create(setflag,n+1,"dihedral:setflag");
memory->create(setflag_d,n+1,"dihedral:setflag_d");
memory->create(setflag_mbt,n+1,"dihedral:setflag_mbt");
memory->create(setflag_ebt,n+1,"dihedral:setflag_ebt");
memory->create(setflag_at,n+1,"dihedral:setflag_at");
memory->create(setflag_aat,n+1,"dihedral:setflag_aat");
memory->create(setflag_bb13t,n+1,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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 * MY_PI;
at_theta0_2[i] = theta0_2_one/180.0 * MY_PI;
setflag_at[i] = 1;
count++;
}
} else if (strcmp(arg[1],"aat") == 0) {
if (narg != 5) error->all(FLERR,"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 * MY_PI;
aat_theta0_2[i] = theta0_2_one/180.0 * MY_PI;
setflag_aat[i] = 1;
count++;
}
} else if (strcmp(arg[1],"bb13") == 0) {
if (narg != 5) error->all(FLERR,"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(FLERR,"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 * MY_PI;
k2[i] = k2_one;
phi2[i] = phi2_one/180.0 * MY_PI;
k3[i] = k3_one;
phi3[i] = phi3_one/180.0 * MY_PI;
setflag_d[i] = 1;
count++;
}
}
if (count == 0) error->all(FLERR,"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 5c0549384..4d06ba933 100644
--- a/src/CLASS2/improper_class2.cpp
+++ b/src/CLASS2/improper_class2.cpp
@@ -1,843 +1,837 @@
/* ----------------------------------------------------------------------
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 "atom.h"
#include "neighbor.h"
#include "update.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
ImproperClass2::ImproperClass2(LAMMPS *lmp) : Improper(lmp) {}
/* ---------------------------------------------------------------------- */
ImproperClass2::~ImproperClass2()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(setflag_i);
memory->destroy(setflag_aa);
memory->destroy(k0);
memory->destroy(chi0);
memory->destroy(aa_k1);
memory->destroy(aa_k2);
memory->destroy(aa_k3);
memory->destroy(aa_theta0_1);
memory->destroy(aa_theta0_2);
memory->destroy(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 " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
memory->create(k0,n+1,"improper:k0");
memory->create(chi0,n+1,"improper:chi0");
memory->create(aa_k1,n+1,"improper:aa_k1");
memory->create(aa_k2,n+1,"improper:aa_k2");
memory->create(aa_k3,n+1,"improper:aa_k3");
memory->create(aa_theta0_1,n+1,"improper:aa_theta0_1");
memory->create(aa_theta0_2,n+1,"improper:aa_theta0_2");
memory->create(aa_theta0_3,n+1,"improper:aa_theta0_3");
memory->create(setflag,n+1,"improper:setflag");
memory->create(setflag_i,n+1,"improper:setflag_i");
memory->create(setflag_aa,n+1,"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(FLERR,"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(FLERR,"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 * MY_PI;
aa_theta0_2[i] = theta0_2_one/180.0 * MY_PI;
aa_theta0_3[i] = theta0_3_one/180.0 * MY_PI;
setflag_aa[i] = 1;
count++;
}
} else {
if (narg != 3) error->all(FLERR,"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 * MY_PI;
setflag_i[i] = 1;
count++;
}
}
if (count == 0) error->all(FLERR,"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];
dthABD = thetaABD - aa_theta0_2[type];
dthCBD = thetaCBD - 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/DIPOLE/atom_vec_dipole.cpp b/src/DIPOLE/atom_vec_dipole.cpp
index 02f048e3d..2b94516b7 100644
--- a/src/DIPOLE/atom_vec_dipole.cpp
+++ b/src/DIPOLE/atom_vec_dipole.cpp
@@ -1,832 +1,833 @@
/* ----------------------------------------------------------------------
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 "atom_vec_dipole.h"
#include "atom.h"
#include "comm.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;
comm_x_only = 0;
comm_f_only = 1;
size_forward = 6;
size_reverse = 3;
size_border = 11;
size_velocity = 3;
size_data_atom = 9;
size_data_vel = 7;
xcol_data = 4;
atom->q_flag = atom->mu_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(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
q = memory->grow(atom->q,nmax,"atom:q");
mu = memory->grow(atom->mu,nmax,4,"atom:mu");
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;
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecDipole::copy(int i, int j, int delflag)
{
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];
mu[j][3] = mu[i][3];
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,dvx,dvy,dvz;
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];
}
} 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;
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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++] = mu[j][0];
buf[m++] = mu[j][1];
buf[m++] = mu[j][2];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::pack_comm_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = mu[j][0];
buf[m++] = mu[j][1];
buf[m++] = mu[j][2];
}
return m;
}
/* ---------------------------------------------------------------------- */
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++];
}
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::unpack_comm_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
mu[i][0] = buf[m++];
mu[i][1] = buf[m++];
mu[i][2] = buf[m++];
}
return m;
}
/* ---------------------------------------------------------------------- */
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];
}
return m;
}
/* ---------------------------------------------------------------------- */
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++];
}
}
/* ---------------------------------------------------------------------- */
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];
buf[m++] = mu[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++] = q[j];
buf[m++] = mu[j][0];
buf[m++] = mu[j][1];
buf[m++] = mu[j][2];
buf[m++] = mu[j][3];
}
}
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,dvx,dvy,dvz;
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++] = mu[j][3];
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];
}
if (!deform_vremap) {
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++] = mu[j][3];
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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++] = mu[j][3];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = q[j];
buf[m++] = mu[j][0];
buf[m++] = mu[j][1];
buf[m++] = mu[j][2];
buf[m++] = mu[j][3];
}
return m;
}
/* ---------------------------------------------------------------------- */
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++];
mu[i][3] = 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++];
mu[i][3] = buf[m++];
v[i][0] = buf[m++];
v[i][1] = buf[m++];
v[i][2] = buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int AtomVecDipole::unpack_border_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
q[i] = buf[m++];
mu[i][0] = buf[m++];
mu[i][1] = buf[m++];
mu[i][2] = buf[m++];
mu[i][3] = buf[m++];
}
return m;
}
/* ----------------------------------------------------------------------
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];
+ *((tagint *) &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++] = mu[i][3];
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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
q[nlocal] = buf[m++];
mu[nlocal][0] = buf[m++];
mu[nlocal][1] = buf[m++];
mu[nlocal][2] = buf[m++];
mu[nlocal][3] = 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 = 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 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];
+ *((tagint *) &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++] = mu[i][3];
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)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &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++];
mu[nlocal][3] = 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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
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;
mu[nlocal][3] = 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)
+void AtomVecDipole::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
type[nlocal] = atoi(values[1]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
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]);
mu[nlocal][3] = sqrt(mu[nlocal][0]*mu[nlocal][0] +
mu[nlocal][1]*mu[nlocal][1] +
mu[nlocal][2]*mu[nlocal][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 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]);
mu[nlocal][3] = sqrt(mu[nlocal][0]*mu[nlocal][0] +
mu[nlocal][1]*mu[nlocal][1] +
mu[nlocal][2]*mu[nlocal][2]);
return 4;
}
/* ----------------------------------------------------------------------
return # of bytes of allocated memory
------------------------------------------------------------------------- */
bigint AtomVecDipole::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("q")) bytes += memory->usage(q,nmax);
if (atom->memcheck("mu")) bytes += memory->usage(mu,nmax,4);
return bytes;
}
diff --git a/src/DIPOLE/atom_vec_dipole.h b/src/DIPOLE/atom_vec_dipole.h
index 949ac04ee..fcbca38f2 100644
--- a/src/DIPOLE/atom_vec_dipole.h
+++ b/src/DIPOLE/atom_vec_dipole.h
@@ -1,83 +1,84 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(dipole,AtomVecDipole)
#else
#ifndef LMP_ATOM_VEC_DIPOLE_H
#define LMP_ATOM_VEC_DIPOLE_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecDipole : public AtomVec {
public:
AtomVecDipole(class LAMMPS *, int, char **);
void grow(int);
void grow_reset();
void copy(int, int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
int pack_comm_hybrid(int, int *, double *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int unpack_comm_hybrid(int, int, double *);
int pack_reverse(int, int, double *);
void unpack_reverse(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
bigint memory_usage();
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
double *q,**mu,**omega,**torque;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
*/
diff --git a/src/Depend.sh b/src/Depend.sh
index 84d642cb3..feb92c3e2 100644
--- a/src/Depend.sh
+++ b/src/Depend.sh
@@ -1,38 +1,49 @@
# Depend.sh = Install/unInstall files for dependent packages
-# only Install/unInstall if dependent package is already installed
-# all packages with dependencies should be listed here
-# install dependent child files when parent files installed
-# uninstall dependent child files when parent files uninstalled
-# decisions on individual files are made by package Install.sh scripts
+# all packages which contain one or more files that depend on
+# other packages should be listed here, in both the 1 and 0 clauses
+# this script is invoked after any parent package is installed/uninstalled
+# this script re-installs child packages that depend on the parent,
+# but only if the child package is already installed
+# this is necessary to insure the child package installs
+# only child files whose parent package files are now installed
+# decisions on installing individual child files are made by
+# the Install.sh script in the child package
if (test $1 = 1) then
- if (test -e pair_lj_cut_opt.h) then
- cd OPT; /bin/sh Install.sh 1; cd ..
- fi
if (test -e pair_lj_cut_gpu.h) then
cd GPU; /bin/sh Install.sh 1; cd ..
fi
+ if (test -e pair_lj_cut_opt.h) then
+ cd OPT; /bin/sh Install.sh 1; cd ..
+ fi
if (test -e cg_cmm_params.h) then
cd USER-CG-CMM; /bin/sh Install.sh 1; cd ..
fi
if (test -e pair_lj_cut_cuda.h) then
cd USER-CUDA; /bin/sh Install.sh 1; cd ..
fi
+ if (test -e fix_imd.h) then
+ cd USER-MISC; /bin/sh Install.sh 1; cd ..
+ fi
elif (test $1 = 0) then
- if (test -e pair_lj_cut_opt.h) then
- cd OPT; /bin/sh Install.sh 0; /bin/sh Install.sh 1; cd ..
- fi
if (test -e pair_lj_cut_gpu.h) then
cd GPU; /bin/sh Install.sh 0; /bin/sh Install.sh 1; cd ..
fi
+ if (test -e pair_lj_cut_opt.h) then
+ cd OPT; /bin/sh Install.sh 0; /bin/sh Install.sh 1; cd ..
+ fi
if (test -e cg_cmm_params.h) then
cd USER-CG-CMM; /bin/sh Install.sh 0; /bin/sh Install.sh 1; cd ..
fi
if (test -e pair_lj_cut_cuda.h) then
cd USER-CUDA; /bin/sh Install.sh 0; /bin/sh Install.sh 1; cd ..
fi
+ if (test -e fix_imd.h) then
+ cd USER-MISC; /bin/sh Install.sh 0; /bin/sh Install.sh 1; cd ..
+ fi
fi
+
diff --git a/src/FLD/pair_brownian.h b/src/FLD/pair_brownian.h
index 9a75f9897..798784b49 100644
--- a/src/FLD/pair_brownian.h
+++ b/src/FLD/pair_brownian.h
@@ -1,94 +1,98 @@
/* -*- c++ -*- ----------------------------------------------------------
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 PAIR_CLASS
PairStyle(brownian,PairBrownian)
#else
#ifndef LMP_PAIR_BROWNIAN_H
#define LMP_PAIR_BROWNIAN_H
#include "pair.h"
namespace LAMMPS_NS {
class PairBrownian : public Pair {
public:
PairBrownian(class LAMMPS *);
virtual ~PairBrownian();
virtual void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
virtual double init_one(int, int);
virtual void init_style();
void write_restart(FILE *);
void read_restart(FILE *);
void write_restart_settings(FILE *);
void read_restart_settings(FILE *);
protected:
double cut_inner_global,cut_global;
double t_target,mu;
int flaglog,flagfld;
int flagHI, flagVF;
int flagdeform, flagwall;
double vol_P;
double rad;
class FixWall *wallfix;
int seed;
double **cut_inner,**cut;
double R0,RT0;
class RanMars *random;
void set_3_orthogonal_vectors(double*,double*,double*);
void allocate();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
+W: Cannot include log terms without 1/r terms; setting flagHI to 1
+
+Self-explanatory.
+
E: Incorrect args for pair coefficients
Self-explanatory. Check the input script or data file.
E: Pair brownian requires atom style sphere
Self-explanatory.
W: Pair brownian needs newton pair on for momentum conservation
Self-explanatory.
E: Pair brownian requires extended particles
One of the particles has radius 0.0.
E: Pair brownian requires monodisperse particles
All particles must be the same finite size.
*/
diff --git a/src/FLD/pair_lubricate.h b/src/FLD/pair_lubricate.h
index b95232f95..7053a2208 100644
--- a/src/FLD/pair_lubricate.h
+++ b/src/FLD/pair_lubricate.h
@@ -1,95 +1,99 @@
/* -*- c++ -*- ----------------------------------------------------------
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 PAIR_CLASS
PairStyle(lubricate,PairLubricate)
#else
#ifndef LMP_PAIR_LUBRICATE_H
#define LMP_PAIR_LUBRICATE_H
#include "pair.h"
namespace LAMMPS_NS {
class PairLubricate : public Pair {
public:
PairLubricate(class LAMMPS *);
virtual ~PairLubricate();
virtual void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
double init_one(int, int);
virtual void init_style();
void write_restart(FILE *);
void read_restart(FILE *);
void write_restart_settings(FILE *);
void read_restart_settings(FILE *);
int pre_adapt(char *, int, int, int, int);
void adapt(int, int, int, int, int, double);
int pack_comm(int, int *, double *, int, int *);
void unpack_comm(int, int, double *);
protected:
double mu,cut_inner_global,cut_global;
double rad;
int flaglog,flagfld,shearing;
int flagdeform, flagwall;
double vol_P;
class FixWall *wallfix;
int flagVF, flagHI;
double Ef[3][3];
double R0,RT0,RS0;
double **cut_inner,**cut;
void allocate();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
+W: Cannot include log terms without 1/r terms; setting flagHI to 1
+
+Self-explanatory.
+
E: Incorrect args for pair coefficients
Self-explanatory. Check the input script or data file.
E: Pair lubricate requires atom style sphere
Self-explanatory.
E: Pair lubricate requires ghost atoms store velocity
Use the communicate vel yes command to enable this.
E: Pair lubricate requires monodisperse particles
All particles must be the same finite size.
E: Using pair lubricate with inconsistent fix deform remap option
-If fix deform is used, the remap v option is required.
+Must use remap v option with fix deform with this pair style.
*/
diff --git a/src/FLD/pair_lubricateU.h b/src/FLD/pair_lubricateU.h
index 8e6a47627..4910da2b5 100644
--- a/src/FLD/pair_lubricateU.h
+++ b/src/FLD/pair_lubricateU.h
@@ -1,106 +1,110 @@
/* -*- c++ -*- ----------------------------------------------------------
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 PAIR_CLASS
PairStyle(lubricateU,PairLubricateU)
#else
#ifndef LMP_PAIR_LUBRICATEU_H
#define LMP_PAIR_LUBRICATEU_H
#include "pair.h"
namespace LAMMPS_NS {
class PairLubricateU : public Pair {
public:
PairLubricateU(class LAMMPS *);
virtual ~PairLubricateU();
virtual void compute(int, int);
virtual void settings(int, char **);
void coeff(int, char **);
double init_one(int, int);
virtual void init_style();
void write_restart(FILE *);
void read_restart(FILE *);
void write_restart_settings(FILE *);
void read_restart_settings(FILE *);
int pack_comm(int, int *, double *, int, int *);
void unpack_comm(int, int, double *);
protected:
double cut_inner_global,cut_global;
double mu;
double rad;
int flaglog;
int flagdeform, flagwall;
int flagVF, flagHI;
double vol_P;
class FixWall *wallfix;
double gdot,Ef[3][3];
double **cut_inner,**cut;
void allocate();
double R0,RT0,RS0;
int nmax;
double **fl,**Tl,**xl;
int cgmax;
double *bcg,*xcg,*rcg,*rcg1,*pcg,*RU;
void compute_RE();
virtual void compute_RE(double **);
void compute_RU();
virtual void compute_RU(double **);
virtual void compute_Fh(double **);
void stage_one();
void intermediates(int, double **);
void stage_two(double **);
void copy_vec_uo(int, double *, double **, double **);
void copy_uo_vec(int, double **, double **, double *);
double dot_vec_vec(int , double *, double *);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
+W: Cannot include log terms without 1/r terms; setting flagHI to 1.
+
+Self-explanatory.
+
E: Incorrect args for pair coefficients
Self-explanatory. Check the input script or data file.
E: Pair lubricateU requires atom style sphere
Self-explanatory.
E: Pair lubricateU requires ghost atoms store velocity
Use the communicate vel yes command to enable this.
E: Pair lubricateU requires monodisperse particles
All particles must be the same finite size.
*/
diff --git a/src/FLD/pair_lubricateU_poly.h b/src/FLD/pair_lubricateU_poly.h
index 7d15c28d6..c09f3f701 100644
--- a/src/FLD/pair_lubricateU_poly.h
+++ b/src/FLD/pair_lubricateU_poly.h
@@ -1,75 +1,79 @@
/* -*- c++ -*- ----------------------------------------------------------
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 PAIR_CLASS
PairStyle(lubricateU/poly,PairLubricateUPoly)
#else
#ifndef LMP_PAIR_LUBRICATEU_POLY_H
#define LMP_PAIR_LUBRICATEU_POLY_H
#include "pair_lubricateU.h"
namespace LAMMPS_NS {
class PairLubricateUPoly : public PairLubricateU {
public:
PairLubricateUPoly(class LAMMPS *);
~PairLubricateUPoly() {}
void compute(int, int);
void settings(int, char **);
void init_style();
private:
double vol_P;
int flagdeform, flagwall, flagVF, flagHI;
class FixWall *wallfix;
void iterate(double **, int);
void compute_RE(double **);
void compute_RU(double **);
void compute_Fh(double **);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
+W: Cannot include log terms without 1/r terms; setting flagHI to 1
+
+Self-explanatory.
+
E: Pair lubricateU/poly requires newton pair off
Self-explanatory.
E: Pair lubricateU/poly requires ghost atoms store velocity
Use the communicate vel yes command to enable this.
E: Pair lubricate/poly requires atom style sphere
Self-explanatory.
E: Pair lubricate/poly requires extended particles
One of the particles has radius 0.0.
*/
diff --git a/src/FLD/pair_lubricate_poly.cpp b/src/FLD/pair_lubricate_poly.cpp
index cb4e65d5a..47909db66 100644
--- a/src/FLD/pair_lubricate_poly.cpp
+++ b/src/FLD/pair_lubricate_poly.cpp
@@ -1,565 +1,565 @@
/* ----------------------------------------------------------------------
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: Randy Schunk (SNL)
Amit Kumar and Michael Bybee (UIUC)
Dave Heine (Corning), polydispersity
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pair_lubricate_poly.h"
#include "atom.h"
#include "atom_vec.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "fix_deform.h"
#include "memory.h"
#include "random_mars.h"
#include "fix_wall.h"
#include "input.h"
#include "variable.h"
#include "math_const.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
// same as fix_deform.cpp
enum{NO_REMAP,X_REMAP,V_REMAP};
// same as fix_wall.cpp
enum{EDGE,CONSTANT,VARIABLE};
/* ---------------------------------------------------------------------- */
PairLubricatePoly::PairLubricatePoly(LAMMPS *lmp) : PairLubricate(lmp)
{
no_virial_fdotr_compute = 1;
}
/* ---------------------------------------------------------------------- */
void PairLubricatePoly::compute(int eflag, int vflag)
{
int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,fpair,fx,fy,fz,tx,ty,tz;
double rsq,r,h_sep,h_sepj,beta0,beta1,betaj,betaj1,radi,radj,tfmag;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3;
double vt1,vt2,vt3,wt1,wt2,wt3,wdotn;
double inertia,inv_inertia,vRS0;
double vi[3],vj[3],wi[3],wj[3],xl[3],jl[3];
double a_sq,a_sh,a_pu,Fbmag,del,delmin,eta;
int *ilist,*jlist,*numneigh,**firstneigh;
double lamda[3],vstream[3];
double vxmu2f = force->vxmu2f;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega;
double **angmom = atom->angmom;
double **torque = atom->torque;
double *radius = atom->radius;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *type = atom->type;
int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
int overlaps = 0;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
// subtract streaming component of velocity, omega, angmom
// assume fluid streaming velocity = box deformation rate
// vstream = (ux,uy,uz)
// ux = h_rate[0]*x + h_rate[5]*y + h_rate[4]*z
// uy = h_rate[1]*y + h_rate[3]*z
// uz = h_rate[2]*z
// omega_new = omega - curl(vstream)/2
// angmom_new = angmom - I*curl(vstream)/2
// Ef = (grad(vstream) + (grad(vstream))^T) / 2
if (shearing) {
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itype = type[i];
radi = radius[i];
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
v[i][0] -= vstream[0];
v[i][1] -= vstream[1];
v[i][2] -= vstream[2];
omega[i][0] += 0.5*h_rate[3];
omega[i][1] -= 0.5*h_rate[4];
omega[i][2] += 0.5*h_rate[5];
}
// set Ef from h_rate in strain units
Ef[0][0] = h_rate[0]/domain->xprd;
Ef[1][1] = h_rate[1]/domain->yprd;
Ef[2][2] = h_rate[2]/domain->zprd;
Ef[0][1] = Ef[1][0] = 0.5 * h_rate[5]/domain->yprd;
Ef[0][2] = Ef[2][0] = 0.5 * h_rate[4]/domain->zprd;
Ef[1][2] = Ef[2][1] = 0.5 * h_rate[3]/domain->zprd;
// copy updated omega to the ghost particles
// no need to do this if not shearing since comm->ghost_velocity is set
comm->forward_comm_pair(this);
}
// This section of code adjusts R0/RT0/RS0 if necessary due to changes
// in the volume fraction as a result of fix deform or moving walls
double dims[3], wallcoord;
if (flagVF) // Flag for volume fraction corrections
if (flagdeform || flagwall == 2){ // Possible changes in volume fraction
if (flagdeform && !flagwall)
for (j = 0; j < 3; j++)
dims[j] = domain->prd[j];
else if (flagwall == 2 || (flagdeform && flagwall == 1)){
double wallhi[3], walllo[3];
for (int j = 0; j < 3; j++){
wallhi[j] = domain->prd[j];
walllo[j] = 0;
}
for (int m = 0; m < wallfix->nwall; m++){
int dim = wallfix->wallwhich[m] / 2;
int side = wallfix->wallwhich[m] % 2;
if (wallfix->wallstyle[m] == VARIABLE){
wallcoord = input->variable->compute_equal(wallfix->varindex[m]);
}
else wallcoord = wallfix->coord0[m];
if (side == 0) walllo[dim] = wallcoord;
else wallhi[dim] = wallcoord;
}
for (int j = 0; j < 3; j++)
dims[j] = wallhi[j] - walllo[j];
}
double vol_T = dims[0]*dims[1]*dims[2];
double vol_f = vol_P/vol_T;
if (flaglog == 0) {
R0 = 6*MY_PI*mu*(1.0 + 2.16*vol_f);
RT0 = 8*MY_PI*mu;
RS0 = 20.0/3.0*MY_PI*mu*(1.0 + 3.33*vol_f + 2.80*vol_f*vol_f);
} else {
R0 = 6*MY_PI*mu*(1.0 + 2.725*vol_f - 6.583*vol_f*vol_f);
RT0 = 8*MY_PI*mu*(1.0 + 0.749*vol_f - 2.469*vol_f*vol_f);
RS0 = 20.0/3.0*MY_PI*mu*(1.0 + 3.64*vol_f - 6.95*vol_f*vol_f);
}
}
// end of R0 adjustment code
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];
radi = radius[i];
// angular velocity
wi[0] = omega[i][0];
wi[1] = omega[i][1];
wi[2] = omega[i][2];
// FLD contribution to force and torque due to isotropic terms
// FLD contribution to stress from isotropic RS0
if (flagfld) {
f[i][0] -= vxmu2f*R0*radi*v[i][0];
f[i][1] -= vxmu2f*R0*radi*v[i][1];
f[i][2] -= vxmu2f*R0*radi*v[i][2];
const double radi3 = radi*radi*radi;
torque[i][0] -= vxmu2f*RT0*radi3*wi[0];
torque[i][1] -= vxmu2f*RT0*radi3*wi[1];
torque[i][2] -= vxmu2f*RT0*radi3*wi[2];
if (shearing && vflag_either) {
vRS0 = -vxmu2f * RS0*radi3;
v_tally_tensor(i,i,nlocal,newton_pair,
vRS0*Ef[0][0],vRS0*Ef[1][1],vRS0*Ef[2][2],
vRS0*Ef[0][1],vRS0*Ef[0][2],vRS0*Ef[1][2]);
}
}
if (!flagHI) continue;
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];
radj = atom->radius[j];
if (rsq < cutsq[itype][jtype]) {
r = sqrt(rsq);
// angular momentum = I*omega = 2/5 * M*R^2 * omega
wj[0] = omega[j][0];
wj[1] = omega[j][1];
wj[2] = omega[j][2];
// xl = point of closest approach on particle i from its center
xl[0] = -delx/r*radi;
xl[1] = -dely/r*radi;
xl[2] = -delz/r*radi;
jl[0] = -delx/r*radj;
jl[1] = -dely/r*radj;
jl[2] = -delz/r*radj;
// velocity at the point of closest approach on both particles
// v = v + omega_cross_xl - Ef.xl
// particle i
vi[0] = v[i][0] + (wi[1]*xl[2] - wi[2]*xl[1])
- (Ef[0][0]*xl[0] + Ef[0][1]*xl[1] + Ef[0][2]*xl[2]);
vi[1] = v[i][1] + (wi[2]*xl[0] - wi[0]*xl[2])
- (Ef[1][0]*xl[0] + Ef[1][1]*xl[1] + Ef[1][2]*xl[2]);
vi[2] = v[i][2] + (wi[0]*xl[1] - wi[1]*xl[0])
- (Ef[2][0]*xl[0] + Ef[2][1]*xl[1] + Ef[2][2]*xl[2]);
// particle j
vj[0] = v[j][0] - (wj[1]*jl[2] - wj[2]*jl[1])
+ (Ef[0][0]*jl[0] + Ef[0][1]*jl[1] + Ef[0][2]*jl[2]);
vj[1] = v[j][1] - (wj[2]*jl[0] - wj[0]*jl[2])
+ (Ef[1][0]*jl[0] + Ef[1][1]*jl[1] + Ef[1][2]*jl[2]);
vj[2] = v[j][2] - (wj[0]*jl[1] - wj[1]*jl[0])
+ (Ef[2][0]*jl[0] + Ef[2][1]*jl[1] + Ef[2][2]*jl[2]);
// scalar resistances XA and YA
h_sep = r - radi-radj;
// check for overlaps
if (h_sep < 0.0) overlaps++;
// if less than the minimum gap use the minimum gap instead
if (r < cut_inner[itype][jtype])
h_sep = cut_inner[itype][jtype] - radi-radj;
// scale h_sep by radi
h_sep = h_sep/radi;
beta0 = radj/radi;
beta1 = 1.0 + beta0;
// scalar resistances
if (flaglog) {
a_sq = beta0*beta0/beta1/beta1/h_sep +
(1.0+7.0*beta0+beta0*beta0)/5.0/pow(beta1,3.0)*log(1.0/h_sep);
a_sq += (1.0+18.0*beta0-29.0*beta0*beta0+18.0 *
pow(beta0,3.0)+pow(beta0,4.0))/21.0/pow(beta1,4.0) *
h_sep*log(1.0/h_sep);
a_sq *= 6.0*MY_PI*mu*radi;
a_sh = 4.0*beta0*(2.0+beta0+2.0*beta0*beta0)/15.0/pow(beta1,3.0) *
log(1.0/h_sep);
a_sh += 4.0*(16.0-45.0*beta0+58.0*beta0*beta0-45.0*pow(beta0,3.0) +
16.0*pow(beta0,4.0))/375.0/pow(beta1,4.0) *
h_sep*log(1.0/h_sep);
a_sh *= 6.0*MY_PI*mu*radi;
a_pu = beta0*(4.0+beta0)/10.0/beta1/beta1*log(1.0/h_sep);
a_pu += (32.0-33.0*beta0+83.0*beta0*beta0+43.0 *
pow(beta0,3.0))/250.0/pow(beta1,3.0)*h_sep*log(1.0/h_sep);
a_pu *= 8.0*MY_PI*mu*pow(radi,3.0);
} else a_sq = 6.0*MY_PI*mu*radi*(beta0*beta0/beta1/beta1/h_sep);
// relative velocity at the point of closest approach
// includes fluid velocity
vr1 = vi[0] - vj[0];
vr2 = vi[1] - vj[1];
vr3 = vi[2] - vj[2];
// normal component (vr.n)n
vnnr = (vr1*delx + vr2*dely + vr3*delz)/r;
vn1 = vnnr*delx/r;
vn2 = vnnr*dely/r;
vn3 = vnnr*delz/r;
// tangential component vr - (vr.n)n
vt1 = vr1 - vn1;
vt2 = vr2 - vn2;
vt3 = vr3 - vn3;
// force due to squeeze type motion
fx = a_sq*vn1;
fy = a_sq*vn2;
fz = a_sq*vn3;
// force due to all shear kind of motions
if (flaglog) {
fx = fx + a_sh*vt1;
fy = fy + a_sh*vt2;
fz = fz + a_sh*vt3;
}
// scale forces for appropriate units
fx *= vxmu2f;
fy *= vxmu2f;
fz *= vxmu2f;
// add to total force
f[i][0] -= fx;
f[i][1] -= fy;
f[i][2] -= fz;
// torque due to this force
if (flaglog) {
tx = xl[1]*fz - xl[2]*fy;
ty = xl[2]*fx - xl[0]*fz;
tz = xl[0]*fy - xl[1]*fx;
torque[i][0] -= vxmu2f*tx;
torque[i][1] -= vxmu2f*ty;
torque[i][2] -= vxmu2f*tz;
// torque due to a_pu
wdotn = ((wi[0]-wj[0])*delx + (wi[1]-wj[1])*dely +
(wi[2]-wj[2])*delz)/r;
wt1 = (wi[0]-wj[0]) - wdotn*delx/r;
wt2 = (wi[1]-wj[1]) - wdotn*dely/r;
wt3 = (wi[2]-wj[2]) - wdotn*delz/r;
tx = a_pu*wt1;
ty = a_pu*wt2;
tz = a_pu*wt3;
torque[i][0] -= vxmu2f*tx;
torque[i][1] -= vxmu2f*ty;
torque[i][2] -= vxmu2f*tz;
}
// set j = nlocal so that only I gets tallied
if (evflag) ev_tally_xyz(i,nlocal,nlocal,0,
0.0,0.0,-fx,-fy,-fz,delx,dely,delz);
}
}
}
// restore streaming component of velocity, omega, angmom
if (shearing) {
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itype = type[i];
radi = atom->radius[i];
domain->x2lamda(x[i],lamda);
vstream[0] = h_rate[0]*lamda[0] + h_rate[5]*lamda[1] +
h_rate[4]*lamda[2] + h_ratelo[0];
vstream[1] = h_rate[1]*lamda[1] + h_rate[3]*lamda[2] + h_ratelo[1];
vstream[2] = h_rate[2]*lamda[2] + h_ratelo[2];
v[i][0] += vstream[0];
v[i][1] += vstream[1];
v[i][2] += vstream[2];
omega[i][0] -= 0.5*h_rate[3];
omega[i][1] += 0.5*h_rate[4];
omega[i][2] -= 0.5*h_rate[5];
}
}
// to DEBUG: set print_overlaps to 1
int print_overlaps = 0;
if (print_overlaps) {
int overlaps_all;
MPI_Allreduce(&overlaps,&overlaps_all,1,MPI_INT,MPI_SUM,world);
if (overlaps_all && comm->me == 0)
printf("Number of overlaps = %d\n",overlaps);
}
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairLubricatePoly::init_style()
{
if (force->newton_pair == 1)
error->all(FLERR,"Pair lubricate/poly requires newton pair off");
if (comm->ghost_velocity == 0)
error->all(FLERR,
"Pair lubricate/poly requires ghost atoms store velocity");
if (!atom->sphere_flag)
error->all(FLERR,"Pair lubricate/poly requires atom style sphere");
// ensure all particles are finite-size
// for pair hybrid, should limit test to types using the pair style
double *radius = atom->radius;
int *type = atom->type;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
if (radius[i] == 0.0)
error->one(FLERR,"Pair lubricate/poly requires extended particles");
int irequest = neighbor->request(this);
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->full = 1;
// set the isotropic constants that depend on the volume fraction
// vol_T = total volume
// check for fix deform, if exists it must use "remap v"
// If box will change volume, set appropriate flag so that volume
// and v.f. corrections are re-calculated at every step.
- //
- // If available volume is different from box volume
+
+ // if available volume is different from box volume
// due to walls, set volume appropriately; if walls will
// move, set appropriate flag so that volume and v.f. corrections
// are re-calculated at every step.
shearing = flagdeform = flagwall = 0;
for (int i = 0; i < modify->nfix; i++){
if (strcmp(modify->fix[i]->style,"deform") == 0) {
shearing = flagdeform = 1;
if (((FixDeform *) modify->fix[i])->remapflag != V_REMAP)
error->all(FLERR,"Using pair lubricate with inconsistent "
"fix deform remap option");
}
if (strstr(modify->fix[i]->style,"wall") != NULL){
flagwall = 1; // Walls exist
if (((FixWall *) modify->fix[i])->varflag ) {
flagwall = 2; // Moving walls exist
wallfix = (FixWall *) modify->fix[i];
}
}
}
double vol_T;
double wallcoord;
if (!flagwall) vol_T = domain->xprd*domain->yprd*domain->zprd;
else {
double wallhi[3], walllo[3];
for (int j = 0; j < 3; j++){
wallhi[j] = domain->prd[j];
walllo[j] = 0;
}
for (int m = 0; m < wallfix->nwall; m++){
int dim = wallfix->wallwhich[m] / 2;
int side = wallfix->wallwhich[m] % 2;
if (wallfix->wallstyle[m] == VARIABLE){
wallfix->varindex[m] = input->variable->find(wallfix->varstr[m]);
//Since fix->wall->init happens after pair->init_style
wallcoord = input->variable->compute_equal(wallfix->varindex[m]);
}
else wallcoord = wallfix->coord0[m];
if (side == 0) walllo[dim] = wallcoord;
else wallhi[dim] = wallcoord;
}
vol_T = (wallhi[0] - walllo[0]) * (wallhi[1] - walllo[1]) *
(wallhi[2] - walllo[2]);
}
double volP = 0.0;
for (int i = 0; i < nlocal; i++)
volP += (4.0/3.0)*MY_PI*pow(atom->radius[i],3.0);
MPI_Allreduce(&volP,&vol_P,1,MPI_DOUBLE,MPI_SUM,world);
double vol_f = vol_P/vol_T;
if (!flagVF) vol_f = 0;
// set isotropic constants
if (flaglog == 0) {
R0 = 6*MY_PI*mu*(1.0 + 2.16*vol_f);
RT0 = 8*MY_PI*mu;
RS0 = 20.0/3.0*MY_PI*mu*(1.0 + 3.33*vol_f + 2.80*vol_f*vol_f);
} else {
R0 = 6*MY_PI*mu*(1.0 + 2.725*vol_f - 6.583*vol_f*vol_f);
RT0 = 8*MY_PI*mu*(1.0 + 0.749*vol_f - 2.469*vol_f*vol_f);
RS0 = 20.0/3.0*MY_PI*mu*(1.0 + 3.64*vol_f - 6.95*vol_f*vol_f);
}
// check for fix deform, if exists it must use "remap v"
shearing = 0;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"deform") == 0) {
shearing = 1;
if (((FixDeform *) modify->fix[i])->remapflag != V_REMAP)
error->all(FLERR,"Using pair lubricate/poly with inconsistent "
"fix deform remap option");
}
// set Ef = 0 since used whether shearing or not
Ef[0][0] = Ef[0][1] = Ef[0][2] = 0.0;
Ef[1][0] = Ef[1][1] = Ef[1][2] = 0.0;
Ef[2][0] = Ef[2][1] = Ef[2][2] = 0.0;
}
diff --git a/src/FLD/pair_lubricate_poly.h b/src/FLD/pair_lubricate_poly.h
index ab55508e9..e3400959c 100644
--- a/src/FLD/pair_lubricate_poly.h
+++ b/src/FLD/pair_lubricate_poly.h
@@ -1,62 +1,66 @@
/* -*- c++ -*- ----------------------------------------------------------
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 PAIR_CLASS
PairStyle(lubricate/poly,PairLubricatePoly)
#else
#ifndef LMP_PAIR_LUBRICATE_POLY_H
#define LMP_PAIR_LUBRICATE_POLY_H
#include "pair_lubricate.h"
namespace LAMMPS_NS {
class PairLubricatePoly : public PairLubricate {
public:
PairLubricatePoly(class LAMMPS *);
~PairLubricatePoly() {}
void compute(int, int);
void init_style();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Pair lubricate/poly requires newton pair off
Self-explanatory.
E: Pair lubricate/poly requires ghost atoms store velocity
Use the communicate vel yes command to enable this.
E: Pair lubricate/poly requires atom style sphere
Self-explanatory.
E: Pair lubricate/poly requires extended particles
One of the particles has radius 0.0.
+E: Using pair lubricate with inconsistent fix deform remap option
+
+Must use remap v option with fix deform with this pair style.
+
E: Using pair lubricate/poly with inconsistent fix deform remap option
If fix deform is used, the remap v option is required.
*/
diff --git a/src/GPU/pair_eam_gpu.cpp b/src/GPU/pair_eam_gpu.cpp
index 344409cd3..113a9df05 100644
--- a/src/GPU/pair_eam_gpu.cpp
+++ b/src/GPU/pair_eam_gpu.cpp
@@ -1,241 +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
+ 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: Trung Dac Nguyen (ORNL), W. Michael Brown (ORNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pair_eam_gpu.h"
#include "atom.h"
#include "force.h"
#include "comm.h"
#include "domain.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "memory.h"
#include "error.h"
#include "neigh_request.h"
#include "gpu_extra.h"
using namespace LAMMPS_NS;
#define MAXLINE 1024
// External functions from cuda library for atom decomposition
int eam_gpu_init(const int ntypes, double host_cutforcesq,
- int **host_type2rhor, int **host_type2z2r,
+ int **host_type2rhor, int **host_type2z2r,
int *host_type2frho, double ***host_rhor_spline,
- double ***host_z2r_spline, double ***host_frho_spline,
+ double ***host_z2r_spline, double ***host_frho_spline,
double rdr, double rdrho, int nrhor, int nrho, int nz2r,
- int nfrho, int nr, const int nlocal, const int nall,
- const int max_nbors, const int maxspecial,
- const double cell_size, int &gpu_mode, FILE *screen,
- int &fp_size);
+ int nfrho, int nr, const int nlocal, const int nall,
+ const int max_nbors, const int maxspecial,
+ const double cell_size, int &gpu_mode, FILE *screen,
+ int &fp_size);
void eam_gpu_clear();
int** eam_gpu_compute_n(const int ago, const int inum_full, const int nall,
- double **host_x, int *host_type, double *sublo,
- double *subhi, int *tag, int **nspecial, int **special,
- const bool eflag, const bool vflag, const bool eatom,
- const bool vatom, int &host_start, int **ilist,
- int **jnum, const double cpu_time, bool &success,
- int &inum, void **fp_ptr);
-void eam_gpu_compute(const int ago, const int inum_full, const int nlocal,
- 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, void **fp_ptr);
+ double **host_x, int *host_type, double *sublo,
+ double *subhi, int *tag, int **nspecial, int **special,
+ const bool eflag, const bool vflag, const bool eatom,
+ const bool vatom, int &host_start, int **ilist,
+ int **jnum, const double cpu_time, bool &success,
+ int &inum, void **fp_ptr);
+void eam_gpu_compute(const int ago, const int inum_full, const int nlocal,
+ 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, void **fp_ptr);
void eam_gpu_compute_force(int *ilist, const bool eflag, const bool vflag,
- const bool eatom, const bool vatom);
+ const bool eatom, const bool vatom);
double eam_gpu_bytes();
/* ---------------------------------------------------------------------- */
PairEAMGPU::PairEAMGPU(LAMMPS *lmp) : PairEAM(lmp), gpu_mode(GPU_FORCE)
{
respa_enable = 0;
cpu_time = 0.0;
- GPU_EXTRA::gpu_ready(lmp->modify, lmp->error);
+ GPU_EXTRA::gpu_ready(lmp->modify, lmp->error);
}
/* ----------------------------------------------------------------------
check if allocated, since class can be destructed when incomplete
------------------------------------------------------------------------- */
PairEAMGPU::~PairEAMGPU()
{
eam_gpu_clear();
}
/* ---------------------------------------------------------------------- */
double PairEAMGPU::memory_usage()
{
double bytes = Pair::memory_usage();
return bytes + eam_gpu_bytes();
}
/* ---------------------------------------------------------------------- */
void PairEAMGPU::compute(int eflag, int vflag)
{
int i,j,ii,jj,m,jnum,itype,jtype;
double evdwl,*coeff;
evdwl = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = eflag_global = eflag_atom = 0;
-
+
int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
// compute density on each atom on GPU
- int nall = atom->nlocal + atom->nghost;
+ int nall = atom->nlocal + atom->nghost;
int inum, host_start, inum_dev;
-
+
bool success = true;
- int *ilist, *numneigh, **firstneigh;
- if (gpu_mode != GPU_FORCE) {
+ int *ilist, *numneigh, **firstneigh;
+ if (gpu_mode != GPU_FORCE) {
inum = atom->nlocal;
firstneigh = eam_gpu_compute_n(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, &ilist, &numneigh, cpu_time,
- success, inum_dev, &fp_pinned);
+ atom->type, domain->sublo, domain->subhi,
+ atom->tag, atom->nspecial, atom->special,
+ eflag, vflag, eflag_atom, vflag_atom,
+ host_start, &ilist, &numneigh, cpu_time,
+ success, inum_dev, &fp_pinned);
} else { // gpu_mode == GPU_FORCE
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
eam_gpu_compute(neighbor->ago, inum, nlocal, nall, atom->x, atom->type,
- ilist, numneigh, firstneigh, eflag, vflag, eflag_atom,
- vflag_atom, host_start, cpu_time, success, &fp_pinned);
+ ilist, numneigh, firstneigh, eflag, vflag, eflag_atom,
+ vflag_atom, host_start, cpu_time, success, &fp_pinned);
}
-
+
if (!success)
error->one(FLERR,"Insufficient memory on accelerator");
// communicate derivative of embedding function
comm->forward_comm_pair(this);
-
+
// compute forces on each atom on GPU
- if (gpu_mode != GPU_FORCE)
+ if (gpu_mode != GPU_FORCE)
eam_gpu_compute_force(NULL, eflag, vflag, eflag_atom, vflag_atom);
else
eam_gpu_compute_force(ilist, eflag, vflag, eflag_atom, vflag_atom);
}
/* ----------------------------------------------------------------------
init specific to this pair style
------------------------------------------------------------------------- */
void PairEAMGPU::init_style()
{
- if (force->newton_pair)
+ if (force->newton_pair)
error->all(FLERR,"Cannot use newton pair with eam/gpu pair style");
-
+
// convert read-in file(s) to arrays and spline them
file2array();
array2spline();
-
+
// 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;
int fp_size;
int success = eam_gpu_init(atom->ntypes+1, cutforcesq, type2rhor, type2z2r,
- type2frho, rhor_spline, z2r_spline, frho_spline,
- rdr, rdrho, nrhor, nrho, nz2r, nfrho, nr,
- atom->nlocal, atom->nlocal+atom->nghost, 300,
- maxspecial, cell_size, gpu_mode, screen, fp_size);
+ type2frho, rhor_spline, z2r_spline, frho_spline,
+ rdr, rdrho, nrhor, nrho, nz2r, nfrho, nr,
+ atom->nlocal, atom->nlocal+atom->nghost, 300,
+ maxspecial, cell_size, gpu_mode, screen, fp_size);
GPU_EXTRA::check_flag(success,error,world);
-
+
if (gpu_mode == GPU_FORCE) {
int irequest = neighbor->request(this);
neighbor->requests[irequest]->half = 0;
neighbor->requests[irequest]->full = 1;
}
if (fp_size == sizeof(double))
fp_single = false;
else
fp_single = true;
}
/* ---------------------------------------------------------------------- */
-int PairEAMGPU::pack_comm(int n, int *list, double *buf, int pbc_flag,
- int *pbc)
+double PairEAMGPU::single(int i, int j, int itype, int jtype,
+ double rsq, double factor_coul, double factor_lj,
+ double &fforce)
+{
+ int m;
+ double r,p,rhoip,rhojp,z2,z2p,recip,phi,phip,psip;
+ double *coeff;
+
+ r = sqrt(rsq);
+ p = r*rdr + 1.0;
+ m = static_cast<int> (p);
+ m = MIN(m,nr-1);
+ p -= m;
+ p = MIN(p,1.0);
+
+ coeff = rhor_spline[type2rhor[itype][jtype]][m];
+ rhoip = (coeff[0]*p + coeff[1])*p + coeff[2];
+ coeff = rhor_spline[type2rhor[jtype][itype]][m];
+ rhojp = (coeff[0]*p + coeff[1])*p + coeff[2];
+ coeff = z2r_spline[type2z2r[itype][jtype]][m];
+ z2p = (coeff[0]*p + coeff[1])*p + coeff[2];
+ z2 = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
+
+ double fp_i,fp_j;
+ if (fp_single == false) {
+ fp_i = ((double*)fp_pinned)[i];
+ fp_j = ((double*)fp_pinned)[j];
+ } else {
+ fp_i = ((float*)fp_pinned)[i];
+ fp_j = ((float*)fp_pinned)[j];
+ }
+
+ recip = 1.0/r;
+ phi = z2*recip;
+ phip = z2p*recip - phi*recip;
+ psip = fp_i*rhojp + fp_j*rhoip + phip;
+ fforce = -psip*recip;
+
+ return phi;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int PairEAMGPU::pack_comm(int n, int *list, double *buf, int pbc_flag,
+ int *pbc)
{
int i,j,m;
m = 0;
if (fp_single) {
float *fp_ptr = (float *)fp_pinned;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = static_cast<double>(fp_ptr[j]);
}
} else {
double *fp_ptr = (double *)fp_pinned;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = fp_ptr[j];
}
}
return 1;
}
/* ---------------------------------------------------------------------- */
void PairEAMGPU::unpack_comm(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
if (fp_single) {
float *fp_ptr = (float *)fp_pinned;
for (i = first; i < last; i++) fp_ptr[i] = buf[m++];
} else {
double *fp_ptr = (double *)fp_pinned;
for (i = first; i < last; i++) fp_ptr[i] = buf[m++];
}
}
diff --git a/src/GPU/pair_eam_gpu.h b/src/GPU/pair_eam_gpu.h
index 08a2013ef..3b48c6b37 100644
--- a/src/GPU/pair_eam_gpu.h
+++ b/src/GPU/pair_eam_gpu.h
@@ -1,66 +1,67 @@
/* ----------------------------------------------------------------------
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
+ 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 PAIR_CLASS
PairStyle(eam/gpu,PairEAMGPU)
#else
#ifndef LMP_PAIR_EAM_GPU_H
#define LMP_PAIR_EAM_GPU_H
#include "stdio.h"
#include "pair_eam.h"
namespace LAMMPS_NS {
class PairEAMGPU : public PairEAM {
public:
PairEAMGPU(class LAMMPS *);
virtual ~PairEAMGPU();
void compute(int, int);
void init_style();
+ double single(int, int, int, int, double, double, double, double &);
double memory_usage();
int pack_comm(int, int *, double *, int, int *);
void unpack_comm(int, int, double *);
enum { GPU_FORCE, GPU_NEIGH, GPU_HYB_NEIGH };
protected:
int gpu_mode;
double cpu_time;
int *gpulist;
void *fp_pinned;
- bool fp_single;
+ bool fp_single;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Insufficient memory on accelerator
There is insufficient memory on one of the devices specified for the gpu
package
E: Cannot use newton pair with eam/gpu pair style
Self-explanatory.
*/
diff --git a/src/KSPACE/ewald.cpp b/src/KSPACE/ewald.cpp
index 8bdf47d5f..7a383d847 100644
--- a/src/KSPACE/ewald.cpp
+++ b/src/KSPACE/ewald.cpp
@@ -1,1140 +1,1144 @@
/* ----------------------------------------------------------------------
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: Roy Pollock (LLNL), Paul Crozier (SNL)
per-atom energy/virial added by German Samolyuk (ORNL), Stan Moore (BYU)
group/group energy/force added by Stan Moore (BYU)
------------------------------------------------------------------------- */
#include "mpi.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "math.h"
#include "ewald.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "pair.h"
#include "domain.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.00001
/* ---------------------------------------------------------------------- */
Ewald::Ewald(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg)
{
if (narg != 1) error->all(FLERR,"Illegal kspace_style ewald command");
group_group_enable = 1;
+ group_allocate_flag = 0;
accuracy_relative = atof(arg[0]);
kmax = 0;
kxvecs = kyvecs = kzvecs = NULL;
ug = NULL;
eg = vg = NULL;
sfacrl = sfacim = sfacrl_all = sfacim_all = NULL;
nmax = 0;
ek = NULL;
cs = sn = NULL;
kcount = 0;
}
/* ----------------------------------------------------------------------
free all memory
------------------------------------------------------------------------- */
Ewald::~Ewald()
{
deallocate();
- deallocate_groups();
+ if (group_allocate_flag) deallocate_groups();
memory->destroy(ek);
memory->destroy3d_offset(cs,-kmax_created);
memory->destroy3d_offset(sn,-kmax_created);
}
/* ---------------------------------------------------------------------- */
void Ewald::init()
{
if (comm->me == 0) {
if (screen) fprintf(screen,"Ewald initialization ...\n");
if (logfile) fprintf(logfile,"Ewald initialization ...\n");
}
// error check
if (domain->triclinic)
error->all(FLERR,"Cannot use Ewald with triclinic box");
if (domain->dimension == 2)
error->all(FLERR,"Cannot use Ewald with 2d simulation");
if (!atom->q_flag) error->all(FLERR,"Kspace style requires atom attribute q");
if (slabflag == 0 && domain->nonperiodic > 0)
error->all(FLERR,"Cannot use nonperiodic boundaries with Ewald");
if (slabflag == 1) {
if (domain->xperiodic != 1 || domain->yperiodic != 1 ||
domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1)
error->all(FLERR,"Incorrect boundaries with slab Ewald");
}
// extract short-range Coulombic cutoff from pair style
scale = 1.0;
if (force->pair == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
int itmp;
double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp);
if (p_cutoff == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
double cutoff = *p_cutoff;
qsum = qsqsum = 0.0;
for (int i = 0; i < atom->nlocal; i++) {
qsum += atom->q[i];
qsqsum += atom->q[i]*atom->q[i];
}
double tmp;
MPI_Allreduce(&qsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
qsum = tmp;
MPI_Allreduce(&qsqsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
qsqsum = tmp;
if (qsqsum == 0.0)
error->all(FLERR,"Cannot use kspace solver on system with no charge");
if (fabs(qsum) > SMALL && comm->me == 0) {
char str[128];
sprintf(str,"System is not charge neutral, net charge = %g",qsum);
error->warning(FLERR,str);
}
// set accuracy (force units) from accuracy_relative or accuracy_absolute
if (accuracy_absolute >= 0.0) accuracy = accuracy_absolute;
else accuracy = accuracy_relative * two_charge_force;
// setup K-space resolution
q2 = qsqsum * force->qqrd2e / force->dielectric;
bigint natoms = atom->natoms;
// use xprd,yprd,zprd even if triclinic so grid size is the same
// adjust z dimension for 2d slab Ewald
// 3d Ewald just uses zprd since slab_volfactor = 1.0
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
double zprd_slab = zprd*slab_volfactor;
// make initial g_ewald estimate
// based on desired accuracy and real space cutoff
// fluid-occupied volume used to estimate real-space error
// zprd used rather than zprd_slab
if (!gewaldflag) {
+ if (accuracy <= 0.0)
+ error->all(FLERR,"KSpace accuracy must be > 0");
g_ewald = accuracy*sqrt(natoms*cutoff*xprd*yprd*zprd) / (2.0*q2);
- if (g_ewald >= 1.0)
- error->all(FLERR,"KSpace accuracy too large to estimate G vector");
- g_ewald = sqrt(-log(g_ewald)) / cutoff;
+ if (g_ewald >= 1.0) g_ewald = (1.35 - 0.15*log(accuracy))/cutoff;
+ else g_ewald = sqrt(-log(g_ewald)) / cutoff;
}
// setup Ewald coefficients so can print stats
setup();
// final RMS accuracy
double lprx = rms(kxmax,xprd,natoms,q2);
double lpry = rms(kymax,yprd,natoms,q2);
double lprz = rms(kzmax,zprd_slab,natoms,q2);
double lpr = sqrt(lprx*lprx + lpry*lpry + lprz*lprz) / sqrt(3.0);
double spr = 2.0*q2 * exp(-g_ewald*g_ewald*cutoff*cutoff) /
sqrt(natoms*cutoff*xprd*yprd*zprd_slab);
+ double tpr = estimate_table_accuracy(spr);
+ double accuracy = sqrt(lpr*lpr + spr*spr + tpr*tpr);
// stats
if (comm->me == 0) {
if (screen) {
fprintf(screen," G vector (1/distance) = %g\n",g_ewald);
fprintf(screen," estimated absolute RMS force accuracy = %g\n",
- MAX(lpr,spr));
+ accuracy);
fprintf(screen," estimated relative force accuracy = %g\n",
- MAX(lpr,spr)/two_charge_force);
+ accuracy/two_charge_force);
fprintf(screen," KSpace vectors: actual max1d max3d = %d %d %d\n",
kcount,kmax,kmax3d);
}
if (logfile) {
fprintf(logfile," G vector (1/distnace) = %g\n",g_ewald);
fprintf(logfile," estimated absolute RMS force accuracy = %g\n",
- MAX(lpr,spr));
+ accuracy);
fprintf(logfile," estimated relative force accuracy = %g\n",
- MAX(lpr,spr)/two_charge_force);
+ accuracy/two_charge_force);
fprintf(logfile," KSpace vectors: actual max1d max3d = %d %d %d\n",
kcount,kmax,kmax3d);
}
}
}
/* ----------------------------------------------------------------------
adjust Ewald coeffs, called initially and whenever volume has changed
------------------------------------------------------------------------- */
void Ewald::setup()
{
// volume-dependent factors
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
// adjustment of z dimension for 2d slab Ewald
// 3d Ewald just uses zprd since slab_volfactor = 1.0
double zprd_slab = zprd*slab_volfactor;
volume = xprd * yprd * zprd_slab;
unitk[0] = 2.0*MY_PI/xprd;
unitk[1] = 2.0*MY_PI/yprd;
unitk[2] = 2.0*MY_PI/zprd_slab;
// determine kmax
// function of current box size, accuracy, G_ewald (short-range cutoff)
bigint natoms = atom->natoms;
double err;
kxmax = 1;
kymax = 1;
kzmax = 1;
err = rms(kxmax,xprd,natoms,q2);
while (err > accuracy) {
kxmax++;
err = rms(kxmax,xprd,natoms,q2);
}
err = rms(kymax,yprd,natoms,q2);
while (err > accuracy) {
kymax++;
err = rms(kymax,yprd,natoms,q2);
}
err = rms(kzmax,zprd_slab,natoms,q2);
while (err > accuracy) {
kzmax++;
err = rms(kzmax,zprd_slab,natoms,q2);
}
int kmax_old = kmax;
kmax = MAX(kxmax,kymax);
kmax = MAX(kmax,kzmax);
kmax3d = 4*kmax*kmax*kmax + 6*kmax*kmax + 3*kmax;
double gsqxmx = unitk[0]*unitk[0]*kxmax*kxmax;
double gsqymx = unitk[1]*unitk[1]*kymax*kymax;
double gsqzmx = unitk[2]*unitk[2]*kzmax*kzmax;
gsqmx = MAX(gsqxmx,gsqymx);
gsqmx = MAX(gsqmx,gsqzmx);
gsqmx *= 1.00001;
// if size has grown, reallocate k-dependent and nlocal-dependent arrays
if (kmax > kmax_old) {
deallocate();
allocate();
group_allocate_flag = 0;
memory->destroy(ek);
memory->destroy3d_offset(cs,-kmax_created);
memory->destroy3d_offset(sn,-kmax_created);
nmax = atom->nmax;
memory->create(ek,nmax,3,"ewald:ek");
memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald:cs");
memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald:sn");
kmax_created = kmax;
}
// pre-compute Ewald coefficients
coeffs();
}
/* ----------------------------------------------------------------------
compute RMS accuracy for a dimension
------------------------------------------------------------------------- */
double Ewald::rms(int km, double prd, bigint natoms, double q2)
{
double value = 2.0*q2*g_ewald/prd *
sqrt(1.0/(MY_PI*km*natoms)) *
exp(-MY_PI*MY_PI*km*km/(g_ewald*g_ewald*prd*prd));
return value;
}
/* ----------------------------------------------------------------------
compute the Ewald long-range force, energy, virial
------------------------------------------------------------------------- */
void Ewald::compute(int eflag, int vflag)
{
int i,j,k;
// set energy/virial flags
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = evflag_atom = eflag_global = vflag_global =
eflag_atom = vflag_atom = 0;
// extend size of per-atom arrays if necessary
if (atom->nlocal > nmax) {
memory->destroy(ek);
memory->destroy3d_offset(cs,-kmax_created);
memory->destroy3d_offset(sn,-kmax_created);
nmax = atom->nmax;
memory->create(ek,nmax,3,"ewald:ek");
memory->create3d_offset(cs,-kmax,kmax,3,nmax,"ewald:cs");
memory->create3d_offset(sn,-kmax,kmax,3,nmax,"ewald:sn");
kmax_created = kmax;
}
// partial structure factors on each processor
// total structure factor by summing over procs
eik_dot_r();
MPI_Allreduce(sfacrl,sfacrl_all,kcount,MPI_DOUBLE,MPI_SUM,world);
MPI_Allreduce(sfacim,sfacim_all,kcount,MPI_DOUBLE,MPI_SUM,world);
// K-space portion of electric field
// double loop over K-vectors and local atoms
// perform per-atom calculations if needed
double **f = atom->f;
double *q = atom->q;
int nlocal = atom->nlocal;
int kx,ky,kz;
double cypz,sypz,exprl,expim,partial,partial_peratom;
for (i = 0; i < nlocal; i++) {
ek[i][0] = 0.0;
ek[i][1] = 0.0;
ek[i][2] = 0.0;
}
for (k = 0; k < kcount; k++) {
kx = kxvecs[k];
ky = kyvecs[k];
kz = kzvecs[k];
for (i = 0; i < nlocal; i++) {
cypz = cs[ky][1][i]*cs[kz][2][i] - sn[ky][1][i]*sn[kz][2][i];
sypz = sn[ky][1][i]*cs[kz][2][i] + cs[ky][1][i]*sn[kz][2][i];
exprl = cs[kx][0][i]*cypz - sn[kx][0][i]*sypz;
expim = sn[kx][0][i]*cypz + cs[kx][0][i]*sypz;
partial = expim*sfacrl_all[k] - exprl*sfacim_all[k];
ek[i][0] += partial*eg[k][0];
ek[i][1] += partial*eg[k][1];
ek[i][2] += partial*eg[k][2];
if (evflag_atom) {
partial_peratom = exprl*sfacrl_all[k] + expim*sfacim_all[k];
if (eflag_atom) eatom[i] += q[i]*ug[k]*partial_peratom;
if (vflag_atom)
for (j = 0; j < 6; j++)
vatom[i][j] += ug[k]*vg[k][j]*partial_peratom;
}
}
}
// convert E-field to force
const double qscale = force->qqrd2e * scale;
for (i = 0; i < nlocal; i++) {
f[i][0] += qscale * q[i]*ek[i][0];
f[i][1] += qscale * q[i]*ek[i][1];
f[i][2] += qscale * q[i]*ek[i][2];
}
// global energy
if (eflag_global) {
for (k = 0; k < kcount; k++)
energy += ug[k] * (sfacrl_all[k]*sfacrl_all[k] +
sfacim_all[k]*sfacim_all[k]);
energy -= g_ewald*qsqsum/MY_PIS +
MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
energy *= qscale;
}
// global virial
if (vflag_global) {
double uk;
for (k = 0; k < kcount; k++) {
uk = ug[k] * (sfacrl_all[k]*sfacrl_all[k] + sfacim_all[k]*sfacim_all[k]);
for (j = 0; j < 6; j++) virial[j] += uk*vg[k][j];
}
for (j = 0; j < 6; j++) virial[j] *= qscale;
}
// per-atom energy/virial
// energy includes self-energy correction
if (evflag_atom) {
if (eflag_atom) {
for (i = 0; i < nlocal; i++) {
eatom[i] -= g_ewald*q[i]*q[i]/MY_PIS + MY_PI2*q[i]*qsum /
(g_ewald*g_ewald*volume);
eatom[i] *= qscale;
}
}
if (vflag_atom)
for (i = 0; i < nlocal; i++)
for (j = 0; j < 6; j++) vatom[i][j] *= q[i]*qscale;
}
// 2d slab correction
if (slabflag) slabcorr();
}
/* ---------------------------------------------------------------------- */
void Ewald::eik_dot_r()
{
int i,k,l,m,n,ic;
double cstr1,sstr1,cstr2,sstr2,cstr3,sstr3,cstr4,sstr4;
double sqk,clpm,slpm;
double **x = atom->x;
double *q = atom->q;
int nlocal = atom->nlocal;
n = 0;
// (k,0,0), (0,l,0), (0,0,m)
for (ic = 0; ic < 3; ic++) {
sqk = unitk[ic]*unitk[ic];
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
for (i = 0; i < nlocal; i++) {
cs[0][ic][i] = 1.0;
sn[0][ic][i] = 0.0;
cs[1][ic][i] = cos(unitk[ic]*x[i][ic]);
sn[1][ic][i] = sin(unitk[ic]*x[i][ic]);
cs[-1][ic][i] = cs[1][ic][i];
sn[-1][ic][i] = -sn[1][ic][i];
cstr1 += q[i]*cs[1][ic][i];
sstr1 += q[i]*sn[1][ic][i];
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
}
}
for (m = 2; m <= kmax; m++) {
for (ic = 0; ic < 3; ic++) {
sqk = m*unitk[ic] * m*unitk[ic];
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
for (i = 0; i < nlocal; i++) {
cs[m][ic][i] = cs[m-1][ic][i]*cs[1][ic][i] -
sn[m-1][ic][i]*sn[1][ic][i];
sn[m][ic][i] = sn[m-1][ic][i]*cs[1][ic][i] +
cs[m-1][ic][i]*sn[1][ic][i];
cs[-m][ic][i] = cs[m][ic][i];
sn[-m][ic][i] = -sn[m][ic][i];
cstr1 += q[i]*cs[m][ic][i];
sstr1 += q[i]*sn[m][ic][i];
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
}
}
}
// 1 = (k,l,0), 2 = (k,-l,0)
for (k = 1; k <= kxmax; k++) {
for (l = 1; l <= kymax; l++) {
sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]);
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
cstr2 = 0.0;
sstr2 = 0.0;
for (i = 0; i < nlocal; i++) {
cstr1 += q[i]*(cs[k][0][i]*cs[l][1][i] - sn[k][0][i]*sn[l][1][i]);
sstr1 += q[i]*(sn[k][0][i]*cs[l][1][i] + cs[k][0][i]*sn[l][1][i]);
cstr2 += q[i]*(cs[k][0][i]*cs[l][1][i] + sn[k][0][i]*sn[l][1][i]);
sstr2 += q[i]*(sn[k][0][i]*cs[l][1][i] - cs[k][0][i]*sn[l][1][i]);
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
sfacrl[n] = cstr2;
sfacim[n++] = sstr2;
}
}
}
// 1 = (0,l,m), 2 = (0,l,-m)
for (l = 1; l <= kymax; l++) {
for (m = 1; m <= kzmax; m++) {
sqk = (l*unitk[1] * l*unitk[1]) + (m*unitk[2] * m*unitk[2]);
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
cstr2 = 0.0;
sstr2 = 0.0;
for (i = 0; i < nlocal; i++) {
cstr1 += q[i]*(cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i]);
sstr1 += q[i]*(sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i]);
cstr2 += q[i]*(cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i]);
sstr2 += q[i]*(sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i]);
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
sfacrl[n] = cstr2;
sfacim[n++] = sstr2;
}
}
}
// 1 = (k,0,m), 2 = (k,0,-m)
for (k = 1; k <= kxmax; k++) {
for (m = 1; m <= kzmax; m++) {
sqk = (k*unitk[0] * k*unitk[0]) + (m*unitk[2] * m*unitk[2]);
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
cstr2 = 0.0;
sstr2 = 0.0;
for (i = 0; i < nlocal; i++) {
cstr1 += q[i]*(cs[k][0][i]*cs[m][2][i] - sn[k][0][i]*sn[m][2][i]);
sstr1 += q[i]*(sn[k][0][i]*cs[m][2][i] + cs[k][0][i]*sn[m][2][i]);
cstr2 += q[i]*(cs[k][0][i]*cs[m][2][i] + sn[k][0][i]*sn[m][2][i]);
sstr2 += q[i]*(sn[k][0][i]*cs[m][2][i] - cs[k][0][i]*sn[m][2][i]);
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
sfacrl[n] = cstr2;
sfacim[n++] = sstr2;
}
}
}
// 1 = (k,l,m), 2 = (k,-l,m), 3 = (k,l,-m), 4 = (k,-l,-m)
for (k = 1; k <= kxmax; k++) {
for (l = 1; l <= kymax; l++) {
for (m = 1; m <= kzmax; m++) {
sqk = (k*unitk[0] * k*unitk[0]) + (l*unitk[1] * l*unitk[1]) +
(m*unitk[2] * m*unitk[2]);
if (sqk <= gsqmx) {
cstr1 = 0.0;
sstr1 = 0.0;
cstr2 = 0.0;
sstr2 = 0.0;
cstr3 = 0.0;
sstr3 = 0.0;
cstr4 = 0.0;
sstr4 = 0.0;
for (i = 0; i < nlocal; i++) {
clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i];
slpm = sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i];
cstr1 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
sstr1 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i];
slpm = -sn[l][1][i]*cs[m][2][i] + cs[l][1][i]*sn[m][2][i];
cstr2 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
sstr2 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
clpm = cs[l][1][i]*cs[m][2][i] + sn[l][1][i]*sn[m][2][i];
slpm = sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i];
cstr3 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
sstr3 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
clpm = cs[l][1][i]*cs[m][2][i] - sn[l][1][i]*sn[m][2][i];
slpm = -sn[l][1][i]*cs[m][2][i] - cs[l][1][i]*sn[m][2][i];
cstr4 += q[i]*(cs[k][0][i]*clpm - sn[k][0][i]*slpm);
sstr4 += q[i]*(sn[k][0][i]*clpm + cs[k][0][i]*slpm);
}
sfacrl[n] = cstr1;
sfacim[n++] = sstr1;
sfacrl[n] = cstr2;
sfacim[n++] = sstr2;
sfacrl[n] = cstr3;
sfacim[n++] = sstr3;
sfacrl[n] = cstr4;
sfacim[n++] = sstr4;
}
}
}
}
}
/* ----------------------------------------------------------------------
pre-compute coefficients for each Ewald K-vector
------------------------------------------------------------------------- */
void Ewald::coeffs()
{
int k,l,m;
double sqk,vterm;
double g_ewald_sq_inv = 1.0 / (g_ewald*g_ewald);
double preu = 4.0*MY_PI/volume;
kcount = 0;
// (k,0,0), (0,l,0), (0,0,m)
for (m = 1; m <= kmax; m++) {
sqk = (m*unitk[0]) * (m*unitk[0]);
if (sqk <= gsqmx) {
kxvecs[kcount] = m;
kyvecs[kcount] = 0;
kzvecs[kcount] = 0;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitk[0]*m*ug[kcount];
eg[kcount][1] = 0.0;
eg[kcount][2] = 0.0;
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0 + vterm*(unitk[0]*m)*(unitk[0]*m);
vg[kcount][1] = 1.0;
vg[kcount][2] = 1.0;
vg[kcount][3] = 0.0;
vg[kcount][4] = 0.0;
vg[kcount][5] = 0.0;
kcount++;
}
sqk = (m*unitk[1]) * (m*unitk[1]);
if (sqk <= gsqmx) {
kxvecs[kcount] = 0;
kyvecs[kcount] = m;
kzvecs[kcount] = 0;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 0.0;
eg[kcount][1] = 2.0*unitk[1]*m*ug[kcount];
eg[kcount][2] = 0.0;
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0;
vg[kcount][1] = 1.0 + vterm*(unitk[1]*m)*(unitk[1]*m);
vg[kcount][2] = 1.0;
vg[kcount][3] = 0.0;
vg[kcount][4] = 0.0;
vg[kcount][5] = 0.0;
kcount++;
}
sqk = (m*unitk[2]) * (m*unitk[2]);
if (sqk <= gsqmx) {
kxvecs[kcount] = 0;
kyvecs[kcount] = 0;
kzvecs[kcount] = m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 0.0;
eg[kcount][1] = 0.0;
eg[kcount][2] = 2.0*unitk[2]*m*ug[kcount];
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0;
vg[kcount][1] = 1.0;
vg[kcount][2] = 1.0 + vterm*(unitk[2]*m)*(unitk[2]*m);
vg[kcount][3] = 0.0;
vg[kcount][4] = 0.0;
vg[kcount][5] = 0.0;
kcount++;
}
}
// 1 = (k,l,0), 2 = (k,-l,0)
for (k = 1; k <= kxmax; k++) {
for (l = 1; l <= kymax; l++) {
sqk = (unitk[0]*k) * (unitk[0]*k) + (unitk[1]*l) * (unitk[1]*l);
if (sqk <= gsqmx) {
kxvecs[kcount] = k;
kyvecs[kcount] = l;
kzvecs[kcount] = 0;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitk[0]*k*ug[kcount];
eg[kcount][1] = 2.0*unitk[1]*l*ug[kcount];
eg[kcount][2] = 0.0;
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0 + vterm*(unitk[0]*k)*(unitk[0]*k);
vg[kcount][1] = 1.0 + vterm*(unitk[1]*l)*(unitk[1]*l);
vg[kcount][2] = 1.0;
vg[kcount][3] = vterm*unitk[0]*k*unitk[1]*l;
vg[kcount][4] = 0.0;
vg[kcount][5] = 0.0;
kcount++;
kxvecs[kcount] = k;
kyvecs[kcount] = -l;
kzvecs[kcount] = 0;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitk[0]*k*ug[kcount];
eg[kcount][1] = -2.0*unitk[1]*l*ug[kcount];
eg[kcount][2] = 0.0;
vg[kcount][0] = 1.0 + vterm*(unitk[0]*k)*(unitk[0]*k);
vg[kcount][1] = 1.0 + vterm*(unitk[1]*l)*(unitk[1]*l);
vg[kcount][2] = 1.0;
vg[kcount][3] = -vterm*unitk[0]*k*unitk[1]*l;
vg[kcount][4] = 0.0;
vg[kcount][5] = 0.0;
kcount++;;
}
}
}
// 1 = (0,l,m), 2 = (0,l,-m)
for (l = 1; l <= kymax; l++) {
for (m = 1; m <= kzmax; m++) {
sqk = (unitk[1]*l) * (unitk[1]*l) + (unitk[2]*m) * (unitk[2]*m);
if (sqk <= gsqmx) {
kxvecs[kcount] = 0;
kyvecs[kcount] = l;
kzvecs[kcount] = m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 0.0;
eg[kcount][1] = 2.0*unitk[1]*l*ug[kcount];
eg[kcount][2] = 2.0*unitk[2]*m*ug[kcount];
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0;
vg[kcount][1] = 1.0 + vterm*(unitk[1]*l)*(unitk[1]*l);
vg[kcount][2] = 1.0 + vterm*(unitk[2]*m)*(unitk[2]*m);
vg[kcount][3] = 0.0;
vg[kcount][4] = 0.0;
vg[kcount][5] = vterm*unitk[1]*l*unitk[2]*m;
kcount++;
kxvecs[kcount] = 0;
kyvecs[kcount] = l;
kzvecs[kcount] = -m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 0.0;
eg[kcount][1] = 2.0*unitk[1]*l*ug[kcount];
eg[kcount][2] = -2.0*unitk[2]*m*ug[kcount];
vg[kcount][0] = 1.0;
vg[kcount][1] = 1.0 + vterm*(unitk[1]*l)*(unitk[1]*l);
vg[kcount][2] = 1.0 + vterm*(unitk[2]*m)*(unitk[2]*m);
vg[kcount][3] = 0.0;
vg[kcount][4] = 0.0;
vg[kcount][5] = -vterm*unitk[1]*l*unitk[2]*m;
kcount++;
}
}
}
// 1 = (k,0,m), 2 = (k,0,-m)
for (k = 1; k <= kxmax; k++) {
for (m = 1; m <= kzmax; m++) {
sqk = (unitk[0]*k) * (unitk[0]*k) + (unitk[2]*m) * (unitk[2]*m);
if (sqk <= gsqmx) {
kxvecs[kcount] = k;
kyvecs[kcount] = 0;
kzvecs[kcount] = m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitk[0]*k*ug[kcount];
eg[kcount][1] = 0.0;
eg[kcount][2] = 2.0*unitk[2]*m*ug[kcount];
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0 + vterm*(unitk[0]*k)*(unitk[0]*k);
vg[kcount][1] = 1.0;
vg[kcount][2] = 1.0 + vterm*(unitk[2]*m)*(unitk[2]*m);
vg[kcount][3] = 0.0;
vg[kcount][4] = vterm*unitk[0]*k*unitk[2]*m;
vg[kcount][5] = 0.0;
kcount++;
kxvecs[kcount] = k;
kyvecs[kcount] = 0;
kzvecs[kcount] = -m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitk[0]*k*ug[kcount];
eg[kcount][1] = 0.0;
eg[kcount][2] = -2.0*unitk[2]*m*ug[kcount];
vg[kcount][0] = 1.0 + vterm*(unitk[0]*k)*(unitk[0]*k);
vg[kcount][1] = 1.0;
vg[kcount][2] = 1.0 + vterm*(unitk[2]*m)*(unitk[2]*m);
vg[kcount][3] = 0.0;
vg[kcount][4] = -vterm*unitk[0]*k*unitk[2]*m;
vg[kcount][5] = 0.0;
kcount++;
}
}
}
// 1 = (k,l,m), 2 = (k,-l,m), 3 = (k,l,-m), 4 = (k,-l,-m)
for (k = 1; k <= kxmax; k++) {
for (l = 1; l <= kymax; l++) {
for (m = 1; m <= kzmax; m++) {
sqk = (unitk[0]*k) * (unitk[0]*k) + (unitk[1]*l) * (unitk[1]*l) +
(unitk[2]*m) * (unitk[2]*m);
if (sqk <= gsqmx) {
kxvecs[kcount] = k;
kyvecs[kcount] = l;
kzvecs[kcount] = m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitk[0]*k*ug[kcount];
eg[kcount][1] = 2.0*unitk[1]*l*ug[kcount];
eg[kcount][2] = 2.0*unitk[2]*m*ug[kcount];
vterm = -2.0*(1.0/sqk + 0.25*g_ewald_sq_inv);
vg[kcount][0] = 1.0 + vterm*(unitk[0]*k)*(unitk[0]*k);
vg[kcount][1] = 1.0 + vterm*(unitk[1]*l)*(unitk[1]*l);
vg[kcount][2] = 1.0 + vterm*(unitk[2]*m)*(unitk[2]*m);
vg[kcount][3] = vterm*unitk[0]*k*unitk[1]*l;
vg[kcount][4] = vterm*unitk[0]*k*unitk[2]*m;
vg[kcount][5] = vterm*unitk[1]*l*unitk[2]*m;
kcount++;
kxvecs[kcount] = k;
kyvecs[kcount] = -l;
kzvecs[kcount] = m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitk[0]*k*ug[kcount];
eg[kcount][1] = -2.0*unitk[1]*l*ug[kcount];
eg[kcount][2] = 2.0*unitk[2]*m*ug[kcount];
vg[kcount][0] = 1.0 + vterm*(unitk[0]*k)*(unitk[0]*k);
vg[kcount][1] = 1.0 + vterm*(unitk[1]*l)*(unitk[1]*l);
vg[kcount][2] = 1.0 + vterm*(unitk[2]*m)*(unitk[2]*m);
vg[kcount][3] = -vterm*unitk[0]*k*unitk[1]*l;
vg[kcount][4] = vterm*unitk[0]*k*unitk[2]*m;
vg[kcount][5] = -vterm*unitk[1]*l*unitk[2]*m;
kcount++;
kxvecs[kcount] = k;
kyvecs[kcount] = l;
kzvecs[kcount] = -m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitk[0]*k*ug[kcount];
eg[kcount][1] = 2.0*unitk[1]*l*ug[kcount];
eg[kcount][2] = -2.0*unitk[2]*m*ug[kcount];
vg[kcount][0] = 1.0 + vterm*(unitk[0]*k)*(unitk[0]*k);
vg[kcount][1] = 1.0 + vterm*(unitk[1]*l)*(unitk[1]*l);
vg[kcount][2] = 1.0 + vterm*(unitk[2]*m)*(unitk[2]*m);
vg[kcount][3] = vterm*unitk[0]*k*unitk[1]*l;
vg[kcount][4] = -vterm*unitk[0]*k*unitk[2]*m;
vg[kcount][5] = -vterm*unitk[1]*l*unitk[2]*m;
kcount++;
kxvecs[kcount] = k;
kyvecs[kcount] = -l;
kzvecs[kcount] = -m;
ug[kcount] = preu*exp(-0.25*sqk*g_ewald_sq_inv)/sqk;
eg[kcount][0] = 2.0*unitk[0]*k*ug[kcount];
eg[kcount][1] = -2.0*unitk[1]*l*ug[kcount];
eg[kcount][2] = -2.0*unitk[2]*m*ug[kcount];
vg[kcount][0] = 1.0 + vterm*(unitk[0]*k)*(unitk[0]*k);
vg[kcount][1] = 1.0 + vterm*(unitk[1]*l)*(unitk[1]*l);
vg[kcount][2] = 1.0 + vterm*(unitk[2]*m)*(unitk[2]*m);
vg[kcount][3] = -vterm*unitk[0]*k*unitk[1]*l;
vg[kcount][4] = -vterm*unitk[0]*k*unitk[2]*m;
vg[kcount][5] = vterm*unitk[1]*l*unitk[2]*m;
kcount++;
}
}
}
}
}
/* ----------------------------------------------------------------------
allocate memory that depends on # of K-vectors
------------------------------------------------------------------------- */
void Ewald::allocate()
{
kxvecs = new int[kmax3d];
kyvecs = new int[kmax3d];
kzvecs = new int[kmax3d];
ug = new double[kmax3d];
memory->create(eg,kmax3d,3,"ewald:eg");
memory->create(vg,kmax3d,6,"ewald:vg");
sfacrl = new double[kmax3d];
sfacim = new double[kmax3d];
sfacrl_all = new double[kmax3d];
sfacim_all = new double[kmax3d];
}
/* ----------------------------------------------------------------------
deallocate memory that depends on # of K-vectors
------------------------------------------------------------------------- */
void Ewald::deallocate()
{
delete [] kxvecs;
delete [] kyvecs;
delete [] kzvecs;
delete [] ug;
memory->destroy(eg);
memory->destroy(vg);
delete [] sfacrl;
delete [] sfacim;
delete [] sfacrl_all;
delete [] sfacim_all;
}
/* ----------------------------------------------------------------------
Slab-geometry correction term to dampen inter-slab interactions between
periodically repeating slabs. Yields good approximation to 2-D Ewald if
adequate empty space is left between repeating slabs (J. Chem. Phys.
111, 3155). Slabs defined here to be parallel to the xy plane.
------------------------------------------------------------------------- */
void Ewald::slabcorr()
{
// compute local contribution to global dipole moment
double *q = atom->q;
double **x = atom->x;
int nlocal = atom->nlocal;
double dipole = 0.0;
for (int i = 0; i < nlocal; i++) dipole += q[i]*x[i][2];
// sum local contributions to get global dipole moment
double dipole_all;
MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world);
// compute corrections
const double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
const double qscale = force->qqrd2e * scale;
if (eflag_global) energy += qscale * e_slabcorr;
// per-atom energy
if (eflag_atom) {
double efact = 2.0*MY_PI*dipole_all/volume;
for (int i = 0; i < nlocal; i++) eatom[i] += qscale * q[i]*x[i][2]*efact;
}
// add on force corrections
double ffact = -4.0*MY_PI*dipole_all/volume;
double **f = atom->f;
for (int i = 0; i < nlocal; i++) f[i][2] += qscale * q[i]*ffact;
}
/* ----------------------------------------------------------------------
memory usage of local arrays
------------------------------------------------------------------------- */
double Ewald::memory_usage()
{
double bytes = 3 * kmax3d * sizeof(int);
bytes += (1 + 3 + 6) * kmax3d * sizeof(double);
bytes += 4 * kmax3d * sizeof(double);
bytes += nmax*3 * sizeof(double);
bytes += 2 * (2*kmax+1)*3*nmax * sizeof(double);
return bytes;
}
/* ----------------------------------------------------------------------
group-group interactions
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
compute the Ewald total long-range force and energy for groups A and B
------------------------------------------------------------------------- */
void Ewald::compute_group_group(int groupbit_A, int groupbit_B, int BA_flag)
{
if (slabflag)
error->all(FLERR,"Cannot (yet) use Kspace slab correction "
"with compute group/group");
int i,k;
if (!group_allocate_flag) {
allocate_groups();
group_allocate_flag = 1;
}
e2group = 0; //energy
f2group[0] = 0; //force in x-direction
f2group[1] = 0; //force in y-direction
f2group[2] = 0; //force in z-direction
// partial and total structure factors for groups A and B
for (k = 0; k < kcount; k++) {
// group A
sfacrl_A[k] = 0;
sfacim_A[k] = 0;
sfacrl_A_all[k] = 0;
sfacim_A_all[k] = 0;
// group B
sfacrl_B[k] = 0;
sfacim_B[k] = 0;
sfacrl_B_all[k] = 0;
sfacim_B_all[k] = 0;
}
double *q = atom->q;
int nlocal = atom->nlocal;
int *mask = atom->mask;
int kx,ky,kz;
double cypz,sypz,exprl,expim;
// partial structure factors for groups A and B on each processor
for (k = 0; k < kcount; k++) {
kx = kxvecs[k];
ky = kyvecs[k];
kz = kzvecs[k];
for (i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit_A) && (mask[i] & groupbit_B))
if (BA_flag) continue;
if ((mask[i] & groupbit_A) || (mask[i] & groupbit_B)) {
cypz = cs[ky][1][i]*cs[kz][2][i] - sn[ky][1][i]*sn[kz][2][i];
sypz = sn[ky][1][i]*cs[kz][2][i] + cs[ky][1][i]*sn[kz][2][i];
exprl = cs[kx][0][i]*cypz - sn[kx][0][i]*sypz;
expim = sn[kx][0][i]*cypz + cs[kx][0][i]*sypz;
// group A
if (mask[i] & groupbit_A) {
sfacrl_A[k] += q[i]*exprl;
sfacim_A[k] += q[i]*expim;
}
// group B
if (mask[i] & groupbit_B) {
sfacrl_B[k] += q[i]*exprl;
sfacim_B[k] += q[i]*expim;
}
}
}
}
// total structure factor by summing over procs
MPI_Allreduce(sfacrl_A,sfacrl_A_all,kcount,MPI_DOUBLE,MPI_SUM,world);
MPI_Allreduce(sfacim_A,sfacim_A_all,kcount,MPI_DOUBLE,MPI_SUM,world);
MPI_Allreduce(sfacrl_B,sfacrl_B_all,kcount,MPI_DOUBLE,MPI_SUM,world);
MPI_Allreduce(sfacim_B,sfacim_B_all,kcount,MPI_DOUBLE,MPI_SUM,world);
const double qscale = force->qqrd2e * scale;
double partial_group;
// total group A <--> group B energy
// self and boundary correction terms are in compute_group_group.cpp
for (k = 0; k < kcount; k++) {
partial_group = sfacrl_A_all[k]*sfacrl_B_all[k] +
sfacim_A_all[k]*sfacim_B_all[k];
e2group += ug[k]*partial_group;
}
e2group *= qscale;
// total group A <--> group B force
for (k = 0; k < kcount; k++) {
partial_group = sfacim_A_all[k]*sfacrl_B_all[k] -
sfacrl_A_all[k]*sfacim_B_all[k];
f2group[0] += eg[k][0]*partial_group;
f2group[1] += eg[k][1]*partial_group;
f2group[2] += eg[k][2]*partial_group;
}
f2group[0] *= qscale;
f2group[1] *= qscale;
f2group[2] *= qscale;
}
/* ----------------------------------------------------------------------
allocate group-group memory that depends on # of K-vectors
------------------------------------------------------------------------- */
void Ewald::allocate_groups()
{
// group A
sfacrl_A = new double[kmax3d];
sfacim_A = new double[kmax3d];
sfacrl_A_all = new double[kmax3d];
sfacim_A_all = new double[kmax3d];
// group B
sfacrl_B = new double[kmax3d];
sfacim_B = new double[kmax3d];
sfacrl_B_all = new double[kmax3d];
sfacim_B_all = new double[kmax3d];
}
/* ----------------------------------------------------------------------
deallocate group-group memory that depends on # of K-vectors
------------------------------------------------------------------------- */
void Ewald::deallocate_groups()
{
// group A
delete [] sfacrl_A;
delete [] sfacim_A;
delete [] sfacrl_A_all;
delete [] sfacim_A_all;
// group B
delete [] sfacrl_B;
delete [] sfacim_B;
delete [] sfacrl_B_all;
delete [] sfacim_B_all;
}
diff --git a/src/KSPACE/ewald.h b/src/KSPACE/ewald.h
index 02b40494b..d57a7caae 100644
--- a/src/KSPACE/ewald.h
+++ b/src/KSPACE/ewald.h
@@ -1,122 +1,130 @@
/* -*- c++ -*- ----------------------------------------------------------
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 KSPACE_CLASS
KSpaceStyle(ewald,Ewald)
#else
#ifndef LMP_EWALD_H
#define LMP_EWALD_H
#include "kspace.h"
namespace LAMMPS_NS {
class Ewald : public KSpace {
public:
Ewald(class LAMMPS *, int, char **);
virtual ~Ewald();
void init();
void setup();
virtual void compute(int, int);
double memory_usage();
void compute_group_group(int, int, int);
protected:
int kxmax,kymax,kzmax;
int kcount,kmax,kmax3d,kmax_created;
double gsqmx,qsum,qsqsum,q2,volume;
int nmax;
double unitk[3];
int *kxvecs,*kyvecs,*kzvecs;
double *ug;
double **eg,**vg;
double **ek;
double *sfacrl,*sfacim,*sfacrl_all,*sfacim_all;
double ***cs,***sn;
// group-group interactions
int group_allocate_flag;
double *sfacrl_A,*sfacim_A,*sfacrl_A_all,*sfacim_A_all;
double *sfacrl_B,*sfacim_B,*sfacrl_B_all,*sfacim_B_all;
double rms(int, double, bigint, double);
virtual void eik_dot_r();
void coeffs();
virtual void allocate();
void deallocate();
void slabcorr();
// group-group interactions
void allocate_groups();
void deallocate_groups();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Cannot use Ewald with triclinic box
This feature is not yet supported.
E: Cannot use Ewald with 2d simulation
The kspace style ewald cannot be used in 2d simulations. You can use
2d Ewald in a 3d simulation; see the kspace_modify command.
E: Kspace style requires atom attribute q
The atom style defined does not have these attributes.
E: Cannot use nonperiodic boundaries with Ewald
For kspace style ewald, all 3 dimensions must have periodic boundaries
unless you use the kspace_modify command to define a 2d slab with a
non-periodic z dimension.
E: Incorrect boundaries with slab Ewald
Must have periodic x,y dimensions and non-periodic z dimension to use
2d slab option with Ewald.
E: KSpace style is incompatible with Pair style
Setting a kspace style requires that a pair style with a long-range
Coulombic component be selected.
E: Cannot use kspace solver on system with no charge
No atoms in system have a non-zero charge.
W: System is not charge neutral, net charge = %g
The total charge on all atoms on the system is not 0.0, which
is not valid for Ewald or PPPM.
+E: KSpace accuracy must be > 0
+
+The kspace accuracy designated in the input must be greater than zero.
+
+E: Cannot (yet) use Kspace slab correction with compute group/group
+
+This option is not yet supported.
+
*/
diff --git a/src/KSPACE/pair_lj_cut_coul_long_tip4p.h b/src/KSPACE/pair_lj_cut_coul_long_tip4p.h
index 008dd3014..b078ae75c 100644
--- a/src/KSPACE/pair_lj_cut_coul_long_tip4p.h
+++ b/src/KSPACE/pair_lj_cut_coul_long_tip4p.h
@@ -1,105 +1,110 @@
/* ----------------------------------------------------------------------
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 PAIR_CLASS
PairStyle(lj/cut/coul/long/tip4p,PairLJCutCoulLongTIP4P)
#else
#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_H
#define LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_H
#include "pair_lj_cut_coul_long.h"
namespace LAMMPS_NS {
class PairLJCutCoulLongTIP4P : public PairLJCutCoulLong {
public:
PairLJCutCoulLongTIP4P(class LAMMPS *);
~PairLJCutCoulLongTIP4P();
virtual void compute(int, int);
void settings(int, char **);
void init_style();
double init_one(int, int);
void write_restart_settings(FILE *fp);
void read_restart_settings(FILE *fp);
void *extract(const char *, int &);
double memory_usage();
protected:
int typeH,typeO; // atom types of TIP4P water H and O atoms
int typeA,typeB; // angle and bond types of TIP4P water
double alpha; // geometric constraint parameter for TIP4P
int nmax; // info on off-oxygen charge sites
int **hneigh; // 0,1 = indices of 2 H associated with O
// 2 = 0 if site loc not yet computed, 1 if yes
double **newsite; // locations of charge sites
void compute_newsite(double *, double *, double *, double *);
};
}
#endif
#endif
/* ERROR/WARNING messages:
+E: TIP4P hydrogen is missing
+
+The TIP4P pairwise computation failed to find the correct H atom
+within a water molecule.
+
+E: TIP4P hydrogen has incorrect atom type
+
+The TIP4P pairwise computation found an H atom whose type does not
+agree with the specified H type.
+
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Pair style lj/cut/coul/long/tip4p requires atom IDs
There are no atom IDs defined in the system and the TIP4P potential
requires them to find O,H atoms with a water molecule.
E: Pair style lj/cut/coul/long/tip4p requires newton pair on
This is because the computation of constraint forces within a water
molecule adds forces to atoms owned by other processors.
E: Pair style lj/cut/coul/long/tip4p requires atom attribute q
The atom style defined does not have these attributes.
E: Pair style is incompatible with KSpace style
If a pair style with a long-range Coulombic component is selected,
then a kspace style must also be used.
E: Must use a bond style with TIP4P potential
TIP4P potentials assume bond lengths in water are constrained
by a fix shake command.
E: Must use an angle style with TIP4P potential
TIP4P potentials assume angles in water are constrained by a fix shake
command.
-E: TIP4P hydrogen is missing
-
-The TIP4P pairwise computation failed to find the correct H atom
-within a water molecule.
+E: Water H epsilon must be 0.0 for pair style lj/cut/coul/long/tip4p
-E: TIP4P hydrogen has incorrect atom type
-
-The TIP4P pairwise computation found an H atom whose type does not
-agree with the specified H type.
+This is because LAMMPS does not compute the Lennard-Jones interactions
+with these particles for efficiency reasons.
*/
diff --git a/src/KSPACE/pppm.cpp b/src/KSPACE/pppm.cpp
index 560389b1f..966d3a98a 100644
--- a/src/KSPACE/pppm.cpp
+++ b/src/KSPACE/pppm.cpp
@@ -1,2836 +1,2839 @@
/* ----------------------------------------------------------------------
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: Roy Pollock (LLNL), Paul Crozier (SNL)
per-atom energy/virial & group/group energy/force added by Stan Moore (BYU)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "pppm.h"
#include "math_const.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "force.h"
#include "pair.h"
#include "bond.h"
#include "angle.h"
#include "domain.h"
#include "fft3d_wrap.h"
#include "remap_wrap.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define MAXORDER 7
#define OFFSET 16384
#define SMALL 0.00001
#define LARGE 10000.0
#define EPS_HOC 1.0e-7
#ifdef FFT_SINGLE
#define ZEROF 0.0f
#define ONEF 1.0f
#else
#define ZEROF 0.0
#define ONEF 1.0
#endif
/* ---------------------------------------------------------------------- */
PPPM::PPPM(LAMMPS *lmp, int narg, char **arg) : KSpace(lmp, narg, arg)
{
if (narg < 1) error->all(FLERR,"Illegal kspace_style pppm command");
group_group_enable = 1;
accuracy_relative = atof(arg[0]);
nfactors = 3;
factors = new int[nfactors];
factors[0] = 2;
factors[1] = 3;
factors[2] = 5;
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
density_brick = vdx_brick = vdy_brick = vdz_brick = NULL;
density_fft = NULL;
u_brick = NULL;
v0_brick = v1_brick = v2_brick = v3_brick = v4_brick = v5_brick = NULL;
greensfn = NULL;
work1 = work2 = NULL;
vg = NULL;
fkx = fky = fkz = NULL;
buf1 = buf2 = buf3 = buf4 = NULL;
density_A_brick = density_B_brick = NULL;
density_A_fft = density_B_fft = NULL;
gf_b = NULL;
rho1d = rho_coeff = NULL;
fft1 = fft2 = NULL;
remap = NULL;
nmax = 0;
part2grid = NULL;
}
/* ----------------------------------------------------------------------
free all memory
------------------------------------------------------------------------- */
PPPM::~PPPM()
{
delete [] factors;
deallocate();
deallocate_peratom();
deallocate_groups();
memory->destroy(part2grid);
}
/* ----------------------------------------------------------------------
called once before run
------------------------------------------------------------------------- */
void PPPM::init()
{
if (me == 0) {
if (screen) fprintf(screen,"PPPM initialization ...\n");
if (logfile) fprintf(logfile,"PPPM initialization ...\n");
}
// error check
if (domain->triclinic)
error->all(FLERR,"Cannot (yet) use PPPM with triclinic box");
if (domain->dimension == 2) error->all(FLERR,
"Cannot use PPPM with 2d simulation");
if (!atom->q_flag) error->all(FLERR,"Kspace style requires atom attribute q");
if (slabflag == 0 && domain->nonperiodic > 0)
error->all(FLERR,"Cannot use nonperiodic boundaries with PPPM");
if (slabflag == 1) {
if (domain->xperiodic != 1 || domain->yperiodic != 1 ||
domain->boundary[2][0] != 1 || domain->boundary[2][1] != 1)
error->all(FLERR,"Incorrect boundaries with slab PPPM");
}
if (order < 2 || order > MAXORDER) {
char str[128];
sprintf(str,"PPPM order cannot be < 2 or > than %d",MAXORDER);
error->all(FLERR,str);
}
// free all arrays previously allocated
deallocate();
deallocate_peratom();
peratom_allocate_flag = 0;
deallocate_groups();
group_allocate_flag = 0;
// extract short-range Coulombic cutoff from pair style
scale = 1.0;
if (force->pair == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
int itmp=0;
double *p_cutoff = (double *) force->pair->extract("cut_coul",itmp);
if (p_cutoff == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
cutoff = *p_cutoff;
// if kspace is TIP4P, extract TIP4P params from pair style
// bond/angle are not yet init(), so insure equilibrium request is valid
qdist = 0.0;
if ( (strcmp(force->kspace_style,"pppm/tip4p") == 0) ||
(strcmp(force->kspace_style,"pppm/tip4p/proxy") == 0) ) {
if (force->pair == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
double *p_qdist = (double *) force->pair->extract("qdist",itmp);
int *p_typeO = (int *) force->pair->extract("typeO",itmp);
int *p_typeH = (int *) force->pair->extract("typeH",itmp);
int *p_typeA = (int *) force->pair->extract("typeA",itmp);
int *p_typeB = (int *) force->pair->extract("typeB",itmp);
if (!p_qdist || !p_typeO || !p_typeH || !p_typeA || !p_typeB)
error->all(FLERR,"KSpace style is incompatible with Pair style");
qdist = *p_qdist;
typeO = *p_typeO;
typeH = *p_typeH;
int typeA = *p_typeA;
int typeB = *p_typeB;
if (force->angle == NULL || force->bond == NULL)
error->all(FLERR,"Bond and angle potentials must be defined for TIP4P");
if (typeA < 1 || typeA > atom->nangletypes ||
force->angle->setflag[typeA] == 0)
error->all(FLERR,"Bad TIP4P angle type for PPPM/TIP4P");
if (typeB < 1 || typeB > atom->nbondtypes ||
force->bond->setflag[typeB] == 0)
error->all(FLERR,"Bad TIP4P bond type for PPPM/TIP4P");
double theta = force->angle->equilibrium_angle(typeA);
double blen = force->bond->equilibrium_distance(typeB);
alpha = qdist / (cos(0.5*theta) * blen);
}
// if we have a /proxy pppm version check if the pair style is compatible
if ((strcmp(force->kspace_style,"pppm/proxy") == 0) ||
(strcmp(force->kspace_style,"pppm/tip4p/proxy") == 0) ) {
if (force->pair == NULL)
error->all(FLERR,"KSpace style is incompatible with Pair style");
if (strstr(force->pair_style,"pppm/") == NULL )
error->all(FLERR,"KSpace style is incompatible with Pair style");
}
// compute qsum & qsqsum and warn if not charge-neutral
qsum = qsqsum = 0.0;
for (int i = 0; i < atom->nlocal; i++) {
qsum += atom->q[i];
qsqsum += atom->q[i]*atom->q[i];
}
double tmp;
MPI_Allreduce(&qsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
qsum = tmp;
MPI_Allreduce(&qsqsum,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
qsqsum = tmp;
if (qsqsum == 0.0)
error->all(FLERR,"Cannot use kspace solver on system with no charge");
if (fabs(qsum) > SMALL && me == 0) {
char str[128];
sprintf(str,"System is not charge neutral, net charge = %g",qsum);
error->warning(FLERR,str);
}
// set accuracy (force units) from accuracy_relative or accuracy_absolute
if (accuracy_absolute >= 0.0) accuracy = accuracy_absolute;
else accuracy = accuracy_relative * two_charge_force;
// setup FFT grid resolution and g_ewald
// normally one iteration thru while loop is all that is required
// if grid stencil extends beyond neighbor proc, reduce order and try again
int iteration = 0;
while (order > 1) {
if (iteration && me == 0)
error->warning(FLERR,"Reducing PPPM order b/c stencil extends "
"beyond neighbor processor");
iteration++;
set_grid();
if (nx_pppm >= OFFSET || ny_pppm >= OFFSET || nz_pppm >= OFFSET)
error->all(FLERR,"PPPM grid is too large");
// global indices of PPPM grid range from 0 to N-1
// nlo_in,nhi_in = lower/upper limits of the 3d sub-brick of
// global PPPM grid that I own without ghost cells
// for slab PPPM, assign z grid as if it were not extended
nxlo_in = static_cast<int> (comm->xsplit[comm->myloc[0]] * nx_pppm);
nxhi_in = static_cast<int> (comm->xsplit[comm->myloc[0]+1] * nx_pppm) - 1;
nylo_in = static_cast<int> (comm->ysplit[comm->myloc[1]] * ny_pppm);
nyhi_in = static_cast<int> (comm->ysplit[comm->myloc[1]+1] * ny_pppm) - 1;
nzlo_in = static_cast<int>
(comm->zsplit[comm->myloc[2]] * nz_pppm/slab_volfactor);
nzhi_in = static_cast<int>
(comm->zsplit[comm->myloc[2]+1] * nz_pppm/slab_volfactor) - 1;
// nlower,nupper = stencil size for mapping particles to PPPM grid
nlower = -(order-1)/2;
nupper = order/2;
// shift values for particle <-> grid mapping
// add/subtract OFFSET to avoid int(-0.75) = 0 when want it to be -1
if (order % 2) shift = OFFSET + 0.5;
else shift = OFFSET;
if (order % 2) shiftone = 0.0;
else shiftone = 0.5;
// nlo_out,nhi_out = lower/upper limits of the 3d sub-brick of
// global PPPM grid that my particles can contribute charge to
// effectively nlo_in,nhi_in + ghost cells
// nlo,nhi = global coords of grid pt to "lower left" of smallest/largest
// position a particle in my box can be at
// dist[3] = particle position bound = subbox + skin/2.0 + qdist
// qdist = offset due to TIP4P fictitious charge
// convert to triclinic if necessary
// nlo_out,nhi_out = nlo,nhi + stencil size for particle mapping
// for slab PPPM, assign z grid as if it were not extended
triclinic = domain->triclinic;
double *prd,*sublo,*subhi;
if (triclinic == 0) {
prd = domain->prd;
boxlo = domain->boxlo;
sublo = domain->sublo;
subhi = domain->subhi;
} else {
prd = domain->prd_lamda;
boxlo = domain->boxlo_lamda;
sublo = domain->sublo_lamda;
subhi = domain->subhi_lamda;
}
double xprd = prd[0];
double yprd = prd[1];
double zprd = prd[2];
double zprd_slab = zprd*slab_volfactor;
double dist[3];
double cuthalf = 0.5*neighbor->skin + qdist;
if (triclinic == 0) dist[0] = dist[1] = dist[2] = cuthalf;
else {
dist[0] = cuthalf/domain->prd[0];
dist[1] = cuthalf/domain->prd[1];
dist[2] = cuthalf/domain->prd[2];
}
int nlo,nhi;
nlo = static_cast<int> ((sublo[0]-dist[0]-boxlo[0]) *
nx_pppm/xprd + shift) - OFFSET;
nhi = static_cast<int> ((subhi[0]+dist[0]-boxlo[0]) *
nx_pppm/xprd + shift) - OFFSET;
nxlo_out = nlo + nlower;
nxhi_out = nhi + nupper;
nlo = static_cast<int> ((sublo[1]-dist[1]-boxlo[1]) *
ny_pppm/yprd + shift) - OFFSET;
nhi = static_cast<int> ((subhi[1]+dist[1]-boxlo[1]) *
ny_pppm/yprd + shift) - OFFSET;
nylo_out = nlo + nlower;
nyhi_out = nhi + nupper;
nlo = static_cast<int> ((sublo[2]-dist[2]-boxlo[2]) *
nz_pppm/zprd_slab + shift) - OFFSET;
nhi = static_cast<int> ((subhi[2]+dist[2]-boxlo[2]) *
nz_pppm/zprd_slab + shift) - OFFSET;
nzlo_out = nlo + nlower;
nzhi_out = nhi + nupper;
// for slab PPPM, change the grid boundary for processors at +z end
// to include the empty volume between periodically repeating slabs
// for slab PPPM, want charge data communicated from -z proc to +z proc,
// but not vice versa, also want field data communicated from +z proc to
// -z proc, but not vice versa
// this is accomplished by nzhi_in = nzhi_out on +z end (no ghost cells)
if (slabflag && (comm->myloc[2] == comm->procgrid[2]-1)) {
nzhi_in = nz_pppm - 1;
nzhi_out = nz_pppm - 1;
}
// nlo_ghost,nhi_ghost = # of planes I will recv from 6 directions
// that overlay domain I own
// proc in that direction tells me via sendrecv()
// if no neighbor proc, value is from self since I have ghosts regardless
int nplanes;
MPI_Status status;
nplanes = nxlo_in - nxlo_out;
if (comm->procneigh[0][0] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[0][0],0,
&nxhi_ghost,1,MPI_INT,comm->procneigh[0][1],0,
world,&status);
else nxhi_ghost = nplanes;
nplanes = nxhi_out - nxhi_in;
if (comm->procneigh[0][1] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[0][1],0,
&nxlo_ghost,1,MPI_INT,comm->procneigh[0][0],
0,world,&status);
else nxlo_ghost = nplanes;
nplanes = nylo_in - nylo_out;
if (comm->procneigh[1][0] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[1][0],0,
&nyhi_ghost,1,MPI_INT,comm->procneigh[1][1],0,
world,&status);
else nyhi_ghost = nplanes;
nplanes = nyhi_out - nyhi_in;
if (comm->procneigh[1][1] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[1][1],0,
&nylo_ghost,1,MPI_INT,comm->procneigh[1][0],0,
world,&status);
else nylo_ghost = nplanes;
nplanes = nzlo_in - nzlo_out;
if (comm->procneigh[2][0] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[2][0],0,
&nzhi_ghost,1,MPI_INT,comm->procneigh[2][1],0,
world,&status);
else nzhi_ghost = nplanes;
nplanes = nzhi_out - nzhi_in;
if (comm->procneigh[2][1] != me)
MPI_Sendrecv(&nplanes,1,MPI_INT,comm->procneigh[2][1],0,
&nzlo_ghost,1,MPI_INT,comm->procneigh[2][0],0,
world,&status);
else nzlo_ghost = nplanes;
// test that ghost overlap is not bigger than my sub-domain
int flag = 0;
if (nxlo_ghost > nxhi_in-nxlo_in+1) flag = 1;
if (nxhi_ghost > nxhi_in-nxlo_in+1) flag = 1;
if (nylo_ghost > nyhi_in-nylo_in+1) flag = 1;
if (nyhi_ghost > nyhi_in-nylo_in+1) flag = 1;
if (nzlo_ghost > nzhi_in-nzlo_in+1) flag = 1;
if (nzhi_ghost > nzhi_in-nzlo_in+1) flag = 1;
int flag_all;
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
if (flag_all == 0) break;
order--;
}
if (order == 0) error->all(FLERR,"PPPM order has been reduced to 0");
// decomposition of FFT mesh
// global indices range from 0 to N-1
// proc owns entire x-dimension, clump of columns in y,z dimensions
// npey_fft,npez_fft = # of procs in y,z dims
// if nprocs is small enough, proc can own 1 or more entire xy planes,
// else proc owns 2d sub-blocks of yz plane
// me_y,me_z = which proc (0-npe_fft-1) I am in y,z dimensions
// nlo_fft,nhi_fft = lower/upper limit of the section
// of the global FFT mesh that I own
int npey_fft,npez_fft;
if (nz_pppm >= nprocs) {
npey_fft = 1;
npez_fft = nprocs;
} else procs2grid2d(nprocs,ny_pppm,nz_pppm,&npey_fft,&npez_fft);
int me_y = me % npey_fft;
int me_z = me / npey_fft;
nxlo_fft = 0;
nxhi_fft = nx_pppm - 1;
nylo_fft = me_y*ny_pppm/npey_fft;
nyhi_fft = (me_y+1)*ny_pppm/npey_fft - 1;
nzlo_fft = me_z*nz_pppm/npez_fft;
nzhi_fft = (me_z+1)*nz_pppm/npez_fft - 1;
// PPPM grid for this proc, including ghosts
ngrid = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) *
(nzhi_out-nzlo_out+1);
// FFT arrays on this proc, without ghosts
// nfft = FFT points in FFT decomposition on this proc
// nfft_brick = FFT points in 3d brick-decomposition on this proc
// nfft_both = greater of 2 values
nfft = (nxhi_fft-nxlo_fft+1) * (nyhi_fft-nylo_fft+1) *
(nzhi_fft-nzlo_fft+1);
int nfft_brick = (nxhi_in-nxlo_in+1) * (nyhi_in-nylo_in+1) *
(nzhi_in-nzlo_in+1);
nfft_both = MAX(nfft,nfft_brick);
// buffer space for use in brick2fft and fillbrick
// idel = max # of ghost planes to send or recv in +/- dir of each dim
// nx,ny,nz = owned planes (including ghosts) in each dim
// nxx,nyy,nzz = max # of grid cells to send in each dim
// nbuf = max in any dim, augment by 3x for components of vd_xyz in fillbrick
int idelx,idely,idelz,nx,ny,nz,nxx,nyy,nzz;
idelx = MAX(nxlo_ghost,nxhi_ghost);
idelx = MAX(idelx,nxhi_out-nxhi_in);
idelx = MAX(idelx,nxlo_in-nxlo_out);
idely = MAX(nylo_ghost,nyhi_ghost);
idely = MAX(idely,nyhi_out-nyhi_in);
idely = MAX(idely,nylo_in-nylo_out);
idelz = MAX(nzlo_ghost,nzhi_ghost);
idelz = MAX(idelz,nzhi_out-nzhi_in);
idelz = MAX(idelz,nzlo_in-nzlo_out);
nx = nxhi_out - nxlo_out + 1;
ny = nyhi_out - nylo_out + 1;
nz = nzhi_out - nzlo_out + 1;
nxx = idelx * ny * nz;
nyy = idely * nx * nz;
nzz = idelz * nx * ny;
nbuf = MAX(nxx,nyy);
nbuf = MAX(nbuf,nzz);
nbuf_peratom = 7*nbuf;
nbuf *= 3;
// print stats
int ngrid_max,nfft_both_max,nbuf_max;
MPI_Allreduce(&ngrid,&ngrid_max,1,MPI_INT,MPI_MAX,world);
MPI_Allreduce(&nfft_both,&nfft_both_max,1,MPI_INT,MPI_MAX,world);
MPI_Allreduce(&nbuf,&nbuf_max,1,MPI_INT,MPI_MAX,world);
if (me == 0) {
if (screen) fprintf(screen," brick FFT buffer size/proc = %d %d %d\n",
ngrid_max,nfft_both_max,nbuf_max);
if (logfile) fprintf(logfile," brick FFT buffer size/proc = %d %d %d\n",
ngrid_max,nfft_both_max,nbuf_max);
}
// allocate K-space dependent memory
// don't invoke allocate_peratom() here, wait to see if needed
allocate();
// pre-compute Green's function denomiator expansion
// pre-compute 1d charge distribution coefficients
compute_gf_denom();
compute_rho_coeff();
}
/* ----------------------------------------------------------------------
adjust PPPM coeffs, called initially and whenever volume has changed
------------------------------------------------------------------------- */
void PPPM::setup()
{
int i,j,k,l,m,n;
double *prd;
// volume-dependent factors
// adjust z dimension for 2d slab PPPM
// z dimension for 3d PPPM is zprd since slab_volfactor = 1.0
if (triclinic == 0) prd = domain->prd;
else prd = domain->prd_lamda;
double xprd = prd[0];
double yprd = prd[1];
double zprd = prd[2];
double zprd_slab = zprd*slab_volfactor;
volume = xprd * yprd * zprd_slab;
delxinv = nx_pppm/xprd;
delyinv = ny_pppm/yprd;
delzinv = nz_pppm/zprd_slab;
delvolinv = delxinv*delyinv*delzinv;
double unitkx = (2.0*MY_PI/xprd);
double unitky = (2.0*MY_PI/yprd);
double unitkz = (2.0*MY_PI/zprd_slab);
// fkx,fky,fkz for my FFT grid pts
double per;
for (i = nxlo_fft; i <= nxhi_fft; i++) {
per = i - nx_pppm*(2*i/nx_pppm);
fkx[i] = unitkx*per;
}
for (i = nylo_fft; i <= nyhi_fft; i++) {
per = i - ny_pppm*(2*i/ny_pppm);
fky[i] = unitky*per;
}
for (i = nzlo_fft; i <= nzhi_fft; i++) {
per = i - nz_pppm*(2*i/nz_pppm);
fkz[i] = unitkz*per;
}
// virial coefficients
double sqk,vterm;
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++) {
for (j = nylo_fft; j <= nyhi_fft; j++) {
for (i = nxlo_fft; i <= nxhi_fft; i++) {
sqk = fkx[i]*fkx[i] + fky[j]*fky[j] + fkz[k]*fkz[k];
if (sqk == 0.0) {
vg[n][0] = 0.0;
vg[n][1] = 0.0;
vg[n][2] = 0.0;
vg[n][3] = 0.0;
vg[n][4] = 0.0;
vg[n][5] = 0.0;
} else {
vterm = -2.0 * (1.0/sqk + 0.25/(g_ewald*g_ewald));
vg[n][0] = 1.0 + vterm*fkx[i]*fkx[i];
vg[n][1] = 1.0 + vterm*fky[j]*fky[j];
vg[n][2] = 1.0 + vterm*fkz[k]*fkz[k];
vg[n][3] = vterm*fkx[i]*fky[j];
vg[n][4] = vterm*fkx[i]*fkz[k];
vg[n][5] = vterm*fky[j]*fkz[k];
}
n++;
}
}
}
// modified (Hockney-Eastwood) Coulomb Green's function
int nx,ny,nz,kper,lper,mper;
double snx,sny,snz,snx2,sny2,snz2;
double argx,argy,argz,wx,wy,wz,sx,sy,sz,qx,qy,qz;
double sum1,dot1,dot2;
double numerator,denominator;
int nbx = static_cast<int> ((g_ewald*xprd/(MY_PI*nx_pppm)) *
pow(-log(EPS_HOC),0.25));
int nby = static_cast<int> ((g_ewald*yprd/(MY_PI*ny_pppm)) *
pow(-log(EPS_HOC),0.25));
int nbz = static_cast<int> ((g_ewald*zprd_slab/(MY_PI*nz_pppm)) *
pow(-log(EPS_HOC),0.25));
double form = 1.0;
n = 0;
for (m = nzlo_fft; m <= nzhi_fft; m++) {
mper = m - nz_pppm*(2*m/nz_pppm);
snz = sin(0.5*unitkz*mper*zprd_slab/nz_pppm);
snz2 = snz*snz;
for (l = nylo_fft; l <= nyhi_fft; l++) {
lper = l - ny_pppm*(2*l/ny_pppm);
sny = sin(0.5*unitky*lper*yprd/ny_pppm);
sny2 = sny*sny;
for (k = nxlo_fft; k <= nxhi_fft; k++) {
kper = k - nx_pppm*(2*k/nx_pppm);
snx = sin(0.5*unitkx*kper*xprd/nx_pppm);
snx2 = snx*snx;
sqk = pow(unitkx*kper,2.0) + pow(unitky*lper,2.0) +
pow(unitkz*mper,2.0);
if (sqk != 0.0) {
numerator = form*12.5663706/sqk;
denominator = gf_denom(snx2,sny2,snz2);
sum1 = 0.0;
const double dorder = static_cast<double>(order);
for (nx = -nbx; nx <= nbx; nx++) {
qx = unitkx*(kper+nx_pppm*nx);
sx = exp(-0.25*pow(qx/g_ewald,2.0));
wx = 1.0;
argx = 0.5*qx*xprd/nx_pppm;
if (argx != 0.0) wx = pow(sin(argx)/argx,dorder);
for (ny = -nby; ny <= nby; ny++) {
qy = unitky*(lper+ny_pppm*ny);
sy = exp(-0.25*pow(qy/g_ewald,2.0));
wy = 1.0;
argy = 0.5*qy*yprd/ny_pppm;
if (argy != 0.0) wy = pow(sin(argy)/argy,dorder);
for (nz = -nbz; nz <= nbz; nz++) {
qz = unitkz*(mper+nz_pppm*nz);
sz = exp(-0.25*pow(qz/g_ewald,2.0));
wz = 1.0;
argz = 0.5*qz*zprd_slab/nz_pppm;
if (argz != 0.0) wz = pow(sin(argz)/argz,dorder);
dot1 = unitkx*kper*qx + unitky*lper*qy + unitkz*mper*qz;
dot2 = qx*qx+qy*qy+qz*qz;
sum1 += (dot1/dot2) * sx*sy*sz * pow(wx*wy*wz,2.0);
}
}
}
greensfn[n++] = numerator*sum1/denominator;
} else greensfn[n++] = 0.0;
}
}
}
}
/* ----------------------------------------------------------------------
compute the PPPM long-range force, energy, virial
------------------------------------------------------------------------- */
void PPPM::compute(int eflag, int vflag)
{
int i,j;
// set energy/virial flags
// invoke allocate_peratom() if needed for first time
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = evflag_atom = eflag_global = vflag_global =
eflag_atom = vflag_atom = 0;
if (evflag_atom && !peratom_allocate_flag) {
allocate_peratom();
peratom_allocate_flag = 1;
}
// convert atoms from box to lamda coords
if (triclinic == 0) boxlo = domain->boxlo;
else {
boxlo = domain->boxlo_lamda;
domain->x2lamda(atom->nlocal);
}
// extend size of per-atom arrays if necessary
if (atom->nlocal > nmax) {
memory->destroy(part2grid);
nmax = atom->nmax;
memory->create(part2grid,nmax,3,"pppm:part2grid");
}
// find grid points for all my particles
// map my particle charge onto my local 3d density grid
particle_map();
make_rho();
// all procs communicate density values from their ghost cells
// to fully sum contribution in their 3d bricks
// remap from 3d decomposition to FFT decomposition
brick2fft();
// compute potential gradient on my FFT grid and
// portion of e_long on this proc's FFT grid
// return gradients (electric fields) in 3d brick decomposition
// also performs per-atom calculations via poisson_peratom()
poisson();
// all procs communicate E-field values
// to fill ghost cells surrounding their 3d bricks
fillbrick();
// extra per-atom energy/virial communication
if (evflag_atom) fillbrick_peratom();
// calculate the force on my particles
fieldforce();
// extra per-atom energy/virial communication
if (evflag_atom) fieldforce_peratom();
// sum global energy across procs and add in volume-dependent term
const double qscale = force->qqrd2e * scale;
if (eflag_global) {
double energy_all;
MPI_Allreduce(&energy,&energy_all,1,MPI_DOUBLE,MPI_SUM,world);
energy = energy_all;
energy *= 0.5*volume;
energy -= g_ewald*qsqsum/MY_PIS +
MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume);
energy *= qscale;
}
// sum global virial across procs
if (vflag_global) {
double virial_all[6];
MPI_Allreduce(virial,virial_all,6,MPI_DOUBLE,MPI_SUM,world);
for (i = 0; i < 6; i++) virial[i] = 0.5*qscale*volume*virial_all[i];
}
// per-atom energy/virial
// energy includes self-energy correction
if (evflag_atom) {
double *q = atom->q;
int nlocal = atom->nlocal;
if (eflag_atom) {
for (i = 0; i < nlocal; i++) {
eatom[i] *= 0.5;
eatom[i] -= g_ewald*q[i]*q[i]/MY_PIS + MY_PI2*q[i]*qsum /
(g_ewald*g_ewald*volume);
eatom[i] *= qscale;
}
}
if (vflag_atom) {
for (i = 0; i < nlocal; i++)
for (j = 0; j < 6; j++) vatom[i][j] *= 0.5*q[i]*qscale;
}
}
// 2d slab correction
if (slabflag) slabcorr();
// convert atoms back from lamda to box coords
if (triclinic) domain->lamda2x(atom->nlocal);
}
/* ----------------------------------------------------------------------
allocate memory that depends on # of K-vectors and order
------------------------------------------------------------------------- */
void PPPM::allocate()
{
memory->create3d_offset(density_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:density_brick");
memory->create3d_offset(vdx_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:vdx_brick");
memory->create3d_offset(vdy_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:vdy_brick");
memory->create3d_offset(vdz_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:vdz_brick");
memory->create(density_fft,nfft_both,"pppm:density_fft");
memory->create(greensfn,nfft_both,"pppm:greensfn");
memory->create(work1,2*nfft_both,"pppm:work1");
memory->create(work2,2*nfft_both,"pppm:work2");
memory->create(vg,nfft_both,6,"pppm:vg");
memory->create1d_offset(fkx,nxlo_fft,nxhi_fft,"pppm:fkx");
memory->create1d_offset(fky,nylo_fft,nyhi_fft,"pppm:fky");
memory->create1d_offset(fkz,nzlo_fft,nzhi_fft,"pppm:fkz");
memory->create(buf1,nbuf,"pppm:buf1");
memory->create(buf2,nbuf,"pppm:buf2");
// summation coeffs
memory->create(gf_b,order,"pppm:gf_b");
memory->create2d_offset(rho1d,3,-order/2,order/2,"pppm:rho1d");
memory->create2d_offset(rho_coeff,order,(1-order)/2,order/2,"pppm:rho_coeff");
// create 2 FFTs and a Remap
// 1st FFT keeps data in FFT decompostion
// 2nd FFT returns data in 3d brick decomposition
// remap takes data from 3d brick to FFT decomposition
int tmp;
fft1 = new FFT3d(lmp,world,nx_pppm,ny_pppm,nz_pppm,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
0,0,&tmp);
fft2 = new FFT3d(lmp,world,nx_pppm,ny_pppm,nz_pppm,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in,
0,0,&tmp);
remap = new Remap(lmp,world,
nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in,
nxlo_fft,nxhi_fft,nylo_fft,nyhi_fft,nzlo_fft,nzhi_fft,
1,0,0,FFT_PRECISION);
}
/* ----------------------------------------------------------------------
allocate per-atom memory that depends on # of K-vectors and order
------------------------------------------------------------------------- */
void PPPM::allocate_peratom()
{
memory->create3d_offset(u_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:u_brick");
memory->create3d_offset(v0_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:v0_brick");
memory->create3d_offset(v1_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:v1_brick");
memory->create3d_offset(v2_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:v2_brick");
memory->create3d_offset(v3_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:v3_brick");
memory->create3d_offset(v4_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:v4_brick");
memory->create3d_offset(v5_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:v5_brick");
memory->create(buf3,nbuf_peratom,"pppm:buf3");
memory->create(buf4,nbuf_peratom,"pppm:buf4");
}
/* ----------------------------------------------------------------------
deallocate memory that depends on # of K-vectors and order
------------------------------------------------------------------------- */
void PPPM::deallocate()
{
memory->destroy3d_offset(density_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(vdx_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(vdy_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(vdz_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy(density_fft);
memory->destroy(greensfn);
memory->destroy(work1);
memory->destroy(work2);
memory->destroy(vg);
memory->destroy1d_offset(fkx,nxlo_fft);
memory->destroy1d_offset(fky,nylo_fft);
memory->destroy1d_offset(fkz,nzlo_fft);
memory->destroy(buf1);
memory->destroy(buf2);
memory->destroy(gf_b);
memory->destroy2d_offset(rho1d,-order/2);
memory->destroy2d_offset(rho_coeff,(1-order)/2);
delete fft1;
delete fft2;
delete remap;
}
/* ----------------------------------------------------------------------
deallocate per-atom memory that depends on # of K-vectors and order
------------------------------------------------------------------------- */
void PPPM::deallocate_peratom()
{
memory->destroy3d_offset(u_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(v0_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(v1_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(v2_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(v3_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(v4_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(v5_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy(buf3);
memory->destroy(buf4);
}
/* ----------------------------------------------------------------------
set size of FFT grid (nx,ny,nz_pppm) and g_ewald
------------------------------------------------------------------------- */
void PPPM::set_grid()
{
// see JCP 109, pg 7698 for derivation of coefficients
// higher order coefficients may be computed if needed
double **acons;
memory->create(acons,8,7,"pppm:acons");
acons[1][0] = 2.0 / 3.0;
acons[2][0] = 1.0 / 50.0;
acons[2][1] = 5.0 / 294.0;
acons[3][0] = 1.0 / 588.0;
acons[3][1] = 7.0 / 1440.0;
acons[3][2] = 21.0 / 3872.0;
acons[4][0] = 1.0 / 4320.0;
acons[4][1] = 3.0 / 1936.0;
acons[4][2] = 7601.0 / 2271360.0;
acons[4][3] = 143.0 / 28800.0;
acons[5][0] = 1.0 / 23232.0;
acons[5][1] = 7601.0 / 13628160.0;
acons[5][2] = 143.0 / 69120.0;
acons[5][3] = 517231.0 / 106536960.0;
acons[5][4] = 106640677.0 / 11737571328.0;
acons[6][0] = 691.0 / 68140800.0;
acons[6][1] = 13.0 / 57600.0;
acons[6][2] = 47021.0 / 35512320.0;
acons[6][3] = 9694607.0 / 2095994880.0;
acons[6][4] = 733191589.0 / 59609088000.0;
acons[6][5] = 326190917.0 / 11700633600.0;
acons[7][0] = 1.0 / 345600.0;
acons[7][1] = 3617.0 / 35512320.0;
acons[7][2] = 745739.0 / 838397952.0;
acons[7][3] = 56399353.0 / 12773376000.0;
acons[7][4] = 25091609.0 / 1560084480.0;
acons[7][5] = 1755948832039.0 / 36229939200000.0;
acons[7][6] = 4887769399.0 / 37838389248.0;
double q2 = qsqsum * force->qqrd2e / force->dielectric;
// use xprd,yprd,zprd even if triclinic so grid size is the same
// adjust z dimension for 2d slab PPPM
// 3d PPPM just uses zprd since slab_volfactor = 1.0
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
double zprd_slab = zprd*slab_volfactor;
// make initial g_ewald estimate
// based on desired accuracy and real space cutoff
// fluid-occupied volume used to estimate real-space error
// zprd used rather than zprd_slab
double h_x,h_y,h_z;
bigint natoms = atom->natoms;
if (!gewaldflag) {
+ if (accuracy <= 0.0)
+ error->all(FLERR,"KSpace accuracy must be > 0");
g_ewald = accuracy*sqrt(natoms*cutoff*xprd*yprd*zprd) / (2.0*q2);
- if (g_ewald >= 1.0)
- error->all(FLERR,"KSpace accuracy too large to estimate G vector");
- g_ewald = sqrt(-log(g_ewald)) / cutoff;
+ if (g_ewald >= 1.0) g_ewald = (1.35 - 0.15*log(accuracy))/cutoff;
+ else g_ewald = sqrt(-log(g_ewald)) / cutoff;
}
// set optimal nx_pppm,ny_pppm,nz_pppm based on order and accuracy
// nz_pppm uses extended zprd_slab instead of zprd
// h = 1/g_ewald is upper bound on h such that h*g_ewald <= 1
// reduce it until accuracy target is met
if (!gridflag) {
double err;
h_x = h_y = h_z = 1.0/g_ewald;
nx_pppm = static_cast<int> (xprd/h_x) + 1;
ny_pppm = static_cast<int> (yprd/h_y) + 1;
nz_pppm = static_cast<int> (zprd_slab/h_z) + 1;
err = rms(h_x,xprd,natoms,q2,acons);
while (err > accuracy) {
err = rms(h_x,xprd,natoms,q2,acons);
nx_pppm++;
h_x = xprd/nx_pppm;
}
err = rms(h_y,yprd,natoms,q2,acons);
while (err > accuracy) {
err = rms(h_y,yprd,natoms,q2,acons);
ny_pppm++;
h_y = yprd/ny_pppm;
}
err = rms(h_z,zprd_slab,natoms,q2,acons);
while (err > accuracy) {
err = rms(h_z,zprd_slab,natoms,q2,acons);
nz_pppm++;
h_z = zprd_slab/nz_pppm;
}
}
// boost grid size until it is factorable
while (!factorable(nx_pppm)) nx_pppm++;
while (!factorable(ny_pppm)) ny_pppm++;
while (!factorable(nz_pppm)) nz_pppm++;
// adjust g_ewald for new grid size
h_x = xprd/static_cast<double>(nx_pppm);
h_y = yprd/static_cast<double>(ny_pppm);
h_z = zprd_slab/static_cast<double>(nz_pppm);
if (!gewaldflag) {
double gew1,gew2,dgew,f,fmid,hmin,rtb;
int ncount;
gew1 = 0.0;
g_ewald = gew1;
f = diffpr(h_x,h_y,h_z,q2,acons);
hmin = MIN(h_x,MIN(h_y,h_z));
gew2 = 10.0/hmin;
g_ewald = gew2;
fmid = diffpr(h_x,h_y,h_z,q2,acons);
if (f*fmid >= 0.0) error->all(FLERR,"Cannot compute PPPM G");
rtb = f < 0.0 ? (dgew=gew2-gew1,gew1) : (dgew=gew1-gew2,gew2);
ncount = 0;
while (fabs(dgew) > SMALL && fmid != 0.0) {
dgew *= 0.5;
g_ewald = rtb + dgew;
fmid = diffpr(h_x,h_y,h_z,q2,acons);
if (fmid <= 0.0) rtb = g_ewald;
ncount++;
if (ncount > LARGE) error->all(FLERR,"Cannot compute PPPM G");
}
}
// final RMS accuracy
double lprx = rms(h_x,xprd,natoms,q2,acons);
double lpry = rms(h_y,yprd,natoms,q2,acons);
double lprz = rms(h_z,zprd_slab,natoms,q2,acons);
double lpr = sqrt(lprx*lprx + lpry*lpry + lprz*lprz) / sqrt(3.0);
double spr = 2.0*q2 * exp(-g_ewald*g_ewald*cutoff*cutoff) /
sqrt(natoms*cutoff*xprd*yprd*zprd_slab);
+ double tpr = estimate_table_accuracy(spr);
+ double accuracy = sqrt(lpr*lpr + spr*spr + tpr*tpr);
// free local memory
memory->destroy(acons);
// print info
if (me == 0) {
#ifdef FFT_SINGLE
const char fft_prec[] = "single";
#else
const char fft_prec[] = "double";
#endif
if (screen) {
fprintf(screen," G vector (1/distance)= %g\n",g_ewald);
fprintf(screen," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm);
fprintf(screen," stencil order = %d\n",order);
fprintf(screen," estimated absolute RMS force accuracy = %g\n",
- MAX(lpr,spr));
+ accuracy);
fprintf(screen," estimated relative force accuracy = %g\n",
- MAX(lpr,spr)/two_charge_force);
+ accuracy/two_charge_force);
fprintf(screen," using %s precision FFTs\n",fft_prec);
}
if (logfile) {
fprintf(logfile," G vector (1/distance) = %g\n",g_ewald);
fprintf(logfile," grid = %d %d %d\n",nx_pppm,ny_pppm,nz_pppm);
fprintf(logfile," stencil order = %d\n",order);
fprintf(logfile," estimated absolute RMS force accuracy = %g\n",
- MAX(lpr,spr));
+ accuracy);
fprintf(logfile," estimated relative force accuracy = %g\n",
- MAX(lpr,spr)/two_charge_force);
+ accuracy/two_charge_force);
fprintf(logfile," using %s precision FFTs\n",fft_prec);
}
}
}
/* ----------------------------------------------------------------------
check if all factors of n are in list of factors
return 1 if yes, 0 if no
------------------------------------------------------------------------- */
int PPPM::factorable(int n)
{
int i;
while (n > 1) {
for (i = 0; i < nfactors; i++) {
if (n % factors[i] == 0) {
n /= factors[i];
break;
}
}
if (i == nfactors) return 0;
}
return 1;
}
/* ----------------------------------------------------------------------
compute RMS accuracy for a dimension
------------------------------------------------------------------------- */
double PPPM::rms(double h, double prd, bigint natoms,
double q2, double **acons)
{
double sum = 0.0;
for (int m = 0; m < order; m++)
sum += acons[order][m] * pow(h*g_ewald,2.0*m);
double value = q2 * pow(h*g_ewald,(double)order) *
sqrt(g_ewald*prd*sqrt(2.0*MY_PI)*sum/natoms) / (prd*prd);
return value;
}
/* ----------------------------------------------------------------------
compute difference in real-space and KSpace RMS accuracy
------------------------------------------------------------------------- */
double PPPM::diffpr(double h_x, double h_y, double h_z, double q2,
double **acons)
{
double lprx,lpry,lprz,kspace_prec,real_prec;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
bigint natoms = atom->natoms;
lprx = rms(h_x,xprd,natoms,q2,acons);
lpry = rms(h_y,yprd,natoms,q2,acons);
lprz = rms(h_z,zprd*slab_volfactor,natoms,q2,acons);
kspace_prec = sqrt(lprx*lprx + lpry*lpry + lprz*lprz) / sqrt(3.0);
real_prec = 2.0*q2 * exp(-g_ewald*g_ewald*cutoff*cutoff) /
sqrt(static_cast<double>(natoms)*cutoff*xprd*yprd*zprd);
double value = kspace_prec - real_prec;
return value;
}
/* ----------------------------------------------------------------------
pre-compute Green's function denominator expansion coeffs, Gamma(2n)
------------------------------------------------------------------------- */
void PPPM::compute_gf_denom()
{
int k,l,m;
for (l = 1; l < order; l++) gf_b[l] = 0.0;
gf_b[0] = 1.0;
for (m = 1; m < order; m++) {
for (l = m; l > 0; l--)
gf_b[l] = 4.0 * (gf_b[l]*(l-m)*(l-m-0.5)-gf_b[l-1]*(l-m-1)*(l-m-1));
gf_b[0] = 4.0 * (gf_b[0]*(l-m)*(l-m-0.5));
}
int ifact = 1;
for (k = 1; k < 2*order; k++) ifact *= k;
double gaminv = 1.0/ifact;
for (l = 0; l < order; l++) gf_b[l] *= gaminv;
}
/* ----------------------------------------------------------------------
ghost-swap to accumulate full density in brick decomposition
remap density from 3d brick decomposition to FFT decomposition
------------------------------------------------------------------------- */
void PPPM::brick2fft()
{
int i,n,ix,iy,iz;
MPI_Request request;
MPI_Status status;
// pack my ghosts for +x processor
// pass data to self or +x processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in+1; ix <= nxhi_out; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[0][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix < nxlo_in+nxlo_ghost; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// pack my ghosts for -x processor
// pass data to self or -x processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_out; ix < nxlo_in; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[0][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in-nxhi_ghost+1; ix <= nxhi_in; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// pack my ghosts for +y processor
// pass data to self or +y processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in+1; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[1][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy < nylo_in+nylo_ghost; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// pack my ghosts for -y processor
// pass data to self or -y processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy < nylo_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[1][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in-nyhi_ghost+1; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// pack my ghosts for +z processor
// pass data to self or +z processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzhi_in+1; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[2][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_in; iz < nzlo_in+nzlo_ghost; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// pack my ghosts for -z processor
// pass data to self or -z processor
// unpack and sum recv data into my real cells
n = 0;
for (iz = nzlo_out; iz < nzlo_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
buf1[n++] = density_brick[iz][iy][ix];
if (comm->procneigh[2][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzhi_in-nzhi_ghost+1; iz <= nzhi_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_brick[iz][iy][ix] += buf2[n++];
// remap from 3d brick decomposition to FFT decomposition
// copy grabs inner portion of density from 3d brick
// remap could be done as pre-stage of FFT,
// but this works optimally on only double values, not complex values
n = 0;
for (iz = nzlo_in; iz <= nzhi_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++)
density_fft[n++] = density_brick[iz][iy][ix];
remap->perform(density_fft,density_fft,work1);
}
/* ----------------------------------------------------------------------
ghost-swap to fill ghost cells of my brick with field values
------------------------------------------------------------------------- */
void PPPM::fillbrick()
{
int i,n,ix,iy,iz;
MPI_Request request;
MPI_Status status;
// pack my real cells for +z processor
// pass data to self or +z processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzhi_in-nzhi_ghost+1; iz <= nzhi_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[2][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz < nzlo_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
// pack my real cells for -z processor
// pass data to self or -z processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_in; iz < nzlo_in+nzlo_ghost; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[2][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzhi_in+1; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
// pack my real cells for +y processor
// pass data to self or +y processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in-nyhi_ghost+1; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[1][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy < nylo_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
// pack my real cells for -y processor
// pass data to self or -y processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy < nylo_in+nylo_ghost; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[1][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in+1; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
// pack my real cells for +x processor
// pass data to self or +x processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in-nxhi_ghost+1; ix <= nxhi_in; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[0][1] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_out; ix < nxlo_in; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
// pack my real cells for -x processor
// pass data to self or -x processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix < nxlo_in+nxlo_ghost; ix++) {
buf1[n++] = vdx_brick[iz][iy][ix];
buf1[n++] = vdy_brick[iz][iy][ix];
buf1[n++] = vdz_brick[iz][iy][ix];
}
if (comm->procneigh[0][0] == me)
for (i = 0; i < n; i++) buf2[i] = buf1[i];
else {
MPI_Irecv(buf2,nbuf,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world,&request);
MPI_Send(buf1,n,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in+1; ix <= nxhi_out; ix++) {
vdx_brick[iz][iy][ix] = buf2[n++];
vdy_brick[iz][iy][ix] = buf2[n++];
vdz_brick[iz][iy][ix] = buf2[n++];
}
}
/* ----------------------------------------------------------------------
ghost-swap to fill ghost cells of my brick with per-atom field values
------------------------------------------------------------------------- */
void PPPM::fillbrick_peratom()
{
int i,n,ix,iy,iz;
MPI_Request request;
MPI_Status status;
// pack my real cells for +z processor
// pass data to self or +z processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzhi_in-nzhi_ghost+1; iz <= nzhi_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
if (eflag_atom) buf3[n++] = u_brick[iz][iy][ix];
if (vflag_atom) {
buf3[n++] = v0_brick[iz][iy][ix];
buf3[n++] = v1_brick[iz][iy][ix];
buf3[n++] = v2_brick[iz][iy][ix];
buf3[n++] = v3_brick[iz][iy][ix];
buf3[n++] = v4_brick[iz][iy][ix];
buf3[n++] = v5_brick[iz][iy][ix];
}
}
if (comm->procneigh[2][1] == me)
for (i = 0; i < n; i++) buf4[i] = buf3[i];
else {
MPI_Irecv(buf4,nbuf_peratom,MPI_FFT_SCALAR,
comm->procneigh[2][0],0,world,&request);
MPI_Send(buf3,n,MPI_FFT_SCALAR,comm->procneigh[2][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz < nzlo_in; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
if (eflag_atom) u_brick[iz][iy][ix] = buf4[n++];
if (vflag_atom) {
v0_brick[iz][iy][ix] = buf4[n++];
v1_brick[iz][iy][ix] = buf4[n++];
v2_brick[iz][iy][ix] = buf4[n++];
v3_brick[iz][iy][ix] = buf4[n++];
v4_brick[iz][iy][ix] = buf4[n++];
v5_brick[iz][iy][ix] = buf4[n++];
}
}
// pack my real cells for -z processor
// pass data to self or -z processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_in; iz < nzlo_in+nzlo_ghost; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
if (eflag_atom) buf3[n++] = u_brick[iz][iy][ix];
if (vflag_atom) {
buf3[n++] = v0_brick[iz][iy][ix];
buf3[n++] = v1_brick[iz][iy][ix];
buf3[n++] = v2_brick[iz][iy][ix];
buf3[n++] = v3_brick[iz][iy][ix];
buf3[n++] = v4_brick[iz][iy][ix];
buf3[n++] = v5_brick[iz][iy][ix];
}
}
if (comm->procneigh[2][0] == me)
for (i = 0; i < n; i++) buf4[i] = buf3[i];
else {
MPI_Irecv(buf4,nbuf_peratom,MPI_FFT_SCALAR,
comm->procneigh[2][1],0,world,&request);
MPI_Send(buf3,n,MPI_FFT_SCALAR,comm->procneigh[2][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzhi_in+1; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
if (eflag_atom) u_brick[iz][iy][ix] = buf4[n++];
if (vflag_atom) {
v0_brick[iz][iy][ix] = buf4[n++];
v1_brick[iz][iy][ix] = buf4[n++];
v2_brick[iz][iy][ix] = buf4[n++];
v3_brick[iz][iy][ix] = buf4[n++];
v4_brick[iz][iy][ix] = buf4[n++];
v5_brick[iz][iy][ix] = buf4[n++];
}
}
// pack my real cells for +y processor
// pass data to self or +y processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in-nyhi_ghost+1; iy <= nyhi_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
if (eflag_atom) buf3[n++] = u_brick[iz][iy][ix];
if (vflag_atom) {
buf3[n++] = v0_brick[iz][iy][ix];
buf3[n++] = v1_brick[iz][iy][ix];
buf3[n++] = v2_brick[iz][iy][ix];
buf3[n++] = v3_brick[iz][iy][ix];
buf3[n++] = v4_brick[iz][iy][ix];
buf3[n++] = v5_brick[iz][iy][ix];
}
}
if (comm->procneigh[1][1] == me)
for (i = 0; i < n; i++) buf4[i] = buf3[i];
else {
MPI_Irecv(buf4,nbuf_peratom,MPI_FFT_SCALAR,
comm->procneigh[1][0],0,world,&request);
MPI_Send(buf3,n,MPI_FFT_SCALAR,comm->procneigh[1][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy < nylo_in; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
if (eflag_atom) u_brick[iz][iy][ix] = buf4[n++];
if (vflag_atom) {
v0_brick[iz][iy][ix] = buf4[n++];
v1_brick[iz][iy][ix] = buf4[n++];
v2_brick[iz][iy][ix] = buf4[n++];
v3_brick[iz][iy][ix] = buf4[n++];
v4_brick[iz][iy][ix] = buf4[n++];
v5_brick[iz][iy][ix] = buf4[n++];
}
}
// pack my real cells for -y processor
// pass data to self or -y processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_in; iy < nylo_in+nylo_ghost; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
if (eflag_atom) buf3[n++] = u_brick[iz][iy][ix];
if (vflag_atom) {
buf3[n++] = v0_brick[iz][iy][ix];
buf3[n++] = v1_brick[iz][iy][ix];
buf3[n++] = v2_brick[iz][iy][ix];
buf3[n++] = v3_brick[iz][iy][ix];
buf3[n++] = v4_brick[iz][iy][ix];
buf3[n++] = v5_brick[iz][iy][ix];
}
}
if (comm->procneigh[1][0] == me)
for (i = 0; i < n; i++) buf4[i] = buf3[i];
else {
MPI_Irecv(buf4,nbuf_peratom,MPI_FFT_SCALAR,
comm->procneigh[1][1],0,world,&request);
MPI_Send(buf3,n,MPI_FFT_SCALAR,comm->procneigh[1][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nyhi_in+1; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix <= nxhi_in; ix++) {
if (eflag_atom) u_brick[iz][iy][ix] = buf4[n++];
if (vflag_atom) {
v0_brick[iz][iy][ix] = buf4[n++];
v1_brick[iz][iy][ix] = buf4[n++];
v2_brick[iz][iy][ix] = buf4[n++];
v3_brick[iz][iy][ix] = buf4[n++];
v4_brick[iz][iy][ix] = buf4[n++];
v5_brick[iz][iy][ix] = buf4[n++];
}
}
// pack my real cells for +x processor
// pass data to self or +x processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in-nxhi_ghost+1; ix <= nxhi_in; ix++) {
if (eflag_atom) buf3[n++] = u_brick[iz][iy][ix];
if (vflag_atom) {
buf3[n++] = v0_brick[iz][iy][ix];
buf3[n++] = v1_brick[iz][iy][ix];
buf3[n++] = v2_brick[iz][iy][ix];
buf3[n++] = v3_brick[iz][iy][ix];
buf3[n++] = v4_brick[iz][iy][ix];
buf3[n++] = v5_brick[iz][iy][ix];
}
}
if (comm->procneigh[0][1] == me)
for (i = 0; i < n; i++) buf4[i] = buf3[i];
else {
MPI_Irecv(buf4,nbuf_peratom,MPI_FFT_SCALAR,
comm->procneigh[0][0],0,world,&request);
MPI_Send(buf3,n,MPI_FFT_SCALAR,comm->procneigh[0][1],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_out; ix < nxlo_in; ix++) {
if (eflag_atom) u_brick[iz][iy][ix] = buf4[n++];
if (vflag_atom) {
v0_brick[iz][iy][ix] = buf4[n++];
v1_brick[iz][iy][ix] = buf4[n++];
v2_brick[iz][iy][ix] = buf4[n++];
v3_brick[iz][iy][ix] = buf4[n++];
v4_brick[iz][iy][ix] = buf4[n++];
v5_brick[iz][iy][ix] = buf4[n++];
}
}
// pack my real cells for -x processor
// pass data to self or -x processor
// unpack and sum recv data into my ghost cells
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxlo_in; ix < nxlo_in+nxlo_ghost; ix++) {
if (eflag_atom) buf3[n++] = u_brick[iz][iy][ix];
if (vflag_atom) {
buf3[n++] = v0_brick[iz][iy][ix];
buf3[n++] = v1_brick[iz][iy][ix];
buf3[n++] = v2_brick[iz][iy][ix];
buf3[n++] = v3_brick[iz][iy][ix];
buf3[n++] = v4_brick[iz][iy][ix];
buf3[n++] = v5_brick[iz][iy][ix];
}
}
if (comm->procneigh[0][0] == me)
for (i = 0; i < n; i++) buf4[i] = buf3[i];
else {
MPI_Irecv(buf4,nbuf_peratom,MPI_FFT_SCALAR,
comm->procneigh[0][1],0,world,&request);
MPI_Send(buf3,n,MPI_FFT_SCALAR,comm->procneigh[0][0],0,world);
MPI_Wait(&request,&status);
}
n = 0;
for (iz = nzlo_out; iz <= nzhi_out; iz++)
for (iy = nylo_out; iy <= nyhi_out; iy++)
for (ix = nxhi_in+1; ix <= nxhi_out; ix++) {
if (eflag_atom) u_brick[iz][iy][ix] = buf4[n++];
if (vflag_atom) {
v0_brick[iz][iy][ix] = buf4[n++];
v1_brick[iz][iy][ix] = buf4[n++];
v2_brick[iz][iy][ix] = buf4[n++];
v3_brick[iz][iy][ix] = buf4[n++];
v4_brick[iz][iy][ix] = buf4[n++];
v5_brick[iz][iy][ix] = buf4[n++];
}
}
}
/* ----------------------------------------------------------------------
find center grid pt for each of my particles
check that full stencil for the particle will fit in my 3d brick
store central grid pt indices in part2grid array
------------------------------------------------------------------------- */
void PPPM::particle_map()
{
int nx,ny,nz;
double **x = atom->x;
int nlocal = atom->nlocal;
int flag = 0;
for (int i = 0; i < nlocal; i++) {
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// current particle coord can be outside global and local box
// add/subtract OFFSET to avoid int(-0.75) = 0 when want it to be -1
nx = static_cast<int> ((x[i][0]-boxlo[0])*delxinv+shift) - OFFSET;
ny = static_cast<int> ((x[i][1]-boxlo[1])*delyinv+shift) - OFFSET;
nz = static_cast<int> ((x[i][2]-boxlo[2])*delzinv+shift) - OFFSET;
part2grid[i][0] = nx;
part2grid[i][1] = ny;
part2grid[i][2] = nz;
// check that entire stencil around nx,ny,nz will fit in my 3d brick
if (nx+nlower < nxlo_out || nx+nupper > nxhi_out ||
ny+nlower < nylo_out || ny+nupper > nyhi_out ||
nz+nlower < nzlo_out || nz+nupper > nzhi_out)
flag = 1;
}
if (flag) error->one(FLERR,"Out of range atoms - cannot compute PPPM");
}
/* ----------------------------------------------------------------------
create discretized "density" on section of global grid due to my particles
density(x,y,z) = charge "density" at grid points of my 3d brick
(nxlo:nxhi,nylo:nyhi,nzlo:nzhi) is extent of my brick (including ghosts)
in global grid
------------------------------------------------------------------------- */
void PPPM::make_rho()
{
int l,m,n,nx,ny,nz,mx,my,mz;
FFT_SCALAR dx,dy,dz,x0,y0,z0;
// clear 3d density array
memset(&(density_brick[nzlo_out][nylo_out][nxlo_out]),0,
ngrid*sizeof(FFT_SCALAR));
// loop over my charges, add their contribution to nearby grid points
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// (dx,dy,dz) = distance to "lower left" grid pt
// (mx,my,mz) = global coords of moving stencil pt
double *q = atom->q;
double **x = atom->x;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
nx = part2grid[i][0];
ny = part2grid[i][1];
nz = part2grid[i][2];
dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv;
dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv;
dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv;
compute_rho1d(dx,dy,dz);
z0 = delvolinv * q[i];
for (n = nlower; n <= nupper; n++) {
mz = n+nz;
y0 = z0*rho1d[2][n];
for (m = nlower; m <= nupper; m++) {
my = m+ny;
x0 = y0*rho1d[1][m];
for (l = nlower; l <= nupper; l++) {
mx = l+nx;
density_brick[mz][my][mx] += x0*rho1d[0][l];
}
}
}
}
}
/* ----------------------------------------------------------------------
FFT-based Poisson solver
------------------------------------------------------------------------- */
void PPPM::poisson()
{
int i,j,k,n;
double eng;
// transform charge density (r -> k)
n = 0;
for (i = 0; i < nfft; i++) {
work1[n++] = density_fft[i];
work1[n++] = ZEROF;
}
fft1->compute(work1,work1,1);
// global energy and virial contribution
double scaleinv = 1.0/(nx_pppm*ny_pppm*nz_pppm);
double s2 = scaleinv*scaleinv;
if (eflag_global || vflag_global) {
if (vflag_global) {
n = 0;
for (i = 0; i < nfft; i++) {
eng = s2 * greensfn[i] * (work1[n]*work1[n] + work1[n+1]*work1[n+1]);
for (j = 0; j < 6; j++) virial[j] += eng*vg[i][j];
if (eflag_global) energy += eng;
n += 2;
}
} else {
n = 0;
for (i = 0; i < nfft; i++) {
energy +=
s2 * greensfn[i] * (work1[n]*work1[n] + work1[n+1]*work1[n+1]);
n += 2;
}
}
}
// scale by 1/total-grid-pts to get rho(k)
// multiply by Green's function to get V(k)
n = 0;
for (i = 0; i < nfft; i++) {
work1[n++] *= scaleinv * greensfn[i];
work1[n++] *= scaleinv * greensfn[i];
}
// extra FFTs for per-atom energy/virial
if (evflag_atom) poisson_peratom();
// compute gradients of V(r) in each of 3 dims by transformimg -ik*V(k)
// FFT leaves data in 3d brick decomposition
// copy it into inner portion of vdx,vdy,vdz arrays
// x direction gradient
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
work2[n] = fkx[i]*work1[n+1];
work2[n+1] = -fkx[i]*work1[n];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
vdx_brick[k][j][i] = work2[n];
n += 2;
}
// y direction gradient
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
work2[n] = fky[j]*work1[n+1];
work2[n+1] = -fky[j]*work1[n];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
vdy_brick[k][j][i] = work2[n];
n += 2;
}
// z direction gradient
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
work2[n] = fkz[k]*work1[n+1];
work2[n+1] = -fkz[k]*work1[n];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
vdz_brick[k][j][i] = work2[n];
n += 2;
}
}
/* ----------------------------------------------------------------------
FFT-based Poisson solver for per-atom energy/virial
------------------------------------------------------------------------- */
void PPPM::poisson_peratom()
{
int i,j,k,n;
// energy
if (eflag_atom) {
n = 0;
for (i = 0; i < nfft; i++) {
work2[n] = work1[n];
work2[n+1] = work1[n+1];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
u_brick[k][j][i] = work2[n];
n += 2;
}
}
// 6 components of virial in v0 thru v5
if (!vflag_atom) return;
n = 0;
for (i = 0; i < nfft; i++) {
work2[n] = work1[n]*vg[i][0];
work2[n+1] = work1[n+1]*vg[i][0];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
v0_brick[k][j][i] = work2[n];
n += 2;
}
n = 0;
for (i = 0; i < nfft; i++) {
work2[n] = work1[n]*vg[i][1];
work2[n+1] = work1[n+1]*vg[i][1];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
v1_brick[k][j][i] = work2[n];
n += 2;
}
n = 0;
for (i = 0; i < nfft; i++) {
work2[n] = work1[n]*vg[i][2];
work2[n+1] = work1[n+1]*vg[i][2];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
v2_brick[k][j][i] = work2[n];
n += 2;
}
n = 0;
for (i = 0; i < nfft; i++) {
work2[n] = work1[n]*vg[i][3];
work2[n+1] = work1[n+1]*vg[i][3];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
v3_brick[k][j][i] = work2[n];
n += 2;
}
n = 0;
for (i = 0; i < nfft; i++) {
work2[n] = work1[n]*vg[i][4];
work2[n+1] = work1[n+1]*vg[i][4];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
v4_brick[k][j][i] = work2[n];
n += 2;
}
n = 0;
for (i = 0; i < nfft; i++) {
work2[n] = work1[n]*vg[i][5];
work2[n+1] = work1[n+1]*vg[i][5];
n += 2;
}
fft2->compute(work2,work2,-1);
n = 0;
for (k = nzlo_in; k <= nzhi_in; k++)
for (j = nylo_in; j <= nyhi_in; j++)
for (i = nxlo_in; i <= nxhi_in; i++) {
v5_brick[k][j][i] = work2[n];
n += 2;
}
}
/* ----------------------------------------------------------------------
interpolate from grid to get electric field & force on my particles
------------------------------------------------------------------------- */
void PPPM::fieldforce()
{
int i,l,m,n,nx,ny,nz,mx,my,mz;
FFT_SCALAR dx,dy,dz,x0,y0,z0;
FFT_SCALAR ekx,eky,ekz;
// loop over my charges, interpolate electric field from nearby grid points
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// (dx,dy,dz) = distance to "lower left" grid pt
// (mx,my,mz) = global coords of moving stencil pt
// ek = 3 components of E-field on particle
double *q = atom->q;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++) {
nx = part2grid[i][0];
ny = part2grid[i][1];
nz = part2grid[i][2];
dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv;
dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv;
dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv;
compute_rho1d(dx,dy,dz);
ekx = eky = ekz = ZEROF;
for (n = nlower; n <= nupper; n++) {
mz = n+nz;
z0 = rho1d[2][n];
for (m = nlower; m <= nupper; m++) {
my = m+ny;
y0 = z0*rho1d[1][m];
for (l = nlower; l <= nupper; l++) {
mx = l+nx;
x0 = y0*rho1d[0][l];
ekx -= x0*vdx_brick[mz][my][mx];
eky -= x0*vdy_brick[mz][my][mx];
ekz -= x0*vdz_brick[mz][my][mx];
}
}
}
// convert E-field to force
const double qfactor = force->qqrd2e * scale * q[i];
f[i][0] += qfactor*ekx;
f[i][1] += qfactor*eky;
f[i][2] += qfactor*ekz;
}
}
/* ----------------------------------------------------------------------
interpolate from grid to get per-atom energy/virial
------------------------------------------------------------------------- */
void PPPM::fieldforce_peratom()
{
int i,l,m,n,nx,ny,nz,mx,my,mz;
FFT_SCALAR dx,dy,dz,x0,y0,z0;
FFT_SCALAR u,v0,v1,v2,v3,v4,v5;
// loop over my charges, interpolate from nearby grid points
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// (dx,dy,dz) = distance to "lower left" grid pt
// (mx,my,mz) = global coords of moving stencil pt
double *q = atom->q;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++) {
nx = part2grid[i][0];
ny = part2grid[i][1];
nz = part2grid[i][2];
dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv;
dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv;
dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv;
compute_rho1d(dx,dy,dz);
u = v0 = v1 = v2 = v3 = v4 = v5 = ZEROF;
for (n = nlower; n <= nupper; n++) {
mz = n+nz;
z0 = rho1d[2][n];
for (m = nlower; m <= nupper; m++) {
my = m+ny;
y0 = z0*rho1d[1][m];
for (l = nlower; l <= nupper; l++) {
mx = l+nx;
x0 = y0*rho1d[0][l];
if (eflag_atom) u += x0*u_brick[mz][my][mx];
if (vflag_atom) {
v0 += x0*v0_brick[mz][my][mx];
v1 += x0*v1_brick[mz][my][mx];
v2 += x0*v2_brick[mz][my][mx];
v3 += x0*v3_brick[mz][my][mx];
v4 += x0*v4_brick[mz][my][mx];
v5 += x0*v5_brick[mz][my][mx];
}
}
}
}
if (eflag_atom) eatom[i] += q[i]*u;
if (vflag_atom) {
vatom[i][0] += v0;
vatom[i][1] += v1;
vatom[i][2] += v2;
vatom[i][3] += v3;
vatom[i][4] += v4;
vatom[i][5] += v5;
}
}
}
/* ----------------------------------------------------------------------
map nprocs to NX by NY grid as PX by PY procs - return optimal px,py
------------------------------------------------------------------------- */
void PPPM::procs2grid2d(int nprocs, int nx, int ny, int *px, int *py)
{
// loop thru all possible factorizations of nprocs
// surf = surface area of largest proc sub-domain
// innermost if test minimizes surface area and surface/volume ratio
int bestsurf = 2 * (nx + ny);
int bestboxx = 0;
int bestboxy = 0;
int boxx,boxy,surf,ipx,ipy;
ipx = 1;
while (ipx <= nprocs) {
if (nprocs % ipx == 0) {
ipy = nprocs/ipx;
boxx = nx/ipx;
if (nx % ipx) boxx++;
boxy = ny/ipy;
if (ny % ipy) boxy++;
surf = boxx + boxy;
if (surf < bestsurf ||
(surf == bestsurf && boxx*boxy > bestboxx*bestboxy)) {
bestsurf = surf;
bestboxx = boxx;
bestboxy = boxy;
*px = ipx;
*py = ipy;
}
}
ipx++;
}
}
/* ----------------------------------------------------------------------
charge assignment into rho1d
dx,dy,dz = distance of particle from "lower left" grid point
------------------------------------------------------------------------- */
void PPPM::compute_rho1d(const FFT_SCALAR &dx, const FFT_SCALAR &dy,
const FFT_SCALAR &dz)
{
int k,l;
FFT_SCALAR r1,r2,r3;
for (k = (1-order)/2; k <= order/2; k++) {
r1 = r2 = r3 = ZEROF;
for (l = order-1; l >= 0; l--) {
r1 = rho_coeff[l][k] + r1*dx;
r2 = rho_coeff[l][k] + r2*dy;
r3 = rho_coeff[l][k] + r3*dz;
}
rho1d[0][k] = r1;
rho1d[1][k] = r2;
rho1d[2][k] = r3;
}
}
/* ----------------------------------------------------------------------
generate coeffients for the weight function of order n
(n-1)
Wn(x) = Sum wn(k,x) , Sum is over every other integer
k=-(n-1)
For k=-(n-1),-(n-1)+2, ....., (n-1)-2,n-1
k is odd integers if n is even and even integers if n is odd
---
| n-1
| Sum a(l,j)*(x-k/2)**l if abs(x-k/2) < 1/2
wn(k,x) = < l=0
|
| 0 otherwise
---
a coeffients are packed into the array rho_coeff to eliminate zeros
rho_coeff(l,((k+mod(n+1,2))/2) = a(l,k)
------------------------------------------------------------------------- */
void PPPM::compute_rho_coeff()
{
int j,k,l,m;
FFT_SCALAR s;
FFT_SCALAR **a;
memory->create2d_offset(a,order,-order,order,"pppm:a");
for (k = -order; k <= order; k++)
for (l = 0; l < order; l++)
a[l][k] = 0.0;
a[0][0] = 1.0;
for (j = 1; j < order; j++) {
for (k = -j; k <= j; k += 2) {
s = 0.0;
for (l = 0; l < j; l++) {
a[l+1][k] = (a[l][k+1]-a[l][k-1]) / (l+1);
#ifdef FFT_SINGLE
s += powf(0.5,(float) l+1) *
(a[l][k-1] + powf(-1.0,(float) l) * a[l][k+1]) / (l+1);
#else
s += pow(0.5,(double) l+1) *
(a[l][k-1] + pow(-1.0,(double) l) * a[l][k+1]) / (l+1);
#endif
}
a[0][k] = s;
}
}
m = (1-order)/2;
for (k = -(order-1); k < order; k += 2) {
for (l = 0; l < order; l++)
rho_coeff[l][m] = a[l][k];
m++;
}
memory->destroy2d_offset(a,-order);
}
/* ----------------------------------------------------------------------
Slab-geometry correction term to dampen inter-slab interactions between
periodically repeating slabs. Yields good approximation to 2D Ewald if
adequate empty space is left between repeating slabs (J. Chem. Phys.
111, 3155). Slabs defined here to be parallel to the xy plane.
------------------------------------------------------------------------- */
void PPPM::slabcorr()
{
// compute local contribution to global dipole moment
double *q = atom->q;
double **x = atom->x;
int nlocal = atom->nlocal;
double dipole = 0.0;
for (int i = 0; i < nlocal; i++) dipole += q[i]*x[i][2];
// sum local contributions to get global dipole moment
double dipole_all;
MPI_Allreduce(&dipole,&dipole_all,1,MPI_DOUBLE,MPI_SUM,world);
// compute corrections
const double e_slabcorr = 2.0*MY_PI*dipole_all*dipole_all/volume;
const double qscale = force->qqrd2e * scale;
if (eflag_global) energy += qscale * e_slabcorr;
// per-atom energy
if (eflag_atom) {
double efact = 2.0*MY_PI*dipole_all/volume;
for (int i = 0; i < nlocal; i++) eatom[i] += qscale * q[i]*x[i][2]*efact;
}
// add on force corrections
double ffact = -4.0*MY_PI*dipole_all/volume;
double **f = atom->f;
for (int i = 0; i < nlocal; i++) f[i][2] += qscale * q[i]*ffact;
}
/* ----------------------------------------------------------------------
perform and time the 4 FFTs required for N timesteps
------------------------------------------------------------------------- */
void PPPM::timing(int n, double &time3d, double &time1d)
{
double time1,time2;
for (int i = 0; i < 2*nfft_both; i++) work1[i] = ZEROF;
MPI_Barrier(world);
time1 = MPI_Wtime();
for (int i = 0; i < n; i++) {
fft1->compute(work1,work1,1);
fft2->compute(work1,work1,-1);
fft2->compute(work1,work1,-1);
fft2->compute(work1,work1,-1);
}
MPI_Barrier(world);
time2 = MPI_Wtime();
time3d = time2 - time1;
MPI_Barrier(world);
time1 = MPI_Wtime();
for (int i = 0; i < n; i++) {
fft1->timing1d(work1,nfft_both,1);
fft2->timing1d(work1,nfft_both,-1);
fft2->timing1d(work1,nfft_both,-1);
fft2->timing1d(work1,nfft_both,-1);
}
MPI_Barrier(world);
time2 = MPI_Wtime();
time1d = time2 - time1;
}
/* ----------------------------------------------------------------------
memory usage of local arrays
------------------------------------------------------------------------- */
double PPPM::memory_usage()
{
double bytes = nmax*3 * sizeof(double);
int nbrick = (nxhi_out-nxlo_out+1) * (nyhi_out-nylo_out+1) *
(nzhi_out-nzlo_out+1);
bytes += 4 * nbrick * sizeof(FFT_SCALAR);
bytes += 6 * nfft_both * sizeof(double);
bytes += nfft_both * sizeof(double);
bytes += nfft_both*5 * sizeof(FFT_SCALAR);
bytes += 2 * nbuf * sizeof(FFT_SCALAR);
if (peratom_allocate_flag) {
bytes += 7 * nbrick * sizeof(FFT_SCALAR);
bytes += 2 * nbuf_peratom * sizeof(FFT_SCALAR);
}
if (group_allocate_flag) {
bytes += 2 * nbrick * sizeof(FFT_SCALAR);
bytes += 2 * nfft_both * sizeof(FFT_SCALAR);;
}
return bytes;
}
/* ----------------------------------------------------------------------
group-group interactions
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
compute the PPPM total long-range force and energy for groups A and B
------------------------------------------------------------------------- */
void PPPM::compute_group_group(int groupbit_A, int groupbit_B, int BA_flag)
{
if (slabflag)
error->all(FLERR,"Cannot (yet) use K-space slab "
"correction with compute group/group");
int i,j;
if (!group_allocate_flag) {
allocate_groups();
group_allocate_flag = 1;
}
e2group = 0; //energy
f2group[0] = 0; //force in x-direction
f2group[1] = 0; //force in y-direction
f2group[2] = 0; //force in z-direction
double *q = atom->q;
int nlocal = atom->nlocal;
int *mask = atom->mask;
// map my particle charge onto my local 3d density grid
make_rho_groups(groupbit_A,groupbit_B,BA_flag);
// all procs communicate density values from their ghost cells
// to fully sum contribution in their 3d bricks
// remap from 3d decomposition to FFT decomposition
// temporarily store and switch pointers so we can
// use brick2fft() for groups A and B (without
// writing an additional function)
FFT_SCALAR ***density_brick_real = density_brick;
FFT_SCALAR *density_fft_real = density_fft;
// group A
density_brick = density_A_brick;
density_fft = density_A_fft;
brick2fft();
// group B
density_brick = density_B_brick;
density_fft = density_B_fft;
brick2fft();
// switch back pointers
density_brick = density_brick_real;
density_fft = density_fft_real;
// compute potential gradient on my FFT grid and
// portion of group-group energy/force on this proc's FFT grid
poisson_groups(BA_flag);
const double qscale = force->qqrd2e * scale;
// total group A <--> group B energy
// self and boundary correction terms are in compute_group_group.cpp
double e2group_all;
MPI_Allreduce(&e2group,&e2group_all,1,MPI_DOUBLE,MPI_SUM,world);
e2group = e2group_all;
e2group *= qscale*0.5*volume;
// total group A <--> group B force
double f2group_all[3];
MPI_Allreduce(f2group,f2group_all,3,MPI_DOUBLE,MPI_SUM,world);
for (i = 0; i < 3; i++) f2group[i] = qscale*volume*f2group_all[i];
}
/* ----------------------------------------------------------------------
allocate group-group memory that depends on # of K-vectors and order
------------------------------------------------------------------------- */
void PPPM::allocate_groups()
{
memory->create3d_offset(density_A_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:density_A_brick");
memory->create3d_offset(density_B_brick,nzlo_out,nzhi_out,nylo_out,nyhi_out,
nxlo_out,nxhi_out,"pppm:density_B_brick");
memory->create(density_A_fft,nfft_both,"pppm:density_A_fft");
memory->create(density_B_fft,nfft_both,"pppm:density_B_fft");
}
/* ----------------------------------------------------------------------
deallocate group-group memory that depends on # of K-vectors and order
------------------------------------------------------------------------- */
void PPPM::deallocate_groups()
{
memory->destroy3d_offset(density_A_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy3d_offset(density_B_brick,nzlo_out,nylo_out,nxlo_out);
memory->destroy(density_A_fft);
memory->destroy(density_B_fft);
}
/* ----------------------------------------------------------------------
create discretized "density" on section of global grid due to my particles
density(x,y,z) = charge "density" at grid points of my 3d brick
(nxlo:nxhi,nylo:nyhi,nzlo:nzhi) is extent of my brick (including ghosts)
in global grid for group-group interactions
------------------------------------------------------------------------- */
void PPPM::make_rho_groups(int groupbit_A, int groupbit_B, int BA_flag)
{
int l,m,n,nx,ny,nz,mx,my,mz;
FFT_SCALAR dx,dy,dz,x0,y0,z0;
// clear 3d density arrays
memset(&(density_A_brick[nzlo_out][nylo_out][nxlo_out]),0,
ngrid*sizeof(FFT_SCALAR));
memset(&(density_B_brick[nzlo_out][nylo_out][nxlo_out]),0,
ngrid*sizeof(FFT_SCALAR));
// loop over my charges, add their contribution to nearby grid points
// (nx,ny,nz) = global coords of grid pt to "lower left" of charge
// (dx,dy,dz) = distance to "lower left" grid pt
// (mx,my,mz) = global coords of moving stencil pt
double *q = atom->q;
double **x = atom->x;
int nlocal = atom->nlocal;
int *mask = atom->mask;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit_A) && (mask[i] & groupbit_B))
if (BA_flag) continue;
if ((mask[i] & groupbit_A) || (mask[i] & groupbit_B)) {
nx = part2grid[i][0];
ny = part2grid[i][1];
nz = part2grid[i][2];
dx = nx+shiftone - (x[i][0]-boxlo[0])*delxinv;
dy = ny+shiftone - (x[i][1]-boxlo[1])*delyinv;
dz = nz+shiftone - (x[i][2]-boxlo[2])*delzinv;
compute_rho1d(dx,dy,dz);
z0 = delvolinv * q[i];
for (n = nlower; n <= nupper; n++) {
mz = n+nz;
y0 = z0*rho1d[2][n];
for (m = nlower; m <= nupper; m++) {
my = m+ny;
x0 = y0*rho1d[1][m];
for (l = nlower; l <= nupper; l++) {
mx = l+nx;
// group A
if (mask[i] & groupbit_A)
density_A_brick[mz][my][mx] += x0*rho1d[0][l];
// group B
if (mask[i] & groupbit_B)
density_B_brick[mz][my][mx] += x0*rho1d[0][l];
}
}
}
}
}
}
/* ----------------------------------------------------------------------
FFT-based Poisson solver for group-group interactions
------------------------------------------------------------------------- */
void PPPM::poisson_groups(int BA_flag)
{
int i,j,k,n;
double eng;
// reuse memory (already declared)
FFT_SCALAR *work_A = work1;
FFT_SCALAR *work_B = work2;
// transform charge density (r -> k)
// group A
n = 0;
for (i = 0; i < nfft; i++) {
work_A[n++] = density_A_fft[i];
work_A[n++] = ZEROF;
}
fft1->compute(work_A,work_A,1);
// group B
n = 0;
for (i = 0; i < nfft; i++) {
work_B[n++] = density_B_fft[i];
work_B[n++] = ZEROF;
}
fft1->compute(work_B,work_B,1);
// group-group energy and force contribution,
// keep everything in reciprocal space so
// no inverse FFTs needed
double scaleinv = 1.0/(nx_pppm*ny_pppm*nz_pppm);
double s2 = scaleinv*scaleinv;
// energy
n = 0;
for (i = 0; i < nfft; i++) {
e2group += s2 * greensfn[i] *
(work_A[n]*work_B[n] + work_A[n+1]*work_B[n+1]);
n += 2;
}
if (BA_flag) return;
// multiply by Green's function and s2
// (only for work_A so it is not squared below)
n = 0;
for (i = 0; i < nfft; i++) {
work_A[n++] *= s2 * greensfn[i];
work_A[n++] *= s2 * greensfn[i];
}
double partial_group;
// force, x direction
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
partial_group = work_A[n+1]*work_B[n] - work_A[n]*work_B[n+1];
f2group[0] += fkx[i] * partial_group;
n += 2;
}
// force, y direction
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
partial_group = work_A[n+1]*work_B[n] - work_A[n]*work_B[n+1];
f2group[1] += fky[j] * partial_group;
n += 2;
}
// force, z direction
n = 0;
for (k = nzlo_fft; k <= nzhi_fft; k++)
for (j = nylo_fft; j <= nyhi_fft; j++)
for (i = nxlo_fft; i <= nxhi_fft; i++) {
partial_group = work_A[n+1]*work_B[n] - work_A[n]*work_B[n+1];
f2group[2] += fkz[k] * partial_group;
n += 2;
}
}
diff --git a/src/KSPACE/pppm.h b/src/KSPACE/pppm.h
index 6a51d6823..849b08322 100644
--- a/src/KSPACE/pppm.h
+++ b/src/KSPACE/pppm.h
@@ -1,269 +1,277 @@
/* -*- c++ -*- ----------------------------------------------------------
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 KSPACE_CLASS
KSpaceStyle(pppm,PPPM)
#else
#ifndef LMP_PPPM_H
#define LMP_PPPM_H
#include "lmptype.h"
#include "mpi.h"
#ifdef FFT_SINGLE
typedef float FFT_SCALAR;
#define MPI_FFT_SCALAR MPI_FLOAT
#else
typedef double FFT_SCALAR;
#define MPI_FFT_SCALAR MPI_DOUBLE
#endif
#include "kspace.h"
namespace LAMMPS_NS {
class PPPM : public KSpace {
public:
PPPM(class LAMMPS *, int, char **);
virtual ~PPPM();
virtual void init();
virtual void setup();
virtual void compute(int, int);
virtual void timing(int, double &, double &);
virtual double memory_usage();
virtual void compute_group_group(int, int, int);
protected:
int me,nprocs;
int nfactors;
int *factors;
double qsum,qsqsum;
double cutoff;
double volume;
double delxinv,delyinv,delzinv,delvolinv;
double shift,shiftone;
int peratom_allocate_flag;
int nxlo_in,nylo_in,nzlo_in,nxhi_in,nyhi_in,nzhi_in;
int nxlo_out,nylo_out,nzlo_out,nxhi_out,nyhi_out,nzhi_out;
int nxlo_ghost,nxhi_ghost,nylo_ghost,nyhi_ghost,nzlo_ghost,nzhi_ghost;
int nxlo_fft,nylo_fft,nzlo_fft,nxhi_fft,nyhi_fft,nzhi_fft;
int nlower,nupper;
int ngrid,nfft,nfft_both;
int nbuf,nbuf_peratom;
FFT_SCALAR ***density_brick;
FFT_SCALAR ***vdx_brick,***vdy_brick,***vdz_brick;
FFT_SCALAR ***u_brick;
FFT_SCALAR ***v0_brick,***v1_brick,***v2_brick;
FFT_SCALAR ***v3_brick,***v4_brick,***v5_brick;
double *greensfn;
double **vg;
double *fkx,*fky,*fkz;
FFT_SCALAR *density_fft;
FFT_SCALAR *work1,*work2;
FFT_SCALAR *buf1,*buf2,*buf3,*buf4;
double *gf_b;
FFT_SCALAR **rho1d,**rho_coeff;
// group-group interactions
int group_allocate_flag;
FFT_SCALAR ***density_A_brick,***density_B_brick;
FFT_SCALAR *density_A_fft,*density_B_fft;
class FFT3d *fft1,*fft2;
class Remap *remap;
int **part2grid; // storage for particle -> grid mapping
int nmax;
int triclinic; // domain settings, orthog or triclinic
double *boxlo;
// TIP4P settings
int typeH,typeO; // atom types of TIP4P water H and O atoms
double qdist; // distance from O site to negative charge
double alpha; // geometric factor
void set_grid();
virtual void allocate();
virtual void allocate_peratom();
virtual void deallocate();
virtual void deallocate_peratom();
int factorable(int);
double rms(double, double, bigint, double, double **);
double diffpr(double, double, double, double, double **);
void compute_gf_denom();
virtual void particle_map();
virtual void make_rho();
virtual void brick2fft();
virtual void fillbrick();
virtual void fillbrick_peratom();
virtual void poisson();
virtual void poisson_peratom();
virtual void fieldforce();
virtual void fieldforce_peratom();
void procs2grid2d(int,int,int,int *, int*);
void compute_rho1d(const FFT_SCALAR &, const FFT_SCALAR &,
const FFT_SCALAR &);
void compute_rho_coeff();
void slabcorr();
// group-group interactions
virtual void allocate_groups();
virtual void deallocate_groups();
virtual void make_rho_groups(int, int, int);
virtual void poisson_groups(int);
/* ----------------------------------------------------------------------
denominator for Hockney-Eastwood Green's function
of x,y,z = sin(kx*deltax/2), etc
inf n-1
S(n,k) = Sum W(k+pi*j)**2 = Sum b(l)*(z*z)**l
j=-inf l=0
= -(z*z)**n /(2n-1)! * (d/dx)**(2n-1) cot(x) at z = sin(x)
gf_b = denominator expansion coeffs
------------------------------------------------------------------------- */
inline double gf_denom(const double &x, const double &y,
const double &z) const {
double sx,sy,sz;
sz = sy = sx = 0.0;
for (int l = order-1; l >= 0; l--) {
sx = gf_b[l] + sx*x;
sy = gf_b[l] + sy*y;
sz = gf_b[l] + sz*z;
}
double s = sx*sy*sz;
return s*s;
};
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Cannot (yet) use PPPM with triclinic box
This feature is not yet supported.
E: Cannot use PPPM with 2d simulation
The kspace style pppm cannot be used in 2d simulations. You can use
2d PPPM in a 3d simulation; see the kspace_modify command.
E: Kspace style requires atom attribute q
The atom style defined does not have these attributes.
E: Cannot use nonperiodic boundaries with PPPM
For kspace style pppm, all 3 dimensions must have periodic boundaries
unless you use the kspace_modify command to define a 2d slab with a
non-periodic z dimension.
E: Incorrect boundaries with slab PPPM
Must have periodic x,y dimensions and non-periodic z dimension to use
2d slab option with PPPM.
-E: PPPM order cannot be greater than %d
+E: PPPM order cannot be < 2 or > than %d
-Self-explanatory.
+This is a limitation of the PPPM implementation in LAMMPS.
E: KSpace style is incompatible with Pair style
Setting a kspace style requires that a pair style with a long-range
Coulombic component be selected.
E: Bond and angle potentials must be defined for TIP4P
Cannot use TIP4P pair potential unless bond and angle potentials
are defined.
E: Bad TIP4P angle type for PPPM/TIP4P
Specified angle type is not valid.
E: Bad TIP4P bond type for PPPM/TIP4P
Specified bond type is not valid.
E: Cannot use kspace solver on system with no charge
No atoms in system have a non-zero charge.
W: System is not charge neutral, net charge = %g
The total charge on all atoms on the system is not 0.0, which
is not valid for Ewald or PPPM.
W: Reducing PPPM order b/c stencil extends beyond neighbor processor
LAMMPS is attempting this in order to allow the simulation
to run. It should not effect the PPPM accuracy.
E: PPPM grid is too large
The global PPPM grid is larger than OFFSET in one or more dimensions.
OFFSET is currently set to 4096. You likely need to decrease the
requested accuracy.
E: PPPM order has been reduced to 0
LAMMPS has attempted to reduce the PPPM order to enable the simulation
to run, but can reduce the order no further. Try increasing the
accuracy of PPPM by reducing the tolerance size, thus inducing a
larger PPPM grid.
+E: KSpace accuracy must be > 0
+
+The kspace accuracy designated in the input must be greater than zero.
+
E: Cannot compute PPPM G
LAMMPS failed to compute a valid approximation for the PPPM g_ewald
factor that partitions the computation between real space and k-space.
E: Out of range atoms - cannot compute PPPM
One or more atoms are attempting to map their charge to a PPPM grid
point that is not owned by a processor. This is likely for one of two
reasons, both of them bad. First, it may mean that an atom near the
boundary of a processor's sub-domain has moved more than 1/2 the
"neighbor skin distance"_neighbor.html without neighbor lists being
rebuilt and atoms being migrated to new processors. This also means
you may be missing pairwise interactions that need to be computed.
The solution is to change the re-neighboring criteria via the
"neigh_modify"_neigh_modify command. The safest settings are "delay 0
every 1 check yes". Second, it may mean that an atom has moved far
outside a processor's sub-domain or even the entire simulation box.
This indicates bad physics, e.g. due to highly overlapping atoms, too
large a timestep, etc.
+E: Cannot (yet) use K-space slab correction with compute group/group
+
+This option is not yet supported.
+
*/
diff --git a/src/MAKE/Makefile.serial b/src/MAKE/Makefile.serial
index 4685dbcc1..f49464993 100644
--- a/src/MAKE/Makefile.serial
+++ b/src/MAKE/Makefile.serial
@@ -1,96 +1,95 @@
# serial = RedHat Linux box, g++4, no MPI, no FFTs
SHELL = /bin/sh
# ---------------------------------------------------------------------
# compiler/linker settings
-# generally no need to edit this section
-# unless additional compiler/linker flags or libraries needed for your machine
+# specify flags and libraries needed for your compiler
CC = g++
CCFLAGS = -O -g
DEPFLAGS = -M
LINK = g++
LINKFLAGS = -O -g
LIB =
ARCHIVE = ar
ARFLAGS = -rc
SIZE = size
# ---------------------------------------------------------------------
# LAMMPS-specific settings
# specify settings for LAMMPS features you will use
# if you change any -D setting, do full re-compile after "make clean"
# LAMMPS ifdef settings, OPTIONAL
# see possible settings in doc/Section_start.html#2_2 (step 4)
LMP_INC = #-DLAMMPS_GZIP -DMALLOC_MEMALIGN=64
# MPI library, REQUIRED
# see discussion in doc/Section_start.html#2_2 (step 5)
# can point to dummy MPI library in src/STUBS as in Makefile.serial
# INC = path for mpi.h, MPI compiler settings
# PATH = path for MPI library
# LIB = name of MPI library
MPI_INC = -I../STUBS
MPI_PATH =
MPI_LIB = ../STUBS/libmpi.a
# FFT library, OPTIONAL
# see discussion in doc/Section_start.html#2_2 (step 6)
# can be left blank to use provided KISS FFT library
# INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings
# PATH = path for FFT library
# LIB = name of FFT library
FFT_INC =
FFT_PATH =
FFT_LIB = -lfftw3f
# JPEG library, OPTIONAL
# see discussion in doc/Section_start.html#2_2 (step 7)
# only needed if -DLAMMPS_JPEG listed with LMP_INC
# INC = path for jpeglib.h
# PATH = path for JPEG library
# LIB = name of JPEG library
JPG_INC =
JPG_PATH =
JPG_LIB =
# ---------------------------------------------------------------------
# build rules and dependencies
# no need to edit this section
include Makefile.package.settings
include Makefile.package
EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(PKG_SYSINC)
EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(PKG_SYSPATH)
EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(PKG_SYSLIB)
# Link target
$(EXE): $(OBJ)
$(LINK) $(LINKFLAGS) $(EXTRA_PATH) $(OBJ) $(EXTRA_LIB) $(LIB) -o $(EXE)
$(SIZE) $(EXE)
# Library target
lib: $(OBJ)
$(ARCHIVE) $(ARFLAGS) $(EXE) $(OBJ)
# Compilation rules
%.o:%.cpp
$(CC) $(CCFLAGS) $(EXTRA_INC) -c $<
%.d:%.cpp
$(CC) $(CCFLAGS) $(EXTRA_INC) $(DEPFLAGS) $< > $@
# Individual dependencies
DEPENDS = $(OBJ:.o=.d)
sinclude $(DEPENDS)
diff --git a/src/MANYBODY/Install.sh b/src/MANYBODY/Install.sh
index 8d36e8e9d..de0181af2 100644
--- a/src/MANYBODY/Install.sh
+++ b/src/MANYBODY/Install.sh
@@ -1,63 +1,67 @@
# Install/unInstall package files in LAMMPS
if (test $1 = 1) then
cp fix_qeq_comb.cpp ..
cp pair_adp.cpp ..
cp pair_airebo.cpp ..
+ cp pair_bop.cpp ..
cp pair_comb.cpp ..
cp pair_eam.cpp ..
cp pair_eam_alloy.cpp ..
cp pair_eam_fs.cpp ..
cp pair_eim.cpp ..
cp pair_lcbop.cpp ..
cp pair_rebo.cpp ..
cp pair_sw.cpp ..
cp pair_tersoff.cpp ..
cp pair_tersoff_zbl.cpp ..
cp fix_qeq_comb.h ..
cp pair_adp.h ..
cp pair_airebo.h ..
+ cp pair_bop.h ..
cp pair_comb.h ..
cp pair_eam.h ..
cp pair_eam_alloy.h ..
cp pair_eam_fs.h ..
cp pair_eim.h ..
cp pair_lcbop.h ..
cp pair_rebo.h ..
cp pair_sw.h ..
cp pair_tersoff.h ..
cp pair_tersoff_zbl.h ..
elif (test $1 = 0) then
rm -f ../fix_qeq_comb.cpp
rm -f ../pair_adp.cpp
rm -f ../pair_airebo.cpp
+ rm -f ../pair_bop.cpp
rm -f ../pair_comb.cpp
rm -f ../pair_eam.cpp
rm -f ../pair_eam_alloy.cpp
rm -f ../pair_eam_fs.cpp
rm -f ../pair_eim.cpp
rm -f ../pair_lcbop.cpp
rm -f ../pair_rebo.cpp
rm -f ../pair_sw.cpp
rm -f ../pair_tersoff.cpp
rm -f ../pair_tersoff_zbl.cpp
rm -f ../fix_qeq_comb.h
rm -f ../pair_adp.h
rm -f ../pair_airebo.h
+ rm -f ../pair_bop.h
rm -f ../pair_comb.h
rm -f ../pair_eam.h
rm -f ../pair_eam_alloy.h
rm -f ../pair_eam_fs.h
rm -f ../pair_eim.h
rm -f ../pair_lcbop.h
rm -f ../pair_rebo.h
rm -f ../pair_sw.h
rm -f ../pair_tersoff.h
rm -f ../pair_tersoff_zbl.h
fi
diff --git a/src/MANYBODY/pair_bop.cpp b/src/MANYBODY/pair_bop.cpp
new file mode 100644
index 000000000..45e50566f
--- /dev/null
+++ b/src/MANYBODY/pair_bop.cpp
@@ -0,0 +1,9547 @@
+/* ----------------------------------------------------------------------
+ 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: D.K. Ward (donward@sandia.gov) and X.W. Zhou (Sandia)
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ The formulation for this work follows (a) D.G. Pettifor, et al., Mat.
+ Sci. and Eng. A365, 2-13, (2004);(b) D.A. Murdick, et al., Phys.
+ Rev. B 73, 045206 (2006);(c) D.G. Pettifor and I.I. Oleinik., Phys
+ Rev. Lett. 84, 4124 (2000); (d) D.K. Ward, et al., Phys. Rev. B 85,
+ 115206 (2012).
+
+ Copyright (2012) Sandia Corporation. Under the terms of Contract DE-
+ AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ rights in this software.
+
+ pairbop v 1.0 comes with no warranty of any kind. pairbop v 1.0 is a
+ copyrighted code that is distributed free-of-charge, under the terms
+ of the GNU Public License (GPL). See "Open-Source
+ Rules"_http://lammps.sandia.gov/open_source.html
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "mpi.h"
+#include "pair_bop.h"
+#include "atom.h"
+#include "neighbor.h"
+#include "neigh_request.h"
+#include "force.h"
+#include "timer.h"
+#include "comm.h"
+#include "domain.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define MAXLINE 1024
+#define EPSILON 1.0e-6
+
+/* ---------------------------------------------------------------------- */
+
+PairBOP::PairBOP(LAMMPS *lmp) : Pair(lmp)
+{
+ single_enable = 0;
+ one_coeff = 1;
+ map = NULL;
+ pi_a = NULL;
+ pro_delta = NULL;
+ pi_delta = NULL;
+ pi_p = NULL;
+ pi_c = NULL;
+ sigma_r0 = NULL;
+ pi_r0 = NULL;
+ phi_r0 = NULL;
+ sigma_rc = NULL;
+ pi_rc = NULL;
+ phi_rc = NULL;
+ r1 = NULL;
+ sigma_beta0 = NULL;
+ pi_beta0 = NULL;
+ phi0 = NULL;
+ sigma_n = NULL;
+ pi_n = NULL;
+ phi_m = NULL;
+ sigma_nc = NULL;
+ pi_nc = NULL;
+ phi_nc = NULL;
+ pro = NULL;
+ sigma_delta = NULL;
+ sigma_c = NULL;
+ sigma_a = NULL;
+ sigma_g0 = NULL;
+ sigma_g1 = NULL;
+ sigma_g2 = NULL;
+ sigma_g3 = NULL;
+ sigma_g4 = NULL;
+ sigma_f = NULL;
+ sigma_k = NULL;
+ small3 = NULL;
+ rcut = NULL;
+ dr = NULL;
+ rdr = NULL;
+ disij = NULL;
+ rij = NULL;
+ cosAng = NULL;
+ betaS = NULL;
+ dBetaS = NULL;
+ betaP = NULL;
+ dBetaP = NULL;
+ repul = NULL;
+ dRepul = NULL;
+ itypeSigBk = NULL;
+ nSigBk = NULL;
+ sigB = NULL;
+ sigB1 = NULL;
+ itypePiBk = NULL;
+ nPiBk = NULL;
+ piB = NULL;
+ pBetaS = NULL;
+ pBetaS1 = NULL;
+ pBetaS2 = NULL;
+ pBetaS3 = NULL;
+ pBetaS4 = NULL;
+ pBetaS5 = NULL;
+ pBetaS6 = NULL;
+ pBetaP = NULL;
+ pBetaP1 = NULL;
+ pBetaP2 = NULL;
+ pBetaP3 = NULL;
+ pBetaP4 = NULL;
+ pBetaP5 = NULL;
+ pBetaP6 = NULL;
+ pRepul = NULL;
+ pRepul1 = NULL;
+ pRepul2 = NULL;
+ pRepul3 = NULL;
+ pRepul4 = NULL;
+ pRepul5 = NULL;
+ pRepul6 = NULL;
+ FsigBO = NULL;
+ FsigBO1 = NULL;
+ FsigBO2 = NULL;
+ FsigBO3 = NULL;
+ FsigBO4 = NULL;
+ FsigBO5 = NULL;
+ FsigBO6 = NULL;
+ rcmin = NULL;
+ rcmax = NULL;
+ rcmaxp = NULL;
+ setflag = NULL;
+ cutsq = NULL;
+ cutghost = NULL;
+
+ ghostneigh = 1;
+ bt_sg=NULL;
+ bt_pi=NULL;
+}
+
+/* ----------------------------------------------------------------------
+ check if allocated, since class can be destructed when incomplete
+------------------------------------------------------------------------- */
+
+PairBOP::~PairBOP()
+{
+ int i;
+ if(allocated) {
+ memory_theta_destroy();
+ if (otfly==0) memory->destroy(cos_index);
+ delete [] map;
+
+ memory->destroy(BOP_index);
+ memory->destroy(rcut);
+ memory->destroy(dr);
+ memory->destroy(rdr);
+ memory->destroy(setflag);
+ memory->destroy(cutsq);
+ memory->destroy(cutghost);
+ memory->destroy(pBetaS);
+ memory->destroy(pBetaS1);
+ memory->destroy(pBetaS2);
+ memory->destroy(pBetaS3);
+ memory->destroy(pBetaS4);
+ memory->destroy(pBetaS5);
+ memory->destroy(pBetaS6);
+ memory->destroy(pBetaP);
+ memory->destroy(pBetaP1);
+ memory->destroy(pBetaP2);
+ memory->destroy(pBetaP3);
+ memory->destroy(pBetaP4);
+ memory->destroy(pBetaP5);
+ memory->destroy(pBetaP6);
+ memory->destroy(pRepul);
+ memory->destroy(pRepul1);
+ memory->destroy(pRepul2);
+ memory->destroy(pRepul3);
+ memory->destroy(pRepul4);
+ memory->destroy(pRepul5);
+ memory->destroy(pRepul6);
+ memory->destroy(FsigBO);
+ memory->destroy(FsigBO1);
+ memory->destroy(FsigBO2);
+ memory->destroy(FsigBO3);
+ memory->destroy(FsigBO4);
+ memory->destroy(FsigBO5);
+ memory->destroy(FsigBO6);
+ if(table==0) {
+ memory->destroy(pi_a);
+ memory->destroy(pro_delta);
+ memory->destroy(pi_delta);
+ memory->destroy(pi_p);
+ memory->destroy(pi_c);
+ memory->destroy(sigma_r0);
+ memory->destroy(pi_r0);
+ memory->destroy(phi_r0);
+ memory->destroy(sigma_rc);
+ memory->destroy(pi_rc);
+ memory->destroy(phi_rc);
+ memory->destroy(r1);
+ memory->destroy(sigma_beta0);
+ memory->destroy(pi_beta0);
+ memory->destroy(phi0);
+ memory->destroy(sigma_n);
+ memory->destroy(pi_n);
+ memory->destroy(phi_m);
+ memory->destroy(sigma_nc);
+ memory->destroy(pi_nc);
+ memory->destroy(phi_nc);
+ memory->destroy(pro);
+ memory->destroy(sigma_delta);
+ memory->destroy(sigma_c);
+ memory->destroy(sigma_a);
+ memory->destroy(sigma_g0);
+ memory->destroy(sigma_g1);
+ memory->destroy(sigma_g2);
+ memory->destroy(sigma_g3);
+ memory->destroy(sigma_g4);
+ memory->destroy(sigma_f);
+ memory->destroy(sigma_k);
+ memory->destroy(small3);
+ }
+ else {
+ memory->destroy(pi_a);
+ memory->destroy(pro_delta);
+ memory->destroy(pi_delta);
+ memory->destroy(pi_p);
+ memory->destroy(pi_c);
+ memory->destroy(r1);
+ memory->destroy(pro);
+ memory->destroy(sigma_delta);
+ memory->destroy(sigma_c);
+ memory->destroy(sigma_a);
+ memory->destroy(sigma_g0);
+ memory->destroy(sigma_g1);
+ memory->destroy(sigma_g2);
+ memory->destroy(sigma_f);
+ memory->destroy(sigma_k);
+ memory->destroy(small3);
+ }
+ }
+ if(allocate_sigma) {
+ destroy_sigma();
+ }
+ if(allocate_pi) {
+ destroy_pi();
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::compute(int eflag, int vflag)
+{
+ int ago,delay,every;
+ int i,j,ii,jj,iij;
+ int n,inum,temp_ij,ks;
+ int itype,jtype,i_tag,j_tag;
+ int *ilist,*iilist,*numneigh;
+ int **firstneigh;
+ double dpr1,ps;
+ double ftmp1,ftmp2,ftmp3,dE;
+ double dis_ij[3],rsq_ij,r_ij;
+ double betaS_ij,dBetaS_ij;
+ double betaP_ij,dBetaP_ij;
+ double repul_ij,dRepul_ij;
+ double totE;
+
+ double **f = atom->f;
+ double **x = atom->x;
+ int *type = atom->type;
+ int *tag = atom->tag;
+ int newton_pair = force->newton_pair;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+ ago=neighbor->ago;
+ delay=neighbor->delay;
+ every=neighbor->every;
+
+ if (eflag || vflag) ev_setup(eflag,vflag);
+ else evflag = vflag_fdotr = 0;
+
+ // BOP Neighbor lists must be updated every time
+ // atoms are moved between processors
+
+ if ((ago ==0)||bop_step==0||(ago>=delay&&(ago%every)==0)||(nall>maxnall))
+ gneigh();
+
+ // For non on the fly calculations cos and derivatives
+ // are calculated in advance and stored
+
+ if(otfly==0) theta();
+ else theta_mod();
+
+ // Calculate Sigma Bond-Order
+
+ if(a_flag==1) {
+ if (otfly==0) sigmaBo_noa();
+ else sigmaBo_noa_otf();
+ }
+ else {
+ if (otfly==0) sigmaBo();
+ else sigmaBo_otf();
+ }
+
+ // Calculate Pi Bond-Order
+
+ if (otfly==0) PiBo();
+ else PiBo_otf();
+
+ n=0;
+ totE=0;
+ for (ii = 0; ii < inum; ii++) {
+ i=ilist[ii];
+ i_tag=tag[i];
+ itype=map[type[i]]+1;
+ iilist=firstneigh[i];
+ for(jj=0;jj<numneigh[i];jj++) {
+ temp_ij=BOP_index[i]+jj;
+ j=iilist[jj];
+ j_tag=tag[j];
+ jtype=map[type[j]]+1;
+ if(j_tag>=i_tag) {
+ if(otfly==0) {
+ if(neigh_flag[temp_ij]) {
+ dpr1=(dRepul[temp_ij]-2.0*dBetaS[temp_ij]*sigB[n]
+ -2.0*dBetaP[temp_ij]*piB[n])/rij[temp_ij];
+ ftmp1=dpr1*disij[0][temp_ij];
+ ftmp2=dpr1*disij[1][temp_ij];
+ ftmp3=dpr1*disij[2][temp_ij];
+ f[i][0]=f[i][0]+ftmp1;
+ f[i][1]=f[i][1]+ftmp2;
+ f[i][2]=f[i][2]+ftmp3;
+ f[j][0]=f[j][0]-ftmp1;
+ f[j][1]=f[j][1]-ftmp2;
+ f[j][2]=f[j][2]-ftmp3;
+
+ // add repulsive and bond order components to total energy
+ // (d) Eq.1
+
+ dE=-2.0*betaS[temp_ij]*sigB[n]-2.0*betaP[temp_ij]*piB[n];
+ totE+=dE+repul[temp_ij];
+ if(evflag) {
+ ev_tally_full(i,repul[temp_ij],dE,0.0,0.0,0.0,0.0);
+ ev_tally_full(j,repul[temp_ij],dE,0.0,0.0,0.0,0.0);
+ ev_tally_xyz(i,j,nlocal,newton_pair,0.0,0.0,-ftmp1,-ftmp2,-ftmp3,
+ disij[0][temp_ij],disij[1][temp_ij],disij[2][temp_ij]);
+ }
+ n++;
+ }
+ }
+ else {
+ if(itype==jtype)
+ iij=itype-1;
+ else if(itype<jtype)
+ iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+ else
+ iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+ dis_ij[0]=x[j][0]-x[i][0];
+ dis_ij[1]=x[j][1]-x[i][1];
+ dis_ij[2]=x[j][2]-x[i][2];
+ rsq_ij=dis_ij[0]*dis_ij[0]
+ +dis_ij[1]*dis_ij[1]
+ +dis_ij[2]*dis_ij[2];
+ r_ij=sqrt(rsq_ij);
+ if(r_ij<=rcut[iij]) {
+ ps=r_ij*rdr[iij]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_ij=((pBetaS3[iij][ks-1]*ps+pBetaS2[iij][ks-1])*ps
+ +pBetaS1[iij][ks-1])*ps+pBetaS[iij][ks-1];
+ dBetaS_ij=(pBetaS6[iij][ks-1]*ps+pBetaS5[iij][ks-1])*ps
+ +pBetaS4[iij][ks-1];
+ betaP_ij=((pBetaP3[iij][ks-1]*ps+pBetaP2[iij][ks-1])*ps
+ +pBetaP1[iij][ks-1])*ps+pBetaP[iij][ks-1];
+ dBetaP_ij=(pBetaP6[iij][ks-1]*ps+pBetaP5[iij][ks-1])*ps
+ +pBetaP4[iij][ks-1];
+ repul_ij=((pRepul3[iij][ks-1]*ps+pRepul2[iij][ks-1])*ps
+ +pRepul1[iij][ks-1])*ps+pRepul[iij][ks-1];
+ dRepul_ij=(pRepul6[iij][ks-1]*ps+pRepul5[iij][ks-1])*ps
+ +pRepul4[iij][ks-1];
+ dpr1=(dRepul_ij-2.0*dBetaS_ij*sigB[n]
+ -2.0*dBetaP_ij*piB[n])/r_ij;
+ ftmp1=dpr1*dis_ij[0];
+ ftmp2=dpr1*dis_ij[1];
+ ftmp3=dpr1*dis_ij[2];
+ f[i][0]=f[i][0]+ftmp1;
+ f[i][1]=f[i][1]+ftmp2;
+ f[i][2]=f[i][2]+ftmp3;
+ f[j][0]=f[j][0]-ftmp1;
+ f[j][1]=f[j][1]-ftmp2;
+ f[j][2]=f[j][2]-ftmp3;
+
+ // add repulsive and bond order components to total energy
+ // (d) Eq. 1
+
+ dE=-2.0*betaS_ij*sigB[n]-2.0*betaP_ij*piB[n];
+ totE+=dE+repul_ij;
+ if(evflag) {
+ ev_tally_full(i,repul_ij,dE,0.0,0.0,0.0,0.0);
+ ev_tally_full(j,repul_ij,dE,0.0,0.0,0.0,0.0);
+ ev_tally_xyz(i,j,nlocal,newton_pair,0.0,0.0,-ftmp1,-ftmp2,-ftmp3,
+ dis_ij[0],dis_ij[1],dis_ij[2]);
+ }
+ n++;
+ }
+ }
+ }
+ }
+ }
+
+ if (vflag_fdotr) virial_fdotr_compute();
+ bop_step = 1;
+}
+
+/* ----------------------------------------------------------------------
+ allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairBOP::allocate()
+{
+ allocated = 1;
+ int n = atom->ntypes;
+
+ memory->create(rcut,npairs,"BOP:rcut");
+ memory->create(dr,npairs,"BOP:dr");
+ memory->create(rdr,npairs,"BOP:dr");
+ memory->create(setflag,n+1,n+1,"pair:setflag");
+ memory->create(cutsq,n+1,n+1,"pair:cutsq");
+ memory->create(cutghost,n+1,n+1,"pair:cutghost");
+ memory->create(pBetaS,npairs,nr,"BOP:pBetaS");
+ memory->create(pBetaS1,npairs,nr,"BOP:pBetaS1");
+ memory->create(pBetaS2,npairs,nr,"BOP:pBetaS2");
+ memory->create(pBetaS3,npairs,nr,"BOP:pBetaS3");
+ memory->create(pBetaS4,npairs,nr,"BOP:pBetaS4");
+ memory->create(pBetaS5,npairs,nr,"BOP:pBetaS5");
+ memory->create(pBetaS6,npairs,nr,"BOP:pBetaS6");
+ memory->create(pBetaP,npairs,nr,"BOP:pBetaP");
+ memory->create(pBetaP1,npairs,nr,"BOP:pBetaP1");
+ memory->create(pBetaP2,npairs,nr,"BOP:pBetaP2");
+ memory->create(pBetaP3,npairs,nr,"BOP:pBetaP3");
+ memory->create(pBetaP4,npairs,nr,"BOP:pBetaP4");
+ memory->create(pBetaP5,npairs,nr,"BOP:pBetaP5");
+ memory->create(pBetaP6,npairs,nr,"BOP:pBetaP6");
+ memory->create(pRepul,npairs,nr,"BOP:pRepul");
+ memory->create(pRepul1,npairs,nr,"BOP:pRepul1");
+ memory->create(pRepul2,npairs,nr,"BOP:pRepul2");
+ memory->create(pRepul3,npairs,nr,"BOP:pRepul3");
+ memory->create(pRepul4,npairs,nr,"BOP:pRepul4");
+ memory->create(pRepul5,npairs,nr,"BOP:pRepul5");
+ memory->create(pRepul6,npairs,nr,"BOP:pRepul6");
+ memory->create(FsigBO,npairs,nBOt,"BOP:FsigBO");
+ memory->create(FsigBO1,npairs,nBOt,"BOP:FsigBO1");
+ memory->create(FsigBO2,npairs,nBOt,"BOP:FsigBO2");
+ memory->create(FsigBO3,npairs,nBOt,"BOP:FsigBO3");
+ memory->create(FsigBO4,npairs,nBOt,"BOP:FsigBO4");
+ memory->create(FsigBO5,npairs,nBOt,"BOP:FsigBO5");
+ memory->create(FsigBO6,npairs,nBOt,"BOP:FsigBO6");
+}
+
+/* ----------------------------------------------------------------------
+ global settings
+------------------------------------------------------------------------- */
+
+void PairBOP::settings(int narg, char **arg)
+{
+ table = 0;
+ otfly = 1;
+ a_flag = 0;
+
+ int iarg = 0;
+ while (iarg < narg) {
+ if (strcmp(arg[iarg],"table") == 0) {
+ table = 1;
+ iarg++;
+ } else if (strcmp(arg[iarg],"save") == 0) {
+ otfly = 0;
+ iarg++;
+ } else if (strcmp(arg[iarg],"sigmaoff") == 0) {
+ a_flag = 1;
+ iarg++;
+ } else error->all(FLERR,"Illegal pair_style command");
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set coeffs for one or more type pairs(Updated: D.K. Ward 05/06/10)
+------------------------------------------------------------------------- */
+
+void PairBOP::coeff(int narg, char **arg)
+{
+ int i,j,n;
+ MPI_Comm_rank(world,&me);
+ map = new int[atom->ntypes+1];
+
+ if (narg < 3 + atom->ntypes)
+ error->all(FLERR,"Incorrect args for pair coefficients");
+
+ // ensure I,J args are * *
+
+ if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
+ error->all(FLERR,"Incorrect args for pair coefficients");
+
+ // read the potential file
+
+ nr=2000;
+ nBOt=2000;
+ bop_step=0;
+ nb_pi=0;
+ nb_sg=0;
+ allocate_sigma=0;
+ allocate_pi=0;
+ allocate_neigh=0;
+ update_list=0;
+
+ if (table == 0) read_file(arg[2]);
+ else read_table(arg[2]);
+
+ if (table == 0) {
+ setPbetaS();
+ setPbetaP();
+ setPrepul();
+ setSign();
+ }
+
+ // match element names to BOP word types
+
+ if (me == 0) {
+ for (i = 3; i < narg; i++) {
+ if (strcmp(arg[i],"NULL") == 0) {
+ map[i-2] = -1;
+ continue;
+ }
+ for (j = 0; j < bop_types; j++)
+ if (strcmp(arg[i],words[j]) == 0) break;
+ map[i-2] = j;
+ }
+ }
+
+ MPI_Bcast(&map[1],atom->ntypes,MPI_INT,0,world);
+
+ if (me == 0) {
+ if (words) {
+ for (i = 0; i < bop_types; i++) delete [] words[i];
+ delete [] words;
+ }
+ }
+
+ // clear setflag since coeff() called once with I,J = * *
+
+ n = atom->ntypes;
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ setflag[i][j] = 0;
+
+ // set setflag i,j for type pairs where both are mapped to elements
+
+ int count = 0;
+ for (int i = 1; i <= n; i++)
+ for (int j = i; j <= n; j++)
+ if (map[i] >= 0 && map[j] >= 0) {
+ setflag[i][j] = 1;
+ count++;
+ }
+
+ if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
+}
+
+/* ----------------------------------------------------------------------
+ init specific to this pair style
+------------------------------------------------------------------------- */
+
+void PairBOP::init_style()
+{
+ if (atom->tag_enable == 0)
+ error->all(FLERR,"Pair style BOP requires atom IDs");
+ if (force->newton_pair == 0)
+ error->all(FLERR,"Pair style BOP requires newton pair on");
+
+ // check that user sets comm->cutghostuser to 3x the max BOP cutoff
+
+ if (comm->cutghostuser < 3.0*cutmax - EPSILON) {
+ char str[128];
+ sprintf(str,"Pair style bop requires comm ghost cutoff "
+ "at least 3x larger than %g",cutmax);
+ error->all(FLERR,str);
+ }
+
+ // need a full neighbor list and neighbors of ghosts
+
+ int irequest = neighbor->request(this);
+ neighbor->requests[irequest]->half = 0;
+ neighbor->requests[irequest]->full = 1;
+ neighbor->requests[irequest]->ghost = 1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBOP::init_one(int i, int j)
+{
+ if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
+
+ int ii = map[i]+1;
+ int jj = map[j]+1;
+
+ int ij;
+ if (ii==jj) ij=ii-1;
+ else if (ii<jj) ij=ii*bop_types-ii*(ii+1)/2+jj-1;
+ else ij=jj*bop_types-jj*(jj+1)/2+ii-1;
+
+ cutghost[i][j] = rcut[ij];
+ cutghost[j][i] = cutghost[i][j];
+ cutsq[i][j] = rcut[ij]*rcut[ij];
+ cutsq[j][i] = cutsq[i][j];
+ return rcut[ij];
+}
+
+/* ----------------------------------------------------------------------
+ create BOP neighbor list from main neighbor list
+ BOP neighbor list stores neighbors of ghost atoms
+ BOP requires neighbor's of k if k is a neighbor of
+ j and j is a neighbor of i
+------------------------------------------------------------------------- */
+
+void PairBOP::gneigh()
+{
+ int i,ii;
+ int *ilist,*numneigh;
+ int **firstneigh;
+ int nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+
+ if(allocate_neigh==0) {
+ memory->create (BOP_index,nall,"BOP_index");
+ if (otfly==0) memory->create (cos_index,nall,"cos_index");
+ allocate_neigh=1;
+ }
+ else {
+ memory->grow (BOP_index,nall,"BOP_index");
+ if (otfly==0) memory->grow (cos_index,nall,"cos_index");
+ allocate_neigh=1;
+ }
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+ if(bop_step==0) {
+ maxneigh=0;
+ maxnall=0;
+ }
+ neigh_total=0;
+ cos_total=0;
+ for (ii = 0; ii < nall; ii++) {
+ if(i<nlocal) {
+ i=ilist[ii];
+ if(numneigh[i]>maxneigh) maxneigh=numneigh[i];
+ }
+ else {
+ i=ii;
+ if(numneigh[i]>maxneigh) maxneigh=numneigh[i];
+ }
+ BOP_index[i]=neigh_total;
+ neigh_total+=numneigh[i];
+ if(otfly==0) {
+ cos_index[i]=cos_total;
+ cos_total+=numneigh[i]*(numneigh[i]-1)/2;
+ }
+ }
+ maxnall=nall;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::theta()
+{
+ int i,j,k,ii,jj,kk;
+ int itype,jtype,i12;
+ int temp_ij,temp_ik,temp_ijk;
+ int n,nlocal,nall,ks;
+ int *ilist,*numneigh;
+ int *iilist;
+ int **firstneigh;
+ double rj2,rk2,rsq,ps;
+ double rj1k1,rj2k2,rj2k1,rj1k2;
+ double **x = atom->x;
+ int *type = atom->type;
+
+ nlocal = atom->nlocal;
+ nall = nlocal+atom->nghost;
+ ilist = list->ilist;
+ firstneigh = list->firstneigh;
+ numneigh = list->numneigh;
+ if(update_list!=0)
+ memory_theta_grow();
+ else
+ memory_theta_create();
+ for (ii = 0; ii < nall; ii++) {
+ if(ii<nlocal)
+ i= ilist[ii];
+ else
+ i=ii;
+ itype = map[type[i]]+1;
+
+ iilist=firstneigh[i];
+ for(jj=0;jj<numneigh[i];jj++) {
+ j=iilist[jj];
+ temp_ij=BOP_index[i]+jj;
+ jtype = map[type[j]]+1;
+
+ if(itype==jtype)
+ i12=itype-1;
+ else if(itype<jtype)
+ i12=itype*bop_types-itype*(itype+1)/2+jtype-1;
+ else
+ i12=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+ if(i12>=npairs) {
+ error->one(FLERR,"Too many atom pairs for pair bop");
+ }
+ disij[0][temp_ij]=x[j][0]-x[i][0];
+ disij[1][temp_ij]=x[j][1]-x[i][1];
+ disij[2][temp_ij]=x[j][2]-x[i][2];
+ rsq=disij[0][temp_ij]*disij[0][temp_ij]
+ +disij[1][temp_ij]*disij[1][temp_ij]
+ +disij[2][temp_ij]*disij[2][temp_ij];
+ rij[temp_ij]=sqrt(rsq);
+ if(rij[temp_ij]<=rcut[i12])
+ neigh_flag[temp_ij]=1;
+ else
+ neigh_flag[temp_ij]=0;
+ ps=rij[temp_ij]*rdr[i12]+1.0;
+ ks=(int)ps;
+
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS[temp_ij]=((pBetaS3[i12][ks-1]*ps+pBetaS2[i12][ks-1])*ps
+ +pBetaS1[i12][ks-1])*ps+pBetaS[i12][ks-1];
+ dBetaS[temp_ij]=(pBetaS6[i12][ks-1]*ps+pBetaS5[i12][ks-1])*ps
+ +pBetaS4[i12][ks-1];
+ betaP[temp_ij]=((pBetaP3[i12][ks-1]*ps+pBetaP2[i12][ks-1])*ps
+ +pBetaP1[i12][ks-1])*ps+pBetaP[i12][ks-1];
+ dBetaP[temp_ij]=(pBetaP6[i12][ks-1]*ps+pBetaP5[i12][ks-1])*ps
+ +pBetaP4[i12][ks-1];
+ repul[temp_ij]=((pRepul3[i12][ks-1]*ps+pRepul2[i12][ks-1])*ps
+ +pRepul1[i12][ks-1])*ps+pRepul[i12][ks-1];
+ dRepul[temp_ij]=(pRepul6[i12][ks-1]*ps+pRepul5[i12][ks-1])*ps
+ +pRepul4[i12][ks-1];
+ }
+ }
+ for (ii = 0; ii < nall; ii++) {
+ n=0;
+ if(ii<nlocal)
+ i= ilist[ii];
+ else
+ i=ii;
+ iilist=firstneigh[i];
+ for(jj=0;jj<numneigh[i];jj++) {
+ j=iilist[jj];
+ temp_ij=BOP_index[i]+jj;
+ rj2=rij[temp_ij]*rij[temp_ij];
+ for(kk=jj+1;kk<numneigh[i];kk++) {
+ if(cos_index[i]+n>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ temp_ik=BOP_index[i]+kk;
+ temp_ijk=cos_index[i]+n;
+ if(temp_ijk>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ rk2=rij[temp_ik]*rij[temp_ik];
+ rj1k1=rij[temp_ij]*rij[temp_ik];
+ rj2k2=rj1k1*rj1k1;
+ rj2k1=rj1k1*rij[temp_ij];
+ rj1k2=rj1k1*rij[temp_ik];
+ k=iilist[kk];
+ if(temp_ijk>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ cosAng[temp_ijk]=(disij[0][temp_ij]*disij[0][temp_ik]+disij[1][temp_ij]
+ *disij[1][temp_ik]+disij[2][temp_ij]*disij[2][temp_ik])/rj1k1;
+ dcAng[temp_ijk][0][0]=(disij[0][temp_ik]*rj1k1-cosAng[temp_ijk]
+ *disij[0][temp_ij]*rk2)/(rj2k2);
+ dcAng[temp_ijk][1][0]=(disij[1][temp_ik]*rj1k1-cosAng[temp_ijk]
+ *disij[1][temp_ij]*rk2)/(rj2k2);
+ dcAng[temp_ijk][2][0]=(disij[2][temp_ik]*rj1k1-cosAng[temp_ijk]
+ *disij[2][temp_ij]*rk2)/(rj2k2);
+ dcAng[temp_ijk][0][1]=(disij[0][temp_ij]*rj1k1-cosAng[temp_ijk]
+ *disij[0][temp_ik]*rj2)/(rj2k2);
+ dcAng[temp_ijk][1][1]=(disij[1][temp_ij]*rj1k1-cosAng[temp_ijk]
+ *disij[1][temp_ik]*rj2)/(rj2k2);
+ dcAng[temp_ijk][2][1]=(disij[2][temp_ij]*rj1k1-cosAng[temp_ijk]
+ *disij[2][temp_ik]*rj2)/(rj2k2);
+ n++;
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::theta_mod()
+{
+ if(update_list!=0)
+ memory_theta_grow();
+ else
+ memory_theta_create();
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* The formulation differs slightly to avoid negative square roots
+ in the calculation of Sigma^(1/2) of (a) Eq. 6 and (b) Eq. 11 */
+
+void PairBOP::sigmaBo()
+{
+ int nb_t,new_n_tot;
+ int n,i,j,k,kp,m,pp,kkp;
+ int iij,ji,ki;
+ int itmp,jtmp,ktmp,ltmp,mtmp;
+ int i_tag,j_tag;
+ int ngi,ngj,ngk,nglkp,ngli,nglj,ngl;
+ int ngji,ngjk,nikj,ngki,ngkj,ngjkp;
+ int ngkpk,ngkpj,ngkkp,nglk;
+ int njik,nijk,nikkp,nkp,nijkp;
+ int nkikp,njikp,nk0;
+ int njkpk,nkjkp,njkkp;
+ int jNeik,kNeii,kNeij,kNeikp;
+ int kpNeij,kpNeik;
+ int new1,new2,nlocal;
+ int inum,*ilist,*iilist,*jlist,*klist,*kplist;
+ int **firstneigh,*numneigh;
+ int temp_ji,temp_ikp,temp_ki,temp_kkp;
+ int temp_ij,temp_ik,temp_jkp,temp_kk,temp_jk;
+ int ang_ijkp,ang_ikkp,ang_jkpk,ang_kjkp;
+ int ang_ijk,ang_ikj,ang_jikp,ang_jkkp;
+ int ang_jik,ang_kikp;
+ int nb_ij,nb_ik,nb_ikp;
+ int nb_jk,nb_jkp,nb_kkp;
+ int kp_nsearch,nsearch;
+ int sig_flag,setting,ncmp,ks;
+ int itype,jtype,ktype,kptype;
+ int bt_i,bt_j,bt_ij;
+ int kp_index,same_ikp,same_jkp;
+ int same_kkp,same_jkpj;
+ double AA,BB,CC,DD,EE,EE1,FF;
+ double AAC,BBC,CCC,DDC,EEC,FFC,GGC;
+ double AACFF,UT,bndtmp,UTcom;
+ double amean,gmean0,gmean1,gmean2,ps;
+ double gfactor1,gprime1,gsqprime,factorsq;
+ double gfactorsq,gfactor2,gprime2;
+ double gfactorsq2,gsqprime2;
+ double gfactor3,gprime3,gfactor,rfactor;
+ double drfactor,gfactor4,gprime4,agpdpr3;
+ double rfactor0,rfactorrt,rfactor1rt,rfactor1;
+ double rcm1,rcm2,gcm1,gcm2,gcm3;
+ double agpdpr1,agpdpr2,app1,app2,app3,app4;
+ double dsigB1,dsigB2;
+ double part0,part1,part2,part3,part4;
+ double psign,bndtmp0,pp1;
+ double bndtmp1,bndtmp2,bndtmp3,bndtmp4,bndtmp5;
+ double ftmp[3];
+ double **x = atom->x;
+ double **f = atom->f;
+ int *tag = atom->tag;
+ int newton_pair = force->newton_pair;
+ int *type = atom->type;
+
+ nlocal = atom->nlocal;
+ int nall = nlocal+atom->nghost;
+ firstneigh = list->firstneigh;
+ numneigh = list->numneigh;
+ inum = list->inum;
+ ilist = list->ilist;
+ n=0;
+
+//loop over all local atoms
+
+ if(nb_sg>16) {
+ nb_sg=16;
+ }
+ if(nb_sg==0) {
+ nb_sg=(maxneigh)*(maxneigh/2);
+ }
+ if(allocate_sigma) {
+ destroy_sigma();
+ }
+ create_sigma(nb_sg);
+ for(itmp=0;itmp<inum;itmp++) {
+ i = ilist[itmp];
+ i_tag=tag[i];
+ itype = map[type[i]]+1;
+
+//j is loop over all neighbors of i
+
+ for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+ temp_ij=BOP_index[i]+jtmp;
+ if(neigh_flag[temp_ij]) {
+ for(m=0;m<nb_sg;m++) {
+ for(pp=0;pp<3;pp++) {
+ bt_sg[m].dAA[pp]=0.0;
+ bt_sg[m].dBB[pp]=0.0;
+ bt_sg[m].dCC[pp]=0.0;
+ bt_sg[m].dDD[pp]=0.0;
+ bt_sg[m].dEE[pp]=0.0;
+ bt_sg[m].dEE1[pp]=0.0;
+ bt_sg[m].dFF[pp]=0.0;
+ bt_sg[m].dAAC[pp]=0.0;
+ bt_sg[m].dBBC[pp]=0.0;
+ bt_sg[m].dCCC[pp]=0.0;
+ bt_sg[m].dDDC[pp]=0.0;
+ bt_sg[m].dEEC[pp]=0.0;
+ bt_sg[m].dFFC[pp]=0.0;
+ bt_sg[m].dGGC[pp]=0.0;
+ bt_sg[m].dUT[pp]=0.0;
+ bt_sg[m].dSigB1[pp]=0.0;
+ bt_sg[m].dSigB[pp]=0.0;
+ }
+ bt_sg[m].i=-1;
+ bt_sg[m].j=-1;
+ bt_sg[m].temp=-1;
+ }
+ nb_t=0;
+ iilist=firstneigh[i];
+ j=iilist[jtmp];
+ jlist=firstneigh[j];
+ for(ki=0;ki<numneigh[j];ki++) {
+ temp_ki=BOP_index[j]+ki;
+ if(x[jlist[ki]][0]==x[i][0]) {
+ if(x[jlist[ki]][1]==x[i][1]) {
+ if(x[jlist[ki]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+ j_tag=tag[j];
+ jtype = map[type[j]]+1;
+ nb_ij=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_ij].temp=temp_ij;
+ bt_sg[nb_ij].i=i;
+ bt_sg[nb_ij].j=j;
+ if(j_tag>=i_tag) {
+ if(itype==jtype)
+ iij=itype-1;
+ else if(itype<jtype)
+ iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+ else
+ iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+ for(ji=0;ji<numneigh[j];ji++) {
+ temp_ji=BOP_index[j]+ji;
+ if(x[jlist[ji]][0]==x[i][0]) {
+ if(x[jlist[ji]][1]==x[i][1]) {
+ if(x[jlist[ji]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+ nSigBk[n]=0;
+
+//AA-EE1 are the components making up Eq. 30 (a)
+
+ AA=0.0;
+ BB=0.0;
+ CC=0.0;
+ DD=0.0;
+ EE=0.0;
+ EE1=0.0;
+
+//FF is the Beta_sigma^2 term
+
+ FF=betaS[temp_ij]*betaS[temp_ij];
+
+//agpdpr1 is derivative of FF w.r.t. r_ij
+
+ agpdpr1=2.0*betaS[temp_ij]*dBetaS[temp_ij]/rij[temp_ij];
+
+//dXX derivatives are taken with respect to all pairs contributing to the energy
+//nb_ij is derivative w.r.t. ij pair
+
+ bt_sg[nb_ij].dFF[0]=agpdpr1*disij[0][temp_ij];
+ bt_sg[nb_ij].dFF[1]=agpdpr1*disij[1][temp_ij];
+ bt_sg[nb_ij].dFF[2]=agpdpr1*disij[2][temp_ij];
+
+//k is loop over all neighbors of i again with j neighbor of i
+
+ for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+ temp_ik=BOP_index[i]+ktmp;
+ if(neigh_flag[temp_ik]) {
+ if(ktmp!=jtmp) {
+ if(jtmp<ktmp) {
+ njik=jtmp*(2*numneigh[i]-jtmp-1)/2+(ktmp-jtmp)-1;
+ ngj=0;
+ ngk=1;
+ }
+ else {
+ njik=ktmp*(2*numneigh[i]-ktmp-1)/2+(jtmp-ktmp)-1;
+ ngj=1;
+ ngk=0;
+ }
+ k=iilist[ktmp];
+ ktype = map[type[k]]+1;
+
+//find neighbor of k that is equal to i
+
+ klist=firstneigh[k];
+ for(kNeii=0;kNeii<numneigh[k];kNeii++) {
+ temp_ki=BOP_index[k]+kNeii;
+ if(x[klist[kNeii]][0]==x[i][0]) {
+ if(x[klist[kNeii]][1]==x[i][1]) {
+ if(x[klist[kNeii]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+
+//find neighbor of i that is equal to k
+
+ for(jNeik=0;jNeik<numneigh[j];jNeik++) {
+ temp_jk=BOP_index[j]+jNeik;
+ if(x[jlist[jNeik]][0]==x[k][0]) {
+ if(x[jlist[jNeik]][1]==x[k][1]) {
+ if(x[jlist[jNeik]][2]==x[k][2]) {
+ break;
+ }
+ }
+ }
+ }
+
+//find neighbor of k that is equal to j
+
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ nk0=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ nk0=nSigBk[n]-1;
+ itypeSigBk[n][nk0]=k;
+ }
+ nb_ik=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_ik].temp=temp_ik;
+ bt_sg[nb_ik].i=i;
+ bt_sg[nb_ik].j=k;
+ nb_jk=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jk].temp=temp_jk;
+ bt_sg[nb_jk].i=j;
+ bt_sg[nb_jk].j=k;
+ ang_jik=cos_index[i]+njik;
+ gmean0=sigma_g0[jtype-1][itype-1][ktype-1];
+ gmean1=sigma_g1[jtype-1][itype-1][ktype-1];
+ gmean2=sigma_g2[jtype-1][itype-1][ktype-1];
+ amean=cosAng[ang_jik];
+ gfactor1=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gfactorsq=gfactor1*gfactor1;
+ gprime1=gmean1+2.0*gmean2*amean;
+ gsqprime=2.0*gfactor1*gprime1;
+
+//AA is Eq. 34 (a) or Eq. 10 (c) for the i atom
+//1st CC is Eq. 11 (c) for i atom where j & k=neighbor of i
+
+ AA=AA+gfactorsq*betaS[temp_ik]*betaS[temp_ik];
+ CC=CC+gfactorsq*betaS[temp_ik]*betaS[temp_ik]*betaS[temp_ik]*betaS[temp_ik];
+
+//agpdpr1 is derivative of AA w.r.t. Beta(rik)
+//agpdpr2 is derivative of CC 1st term w.r.t. Beta(rik)
+//app1 is derivative of AA w.r.t. cos(theta_jik)
+//app2 is derivative of CC 1st term w.r.t. cos(theta_jik)
+
+ agpdpr1=2.0*gfactorsq*betaS[temp_ik]*dBetaS[temp_ik]/rij[temp_ik];
+ agpdpr1=2.0*betaS[temp_ik]*betaS[temp_ik]*agpdpr1;
+ app1=betaS[temp_ik]*betaS[temp_ik]*gsqprime;
+ app1=betaS[temp_ik]*betaS[temp_ik]*app1;
+ bt_sg[nb_ij].dAA[0]+=
+ app1*dcAng[ang_jik][0][ngj];
+ bt_sg[nb_ij].dAA[1]+=
+ app1*dcAng[ang_jik][1][ngj];
+ bt_sg[nb_ij].dAA[2]+=
+ app1*dcAng[ang_jik][2][ngj];
+ bt_sg[nb_ij].dCC[0]+=
+ app2*dcAng[ang_jik][0][ngj];
+ bt_sg[nb_ij].dCC[1]+=
+ app2*dcAng[ang_jik][1][ngj];
+ bt_sg[nb_ij].dCC[2]+=
+ app2*dcAng[ang_jik][2][ngj];
+ bt_sg[nb_ik].dAA[0]+=
+ app1*dcAng[ang_jik][0][ngk]
+ +agpdpr1*disij[0][temp_ik];
+ bt_sg[nb_ik].dAA[1]+=
+ app1*dcAng[ang_jik][1][ngk]
+ +agpdpr1*disij[1][temp_ik];
+ bt_sg[nb_ik].dAA[2]+=
+ app1*dcAng[ang_jik][2][ngk]
+ +agpdpr1*disij[2][temp_ik];
+ bt_sg[nb_ik].dCC[0]+=
+ app2*dcAng[ang_jik][0][ngk]
+ +agpdpr2*disij[0][temp_ik];
+ bt_sg[nb_ik].dCC[1]+=
+ app2*dcAng[ang_jik][1][ngk]
+ +agpdpr2*disij[1][temp_ik];
+ bt_sg[nb_ik].dCC[2]+=
+ app2*dcAng[ang_jik][2][ngk]
+ +agpdpr2*disij[2][temp_ik];
+
+//k' is loop over neighbors all neighbors of j with k a neighbor
+//of i and j a neighbor of i and determine which k' is k
+
+ kp_index=0;
+ for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+ temp_jkp=BOP_index[j]+ltmp;
+ kp=jlist[ltmp];
+ if(x[kp][0]==x[k][0]) {
+ if(x[kp][1]==x[k][1]) {
+ if(x[kp][2]==x[k][2]) {
+ kp_index=1;
+ break;
+ }
+ }
+ }
+ }
+ if(kp_index) {
+
+//loop over neighbors of k
+
+ for(mtmp=0;mtmp<numneigh[k];mtmp++) {
+ kp=klist[mtmp];
+ if(x[kp][0]==x[j][0]) {
+ if(x[kp][1]==x[j][1]) {
+ if(x[kp][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(ki<ltmp) {
+ nijk=ki*(2*numneigh[j]-ki-1)/2+(ltmp-ki)-1;
+ ngji=0;
+ ngjk=1;
+ }
+ else {
+ nijk=ltmp*(2*numneigh[j]-ltmp-1)/2+(ki-ltmp)-1;
+ ngji=1;
+ ngjk=0;
+ }
+ if(kNeii<mtmp) {
+ nikj=kNeii*(2*numneigh[k]-kNeii-1)/2+(mtmp-kNeii)-1;
+ ngki=0;
+ ngkj=1;
+ }
+ else {
+ nikj=mtmp*(2*numneigh[k]-mtmp-1)/2+(kNeii-mtmp)-1;
+ ngki=1;
+ ngkj=0;
+ }
+ ang_ijk=cos_index[j]+nijk;
+ gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+ amean=cosAng[ang_ijk];
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[itype-1][ktype-1][jtype-1];
+ gmean1=sigma_g1[itype-1][ktype-1][jtype-1];
+ gmean2=sigma_g2[itype-1][ktype-1][jtype-1];
+ ang_ikj=cos_index[k]+nikj;
+ amean=cosAng[ang_ikj];
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactor=betaS[temp_ik]*betaS[temp_jkp];
+
+//EE1 is (b) Eq. 12
+
+ EE1=EE1+gfactor*rfactor;
+
+//rcm2 is derivative of EE1 w.r.t Beta(r_jk')
+//gcm1 is derivative of EE1 w.r.t cos(theta_jik)
+//gcm2 is derivative of EE1 w.r.t cos(theta_ijk)
+//gcm3 is derivative of EE1 w.r.t cos(theta_ikj)
+
+ rcm1=gfactor*betaS[temp_jkp]*dBetaS[temp_ik]/rij[temp_ik];
+ rcm2=gfactor*betaS[temp_ik]*dBetaS[temp_jkp]/rij[temp_jkp];
+ gcm1=rfactor*gprime1*gfactor2*gfactor3;
+ gcm2=rfactor*gfactor1*gprime2*gfactor3;
+ gcm3=rfactor*gfactor1*gfactor2*gprime3;
+ bt_sg[nb_ij].dEE1[0]+=
+ gcm1*dcAng[ang_jik][0][ngj]
+ -gcm2*dcAng[ang_ijk][0][ngji];
+ bt_sg[nb_ij].dEE1[1]+=
+ gcm1*dcAng[ang_jik][1][ngj]
+ -gcm2*dcAng[ang_ijk][1][ngji];
+ bt_sg[nb_ij].dEE1[2]+=
+ gcm1*dcAng[ang_jik][2][ngj]
+ -gcm2*dcAng[ang_ijk][2][ngji];
+ bt_sg[nb_ik].dEE1[0]+=
+ gcm1*dcAng[ang_jik][0][ngk]
+ +rcm1*disij[0][temp_ik]
+ -gcm3*dcAng[ang_ikj][0][ngki];
+ bt_sg[nb_ik].dEE1[1]+=
+ gcm1*dcAng[ang_jik][1][ngk]
+ +rcm1*disij[1][temp_ik]
+ -gcm3*dcAng[ang_ikj][1][ngki];
+ bt_sg[nb_ik].dEE1[2]+=
+ gcm1*dcAng[ang_jik][2][ngk]
+ +rcm1*disij[2][temp_ik]
+ -gcm3*dcAng[ang_ikj][2][ngki];
+ bt_sg[nb_jk].dEE1[0]+=
+ gcm2*dcAng[ang_ijk][0][ngjk]
+ +rcm2*disij[0][temp_jkp]
+ -gcm3*dcAng[ang_ikj][0][ngkj];
+ bt_sg[nb_jk].dEE1[1]+=
+ gcm2*dcAng[ang_ijk][1][ngjk]
+ +rcm2*disij[1][temp_jkp]
+ -gcm3*dcAng[ang_ikj][1][ngkj];
+ bt_sg[nb_jk].dEE1[2]+=
+ gcm2*dcAng[ang_ijk][2][ngjk]
+ +rcm2*disij[2][temp_jkp]
+ -gcm3*dcAng[ang_ikj][2][ngkj];
+ }
+
+// k and k' and j are all different neighbors of i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=jtmp) {
+ temp_ikp=BOP_index[i]+ltmp;
+ if(neigh_flag[temp_ikp]) {
+ kp=iilist[ltmp];
+ kptype = map[type[kp]]+1;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(jtmp<ltmp) {
+ njikp=jtmp*(2*numneigh[i]-jtmp-1)/2+(ltmp-jtmp)-1;
+ nglj=0;
+ ngl=1;
+ }
+ else {
+ njikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(jtmp-ltmp)-1;
+ nglj=1;
+ ngl=0;
+ }
+ if(ktmp<ltmp) {
+ nkikp=ktmp*(2*numneigh[i]-ktmp-1)/2+(ltmp-ktmp)-1;
+ nglk=0;
+ nglkp=1;
+ }
+ else {
+ nkikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(ktmp-ltmp)-1;
+ nglk=1;
+ nglkp=0;
+ }
+ ang_jikp=cos_index[i]+njikp;
+ nb_ikp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_ikp].temp=temp_ikp;
+ bt_sg[nb_ikp].i=i;
+ bt_sg[nb_ikp].j=kp;
+ gmean0=sigma_g0[jtype-1][itype-1][kptype-1];
+ gmean1=sigma_g1[jtype-1][itype-1][kptype-1];
+ gmean2=sigma_g2[jtype-1][itype-1][kptype-1];
+ amean=cosAng[ang_jikp];
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[ktype-1][itype-1][kptype-1];
+ gmean1=sigma_g1[ktype-1][itype-1][kptype-1];
+ gmean2=sigma_g2[ktype-1][itype-1][kptype-1];
+ ang_kikp=cos_index[i]+nkikp;
+ amean=cosAng[ang_kikp];
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactorrt=betaS[temp_ik]*betaS[temp_ikp];
+ rfactor=rfactorrt*rfactorrt;
+
+//2nd CC is second term of Eq. 11 (c) for i atom where j , k & k' =neighbor of i
+
+ CC=CC+2.0*gfactor*rfactor;
+
+//agpdpr1 is derivative of CC 2nd term w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of CC 2nd term w.r.t. Beta(r_ik')
+//app1 is derivative of CC 2nd term w.r.t. cos(theta_jik)
+//app2 is derivative of CC 2nd term w.r.t. cos(theta_jik')
+//app3 is derivative of CC 2nd term w.r.t. cos(theta_kik')
+
+ agpdpr1=4.0*gfactor*rfactorrt*betaS[temp_ikp]
+ *dBetaS[temp_ik]/rij[temp_ik];
+ agpdpr2=4.0*gfactor*rfactorrt*betaS[temp_ik]
+ *dBetaS[temp_ikp]/rij[temp_ikp];
+ app1=2.0*rfactor*gfactor2*gfactor3*gprime1;
+ app2=2.0*rfactor*gfactor1*gfactor3*gprime2;
+ app3=2.0*rfactor*gfactor1*gfactor2*gprime3;
+ bt_sg[nb_ij].dCC[0]+=
+ app1*dcAng[ang_jik][0][ngj]
+ +app2*dcAng[ang_jikp][0][nglj];
+ bt_sg[nb_ij].dCC[1]+=
+ app1*dcAng[ang_jik][1][ngj]
+ +app2*dcAng[ang_jikp][1][nglj];
+ bt_sg[nb_ij].dCC[2]+=
+ app1*dcAng[ang_jik][2][ngj]
+ +app2*dcAng[ang_jikp][2][nglj];
+ bt_sg[nb_ik].dCC[0]+=
+ app1*dcAng[ang_jik][0][ngk]
+ +app3*dcAng[ang_kikp][0][nglk]
+ +agpdpr1*disij[0][temp_ik];
+ bt_sg[nb_ik].dCC[1]+=
+ app1*dcAng[ang_jik][1][ngk]
+ +app3*dcAng[ang_kikp][1][nglk]
+ +agpdpr1*disij[1][temp_ik];
+ bt_sg[nb_ik].dCC[2]+=
+ app1*dcAng[ang_jik][2][ngk]
+ +app3*dcAng[ang_kikp][2][nglk]
+ +agpdpr1*disij[2][temp_ik];
+ bt_sg[nb_ikp].dCC[0]+=
+ app2*dcAng[ang_jikp][0][ngl]
+ +app3*dcAng[ang_kikp][0][nglkp]
+ +agpdpr2*disij[0][temp_ikp];
+ bt_sg[nb_ikp].dCC[1]+=
+ app2*dcAng[ang_jikp][1][ngl]
+ +app3*dcAng[ang_kikp][1][nglkp]
+ +agpdpr2*disij[1][temp_ikp];
+ bt_sg[nb_ikp].dCC[2]+=
+ app2*dcAng[ang_jikp][2][ngl]
+ +app3*dcAng[ang_kikp][2][nglkp]
+ +agpdpr2*disij[2][temp_ikp];
+ }
+ }
+ }
+
+// j and k are different neighbors of i and k' is a neighbor k not equal to i
+
+ for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+ temp_kkp=BOP_index[k]+ltmp;
+ if(neigh_flag[temp_kkp]) {
+ kp=klist[ltmp];;
+ kptype = map[type[kp]]+1;
+ same_ikp=0;
+ same_jkp=0;
+ if(x[i][0]==x[kp][0]) {
+ if(x[i][1]==x[kp][1]) {
+ if(x[i][2]==x[kp][2]) {
+ same_ikp=1;
+ }
+ }
+ }
+ if(x[j][0]==x[kp][0]) {
+ if(x[j][1]==x[kp][1]) {
+ if(x[j][2]==x[kp][2]) {
+ same_jkp=1;
+ }
+ }
+ }
+ if(!same_ikp&&!same_jkp) {
+ if(kNeii<ltmp) {
+ nikkp=kNeii*(2*numneigh[k]-kNeii-1)/2+(ltmp-kNeii)-1;
+ nglkp=1;
+ ngli=0;
+ }
+ else {
+ nikkp=ltmp*(2*numneigh[k]-ltmp-1)/2+(kNeii-ltmp)-1;
+ nglkp=0;
+ ngli=1;
+ }
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ sig_flag=1;
+ nkp=nsearch;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ nkp=nSigBk[n]-1;
+ itypeSigBk[n][nkp]=kp;
+ }
+ ang_ikkp=cos_index[k]+nikkp;
+ nb_kkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_kkp].temp=temp_kkp;
+ bt_sg[nb_kkp].i=k;
+ bt_sg[nb_kkp].j=kp;
+ gmean0=sigma_g0[itype-1][ktype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][ktype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][ktype-1][kptype-1];
+ amean=cosAng[ang_ikkp];
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gfactorsq2=gfactor2*gfactor2;
+ gsqprime2=2.0*gfactor2*gprime2;
+ gfactor=gfactorsq*gfactorsq2;
+ rfactorrt=betaS[temp_ik]*betaS[temp_kkp];
+ rfactor=rfactorrt*rfactorrt;
+
+//3rd CC is third term of Eq. 11 (c) for i atom
+//where j , k =neighbor of i & k' =neighbor of k
+
+ CC=CC+gfactor*rfactor;
+ agpdpr1=2.0*gfactor*rfactorrt*betaS[temp_kkp]
+ *dBetaS[temp_ik]/rij[temp_ik];
+ agpdpr2=2.0*gfactor*rfactorrt*betaS[temp_ik]
+ *dBetaS[temp_kkp]/rij[temp_kkp];
+ app1=rfactor*gfactorsq2*gsqprime;
+ app2=rfactor*gfactorsq*gsqprime2;
+ bt_sg[nb_ij].dCC[0]+=
+ app1*dcAng[ang_jik][0][ngj];
+ bt_sg[nb_ij].dCC[1]+=
+ app1*dcAng[ang_jik][1][ngj];
+ bt_sg[nb_ij].dCC[2]+=
+ app1*dcAng[ang_jik][2][ngj];
+ bt_sg[nb_ik].dCC[0]+=
+ app1*dcAng[ang_jik][0][ngk]
+ +agpdpr1*disij[0][temp_ik]
+ -app2*dcAng[ang_ikkp][0][ngli];
+ bt_sg[nb_ik].dCC[1]+=
+ app1*dcAng[ang_jik][1][ngk]
+ +agpdpr1*disij[1][temp_ik]
+ -app2*dcAng[ang_ikkp][1][ngli];
+ bt_sg[nb_ik].dCC[2]+=
+ app1*dcAng[ang_jik][2][ngk]
+ +agpdpr1*disij[2][temp_ik]
+ -app2*dcAng[ang_ikkp][2][ngli];
+ bt_sg[nb_kkp].dCC[0]+=
+ app2*dcAng[ang_ikkp][0][nglkp]
+ +agpdpr2*disij[0][temp_kkp];
+ bt_sg[nb_kkp].dCC[1]+=
+ app2*dcAng[ang_ikkp][1][nglkp]
+ +agpdpr2*disij[1][temp_kkp];
+ bt_sg[nb_kkp].dCC[2]+=
+ app2*dcAng[ang_ikkp][2][nglkp]
+ +agpdpr2*disij[2][temp_kkp];
+
+ }
+ }
+ }
+
+ //j and k are different neighbors of i and k' is a neighbor j not equal to k
+
+ kplist=firstneigh[kp];
+ for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+ sig_flag=0;
+ temp_jkp=BOP_index[j]+ltmp;
+ if(neigh_flag[temp_jkp]) {
+ kp=jlist[ltmp];
+ kptype = map[type[kp]]+1;
+ same_jkp=0;
+ same_kkp=0;
+ for(kpNeij=0;kpNeij<numneigh[kp];kpNeij++) {
+ if(x[j][0]==x[kp][0]) {
+ if(x[j][1]==x[kp][1]) {
+ if(x[j][2]==x[kp][2]) {
+ same_jkp=1;
+ break;
+ }
+ }
+ }
+ }
+ for(kpNeik=0;kpNeik<numneigh[kp];kpNeik++) {
+ if(x[k][0]==x[kp][0]) {
+ if(x[k][1]==x[kp][1]) {
+ if(x[k][2]==x[kp][2]) {
+ same_kkp=1;
+ break;
+ }
+ }
+ }
+ }
+ if(!same_kkp&&!same_jkp) {
+ for(kNeikp=0;kNeikp<numneigh[k];kNeikp++) {
+ temp_kkp=BOP_index[k]+kNeikp;
+ kkp=klist[kNeikp];
+ if(x[kkp][0]==x[kp][0]) {
+ if(x[kkp][1]==x[kp][1]) {
+ if(x[kkp][2]==x[kp][2]) {
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==1) {
+ for(nsearch=0;nsearch<numneigh[kp];nsearch++) {
+ kp_nsearch=BOP_index[kp]+nsearch;
+ ncmp=kplist[nsearch];
+ if(x[ncmp][0]==x[j][0]) {
+ if(x[ncmp][1]==x[j][1]) {
+ if(x[ncmp][2]==x[j][2]) {
+ kpNeij=nsearch;
+ }
+ }
+ }
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ kpNeik=nsearch;
+ }
+ }
+ }
+ }
+ if(ji<ltmp) {
+ nijkp=(ji)*numneigh[j]-(ji+1)*(ji+2)/2+ltmp;
+ ngji=0;
+ ngjkp=1;
+ }
+ else {
+ nijkp=(ltmp)*numneigh[j]-(ltmp+1)*(ltmp+2)/2+ji;
+ ngji=1;
+ ngjkp=0;
+ }
+ if(kNeii<kNeikp) {
+ nikkp=(kNeii)*numneigh[k]-(kNeii+1)*(kNeii+2)/2+kNeikp;
+ ngki=0;
+ ngkkp=1;
+ }
+ else {
+ nikkp=(kNeikp)*numneigh[k]-(kNeikp+1)*(kNeikp+2)/2+kNeii;
+ ngki=1;
+ ngkkp=0;
+ }
+ if(kpNeij<kpNeik) {
+ njkpk=(kpNeij)*numneigh[kp]-(kpNeij+1)*(kpNeij+2)/2+kpNeik;
+ ngkpj=0;
+ ngkpk=1;
+ }
+ else {
+ njkpk=(kpNeik)*numneigh[kp]-(kpNeik+1)*(kpNeik+2)/2+kpNeij;
+ ngkpj=1;
+ ngkpk=0;
+ }
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ nkp=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ nkp=nSigBk[n]-1;
+ itypeSigBk[n][nkp]=kp;
+ }
+ ang_ijkp=cos_index[j]+nijkp;
+ ang_ikkp=cos_index[k]+nikkp;
+ ang_jkpk=cos_index[kp]+njkpk;
+ nb_jkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jkp].temp=temp_jkp;
+ bt_sg[nb_jkp].i=j;
+ bt_sg[nb_jkp].j=kp;
+ nb_kkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_kkp].temp=temp_kkp;
+ bt_sg[nb_kkp].i=k;
+ bt_sg[nb_kkp].j=kp;
+ gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+ amean=cosAng[ang_ijkp];
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[itype-1][ktype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][ktype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][ktype-1][kptype-1];
+ amean=cosAng[ang_ikkp];
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[jtype-1][kptype-1][ktype-1];
+ gmean1=sigma_g1[jtype-1][kptype-1][ktype-1];
+ gmean2=sigma_g2[jtype-1][kptype-1][ktype-1];
+ amean=cosAng[ang_jkpk];
+ gfactor4=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime4=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3*gfactor4;
+ rfactor0=(betaS[temp_ik]+small2)*(betaS[temp_jkp]+small2)
+ *(betaS[temp_kkp]+small2);
+ rfactor=pow(rfactor0,2.0/3.0);
+ drfactor=2.0/3.0*pow(rfactor0,-1.0/3.0);
+
+//EE is Eq. 25(notes)
+
+ EE=EE+gfactor*rfactor;
+
+//agpdpr1 is derivative of agpdpr1 w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of agpdpr1 w.r.t. Beta(r_jk')
+//agpdpr3 is derivative of agpdpr1 w.r.t. Beta(r_kk')
+//app1 is derivative of agpdpr1 w.r.t. cos(theta_jik)
+//app2 is derivative of agpdpr1 w.r.t. cos(theta_ijk')
+//app3 is derivative of agpdpr1 w.r.t. cos(theta_ikk')
+//app4 is derivative of agpdpr1 w.r.t. cos(theta_jk'k)
+
+ agpdpr1=gfactor*drfactor*(betaS[temp_jkp]+small2)*(betaS[temp_kkp]
+ +small2)*dBetaS[temp_ik]/rij[temp_ik];
+ agpdpr2=gfactor*drfactor*(betaS[temp_ik]+small2)*(betaS[temp_kkp]
+ +small2)*dBetaS[temp_jkp]/rij[temp_jkp];
+ agpdpr3=gfactor*drfactor*(betaS[temp_ik]+small2)*(betaS[temp_jkp]
+ +small2)*dBetaS[temp_kkp]/rij[temp_kkp];
+ app1=rfactor*gfactor2*gfactor3*gfactor4*gprime1;
+ app2=rfactor*gfactor1*gfactor3*gfactor4*gprime2;
+ app3=rfactor*gfactor1*gfactor2*gfactor4*gprime3;
+ app4=rfactor*gfactor1*gfactor2*gfactor3*gprime4;
+ bt_sg[nb_ij].dEE[0]+=
+ app1*dcAng[ang_jik][0][ngj]
+ -app2*dcAng[ang_ijkp][0][ngji];
+ bt_sg[nb_ij].dEE[1]+=
+ app1*dcAng[ang_jik][1][ngj]
+ -app2*dcAng[ang_ijkp][1][ngji];
+ bt_sg[nb_ij].dEE[2]+=
+ app1*dcAng[ang_jik][2][ngj]
+ -app2*dcAng[ang_ijkp][2][ngji];
+ bt_sg[nb_ik].dEE[0]+=
+ app1*dcAng[ang_jik][0][ngk]
+ +agpdpr1*disij[0][temp_ik]
+ -app3*dcAng[ang_ikkp][0][ngki];
+ bt_sg[nb_ik].dEE[1]+=
+ app1*dcAng[ang_jik][1][ngk]
+ +agpdpr1*disij[1][temp_ik]
+ -app3*dcAng[ang_ikkp][1][ngki];
+ bt_sg[nb_ik].dEE[2]+=
+ app1*dcAng[ang_jik][2][ngk]
+ +agpdpr1*disij[2][temp_ik]
+ -app3*dcAng[ang_ikkp][2][ngki];
+ bt_sg[nb_jkp].dEE[0]+=
+ app2*dcAng[ang_ijkp][0][ngjkp]
+ +agpdpr2*disij[0][temp_jkp]
+ -app4*dcAng[ang_jkpk][0][ngkpj];
+ bt_sg[nb_jkp].dEE[1]+=
+ app2*dcAng[ang_ijkp][1][ngjkp]
+ +agpdpr2*disij[1][temp_jkp]
+ -app4*dcAng[ang_jkpk][1][ngkpj];
+ bt_sg[nb_jkp].dEE[2]+=
+ app2*dcAng[ang_ijkp][2][ngjkp]
+ +agpdpr2*disij[2][temp_jkp]
+ -app4*dcAng[ang_jkpk][2][ngkpj];
+ bt_sg[nb_kkp].dEE[0]+=
+ app3*dcAng[ang_ikkp][0][ngkkp]
+ +agpdpr3*disij[0][temp_kkp]
+ -app4*dcAng[ang_jkpk][0][ngkpk];
+ bt_sg[nb_kkp].dEE[1]+=
+ app3*dcAng[ang_ikkp][1][ngkkp]
+ +agpdpr3*disij[1][temp_kkp]
+ -app4*dcAng[ang_jkpk][1][ngkpk];
+ bt_sg[nb_kkp].dEE[2]+=
+ app3*dcAng[ang_ikkp][2][ngkkp]
+ +agpdpr3*disij[2][temp_kkp]
+ -app4*dcAng[ang_jkpk][2][ngkpk];
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+//j is a neighbor of i and k is a neighbor of j not equal to i
+
+ for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+ if(ktmp!=ji) {
+ if(ktmp<ji) {
+ njik=ktmp*(2*numneigh[j]-ktmp-1)/2+(ji-ktmp)-1;
+ ngi=1;
+ ngk=0;
+ }
+ else {
+ njik=ji*(2*numneigh[j]-ji-1)/2+(ktmp-ji)-1;
+ ngi=0;
+ ngk=1;
+ }
+ temp_jk=BOP_index[j]+ktmp;
+ if(neigh_flag[temp_jk]) {
+ k=jlist[ktmp];
+ ktype=map[type[k]]+1;
+ klist=firstneigh[k];
+
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ new1=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ new1=nSigBk[n]-1;
+ itypeSigBk[n][new1]=k;
+ }
+ ang_ijk=cos_index[j]+njik;
+ nb_jk=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jk].temp=temp_jk;
+ bt_sg[nb_jk].i=j;
+ bt_sg[nb_jk].j=k;
+ gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+ amean=cosAng[ang_ijk];
+ gfactor1=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime1=gmean1+2.0*gmean2*amean;
+ gfactorsq=gfactor1*gfactor1;
+ gsqprime=2.0*gfactor1*gprime1;
+ rfactor1rt=betaS[temp_jk]*betaS[temp_jk];
+ rfactor1=rfactor1rt*rfactor1rt;
+
+//BB is Eq. 34 (a) or Eq. 10 (c) for the j atom
+//1st DD is Eq. 11 (c) for j atom where i & k=neighbor of j
+
+ BB=BB+gfactorsq*rfactor1rt;
+ DD=DD+gfactorsq*rfactor1;
+
+//agpdpr1 is derivative of BB w.r.t. Beta(r_jk)
+//app1 is derivative of BB w.r.t. cos(theta_ijk)
+
+ agpdpr1=2.0*gfactorsq*betaS[temp_jk]*dBetaS[temp_jk]/rij[temp_jk];
+ app1=rfactor1rt*gsqprime;
+ bt_sg[nb_ij].dBB[0]-=
+ app1*dcAng[ang_ijk][0][ngi];
+ bt_sg[nb_ij].dBB[1]-=
+ app1*dcAng[ang_ijk][1][ngi];
+ bt_sg[nb_ij].dBB[2]-=
+ app1*dcAng[ang_ijk][2][ngi];
+ bt_sg[nb_ij].dDD[0]-=
+ app2*dcAng[ang_ijk][0][ngi];
+ bt_sg[nb_ij].dDD[1]-=
+ app2*dcAng[ang_ijk][1][ngi];
+ bt_sg[nb_ij].dDD[2]-=
+ app2*dcAng[ang_ijk][2][ngi];
+ bt_sg[nb_jk].dBB[0]+=
+ app1*dcAng[ang_ijk][0][ngk]
+ +agpdpr1*disij[0][temp_jk];
+ bt_sg[nb_jk].dBB[1]+=
+ app1*dcAng[ang_ijk][1][ngk]
+ +agpdpr1*disij[1][temp_jk];
+ bt_sg[nb_jk].dBB[2]+=
+ app1*dcAng[ang_ijk][2][ngk]
+ +agpdpr1*disij[2][temp_jk];
+ bt_sg[nb_jk].dDD[0]+=
+ app2*dcAng[ang_ijk][0][ngk]
+ +agpdpr2*disij[0][temp_jk];
+ bt_sg[nb_jk].dDD[1]+=
+ app2*dcAng[ang_ijk][1][ngk]
+ +agpdpr2*disij[1][temp_jk];
+ bt_sg[nb_jk].dDD[2]+=
+ app2*dcAng[ang_ijk][2][ngk]
+ +agpdpr2*disij[2][temp_jk];
+
+//j is a neighbor of i, k and k' prime different neighbors of j not equal to i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=ji) {
+ temp_jkp=BOP_index[j]+ltmp;
+ if(neigh_flag[temp_jkp]) {
+ kp=jlist[ltmp];
+ kptype=map[type[kp]]+1;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ new2=nsearch;
+ break;
+ }
+ }
+ }
+ }
+ if(ji<ltmp) {
+ nijkp=ji*(2*numneigh[j]-ji-1)/2+(ltmp-ji)-1;
+ ngli=0;
+ ngl=1;
+ }
+ else {
+ nijkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ji-ltmp)-1;
+ ngli=1;
+ ngl=0;
+ }
+ if(ktmp<ltmp) {
+ nkjkp=ktmp*(2*numneigh[j]-ktmp-1)/2+(ltmp-ktmp)-1;
+ ngjk=0;
+ ngjkp=1;
+ }
+ else {
+ nkjkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ktmp-ltmp)-1;
+ ngjk=1;
+ ngjkp=0;
+ }
+ ang_ijkp=cos_index[j]+nijkp;
+ ang_kjkp=cos_index[j]+nkjkp;
+ gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+ amean=cosAng[ang_ijkp];
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[ktype-1][jtype-1][kptype-1];
+ gmean1=sigma_g1[ktype-1][jtype-1][kptype-1];
+ gmean2=sigma_g2[ktype-1][jtype-1][kptype-1];
+ amean=cosAng[ang_kjkp];
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactorrt=betaS[temp_jk]*betaS[temp_jkp];
+ rfactor=rfactorrt*rfactorrt;
+
+//2nd DD is Eq. 11 (c) for j atom where i , k & k'=neighbor of j
+
+ DD=DD+2.0*gfactor*rfactor;
+
+//agpdpr1 is derivative of DD w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of DD w.r.t. Beta(r_jk')
+//app1 is derivative of DD w.r.t. cos(theta_ijk)
+//app2 is derivative of DD w.r.t. cos(theta_ijkp)
+//app3 is derivative of DD w.r.t. cos(theta_kjkp)
+
+ agpdpr1=4.0*gfactor*rfactorrt*betaS[temp_jkp]
+ *dBetaS[temp_jk]/rij[temp_jk];
+ agpdpr2=4.0*gfactor*rfactorrt*betaS[temp_jk]
+ *dBetaS[temp_jkp]/rij[temp_jkp];
+ app1=2.0*rfactor*gfactor2*gfactor3*gprime1;
+ app2=2.0*rfactor*gfactor1*gfactor3*gprime2;
+ app3=2.0*rfactor*gfactor1*gfactor2*gprime3;
+ bt_sg[nb_ij].dDD[0]-=
+ app1*dcAng[ang_ijk][0][ngi]
+ +app2*dcAng[ang_ijkp][0][ngli];
+ bt_sg[nb_ij].dDD[1]-=
+ app1*dcAng[ang_ijk][1][ngi]
+ +app2*dcAng[ang_ijkp][1][ngli];
+ bt_sg[nb_ij].dDD[2]-=
+ app1*dcAng[ang_ijk][2][ngi]
+ +app2*dcAng[ang_ijkp][2][ngli];
+ bt_sg[nb_jk].dDD[0]+=
+ app1*dcAng[ang_ijk][0][ngk]
+ +app3*dcAng[ang_kjkp][0][ngjk]
+ +agpdpr1*disij[0][temp_jk];
+ bt_sg[nb_jk].dDD[1]+=
+ app1*dcAng[ang_ijk][1][ngk]
+ +app3*dcAng[ang_kjkp][1][ngjk]
+ +agpdpr1*disij[1][temp_jk];
+ bt_sg[nb_jk].dDD[2]+=
+ app1*dcAng[ang_ijk][2][ngk]
+ +app3*dcAng[ang_kjkp][2][ngjk]
+ +agpdpr1*disij[2][temp_jk];
+ bt_sg[nb_jkp].dDD[0]+=
+ app2*dcAng[ang_ijkp][0][ngl]
+ +app3*dcAng[ang_kjkp][0][ngjkp]
+ +agpdpr2*disij[0][temp_jkp];
+ bt_sg[nb_jkp].dDD[1]+=
+ app2*dcAng[ang_ijkp][1][ngl]
+ +app3*dcAng[ang_kjkp][1][ngjkp]
+ +agpdpr2*disij[1][temp_jkp];
+ bt_sg[nb_jkp].dDD[2]+=
+ app2*dcAng[ang_ijkp][2][ngl]
+ +app3*dcAng[ang_kjkp][2][ngjkp]
+ +agpdpr2*disij[2][temp_jkp];
+ }
+ }
+ }
+
+//j is a neighbor of i, k is a neighbor of j not equal to i and k'
+//is a neighbor of k not equal to j or i
+
+ for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+ temp_kkp=BOP_index[k]+ltmp;
+ if(neigh_flag[temp_kkp]) {
+ kp=klist[ltmp];
+ kptype=map[type[kp]]+1;
+ same_ikp=0;
+ same_jkp=0;
+ if(x[i][0]==x[kp][0]) {
+ if(x[i][1]==x[kp][1]) {
+ if(x[i][2]==x[kp][2]) {
+ same_ikp=1;
+ }
+ }
+ }
+ if(x[j][0]==x[kp][0]) {
+ if(x[j][1]==x[kp][1]) {
+ if(x[j][2]==x[kp][2]) {
+ same_jkp=1;
+ }
+ }
+ }
+ if(!same_ikp&&!same_jkp) {
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(kNeij<ltmp) {
+ njkkp=kNeij*(2*numneigh[k]-kNeij-1)/2+(ltmp-kNeij)-1;
+ nglkp=1;
+ nglj=0;
+ }
+ else {
+ njkkp=ltmp*(2*numneigh[k]-ltmp-1)/2+(kNeij-ltmp)-1;
+ nglkp=0;
+ nglj=1;
+ }
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ new2=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ new2=nSigBk[n]-1;
+ itypeSigBk[n][new2]=kp;
+ }
+ ang_jkkp=cos_index[k]+njkkp;
+ nb_kkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_kkp].temp=temp_kkp;
+ bt_sg[nb_kkp].i=k;
+ bt_sg[nb_kkp].j=kp;
+ gmean0=sigma_g0[jtype-1][ktype-1][kptype-1];
+ gmean1=sigma_g1[jtype-1][ktype-1][kptype-1];
+ gmean2=sigma_g2[jtype-1][ktype-1][kptype-1];
+ amean=cosAng[ang_jkkp];
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gfactorsq2=gfactor2*gfactor2;
+ gsqprime2=2.0*gfactor2*gprime2;
+ gfactor=gfactorsq*gfactorsq2;
+ rfactorrt=betaS[temp_jk]*betaS[temp_kkp];
+ rfactor=rfactorrt*rfactorrt;
+
+//3rd DD is Eq. 11 (c) for j atom where i & k=neighbor of j & k'=neighbor of k
+
+ DD=DD+gfactor*rfactor;
+
+//agpdpr1 is derivative of DD 3rd term w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of DD 3rd term w.r.t. Beta(r_kk')
+//app1 is derivative of DD 3rd term w.r.t. cos(theta_ijk)
+//app2 is derivative of DD 3rd term w.r.t. cos(theta_jkkp)
+
+ agpdpr1=2.0*gfactor*rfactorrt*betaS[temp_kkp]
+ *dBetaS[temp_jk]/rij[temp_jk];
+ agpdpr2=2.0*gfactor*rfactorrt*betaS[temp_jk]
+ *dBetaS[temp_kkp]/rij[temp_kkp];
+ app1=rfactor*gfactorsq2*gsqprime;
+ app2=rfactor*gfactorsq*gsqprime2;
+ bt_sg[nb_ij].dDD[0]-=
+ app1*dcAng[ang_ijk][0][ngi];
+ bt_sg[nb_ij].dDD[1]-=
+ app1*dcAng[ang_ijk][1][ngi];
+ bt_sg[nb_ij].dDD[2]-=
+ app1*dcAng[ang_ijk][2][ngi];
+ bt_sg[nb_jk].dDD[0]+=
+ app1*dcAng[ang_ijk][0][ngk]
+ +agpdpr1*disij[0][temp_jk]
+ -app2*dcAng[ang_jkkp][0][nglj];
+ bt_sg[nb_jk].dDD[1]+=
+ app1*dcAng[ang_ijk][1][ngk]
+ +agpdpr1*disij[1][temp_jk]
+ -app2*dcAng[ang_jkkp][1][nglj];
+ bt_sg[nb_jk].dDD[2]+=
+ app1*dcAng[ang_ijk][2][ngk]
+ +agpdpr1*disij[2][temp_jk]
+ -app2*dcAng[ang_jkkp][2][nglj];
+ bt_sg[nb_kkp].dDD[0]+=
+ app2*dcAng[ang_jkkp][0][nglkp]
+ +agpdpr2*disij[0][temp_kkp];
+ bt_sg[nb_kkp].dDD[1]+=
+ app2*dcAng[ang_jkkp][1][nglkp]
+ +agpdpr2*disij[1][temp_kkp];
+ bt_sg[nb_kkp].dDD[2]+=
+ app2*dcAng[ang_jkkp][2][nglkp]
+ +agpdpr2*disij[2][temp_kkp];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sig_flag=0;
+ if(FF<=0.000001) {
+ sigB[n]=0.0;
+ sig_flag=1;
+ }
+ if(sig_flag==0) {
+ if(AA<0.0)
+ AA=0.0;
+ if(BB<0.0)
+ BB=0.0;
+ if(CC<0.0)
+ CC=0.0;
+ if(DD<0.0)
+ DD=0.0;
+
+// AA and BB are the representations of (a) Eq. 34 and (b) Eq. 9
+// for atoms i and j respectively
+
+ AAC=AA+BB;
+ BBC=AA*BB;
+ CCC=AA*AA+BB*BB;
+ DDC=CC+DD;
+
+//EEC is a modified form of (a) Eq. 33
+
+ EEC=(DDC-CCC)/(AAC+2.0*small1);
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ bt_i=bt_sg[m].i;
+ bt_j=bt_sg[m].j;
+ bt_sg[m].dAAC[0]=bt_sg[m].dAA[0]
+ +bt_sg[m].dBB[0];
+ bt_sg[m].dAAC[1]=bt_sg[m].dAA[1]
+ +bt_sg[m].dBB[1];
+ bt_sg[m].dAAC[2]=bt_sg[m].dAA[2]
+ +bt_sg[m].dBB[2];
+ bt_sg[m].dBBC[0]=bt_sg[m].dAA[0]*BB
+ +AA*bt_sg[m].dBB[0];
+ bt_sg[m].dBBC[1]=bt_sg[m].dAA[1]*BB
+ +AA*bt_sg[m].dBB[1];
+ bt_sg[m].dBBC[2]=bt_sg[m].dAA[2]*BB
+ +AA*bt_sg[m].dBB[2];
+ bt_sg[m].dCCC[0]=2.0*AA*bt_sg[m].dAA[0]
+ +2.0*BB*bt_sg[m].dBB[0];
+ bt_sg[m].dCCC[1]=2.0*AA*bt_sg[m].dAA[1]
+ +2.0*BB*bt_sg[m].dBB[1];
+ bt_sg[m].dCCC[2]=2.0*AA*bt_sg[m].dAA[2]
+ +2.0*BB*bt_sg[m].dBB[2];
+ bt_sg[m].dDDC[0]=bt_sg[m].dCC[0]
+ +bt_sg[m].dDD[0];
+ bt_sg[m].dDDC[1]=bt_sg[m].dCC[1]
+ +bt_sg[m].dDD[1];
+ bt_sg[m].dDDC[2]=bt_sg[m].dCC[2]
+ +bt_sg[m].dDD[2];
+ bt_sg[m].dEEC[0]=(bt_sg[m].dDDC[0]
+ -bt_sg[m].dCCC[0]
+ -EEC*bt_sg[m].dAAC[0])*AACFF;
+ bt_sg[m].dEEC[1]=(bt_sg[m].dDDC[1]
+ -bt_sg[m].dCCC[1]
+ -EEC*bt_sg[m].dAAC[1])*AACFF;
+ bt_sg[m].dEEC[2]=(bt_sg[m].dDDC[2]
+ -bt_sg[m].dCCC[2]
+ -EEC*bt_sg[m].dAAC[2])*AACFF;
+ }
+ }
+ UT=EEC*FF+BBC+small3[iij];
+ UT=1.0/sqrt(UT);
+
+// FFC is slightly modified form of (a) Eq. 31
+// GGC is slightly modified form of (a) Eq. 32
+// bndtmp is a slightly modified form of (a) Eq. 30 and (b) Eq. 8
+
+ FFC=BBC*UT;
+ GGC=EEC*UT;
+ bndtmp=(FF+sigma_delta[iij]*sigma_delta[iij])
+ +sigma_c[iij]*AAC+small4;
+ UTcom=-0.5*UT*UT*UT;
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ bt_sg[m].dUT[0]=UTcom*(bt_sg[m].dEEC[0]*FF
+ +EEC*bt_sg[m].dFF[0]+bt_sg[m].dBBC[0]);
+ bt_sg[m].dUT[1]=UTcom*(bt_sg[m].dEEC[1]*FF
+ +EEC*bt_sg[m].dFF[1]+bt_sg[m].dBBC[1]);
+ bt_sg[m].dUT[2]=UTcom*(bt_sg[m].dEEC[2]*FF
+ +EEC*bt_sg[m].dFF[2]+bt_sg[m].dBBC[2]);
+ bt_sg[m].dFFC[0]=bt_sg[m].dBBC[0]*UT
+ +BBC*bt_sg[m].dUT[0];
+ bt_sg[m].dFFC[1]=bt_sg[m].dBBC[1]*UT
+ +BBC*bt_sg[m].dUT[1];
+ bt_sg[m].dFFC[2]=bt_sg[m].dBBC[2]*UT
+ +BBC*bt_sg[m].dUT[2];
+ bt_sg[m].dGGC[0]=bt_sg[m].dEEC[0]*UT
+ +EEC*bt_sg[m].dUT[0];
+ bt_sg[m].dGGC[1]=bt_sg[m].dEEC[1]*UT
+ +EEC*bt_sg[m].dUT[1];
+ bt_sg[m].dGGC[2]=bt_sg[m].dEEC[2]*UT
+ +EEC*bt_sg[m].dUT[2];
+ }
+ }
+ psign=1.0;
+ if(1.0+sigma_a[iij]*GGC<0.0)
+ psign=-1.0;
+ bndtmp0=1.0/sqrtl(bndtmp);
+ sigB1[n]=psign*betaS[temp_ij]*(1.0+sigma_a[iij]*GGC)*bndtmp0;
+ bndtmp=-0.5*bndtmp0*bndtmp0*bndtmp0;
+ bndtmp1=psign*(1.0+sigma_a[iij]*GGC)*bndtmp0+psign*betaS[temp_ij]
+ *(1.0+sigma_a[iij]*GGC)*bndtmp*2.0*betaS[temp_ij]*(1.0
+ +sigma_a[iij]*GGC)*(1.0+sigma_a[iij]*GGC);
+ bndtmp1=bndtmp1*dBetaS[temp_ij]/rij[temp_ij];
+ bndtmp2=psign*betaS[temp_ij]*(1.0+sigma_a[iij]*GGC)*bndtmp*sigma_c[iij];
+ bndtmp3=psign*betaS[temp_ij]*(1.0+sigma_a[iij]*GGC)
+ *bndtmp*sigma_c[iij]*sigma_a[iij];
+ bndtmp4=psign*betaS[temp_ij]*(1.0+sigma_a[iij]*GGC)
+ *bndtmp*sigma_c[iij]*sigma_a[iij]*(2.0+GGC);
+ bndtmp5=sigma_a[iij]*psign*betaS[temp_ij]*bndtmp0
+ +psign*betaS[temp_ij]*(1.0+sigma_a[iij]*GGC)*bndtmp
+ *(2.0*(FF+sigma_delta[iij]*sigma_delta[iij])*(1.0
+ +sigma_a[iij]*GGC)*sigma_a[iij]+sigma_c[iij]*sigma_a[iij]*FFC);
+ setting=0;
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ temp_kk=bt_sg[m].temp;
+ if(temp_kk==temp_ij&&setting==0) {
+ bt_sg[m].dSigB1[0]=bndtmp1*disij[0][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[0]
+ +bndtmp3*bt_sg[m].dEE[0]
+ +bndtmp4*bt_sg[m].dFFC[0]
+ +bndtmp5*bt_sg[m].dGGC[0]);
+ bt_sg[m].dSigB1[1]=bndtmp1*disij[1][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[1]
+ +bndtmp3*bt_sg[m].dEE[1]
+ +bndtmp4*bt_sg[m].dFFC[1]
+ +bndtmp5*bt_sg[m].dGGC[1]);
+ bt_sg[m].dSigB1[2]=bndtmp1*disij[2][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[2]
+ +bndtmp3*bt_sg[m].dEE[2]
+ +bndtmp4*bt_sg[m].dFFC[2]
+ +bndtmp5*bt_sg[m].dGGC[2]);
+ setting=1;
+ }
+ else if(temp_kk==temp_ji&&setting==0) {
+ bt_sg[m].dSigB1[0]=-bndtmp1*disij[0][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[0]
+ +bndtmp3*bt_sg[m].dEE[0]
+ +bndtmp4*bt_sg[m].dFFC[0]
+ +bndtmp5*bt_sg[m].dGGC[0]);
+ bt_sg[m].dSigB1[1]=-bndtmp1*disij[1][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[1]
+ +bndtmp3*bt_sg[m].dEE[1]
+ +bndtmp4*bt_sg[m].dFFC[1]
+ +bndtmp5*bt_sg[m].dGGC[1]);
+ bt_sg[m].dSigB1[2]=-bndtmp1*disij[2][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[2]
+ +bndtmp3*bt_sg[m].dEE[2]
+ +bndtmp4*bt_sg[m].dFFC[2]
+ +bndtmp5*bt_sg[m].dGGC[2]);
+ setting=1;
+ }
+ else {
+ bt_sg[m].dSigB1[0]=(bndtmp2*bt_sg[m].dAAC[0]
+ +bndtmp3*bt_sg[m].dEE[0]
+ +bndtmp4*bt_sg[m].dFFC[0]
+ +bndtmp5*bt_sg[m].dGGC[0]);
+ bt_sg[m].dSigB1[1]=(bndtmp2*bt_sg[m].dAAC[1]
+ +bndtmp3*bt_sg[m].dEE[1]
+ +bndtmp4*bt_sg[m].dFFC[1]
+ +bndtmp5*bt_sg[m].dGGC[1]);
+ bt_sg[m].dSigB1[2]=(bndtmp2*bt_sg[m].dAAC[2]
+ +bndtmp3*bt_sg[m].dEE[2]
+ +bndtmp4*bt_sg[m].dFFC[2]
+ +bndtmp5*bt_sg[m].dGGC[2]);
+ }
+ }
+ }
+
+//This loop is to ensure there is not an error for atoms with no neighbors (deposition)
+
+ if(nb_t==0) {
+ if(j>i) {
+ bt_sg[0].dSigB1[0]=bndtmp1*disij[0][temp_ij];
+ bt_sg[0].dSigB1[1]=bndtmp1*disij[1][temp_ij];
+ bt_sg[0].dSigB1[2]=bndtmp1*disij[2][temp_ij];
+ }
+ else {
+ bt_sg[0].dSigB1[0]=-bndtmp1*disij[0][temp_ij];
+ bt_sg[0].dSigB1[1]=-bndtmp1*disij[1][temp_ij];
+ bt_sg[0].dSigB1[2]=-bndtmp1*disij[2][temp_ij];
+ }
+ for(pp=0;pp<3;pp++) {
+ bt_sg[0].dAA[pp]=0.0;
+ bt_sg[0].dBB[pp]=0.0;
+ bt_sg[0].dCC[pp]=0.0;
+ bt_sg[0].dDD[pp]=0.0;
+ bt_sg[0].dEE[pp]=0.0;
+ bt_sg[0].dEE1[pp]=0.0;
+ bt_sg[0].dFF[pp]=0.0;
+ bt_sg[0].dAAC[pp]=0.0;
+ bt_sg[0].dBBC[pp]=0.0;
+ bt_sg[0].dCCC[pp]=0.0;
+ bt_sg[0].dDDC[pp]=0.0;
+ bt_sg[0].dEEC[pp]=0.0;
+ bt_sg[0].dFFC[pp]=0.0;
+ bt_sg[0].dGGC[pp]=0.0;
+ bt_sg[0].dUT[pp]=0.0;
+ bt_sg[0].dSigB1[pp]=0.0;
+ bt_sg[0].dSigB[pp]=0.0;
+ }
+ bt_sg[0].i=i;
+ bt_sg[0].j=j;
+ bt_sg[0].temp=temp_ij;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ }
+ ps=sigB1[n]*rdBO+1.0;
+ ks=(int)ps;
+ if(nBOt-1<ks)
+ ks=nBOt-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ dsigB1=((FsigBO3[iij][ks-1]*ps+FsigBO2[iij][ks-1])*ps
+ +FsigBO1[iij][ks-1])*ps+FsigBO[iij][ks-1];
+ dsigB2=(FsigBO6[iij][ks-1]*ps+FsigBO5[iij][ks-1])*ps+FsigBO4[iij][ks-1];
+ part0=(FF+0.5*AAC+small5);
+ part1=(sigma_f[iij]-0.5)*sigma_k[iij];
+ part2=1.0-part1*EE1/part0;
+ part3=dsigB1*part1/part0;
+ part4=part3/part0*EE1;
+
+// sigB is the final expression for (a) Eq. 6 and (b) Eq. 11
+
+ sigB[n]=dsigB1*part2;
+ pp1=2.0*betaS[temp_ij];
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ temp_kk=bt_sg[m].temp;
+ bt_ij=bt_sg[m].temp;
+ bt_i=bt_sg[m].i;
+ bt_j=bt_sg[m].j;
+ for(pp=0;pp<3;pp++) {
+ bt_sg[m].dSigB[pp]=dsigB2*part2*bt_sg[m].dSigB1[pp]
+ -part3*bt_sg[m].dEE1[pp]
+ +part4*(bt_sg[m].dFF[pp]
+ +0.5*bt_sg[m].dAAC[pp]);
+ }
+ for(pp=0;pp<3;pp++) {
+ ftmp[pp]=pp1*bt_sg[m].dSigB[pp];
+ f[bt_i][pp]-=ftmp[pp];
+ f[bt_j][pp]+=ftmp[pp];
+ }
+ if(evflag) {
+ ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+ ,ftmp[2],disij[0][bt_ij],disij[1][bt_ij],disij[2][bt_ij]);
+ }
+ }
+ }
+ }
+ n++;
+ }
+ }
+ }
+ }
+ if(allocate_sigma)
+ destroy_sigma();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::sigmaBo_noa()
+{
+ int nb_t,new_n_tot;
+ int n,i,j,k,kp,m,pp;
+ int iij,ji,ki;
+ int itmp,jtmp,ktmp,ltmp,mtmp;
+ int i_tag,j_tag;
+ int ngi,ngj,ngk,ngli,nglj,ngl;
+ int ngji,ngjk,nikj,ngki,ngkj;
+ int njik,nijk,nikkp,nkp,nijkp;
+ int nkikp,njikp,nk0,nkjkp,njkkp;
+ int jNeik,kNeii,kNeij;
+ int new1,new2,nlocal,nsearch;
+ int inum,*ilist,*iilist,*jlist,*klist;
+ int **firstneigh,*numneigh;
+ int temp_ji,temp_ikp,temp_ki,temp_kkp;
+ int temp_ij,temp_ik,temp_jkp,temp_kk,temp_jk;
+ int ang_ijkp,ang_ikkp,ang_kjkp;
+ int ang_ijk,ang_ikj,ang_jikp,ang_jkkp;
+ int ang_jik,ang_kikp;
+ int nb_ij,nb_ik,nb_jk;
+ int sig_flag,setting,ncmp,ks;
+ int itype,jtype,ktype,kptype;
+ int bt_i,bt_j,bt_ij;
+ int kp_index,same_ikp,same_jkp;
+ double AA,BB,CC,DD,EE,EE1,FF;
+ double AAC,BBC,CCC,DDC,EEC,FFC,GGC;
+ double AACFF,UT,bndtmp,UTcom;
+ double amean,gmean0,gmean1,gmean2,ps;
+ double gfactor1,gprime1,gsqprime,factorsq;
+ double gfactorsq,gfactor2,gprime2;
+ double gfactorsq2,gsqprime2;
+ double gfactor3,gprime3,gfactor,rfactor;
+ double drfactor,gfactor4,gprime4,agpdpr3;
+ double rfactor0,rfactorrt,rfactor1rt,rfactor1;
+ double rcm1,rcm2,gcm1,gcm2,gcm3;
+ double agpdpr1,agpdpr2,app1,app2,app3,app4;
+ double dsigB1,dsigB2;
+ double part0,part1,part2,part3,part4;
+ double psign,bndtmp0,pp1,bndtmp1,bndtmp2;
+ double ftmp[3];
+ double **x = atom->x;
+ double **f = atom->f;
+ int *tag = atom->tag;
+ int newton_pair = force->newton_pair;
+ int *type = atom->type;
+
+ nlocal = atom->nlocal;
+ int nall = nlocal+atom->nghost;
+ firstneigh = list->firstneigh;
+ numneigh = list->numneigh;
+ inum = list->inum;
+ ilist = list->ilist;
+ n=0;
+
+//loop over all local atoms
+
+ if(nb_sg>16) {
+ nb_sg=16;
+ }
+ if(nb_sg==0) {
+ nb_sg=(maxneigh)*(maxneigh/2);
+ }
+ if(allocate_sigma) {
+ destroy_sigma();
+ }
+ create_sigma(nb_sg);
+ for(itmp=0;itmp<inum;itmp++) {
+ i = ilist[itmp];
+ i_tag=tag[i];
+ itype = map[type[i]]+1;
+
+//j is loop over all neighbors of i
+
+ for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+ temp_ij=BOP_index[i]+jtmp;
+ if(neigh_flag[temp_ij]) {
+ for(m=0;m<nb_sg;m++) {
+ for(pp=0;pp<3;pp++) {
+ bt_sg[m].dAA[pp]=0.0;
+ bt_sg[m].dBB[pp]=0.0;
+ bt_sg[m].dEE1[pp]=0.0;
+ bt_sg[m].dFF[pp]=0.0;
+ bt_sg[m].dAAC[pp]=0.0;
+ bt_sg[m].dSigB1[pp]=0.0;
+ bt_sg[m].dSigB[pp]=0.0;
+ }
+ bt_sg[m].i=-1;
+ bt_sg[m].j=-1;
+ }
+ nb_t=0;
+ iilist=firstneigh[i];
+ j=iilist[jtmp];
+ jlist=firstneigh[j];
+ for(ki=0;ki<numneigh[j];ki++) {
+ temp_ki=BOP_index[j]+ki;
+ if(x[jlist[ki]][0]==x[i][0]) {
+ if(x[jlist[ki]][1]==x[i][1]) {
+ if(x[jlist[ki]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+ j_tag=tag[j];
+ jtype = map[type[j]]+1;
+ nb_ij=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_ij].temp=temp_ij;
+ bt_sg[nb_ij].i=i;
+ bt_sg[nb_ij].j=j;
+ if(j_tag>=i_tag) {
+ if(itype==jtype)
+ iij=itype-1;
+ else if(itype<jtype)
+ iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+ else
+ iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+ for(ji=0;ji<numneigh[j];ji++) {
+ temp_ji=BOP_index[j]+ji;
+ if(x[jlist[ji]][0]==x[i][0]) {
+ if(x[jlist[ji]][1]==x[i][1]) {
+ if(x[jlist[ji]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+ nSigBk[n]=0;
+
+//AA-EE1 are the components making up Eq. 30 (a)
+
+ AA=0.0;
+ BB=0.0;
+ CC=0.0;
+ DD=0.0;
+ EE1=0.0;
+
+//FF is the Beta_sigma^2 term
+
+ FF=betaS[temp_ij]*betaS[temp_ij];
+
+//agpdpr1 is derivative of FF w.r.t. r_ij
+
+ agpdpr1=2.0*betaS[temp_ij]*dBetaS[temp_ij]/rij[temp_ij];
+
+//dXX derivatives are taken with respect to all pairs contributing to the energy
+//nb_ij is derivative w.r.t. ij pair
+
+ bt_sg[nb_ij].dFF[0]=agpdpr1*disij[0][temp_ij];
+ bt_sg[nb_ij].dFF[1]=agpdpr1*disij[1][temp_ij];
+ bt_sg[nb_ij].dFF[2]=agpdpr1*disij[2][temp_ij];
+
+//k is loop over all neighbors of i again with j neighbor of i
+ for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+ temp_ik=BOP_index[i]+ktmp;
+ if(neigh_flag[temp_ik]) {
+ if(ktmp!=jtmp) {
+ if(jtmp<ktmp) {
+ njik=jtmp*(2*numneigh[i]-jtmp-1)/2+(ktmp-jtmp)-1;
+ ngj=0;
+ ngk=1;
+ }
+ else {
+ njik=ktmp*(2*numneigh[i]-ktmp-1)/2+(jtmp-ktmp)-1;
+ ngj=1;
+ ngk=0;
+ }
+ k=iilist[ktmp];
+ ktype = map[type[k]]+1;
+
+//find neighbor of k that is equal to i
+
+ klist=firstneigh[k];
+ for(kNeii=0;kNeii<numneigh[k];kNeii++) {
+ temp_ki=BOP_index[k]+kNeii;
+ if(x[klist[kNeii]][0]==x[i][0]) {
+ if(x[klist[kNeii]][1]==x[i][1]) {
+ if(x[klist[kNeii]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+
+//find neighbor of i that is equal to k
+
+ for(jNeik=0;jNeik<numneigh[j];jNeik++) {
+ temp_jk=BOP_index[j]+jNeik;
+ if(x[jlist[jNeik]][0]==x[k][0]) {
+ if(x[jlist[jNeik]][1]==x[k][1]) {
+ if(x[jlist[jNeik]][2]==x[k][2]) {
+ break;
+ }
+ }
+ }
+ }
+
+//find neighbor of k that is equal to j
+
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ nk0=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ nk0=nSigBk[n]-1;
+ itypeSigBk[n][nk0]=k;
+ }
+ nb_ik=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_ik].temp=temp_ik;
+ bt_sg[nb_ik].i=i;
+ bt_sg[nb_ik].j=k;
+ nb_jk=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jk].temp=temp_jk;
+ bt_sg[nb_jk].i=j;
+ bt_sg[nb_jk].j=k;
+ ang_jik=cos_index[i]+njik;
+ if(ang_jik>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ gmean0=sigma_g0[jtype-1][itype-1][ktype-1];
+ gmean1=sigma_g1[jtype-1][itype-1][ktype-1];
+ gmean2=sigma_g2[jtype-1][itype-1][ktype-1];
+ amean=cosAng[ang_jik];
+ gfactor1=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gfactorsq=gfactor1*gfactor1;
+ gprime1=gmean1+2.0*gmean2*amean;
+ gsqprime=2.0*gfactor1*gprime1;
+
+//AA is Eq. 34 (a) or Eq. 10 (c) for the i atom
+//1st CC is Eq. 11 (c) for i atom where j & k=neighbor of i
+
+ AA=AA+gfactorsq*betaS[temp_ik]*betaS[temp_ik];
+ CC=CC+gfactorsq*betaS[temp_ik]*betaS[temp_ik]*betaS[temp_ik]*betaS[temp_ik];
+//agpdpr1 is derivative of AA w.r.t. Beta(rik)
+//agpdpr2 is derivative of CC 1st term w.r.t. Beta(rik)
+//app1 is derivative of AA w.r.t. cos(theta_jik)
+//app2 is derivative of CC 1st term w.r.t. cos(theta_jik)
+
+ agpdpr1=2.0*gfactorsq*betaS[temp_ik]*dBetaS[temp_ik]/rij[temp_ik];
+ app1=betaS[temp_ik]*betaS[temp_ik]*gsqprime;
+ bt_sg[nb_ij].dAA[0]+=
+ app1*dcAng[ang_jik][0][ngj];
+ bt_sg[nb_ij].dAA[1]+=
+ app1*dcAng[ang_jik][1][ngj];
+ bt_sg[nb_ij].dAA[2]+=
+ app1*dcAng[ang_jik][2][ngj];
+ bt_sg[nb_ik].dAA[0]+=
+ app1*dcAng[ang_jik][0][ngk]
+ +agpdpr1*disij[0][temp_ik];
+ bt_sg[nb_ik].dAA[1]+=
+ app1*dcAng[ang_jik][1][ngk]
+ +agpdpr1*disij[1][temp_ik];
+ bt_sg[nb_ik].dAA[2]+=
+ app1*dcAng[ang_jik][2][ngk]
+ +agpdpr1*disij[2][temp_ik];
+
+//k' is loop over neighbors all neighbors of j with k a neighbor
+//of i and j a neighbor of i and determine which k' is k
+
+ kp_index=0;
+ for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+ temp_jkp=BOP_index[j]+ltmp;
+ kp=jlist[ltmp];
+ if(x[kp][0]==x[k][0]) {
+ if(x[kp][1]==x[k][1]) {
+ if(x[kp][2]==x[k][2]) {
+ kp_index=1;
+ break;
+ }
+ }
+ }
+ }
+ if(kp_index) {
+
+//loop over neighbors of k
+
+ for(mtmp=0;mtmp<numneigh[k];mtmp++) {
+ kp=klist[mtmp];
+ if(x[kp][0]==x[j][0]) {
+ if(x[kp][1]==x[j][1]) {
+ if(x[kp][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(ki<ltmp) {
+ nijk=ki*(2*numneigh[j]-ki-1)/2+(ltmp-ki)-1;
+ ngji=0;
+ ngjk=1;
+ }
+ else {
+ nijk=ltmp*(2*numneigh[j]-ltmp-1)/2+(ki-ltmp)-1;
+ ngji=1;
+ ngjk=0;
+ }
+ if(kNeii<mtmp) {
+ nikj=kNeii*(2*numneigh[k]-kNeii-1)/2+(mtmp-kNeii)-1;
+ ngki=0;
+ ngkj=1;
+ }
+ else {
+ nikj=mtmp*(2*numneigh[k]-mtmp-1)/2+(kNeii-mtmp)-1;
+ ngki=1;
+ ngkj=0;
+ }
+ ang_ijk=cos_index[j]+nijk;
+ if(ang_ijk>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+ amean=cosAng[ang_ijk];
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[itype-1][ktype-1][jtype-1];
+ gmean1=sigma_g1[itype-1][ktype-1][jtype-1];
+ gmean2=sigma_g2[itype-1][ktype-1][jtype-1];
+ ang_ikj=cos_index[k]+nikj;
+ if(ang_ikj>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ amean=cosAng[ang_ikj];
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactor=betaS[temp_ik]*betaS[temp_jkp];
+
+//EE1 is (b) Eq. 12
+
+ EE1=EE1+gfactor*rfactor;
+
+//rcm2 is derivative of EE1 w.r.t Beta(r_jk')
+//gcm1 is derivative of EE1 w.r.t cos(theta_jik)
+//gcm2 is derivative of EE1 w.r.t cos(theta_ijk)
+//gcm3 is derivative of EE1 w.r.t cos(theta_ikj)
+
+ rcm1=gfactor*betaS[temp_jkp]*dBetaS[temp_ik]/rij[temp_ik];
+ rcm2=gfactor*betaS[temp_ik]*dBetaS[temp_jkp]/rij[temp_jkp];
+ gcm1=rfactor*gprime1*gfactor2*gfactor3;
+ gcm2=rfactor*gfactor1*gprime2*gfactor3;
+ gcm3=rfactor*gfactor1*gfactor2*gprime3;
+ bt_sg[nb_ij].dEE1[0]+=
+ gcm1*dcAng[ang_jik][0][ngj]
+ -gcm2*dcAng[ang_ijk][0][ngji];
+ bt_sg[nb_ij].dEE1[1]+=
+ gcm1*dcAng[ang_jik][1][ngj]
+ -gcm2*dcAng[ang_ijk][1][ngji];
+ bt_sg[nb_ij].dEE1[2]+=
+ gcm1*dcAng[ang_jik][2][ngj]
+ -gcm2*dcAng[ang_ijk][2][ngji];
+ bt_sg[nb_ik].dEE1[0]+=
+ gcm1*dcAng[ang_jik][0][ngk]
+ +rcm1*disij[0][temp_ik]
+ -gcm3*dcAng[ang_ikj][0][ngki];
+ bt_sg[nb_ik].dEE1[1]+=
+ gcm1*dcAng[ang_jik][1][ngk]
+ +rcm1*disij[1][temp_ik]
+ -gcm3*dcAng[ang_ikj][1][ngki];
+ bt_sg[nb_ik].dEE1[2]+=
+ gcm1*dcAng[ang_jik][2][ngk]
+ +rcm1*disij[2][temp_ik]
+ -gcm3*dcAng[ang_ikj][2][ngki];
+ bt_sg[nb_jk].dEE1[0]+=
+ gcm2*dcAng[ang_ijk][0][ngjk]
+ +rcm2*disij[0][temp_jkp]
+ -gcm3*dcAng[ang_ikj][0][ngkj];
+ bt_sg[nb_jk].dEE1[1]+=
+ gcm2*dcAng[ang_ijk][1][ngjk]
+ +rcm2*disij[1][temp_jkp]
+ -gcm3*dcAng[ang_ikj][1][ngkj];
+ bt_sg[nb_jk].dEE1[2]+=
+ gcm2*dcAng[ang_ijk][2][ngjk]
+ +rcm2*disij[2][temp_jkp]
+ -gcm3*dcAng[ang_ikj][2][ngkj];
+ }
+
+// k and k' and j are all different neighbors of i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=jtmp) {
+ temp_ikp=BOP_index[i]+ltmp;
+ if(neigh_flag[temp_ikp]) {
+ kp=iilist[ltmp];
+ kptype = map[type[kp]]+1;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(jtmp<ltmp) {
+ njikp=jtmp*(2*numneigh[i]-jtmp-1)/2+(ltmp-jtmp)-1;
+ nglj=0;
+ ngl=1;
+ }
+ else {
+ njikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(jtmp-ltmp)-1;
+ nglj=1;
+ ngl=0;
+ }
+ if(ktmp<ltmp) {
+ nkikp=ktmp*(2*numneigh[i]-ktmp-1)/2+(ltmp-ktmp)-1;
+ }
+ else {
+ nkikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(ktmp-ltmp)-1;
+ }
+ ang_jikp=cos_index[i]+njikp;
+ if(ang_jikp>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ gmean0=sigma_g0[jtype-1][itype-1][kptype-1];
+ gmean1=sigma_g1[jtype-1][itype-1][kptype-1];
+ gmean2=sigma_g2[jtype-1][itype-1][kptype-1];
+ amean=cosAng[ang_jikp];
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[ktype-1][itype-1][kptype-1];
+ gmean1=sigma_g1[ktype-1][itype-1][kptype-1];
+ gmean2=sigma_g2[ktype-1][itype-1][kptype-1];
+ ang_kikp=cos_index[i]+nkikp;
+ if(ang_kikp>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ amean=cosAng[ang_kikp];
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactorrt=betaS[temp_ik]*betaS[temp_ikp];
+ rfactor=rfactorrt*rfactorrt;
+
+//2nd CC is second term of Eq. 11 (c) for i atom where j , k & k' =neighbor of i
+
+ CC=CC+2.0*gfactor*rfactor;
+ }
+ }
+ }
+
+// j and k are different neighbors of i and k' is a neighbor k not equal to i
+
+ for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+ temp_kkp=BOP_index[k]+ltmp;
+ if(neigh_flag[temp_kkp]) {
+ kp=klist[ltmp];;
+ kptype = map[type[kp]]+1;
+ same_ikp=0;
+ same_jkp=0;
+ if(x[i][0]==x[kp][0]) {
+ if(x[i][1]==x[kp][1]) {
+ if(x[i][2]==x[kp][2]) {
+ same_ikp=1;
+ }
+ }
+ }
+ if(x[j][0]==x[kp][0]) {
+ if(x[j][1]==x[kp][1]) {
+ if(x[j][2]==x[kp][2]) {
+ same_jkp=1;
+ }
+ }
+ }
+ if(!same_ikp&&!same_jkp) {
+ if(kNeii<ltmp) {
+ nikkp=kNeii*(2*numneigh[k]-kNeii-1)/2+(ltmp-kNeii)-1;
+ ngli=0;
+ }
+ else {
+ nikkp=ltmp*(2*numneigh[k]-ltmp-1)/2+(kNeii-ltmp)-1;
+ ngli=1;
+ }
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ sig_flag=1;
+ nkp=nsearch;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ nkp=nSigBk[n]-1;
+ itypeSigBk[n][nkp]=kp;
+ }
+ ang_ikkp=cos_index[k]+nikkp;
+ if(ang_ikkp>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ gmean0=sigma_g0[itype-1][ktype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][ktype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][ktype-1][kptype-1];
+ amean=cosAng[ang_ikkp];
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gfactorsq2=gfactor2*gfactor2;
+ gsqprime2=2.0*gfactor2*gprime2;
+ gfactor=gfactorsq*gfactorsq2;
+ rfactorrt=betaS[temp_ik]*betaS[temp_kkp];
+ rfactor=rfactorrt*rfactorrt;
+
+//3rd CC is third term of Eq. 11 (c) for i atom
+//where j , k =neighbor of i & k' =neighbor of k
+
+ CC=CC+gfactor*rfactor;
+ }
+ }
+ }
+ }
+ }
+ }
+
+//j is a neighbor of i and k is a neighbor of j not equal to i
+
+ for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+ if(ktmp!=ji) {
+ if(ktmp<ji) {
+ njik=ktmp*(2*numneigh[j]-ktmp-1)/2+(ji-ktmp)-1;
+ ngi=1;
+ ngk=0;
+ }
+ else {
+ njik=ji*(2*numneigh[j]-ji-1)/2+(ktmp-ji)-1;
+ ngi=0;
+ ngk=1;
+ }
+ temp_jk=BOP_index[j]+ktmp;
+ if(neigh_flag[temp_jk]) {
+ k=jlist[ktmp];
+ ktype=map[type[k]]+1;
+ klist=firstneigh[k];
+
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ new1=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ new1=nSigBk[n]-1;
+ itypeSigBk[n][new1]=k;
+ }
+ ang_ijk=cos_index[j]+njik;
+ if(ang_ijk>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ nb_jk=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jk].temp=temp_jk;
+ bt_sg[nb_jk].i=j;
+ bt_sg[nb_jk].j=k;
+ gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+ amean=cosAng[ang_ijk];
+ gfactor1=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime1=gmean1+2.0*gmean2*amean;
+ gfactorsq=gfactor1*gfactor1;
+ gsqprime=2.0*gfactor1*gprime1;
+ rfactor1rt=betaS[temp_jk]*betaS[temp_jk];
+ rfactor1=rfactor1rt*rfactor1rt;
+
+//BB is Eq. 34 (a) or Eq. 10 (c) for the j atom
+//1st DD is Eq. 11 (c) for j atom where i & k=neighbor of j
+ BB=BB+gfactorsq*rfactor1rt;
+ DD=DD+gfactorsq*rfactor1;
+
+//agpdpr1 is derivative of BB w.r.t. Beta(r_jk)
+//app1 is derivative of BB w.r.t. cos(theta_ijk)
+
+ agpdpr1=2.0*gfactorsq*betaS[temp_jk]*dBetaS[temp_jk]/rij[temp_jk];
+ app1=rfactor1rt*gsqprime;
+ bt_sg[nb_ij].dBB[0]-=
+ app1*dcAng[ang_ijk][0][ngi];
+ bt_sg[nb_ij].dBB[1]-=
+ app1*dcAng[ang_ijk][1][ngi];
+ bt_sg[nb_ij].dBB[2]-=
+ app1*dcAng[ang_ijk][2][ngi];
+ bt_sg[nb_jk].dBB[0]+=
+ app1*dcAng[ang_ijk][0][ngk]
+ +agpdpr1*disij[0][temp_jk];
+ bt_sg[nb_jk].dBB[1]+=
+ app1*dcAng[ang_ijk][1][ngk]
+ +agpdpr1*disij[1][temp_jk];
+ bt_sg[nb_jk].dBB[2]+=
+ app1*dcAng[ang_ijk][2][ngk]
+ +agpdpr1*disij[2][temp_jk];
+
+//j is a neighbor of i, k and k' prime different neighbors of j not equal to i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=ji) {
+ temp_jkp=BOP_index[j]+ltmp;
+ if(neigh_flag[temp_jkp]) {
+ kp=jlist[ltmp];
+ kptype=map[type[kp]]+1;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ new2=nsearch;
+ break;
+ }
+ }
+ }
+ }
+ if(ji<ltmp) {
+ nijkp=ji*(2*numneigh[j]-ji-1)/2+(ltmp-ji)-1;
+ ngli=0;
+ ngl=1;
+ }
+ else {
+ nijkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ji-ltmp)-1;
+ ngli=1;
+ ngl=0;
+ }
+ if(ktmp<ltmp) {
+ nkjkp=ktmp*(2*numneigh[j]-ktmp-1)/2+(ltmp-ktmp)-1;
+ ngjk=0;
+ }
+ else {
+ nkjkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ktmp-ltmp)-1;
+ ngjk=1;
+ }
+ ang_ijkp=cos_index[j]+nijkp;
+ if(ang_ijkp>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ ang_kjkp=cos_index[j]+nkjkp;
+ if(ang_kjkp>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+ amean=cosAng[ang_ijkp];
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[ktype-1][jtype-1][kptype-1];
+ gmean1=sigma_g1[ktype-1][jtype-1][kptype-1];
+ gmean2=sigma_g2[ktype-1][jtype-1][kptype-1];
+ amean=cosAng[ang_kjkp];
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactorrt=betaS[temp_jk]*betaS[temp_jkp];
+ rfactor=rfactorrt*rfactorrt;
+
+//2nd DD is Eq. 11 (c) for j atom where i , k & k'=neighbor of j
+
+ DD=DD+2.0*gfactor*rfactor;
+ }
+ }
+ }
+
+//j is a neighbor of i, k is a neighbor of j not equal to i and k'
+//is a neighbor of k not equal to j or i
+
+ for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+ temp_kkp=BOP_index[k]+ltmp;
+ if(neigh_flag[temp_kkp]) {
+ kp=klist[ltmp];
+ kptype=map[type[kp]]+1;
+ same_ikp=0;
+ same_jkp=0;
+ if(x[i][0]==x[kp][0]) {
+ if(x[i][1]==x[kp][1]) {
+ if(x[i][2]==x[kp][2]) {
+ same_ikp=1;
+ }
+ }
+ }
+ if(x[j][0]==x[kp][0]) {
+ if(x[j][1]==x[kp][1]) {
+ if(x[j][2]==x[kp][2]) {
+ same_jkp=1;
+ }
+ }
+ }
+ if(!same_ikp&&!same_jkp) {
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(kNeij<ltmp) {
+ njkkp=kNeij*(2*numneigh[k]-kNeij-1)/2+(ltmp-kNeij)-1;
+ nglj=0;
+ }
+ else {
+ njkkp=ltmp*(2*numneigh[k]-ltmp-1)/2+(kNeij-ltmp)-1;
+ nglj=1;
+ }
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ new2=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ new2=nSigBk[n]-1;
+ itypeSigBk[n][new2]=kp;
+ }
+ ang_jkkp=cos_index[k]+njkkp;
+ if(ang_jkkp>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ gmean0=sigma_g0[jtype-1][ktype-1][kptype-1];
+ gmean1=sigma_g1[jtype-1][ktype-1][kptype-1];
+ gmean2=sigma_g2[jtype-1][ktype-1][kptype-1];
+ amean=cosAng[ang_jkkp];
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gfactorsq2=gfactor2*gfactor2;
+ gsqprime2=2.0*gfactor2*gprime2;
+ gfactor=gfactorsq*gfactorsq2;
+ rfactorrt=betaS[temp_jk]*betaS[temp_kkp];
+ rfactor=rfactorrt*rfactorrt;
+
+//3rd DD is Eq. 11 (c) for j atom where i & k=neighbor of j & k'=neighbor of k
+
+ DD=DD+gfactor*rfactor;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sig_flag=0;
+ if(sig_flag==0) {
+
+// AA and BB are the representations of (a) Eq. 34 and (b) Eq. 9
+// for atoms i and j respectively
+
+ AAC=AA+BB;
+ BBC=AA*BB;
+ CCC=AA*AA+BB*BB;
+ DDC=CC+DD;
+
+//EEC is a modified form of (a) Eq. 33
+
+ EEC=(DDC-CCC)/(AAC+2.0*small1);
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ bt_i=bt_sg[m].i;
+ bt_j=bt_sg[m].j;
+ bt_sg[m].dAAC[0]=bt_sg[m].dAA[0]
+ +bt_sg[m].dBB[0];
+ bt_sg[m].dAAC[1]=bt_sg[m].dAA[1]
+ +bt_sg[m].dBB[1];
+ bt_sg[m].dAAC[2]=bt_sg[m].dAA[2]
+ +bt_sg[m].dBB[2];
+ }
+ }
+ UT=EEC*FF+BBC+small3[iij];
+ UT=1.0/sqrt(UT);
+
+// FFC is slightly modified form of (a) Eq. 31
+// GGC is slightly modified form of (a) Eq. 32
+// bndtmp is a slightly modified form of (a) Eq. 30 and (b) Eq. 8
+
+ bndtmp=(FF+sigma_delta[iij]*sigma_delta[iij])
+ +sigma_c[iij]*AAC+small4;
+ UTcom=-0.5*UT*UT*UT;
+ psign=1.0;
+ bndtmp0=1.0/sqrt(bndtmp);
+ sigB1[n]=psign*betaS[temp_ij]*bndtmp0;
+ bndtmp=-0.5*bndtmp0*bndtmp0*bndtmp0;
+ bndtmp1=psign*bndtmp0+psign*betaS[temp_ij]
+ *bndtmp*2.0*betaS[temp_ij];
+ bndtmp1=bndtmp1*dBetaS[temp_ij]/rij[temp_ij];
+ bndtmp2=psign*betaS[temp_ij]*bndtmp*sigma_c[iij];
+ setting=0;
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ temp_kk=bt_sg[m].temp;
+ if(temp_kk==temp_ij&&setting==0) {
+ bt_sg[m].dSigB1[0]=bndtmp1*disij[0][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[0]);
+ bt_sg[m].dSigB1[1]=bndtmp1*disij[1][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[1]);
+ bt_sg[m].dSigB1[2]=bndtmp1*disij[2][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[2]);
+ setting=1;
+ }
+ else if(temp_kk==temp_ji&&setting==0) {
+ bt_sg[m].dSigB1[0]=-bndtmp1*disij[0][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[0]);
+ bt_sg[m].dSigB1[1]=-bndtmp1*disij[1][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[1]);
+ bt_sg[m].dSigB1[2]=-bndtmp1*disij[2][temp_ij]
+ +(bndtmp2*bt_sg[m].dAAC[2]);
+ setting=1;
+ }
+ else {
+ bt_sg[m].dSigB1[0]=(bndtmp2*bt_sg[m].dAAC[0]);
+ bt_sg[m].dSigB1[1]=(bndtmp2*bt_sg[m].dAAC[1]);
+ bt_sg[m].dSigB1[2]=(bndtmp2*bt_sg[m].dAAC[2]);
+ }
+ }
+ }
+
+//This loop is to ensure there is not an error for atoms with no neighbors (deposition)
+
+ if(nb_t==0) {
+ if(j>i) {
+ bt_sg[0].dSigB1[0]=bndtmp1*disij[0][temp_ij];
+ bt_sg[0].dSigB1[1]=bndtmp1*disij[1][temp_ij];
+ bt_sg[0].dSigB1[2]=bndtmp1*disij[2][temp_ij];
+ }
+ else {
+ bt_sg[0].dSigB1[0]=-bndtmp1*disij[0][temp_ij];
+ bt_sg[0].dSigB1[1]=-bndtmp1*disij[1][temp_ij];
+ bt_sg[0].dSigB1[2]=-bndtmp1*disij[2][temp_ij];
+ }
+ for(pp=0;pp<3;pp++) {
+ bt_sg[0].dAA[pp]=0.0;
+ bt_sg[0].dBB[pp]=0.0;
+ bt_sg[0].dEE1[pp]=0.0;
+ bt_sg[0].dFF[pp]=0.0;
+ bt_sg[0].dAAC[pp]=0.0;
+ bt_sg[0].dSigB[pp]=0.0;
+ }
+ bt_sg[0].i=i;
+ bt_sg[0].j=j;
+ bt_sg[0].temp=temp_ij;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ }
+ ps=sigB1[n]*rdBO+1.0;
+ ks=(int)ps;
+ if(nBOt-1<ks)
+ ks=nBOt-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ dsigB1=((FsigBO3[iij][ks-1]*ps+FsigBO2[iij][ks-1])*ps
+ +FsigBO1[iij][ks-1])*ps+FsigBO[iij][ks-1];
+ dsigB2=(FsigBO6[iij][ks-1]*ps+FsigBO5[iij][ks-1])*ps+FsigBO4[iij][ks-1];
+ part0=(FF+0.5*AAC+small5);
+ part1=(sigma_f[iij]-0.5)*sigma_k[iij];
+ part2=1.0-part1*EE1/part0;
+ part3=dsigB1*part1/part0;
+ part4=part3/part0*EE1;
+
+// sigB is the final expression for (a) Eq. 6 and (b) Eq. 11
+
+ sigB[n]=dsigB1*part2;
+ pp1=2.0*betaS[temp_ij];
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ temp_kk=bt_sg[m].temp;
+ bt_ij=bt_sg[m].temp;
+ bt_i=bt_sg[m].i;
+ bt_j=bt_sg[m].j;
+ for(pp=0;pp<3;pp++) {
+ bt_sg[m].dSigB[pp]=dsigB2*part2*bt_sg[m].dSigB1[pp]
+ -part3*bt_sg[m].dEE1[pp]
+ +part4*(bt_sg[m].dFF[pp]
+ +0.5*bt_sg[m].dAAC[pp]);
+ }
+ for(pp=0;pp<3;pp++) {
+ ftmp[pp]=pp1*bt_sg[m].dSigB[pp];
+ f[bt_i][pp]-=ftmp[pp];
+ f[bt_j][pp]+=ftmp[pp];
+ }
+ if(evflag) {
+ ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+ ,ftmp[2],disij[0][bt_ij],disij[1][bt_ij],disij[2][bt_ij]);
+ }
+ }
+ }
+ }
+ n++;
+ }
+ }
+ }
+ }
+ destroy_sigma();
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* The formulation differs slightly to avoid negative square roots
+ in the calculation of Theta_pi,ij of (a) Eq. 36 and (b) Eq. 18 */
+
+void PairBOP::sigmaBo_otf()
+{
+ int nb_t,new_n_tot;
+ int n,i,j,k,kp,m,pp,kpj,kpk,kkp;
+ int itmp,jtmp,ktmp,ltmp,mtmp;
+ int i_tag,j_tag;
+ int kp1,kp2,kp1type;
+ int iij,iik,ijk,ikkp,ji,iikp,ijkp;
+ int nkp;
+ int nk0;
+ int jNeik,kNeii,kNeij,kNeikp;
+ int kpNeij,kpNeik;
+ int new1,new2,nlocal;
+ int inum,*ilist,*iilist,*jlist,*klist,*kplist;
+ int **firstneigh,*numneigh;
+ int temp_ij,temp_ik,temp_jkp,temp_kk,temp_jk;
+ int temp_ji,temp_kpj,temp_kkp;
+ int temp_ikp,temp_kpk;
+ int nb_ij,nb_ik,nb_ikp;
+ int nb_jk,nb_jkp,nb_kkp;
+ int kp_nsearch,nsearch;
+ int sig_flag,setting,ncmp,ks;
+ int itype,jtype,ktype,kptype;
+ int bt_i,bt_j;
+ int same_ikp,same_jkp,same_kpk;
+ int same_jkpj,same_kkpk;
+ double AA,BB,CC,DD,EE,EE1,FF;
+ double AAC,BBC,CCC,DDC,EEC,FFC,GGC;
+ double AACFF,UT,bndtmp,UTcom;
+ double amean,gmean0,gmean1,gmean2,ps;
+ double gfactor1,gprime1,gsqprime,factorsq;
+ double gfactorsq,gfactor2,gprime2;
+ double gfactorsq2,gsqprime2;
+ double gfactor3,gprime3,gfactor,rfactor;
+ double drfactor,gfactor4,gprime4,agpdpr3;
+ double rfactor0,rfactorrt,rfactor1rt,rfactor1;
+ double rcm1,rcm2,gcm1,gcm2,gcm3;
+ double agpdpr1,agpdpr2,app1,app2,app3,app4;
+ double dsigB1,dsigB2;
+ double part0,part1,part2,part3,part4;
+ double psign,bndtmp0,pp1;
+ double bndtmp1,bndtmp2,bndtmp3,bndtmp4,bndtmp5;
+ double dis_ij[3],rsq_ij,r_ij;
+ double betaS_ij,dBetaS_ij;
+ double betaP_ij,dBetaP_ij;
+ double dis_ik[3],rsq_ik,r_ik;
+ double betaS_ik,dBetaS_ik;
+ double betaP_ik,dBetaP_ik;
+ double dis_ikp[3],rsq_ikp,r_ikp;
+ double betaS_ikp,dBetaS_ikp;
+ double betaP_ikp,dBetaP_ikp;
+ double dis_jk[3],rsq_jk,r_jk;
+ double betaS_jk,dBetaS_jk;
+ double betaP_jk,dBetaP_jk;
+ double dis_jkp[3],rsq_jkp,r_jkp;
+ double betaS_jkp,dBetaS_jkp;
+ double betaP_jkp,dBetaP_jkp;
+ double dis_kkp[3],rsq_kkp,r_kkp;
+ double betaS_kkp,dBetaS_kkp;
+ double betaP_kkp,dBetaP_kkp;
+ double cosAng_jik,dcA_jik[3][2];
+ double cosAng_jikp,dcA_jikp[3][2];
+ double cosAng_kikp,dcA_kikp[3][2];
+ double cosAng_ijk,dcA_ijk[3][2];
+ double cosAng_ijkp,dcA_ijkp[3][2];
+ double cosAng_kjkp,dcA_kjkp[3][2];
+ double cosAng_ikj,dcA_ikj[3][2];
+ double cosAng_ikkp,dcA_ikkp[3][2];
+ double cosAng_jkkp,dcA_jkkp[3][2];
+ double cosAng_jkpk,dcA_jkpk[3][2];
+
+ double ftmp[3],xtmp[3];
+ double **x = atom->x;
+ double **f = atom->f;
+ int *tag = atom->tag;
+ int newton_pair = force->newton_pair;
+ int *type = atom->type;
+
+ nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ n=0;
+ if(nb_sg==0) {
+ nb_sg=(maxneigh)*(maxneigh/2);
+ }
+ if(allocate_sigma) {
+ destroy_sigma();
+ }
+
+ create_sigma(nb_sg);
+
+ for(itmp=0;itmp<inum;itmp++) {
+ i = ilist[itmp];
+ i_tag=tag[i];
+ itype = map[type[i]]+1;
+
+//j is loop over all neighbors of i
+
+ for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+ for(m=0;m<nb_sg;m++) {
+ for(pp=0;pp<3;pp++) {
+ bt_sg[m].dAA[pp]=0.0;
+ bt_sg[m].dBB[pp]=0.0;
+ bt_sg[m].dCC[pp]=0.0;
+ bt_sg[m].dDD[pp]=0.0;
+ bt_sg[m].dEE[pp]=0.0;
+ bt_sg[m].dEE1[pp]=0.0;
+ bt_sg[m].dFF[pp]=0.0;
+ bt_sg[m].dAAC[pp]=0.0;
+ bt_sg[m].dBBC[pp]=0.0;
+ bt_sg[m].dCCC[pp]=0.0;
+ bt_sg[m].dDDC[pp]=0.0;
+ bt_sg[m].dEEC[pp]=0.0;
+ bt_sg[m].dFFC[pp]=0.0;
+ bt_sg[m].dGGC[pp]=0.0;
+ bt_sg[m].dUT[pp]=0.0;
+ bt_sg[m].dSigB1[pp]=0.0;
+ bt_sg[m].dSigB[pp]=0.0;
+ }
+ bt_sg[m].i=-1;
+ bt_sg[m].j=-1;
+ bt_sg[m].temp=-1;
+ }
+ nb_t=0;
+ iilist=firstneigh[i];
+ temp_ij=BOP_index[i]+jtmp;
+ j=iilist[jtmp];
+ jlist=firstneigh[j];
+ j_tag=tag[j];
+ jtype = map[type[j]]+1;
+ nb_ij=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_ij].temp=temp_ij;
+ bt_sg[nb_ij].i=i;
+ bt_sg[nb_ij].j=j;
+ if(j_tag>=i_tag) {
+ if(itype==jtype)
+ iij=itype-1;
+ else if(itype<jtype)
+ iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+ else
+ iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+ for(ji=0;ji<numneigh[j];ji++) {
+ temp_ji=BOP_index[j]+ji;
+ if(x[jlist[ji]][0]==x[i][0]) {
+ if(x[jlist[ji]][1]==x[i][1]) {
+ if(x[jlist[ji]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+ dis_ij[0]=x[j][0]-x[i][0];
+ dis_ij[1]=x[j][1]-x[i][1];
+ dis_ij[2]=x[j][2]-x[i][2];
+ rsq_ij=dis_ij[0]*dis_ij[0]
+ +dis_ij[1]*dis_ij[1]
+ +dis_ij[2]*dis_ij[2];
+ r_ij=sqrt(rsq_ij);
+
+ if(r_ij<rcut[iij]) {
+ ps=r_ij*rdr[iij]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_ij=((pBetaS3[iij][ks-1]*ps+pBetaS2[iij][ks-1])*ps
+ +pBetaS1[iij][ks-1])*ps+pBetaS[iij][ks-1];
+ dBetaS_ij=(pBetaS6[iij][ks-1]*ps+pBetaS5[iij][ks-1])*ps
+ +pBetaS4[iij][ks-1];
+ betaP_ij=((pBetaP3[iij][ks-1]*ps+pBetaP2[iij][ks-1])*ps
+ +pBetaP1[iij][ks-1])*ps+pBetaP[iij][ks-1];
+ dBetaP_ij=(pBetaP6[iij][ks-1]*ps+pBetaP5[iij][ks-1])*ps
+ +pBetaP4[iij][ks-1];
+ nSigBk[n]=0;
+
+//AA-EE1 are the components making up Eq. 30 (a)
+
+ AA=0.0;
+ BB=0.0;
+ CC=0.0;
+ DD=0.0;
+ EE=0.0;
+ EE1=0.0;
+
+//FF is the Beta_sigma^2 term
+
+ FF=betaS_ij*betaS_ij;
+
+//agpdpr1 is derivative of FF w.r.t. r_ij
+
+ agpdpr1=2.0*betaS_ij*dBetaS_ij/r_ij;
+
+//dXX derivatives are taken with respect to all pairs contributing to the energy
+//nb_ij is derivative w.r.t. ij pair
+
+ bt_sg[nb_ij].dFF[0]=agpdpr1*dis_ij[0];
+ bt_sg[nb_ij].dFF[1]=agpdpr1*dis_ij[1];
+ bt_sg[nb_ij].dFF[2]=agpdpr1*dis_ij[2];
+
+//k is loop over all neighbors of i again with j neighbor of i
+
+ for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+ temp_ik=BOP_index[i]+ktmp;
+ if(ktmp!=jtmp) {
+ k=iilist[ktmp];
+ klist=firstneigh[k];
+ ktype = map[type[k]]+1;
+ if(itype==ktype)
+ iik=itype-1;
+ else if(itype<ktype)
+ iik=itype*bop_types-itype*(itype+1)/2+ktype-1;
+ else
+ iik=ktype*bop_types-ktype*(ktype+1)/2+itype-1;
+
+//find neighbor of k that is equal to i
+
+ for(kNeii=0;kNeii<numneigh[k];kNeii++) {
+ if(x[klist[kNeii]][0]==x[i][0]) {
+ if(x[klist[kNeii]][1]==x[i][1]) {
+ if(x[klist[kNeii]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+ dis_ik[0]=x[k][0]-x[i][0];
+ dis_ik[1]=x[k][1]-x[i][1];
+ dis_ik[2]=x[k][2]-x[i][2];
+ rsq_ik=dis_ik[0]*dis_ik[0]
+ +dis_ik[1]*dis_ik[1]
+ +dis_ik[2]*dis_ik[2];
+ r_ik=sqrt(rsq_ik);
+ if(r_ik<=rcut[iik]) {
+ ps=r_ik*rdr[iik]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_ik=((pBetaS3[iik][ks-1]*ps+pBetaS2[iik][ks-1])*ps
+ +pBetaS1[iik][ks-1])*ps+pBetaS[iik][ks-1];
+ dBetaS_ik=(pBetaS6[iik][ks-1]*ps+pBetaS5[iik][ks-1])*ps
+ +pBetaS4[iik][ks-1];
+ betaP_ik=((pBetaP3[iik][ks-1]*ps+pBetaP2[iik][ks-1])*ps
+ +pBetaP1[iik][ks-1])*ps+pBetaP[iik][ks-1];
+ dBetaP_ik=(pBetaP6[iik][ks-1]*ps+pBetaP5[iik][ks-1])*ps
+ +pBetaP4[iik][ks-1];
+
+//find neighbor of i that is equal to k
+
+ for(jNeik=0;jNeik<numneigh[j];jNeik++) {
+ temp_jk=BOP_index[j]+jNeik;
+ if(x[jlist[jNeik]][0]==x[k][0]) {
+ if(x[jlist[jNeik]][1]==x[k][1]) {
+ if(x[jlist[jNeik]][2]==x[k][2]) {
+ break;
+ }
+ }
+ }
+ }
+
+//find neighbor of k that is equal to j
+
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ dis_jk[0]=x[k][0]-x[j][0];
+ dis_jk[1]=x[k][1]-x[j][1];
+ dis_jk[2]=x[k][2]-x[j][2];
+ rsq_jk=dis_jk[0]*dis_jk[0]
+ +dis_jk[1]*dis_jk[1]
+ +dis_jk[2]*dis_jk[2];
+ r_jk=sqrt(rsq_jk);
+
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ nk0=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ nk0=nSigBk[n]-1;
+ itypeSigBk[n][nk0]=k;
+ }
+ nb_ik=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_ik].temp=temp_ik;
+ bt_sg[nb_ik].i=i;
+ bt_sg[nb_ik].j=k;
+ nb_jk=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jk].temp=temp_jk;
+ bt_sg[nb_jk].i=j;
+ bt_sg[nb_jk].j=k;
+ cosAng_jik=(dis_ij[0]*dis_ik[0]+dis_ij[1]*dis_ik[1]
+ +dis_ij[2]*dis_ik[2])/(r_ij*r_ik);
+ dcA_jik[0][0]=(dis_ik[0]*r_ij*r_ik-cosAng_jik
+ *dis_ij[0]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[1][0]=(dis_ik[1]*r_ij*r_ik-cosAng_jik
+ *dis_ij[1]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[2][0]=(dis_ik[2]*r_ij*r_ik-cosAng_jik
+ *dis_ij[2]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[0][1]=(dis_ij[0]*r_ij*r_ik-cosAng_jik
+ *dis_ik[0]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[1][1]=(dis_ij[1]*r_ij*r_ik-cosAng_jik
+ *dis_ik[1]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[2][1]=(dis_ij[2]*r_ij*r_ik-cosAng_jik
+ *dis_ik[2]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+ gmean0=sigma_g0[jtype-1][itype-1][ktype-1];
+ gmean1=sigma_g1[jtype-1][itype-1][ktype-1];
+ gmean2=sigma_g2[jtype-1][itype-1][ktype-1];
+ amean=cosAng_jik;
+ gfactor1=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gfactorsq=gfactor1*gfactor1;
+ gprime1=gmean1+2.0*gmean2*amean;
+ gsqprime=2.0*gfactor1*gprime1;
+
+//AA is Eq. 34 (a) or Eq. 10 (c) for the i atom
+//1st CC is Eq. 11 (c) for i atom where j & k=neighbor of i
+
+ AA=AA+gfactorsq*betaS_ik*betaS_ik;
+ CC=CC+gfactorsq*betaS_ik*betaS_ik*betaS_ik*betaS_ik;
+
+//agpdpr1 is derivative of AA w.r.t. Beta(rik)
+//app1 is derivative of AA w.r.t. cos(theta_jik)
+
+ agpdpr1=2.0*gfactorsq*betaS_ik*dBetaS_ik/r_ik;
+ app1=betaS_ik*betaS_ik*gsqprime;
+ bt_sg[nb_ij].dAA[0]+=
+ app1*dcA_jik[0][0];
+ bt_sg[nb_ij].dAA[1]+=
+ app1*dcA_jik[1][0];
+ bt_sg[nb_ij].dAA[2]+=
+ app1*dcA_jik[2][0];
+ bt_sg[nb_ij].dCC[0]+=
+ app2*dcA_jik[0][0];
+ bt_sg[nb_ij].dCC[1]+=
+ app2*dcA_jik[1][0];
+ bt_sg[nb_ij].dCC[2]+=
+ app2*dcA_jik[2][0];
+ bt_sg[nb_ik].dAA[0]+=
+ app1*dcA_jik[0][1]
+ +agpdpr1*dis_ik[0];
+ bt_sg[nb_ik].dAA[1]+=
+ app1*dcA_jik[1][1]
+ +agpdpr1*dis_ik[1];
+ bt_sg[nb_ik].dAA[2]+=
+ app1*dcA_jik[2][1]
+ +agpdpr1*dis_ik[2];
+ bt_sg[nb_ik].dCC[0]+=
+ app2*dcA_jik[0][1]
+ +agpdpr2*dis_ik[0];
+ bt_sg[nb_ik].dCC[1]+=
+ app2*dcA_jik[1][1]
+ +agpdpr2*dis_ik[1];
+ bt_sg[nb_ik].dCC[2]+=
+ app2*dcA_jik[2][1]
+ +agpdpr2*dis_ik[2];
+
+//k' is loop over neighbors all neighbors of j with k a neighbor
+//of i and j a neighbor of i and determine which k' is k
+
+ same_kpk=0;
+ for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+ temp_jkp=BOP_index[j]+ltmp;
+ kp1=jlist[ltmp];
+ kp1type=map[type[kp1]]+1;
+ if(x[kp1][0]==x[k][0]) {
+ if(x[kp1][1]==x[k][1]) {
+ if(x[kp1][2]==x[k][2]) {
+ same_kpk=1;
+ break;
+ }
+ }
+ }
+ }
+ if(same_kpk){
+
+//loop over neighbors of k
+
+ for(mtmp=0;mtmp<numneigh[k];mtmp++) {
+ temp_kpj=BOP_index[k]+mtmp;
+ kp2=klist[mtmp];
+ if(x[kp2][0]==x[k][0]) {
+ if(x[kp2][1]==x[k][1]) {
+ if(x[kp2][2]==x[k][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(jtype==ktype)
+ ijk=jtype-1;
+ else if(jtype < ktype)
+ ijk=jtype*bop_types-jtype*(jtype+1)/2+ktype-1;
+ else
+ ijk=ktype*bop_types-ktype*(ktype+1)/2+jtype-1;
+ if(jtype==kp1type)
+ ijkp=jtype-1;
+ else if(jtype<kp1type)
+ ijkp=jtype*bop_types-jtype*(jtype+1)/2+kp1type-1;
+ else
+ ijkp=kp1type*bop_types-kp1type*(kp1type+1)/2+jtype-1;
+
+ dis_jkp[0]=x[kp1][0]-x[j][0];
+ dis_jkp[1]=x[kp1][1]-x[j][1];
+ dis_jkp[2]=x[kp1][2]-x[j][2];
+ rsq_jkp=dis_jkp[0]*dis_jkp[0]
+ +dis_jkp[1]*dis_jkp[1]
+ +dis_jkp[2]*dis_jkp[2];
+ r_jkp=sqrt(rsq_jkp);
+ if(r_jkp<=rcut[ijkp]) {
+ ps=r_jkp*rdr[ijkp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+ +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+ dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+ +pBetaS4[ijkp][ks-1];
+ betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+ +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+ dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+ +pBetaP4[ijkp][ks-1];
+ cosAng_ijk=(-dis_ij[0]*dis_jk[0]-dis_ij[1]*dis_jk[1]
+ -dis_ij[2]*dis_jk[2])/(r_ij*r_jk);
+ dcA_ijk[0][0]=(dis_jk[0]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[0]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[1][0]=(dis_jk[1]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[1]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[2][0]=(dis_jk[2]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[2]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[0][1]=(-dis_ij[0]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[0]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[1][1]=(-dis_ij[1]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[1]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[2][1]=(-dis_ij[2]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[2]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+ amean=cosAng_ijk;
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[itype-1][ktype-1][jtype-1];
+ gmean1=sigma_g1[itype-1][ktype-1][jtype-1];
+ gmean2=sigma_g2[itype-1][ktype-1][jtype-1];
+ cosAng_ikj=(dis_ik[0]*dis_jk[0]+dis_ik[1]*dis_jk[1]
+ +dis_ik[2]*dis_jk[2])/(r_ik*r_jk);
+ dcA_ikj[0][0]=(-dis_jk[0]*r_ik*r_jk-cosAng_ikj
+ *-dis_ik[0]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+ dcA_ikj[1][0]=(-dis_jk[1]*r_ik*r_jk-cosAng_ikj
+ *-dis_ik[1]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+ dcA_ikj[2][0]=(-dis_jk[2]*r_ik*r_jk-cosAng_ikj
+ *-dis_ik[2]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+ dcA_ikj[0][1]=(-dis_ik[0]*r_ik*r_jk-cosAng_ikj
+ *-dis_jk[0]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+ dcA_ikj[1][1]=(-dis_ik[1]*r_ik*r_jk-cosAng_ikj
+ *-dis_jk[1]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+ dcA_ikj[2][1]=(-dis_ik[2]*r_ik*r_jk-cosAng_ikj
+ *-dis_jk[2]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+ amean=cosAng_ikj;
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactor=betaS_ik*betaS_jkp;
+
+//EE1 is (b) Eq. 12
+
+ EE1=EE1+gfactor*rfactor;
+
+//rcm1 is derivative of EE1 w.r.t Beta(r_ik)
+//rcm2 is derivative of EE1 w.r.t Beta(r_jk')
+//gcm1 is derivative of EE1 w.r.t cos(theta_jik)
+//gcm2 is derivative of EE1 w.r.t cos(theta_ijk)
+//gcm3 is derivative of EE1 w.r.t cos(theta_ikj)
+
+ rcm1=gfactor*betaS_jkp*dBetaS_ik/r_ik;
+ rcm2=gfactor*betaS_ik*dBetaS_jkp/r_jkp;
+ gcm1=rfactor*gprime1*gfactor2*gfactor3;
+ gcm2=rfactor*gfactor1*gprime2*gfactor3;
+ gcm3=rfactor*gfactor1*gfactor2*gprime3;
+ bt_sg[nb_ij].dEE1[0]+=
+ gcm1*dcA_jik[0][0]
+ -gcm2*dcA_ijk[0][0];
+ bt_sg[nb_ij].dEE1[1]+=
+ gcm1*dcA_jik[1][0]
+ -gcm2*dcA_ijk[1][0];
+ bt_sg[nb_ij].dEE1[2]+=
+ gcm1*dcA_jik[2][0]
+ -gcm2*dcA_ijk[2][0];
+ bt_sg[nb_ik].dEE1[0]+=
+ gcm1*dcA_jik[0][1]
+ +rcm1*dis_ik[0]
+ -gcm3*dcA_ikj[0][0];
+ bt_sg[nb_ik].dEE1[1]+=
+ gcm1*dcA_jik[1][1]
+ +rcm1*dis_ik[1]
+ -gcm3*dcA_ikj[1][0];
+ bt_sg[nb_ik].dEE1[2]+=
+ gcm1*dcA_jik[2][1]
+ +rcm1*dis_ik[2]
+ -gcm3*dcA_ikj[2][0];
+ bt_sg[nb_jk].dEE1[0]+=
+ gcm2*dcA_ijk[0][1]
+ +rcm2*dis_jkp[0]
+ -gcm3*dcA_ikj[0][1];
+ bt_sg[nb_jk].dEE1[1]+=
+ gcm2*dcA_ijk[1][1]
+ +rcm2*dis_jkp[1]
+ -gcm3*dcA_ikj[1][1];
+ bt_sg[nb_jk].dEE1[2]+=
+ gcm2*dcA_ijk[2][1]
+ +rcm2*dis_jkp[2]
+ -gcm3*dcA_ikj[2][1];
+ }
+ }
+
+// k and k' and j are all different neighbors of i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=jtmp) {
+ temp_ikp=BOP_index[i]+ltmp;
+ kp=iilist[ltmp];;
+ kptype = map[type[kp]]+1;
+ if(itype==kptype)
+ iikp=itype-1;
+ else if(itype<kptype)
+ iikp=itype*bop_types-itype*(itype+1)/2+kptype-1;
+ else
+ iikp=kptype*bop_types-kptype*(kptype+1)/2+itype-1;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ break;
+ }
+ }
+ }
+ }
+ dis_ikp[0]=x[kp][0]-x[i][0];
+ dis_ikp[1]=x[kp][1]-x[i][1];
+ dis_ikp[2]=x[kp][2]-x[i][2];
+ rsq_ikp=dis_ikp[0]*dis_ikp[0]
+ +dis_ikp[1]*dis_ikp[1]
+ +dis_ikp[2]*dis_ikp[2];
+ r_ikp=sqrt(rsq_ikp);
+ if(r_ikp<=rcut[iikp]) {
+ ps=r_ikp*rdr[iikp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_ikp=((pBetaS3[iikp][ks-1]*ps+pBetaS2[iikp][ks-1])*ps
+ +pBetaS1[iikp][ks-1])*ps+pBetaS[iikp][ks-1];
+ dBetaS_ikp=(pBetaS6[iikp][ks-1]*ps+pBetaS5[iikp][ks-1])*ps
+ +pBetaS4[iikp][ks-1];
+ betaP_ikp=((pBetaP3[iikp][ks-1]*ps+pBetaP2[iikp][ks-1])*ps
+ +pBetaP1[iikp][ks-1])*ps+pBetaP[iikp][ks-1];
+ dBetaP_ikp=(pBetaP6[iikp][ks-1]*ps+pBetaP5[iikp][ks-1])*ps
+ +pBetaP4[iikp][ks-1];
+ nb_ikp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_ikp].temp=temp_ikp;
+ bt_sg[nb_ikp].i=i;
+ bt_sg[nb_ikp].j=kp;
+ gmean0=sigma_g0[jtype-1][itype-1][kptype-1];
+ gmean1=sigma_g1[jtype-1][itype-1][kptype-1];
+ gmean2=sigma_g2[jtype-1][itype-1][kptype-1];
+ cosAng_jikp=(dis_ij[0]*dis_ikp[0]+dis_ij[1]*dis_ikp[1]
+ +dis_ij[2]*dis_ikp[2])/(r_ij*r_ikp);
+ dcA_jikp[0][0]=(dis_ikp[0]*r_ij*r_ikp-cosAng_jikp
+ *dis_ij[0]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[1][0]=(dis_ikp[1]*r_ij*r_ikp-cosAng_jikp
+ *dis_ij[1]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[2][0]=(dis_ikp[2]*r_ij*r_ikp-cosAng_jikp
+ *dis_ij[2]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[0][1]=(dis_ij[0]*r_ij*r_ikp-cosAng_jikp
+ *dis_ikp[0]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[1][1]=(dis_ij[1]*r_ij*r_ikp-cosAng_jikp
+ *dis_ikp[1]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[2][1]=(dis_ij[2]*r_ij*r_ikp-cosAng_jikp
+ *dis_ikp[2]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+ cosAng_kikp=(dis_ik[0]*dis_ikp[0]+dis_ik[1]*dis_ikp[1]
+ +dis_ik[2]*dis_ikp[2])/(r_ik*r_ikp);
+ dcA_kikp[0][0]=(dis_ikp[0]*r_ik*r_ikp-cosAng_kikp
+ *dis_ik[0]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+ dcA_kikp[1][0]=(dis_ikp[1]*r_ik*r_ikp-cosAng_kikp
+ *dis_ik[1]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+ dcA_kikp[2][0]=(dis_ikp[2]*r_ik*r_ikp-cosAng_kikp
+ *dis_ik[2]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+ dcA_kikp[0][1]=(dis_ik[0]*r_ik*r_ikp-cosAng_kikp
+ *dis_ikp[0]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+ dcA_kikp[1][1]=(dis_ik[1]*r_ik*r_ikp-cosAng_kikp
+ *dis_ikp[1]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+ dcA_kikp[2][1]=(dis_ik[2]*r_ik*r_ikp-cosAng_kikp
+ *dis_ikp[2]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+ amean=cosAng_jikp;
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[ktype-1][itype-1][kptype-1];
+ gmean1=sigma_g1[ktype-1][itype-1][kptype-1];
+ gmean2=sigma_g2[ktype-1][itype-1][kptype-1];
+ amean=cosAng_kikp;
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactorrt=betaS_ik*betaS_ikp;
+ rfactor=rfactorrt*rfactorrt;
+
+//2nd CC is second term of Eq. 11 (c) for i atom where j , k & k' =neighbor of i
+
+ CC=CC+2.0*gfactor*rfactor;
+
+//agpdpr1 is derivative of CC 2nd term w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of CC 2nd term w.r.t. Beta(r_ik')
+//app1 is derivative of CC 2nd term w.r.t. cos(theta_jik)
+//app2 is derivative of CC 2nd term w.r.t. cos(theta_jik')
+//app3 is derivative of CC 2nd term w.r.t. cos(theta_kik')
+
+ agpdpr1=4.0*gfactor*rfactorrt*betaS_ikp
+ *dBetaS_ik/r_ik;
+ agpdpr2=4.0*gfactor*rfactorrt*betaS_ik
+ *dBetaS_ikp/r_ikp;
+ app1=2.0*rfactor*gfactor2*gfactor3*gprime1;
+ app2=2.0*rfactor*gfactor1*gfactor3*gprime2;
+ app3=2.0*rfactor*gfactor1*gfactor2*gprime3;
+ bt_sg[nb_ij].dCC[0]+=
+ app1*dcA_jik[0][0]
+ +app2*dcA_jikp[0][0];
+ bt_sg[nb_ij].dCC[1]+=
+ app1*dcA_jik[1][0]
+ +app2*dcA_jikp[1][0];
+ bt_sg[nb_ij].dCC[2]+=
+ app1*dcA_jik[2][0]
+ +app2*dcA_jikp[2][0];
+ bt_sg[nb_ik].dCC[0]+=
+ app1*dcA_jik[0][1]
+ +app3*dcA_kikp[0][0]
+ +agpdpr1*dis_ik[0];
+ bt_sg[nb_ik].dCC[1]+=
+ app1*dcA_jik[1][1]
+ +app3*dcA_kikp[1][0]
+ +agpdpr1*dis_ik[1];
+ bt_sg[nb_ik].dCC[2]+=
+ app1*dcA_jik[2][1]
+ +app3*dcA_kikp[2][0]
+ +agpdpr1*dis_ik[2];
+ bt_sg[nb_ikp].dCC[0]=
+ app2*dcA_jikp[0][1]
+ +app3*dcA_kikp[0][1]
+ +agpdpr2*dis_ikp[0];
+ bt_sg[nb_ikp].dCC[1]=
+ app2*dcA_jikp[1][1]
+ +app3*dcA_kikp[1][1]
+ +agpdpr2*dis_ikp[1];
+ bt_sg[nb_ikp].dCC[2]=
+ app2*dcA_jikp[2][1]
+ +app3*dcA_kikp[2][1]
+ +agpdpr2*dis_ikp[2];
+ }
+ }
+ }
+
+// j and k are different neighbors of i and k' is a neighbor k not equal to i
+
+ for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+ temp_kkp=BOP_index[k]+ltmp;
+ kp=klist[ltmp];;
+ kptype = map[type[kp]]+1;
+ same_ikp=0;
+ same_jkp=0;
+ if(x[i][0]==x[kp][0]) {
+ if(x[i][1]==x[kp][1]) {
+ if(x[i][2]==x[kp][2]) {
+ same_ikp=1;
+ }
+ }
+ }
+ if(x[j][0]==x[kp][0]) {
+ if(x[j][1]==x[kp][1]) {
+ if(x[j][2]==x[kp][2]) {
+ same_jkp=1;
+ }
+ }
+ }
+ if(!same_ikp&&!same_jkp) {
+ if(ktype==kptype)
+ ikkp=ktype-1;
+ else if(ktype<kptype)
+ ikkp=ktype*bop_types-ktype*(ktype+1)/2+kptype-1;
+ else
+ ikkp=kptype*bop_types-kptype*(kptype+1)/2+ktype-1;
+ dis_kkp[0]=x[kp][0]-x[k][0];
+ dis_kkp[1]=x[kp][1]-x[k][1];
+ dis_kkp[2]=x[kp][2]-x[k][2];
+ rsq_kkp=dis_kkp[0]*dis_kkp[0]
+ +dis_kkp[1]*dis_kkp[1]
+ +dis_kkp[2]*dis_kkp[2];
+ r_kkp=sqrt(rsq_kkp);
+ if(r_kkp<=rcut[ikkp]) {
+ ps=r_kkp*rdr[ikkp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_kkp=((pBetaS3[ikkp][ks-1]*ps+pBetaS2[ikkp][ks-1])*ps
+ +pBetaS1[ikkp][ks-1])*ps+pBetaS[ikkp][ks-1];
+ dBetaS_kkp=(pBetaS6[ikkp][ks-1]*ps+pBetaS5[ikkp][ks-1])*ps
+ +pBetaS4[ikkp][ks-1];
+ betaP_kkp=((pBetaP3[ikkp][ks-1]*ps+pBetaP2[ikkp][ks-1])*ps
+ +pBetaP1[ikkp][ks-1])*ps+pBetaP[ikkp][ks-1];
+ dBetaP_kkp=(pBetaP6[ikkp][ks-1]*ps+pBetaP5[ikkp][ks-1])*ps
+ +pBetaP4[ikkp][ks-1];
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ sig_flag=1;
+ nkp=nsearch;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ nkp=nSigBk[n]-1;
+ itypeSigBk[n][nkp]=kp;
+ }
+ cosAng_ikkp=(-dis_ik[0]*dis_kkp[0]-dis_ik[1]*dis_kkp[1]
+ -dis_ik[2]*dis_kkp[2])/(r_ik*r_kkp);
+ dcA_ikkp[0][0]=(dis_kkp[0]*r_ik*r_kkp-cosAng_ikkp
+ *-dis_ik[0]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+ dcA_ikkp[1][0]=(dis_kkp[1]*r_ik*r_kkp-cosAng_ikkp
+ *-dis_ik[1]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+ dcA_ikkp[2][0]=(dis_kkp[2]*r_ik*r_kkp-cosAng_ikkp
+ *-dis_ik[2]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+ dcA_ikkp[0][1]=(-dis_ik[0]*r_ik*r_kkp-cosAng_ikkp
+ *dis_kkp[0]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+ dcA_ikkp[1][1]=(-dis_ik[1]*r_ik*r_kkp-cosAng_ikkp
+ *dis_kkp[1]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+ dcA_ikkp[2][1]=(-dis_ik[2]*r_ik*r_kkp-cosAng_ikkp
+ *dis_kkp[2]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+ nb_kkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_kkp].temp=temp_kkp;
+ bt_sg[nb_kkp].i=k;
+ bt_sg[nb_kkp].j=kp;
+ gmean0=sigma_g0[itype-1][ktype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][ktype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][ktype-1][kptype-1];
+ amean=cosAng_ikkp;
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gfactorsq2=gfactor2*gfactor2;
+ gsqprime2=2.0*gfactor2*gprime2;
+ gfactor=gfactorsq*gfactorsq2;
+ rfactorrt=betaS_ik*betaS_kkp;
+ rfactor=rfactorrt*rfactorrt;
+
+//3rd CC is third term of Eq. 11 (c) for i atom
+//where j , k =neighbor of i & k' =neighbor of k
+
+ CC=CC+gfactor*rfactor;
+
+//agpdpr1 is derivative of CC 3rd term w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of CC 3rd term w.r.t. Beta(r_kk')
+//app1 is derivative of CC 3rd term w.r.t. cos(theta_jik)
+//app2 is derivative of CC 3rd term w.r.t. cos(theta_ikk')
+
+ agpdpr1=2.0*gfactor*rfactorrt*betaS_kkp
+ *dBetaS_ik/r_ik;
+ agpdpr2=2.0*gfactor*rfactorrt*betaS_ik
+ *dBetaS_kkp/r_kkp;
+ app1=rfactor*gfactorsq2*gsqprime;
+ app2=rfactor*gfactorsq*gsqprime2;
+ bt_sg[nb_ij].dCC[0]+=
+ app1*dcA_jik[0][0];
+ bt_sg[nb_ij].dCC[1]+=
+ app1*dcA_jik[1][0];
+ bt_sg[nb_ij].dCC[2]+=
+ app1*dcA_jik[2][0];
+ bt_sg[nb_ik].dCC[0]+=
+ app1*dcA_jik[0][1]
+ +agpdpr1*dis_ik[0]
+ -app2*dcA_ikkp[0][0];
+ bt_sg[nb_ik].dCC[1]+=
+ app1*dcA_jik[1][1]
+ +agpdpr1*dis_ik[1]
+ -app2*dcA_ikkp[1][0];
+ bt_sg[nb_ik].dCC[2]+=
+ app1*dcA_jik[2][1]
+ +agpdpr1*dis_ik[2]
+ -app2*dcA_ikkp[2][0];
+ bt_sg[nb_kkp].dCC[0]+=
+ app2*dcA_ikkp[0][1]
+ +agpdpr2*dis_kkp[0];
+ bt_sg[nb_kkp].dCC[1]+=
+ app2*dcA_ikkp[1][1]
+ +agpdpr2*dis_kkp[1];
+ bt_sg[nb_kkp].dCC[2]+=
+ app2*dcA_ikkp[2][1]
+ +agpdpr2*dis_kkp[2];
+ }
+ }
+ }
+
+//j and k are different neighbors of i and k' is a neighbor j not equal to k
+
+ for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+ sig_flag=0;
+ temp_jkp=BOP_index[j]+ltmp;
+ kp=jlist[ltmp];
+ kptype = map[type[kp]]+1;
+ kplist=firstneigh[kp];
+
+ same_kkpk=0;
+ same_jkpj=0;
+
+ for(kpNeij=0;kpNeij<numneigh[kp];kpNeij++) {
+ temp_kpj=BOP_index[kp]+kpNeij;
+ kpj=kplist[kpNeij];
+ if(x[j][0]==x[kpj][0]) {
+ if(x[j][1]==x[kpj][1]) {
+ if(x[j][2]==x[kpj][2]) {
+ same_jkpj=1;
+ break;
+ }
+ }
+ }
+ }
+ for(kpNeik=0;kpNeik<numneigh[kp];kpNeik++) {
+ temp_kpk=BOP_index[kp]+kpNeik;
+ kpk=kplist[kpNeik];
+ if(x[k][0]==x[kpk][0]) {
+ if(x[k][1]==x[kpk][1]) {
+ if(x[k][2]==x[kpk][2]) {
+ same_kkpk=1;
+ break;
+ }
+ }
+ }
+ }
+ if(!same_jkpj&&!same_kkpk) {
+ same_kkpk=0;
+ for(kNeikp=0;kNeikp<numneigh[k];kNeikp++) {
+ temp_kkp=BOP_index[k]+kNeikp;
+ kkp=kplist[kNeikp];
+ if(x[kp][0]==x[kkp][0]) {
+ if(x[kp][1]==x[kkp][1]) {
+ if(x[kp][2]==x[kkp][2]) {
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==1) {
+ for(nsearch=0;nsearch<numneigh[kp];nsearch++) {
+ kp_nsearch=BOP_index[kp]+nsearch;
+ ncmp=kplist[nsearch];
+ if(x[ncmp][0]==x[j][0]) {
+ if(x[ncmp][1]==x[j][1]) {
+ if(x[ncmp][2]==x[j][2]) {
+ kpNeij=nsearch;
+ }
+ }
+ }
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ kpNeik=nsearch;
+ }
+ }
+ }
+ }
+ if(jtype==kptype)
+ ijkp=jtype-1;
+ else if(jtype<kptype)
+ ijkp=jtype*bop_types-jtype*(jtype+1)/2+kptype-1;
+ else
+ ijkp=kptype*bop_types-kptype*(kptype+1)/2+jtype-1;
+ if(ktype==kptype)
+ ikkp=ktype-1;
+ else if(ktype<kptype)
+ ikkp=ktype*bop_types-ktype*(ktype+1)/2+kptype-1;
+ else
+ ikkp=kptype*bop_types-kptype*(kptype+1)/2+ktype-1;
+
+ dis_jkp[0]=x[kp][0]-x[j][0];
+ dis_jkp[1]=x[kp][1]-x[j][1];
+ dis_jkp[2]=x[kp][2]-x[j][2];
+ rsq_jkp=dis_jkp[0]*dis_jkp[0]
+ +dis_jkp[1]*dis_jkp[1]
+ +dis_jkp[2]*dis_jkp[2];
+ r_jkp=sqrtl(rsq_jkp);
+ ps=r_jkp*rdr[ijkp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+ +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+ dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+ +pBetaS4[ijkp][ks-1];
+ betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+ +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+ dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+ +pBetaP4[ijkp][ks-1];
+ dis_kkp[0]=x[kp][0]-x[k][0];
+ dis_kkp[1]=x[kp][1]-x[k][1];
+ dis_kkp[2]=x[kp][2]-x[k][2];
+ rsq_kkp=dis_kkp[0]*dis_kkp[0]
+ +dis_kkp[1]*dis_kkp[1]
+ +dis_kkp[2]*dis_kkp[2];
+ r_kkp=sqrtl(rsq_kkp);
+ ps=r_kkp*rdr[ikkp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_kkp=((pBetaS3[ikkp][ks-1]*ps+pBetaS2[ikkp][ks-1])*ps
+ +pBetaS1[ikkp][ks-1])*ps+pBetaS[ikkp][ks-1];
+ dBetaS_kkp=(pBetaS6[ikkp][ks-1]*ps+pBetaS5[ikkp][ks-1])*ps
+ +pBetaS4[ikkp][ks-1];
+ betaP_kkp=((pBetaP3[ikkp][ks-1]*ps+pBetaP2[ikkp][ks-1])*ps
+ +pBetaP1[ikkp][ks-1])*ps+pBetaP[ikkp][ks-1];
+ dBetaP_kkp=(pBetaP6[ikkp][ks-1]*ps+pBetaP5[ikkp][ks-1])*ps
+ +pBetaP4[ikkp][ks-1];
+ cosAng_ijkp=(-dis_ij[0]*dis_jkp[0]-dis_ij[1]*dis_jkp[1]
+ -dis_ij[2]*dis_jkp[2])/(r_ij*r_jkp);
+ dcA_ijkp[0][0]=(dis_jkp[0]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[0]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[1][0]=(dis_jkp[1]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[1]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[2][0]=(dis_jkp[2]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[2]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[0][1]=(-dis_ij[0]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[0]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[1][1]=(-dis_ij[1]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[1]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[2][1]=(-dis_ij[2]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[2]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ cosAng_ikkp=(-dis_ik[0]*dis_kkp[0]-dis_ik[1]*dis_kkp[1]
+ -dis_ik[2]*dis_kkp[2])/(r_ik*r_kkp);
+ dcA_ikkp[0][0]=(dis_kkp[0]*r_ik*r_kkp-cosAng_ikkp
+ *-dis_ik[0]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+ dcA_ikkp[1][0]=(dis_kkp[1]*r_ik*r_kkp-cosAng_ikkp
+ *-dis_ik[1]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+ dcA_ikkp[2][0]=(dis_kkp[2]*r_ik*r_kkp-cosAng_ikkp
+ *-dis_ik[2]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+ dcA_ikkp[0][1]=(-dis_ik[0]*r_ik*r_kkp-cosAng_ikkp
+ *dis_kkp[0]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+ dcA_ikkp[1][1]=(-dis_ik[1]*r_ik*r_kkp-cosAng_ikkp
+ *dis_kkp[1]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+ dcA_ikkp[2][1]=(-dis_ik[2]*r_ik*r_kkp-cosAng_ikkp
+ *dis_kkp[2]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+ cosAng_jkpk=(dis_jkp[0]*dis_kkp[0]+dis_jkp[1]*dis_kkp[1]
+ +dis_jkp[2]*dis_kkp[2])/(r_jkp*r_kkp);
+ dcA_jkpk[0][0]=(-dis_kkp[0]*r_jkp*r_kkp-cosAng_jkpk
+ *-dis_jkp[0]*r_kkp*r_kkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+ dcA_jkpk[1][0]=(-dis_kkp[1]*r_jkp*r_kkp-cosAng_jkpk
+ *-dis_jkp[1]*r_kkp*r_kkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+ dcA_jkpk[2][0]=(-dis_kkp[2]*r_jkp*r_kkp-cosAng_jkpk
+ *-dis_jkp[2]*r_kkp*r_kkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+ dcA_jkpk[0][1]=(-dis_jkp[0]*r_jkp*r_kkp-cosAng_jkpk
+ *-dis_kkp[0]*r_jkp*r_jkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+ dcA_jkpk[1][1]=(-dis_jkp[1]*r_jkp*r_kkp-cosAng_jkpk
+ *-dis_kkp[1]*r_jkp*r_jkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+ dcA_jkpk[2][1]=(-dis_jkp[2]*r_jkp*r_kkp-cosAng_jkpk
+ *-dis_kkp[2]*r_jkp*r_jkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ nkp=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ nkp=nSigBk[n]-1;
+ itypeSigBk[n][nkp]=kp;
+ }
+ temp_kpk=BOP_index[kp]+kpNeik;
+ nb_jkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jkp].temp=temp_jkp;
+ bt_sg[nb_jkp].i=j;
+ bt_sg[nb_jkp].j=kp;
+ nb_kkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_kkp].temp=temp_kkp;
+ bt_sg[nb_kkp].i=k;
+ bt_sg[nb_kkp].j=kp;
+ gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+ amean=cosAng_ijkp;
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[itype-1][ktype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][ktype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][ktype-1][kptype-1];
+ amean=cosAng_ikkp;
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[jtype-1][kptype-1][ktype-1];
+ gmean1=sigma_g1[jtype-1][kptype-1][ktype-1];
+ gmean2=sigma_g2[jtype-1][kptype-1][ktype-1];
+ amean=cosAng_jkpk;
+ gfactor4=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime4=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3*gfactor4;
+ rfactor0=(betaS_ik+small2)*(betaS_jkp+small2)
+ *(betaS_kkp+small2);
+ rfactor=pow(rfactor0,2.0/3.0);
+ drfactor=2.0/3.0*pow(rfactor0,-1.0/3.0);
+
+//EE is Eq. 25(notes)
+
+ EE=EE+gfactor*rfactor;
+
+//agpdpr1 is derivative of agpdpr1 w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of agpdpr1 w.r.t. Beta(r_jk')
+//agpdpr3 is derivative of agpdpr1 w.r.t. Beta(r_kk')
+//app1 is derivative of agpdpr1 w.r.t. cos(theta_jik)
+//app2 is derivative of agpdpr1 w.r.t. cos(theta_ijk')
+//app3 is derivative of agpdpr1 w.r.t. cos(theta_ikk')
+//app4 is derivative of agpdpr1 w.r.t. cos(theta_jk'k)
+
+ agpdpr1=gfactor*drfactor*(betaS_jkp+small2)*(betaS_kkp
+ +small2)*dBetaS_ik/r_ik;
+ agpdpr2=gfactor*drfactor*(betaS_ik+small2)*(betaS_kkp
+ +small2)*dBetaS_jkp/r_jkp;
+ agpdpr3=gfactor*drfactor*(betaS_ik+small2)*(betaS_jkp
+ +small2)*dBetaS_kkp/r_kkp;
+ app1=rfactor*gfactor2*gfactor3*gfactor4*gprime1;
+ app2=rfactor*gfactor1*gfactor3*gfactor4*gprime2;
+ app3=rfactor*gfactor1*gfactor2*gfactor4*gprime3;
+ app4=rfactor*gfactor1*gfactor2*gfactor3*gprime4;
+ bt_sg[nb_ij].dEE[0]+=
+ app1*dcA_jik[0][0]
+ -app2*dcA_ijkp[0][0];
+ bt_sg[nb_ij].dEE[1]+=
+ app1*dcA_jik[1][0]
+ -app2*dcA_ijkp[1][0];
+ bt_sg[nb_ij].dEE[2]+=
+ app1*dcA_jik[2][0]
+ -app2*dcA_ijkp[2][0];
+ bt_sg[nb_ik].dEE[0]+=
+ app1*dcA_jik[0][1]
+ +agpdpr1*dis_ik[0]
+ -app3*dcA_ikkp[0][0];
+ bt_sg[nb_ik].dEE[1]+=
+ app1*dcA_jik[1][1]
+ +agpdpr1*dis_ik[1]
+ -app3*dcA_ikkp[1][0];
+ bt_sg[nb_ik].dEE[2]+=
+ app1*dcA_jik[2][1]
+ +agpdpr1*dis_ik[2]
+ -app3*dcA_ikkp[2][0];
+ bt_sg[nb_jkp].dEE[0]+=
+ app2*dcA_ijkp[0][1]
+ +agpdpr2*dis_jkp[0]
+ -app4*dcA_jkpk[0][0];
+ bt_sg[nb_jkp].dEE[1]+=
+ app2*dcA_ijkp[1][1]
+ +agpdpr2*dis_jkp[1]
+ -app4*dcA_jkpk[1][0];
+ bt_sg[nb_jkp].dEE[2]+=
+ app2*dcA_ijkp[2][1]
+ +agpdpr2*dis_jkp[2]
+ -app4*dcA_jkpk[2][0];
+ bt_sg[nb_kkp].dEE[0]+=
+ app3*dcA_ikkp[0][1]
+ +agpdpr3*dis_kkp[0]
+ -app4*dcA_jkpk[0][1];
+ bt_sg[nb_kkp].dEE[1]+=
+ app3*dcA_ikkp[1][1]
+ +agpdpr3*dis_kkp[1]
+ -app4*dcA_jkpk[1][1];
+ bt_sg[nb_kkp].dEE[2]+=
+ app3*dcA_ikkp[2][1]
+ +agpdpr3*dis_kkp[2]
+ -app4*dcA_jkpk[2][1];
+ }
+ }
+ }
+ }
+ }
+ }
+
+//j is a neighbor of i and k is a neighbor of j not equal to i
+
+ for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+ if(ktmp!=ji) {
+ temp_jk=BOP_index[j]+ktmp;
+ k=jlist[ktmp];
+ klist=firstneigh[k];
+ ktype=map[type[k]]+1;
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(jtype==ktype)
+ ijk=jtype-1;
+ else if(jtype<ktype)
+ ijk=jtype*bop_types-jtype*(jtype+1)/2+ktype-1;
+ else
+ ijk=ktype*bop_types-ktype*(ktype+1)/2+jtype-1;
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ new1=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ new1=nSigBk[n]-1;
+ itypeSigBk[n][new1]=k;
+ }
+ dis_jk[0]=x[k][0]-x[j][0];
+ dis_jk[1]=x[k][1]-x[j][1];
+ dis_jk[2]=x[k][2]-x[j][2];
+ rsq_jk=dis_jk[0]*dis_jk[0]
+ +dis_jk[1]*dis_jk[1]
+ +dis_jk[2]*dis_jk[2];
+ r_jk=sqrt(rsq_jk);
+ if(r_jk<=rcut[ijk]) {
+ ps=r_jk*rdr[ijk]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_jk=((pBetaS3[ijk][ks-1]*ps+pBetaS2[ijk][ks-1])*ps
+ +pBetaS1[ijk][ks-1])*ps+pBetaS[ijk][ks-1];
+ dBetaS_jk=(pBetaS6[ijk][ks-1]*ps+pBetaS5[ijk][ks-1])*ps
+ +pBetaS4[ijk][ks-1];
+ betaP_jk=((pBetaP3[ijk][ks-1]*ps+pBetaP2[ijk][ks-1])*ps
+ +pBetaP1[ijk][ks-1])*ps+pBetaP[ijk][ks-1];
+ dBetaP_jk=(pBetaP6[ijk][ks-1]*ps+pBetaP5[ijk][ks-1])*ps
+ +pBetaP4[ijk][ks-1];
+ cosAng_ijk=(-dis_ij[0]*dis_jk[0]-dis_ij[1]*dis_jk[1]
+ -dis_ij[2]*dis_jk[2])/(r_ij*r_jk);
+ dcA_ijk[0][0]=(dis_jk[0]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[0]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[1][0]=(dis_jk[1]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[1]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[2][0]=(dis_jk[2]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[2]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[0][1]=(-dis_ij[0]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[0]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[1][1]=(-dis_ij[1]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[1]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[2][1]=(-dis_ij[2]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[2]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ nb_jk=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jk].temp=temp_jk;
+ bt_sg[nb_jk].i=j;
+ bt_sg[nb_jk].j=k;
+ gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+ amean=cosAng_ijk;
+ gfactor1=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime1=gmean1+2.0*gmean2*amean;
+ gfactorsq=gfactor1*gfactor1;
+ gsqprime=2.0*gfactor1*gprime1;
+ rfactor1rt=betaS_jk*betaS_jk;
+ rfactor1=rfactor1rt*rfactor1rt;
+
+//BB is Eq. 34 (a) or Eq. 10 (c) for the j atom
+//1st DD is Eq. 11 (c) for j atom where i & k=neighbor of j
+
+ BB=BB+gfactorsq*rfactor1rt;
+ DD=DD+gfactorsq*rfactor1;
+
+//agpdpr1 is derivative of BB w.r.t. Beta(r_jk)
+//app1 is derivative of BB w.r.t. cos(theta_ijk)
+
+ agpdpr1=2.0*gfactorsq*betaS_jk*dBetaS_jk/r_jk;
+ agpdpr2=2.0*rfactor1rt*agpdpr1;
+ app1=rfactor1rt*gsqprime;
+ app2=rfactor1rt*app1;
+ bt_sg[nb_ij].dBB[0]-=
+ app1*dcA_ijk[0][0];
+ bt_sg[nb_ij].dBB[1]-=
+ app1*dcA_ijk[1][0];
+ bt_sg[nb_ij].dBB[2]-=
+ app1*dcA_ijk[2][0];
+ bt_sg[nb_ij].dDD[0]-=
+ app2*dcA_ijk[0][0];
+ bt_sg[nb_ij].dDD[1]-=
+ app2*dcA_ijk[1][0];
+ bt_sg[nb_ij].dDD[2]-=
+ app2*dcA_ijk[2][0];
+ bt_sg[nb_jk].dBB[0]+=
+ app1*dcA_ijk[0][1]
+ +agpdpr1*dis_jk[0];
+ bt_sg[nb_jk].dBB[1]+=
+ app1*dcA_ijk[1][1]
+ +agpdpr1*dis_jk[1];
+ bt_sg[nb_jk].dBB[2]+=
+ app1*dcA_ijk[2][1]
+ +agpdpr1*dis_jk[2];
+ bt_sg[nb_jk].dDD[0]+=
+ app2*dcA_ijk[0][1]
+ +agpdpr2*dis_jk[0];
+ bt_sg[nb_jk].dDD[1]+=
+ app2*dcA_ijk[1][1]
+ +agpdpr2*dis_jk[1];
+ bt_sg[nb_jk].dDD[2]+=
+ app2*dcA_ijk[2][1]
+ +agpdpr2*dis_jk[2];
+
+//j is a neighbor of i, k and k' prime different neighbors of j not equal to i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=ji) {
+ temp_jkp=BOP_index[j]+ltmp;
+ kp=jlist[ltmp];
+ kptype=map[type[kp]]+1;
+ if(jtype==kptype)
+ ijkp=jtype-1;
+ else if(jtype<kptype)
+ ijkp=jtype*bop_types-jtype*(jtype+1)/2+kptype-1;
+ else
+ ijkp=kptype*bop_types-kptype*(kptype+1)/2+jtype-1;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ new2=nsearch;
+ break;
+ }
+ }
+ }
+ }
+ dis_jkp[0]=x[kp][0]-x[j][0];
+ dis_jkp[1]=x[kp][1]-x[j][1];
+ dis_jkp[2]=x[kp][2]-x[j][2];
+ rsq_jkp=dis_jkp[0]*dis_jkp[0]
+ +dis_jkp[1]*dis_jkp[1]
+ +dis_jkp[2]*dis_jkp[2];
+ r_jkp=sqrt(rsq_jkp);
+ if(r_jkp<=rcut[ijkp]) {
+ ps=r_jkp*rdr[ijkp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+ +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+ dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+ +pBetaS4[ijkp][ks-1];
+ betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+ +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+ dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+ +pBetaP4[ijkp][ks-1];
+ cosAng_ijkp=(-dis_ij[0]*dis_jkp[0]-dis_ij[1]*dis_jkp[1]
+ -dis_ij[2]*dis_jkp[2])/(r_ij*r_jkp);
+ dcA_ijkp[0][0]=(dis_jkp[0]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[0]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[1][0]=(dis_jkp[1]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[1]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[2][0]=(dis_jkp[2]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[2]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[0][1]=(-dis_ij[0]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[0]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[1][1]=(-dis_ij[1]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[1]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[2][1]=(-dis_ij[2]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[2]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ cosAng_kjkp=(dis_jk[0]*dis_jkp[0]+dis_jk[1]*dis_jkp[1]
+ +dis_jk[2]*dis_jkp[2])/(r_jk*r_jkp);
+ dcA_kjkp[0][0]=(dis_jkp[0]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jk[0]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[1][0]=(dis_jkp[1]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jk[1]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[2][0]=(dis_jkp[2]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jk[2]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[0][1]=(dis_jk[0]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jkp[0]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[1][1]=(dis_jk[1]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jkp[1]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[2][1]=(dis_jk[2]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jkp[2]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+ nb_jkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jkp].temp=temp_jkp;
+ bt_sg[nb_jkp].i=j;
+ bt_sg[nb_jkp].j=kp;
+ gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+ amean=cosAng_ijkp;
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[ktype-1][jtype-1][kptype-1];
+ gmean1=sigma_g1[ktype-1][jtype-1][kptype-1];
+ gmean2=sigma_g2[ktype-1][jtype-1][kptype-1];
+ amean=cosAng_kjkp;
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactorrt=betaS_jk*betaS_jkp;
+ rfactor=rfactorrt*rfactorrt;
+
+//2nd DD is Eq. 11 (c) for j atom where i , k & k'=neighbor of j
+
+ DD=DD+2.0*gfactor*rfactor;
+
+//agpdpr1 is derivative of DD w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of DD w.r.t. Beta(r_jk')
+//app1 is derivative of DD w.r.t. cos(theta_ijk)
+//app2 is derivative of DD w.r.t. cos(theta_ijkp)
+//app3 is derivative of DD w.r.t. cos(theta_kjkp)
+
+ agpdpr1=4.0*gfactor*rfactorrt*betaS_jkp
+ *dBetaS_jk/r_jk;
+ agpdpr2=4.0*gfactor*rfactorrt*betaS_jk
+ *dBetaS_jkp/r_jkp;
+ app1=2.0*rfactor*gfactor2*gfactor3*gprime1;
+ app2=2.0*rfactor*gfactor1*gfactor3*gprime2;
+ app3=2.0*rfactor*gfactor1*gfactor2*gprime3;
+ bt_sg[nb_ij].dDD[0]-=
+ app1*dcA_ijk[0][0]
+ +app2*dcA_ijkp[0][0];
+ bt_sg[nb_ij].dDD[1]-=
+ app1*dcA_ijk[1][0]
+ +app2*dcA_ijkp[1][0];
+ bt_sg[nb_ij].dDD[2]-=
+ app1*dcA_ijk[2][0]
+ +app2*dcA_ijkp[2][0];
+ bt_sg[nb_jk].dDD[0]+=
+ app1*dcA_ijk[0][1]
+ +app3*dcA_kjkp[0][0]
+ +agpdpr1*dis_jk[0];
+ bt_sg[nb_jk].dDD[1]+=
+ app1*dcA_ijk[1][1]
+ +app3*dcA_kjkp[1][0]
+ +agpdpr1*dis_jk[1];
+ bt_sg[nb_jk].dDD[2]+=
+ app1*dcA_ijk[2][1]
+ +app3*dcA_kjkp[2][0]
+ +agpdpr1*dis_jk[2];
+ bt_sg[nb_jkp].dDD[0]+=
+ app2*dcA_ijkp[0][1]
+ +app3*dcA_kjkp[0][1]
+ +agpdpr2*dis_jkp[0];
+ bt_sg[nb_jkp].dDD[1]+=
+ app2*dcA_ijkp[1][1]
+ +app3*dcA_kjkp[1][1]
+ +agpdpr2*dis_jkp[1];
+ bt_sg[nb_jkp].dDD[2]+=
+ app2*dcA_ijkp[2][1]
+ +app3*dcA_kjkp[2][1]
+ +agpdpr2*dis_jkp[2];
+
+ }
+ }
+ }
+
+//j is a neighbor of i, k is a neighbor of j not equal to i and k'
+//is a neighbor of k not equal to j or i
+
+ for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+ temp_kkp=BOP_index[k]+ltmp;
+ kp=klist[ltmp];
+ kptype=map[type[kp]]+1;
+ same_ikp=0;
+ same_jkp=0;
+ if(x[i][0]==x[kp][0]) {
+ if(x[i][1]==x[kp][1]) {
+ if(x[i][2]==x[kp][2]) {
+ same_ikp=1;
+ }
+ }
+ }
+ if(x[j][0]==x[kp][0]) {
+ if(x[j][1]==x[kp][1]) {
+ if(x[j][2]==x[kp][2]) {
+ same_jkp=1;
+ }
+ }
+ }
+ if(!same_ikp&&!same_jkp) {
+ if(ktype==kptype)
+ ikkp=ktype-1;
+ else if(ktype<kptype)
+ ikkp=ktype*bop_types-ktype*(ktype+1)/2+kptype-1;
+ else
+ ikkp=kptype*bop_types-kptype*(kptype+1)/2+ktype-1;
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ new2=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ new2=nSigBk[n]-1;
+ itypeSigBk[n][new2]=kp;
+ }
+ dis_kkp[0]=x[kp][0]-x[k][0];
+ dis_kkp[1]=x[kp][1]-x[k][1];
+ dis_kkp[2]=x[kp][2]-x[k][2];
+ rsq_kkp=dis_kkp[0]*dis_kkp[0]
+ +dis_kkp[1]*dis_kkp[1]
+ +dis_kkp[2]*dis_kkp[2];
+ r_kkp=sqrt(rsq_kkp);
+ if(r_kkp<=rcut[ikkp]) {
+ ps=r_kkp*rdr[ikkp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_kkp=((pBetaS3[ikkp][ks-1]*ps+pBetaS2[ikkp][ks-1])*ps
+ +pBetaS1[ikkp][ks-1])*ps+pBetaS[ikkp][ks-1];
+ dBetaS_kkp=(pBetaS6[ikkp][ks-1]*ps+pBetaS5[ikkp][ks-1])*ps
+ +pBetaS4[ikkp][ks-1];
+ betaP_kkp=((pBetaP3[ikkp][ks-1]*ps+pBetaP2[ikkp][ks-1])*ps
+ +pBetaP1[ikkp][ks-1])*ps+pBetaP[ikkp][ks-1];
+ dBetaP_kkp=(pBetaP6[ikkp][ks-1]*ps+pBetaP5[ikkp][ks-1])*ps
+ +pBetaP4[ikkp][ks-1];
+ cosAng_jkkp=(-dis_jk[0]*dis_kkp[0]-dis_jk[1]*dis_kkp[1]
+ -dis_jk[2]*dis_kkp[2])/(r_jk*r_kkp);
+ dcA_jkkp[0][0]=(dis_kkp[0]*r_jk*r_kkp-cosAng_jkkp
+ *-dis_jk[0]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+ dcA_jkkp[1][0]=(dis_kkp[1]*r_jk*r_kkp-cosAng_jkkp
+ *-dis_jk[1]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+ dcA_jkkp[2][0]=(dis_kkp[2]*r_jk*r_kkp-cosAng_jkkp
+ *-dis_jk[2]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+ dcA_jkkp[0][1]=(-dis_jk[0]*r_jk*r_kkp-cosAng_jkkp
+ *dis_kkp[0]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+ dcA_jkkp[1][1]=(-dis_jk[1]*r_jk*r_kkp-cosAng_jkkp
+ *dis_kkp[1]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+ dcA_jkkp[2][1]=(-dis_jk[2]*r_jk*r_kkp-cosAng_jkkp
+ *dis_kkp[2]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+ nb_kkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_kkp].temp=temp_kkp;
+ bt_sg[nb_kkp].i=k;
+ bt_sg[nb_kkp].j=kp;
+ gmean0=sigma_g0[jtype-1][ktype-1][kptype-1];
+ gmean1=sigma_g1[jtype-1][ktype-1][kptype-1];
+ gmean2=sigma_g2[jtype-1][ktype-1][kptype-1];
+ amean=cosAng_jkkp;
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gfactorsq2=gfactor2*gfactor2;
+ gsqprime2=2.0*gfactor2*gprime2;
+ gfactor=gfactorsq*gfactorsq2;
+ rfactorrt=betaS_jk*betaS_kkp;
+ rfactor=rfactorrt*rfactorrt;
+
+//3rd DD is Eq. 11 (c) for j atom where i & k=neighbor of j & k'=neighbor of k
+
+ DD=DD+gfactor*rfactor;
+
+//agpdpr1 is derivative of DD 3rd term w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of DD 3rd term w.r.t. Beta(r_kk')
+//app1 is derivative of DD 3rd term w.r.t. cos(theta_ijk)
+//app2 is derivative of DD 3rd term w.r.t. cos(theta_jkkp)
+
+ agpdpr1=2.0*gfactor*rfactorrt*betaS_kkp
+ *dBetaS_jk/r_jk;
+ agpdpr2=2.0*gfactor*rfactorrt*betaS_jk
+ *dBetaS_kkp/r_kkp;
+ app1=rfactor*gfactorsq2*gsqprime;
+ app2=rfactor*gfactorsq*gsqprime2;
+ bt_sg[nb_ij].dDD[0]-=
+ app1*dcA_ijk[0][0];
+ bt_sg[nb_ij].dDD[1]-=
+ app1*dcA_ijk[1][0];
+ bt_sg[nb_ij].dDD[2]-=
+ app1*dcA_ijk[2][0];
+ bt_sg[nb_jk].dDD[0]+=
+ app1*dcA_ijk[0][1]
+ +agpdpr1*dis_jk[0]
+ -app2*dcA_jkkp[0][0];
+ bt_sg[nb_jk].dDD[1]+=
+ app1*dcA_ijk[1][1]
+ +agpdpr1*dis_jk[1]
+ -app2*dcA_jkkp[1][0];
+ bt_sg[nb_jk].dDD[2]+=
+ app1*dcA_ijk[2][1]
+ +agpdpr1*dis_jk[2]
+ -app2*dcA_jkkp[2][0];
+ bt_sg[nb_kkp].dDD[0]+=
+ app2*dcA_jkkp[0][1]
+ +agpdpr2*dis_kkp[0];
+ bt_sg[nb_kkp].dDD[1]+=
+ app2*dcA_jkkp[1][1]
+ +agpdpr2*dis_kkp[1];
+ bt_sg[nb_kkp].dDD[2]+=
+ app2*dcA_jkkp[2][1]
+ +agpdpr2*dis_kkp[2];
+
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sig_flag=0;
+ if(FF<=0.000001) {
+ sigB[n]=0.0;
+ sig_flag=1;
+ }
+ if(sig_flag==0) {
+ if(AA<0.0)
+ AA=0.0;
+ if(BB<0.0)
+ BB=0.0;
+ if(CC<0.0)
+ CC=0.0;
+ if(DD<0.0)
+ DD=0.0;
+
+// AA and BB are the representations of (a) Eq. 34 and (b) Eq. 9
+// for atoms i and j respectively
+
+ AAC=AA+BB;
+ BBC=AA*BB;
+ CCC=AA*AA+BB*BB;
+ DDC=CC+DD;
+
+//EEC is a modified form of (a) Eq. 33
+
+ EEC=(DDC-CCC)/(AAC+2.0*small1);
+ AACFF=1.0/(AAC+2.0*small1);
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ bt_sg[m].dAAC[0]=bt_sg[m].dAA[0]
+ +bt_sg[m].dBB[0];
+ bt_sg[m].dAAC[1]=bt_sg[m].dAA[1]
+ +bt_sg[m].dBB[1];
+ bt_sg[m].dAAC[2]=bt_sg[m].dAA[2]
+ +bt_sg[m].dBB[2];
+ bt_sg[m].dBBC[0]=bt_sg[m].dAA[0]*BB
+ +AA*bt_sg[m].dBB[0];
+ bt_sg[m].dBBC[1]=bt_sg[m].dAA[1]*BB
+ +AA*bt_sg[m].dBB[1];
+ bt_sg[m].dBBC[2]=bt_sg[m].dAA[2]*BB
+ +AA*bt_sg[m].dBB[2];
+ bt_sg[m].dCCC[0]=2.0*AA*bt_sg[m].dAA[0]
+ +2.0*BB*bt_sg[m].dBB[0];
+ bt_sg[m].dCCC[1]=2.0*AA*bt_sg[m].dAA[1]
+ +2.0*BB*bt_sg[m].dBB[1];
+ bt_sg[m].dCCC[2]=2.0*AA*bt_sg[m].dAA[2]
+ +2.0*BB*bt_sg[m].dBB[2];
+ bt_sg[m].dDDC[0]=bt_sg[m].dCC[0]
+ +bt_sg[m].dDD[0];
+ bt_sg[m].dDDC[1]=bt_sg[m].dCC[1]
+ +bt_sg[m].dDD[1];
+ bt_sg[m].dDDC[2]=bt_sg[m].dCC[2]
+ +bt_sg[m].dDD[2];
+ bt_sg[m].dEEC[0]=(bt_sg[m].dDDC[0]
+ -bt_sg[m].dCCC[0]
+ -EEC*bt_sg[m].dAAC[0])*AACFF;
+ bt_sg[m].dEEC[1]=(bt_sg[m].dDDC[1]
+ -bt_sg[m].dCCC[1]
+ -EEC*bt_sg[m].dAAC[1])*AACFF;
+ bt_sg[m].dEEC[2]=(bt_sg[m].dDDC[2]
+ -bt_sg[m].dCCC[2]
+ -EEC*bt_sg[m].dAAC[2])*AACFF;
+ }
+ }
+ UT=EEC*FF+BBC+small3[iij];
+ UT=1.0/sqrt(UT);
+
+// FFC is slightly modified form of (a) Eq. 31
+// GGC is slightly modified form of (a) Eq. 32
+// bndtmp is a slightly modified form of (a) Eq. 30 and (b) Eq. 8
+
+ FFC=BBC*UT;
+ GGC=EEC*UT;
+ bndtmp=(FF+sigma_delta[iij]*sigma_delta[iij])*(1.0+sigma_a[iij]*GGC)
+ *(1.0+sigma_a[iij]*GGC)+sigma_c[iij]*(AAC+sigma_a[iij]*EE
+ +sigma_a[iij]*FFC*(2.0+GGC))+small4;
+ UTcom=-0.5*UT*UT*UT;
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ bt_sg[m].dUT[0]=UTcom*(bt_sg[m].dEEC[0]*FF
+ +EEC*bt_sg[m].dFF[0]+bt_sg[m].dBBC[0]);
+ bt_sg[m].dUT[1]=UTcom*(bt_sg[m].dEEC[1]*FF
+ +EEC*bt_sg[m].dFF[1]+bt_sg[m].dBBC[1]);
+ bt_sg[m].dUT[2]=UTcom*(bt_sg[m].dEEC[2]*FF
+ +EEC*bt_sg[m].dFF[2]+bt_sg[m].dBBC[2]);
+ bt_sg[m].dFFC[0]=bt_sg[m].dBBC[0]*UT
+ +BBC*bt_sg[m].dUT[0];
+ bt_sg[m].dFFC[1]=bt_sg[m].dBBC[1]*UT
+ +BBC*bt_sg[m].dUT[1];
+ bt_sg[m].dFFC[2]=bt_sg[m].dBBC[2]*UT
+ +BBC*bt_sg[m].dUT[2];
+ bt_sg[m].dGGC[0]=bt_sg[m].dEEC[0]*UT
+ +EEC*bt_sg[m].dUT[0];
+ bt_sg[m].dGGC[1]=bt_sg[m].dEEC[1]*UT
+ +EEC*bt_sg[m].dUT[1];
+ bt_sg[m].dGGC[2]=bt_sg[m].dEEC[2]*UT
+ +EEC*bt_sg[m].dUT[2];
+ }
+ }
+ psign=1.0;
+ if(1.0+sigma_a[iij]*GGC<0.0)
+ psign=-1.0;
+ bndtmp0=1.0/sqrtl(bndtmp);
+ sigB1[n]=psign*betaS_ij*(1.0+sigma_a[iij]*GGC)*bndtmp0;
+ bndtmp=-0.5*bndtmp0*bndtmp0*bndtmp0;
+ bndtmp1=psign*(1.0+sigma_a[iij]*GGC)*bndtmp0+psign*betaS_ij
+ *(1.0+sigma_a[iij]*GGC)*bndtmp*2.0*betaS_ij*(1.0
+ +sigma_a[iij]*GGC)*(1.0+sigma_a[iij]*GGC);
+ bndtmp1=bndtmp1*dBetaS_ij/r_ij;
+ bndtmp2=psign*betaS_ij*(1.0+sigma_a[iij]*GGC)*bndtmp*sigma_c[iij];
+ bndtmp3=psign*betaS_ij*(1.0+sigma_a[iij]*GGC)
+ *bndtmp*sigma_c[iij]*sigma_a[iij];
+ bndtmp4=psign*betaS_ij*(1.0+sigma_a[iij]*GGC)
+ *bndtmp*sigma_c[iij]*sigma_a[iij]*(2.0+GGC);
+ bndtmp5=sigma_a[iij]*psign*betaS_ij*bndtmp0
+ +psign*betaS_ij*(1.0+sigma_a[iij]*GGC)*bndtmp
+ *(2.0*(FF+sigma_delta[iij]*sigma_delta[iij])*(1.0
+ +sigma_a[iij]*GGC)*sigma_a[iij]+sigma_c[iij]*sigma_a[iij]*FFC);
+ setting=0;
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ temp_kk=bt_sg[m].temp;
+ if(temp_kk==temp_ij&&setting==0) {
+ bt_sg[m].dSigB1[0]=bndtmp1*dis_ij[0]
+ +(bndtmp2*bt_sg[m].dAAC[0]
+ +bndtmp3*bt_sg[m].dEE[0]
+ +bndtmp4*bt_sg[m].dFFC[0]
+ +bndtmp5*bt_sg[m].dGGC[0]);
+ bt_sg[m].dSigB1[1]=bndtmp1*dis_ij[1]
+ +(bndtmp2*bt_sg[m].dAAC[1]
+ +bndtmp3*bt_sg[m].dEE[1]
+ +bndtmp4*bt_sg[m].dFFC[1]
+ +bndtmp5*bt_sg[m].dGGC[1]);
+ bt_sg[m].dSigB1[2]=bndtmp1*dis_ij[2]
+ +(bndtmp2*bt_sg[m].dAAC[2]
+ +bndtmp3*bt_sg[m].dEE[2]
+ +bndtmp4*bt_sg[m].dFFC[2]
+ +bndtmp5*bt_sg[m].dGGC[2]);
+ setting=1;
+ }
+ else if(temp_kk==temp_ji&&setting==0) {
+ bt_sg[m].dSigB1[0]=-bndtmp1*dis_ij[0]
+ +(bndtmp2*bt_sg[m].dAAC[0]
+ +bndtmp3*bt_sg[m].dEE[0]
+ +bndtmp4*bt_sg[m].dFFC[0]
+ +bndtmp5*bt_sg[m].dGGC[0]);
+ bt_sg[m].dSigB1[1]=-bndtmp1*dis_ij[1]
+ +(bndtmp2*bt_sg[m].dAAC[1]
+ +bndtmp3*bt_sg[m].dEE[1]
+ +bndtmp4*bt_sg[m].dFFC[1]
+ +bndtmp5*bt_sg[m].dGGC[1]);
+ bt_sg[m].dSigB1[2]=-bndtmp1*dis_ij[2]
+ +(bndtmp2*bt_sg[m].dAAC[2]
+ +bndtmp3*bt_sg[m].dEE[2]
+ +bndtmp4*bt_sg[m].dFFC[2]
+ +bndtmp5*bt_sg[m].dGGC[2]);
+ setting=1;
+ }
+ else {
+ bt_sg[m].dSigB1[0]=(bndtmp2*bt_sg[m].dAAC[0]
+ +bndtmp3*bt_sg[m].dEE[0]
+ +bndtmp4*bt_sg[m].dFFC[0]
+ +bndtmp5*bt_sg[m].dGGC[0]);
+ bt_sg[m].dSigB1[1]=(bndtmp2*bt_sg[m].dAAC[1]
+ +bndtmp3*bt_sg[m].dEE[1]
+ +bndtmp4*bt_sg[m].dFFC[1]
+ +bndtmp5*bt_sg[m].dGGC[1]);
+ bt_sg[m].dSigB1[2]=(bndtmp2*bt_sg[m].dAAC[2]
+ +bndtmp3*bt_sg[m].dEE[2]
+ +bndtmp4*bt_sg[m].dFFC[2]
+ +bndtmp5*bt_sg[m].dGGC[2]);
+ }
+ }
+ }
+
+//This loop is to ensure there is not an error for atoms with no neighbors (deposition)
+
+ if(nb_t==0) {
+ if(j>i) {
+ bt_sg[0].dSigB1[0]=bndtmp1*dis_ij[0];
+ bt_sg[0].dSigB1[1]=bndtmp1*dis_ij[1];
+ bt_sg[0].dSigB1[2]=bndtmp1*dis_ij[2];
+ }
+ else {
+ bt_sg[0].dSigB1[0]=-bndtmp1*dis_ij[0];
+ bt_sg[0].dSigB1[1]=-bndtmp1*dis_ij[1];
+ bt_sg[0].dSigB1[2]=-bndtmp1*dis_ij[2];
+ }
+ for(pp=0;pp<3;pp++) {
+ bt_sg[0].dAA[pp]=0.0;
+ bt_sg[0].dBB[pp]=0.0;
+ bt_sg[0].dCC[pp]=0.0;
+ bt_sg[0].dDD[pp]=0.0;
+ bt_sg[0].dEE[pp]=0.0;
+ bt_sg[0].dEE1[pp]=0.0;
+ bt_sg[0].dFF[pp]=0.0;
+ bt_sg[0].dAAC[pp]=0.0;
+ bt_sg[0].dBBC[pp]=0.0;
+ bt_sg[0].dCCC[pp]=0.0;
+ bt_sg[0].dDDC[pp]=0.0;
+ bt_sg[0].dEEC[pp]=0.0;
+ bt_sg[0].dFFC[pp]=0.0;
+ bt_sg[0].dGGC[pp]=0.0;
+ bt_sg[0].dUT[pp]=0.0;
+ bt_sg[0].dSigB1[pp]=0.0;
+ bt_sg[0].dSigB[pp]=0.0;
+ }
+ bt_sg[0].i=i;
+ bt_sg[0].j=j;
+ bt_sg[0].temp=temp_ij;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ }
+ ps=sigB1[n]*rdBO+1.0;
+ ks=(int)ps;
+ if(nBOt-1<ks)
+ ks=nBOt-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ dsigB1=((FsigBO3[iij][ks-1]*ps+FsigBO2[iij][ks-1])*ps
+ +FsigBO1[iij][ks-1])*ps+FsigBO[iij][ks-1];
+ dsigB2=(FsigBO6[iij][ks-1]*ps+FsigBO5[iij][ks-1])*ps+FsigBO4[iij][ks-1];
+ part0=(FF+0.5*AAC+small5);
+ part1=(sigma_f[iij]-0.5)*sigma_k[iij];
+ part2=1.0-part1*EE1/part0;
+ part3=dsigB1*part1/part0;
+ part4=part3/part0*EE1;
+
+// sigB is the final expression for (a) Eq. 6 and (b) Eq. 11
+
+ sigB[n]=dsigB1*part2;
+ pp1=2.0*betaS_ij;
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ temp_kk=bt_sg[m].temp;
+ bt_i=bt_sg[m].i;
+ bt_j=bt_sg[m].j;
+ xtmp[0]=x[bt_j][0]-x[bt_i][0];
+ xtmp[1]=x[bt_j][1]-x[bt_i][1];
+ xtmp[2]=x[bt_j][2]-x[bt_i][2];
+ for(pp=0;pp<3;pp++) {
+ bt_sg[m].dSigB[pp]=dsigB2*part2*bt_sg[m].dSigB1[pp]
+ -part3*bt_sg[m].dEE1[pp]
+ +part4*(bt_sg[m].dFF[pp]
+ +0.5*bt_sg[m].dAAC[pp]);
+ }
+ for(pp=0;pp<3;pp++) {
+ ftmp[pp]=pp1*bt_sg[m].dSigB[pp];
+ f[bt_i][pp]-=ftmp[pp];
+ f[bt_j][pp]+=ftmp[pp];
+ }
+ if(evflag) {
+ ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+ ,ftmp[2],xtmp[0],xtmp[1],xtmp[2]);
+ }
+ }
+ }
+ }
+ n++;
+ }
+ }
+ }
+ }
+ destroy_sigma();
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* The formulation differs slightly to avoid negative square roots
+ in the calculation of Theta_pi,ij of (a) Eq. 36 and (b) Eq. 18
+ see (d) */
+
+void PairBOP::sigmaBo_noa_otf()
+{
+ int nb_t,new_n_tot;
+ int n,i,j,k,kp,m,pp;
+ int itmp,jtmp,ktmp,ltmp,mtmp;
+ int i_tag,j_tag;
+ int kp1,kp2,kp1type;
+ int iij,iik,ijk,ikkp,ji,iikp,ijkp;
+ int nkp;
+ int nk0;
+ int jNeik,kNeii,kNeij;
+ int new1,new2,nlocal;
+ int inum,*ilist,*iilist,*jlist,*klist;
+ int **firstneigh,*numneigh;
+ int temp_ij,temp_ik,temp_jkp,temp_kk,temp_jk;
+ int temp_ji,temp_kkp;
+ int temp_kpk;
+ int nb_ij,nb_ik,nb_ikp;
+ int nb_jk,nb_jkp,nb_kkp;
+ int kp_nsearch,nsearch;
+ int sig_flag,setting,ncmp,ks;
+ int itype,jtype,ktype,kptype;
+ int bt_i,bt_j,bt_ij;
+ int kp_index,same_ikp,same_jkp,same_kpk;
+ double AA,BB,CC,DD,EE,EE1,FF;
+ double AAC,BBC,CCC,DDC,EEC,FFC,GGC;
+ double AACFF,UT,bndtmp,UTcom;
+ double amean,gmean0,gmean1,gmean2,ps;
+ double gfactor1,gprime1,gsqprime,factorsq;
+ double gfactorsq,gfactor2,gprime2;
+ double gfactorsq2,gsqprime2;
+ double gfactor3,gprime3,gfactor,rfactor;
+ double drfactor,gfactor4,gprime4,agpdpr3;
+ double rfactor0,rfactorrt,rfactor1rt,rfactor1;
+ double rcm1,rcm2,gcm1,gcm2,gcm3;
+ double agpdpr1,agpdpr2,app1,app2,app3,app4;
+ double dsigB1,dsigB2;
+ double part0,part1,part2,part3,part4;
+ double psign,bndtmp0,pp1;
+ double bndtmp1,bndtmp2;
+ double dis_ij[3],rsq_ij,r_ij;
+ double betaS_ij,dBetaS_ij;
+ double betaP_ij,dBetaP_ij;
+ double dis_ik[3],rsq_ik,r_ik;
+ double betaS_ik,dBetaS_ik;
+ double betaP_ik,dBetaP_ik;
+ double dis_ikp[3],rsq_ikp,r_ikp;
+ double betaS_ikp,dBetaS_ikp;
+ double betaP_ikp,dBetaP_ikp;
+ double dis_jk[3],rsq_jk,r_jk;
+ double betaS_jk,dBetaS_jk;
+ double betaP_jk,dBetaP_jk;
+ double dis_jkp[3],rsq_jkp,r_jkp;
+ double betaS_jkp,dBetaS_jkp;
+ double betaP_jkp,dBetaP_jkp;
+ double dis_kkp[3],rsq_kkp,r_kkp;
+ double betaS_kkp,dBetaS_kkp;
+ double betaP_kkp,dBetaP_kkp;
+ double cosAng_jik,dcA_jik[3][2];
+ double cosAng_jikp,dcA_jikp[3][2];
+ double cosAng_kikp,dcA_kikp[3][2];
+ double cosAng_ijk,dcA_ijk[3][2];
+ double cosAng_ijkp,dcA_ijkp[3][2];
+ double cosAng_kjkp,dcA_kjkp[3][2];
+ double cosAng_ikj,dcA_ikj[3][2];
+ double cosAng_ikkp,dcA_ikkp[3][2];
+ double cosAng_jkkp,dcA_jkkp[3][2];
+ double cosAng_jkpk,dcA_jkpk[3][2];
+
+
+ double ftmp[3],xtmp[3];
+ double **x = atom->x;
+ double **f = atom->f;
+ int *tag = atom->tag;
+ int newton_pair = force->newton_pair;
+ int *type = atom->type;
+
+ nlocal = atom->nlocal;
+ int nall = nlocal + atom->nghost;
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ n=0;
+ if(nb_sg==0) {
+ nb_sg=4;
+ }
+ if(allocate_sigma) {
+ destroy_sigma();
+ }
+ create_sigma(nb_sg);
+ for(itmp=0;itmp<inum;itmp++) {
+
+ i = ilist[itmp];
+ i_tag=tag[i];
+ itype = map[type[i]]+1;
+
+//j is loop over all neighbors of i
+
+ for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+ for(m=0;m<nb_sg;m++) {
+ for(pp=0;pp<3;pp++) {
+ bt_sg[m].dAA[pp]=0.0;
+ bt_sg[m].dBB[pp]=0.0;
+ bt_sg[m].dEE1[pp]=0.0;
+ bt_sg[m].dFF[pp]=0.0;
+ bt_sg[m].dAAC[pp]=0.0;
+ bt_sg[m].dSigB1[pp]=0.0;
+ bt_sg[m].dSigB[pp]=0.0;
+ }
+ bt_sg[m].i=-1;
+ bt_sg[m].j=-1;
+ }
+ nb_t=0;
+ iilist=firstneigh[i];
+ temp_ij=BOP_index[i]+jtmp;
+ j=iilist[jtmp];
+ jlist=firstneigh[j];
+ j_tag=tag[j];
+ jtype = map[type[j]]+1;
+ nb_ij=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_ij].temp=temp_ij;
+ bt_sg[nb_ij].i=i;
+ bt_sg[nb_ij].j=j;
+ if(j_tag>=i_tag) {
+ if(itype==jtype)
+ iij=itype-1;
+ else if(itype<jtype)
+ iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+ else
+ iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+ for(ji=0;ji<numneigh[j];ji++) {
+ temp_ji=BOP_index[j]+ji;
+ if(x[jlist[ji]][0]==x[i][0]) {
+ if(x[jlist[ji]][1]==x[i][1]) {
+ if(x[jlist[ji]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+ dis_ij[0]=x[j][0]-x[i][0];
+ dis_ij[1]=x[j][1]-x[i][1];
+ dis_ij[2]=x[j][2]-x[i][2];
+ rsq_ij=dis_ij[0]*dis_ij[0]
+ +dis_ij[1]*dis_ij[1]
+ +dis_ij[2]*dis_ij[2];
+ r_ij=sqrt(rsq_ij);
+
+ if(r_ij<rcut[iij]) {
+
+ ps=r_ij*rdr[iij]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_ij=((pBetaS3[iij][ks-1]*ps+pBetaS2[iij][ks-1])*ps
+ +pBetaS1[iij][ks-1])*ps+pBetaS[iij][ks-1];
+ dBetaS_ij=(pBetaS6[iij][ks-1]*ps+pBetaS5[iij][ks-1])*ps
+ +pBetaS4[iij][ks-1];
+ betaP_ij=((pBetaP3[iij][ks-1]*ps+pBetaP2[iij][ks-1])*ps
+ +pBetaP1[iij][ks-1])*ps+pBetaP[iij][ks-1];
+ dBetaP_ij=(pBetaP6[iij][ks-1]*ps+pBetaP5[iij][ks-1])*ps
+ +pBetaP4[iij][ks-1];
+ nSigBk[n]=0;
+
+//AA-EE1 are the components making up Eq. 30 (a)
+
+ AA=0.0;
+ BB=0.0;
+ CC=0.0;
+ DD=0.0;
+ EE=0.0;
+ EE1=0.0;
+
+//FF is the Beta_sigma^2 term
+
+ FF=betaS_ij*betaS_ij;
+
+//agpdpr1 is derivative of FF w.r.t. r_ij
+
+ agpdpr1=2.0*betaS_ij*dBetaS_ij/r_ij;
+
+//dXX derivatives are taken with respect to all pairs contributing to the energy
+//nb_ij is derivative w.r.t. ij pair
+
+ bt_sg[nb_ij].dFF[0]=agpdpr1*dis_ij[0];
+ bt_sg[nb_ij].dFF[1]=agpdpr1*dis_ij[1];
+ bt_sg[nb_ij].dFF[2]=agpdpr1*dis_ij[2];
+
+//k is loop over all neighbors of i again with j neighbor of i
+
+ for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+ temp_ik=BOP_index[i]+ktmp;
+ if(ktmp!=jtmp) {
+ k=iilist[ktmp];
+ klist=firstneigh[k];
+ ktype = map[type[k]]+1;
+ if(itype==ktype)
+ iik=itype-1;
+ else if(itype<ktype)
+ iik=itype*bop_types-itype*(itype+1)/2+ktype-1;
+ else
+ iik=ktype*bop_types-ktype*(ktype+1)/2+itype-1;
+
+//find neighbor of k that is equal to i
+
+ for(kNeii=0;kNeii<numneigh[k];kNeii++) {
+ if(x[klist[kNeii]][0]==x[i][0]) {
+ if(x[klist[kNeii]][1]==x[i][1]) {
+ if(x[klist[kNeii]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+ dis_ik[0]=x[k][0]-x[i][0];
+ dis_ik[1]=x[k][1]-x[i][1];
+ dis_ik[2]=x[k][2]-x[i][2];
+ rsq_ik=dis_ik[0]*dis_ik[0]
+ +dis_ik[1]*dis_ik[1]
+ +dis_ik[2]*dis_ik[2];
+ r_ik=sqrt(rsq_ik);
+ if(r_ik<=rcut[iik]) {
+ ps=r_ik*rdr[iik]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_ik=((pBetaS3[iik][ks-1]*ps+pBetaS2[iik][ks-1])*ps
+ +pBetaS1[iik][ks-1])*ps+pBetaS[iik][ks-1];
+ dBetaS_ik=(pBetaS6[iik][ks-1]*ps+pBetaS5[iik][ks-1])*ps
+ +pBetaS4[iik][ks-1];
+ betaP_ik=((pBetaP3[iik][ks-1]*ps+pBetaP2[iik][ks-1])*ps
+ +pBetaP1[iik][ks-1])*ps+pBetaP[iik][ks-1];
+ dBetaP_ik=(pBetaP6[iik][ks-1]*ps+pBetaP5[iik][ks-1])*ps
+ +pBetaP4[iik][ks-1];
+
+//find neighbor of i that is equal to k
+
+ for(jNeik=0;jNeik<numneigh[j];jNeik++) {
+ temp_jk=BOP_index[j]+jNeik;
+ if(x[jlist[jNeik]][0]==x[k][0]) {
+ if(x[jlist[jNeik]][1]==x[k][1]) {
+ if(x[jlist[jNeik]][2]==x[k][2]) {
+ break;
+ }
+ }
+ }
+ }
+
+//find neighbor of k that is equal to j
+
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ dis_jk[0]=x[k][0]-x[j][0];
+ dis_jk[1]=x[k][1]-x[j][1];
+ dis_jk[2]=x[k][2]-x[j][2];
+ rsq_jk=dis_jk[0]*dis_jk[0]
+ +dis_jk[1]*dis_jk[1]
+ +dis_jk[2]*dis_jk[2];
+ r_jk=sqrt(rsq_jk);
+
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ nk0=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ nk0=nSigBk[n]-1;
+ itypeSigBk[n][nk0]=k;
+ }
+ nb_ik=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_ik].temp=temp_ik;
+ bt_sg[nb_ik].i=i;
+ bt_sg[nb_ik].j=k;
+ nb_jk=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jk].temp=temp_jk;
+ bt_sg[nb_jk].i=j;
+ bt_sg[nb_jk].j=k;
+ cosAng_jik=(dis_ij[0]*dis_ik[0]+dis_ij[1]*dis_ik[1]
+ +dis_ij[2]*dis_ik[2])/(r_ij*r_ik);
+ dcA_jik[0][0]=(dis_ik[0]*r_ij*r_ik-cosAng_jik
+ *dis_ij[0]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[1][0]=(dis_ik[1]*r_ij*r_ik-cosAng_jik
+ *dis_ij[1]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[2][0]=(dis_ik[2]*r_ij*r_ik-cosAng_jik
+ *dis_ij[2]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[0][1]=(dis_ij[0]*r_ij*r_ik-cosAng_jik
+ *dis_ik[0]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[1][1]=(dis_ij[1]*r_ij*r_ik-cosAng_jik
+ *dis_ik[1]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[2][1]=(dis_ij[2]*r_ij*r_ik-cosAng_jik
+ *dis_ik[2]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+ gmean0=sigma_g0[jtype-1][itype-1][ktype-1];
+ gmean1=sigma_g1[jtype-1][itype-1][ktype-1];
+ gmean2=sigma_g2[jtype-1][itype-1][ktype-1];
+ amean=cosAng_jik;
+ gfactor1=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gfactorsq=gfactor1*gfactor1;
+ gprime1=gmean1+2.0*gmean2*amean;
+ gsqprime=2.0*gfactor1*gprime1;
+
+//AA is Eq. 34 (a) or Eq. 10 (c) for the i atom
+//1st CC is Eq. 11 (c) for i atom where j & k=neighbor of i
+
+ AA=AA+gfactorsq*betaS_ik*betaS_ik;
+ CC=CC+gfactorsq*betaS_ik*betaS_ik*betaS_ik*betaS_ik;
+
+//agpdpr1 is derivative of AA w.r.t. Beta(rik)
+//app1 is derivative of AA w.r.t. cos(theta_jik)
+
+ agpdpr1=2.0*gfactorsq*betaS_ik*dBetaS_ik/r_ik;
+ app1=betaS_ik*betaS_ik*gsqprime;
+ bt_sg[nb_ij].dAA[0]+=
+ app1*dcA_jik[0][0];
+ bt_sg[nb_ij].dAA[1]+=
+ app1*dcA_jik[1][0];
+ bt_sg[nb_ij].dAA[2]+=
+ app1*dcA_jik[2][0];
+ bt_sg[nb_ik].dAA[0]+=
+ app1*dcA_jik[0][1]
+ +agpdpr1*dis_ik[0];
+ bt_sg[nb_ik].dAA[1]+=
+ app1*dcA_jik[1][1]
+ +agpdpr1*dis_ik[1];
+ bt_sg[nb_ik].dAA[2]+=
+ app1*dcA_jik[2][1]
+ +agpdpr1*dis_ik[2];
+
+//k' is loop over neighbors all neighbors of j with k a neighbor
+//of i and j a neighbor of i and determine which k' is k
+
+ same_kpk=0;
+ for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+ temp_jkp=BOP_index[j]+ltmp;
+ kp1=jlist[ltmp];
+ kp1type=map[type[kp1]]+1;
+ if(x[kp1][0]==x[k][0]) {
+ if(x[kp1][1]==x[k][1]) {
+ if(x[kp1][2]==x[k][2]) {
+ same_kpk=1;
+ break;
+ }
+ }
+ }
+ }
+ if(same_kpk){
+
+//loop over neighbors of k
+
+ for(mtmp=0;mtmp<numneigh[k];mtmp++) {
+ kp2=klist[mtmp];
+ if(x[kp2][0]==x[k][0]) {
+ if(x[kp2][1]==x[k][1]) {
+ if(x[kp2][2]==x[k][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(jtype==ktype)
+ ijk=jtype-1;
+ else if(jtype < ktype)
+ ijk=jtype*bop_types-jtype*(jtype+1)/2+ktype-1;
+ else
+ ijk=ktype*bop_types-ktype*(ktype+1)/2+jtype-1;
+ if(jtype==kp1type)
+ ijkp=jtype-1;
+ else if(jtype<kp1type)
+ ijkp=jtype*bop_types-jtype*(jtype+1)/2+kp1type-1;
+ else
+ ijkp=kp1type*bop_types-kp1type*(kp1type+1)/2+jtype-1;
+
+ dis_jkp[0]=x[kp1][0]-x[j][0];
+ dis_jkp[1]=x[kp1][1]-x[j][1];
+ dis_jkp[2]=x[kp1][2]-x[j][2];
+ rsq_jkp=dis_jkp[0]*dis_jkp[0]
+ +dis_jkp[1]*dis_jkp[1]
+ +dis_jkp[2]*dis_jkp[2];
+ r_jkp=sqrt(rsq_jkp);
+ if(r_jkp<=rcut[ijkp]) {
+ ps=r_jkp*rdr[ijkp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+ +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+ dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+ +pBetaS4[ijkp][ks-1];
+ betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+ +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+ dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+ +pBetaP4[ijkp][ks-1];
+ cosAng_ijk=(-dis_ij[0]*dis_jk[0]-dis_ij[1]*dis_jk[1]
+ -dis_ij[2]*dis_jk[2])/(r_ij*r_jk);
+ dcA_ijk[0][0]=(dis_jk[0]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[0]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[1][0]=(dis_jk[1]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[1]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[2][0]=(dis_jk[2]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[2]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[0][1]=(-dis_ij[0]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[0]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[1][1]=(-dis_ij[1]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[1]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[2][1]=(-dis_ij[2]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[2]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+ amean=cosAng_ijk;
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[itype-1][ktype-1][jtype-1];
+ gmean1=sigma_g1[itype-1][ktype-1][jtype-1];
+ gmean2=sigma_g2[itype-1][ktype-1][jtype-1];
+ cosAng_ikj=(dis_ik[0]*dis_jk[0]+dis_ik[1]*dis_jk[1]
+ +dis_ik[2]*dis_jk[2])/(r_ik*r_jk);
+ dcA_ikj[0][0]=(-dis_jk[0]*r_ik*r_jk-cosAng_ikj
+ *-dis_ik[0]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+ dcA_ikj[1][0]=(-dis_jk[1]*r_ik*r_jk-cosAng_ikj
+ *-dis_ik[1]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+ dcA_ikj[2][0]=(-dis_jk[2]*r_ik*r_jk-cosAng_ikj
+ *-dis_ik[2]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+ dcA_ikj[0][1]=(-dis_ik[0]*r_ik*r_jk-cosAng_ikj
+ *-dis_jk[0]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+ dcA_ikj[1][1]=(-dis_ik[1]*r_ik*r_jk-cosAng_ikj
+ *-dis_jk[1]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+ dcA_ikj[2][1]=(-dis_ik[2]*r_ik*r_jk-cosAng_ikj
+ *-dis_jk[2]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+ amean=cosAng_ikj;
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactor=betaS_ik*betaS_jkp;
+
+//EE1 is (b) Eq. 12
+
+ EE1=EE1+gfactor*rfactor;
+
+//rcm1 is derivative of EE1 w.r.t Beta(r_ik)
+//rcm2 is derivative of EE1 w.r.t Beta(r_jk')
+//gcm1 is derivative of EE1 w.r.t cos(theta_jik)
+//gcm2 is derivative of EE1 w.r.t cos(theta_ijk)
+//gcm3 is derivative of EE1 w.r.t cos(theta_ikj)
+
+ rcm1=gfactor*betaS_jkp*dBetaS_ik/r_ik;
+ rcm2=gfactor*betaS_ik*dBetaS_jkp/r_jkp;
+ gcm1=rfactor*gprime1*gfactor2*gfactor3;
+ gcm2=rfactor*gfactor1*gprime2*gfactor3;
+ gcm3=rfactor*gfactor1*gfactor2*gprime3;
+ bt_sg[nb_ij].dEE1[0]+=
+ gcm1*dcA_jik[0][0]
+ -gcm2*dcA_ijk[0][0];
+ bt_sg[nb_ij].dEE1[1]+=
+ gcm1*dcA_jik[1][0]
+ -gcm2*dcA_ijk[1][0];
+ bt_sg[nb_ij].dEE1[2]+=
+ gcm1*dcA_jik[2][0]
+ -gcm2*dcA_ijk[2][0];
+ bt_sg[nb_ik].dEE1[0]+=
+ gcm1*dcA_jik[0][1]
+ +rcm1*dis_ik[0]
+ -gcm3*dcA_ikj[0][0];
+ bt_sg[nb_ik].dEE1[1]+=
+ gcm1*dcA_jik[1][1]
+ +rcm1*dis_ik[1]
+ -gcm3*dcA_ikj[1][0];
+ bt_sg[nb_ik].dEE1[2]+=
+ gcm1*dcA_jik[2][1]
+ +rcm1*dis_ik[2]
+ -gcm3*dcA_ikj[2][0];
+ bt_sg[nb_jk].dEE1[0]+=
+ gcm2*dcA_ijk[0][1]
+ +rcm2*dis_jkp[0]
+ -gcm3*dcA_ikj[0][1];
+ bt_sg[nb_jk].dEE1[1]+=
+ gcm2*dcA_ijk[1][1]
+ +rcm2*dis_jkp[1]
+ -gcm3*dcA_ikj[1][1];
+ bt_sg[nb_jk].dEE1[2]+=
+ gcm2*dcA_ijk[2][1]
+ +rcm2*dis_jkp[2]
+ -gcm3*dcA_ikj[2][1];
+ }
+ }
+
+// k and k' and j are all different neighbors of i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=jtmp) {
+ kp=iilist[ltmp];;
+ kptype = map[type[kp]]+1;
+ if(itype==kptype)
+ iikp=itype-1;
+ else if(itype<kptype)
+ iikp=itype*bop_types-itype*(itype+1)/2+kptype-1;
+ else
+ iikp=kptype*bop_types-kptype*(kptype+1)/2+itype-1;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ break;
+ }
+ }
+ }
+ }
+ dis_ikp[0]=x[kp][0]-x[i][0];
+ dis_ikp[1]=x[kp][1]-x[i][1];
+ dis_ikp[2]=x[kp][2]-x[i][2];
+ rsq_ikp=dis_ikp[0]*dis_ikp[0]
+ +dis_ikp[1]*dis_ikp[1]
+ +dis_ikp[2]*dis_ikp[2];
+ r_ikp=sqrt(rsq_ikp);
+ if(r_ikp<=rcut[iikp]) {
+ ps=r_ikp*rdr[iikp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_ikp=((pBetaS3[iikp][ks-1]*ps+pBetaS2[iikp][ks-1])*ps
+ +pBetaS1[iikp][ks-1])*ps+pBetaS[iikp][ks-1];
+ dBetaS_ikp=(pBetaS6[iikp][ks-1]*ps+pBetaS5[iikp][ks-1])*ps
+ +pBetaS4[iikp][ks-1];
+ betaP_ikp=((pBetaP3[iikp][ks-1]*ps+pBetaP2[iikp][ks-1])*ps
+ +pBetaP1[iikp][ks-1])*ps+pBetaP[iikp][ks-1];
+ dBetaP_ikp=(pBetaP6[iikp][ks-1]*ps+pBetaP5[iikp][ks-1])*ps
+ +pBetaP4[iikp][ks-1];
+ gmean0=sigma_g0[jtype-1][itype-1][kptype-1];
+ gmean1=sigma_g1[jtype-1][itype-1][kptype-1];
+ gmean2=sigma_g2[jtype-1][itype-1][kptype-1];
+ cosAng_jikp=(dis_ij[0]*dis_ikp[0]+dis_ij[1]*dis_ikp[1]
+ +dis_ij[2]*dis_ikp[2])/(r_ij*r_ikp);
+ cosAng_kikp=(dis_ik[0]*dis_ikp[0]+dis_ik[1]*dis_ikp[1]
+ +dis_ik[2]*dis_ikp[2])/(r_ik*r_ikp);
+ amean=cosAng_jikp;
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[ktype-1][itype-1][kptype-1];
+ gmean1=sigma_g1[ktype-1][itype-1][kptype-1];
+ gmean2=sigma_g2[ktype-1][itype-1][kptype-1];
+ amean=cosAng_kikp;
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactorrt=betaS_ik*betaS_ikp;
+ rfactor=rfactorrt*rfactorrt;
+
+//2nd CC is second term of Eq. 11 (c) for i atom where j , k & k' =neighbor of i
+
+ CC=CC+2.0*gfactor*rfactor;
+ }
+ }
+ }
+
+// j and k are different neighbors of i and k' is a neighbor k not equal to i
+
+ for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+ temp_kkp=BOP_index[k]+ltmp;
+ kp=klist[ltmp];;
+ kptype = map[type[kp]]+1;
+ same_ikp=0;
+ same_jkp=0;
+ if(x[i][0]==x[kp][0]) {
+ if(x[i][1]==x[kp][1]) {
+ if(x[i][2]==x[kp][2]) {
+ same_ikp=1;
+ }
+ }
+ }
+ if(x[j][0]==x[kp][0]) {
+ if(x[j][1]==x[kp][1]) {
+ if(x[j][2]==x[kp][2]) {
+ same_jkp=1;
+ }
+ }
+ }
+ if(!same_ikp&&!same_jkp) {
+ if(ktype==kptype)
+ ikkp=ktype-1;
+ else if(ktype<kptype)
+ ikkp=ktype*bop_types-ktype*(ktype+1)/2+kptype-1;
+ else
+ ikkp=kptype*bop_types-kptype*(kptype+1)/2+ktype-1;
+ dis_kkp[0]=x[kp][0]-x[k][0];
+ dis_kkp[1]=x[kp][1]-x[k][1];
+ dis_kkp[2]=x[kp][2]-x[k][2];
+ rsq_kkp=dis_kkp[0]*dis_kkp[0]
+ +dis_kkp[1]*dis_kkp[1]
+ +dis_kkp[2]*dis_kkp[2];
+ r_kkp=sqrt(rsq_kkp);
+ if(r_kkp<=rcut[ikkp]) {
+ ps=r_kkp*rdr[ikkp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_kkp=((pBetaS3[ikkp][ks-1]*ps+pBetaS2[ikkp][ks-1])*ps
+ +pBetaS1[ikkp][ks-1])*ps+pBetaS[ikkp][ks-1];
+ dBetaS_kkp=(pBetaS6[ikkp][ks-1]*ps+pBetaS5[ikkp][ks-1])*ps
+ +pBetaS4[ikkp][ks-1];
+ betaP_kkp=((pBetaP3[ikkp][ks-1]*ps+pBetaP2[ikkp][ks-1])*ps
+ +pBetaP1[ikkp][ks-1])*ps+pBetaP[ikkp][ks-1];
+ dBetaP_kkp=(pBetaP6[ikkp][ks-1]*ps+pBetaP5[ikkp][ks-1])*ps
+ +pBetaP4[ikkp][ks-1];
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ sig_flag=1;
+ nkp=nsearch;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ nkp=nSigBk[n]-1;
+ itypeSigBk[n][nkp]=kp;
+ }
+ cosAng_ikkp=(-dis_ik[0]*dis_kkp[0]-dis_ik[1]*dis_kkp[1]
+ -dis_ik[2]*dis_kkp[2])/(r_ik*r_kkp);
+ gmean0=sigma_g0[itype-1][ktype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][ktype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][ktype-1][kptype-1];
+ amean=cosAng_ikkp;
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gfactorsq2=gfactor2*gfactor2;
+ gsqprime2=2.0*gfactor2*gprime2;
+ gfactor=gfactorsq*gfactorsq2;
+ rfactorrt=betaS_ik*betaS_kkp;
+ rfactor=rfactorrt*rfactorrt;
+
+//3rd CC is third term of Eq. 11 (c) for i atom
+//where j , k =neighbor of i & k' =neighbor of k
+
+ CC=CC+gfactor*rfactor;
+ }
+ }
+ }
+ }
+ }
+ }
+
+//j is a neighbor of i and k is a neighbor of j not equal to i
+
+ for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+ if(ktmp!=ji) {
+ temp_jk=BOP_index[j]+ktmp;
+ k=jlist[ktmp];
+ klist=firstneigh[k];
+ ktype=map[type[k]]+1;
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(jtype==ktype)
+ ijk=jtype-1;
+ else if(jtype<ktype)
+ ijk=jtype*bop_types-jtype*(jtype+1)/2+ktype-1;
+ else
+ ijk=ktype*bop_types-ktype*(ktype+1)/2+jtype-1;
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ new1=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ new1=nSigBk[n]-1;
+ itypeSigBk[n][new1]=k;
+ }
+ dis_jk[0]=x[k][0]-x[j][0];
+ dis_jk[1]=x[k][1]-x[j][1];
+ dis_jk[2]=x[k][2]-x[j][2];
+ rsq_jk=dis_jk[0]*dis_jk[0]
+ +dis_jk[1]*dis_jk[1]
+ +dis_jk[2]*dis_jk[2];
+ r_jk=sqrt(rsq_jk);
+ if(r_jk<=rcut[ijk]) {
+ ps=r_jk*rdr[ijk]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_jk=((pBetaS3[ijk][ks-1]*ps+pBetaS2[ijk][ks-1])*ps
+ +pBetaS1[ijk][ks-1])*ps+pBetaS[ijk][ks-1];
+ dBetaS_jk=(pBetaS6[ijk][ks-1]*ps+pBetaS5[ijk][ks-1])*ps
+ +pBetaS4[ijk][ks-1];
+ betaP_jk=((pBetaP3[ijk][ks-1]*ps+pBetaP2[ijk][ks-1])*ps
+ +pBetaP1[ijk][ks-1])*ps+pBetaP[ijk][ks-1];
+ dBetaP_jk=(pBetaP6[ijk][ks-1]*ps+pBetaP5[ijk][ks-1])*ps
+ +pBetaP4[ijk][ks-1];
+ cosAng_ijk=(-dis_ij[0]*dis_jk[0]-dis_ij[1]*dis_jk[1]
+ -dis_ij[2]*dis_jk[2])/(r_ij*r_jk);
+ dcA_ijk[0][0]=(dis_jk[0]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[0]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[1][0]=(dis_jk[1]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[1]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[2][0]=(dis_jk[2]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[2]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[0][1]=(-dis_ij[0]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[0]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[1][1]=(-dis_ij[1]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[1]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[2][1]=(-dis_ij[2]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[2]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ nb_jk=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jk].temp=temp_jk;
+ bt_sg[nb_jk].i=j;
+ bt_sg[nb_jk].j=k;
+ gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+ amean=cosAng_ijk;
+ gfactor1=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime1=gmean1+2.0*gmean2*amean;
+ gfactorsq=gfactor1*gfactor1;
+ gsqprime=2.0*gfactor1*gprime1;
+ rfactor1rt=betaS_jk*betaS_jk;
+ rfactor1=rfactor1rt*rfactor1rt;
+
+//BB is Eq. 34 (a) or Eq. 10 (c) for the j atom
+//1st DD is Eq. 11 (c) for j atom where i & k=neighbor of j
+
+ BB=BB+gfactorsq*rfactor1rt;
+ DD=DD+gfactorsq*rfactor1;
+
+//agpdpr1 is derivative of BB w.r.t. Beta(r_jk)
+//app1 is derivative of BB w.r.t. cos(theta_ijk)
+
+ agpdpr1=2.0*gfactorsq*betaS_jk*dBetaS_jk/r_jk;
+ app1=rfactor1rt*gsqprime;
+ bt_sg[nb_ij].dBB[0]-=
+ app1*dcA_ijk[0][0];
+ bt_sg[nb_ij].dBB[1]-=
+ app1*dcA_ijk[1][0];
+ bt_sg[nb_ij].dBB[2]-=
+ app1*dcA_ijk[2][0];
+ bt_sg[nb_jk].dBB[0]+=
+ app1*dcA_ijk[0][1]
+ +agpdpr1*dis_jk[0];
+ bt_sg[nb_jk].dBB[1]+=
+ app1*dcA_ijk[1][1]
+ +agpdpr1*dis_jk[1];
+ bt_sg[nb_jk].dBB[2]+=
+ app1*dcA_ijk[2][1]
+ +agpdpr1*dis_jk[2];
+
+//j is a neighbor of i, k and k' prime different neighbors of j not equal to i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=ji) {
+ temp_jkp=BOP_index[j]+ltmp;
+ kp=jlist[ltmp];
+ kptype=map[type[kp]]+1;
+ if(jtype==kptype)
+ ijkp=jtype-1;
+ else if(jtype<kptype)
+ ijkp=jtype*bop_types-jtype*(jtype+1)/2+kptype-1;
+ else
+ ijkp=kptype*bop_types-kptype*(kptype+1)/2+jtype-1;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ new2=nsearch;
+ break;
+ }
+ }
+ }
+ }
+ dis_jkp[0]=x[kp][0]-x[j][0];
+ dis_jkp[1]=x[kp][1]-x[j][1];
+ dis_jkp[2]=x[kp][2]-x[j][2];
+ rsq_jkp=dis_jkp[0]*dis_jkp[0]
+ +dis_jkp[1]*dis_jkp[1]
+ +dis_jkp[2]*dis_jkp[2];
+ r_jkp=sqrt(rsq_jkp);
+ if(r_jkp<=rcut[ijkp]) {
+ ps=r_jkp*rdr[ijkp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+ +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+ dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+ +pBetaS4[ijkp][ks-1];
+ betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+ +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+ dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+ +pBetaP4[ijkp][ks-1];
+ cosAng_ijkp=(-dis_ij[0]*dis_jkp[0]-dis_ij[1]*dis_jkp[1]
+ -dis_ij[2]*dis_jkp[2])/(r_ij*r_jkp);
+ dcA_ijkp[0][0]=(dis_jkp[0]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[0]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[1][0]=(dis_jkp[1]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[1]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[2][0]=(dis_jkp[2]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[2]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[0][1]=(-dis_ij[0]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[0]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[1][1]=(-dis_ij[1]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[1]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[2][1]=(-dis_ij[2]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[2]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ cosAng_kjkp=(dis_jk[0]*dis_jkp[0]+dis_jk[1]*dis_jkp[1]
+ +dis_jk[2]*dis_jkp[2])/(r_jk*r_jkp);
+ dcA_kjkp[0][0]=(dis_jkp[0]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jk[0]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[1][0]=(dis_jkp[1]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jk[1]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[2][0]=(dis_jkp[2]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jk[2]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[0][1]=(dis_jk[0]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jkp[0]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[1][1]=(dis_jk[1]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jkp[1]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[2][1]=(dis_jk[2]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jkp[2]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+ nb_jkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_jkp].temp=temp_jkp;
+ bt_sg[nb_jkp].i=j;
+ bt_sg[nb_jkp].j=kp;
+ gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+ gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+ gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+ amean=cosAng_ijkp;
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gmean0=sigma_g0[ktype-1][jtype-1][kptype-1];
+ gmean1=sigma_g1[ktype-1][jtype-1][kptype-1];
+ gmean2=sigma_g2[ktype-1][jtype-1][kptype-1];
+ amean=cosAng_kjkp;
+ gfactor3=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime3=gmean1+2.0*gmean2*amean;
+ gfactor=gfactor1*gfactor2*gfactor3;
+ rfactorrt=betaS_jk*betaS_jkp;
+ rfactor=rfactorrt*rfactorrt;
+
+//2nd DD is Eq. 11 (c) for j atom where i , k & k'=neighbor of j
+
+ DD=DD+2.0*gfactor*rfactor;
+ }
+ }
+ }
+
+//j is a neighbor of i, k is a neighbor of j not equal to i and k'
+//is a neighbor of k not equal to j or i
+
+ for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+ temp_kkp=BOP_index[k]+ltmp;
+ kp=klist[ltmp];
+ kptype=map[type[kp]]+1;
+ same_ikp=0;
+ same_jkp=0;
+ if(x[i][0]==x[kp][0]) {
+ if(x[i][1]==x[kp][1]) {
+ if(x[i][2]==x[kp][2]) {
+ same_ikp=1;
+ }
+ }
+ }
+ if(x[j][0]==x[kp][0]) {
+ if(x[j][1]==x[kp][1]) {
+ if(x[j][2]==x[kp][2]) {
+ same_jkp=1;
+ }
+ }
+ }
+ if(!same_ikp&&!same_jkp) {
+ if(ktype==kptype)
+ ikkp=ktype-1;
+ else if(ktype<kptype)
+ ikkp=ktype*bop_types-ktype*(ktype+1)/2+kptype-1;
+ else
+ ikkp=kptype*bop_types-kptype*(kptype+1)/2+ktype-1;
+ for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+ if(x[klist[kNeij]][0]==x[j][0]) {
+ if(x[klist[kNeij]][1]==x[j][1]) {
+ if(x[klist[kNeij]][2]==x[j][2]) {
+ break;
+ }
+ }
+ }
+ }
+ sig_flag=0;
+ for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+ ncmp=itypeSigBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ new2=nsearch;
+ sig_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(sig_flag==0) {
+ nSigBk[n]=nSigBk[n]+1;
+ new2=nSigBk[n]-1;
+ itypeSigBk[n][new2]=kp;
+ }
+ dis_kkp[0]=x[kp][0]-x[k][0];
+ dis_kkp[1]=x[kp][1]-x[k][1];
+ dis_kkp[2]=x[kp][2]-x[k][2];
+ rsq_kkp=dis_kkp[0]*dis_kkp[0]
+ +dis_kkp[1]*dis_kkp[1]
+ +dis_kkp[2]*dis_kkp[2];
+ r_kkp=sqrt(rsq_kkp);
+ if(r_kkp<=rcut[ikkp]) {
+ ps=r_kkp*rdr[ikkp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_kkp=((pBetaS3[ikkp][ks-1]*ps+pBetaS2[ikkp][ks-1])*ps
+ +pBetaS1[ikkp][ks-1])*ps+pBetaS[ikkp][ks-1];
+ dBetaS_kkp=(pBetaS6[ikkp][ks-1]*ps+pBetaS5[ikkp][ks-1])*ps
+ +pBetaS4[ikkp][ks-1];
+ betaP_kkp=((pBetaP3[ikkp][ks-1]*ps+pBetaP2[ikkp][ks-1])*ps
+ +pBetaP1[ikkp][ks-1])*ps+pBetaP[ikkp][ks-1];
+ dBetaP_kkp=(pBetaP6[ikkp][ks-1]*ps+pBetaP5[ikkp][ks-1])*ps
+ +pBetaP4[ikkp][ks-1];
+ cosAng_jkkp=(-dis_jk[0]*dis_kkp[0]-dis_jk[1]*dis_kkp[1]
+ -dis_jk[2]*dis_kkp[2])/(r_jk*r_kkp);
+ dcA_jkkp[0][0]=(dis_kkp[0]*r_jk*r_kkp-cosAng_jkkp
+ *-dis_jk[0]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+ dcA_jkkp[1][0]=(dis_kkp[1]*r_jk*r_kkp-cosAng_jkkp
+ *-dis_jk[1]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+ dcA_jkkp[2][0]=(dis_kkp[2]*r_jk*r_kkp-cosAng_jkkp
+ *-dis_jk[2]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+ dcA_jkkp[0][1]=(-dis_jk[0]*r_jk*r_kkp-cosAng_jkkp
+ *dis_kkp[0]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+ dcA_jkkp[1][1]=(-dis_jk[1]*r_jk*r_kkp-cosAng_jkkp
+ *dis_kkp[1]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+ dcA_jkkp[2][1]=(-dis_jk[2]*r_jk*r_kkp-cosAng_jkkp
+ *dis_kkp[2]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+ nb_kkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ bt_sg[nb_kkp].temp=temp_kkp;
+ bt_sg[nb_kkp].i=k;
+ bt_sg[nb_kkp].j=kp;
+ gmean0=sigma_g0[jtype-1][ktype-1][kptype-1];
+ gmean1=sigma_g1[jtype-1][ktype-1][kptype-1];
+ gmean2=sigma_g2[jtype-1][ktype-1][kptype-1];
+ amean=cosAng_jkkp;
+ gfactor2=gmean0+gmean1*amean
+ +gmean2*amean*amean;
+ gprime2=gmean1+2.0*gmean2*amean;
+ gfactorsq2=gfactor2*gfactor2;
+ gsqprime2=2.0*gfactor2*gprime2;
+ gfactor=gfactorsq*gfactorsq2;
+ rfactorrt=betaS_jk*betaS_kkp;
+ rfactor=rfactorrt*rfactorrt;
+
+//3rd DD is Eq. 11 (c) for j atom where i & k=neighbor of j & k'=neighbor of k
+
+ DD=DD+gfactor*rfactor;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sig_flag=0;
+ if(FF<=0.000001) {
+ sigB[n]=0.0;
+ sig_flag=1;
+ }
+ if(sig_flag==0) {
+ if(AA<0.0)
+ AA=0.0;
+ if(BB<0.0)
+ BB=0.0;
+ if(CC<0.0)
+ CC=0.0;
+ if(DD<0.0)
+ DD=0.0;
+
+// AA and BB are the representations of (a) Eq. 34 and (b) Eq. 9
+// for atoms i and j respectively
+
+ AAC=AA+BB;
+ BBC=AA*BB;
+ CCC=AA*AA+BB*BB;
+ DDC=CC+DD;
+
+//EEC is a modified form of (a) Eq. 33
+
+ EEC=(DDC-CCC)/(AAC+2.0*small1);
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ bt_sg[m].dAAC[0]=bt_sg[m].dAA[0]
+ +bt_sg[m].dBB[0];
+ bt_sg[m].dAAC[1]=bt_sg[m].dAA[1]
+ +bt_sg[m].dBB[1];
+ bt_sg[m].dAAC[2]=bt_sg[m].dAA[2]
+ +bt_sg[m].dBB[2];
+ }
+ }
+ UT=EEC*FF+BBC+small3[iij];
+ UT=1.0/sqrt(UT);
+
+// FFC is slightly modified form of (a) Eq. 31
+// GGC is slightly modified form of (a) Eq. 32
+// bndtmp is a slightly modified form of (a) Eq. 30 and (b) Eq. 8
+
+ FFC=BBC*UT;
+ GGC=EEC*UT;
+ bndtmp=(FF+sigma_delta[iij]*sigma_delta[iij])
+ +sigma_c[iij]*AAC+small4;
+ UTcom=-0.5*UT*UT*UT;
+ psign=1.0;
+ bndtmp0=1.0/sqrt(bndtmp);
+ sigB1[n]=psign*betaS_ij*bndtmp0;
+ bndtmp=-0.5*bndtmp0*bndtmp0*bndtmp0;
+ bndtmp1=psign*bndtmp0+psign*betaS_ij
+ *bndtmp*2.0*betaS_ij;
+ bndtmp1=bndtmp1*dBetaS_ij/r_ij;
+ bndtmp2=psign*betaS_ij*bndtmp*sigma_c[iij];
+ setting=0;
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ temp_kk=bt_sg[m].temp;
+ if(temp_kk==temp_ij&&setting==0) {
+ bt_sg[m].dSigB1[0]=bndtmp1*dis_ij[0]
+ +(bndtmp2*bt_sg[m].dAAC[0]);
+ bt_sg[m].dSigB1[1]=bndtmp1*dis_ij[1]
+ +(bndtmp2*bt_sg[m].dAAC[1]);
+ bt_sg[m].dSigB1[2]=bndtmp1*dis_ij[2]
+ +(bndtmp2*bt_sg[m].dAAC[2]);
+ setting=1;
+ }
+ else if(temp_kk==temp_ji&&setting==0) {
+ bt_sg[m].dSigB1[0]=-bndtmp1*dis_ij[0]
+ +(bndtmp2*bt_sg[m].dAAC[0]);
+ bt_sg[m].dSigB1[1]=-bndtmp1*dis_ij[1]
+ +(bndtmp2*bt_sg[m].dAAC[1]);
+ bt_sg[m].dSigB1[2]=-bndtmp1*dis_ij[2]
+ +(bndtmp2*bt_sg[m].dAAC[2]);
+ setting=1;
+ }
+ else {
+ bt_sg[m].dSigB1[0]=(bndtmp2*bt_sg[m].dAAC[0]);
+ bt_sg[m].dSigB1[1]=(bndtmp2*bt_sg[m].dAAC[1]);
+ bt_sg[m].dSigB1[2]=(bndtmp2*bt_sg[m].dAAC[2]);
+ }
+ }
+ }
+
+//This loop is to ensure there is not an error for atoms with no neighbors (deposition)
+
+ if(nb_t==0) {
+ if(j>i) {
+ bt_sg[0].dSigB1[0]=bndtmp1*dis_ij[0];
+ bt_sg[0].dSigB1[1]=bndtmp1*dis_ij[1];
+ bt_sg[0].dSigB1[2]=bndtmp1*dis_ij[2];
+ }
+ else {
+ bt_sg[0].dSigB1[0]=-bndtmp1*dis_ij[0];
+ bt_sg[0].dSigB1[1]=-bndtmp1*dis_ij[1];
+ bt_sg[0].dSigB1[2]=-bndtmp1*dis_ij[2];
+ }
+ for(pp=0;pp<3;pp++) {
+ bt_sg[0].dAA[pp]=0.0;
+ bt_sg[0].dBB[pp]=0.0;
+ bt_sg[0].dEE1[pp]=0.0;
+ bt_sg[0].dFF[pp]=0.0;
+ bt_sg[0].dAAC[pp]=0.0;
+ bt_sg[0].dSigB[pp]=0.0;
+ }
+ bt_sg[0].i=i;
+ bt_sg[0].j=j;
+ bt_sg[0].temp=temp_ij;
+ nb_t++;
+ if(nb_t>nb_sg) {
+ new_n_tot=nb_sg+maxneigh;
+ grow_sigma(nb_sg,new_n_tot);
+ nb_sg=new_n_tot;
+ }
+ }
+ ps=sigB1[n]*rdBO+1.0;
+ ks=(int)ps;
+ if(nBOt-1<ks)
+ ks=nBOt-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ dsigB1=((FsigBO3[iij][ks-1]*ps+FsigBO2[iij][ks-1])*ps
+ +FsigBO1[iij][ks-1])*ps+FsigBO[iij][ks-1];
+ dsigB2=(FsigBO6[iij][ks-1]*ps+FsigBO5[iij][ks-1])*ps+FsigBO4[iij][ks-1];
+ part0=(FF+0.5*AAC+small5);
+ part1=(sigma_f[iij]-0.5)*sigma_k[iij];
+ part2=1.0-part1*EE1/part0;
+ part3=dsigB1*part1/part0;
+ part4=part3/part0*EE1;
+
+// sigB is the final expression for (a) Eq. 6 and (b) Eq. 11
+
+ sigB[n]=dsigB1*part2;
+ pp1=2.0*betaS_ij;
+ for(m=0;m<nb_t;m++) {
+ if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+ temp_kk=bt_sg[m].temp;
+ bt_ij=bt_sg[m].temp;
+ bt_i=bt_sg[m].i;
+ bt_j=bt_sg[m].j;
+ xtmp[0]=x[bt_j][0]-x[bt_i][0];
+ xtmp[1]=x[bt_j][1]-x[bt_i][1];
+ xtmp[2]=x[bt_j][2]-x[bt_i][2];
+ for(pp=0;pp<3;pp++) {
+ bt_sg[m].dSigB[pp]=dsigB2*part2*bt_sg[m].dSigB1[pp]
+ -part3*bt_sg[m].dEE1[pp]
+ +part4*(bt_sg[m].dFF[pp]
+ +0.5*bt_sg[m].dAAC[pp]);
+ }
+ for(pp=0;pp<3;pp++) {
+ ftmp[pp]=pp1*bt_sg[m].dSigB[pp];
+ f[bt_i][pp]-=ftmp[pp];
+ f[bt_j][pp]+=ftmp[pp];
+ }
+ if(evflag) {
+ ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+ ,ftmp[2],xtmp[0],xtmp[1],xtmp[2]);
+ }
+ }
+ }
+ }
+ n++;
+ }
+ }
+ }
+ }
+ destroy_sigma();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::PiBo()
+{
+ int new_n_tot;
+ int i,j,k,kp,m,n,pp,nb_t;
+ int iij,ji,ki;
+ int nsearch,ncmp;
+ int i_tag,j_tag;
+ int njik,ngj,ngk,nglj,ngl,ngi;
+ int nkjkp,nijkp,ngli,nkikp,njikp;
+ int itmp,ltmp,jtmp,ktmp;
+ int nlocal,pi_flag;
+ int inum,*ilist,*iilist,*jlist;
+ int **firstneigh,*numneigh;
+ int itype,jtype;
+ int temp_ij,temp_ik,temp_ikp;
+ int temp_ji,temp_jki,temp_jk,temp_jkp;
+ int ang_jikp,ang_kikp,ang_ijk;
+ int ang_ijkp,ang_kjkp,ang_jik;
+ int nb_ij,nb_ik,nb_jk,nb_ikp,nb_jkp;
+ int bt_ij,bt_i,bt_j;
+ double AA,BB,CC,DD,EE,FF;
+ double cosSq,sinFactor,cosFactor;
+ double cosSq1,dotV,BBrt,AB1,AB2;
+ double BBrtR,ABrtR,ABrtR1,ABrtR2;
+ double angFactor,angFactor1,angFactor2;
+ double angFactor3,angFactor4,angRfactor;
+ double dAngR1,dAngR2,agpdpr3;
+ double agpdpr1,agpdpr2,app1,app2,app3;
+ double betaCapSq1,dbetaCapSq1;
+ double betaCapSq2,dbetaCapSq2;
+ double betaCapSum,ftmp[3];
+ double dPiB1,dPiB2,dPiB3,pp2;
+ double **f = atom->f;
+ double **x = atom->x;
+ int *type = atom->type;
+ int *tag = atom->tag;
+ int newton_pair = force->newton_pair;
+
+ nlocal = atom->nlocal;
+ inum = list->inum;
+ ilist = list->ilist;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+
+ n=0;
+
+// Loop over all local atoms for i
+
+ if(nb_pi>16) {
+ nb_pi=16;
+ }
+ if(nb_pi==0) {
+ nb_pi=(maxneigh)*(maxneigh/2);
+ }
+ if(allocate_pi) {
+ destroy_pi();
+ }
+ create_pi(nb_pi);
+ for(itmp=0;itmp<inum;itmp++) {
+ nb_t=0;
+ i = ilist[itmp];
+ itype = map[type[i]]+1;
+ i_tag=tag[i];
+
+// j is a loop over all neighbors of i
+
+ iilist=firstneigh[i];
+ for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+ temp_ij=BOP_index[i]+jtmp;
+ if(neigh_flag[temp_ij]) {
+ for(m=0;m<nb_pi;m++) {
+ for(pp=0;pp<3;pp++) {
+ bt_pi[m].dAA[pp]=0.0;
+ bt_pi[m].dBB[pp]=0.0;
+ bt_pi[m].dPiB[pp]=0.0;
+ }
+ bt_pi[m].i=-1;
+ bt_pi[m].j=-1;
+ }
+ j=iilist[jtmp];
+ jlist=firstneigh[j];
+ jtype=map[type[j]]+1;
+ j_tag=tag[j];
+ nb_t=0;
+ ftmp[0]=0.0;
+ ftmp[1]=0.0;
+ ftmp[2]=0.0;
+ nb_ij=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_ij].i=i;
+ bt_pi[nb_ij].j=j;
+ bt_pi[nb_ij].temp=temp_ij;
+ if(j_tag>=i_tag) {
+ if(itype==jtype)
+ iij=itype-1;
+ else if(itype<jtype)
+ iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+ else
+ iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+ AA=0.0;
+ BB=0.0;
+ nPiBk[n]=0;
+ for(ji=0;ji<numneigh[j];ji++) {
+ temp_ji=BOP_index[j]+ji;
+ if(x[jlist[ji]][0]==x[i][0]) {
+ if(x[jlist[ji]][1]==x[i][1]) {
+ if(x[jlist[ji]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+
+// j and k are different neighbors of i
+
+ for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+ if(ktmp!=jtmp) {
+ temp_ik=BOP_index[i]+ktmp;
+ if(neigh_flag[temp_ik]) {
+ k=iilist[ktmp];
+ if(jtmp<ktmp) {
+ njik=jtmp*(2*numneigh[i]-jtmp-1)/2+(ktmp-jtmp)-1;
+ ngj=0;
+ ngk=1;
+ }
+ else {
+ njik=ktmp*(2*numneigh[i]-ktmp-1)/2+(jtmp-ktmp)-1;
+ ngj=1;
+ ngk=0;
+ }
+ ang_jik=cos_index[i]+njik;
+ if(ang_jik>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ nb_ik=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_ik].i=i;
+ bt_pi[nb_ik].j=k;
+ bt_pi[nb_ik].temp=temp_ik;
+ cosSq=cosAng[ang_jik]*cosAng[ang_jik];
+ sinFactor=.5*(1.0-cosSq)*pi_p[itype-1]*betaS[temp_ik];
+ cosFactor=.5*(1.0+cosSq)*betaP[temp_ik];
+ betaCapSq1=pi_p[itype-1]*betaS[temp_ik]*betaS[temp_ik]-betaP[temp_ik]
+ *betaP[temp_ik];
+ dbetaCapSq1=2.0*pi_p[itype-1]*betaS[temp_ik]*dBetaS[temp_ik]
+ -2.0*betaP[temp_ik]*dBetaP[temp_ik];
+
+//AA is Eq. 37 (a) and Eq. 19 (b) or i atoms
+//1st BB is first term of Eq. 38 (a) where j and k =neighbors i
+
+ AA=AA+sinFactor*betaS[temp_ik]+cosFactor*betaP[temp_ik];
+ BB=BB+.25*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*betaCapSq1;
+
+//agpdpr1 is derivative of AA w.r.t. for atom i w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik)
+//app1 is derivative of AA w.r.t. for atom i w.r.t. cos(theta_jik)
+//app2 is derivative of BB w.r.t. for atom i w.r.t. cos(theta_jik)
+
+ agpdpr1=(2.0*sinFactor*dBetaS[temp_ik]+2.0*cosFactor
+ *dBetaP[temp_ik])/rij[temp_ik];
+ app1=cosAng[ang_jik]*(-pi_p[itype-1]*betaS[temp_ik]*betaS[temp_ik]
+ +betaP[temp_ik]*betaP[temp_ik]);
+ app2=-(1.0-cosSq)*cosAng[ang_jik]*betaCapSq1*betaCapSq1;
+ agpdpr2=.5*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*dbetaCapSq1/rij[temp_ik];
+ itypePiBk[n][nPiBk[n]]=k;
+ bt_pi[nb_ij].dAA[0]+=
+ app1*dcAng[ang_jik][0][ngj];
+ bt_pi[nb_ij].dAA[1]+=
+ app1*dcAng[ang_jik][1][ngj];
+ bt_pi[nb_ij].dAA[2]+=
+ app1*dcAng[ang_jik][2][ngj];
+ bt_pi[nb_ij].dBB[0]+=
+ app2*dcAng[ang_jik][0][ngj];
+ bt_pi[nb_ij].dBB[1]+=
+ app2*dcAng[ang_jik][1][ngj];
+ bt_pi[nb_ij].dBB[2]+=
+ app2*dcAng[ang_jik][2][ngj];
+ bt_pi[nb_ik].dAA[0]+=
+ agpdpr1*disij[0][temp_ik]
+ +app1*dcAng[ang_jik][0][ngk];
+ bt_pi[nb_ik].dAA[1]+=
+ agpdpr1*disij[1][temp_ik]
+ +app1*dcAng[ang_jik][1][ngk];
+ bt_pi[nb_ik].dAA[2]+=
+ agpdpr1*disij[2][temp_ik]
+ +app1*dcAng[ang_jik][2][ngk];
+ bt_pi[nb_ik].dBB[0]+=
+ app2*dcAng[ang_jik][0][ngk]
+ +agpdpr2*disij[0][temp_ik];
+ bt_pi[nb_ik].dBB[1]+=
+ app2*dcAng[ang_jik][1][ngk]
+ +agpdpr2*disij[1][temp_ik];
+ bt_pi[nb_ik].dBB[2]+=
+ app2*dcAng[ang_jik][2][ngk]
+ +agpdpr2*disij[2][temp_ik];
+
+// j and k and k' are different neighbors of i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=jtmp) {
+ temp_ikp=BOP_index[i]+ltmp;
+ if(neigh_flag[temp_ikp]) {
+ kp=iilist[ltmp];
+ for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+ ncmp=itypePiBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ break;
+ }
+ }
+ }
+ }
+ nkikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(ktmp-ltmp)-1;
+ if(jtmp<ltmp) {
+ njikp=jtmp*(2*numneigh[i]-jtmp-1)/2+(ltmp-jtmp)-1;
+ nglj=0;
+ ngl=1;
+ }
+ else {
+ njikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(jtmp-ltmp)-1;
+ nglj=1;
+ ngl=0;
+ }
+ ang_jikp=cos_index[i]+njikp;
+ if(ang_jikp>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ nb_ikp=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_ikp].i=i;
+ bt_pi[nb_ikp].j=kp;
+ bt_pi[nb_ikp].temp=temp_ikp;
+ ang_kikp=cos_index[i]+nkikp;
+ if(ang_kikp>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ betaCapSq2=pi_p[itype-1]*betaS[temp_ikp]*betaS[temp_ikp]
+ -betaP[temp_ikp]*betaP[temp_ikp];
+ dbetaCapSq2=2.0*pi_p[itype-1]*betaS[temp_ikp]*dBetaS[temp_ikp]
+ -2.0*betaP[temp_ikp]*dBetaP[temp_ikp];
+ cosSq1=cosAng[ang_jikp]*cosAng[ang_jikp];
+ angFactor=cosAng[ang_kikp]-cosAng[ang_jikp]*cosAng[ang_jik];
+ angFactor1=4.0*angFactor;
+ angFactor2=-angFactor1*cosAng[ang_jikp]
+ +2.0*cosAng[ang_jik]*(1.0-cosSq1);
+ angFactor3=-angFactor1*cosAng[ang_jik]
+ +2.0*cosAng[ang_jikp]*(1.0-cosSq);
+ angFactor4=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+ betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//2nd BB is third term of Eq. 38 (a) where j , k and k'=neighbors i
+
+ BB=BB+betaCapSum*angFactor4;
+
+//agpdpr1 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik')
+//app1 is derivative of BB 3rd term w.r.t. cos(theta_kik')
+//app2 is derivative of BB 3rd term w.r.t. cos(theta_jik)
+//app3 is derivative of BB 3rd term w.r.t. cos(theta_jik')
+
+ app1=betaCapSum*angFactor1;
+ app2=betaCapSum*angFactor2;
+ app3=betaCapSum*angFactor3;
+ agpdpr1=.5*angFactor4*dbetaCapSq1*betaCapSq2/rij[temp_ik];
+ agpdpr2=.5*angFactor4*betaCapSq1*dbetaCapSq2/rij[temp_ikp];
+
+ bt_pi[nb_ij].dBB[0]+=
+ app2*dcAng[ang_jik][0][ngj]
+ +app3*dcAng[ang_jikp][0][nglj];
+ bt_pi[nb_ij].dBB[1]+=
+ app2*dcAng[ang_jik][1][ngj]
+ +app3*dcAng[ang_jikp][1][nglj];
+ bt_pi[nb_ij].dBB[2]+=
+ app2*dcAng[ang_jik][2][ngj]
+ +app3*dcAng[ang_jikp][2][nglj];
+ bt_pi[nb_ik].dBB[0]+=
+ agpdpr1*disij[0][temp_ik]
+ +app1*dcAng[ang_kikp][0][1]
+ +app2*dcAng[ang_jik][0][ngk];
+ bt_pi[nb_ik].dBB[1]+=
+ agpdpr1*disij[1][temp_ik]
+ +app1*dcAng[ang_kikp][1][1]
+ +app2*dcAng[ang_jik][1][ngk];
+ bt_pi[nb_ik].dBB[2]+=
+ agpdpr1*disij[2][temp_ik]
+ +app1*dcAng[ang_kikp][2][1]
+ +app2*dcAng[ang_jik][2][ngk];
+ bt_pi[nb_ikp].dBB[0]+=
+ agpdpr2*disij[0][temp_ikp]
+ +app1*dcAng[ang_kikp][0][0]
+ +app3*dcAng[ang_jikp][0][ngl];
+ bt_pi[nb_ikp].dBB[1]+=
+ agpdpr2*disij[1][temp_ikp]
+ +app1*dcAng[ang_kikp][1][0]
+ +app3*dcAng[ang_jikp][1][ngl];
+ bt_pi[nb_ikp].dBB[2]+=
+ agpdpr2*disij[2][temp_ikp]
+ +app1*dcAng[ang_kikp][2][0]
+ +app3*dcAng[ang_jikp][2][ngl];
+ }
+ }
+ }
+ nPiBk[n]=nPiBk[n]+1;
+ }
+ }
+ }
+
+//j is a neighbor of i and k is a neighbor of j and equal to i
+
+ for(ki=0;ki<numneigh[j];ki++) {
+ temp_jki=BOP_index[j]+ki;
+ k=jlist[ki];
+ if(x[k][0]==x[i][0]) {
+ if(x[k][1]==x[i][1]) {
+ if(x[k][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+
+//j is a neighbor of i and k is a neighbor of j not equal to i
+
+ for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+ if(ktmp!=ki) {
+ temp_jk=BOP_index[j]+ktmp;
+ if(neigh_flag[temp_jk]) {
+ k=jlist[ktmp];
+ pi_flag=0;
+ for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+ ncmp=itypePiBk[n][nsearch];
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ pi_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(pi_flag==0) {
+ itypePiBk[n][nPiBk[n]]=k;
+ }
+ if(ktmp<ki) {
+ njik=ktmp*(2*numneigh[j]-ktmp-1)/2+(ki-ktmp)-1;
+ ngi=1;
+ ngk=0;
+ }
+ else {
+ njik=ki*(2*numneigh[j]-ki-1)/2+(ktmp-ki)-1;
+ ngi=0;
+ ngk=1;
+ }
+ ang_ijk=cos_index[j]+njik;
+ if(ang_ijk>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ nb_jk=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_jk].i=j;
+ bt_pi[nb_jk].j=k;
+ bt_pi[nb_jk].temp=temp_jk;
+ cosSq=cosAng[ang_ijk]*cosAng[ang_ijk];
+ sinFactor=.5*(1.0-cosSq)*pi_p[jtype-1]*betaS[temp_jk];
+ cosFactor=.5*(1.0+cosSq)*betaP[temp_jk];
+ betaCapSq1=pi_p[jtype-1]*betaS[temp_jk]*betaS[temp_jk]
+ -betaP[temp_jk]*betaP[temp_jk];
+ dbetaCapSq1=2.0*pi_p[jtype-1]*betaS[temp_jk]*dBetaS[temp_jk]
+ -2.0*betaP[temp_jk]*dBetaP[temp_jk];
+
+//AA is Eq. 37 (a) and Eq. 19 (b) for j atoms
+//3rd BB is 2nd term of Eq. 38 (a) where i and k =neighbors j
+
+ AA=AA+sinFactor*betaS[temp_jk]+cosFactor*betaP[temp_jk];
+ BB=BB+.25*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*betaCapSq1;
+
+//agpdpr1 is derivative of AA for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB for atom j w.r.t. Beta(r_jk)
+//app1 is derivative of AA for j atom w.r.t. cos(theta_ijk)
+//app2 is derivative of BB 2nd term w.r.t. cos(theta_ijk)
+
+ agpdpr1=(2.0*sinFactor*dBetaS[temp_jk]+2.0*cosFactor
+ *dBetaP[temp_jk])/rij[temp_jk];
+ agpdpr2=.5*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*dbetaCapSq1/rij[temp_jk];
+ app1=cosAng[ang_ijk]*(-pi_p[jtype-1]*betaS[temp_jk]*betaS[temp_jk]
+ +betaP[temp_jk]*betaP[temp_jk]);
+ app2=-(1.0-cosSq)*cosAng[ang_ijk]*betaCapSq1*betaCapSq1;
+ bt_pi[nb_ij].dAA[0]-=
+ app1*dcAng[ang_ijk][0][ngi];
+ bt_pi[nb_ij].dAA[1]-=
+ app1*dcAng[ang_ijk][1][ngi];
+ bt_pi[nb_ij].dAA[2]-=
+ app1*dcAng[ang_ijk][2][ngi];
+ bt_pi[nb_ij].dBB[0]-=
+ app2*dcAng[ang_ijk][0][ngi];
+ bt_pi[nb_ij].dBB[1]-=
+ app2*dcAng[ang_ijk][1][ngi];
+ bt_pi[nb_ij].dBB[2]-=
+ app2*dcAng[ang_ijk][2][ngi];
+ bt_pi[nb_jk].dAA[0]+=
+ agpdpr1*disij[0][temp_jk]
+ +app1*dcAng[ang_ijk][0][ngk];
+ bt_pi[nb_jk].dAA[1]+=
+ agpdpr1*disij[1][temp_jk]
+ +app1*dcAng[ang_ijk][1][ngk];
+ bt_pi[nb_jk].dAA[2]+=
+ agpdpr1*disij[2][temp_jk]
+ +app1*dcAng[ang_ijk][2][ngk];
+ bt_pi[nb_jk].dBB[0]+=
+ app2*dcAng[ang_ijk][0][ngk]
+ +agpdpr2*disij[0][temp_jk];
+ bt_pi[nb_jk].dBB[1]+=
+ app2*dcAng[ang_ijk][1][ngk]
+ +agpdpr2*disij[1][temp_jk];
+ bt_pi[nb_jk].dBB[2]+=
+ app2*dcAng[ang_ijk][2][ngk]
+ +agpdpr2*disij[2][temp_jk];
+
+//j is a neighbor of i and k and k' are different neighbors of j not equal to i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=ki) {
+ temp_jkp=BOP_index[j]+ltmp;
+ if(neigh_flag[temp_jkp]) {
+ kp=jlist[ltmp];
+ for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+ ncmp=itypePiBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ break;
+ }
+ }
+ }
+ }
+ nkjkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ktmp-ltmp)-1;
+ if(ki<ltmp) {
+ nijkp=ki*(2*numneigh[j]-ki-1)/2+(ltmp-ki)-1;
+ ngli=0;
+ ngl=1;
+ }
+ else {
+ nijkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ki-ltmp)-1;
+ ngli=1;
+ ngl=0;
+ }
+ ang_ijkp=cos_index[j]+nijkp;
+ if(ang_ijkp>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ ang_kjkp=cos_index[j]+nkjkp;
+ if(ang_kjkp>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ nb_jkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_jkp].i=j;
+ bt_pi[nb_jkp].j=kp;
+ bt_pi[nb_jkp].temp=temp_jkp;
+ betaCapSq2=pi_p[jtype-1]*betaS[temp_jkp]*betaS[temp_jkp]
+ -betaP[temp_jkp]*betaP[temp_jkp];
+ dbetaCapSq2=2.0*pi_p[jtype-1]*betaS[temp_jkp]*dBetaS[temp_jkp]
+ -2.0*betaP[temp_jkp]*dBetaP[temp_jkp];
+ cosSq1=cosAng[ang_ijkp]*cosAng[ang_ijkp];
+ angFactor=cosAng[ang_kjkp]-cosAng[ang_ijkp]*cosAng[ang_ijk];
+ angFactor1=4.0*angFactor;
+ angFactor2=-angFactor1*cosAng[ang_ijkp]
+ +2.0*cosAng[ang_ijk]*(1.0-cosSq1);
+ angFactor3=-angFactor1*cosAng[ang_ijk]
+ +2.0*cosAng[ang_ijkp]*(1.0-cosSq);
+ angFactor4=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+ betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//4th BB is 4th term of Eq. 38 (a) where i , k and k' =neighbors j
+
+ BB=BB+betaCapSum*angFactor4;
+
+//app1 is derivative of BB 4th term w.r.t. cos(theta_kjk')
+//app2 is derivative of BB 4th term w.r.t. cos(theta_ijk)
+//app3 is derivative of BB 4th term w.r.t. cos(theta_ijk')
+//agpdpr1 is derivative of BB 4th term for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB 4th term for atom j w.r.t. Beta(r_jk')
+
+ app1=betaCapSum*angFactor1;
+ app2=betaCapSum*angFactor2;
+ app3=betaCapSum*angFactor3;
+ agpdpr1=.5*angFactor4*dbetaCapSq1*betaCapSq2/rij[temp_jk];
+ agpdpr2=.5*angFactor4*betaCapSq1*dbetaCapSq2/rij[temp_jkp];
+
+ bt_pi[nb_ij].dBB[0]-=
+ app3*dcAng[ang_ijkp][0][ngli]
+ +app2*dcAng[ang_ijk][0][ngi];
+ bt_pi[nb_ij].dBB[1]-=
+ app3*dcAng[ang_ijkp][1][ngli]
+ +app2*dcAng[ang_ijk][1][ngi];
+ bt_pi[nb_ij].dBB[2]-=
+ app3*dcAng[ang_ijkp][2][ngli]
+ +app2*dcAng[ang_ijk][2][ngi];
+ bt_pi[nb_jk].dBB[0]+=
+ agpdpr1*disij[0][temp_jk]
+ +app1*dcAng[ang_kjkp][0][1]
+ +app2*dcAng[ang_ijk][0][ngk];
+ bt_pi[nb_jk].dBB[1]+=
+ agpdpr1*disij[1][temp_jk]
+ +app1*dcAng[ang_kjkp][1][1]
+ +app2*dcAng[ang_ijk][1][ngk];
+ bt_pi[nb_jk].dBB[2]+=
+ agpdpr1*disij[2][temp_jk]
+ +app1*dcAng[ang_kjkp][2][1]
+ +app2*dcAng[ang_ijk][2][ngk];
+ bt_pi[nb_jkp].dBB[0]+=
+ agpdpr2*disij[0][temp_jkp]
+ +app1*dcAng[ang_kjkp][0][0]
+ +app3*dcAng[ang_ijkp][0][ngl];
+ bt_pi[nb_jkp].dBB[1]+=
+ agpdpr2*disij[1][temp_jkp]
+ +app1*dcAng[ang_kjkp][1][0]
+ +app3*dcAng[ang_ijkp][1][ngl];
+ bt_pi[nb_jkp].dBB[2]+=
+ agpdpr2*disij[2][temp_jkp]
+ +app1*dcAng[ang_kjkp][2][0]
+ +app3*dcAng[ang_ijkp][2][ngl];
+ }
+ }
+ }
+
+//j and k' are different neighbors of i and k is a neighbor of j not equal to i
+
+ for(ltmp=0;ltmp<numneigh[i];ltmp++) {
+ if(ltmp!=jtmp) {
+ temp_ikp=BOP_index[i]+ltmp;
+ if(neigh_flag[temp_ikp]) {
+ kp=iilist[ltmp];
+ for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+ ncmp=itypePiBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(ltmp<jtmp) {
+ njikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(jtmp-ltmp)-1;
+ ngl=1;
+ nglj=0;
+ }
+ else {
+ njikp=jtmp*(2*numneigh[i]-jtmp-1)/2+(ltmp-jtmp)-1;
+ ngl=0;
+ nglj=1;
+ }
+ ang_jikp=cos_index[i]+njikp;
+ if(ang_jikp>=cos_total) {
+ error->one(FLERR,"Too many atom triplets for pair bop");
+ }
+ nb_ikp=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_ikp].i=i;
+ bt_pi[nb_ikp].j=kp;
+ bt_pi[nb_ikp].temp=temp_ikp;
+ betaCapSq2=pi_p[itype-1]*betaS[temp_ikp]*betaS[temp_ikp]
+ -betaP[temp_ikp]*betaP[temp_ikp];
+ dbetaCapSq2=2.0*pi_p[itype-1]*betaS[temp_ikp]*dBetaS[temp_ikp]
+ -2.0*betaP[temp_ikp]*dBetaP[temp_ikp];
+ dotV=(disij[0][temp_jk]*disij[0][temp_ikp]+disij[1][temp_jk]
+ *disij[1][temp_ikp]+disij[2][temp_jk]*disij[2][temp_ikp])
+ /(rij[temp_jk]*rij[temp_ikp]);
+ cosSq1=cosAng[ang_jikp]*cosAng[ang_jikp];
+ angFactor=dotV+cosAng[ang_jikp]*cosAng[ang_ijk];
+ angRfactor=4.0*angFactor*dotV;
+ dAngR1=-angRfactor/rij[temp_jk];
+ dAngR2=-angRfactor/rij[temp_ikp];
+ angFactor1=4.0*angFactor*cosAng[ang_jikp]
+ +2.0*cosAng[ang_ijk]*(1.0-cosSq1);
+ angFactor2=4.0*angFactor*cosAng[ang_ijk]
+ +2.0*cosAng[ang_jikp]*(1.0-cosSq);
+ angFactor3=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+ betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//5th BB is 5th term of Eq. 38 (a) Eq. 21 (b) where i , k and k' =neighbors j
+
+ BB=BB+betaCapSum*angFactor3;
+
+//app1 is derivative of BB 5th term w.r.t. cos(theta_ijk)
+//app2 is derivative of BB 5th term w.r.t. cos(theta_jik')
+//agpdpr1 is derivative of BB 5th term for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB 5th term for atom j w.r.t. Beta(r_ik')
+//agpdpr3 is derivative of BB 5th term for atom j w.r.t. dot(r_ik',r_ij)
+
+ app1=betaCapSum*angFactor1;
+ app2=betaCapSum*angFactor2;
+ agpdpr1=(.5*angFactor3*dbetaCapSq1*betaCapSq2
+ +betaCapSum*dAngR1)/rij[temp_jk];
+ agpdpr2=(.5*angFactor3*betaCapSq1*dbetaCapSq2
+ +betaCapSum*dAngR2)/rij[temp_ikp];
+ agpdpr3=4.0*betaCapSum*angFactor/(rij[temp_ikp]*rij[temp_jk]);
+
+ bt_pi[nb_ij].dBB[0]+=
+ +app2*dcAng[ang_jikp][0][ngl]
+ -app1*dcAng[ang_ijk][0][ngi];
+ bt_pi[nb_ij].dBB[1]+=
+ +app2*dcAng[ang_jikp][1][ngl]
+ -app1*dcAng[ang_ijk][1][ngi];
+ bt_pi[nb_ij].dBB[2]+=
+ +app2*dcAng[ang_jikp][2][ngl]
+ -app1*dcAng[ang_ijk][2][ngi];
+ bt_pi[nb_ikp].dBB[0]+=
+ agpdpr2*disij[0][temp_ikp]
+ +agpdpr3*disij[0][temp_jk]
+ +app2*dcAng[ang_jikp][0][nglj];
+ bt_pi[nb_ikp].dBB[1]+=
+ agpdpr2*disij[1][temp_ikp]
+ +agpdpr3*disij[1][temp_jk]
+ +app2*dcAng[ang_jikp][1][nglj];
+ bt_pi[nb_ikp].dBB[2]+=
+ agpdpr2*disij[2][temp_ikp]
+ +agpdpr3*disij[2][temp_jk]
+ +app2*dcAng[ang_jikp][2][nglj];
+ bt_pi[nb_jk].dBB[0]+=
+ agpdpr1*disij[0][temp_jk]
+ +agpdpr3*disij[0][temp_ikp]
+ +app1*dcAng[ang_ijk][0][ngk];
+ bt_pi[nb_jk].dBB[1]+=
+ agpdpr1*disij[1][temp_jk]
+ +agpdpr3*disij[1][temp_ikp]
+ +app1*dcAng[ang_ijk][1][ngk];
+ bt_pi[nb_jk].dBB[2]+=
+ agpdpr1*disij[2][temp_jk]
+ +agpdpr3*disij[2][temp_ikp]
+ +app1*dcAng[ang_ijk][2][ngk];
+ }
+ }
+ }
+ if(pi_flag==0)
+ nPiBk[n]=nPiBk[n]+1;
+ }
+ }
+ }
+ CC=betaP[temp_ij]*betaP[temp_ij]+pi_delta[iij]*pi_delta[iij];
+ BBrt=sqrt(BB+small6);
+ AB1=CC+pi_c[iij]*(AA+BBrt)+small7;
+ AB2=CC+pi_c[iij]*(AA-BBrt+sqrt(small6))+small7;
+ BBrtR=1.0/BBrt;
+ ABrtR1=1.0/sqrt(AB1);
+ ABrtR2=1.0/sqrt(AB2);
+
+// piB is similary formulation to (a) Eq. 36 and (b) Eq. 18
+
+ piB[n]=(ABrtR1+ABrtR2)*pi_a[iij]*betaP[temp_ij];
+ dPiB1=-.5*(pow(ABrtR1,3)+pow(ABrtR2,3))*pi_c[iij]*pi_a[iij]*betaP[temp_ij];
+ dPiB2=.25*BBrtR*(pow(ABrtR2,3)-pow(ABrtR1,3))*pi_c[iij]*pi_a[iij]*betaP[temp_ij];
+ dPiB3=((ABrtR1+ABrtR2)*pi_a[iij]-(pow(ABrtR1,3)+pow(ABrtR2,3))*pi_a[iij]
+ *betaP[temp_ij]*betaP[temp_ij])*dBetaP[temp_ij]/rij[temp_ij];
+ n++;
+ pp2=2.0*betaP[temp_ij];
+ for(m=0;m<nb_t;m++) {
+ bt_ij=bt_pi[m].temp;
+ bt_i=bt_pi[m].i;
+ bt_j=bt_pi[m].j;
+ for(pp=0;pp<3;pp++) {
+ bt_pi[m].dPiB[pp]=
+ +dPiB1*bt_pi[m].dAA[pp]
+ +dPiB2*bt_pi[m].dBB[pp];
+ ftmp[pp]=pp2*bt_pi[m].dPiB[pp];
+ f[bt_i][pp]-=ftmp[pp];
+ f[bt_j][pp]+=ftmp[pp];
+
+ }
+ if(evflag) {
+ ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+ ,ftmp[2],disij[0][bt_ij],disij[1][bt_ij],disij[2][bt_ij]);
+ }
+ }
+ for(pp=0;pp<3;pp++) {
+ ftmp[pp]=pp2*dPiB3*disij[pp][temp_ij];
+ f[i][pp]-=ftmp[pp];
+ f[j][pp]+=ftmp[pp];
+ }
+ if(evflag) {
+ ev_tally_xyz(i,j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+ ,ftmp[2],disij[0][temp_ij],disij[1][temp_ij],disij[2][temp_ij]);
+ }
+ }
+ }
+ }
+ }
+ destroy_pi();
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::PiBo_otf()
+{
+ int new_n_tot;
+ int i,j,k,kp,m,n,pp,nb_t;
+ int iij,iik,iikp,ji,ki,ijkp,ijk;
+ int nsearch,ncmp;
+ int i_tag,j_tag;
+ int itmp,ltmp,jtmp,ktmp;
+ int pi_flag,ks;
+ int nlocal;
+ int inum,*ilist,*iilist,*jlist;
+ int **firstneigh,*numneigh;
+ int itype,jtype,ktype,kptype;
+ int temp_ij,temp_ik,temp_ikp;
+ int temp_jk,temp_jkp;
+ int nb_ij,nb_ik,nb_jk,nb_ikp,nb_jkp;
+ int bt_i,bt_j;
+ double AA,BB,CC,DD,EE,FF;
+ double cosSq,sinFactor,cosFactor;
+ double cosSq1,dotV,BBrt,AB1,AB2;
+ double BBrtR,ABrtR,ABrtR1,ABrtR2;
+ double angFactor,angFactor1,angFactor2;
+ double angFactor3,angFactor4,angRfactor;
+ double dAngR1,dAngR2,agpdpr3;
+ double agpdpr1,agpdpr2,app1,app2,app3;
+ double betaCapSq1,dbetaCapSq1;
+ double betaCapSq2,dbetaCapSq2;
+ double betaCapSum,ps;
+ double ftmp[3],xtmp[3];
+ double dPiB1,dPiB2,dPiB3,pp2;
+
+ double dis_ij[3],rsq_ij,r_ij;
+ double betaP_ij,dBetaP_ij;
+ double dis_ik[3],rsq_ik,r_ik;
+ double betaS_ik,dBetaS_ik;
+ double betaP_ik,dBetaP_ik;
+ double dis_ikp[3],rsq_ikp,r_ikp;
+ double betaS_ikp,dBetaS_ikp;
+ double betaP_ikp,dBetaP_ikp;
+ double dis_jk[3],rsq_jk,r_jk;
+ double betaS_jk,dBetaS_jk;
+ double betaP_jk,dBetaP_jk;
+ double dis_jkp[3],rsq_jkp,r_jkp;
+ double betaS_jkp,dBetaS_jkp;
+ double betaP_jkp,dBetaP_jkp;
+
+ double cosAng_jik,dcA_jik[3][2];
+ double cosAng_jikp,dcA_jikp[3][2];
+ double cosAng_kikp,dcA_kikp[3][2];
+ double cosAng_ijk,dcA_ijk[3][2];
+ double cosAng_ijkp,dcA_ijkp[3][2];
+ double cosAng_kjkp,dcA_kjkp[3][2];
+
+ int newton_pair = force->newton_pair;
+
+ double **f = atom->f;
+ double **x = atom->x;
+ int *type = atom->type;
+ int *tag = atom->tag;
+
+ nlocal = atom->nlocal;
+ numneigh = list->numneigh;
+ firstneigh = list->firstneigh;
+ inum = list->inum;
+ ilist = list->ilist;
+ n=0;
+ if(nb_pi>16) {
+ nb_pi=16;
+ }
+ if(nb_pi==0) {
+ nb_pi=(maxneigh)*(maxneigh/2);
+ }
+
+// Loop over all local atoms for i
+
+ if(allocate_pi) {
+ destroy_pi();
+ }
+ create_pi(nb_pi);
+
+ for(itmp=0;itmp<inum;itmp++) {
+ nb_t=0;
+ i = ilist[itmp];
+ itype = map[type[i]]+1;
+ i_tag=tag[i];
+
+// j is a loop over all neighbors of i
+
+ iilist=firstneigh[i];
+ for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+ for(m=0;m<nb_pi;m++) {
+ for(pp=0;pp<3;pp++) {
+ bt_pi[m].dAA[pp]=0.0;
+ bt_pi[m].dBB[pp]=0.0;
+ bt_pi[m].dPiB[pp]=0.0;
+ }
+ bt_pi[m].i=-1;
+ bt_pi[m].j=-1;
+ }
+ temp_ij=BOP_index[i]+jtmp;
+ j=iilist[jtmp];
+ jlist=firstneigh[j];
+ jtype=map[type[j]]+1;
+ j_tag=tag[j];
+ nb_t=0;
+ ftmp[0]=0.0;
+ ftmp[1]=0.0;
+ ftmp[2]=0.0;
+ if(j_tag>=i_tag) {
+ if(itype==jtype)
+ iij=itype-1;
+ else if(itype<jtype)
+ iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+ else
+ iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+ AA=0.0;
+ BB=0.0;
+ nPiBk[n]=0;
+ for(ji=0;ji<numneigh[j];ji++) {
+ if(x[jlist[ji]][0]==x[i][0]) {
+ if(x[jlist[ji]][1]==x[i][1]) {
+ if(x[jlist[ji]][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+ nb_ij=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_ij].i=i;
+ bt_pi[nb_ij].j=j;
+ bt_pi[nb_ij].temp=temp_ij;
+ dis_ij[0]=x[j][0]-x[i][0];
+ dis_ij[1]=x[j][1]-x[i][1];
+ dis_ij[2]=x[j][2]-x[i][2];
+ rsq_ij=dis_ij[0]*dis_ij[0]
+ +dis_ij[1]*dis_ij[1]
+ +dis_ij[2]*dis_ij[2];
+ r_ij=sqrt(rsq_ij);
+ if(r_ij<=rcut[iij]) {
+ ps=r_ij*rdr[iij]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaP_ij=((pBetaP3[iij][ks-1]*ps+pBetaP2[iij][ks-1])*ps
+ +pBetaP1[iij][ks-1])*ps+pBetaP[iij][ks-1];
+ dBetaP_ij=(pBetaP6[iij][ks-1]*ps+pBetaP5[iij][ks-1])*ps
+ +pBetaP4[iij][ks-1];
+
+// j and k are different neighbors of i
+
+ for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+ if(ktmp!=jtmp) {
+ temp_ik=BOP_index[i]+ktmp;
+ k=iilist[ktmp];
+ ktype=map[type[k]]+1;
+ if(itype==ktype)
+ iik=itype-1;
+ else if(itype<ktype)
+ iik=itype*bop_types-itype*(itype+1)/2+ktype-1;
+ else
+ iik=ktype*bop_types-ktype*(ktype+1)/2+itype-1;
+ dis_ik[0]=x[k][0]-x[i][0];
+ dis_ik[1]=x[k][1]-x[i][1];
+ dis_ik[2]=x[k][2]-x[i][2];
+ rsq_ik=dis_ik[0]*dis_ik[0]
+ +dis_ik[1]*dis_ik[1]
+ +dis_ik[2]*dis_ik[2];
+ r_ik=sqrt(rsq_ik);
+ if(r_ik<=rcut[iik]) {
+ ps=r_ik*rdr[iik]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_ik=((pBetaS3[iik][ks-1]*ps+pBetaS2[iik][ks-1])*ps
+ +pBetaS1[iik][ks-1])*ps+pBetaS[iik][ks-1];
+ dBetaS_ik=(pBetaS6[iik][ks-1]*ps+pBetaS5[iik][ks-1])*ps
+ +pBetaS4[iik][ks-1];
+ betaP_ik=((pBetaP3[iik][ks-1]*ps+pBetaP2[iik][ks-1])*ps
+ +pBetaP1[iik][ks-1])*ps+pBetaP[iik][ks-1];
+ dBetaP_ik=(pBetaP6[iik][ks-1]*ps+pBetaP5[iik][ks-1])*ps
+ +pBetaP4[iik][ks-1];
+ cosAng_jik=(dis_ij[0]*dis_ik[0]+dis_ij[1]*dis_ik[1]
+ +dis_ij[2]*dis_ik[2])/(r_ij*r_ik);
+ dcA_jik[0][0]=(dis_ik[0]*r_ij*r_ik-cosAng_jik
+ *dis_ij[0]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[1][0]=(dis_ik[1]*r_ij*r_ik-cosAng_jik
+ *dis_ij[1]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[2][0]=(dis_ik[2]*r_ij*r_ik-cosAng_jik
+ *dis_ij[2]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[0][1]=(dis_ij[0]*r_ij*r_ik-cosAng_jik
+ *dis_ik[0]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[1][1]=(dis_ij[1]*r_ij*r_ik-cosAng_jik
+ *dis_ik[1]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+ dcA_jik[2][1]=(dis_ij[2]*r_ij*r_ik-cosAng_jik
+ *dis_ik[2]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+ nb_ik=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_ik].i=i;
+ bt_pi[nb_ik].j=k;
+ bt_pi[nb_ik].temp=temp_ik;
+ cosSq=cosAng_jik*cosAng_jik;
+ sinFactor=.5*(1.0-cosSq)*pi_p[itype-1]*betaS_ik;
+ cosFactor=.5*(1.0+cosSq)*betaP_ik;
+ betaCapSq1=pi_p[itype-1]*betaS_ik*betaS_ik-betaP_ik
+ *betaP_ik;
+ dbetaCapSq1=2.0*pi_p[itype-1]*betaS_ik*dBetaS_ik
+ -2.0*betaP_ik*dBetaP_ik;
+
+//AA is Eq. 37 (a) and Eq. 19 (b) or i atoms
+//1st BB is first term of Eq. 38 (a) where j and k =neighbors i
+
+ AA=AA+sinFactor*betaS_ik+cosFactor*betaP_ik;
+ BB=BB+.25*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*betaCapSq1;
+
+//agpdpr1 is derivative of AA w.r.t. for atom i w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik)
+//app1 is derivative of AA w.r.t. for atom i w.r.t. cos(theta_jik)
+//app2 is derivative of BB w.r.t. for atom i w.r.t. cos(theta_jik)
+
+ agpdpr1=(2.0*sinFactor*dBetaS_ik+2.0*cosFactor
+ *dBetaP_ik)/r_ik;
+ app1=cosAng_jik*(-pi_p[itype-1]*betaS_ik*betaS_ik
+ +betaP_ik*betaP_ik);
+ app2=-(1.0-cosSq)*cosAng_jik*betaCapSq1*betaCapSq1;
+ agpdpr2=.5*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*dbetaCapSq1/r_ik;
+ itypePiBk[n][nPiBk[n]]=k;
+ bt_pi[nb_ij].dAA[0]+=
+ app1*dcA_jik[0][0];
+ bt_pi[nb_ij].dAA[1]+=
+ app1*dcA_jik[1][0];
+ bt_pi[nb_ij].dAA[2]+=
+ app1*dcA_jik[2][0];
+ bt_pi[nb_ij].dBB[0]+=
+ app2*dcA_jik[0][0];
+ bt_pi[nb_ij].dBB[1]+=
+ app2*dcA_jik[1][0];
+ bt_pi[nb_ij].dBB[2]+=
+ app2*dcA_jik[2][0];
+ bt_pi[nb_ik].dAA[0]+=
+ agpdpr1*dis_ik[0]
+ +app1*dcA_jik[0][1];
+ bt_pi[nb_ik].dAA[1]+=
+ agpdpr1*dis_ik[1]
+ +app1*dcA_jik[1][1];
+ bt_pi[nb_ik].dAA[2]+=
+ agpdpr1*dis_ik[2]
+ +app1*dcA_jik[2][1];
+ bt_pi[nb_ik].dBB[0]+=
+ app2*dcA_jik[0][1]
+ +agpdpr2*dis_ik[0];
+ bt_pi[nb_ik].dBB[1]+=
+ app2*dcA_jik[1][1]
+ +agpdpr2*dis_ik[1];
+ bt_pi[nb_ik].dBB[2]+=
+ app2*dcA_jik[2][1]
+ +agpdpr2*dis_ik[2];
+
+// j and k and k' are different neighbors of i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=jtmp) {
+ temp_ikp=BOP_index[i]+ltmp;
+ kp=iilist[ltmp];
+ kptype=map[type[kp]]+1;
+ for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+ ncmp=itypePiBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(itype==kptype)
+ iikp=itype-1;
+ else if(itype<kptype)
+ iikp=itype*bop_types-itype*(itype+1)/2+kptype-1;
+ else
+ iikp=kptype*bop_types-kptype*(kptype+1)/2+itype-1;
+ dis_ikp[0]=x[kp][0]-x[i][0];
+ dis_ikp[1]=x[kp][1]-x[i][1];
+ dis_ikp[2]=x[kp][2]-x[i][2];
+ rsq_ikp=dis_ikp[0]*dis_ikp[0]
+ +dis_ikp[1]*dis_ikp[1]
+ +dis_ikp[2]*dis_ikp[2];
+ r_ikp=sqrt(rsq_ikp);
+ if(r_ikp<=rcut[iikp]) {
+ ps=r_ikp*rdr[iikp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_ikp=((pBetaS3[iikp][ks-1]*ps+pBetaS2[iikp][ks-1])*ps
+ +pBetaS1[iikp][ks-1])*ps+pBetaS[iikp][ks-1];
+ dBetaS_ikp=(pBetaS6[iikp][ks-1]*ps+pBetaS5[iikp][ks-1])*ps
+ +pBetaS4[iikp][ks-1];
+ betaP_ikp=((pBetaP3[iikp][ks-1]*ps+pBetaP2[iikp][ks-1])*ps
+ +pBetaP1[iikp][ks-1])*ps+pBetaP[iikp][ks-1];
+ dBetaP_ikp=(pBetaP6[iikp][ks-1]*ps+pBetaP5[iikp][ks-1])*ps
+ +pBetaP4[iikp][ks-1];
+ cosAng_jikp=(dis_ij[0]*dis_ikp[0]+dis_ij[1]*dis_ikp[1]
+ +dis_ij[2]*dis_ikp[2])/(r_ij*r_ikp);
+ dcA_jikp[0][0]=(dis_ikp[0]*r_ij*r_ikp-cosAng_jikp
+ *dis_ij[0]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[1][0]=(dis_ikp[1]*r_ij*r_ikp-cosAng_jikp
+ *dis_ij[1]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[2][0]=(dis_ikp[2]*r_ij*r_ikp-cosAng_jikp
+ *dis_ij[2]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[0][1]=(dis_ij[0]*r_ij*r_ikp-cosAng_jikp
+ *dis_ikp[0]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[1][1]=(dis_ij[1]*r_ij*r_ikp-cosAng_jikp
+ *dis_ikp[1]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[2][1]=(dis_ij[2]*r_ij*r_ikp-cosAng_jikp
+ *dis_ikp[2]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+ cosAng_kikp=(dis_ik[0]*dis_ikp[0]+dis_ik[1]*dis_ikp[1]
+ +dis_ik[2]*dis_ikp[2])/(r_ik*r_ikp);
+ dcA_kikp[0][0]=(dis_ikp[0]*r_ik*r_ikp-cosAng_kikp
+ *dis_ik[0]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+ dcA_kikp[1][0]=(dis_ikp[1]*r_ik*r_ikp-cosAng_kikp
+ *dis_ik[1]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+ dcA_kikp[2][0]=(dis_ikp[2]*r_ik*r_ikp-cosAng_kikp
+ *dis_ik[2]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+ dcA_kikp[0][1]=(dis_ik[0]*r_ik*r_ikp-cosAng_kikp
+ *dis_ikp[0]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+ dcA_kikp[1][1]=(dis_ik[1]*r_ik*r_ikp-cosAng_kikp
+ *dis_ikp[1]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+ dcA_kikp[2][1]=(dis_ik[2]*r_ik*r_ikp-cosAng_kikp
+ *dis_ikp[2]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+ nb_ikp=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_ikp].i=i;
+ bt_pi[nb_ikp].j=kp;
+ bt_pi[nb_ikp].temp=temp_ikp;
+ betaCapSq2=pi_p[itype-1]*betaS_ikp*betaS_ikp
+ -betaP_ikp*betaP_ikp;
+ dbetaCapSq2=2.0*pi_p[itype-1]*betaS_ikp*dBetaS_ikp
+ -2.0*betaP_ikp*dBetaP_ikp;
+ cosSq1=cosAng_jikp*cosAng_jikp;
+ angFactor=cosAng_kikp-cosAng_jikp*cosAng_jik;
+ angFactor1=4.0*angFactor;
+ angFactor2=-angFactor1*cosAng_jikp
+ +2.0*cosAng_jik*(1.0-cosSq1);
+ angFactor3=-angFactor1*cosAng_jik
+ +2.0*cosAng_jikp*(1.0-cosSq);
+ angFactor4=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+ betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//2nd BB is third term of Eq. 38 (a) where j , k and k'=neighbors i
+
+ BB=BB+betaCapSum*angFactor4;
+
+//agpdpr1 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik')
+//app1 is derivative of BB 3rd term w.r.t. cos(theta_kik')
+//app2 is derivative of BB 3rd term w.r.t. cos(theta_jik)
+//app3 is derivative of BB 3rd term w.r.t. cos(theta_jik')
+
+ app1=betaCapSum*angFactor1;
+ app2=betaCapSum*angFactor2;
+ app3=betaCapSum*angFactor3;
+ agpdpr1=.5*angFactor4*dbetaCapSq1*betaCapSq2/r_ik;
+ agpdpr2=.5*angFactor4*betaCapSq1*dbetaCapSq2/r_ikp;
+ bt_pi[nb_ij].dBB[0]+=
+ app2*dcA_jik[0][0]
+ +app3*dcA_jikp[0][0];
+ bt_pi[nb_ij].dBB[1]+=
+ app2*dcA_jik[1][0]
+ +app3*dcA_jikp[1][0];
+ bt_pi[nb_ij].dBB[2]+=
+ app2*dcA_jik[2][0]
+ +app3*dcA_jikp[2][0];
+ bt_pi[nb_ik].dBB[0]+=
+ agpdpr1*dis_ik[0]
+ +app1*dcA_kikp[0][0]
+ +app2*dcA_jik[0][1];
+ bt_pi[nb_ik].dBB[1]+=
+ agpdpr1*dis_ik[1]
+ +app1*dcA_kikp[1][0]
+ +app2*dcA_jik[1][1];
+ bt_pi[nb_ik].dBB[2]+=
+ agpdpr1*dis_ik[2]
+ +app1*dcA_kikp[2][0]
+ +app2*dcA_jik[2][1];
+ bt_pi[nb_ikp].dBB[0]+=
+ agpdpr2*dis_ikp[0]
+ +app1*dcA_kikp[0][1]
+ +app3*dcA_jikp[0][1];
+ bt_pi[nb_ikp].dBB[1]+=
+ agpdpr2*dis_ikp[1]
+ +app1*dcA_kikp[1][1]
+ +app3*dcA_jikp[1][1];
+ bt_pi[nb_ikp].dBB[2]+=
+ agpdpr2*dis_ikp[2]
+ +app1*dcA_kikp[2][1]
+ +app3*dcA_jikp[2][1];
+ }
+ }
+ }
+ nPiBk[n]=nPiBk[n]+1;
+ }
+ }
+ }
+
+//j is a neighbor of i and k is a neighbor of j and equal to i
+
+ for(ki=0;ki<numneigh[j];ki++) {
+ k=jlist[ki];
+ if(x[k][0]==x[i][0]) {
+ if(x[k][1]==x[i][1]) {
+ if(x[k][2]==x[i][2]) {
+ break;
+ }
+ }
+ }
+ }
+
+//j is a neighbor of i and k is a neighbor of j not equal to i
+
+ for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+ if(ktmp!=ki) {
+ temp_jk=BOP_index[j]+ktmp;
+ k=jlist[ktmp];
+ ktype=map[type[k]]+1;
+ pi_flag=0;
+ for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+ ncmp=itypePiBk[n][nsearch];
+ if(x[ncmp][0]==x[k][0]) {
+ if(x[ncmp][1]==x[k][1]) {
+ if(x[ncmp][2]==x[k][2]) {
+ pi_flag=1;
+ break;
+ }
+ }
+ }
+ }
+ if(pi_flag==0) {
+ itypePiBk[n][nPiBk[n]]=k;
+ }
+ if(jtype==ktype)
+ ijk=jtype-1;
+ else if(jtype<ktype)
+ ijk=jtype*bop_types-jtype*(jtype+1)/2+ktype-1;
+ else
+ ijk=ktype*bop_types-ktype*(ktype+1)/2+jtype-1;
+ dis_jk[0]=x[k][0]-x[j][0];
+ dis_jk[1]=x[k][1]-x[j][1];
+ dis_jk[2]=x[k][2]-x[j][2];
+ rsq_jk=dis_jk[0]*dis_jk[0]
+ +dis_jk[1]*dis_jk[1]
+ +dis_jk[2]*dis_jk[2];
+ r_jk=sqrt(rsq_jk);
+ if(r_jk<=rcut[ijk]) {
+ ps=r_jk*rdr[ijk]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_jk=((pBetaS3[ijk][ks-1]*ps+pBetaS2[ijk][ks-1])*ps
+ +pBetaS1[ijk][ks-1])*ps+pBetaS[ijk][ks-1];
+ dBetaS_jk=(pBetaS6[ijk][ks-1]*ps+pBetaS5[ijk][ks-1])*ps
+ +pBetaS4[ijk][ks-1];
+ betaP_jk=((pBetaP3[ijk][ks-1]*ps+pBetaP2[ijk][ks-1])*ps
+ +pBetaP1[ijk][ks-1])*ps+pBetaP[ijk][ks-1];
+ dBetaP_jk=(pBetaP6[ijk][ks-1]*ps+pBetaP5[ijk][ks-1])*ps
+ +pBetaP4[ijk][ks-1];
+ cosAng_ijk=(-dis_ij[0]*dis_jk[0]-dis_ij[1]*dis_jk[1]
+ -dis_ij[2]*dis_jk[2])/(r_ij*r_jk);
+ dcA_ijk[0][0]=(dis_jk[0]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[0]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[1][0]=(dis_jk[1]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[1]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[2][0]=(dis_jk[2]*r_ij*r_jk-cosAng_ijk
+ *-dis_ij[2]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[0][1]=(-dis_ij[0]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[0]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[1][1]=(-dis_ij[1]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[1]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ dcA_ijk[2][1]=(-dis_ij[2]*r_ij*r_jk-cosAng_ijk
+ *dis_jk[2]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+ nb_jk=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_jk].i=j;
+ bt_pi[nb_jk].j=k;
+ bt_pi[nb_jk].temp=temp_jk;
+ cosSq=cosAng_ijk*cosAng_ijk;
+ sinFactor=.5*(1.0-cosSq)*pi_p[jtype-1]*betaS_jk;
+ cosFactor=.5*(1.0+cosSq)*betaP_jk;
+ betaCapSq1=pi_p[jtype-1]*betaS_jk*betaS_jk
+ -betaP_jk*betaP_jk;
+ dbetaCapSq1=2.0*pi_p[jtype-1]*betaS_jk*dBetaS_jk
+ -2.0*betaP_jk*dBetaP_jk;
+
+//AA is Eq. 37 (a) and Eq. 19 (b) for j atoms
+//3rd BB is 2nd term of Eq. 38 (a) where i and k =neighbors j
+
+ AA=AA+sinFactor*betaS_jk+cosFactor*betaP_jk;
+ BB=BB+.25*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*betaCapSq1;
+
+ agpdpr1=(2.0*sinFactor*dBetaS_jk+2.0*cosFactor
+ *dBetaP_jk)/r_jk;
+
+//agpdpr1 is derivative of AA for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB for atom j w.r.t. Beta(r_jk)
+//app1 is derivative of AA for j atom w.r.t. cos(theta_ijk)
+//app2 is derivative of BB 2nd term w.r.t. cos(theta_ijk)
+
+ agpdpr2=.5*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*dbetaCapSq1/r_jk;
+ app1=cosAng_ijk*(-pi_p[jtype-1]*betaS_jk*betaS_jk
+ +betaP_jk*betaP_jk);
+ app2=-(1.0-cosSq)*cosAng_ijk*betaCapSq1*betaCapSq1;
+ bt_pi[nb_ij].dAA[0]-=
+ app1*dcA_ijk[0][0];
+ bt_pi[nb_ij].dAA[1]-=
+ app1*dcA_ijk[1][0];
+ bt_pi[nb_ij].dAA[2]-=
+ app1*dcA_ijk[2][0];
+ bt_pi[nb_ij].dBB[0]-=
+ app2*dcA_ijk[0][0];
+ bt_pi[nb_ij].dBB[1]-=
+ app2*dcA_ijk[1][0];
+ bt_pi[nb_ij].dBB[2]-=
+ app2*dcA_ijk[2][0];
+ bt_pi[nb_jk].dAA[0]+=
+ agpdpr1*dis_jk[0]
+ +app1*dcA_ijk[0][1];
+ bt_pi[nb_jk].dAA[1]+=
+ agpdpr1*dis_jk[1]
+ +app1*dcA_ijk[1][1];
+ bt_pi[nb_jk].dAA[2]+=
+ agpdpr1*dis_jk[2]
+ +app1*dcA_ijk[2][1];
+ bt_pi[nb_jk].dBB[0]+=
+ app2*dcA_ijk[0][1]
+ +agpdpr2*dis_jk[0];
+ bt_pi[nb_jk].dBB[1]+=
+ app2*dcA_ijk[1][1]
+ +agpdpr2*dis_jk[1];
+ bt_pi[nb_jk].dBB[2]+=
+ app2*dcA_ijk[2][1]
+ +agpdpr2*dis_jk[2];
+
+//j is a neighbor of i and k and k' are different neighbors of j not equal to i
+
+ for(ltmp=0;ltmp<ktmp;ltmp++) {
+ if(ltmp!=ki) {
+ temp_jkp=BOP_index[j]+ltmp;
+ kp=jlist[ltmp];
+ kptype=map[type[kp]]+1;
+ for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+ ncmp=itypePiBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(jtype==kptype)
+ ijkp=jtype-1;
+ else if(jtype<kptype)
+ ijkp=jtype*bop_types-jtype*(jtype+1)/2+kptype-1;
+ else
+ ijkp=kptype*bop_types-kptype*(kptype+1)/2+jtype-1;
+ dis_jkp[0]=x[kp][0]-x[j][0];
+ dis_jkp[1]=x[kp][1]-x[j][1];
+ dis_jkp[2]=x[kp][2]-x[j][2];
+ rsq_jkp=dis_jkp[0]*dis_jkp[0]
+ +dis_jkp[1]*dis_jkp[1]
+ +dis_jkp[2]*dis_jkp[2];
+ r_jkp=sqrt(rsq_jkp);
+ if(r_jkp<=rcut[ijkp]) {
+ ps=r_jkp*rdr[ijkp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+ +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+ dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+ +pBetaS4[ijkp][ks-1];
+ betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+ +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+ dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+ +pBetaP4[ijkp][ks-1];
+ cosAng_ijkp=(-dis_ij[0]*dis_jkp[0]-dis_ij[1]*dis_jkp[1]
+ -dis_ij[2]*dis_jkp[2])/(r_ij*r_jkp);
+ dcA_ijkp[0][0]=(dis_jkp[0]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[0]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[1][0]=(dis_jkp[1]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[1]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[2][0]=(dis_jkp[2]*r_ij*r_jkp-cosAng_ijkp
+ *-dis_ij[2]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[0][1]=(-dis_ij[0]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[0]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[1][1]=(-dis_ij[1]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[1]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ dcA_ijkp[2][1]=(-dis_ij[2]*r_ij*r_jkp-cosAng_ijkp
+ *dis_jkp[2]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+ cosAng_kjkp=(dis_jk[0]*dis_jkp[0]+dis_jk[1]*dis_jkp[1]
+ +dis_jk[2]*dis_jkp[2])/(r_jk*r_jkp);
+ dcA_kjkp[0][0]=(dis_jkp[0]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jk[0]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[1][0]=(dis_jkp[1]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jk[1]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[2][0]=(dis_jkp[2]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jk[2]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[0][1]=(dis_jk[0]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jkp[0]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[1][1]=(dis_jk[1]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jkp[1]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+ dcA_kjkp[2][1]=(dis_jk[2]*r_jk*r_jkp-cosAng_kjkp
+ *dis_jkp[2]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+ nb_jkp=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_jkp].i=j;
+ bt_pi[nb_jkp].j=kp;
+ bt_pi[nb_jkp].temp=temp_jkp;
+ betaCapSq2=pi_p[jtype-1]*betaS_jkp*betaS_jkp
+ -betaP_jkp*betaP_jkp;
+ dbetaCapSq2=2.0*pi_p[jtype-1]*betaS_jkp*dBetaS_jkp
+ -2.0*betaP_jkp*dBetaP_jkp;
+ cosSq1=cosAng_ijkp*cosAng_ijkp;
+ angFactor=cosAng_kjkp-cosAng_ijkp*cosAng_ijk;
+ angFactor1=4.0*angFactor;
+ angFactor2=-angFactor1*cosAng_ijkp
+ +2.0*cosAng_ijk*(1.0-cosSq1);
+ angFactor3=-angFactor1*cosAng_ijk
+ +2.0*cosAng_ijkp*(1.0-cosSq);
+ angFactor4=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+ betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//4th BB is 4th term of Eq. 38 (a) where i , k and k' =neighbors j
+
+ BB=BB+betaCapSum*angFactor4;
+
+//app1 is derivative of BB 4th term w.r.t. cos(theta_kjk')
+//app2 is derivative of BB 4th term w.r.t. cos(theta_ijk)
+//app3 is derivative of BB 4th term w.r.t. cos(theta_ijk')
+//agpdpr1 is derivative of BB 4th term for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB 4th term for atom j w.r.t. Beta(r_jk')
+
+ app1=betaCapSum*angFactor1;
+ app2=betaCapSum*angFactor2;
+ app3=betaCapSum*angFactor3;
+ agpdpr1=.5*angFactor4*dbetaCapSq1*betaCapSq2/r_jk;
+ agpdpr2=.5*angFactor4*betaCapSq1*dbetaCapSq2/r_jkp;
+ bt_pi[nb_ij].dBB[0]-=
+ app3*dcA_ijkp[0][0]
+ +app2*dcA_ijk[0][0];
+ bt_pi[nb_ij].dBB[1]-=
+ app3*dcA_ijkp[1][0]
+ +app2*dcA_ijk[1][0];
+ bt_pi[nb_ij].dBB[2]-=
+ app3*dcA_ijkp[2][0]
+ +app2*dcA_ijk[2][0];
+ bt_pi[nb_jk].dBB[0]+=
+ agpdpr1*dis_jk[0]
+ +app1*dcA_kjkp[0][0]
+ +app2*dcA_ijk[0][1];
+ bt_pi[nb_jk].dBB[1]+=
+ agpdpr1*dis_jk[1]
+ +app1*dcA_kjkp[1][0]
+ +app2*dcA_ijk[1][1];
+ bt_pi[nb_jk].dBB[2]+=
+ agpdpr1*dis_jk[2]
+ +app1*dcA_kjkp[2][0]
+ +app2*dcA_ijk[2][1];
+ bt_pi[nb_jkp].dBB[0]+=
+ agpdpr2*dis_jkp[0]
+ +app1*dcA_kjkp[0][1]
+ +app3*dcA_ijkp[0][1];
+ bt_pi[nb_jkp].dBB[1]+=
+ agpdpr2*dis_jkp[1]
+ +app1*dcA_kjkp[1][1]
+ +app3*dcA_ijkp[1][1];
+ bt_pi[nb_jkp].dBB[2]+=
+ agpdpr2*dis_jkp[2]
+ +app1*dcA_kjkp[2][1]
+ +app3*dcA_ijkp[2][1];
+ }
+ }
+ }
+
+//j and k' are different neighbors of i and k is a neighbor of j not equal to i
+
+ for(ltmp=0;ltmp<numneigh[i];ltmp++) {
+ if(ltmp!=jtmp) {
+ temp_ikp=BOP_index[i]+ltmp;
+ kp=iilist[ltmp];
+ kptype=map[type[kp]]+1;
+ for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+ ncmp=itypePiBk[n][nsearch];
+ if(x[ncmp][0]==x[kp][0]) {
+ if(x[ncmp][1]==x[kp][1]) {
+ if(x[ncmp][2]==x[kp][2]) {
+ break;
+ }
+ }
+ }
+ }
+ if(itype==kptype)
+ iikp=itype-1;
+ else if(itype<kptype)
+ iikp=itype*bop_types-itype*(itype+1)/2+kptype-1;
+ else
+ iikp=kptype*bop_types-kptype*(kptype+1)/2+itype-1;
+ dis_ikp[0]=x[kp][0]-x[i][0];
+ dis_ikp[1]=x[kp][1]-x[i][1];
+ dis_ikp[2]=x[kp][2]-x[i][2];
+ rsq_ikp=dis_ikp[0]*dis_ikp[0]
+ +dis_ikp[1]*dis_ikp[1]
+ +dis_ikp[2]*dis_ikp[2];
+ r_ikp=sqrt(rsq_ikp);
+ if(r_ikp<=rcut[iikp]) {
+ ps=r_ikp*rdr[iikp]+1.0;
+ ks=(int)ps;
+ if(nr-1<ks)
+ ks=nr-1;
+ ps=ps-ks;
+ if(ps>1.0)
+ ps=1.0;
+ betaS_ikp=((pBetaS3[iikp][ks-1]*ps+pBetaS2[iikp][ks-1])*ps
+ +pBetaS1[iikp][ks-1])*ps+pBetaS[iikp][ks-1];
+ dBetaS_ikp=(pBetaS6[iikp][ks-1]*ps+pBetaS5[iikp][ks-1])*ps
+ +pBetaS4[iikp][ks-1];
+ betaP_ikp=((pBetaP3[iikp][ks-1]*ps+pBetaP2[iikp][ks-1])*ps
+ +pBetaP1[iikp][ks-1])*ps+pBetaP[iikp][ks-1];
+ dBetaP_ikp=(pBetaP6[iikp][ks-1]*ps+pBetaP5[iikp][ks-1])*ps
+ +pBetaP4[iikp][ks-1];
+ cosAng_jikp=(dis_ij[0]*dis_ikp[0]+dis_ij[1]*dis_ikp[1]
+ +dis_ij[2]*dis_ikp[2])/(r_ij*r_ikp);
+ dcA_jikp[0][0]=(dis_ikp[0]*r_ij*r_ikp-cosAng_jikp
+ *dis_ij[0]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[1][0]=(dis_ikp[1]*r_ij*r_ikp-cosAng_jikp
+ *dis_ij[1]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[2][0]=(dis_ikp[2]*r_ij*r_ikp-cosAng_jikp
+ *dis_ij[2]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[0][1]=(dis_ij[0]*r_ij*r_ikp-cosAng_jikp
+ *dis_ikp[0]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[1][1]=(dis_ij[1]*r_ij*r_ikp-cosAng_jikp
+ *dis_ikp[1]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+ dcA_jikp[2][1]=(dis_ij[2]*r_ij*r_ikp-cosAng_jikp
+ *dis_ikp[2]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+ nb_ikp=nb_t;
+ nb_t++;
+ if(nb_t>nb_pi) {
+ new_n_tot=nb_pi+maxneigh;
+ grow_pi(nb_pi,new_n_tot);
+ nb_pi=new_n_tot;
+ }
+ bt_pi[nb_ikp].i=i;
+ bt_pi[nb_ikp].j=kp;
+ bt_pi[nb_ikp].temp=temp_ikp;
+
+ betaCapSq2=pi_p[itype-1]*betaS_ikp*betaS_ikp
+ -betaP_ikp*betaP_ikp;
+ dbetaCapSq2=2.0*pi_p[itype-1]*betaS_ikp*dBetaS_ikp
+ -2.0*betaP_ikp*dBetaP_ikp;
+ dotV=(dis_jk[0]*dis_ikp[0]+dis_jk[1]
+ *dis_ikp[1]+dis_jk[2]*dis_ikp[2])
+ /(r_jk*r_ikp);
+ cosSq1=cosAng_jikp*cosAng_jikp;
+ angFactor=dotV+cosAng_jikp*cosAng_ijk;
+ angRfactor=4.0*angFactor*dotV;
+ dAngR1=-angRfactor/r_jk;
+ dAngR2=-angRfactor/r_ikp;
+ angFactor1=4.0*angFactor*cosAng_jikp
+ +2.0*cosAng_ijk*(1.0-cosSq1);
+ angFactor2=4.0*angFactor*cosAng_ijk
+ +2.0*cosAng_jikp*(1.0-cosSq);
+ angFactor3=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+ betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//5th BB is 5th term of Eq. 38 (a) Eq. 21 (b) where i , k and k' =neighbors j
+
+ BB=BB+betaCapSum*angFactor3;
+
+//app1 is derivative of BB 5th term w.r.t. cos(theta_ijk)
+//app2 is derivative of BB 5th term w.r.t. cos(theta_jik')
+//agpdpr1 is derivative of BB 5th term for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB 5th term for atom j w.r.t. Beta(r_ik')
+//agpdpr3 is derivative of BB 5th term for atom j w.r.t. dot(r_ik',r_ij)
+
+ app1=betaCapSum*angFactor1;
+ app2=betaCapSum*angFactor2;
+ agpdpr1=(.5*angFactor3*dbetaCapSq1*betaCapSq2
+ +betaCapSum*dAngR1)/r_jk;
+ agpdpr2=(.5*angFactor3*betaCapSq1*dbetaCapSq2
+ +betaCapSum*dAngR2)/r_ikp;
+ agpdpr3=4.0*betaCapSum*angFactor/(r_ikp*r_jk);
+ bt_pi[nb_ij].dBB[0]+=
+ +app2*dcA_jikp[0][0]
+ -app1*dcA_ijk[0][0];
+ bt_pi[nb_ij].dBB[1]+=
+ +app2*dcA_jikp[1][0]
+ -app1*dcA_ijk[1][0];
+ bt_pi[nb_ij].dBB[2]+=
+ +app2*dcA_jikp[2][0]
+ -app1*dcA_ijk[2][0];
+ bt_pi[nb_ikp].dBB[0]+=
+ agpdpr2*dis_ikp[0]
+ +agpdpr3*dis_jk[0]
+ +app2*dcA_jikp[0][1];
+ bt_pi[nb_ikp].dBB[1]+=
+ agpdpr2*dis_ikp[1]
+ +agpdpr3*dis_jk[1]
+ +app2*dcA_jikp[1][1];
+ bt_pi[nb_ikp].dBB[2]+=
+ agpdpr2*dis_ikp[2]
+ +agpdpr3*dis_jk[2]
+ +app2*dcA_jikp[2][1];
+ bt_pi[nb_jk].dBB[0]+=
+ agpdpr1*dis_jk[0]
+ +agpdpr3*dis_ikp[0]
+ +app1*dcA_ijk[0][1];
+ bt_pi[nb_jk].dBB[1]+=
+ agpdpr1*dis_jk[1]
+ +agpdpr3*dis_ikp[1]
+ +app1*dcA_ijk[1][1];
+ bt_pi[nb_jk].dBB[2]+=
+ agpdpr1*dis_jk[2]
+ +agpdpr3*dis_ikp[2]
+ +app1*dcA_ijk[2][1];
+ }
+ }
+ }
+ if(pi_flag==0)
+ nPiBk[n]=nPiBk[n]+1;
+ }
+ }
+ }
+ CC=betaP_ij*betaP_ij+pi_delta[iij]*pi_delta[iij];
+ BBrt=sqrt(BB+small6);
+ AB1=CC+pi_c[iij]*(AA+BBrt)+small7;
+ AB2=CC+pi_c[iij]*(AA-BBrt+sqrt(small6))+small7;
+ BBrtR=1.0/BBrt;
+ ABrtR1=1.0/sqrt(AB1);
+ ABrtR2=1.0/sqrt(AB2);
+
+// piB is similary formulation to (a) Eq. 36 and (b) Eq. 18
+
+ piB[n]=(ABrtR1+ABrtR2)*pi_a[iij]*betaP_ij;
+ dPiB1=-.5*(pow(ABrtR1,3)+pow(ABrtR2,3))*pi_c[iij]*pi_a[iij]*betaP_ij;
+ dPiB2=.25*BBrtR*(pow(ABrtR2,3)-pow(ABrtR1,3))*pi_c[iij]*pi_a[iij]*betaP_ij;
+ dPiB3=((ABrtR1+ABrtR2)*pi_a[iij]-(pow(ABrtR1,3)+pow(ABrtR2,3))*pi_a[iij]
+ *betaP_ij*betaP_ij)*dBetaP_ij/r_ij;
+ n++;
+
+ pp2=2.0*betaP_ij;
+ for(m=0;m<nb_t;m++) {
+ bt_i=bt_pi[m].i;
+ bt_j=bt_pi[m].j;
+ xtmp[0]=x[bt_j][0]-x[bt_i][0];
+ xtmp[1]=x[bt_j][1]-x[bt_i][1];
+ xtmp[2]=x[bt_j][2]-x[bt_i][2];
+ for(pp=0;pp<3;pp++) {
+ bt_pi[m].dPiB[pp]=
+ +dPiB1*bt_pi[m].dAA[pp]
+ +dPiB2*bt_pi[m].dBB[pp];
+ ftmp[pp]=pp2*bt_pi[m].dPiB[pp];
+ f[bt_i][pp]-=ftmp[pp];
+ f[bt_j][pp]+=ftmp[pp];
+ }
+ if(evflag) {
+ ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+ ,ftmp[2],xtmp[0],xtmp[1],xtmp[2]);
+ }
+ }
+ for(pp=0;pp<3;pp++) {
+ ftmp[pp]=pp2*dPiB3*dis_ij[pp];
+ f[i][pp]-=ftmp[pp];
+ f[j][pp]+=ftmp[pp];
+ }
+ if(evflag) {
+ ev_tally_xyz(i,j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+ ,ftmp[2],dis_ij[0],dis_ij[1],dis_ij[2]);
+ }
+ }
+ }
+ }
+ }
+ destroy_pi();
+}
+
+/* ----------------------------------------------------------------------
+ read BOP potential file
+------------------------------------------------------------------------- */
+
+void PairBOP::read_file(char *filename)
+{
+ int i,j,k;
+ int ij,ii,jj;
+ int buf1;
+ int n;
+ double buf2;
+ char s[MAXLINE];
+ char buf[2];
+
+ MPI_Comm_rank(world,&me);
+
+// read file on proc 0
+
+ rcore=0.1;
+
+ if (me == 0) {
+ FILE *fp = fopen(filename,"r");
+ if (fp == NULL) {
+ char str[128];
+ sprintf(str,"Cannot open BOP potential file %s",filename);
+ error->one(FLERR,str);
+ }
+
+// read parameters
+
+ fgets(s,MAXLINE,fp);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%d",&bop_types);
+ fclose(fp);
+ npairs=bop_types*(bop_types+1)/2;
+ }
+ MPI_Bcast(&bop_types,1,MPI_INT,0,world);
+ MPI_Bcast(&npairs,1,MPI_INT,0,world);
+ allocate();
+ memory->create(pi_a,npairs,"BOP:pi_a");
+ memory->create(pro_delta,bop_types,"BOP:pro_delta");
+ memory->create(pi_delta,npairs,"BOP:pi_delta");
+ memory->create(pi_p,bop_types,"BOP:pi_p");
+ memory->create(pi_c,npairs,"BOP:pi_c");
+ memory->create(sigma_r0,npairs,"BOP:sigma_r0");
+ memory->create(pi_r0,npairs,"BOP:pi_r0");
+ memory->create(phi_r0,npairs,"BOP:phi_r0");
+ memory->create(sigma_rc,npairs,"BOP:sigma_rc");
+ memory->create(pi_rc,npairs,"BOP:pi_rc");
+ memory->create(phi_rc,npairs,"BOP:phi_rc");
+ memory->create(r1,npairs,"BOP:r1");
+ memory->create(sigma_beta0,npairs,"BOP:sigma_beta0");
+ memory->create(pi_beta0,npairs,"BOP:pi_beta0");
+ memory->create(phi0,npairs,"BOP:phi0");
+ memory->create(sigma_n,npairs,"BOP:sigma_n");
+ memory->create(pi_n,npairs,"BOP:pi_n");
+ memory->create(phi_m,npairs,"BOP:phi_m");
+ memory->create(sigma_nc,npairs,"BOP:sigma_nc");
+ memory->create(pi_nc,npairs,"BOP:pi_nc");
+ memory->create(phi_nc,npairs,"BOP:phi_nc");
+ memory->create(pro,bop_types,"BOP:pro");
+ memory->create(sigma_delta,npairs,"BOP:sigma_delta");
+ memory->create(sigma_c,npairs,"BOP:sigma_c");
+ memory->create(sigma_a,npairs,"BOP:sigma_a");
+ memory->create(sigma_g0,bop_types
+ ,bop_types,bop_types,"BOP:sigma_g0");
+ memory->create(sigma_g1,bop_types
+ ,bop_types,bop_types,"BOP:sigma_g1");
+ memory->create(sigma_g2,bop_types
+ ,bop_types,bop_types,"BOP:sigma_g2");
+ memory->create(sigma_g3,bop_types
+ ,bop_types,bop_types,"BOP:sigma_g3");
+ memory->create(sigma_g4,bop_types
+ ,bop_types,bop_types,"BOP:sigma_g4");
+ memory->create(sigma_f,npairs,"BOP:sigma_f");
+ memory->create(sigma_k,npairs,"BOP:sigma_k");
+ memory->create(small3,npairs,"BOP:small3");
+
+ if (me == 0) {
+ words = new char*[bop_types];
+ for(i=0;i<bop_types;i++) words[i]=NULL;
+ FILE *fp = fopen(filename,"r");
+ if (fp == NULL) {
+ char str[128];
+ sprintf(str,"Cannot open BOP potential file %s",filename);
+ error->one(FLERR,str);
+ }
+ fgets(s,MAXLINE,fp);
+ fgets(s,MAXLINE,fp);
+ for(i=0;i<bop_types;i++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%d %lf %s",&buf1,&buf2,buf);
+ n= strlen(buf)+1;
+ words[i] = new char[n];
+ strcpy(words[i],buf);
+ }
+ fgets(s,MAXLINE,fp);
+ fgets(s,MAXLINE,fp);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf%lf%lf%lf%lf",&small1,&small2,&small3g,&small4
+ ,&small5,&small6,&small7);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%d%lf%lf",&ncutoff,&rbig,&rsmall);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%d",&which,&alpha,&nfunc);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf",&alpha1,&beta1,&gamma1);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf",&alpha2,&beta2);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf",&alpha3,&beta3);
+ fgets(s,MAXLINE,fp);
+ fgets(s,MAXLINE,fp);
+ for(i=0;i<bop_types;i++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf",&pro[i],&pro_delta[i],&pi_p[i]);
+ }
+ fgets(s,MAXLINE,fp);
+ fgets(s,MAXLINE,fp);
+ cutmax=0;
+
+ for(i=0;i<bop_types;i++) {
+ ii=i+1;
+ for(j=i;j<bop_types;j++) {
+ jj=j+1;
+ if(ii==jj)
+ ij=ii-1;
+ else if(ii<jj)
+ ij=ii*bop_types-ii*(ii+1)/2+jj-1;
+ else
+ ij=jj*bop_types-jj*(jj+1)/2+ii-1;
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf%lf",&sigma_r0[ij],&sigma_rc[ij],&r1[ij],&rcut[ij]);
+ if(rcut[ij]>cutmax)
+ cutmax=rcut[ij];
+ pi_r0[ij]=sigma_r0[ij];
+ phi_r0[ij]=sigma_r0[ij];
+ pi_rc[ij]=sigma_rc[ij];
+ phi_rc[ij]=sigma_rc[ij];
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf",&phi_m[ij],&sigma_n[ij],&sigma_nc[ij]);
+ pi_n[ij]=sigma_n[ij];
+ pi_nc[ij]=sigma_nc[ij];
+ phi_nc[ij]=sigma_nc[ij];
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf",&phi0[ij],&sigma_beta0[ij],&pi_beta0[ij]);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf",&sigma_a[ij],&sigma_c[ij],&sigma_delta[ij]);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf",&pi_a[ij],&pi_c[ij],&pi_delta[ij]);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf",&sigma_f[ij],&sigma_k[ij],&small3[ij]);
+ }
+ }
+ fgets(s,MAXLINE,fp);
+ fgets(s,MAXLINE,fp);
+ for(i=0;i<bop_types;i++) {
+ for(j=0;j<bop_types;j++) {
+ for(k=j;k<bop_types;k++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf",&sigma_g0[j][i][k],&sigma_g1[j][i][k]
+ ,&sigma_g2[j][i][k]);
+ sigma_g0[k][i][j]=sigma_g0[j][i][k];
+ sigma_g1[k][i][j]=sigma_g1[j][i][k];
+ sigma_g2[k][i][j]=sigma_g2[j][i][k];
+ }
+ }
+ }
+ for(i=0;i<npairs;i++) {
+ dr[i]=rcut[i]/(nr-1.0);
+ rdr[i]=1.0/dr[i];
+ }
+ fclose(fp);
+ }
+ MPI_Bcast(&small1,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small2,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small3g,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small4,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small5,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small6,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small7,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&ncutoff,1,MPI_INT,0,world);
+ MPI_Bcast(&rbig,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&rsmall,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&which,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&alpha,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&nfunc,1,MPI_INT,0,world);
+ MPI_Bcast(&alpha1,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&beta1,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&gamma1,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&alpha2,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&beta2,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&alpha3,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&beta3,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pro[0],bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pro_delta[0],bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_p[0],bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_r0[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_rc[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&r1[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&rcut[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cutmax,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_r0[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&phi_r0[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_rc[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&phi_rc[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&phi_m[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_n[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_nc[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_n[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_nc[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&phi_nc[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&phi0[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_beta0[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_beta0[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_a[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_c[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_delta[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_a[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_c[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_delta[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_f[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_k[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small3[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_g0[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_g1[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_g2[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_g3[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_g4[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&dr[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&rdr[0],npairs,MPI_DOUBLE,0,world);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::read_table(char *filename)
+{
+ int i,j,k,n;
+ int buf1;
+ double buf2;
+ char s[MAXLINE],buf[2];
+
+ MPI_Comm_rank(world,&me);
+
+ if (me == 0) {
+ FILE *fp = fopen(filename,"r");
+ if (fp == NULL) {
+ char str[128];
+ sprintf(str,"Cannot open BOP potential file %s",filename);
+ error->one(FLERR,str);
+ }
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%d",&bop_types);
+ words = new char*[bop_types];
+ for(i=0;i<bop_types;i++) words[i]=NULL;
+ for(i=0;i<bop_types;i++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%d %lf %s",&buf1,&buf2,buf);
+ n= strlen(buf)+1;
+ words[i] = new char[n];
+ strcpy(words[i],buf);
+ }
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%d %d",&nr,&nBOt);
+ fclose(fp);
+ npairs=bop_types*(bop_types+1)/2;
+ }
+
+ MPI_Bcast(&nr,1,MPI_INT,0,world);
+ MPI_Bcast(&nBOt,1,MPI_INT,0,world);
+ MPI_Bcast(&bop_types,1,MPI_INT,0,world);
+ MPI_Bcast(&npairs,1,MPI_INT,0,world);
+ memory->create(pi_a,npairs,"BOP:pi_a");
+ memory->create(pro_delta,bop_types,"BOP:pro_delta");
+ memory->create(pi_delta,npairs,"BOP:pi_delta");
+ memory->create(pi_p,bop_types,"BOP:pi_p");
+ memory->create(pi_c,npairs,"BOP:pi_c");
+ memory->create(r1,npairs,"BOP:r1");
+ memory->create(pro,bop_types,"BOP:pro");
+ memory->create(sigma_delta,npairs,"BOP:sigma_delta");
+ memory->create(sigma_c,npairs,"BOP:sigma_c");
+ memory->create(sigma_a,npairs,"BOP:sigma_a");
+ memory->create(sigma_g0,bop_types
+ ,bop_types,bop_types,"BOP:sigma_g0");
+ memory->create(sigma_g1,bop_types
+ ,bop_types,bop_types,"BOP:sigma_g1");
+ memory->create(sigma_g2,bop_types
+ ,bop_types,bop_types,"BOP:sigma_g2");
+ memory->create(sigma_f,npairs,"BOP:sigma_f");
+ memory->create(sigma_k,npairs,"BOP:sigma_k");
+ memory->create(small3,npairs,"BOP:small3");
+ allocate();
+
+ if (me == 0) {
+ FILE *fp = fopen(filename,"r");
+ if (fp == NULL) {
+ char str[128];
+ sprintf(str,"Cannot open BOP potential file %s",filename);
+ error->one(FLERR,str);
+ }
+ for(i=0;i<bop_types+2;i++) {
+ fgets(s,MAXLINE,fp);
+ }
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf%lf%lf%lf%lf",&small1,&small2,&small3g
+ ,&small4,&small5,&small6,&small7);
+ for(i=0;i<bop_types;i++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf",&pi_p[i]);
+ }
+ cutmax=0;
+ for(i=0;i<npairs;i++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf",&rcut[i]);
+ if(rcut[i]>cutmax)
+ cutmax=rcut[i];
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf%lf",&sigma_c[i],&sigma_a[i],&pi_c[i],&pi_a[i]);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf",&sigma_delta[i],&pi_delta[i]);
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf",&sigma_f[i],&sigma_k[i],&small3[i]);
+ }
+ for(i=0;i<bop_types;i++)
+ for(j=0;j<bop_types;j++)
+ for(k=0;k<bop_types;k++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf",&sigma_g0[i][j][k],&sigma_g1[i][j][k],&sigma_g2[i][j][k]);
+ }
+ for(i=0;i<npairs;i++) {
+ for(j=0;j<nr;j++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf%lf%lf",&pRepul[i][j],&pRepul[i][j+1]
+ ,&pRepul[i][j+2],&pRepul[i][j+3],&pRepul[i][j+4]);
+ j+=4;
+ }
+ }
+ for(i=0;i<npairs;i++) {
+ for(j=0;j<nr;j++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf%lf%lf",&pBetaS[i][j],&pBetaS[i][j+1]
+ ,&pBetaS[i][j+2],&pBetaS[i][j+3],&pBetaS[i][j+4]);
+ j+=4;
+ }
+ }
+ for(i=0;i<npairs;i++) {
+ for(j=0;j<nr;j++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf%lf%lf",&pBetaP[i][j],&pBetaP[i][j+1]
+ ,&pBetaP[i][j+2],&pBetaP[i][j+3],&pBetaP[i][j+4]);
+ j+=4;
+ }
+ }
+ for(i=0;i<npairs;i++) {
+ for(j=0;j<nBOt;j++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf%lf%lf%lf%lf",&FsigBO[i][j],&FsigBO[i][j+1]
+ ,&FsigBO[i][j+2],&FsigBO[i][j+3],&FsigBO[i][j+4]);
+ j+=4;
+ }
+ }
+ for(i=0;i<bop_types;i++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf",&pro_delta[i]);
+ }
+ for(i=0;i<bop_types;i++) {
+ fgets(s,MAXLINE,fp);
+ sscanf(s,"%lf",&pro[i]);
+ }
+ for(i=0;i<npairs;i++) {
+ dr[i]=rcut[i]/((double)nr-1.0);
+ rdr[i]=1.0/dr[i];
+ }
+ dBO=1.0/((double)nBOt-1.0);
+ rdBO=1.0/(double)dBO;
+
+ for(i=0;i<npairs;i++) {
+ pBetaS1[i][0]=pBetaS[i][1]-pBetaS[i][0];
+ pBetaS1[i][1]=0.5*(pBetaS[i][2]-pBetaS[i][0]);
+ pBetaS1[i][nr-2]=0.5*(pBetaS[i][nr-1]-pBetaS[i][nr-3]);
+ pBetaS1[i][nr-1]=pBetaS[i][nr-1]-pBetaS[i][nr-2];
+ pBetaP1[i][0]=pBetaP[i][1]-pBetaP[i][0];
+ pBetaP1[i][1]=0.5*(pBetaP[i][2]-pBetaP[i][0]);
+ pBetaP1[i][nr-2]=0.5*(pBetaP[i][nr-1]-pBetaP[i][nr-3]);
+ pBetaP1[i][nr-1]=pBetaP[i][nr-1]-pBetaP[i][nr-2];
+ pRepul1[i][0]=pRepul[i][1]-pRepul[i][0];
+ pRepul1[i][1]=0.5*(pRepul[i][2]-pRepul[i][0]);
+ pRepul1[i][nr-2]=0.5*(pRepul[i][nr-1]-pRepul[i][nr-3]);
+ pRepul1[i][nr-1]=pRepul[i][nr-1]-pRepul[i][nr-2];
+ FsigBO1[i][0]=FsigBO[i][1]-FsigBO[i][0];
+ FsigBO1[i][1]=0.5*(FsigBO[i][2]-FsigBO[i][0]);
+ FsigBO1[i][nBOt-2]=0.5*(FsigBO[i][nBOt-1]-FsigBO[i][nBOt-3]);
+ FsigBO1[i][nBOt-1]=FsigBO[i][nBOt-1]-FsigBO[i][nBOt-2];
+ for(k=2;k<nr-2;k++) {
+ pBetaS1[i][k]=((pBetaS[i][k-2]-pBetaS[i][k+2])
+ +8.0*(pBetaS[i][k+1]-pBetaS[i][k-1]))/12.0;
+ pBetaP1[i][k]=((pBetaP[i][k-2]-pBetaP[i][k+2])
+ +8.0*(pBetaP[i][k+1]-pBetaP[i][k-1]))/12.0;
+ pRepul1[i][k]=((pRepul[i][k-2]-pRepul[i][k+2])
+ +8.0*(pRepul[i][k+1]-pRepul[i][k-1]))/12.0;
+ }
+ for(k=2;k<nr-2;k++) {
+ FsigBO1[i][k]=((FsigBO[i][k-2]-FsigBO[i][k+2])
+ +8.0*(FsigBO[i][k+1]-FsigBO[i][k-1]))/12.0;
+ }
+ for(k=0;k<nr-1;k++) {
+ pBetaS2[i][k]=3.0*(pBetaS[i][k+1]-pBetaS[i][k])
+ -2.0*pBetaS1[i][k]-pBetaS1[i][k+1];
+ pBetaS3[i][k]=pBetaS1[i][k]+pBetaS1[i][k+1]
+ -2.0*(pBetaS[i][k+1]-pBetaS[i][k]);
+ pBetaP2[i][k]=3.0*(pBetaP[i][k+1]-pBetaP[i][k])
+ -2.0*pBetaP1[i][k]-pBetaP1[i][k+1];
+ pBetaP3[i][k]=pBetaP1[i][k]+pBetaP1[i][k+1]
+ -2.0*(pBetaP[i][k+1]-pBetaP[i][k]);
+ pRepul2[i][k]=3.0*(pRepul[i][k+1]-pRepul[i][k])
+ -2.0*pRepul1[i][k]-pRepul1[i][k+1];
+ pRepul3[i][k]=pRepul1[i][k]+pRepul1[i][k+1]
+ -2.0*(pRepul[i][k+1]-pRepul[i][k]);
+ }
+ for(k=0;k<nBOt-1;k++) {
+ FsigBO2[i][k]=3.0*(FsigBO[i][k+1]-FsigBO[i][k])
+ -2.0*FsigBO1[i][k]-FsigBO1[i][k+1];
+ FsigBO3[i][k]=FsigBO1[i][k]+FsigBO1[i][k+1]
+ -2.0*(FsigBO[i][k+1]-FsigBO[i][k]);
+ }
+ pBetaS2[i][nr-1]=0.0;
+ pBetaS3[i][nr-1]=0.0;
+ pBetaP2[i][nr-1]=0.0;
+ pBetaP3[i][nr-1]=0.0;
+ pRepul2[i][nr-1]=0.0;
+ pRepul3[i][nr-1]=0.0;
+ FsigBO2[i][nBOt-1]=0.0;
+ FsigBO3[i][nBOt-1]=0.0;
+ for(k=0;k<nr;k++) {
+ pBetaS4[i][k]=pBetaS1[i][k]/dr[i];
+ pBetaS5[i][k]=2.0*pBetaS2[i][k]/dr[i];
+ pBetaS6[i][k]=3.0*pBetaS3[i][k]/dr[i];
+ pBetaP4[i][k]=pBetaP1[i][k]/dr[i];
+ pBetaP5[i][k]=2.0*pBetaP2[i][k]/dr[i];
+ pBetaP6[i][k]=3.0*pBetaP3[i][k]/dr[i];
+ pRepul4[i][k]=pRepul1[i][k]/dr[i];
+ pRepul5[i][k]=2.0*pRepul2[i][k]/dr[i];
+ pRepul6[i][k]=3.0*pRepul3[i][k]/dr[i];
+ }
+ for(k=0;k<nBOt;k++) {
+ FsigBO4[i][k]=FsigBO1[i][k]/dBO;
+ FsigBO5[i][k]=2.0*FsigBO2[i][k]/dBO;
+ FsigBO6[i][k]=3.0*FsigBO3[i][k]/dBO;
+ }
+ }
+ fclose(fp);
+ }
+ MPI_Bcast(&rdBO,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&dBO,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&bop_types,1,MPI_INT,0,world);
+ MPI_Bcast(&small1,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small2,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small3g,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small4,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small5,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small6,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small7,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pro[0],bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pro_delta[0],bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_p[0],bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&r1[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&rcut[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&cutmax,1,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_a[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_c[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_delta[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_a[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_c[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pi_delta[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_f[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_k[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&small3[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_g0[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_g1[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&sigma_g2[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+ MPI_Bcast(&dr[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&rdr[0],npairs,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaS[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaS1[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaS2[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaS3[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaS4[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaS5[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaS6[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaP[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaP1[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaP2[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaP3[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaP4[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaP5[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pBetaP6[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pRepul[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pRepul1[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pRepul2[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pRepul3[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pRepul4[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pRepul5[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&pRepul6[0][0],npairs*nr,MPI_DOUBLE,0,world);
+ MPI_Bcast(&FsigBO[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+ MPI_Bcast(&FsigBO1[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+ MPI_Bcast(&FsigBO2[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+ MPI_Bcast(&FsigBO3[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+ MPI_Bcast(&FsigBO4[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+ MPI_Bcast(&FsigBO5[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+ MPI_Bcast(&FsigBO6[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::setPbetaS()
+{
+ int i,j,k;
+ double r,value,dvalue;
+
+ for(i=0;i<npairs;i++) {
+ for(j=0;j<nr;j++) {
+ r=(double)j*dr[i];
+ if(r<rcore)
+ r=rcore;
+ if(ncutoff==3) {
+ if(r>=rcut[i])
+ pBetaS[i][j]=0.0;
+ else if(r<=r1[i]) {
+ value=betaSfunc(i,r);
+ dvalue=dBetaSfunc(i,r,value,1.0);
+ pBetaS[i][j]=value;
+ }
+ else {
+ value=betaSfunc(i,r1[i]);
+ dvalue=dBetaSfunc(i,r1[i],value,1.0);
+ pBetaS[i][j]=-(r-rcut[i])*(r-rcut[i])*(value*(2.0*r-3.0*r1[i]+rcut[i])
+ -dvalue*(r-r1[i])*(r1[i]-rcut[i]))/((r1[i]-rcut[i])
+ *(r1[i]-rcut[i])*(r1[i]-rcut[i]));
+ }
+ }
+ else {
+ if(r>=rcut[i])
+ pBetaS[i][j]=0.0;
+ else {
+ value=betaSfunc(i,r);
+ dvalue=dBetaSfunc(i,r,value,0.0);
+ pBetaS[i][j]=value*cutoff(r1[i],rcut[i],ncutoff,r);
+ }
+ }
+ }
+ pBetaS[i][nr-1]=0.0;
+ pBetaS1[i][0]=pBetaS[i][1]-pBetaS[i][0];
+ pBetaS1[i][1]=0.5*(pBetaS[i][2]-pBetaS[i][0]);
+ pBetaS1[i][nr-2]=0.5*(pBetaS[i][nr-1]-pBetaS[i][nr-3]);
+ pBetaS1[i][nr-1]=pBetaS[i][nr-1]-pBetaS[i][nr-2];
+
+ for(k=2;k<nr-2;k++) {
+ pBetaS1[i][k]=((pBetaS[i][k-2]-pBetaS[i][k+2])+8.0*(pBetaS[i][k+1]
+ -pBetaS[i][k-1]))/12.0;
+ }
+ for(k=0;k<nr-1;k++) {
+ pBetaS2[i][k]=3.0*(pBetaS[i][k+1]-pBetaS[i][k])-2.0*pBetaS1[i][k]-pBetaS1[i][k+1];
+ pBetaS3[i][k]=pBetaS1[i][k]+pBetaS1[i][k+1]-2.0*(pBetaS[i][k+1]-pBetaS[i][k]);
+ }
+ pBetaS2[i][nr-1]=0.0;
+ pBetaS3[i][nr-1]=0.0;
+ for(k=0;k<nr;k++) {
+ pBetaS4[i][k]=pBetaS1[i][k]/dr[i];
+ pBetaS5[i][k]=2.0*pBetaS2[i][k]/dr[i];
+ pBetaS6[i][k]=3.0*pBetaS3[i][k]/dr[i];
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::setPbetaP()
+{
+ int i,j,k;
+ double r,value,dvalue;
+
+ for(i=0;i<npairs;i++) {
+ for(j=0;j<nr;j++) {
+ r=(double)j*dr[i];
+ if(r<rcore)
+ r=rcore;
+ if(ncutoff==3) {
+ if(r>=rcut[i])
+ pBetaP[i][j]=0.0;
+ else if(r<=r1[i]) {
+ value=betaPfunc(i,r);
+ dvalue=dBetaPfunc(i,r,value,0.0);
+ pBetaP[i][j]=value;
+ }
+ else {
+ value=betaPfunc(i,r1[i]);
+ dvalue=dBetaPfunc(i,r1[i],value,1.0);
+ pBetaP[i][j]=-(r-rcut[i])*(r-rcut[i])*(value*(2.0*r-3.0*r1[i]
+ +rcut[i])-dvalue*(r-r1[1])*(r1[i]-rcut[i]))/((r1[i]-rcut[i])
+ *(r1[i]-rcut[i])*(r1[i]-rcut[i]));
+ }
+ }
+ else {
+ if(r>=rcut[i])
+ pBetaP[i][j]=0.0;
+ else {
+ value=betaPfunc(i,r);
+ dvalue=dBetaPfunc(i,r,value,0.0);
+ pBetaP[i][j]=value*cutoff(r1[i],rcut[i],ncutoff,r);
+ }
+ }
+ }
+ pBetaP[i][nr-1]=0.0;
+ pBetaP1[i][0]=pBetaP[i][1]-pBetaP[i][0];
+ pBetaP1[i][1]=0.5*(pBetaP[i][2]-pBetaP[i][0]);
+ pBetaP1[i][nr-2]=0.5*(pBetaP[i][nr-1]-pBetaP[i][nr-3]);
+ pBetaP1[i][nr-1]=pBetaP[i][nr-1]-pBetaP[i][nr-2];
+ for(k=2;k<nr-2;k++)
+ pBetaP1[i][k]=((pBetaP[i][k-2]-pBetaP[i][k+2])+8.0*(pBetaP[i][k+1]
+ -pBetaP[i][k-1]))/12.0;
+ for(k=0;k<nr-1;k++) {
+ pBetaP2[i][k]=3.0*(pBetaP[i][k+1]-pBetaP[i][k])-2.0*pBetaP1[i][k]-pBetaP1[i][k+1];
+ pBetaP3[i][k]=pBetaP1[i][k]+pBetaP1[i][k+1]-2.0*(pBetaP[i][k+1]-pBetaP[i][k]);
+ }
+ pBetaP2[i][nr-1]=0.0;
+ pBetaP3[i][nr-1]=0.0;
+ for(k=0;k<nr;k++) {
+ pBetaP4[i][k]=pBetaP1[i][k]/dr[i];
+ pBetaP5[i][k]=2.0*pBetaP2[i][k]/dr[i];
+ pBetaP6[i][k]=3.0*pBetaP3[i][k]/dr[i];
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::setPrepul()
+{
+ int i,j,k;
+ double r,value,dvalue;
+
+ for(i=0;i<npairs;i++) {
+ for(j=0;j<nr;j++) {
+ r=(double)j*dr[i];
+ if(r<rcore)
+ r=rcore;
+ if(ncutoff==3) {
+ if(r>=rcut[i])
+ pRepul[i][j]=0.0;
+ else if(r<=r1[i]) {
+ value=repulfunc(i,r);
+ dvalue=dRepulfunc(i,r,value,0.0);
+ pRepul[i][j]=value;
+ }
+ else {
+ value=repulfunc(i,r1[i]);
+ dvalue=dRepulfunc(i,r1[i],value,1.0);
+ pRepul[i][j]=-(r-rcut[i])*(r-rcut[i])*(value*(2.0*r-3.0*r1[i]+rcut[i])
+ -dvalue*(r-r1[i])*(r1[i]-rcut[i]))/((r1[i]-rcut[i])
+ *(r1[i]-rcut[i])*(r1[i]-rcut[i]));
+ }
+ }
+ else {
+ if(r>=rcut[i])
+ pRepul[i][j]=0.0;
+ else {
+ value=repulfunc(i,r);
+ dvalue=dRepulfunc(i,r,value,0.0);
+ pRepul[i][j]=value*cutoff(r1[i],rcut[i],ncutoff,r);
+ }
+ }
+ }
+ pRepul[i][nr-1]=0.0;
+ pRepul1[i][0]=pRepul[i][1]-pRepul[i][0];
+ pRepul1[i][1]=0.5*(pRepul[i][2]-pRepul[i][0]);
+ pRepul1[i][nr-2]=0.5*(pRepul[i][nr-1]-pRepul[i][nr-3]);
+ pRepul1[i][nr-1]=pRepul[i][nr-1]-pRepul[i][nr-2];
+ for(k=2;k<nr-2;k++)
+ pRepul1[i][k]=((pRepul[i][k-2]-pRepul[i][k+2])+8.0*(pRepul[i][k+1]
+ -pRepul[i][k-1]))/12.0;
+ for(k=0;k<nr-1;k++) {
+ pRepul2[i][k]=3.0*(pRepul[i][k+1]-pRepul[i][k])-2.0*pRepul1[i][k]-pRepul1[i][k+1];
+ pRepul3[i][k]=pRepul1[i][k]+pRepul1[i][k+1]-2.0*(pRepul[i][k+1]-pRepul[i][k]);
+ }
+ pRepul2[i][nr-1]=0.0;
+ pRepul3[i][nr-1]=0.0;
+ for(k=0;k<nr;k++) {
+ pRepul4[i][k]=pRepul1[i][k]/dr[i];
+ pRepul5[i][k]=2.0*pRepul2[i][k]/dr[i];
+ pRepul6[i][k]=3.0*pRepul3[i][k]/dr[i];
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBOP::betaSfunc(int i,double r)
+{
+ double temp_value;
+
+ if(nfunc==1) {
+ temp_value=pow(sigma_r0[i]/r,sigma_n[i])*exp(sigma_n[i]*pow(sigma_r0[i]
+ /sigma_rc[i],sigma_nc[i])-sigma_n[i]*pow(r/sigma_rc[i],sigma_nc[i]));
+ temp_value=sigma_beta0[i]*temp_value;
+ }
+ if(nfunc==2)
+ temp_value=sigma_beta0[i]*exp(-sigma_n[i]*r);
+ if(nfunc==3)
+ temp_value=sigma_beta0[i]/pow(r,sigma_n[i]);
+ return(temp_value);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBOP::dBetaSfunc(int i,double r,double value,double dmore)
+{
+ double temp_dvalue;
+
+ if(nfunc==1)
+ if(dmore==1.0)
+ temp_dvalue=-sigma_n[i]*value/r*(1.0+sigma_nc[i]
+ *pow(r/sigma_rc[i],sigma_nc[i]));
+ if(nfunc==2)
+ if(dmore==1.0)
+ temp_dvalue=-sigma_n[i]*value;
+ if(nfunc==3)
+ if(dmore==1.0)
+ temp_dvalue=-sigma_n[i]*value/r;
+ return(temp_dvalue);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBOP::betaPfunc(int i,double r)
+{
+ double temp_value;
+
+ if(nfunc==1) {
+ temp_value=pow(pi_r0[i]/r,pi_n[i])*exp(pi_n[i]*pow(pi_r0[i]
+ /pi_rc[i],pi_nc[i])-pi_n[i]*pow(r/pi_rc[i],pi_nc[i]));
+ temp_value=pi_beta0[i]*temp_value;
+ }
+ if(nfunc==2)
+ temp_value=pi_beta0[i]*exp(-pi_n[i]*r);
+ if(nfunc==3)
+ temp_value=pi_beta0[i]/pow(r,pi_n[i]);
+ return(temp_value);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBOP::dBetaPfunc(int i,double r,double value,double dmore)
+{
+ double temp_dvalue;
+
+ if(nfunc==1)
+ if(dmore==1.0)
+ temp_dvalue=-pi_n[i]*value/r*(1.0+pi_nc[i]*pow(r/pi_rc[i],pi_nc[i]));
+ if(nfunc==2)
+ if(dmore==1.0)
+ temp_dvalue=-pi_n[i]*value;
+ if(nfunc==3)
+ if(dmore==1.0)
+ temp_dvalue=-pi_n[i]*value/r;
+ return(temp_dvalue);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBOP::repulfunc(int i,double r)
+{
+ double temp_value;
+
+ if(nfunc==1) {
+ temp_value=pow(phi_r0[i]/r,phi_m[i])*exp(phi_m[i]*pow(phi_r0[i]/phi_rc[i]
+ ,phi_nc[i])-phi_m[i]*pow(r/phi_rc[i],phi_nc[i]));
+ temp_value=phi0[i]*temp_value;
+ }
+ if(nfunc==2)
+ temp_value=phi0[i]*exp(-phi_m[i]*r);
+ if(nfunc==3)
+ temp_value=phi0[i]/pow(r,phi_m[i]);
+ return(temp_value);
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBOP::dRepulfunc(int i,double r,double value,double dmore)
+{
+ double temp_dvalue;
+
+ if(nfunc==1)
+ if(dmore==1.0)
+ temp_dvalue=-phi_m[i]*value/r*(1.0+phi_nc[i]*pow(r/phi_rc[i],phi_nc[i]));
+ if(nfunc==2)
+ if(dmore==1.0)
+ temp_dvalue=-phi_m[i]*value;
+ if(nfunc==3)
+ if(dmore==1.0)
+ temp_dvalue=-phi_m[i]*value/r;
+ return(temp_dvalue);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::setSign()
+{
+ int i,j,k;
+ double y0,tmp,xBO,fth,cs,bigF;
+ double epsilon,fsigma1,slope,sat;
+
+ dBO=1.0/(nBOt-1.0);
+ rdBO=1.0/dBO;
+ for(i=0;i<npairs;i++) {
+ for(j=0;j<nBOt;j++) {
+ xBO=(double)j*dBO;
+ if(which==1.0) {
+ fth=0.0;
+ if(xBO>alpha)
+ fth=4.0/3.0*(xBO-alpha);
+ if(sigma_f[i]<=fth)
+ FsigBO[i][j]=2.0*sigma_f[i];
+ else if(sigma_f[i]>=1.0-fth)
+ FsigBO[i][j]=2.0*(1.0-sigma_f[i]);
+ else {
+ cs=0.0;
+ if(xBO<alpha)
+ cs=32.0*(alpha-xBO);
+ bigF=(sigma_f[i]*(1.0-sigma_f[i])-fth*(1.0-fth))/pow(1.0-2.0*fth,2);
+ FsigBO[i][j]=2.0*fth+2.0*bigF*(1.0-2.0*fth)*(1.0+bigF*(1.0-cs*bigF));
+ }
+ }
+ else if(which==2.0) {
+ epsilon=0.0000000001;
+ fsigma1=sigma_f[i];
+ if(fsigma1>0.5)
+ fsigma1=1.0-fsigma1;
+ y0=alpha1*pow(fsigma1,beta1)*pow(0.5-fsigma1,gamma1);
+ slope=(1.0-exp(-alpha2*pow(fsigma1,beta2)))/(1.0-exp(-alpha2*pow(0.5,beta2)));
+ sat=alpha3*fsigma1+beta3;
+ tmp=y0+slope*xBO+sat;
+ FsigBO[i][j]=(tmp-sqrt(tmp*tmp-4.0*(-epsilon*sqrt(1.0+slope*slope)
+ +y0*sat+slope*sat*xBO)))/2.0;
+ }
+ }
+ FsigBO1[i][0]=FsigBO[i][1]-FsigBO[i][0];
+ FsigBO1[i][1]=0.5*(FsigBO[i][2]-FsigBO[i][0]);
+ FsigBO1[i][nBOt-2]=0.5*(FsigBO[i][nBOt-1]-FsigBO[i][nBOt-3]);
+ FsigBO1[i][nBOt-1]=FsigBO[i][nBOt-1]-FsigBO[i][nBOt-2];
+ for(k=2;k<nBOt-2;k++)
+ FsigBO1[i][k]=((FsigBO[i][k-2]-FsigBO[i][k+2])+8.0*(FsigBO[i][k+1]
+ -FsigBO[i][k-1]))/12.0;
+ for(k=0;k<nBOt-1;k++) {
+ FsigBO2[i][k]=3.0*(FsigBO[i][k+1]-FsigBO[i][k])-2.0*FsigBO1[i][k]-FsigBO1[i][k+1];
+ FsigBO3[i][k]=FsigBO1[i][k]+FsigBO1[i][k+1]-2.0*(FsigBO[i][k+1]-FsigBO[i][k]);
+ }
+ FsigBO2[i][nBOt-1]=0.0;
+ FsigBO3[i][nBOt-1]=0.0;
+ for(k=0;k<nBOt;k++) {
+ FsigBO4[i][k]=FsigBO1[i][k]/dBO;
+ FsigBO5[i][k]=2.0*FsigBO2[i][k]/dBO;
+ FsigBO6[i][k]=3.0*FsigBO3[i][k]/dBO;
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+
+double PairBOP::cutoff(double rp,double vrcut,int mode,double r)
+{
+ double tmp,tmp_beta,tmp_alpha,cut_store;
+
+ if(mode==1) {
+ tmp=(rsmall-rbig)*(r-rp)/(vrcut-rp)+rbig;
+ cut_store=(erfc(tmp)-erfc(rsmall))/(erfc(rbig)-erfc(rsmall));
+ }
+ else {
+ tmp_beta=log(log(rbig)/log(rsmall))/log(rp/vrcut);
+ tmp_alpha=-log(rbig)/pow(rp,tmp_beta);
+ cut_store=(exp(-tmp_alpha*pow(r,tmp_beta))-exp(-tmp_alpha*pow(vrcut
+ ,tmp_beta)))/(exp(-tmp_alpha*pow(rp,tmp_beta))-exp(-tmp_alpha
+ *pow(vrcut,tmp_beta)));
+ }
+ return(cut_store);
+}
+
+/* ----------------------------------------------------------------------
+ memory usage of local atom-based arrays
+------------------------------------------------------------------------- */
+
+double PairBOP::memory_usage()
+{
+ int nlocal,nghost,nall;
+ int n = atom->ntypes;
+ nlocal = atom->nlocal;
+ nghost = atom->nghost;
+ nall = nlocal + nghost;
+ double bytes = 0.0;
+
+// rcut
+ bytes += npairs * sizeof (double);
+// dr
+ bytes += npairs * sizeof (double);
+// rdr
+ bytes += npairs * sizeof (double);
+// setflag
+ bytes += (n+1) * (n+1) * sizeof (int);
+// cutsq
+ bytes += (n+1) * (n+1) * sizeof (double);
+// cutghost
+ bytes += (n+1) * (n+1) * sizeof (double);
+// cutghost
+ bytes += (n+1) * (n+1) * sizeof (double);
+// pBetaS
+ bytes += npairs * nr * sizeof (double);
+// pBetaS1
+ bytes += npairs * nr * sizeof (double);
+// pBetaS2
+ bytes += npairs * nr * sizeof (double);
+// pBetaS3
+ bytes += npairs * nr * sizeof (double);
+// pBetaS4
+ bytes += npairs * nr * sizeof (double);
+// pBetaS5
+ bytes += npairs * nr * sizeof (double);
+// pBetaS6
+ bytes += npairs * nr * sizeof (double);
+// pBetaP
+ bytes += npairs * nr * sizeof (double);
+// pBetaP1
+ bytes += npairs * nr * sizeof (double);
+// pBetaP2
+ bytes += npairs * nr * sizeof (double);
+// pBetaP3
+ bytes += npairs * nr * sizeof (double);
+// pBetaP4
+ bytes += npairs * nr * sizeof (double);
+// pBetaP5
+ bytes += npairs * nr * sizeof (double);
+// pBetaP6
+ bytes += npairs * nr * sizeof (double);
+// pRepul
+ bytes += npairs * nr * sizeof (double);
+// pRepul1
+ bytes += npairs * nr * sizeof (double);
+// pRepul2
+ bytes += npairs * nr * sizeof (double);
+// pRepul3
+ bytes += npairs * nr * sizeof (double);
+// pRepul4
+ bytes += npairs * nr * sizeof (double);
+// pRepul5
+ bytes += npairs * nr * sizeof (double);
+// pRepul6
+ bytes += npairs * nr * sizeof (double);
+// FsigBO
+ bytes += npairs * nr * sizeof (double);
+// FsigBO1
+ bytes += npairs * nr * sizeof (double);
+// FsigBO2
+ bytes += npairs * nr * sizeof (double);
+// FsigBO3
+ bytes += npairs * nr * sizeof (double);
+// FsigBO4
+ bytes += npairs * nr * sizeof (double);
+// FsigBO5
+ bytes += npairs * nr * sizeof (double);
+// FsigBO6
+ bytes += npairs * nr * sizeof (double);
+// itypeSigBk
+ bytes += neigh_total *neigh_ct* sizeof(int);
+// nSigBk
+ bytes += neigh_total * sizeof(int);
+// sigB
+ bytes += neigh_total * sizeof(int);
+// sigB1
+ bytes += neigh_total * sizeof(int);
+// nPiBk
+ bytes += neigh_total * sizeof(int);
+// piB
+ bytes += neigh_total * sizeof(int);
+// itypePiBk
+ bytes += neigh_total *neigh_ct* sizeof(int);
+// BOP_index
+ bytes += nall * sizeof(double);
+ if(otfly==0) {
+// cosAng
+ bytes += cos_total* sizeof(double);
+// dcAng
+ bytes += cos_total * 3 * 2 * sizeof(double);
+// disij
+ bytes += neigh_total * 3 * sizeof(double);
+// rij
+ bytes += neigh_total * sizeof(double);
+// betaS
+ bytes += neigh_total * sizeof(double);
+// dBetaS
+ bytes += neigh_total * sizeof(double);
+// betaP
+ bytes += neigh_total * sizeof(double);
+// dBetaP
+ bytes += neigh_total * sizeof(double);
+// repul
+ bytes += neigh_total * sizeof(double);
+// dRepul
+ bytes += neigh_total * sizeof(double);
+// cos_index
+ bytes += nall * sizeof(double);
+ }
+// pi_a
+ bytes += npairs * sizeof(double);
+// pro_delta
+ bytes += npairs * sizeof(double);
+// pi_delta
+ bytes += npairs * sizeof(double);
+// pi_p
+ bytes += npairs * sizeof(double);
+// pi_c
+ bytes += npairs * sizeof(double);
+// sigma_r0
+ bytes += npairs * sizeof(double);
+// pi_r0
+ bytes += npairs * sizeof(double);
+// phi_r0
+ bytes += npairs * sizeof(double);
+// sigma_rc
+ bytes += npairs * sizeof(double);
+// pi_rc
+ bytes += npairs * sizeof(double);
+// pi_a
+ bytes += npairs * sizeof(double);
+// pro_delta
+ bytes += npairs * sizeof(double);
+// pi_delta
+ bytes += npairs * sizeof(double);
+// pi_p
+ bytes += npairs * sizeof(double);
+// pi_c
+ bytes += npairs * sizeof(double);
+// sigma_r0
+ bytes += npairs * sizeof(double);
+// pi_r0
+ bytes += npairs * sizeof(double);
+// phi_r0
+ bytes += npairs * sizeof(double);
+// sigma_rc
+ bytes += npairs * sizeof(double);
+// pi_rc
+ bytes += npairs * sizeof(double);
+// phi_rc
+ bytes += npairs * sizeof(double);
+// r1
+ bytes += npairs * sizeof(double);
+// sigma_beta0
+ bytes += npairs * sizeof(double);
+// pi_beta0
+ bytes += npairs * sizeof(double);
+// phi0
+ bytes += npairs * sizeof(double);
+// sigma_n
+ bytes += npairs * sizeof(double);
+// pi_n
+ bytes += npairs * sizeof(double);
+// phi_m
+ bytes += npairs * sizeof(double);
+// sigma_nc
+ bytes += npairs * sizeof(double);
+// pi_nc
+ bytes += npairs * sizeof(double);
+// phi_nc
+ bytes += npairs * sizeof(double);
+// pro
+ bytes += npairs * sizeof(double);
+// sigma_delta
+ bytes += npairs * sizeof(double);
+// sigma_c
+ bytes += npairs * sizeof(double);
+// sigma_a
+ bytes += npairs * sizeof(double);
+// sigma_g0
+ bytes += bop_types * bop_types *bop_types * sizeof(double);
+// sigma_g1
+ bytes += bop_types * bop_types *bop_types * sizeof(double);
+// sigma_g2
+ bytes += bop_types * bop_types *bop_types * sizeof(double);
+// sigma_g3
+ bytes += bop_types * bop_types *bop_types * sizeof(double);
+// sigma_g4
+ bytes += bop_types * bop_types *bop_types * sizeof(double);
+// sigma_f
+ bytes += npairs * sizeof(double);
+// sigma_k
+ bytes += npairs * sizeof(double);
+// small3
+ bytes += npairs * sizeof(double);
+// bt_pi
+ bytes += maxneigh*(maxneigh/2) *sizeof(B_PI);
+// bt_sigma
+ bytes += maxneigh*(maxneigh/2) *sizeof(B_SG);
+
+ return bytes;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::memory_theta_create()
+{
+ int nlocal,nghost,nall;
+
+ nlocal = atom->nlocal;
+ nghost = atom->nghost;
+ nall = nlocal + nghost;
+ if(maxneigh<8)
+ neigh_ct=(maxneigh-1)*(maxneigh-1)*(maxneigh-1);
+ else
+ neigh_ct=(maxneigh-1)*(maxneigh-1);
+ memory->create(itypeSigBk,neigh_total
+ ,neigh_ct,"itypeSigBk");
+ memory->create(nSigBk,neigh_total,"nSigBk");
+ memory->create(sigB,neigh_total,"sigB");
+ memory->create(sigB1,neigh_total,"sigB1");
+ memory->create(itypePiBk,neigh_total
+ ,neigh_ct,"itypePiBk");
+ memory->create(nPiBk,neigh_total,"nPiBk");
+ memory->create(piB,neigh_total,"piB");
+ memory->create(neigh_flag,neigh_total,"neigh_flag");
+ if(otfly==0) {
+ memory->create(cosAng,cos_total,"BOP:cosAng");
+ memory->create(dcAng,cos_total*2,3,2,"BOP:dcAng");
+ memory->create(disij,3,neigh_total,"disij");
+ memory->create(rij,neigh_total,"rij");
+ memory->create(betaS,neigh_total,"betaS");
+ memory->create(dBetaS,neigh_total,"dBetaS");
+ memory->create(betaP,neigh_total,"betaP");
+ memory->create(dBetaP,neigh_total,"dBetaP");
+ memory->create(repul,neigh_total,"repul");
+ memory->create(dRepul,neigh_total,"dRepul");
+ }
+ update_list=1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::memory_theta_grow()
+{
+ int nlocal,nghost,nall;
+
+ nlocal = atom->nlocal;
+ nghost = atom->nghost;
+ nall = nlocal + nghost;
+ if(maxneigh<8)
+ neigh_ct=(maxneigh-1)*(maxneigh-1)*(maxneigh-1);
+ else
+ neigh_ct=(maxneigh-1)*(maxneigh-1);
+ memory->grow(itypeSigBk,neigh_total
+ ,neigh_ct,"itypeSigBk");
+ memory->grow(nSigBk,neigh_total,"nSigBk");
+ memory->grow(sigB,neigh_total,"sigB");
+ memory->grow(sigB1,neigh_total,"sigB1");
+ memory->grow(itypePiBk,neigh_total
+ ,neigh_ct,"itypePiBk");
+ memory->grow(nPiBk,neigh_total,"nPiBk");
+ memory->grow(piB,neigh_total,"piB");
+ memory->grow(neigh_flag,neigh_total,"neigh_flag");
+ if(otfly==0) {
+ memory->grow(cosAng,cos_total,"BOP:cosAng");
+ memory->grow(dcAng,cos_total*2,3,2,"BOP:dcAng");
+ memory->grow(disij,3,neigh_total,"disij");
+ memory->grow(rij,neigh_total,"rij");
+ memory->grow(betaS,neigh_total,"betaS");
+ memory->grow(dBetaS,neigh_total,"dBetaS");
+ memory->grow(betaP,neigh_total,"betaP");
+ memory->grow(dBetaP,neigh_total,"dBetaP");
+ memory->grow(repul,neigh_total,"repul");
+ memory->grow(dRepul,neigh_total,"dRepul");
+ }
+ update_list=1;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::memory_theta_destroy()
+{
+
+ memory->destroy(itypeSigBk);
+ memory->destroy(nSigBk);
+ memory->destroy(sigB);
+ memory->destroy(sigB1);
+ memory->destroy(itypePiBk);
+ memory->destroy(nPiBk);
+ memory->destroy(piB);
+ memory->destroy(neigh_flag);
+ if(otfly==0) {
+ memory->destroy(cosAng);
+ memory->destroy(dcAng);
+ memory->destroy(disij);
+ memory->destroy(rij);
+ memory->destroy(betaS);
+ memory->destroy(dBetaS);
+ memory->destroy(betaP);
+ memory->destroy(dBetaP);
+ memory->destroy(repul);
+ memory->destroy(dRepul);
+ }
+ update_list=0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::create_pi(int n_tot)
+{
+ bt_pi = (B_PI *) memory->smalloc(n_tot*sizeof(B_PI),"BOP:bt_pi");
+ allocate_pi=1;
+}
+
+void PairBOP::create_sigma(int n_tot)
+{
+ bt_sg = (B_SG *) memory->smalloc(n_tot*sizeof(B_SG),"BOP:bt_sg");
+ allocate_sigma=1;
+}
+
+void PairBOP::destroy_pi()
+{
+ memory->destroy(bt_pi);
+ allocate_pi=0;
+}
+
+void PairBOP::destroy_sigma()
+{
+ memory->destroy(bt_sg);
+ allocate_sigma=0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::grow_pi(int n1, int n2)
+{
+ int i,j;
+ B_PI *bt_temp;
+ bt_temp = (B_PI *) memory->smalloc(n1*sizeof(B_PI),"BOP:b_temp");
+ for(i=0;i<n1;i++) {
+ bt_temp[i].temp = bt_pi[i].temp;
+ bt_temp[i].i = bt_pi[i].i;
+ bt_temp[i].j = bt_pi[i].j;
+ for(j=0;j<3;j++) {
+ bt_temp[i].dAA[j] = bt_pi[i].dAA[j];
+ bt_temp[i].dBB[j] = bt_pi[i].dBB[j];
+ bt_temp[i].dPiB[j] = bt_pi[i].dPiB[j];
+ }
+ }
+ memory->destroy(bt_pi);
+ bt_pi=NULL;
+ bt_pi = (B_PI *) memory->smalloc(n2*sizeof(B_PI),"BOP:bt_pi");
+ for(i=0;i<n1;i++) {
+ bt_pi[i].temp = bt_temp[i].temp;
+ bt_pi[i].i = bt_temp[i].i;
+ bt_pi[i].j = bt_temp[i].j;
+ for(j=0;j<3;j++) {
+ bt_pi[i].dAA[j] = bt_temp[i].dAA[j];
+ bt_pi[i].dBB[j] = bt_temp[i].dBB[j];
+ bt_pi[i].dPiB[j] = bt_temp[i].dPiB[j];
+ }
+ }
+ for(i=n1;i<n2;i++) {
+ bt_pi[i].i = -1;
+ bt_pi[i].j = -1;
+ for(j=0;j<3;j++) {
+ bt_pi[i].dAA[j] = 0.0;
+ bt_pi[i].dBB[j] = 0.0;
+ bt_pi[i].dPiB[j] = 0.0;
+ }
+ }
+ memory->destroy(bt_temp);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::grow_sigma(int n1,int n2)
+{
+ int i,j;
+ B_SG *bt_temp;
+ bt_temp = (B_SG *) memory->smalloc(n1*sizeof(B_SG),"BOP:bt_temp");
+ for(i=0;i<n1;i++) {
+ bt_temp[i].temp = bt_sg[i].temp;
+ bt_temp[i].i = bt_sg[i].i;
+ bt_temp[i].j = bt_sg[i].j;
+ for(j=0;j<3;j++) {
+ bt_temp[i].dAA[j] = bt_sg[i].dAA[j];
+ bt_temp[i].dBB[j] = bt_sg[i].dBB[j];
+ bt_temp[i].dCC[j] = bt_sg[i].dCC[j];
+ bt_temp[i].dDD[j] = bt_sg[i].dDD[j];
+ bt_temp[i].dEE[j] = bt_sg[i].dEE[j];
+ bt_temp[i].dEE1[j] = bt_sg[i].dEE1[j];
+ bt_temp[i].dFF[j] = bt_sg[i].dFF[j];
+ bt_temp[i].dAAC[j] = bt_sg[i].dAAC[j];
+ bt_temp[i].dBBC[j] = bt_sg[i].dBBC[j];
+ bt_temp[i].dCCC[j] = bt_sg[i].dCCC[j];
+ bt_temp[i].dDDC[j] = bt_sg[i].dDDC[j];
+ bt_temp[i].dEEC[j] = bt_sg[i].dEEC[j];
+ bt_temp[i].dFFC[j] = bt_sg[i].dFFC[j];
+ bt_temp[i].dGGC[j] = bt_sg[i].dGGC[j];
+ bt_temp[i].dUT[j] = bt_sg[i].dUT[j];
+ bt_temp[i].dSigB1[j] = bt_sg[i].dSigB1[j];
+ bt_temp[i].dSigB[j] = bt_sg[i].dSigB[j];
+ }
+ }
+ memory->destroy(bt_sg);
+ bt_sg=NULL;
+ bt_sg = (B_SG *) memory->smalloc(n2*sizeof(B_SG),"BOP:bt_sg");
+ for(i=0;i<n1;i++) {
+ bt_sg[i].temp = bt_temp[i].temp;
+ bt_sg[i].i = bt_temp[i].i;
+ bt_sg[i].j = bt_temp[i].j;
+ for(j=0;j<3;j++) {
+ bt_sg[i].dAA[j] = bt_temp[i].dAA[j];
+ bt_sg[i].dBB[j] = bt_temp[i].dBB[j];
+ bt_sg[i].dCC[j] = bt_temp[i].dCC[j];
+ bt_sg[i].dDD[j] = bt_temp[i].dDD[j];
+ bt_sg[i].dEE[j] = bt_temp[i].dEE[j];
+ bt_sg[i].dEE1[j] = bt_temp[i].dEE1[j];
+ bt_sg[i].dFF[j] = bt_temp[i].dFF[j];
+ bt_sg[i].dAAC[j] = bt_temp[i].dAAC[j];
+ bt_sg[i].dBBC[j] = bt_temp[i].dBBC[j];
+ bt_sg[i].dCCC[j] = bt_temp[i].dCCC[j];
+ bt_sg[i].dDDC[j] = bt_temp[i].dDDC[j];
+ bt_sg[i].dEEC[j] = bt_temp[i].dEEC[j];
+ bt_sg[i].dFFC[j] = bt_temp[i].dFFC[j];
+ bt_sg[i].dGGC[j] = bt_temp[i].dGGC[j];
+ bt_sg[i].dUT[j] = bt_temp[i].dUT[j];
+ bt_sg[i].dSigB1[j] = bt_temp[i].dSigB1[j];
+ bt_sg[i].dSigB[j] = bt_temp[i].dSigB[j];
+ }
+ }
+ for(i=n1;i<n2;i++) {
+ bt_sg[i].i = -1;
+ bt_sg[i].j = -1;
+ for(j=0;j<3;j++) {
+ bt_sg[i].dAA[j] = 0.0;
+ bt_sg[i].dBB[j] = 0.0;
+ bt_sg[i].dCC[j] = 0.0;
+ bt_sg[i].dDD[j] = 0.0;
+ bt_sg[i].dEE[j] = 0.0;
+ bt_sg[i].dEE1[j] = 0.0;
+ bt_sg[i].dFF[j] = 0.0;
+ bt_sg[i].dAAC[j] = 0.0;
+ bt_sg[i].dBBC[j] = 0.0;
+ bt_sg[i].dCCC[j] = 0.0;
+ bt_sg[i].dDDC[j] = 0.0;
+ bt_sg[i].dEEC[j] = 0.0;
+ bt_sg[i].dFFC[j] = 0.0;
+ bt_sg[i].dGGC[j] = 0.0;
+ bt_sg[i].dUT[j] = 0.0;
+ bt_sg[i].dSigB1[j] = 0.0;
+ bt_sg[i].dSigB[j] = 0.0;
+ }
+ }
+ memory->destroy(bt_temp);
+}
diff --git a/src/MANYBODY/pair_bop.h b/src/MANYBODY/pair_bop.h
new file mode 100644
index 000000000..c6a4557fc
--- /dev/null
+++ b/src/MANYBODY/pair_bop.h
@@ -0,0 +1,270 @@
+/* ----------------------------------------------------------------------
+ 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.
+
+ The this work follows the formulation from (a) D.G. Pettifor, et al., Mat.
+ Sci. and Eng. A365, 2-13, (2004) and (b) D.A. Murdick, et al., Phys.
+ Rev. B 73, 045206 (2006). (c) D.K. Ward, et al., Phys. Rev. B 85, 115206
+ (2012)
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(bop,PairBOP)
+
+#else
+
+#ifndef LMP_PAIR_BOP_H
+#define LMP_PAIR_BOP_H
+
+#include "pair.h"
+#include "update.h"
+
+namespace LAMMPS_NS {
+
+class PairBOP : public Pair {
+ public:
+ PairBOP(class LAMMPS *);
+ virtual ~PairBOP();
+ void compute(int, int);
+ void settings(int, char **);
+ void coeff(int, char **);
+ void init_style();
+ double init_one(int, int);
+ double memory_usage();
+
+ private:
+ int me;
+ int maxneigh; // maximum size of neighbor list on this processor
+ int update_list; // check for changing maximum size of neighbor list
+ int maxbopn; // maximum size of bop neighbor list for allocation
+ int maxnall; // maximum size of bop neighbor list for allocation
+ int *map; // mapping from atom types to elements
+ int nelements; // # of unique elments
+ int nr; // increments for the BOP potential
+ int nBOt; // second BO increments
+ int bop_types; // number of elments in potential
+ int npairs; // number of element pairs
+ char **elements; // names of unique elements
+ int ***elem2param;
+ int nparams;
+ int bop_step;
+ int allocate_pi;
+ int allocate_sigma;
+ int allocate_neigh;
+ int nb_pi,nb_sg;
+
+ int *BOP_index; // index for neighbor list position
+ int neigh_total; // total number of neighbors stored
+ int *cos_index; // index for neighbor cosine if not using on the fly
+ int *neigh_flag; // index for neighbor cosine if not using on the fly
+ int cos_total; // number of cosines stored if not using on the fly
+ int neigh_ct; // limit for large arrays
+
+/*Parameters variables*/
+
+ int ncutoff,nfunc;
+ int a_flag;
+ double *pi_a,*pro_delta,*pi_delta;
+ double *pi_p,*pi_c,*sigma_r0,*pi_r0,*phi_r0;
+ double *sigma_rc,*pi_rc,*phi_rc,*r1,*sigma_beta0;
+ double *pi_beta0,*phi0,*sigma_n,*pi_n,*phi_m;
+ double *sigma_nc,*pi_nc,*phi_nc;
+ double *pro,*sigma_delta,*sigma_c,*sigma_a;
+ double ***sigma_g0,***sigma_g1,***sigma_g2,***sigma_g3;
+ double ***sigma_g4,*sigma_f,*sigma_k,*small3;
+ double small1,small2,small3g,small4,small5,small6,small7;
+ double which,alpha,alpha1,beta1,gamma1,alpha2,beta2,alpha3;
+ double beta3,rsmall,rbig,rcore;
+ char **words;
+
+ double cutmax; //max cutoff for all elements
+ int otfly; //Defines whether to do on the fly
+ //calculations of angles and distances
+ //on the fly will slow down calculations
+ //but requires less memory on = 1, off=0
+
+ int table; //determines the method for reading in
+ //potential parameters a preset table
+ //or generate the tables using a spline
+
+/* Neigh variables */
+
+ double *rcut,*dr,*rdr;
+ double **disij,*rij;
+
+/*Triple variables */
+
+ double *cosAng,***dcosAng,***dcAng;
+
+/*Double variables */
+
+ double *betaS,*dBetaS,*betaP;
+ double *dBetaP,*repul,*dRepul;
+
+/*Sigma variables */
+
+ int **itypeSigBk,*nSigBk;
+ double *sigB;
+ double *sigB1;
+
+
+/*Pi variables */
+
+ int **itypePiBk,*nPiBk;
+ double *piB;
+
+/*Grids1 variables */
+
+ double **pBetaS,**pBetaS1,**pBetaS2,**pBetaS3;
+ double **pBetaS4,**pBetaS5,**pBetaS6;
+
+/*Grids2 variables */
+
+ double **pBetaP,**pBetaP1,**pBetaP2,**pBetaP3;
+ double **pBetaP4,**pBetaP5,**pBetaP6;
+
+/*Grids3 variables */
+
+ double **pRepul,**pRepul1,**pRepul2,**pRepul3;
+ double **pRepul4,**pRepul5,**pRepul6;
+
+/*Grids4 variables */
+
+ double **FsigBO,**FsigBO1,**FsigBO2,**FsigBO3;
+ double **FsigBO4,**FsigBO5,**FsigBO6;
+ double dBO,rdBO;
+
+/* End of BOP variables */
+
+ double **rcmin,**rcmax,**rcmaxp;
+ struct B_PI{
+ double dAA[3];
+ double dBB[3];
+ double dPiB[3];
+ int temp;
+ int i;
+ int j;
+ };
+ B_PI *bt_pi;
+
+ struct B_SG{
+ double dAA[3];
+ double dBB[3];
+ double dCC[3];
+ double dDD[3];
+ double dEE[3];
+ double dEE1[3];
+ double dFF[3];
+ double dAAC[3];
+ double dBBC[3];
+ double dCCC[3];
+ double dDDC[3];
+ double dEEC[3];
+ double dFFC[3];
+ double dGGC[3];
+ double dUT[3];
+ double dSigB1[3];
+ double dSigB[3];
+ int temp;
+ int i;
+ int j;
+ };
+ B_SG *bt_sg;
+
+ void setPbetaS();
+ void setPbetaP();
+ void setPrepul();
+ void setSign();
+ void gneigh();
+ void theta();
+ void theta_mod();
+ void sigmaBo();
+ void PiBo();
+ void sigmaBo_otf();
+ void PiBo_otf();
+ void sigmaBo_noa();
+ void sigmaBo_noa_otf();
+ void memory_theta_create();
+ void memory_theta_destroy();
+ void memory_theta_grow();
+ double cutoff(double, double, int, double);
+ double betaSfunc(int, double);
+ double dBetaSfunc(int, double, double, double);
+ double betaPfunc(int, double);
+ double dBetaPfunc(int, double, double, double);
+ double repulfunc(int, double);
+ double dRepulfunc(int, double, double, double);
+
+ void read_file(char *);
+ void read_table(char *);
+ void allocate();
+ void create_pi(int);
+ void create_sigma(int);
+ void destroy_pi();
+ void destroy_sigma();
+ void grow_pi(int,int);
+ void grow_sigma(int,int);
+};
+
+}
+
+#endif
+#endif
+
+/* ERROR/WARNING messages:
+
+E: Illegal ... command
+
+Self-explanatory. Check the input script syntax and compare to the
+documentation for the command. You can use -echo screen as a
+command-line option when running LAMMPS to see the offending line.
+
+E: Incorrect args for pair coefficients
+
+Self-explanatory. Check the input script or data file.
+
+E: Pair style BOP requires atom IDs
+
+This is a requirement to use the BOP potential.
+
+E: Pair style BOP requires newton pair on
+
+See the newton command. This is a restriction to use the BOP
+potential.
+
+E: Pair style bop requires comm ghost cutoff at least 3x larger than %g
+
+Use the communicate ghost command to set this. See the pair bop
+doc page for more details.
+
+E: All pair coeffs are not set
+
+All pair coefficients must be set in the data file or by the
+pair_coeff command before running a simulation.
+
+E: Too many atom pairs for pair bop
+
+The number of atomic pairs exceeds the expected number. Check your
+atomic structure to ensure that it is realistic.
+
+E: Too many atom triplets for pair bop
+
+The number of three atom groups for angle determinations exceeds the
+expected number. Check your atomic structrure to ensure that it is
+realistic.
+
+E: Cannot open BOP potential file %s
+
+The specified BOP potential file cannot be opened. Check that the
+path and name are correct.
+
+*/
diff --git a/src/MC/fix_bond_break.cpp b/src/MC/fix_bond_break.cpp
index e24e733f6..57828e909 100755
--- a/src/MC/fix_bond_break.cpp
+++ b/src/MC/fix_bond_break.cpp
@@ -1,390 +1,389 @@
/* ----------------------------------------------------------------------
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 "fix_bond_break.h"
#include "update.h"
#include "respa.h"
#include "atom.h"
#include "force.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "random_mars.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixBondBreak::FixBondBreak(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 6) error->all(FLERR,"Illegal fix bond/break command");
MPI_Comm_rank(world,&me);
nevery = atoi(arg[3]);
if (nevery <= 0) error->all(FLERR,"Illegal fix bond/break command");
force_reneighbor = 1;
next_reneighbor = -1;
vector_flag = 1;
size_vector = 2;
global_freq = 1;
extvector = 0;
btype = atoi(arg[4]);
double cutoff = atof(arg[5]);
if (btype < 1 || btype > atom->nbondtypes)
error->all(FLERR,"Invalid bond type in fix bond/break command");
if (cutoff < 0.0) error->all(FLERR,"Illegal fix bond/break command");
cutsq = cutoff*cutoff;
// optional keywords
fraction = 1.0;
int seed = 12345;
int iarg = 6;
while (iarg < narg) {
if (strcmp(arg[iarg],"prob") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix bond/break command");
fraction = atof(arg[iarg+1]);
seed = atoi(arg[iarg+2]);
if (fraction < 0.0 || fraction > 1.0)
error->all(FLERR,"Illegal fix bond/break command");
if (seed <= 0) error->all(FLERR,"Illegal fix bond/break command");
iarg += 3;
} else error->all(FLERR,"Illegal fix bond/break command");
}
// error check
if (atom->molecular == 0)
error->all(FLERR,"Cannot use fix bond/break with non-molecular systems");
// initialize Marsaglia RNG with processor-unique seed
random = new RanMars(lmp,seed + me);
// set comm sizes needed by this fix
comm_forward = 2;
comm_reverse = 2;
// allocate arrays local to this fix
nmax = 0;
partner = NULL;
distsq = NULL;
// zero out stats
breakcount = 0;
breakcounttotal = 0;
}
/* ---------------------------------------------------------------------- */
FixBondBreak::~FixBondBreak()
{
delete random;
// delete locally stored arrays
memory->destroy(partner);
memory->destroy(distsq);
}
/* ---------------------------------------------------------------------- */
int FixBondBreak::setmask()
{
int mask = 0;
mask |= POST_INTEGRATE;
mask |= POST_INTEGRATE_RESPA;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixBondBreak::init()
{
// require special bonds = 0,1,1
int flag = 0;
if (force->special_lj[1] != 0.0 || force->special_lj[2] != 1.0 ||
force->special_lj[3] != 1.0) flag = 1;
if (force->special_coul[1] != 0.0 || force->special_coul[2] != 1.0 ||
force->special_coul[3] != 1.0) flag = 1;
if (flag) error->all(FLERR,"Fix bond/break requires special_bonds = 0,1,1");
// warn if angles, dihedrals, impropers are being used
if (force->angle || force->dihedral || force->improper) {
if (me == 0)
error->warning(FLERR,"Broken bonds will not alter angles, "
"dihedrals, or impropers");
}
if (strstr(update->integrate_style,"respa"))
nlevels_respa = ((Respa *) update->integrate)->nlevels;
}
/* ---------------------------------------------------------------------- */
void FixBondBreak::post_integrate()
{
int i,j,k,m,n,i1,i2,n1,n3,type;
double delx,dely,delz,rsq,min,max;
int *slist;
if (update->ntimestep % nevery) return;
// need updated ghost atom positions
comm->forward_comm();
// resize bond partner list and initialize it
// probability array overlays distsq array
// needs to be atom->nmax in length
if (atom->nmax > nmax) {
memory->destroy(partner);
memory->destroy(distsq);
nmax = atom->nmax;
memory->create(partner,nmax,"bond/break:partner");
memory->create(distsq,nmax,"bond/break:distsq");
probability = distsq;
}
int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost;
for (i = 0; i < nall; i++) {
partner[i] = 0;
distsq[i] = 0.0;
}
// loop over bond list
// setup possible partner list of bonds to break
double **x = atom->x;
int *tag = atom->tag;
int *mask = atom->mask;
int **bondlist = neighbor->bondlist;
int nbondlist = neighbor->nbondlist;
for (n = 0; n < nbondlist; n++) {
i1 = bondlist[n][0];
i2 = bondlist[n][1];
type = bondlist[n][2];
if (!(mask[i1] & groupbit)) continue;
if (!(mask[i2] & groupbit)) continue;
if (type != btype) continue;
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);
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutsq) continue;
if (rsq > distsq[i1]) {
partner[i1] = tag[i2];
distsq[i1] = rsq;
}
if (rsq > distsq[i2]) {
partner[i2] = tag[i1];
distsq[i2] = rsq;
}
}
// reverse comm of partner info
if (force->newton_bond) comm->reverse_comm_fix(this);
// each atom now knows its winning partner
// for prob check, generate random value for each atom with a bond partner
// forward comm of partner and random value, so ghosts have it
if (fraction < 1.0) {
for (i = 0; i < nlocal; i++)
if (partner[i]) probability[i] = random->uniform();
}
comm->forward_comm_fix(this);
// break bonds
// if both atoms list each other as winning bond partner
// and probability constraint is satisfied
int **bond_type = atom->bond_type;
int **bond_atom = atom->bond_atom;
int *num_bond = atom->num_bond;
int **nspecial = atom->nspecial;
int **special = atom->special;
int nbreak = 0;
for (i = 0; i < nlocal; i++) {
if (partner[i] == 0) continue;
j = atom->map(partner[i]);
if (partner[j] != tag[i]) continue;
// apply probability constraint
// MIN,MAX insures values are added in same order on different procs
if (fraction < 1.0) {
min = MIN(probability[i],probability[j]);
max = MAX(probability[i],probability[j]);
if (0.5*(min+max) >= fraction) continue;
}
// delete bond from atom I if I stores it
// atom J will also do this
for (m = 0; m < num_bond[i]; m++) {
if (bond_atom[i][m] == partner[i]) {
for (k = m; k < num_bond[i]-1; k++) {
bond_atom[i][k] = bond_atom[i][k+1];
bond_type[i][k] = bond_type[i][k+1];
}
num_bond[i]--;
break;
}
}
// remove J from special bond list for atom I
// atom J will also do this
slist = special[i];
n1 = nspecial[i][0];
n3 = nspecial[i][2];
for (m = 0; m < n1; m++)
if (slist[m] == partner[i]) break;
for (; m < n3-1; m++) slist[m] = slist[m+1];
nspecial[i][0]--;
nspecial[i][1]--;
nspecial[i][2]--;
// count the broken bond once
if (tag[i] < tag[j]) nbreak++;
}
// tally stats
MPI_Allreduce(&nbreak,&breakcount,1,MPI_INT,MPI_SUM,world);
breakcounttotal += breakcount;
atom->nbonds -= breakcount;
// trigger reneighboring if any bonds were formed
if (breakcount) next_reneighbor = update->ntimestep;
}
/* ---------------------------------------------------------------------- */
void FixBondBreak::post_integrate_respa(int ilevel, int iloop)
{
if (ilevel == nlevels_respa-1) post_integrate();
}
/* ---------------------------------------------------------------------- */
int FixBondBreak::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++] = partner[j];
buf[m++] = probability[j];
}
return 2;
}
/* ---------------------------------------------------------------------- */
void FixBondBreak::unpack_comm(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
partner[i] = static_cast<int> (buf[m++]);
probability[i] = buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int FixBondBreak::pack_reverse_comm(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = partner[i];
buf[m++] = distsq[i];
}
return 2;
}
/* ---------------------------------------------------------------------- */
void FixBondBreak::unpack_reverse_comm(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
if (buf[m+1] > distsq[j]) {
partner[j] = static_cast<int> (buf[m++]);
distsq[j] = buf[m++];
} else m += 2;
}
}
/* ---------------------------------------------------------------------- */
double FixBondBreak::compute_vector(int n)
{
if (n == 1) return (double) breakcount;
return (double) breakcounttotal;
}
/* ----------------------------------------------------------------------
memory usage of local atom-based arrays
------------------------------------------------------------------------- */
double FixBondBreak::memory_usage()
{
int nmax = atom->nmax;
double bytes = nmax * sizeof(int);
bytes += nmax * sizeof(double);
return bytes;
}
diff --git a/src/MOLECULE/angle_charmm.cpp b/src/MOLECULE/angle_charmm.cpp
index 8d086838f..9c9a86179 100644
--- a/src/MOLECULE/angle_charmm.cpp
+++ b/src/MOLECULE/angle_charmm.cpp
@@ -1,300 +1,297 @@
/* ----------------------------------------------------------------------
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 "math.h"
#include "stdlib.h"
#include "angle_charmm.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCharmm::AngleCharmm(LAMMPS *lmp) : Angle(lmp) {}
/* ---------------------------------------------------------------------- */
AngleCharmm::~AngleCharmm()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(theta0);
memory->destroy(k_ub);
memory->destroy(r_ub);
}
}
/* ---------------------------------------------------------------------- */
void AngleCharmm::compute(int eflag, int vflag)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double dtheta,tk;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
double delxUB,delyUB,delzUB,rsqUB,rUB,dr,rk,forceUB;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// Urey-Bradley bond
delxUB = x[i3][0] - x[i1][0];
delyUB = x[i3][1] - x[i1][1];
delzUB = x[i3][2] - x[i1][2];
- domain->minimum_image(delxUB,delyUB,delzUB);
rsqUB = delxUB*delxUB + delyUB*delyUB + delzUB*delzUB;
rUB = sqrt(rsqUB);
// Urey-Bradley force & energy
dr = rUB - r_ub[type];
rk = k_ub[type] * dr;
if (rUB > 0.0) forceUB = -2.0*rk/rUB;
else forceUB = 0.0;
if (eflag) eangle = rk*dr;
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
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;
s = 1.0/s;
// harmonic force & energy
dtheta = acos(c) - theta0[type];
tk = k[type] * dtheta;
if (eflag) eangle += tk*dtheta;
a = -2.0 * tk * s;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2 - delxUB*forceUB;
f1[1] = a11*dely1 + a12*dely2 - delyUB*forceUB;
f1[2] = a11*delz1 + a12*delz2 - delzUB*forceUB;
f3[0] = a22*delx2 + a12*delx1 + delxUB*forceUB;
f3[1] = a22*dely2 + a12*dely1 + delyUB*forceUB;
f3[2] = a22*delz2 + a12*delz1 + delzUB*forceUB;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
}
}
/* ---------------------------------------------------------------------- */
void AngleCharmm::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(k,n+1,"angle:k");
memory->create(theta0,n+1,"angle:theta0");
memory->create(k_ub,n+1,"angle:k_ub");
memory->create(r_ub,n+1,"angle:r_ub");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one type
------------------------------------------------------------------------- */
void AngleCharmm::coeff(int narg, char **arg)
{
if (narg != 5) error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
double k_one = force->numeric(arg[1]);
double theta0_one = force->numeric(arg[2]);
double k_ub_one = force->numeric(arg[3]);
double r_ub_one = force->numeric(arg[4]);
// convert theta0 from degrees to radians
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
theta0[i] = theta0_one/180.0 * MY_PI;
k_ub[i] = k_ub_one;
r_ub[i] = r_ub_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
}
/* ---------------------------------------------------------------------- */
double AngleCharmm::equilibrium_angle(int i)
{
return theta0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleCharmm::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nangletypes,fp);
fwrite(&theta0[1],sizeof(double),atom->nangletypes,fp);
fwrite(&k_ub[1],sizeof(double),atom->nangletypes,fp);
fwrite(&r_ub[1],sizeof(double),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleCharmm::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&k[1],sizeof(double),atom->nangletypes,fp);
fread(&theta0[1],sizeof(double),atom->nangletypes,fp);
fread(&k_ub[1],sizeof(double),atom->nangletypes,fp);
fread(&r_ub[1],sizeof(double),atom->nangletypes,fp);
}
MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&theta0[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&k_ub[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&r_ub[1],atom->nangletypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double AngleCharmm::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double delxUB = x[i3][0] - x[i1][0];
double delyUB = x[i3][1] - x[i1][1];
double delzUB = x[i3][2] - x[i1][2];
domain->minimum_image(delxUB,delyUB,delzUB);
double rUB = sqrt(delxUB*delxUB + delyUB*delyUB + delzUB*delzUB);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double dtheta = acos(c) - theta0[type];
double tk = k[type] * dtheta;
double dr = rUB - r_ub[type];
double rk = k_ub[type] * dr;
return (tk*dtheta + rk*dr);
}
diff --git a/src/MOLECULE/angle_cosine.cpp b/src/MOLECULE/angle_cosine.cpp
index d6bd3965d..6ff698527 100644
--- a/src/MOLECULE/angle_cosine.cpp
+++ b/src/MOLECULE/angle_cosine.cpp
@@ -1,229 +1,227 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "angle_cosine.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosine::AngleCosine(LAMMPS *lmp) : Angle(lmp) {}
/* ---------------------------------------------------------------------- */
AngleCosine::~AngleCosine()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
}
}
/* ---------------------------------------------------------------------- */
void AngleCosine::compute(int eflag, int vflag)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double rsq1,rsq2,r1,r2,c,a,a11,a12,a22;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// c = cosine of angle
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// force & energy
if (eflag) eangle = k[type]*(1.0+c);
a = k[type];
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
}
}
/* ---------------------------------------------------------------------- */
void AngleCosine::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(k,n+1,"angle:k");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one type
------------------------------------------------------------------------- */
void AngleCosine::coeff(int narg, char **arg)
{
if (narg != 2) error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
double k_one = force->numeric(arg[1]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
}
/* ---------------------------------------------------------------------- */
double AngleCosine::equilibrium_angle(int i)
{
return MY_PI;
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleCosine::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleCosine::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) fread(&k[1],sizeof(double),atom->nangletypes,fp);
MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double AngleCosine::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
return k[type]*(1.0+c);
}
diff --git a/src/MOLECULE/angle_cosine_delta.cpp b/src/MOLECULE/angle_cosine_delta.cpp
index b7cceb618..08124142e 100644
--- a/src/MOLECULE/angle_cosine_delta.cpp
+++ b/src/MOLECULE/angle_cosine_delta.cpp
@@ -1,182 +1,180 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U), akohlmey at gmail.com
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "angle_cosine_delta.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosineDelta::AngleCosineDelta(LAMMPS *lmp) : AngleCosineSquared(lmp) {}
/* ---------------------------------------------------------------------- */
void AngleCosineDelta::compute(int eflag, int vflag)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2,theta,dtheta,dcostheta,tk;
double eangle,f1[3],f3[3];
double rsq1,rsq2,r1,r2,c,a,cot,a11,a12,a22,b11,b12,b22,c0,s0,s;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
theta = acos(c);
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
s = 1.0/s;
cot = c/s;
// force & energy
dtheta = theta - theta0[type];
dcostheta = cos(dtheta);
tk = k[type] * (1.0-dcostheta);
if (eflag) eangle = tk;
a = -k[type];
// expand dtheta for cos and sin contribution to force
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
b11 = -a*c*cot / rsq1;
b12 = a*cot / (r1*r2);
b22 = -a*c*cot / rsq2;
c0 = cos(theta0[type]);
s0 = sin(theta0[type]);
f1[0] = (a11*delx1 + a12*delx2)*c0 + (b11*delx1 + b12*delx2)*s0;
f1[1] = (a11*dely1 + a12*dely2)*c0 + (b11*dely1 + b12*dely2)*s0;
f1[2] = (a11*delz1 + a12*delz2)*c0 + (b11*delz1 + b12*delz2)*s0;
f3[0] = (a22*delx2 + a12*delx1)*c0 + (b22*delx2 + b12*delx1)*s0;
f3[1] = (a22*dely2 + a12*dely1)*c0 + (b22*dely2 + b12*dely1)*s0;
f3[2] = (a22*delz2 + a12*delz1)*c0 + (b22*delz2 + b12*delz1)*s0;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
}
}
/* ---------------------------------------------------------------------- */
double AngleCosineDelta::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double theta = acos(c);
double dtheta = theta - theta0[type];
double dcostheta = cos(dtheta);
double tk = k[type] * (1.0-dcostheta);
return tk;
}
diff --git a/src/MOLECULE/angle_cosine_periodic.cpp b/src/MOLECULE/angle_cosine_periodic.cpp
index 7c676d309..39ab78114 100644
--- a/src/MOLECULE/angle_cosine_periodic.cpp
+++ b/src/MOLECULE/angle_cosine_periodic.cpp
@@ -1,290 +1,288 @@
/* ----------------------------------------------------------------------
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 "math.h"
#include "stdlib.h"
#include "angle_cosine_periodic.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosinePeriodic::AngleCosinePeriodic(LAMMPS *lmp) : Angle(lmp) {}
/* ---------------------------------------------------------------------- */
AngleCosinePeriodic::~AngleCosinePeriodic()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(b);
memory->destroy(multiplicity);
}
}
/* ---------------------------------------------------------------------- */
void AngleCosinePeriodic::compute(int eflag, int vflag)
{
int i,i1,i2,i3,n,m,type,b_factor;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
double tn,tn_1,tn_2,un,un_1,un_2;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// c = cosine of angle
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
m = multiplicity[type];
b_factor = b[type];
// cos(n*x) = Tn(cos(x))
// Tn(x) = Chebyshev polynomials of the first kind: T_0 = 1, T_1 = x, ...
// recurrence relationship:
// Tn(x) = 2*x*T[n-1](x) - T[n-2](x) where T[-1](x) = 0
// also, dTn(x)/dx = n*U[n-1](x)
// where Un(x) = 2*x*U[n-1](x) - U[n-2](x) and U[-1](x) = 0
// finally need to handle special case for n = 1
tn = 1.0;
tn_1 = 1.0;
tn_2 = 0.0;
un = 1.0;
un_1 = 2.0;
un_2 = 0.0;
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
s = 1.0/s;
// force & energy
tn_2 = c;
for (i = 1; i <= m; i++) {
tn = 2*c*tn_1 - tn_2;
tn_2 = tn_1;
tn_1 = tn;
}
for (i = 2; i <= m; i++) {
un = 2*c*un_1 - un_2;
un_2 = un_1;
un_1 = un;
}
tn = b_factor*pow(-1.0,(double)m)*tn;
un = b_factor*pow(-1.0,(double)m)*m*un;
if (eflag) eangle = 2*k[type]*(1.0 - tn);
a = -k[type]*un;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
}
}
/* ---------------------------------------------------------------------- */
void AngleCosinePeriodic::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(k,n+1,"angle:k");
memory->create(multiplicity,n+1,"angle:multiplicity");
memory->create(b,n+1,"angle:b");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void AngleCosinePeriodic::coeff(int narg, char **arg)
{
if (narg != 4) error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
double c_one = atof(arg[1]);
int b_one = atoi(arg[2]);
int n_one = atoi(arg[3]);
if (n_one <= 0) error->all(FLERR,"Incorrect args for angle coefficients");
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = c_one/(n_one*n_one);
b[i] = b_one;
multiplicity[i] = n_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
}
/* ---------------------------------------------------------------------- */
double AngleCosinePeriodic::equilibrium_angle(int i)
{
return MY_PI;
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleCosinePeriodic::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nangletypes,fp);
fwrite(&b[1],sizeof(int),atom->nangletypes,fp);
fwrite(&multiplicity[1],sizeof(int),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleCosinePeriodic::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&k[1],sizeof(double),atom->nangletypes,fp);
fread(&b[1],sizeof(int),atom->nangletypes,fp);
fread(&multiplicity[1],sizeof(int),atom->nangletypes,fp);
}
MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&b[1],atom->nangletypes,MPI_INT,0,world);
MPI_Bcast(&multiplicity[1],atom->nangletypes,MPI_INT,0,world);
for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double AngleCosinePeriodic::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
c = cos(acos(c)*multiplicity[type]);
return k[type]*(1.0-b[type]*pow(-1.0,(double)multiplicity[type])*c);
}
diff --git a/src/MOLECULE/angle_cosine_squared.cpp b/src/MOLECULE/angle_cosine_squared.cpp
index f9275589e..9eaa4c31a 100644
--- a/src/MOLECULE/angle_cosine_squared.cpp
+++ b/src/MOLECULE/angle_cosine_squared.cpp
@@ -1,252 +1,250 @@
/* ----------------------------------------------------------------------
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)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "angle_cosine_squared.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosineSquared::AngleCosineSquared(LAMMPS *lmp) : Angle(lmp) {}
/* ---------------------------------------------------------------------- */
AngleCosineSquared::~AngleCosineSquared()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(theta0);
}
}
/* ---------------------------------------------------------------------- */
void AngleCosineSquared::compute(int eflag, int vflag)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double dcostheta,tk;
double rsq1,rsq2,r1,r2,c,a,a11,a12,a22;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// force & energy
dcostheta = c - cos(theta0[type]);
tk = k[type] * dcostheta;
if (eflag) eangle = tk*dcostheta;
a = 2.0 * tk;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
}
}
/* ---------------------------------------------------------------------- */
void AngleCosineSquared::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(k,n+1,"angle:k");
memory->create(theta0,n+1,"angle:theta0");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void AngleCosineSquared::coeff(int narg, char **arg)
{
if (narg != 3) error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
double k_one = force->numeric(arg[1]);
double theta0_one = force->numeric(arg[2]);
// convert theta0 from degrees to radians
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
theta0[i] = theta0_one/180.0 * MY_PI;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
}
/* ---------------------------------------------------------------------- */
double AngleCosineSquared::equilibrium_angle(int i)
{
return theta0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleCosineSquared::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nangletypes,fp);
fwrite(&theta0[1],sizeof(double),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleCosineSquared::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&k[1],sizeof(double),atom->nangletypes,fp);
fread(&theta0[1],sizeof(double),atom->nangletypes,fp);
}
MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&theta0[1],atom->nangletypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double AngleCosineSquared::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double dcostheta = c - cos(theta0[type]);
double tk = k[type] * dcostheta;
return tk*dcostheta;
}
diff --git a/src/MOLECULE/angle_harmonic.cpp b/src/MOLECULE/angle_harmonic.cpp
index a1d36aca6..87a733ba1 100644
--- a/src/MOLECULE/angle_harmonic.cpp
+++ b/src/MOLECULE/angle_harmonic.cpp
@@ -1,252 +1,250 @@
/* ----------------------------------------------------------------------
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 "angle_harmonic.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleHarmonic::AngleHarmonic(LAMMPS *lmp) : Angle(lmp) {}
/* ---------------------------------------------------------------------- */
AngleHarmonic::~AngleHarmonic()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(theta0);
}
}
/* ---------------------------------------------------------------------- */
void AngleHarmonic::compute(int eflag, int vflag)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double dtheta,tk;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
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;
s = 1.0/s;
// force & energy
dtheta = acos(c) - theta0[type];
tk = k[type] * dtheta;
if (eflag) eangle = tk*dtheta;
a = -2.0 * tk * s;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
}
}
/* ---------------------------------------------------------------------- */
void AngleHarmonic::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(k,n+1,"angle:k");
memory->create(theta0,n+1,"angle:theta0");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void AngleHarmonic::coeff(int narg, char **arg)
{
if (narg != 3) error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
double k_one = force->numeric(arg[1]);
double theta0_one = force->numeric(arg[2]);
// convert theta0 from degrees to radians
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
theta0[i] = theta0_one/180.0 * MY_PI;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
}
/* ---------------------------------------------------------------------- */
double AngleHarmonic::equilibrium_angle(int i)
{
return theta0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleHarmonic::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nangletypes,fp);
fwrite(&theta0[1],sizeof(double),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleHarmonic::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&k[1],sizeof(double),atom->nangletypes,fp);
fread(&theta0[1],sizeof(double),atom->nangletypes,fp);
}
MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&theta0[1],atom->nangletypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double AngleHarmonic::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double dtheta = acos(c) - theta0[type];
double tk = k[type] * dtheta;
return tk*dtheta;
}
diff --git a/src/MOLECULE/angle_table.cpp b/src/MOLECULE/angle_table.cpp
index a5d16910d..0be817acc 100644
--- a/src/MOLECULE/angle_table.cpp
+++ b/src/MOLECULE/angle_table.cpp
@@ -1,662 +1,660 @@
/* ----------------------------------------------------------------------
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: Chuanfu Luo (luochuanfu@gmail.com)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "angle_table.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
enum{LINEAR,SPLINE};
#define MAXLINE 1024
#define SMALL 0.001
#define TINY 1.E-10
/* ---------------------------------------------------------------------- */
AngleTable::AngleTable(LAMMPS *lmp) : Angle(lmp)
{
ntables = 0;
tables = NULL;
}
/* ---------------------------------------------------------------------- */
AngleTable::~AngleTable()
{
for (int m = 0; m < ntables; m++) free_table(&tables[m]);
memory->sfree(tables);
if (allocated) {
memory->destroy(setflag);
memory->destroy(theta0);
memory->destroy(tabindex);
}
}
/* ---------------------------------------------------------------------- */
void AngleTable::compute(int eflag, int vflag)
{
int i1,i2,i3,n,type;
double eangle,f1[3],f3[3];
double delx1,dely1,delz1,delx2,dely2,delz2;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
double theta,u,mdu; //mdu: minus du, -du/dx=f
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
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;
s = 1.0/s;
// tabulated force & energy
theta = acos(c);
uf_lookup(type,theta,u,mdu);
if (eflag) eangle = u;
a = mdu * s;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
}
}
/* ---------------------------------------------------------------------- */
void AngleTable::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(theta0,n+1,"angle:theta0");
memory->create(tabindex,n+1,"angle:tabindex");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void AngleTable::settings(int narg, char **arg)
{
if (narg != 2) error->all(FLERR,"Illegal angle_style command");
if (strcmp(arg[0],"linear") == 0) tabstyle = LINEAR;
else if (strcmp(arg[0],"spline") == 0) tabstyle = SPLINE;
else error->all(FLERR,"Unknown table style in angle style table");
tablength = force->inumeric(arg[1]);
if (tablength < 2) error->all(FLERR,"Illegal number of angle table entries");
// delete old tables, since cannot just change settings
for (int m = 0; m < ntables; m++) free_table(&tables[m]);
memory->sfree(tables);
if (allocated) {
memory->destroy(setflag);
memory->destroy(tabindex);
}
allocated = 0;
ntables = 0;
tables = NULL;
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void AngleTable::coeff(int narg, char **arg)
{
if (narg != 3) error->all(FLERR,"Illegal angle_coeff command");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
int me;
MPI_Comm_rank(world,&me);
tables = (Table *)
memory->srealloc(tables,(ntables+1)*sizeof(Table),"angle:tables");
Table *tb = &tables[ntables];
null_table(tb);
if (me == 0) read_table(tb,arg[1],arg[2]);
bcast_table(tb);
// error check on table parameters
if (tb->ninput <= 1) error->one(FLERR,"Invalid angle table length");
double alo,ahi;
alo = tb->afile[0];
ahi = tb->afile[tb->ninput-1];
if (fabs(alo-0.0) > TINY || fabs(ahi-180.0) > TINY)
error->all(FLERR,"Angle table must range from 0 to 180 degrees");
// convert theta from degrees to radians
for (int i = 0; i < tb->ninput; i++){
tb->afile[i] *= MY_PI/180.0;
tb->ffile[i] *= 180.0/MY_PI;
}
// spline read-in and compute a,e,f vectors within table
spline_table(tb);
compute_table(tb);
// store ptr to table in tabindex
int count = 0;
for (int i = ilo; i <= ihi; i++) {
tabindex[i] = ntables;
setflag[i] = 1;
theta0[i] = tb->theta0;
count++;
}
ntables++;
if (count == 0) error->all(FLERR,"Illegal angle_coeff command");
}
/* ----------------------------------------------------------------------
return an equilbrium angle length
should not be used, since don't know minimum of tabulated function
------------------------------------------------------------------------- */
double AngleTable::equilibrium_angle(int i)
{
return theta0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void AngleTable::write_restart(FILE *fp)
{
fwrite(&tabstyle,sizeof(int),1,fp);
fwrite(&tablength,sizeof(int),1,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void AngleTable::read_restart(FILE *fp)
{
if (comm->me == 0) {
fread(&tabstyle,sizeof(int),1,fp);
fread(&tablength,sizeof(int),1,fp);
}
MPI_Bcast(&tabstyle,1,MPI_INT,0,world);
MPI_Bcast(&tablength,1,MPI_INT,0,world);
allocate();
}
/* ---------------------------------------------------------------------- */
double AngleTable::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double theta = acos(c);
double u;
u_lookup(type,theta,u);
return u;
}
/* ---------------------------------------------------------------------- */
void AngleTable::null_table(Table *tb)
{
tb->afile = tb->efile = tb->ffile = NULL;
tb->e2file = tb->f2file = NULL;
tb->ang = tb->e = tb->de = NULL;
tb->f = tb->df = tb->e2 = tb->f2 = NULL;
}
/* ---------------------------------------------------------------------- */
void AngleTable::free_table(Table *tb)
{
memory->destroy(tb->afile);
memory->destroy(tb->efile);
memory->destroy(tb->ffile);
memory->destroy(tb->e2file);
memory->destroy(tb->f2file);
memory->destroy(tb->ang);
memory->destroy(tb->e);
memory->destroy(tb->de);
memory->destroy(tb->f);
memory->destroy(tb->df);
memory->destroy(tb->e2);
memory->destroy(tb->f2);
}
/* ----------------------------------------------------------------------
read table file, only called by proc 0
------------------------------------------------------------------------- */
void AngleTable::read_table(Table *tb, char *file, char *keyword)
{
char line[MAXLINE];
// open file
FILE *fp = fopen(file,"r");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open file %s",file);
error->one(FLERR,str);
}
// loop until section found with matching keyword
while (1) {
if (fgets(line,MAXLINE,fp) == NULL)
error->one(FLERR,"Did not find keyword in table file");
if (strspn(line," \t\n") == strlen(line)) continue; // blank line
if (line[0] == '#') continue; // comment
if (strstr(line,keyword) == line) break; // matching keyword
fgets(line,MAXLINE,fp); // no match, skip section
param_extract(tb,line);
fgets(line,MAXLINE,fp);
for (int i = 0; i < tb->ninput; i++) fgets(line,MAXLINE,fp);
}
// read args on 2nd line of section
// allocate table arrays for file values
fgets(line,MAXLINE,fp);
param_extract(tb,line);
memory->create(tb->afile,tb->ninput,"angle:afile");
memory->create(tb->efile,tb->ninput,"angle:efile");
memory->create(tb->ffile,tb->ninput,"angle:ffile");
// read a,e,f table values from file
int itmp;
fgets(line,MAXLINE,fp);
for (int i = 0; i < tb->ninput; i++) {
fgets(line,MAXLINE,fp);
sscanf(line,"%d %lg %lg %lg",
&itmp,&tb->afile[i],&tb->efile[i],&tb->ffile[i]);
}
fclose(fp);
}
/* ----------------------------------------------------------------------
build spline representation of e,f over entire range of read-in table
this function sets these values in e2file,f2file
------------------------------------------------------------------------- */
void AngleTable::spline_table(Table *tb)
{
memory->create(tb->e2file,tb->ninput,"angle:e2file");
memory->create(tb->f2file,tb->ninput,"angle:f2file");
double ep0 = - tb->ffile[0];
double epn = - tb->ffile[tb->ninput-1];
spline(tb->afile,tb->efile,tb->ninput,ep0,epn,tb->e2file);
if (tb->fpflag == 0) {
tb->fplo = (tb->ffile[1] - tb->ffile[0]) / (tb->afile[1] - tb->afile[0]);
tb->fphi = (tb->ffile[tb->ninput-1] - tb->ffile[tb->ninput-2]) /
(tb->afile[tb->ninput-1] - tb->afile[tb->ninput-2]);
}
double fp0 = tb->fplo;
double fpn = tb->fphi;
spline(tb->afile,tb->ffile,tb->ninput,fp0,fpn,tb->f2file);
}
/* ----------------------------------------------------------------------
compute a,e,f vectors from splined values
------------------------------------------------------------------------- */
void AngleTable::compute_table(Table *tb)
{
// delta = table spacing in angle for N-1 bins
int tlm1 = tablength-1;
tb->delta = MY_PI / tlm1;
tb->invdelta = 1.0/tb->delta;
tb->deltasq6 = tb->delta*tb->delta / 6.0;
// N-1 evenly spaced bins in angle from 0 to PI
// ang,e,f = value at lower edge of bin
// de,df values = delta values of e,f
// ang,e,f are N in length so de,df arrays can compute difference
memory->create(tb->ang,tablength,"angle:ang");
memory->create(tb->e,tablength,"angle:e");
memory->create(tb->de,tlm1,"angle:de");
memory->create(tb->f,tablength,"angle:f");
memory->create(tb->df,tlm1,"angle:df");
memory->create(tb->e2,tablength,"angle:e2");
memory->create(tb->f2,tablength,"angle:f2");
double a;
for (int i = 0; i < tablength; i++) {
a = i*tb->delta;
tb->ang[i] = a;
tb->e[i] = splint(tb->afile,tb->efile,tb->e2file,tb->ninput,a);
tb->f[i] = splint(tb->afile,tb->ffile,tb->f2file,tb->ninput,a);
}
for (int i = 0; i < tlm1; i++) {
tb->de[i] = tb->e[i+1] - tb->e[i];
tb->df[i] = tb->f[i+1] - tb->f[i];
}
double ep0 = - tb->f[0];
double epn = - tb->f[tlm1];
spline(tb->ang,tb->e,tablength,ep0,epn,tb->e2);
spline(tb->ang,tb->f,tablength,tb->fplo,tb->fphi,tb->f2);
}
/* ----------------------------------------------------------------------
extract attributes from parameter line in table section
format of line: N value FP fplo fphi EQ theta0
N is required, other params are optional
------------------------------------------------------------------------- */
void AngleTable::param_extract(Table *tb, char *line)
{
tb->ninput = 0;
tb->fpflag = 0;
tb->theta0 = 180.0;
char *word = strtok(line," \t\n\r\f");
while (word) {
if (strcmp(word,"N") == 0) {
word = strtok(NULL," \t\n\r\f");
tb->ninput = atoi(word);
} else if (strcmp(word,"FP") == 0) {
tb->fpflag = 1;
word = strtok(NULL," \t\n\r\f");
tb->fplo = atof(word);
word = strtok(NULL," \t\n\r\f");
tb->fphi = atof(word);
tb->fplo *= (180.0/MY_PI)*(180.0/MY_PI);
tb->fphi *= (180.0/MY_PI)*(180.0/MY_PI);
} else if (strcmp(word,"EQ") == 0) {
word = strtok(NULL," \t\n\r\f");
tb->theta0 = atof(word);
} else {
error->one(FLERR,"Invalid keyword in angle table parameters");
}
word = strtok(NULL," \t\n\r\f");
}
if (tb->ninput == 0) error->one(FLERR,"Angle table parameters did not set N");
}
/* ----------------------------------------------------------------------
broadcast read-in table info from proc 0 to other procs
this function communicates these values in Table:
ninput,afile,efile,ffile,fpflag,fplo,fphi,theta0
------------------------------------------------------------------------- */
void AngleTable::bcast_table(Table *tb)
{
MPI_Bcast(&tb->ninput,1,MPI_INT,0,world);
int me;
MPI_Comm_rank(world,&me);
if (me > 0) {
memory->create(tb->afile,tb->ninput,"angle:afile");
memory->create(tb->efile,tb->ninput,"angle:efile");
memory->create(tb->ffile,tb->ninput,"angle:ffile");
}
MPI_Bcast(tb->afile,tb->ninput,MPI_DOUBLE,0,world);
MPI_Bcast(tb->efile,tb->ninput,MPI_DOUBLE,0,world);
MPI_Bcast(tb->ffile,tb->ninput,MPI_DOUBLE,0,world);
MPI_Bcast(&tb->fpflag,1,MPI_INT,0,world);
if (tb->fpflag) {
MPI_Bcast(&tb->fplo,1,MPI_DOUBLE,0,world);
MPI_Bcast(&tb->fphi,1,MPI_DOUBLE,0,world);
}
MPI_Bcast(&tb->theta0,1,MPI_DOUBLE,0,world);
}
/* ----------------------------------------------------------------------
spline and splint routines modified from Numerical Recipes
------------------------------------------------------------------------- */
void AngleTable::spline(double *x, double *y, int n,
double yp1, double ypn, double *y2)
{
int i,k;
double p,qn,sig,un;
double *u = new double[n];
if (yp1 > 0.99e30) y2[0] = u[0] = 0.0;
else {
y2[0] = -0.5;
u[0] = (3.0/(x[1]-x[0])) * ((y[1]-y[0]) / (x[1]-x[0]) - yp1);
}
for (i = 1; i < n-1; i++) {
sig = (x[i]-x[i-1]) / (x[i+1]-x[i-1]);
p = sig*y2[i-1] + 2.0;
y2[i] = (sig-1.0) / p;
u[i] = (y[i+1]-y[i]) / (x[i+1]-x[i]) - (y[i]-y[i-1]) / (x[i]-x[i-1]);
u[i] = (6.0*u[i] / (x[i+1]-x[i-1]) - sig*u[i-1]) / p;
}
if (ypn > 0.99e30) qn = un = 0.0;
else {
qn = 0.5;
un = (3.0/(x[n-1]-x[n-2])) * (ypn - (y[n-1]-y[n-2]) / (x[n-1]-x[n-2]));
}
y2[n-1] = (un-qn*u[n-2]) / (qn*y2[n-2] + 1.0);
for (k = n-2; k >= 0; k--) y2[k] = y2[k]*y2[k+1] + u[k];
delete [] u;
}
/* ---------------------------------------------------------------------- */
double AngleTable::splint(double *xa, double *ya, double *y2a, int n, double x)
{
int klo,khi,k;
double h,b,a,y;
klo = 0;
khi = n-1;
while (khi-klo > 1) {
k = (khi+klo) >> 1;
if (xa[k] > x) khi = k;
else klo = k;
}
h = xa[khi]-xa[klo];
a = (xa[khi]-x) / h;
b = (x-xa[klo]) / h;
y = a*ya[klo] + b*ya[khi] +
((a*a*a-a)*y2a[klo] + (b*b*b-b)*y2a[khi]) * (h*h)/6.0;
return y;
}
/* ----------------------------------------------------------------------
calculate potential u and force f at angle x
------------------------------------------------------------------------- */
void AngleTable::uf_lookup(int type, double x, double &u, double &f)
{
int itable;
double fraction,a,b;
Table *tb = &tables[tabindex[type]];
if (tabstyle == LINEAR) {
itable = static_cast<int> ( x * tb->invdelta);
fraction = (x - tb->ang[itable]) * tb->invdelta;
u = tb->e[itable] + fraction*tb->de[itable];
f = tb->f[itable] + fraction*tb->df[itable];
} else if (tabstyle == SPLINE) {
itable = static_cast<int> ( x * tb->invdelta);
fraction = (x - tb->ang[itable]) * tb->invdelta;
b = (x - tb->ang[itable]) * tb->invdelta;
a = 1.0 - b;
u = a * tb->e[itable] + b * tb->e[itable+1] +
((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) *
tb->deltasq6;
f = a * tb->f[itable] + b * tb->f[itable+1] +
((a*a*a-a)*tb->f2[itable] + (b*b*b-b)*tb->f2[itable+1]) *
tb->deltasq6;
}
}
/* ----------------------------------------------------------------------
calculate potential u at angle x
------------------------------------------------------------------------- */
void AngleTable::u_lookup(int type, double x, double &u)
{
int itable;
double fraction,a,b;
Table *tb = &tables[tabindex[type]];
if (tabstyle == LINEAR) {
itable = static_cast<int> ( x * tb->invdelta);
fraction = (x - tb->ang[itable]) * tb->invdelta;
u = tb->e[itable] + fraction*tb->de[itable];
} else if (tabstyle == SPLINE) {
itable = static_cast<int> ( x * tb->invdelta);
fraction = (x - tb->ang[itable]) * tb->invdelta;
b = (x - tb->ang[itable]) * tb->invdelta;
a = 1.0 - b;
u = a * tb->e[itable] + b * tb->e[itable+1] +
((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) *
tb->deltasq6;
}
}
diff --git a/src/MOLECULE/atom_vec_angle.cpp b/src/MOLECULE/atom_vec_angle.cpp
index ceda77751..ceac39e34 100644
--- a/src/MOLECULE/atom_vec_angle.cpp
+++ b/src/MOLECULE/atom_vec_angle.cpp
@@ -1,853 +1,854 @@
/* ----------------------------------------------------------------------
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 "atom.h"
#include "comm.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#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(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
molecule = memory->grow(atom->molecule,nmax,"atom:molecule");
nspecial = memory->grow(atom->nspecial,nmax,3,"atom:nspecial");
special = memory->grow(atom->special,nmax,atom->maxspecial,"atom:special");
num_bond = memory->grow(atom->num_bond,nmax,"atom:num_bond");
bond_type = memory->grow(atom->bond_type,nmax,atom->bond_per_atom,
"atom:bond_type");
bond_atom = memory->grow(atom->bond_atom,nmax,atom->bond_per_atom,
"atom:bond_atom");
num_angle = memory->grow(atom->num_angle,nmax,"atom:num_angle");
angle_type = memory->grow(atom->angle_type,nmax,atom->angle_per_atom,
"atom:angle_type");
angle_atom1 = memory->grow(atom->angle_atom1,nmax,atom->angle_per_atom,
"atom:angle_atom1");
angle_atom2 = memory->grow(atom->angle_atom2,nmax,atom->angle_per_atom,
"atom:angle_atom2");
angle_atom3 = memory->grow(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;
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecAngle::copy(int i, int j, int delflag)
{
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,dvx,dvy,dvz;
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;
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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;
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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,dvx,dvy,dvz;
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];
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecAngle::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = molecule[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
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_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++)
molecule[i] = static_cast<int> (buf[m++]);
return 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 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];
+ *((tagint *) &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++]);
+ image[nlocal] = *((tagint *) &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];
+ *((tagint *) &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)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
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)
+void AtomVecAngle::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
molecule[nlocal] = atoi(values[1]);
type[nlocal] = atoi(values[2]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
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
------------------------------------------------------------------------- */
bigint AtomVecAngle::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax);
if (atom->memcheck("nspecial")) bytes += memory->usage(nspecial,nmax,3);
if (atom->memcheck("special"))
bytes += memory->usage(special,nmax,atom->maxspecial);
if (atom->memcheck("num_bond")) bytes += memory->usage(num_bond,nmax);
if (atom->memcheck("bond_type"))
bytes += memory->usage(bond_type,nmax,atom->bond_per_atom);
if (atom->memcheck("bond_atom"))
bytes += memory->usage(bond_atom,nmax,atom->bond_per_atom);
if (atom->memcheck("num_angle")) bytes += memory->usage(num_angle,nmax);
if (atom->memcheck("angle_type"))
bytes += memory->usage(angle_type,nmax,atom->angle_per_atom);
if (atom->memcheck("angle_atom1"))
bytes += memory->usage(angle_atom1,nmax,atom->angle_per_atom);
if (atom->memcheck("angle_atom2"))
bytes += memory->usage(angle_atom2,nmax,atom->angle_per_atom);
if (atom->memcheck("angle_atom3"))
bytes += memory->usage(angle_atom3,nmax,atom->angle_per_atom);
return bytes;
}
diff --git a/src/MOLECULE/atom_vec_angle.h b/src/MOLECULE/atom_vec_angle.h
index 8c4f71bc4..4fc203314 100644
--- a/src/MOLECULE/atom_vec_angle.h
+++ b/src/MOLECULE/atom_vec_angle.h
@@ -1,88 +1,89 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(angle,AtomVecAngle)
#else
#ifndef LMP_ATOM_VEC_ANGLE_H
#define LMP_ATOM_VEC_ANGLE_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecAngle : public AtomVec {
public:
AtomVecAngle(class LAMMPS *, int, char **);
virtual ~AtomVecAngle() {}
void grow(int);
void grow_reset();
void copy(int, int, int);
virtual int pack_comm(int, int *, double *, int, int *);
virtual int pack_comm_vel(int, int *, double *, int, int *);
virtual void unpack_comm(int, int, double *);
virtual void unpack_comm_vel(int, int, double *);
int pack_reverse(int, int, double *);
void unpack_reverse(int, int *, double *);
virtual int pack_border(int, int *, double *, int, int *);
virtual int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
virtual void unpack_border(int, int, double *);
virtual void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
virtual int pack_exchange(int, double *);
virtual int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
bigint memory_usage();
protected:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
int *molecule;
int **nspecial,**special;
int *num_bond;
int **bond_type,**bond_atom;
int *num_angle;
int **angle_type;
int **angle_atom1,**angle_atom2,**angle_atom3;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
*/
diff --git a/src/MOLECULE/atom_vec_bond.cpp b/src/MOLECULE/atom_vec_bond.cpp
index ee4aabb6f..16a2577bd 100644
--- a/src/MOLECULE/atom_vec_bond.cpp
+++ b/src/MOLECULE/atom_vec_bond.cpp
@@ -1,787 +1,788 @@
/* ----------------------------------------------------------------------
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 "atom.h"
#include "comm.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#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(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
molecule = memory->grow(atom->molecule,nmax,"atom:molecule");
nspecial = memory->grow(atom->nspecial,nmax,3,"atom:nspecial");
special = memory->grow(atom->special,nmax,atom->maxspecial,"atom:special");
num_bond = memory->grow(atom->num_bond,nmax,"atom:num_bond");
bond_type = memory->grow(atom->bond_type,nmax,atom->bond_per_atom,
"atom:bond_type");
bond_atom = memory->grow(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;
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecBond::copy(int i, int j, int delflag)
{
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,dvx,dvy,dvz;
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;
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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;
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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,dvx,dvy,dvz;
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];
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecBond::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = molecule[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
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_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++)
molecule[i] = static_cast<int> (buf[m++]);
return 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 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];
+ *((tagint *) &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++]);
+ image[nlocal] = *((tagint *) &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];
+ *((tagint *) &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)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
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)
+void AtomVecBond::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
molecule[nlocal] = atoi(values[1]);
type[nlocal] = atoi(values[2]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
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
------------------------------------------------------------------------- */
bigint AtomVecBond::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax);
if (atom->memcheck("nspecial")) bytes += memory->usage(nspecial,nmax,3);
if (atom->memcheck("special"))
bytes += memory->usage(special,nmax,atom->maxspecial);
if (atom->memcheck("num_bond")) bytes += memory->usage(num_bond,nmax);
if (atom->memcheck("bond_type"))
bytes += memory->usage(bond_type,nmax,atom->bond_per_atom);
if (atom->memcheck("bond_atom"))
bytes += memory->usage(bond_atom,nmax,atom->bond_per_atom);
return bytes;
}
diff --git a/src/MOLECULE/atom_vec_bond.h b/src/MOLECULE/atom_vec_bond.h
index 4ae9229df..0ccd38bbf 100644
--- a/src/MOLECULE/atom_vec_bond.h
+++ b/src/MOLECULE/atom_vec_bond.h
@@ -1,84 +1,85 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(bond,AtomVecBond)
#else
#ifndef LMP_ATOM_VEC_BOND_H
#define LMP_ATOM_VEC_BOND_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecBond : public AtomVec {
public:
AtomVecBond(class LAMMPS *, int, char **);
void grow(int);
void grow_reset();
void copy(int, int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int pack_reverse(int, int, double *);
void unpack_reverse(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
bigint memory_usage();
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
int *molecule;
int **nspecial,**special;
int *num_bond;
int **bond_type,**bond_atom;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
*/
diff --git a/src/MOLECULE/atom_vec_full.cpp b/src/MOLECULE/atom_vec_full.cpp
index 0a8a3785d..2e180714b 100644
--- a/src/MOLECULE/atom_vec_full.cpp
+++ b/src/MOLECULE/atom_vec_full.cpp
@@ -1,1034 +1,1035 @@
/* ----------------------------------------------------------------------
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 "atom.h"
#include "comm.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#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(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
q = memory->grow(atom->q,nmax,"atom:q");
molecule = memory->grow(atom->molecule,nmax,"atom:molecule");
nspecial = memory->grow(atom->nspecial,nmax,3,"atom:nspecial");
special = memory->grow(atom->special,nmax,atom->maxspecial,"atom:special");
num_bond = memory->grow(atom->num_bond,nmax,"atom:num_bond");
bond_type = memory->grow(atom->bond_type,nmax,atom->bond_per_atom,
"atom:bond_type");
bond_atom = memory->grow(atom->bond_atom,nmax,atom->bond_per_atom,
"atom:bond_atom");
num_angle = memory->grow(atom->num_angle,nmax,"atom:num_angle");
angle_type = memory->grow(atom->angle_type,nmax,atom->angle_per_atom,
"atom:angle_type");
angle_atom1 = memory->grow(atom->angle_atom1,nmax,atom->angle_per_atom,
"atom:angle_atom1");
angle_atom2 = memory->grow(atom->angle_atom2,nmax,atom->angle_per_atom,
"atom:angle_atom2");
angle_atom3 = memory->grow(atom->angle_atom3,nmax,atom->angle_per_atom,
"atom:angle_atom3");
num_dihedral = memory->grow(atom->num_dihedral,nmax,"atom:num_dihedral");
dihedral_type = memory->grow(atom->dihedral_type,nmax,
atom->dihedral_per_atom,"atom:dihedral_type");
dihedral_atom1 =
memory->grow(atom->dihedral_atom1,nmax,atom->dihedral_per_atom,
"atom:dihedral_atom1");
dihedral_atom2 =
memory->grow(atom->dihedral_atom2,nmax,atom->dihedral_per_atom,
"atom:dihedral_atom2");
dihedral_atom3 =
memory->grow(atom->dihedral_atom3,nmax,atom->dihedral_per_atom,
"atom:dihedral_atom3");
dihedral_atom4 =
memory->grow(atom->dihedral_atom4,nmax,atom->dihedral_per_atom,
"atom:dihedral_atom4");
num_improper = memory->grow(atom->num_improper,nmax,"atom:num_improper");
improper_type =
memory->grow(atom->improper_type,nmax,atom->improper_per_atom,
"atom:improper_type");
improper_atom1 =
memory->grow(atom->improper_atom1,nmax,atom->improper_per_atom,
"atom:improper_atom1");
improper_atom2 =
memory->grow(atom->improper_atom2,nmax,atom->improper_per_atom,
"atom:improper_atom2");
improper_atom3 =
memory->grow(atom->improper_atom3,nmax,atom->improper_per_atom,
"atom:improper_atom3");
improper_atom4 =
memory->grow(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;
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecFull::copy(int i, int j, int delflag)
{
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,dvx,dvy,dvz;
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;
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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;
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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,dvx,dvy,dvz;
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];
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecFull::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = q[j];
buf[m++] = molecule[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
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_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
q[i] = buf[m++];
molecule[i] = static_cast<int> (buf[m++]);
}
return 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 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];
+ *((tagint *) &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++]);
+ image[nlocal] = *((tagint *) &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];
+ *((tagint *) &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)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
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)
+void AtomVecFull::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
molecule[nlocal] = atoi(values[1]);
type[nlocal] = atoi(values[2]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
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
------------------------------------------------------------------------- */
bigint AtomVecFull::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("q")) bytes += memory->usage(q,nmax);
if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax);
if (atom->memcheck("nspecial")) bytes += memory->usage(nspecial,nmax,3);
if (atom->memcheck("special"))
bytes += memory->usage(special,nmax,atom->maxspecial);
if (atom->memcheck("num_bond")) bytes += memory->usage(num_bond,nmax);
if (atom->memcheck("bond_type"))
bytes += memory->usage(bond_type,nmax,atom->bond_per_atom);
if (atom->memcheck("bond_atom"))
bytes += memory->usage(bond_atom,nmax,atom->bond_per_atom);
if (atom->memcheck("num_angle")) bytes += memory->usage(num_angle,nmax);
if (atom->memcheck("angle_type"))
bytes += memory->usage(angle_type,nmax,atom->angle_per_atom);
if (atom->memcheck("angle_atom1"))
bytes += memory->usage(angle_atom1,nmax,atom->angle_per_atom);
if (atom->memcheck("angle_atom2"))
bytes += memory->usage(angle_atom2,nmax,atom->angle_per_atom);
if (atom->memcheck("angle_atom3"))
bytes += memory->usage(angle_atom3,nmax,atom->angle_per_atom);
if (atom->memcheck("num_dihedral")) bytes += memory->usage(num_dihedral,nmax);
if (atom->memcheck("dihedral_type"))
bytes += memory->usage(dihedral_type,nmax,atom->dihedral_per_atom);
if (atom->memcheck("dihedral_atom1"))
bytes += memory->usage(dihedral_atom1,nmax,atom->dihedral_per_atom);
if (atom->memcheck("dihedral_atom2"))
bytes += memory->usage(dihedral_atom2,nmax,atom->dihedral_per_atom);
if (atom->memcheck("dihedral_atom3"))
bytes += memory->usage(dihedral_atom3,nmax,atom->dihedral_per_atom);
if (atom->memcheck("dihedral_atom4"))
bytes += memory->usage(dihedral_atom4,nmax,atom->dihedral_per_atom);
if (atom->memcheck("num_improper")) bytes += memory->usage(num_improper,nmax);
if (atom->memcheck("improper_type"))
bytes += memory->usage(improper_type,nmax,atom->improper_per_atom);
if (atom->memcheck("improper_atom1"))
bytes += memory->usage(improper_atom1,nmax,atom->improper_per_atom);
if (atom->memcheck("improper_atom2"))
bytes += memory->usage(improper_atom2,nmax,atom->improper_per_atom);
if (atom->memcheck("improper_atom3"))
bytes += memory->usage(improper_atom3,nmax,atom->improper_per_atom);
if (atom->memcheck("improper_atom4"))
bytes += memory->usage(improper_atom4,nmax,atom->improper_per_atom);
return bytes;
}
diff --git a/src/MOLECULE/atom_vec_full.h b/src/MOLECULE/atom_vec_full.h
index 85203008a..2169b5db8 100644
--- a/src/MOLECULE/atom_vec_full.h
+++ b/src/MOLECULE/atom_vec_full.h
@@ -1,95 +1,96 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(full,AtomVecFull)
#else
#ifndef LMP_ATOM_VEC_FULL_H
#define LMP_ATOM_VEC_FULL_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecFull : public AtomVec {
public:
AtomVecFull(class LAMMPS *, int, char **);
virtual ~AtomVecFull() {}
void grow(int);
void grow_reset();
void copy(int, int, int);
virtual int pack_comm(int, int *, double *, int, int *);
virtual int pack_comm_vel(int, int *, double *, int, int *);
virtual void unpack_comm(int, int, double *);
virtual void unpack_comm_vel(int, int, double *);
int pack_reverse(int, int, double *);
void unpack_reverse(int, int *, double *);
virtual int pack_border(int, int *, double *, int, int *);
virtual int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
virtual void unpack_border(int, int, double *);
virtual void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
virtual int pack_exchange(int, double *);
virtual int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
bigint memory_usage();
protected:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
double *q;
int *molecule;
int **nspecial,**special;
int *num_bond;
int **bond_type,**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;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
*/
diff --git a/src/MOLECULE/atom_vec_molecular.cpp b/src/MOLECULE/atom_vec_molecular.cpp
index c2d2ca9fc..5d5cb0df2 100644
--- a/src/MOLECULE/atom_vec_molecular.cpp
+++ b/src/MOLECULE/atom_vec_molecular.cpp
@@ -1,1013 +1,1014 @@
/* ----------------------------------------------------------------------
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 "atom.h"
#include "comm.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#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(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
molecule = memory->grow(atom->molecule,nmax,"atom:molecule");
nspecial = memory->grow(atom->nspecial,nmax,3,"atom:nspecial");
special = memory->grow(atom->special,nmax,atom->maxspecial,"atom:special");
num_bond = memory->grow(atom->num_bond,nmax,"atom:num_bond");
bond_type = memory->grow(atom->bond_type,nmax,atom->bond_per_atom,
"atom:bond_type");
bond_atom = memory->grow(atom->bond_atom,nmax,atom->bond_per_atom,
"atom:bond_atom");
num_angle = memory->grow(atom->num_angle,nmax,"atom:num_angle");
angle_type = memory->grow(atom->angle_type,nmax,atom->angle_per_atom,
"atom:angle_type");
angle_atom1 = memory->grow(atom->angle_atom1,nmax,atom->angle_per_atom,
"atom:angle_atom1");
angle_atom2 = memory->grow(atom->angle_atom2,nmax,atom->angle_per_atom,
"atom:angle_atom2");
angle_atom3 = memory->grow(atom->angle_atom3,nmax,atom->angle_per_atom,
"atom:angle_atom3");
num_dihedral = memory->grow(atom->num_dihedral,nmax,"atom:num_dihedral");
dihedral_type = memory->grow(atom->dihedral_type,nmax,
atom->dihedral_per_atom,"atom:dihedral_type");
dihedral_atom1 =
memory->grow(atom->dihedral_atom1,nmax,atom->dihedral_per_atom,
"atom:dihedral_atom1");
dihedral_atom2 =
memory->grow(atom->dihedral_atom2,nmax,atom->dihedral_per_atom,
"atom:dihedral_atom2");
dihedral_atom3 =
memory->grow(atom->dihedral_atom3,nmax,atom->dihedral_per_atom,
"atom:dihedral_atom3");
dihedral_atom4 =
memory->grow(atom->dihedral_atom4,nmax,atom->dihedral_per_atom,
"atom:dihedral_atom4");
num_improper = memory->grow(atom->num_improper,nmax,"atom:num_improper");
improper_type =
memory->grow(atom->improper_type,nmax,atom->improper_per_atom,
"atom:improper_type");
improper_atom1 =
memory->grow(atom->improper_atom1,nmax,atom->improper_per_atom,
"atom:improper_atom1");
improper_atom2 =
memory->grow(atom->improper_atom2,nmax,atom->improper_per_atom,
"atom:improper_atom2");
improper_atom3 =
memory->grow(atom->improper_atom3,nmax,atom->improper_per_atom,
"atom:improper_atom3");
improper_atom4 =
memory->grow(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;
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecMolecular::copy(int i, int j, int delflag)
{
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,dvx,dvy,dvz;
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;
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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;
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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,dvx,dvy,dvz;
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];
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecMolecular::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = molecule[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
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_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++)
molecule[i] = static_cast<int> (buf[m++]);
return 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 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];
+ *((tagint *) &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++]);
+ image[nlocal] = *((tagint *) &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];
+ *((tagint *) &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)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
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)
+void AtomVecMolecular::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
molecule[nlocal] = atoi(values[1]);
type[nlocal] = atoi(values[2]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
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
------------------------------------------------------------------------- */
bigint AtomVecMolecular::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax);
if (atom->memcheck("nspecial")) bytes += memory->usage(nspecial,nmax,3);
if (atom->memcheck("special"))
bytes += memory->usage(special,nmax,atom->maxspecial);
if (atom->memcheck("num_bond")) bytes += memory->usage(num_bond,nmax);
if (atom->memcheck("bond_type"))
bytes += memory->usage(bond_type,nmax,atom->bond_per_atom);
if (atom->memcheck("bond_atom"))
bytes += memory->usage(bond_atom,nmax,atom->bond_per_atom);
if (atom->memcheck("num_angle")) bytes += memory->usage(num_angle,nmax);
if (atom->memcheck("angle_type"))
bytes += memory->usage(angle_type,nmax,atom->angle_per_atom);
if (atom->memcheck("angle_atom1"))
bytes += memory->usage(angle_atom1,nmax,atom->angle_per_atom);
if (atom->memcheck("angle_atom2"))
bytes += memory->usage(angle_atom2,nmax,atom->angle_per_atom);
if (atom->memcheck("angle_atom3"))
bytes += memory->usage(angle_atom3,nmax,atom->angle_per_atom);
if (atom->memcheck("num_dihedral")) bytes += memory->usage(num_dihedral,nmax);
if (atom->memcheck("dihedral_type"))
bytes += memory->usage(dihedral_type,nmax,atom->dihedral_per_atom);
if (atom->memcheck("dihedral_atom1"))
bytes += memory->usage(dihedral_atom1,nmax,atom->dihedral_per_atom);
if (atom->memcheck("dihedral_atom2"))
bytes += memory->usage(dihedral_atom2,nmax,atom->dihedral_per_atom);
if (atom->memcheck("dihedral_atom3"))
bytes += memory->usage(dihedral_atom3,nmax,atom->dihedral_per_atom);
if (atom->memcheck("dihedral_atom4"))
bytes += memory->usage(dihedral_atom4,nmax,atom->dihedral_per_atom);
if (atom->memcheck("num_improper")) bytes += memory->usage(num_improper,nmax);
if (atom->memcheck("improper_type"))
bytes += memory->usage(improper_type,nmax,atom->improper_per_atom);
if (atom->memcheck("improper_atom1"))
bytes += memory->usage(improper_atom1,nmax,atom->improper_per_atom);
if (atom->memcheck("improper_atom2"))
bytes += memory->usage(improper_atom2,nmax,atom->improper_per_atom);
if (atom->memcheck("improper_atom3"))
bytes += memory->usage(improper_atom3,nmax,atom->improper_per_atom);
if (atom->memcheck("improper_atom4"))
bytes += memory->usage(improper_atom4,nmax,atom->improper_per_atom);
return bytes;
}
diff --git a/src/MOLECULE/atom_vec_molecular.h b/src/MOLECULE/atom_vec_molecular.h
index 4a40f5f26..7f165bda3 100644
--- a/src/MOLECULE/atom_vec_molecular.h
+++ b/src/MOLECULE/atom_vec_molecular.h
@@ -1,93 +1,94 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(molecular,AtomVecMolecular)
#else
#ifndef LMP_ATOM_VEC_MOLECULAR_H
#define LMP_ATOM_VEC_MOLECULAR_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecMolecular : public AtomVec {
public:
AtomVecMolecular(class LAMMPS *, int, char **);
void grow(int);
void grow_reset();
void copy(int, int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int pack_reverse(int, int, double *);
void unpack_reverse(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
bigint memory_usage();
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
int *molecule;
int **nspecial,**special;
int *num_bond;
int **bond_type,**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;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
*/
diff --git a/src/MOLECULE/bond_fene.cpp b/src/MOLECULE/bond_fene.cpp
index 27880ee1e..41d81f5e1 100644
--- a/src/MOLECULE/bond_fene.cpp
+++ b/src/MOLECULE/bond_fene.cpp
@@ -1,262 +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 "math.h"
#include "stdlib.h"
#include "bond_fene.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->destroy(setflag);
memory->destroy(k);
memory->destroy(r0);
memory->destroy(epsilon);
memory->destroy(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: " BIGINT_FORMAT " %d %d %g",
update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
error->warning(FLERR,str,0);
if (rlogarg <= -3.0) error->one(FLERR,"Bad FENE bond");
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;
memory->create(k,n+1,"bond:k");
memory->create(r0,n+1,"bond:r0");
memory->create(epsilon,n+1,"bond:epsilon");
memory->create(sigma,n+1,"bond:sigma");
memory->create(setflag,n+1,"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(FLERR,"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(FLERR,"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(FLERR,"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: " BIGINT_FORMAT " %g",
update->ntimestep,sqrt(rsq));
error->warning(FLERR,str,0);
if (rlogarg <= -3.0) error->one(FLERR,"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 6b80478e5..a8051468a 100644
--- a/src/MOLECULE/bond_fene_expand.cpp
+++ b/src/MOLECULE/bond_fene_expand.cpp
@@ -1,276 +1,275 @@
/* ----------------------------------------------------------------------
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 "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->destroy(setflag);
memory->destroy(k);
memory->destroy(r0);
memory->destroy(epsilon);
memory->destroy(sigma);
memory->destroy(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: " BIGINT_FORMAT " %d %d %g",
update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
error->warning(FLERR,str,0);
if (rlogarg <= -3.0) error->one(FLERR,"Bad FENE bond");
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;
memory->create(k,n+1,"bond:k");
memory->create(r0,n+1,"bond:r0");
memory->create(epsilon,n+1,"bond:epsilon");
memory->create(sigma,n+1,"bond:sigma");
memory->create(shift,n+1,"bond:shift");
memory->create(setflag,n+1,"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(FLERR,"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(FLERR,"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(FLERR,"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: " BIGINT_FORMAT " %g",
update->ntimestep,sqrt(rsq));
error->warning(FLERR,str,0);
if (rlogarg <= -3.0) error->one(FLERR,"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/bond_harmonic.cpp b/src/MOLECULE/bond_harmonic.cpp
index ab67e8bec..4fb18d13c 100644
--- a/src/MOLECULE/bond_harmonic.cpp
+++ b/src/MOLECULE/bond_harmonic.cpp
@@ -1,186 +1,185 @@
/* ----------------------------------------------------------------------
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_harmonic.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondHarmonic::BondHarmonic(LAMMPS *lmp) : Bond(lmp) {}
/* ---------------------------------------------------------------------- */
BondHarmonic::~BondHarmonic()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(r0);
}
}
/* ---------------------------------------------------------------------- */
void BondHarmonic::compute(int eflag, int vflag)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,rk;
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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
dr = r - r0[type];
rk = k[type] * dr;
// force & energy
if (r > 0.0) fbond = -2.0*rk/r;
else fbond = 0.0;
if (eflag) ebond = rk*dr;
// 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 BondHarmonic::allocate()
{
allocated = 1;
int n = atom->nbondtypes;
memory->create(k,n+1,"bond:k");
memory->create(r0,n+1,"bond:r0");
memory->create(setflag,n+1,"bond:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void BondHarmonic::coeff(int narg, char **arg)
{
if (narg != 3) error->all(FLERR,"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]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
r0[i] = r0_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients");
}
/* ----------------------------------------------------------------------
return an equilbrium bond length
------------------------------------------------------------------------- */
double BondHarmonic::equilibrium_distance(int i)
{
return r0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void BondHarmonic::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void BondHarmonic::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);
}
MPI_Bcast(&k[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&r0[1],atom->nbondtypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double BondHarmonic::single(int type, double rsq, int i, int j)
{
double r = sqrt(rsq);
double dr = r - r0[type];
double rk = k[type] * dr;
return rk*dr;
}
diff --git a/src/MOLECULE/bond_morse.cpp b/src/MOLECULE/bond_morse.cpp
index 070c30113..22d290924 100644
--- a/src/MOLECULE/bond_morse.cpp
+++ b/src/MOLECULE/bond_morse.cpp
@@ -1,196 +1,195 @@
/* ----------------------------------------------------------------------
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: Jeff Greathouse (SNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "bond_morse.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondMorse::BondMorse(LAMMPS *lmp) : Bond(lmp) {}
/* ---------------------------------------------------------------------- */
BondMorse::~BondMorse()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(d0);
memory->destroy(alpha);
memory->destroy(r0);
}
}
/* ---------------------------------------------------------------------- */
void BondMorse::compute(int eflag, int vflag)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,ralpha;
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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
dr = r - r0[type];
ralpha = exp(-alpha[type]*dr);
// force & energy
if (r > 0.0) fbond = -2.0*d0[type]*alpha[type]*(1-ralpha)*ralpha/r;
else fbond = 0.0;
if (eflag) ebond = d0[type]*(1-ralpha)*(1-ralpha);
// 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 BondMorse::allocate()
{
allocated = 1;
int n = atom->nbondtypes;
memory->create(d0,n+1,"bond:d0");
memory->create(alpha,n+1,"bond:alpha");
memory->create(r0,n+1,"bond:r0");
memory->create(setflag,n+1,"bond:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one type
------------------------------------------------------------------------- */
void BondMorse::coeff(int narg, char **arg)
{
if (narg != 4) error->all(FLERR,"Incorrect args for bond coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nbondtypes,ilo,ihi);
double d0_one = force->numeric(arg[1]);
double alpha_one = force->numeric(arg[2]);
double r0_one = force->numeric(arg[3]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
d0[i] = d0_one;
alpha[i] = alpha_one;
r0[i] = r0_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients");
}
/* ----------------------------------------------------------------------
return an equilbrium bond length
------------------------------------------------------------------------- */
double BondMorse::equilibrium_distance(int i)
{
return r0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void BondMorse::write_restart(FILE *fp)
{
fwrite(&d0[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&alpha[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void BondMorse::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&d0[1],sizeof(double),atom->nbondtypes,fp);
fread(&alpha[1],sizeof(double),atom->nbondtypes,fp);
fread(&r0[1],sizeof(double),atom->nbondtypes,fp);
}
MPI_Bcast(&d0[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&alpha[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&r0[1],atom->nbondtypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double BondMorse::single(int type, double rsq, int i, int j)
{
double r = sqrt(rsq);
double dr = r - r0[type];
double ralpha = exp(-alpha[type]*dr);
return d0[type]*(1-ralpha)*(1-ralpha);
}
diff --git a/src/MOLECULE/bond_nonlinear.cpp b/src/MOLECULE/bond_nonlinear.cpp
index 5bc12e650..6577d4380 100644
--- a/src/MOLECULE/bond_nonlinear.cpp
+++ b/src/MOLECULE/bond_nonlinear.cpp
@@ -1,193 +1,192 @@
/* ----------------------------------------------------------------------
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_nonlinear.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondNonlinear::BondNonlinear(LAMMPS *lmp) : Bond(lmp) {}
/* ---------------------------------------------------------------------- */
BondNonlinear::~BondNonlinear()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(epsilon);
memory->destroy(r0);
memory->destroy(lamda);
}
}
/* ---------------------------------------------------------------------- */
void BondNonlinear::compute(int eflag, int vflag)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,drsq,lamdasq,denom,denomsq;
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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
dr = r - r0[type];
drsq = dr*dr;
lamdasq = lamda[type]*lamda[type];
denom = lamdasq - drsq;
denomsq = denom*denom;
// force & energy
fbond = -epsilon[type]/r * 2.0*dr*lamdasq/denomsq;
if (eflag) ebond = epsilon[type] * drsq / denom;
// 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 BondNonlinear::allocate()
{
allocated = 1;
int n = atom->nbondtypes;
memory->create(epsilon,n+1,"bond:epsilon");
memory->create(r0,n+1,"bond:r0");
memory->create(lamda,n+1,"bond:lamda");
memory->create(setflag,n+1,"bond:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one type
------------------------------------------------------------------------- */
void BondNonlinear::coeff(int narg, char **arg)
{
if (narg != 4) error->all(FLERR,"Incorrect args for bond coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nbondtypes,ilo,ihi);
double epsilon_one = force->numeric(arg[1]);
double r0_one = force->numeric(arg[2]);
double lamda_one = force->numeric(arg[3]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
epsilon[i] = epsilon_one;
r0[i] = r0_one;
lamda[i] = lamda_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients");
}
/* ---------------------------------------------------------------------- */
double BondNonlinear::equilibrium_distance(int i)
{
return r0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void BondNonlinear::write_restart(FILE *fp)
{
fwrite(&epsilon[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&lamda[1],sizeof(double),atom->nbondtypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void BondNonlinear::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&epsilon[1],sizeof(double),atom->nbondtypes,fp);
fread(&r0[1],sizeof(double),atom->nbondtypes,fp);
fread(&lamda[1],sizeof(double),atom->nbondtypes,fp);
}
MPI_Bcast(&epsilon[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&r0[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&lamda[1],atom->nbondtypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double BondNonlinear::single(int type, double rsq, int i, int j)
{
double r = sqrt(rsq);
double dr = r - r0[type];
double drsq = dr*dr;
double lamdasq = lamda[type]*lamda[type];
double denom = lamdasq - drsq;
return epsilon[type] * drsq / denom;
}
diff --git a/src/MOLECULE/bond_quartic.cpp b/src/MOLECULE/bond_quartic.cpp
index 8b5264bac..9c49a5e51 100644
--- a/src/MOLECULE/bond_quartic.cpp
+++ b/src/MOLECULE/bond_quartic.cpp
@@ -1,336 +1,335 @@
/* ----------------------------------------------------------------------
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: Chris Lorenz and Mark Stevens (SNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "bond_quartic.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "update.h"
#include "force.h"
#include "pair.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondQuartic::BondQuartic(LAMMPS *lmp) : Bond(lmp)
{
TWO_1_3 = pow(2.0,(1.0/3.0));
}
/* ---------------------------------------------------------------------- */
BondQuartic::~BondQuartic()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(b1);
memory->destroy(b2);
memory->destroy(rc);
memory->destroy(u0);
}
}
/* ---------------------------------------------------------------------- */
void BondQuartic::compute(int eflag, int vflag)
{
int i1,i2,n,m,type,itype,jtype;
double delx,dely,delz,ebond,fbond,evdwl,fpair;
double r,rsq,dr,r2,ra,rb,sr2,sr6;
ebond = evdwl = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
// insure pair->ev_tally() will use 1-4 virial contribution
if (vflag_global == 2)
force->pair->vflag_either = force->pair->vflag_global = 1;
double **cutsq = force->pair->cutsq;
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++) {
// skip bond if already broken
if (bondlist[n][2] <= 0) continue;
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);
rsq = delx*delx + dely*dely + delz*delz;
// if bond breaks, set type to 0
// both in temporary bondlist and permanent bond_type
// if this proc owns both atoms,
// negate bond_type twice if other atom stores it
// if other proc owns 2nd atom, other proc will also break bond
if (rsq > rc[type]*rc[type]) {
bondlist[n][2] = 0;
for (m = 0; m < atom->num_bond[i1]; m++)
if (atom->bond_atom[i1][m] == atom->tag[i2])
atom->bond_type[i1][m] = 0;
if (i2 < atom->nlocal)
for (m = 0; m < atom->num_bond[i2]; m++)
if (atom->bond_atom[i2][m] == atom->tag[i1])
atom->bond_type[i2][m] = 0;
continue;
}
// quartic bond
// 1st portion is from quartic term
// 2nd portion is from LJ term cut at 2^(1/6) with eps = sigma = 1.0
r = sqrt(rsq);
dr = r - rc[type];
r2 = dr*dr;
ra = dr - b1[type];
rb = dr - b2[type];
fbond = -k[type]/r * (r2*(ra+rb) + 2.0*dr*ra*rb);
if (rsq < TWO_1_3) {
sr2 = 1.0/rsq;
sr6 = sr2*sr2*sr2;
fbond += 48.0*sr6*(sr6-0.5)/rsq;
}
if (eflag) {
ebond = k[type]*r2*ra*rb + u0[type];
if (rsq < TWO_1_3) ebond += 4.0*sr6*(sr6-1.0) + 1.0;
}
// 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);
// subtract out pairwise contribution from 2 atoms via pair->single()
// required since special_bond = 1,1,1
// tally energy/virial in pair, using newton_bond as newton flag
itype = atom->type[i1];
jtype = atom->type[i2];
if (rsq < cutsq[itype][jtype]) {
evdwl = -force->pair->single(i1,i2,itype,jtype,rsq,1.0,1.0,fpair);
fpair = -fpair;
if (newton_bond || i1 < nlocal) {
f[i1][0] += delx*fpair;
f[i1][1] += dely*fpair;
f[i1][2] += delz*fpair;
}
if (newton_bond || i2 < nlocal) {
f[i2][0] -= delx*fpair;
f[i2][1] -= dely*fpair;
f[i2][2] -= delz*fpair;
}
if (evflag) force->pair->ev_tally(i1,i2,nlocal,newton_bond,
evdwl,0.0,fpair,delx,dely,delz);
}
}
}
/* ---------------------------------------------------------------------- */
void BondQuartic::allocate()
{
allocated = 1;
int n = atom->nbondtypes;
memory->create(k,n+1,"bond:k");
memory->create(b1,n+1,"bond:b1");
memory->create(b2,n+1,"bond:b2");
memory->create(rc,n+1,"bond:rc");
memory->create(u0,n+1,"bond:u0");
memory->create(setflag,n+1,"bond:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void BondQuartic::coeff(int narg, char **arg)
{
if (narg != 6) error->all(FLERR,"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 b1_one = force->numeric(arg[2]);
double b2_one = force->numeric(arg[3]);
double rc_one = force->numeric(arg[4]);
double u0_one = force->numeric(arg[5]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
b1[i] = b1_one;
b2[i] = b2_one;
rc[i] = rc_one;
u0[i] = u0_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients");
}
/* ----------------------------------------------------------------------
check if pair defined and special_bond settings are valid
------------------------------------------------------------------------- */
void BondQuartic::init_style()
{
if (force->pair == NULL || force->pair->single_enable == 0)
error->all(FLERR,"Pair style does not support bond_style quartic");
if (force->angle)
error->all(FLERR,"Bond style quartic cannot be used with 3,4-body interactions");
if (force->dihedral)
error->all(FLERR,"Bond style quartic cannot be used with 3,4-body interactions");
if (force->improper)
error->all(FLERR,"Bond style quartic cannot be used with 3,4-body interactions");
// special bonds must be 1 1 1
if (force->special_lj[1] != 1.0 || force->special_lj[2] != 1.0 ||
force->special_lj[3] != 1.0)
error->all(FLERR,"Bond style quartic requires special_bonds = 1,1,1");
}
/* ----------------------------------------------------------------------
return an equilbrium bond length
------------------------------------------------------------------------- */
double BondQuartic::equilibrium_distance(int i)
{
return 0.97;
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void BondQuartic::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&b1[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&b2[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&rc[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&u0[1],sizeof(double),atom->nbondtypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void BondQuartic::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&k[1],sizeof(double),atom->nbondtypes,fp);
fread(&b1[1],sizeof(double),atom->nbondtypes,fp);
fread(&b2[1],sizeof(double),atom->nbondtypes,fp);
fread(&rc[1],sizeof(double),atom->nbondtypes,fp);
fread(&u0[1],sizeof(double),atom->nbondtypes,fp);
}
MPI_Bcast(&k[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&b1[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&b2[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&rc[1],atom->nbondtypes,MPI_DOUBLE,0,world);
MPI_Bcast(&u0[1],atom->nbondtypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double BondQuartic::single(int type, double rsq, int i, int j)
{
double r,dr,r2,ra,rb,sr2,sr6;
if (type <= 0) return 0.0;
double eng = 0.0;
// subtract out pairwise contribution from 2 atoms via pair->single()
// required since special_bond = 1,1,1
int itype = atom->type[i];
int jtype = atom->type[j];
if (rsq < force->pair->cutsq[itype][jtype]) {
double tmp;
eng = -force->pair->single(i,j,itype,jtype,rsq,1.0,1.0,tmp);
}
// quartic bond
// 1st portion is from quartic term
// 2nd portion is from LJ term cut at 2^(1/6) with eps = sigma = 1.0
r = sqrt(rsq);
dr = r - rc[type];
r2 = dr*dr;
ra = dr - b1[type];
rb = dr - b2[type];
eng += k[type]*r2*ra*rb + u0[type];
if (rsq < TWO_1_3) {
sr2 = 1.0/rsq;
sr6 = sr2*sr2*sr2;
eng += 4.0*sr6*(sr6-1.0) + 1.0;
}
return eng;
}
diff --git a/src/MOLECULE/bond_table.cpp b/src/MOLECULE/bond_table.cpp
index 19b3f6640..1f83c7980 100644
--- a/src/MOLECULE/bond_table.cpp
+++ b/src/MOLECULE/bond_table.cpp
@@ -1,590 +1,589 @@
/* ----------------------------------------------------------------------
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: Chuanfu Luo (luochuanfu@gmail.com)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "bond_table.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
enum{LINEAR,SPLINE};
#define MAXLINE 1024
/* ---------------------------------------------------------------------- */
BondTable::BondTable(LAMMPS *lmp) : Bond(lmp)
{
ntables = 0;
tables = NULL;
}
/* ---------------------------------------------------------------------- */
BondTable::~BondTable()
{
for (int m = 0; m < ntables; m++) free_table(&tables[m]);
memory->sfree(tables);
if (allocated) {
memory->destroy(setflag);
memory->destroy(r0);
memory->destroy(tabindex);
}
}
/* ---------------------------------------------------------------------- */
void BondTable::compute(int eflag, int vflag)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r;
double u,mdu;
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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
// force & energy
uf_lookup(type,r,u,mdu);
fbond = mdu/r;
ebond = u;
// 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 BondTable::allocate()
{
allocated = 1;
int n = atom->nbondtypes;
memory->create(tabindex,n+1,"bond:tabindex");
memory->create(r0,n+1,"bond:r0");
memory->create(setflag,n+1,"bond:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void BondTable::settings(int narg, char **arg)
{
if (narg != 2) error->all(FLERR,"Illegal bond_style command");
if (strcmp(arg[0],"linear") == 0) tabstyle = LINEAR;
else if (strcmp(arg[0],"spline") == 0) tabstyle = SPLINE;
else error->all(FLERR,"Unknown table style in bond style table");
tablength = force->inumeric(arg[1]);
if (tablength < 2) error->all(FLERR,"Illegal number of bond table entries");
// delete old tables, since cannot just change settings
for (int m = 0; m < ntables; m++) free_table(&tables[m]);
memory->sfree(tables);
if (allocated) {
memory->destroy(setflag);
memory->destroy(tabindex);
}
allocated = 0;
ntables = 0;
tables = NULL;
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void BondTable::coeff(int narg, char **arg)
{
if (narg != 3) error->all(FLERR,"Illegal bond_coeff command");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nbondtypes,ilo,ihi);
int me;
MPI_Comm_rank(world,&me);
tables = (Table *)
memory->srealloc(tables,(ntables+1)*sizeof(Table),"bond:tables");
Table *tb = &tables[ntables];
null_table(tb);
if (me == 0) read_table(tb,arg[1],arg[2]);
bcast_table(tb);
// error check on table parameters
if (tb->ninput <= 1) error->one(FLERR,"Invalid bond table length");
tb->lo = tb->rfile[0];
tb->hi = tb->rfile[tb->ninput-1];
if (tb->lo >= tb->hi) error->all(FLERR,"Bond table values are not increasing");
// spline read-in and compute r,e,f vectors within table
spline_table(tb);
compute_table(tb);
// store ptr to table in tabindex
int count = 0;
for (int i = ilo; i <= ihi; i++) {
tabindex[i] = ntables;
r0[i] = tb->r0;
setflag[i] = 1;
count++;
}
ntables++;
if (count == 0) error->all(FLERR,"Illegal bond_coeff command");
}
/* ----------------------------------------------------------------------
return an equilbrium bond length
should not be used, since don't know minimum of tabulated function
------------------------------------------------------------------------- */
double BondTable::equilibrium_distance(int i)
{
return r0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void BondTable::write_restart(FILE *fp)
{
fwrite(&tabstyle,sizeof(int),1,fp);
fwrite(&tablength,sizeof(int),1,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void BondTable::read_restart(FILE *fp)
{
if (comm->me == 0) {
fread(&tabstyle,sizeof(int),1,fp);
fread(&tablength,sizeof(int),1,fp);
}
MPI_Bcast(&tabstyle,1,MPI_INT,0,world);
MPI_Bcast(&tablength,1,MPI_INT,0,world);
allocate();
}
/* ---------------------------------------------------------------------- */
double BondTable::single(int type, double rsq, int i, int j)
{
double r = sqrt(rsq);
double u;
u_lookup(type,r,u);
return u;
}
/* ---------------------------------------------------------------------- */
void BondTable::null_table(Table *tb)
{
tb->rfile = tb->efile = tb->ffile = NULL;
tb->e2file = tb->f2file = NULL;
tb->r = tb->e = tb->de = NULL;
tb->f = tb->df = tb->e2 = tb->f2 = NULL;
}
/* ---------------------------------------------------------------------- */
void BondTable::free_table(Table *tb)
{
memory->destroy(tb->rfile);
memory->destroy(tb->efile);
memory->destroy(tb->ffile);
memory->destroy(tb->e2file);
memory->destroy(tb->f2file);
memory->destroy(tb->r);
memory->destroy(tb->e);
memory->destroy(tb->de);
memory->destroy(tb->f);
memory->destroy(tb->df);
memory->destroy(tb->e2);
memory->destroy(tb->f2);
}
/* ----------------------------------------------------------------------
read table file, only called by proc 0
------------------------------------------------------------------------- */
void BondTable::read_table(Table *tb, char *file, char *keyword)
{
char line[MAXLINE];
// open file
FILE *fp = fopen(file,"r");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open file %s",file);
error->one(FLERR,str);
}
// loop until section found with matching keyword
while (1) {
if (fgets(line,MAXLINE,fp) == NULL)
error->one(FLERR,"Did not find keyword in table file");
if (strspn(line," \t\n") == strlen(line)) continue; // blank line
if (line[0] == '#') continue; // comment
if (strstr(line,keyword) == line) break; // matching keyword
fgets(line,MAXLINE,fp); // no match, skip section
param_extract(tb,line);
fgets(line,MAXLINE,fp);
for (int i = 0; i < tb->ninput; i++) fgets(line,MAXLINE,fp);
}
// read args on 2nd line of section
// allocate table arrays for file values
fgets(line,MAXLINE,fp);
param_extract(tb,line);
memory->create(tb->rfile,tb->ninput,"bond:rfile");
memory->create(tb->efile,tb->ninput,"bond:efile");
memory->create(tb->ffile,tb->ninput,"bond:ffile");
// read r,e,f table values from file
int itmp;
fgets(line,MAXLINE,fp);
for (int i = 0; i < tb->ninput; i++) {
fgets(line,MAXLINE,fp);
sscanf(line,"%d %lg %lg %lg",
&itmp,&tb->rfile[i],&tb->efile[i],&tb->ffile[i]);
}
fclose(fp);
}
/* ----------------------------------------------------------------------
build spline representation of e,f over entire range of read-in table
this function sets these values in e2file,f2file
------------------------------------------------------------------------- */
void BondTable::spline_table(Table *tb)
{
memory->create(tb->e2file,tb->ninput,"bond:e2file");
memory->create(tb->f2file,tb->ninput,"bond:f2file");
double ep0 = - tb->ffile[0];
double epn = - tb->ffile[tb->ninput-1];
spline(tb->rfile,tb->efile,tb->ninput,ep0,epn,tb->e2file);
if (tb->fpflag == 0) {
tb->fplo = (tb->ffile[1] - tb->ffile[0]) / (tb->rfile[1] - tb->rfile[0]);
tb->fphi = (tb->ffile[tb->ninput-1] - tb->ffile[tb->ninput-2]) /
(tb->rfile[tb->ninput-1] - tb->rfile[tb->ninput-2]);
}
double fp0 = tb->fplo;
double fpn = tb->fphi;
spline(tb->rfile,tb->ffile,tb->ninput,fp0,fpn,tb->f2file);
}
/* ----------------------------------------------------------------------
compute r,e,f vectors from splined values
------------------------------------------------------------------------- */
void BondTable::compute_table(Table *tb)
{
// delta = table spacing for N-1 bins
int tlm1 = tablength-1;
tb->delta = (tb->hi - tb->lo)/ tlm1;
tb->invdelta = 1.0/tb->delta;
tb->deltasq6 = tb->delta*tb->delta / 6.0;
// N-1 evenly spaced bins in r from min to max
// r,e,f = value at lower edge of bin
// de,df values = delta values of e,f
// r,e,f are N in length so de,df arrays can compute difference
memory->create(tb->r,tablength,"bond:r");
memory->create(tb->e,tablength,"bond:e");
memory->create(tb->de,tlm1,"bond:de");
memory->create(tb->f,tablength,"bond:f");
memory->create(tb->df,tlm1,"bond:df");
memory->create(tb->e2,tablength,"bond:e2");
memory->create(tb->f2,tablength,"bond:f2");
double a;
for (int i = 0; i < tablength; i++) {
a = tb->lo + i*tb->delta;
tb->r[i] = a;
tb->e[i] = splint(tb->rfile,tb->efile,tb->e2file,tb->ninput,a);
tb->f[i] = splint(tb->rfile,tb->ffile,tb->f2file,tb->ninput,a);
}
for (int i = 0; i < tlm1; i++) {
tb->de[i] = tb->e[i+1] - tb->e[i];
tb->df[i] = tb->f[i+1] - tb->f[i];
}
double ep0 = - tb->f[0];
double epn = - tb->f[tlm1];
spline(tb->r,tb->e,tablength,ep0,epn,tb->e2);
spline(tb->r,tb->f,tablength,tb->fplo,tb->fphi,tb->f2);
}
/* ----------------------------------------------------------------------
extract attributes from parameter line in table section
format of line: N value FP fplo fphi EQ r0
N is required, other params are optional
------------------------------------------------------------------------- */
void BondTable::param_extract(Table *tb, char *line)
{
tb->ninput = 0;
tb->fpflag = 0;
tb->r0 = 0.0;
char *word = strtok(line," \t\n\r\f");
while (word) {
if (strcmp(word,"N") == 0) {
word = strtok(NULL," \t\n\r\f");
tb->ninput = atoi(word);
} else if (strcmp(word,"FP") == 0) {
tb->fpflag = 1;
word = strtok(NULL," \t\n\r\f");
tb->fplo = atof(word);
word = strtok(NULL," \t\n\r\f");
tb->fphi = atof(word);
} else if (strcmp(word,"EQ") == 0) {
word = strtok(NULL," \t\n\r\f");
tb->r0 = atof(word);
} else {
error->one(FLERR,"Invalid keyword in bond table parameters");
}
word = strtok(NULL," \t\n\r\f");
}
if (tb->ninput == 0) error->one(FLERR,"Bond table parameters did not set N");
}
/* ----------------------------------------------------------------------
broadcast read-in table info from proc 0 to other procs
this function communicates these values in Table:
ninput,rfile,efile,ffile,fpflag,fplo,fphi,r0
------------------------------------------------------------------------- */
void BondTable::bcast_table(Table *tb)
{
MPI_Bcast(&tb->ninput,1,MPI_INT,0,world);
MPI_Bcast(&tb->r0,1,MPI_INT,0,world);
int me;
MPI_Comm_rank(world,&me);
if (me > 0) {
memory->create(tb->rfile,tb->ninput,"angle:rfile");
memory->create(tb->efile,tb->ninput,"angle:efile");
memory->create(tb->ffile,tb->ninput,"angle:ffile");
}
MPI_Bcast(tb->rfile,tb->ninput,MPI_DOUBLE,0,world);
MPI_Bcast(tb->efile,tb->ninput,MPI_DOUBLE,0,world);
MPI_Bcast(tb->ffile,tb->ninput,MPI_DOUBLE,0,world);
MPI_Bcast(&tb->fpflag,1,MPI_INT,0,world);
if (tb->fpflag) {
MPI_Bcast(&tb->fplo,1,MPI_DOUBLE,0,world);
MPI_Bcast(&tb->fphi,1,MPI_DOUBLE,0,world);
}
MPI_Bcast(&tb->r0,1,MPI_INT,0,world);
}
/* ----------------------------------------------------------------------
spline and splint routines modified from Numerical Recipes
------------------------------------------------------------------------- */
void BondTable::spline(double *x, double *y, int n,
double yp1, double ypn, double *y2)
{
int i,k;
double p,qn,sig,un;
double *u = new double[n];
if (yp1 > 0.99e30) y2[0] = u[0] = 0.0;
else {
y2[0] = -0.5;
u[0] = (3.0/(x[1]-x[0])) * ((y[1]-y[0]) / (x[1]-x[0]) - yp1);
}
for (i = 1; i < n-1; i++) {
sig = (x[i]-x[i-1]) / (x[i+1]-x[i-1]);
p = sig*y2[i-1] + 2.0;
y2[i] = (sig-1.0) / p;
u[i] = (y[i+1]-y[i]) / (x[i+1]-x[i]) - (y[i]-y[i-1]) / (x[i]-x[i-1]);
u[i] = (6.0*u[i] / (x[i+1]-x[i-1]) - sig*u[i-1]) / p;
}
if (ypn > 0.99e30) qn = un = 0.0;
else {
qn = 0.5;
un = (3.0/(x[n-1]-x[n-2])) * (ypn - (y[n-1]-y[n-2]) / (x[n-1]-x[n-2]));
}
y2[n-1] = (un-qn*u[n-2]) / (qn*y2[n-2] + 1.0);
for (k = n-2; k >= 0; k--) y2[k] = y2[k]*y2[k+1] + u[k];
delete [] u;
}
/* ---------------------------------------------------------------------- */
double BondTable::splint(double *xa, double *ya, double *y2a, int n, double x)
{
int klo,khi,k;
double h,b,a,y;
klo = 0;
khi = n-1;
while (khi-klo > 1) {
k = (khi+klo) >> 1;
if (xa[k] > x) khi = k;
else klo = k;
}
h = xa[khi]-xa[klo];
a = (xa[khi]-x) / h;
b = (x-xa[klo]) / h;
y = a*ya[klo] + b*ya[khi] +
((a*a*a-a)*y2a[klo] + (b*b*b-b)*y2a[khi]) * (h*h)/6.0;
return y;
}
/* ----------------------------------------------------------------------
calculate potential u and force f at distance x
insure x is between bond min/max
------------------------------------------------------------------------- */
void BondTable::uf_lookup(int type, double x, double &u, double &f)
{
int itable;
double fraction,a,b;
Table *tb = &tables[tabindex[type]];
x = MAX(x,tb->lo);
x = MIN(x,tb->hi);
if (tabstyle == LINEAR) {
itable = static_cast<int> ((x - tb->lo) * tb->invdelta);
fraction = (x - tb->r[itable]) * tb->invdelta;
u = tb->e[itable] + fraction*tb->de[itable];
f = tb->f[itable] + fraction*tb->df[itable];
} else if (tabstyle == SPLINE) {
itable = static_cast<int> ((x - tb->lo) * tb->invdelta);
fraction = (x - tb->r[itable]) * tb->invdelta;
b = (x - tb->r[itable]) * tb->invdelta;
a = 1.0 - b;
u = a * tb->e[itable] + b * tb->e[itable+1] +
((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) *
tb->deltasq6;
f = a * tb->f[itable] + b * tb->f[itable+1] +
((a*a*a-a)*tb->f2[itable] + (b*b*b-b)*tb->f2[itable+1]) *
tb->deltasq6;
}
}
/* ----------------------------------------------------------------------
calculate potential u at distance x
insure x is between bond min/max
------------------------------------------------------------------------- */
void BondTable::u_lookup(int type, double x, double &u)
{
int itable;
double fraction,a,b;
Table *tb = &tables[tabindex[type]];
x = MAX(x,tb->lo);
x = MIN(x,tb->hi);
if (tabstyle == LINEAR) {
itable = static_cast<int> ((x - tb->lo) * tb->invdelta);
fraction = (x - tb->r[itable]) * tb->invdelta;
u = tb->e[itable] + fraction*tb->de[itable];
} else if (tabstyle == SPLINE) {
itable = static_cast<int> ((x - tb->lo) * tb->invdelta);
fraction = (x - tb->r[itable]) * tb->invdelta;
b = (x - tb->r[itable]) * tb->invdelta;
a = 1.0 - b;
u = a * tb->e[itable] + b * tb->e[itable+1] +
((a*a*a-a)*tb->e2[itable] + (b*b*b-b)*tb->e2[itable+1]) *
tb->deltasq6;
}
}
diff --git a/src/MOLECULE/dihedral_charmm.cpp b/src/MOLECULE/dihedral_charmm.cpp
index 644655f58..6c0719593 100644
--- a/src/MOLECULE/dihedral_charmm.cpp
+++ b/src/MOLECULE/dihedral_charmm.cpp
@@ -1,428 +1,423 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "dihedral_charmm.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "pair.h"
#include "update.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define TOLERANCE 0.05
/* ---------------------------------------------------------------------- */
DihedralCharmm::DihedralCharmm(LAMMPS *lmp) : Dihedral(lmp) {}
/* ---------------------------------------------------------------------- */
DihedralCharmm::~DihedralCharmm()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(multiplicity);
memory->destroy(shift);
memory->destroy(cos_shift);
memory->destroy(sin_shift);
memory->destroy(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 " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
ddf1 = 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;
memory->create(k,n+1,"dihedral:k");
memory->create(multiplicity,n+1,"dihedral:k");
memory->create(shift,n+1,"dihedral:shift");
memory->create(cos_shift,n+1,"dihedral:cos_shift");
memory->create(sin_shift,n+1,"dihedral:sin_shift");
memory->create(weight,n+1,"dihedral:weight");
memory->create(setflag,n+1,"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(FLERR,"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(FLERR,"Incorrect multiplicity arg for dihedral coefficients");
if (weight_one < 0.0 || weight_one > 1.0)
error->all(FLERR,"Incorrect weight arg for dihedral coefficients");
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
shift[i] = shift_one;
cos_shift[i] = cos(MY_PI*shift_one/180.0);
sin_shift[i] = sin(MY_PI*shift_one/180.0);
multiplicity[i] = multiplicity_one;
weight[i] = weight_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"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(FLERR,"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(FLERR,"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);
for (int i = 1; i <= atom->ndihedraltypes; i++) {
setflag[i] = 1;
cos_shift[i] = cos(MY_PI*shift[i]/180.0);
sin_shift[i] = sin(MY_PI*shift[i]/180.0);
}
}
diff --git a/src/MOLECULE/dihedral_harmonic.cpp b/src/MOLECULE/dihedral_harmonic.cpp
index a951f3816..6f2e887f7 100644
--- a/src/MOLECULE/dihedral_harmonic.cpp
+++ b/src/MOLECULE/dihedral_harmonic.cpp
@@ -1,351 +1,347 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "dihedral_harmonic.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->destroy(setflag);
memory->destroy(k);
memory->destroy(sign);
memory->destroy(multiplicity);
memory->destroy(cos_shift);
memory->destroy(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 " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
ddf1 = 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;
memory->create(k,n+1,"dihedral:k");
memory->create(sign,n+1,"dihedral:sign");
memory->create(multiplicity,n+1,"dihedral:multiplicity");
memory->create(cos_shift,n+1,"dihedral:cos_shift");
memory->create(sin_shift,n+1,"dihedral:sin_shift");
memory->create(setflag,n+1,"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(FLERR,"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(FLERR,"Incorrect sign arg for dihedral coefficients");
if (multiplicity_one < 0)
error->all(FLERR,"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(FLERR,"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 e9c17392d..04bc7b029 100644
--- a/src/MOLECULE/dihedral_helix.cpp
+++ b/src/MOLECULE/dihedral_helix.cpp
@@ -1,337 +1,333 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "dihedral_helix.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "update.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.001
#define SMALLER 0.00001
/* ---------------------------------------------------------------------- */
DihedralHelix::DihedralHelix(LAMMPS *lmp) : Dihedral(lmp) {}
/* ---------------------------------------------------------------------- */
DihedralHelix::~DihedralHelix()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(aphi);
memory->destroy(bphi);
memory->destroy(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 " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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 + MY_PI4));
pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv +
cphi[type]*sin(phi + MY_PI4)*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;
memory->create(aphi,n+1,"dihedral:aphi");
memory->create(bphi,n+1,"dihedral:bphi");
memory->create(cphi,n+1,"dihedral:cphi");
memory->create(setflag,n+1,"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(FLERR,"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(FLERR,"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 cff19447f..d004a4cd9 100644
--- a/src/MOLECULE/dihedral_multi_harmonic.cpp
+++ b/src/MOLECULE/dihedral_multi_harmonic.cpp
@@ -1,335 +1,331 @@
/* ----------------------------------------------------------------------
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 "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 TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
DihedralMultiHarmonic::DihedralMultiHarmonic(LAMMPS *lmp) : Dihedral(lmp) {}
/* ---------------------------------------------------------------------- */
DihedralMultiHarmonic::~DihedralMultiHarmonic()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(a1);
memory->destroy(a2);
memory->destroy(a3);
memory->destroy(a4);
memory->destroy(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 " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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 = 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;
memory->create(a1,n+1,"dihedral:a1");
memory->create(a2,n+1,"dihedral:a2");
memory->create(a3,n+1,"dihedral:a3");
memory->create(a4,n+1,"dihedral:a4");
memory->create(a5,n+1,"dihedral:a5");
memory->create(setflag,n+1,"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(FLERR,"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(FLERR,"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 676434a06..0e40843fa 100644
--- a/src/MOLECULE/dihedral_opls.cpp
+++ b/src/MOLECULE/dihedral_opls.cpp
@@ -1,345 +1,341 @@
/* ----------------------------------------------------------------------
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 "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
#define SMALLER 0.00001
/* ---------------------------------------------------------------------- */
DihedralOPLS::DihedralOPLS(LAMMPS *lmp) : Dihedral(lmp) {}
/* ---------------------------------------------------------------------- */
DihedralOPLS::~DihedralOPLS()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k1);
memory->destroy(k2);
memory->destroy(k3);
memory->destroy(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 " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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 = 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;
memory->create(k1,n+1,"dihedral:k1");
memory->create(k2,n+1,"dihedral:k2");
memory->create(k3,n+1,"dihedral:k3");
memory->create(k4,n+1,"dihedral:k4");
memory->create(setflag,n+1,"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(FLERR,"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(FLERR,"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 a75d6c077..a0aa12832 100644
--- a/src/MOLECULE/improper_cvff.cpp
+++ b/src/MOLECULE/improper_cvff.cpp
@@ -1,349 +1,345 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "improper_cvff.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->destroy(setflag);
memory->destroy(k);
memory->destroy(sign);
memory->destroy(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 " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
memory->create(k,n+1,"improper:k");
memory->create(sign,n+1,"improper:sign");
memory->create(multiplicity,n+1,"improper:multiplicity");
memory->create(setflag,n+1,"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(FLERR,"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(FLERR,"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 dae70277c..da6f50bd8 100644
--- a/src/MOLECULE/improper_harmonic.cpp
+++ b/src/MOLECULE/improper_harmonic.cpp
@@ -1,287 +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 "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "improper_harmonic.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
ImproperHarmonic::ImproperHarmonic(LAMMPS *lmp) : Improper(lmp) {}
/* ---------------------------------------------------------------------- */
ImproperHarmonic::~ImproperHarmonic()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(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 " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
memory->create(k,n+1,"improper:k");
memory->create(chi,n+1,"improper:chi");
memory->create(setflag,n+1,"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(FLERR,"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 * MY_PI;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"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 61055a959..939566a24 100644
--- a/src/MOLECULE/improper_umbrella.cpp
+++ b/src/MOLECULE/improper_umbrella.cpp
@@ -1,313 +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 "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
ImproperUmbrella::ImproperUmbrella(LAMMPS *lmp) : Improper(lmp) {}
/* ---------------------------------------------------------------------- */
ImproperUmbrella::~ImproperUmbrella()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(kw);
memory->destroy(w0);
memory->destroy(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) {
char str[128];
sprintf(str,
"Improper problem: %d " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
memory->create(kw,n+1,"improper:kw");
memory->create(w0,n+1,"improper:w0");
memory->create(C,n+1,"improper:C");
memory->create(setflag,n+1,"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(FLERR,"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 * MY_PI;
if (w_one == 0) C[i] = 1.0;
else C[i] = kw[i]/(pow(sin(w0[i]),2.0));
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"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/OPT/pair_lj_cut_coul_long_tip4p_opt.h b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.h
index 0b8df5e84..7f2533409 100644
--- a/src/OPT/pair_lj_cut_coul_long_tip4p_opt.h
+++ b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.h
@@ -1,54 +1,59 @@
/* -*- c++ -*- ----------------------------------------------------------
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 PAIR_CLASS
PairStyle(lj/cut/coul/long/tip4p/opt,PairLJCutCoulLongTIP4POpt)
#else
#ifndef LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OPT_H
#define LMP_PAIR_LJ_CUT_COUL_LONG_TIP4P_OPT_H
#include "pair_lj_cut_coul_long_tip4p.h"
namespace LAMMPS_NS {
class PairLJCutCoulLongTIP4POpt : public PairLJCutCoulLongTIP4P {
public:
PairLJCutCoulLongTIP4POpt(class LAMMPS *);
virtual ~PairLJCutCoulLongTIP4POpt() {};
virtual void compute(int, int);
virtual double memory_usage();
protected:
template < const int, const int, const int, const int >
void eval();
void compute_newsite_opt(const double *, const double *,
const double *, double *) const;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: TIP4P hydrogen is missing
The TIP4P pairwise computation failed to find the correct H atom
within a water molecule.
+E: TIP4P hydrogen has incorrect atom type
+
+The TIP4P pairwise computation found an H atom whose type does not
+agree with the specified H type.
+
*/
diff --git a/src/PERI/atom_vec_peri.cpp b/src/PERI/atom_vec_peri.cpp
index 586823e71..6c3992d77 100644
--- a/src/PERI/atom_vec_peri.cpp
+++ b/src/PERI/atom_vec_peri.cpp
@@ -1,834 +1,835 @@
/* ----------------------------------------------------------------------
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 "atom.h"
#include "comm.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->peri_flag = 1;
atom->vfrac_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(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
vfrac = memory->grow(atom->vfrac,nmax,"atom:vfrac");
rmass = memory->grow(atom->rmass,nmax,"atom:rmass");
s0 = memory->grow(atom->s0,nmax,"atom:s0");
x0 = memory->grow(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; rmass = atom->rmass;
s0 = atom->s0; x0 = atom->x0;
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecPeri::copy(int i, int j, int delflag)
{
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];
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,dvx,dvy,dvz;
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;
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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++] = s0[j];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecPeri::pack_comm_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = s0[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
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_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++)
s0[i] = buf[m++];
return m;
}
/* ---------------------------------------------------------------------- */
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,dvx,dvy,dvz;
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];
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecPeri::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
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;
}
/* ---------------------------------------------------------------------- */
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_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
vfrac[i] = buf[m++];
s0[i] = buf[m++];
x0[i][0] = buf[m++];
x0[i][1] = buf[m++];
x0[i][2] = buf[m++];
}
return 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 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];
+ *((tagint *) &buf[m++]) = image[i];
buf[m++] = vfrac[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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
vfrac[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 = 17 * 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];
+ *((tagint *) &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++] = 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)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
v[nlocal][0] = buf[m++];
v[nlocal][1] = buf[m++];
v[nlocal][2] = buf[m++];
vfrac[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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
v[nlocal][0] = 0.0;
v[nlocal][1] = 0.0;
v[nlocal][2] = 0.0;
vfrac[nlocal] = 1.0;
rmass[nlocal] = 1.0;
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)
+void AtomVecPeri::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
type[nlocal] = atoi(values[1]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
vfrac[nlocal] = atof(values[2]);
rmass[nlocal] = atof(values[3]);
if (rmass[nlocal] <= 0.0) error->one(FLERR,"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]);
rmass[nlocal] = atof(values[1]);
if (rmass[nlocal] <= 0.0) error->one(FLERR,"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
------------------------------------------------------------------------- */
bigint AtomVecPeri::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("vfrac")) bytes += memory->usage(vfrac,nmax);
if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax);
if (atom->memcheck("s0")) bytes += memory->usage(s0,nmax);
if (atom->memcheck("x0")) bytes += memory->usage(x0,nmax,3);
return bytes;
}
diff --git a/src/PERI/atom_vec_peri.h b/src/PERI/atom_vec_peri.h
index 11adc2b68..9f09e07c9 100644
--- a/src/PERI/atom_vec_peri.h
+++ b/src/PERI/atom_vec_peri.h
@@ -1,87 +1,88 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(peri,AtomVecPeri)
#else
#ifndef LMP_ATOM_VEC_PERI_H
#define LMP_ATOM_VEC_PERI_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecPeri : public AtomVec {
public:
AtomVecPeri(class LAMMPS *, int, char **);
void grow(int);
void grow_reset();
void copy(int, int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
int pack_comm_hybrid(int, int *, double *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int unpack_comm_hybrid(int, int, double *);
int pack_reverse(int, int, double *);
void unpack_reverse(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
bigint memory_usage();
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
double *vfrac,*density,*rmass,*s0,**x0;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
E: Invalid mass value
Self-explanatory.
*/
diff --git a/src/POEMS/fix_poems.cpp b/src/POEMS/fix_poems.cpp
index 73330823d..4f54b55b9 100644
--- a/src/POEMS/fix_poems.cpp
+++ b/src/POEMS/fix_poems.cpp
@@ -1,1592 +1,1592 @@
/* ----------------------------------------------------------------------
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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
FixPOEMS is a LAMMPS interface to the POEMS coupled multi-body simulator
POEMS authors: Rudranarayan Mukherjee (mukher@rpi.edu)
Kurt Anderson (anderk5@rpi.edu)
------------------------------------------------------------------------- */
#include "mpi.h"
#include "math.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "workspace.h"
#include "fix_poems.h"
#include "atom.h"
#include "domain.h"
#include "update.h"
#include "respa.h"
#include "modify.h"
#include "force.h"
#include "output.h"
#include "group.h"
#include "comm.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
#define MAXBODY 2 // currently 2 since only linear chains allowed
#define DELTA 128
#define TOLERANCE 1.0e-6
#define EPSILON 1.0e-7
#define MAXJACOBI 50
/* ----------------------------------------------------------------------
define rigid bodies and joints, initiate POEMS
------------------------------------------------------------------------- */
FixPOEMS::FixPOEMS(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
int i,j,ibody;
time_integrate = 1;
rigid_flag = 1;
virial_flag = 1;
MPI_Comm_rank(world,&me);
// perform initial allocation of atom-based arrays
// register with atom class
natom2body = NULL;
atom2body = NULL;
displace = NULL;
grow_arrays(atom->nmax);
atom->add_callback(0);
// initialize each atom to belong to no rigid bodies
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) natom2body[i] = 0;
// create an atom map if one doesn't exist already
// readfile() and jointbuild() use global atom IDs
int mapflag = 0;
if (atom->map_style == 0) {
mapflag = 1;
atom->map_style = 1;
atom->map_init();
atom->map_set();
}
// parse command-line args
// set natom2body, atom2body for all atoms and nbody = # of rigid bodies
// atoms must also be in fix group to be in a body
if (narg < 4) error->all(FLERR,"Illegal fix poems command");
// group = arg has list of groups
if (strcmp(arg[3],"group") == 0) {
nbody = narg-4;
if (nbody <= 0) error->all(FLERR,"Illegal fix poems command");
int *igroups = new int[nbody];
for (ibody = 0; ibody < nbody; ibody++) {
igroups[ibody] = group->find(arg[ibody+4]);
if (igroups[ibody] == -1)
error->all(FLERR,"Could not find fix poems group ID");
}
int *mask = atom->mask;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
for (ibody = 0; ibody < nbody; ibody++)
if (mask[i] & group->bitmask[igroups[ibody]]) {
if (natom2body[i] < MAXBODY) atom2body[i][natom2body[i]] = ibody;
natom2body[i]++;
}
}
delete [] igroups;
// file = read bodies from file
// file read doesn't pay attention to fix group,
// so after read, reset natom2body = 0 if atom is not in fix group
} else if (strcmp(arg[3],"file") == 0) {
readfile(arg[4]);
int *mask = atom->mask;
for (int i = 0; i < nlocal; i++)
if (!(mask[i] & groupbit)) natom2body[i] = 0;
// each molecule in fix group is a rigid body
// maxmol = largest molecule #
// ncount = # of atoms in each molecule (have to sum across procs)
// nbody = # of non-zero ncount values
// use nall as incremented ptr to set atom2body[] values for each atom
} else if (strcmp(arg[3],"molecule") == 0) {
if (narg != 4) error->all(FLERR,"Illegal fix poems command");
if (atom->molecular == 0)
error->all(FLERR,"Must use a molecular atom style with fix poems molecule");
int *mask = atom->mask;
int *molecule = atom->molecule;
int nlocal = atom->nlocal;
int maxmol = -1;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) maxmol = MAX(maxmol,molecule[i]);
int itmp;
MPI_Allreduce(&maxmol,&itmp,1,MPI_INT,MPI_MAX,world);
maxmol = itmp + 1;
int *ncount = new int[maxmol];
for (i = 0; i < maxmol; i++) ncount[i] = 0;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) ncount[molecule[i]]++;
int *nall = new int[maxmol];
MPI_Allreduce(ncount,nall,maxmol,MPI_INT,MPI_SUM,world);
nbody = 0;
for (i = 0; i < maxmol; i++)
if (nall[i]) nall[i] = nbody++;
else nall[i] = -1;
for (i = 0; i < nlocal; i++) {
natom2body[i] = 0;
if (mask[i] & groupbit) {
natom2body[i] = 1;
atom2body[i][0] = nall[molecule[i]];
}
}
delete [] ncount;
delete [] nall;
} else error->all(FLERR,"Illegal fix poems command");
// error if no bodies
// error if any atom in too many bodies
if (nbody == 0) error->all(FLERR,"No rigid bodies defined");
int flag = 0;
for (int i = 0; i < nlocal; i++)
if (natom2body[i] > MAXBODY) flag = 1;
int flagall;
MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
if (flagall) error->all(FLERR,"Atom in too many rigid bodies - boost MAXBODY");
// create all nbody-length arrays
nrigid = new int[nbody];
masstotal = new double[nbody];
memory->create(xcm,nbody,3,"poems:xcm");
memory->create(vcm,nbody,3,"poems:vcm");
memory->create(fcm,nbody,3,"poems:fcm");
memory->create(inertia,nbody,3,"poems:inertia");
memory->create(ex_space,nbody,3,"poems:ex_space");
memory->create(ey_space,nbody,3,"poems:ey_space");
memory->create(ez_space,nbody,3,"poems:ez_space");
memory->create(angmom,nbody,3,"poems:angmom");
memory->create(omega,nbody,3,"poems:omega");
memory->create(torque,nbody,3,"poems:torque");
memory->create(sum,nbody,6,"poems:sum");
memory->create(all,nbody,6,"poems:all");
// nrigid[n] = # of atoms in Nth rigid body
// double count joint atoms as being in multiple bodies
// error if one or zero atoms
int *ncount = new int[nbody];
for (ibody = 0; ibody < nbody; ibody++) ncount[ibody] = 0;
for (i = 0; i < nlocal; i++)
for (j = 0; j < natom2body[i]; j++)
ncount[atom2body[i][j]]++;
MPI_Allreduce(ncount,nrigid,nbody,MPI_INT,MPI_SUM,world);
delete [] ncount;
for (ibody = 0; ibody < nbody; ibody++)
if (nrigid[ibody] <= 1) error->all(FLERR,"One or zero atoms in rigid body");
// build list of joint connections and check for cycles and trees
jointbuild();
// delete temporary atom map
if (mapflag) {
atom->map_delete();
atom->map_style = 0;
}
// create POEMS instance
poems = new Workspace;
// print statistics
int nsum = 0;
for (ibody = 0; ibody < nbody; ibody++) nsum += nrigid[ibody];
nsum -= njoint;
if (me == 0) {
if (screen)
fprintf(screen,"%d clusters, %d bodies, %d joints, %d atoms\n",
ncluster,nbody,njoint,nsum);
if (logfile)
fprintf(logfile,"%d clusters, %d bodies, %d joints, %d atoms\n",
ncluster,nbody,njoint,nsum);
}
}
/* ----------------------------------------------------------------------
free all memory for rigid bodies, joints, and POEMS
------------------------------------------------------------------------- */
FixPOEMS::~FixPOEMS()
{
// if atom class still exists:
// unregister this fix so atom class doesn't invoke it any more
if (atom) atom->delete_callback(id,0);
// delete locally stored arrays
memory->destroy(natom2body);
memory->destroy(atom2body);
memory->destroy(displace);
// delete nbody-length arrays
delete [] nrigid;
delete [] masstotal;
memory->destroy(xcm);
memory->destroy(vcm);
memory->destroy(fcm);
memory->destroy(inertia);
memory->destroy(ex_space);
memory->destroy(ey_space);
memory->destroy(ez_space);
memory->destroy(angmom);
memory->destroy(omega);
memory->destroy(torque);
memory->destroy(sum);
memory->destroy(all);
// delete joint arrays
memory->destroy(jointbody);
memory->destroy(xjoint);
delete [] freelist;
// delete POEMS object
delete poems;
}
/* ---------------------------------------------------------------------- */
int FixPOEMS::setmask()
{
int mask = 0;
mask |= INITIAL_INTEGRATE;
mask |= FINAL_INTEGRATE;
mask |= PRE_NEIGHBOR;
mask |= POST_FORCE;
mask |= INITIAL_INTEGRATE_RESPA;
mask |= FINAL_INTEGRATE_RESPA;
mask |= POST_FORCE_RESPA;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixPOEMS::init()
{
int i,ibody;
// warn if more than one POEMS fix
int count = 0;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"poems") == 0) count++;
if (count > 1 && comm->me == 0) error->warning(FLERR,"More than one fix poems");
// error if npt,nph fix comes before rigid 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,"poems") == 0)
error->all(FLERR,"POEMS fix must come before NPT/NPH fix");
}
// timestep info
dtv = update->dt;
dtf = 0.5 * update->dt * force->ftm2v;
dthalf = 0.5 * update->dt;
// rRESPA info
if (strstr(update->integrate_style,"respa")) {
step_respa = ((Respa *) update->integrate)->step;
nlevels_respa = ((Respa *) update->integrate)->nlevels;
}
// compute masstotal & center-of-mass xcm of each rigid body
// only count joint atoms in 1st body
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
double *mass = atom->mass;
double **x = atom->x;
double **v = atom->v;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
int xbox,ybox,zbox;
double massone;
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
for (i = 0; i < nlocal; i++) {
if (natom2body[i]) {
ibody = atom2body[i][0];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
massone = mass[type[i]];
sum[ibody][0] += (x[i][0] + xbox*xprd) * massone;
sum[ibody][1] += (x[i][1] + ybox*yprd) * massone;
sum[ibody][2] += (x[i][2] + zbox*zprd) * massone;
sum[ibody][3] += massone;
sum[ibody][4] += massone *
(v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]);
}
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
total_ke = 0.0;
for (ibody = 0; ibody < nbody; ibody++) {
masstotal[ibody] = all[ibody][3];
xcm[ibody][0] = all[ibody][0]/masstotal[ibody];
xcm[ibody][1] = all[ibody][1]/masstotal[ibody];
xcm[ibody][2] = all[ibody][2]/masstotal[ibody];
total_ke += 0.5 * all[ibody][4];
}
// compute 6 moments of inertia of each body
// only count joint atoms in 1st body
// dx,dy,dz = coords relative to center-of-mass
double dx,dy,dz;
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
for (i = 0; i < nlocal; i++) {
if (natom2body[i]) {
ibody = atom2body[i][0];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + xbox*xprd - xcm[ibody][0];
dy = x[i][1] + ybox*yprd - xcm[ibody][1];
dz = x[i][2] + zbox*zprd - xcm[ibody][2];
massone = mass[type[i]];
sum[ibody][0] += massone * (dy*dy + dz*dz);
sum[ibody][1] += massone * (dx*dx + dz*dz);
sum[ibody][2] += massone * (dx*dx + dy*dy);
sum[ibody][3] -= massone * dx*dy;
sum[ibody][4] -= massone * dy*dz;
sum[ibody][5] -= massone * dx*dz;
}
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
// inertia = 3 eigenvalues = principal moments of inertia
// ex_space,ey_space,ez_space = 3 eigenvectors = principal axes of rigid body
double **tensor,**evectors;
memory->create(tensor,3,3,"fix_rigid:tensor");
memory->create(evectors,3,3,"fix_rigid:evectors");
int ierror;
double ez0,ez1,ez2;
for (ibody = 0; ibody < nbody; ibody++) {
tensor[0][0] = all[ibody][0];
tensor[1][1] = all[ibody][1];
tensor[2][2] = all[ibody][2];
tensor[0][1] = tensor[1][0] = all[ibody][3];
tensor[1][2] = tensor[2][1] = all[ibody][4];
tensor[0][2] = tensor[2][0] = all[ibody][5];
ierror = jacobi(tensor,inertia[ibody],evectors);
if (ierror) error->all(FLERR,"Insufficient Jacobi rotations for POEMS body");
ex_space[ibody][0] = evectors[0][0];
ex_space[ibody][1] = evectors[1][0];
ex_space[ibody][2] = evectors[2][0];
ey_space[ibody][0] = evectors[0][1];
ey_space[ibody][1] = evectors[1][1];
ey_space[ibody][2] = evectors[2][1];
ez_space[ibody][0] = evectors[0][2];
ez_space[ibody][1] = evectors[1][2];
ez_space[ibody][2] = evectors[2][2];
// if any principal moment < scaled EPSILON, error
// this is b/c POEMS cannot yet handle degenerate bodies
double max;
max = MAX(inertia[ibody][0],inertia[ibody][1]);
max = MAX(max,inertia[ibody][2]);
if (inertia[ibody][0] < EPSILON*max ||
inertia[ibody][1] < EPSILON*max ||
inertia[ibody][2] < EPSILON*max)
error->all(FLERR,"Rigid body has degenerate moment of inertia");
// enforce 3 evectors as a right-handed coordinate system
// flip 3rd evector if needed
ez0 = ex_space[ibody][1]*ey_space[ibody][2] -
ex_space[ibody][2]*ey_space[ibody][1];
ez1 = ex_space[ibody][2]*ey_space[ibody][0] -
ex_space[ibody][0]*ey_space[ibody][2];
ez2 = ex_space[ibody][0]*ey_space[ibody][1] -
ex_space[ibody][1]*ey_space[ibody][0];
if (ez0*ez_space[ibody][0] + ez1*ez_space[ibody][1] +
ez2*ez_space[ibody][2] < 0.0) {
ez_space[ibody][0] = -ez_space[ibody][0];
ez_space[ibody][1] = -ez_space[ibody][1];
ez_space[ibody][2] = -ez_space[ibody][2];
}
}
// free temporary memory
memory->destroy(tensor);
memory->destroy(evectors);
// displace = initial atom coords in basis of principal axes
// only set joint atoms relative to 1st body
// set displace = 0.0 for atoms not in any rigid body
for (i = 0; i < nlocal; i++) {
if (natom2body[i]) {
ibody = atom2body[i][0];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + xbox*xprd - xcm[ibody][0];
dy = x[i][1] + ybox*yprd - xcm[ibody][1];
dz = x[i][2] + zbox*zprd - xcm[ibody][2];
displace[i][0] = dx*ex_space[ibody][0] + dy*ex_space[ibody][1] +
dz*ex_space[ibody][2];
displace[i][1] = dx*ey_space[ibody][0] + dy*ey_space[ibody][1] +
dz*ey_space[ibody][2];
displace[i][2] = dx*ez_space[ibody][0] + dy*ez_space[ibody][1] +
dz*ez_space[ibody][2];
} else displace[i][0] = displace[i][1] = displace[i][2] = 0.0;
}
// test for valid principal moments & axes
// recompute moments of inertia around new axes
// only count joint atoms in 1st body
// 3 diagonal moments should equal principal moments
// 3 off-diagonal moments should be 0.0
// (ddx,ddy,ddz) is projection of atom within rigid body onto principal axes
// 6 moments use (ddx,ddy,ddz) displacements from principal axes
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
double ddx,ddy,ddz;
for (i = 0; i < nlocal; i++) {
if (natom2body[i]) {
ibody = atom2body[i][0];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + xbox*xprd - xcm[ibody][0];
dy = x[i][1] + ybox*yprd - xcm[ibody][1];
dz = x[i][2] + zbox*zprd - xcm[ibody][2];
massone = mass[type[i]];
ddx = dx*ex_space[ibody][0] + dy*ex_space[ibody][1] +
dz*ex_space[ibody][2];
ddy = dx*ey_space[ibody][0] + dy*ey_space[ibody][1] +
dz*ey_space[ibody][2];
ddz = dx*ez_space[ibody][0] + dy*ez_space[ibody][1] +
dz*ez_space[ibody][2];
sum[ibody][0] += massone * (ddy*ddy + ddz*ddz);
sum[ibody][1] += massone * (ddx*ddx + ddz*ddz);
sum[ibody][2] += massone * (ddx*ddx + ddy*ddy);
sum[ibody][3] -= massone * ddx*ddy;
sum[ibody][4] -= massone * ddy*ddz;
sum[ibody][5] -= massone * ddx*ddz;
}
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
for (ibody = 0; ibody < nbody; ibody++) {
if (fabs(all[ibody][0]-inertia[ibody][0]) > TOLERANCE ||
fabs(all[ibody][1]-inertia[ibody][1]) > TOLERANCE ||
fabs(all[ibody][2]-inertia[ibody][2]) > TOLERANCE)
error->all(FLERR,"Bad principal moments");
if (fabs(all[ibody][3]) > TOLERANCE ||
fabs(all[ibody][4]) > TOLERANCE ||
fabs(all[ibody][5]) > TOLERANCE)
error->all(FLERR,"Bad principal moments");
}
}
/* ----------------------------------------------------------------------
compute initial rigid body info
make setup call to POEMS
------------------------------------------------------------------------- */
void FixPOEMS::setup(int vflag)
{
int i,n,ibody;
// vcm = velocity of center-of-mass of each rigid body
// angmom = angular momentum of each rigid body
// only count joint atoms in 1st body
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
double *mass = atom->mass;
double **x = atom->x;
double **v = atom->v;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
int xbox,ybox,zbox;
double massone,dx,dy,dz;
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
for (i = 0; i < nlocal; i++) {
if (natom2body[i]) {
ibody = atom2body[i][0];
massone = mass[type[i]];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + xbox*xprd - xcm[ibody][0];
dy = x[i][1] + ybox*yprd - xcm[ibody][1];
dz = x[i][2] + zbox*zprd - xcm[ibody][2];
sum[ibody][0] += v[i][0] * massone;
sum[ibody][1] += v[i][1] * massone;
sum[ibody][2] += v[i][2] * massone;
sum[ibody][3] += dy * massone*v[i][2] - dz * massone*v[i][1];
sum[ibody][4] += dz * massone*v[i][0] - dx * massone*v[i][2];
sum[ibody][5] += dx * massone*v[i][1] - dy * massone*v[i][0];
}
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
for (ibody = 0; ibody < nbody; ibody++) {
vcm[ibody][0] = all[ibody][0]/masstotal[ibody];
vcm[ibody][1] = all[ibody][1]/masstotal[ibody];
vcm[ibody][2] = all[ibody][2]/masstotal[ibody];
angmom[ibody][0] = all[ibody][3];
angmom[ibody][1] = all[ibody][4];
angmom[ibody][2] = all[ibody][5];
}
// virial setup before call to set_v
if (vflag) v_setup(vflag);
else evflag = 0;
// set velocities from angmom & omega
for (ibody = 0; ibody < nbody; ibody++)
omega_from_mq(angmom[ibody],ex_space[ibody],ey_space[ibody],
ez_space[ibody],inertia[ibody],omega[ibody]);
set_v();
// guestimate virial as 2x the set_v contribution
if (vflag_global)
for (n = 0; n < 6; n++) virial[n] *= 2.0;
if (vflag_atom) {
for (i = 0; i < nlocal; i++)
for (n = 0; n < 6; n++)
vatom[i][n] *= 2.0;
}
// use post_force() to compute initial fcm & torque
post_force(vflag);
// setup for POEMS
poems->MakeSystem(nbody,masstotal,inertia,xcm,vcm,omega,
ex_space,ey_space,ez_space,
njoint,jointbody,xjoint,nfree,freelist,
dthalf,dtv,force->ftm2v,total_ke);
}
/* ----------------------------------------------------------------------
update vcm,omega by 1/2 step and xcm,orientation by full step
set x,v of body atoms accordingly
---------------------------------------------------------------------- */
void FixPOEMS::initial_integrate(int vflag)
{
// perform POEMS integration
poems->LobattoOne(xcm,vcm,omega,torque,fcm,ex_space,ey_space,ez_space);
// virial setup before call to set_xv
if (vflag) v_setup(vflag);
else evflag = 0;
// set coords and velocities of atoms in rigid bodies
set_xv();
}
/* ----------------------------------------------------------------------
compute fcm,torque on each rigid body
only count joint atoms in 1st body
------------------------------------------------------------------------- */
void FixPOEMS::post_force(int vflag)
{
int i,ibody;
int xbox,ybox,zbox;
double dx,dy,dz;
- int *image = atom->image;
+ tagint *image = atom->image;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
for (i = 0; i < nlocal; i++) {
if (natom2body[i]) {
ibody = atom2body[i][0];
sum[ibody][0] += f[i][0];
sum[ibody][1] += f[i][1];
sum[ibody][2] += f[i][2];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + xbox*xprd - xcm[ibody][0];
dy = x[i][1] + ybox*yprd - xcm[ibody][1];
dz = x[i][2] + zbox*zprd - xcm[ibody][2];
sum[ibody][3] += dy*f[i][2] - dz*f[i][1];
sum[ibody][4] += dz*f[i][0] - dx*f[i][2];
sum[ibody][5] += dx*f[i][1] - dy*f[i][0];
}
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
for (ibody = 0; ibody < nbody; ibody++) {
fcm[ibody][0] = all[ibody][0];
fcm[ibody][1] = all[ibody][1];
fcm[ibody][2] = all[ibody][2];
torque[ibody][0] = all[ibody][3];
torque[ibody][1] = all[ibody][4];
torque[ibody][2] = all[ibody][5];
}
}
/* ----------------------------------------------------------------------
update vcm,omega by last 1/2 step
set v of body atoms accordingly
------------------------------------------------------------------------- */
void FixPOEMS::final_integrate()
{
// perform POEMS integration
poems->LobattoTwo(vcm,omega,torque,fcm);
// set velocities of atoms in rigid bodies
// virial is already setup from initial_integrate
set_v();
}
/* ---------------------------------------------------------------------- */
void FixPOEMS::initial_integrate_respa(int vflag, int ilevel, int iloop)
{
dtv = step_respa[ilevel];
dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
dthalf = 0.5 * step_respa[ilevel];
if (ilevel == 0) initial_integrate(vflag);
else final_integrate();
}
/* ---------------------------------------------------------------------- */
void FixPOEMS::post_force_respa(int vflag, int ilevel, int iloop)
{
if (ilevel == nlevels_respa-1) post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixPOEMS::final_integrate_respa(int ilevel, int iloop)
{
dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
final_integrate();
}
/* ----------------------------------------------------------------------
remap xcm of each rigid body back into periodic simulation box
done during pre_neighbor so will be after call to pbc()
and after fix_deform::pre_exchange() may have flipped box
if don't do this, then atoms of a body which drifts far away
from a triclinic box will be remapped back into box
with huge displacements when the box tilt changes via set_x()
NOTE: cannot do this by changing xcm of each body in cluster
or even 1st body in cluster
b/c POEMS library does not see xcm but only sets xcm
so remap needs to be coordinated with POEMS library
thus this routine does nothing for now
------------------------------------------------------------------------- */
void FixPOEMS::pre_neighbor() {}
/* ----------------------------------------------------------------------
count # of degrees-of-freedom removed by fix_poems for atoms in igroup
------------------------------------------------------------------------- */
int FixPOEMS::dof(int igroup)
{
int groupbit = group->bitmask[igroup];
// ncount = # of atoms in each rigid body that are also in group
// only count joint atoms as part of first body
int *mask = atom->mask;
int nlocal = atom->nlocal;
int *ncount = new int[nbody];
for (int ibody = 0; ibody < nbody; ibody++) ncount[ibody] = 0;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
if (natom2body[i]) ncount[atom2body[i][0]]++;
int *nall = new int[nbody];
MPI_Allreduce(ncount,nall,nbody,MPI_INT,MPI_SUM,world);
// remove 3N - 6 dof for each rigid body if at least 2 atoms are in igroup
int n = 0;
for (int ibody = 0; ibody < nbody; ibody++)
if (nall[ibody] > 2) n += 3*nall[ibody] - 6;
// subtract 3 additional dof for each joint if atom is also in igroup
int m = 0;
for (int i = 0; i < nlocal; i++)
if (natom2body[i] > 1 && (mask[i] & groupbit)) m += 3*(natom2body[i]-1);
int mall;
MPI_Allreduce(&m,&mall,1,MPI_INT,MPI_SUM,world);
n += mall;
// delete local memory
delete [] ncount;
delete [] nall;
return n;
}
/* ----------------------------------------------------------------------
adjust xcm of each cluster due to box deformation
called by various fixes that change box size/shape
flag = 0/1 means map from box to lamda coords or vice versa
NOTE: cannot do this by changing xcm of each body in cluster
or even 1st body in cluster
b/c POEMS library does not see xcm but only sets xcm
so deform needs to be coordinated with POEMS library
thus this routine does nothing for now
------------------------------------------------------------------------- */
void FixPOEMS::deform(int flag) {}
/* ---------------------------------------------------------------------- */
void FixPOEMS::readfile(char *file)
{
FILE *fp;
if (me == 0) {
fp = fopen(file,"r");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open fix poems file %s",file);
error->one(FLERR,str);
}
}
nbody = 0;
char *line = NULL;
int maxline = 0;
char *ptr;
int nlocal = atom->nlocal;
int i,id,nlen;
while (1) {
if (me == 0) nlen = readline(fp,&line,&maxline);
MPI_Bcast(&nlen,1,MPI_INT,0,world);
if (nlen == 0) break;
MPI_Bcast(line,nlen,MPI_CHAR,0,world);
ptr = strtok(line," ,\t\n\0");
if (ptr == NULL || ptr[0] == '#') continue;
ptr = strtok(NULL," ,\t\n\0");
while (ptr = strtok(NULL," ,\t\n\0")) {
id = atoi(ptr);
i = atom->map(id);
if (i < 0 || i >= nlocal) continue;
if (natom2body[i] < MAXBODY) atom2body[i][natom2body[i]] = nbody;
natom2body[i]++;
}
nbody++;
}
memory->destroy(line);
fclose(fp);
}
/* ---------------------------------------------------------------------- */
int FixPOEMS::readline(FILE *fp, char **pline, int *pmaxline)
{
int n = 0;
char *line = *pline;
int maxline = *pmaxline;
while (1) {
if (n+1 >= maxline) {
maxline += DELTA;
memory->grow(line,maxline,"fix_poems:line");
}
if (fgets(&line[n],maxline-n,fp) == NULL) {
n = 0;
break;
}
n = strlen(line);
if (n < maxline-1 || line[n-1] == '\n') break;
}
*pmaxline = maxline;
*pline = line;
return n;
}
/* ----------------------------------------------------------------------
build list of joints and error check for cycles and trees
------------------------------------------------------------------------- */
void FixPOEMS::jointbuild()
{
int i,j;
// convert atom2body into list of joint atoms on this proc
// mjoint = # of joint atoms in this proc
// an atom in N rigid bodies, infers N-1 joints between 1st body and others
// mylist = [0],[1] = 2 body indices, [2] = global ID of joint atom
int *tag = atom->tag;
int nlocal = atom->nlocal;
int mjoint = 0;
for (i = 0; i < nlocal; i++) {
if (natom2body[i] <= 1) continue;
mjoint += natom2body[i]-1;
}
int **mylist = NULL;
if (mjoint) memory->create(mylist,mjoint,3,"poems:mylist");
mjoint = 0;
for (i = 0; i < nlocal; i++) {
if (natom2body[i] <= 1) continue;
for (j = 1; j < natom2body[i]; j++) {
mylist[mjoint][0] = atom2body[i][0];
mylist[mjoint][1] = atom2body[i][j];
mylist[mjoint][2] = tag[i];
mjoint++;
}
}
// jlist = mylist concatenated across all procs via MPI_Allgatherv
MPI_Allreduce(&mjoint,&njoint,1,MPI_INT,MPI_SUM,world);
int **jlist = NULL;
if (njoint) memory->create(jlist,njoint,3,"poems:jlist");
int nprocs;
MPI_Comm_size(world,&nprocs);
int *recvcounts = new int[nprocs];
int tmp = 3*mjoint;
MPI_Allgather(&tmp,1,MPI_INT,recvcounts,1,MPI_INT,world);
int *displs = new int[nprocs];
displs[0] = 0;
for (i = 1; i < nprocs; i++) displs[i] = displs[i-1] + recvcounts[i-1];
// allgather the local joint lists
// 2 versions in case mjoint is 0 on this proc
if (njoint) {
if (mjoint)
MPI_Allgatherv(mylist[0],3*mjoint,MPI_INT,jlist[0],
recvcounts,displs,MPI_INT,world);
else
MPI_Allgatherv(NULL,3*mjoint,MPI_INT,jlist[0],
recvcounts,displs,MPI_INT,world);
}
delete [] recvcounts;
delete [] displs;
// warning if no joints
if (njoint == 0 && me == 0)
error->warning(FLERR,"No joints between rigid bodies, use fix rigid instead");
// sort joint list in ascending order by body indices
// check for loops in joint connections between rigid bodies
// check for trees = same body in more than 2 joints
sortlist(njoint,jlist);
if (loopcheck(nbody,njoint,jlist))
error->all(FLERR,"Cyclic loop in joint connections");
int *bodyflag = new int[nbody];
for (i = 0; i < nbody; i++) bodyflag[i] = 0;
for (i = 0; i < njoint; i++) {
bodyflag[jlist[i][0]]++;
bodyflag[jlist[i][1]]++;
}
for (i = 0; i < nbody; i++)
if (bodyflag[i] > 2) error->all(FLERR,"Tree structure in joint connections");
delete [] bodyflag;
// allocate and setup joint arrays
// jointbody stores body indices from 1 to Nbody to pass to POEMS
// each proc sets myjoint if it owns joint atom
// MPI_Allreduce gives all procs the xjoint coords
jointbody = NULL;
xjoint = NULL;
double **myjoint = NULL;
if (njoint) {
memory->create(jointbody,njoint,2,"poems:jointbody");
memory->create(xjoint,njoint,3,"poems:xjoint");
memory->create(myjoint,njoint,3,"poems:myjoint");
}
double **x = atom->x;
for (i = 0; i < njoint; i++) {
jointbody[i][0] = jlist[i][0] + 1;
jointbody[i][1] = jlist[i][1] + 1;
j = atom->map(jlist[i][2]);
if (j >= 0 && j < nlocal) {
myjoint[i][0] = x[j][0];
myjoint[i][1] = x[j][1];
myjoint[i][2] = x[j][2];
} else myjoint[i][0] = myjoint[i][1] = myjoint[i][2] = 0.0;
}
if (njoint)
MPI_Allreduce(myjoint[0],xjoint[0],3*njoint,MPI_DOUBLE,MPI_SUM,world);
// compute freelist of nfree single unconnected bodies
// POEMS could do this itself
int *mark = new int[nbody];
for (i = 0; i < nbody; i++) mark[i] = 1;
for (i = 0; i < njoint; i++) {
mark[jointbody[i][0]-1] = 0;
mark[jointbody[i][1]-1] = 0;
}
nfree = 0;
for (i = 0; i < nbody; i++)
if (mark[i]) nfree++;
if (nfree) freelist = new int[nfree];
else freelist = NULL;
nfree = 0;
for (i = 0; i < nbody; i++)
if (mark[i]) freelist[nfree++] = i + 1;
delete [] mark;
// free memory local to this routine
memory->destroy(mylist);
memory->destroy(jlist);
memory->destroy(myjoint);
}
/* ----------------------------------------------------------------------
sort joint list (Numerical Recipes shell sort)
sort criterion: sort on 1st body, if equal sort on 2nd body
------------------------------------------------------------------------- */
void FixPOEMS::sortlist(int n, int **list)
{
int i,j,v0,v1,v2,flag;
int inc = 1;
while (inc <= n) inc = 3*inc + 1;
do {
inc /= 3;
for (i = inc+1; i <= n; i++) {
v0 = list[i-1][0];
v1 = list[i-1][1];
v2 = list[i-1][2];
j = i;
flag = 0;
if (list[j-inc-1][0] > v0 ||
(list[j-inc-1][0] == v0 && list[j-inc-1][1] > v1)) flag = 1;
while (flag) {
list[j-1][0] = list[j-inc-1][0];
list[j-1][1] = list[j-inc-1][1];
list[j-1][2] = list[j-inc-1][2];
j -= inc;
if (j <= inc) break;
flag = 0;
if (list[j-inc-1][0] > v0 ||
(list[j-inc-1][0] == v0 && list[j-inc-1][1] > v1)) flag = 1;
}
list[j-1][0] = v0;
list[j-1][1] = v1;
list[j-1][2] = v2;
}
} while (inc > 1);
}
/* ----------------------------------------------------------------------
check for cycles in list of joint connections between rigid bodies
treat as graph: vertex = body, edge = joint between 2 bodies
------------------------------------------------------------------------- */
int FixPOEMS::loopcheck(int nvert, int nedge, int **elist)
{
int i,j,k;
// ecount[i] = # of vertices connected to vertex i via edge
// elistfull[i][*] = list of vertices connected to vertex i
int *ecount = new int[nvert];
for (i = 0; i < nvert; i++) ecount[i] = 0;
for (i = 0; i < nedge; i++) {
ecount[elist[i][0]]++;
ecount[elist[i][1]]++;
}
int emax = 0;
for (i = 0; i < nvert; i++) emax = MAX(emax,ecount[i]);
int **elistfull;
memory->create(elistfull,nvert,emax,"poems:elistfull");
for (i = 0; i < nvert; i++) ecount[i] = 0;
for (i = 0; i < nedge; i++) {
elistfull[elist[i][0]][ecount[elist[i][0]]++] = elist[i][1];
elistfull[elist[i][1]][ecount[elist[i][1]]++] = elist[i][0];
}
// cycle detection algorithm
// mark = 0/1 marking of each vertex, all initially unmarked
// outer while loop:
// if all vertices are marked, no cycles, exit loop
// push an unmarked vertex on stack and mark it, parent is -1
// while stack is not empty:
// pop vertex I from stack
// loop over vertices J connected to I via edge
// if J is parent (vertex that pushed I on stack), skip it
// else if J is marked, a cycle is found, return 1
// else push J on stack and mark it, parent is I
// increment ncluster each time stack empties since that is new cluster
int *parent = new int[nvert];
int *mark = new int[nvert];
for (i = 0; i < nvert; i++) mark[i] = 0;
int nstack = 0;
int *stack = new int[nvert];
ncluster = 0;
while (1) {
for (i = 0; i < nvert; i++)
if (mark[i] == 0) break;
if (i == nvert) break;
stack[nstack++] = i;
mark[i] = 1;
parent[i] = -1;
while (nstack) {
i = stack[--nstack];
for (k = 0; k < ecount[i]; k++) {
j = elistfull[i][k];
if (j == parent[i]) continue;
if (mark[j]) return 1;
stack[nstack++] = j;
mark[j] = 1;
parent[j] = i;
}
}
ncluster++;
}
// free memory local to this routine
delete [] ecount;
memory->destroy(elistfull);
delete [] parent;
delete [] mark;
delete [] stack;
return 0;
}
/* ----------------------------------------------------------------------
compute evalues and evectors of 3x3 real symmetric matrix
based on Jacobi rotations
adapted from Numerical Recipes jacobi() function
------------------------------------------------------------------------- */
int FixPOEMS::jacobi(double **matrix, double *evalues, double **evectors)
{
int i,j,k;
double tresh,theta,tau,t,sm,s,h,g,c,b[3],z[3];
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) evectors[i][j] = 0.0;
evectors[i][i] = 1.0;
}
for (i = 0; i < 3; i++) {
b[i] = evalues[i] = matrix[i][i];
z[i] = 0.0;
}
for (int iter = 1; iter <= MAXJACOBI; iter++) {
sm = 0.0;
for (i = 0; i < 2; i++)
for (j = i+1; j < 3; j++)
sm += fabs(matrix[i][j]);
if (sm == 0.0) return 0;
if (iter < 4) tresh = 0.2*sm/(3*3);
else tresh = 0.0;
for (i = 0; i < 2; i++) {
for (j = i+1; j < 3; j++) {
g = 100.0*fabs(matrix[i][j]);
if (iter > 4 && fabs(evalues[i])+g == fabs(evalues[i])
&& fabs(evalues[j])+g == fabs(evalues[j]))
matrix[i][j] = 0.0;
else if (fabs(matrix[i][j]) > tresh) {
h = evalues[j]-evalues[i];
if (fabs(h)+g == fabs(h)) t = (matrix[i][j])/h;
else {
theta = 0.5*h/(matrix[i][j]);
t = 1.0/(fabs(theta)+sqrt(1.0+theta*theta));
if (theta < 0.0) t = -t;
}
c = 1.0/sqrt(1.0+t*t);
s = t*c;
tau = s/(1.0+c);
h = t*matrix[i][j];
z[i] -= h;
z[j] += h;
evalues[i] -= h;
evalues[j] += h;
matrix[i][j] = 0.0;
for (k = 0; k < i; k++) rotate(matrix,k,i,k,j,s,tau);
for (k = i+1; k < j; k++) rotate(matrix,i,k,k,j,s,tau);
for (k = j+1; k < 3; k++) rotate(matrix,i,k,j,k,s,tau);
for (k = 0; k < 3; k++) rotate(evectors,k,i,k,j,s,tau);
}
}
}
for (i = 0; i < 3; i++) {
evalues[i] = b[i] += z[i];
z[i] = 0.0;
}
}
return 1;
}
/* ----------------------------------------------------------------------
perform a single Jacobi rotation
------------------------------------------------------------------------- */
void FixPOEMS::rotate(double **matrix, int i, int j, int k, int l,
double s, double tau)
{
double g = matrix[i][j];
double h = matrix[k][l];
matrix[i][j] = g-s*(h+g*tau);
matrix[k][l] = h+s*(g-h*tau);
}
/* ----------------------------------------------------------------------
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 FixPOEMS::omega_from_mq(double *m, double *ex, double *ey, double *ez,
double *inertia, double *w)
{
double wbody[3];
if (inertia[0] == 0.0) wbody[0] = 0.0;
else wbody[0] = (m[0]*ex[0] + m[1]*ex[1] + m[2]*ex[2]) / inertia[0];
if (inertia[1] == 0.0) wbody[1] = 0.0;
else wbody[1] = (m[0]*ey[0] + m[1]*ey[1] + m[2]*ey[2]) / inertia[1];
if (inertia[2] == 0.0) wbody[2] = 0.0;
else 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];
}
/* ----------------------------------------------------------------------
set space-frame coords and velocity of each atom in each rigid body
x = Q displace + Xcm, mapped back to periodic box
v = Vcm + (W cross (x - Xcm))
------------------------------------------------------------------------- */
void FixPOEMS::set_xv()
{
int ibody;
int xbox,ybox,zbox;
double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone;
double vr[6];
- int *image = atom->image;
+ tagint *image = atom->image;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double *mass = atom->mass;
int *type = atom->type;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
// set x and v of each atom
// only set joint atoms for 1st rigid body they belong to
for (int i = 0; i < nlocal; i++) {
if (natom2body[i] == 0) continue;
ibody = atom2body[i][0];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
// save old positions and velocities for virial
if (evflag) {
x0 = x[i][0] + xbox*xprd;
x1 = x[i][1] + ybox*yprd;
x2 = x[i][2] + zbox*zprd;
v0 = v[i][0];
v1 = v[i][1];
v2 = v[i][2];
}
// x = displacement from center-of-mass, based on body orientation
// v = vcm + omega around center-of-mass
x[i][0] = ex_space[ibody][0]*displace[i][0] +
ey_space[ibody][0]*displace[i][1] +
ez_space[ibody][0]*displace[i][2];
x[i][1] = ex_space[ibody][1]*displace[i][0] +
ey_space[ibody][1]*displace[i][1] +
ez_space[ibody][1]*displace[i][2];
x[i][2] = ex_space[ibody][2]*displace[i][0] +
ey_space[ibody][2]*displace[i][1] +
ez_space[ibody][2]*displace[i][2];
v[i][0] = omega[ibody][1]*x[i][2] - omega[ibody][2]*x[i][1] +
vcm[ibody][0];
v[i][1] = omega[ibody][2]*x[i][0] - omega[ibody][0]*x[i][2] +
vcm[ibody][1];
v[i][2] = omega[ibody][0]*x[i][1] - omega[ibody][1]*x[i][0] +
vcm[ibody][2];
// add center of mass to displacement
// map back into periodic box via xbox,ybox,zbox
x[i][0] += xcm[ibody][0] - xbox*xprd;
x[i][1] += xcm[ibody][1] - ybox*yprd;
x[i][2] += xcm[ibody][2] - zbox*zprd;
// virial = unwrapped coords dotted into body constraint force
// body constraint force = implied force due to v change minus f external
// assume f does not include forces internal to body
// 1/2 factor b/c final_integrate contributes other half
// assume per-atom contribution is due to constraint force on that atom
if (evflag) {
massone = mass[type[i]];
fc0 = massone*(v[i][0] - v0)/dtf - f[i][0];
fc1 = massone*(v[i][1] - v1)/dtf - f[i][1];
fc2 = massone*(v[i][2] - v2)/dtf - f[i][2];
vr[0] = 0.5*fc0*x0;
vr[1] = 0.5*fc1*x1;
vr[2] = 0.5*fc2*x2;
vr[3] = 0.5*fc1*x0;
vr[4] = 0.5*fc2*x0;
vr[5] = 0.5*fc2*x1;
v_tally(1,&i,1.0,vr);
}
}
}
/* ----------------------------------------------------------------------
set space-frame velocity of each atom in a rigid body
v = Vcm + (W cross (x - Xcm))
------------------------------------------------------------------------- */
void FixPOEMS::set_v()
{
int ibody;
int xbox,ybox,zbox;
double dx,dy,dz;
double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone;
double vr[6];
double *mass = atom->mass;
double **f = atom->f;
double **x = atom->x;
double **v = atom->v;
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
// set v of each atom
// only set joint atoms for 1st rigid body they belong to
for (int i = 0; i < nlocal; i++) {
if (natom2body[i] == 0) continue;
ibody = atom2body[i][0];
dx = ex_space[ibody][0]*displace[i][0] +
ey_space[ibody][0]*displace[i][1] +
ez_space[ibody][0]*displace[i][2];
dy = ex_space[ibody][1]*displace[i][0] +
ey_space[ibody][1]*displace[i][1] +
ez_space[ibody][1]*displace[i][2];
dz = ex_space[ibody][2]*displace[i][0] +
ey_space[ibody][2]*displace[i][1] +
ez_space[ibody][2]*displace[i][2];
// save old velocities for virial
if (evflag) {
v0 = v[i][0];
v1 = v[i][1];
v2 = v[i][2];
}
v[i][0] = omega[ibody][1]*dz - omega[ibody][2]*dy + vcm[ibody][0];
v[i][1] = omega[ibody][2]*dx - omega[ibody][0]*dz + vcm[ibody][1];
v[i][2] = omega[ibody][0]*dy - omega[ibody][1]*dx + vcm[ibody][2];
// virial = unwrapped coords dotted into body constraint force
// body constraint force = implied force due to v change minus f external
// assume f does not include forces internal to body
// 1/2 factor b/c initial_integrate contributes other half
// assume per-atom contribution is due to constraint force on that atom
if (evflag) {
massone = mass[type[i]];
fc0 = massone*(v[i][0] - v0)/dtf - f[i][0];
fc1 = massone*(v[i][1] - v1)/dtf - f[i][1];
fc2 = massone*(v[i][2] - v2)/dtf - f[i][2];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
x0 = x[i][0] + xbox*xprd;
x1 = x[i][1] + ybox*yprd;
x2 = x[i][2] + zbox*zprd;
vr[0] = 0.5*fc0*x0;
vr[1] = 0.5*fc1*x1;
vr[2] = 0.5*fc2*x2;
vr[3] = 0.5*fc1*x0;
vr[4] = 0.5*fc2*x0;
vr[5] = 0.5*fc2*x1;
v_tally(1,&i,1.0,vr);
}
}
}
/* ----------------------------------------------------------------------
allocate local atom-based arrays
------------------------------------------------------------------------- */
void FixPOEMS::grow_arrays(int nmax)
{
memory->grow(natom2body,nmax,"fix_poems:natom2body");
memory->grow(atom2body,nmax,MAXBODY,"fix_poems:atom2body");
memory->grow(displace,nmax,3,"fix_poems:displace");
}
/* ----------------------------------------------------------------------
copy values within local atom-based arrays
------------------------------------------------------------------------- */
void FixPOEMS::copy_arrays(int i, int j)
{
natom2body[j] = natom2body[i];
for (int k = 0; k < natom2body[j]; k++) atom2body[j][k] = atom2body[i][k];
displace[j][0] = displace[i][0];
displace[j][1] = displace[i][1];
displace[j][2] = displace[i][2];
}
/* ----------------------------------------------------------------------
memory usage of local atom-based arrays
------------------------------------------------------------------------- */
double FixPOEMS::memory_usage()
{
int nmax = atom->nmax;
double bytes = nmax * sizeof(int);
bytes += nmax*MAXBODY * sizeof(int);
bytes += nmax*3 * sizeof(double);
return bytes;
}
/* ----------------------------------------------------------------------
pack values in local atom-based arrays for exchange with another proc
------------------------------------------------------------------------- */
int FixPOEMS::pack_exchange(int i, double *buf)
{
int m = 0;
buf[m++] = static_cast<double> (natom2body[i]);
for (int j = 0; j < natom2body[i]; j++)
buf[m++] = static_cast<double> (atom2body[i][j]);
buf[m++] = displace[i][0];
buf[m++] = displace[i][1];
buf[m++] = displace[i][2];
return m;
}
/* ----------------------------------------------------------------------
unpack values in local atom-based arrays from exchange with another proc
------------------------------------------------------------------------- */
int FixPOEMS::unpack_exchange(int nlocal, double *buf)
{
int m = 0;
natom2body[nlocal] = static_cast<int> (buf[m++]);
for (int i = 0; i < natom2body[nlocal]; i++)
atom2body[nlocal][i] = static_cast<int> (buf[m++]);
displace[nlocal][0] = buf[m++];
displace[nlocal][1] = buf[m++];
displace[nlocal][2] = buf[m++];
return m;
}
/* ---------------------------------------------------------------------- */
void FixPOEMS::reset_dt()
{
dtv = update->dt;
dtf = 0.5 * update->dt * force->ftm2v;
dthalf = 0.5 * update->dt;
}
diff --git a/src/REPLICA/compute_event_displace.cpp b/src/REPLICA/compute_event_displace.cpp
index 8cfe64461..45d434127 100644
--- a/src/REPLICA/compute_event_displace.cpp
+++ b/src/REPLICA/compute_event_displace.cpp
@@ -1,158 +1,158 @@
/* ----------------------------------------------------------------------
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 "compute_event_displace.h"
#include "atom.h"
#include "domain.h"
#include "modify.h"
#include "fix_event.h"
#include "memory.h"
#include "error.h"
#include "update.h"
using namespace LAMMPS_NS;
#define INVOKED_SCALAR 1
/* ---------------------------------------------------------------------- */
ComputeEventDisplace::ComputeEventDisplace(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg != 4) error->all(FLERR,"Illegal compute event/displace command");
scalar_flag = 1;
extscalar = 0;
double displace_dist = atof(arg[3]);
if (displace_dist <= 0.0)
error->all(FLERR,"Distance must be > 0 for compute event/displace");
displace_distsq = displace_dist * displace_dist;
// fix event ID will be set later by PRD
id_event = NULL;
}
/* ---------------------------------------------------------------------- */
ComputeEventDisplace::~ComputeEventDisplace()
{
delete [] id_event;
}
/* ---------------------------------------------------------------------- */
void ComputeEventDisplace::init()
{
// if id_event is not set, this compute is not active
// if set by PRD, then find fix which stores original atom coords
// check if it is correct style
if (id_event != NULL) {
int ifix = modify->find_fix(id_event);
if (ifix < 0) error->all(FLERR,
"Could not find compute event/displace fix ID");
fix_event = (FixEvent*) modify->fix[ifix];
if (strcmp(fix_event->style,"EVENT/PRD") != 0 &&
strcmp(fix_event->style,"EVENT/TAD") != 0)
error->all(FLERR,"Compute event/displace has invalid fix event assigned");
}
triclinic = domain->triclinic;
}
/* ----------------------------------------------------------------------
return non-zero if an atom has moved > displace_dist since last event
------------------------------------------------------------------------- */
double ComputeEventDisplace::compute_scalar()
{
invoked_scalar = update->ntimestep;
if (id_event == NULL) return 0.0;
double event = 0.0;
double **xevent = fix_event->array_atom;
double **x = atom->x;
int *mask = atom->mask;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
double *h = domain->h;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
int xbox,ybox,zbox;
double dx,dy,dz,rsq;
if (triclinic == 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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + xbox*xprd - xevent[i][0];
dy = x[i][1] + ybox*yprd - xevent[i][1];
dz = x[i][2] + zbox*zprd - xevent[i][2];
rsq = dx*dx + dy*dy + dz*dz;
if (rsq >= displace_distsq) {
event = 1.0;
break;
}
}
} 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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox - xevent[i][0];
dy = x[i][1] + h[1]*ybox + h[3]*zbox - xevent[i][1];
dz = x[i][2] + h[2]*zbox - xevent[i][2];
rsq = dx*dx + dy*dy + dz*dz;
if (rsq >= displace_distsq) {
event = 1.0;
break;
}
}
}
MPI_Allreduce(&event,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
return scalar;
}
/* ---------------------------------------------------------------------- */
void ComputeEventDisplace::reset_extra_compute_fix(const char *id_new)
{
delete [] id_event;
id_event = NULL;
if (id_new == NULL) return;
int n = strlen(id_new) + 1;
id_event = new char[n];
strcpy(id_event,id_new);
}
diff --git a/src/REPLICA/fix_event.cpp b/src/REPLICA/fix_event.cpp
index 4f5953057..ff4303603 100644
--- a/src/REPLICA/fix_event.cpp
+++ b/src/REPLICA/fix_event.cpp
@@ -1,264 +1,265 @@
/* ----------------------------------------------------------------------
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), Aidan Thompson (SNL)
------------------------------------------------------------------------- */
#include "stdlib.h"
#include "string.h"
#include "fix_event.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;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixEvent::FixEvent(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg != 3) error->all(FLERR,"Illegal fix event command");
restart_global = 1;
// perform initial allocation of atom-based array
// register with Atom class
xevent = NULL;
xold = NULL;
vold = NULL;
imageold = NULL;
grow_arrays(atom->nmax);
atom->add_callback(0);
}
/* ---------------------------------------------------------------------- */
FixEvent::~FixEvent()
{
// unregister callbacks to this fix from Atom class
atom->delete_callback(id,0);
// delete locally stored array
memory->destroy(xevent);
memory->destroy(xold);
memory->destroy(vold);
memory->destroy(imageold);
}
/* ---------------------------------------------------------------------- */
int FixEvent::setmask()
{
return 0;
}
/* ----------------------------------------------------------------------
save current atom coords as an event
called when an event occurs
------------------------------------------------------------------------- */
void FixEvent::store_event()
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
domain->unmap(x[i],image[i],xevent[i]);
}
/* ----------------------------------------------------------------------
restore atom coords to quenched initial state
called prior to NEB calculation
------------------------------------------------------------------------- */
void FixEvent::restore_event()
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
x[i][0] = xevent[i][0];
x[i][1] = xevent[i][1];
x[i][2] = xevent[i][2];
// Since xevent is unwrapped coordinate, need to
// adjust image flags when remapping
- image[i] = (512 << 20) | (512 << 10) | 512;
+ image[i] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMASK << IMGBITS) | IMGMASK;
domain->remap(x[i],image[i]);
- // domain->remap(x[i]);
+ // domain->remap(x[i]);
}
}
/* ----------------------------------------------------------------------
store state of all atoms
called before quench and subsequent check for event
so can later restore pre-quench state if no event occurs
------------------------------------------------------------------------- */
void FixEvent::store_state()
{
double **x = atom->x;
double **v = atom->v;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
xold[i][0] = x[i][0];
xold[i][1] = x[i][1];
xold[i][2] = x[i][2];
vold[i][0] = v[i][0];
vold[i][1] = v[i][1];
vold[i][2] = v[i][2];
imageold[i] = image[i];
}
}
/* ----------------------------------------------------------------------
restore state of all atoms to pre-quench state
called after no event detected so can continue
------------------------------------------------------------------------- */
void FixEvent::restore_state()
{
double **x = atom->x;
double **v = atom->v;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
x[i][0] = xold[i][0];
x[i][1] = xold[i][1];
x[i][2] = xold[i][2];
v[i][0] = vold[i][0];
v[i][1] = vold[i][1];
v[i][2] = vold[i][2];
image[i] = imageold[i];
}
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double FixEvent::memory_usage()
{
double bytes = 6*atom->nmax * sizeof(double);
bytes += atom->nmax*sizeof(int);
return bytes;
}
/* ----------------------------------------------------------------------
allocate atom-based array
------------------------------------------------------------------------- */
void FixEvent::grow_arrays(int nmax)
{
memory->grow(xevent,nmax,3,"event:xevent");
memory->grow(xold,nmax,3,"event:xold");
memory->grow(vold,nmax,3,"event:vold");
memory->grow(imageold,nmax,"event:imageold");
// allow compute event to access stored event coords
array_atom = xevent;
}
/* ----------------------------------------------------------------------
copy values within local atom-based array
------------------------------------------------------------------------- */
void FixEvent::copy_arrays(int i, int j)
{
xevent[j][0] = xevent[i][0];
xevent[j][1] = xevent[i][1];
xevent[j][2] = xevent[i][2];
xold[j][0] = xold[i][0];
xold[j][1] = xold[i][1];
xold[j][2] = xold[i][2];
vold[j][0] = vold[i][0];
vold[j][1] = vold[i][1];
vold[j][2] = vold[i][2];
imageold[j] = imageold[i];
}
/* ----------------------------------------------------------------------
pack values in local atom-based array for exchange with another proc
------------------------------------------------------------------------- */
int FixEvent::pack_exchange(int i, double *buf)
{
buf[0] = xevent[i][0];
buf[1] = xevent[i][1];
buf[2] = xevent[i][2];
buf[3] = xold[i][0];
buf[4] = xold[i][1];
buf[5] = xold[i][2];
buf[6] = vold[i][0];
buf[7] = vold[i][1];
buf[8] = vold[i][2];
buf[9] = imageold[i];
return 10;
}
/* ----------------------------------------------------------------------
unpack values in local atom-based array from exchange with another proc
------------------------------------------------------------------------- */
int FixEvent::unpack_exchange(int nlocal, double *buf)
{
xevent[nlocal][0] = buf[0];
xevent[nlocal][1] = buf[1];
xevent[nlocal][2] = buf[2];
xold[nlocal][0] = buf[3];
xold[nlocal][1] = buf[4];
xold[nlocal][2] = buf[5];
vold[nlocal][0] = buf[6];
vold[nlocal][1] = buf[7];
vold[nlocal][2] = buf[8];
imageold[nlocal] = static_cast<int>(buf[9]);
return 10;
}
/* ----------------------------------------------------------------------
pack entire state of Fix into one write
------------------------------------------------------------------------- */
void FixEvent::write_restart(FILE *fp)
{
}
/* ----------------------------------------------------------------------
use state info from restart file to restart the Fix
------------------------------------------------------------------------- */
void FixEvent::restart(char *buf)
{
}
diff --git a/src/REPLICA/tad.cpp b/src/REPLICA/tad.cpp
index 1de01883d..70f3ed809 100644
--- a/src/REPLICA/tad.cpp
+++ b/src/REPLICA/tad.cpp
@@ -1,1020 +1,1021 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#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(FLERR,"Tad command before simulation box is defined");
if (universe->nworlds == 1)
error->all(FLERR,"Cannot use TAD with a single replica for NEB");
if (universe->nworlds != universe->nprocs)
error->all(FLERR,"Can only use TAD with 1-processor replicas for NEB");
if (atom->sortfreq > 0)
error->all(FLERR,"Cannot use TAD with atom_modify sort enabled for NEB");
if (atom->map_style == 0)
error->all(FLERR,"Cannot use TAD unless atom map exists for NEB");
if (narg < 7) error->universe_all(FLERR,"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 = new char[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(FLERR,"Invalid t_event in tad command");
if (nsteps % t_event)
error->universe_all(FLERR,"TAD nsteps must be multiple of t_event");
if (delta_conf <= 0.0 || delta_conf >= 1.0)
error->universe_all(FLERR,"Invalid delta_conf in tad command");
if (tmax <= 0.0)
error->universe_all(FLERR,"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(FLERR,"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(FLERR,"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;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many timesteps");
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 N M Status Barrier Margin t_lo delt_lo\n"
);
if (universe->ulogfile)
fprintf(universe->ulogfile,
"Step CPU N M Status Barrier Margin t_lo delt_lo\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->init();
timer->barrier_start(Timer::LOOP);
time_start = timer->get_wall(Timer::LOOP);
fix_event->store_event_tad(update->ntimestep);
log_event(0);
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(Timer::LOOP);
time_start = timer->get_wall(Timer::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_flag && universe->iworld == 0) {
if (output->restart_every_single &&
fix_event->event_number % output->restart_every_single == 0)
restart_flag = 1;
if (output->restart_every_double &&
fix_event->event_number % output->restart_every_double == 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(Timer::LOOP);
output->write_restart(update->ntimestep);
timer->barrier_stop(Timer::LOOP);
time_output += timer->get_wall(Timer::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->set_wall(Timer::LOOP, time_start);
timer->barrier_stop(Timer::LOOP);
timer->set_wall(Timer::PAIR, time_neb);
timer->set_wall(Timer::BOND, time_dynamics);
timer->set_wall(Timer::KSPACE, time_quench);
timer->set_wall(Timer::COMM, time_comm);
timer->set_wall(Timer::OUTPUT, time_output);
neighbor->ncalls = nbuild;
neighbor->ndanger = ndanger;
if (me_universe == 0) {
if (universe->uscreen)
fprintf(universe->uscreen,
"Loop time of %g on %d procs for %d steps with " BIGINT_FORMAT
" atoms\n",
timer->get_wall(Timer::LOOP),nprocs_universe,nsteps,atom->natoms);
if (universe->ulogfile)
fprintf(universe->ulogfile,
"Loop time of %g on %d procs for %d steps with " BIGINT_FORMAT
" atoms\n",
timer->get_wall(Timer::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 [] id_compute;
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(Timer::LOOP);
update->integrate->run(t_event);
timer->barrier_stop(Timer::LOOP);
time_dynamics += timer->get_wall(Timer::LOOP);
nbuild += neighbor->ncalls - ncalls;
ndanger += neighbor->ndanger;
update->integrate->cleanup();
finish->end(0);
}
/* ----------------------------------------------------------------------
quench minimization
------------------------------------------------------------------------- */
void TAD::quench()
{
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;
if (update->laststep < 0 || update->laststep > MAXBIGINT)
error->all(FLERR,"Too many iterations");
// 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(Timer::LOOP);
update->minimize->run(maxiter);
timer->barrier_stop(Timer::LOOP);
time_quench += timer->get_wall(Timer::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(int ievent)
{
timer->set_wall(Timer::LOOP, time_start);
if (universe->me == 0) {
double tfrac = 0.0;
if (universe->uscreen)
fprintf(universe->uscreen,
BIGINT_FORMAT " %.3f %d %d %s %.3f %.3f %.3f %.3f\n",
fix_event->event_timestep,
timer->elapsed(Timer::LOOP),
fix_event->event_number,ievent,
"E ",
fix_event->ebarrier,tfrac,
fix_event->tlo,deltfirst);
if (universe->ulogfile)
fprintf(universe->ulogfile,
BIGINT_FORMAT " %.3f %d %d %s %.3f %.3f %.3f %.3f\n",
fix_event->event_timestep,
timer->elapsed(Timer::LOOP),
fix_event->event_number,ievent,
"E ",
fix_event->ebarrier,tfrac,
fix_event->tlo,deltfirst);
}
// 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(Timer::LOOP);
modify->addstep_compute_all(update->ntimestep);
update->integrate->setup_minimal(1);
output->write_dump(update->ntimestep);
timer->barrier_stop(Timer::LOOP);
time_output += timer->get_wall(Timer::LOOP);
}
}
/* ----------------------------------------------------------------------
parse optional parameters at end of TAD input line
------------------------------------------------------------------------- */
void TAD::options(int narg, char **arg)
{
if (narg < 0) error->all(FLERR,"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(FLERR,"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(FLERR,"Illegal tad command");
iarg += 5;
} else if (strcmp(arg[iarg],"neb") == 0) {
if (iarg+6 > narg) error->all(FLERR,"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(FLERR,"Illegal tad command");
iarg += 6;
} else if (strcmp(arg[iarg],"min_style") == 0) {
if (iarg+2 > narg) error->all(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"Illegal tad command");
}
}
/* ----------------------------------------------------------------------
perform NEB calculation
------------------------------------------------------------------------- */
void TAD::perform_neb(int ievent)
{
double **x = atom->x;
int nlocal = atom->nlocal;
double *buf_final;
memory->create(buf_final,3*nlocal,"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;
memory->create(buf_init,3*nlocal,"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->destroy(buf_init);
memory->destroy(buf_final);
// run NEB
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(Timer::LOOP);
// neb->run();
// timer->barrier_stop(Timer::LOOP);
// time_neb += timer->get_wall(Timer::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;
+ tagint *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);
+ image[i] =
+ ((int(array_atom[i][5]) + (tagint) IMGMAX & IMGMASK) << IMG2BITS) |
+ ((int(array_atom[i][4]) + (tagint) IMGMAX & IMGMASK) << IMGBITS) |
+ (int(array_atom[i][3]) + IMGMAX & IMGMASK);
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;
// update first event
char* statstr = (char *) "D ";
if (ievent == 0) {
deltfirst = deltlo;
event_first = ievent;
statstr = (char *) "DF";
} else if (deltlo < deltfirst) {
deltfirst = deltlo;
event_first = ievent;
statstr = (char *) "DF";
}
// first-replica output about each event
timer->set_wall(Timer::LOOP, time_start);
if (universe->me == 0) {
double tfrac = 0.0;
if (ievent > 0) tfrac = delthi/deltstop;
if (universe->uscreen)
fprintf(universe->uscreen,
BIGINT_FORMAT " %.3f %d %d %s %.3f %.3f %.3f %.3f\n",
fix_event_list[ievent]->event_timestep,
timer->elapsed(Timer::LOOP),
fix_event->event_number,
ievent,statstr,ebarrier,tfrac,
fix_event->tlo,deltlo);
if (universe->ulogfile)
fprintf(universe->ulogfile,
BIGINT_FORMAT " %.3f %d %d %s %.3f %.3f %.3f %.3f\n",
fix_event_list[ievent]->event_timestep,
timer->elapsed(Timer::LOOP),
fix_event->event_number,
ievent,statstr,ebarrier,tfrac,
fix_event->tlo,deltlo);
}
}
/* ----------------------------------------------------------------------
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
// Should really use copy constructor for this
fix_event->tlo = fix_event_list[ievent]->tlo;
fix_event->ebarrier = fix_event_list[ievent]->ebarrier;
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(ievent);
// 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/USER-AWPMD/atom_vec_wavepacket.cpp b/src/USER-AWPMD/atom_vec_wavepacket.cpp
index 52aa2c182..538245d07 100644
--- a/src/USER-AWPMD/atom_vec_wavepacket.cpp
+++ b/src/USER-AWPMD/atom_vec_wavepacket.cpp
@@ -1,1009 +1,1014 @@
/* ----------------------------------------------------------------------
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: Ilya Valuev (JIHT, Moscow, Russia)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "atom_vec_wavepacket.h"
#include "atom.h"
#include "comm.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
/* ---------------------------------------------------------------------- */
AtomVecWavepacket::AtomVecWavepacket(LAMMPS *lmp, int narg, char **arg) :
AtomVec(lmp, narg, arg)
{
comm_x_only = comm_f_only = 0;
mass_type = 1;
molecular = 0;
size_forward = 4; // coords[3]+radius[1]
size_reverse = 10; // force[3]+erforce[1]+ervelforce[1]+vforce[3]+csforce[2]
size_border = 10; // coords[3]+tag[1]+type[1]+mask[1]+q[1]+spin[1]+eradius[1]+etag[1]
size_velocity = 6; // +velocities[3]+ ervel[1]+cs[2]
size_data_atom = 11; // for input file: 1-tag 2-type 3-q 4-spin 5-eradius 6-etag 7-cs_re 8-cs_im 9-x 10-y 11-z
size_data_vel = 5; // for input file: vx vy vz ervel <??>
xcol_data = 9; // starting column for x data
atom->wavepacket_flag = 1;
atom->electron_flag = 1; // compatible with eff
atom->q_flag = atom->spin_flag = atom->eradius_flag =
atom->ervel_flag = atom->erforce_flag = 1;
atom->cs_flag = atom->csforce_flag = atom->vforce_flag = atom->ervelforce_flag = atom->etag_flag = 1;
}
/* ----------------------------------------------------------------------
grow atom-electron arrays
n = 0 grows arrays by DELTA
n > 0 allocates arrays to size n
------------------------------------------------------------------------- */
void AtomVecWavepacket::grow(int n)
{
if (n == 0) nmax += DELTA;
else nmax = n;
atom->nmax = nmax;
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
q = memory->grow(atom->q,nmax,"atom:q");
spin = memory->grow(atom->spin,nmax,"atom:spin");
eradius = memory->grow(atom->eradius,nmax,"atom:eradius");
ervel = memory->grow(atom->ervel,nmax,"atom:ervel");
erforce = memory->grow(atom->erforce,nmax*comm->nthreads,"atom:erforce");
cs = memory->grow(atom->cs,2*nmax,"atom:cs");
csforce = memory->grow(atom->csforce,2*nmax,"atom:csforce");
vforce = memory->grow(atom->vforce,3*nmax,"atom:vforce");
ervelforce = memory->grow(atom->ervelforce,nmax,"atom:ervelforce");
etag = memory->grow(atom->etag,nmax,"atom:etag");
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 AtomVecWavepacket::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;
cs = atom->cs;
csforce = atom->csforce;
vforce = atom->vforce;
ervelforce = atom->ervelforce;
etag = atom->etag;
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecWavepacket::copy(int i, int j, int delflag)
{
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];
cs[2*j] = cs[2*i];
cs[2*j+1] = cs[2*i+1];
etag[j] = etag[i];
if (atom->nextra_grow)
for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
}
/* ---------------------------------------------------------------------- */
// this will be used as partial pack for unsplit Hartree packets (v, ervel not regarded as separate variables)
int AtomVecWavepacket::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];
}
} 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];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
// this is a complete pack of all 'position' variables of AWPMD
int AtomVecWavepacket::pack_comm_vel(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz,dvx,dvy,dvz;
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++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
buf[m++] = ervel[j];
buf[m++] = cs[2*j];
buf[m++] = cs[2*j+1];
}
} 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;
}
if (!deform_vremap) {
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++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
buf[m++] = ervel[j];
buf[m++] = cs[2*j];
buf[m++] = cs[2*j+1];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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++] = eradius[j];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
buf[m++] = ervel[j];
buf[m++] = cs[2*j];
buf[m++] = cs[2*j+1];
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecWavepacket::pack_comm_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = eradius[j];
buf[m++] = ervel[j];
buf[m++] = cs[2*j];
buf[m++] = cs[2*j+1];
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecWavepacket::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++];
}
}
/* ---------------------------------------------------------------------- */
void AtomVecWavepacket::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++];
eradius[i] = buf[m++];
v[i][0] = buf[m++];
v[i][1] = buf[m++];
v[i][2] = buf[m++];
ervel[i] = buf[m++];
cs[2*i] = buf[m++];
cs[2*i+1] = buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int AtomVecWavepacket::unpack_comm_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++){
eradius[i] = buf[m++];
ervel[i] = buf[m++];
cs[2*i] = buf[m++];
cs[2*i+1] = buf[m++];
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecWavepacket::pack_reverse(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) { //10
buf[m++] = f[i][0];
buf[m++] = f[i][1];
buf[m++] = f[i][2];
buf[m++] = erforce[i];
buf[m++] = ervelforce[i];
buf[m++] = vforce[3*i];
buf[m++] = vforce[3*i+1];
buf[m++] = vforce[3*i+2];
buf[m++] = csforce[2*i];
buf[m++] = csforce[2*i+1];
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecWavepacket::pack_reverse_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++){
buf[m++] = erforce[i];
buf[m++] = ervelforce[i];
buf[m++] = vforce[3*i];
buf[m++] = vforce[3*i+1];
buf[m++] = vforce[3*i+2];
buf[m++] = csforce[2*i];
buf[m++] = csforce[2*i+1];
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecWavepacket::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++];
ervelforce[j] += buf[m++];
vforce[3*j] += buf[m++];
vforce[3*j+1] += buf[m++];
vforce[3*j+2] += buf[m++];
csforce[2*j] += buf[m++];
csforce[2*j+1] += buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int AtomVecWavepacket::unpack_reverse_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
erforce[j] += buf[m++];
ervelforce[j] += buf[m++];
vforce[3*j] += buf[m++];
vforce[3*j+1] += buf[m++];
vforce[3*j+2] += buf[m++];
csforce[2*j] += buf[m++];
csforce[2*j+1] += buf[m++];
}
return m;
}
/* ---------------------------------------------------------------------- */
// will be used for Hartree unsplit version (the etag is added however)
int AtomVecWavepacket::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++] = etag[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++] = etag[j];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecWavepacket::pack_border_vel(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz,dvx,dvy,dvz;
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++] = etag[j];
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
buf[m++] = ervel[j];
buf[m++] = cs[2*j];
buf[m++] = cs[2*j+1];
}
} 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];
}
if (domain->triclinic == 0) {
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++] = etag[j];
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
buf[m++] = ervel[j];
buf[m++] = cs[2*j];
buf[m++] = cs[2*j+1];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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++] = etag[j];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
buf[m++] = ervel[j];
buf[m++] = cs[2*j];
buf[m++] = cs[2*j+1];
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecWavepacket::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = q[j];
buf[m++] = spin[j];
buf[m++] = eradius[j];
buf[m++] = etag[j];
buf[m++] = ervel[j];
buf[m++] = cs[2*j];
buf[m++] = cs[2*j+1];
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecWavepacket::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++];
etag[i] = (int)buf[m++];
}
}
/* ---------------------------------------------------------------------- */
void AtomVecWavepacket::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++];
spin[i] = static_cast<int> (buf[m++]);
eradius[i] = buf[m++];
etag[i] = (int)buf[m++];
v[i][0] = buf[m++];
v[i][1] = buf[m++];
v[i][2] = buf[m++];
ervel[i] = buf[m++];
cs[2*i] = buf[m++];
cs[2*i+1] = buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int AtomVecWavepacket::unpack_border_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
q[i] = buf[m++];
spin[i] = static_cast<int> (buf[m++]);
eradius[i] = buf[m++];
etag[i] = (int)buf[m++];
ervel[i] = buf[m++];
cs[2*i] = buf[m++];
cs[2*i+1] = buf[m++];
}
return 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 AtomVecWavepacket::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];
+ *((tagint *) &buf[m++]) = image[i];
+
buf[m++] = q[i];
buf[m++] = spin[i];
buf[m++] = eradius[i];
buf[m++] = ervel[i];
buf[m++] = etag[i];
buf[m++] = cs[2*i];
buf[m++] = cs[2*i+1];
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 AtomVecWavepacket::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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
+
q[nlocal] = buf[m++];
spin[nlocal] = static_cast<int> (buf[m++]);
eradius[nlocal] = buf[m++];
ervel[nlocal] = buf[m++];
etag[nlocal] = buf[m++];
cs[2*nlocal] = buf[m++];
cs[2*nlocal+1] = 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 AtomVecWavepacket::size_restart()
{
int i;
int nlocal = atom->nlocal;
int n = 18 * 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 AtomVecWavepacket::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];
+ *((tagint *) &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];
buf[m++] = etag[i];
buf[m++] = cs[2*i];
buf[m++] = cs[2*i+1];
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 AtomVecWavepacket::unpack_restart(double *buf)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) {
grow(0);
if (atom->nextra_store)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &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++];
etag[nlocal] = buf[m++];
cs[2*nlocal] = buf[m++];
cs[2*nlocal+1] = 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
AWPMD: creates a proton
------------------------------------------------------------------------- */
void AtomVecWavepacket::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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
v[nlocal][0] = 0.0;
v[nlocal][1] = 0.0;
v[nlocal][2] = 0.0;
q[nlocal] = 1.;
spin[nlocal] = 0.;
eradius[nlocal] = 0.0;
ervel[nlocal] = 0.0;
etag[nlocal]= 0.;
cs[2*nlocal] = 0.;
cs[2*nlocal+1] = 0.;
atom->nlocal++;
}
/* ----------------------------------------------------------------------
unpack one line from Atoms section of data file
initialize other atom quantities
AWPMD: 0-tag 1-type 2-q 3-spin 4-eradius 5-etag 6-cs_re 7-cs_im
------------------------------------------------------------------------- */
-void AtomVecWavepacket::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecWavepacket::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
- error->one(FLERR,"Invalid atom ID in Atoms section of data file (ID tag must be >0)");
+ error->one(FLERR,"Invalid atom ID in Atoms section of "
+ "data file (ID tag must be >0)");
type[nlocal] = atoi(values[1]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
q[nlocal] = atof(values[2]);
spin[nlocal] = atoi(values[3]);
eradius[nlocal] = atof(values[4]);
if (eradius[nlocal] < 0.0)
error->one(FLERR,"Invalid eradius in Atoms section of data file");
etag[nlocal] = atoi(values[5]);
cs[2*nlocal] = atoi(values[6]);
cs[2*nlocal+1] = atof(values[7]);
x[nlocal][0] = coord[0];
x[nlocal][1] = coord[1];
x[nlocal][2] = coord[2];
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 AtomVecWavepacket::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(FLERR,"Invalid eradius in Atoms section of data file");
etag[nlocal] = atoi(values[3]);
cs[2*nlocal] = atoi(values[4]);
cs[2*nlocal+1] = atof(values[5]);
v[nlocal][0] = 0.0;
v[nlocal][1] = 0.0;
v[nlocal][2] = 0.0;
ervel[nlocal] = 0.0;
return 3;
}
/* ----------------------------------------------------------------------
unpack one line from Velocities section of data file
------------------------------------------------------------------------- */
void AtomVecWavepacket::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 AtomVecWavepacket::data_vel_hybrid(int m, char **values)
{
ervel[m] = atof(values[0]);
return 1;
}
/* ----------------------------------------------------------------------
return # of bytes of allocated memory
------------------------------------------------------------------------- */
bigint AtomVecWavepacket::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("q")) bytes += memory->usage(q,nmax);
if (atom->memcheck("spin")) bytes += memory->usage(spin,nmax);
if (atom->memcheck("eradius")) bytes += memory->usage(eradius,nmax);
if (atom->memcheck("ervel")) bytes += memory->usage(ervel,nmax);
- if (atom->memcheck("erforce")) bytes += memory->usage(erforce,nmax*comm->nthreads);
+ if (atom->memcheck("erforce"))
+ bytes += memory->usage(erforce,nmax*comm->nthreads);
if (atom->memcheck("ervelforce")) bytes += memory->usage(ervelforce,nmax);
if (atom->memcheck("cs")) bytes += memory->usage(cs,2*nmax);
if (atom->memcheck("csforce")) bytes += memory->usage(csforce,2*nmax);
if (atom->memcheck("vforce")) bytes += memory->usage(vforce,3*nmax);
if (atom->memcheck("etag")) bytes += memory->usage(etag,nmax);
return bytes;
}
diff --git a/src/USER-AWPMD/atom_vec_wavepacket.h b/src/USER-AWPMD/atom_vec_wavepacket.h
index d6a556835..f7a46675c 100644
--- a/src/USER-AWPMD/atom_vec_wavepacket.h
+++ b/src/USER-AWPMD/atom_vec_wavepacket.h
@@ -1,98 +1,99 @@
/* -*- c++ -*- ----------------------------------------------------------
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: Ilya Valuev (JIHT RAS)
------------------------------------------------------------------------- */
#ifdef ATOM_CLASS
AtomStyle(wavepacket,AtomVecWavepacket)
#else
#ifndef LMP_ATOM_VEC_WAVEPACKET_H
#define LMP_ATOM_VEC_WAVEPACKET_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecWavepacket : public AtomVec {
public:
AtomVecWavepacket(class LAMMPS *, int, char **);
~AtomVecWavepacket() {}
void grow(int);
void grow_reset();
void copy(int, int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
int pack_comm_hybrid(int, int *, double *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int unpack_comm_hybrid(int, int, double *);
int pack_reverse(int, int, double *);
int pack_reverse_hybrid(int, int, double *);
void unpack_reverse(int, int *, double *);
int unpack_reverse_hybrid(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
void data_vel(int, char **);
int data_vel_hybrid(int, char **);
bigint memory_usage();
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
///\en spin: -1 or 1 for electron, 0 for ion (compatible with eff)
int *spin;
///\en charge: must be specified in the corresponding units (-1 for electron in real units, eff compatible)
double *q;
///\en width of the wavepacket (compatible with eff)
double *eradius;
///\en width velocity for the wavepacket (compatible with eff)
double *ervel;
///\en (generalized) force on width (compatible with eff)
double *erforce;
// AWPMD- specific:
///\en electron tag: must be the same for the WPs belonging to the same electron
int *etag;
///\en wavepacket split coeffcients: cre, cim, size is 2*N
double *cs;
///\en force on wavepacket split coeffcients: re, im, size is 2*N
double *csforce;
///\en (generalized) force on velocity, size is 3*N
double *vforce;
///\en (generalized) force on radius velocity, size is N
double *ervelforce;
};
}
#endif
#endif
diff --git a/src/USER-CG-CMM/angle_cg_cmm.cpp b/src/USER-CG-CMM/angle_cg_cmm.cpp
index f147a8723..dbeb04f50 100644
--- a/src/USER-CG-CMM/angle_cg_cmm.cpp
+++ b/src/USER-CG-CMM/angle_cg_cmm.cpp
@@ -1,436 +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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Special Angle Potential for the CMM coarse grained MD potentials.
Contributing author: Axel Kohlmeyer <akohlmey@gmail.com>
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "angle_cg_cmm.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCGCMM::AngleCGCMM(LAMMPS *lmp) : Angle(lmp) {}
/* ---------------------------------------------------------------------- */
AngleCGCMM::~AngleCGCMM()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(theta0);
memory->destroy(cg_type);
memory->destroy(epsilon);
memory->destroy(sigma);
memory->destroy(rcut);
}
}
/* ---------------------------------------------------------------------- */
void AngleCGCMM::ev_tally_lj13(int i, int j, int nlocal, int newton_bond,
double evdwl, double fpair,
double delx, double dely, double delz)
{
double v[6];
if (eflag_either) {
if (eflag_global) {
if (newton_bond) {
energy += evdwl;
} else {
if (i < nlocal)
energy += 0.5*evdwl;
if (j < nlocal)
energy += 0.5*evdwl;
}
}
if (eflag_atom) {
if (newton_bond || i < nlocal) eatom[i] += 0.5*evdwl;
if (newton_bond || j < nlocal) eatom[i] += 0.5*evdwl;
}
}
if (vflag_either) {
v[0] = delx*delx*fpair;
v[1] = dely*dely*fpair;
v[2] = delz*delz*fpair;
v[3] = delx*dely*fpair;
v[4] = delx*delz*fpair;
v[5] = dely*delz*fpair;
if (vflag_global) {
if (newton_bond) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
} else {
if (i < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
if (j < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
}
}
if (vflag_atom) {
if (newton_bond || i < nlocal) {
vatom[i][0] += 0.5*v[0];
vatom[i][1] += 0.5*v[1];
vatom[i][2] += 0.5*v[2];
vatom[i][3] += 0.5*v[3];
vatom[i][4] += 0.5*v[4];
vatom[i][5] += 0.5*v[5];
}
if (newton_bond || j < nlocal) {
vatom[j][0] += 0.5*v[0];
vatom[j][1] += 0.5*v[1];
vatom[j][2] += 0.5*v[2];
vatom[j][3] += 0.5*v[3];
vatom[j][4] += 0.5*v[4];
vatom[j][5] += 0.5*v[5];
}
}
}
}
/* ---------------------------------------------------------------------- */
void AngleCGCMM::compute(int eflag, int vflag)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2,delx3,dely3,delz3;
double eangle,f1[3],f3[3],e13,f13;
double dtheta,tk;
double rsq1,rsq2,rsq3,r1,r2,r3,c,s,a,a11,a12,a22;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
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;
s = 1.0/s;
// 1-3 LJ interaction.
// we only want to use the repulsive part,
// so this has to be done here and not in the
// general non-bonded code.
delx3 = x[i1][0] - x[i3][0];
dely3 = x[i1][1] - x[i3][1];
delz3 = x[i1][2] - x[i3][2];
- domain->minimum_image(delx3,dely3,delz3);
rsq3 = delx3*delx3 + dely3*dely3 + delz3*delz3;
r3 = sqrt(rsq3);
f13=0.0;
e13=0.0;
if (r3 < rcut[type]) {
const int cgt = cg_type[type];
const double cgpow1 = cg_pow1[cgt];
const double cgpow2 = cg_pow2[cgt];
const double cgpref = cg_prefact[cgt];
const double ratio = sigma[type]/r3;
const double eps = epsilon[type];
f13 = cgpref*eps / rsq3 * (cgpow1*pow(ratio,cgpow1)
- cgpow2*pow(ratio,cgpow2));
if (eflag) e13 = eps + cgpref*eps * (pow(ratio,cgpow1)
- pow(ratio,cgpow2));
}
// force & energy
dtheta = acos(c) - theta0[type];
tk = k[type] * dtheta;
if (eflag) eangle = tk*dtheta;
a = -2.0 * tk * s;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 atoms
if (newton_bond || i1 < nlocal) {
f[i1][0] += f1[0] + f13*delx3;
f[i1][1] += f1[1] + f13*dely3;
f[i1][2] += f1[2] + f13*delz3;
}
if (newton_bond || i2 < nlocal) {
f[i2][0] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0] - f13*delx3;
f[i3][1] += f3[1] - f13*dely3;
f[i3][2] += f3[2] - f13*delz3;
}
if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
if (evflag) ev_tally_lj13(i1,i3,nlocal,newton_bond,
e13,f13,delx3,dely3,delz3);
}
}
/* ---------------------------------------------------------------------- */
void AngleCGCMM::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(k,n+1,"angle:k");
memory->create(theta0,n+1,"angle:theta0");
memory->create(epsilon,n+1,"angle:epsilon");
memory->create(sigma,n+1,"angle:sigma");
memory->create(rcut,n+1,"angle:rcut");
memory->create(cg_type,n+1,"angle:cg_type");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) {
cg_type[i] = CG_NOT_SET;
setflag[i] = 0;
}
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void AngleCGCMM::coeff(int narg, char **arg)
{
if (narg != 6) error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
double k_one = atof(arg[1]);
double theta0_one = atof(arg[2]);
int cg_type_one=find_cg_type(arg[3]);
if (cg_type_one == CG_NOT_SET) error->all(FLERR,"Error reading CG type flag.");
double epsilon_one = atof(arg[4]);
double sigma_one = atof(arg[5]);
// find minimum of LJ potential. we only want to include
// the repulsive part of the 1-3 LJ.
double rcut_one = sigma_one*exp(
1.0/(cg_pow1[cg_type_one]-cg_pow2[cg_type_one])
*log(cg_pow1[cg_type_one]/cg_pow2[cg_type_one])
);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
// convert theta0 from degrees to radians
theta0[i] = theta0_one/180.0 * MY_PI;
epsilon[i] = epsilon_one;
sigma[i] = sigma_one;
rcut[i] = rcut_one;
cg_type[i] = cg_type_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
}
/* ---------------------------------------------------------------------- */
double AngleCGCMM::equilibrium_angle(int i)
{
return theta0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleCGCMM::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nangletypes,fp);
fwrite(&theta0[1],sizeof(double),atom->nangletypes,fp);
fwrite(&epsilon[1],sizeof(double),atom->nangletypes,fp);
fwrite(&sigma[1],sizeof(double),atom->nangletypes,fp);
fwrite(&rcut[1],sizeof(double),atom->nangletypes,fp);
fwrite(&cg_type[1],sizeof(int),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleCGCMM::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&k[1],sizeof(double),atom->nangletypes,fp);
fread(&theta0[1],sizeof(double),atom->nangletypes,fp);
fread(&epsilon[1],sizeof(double),atom->nangletypes,fp);
fread(&sigma[1],sizeof(double),atom->nangletypes,fp);
fread(&rcut[1],sizeof(double),atom->nangletypes,fp);
fread(&cg_type[1],sizeof(int),atom->nangletypes,fp);
}
MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&theta0[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&epsilon[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&sigma[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&rcut[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&cg_type[1],atom->nangletypes,MPI_INT,0,world);
for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double AngleCGCMM::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// 1-3 LJ interaction.
double delx3 = x[i1][0] - x[i3][0];
double dely3 = x[i1][1] - x[i3][1];
double delz3 = x[i1][2] - x[i3][2];
domain->minimum_image(delx3,dely3,delz3);
const double r3 = sqrt(delx3*delx3 + dely3*dely3 + delz3*delz3);
double e13=0.0;
if (r3 < rcut[type]) {
const int cgt = cg_type[type];
const double cgpow1 = cg_pow1[cgt];
const double cgpow2 = cg_pow2[cgt];
const double cgpref = cg_prefact[cgt];
const double ratio = sigma[type]/r3;
const double eps = epsilon[type];
e13 = eps + cgpref*eps * (pow(ratio,cgpow1)
- pow(ratio,cgpow2));
}
double dtheta = acos(c) - theta0[type];
double tk = k[type] * dtheta;
return tk*dtheta + e13;
}
diff --git a/src/USER-CG-CMM/angle_sdk.cpp b/src/USER-CG-CMM/angle_sdk.cpp
index 35c4416af..fef80ea83 100644
--- a/src/USER-CG-CMM/angle_sdk.cpp
+++ b/src/USER-CG-CMM/angle_sdk.cpp
@@ -1,497 +1,494 @@
/* ----------------------------------------------------------------------
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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Variant of the harmonic angle potential for use with the
lj/sdk potential for coarse grained MD simulations.
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "angle_sdk.h"
#include "atom.h"
#include "neighbor.h"
#include "pair.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
#include "lj_sdk_common.h"
using namespace LAMMPS_NS;
using namespace MathConst;
using namespace LJSDKParms;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleSDK::AngleSDK(LAMMPS *lmp) : Angle(lmp) { repflag = 0;}
/* ---------------------------------------------------------------------- */
AngleSDK::~AngleSDK()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(theta0);
memory->destroy(repscale);
allocated = 0;
}
}
/* ---------------------------------------------------------------------- */
void AngleSDK::compute(int eflag, int vflag)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2,delx3,dely3,delz3;
double eangle,f1[3],f3[3],e13,f13;
double dtheta,tk;
double rsq1,rsq2,rsq3,r1,r2,c,s,a,a11,a12,a22;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
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;
s = 1.0/s;
// 1-3 LJ interaction.
// we only want to use the repulsive part,
// and it can be scaled (or off).
// so this has to be done here and not in the
// general non-bonded code.
f13 = e13 = delx3 = dely3 = delz3 = 0.0;
if (repflag) {
delx3 = x[i1][0] - x[i3][0];
dely3 = x[i1][1] - x[i3][1];
delz3 = x[i1][2] - x[i3][2];
- domain->minimum_image(delx3,dely3,delz3);
rsq3 = delx3*delx3 + dely3*dely3 + delz3*delz3;
const int type1 = atom->type[i1];
const int type3 = atom->type[i3];
f13=0.0;
e13=0.0;
if (rsq3 < rminsq[type1][type3]) {
const int ljt = lj_type[type1][type3];
const double r2inv = 1.0/rsq3;
if (ljt == LJ12_4) {
const double r4inv=r2inv*r2inv;
f13 = r4inv*(lj1[type1][type3]*r4inv*r4inv - lj2[type1][type3]);
if (eflag) e13 = r4inv*(lj3[type1][type3]*r4inv*r4inv - lj4[type1][type3]);
} else if (ljt == LJ9_6) {
const double r3inv = r2inv*sqrt(r2inv);
const double r6inv = r3inv*r3inv;
f13 = r6inv*(lj1[type1][type3]*r3inv - lj2[type1][type3]);
if (eflag) e13 = r6inv*(lj3[type1][type3]*r3inv - lj4[type1][type3]);
} else if (ljt == LJ12_6) {
const double r6inv = r2inv*r2inv*r2inv;
f13 = r6inv*(lj1[type1][type3]*r6inv - lj2[type1][type3]);
if (eflag) e13 = r6inv*(lj3[type1][type3]*r6inv - lj4[type1][type3]);
}
// make sure energy is 0.0 at the cutoff.
if (eflag) e13 -= emin[type1][type3];
f13 *= r2inv;
}
}
// force & energy
dtheta = acos(c) - theta0[type];
tk = k[type] * dtheta;
if (eflag) eangle = tk*dtheta;
a = -2.0 * tk * s;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of the 3 atoms
if (newton_bond || i1 < nlocal) {
f[i1][0] += f1[0] + f13*delx3;
f[i1][1] += f1[1] + f13*dely3;
f[i1][2] += f1[2] + f13*delz3;
}
if (newton_bond || i2 < nlocal) {
f[i2][0] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0] - f13*delx3;
f[i3][1] += f3[1] - f13*dely3;
f[i3][2] += f3[2] - f13*delz3;
}
if (evflag) {
ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
if (repflag)
ev_tally13(i1,i3,nlocal,newton_bond,e13,f13,delx3,dely3,delz3);
}
}
}
/* ---------------------------------------------------------------------- */
void AngleSDK::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(k,n+1,"angle:k");
memory->create(theta0,n+1,"angle:theta0");
memory->create(repscale,n+1,"angle:repscale");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void AngleSDK::coeff(int narg, char **arg)
{
if ((narg < 3) || (narg > 6))
error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
double k_one = force->numeric(arg[1]);
double theta0_one = force->numeric(arg[2]);
double repscale_one;
// backward compatibility with old cg/cmm style input:
// this had <lj_type> <epsilon> <sigma>
// if epsilon is set to 0.0 we accept it as repscale 0.0
// otherwise assume repscale 1.0, since we were using
// epsilon to turn repulsion on or off.
if (narg == 6) {
repscale_one = force->numeric(arg[4]);
if (repscale_one > 0.0) repscale_one = 1.0;
} else if (narg == 4) repscale_one = force->numeric(arg[3]);
else if (narg == 3) repscale_one = 1.0;
else error->all(FLERR,"Incorrect args for angle coefficients");
// convert theta0 from degrees to radians and store coefficients
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
theta0[i] = theta0_one/180.0 * MY_PI;
repscale[i] = repscale_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
}
/* ----------------------------------------------------------------------
error check and initialize all values needed for force computation
------------------------------------------------------------------------- */
void AngleSDK::init_style()
{
// make sure we use an SDK pair_style and that we need the 1-3 repulsion
repflag = 0;
for (int i = 1; i <= atom->nangletypes; i++)
if (repscale[i] > 0.0) repflag = 1;
// set up pointers to access SDK LJ parameters for 1-3 interactions
if (repflag) {
int itmp;
if (force->pair == NULL)
error->all(FLERR,"Angle style SDK requires use of a compatible with Pair style");
lj1 = (double **) force->pair->extract("lj1",itmp);
lj2 = (double **) force->pair->extract("lj2",itmp);
lj3 = (double **) force->pair->extract("lj3",itmp);
lj4 = (double **) force->pair->extract("lj4",itmp);
lj_type = (int **) force->pair->extract("lj_type",itmp);
rminsq = (double **) force->pair->extract("rminsq",itmp);
emin = (double **) force->pair->extract("emin",itmp);
if (!lj1 || !lj2 || !lj3 || !lj4 || !lj_type || !rminsq || !emin)
error->all(FLERR,"Angle style SDK is incompatible with Pair style");
}
}
/* ---------------------------------------------------------------------- */
double AngleSDK::equilibrium_angle(int i)
{
return theta0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleSDK::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nangletypes,fp);
fwrite(&theta0[1],sizeof(double),atom->nangletypes,fp);
fwrite(&repscale[1],sizeof(double),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleSDK::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&k[1],sizeof(double),atom->nangletypes,fp);
fread(&theta0[1],sizeof(double),atom->nangletypes,fp);
fread(&repscale[1],sizeof(double),atom->nangletypes,fp);
}
MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&theta0[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&repscale[1],atom->nangletypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
void AngleSDK::ev_tally13(int i, int j, int nlocal, int newton_bond,
double evdwl, double fpair,
double delx, double dely, double delz)
{
double v[6];
if (eflag_either) {
if (eflag_global) {
if (newton_bond) {
energy += evdwl;
} else {
if (i < nlocal)
energy += 0.5*evdwl;
if (j < nlocal)
energy += 0.5*evdwl;
}
}
if (eflag_atom) {
if (newton_bond || i < nlocal) eatom[i] += 0.5*evdwl;
if (newton_bond || j < nlocal) eatom[i] += 0.5*evdwl;
}
}
if (vflag_either) {
v[0] = delx*delx*fpair;
v[1] = dely*dely*fpair;
v[2] = delz*delz*fpair;
v[3] = delx*dely*fpair;
v[4] = delx*delz*fpair;
v[5] = dely*delz*fpair;
if (vflag_global) {
if (newton_bond) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
} else {
if (i < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
if (j < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
}
}
if (vflag_atom) {
if (newton_bond || i < nlocal) {
vatom[i][0] += 0.5*v[0];
vatom[i][1] += 0.5*v[1];
vatom[i][2] += 0.5*v[2];
vatom[i][3] += 0.5*v[3];
vatom[i][4] += 0.5*v[4];
vatom[i][5] += 0.5*v[5];
}
if (newton_bond || j < nlocal) {
vatom[j][0] += 0.5*v[0];
vatom[j][1] += 0.5*v[1];
vatom[j][2] += 0.5*v[2];
vatom[j][3] += 0.5*v[3];
vatom[j][4] += 0.5*v[4];
vatom[j][5] += 0.5*v[5];
}
}
}
}
/* ---------------------------------------------------------------------- */
double AngleSDK::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double e13=0.0;
if (repflag) {
// 1-3 LJ interaction.
double delx3 = x[i1][0] - x[i3][0];
double dely3 = x[i1][1] - x[i3][1];
double delz3 = x[i1][2] - x[i3][2];
domain->minimum_image(delx3,dely3,delz3);
const int type1 = atom->type[i1];
const int type3 = atom->type[i3];
const double rsq3 = delx3*delx3 + dely3*dely3 + delz3*delz3;
if (rsq3 < rminsq[type1][type3]) {
const int ljt = lj_type[type1][type3];
const double r2inv = 1.0/rsq3;
if (ljt == LJ12_4) {
const double r4inv=r2inv*r2inv;
e13 = r4inv*(lj3[type1][type3]*r4inv*r4inv - lj4[type1][type3]);
} else if (ljt == LJ9_6) {
const double r3inv = r2inv*sqrt(r2inv);
const double r6inv = r3inv*r3inv;
e13 = r6inv*(lj3[type1][type3]*r3inv - lj4[type1][type3]);
} else if (ljt == LJ12_6) {
const double r6inv = r2inv*r2inv*r2inv;
e13 = r6inv*(lj3[type1][type3]*r6inv - lj4[type1][type3]);
}
// make sure energy is 0.0 at the cutoff.
e13 -= emin[type1][type3];
}
}
double dtheta = acos(c) - theta0[type];
double tk = k[type] * dtheta;
return tk*dtheta + e13;
}
diff --git a/src/USER-EFF/atom_vec_electron.cpp b/src/USER-EFF/atom_vec_electron.cpp
index 9cbdf22cb..ff1c47274 100644
--- a/src/USER-EFF/atom_vec_electron.cpp
+++ b/src/USER-EFF/atom_vec_electron.cpp
@@ -1,851 +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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Andres Jaramillo-Botero (Caltech)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "atom_vec_electron.h"
#include "atom.h"
#include "comm.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 = 4;
size_reverse = 4;
size_border = 9;
size_velocity = 3;
size_data_atom = 8;
size_data_vel = 5;
xcol_data = 6;
atom->electron_flag = 1;
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;
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
q = memory->grow(atom->q,nmax,"atom:q");
spin = memory->grow(atom->spin,nmax,"atom:spin");
eradius = memory->grow(atom->eradius,nmax,"atom:eradius");
ervel = memory->grow(atom->ervel,nmax,"atom:ervel");
erforce = memory->grow(atom->erforce,nmax*comm->nthreads,"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;
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecElectron::copy(int i, int j, int delflag)
{
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];
}
} 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];
}
}
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,dvx,dvy,dvz;
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++] = 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;
}
if (!deform_vremap) {
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++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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++] = eradius[j];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecElectron::pack_comm_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = eradius[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++];
}
}
/* ---------------------------------------------------------------------- */
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++];
eradius[i] = buf[m++];
v[i][0] = buf[m++];
v[i][1] = buf[m++];
v[i][2] = buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int AtomVecElectron::unpack_comm_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++)
eradius[i] = buf[m++];
return m;
}
/* ---------------------------------------------------------------------- */
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_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++)
buf[m++] = erforce[i];
return m;
}
/* ---------------------------------------------------------------------- */
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_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
erforce[j] += buf[m++];
}
return 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];
}
} 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];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecElectron::pack_border_vel(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz,dvx,dvy,dvz;
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++] = 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];
}
if (domain->triclinic == 0) {
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++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecElectron::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = q[j];
buf[m++] = spin[j];
buf[m++] = eradius[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
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++];
}
}
/* ---------------------------------------------------------------------- */
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++]);
q[i] = buf[m++];
spin[i] = static_cast<int> (buf[m++]);
eradius[i] = buf[m++];
v[i][0] = buf[m++];
v[i][1] = buf[m++];
v[i][2] = buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int AtomVecElectron::unpack_border_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
q[i] = buf[m++];
spin[i] = static_cast<int> (buf[m++]);
eradius[i] = buf[m++];
}
return 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 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];
+ *((tagint *) &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++]);
+ image[nlocal] = *((tagint *) &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];
+ *((tagint *) &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)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
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)
+void AtomVecElectron::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
type[nlocal] = atoi(values[1]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
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(FLERR,"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 3;
}
/* ----------------------------------------------------------------------
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
------------------------------------------------------------------------- */
bigint AtomVecElectron::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("q")) bytes += memory->usage(q,nmax);
if (atom->memcheck("spin")) bytes += memory->usage(spin,nmax);
if (atom->memcheck("eradius")) bytes += memory->usage(eradius,nmax);
if (atom->memcheck("ervel")) bytes += memory->usage(ervel,nmax);
if (atom->memcheck("erforce")) bytes += memory->usage(erforce,nmax*comm->nthreads);
return bytes;
}
diff --git a/src/USER-EFF/atom_vec_electron.h b/src/USER-EFF/atom_vec_electron.h
index 337e08eb5..0d0f8c9b5 100644
--- a/src/USER-EFF/atom_vec_electron.h
+++ b/src/USER-EFF/atom_vec_electron.h
@@ -1,72 +1,73 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(electron,AtomVecElectron)
#else
#ifndef LMP_ATOM_VEC_ELECTRON_H
#define LMP_ATOM_VEC_ELECTRON_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecElectron : public AtomVec {
public:
AtomVecElectron(class LAMMPS *, int, char **);
~AtomVecElectron() {}
void grow(int);
void grow_reset();
void copy(int, int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
int pack_comm_hybrid(int, int *, double *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int unpack_comm_hybrid(int, int, double *);
int pack_reverse(int, int, double *);
int pack_reverse_hybrid(int, int, double *);
void unpack_reverse(int, int *, double *);
int unpack_reverse_hybrid(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
void data_vel(int, char **);
int data_vel_hybrid(int, char **);
bigint memory_usage();
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
int *spin;
double *q,*eradius,*ervel,*erforce;
};
}
#endif
#endif
diff --git a/src/USER-MISC/Install.sh b/src/USER-MISC/Install.sh
index 751489049..6340eda73 100644
--- a/src/USER-MISC/Install.sh
+++ b/src/USER-MISC/Install.sh
@@ -1,103 +1,106 @@
# Install/unInstall package files in LAMMPS
if (test $1 = 1) then
+ if (test -e ../pair_eam_alloy.cpp) then
+ cp pair_cdeam.cpp ..
+ cp pair_cdeam.h ..
+ fi
+
cp angle_cosine_shift.cpp ..
cp angle_cosine_shift_exp.cpp ..
cp angle_dipole.cpp ..
cp bond_harmonic_shift.cpp ..
cp bond_harmonic_shift_cut.cpp ..
cp compute_ackland_atom.cpp ..
cp compute_temp_rotate.cpp ..
cp dihedral_cosine_shift_exp.cpp ..
cp dihedral_table.cpp ..
cp fix_addtorque.cpp ..
cp fix_imd.cpp ..
cp fix_smd.cpp ..
cp fix_spring_pull.cpp ..
cp improper_cossq.cpp ..
cp improper_ring.cpp ..
- cp pair_cdeam.cpp ..
cp pair_coul_diel.cpp ..
cp pair_dipole_sf.cpp ..
cp pair_edip.cpp ..
cp pair_gauss_cut.cpp ..
cp pair_lj_sf.cpp ..
cp pair_meam_spline.cpp ..
cp pair_tersoff_table.cpp ..
cp angle_cosine_shift.h ..
cp angle_cosine_shift_exp.h ..
cp angle_dipole.h ..
cp bond_harmonic_shift.h ..
cp bond_harmonic_shift_cut.h ..
cp compute_ackland_atom.h ..
cp compute_temp_rotate.h ..
cp dihedral_cosine_shift_exp.h ..
cp dihedral_table.h ..
cp fix_addtorque.h ..
cp fix_imd.h ..
cp fix_smd.h ..
cp fix_spring_pull.h ..
cp improper_cossq.h ..
cp improper_ring.h ..
- cp pair_cdeam.h ..
cp pair_coul_diel.h ..
cp pair_dipole_sf.h ..
cp pair_edip.h ..
cp pair_gauss_cut.h ..
cp pair_lj_sf.h ..
cp pair_meam_spline.h ..
cp pair_tersoff_table.h ..
elif (test $1 = 0) then
rm -f ../angle_cosine_shift.cpp
rm -f ../angle_cosine_shift_exp.cpp
rm -f ../angle_dipole.cpp
rm -f ../bond_harmonic_shift.cpp
rm -f ../bond_harmonic_shift_cut.cpp
rm -f ../compute_ackland_atom.cpp
rm -f ../compute_temp_rotate.cpp
rm -f ../dihedral_cosine_shift_exp.cpp
rm -f ../dihedral_table.cpp
rm -f ../fix_addtorque.cpp
rm -f ../fix_imd.cpp
rm -f ../fix_smd.cpp
rm -f ../fix_spring_pull.cpp
rm -f ../improper_cossq.cpp
rm -f ../improper_ring.cpp
rm -f ../pair_cdeam.cpp
rm -f ../pair_coul_diel.cpp
rm -f ../pair_dipole_sf.cpp
rm -f ../pair_edip.cpp
rm -f ../pair_gauss_cut.cpp
rm -f ../pair_lj_sf.cpp
rm -f ../pair_meam_spline.cpp
rm -f ../pair_tersoff_table.cpp
rm -f ../angle_cosine_shift.h
rm -f ../angle_cosine_shift_exp.h
rm -f ../angle_dipole.h
rm -f ../bond_harmonic_shift.h
rm -f ../bond_harmonic_shift_cut.h
rm -f ../compute_ackland_atom.h
rm -f ../compute_temp_rotate.h
rm -f ../dihedral_cosine_shift_exp.h
rm -f ../dihedral_table.h
rm -f ../fix_addtorque.h
rm -f ../fix_imd.h
rm -f ../fix_smd.h
rm -f ../fix_spring_pull.h
rm -f ../improper_cossq.h
rm -f ../improper_ring.h
rm -f ../pair_cdeam.h
rm -f ../pair_coul_diel.h
rm -f ../pair_dipole_sf.h
rm -f ../pair_edip.h
rm -f ../pair_gauss_cut.h
rm -f ../pair_lj_sf.h
rm -f ../pair_meam_spline.h
rm -f ../pair_tersoff_table.h
fi
diff --git a/src/USER-MISC/angle_cosine_shift.cpp b/src/USER-MISC/angle_cosine_shift.cpp
index 11b4cd070..edeececff 100644
--- a/src/USER-MISC/angle_cosine_shift.cpp
+++ b/src/USER-MISC/angle_cosine_shift.cpp
@@ -1,263 +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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Carsten Svaneborg, science@zqex.dk
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "angle_cosine_shift.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosineShift::AngleCosineShift(LAMMPS *lmp) : Angle(lmp) {}
/* ---------------------------------------------------------------------- */
AngleCosineShift::~AngleCosineShift()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(kcost);
memory->destroy(ksint);
memory->destroy(theta);
}
}
/* ---------------------------------------------------------------------- */
void AngleCosineShift::compute(int eflag, int vflag)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double rsq1,rsq2,r1,r2,c,s,cps,kcos,ksin,a11,a12,a22;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// c = cosine of angle
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// C= sine of angle
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
// force & energy
kcos=kcost[type];
ksin=ksint[type];
if (eflag) eangle = -k[type]-kcos*c-ksin*s;
cps = c/s; // NOTE absorbed one c
a11 = (-kcos +ksin*cps )*c/ rsq1;
a12 = ( kcos -ksin*cps ) / (r1*r2);
a22 = (-kcos +ksin*cps )*c/ rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
}
}
/* ---------------------------------------------------------------------- */
void AngleCosineShift::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(k ,n+1,"Angle:k");
memory->create(ksint ,n+1,"Angle:ksint");
memory->create(kcost ,n+1,"Angle:kcost");
memory->create(theta ,n+1,"Angle:theta");
memory->create(setflag,n+1, "Angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one type
------------------------------------------------------------------------- */
void AngleCosineShift::coeff(int narg, char **arg)
{
if (narg != 3) error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
double umin = force->numeric(arg[1]);
double theta0 = force->numeric(arg[2]);
// k=Umin/2
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = umin/2;
kcost[i] = umin/2*cos(theta0*3.14159265/180);
ksint[i] = umin/2*sin(theta0*3.14159265/180);
theta[i] = theta0*3.14159265/180;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
}
/* ---------------------------------------------------------------------- */
double AngleCosineShift::equilibrium_angle(int i)
{
return theta[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleCosineShift::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nangletypes,fp);
fwrite(&kcost[1],sizeof(double),atom->nangletypes,fp);
fwrite(&ksint[1],sizeof(double),atom->nangletypes,fp);
fwrite(&theta[1],sizeof(double),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleCosineShift::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0)
{
fread(&k[1],sizeof(double),atom->nangletypes,fp);
fread(&kcost[1],sizeof(double),atom->nangletypes,fp);
fread(&ksint[1],sizeof(double),atom->nangletypes,fp);
fread(&theta[1],sizeof(double),atom->nangletypes,fp);
}
MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&kcost[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&ksint[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&theta[1],atom->nangletypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double AngleCosineShift::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double s=sqrt(1.0-c*c);
return -k[type]-kcost[type]*c-ksint[type]*s;
}
diff --git a/src/USER-MISC/angle_cosine_shift_exp.cpp b/src/USER-MISC/angle_cosine_shift_exp.cpp
index 0c607b4c4..db75fb0b2 100644
--- a/src/USER-MISC/angle_cosine_shift_exp.cpp
+++ b/src/USER-MISC/angle_cosine_shift_exp.cpp
@@ -1,306 +1,304 @@
/* ----------------------------------------------------------------------
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: Carsten Svaneborg, science@zqex.dk
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "angle_cosine_shift_exp.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosineShiftExp::AngleCosineShiftExp(LAMMPS *lmp) : Angle(lmp) {}
/* ---------------------------------------------------------------------- */
AngleCosineShiftExp::~AngleCosineShiftExp()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(umin);
memory->destroy(a);
memory->destroy(opt1);
memory->destroy(cost);
memory->destroy(sint);
memory->destroy(theta0);
memory->destroy(doExpansion);
}
}
/* ---------------------------------------------------------------------- */
void AngleCosineShiftExp::compute(int eflag, int vflag)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3],ff;
double rsq1,rsq2,r1,r2,c,s,a11,a12,a22;
double exp2,aa,uumin,cccpsss,cssmscc;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x;
double **f = atom->f;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// c = cosine of angle
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// C= sine of angle
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
// force & energy
aa=a[type];
uumin=umin[type];
cccpsss = c*cost[type]+s*sint[type];
cssmscc = c*sint[type]-s*cost[type];
if (doExpansion[type])
{ // |a|<0.01 so use expansions relative precision <1e-5
// std::cout << "Using expansion\n";
if (eflag) eangle = -0.125*(1+cccpsss)*(4+aa*(cccpsss-1))*uumin;
ff=0.25*uumin*cssmscc*(2+aa*cccpsss)/s;
}
else
{
// std::cout << "Not using expansion\n";
exp2=exp(0.5*aa*(1+cccpsss));
if (eflag) eangle = opt1[type]*(1-exp2);
ff=0.5*a[type]*opt1[type]*exp2*cssmscc/s;
}
a11 = ff*c/ rsq1;
a12 = -ff / (r1*r2);
a22 = ff*c/ rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (newton_bond || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
}
}
/* ---------------------------------------------------------------------- */
void AngleCosineShiftExp::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(doExpansion, n+1, "angle:doExpansion");
memory->create(umin , n+1, "angle:umin");
memory->create(a , n+1, "angle:a");
memory->create(sint , n+1, "angle:sint");
memory->create(cost , n+1, "angle:cost");
memory->create(opt1 , n+1, "angle:opt1");
memory->create(theta0 , n+1, "angle:theta0");
memory->create(setflag , n+1, "angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one type
------------------------------------------------------------------------- */
void AngleCosineShiftExp::coeff(int narg, char **arg)
{
if (narg != 4) error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
double umin_ = force->numeric(arg[1]);
double theta0_ = force->numeric(arg[2]);
double a_ = force->numeric(arg[3]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
doExpansion[i]=(fabs(a_)<0.001);
umin[i] = umin_;
a[i] = a_;
cost[i] = cos(theta0_*3.14159265/180);
sint[i] = sin(theta0_*3.14159265/180);
theta0[i]= theta0_*3.14159265/180;
if (!doExpansion[i]) opt1[i]=umin_/(exp(a_)-1);
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
}
/* ---------------------------------------------------------------------- */
double AngleCosineShiftExp::equilibrium_angle(int i)
{
return theta0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleCosineShiftExp::write_restart(FILE *fp)
{
fwrite(&umin[1],sizeof(double),atom->nangletypes,fp);
fwrite(&a[1],sizeof(double),atom->nangletypes,fp);
fwrite(&cost[1],sizeof(double),atom->nangletypes,fp);
fwrite(&sint[1],sizeof(double),atom->nangletypes,fp);
fwrite(&theta0[1],sizeof(double),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleCosineShiftExp::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0)
{
fread(&umin[1],sizeof(double),atom->nangletypes,fp);
fread(&a[1],sizeof(double),atom->nangletypes,fp);
fread(&cost[1],sizeof(double),atom->nangletypes,fp);
fread(&sint[1],sizeof(double),atom->nangletypes,fp);
fread(&theta0[1],sizeof(double),atom->nangletypes,fp);
}
MPI_Bcast(&umin[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&a[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&cost[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&sint[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&theta0[1],atom->nangletypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nangletypes; i++)
{
setflag[i] = 1;
doExpansion[i]=(fabs(a[i])<0.01);
if (!doExpansion[i]) opt1[i]=umin[i]/(exp(a[i])-1);
}
}
/* ---------------------------------------------------------------------- */
double AngleCosineShiftExp::single(int type, int i1, int i2, int i3)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double s=sqrt(1.0-c*c);
double cccpsss=c*cost[type]+s*sint[type];
double cssmscc=c*sint[type]-s*cost[type];
if (doExpansion[type])
{
return -0.125*(1+cccpsss)*(4+a[type]*(cccpsss-1))*umin[type];
}
else
{
return opt1[type]*(1-exp(0.5*a[type]*(1+cccpsss)));
}
}
diff --git a/src/USER-MISC/angle_dipole.cpp b/src/USER-MISC/angle_dipole.cpp
index 402084241..b80007e50 100644
--- a/src/USER-MISC/angle_dipole.cpp
+++ b/src/USER-MISC/angle_dipole.cpp
@@ -1,207 +1,206 @@
/* ----------------------------------------------------------------------
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: Mario Orsi (U Southampton), orsimario@gmail.com
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "angle_dipole.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
/* ---------------------------------------------------------------------- */
AngleDipole::AngleDipole(LAMMPS *lmp) : Angle(lmp) {}
/* ---------------------------------------------------------------------- */
AngleDipole::~AngleDipole()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(gamma0);
}
}
/* ---------------------------------------------------------------------- */
void AngleDipole::compute(int eflag, int vflag)
{
int iRef,iDip,iDummy,n,type;
double delx,dely,delz;
double eangle,tangle,f1[3],f3[3];
double r,dr,cosGamma,deltaGamma,kdg,rmu;
eangle = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; // position vector
double **mu = atom->mu; // point-dipole components and moment magnitude
double **torque = atom->torque;
int **anglelist = neighbor->anglelist;
int nanglelist = neighbor->nanglelist;
int nlocal = atom->nlocal;
int newton_bond = force->newton_bond;
if (!newton_bond)
error->all(FLERR,"'newton' flag for bonded interactions must be 'on'");
for (n = 0; n < nanglelist; n++) {
iDip = anglelist[n][0]; // dipole whose orientation is to be restrained
iRef = anglelist[n][1]; // reference atom toward which dipole will point
iDummy = anglelist[n][2]; // dummy atom - irrelevant to the interaction
type = anglelist[n][3];
delx = x[iRef][0] - x[iDip][0];
dely = x[iRef][1] - x[iDip][1];
delz = x[iRef][2] - x[iDip][2];
- domain->minimum_image(delx,dely,delz);
r = sqrt(delx*delx + dely*dely + delz*delz);
rmu = r * mu[iDip][3];
cosGamma = (mu[iDip][0]*delx+mu[iDip][1]*dely+mu[iDip][2]*delz) / rmu;
deltaGamma = cosGamma - cos(gamma0[type]);
kdg = k[type] * deltaGamma;
if (eflag) eangle = kdg * deltaGamma; // energy
tangle = 2.0 * kdg / rmu;
torque[iDip][0] += tangle * (dely*mu[iDip][2] - delz*mu[iDip][1]);
torque[iDip][1] += tangle * (delz*mu[iDip][0] - delx*mu[iDip][2]);
torque[iDip][2] += tangle * (delx*mu[iDip][1] - dely*mu[iDip][0]);
f1[0] = f1[1] = f1[2] = f3[0] = f3[1] = f3[2] = 0.0;
if (evflag) // tally energy (virial=0 because force=0)
ev_tally(iRef,iDip,iDummy,nlocal,newton_bond,eangle,f1,f3,
0.0,0.0,0.0,0.0,0.0,0.0);
}
}
/* ---------------------------------------------------------------------- */
void AngleDipole::allocate()
{
allocated = 1;
int n = atom->nangletypes;
memory->create(k,n+1,"angle:k");
memory->create(gamma0,n+1,"angle:gamma0");
memory->create(setflag,n+1,"angle:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void AngleDipole::coeff(int narg, char **arg)
{
if (narg != 3) error->all(FLERR,"Incorrect args for angle coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nangletypes,ilo,ihi);
double k_one = force->numeric(arg[1]);
double gamma0_one = force->numeric(arg[2]);
// convert gamma0 from degrees to radians
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
gamma0[i] = gamma0_one/180.0 * MY_PI;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for angle coefficients");
}
/* ----------------------------------------------------------------------
used by SHAKE
------------------------------------------------------------------------- */
double AngleDipole::equilibrium_angle(int i)
{
return gamma0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void AngleDipole::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nangletypes,fp);
fwrite(&gamma0[1],sizeof(double),atom->nangletypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void AngleDipole::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&k[1],sizeof(double),atom->nangletypes,fp);
fread(&gamma0[1],sizeof(double),atom->nangletypes,fp);
}
MPI_Bcast(&k[1],atom->nangletypes,MPI_DOUBLE,0,world);
MPI_Bcast(&gamma0[1],atom->nangletypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nangletypes; i++) setflag[i] = 1;
}
/* ----------------------------------------------------------------------
used by ComputeAngleLocal
------------------------------------------------------------------------- */
double AngleDipole::single(int type, int iRef, int iDip, int iDummy)
{
double **x = atom->x; // position vector
double **mu = atom->mu; // point-dipole components and moment magnitude
double delx = x[iRef][0] - x[iDip][0];
double dely = x[iRef][1] - x[iDip][1];
double delz = x[iRef][2] - x[iDip][2];
domain->minimum_image(delx,dely,delz);
double r = sqrt(delx*delx + dely*dely + delz*delz);
double rmu = r * mu[iDip][3];
double cosGamma = (mu[iDip][0]*delx+mu[iDip][1]*dely+mu[iDip][2]*delz) / rmu;
double deltaGamma = cosGamma - cos(gamma0[type]);
double kdg = k[type] * deltaGamma;
return kdg * deltaGamma; // energy
}
diff --git a/src/USER-MISC/bond_harmonic_shift.cpp b/src/USER-MISC/bond_harmonic_shift.cpp
index e14089214..21b0ff40a 100644
--- a/src/USER-MISC/bond_harmonic_shift.cpp
+++ b/src/USER-MISC/bond_harmonic_shift.cpp
@@ -1,199 +1,199 @@
/* ----------------------------------------------------------------------
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: Carsten Svaneborg, science@zqex.dk
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "bond_harmonic_shift.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondHarmonicShift::BondHarmonicShift(LAMMPS *lmp) : Bond(lmp) {}
/* ---------------------------------------------------------------------- */
BondHarmonicShift::~BondHarmonicShift()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(r0);
memory->destroy(r1);
}
}
/* ---------------------------------------------------------------------- */
void BondHarmonicShift::compute(int eflag, int vflag)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,rk;
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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
dr = r - r0[type];
rk = k[type] * dr;
// force & energy
if (r > 0.0) fbond = -2.0*rk/r;
else fbond = 0.0;
- if (eflag) ebond = k[type]*(dr*dr -(r0[type]-r1[type])*(r0[type]-r1[type]) );
+ if (eflag)
+ ebond = k[type]*(dr*dr -(r0[type]-r1[type])*(r0[type]-r1[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 BondHarmonicShift::allocate()
{
allocated = 1;
int n = atom->nbondtypes;
memory->create(k , n+1,"bond:k");
memory->create(r0, n+1,"bond:r0");
memory->create(r1, n+1,"bond:r1");
memory->create(setflag,n+1,"bond:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void BondHarmonicShift::coeff(int narg, char **arg)
{
if (narg != 4) error->all(FLERR,"Incorrect args for bond coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nbondtypes,ilo,ihi);
double Umin = force->numeric(arg[1]); // energy at minimum
double r0_one = force->numeric(arg[2]); // position of minimum
double r1_one = force->numeric(arg[3]); // position where energy = 0
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = Umin/((r0_one-r1_one)*(r0_one-r1_one));
r0[i] = r0_one;
r1[i] = r1_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients");
}
/* ----------------------------------------------------------------------
return an equilbrium bond length
------------------------------------------------------------------------- */
double BondHarmonicShift::equilibrium_distance(int i)
{
return r0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void BondHarmonicShift::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&r1[1],sizeof(double),atom->nbondtypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void BondHarmonicShift::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(&r1[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(&r1[1],atom->nbondtypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double BondHarmonicShift::single(int type, double rsq, int i, int j)
{
double r = sqrt(rsq);
double dr = r - r0[type];
double dr2=r0[type]-r1[type];
return k[type]*(dr*dr - dr2*dr2);
}
diff --git a/src/USER-MISC/bond_harmonic_shift_cut.cpp b/src/USER-MISC/bond_harmonic_shift_cut.cpp
index 8ebb820e0..d867b5e0c 100644
--- a/src/USER-MISC/bond_harmonic_shift_cut.cpp
+++ b/src/USER-MISC/bond_harmonic_shift_cut.cpp
@@ -1,202 +1,202 @@
/* ----------------------------------------------------------------------
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: Carsten Svaneborg, science@zqex.dk
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "bond_harmonic_shift_cut.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondHarmonicShiftCut::BondHarmonicShiftCut(LAMMPS *lmp) : Bond(lmp) {}
/* ---------------------------------------------------------------------- */
BondHarmonicShiftCut::~BondHarmonicShiftCut()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(r0);
memory->destroy(r1);
}
}
/* ---------------------------------------------------------------------- */
void BondHarmonicShiftCut::compute(int eflag, int vflag)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,rk;
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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
if (r>r1[type]) continue;
dr = r - r0[type];
rk = k[type] * dr;
// force & energy
if (r > 0.0) fbond = -2.0*rk/r;
else fbond = 0.0;
- if (eflag) ebond = k[type]*(dr*dr -(r0[type]-r1[type])*(r0[type]-r1[type]) );
+ if (eflag)
+ ebond = k[type]*(dr*dr -(r0[type]-r1[type])*(r0[type]-r1[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 BondHarmonicShiftCut::allocate()
{
allocated = 1;
int n = atom->nbondtypes;
memory->create(k , n+1,"bond:k");
memory->create(r0, n+1,"bond:r0");
memory->create(r1, n+1,"bond:r1");
memory->create(setflag,n+1,"bond:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one or more types
------------------------------------------------------------------------- */
void BondHarmonicShiftCut::coeff(int narg, char **arg)
{
if (narg != 4) error->all(FLERR,"Incorrect args for bond coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->nbondtypes,ilo,ihi);
double Umin = force->numeric(arg[1]); // energy at minimum
double r0_one = force->numeric(arg[2]); // position of minimum
double r1_one = force->numeric(arg[3]); // position where energy = 0 = cutoff
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = Umin/((r0_one-r1_one)*(r0_one-r1_one));
r0[i] = r0_one;
r1[i] = r1_one;
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for bond coefficients");
}
/* ----------------------------------------------------------------------
return an equilbrium bond length
------------------------------------------------------------------------- */
double BondHarmonicShiftCut::equilibrium_distance(int i)
{
return r0[i];
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void BondHarmonicShiftCut::write_restart(FILE *fp)
{
fwrite(&k[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&r0[1],sizeof(double),atom->nbondtypes,fp);
fwrite(&r1[1],sizeof(double),atom->nbondtypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void BondHarmonicShiftCut::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(&r1[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(&r1[1],atom->nbondtypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->nbondtypes; i++) setflag[i] = 1;
}
/* ---------------------------------------------------------------------- */
double BondHarmonicShiftCut::single(int type, double rsq, int i, int j)
{
double r = sqrt(rsq);
if (r>r1[type]) return 0;
double dr = r - r0[type];
double dr2=r0[type]-r1[type];
return k[type]*(dr*dr - dr2*dr2);
}
diff --git a/src/USER-MISC/compute_temp_rotate.cpp b/src/USER-MISC/compute_temp_rotate.cpp
index 69519249c..b79634540 100644
--- a/src/USER-MISC/compute_temp_rotate.cpp
+++ b/src/USER-MISC/compute_temp_rotate.cpp
@@ -1,291 +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: Laurent Joly (U Lyon, France), ljoly.ulyon@gmail.com
------------------------------------------------------------------------- */
#include "mpi.h"
#include "stdlib.h"
#include "string.h"
#include "compute_temp_rotate.h"
#include "atom.h"
#include "update.h"
#include "force.h"
#include "group.h"
#include "modify.h"
#include "fix.h"
#include "domain.h"
#include "lattice.h"
#include "error.h"
#include "memory.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeTempRotate::ComputeTempRotate(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg != 3) error->all(FLERR,"Illegal compute temp/rotate command");
scalar_flag = vector_flag = 1;
size_vector = 6;
extscalar = 0;
extvector = 1;
tempflag = 1;
tempbias = 1;
maxbias = 0;
vbiasall = NULL;
vector = new double[6];
}
/* ---------------------------------------------------------------------- */
ComputeTempRotate::~ComputeTempRotate()
{
memory->destroy(vbiasall);
delete [] vector;
}
/* ---------------------------------------------------------------------- */
void ComputeTempRotate::init()
{
fix_dof = 0;
for (int i = 0; i < modify->nfix; i++)
fix_dof += modify->fix[i]->dof(igroup);
dof_compute();
masstotal = group->mass(igroup);
}
/* ---------------------------------------------------------------------- */
void ComputeTempRotate::dof_compute()
{
double natoms = group->count(igroup);
int nper = domain->dimension;
dof = nper * natoms;
dof -= extra_dof + fix_dof;
if (dof > 0) tfactor = force->mvv2e / (dof * force->boltz);
else tfactor = 0.0;
}
/* ---------------------------------------------------------------------- */
double ComputeTempRotate::compute_scalar()
{
double vthermal[3];
double vcm[3],xcm[3],inertia[3][3],angmom[3],omega[3];
int xbox,ybox,zbox;
double dx,dy,dz;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
invoked_scalar = update->ntimestep;
if (dynamic) masstotal = group->mass(igroup);
group->vcm(igroup,masstotal,vcm);
group->xcm(igroup,masstotal,xcm);
group->inertia(igroup,xcm,inertia);
group->angmom(igroup,xcm,angmom);
group->omega(angmom,inertia,omega);
double **x = atom->x;
double **v = atom->v;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (nlocal > maxbias) {
memory->destroy(vbiasall);
maxbias = atom->nmax;
memory->create(vbiasall,maxbias,3,"temp/rotate:vbiasall");
}
double t = 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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = (x[i][0] + xbox*xprd) - xcm[0];
dy = (x[i][1] + ybox*yprd) - xcm[1];
dz = (x[i][2] + zbox*zprd) - xcm[2];
vbiasall[i][0] = vcm[0] + dz*omega[1]-dy*omega[2];
vbiasall[i][1] = vcm[1] + dx*omega[2]-dz*omega[0];
vbiasall[i][2] = vcm[2] + dy*omega[0]-dx*omega[1];
vthermal[0] = v[i][0] - vbiasall[i][0];
vthermal[1] = v[i][1] - vbiasall[i][1];
vthermal[2] = v[i][2] - vbiasall[i][2];
if (rmass)
t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] +
vthermal[2]*vthermal[2]) * rmass[i];
else
t += (vthermal[0]*vthermal[0] + vthermal[1]*vthermal[1] +
vthermal[2]*vthermal[2]) * mass[type[i]];
}
MPI_Allreduce(&t,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
if (dynamic) dof_compute();
scalar *= tfactor;
return scalar;
}
/* ---------------------------------------------------------------------- */
void ComputeTempRotate::compute_vector()
{
int i;
double vthermal[3];
double vcm[3],xcm[3],inertia[3][3],angmom[3],omega[3];
int xbox,ybox,zbox;
double dx,dy,dz;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
invoked_vector = update->ntimestep;
if (dynamic) masstotal = group->mass(igroup);
group->vcm(igroup,masstotal,vcm);
group->xcm(igroup,masstotal,xcm);
group->inertia(igroup,xcm,inertia);
group->angmom(igroup,xcm,angmom);
group->omega(angmom,inertia,omega);
double **x = atom->x;
double **v = atom->v;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (nlocal > maxbias) {
memory->destroy(vbiasall);
maxbias = atom->nmax;
memory->create(vbiasall,maxbias,3,"temp/rotate:vbiasall");
}
double massone,t[6];
for (i = 0; i < 6; i++) t[i] = 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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = (x[i][0] + xbox*xprd) - xcm[0];
dy = (x[i][1] + ybox*yprd) - xcm[1];
dz = (x[i][2] + zbox*zprd) - xcm[2];
vbiasall[i][0] = vcm[0] + dz*omega[1]-dy*omega[2];
vbiasall[i][1] = vcm[1] + dx*omega[2]-dz*omega[0];
vbiasall[i][2] = vcm[2] + dy*omega[0]-dx*omega[1];
vthermal[0] = v[i][0] - vbiasall[i][0];
vthermal[1] = v[i][1] - vbiasall[i][1];
vthermal[2] = v[i][2] - vbiasall[i][2];
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
t[0] += massone * vthermal[0]*vthermal[0];
t[1] += massone * vthermal[1]*vthermal[1];
t[2] += massone * vthermal[2]*vthermal[2];
t[3] += massone * vthermal[0]*vthermal[1];
t[4] += massone * vthermal[0]*vthermal[2];
t[5] += massone * vthermal[1]*vthermal[2];
}
MPI_Allreduce(t,vector,6,MPI_DOUBLE,MPI_SUM,world);
for (i = 0; i < 6; i++) vector[i] *= force->mvv2e;
}
/* ----------------------------------------------------------------------
remove velocity bias from atom I to leave thermal velocity
------------------------------------------------------------------------- */
void ComputeTempRotate::remove_bias(int i, double *v)
{
v[0] -= vbiasall[i][0];
v[1] -= vbiasall[i][1];
v[2] -= vbiasall[i][2];
}
/* ----------------------------------------------------------------------
remove velocity bias from all atoms to leave thermal velocity
------------------------------------------------------------------------- */
void ComputeTempRotate::remove_bias_all()
{
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] -= vbiasall[i][0];
v[i][1] -= vbiasall[i][1];
v[i][2] -= vbiasall[i][2];
}
}
/* ----------------------------------------------------------------------
add back in velocity bias to atom I removed by remove_bias()
assume remove_bias() was previously called
------------------------------------------------------------------------- */
void ComputeTempRotate::restore_bias(int i, double *v)
{
v[0] += vbiasall[i][0];
v[1] += vbiasall[i][1];
v[2] += vbiasall[i][2];
}
/* ----------------------------------------------------------------------
add back in velocity bias to all atoms removed by remove_bias_all()
assume remove_bias_all() was previously called
------------------------------------------------------------------------- */
void ComputeTempRotate::restore_bias_all()
{
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] += vbiasall[i][0];
v[i][1] += vbiasall[i][1];
v[i][2] += vbiasall[i][2];
}
}
/* ---------------------------------------------------------------------- */
double ComputeTempRotate::memory_usage()
{
double bytes = maxbias * sizeof(double);
return bytes;
}
diff --git a/src/USER-MISC/dihedral_cosine_shift_exp.cpp b/src/USER-MISC/dihedral_cosine_shift_exp.cpp
index d607051d9..0491f87c0 100644
--- a/src/USER-MISC/dihedral_cosine_shift_exp.cpp
+++ b/src/USER-MISC/dihedral_cosine_shift_exp.cpp
@@ -1,343 +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: Carsten Svaneborg, science@zqex.dk
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "dihedral_cosine_shift_exp.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
/* ---------------------------------------------------------------------- */
DihedralCosineShiftExp::DihedralCosineShiftExp(LAMMPS *lmp) : Dihedral(lmp) {}
/* ---------------------------------------------------------------------- */
DihedralCosineShiftExp::~DihedralCosineShiftExp()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(umin);
memory->destroy(a);
memory->destroy(opt1);
memory->destroy(cost);
memory->destroy(sint);
memory->destroy(theta);
memory->destroy(doExpansion);
}
}
/* ---------------------------------------------------------------------- */
void DihedralCosineShiftExp::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;
double cccpsss,cssmscc,exp2;
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 " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
double aa=a[type];
double uumin=umin[type];
cccpsss = c*cost[type]+s*sint[type];
cssmscc = c*sint[type]-s*cost[type];
// eflag=1;
if (doExpansion[type])
{ // |a|<0.001 so use expansions relative precision <1e-5
if (eflag) edihedral = -0.125*(1+cccpsss)*(4+aa*(cccpsss-1))*uumin;
df=0.5*uumin*( cssmscc + 0.5*aa*cccpsss);
}
else
{
exp2=exp(0.5*aa*(1+cccpsss));
if (eflag) edihedral = opt1[type]*(1-exp2);
df= 0.5*opt1[type]*aa* ( exp2*cssmscc );
}
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;
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 DihedralCosineShiftExp::allocate()
{
allocated = 1;
int n = atom->ndihedraltypes;
memory->create(doExpansion, n+1, "dihedral:doExpansion");
memory->create(umin,n+1,"dihedral:umin");
memory->create(a,n+1,"dihedral:a");
memory->create(sint,n+1,"dihedral:sind");
memory->create(cost,n+1,"dihedral:cosd");
memory->create(opt1,n+1,"dihedral:opt1");
memory->create(theta,n+1,"dihedral:opt1");
memory->create(setflag, n+1,"dihedral:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one type
------------------------------------------------------------------------- */
void DihedralCosineShiftExp::coeff(int narg, char **arg)
{
if (narg != 4) error->all(FLERR,"Incorrect args for dihedral coefficients");
if (!allocated) allocate();
int ilo,ihi;
force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi);
double umin_ = force->numeric(arg[1]);
double theta0_ = force->numeric(arg[2]);
double a_ = force->numeric(arg[3]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
doExpansion[i]=(fabs(a_)<0.001);
umin[i] = umin_;
a[i] = a_;
cost[i] = cos(theta0_*3.14159265/180);
sint[i] = sin(theta0_*3.14159265/180);
theta[i] = theta0_*3.14159265/180;
if (!doExpansion[i]) opt1[i]=umin_/(exp(a_)-1);
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for dihedral coefficients");
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void DihedralCosineShiftExp::write_restart(FILE *fp)
{
fwrite(&umin[1],sizeof(double),atom->ndihedraltypes,fp);
fwrite(&a[1],sizeof(double),atom->ndihedraltypes,fp);
fwrite(&cost[1],sizeof(double),atom->ndihedraltypes,fp);
fwrite(&sint[1],sizeof(double),atom->ndihedraltypes,fp);
fwrite(&theta[1],sizeof(double),atom->ndihedraltypes,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads coeffs from restart file, bcasts them
------------------------------------------------------------------------- */
void DihedralCosineShiftExp::read_restart(FILE *fp)
{
allocate();
if (comm->me == 0) {
fread(&umin[1],sizeof(double),atom->ndihedraltypes,fp);
fread(&a[1],sizeof(double),atom->ndihedraltypes,fp);
fread(&cost[1],sizeof(double),atom->ndihedraltypes,fp);
fread(&sint[1],sizeof(double),atom->ndihedraltypes,fp);
fread(&theta[1],sizeof(double),atom->ndihedraltypes,fp);
}
MPI_Bcast(&umin[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
MPI_Bcast(&a[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
MPI_Bcast(&cost[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
MPI_Bcast(&sint[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
MPI_Bcast(&theta[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
for (int i = 1; i <= atom->ndihedraltypes; i++) {
setflag[i] = 1;
doExpansion[i]=(fabs(a[i])<0.01);
if (!doExpansion[i]) opt1[i]=umin[i]/(exp(a[i])-1);
}
}
diff --git a/src/USER-MISC/fix_addtorque.cpp b/src/USER-MISC/fix_addtorque.cpp
index 9d0d621fe..7862b2e49 100644
--- a/src/USER-MISC/fix_addtorque.cpp
+++ b/src/USER-MISC/fix_addtorque.cpp
@@ -1,293 +1,293 @@
/* ----------------------------------------------------------------------
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: Laurent Joly (U Lyon, France), ljoly.ulyon@gmail.com
------------------------------------------------------------------------- */
#include "string.h"
#include "stdlib.h"
#include "fix_addtorque.h"
#include "atom.h"
#include "update.h"
#include "modify.h"
#include "domain.h"
#include "respa.h"
#include "input.h"
#include "variable.h"
#include "memory.h"
#include "error.h"
#include "group.h"
#include "force.h"
using namespace LAMMPS_NS;
using namespace FixConst;
enum{NONE,CONSTANT,EQUAL,ATOM};
/* ---------------------------------------------------------------------- */
FixAddTorque::FixAddTorque(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg != 6) error->all(FLERR,"Illegal fix addtorque command");
scalar_flag = 1;
vector_flag = 1;
size_vector = 3;
global_freq = 1;
extscalar = 1;
extvector = 1;
xstr = ystr = zstr = NULL;
if (strstr(arg[3],"v_") == arg[3]) {
int n = strlen(&arg[3][2]) + 1;
xstr = new char[n];
strcpy(xstr,&arg[3][2]);
} else {
xvalue = atof(arg[3]);
xstyle = CONSTANT;
}
if (strstr(arg[4],"v_") == arg[4]) {
int n = strlen(&arg[4][2]) + 1;
ystr = new char[n];
strcpy(ystr,&arg[4][2]);
} else {
yvalue = atof(arg[4]);
ystyle = CONSTANT;
}
if (strstr(arg[5],"v_") == arg[5]) {
int n = strlen(&arg[5][2]) + 1;
zstr = new char[n];
strcpy(zstr,&arg[5][2]);
} else {
zvalue = atof(arg[5]);
zstyle = CONSTANT;
}
force_flag = 0;
foriginal[0] = foriginal[1] = foriginal[2] = foriginal[3] = 0.0;
}
/* ---------------------------------------------------------------------- */
FixAddTorque::~FixAddTorque()
{
delete [] xstr;
delete [] ystr;
delete [] zstr;
}
/* ---------------------------------------------------------------------- */
int FixAddTorque::setmask()
{
int mask = 0;
mask |= POST_FORCE;
mask |= THERMO_ENERGY;
mask |= POST_FORCE_RESPA;
mask |= MIN_POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixAddTorque::init()
{
// check variables
if (xstr) {
xvar = input->variable->find(xstr);
if (xvar < 0) error->all(FLERR,"Variable name for fix addtorque does not exist");
if (input->variable->equalstyle(xvar)) xstyle = EQUAL;
else error->all(FLERR,"Variable for fix addtorque is invalid style");
}
if (ystr) {
yvar = input->variable->find(ystr);
if (yvar < 0) error->all(FLERR,"Variable name for fix addtorque does not exist");
if (input->variable->equalstyle(yvar)) ystyle = EQUAL;
else error->all(FLERR,"Variable for fix addtorque is invalid style");
}
if (zstr) {
zvar = input->variable->find(zstr);
if (zvar < 0) error->all(FLERR,"Variable name for fix addtorque does not exist");
if (input->variable->equalstyle(zvar)) zstyle = EQUAL;
else error->all(FLERR,"Variable for fix addtorque is invalid style");
}
if (xstyle == EQUAL || ystyle == EQUAL || zstyle == EQUAL)
varflag = EQUAL;
else varflag = CONSTANT;
if (strcmp(update->integrate_style,"respa") == 0)
nlevels_respa = ((Respa *) update->integrate)->nlevels;
}
/* ---------------------------------------------------------------------- */
void FixAddTorque::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 FixAddTorque::min_setup(int vflag)
{
post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixAddTorque::post_force(int vflag)
{
double **x = atom->x;
double **f = atom->f;
int *mask = atom->mask;
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
double *mass = atom->mass;
double *rmass = atom->rmass;
int nlocal = atom->nlocal;
double mvv2e = force->mvv2e;
int xbox,ybox,zbox;
double dx,dy,dz,vx,vy,vz,fx,fy,fz,massone,omegadotr;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
double tcm[3],xcm[3],angmom[3],omega[3],itorque[3],domegadt[3],tlocal[3];
double inertia[3][3];
// foriginal[0] = "potential energy" for added force
// foriginal[123] = torque on atoms before extra force added
foriginal[0] = foriginal[1] = foriginal[2] = foriginal[3] = 0.0;
force_flag = 0;
if (varflag == EQUAL) {
// variable torque, wrap with clear/add
modify->clearstep_compute();
if (xstyle == EQUAL) xvalue = input->variable->compute_equal(xvar);
if (ystyle == EQUAL) yvalue = input->variable->compute_equal(yvar);
if (zstyle == EQUAL) zvalue = input->variable->compute_equal(zvar);
modify->addstep_compute(update->ntimestep + 1);
}
atom->check_mass();
double masstotal = group->mass(igroup);
group->xcm(igroup,masstotal,xcm);
group->inertia(igroup,xcm,inertia);
group->angmom(igroup,xcm,angmom);
group->omega(angmom,inertia,omega);
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = (x[i][0] + xbox*xprd) - xcm[0];
dy = (x[i][1] + ybox*yprd) - xcm[1];
dz = (x[i][2] + zbox*zprd) - xcm[2];
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
omegadotr = omega[0]*dx+omega[1]*dy+omega[2]*dz;
tlocal[0] += massone * omegadotr * (dy*omega[2] - dz*omega[1]);
tlocal[1] += massone * omegadotr * (dz*omega[0] - dx*omega[2]);
tlocal[2] += massone * omegadotr * (dx*omega[1] - dy*omega[0]);
}
MPI_Allreduce(tlocal,itorque,3,MPI_DOUBLE,MPI_SUM,world);
tcm[0] = xvalue - mvv2e*itorque[0];
tcm[1] = yvalue - mvv2e*itorque[1];
tcm[2] = zvalue - mvv2e*itorque[2];
group->omega(tcm,inertia,domegadt);
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = (x[i][0] + xbox*xprd) - xcm[0];
dy = (x[i][1] + ybox*yprd) - xcm[1];
dz = (x[i][2] + zbox*zprd) - xcm[2];
vx = mvv2e*(dz*omega[1]-dy*omega[2]);
vy = mvv2e*(dx*omega[2]-dz*omega[0]);
vz = mvv2e*(dy*omega[0]-dx*omega[1]);
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
fx = massone * (dz*domegadt[1]-dy*domegadt[2] + vz*omega[1]-vy*omega[2]);
fy = massone * (dx*domegadt[2]-dz*domegadt[0] + vx*omega[2]-vz*omega[0]);
fz = massone * (dy*domegadt[0]-dx*domegadt[1] + vy*omega[0]-vx*omega[1]);
// potential energy = - x dot f
foriginal[0] -= fx*x[i][0] + fy*x[i][1] + fz*x[i][2];
foriginal[1] += dy*f[i][2] - dz*f[i][1];
foriginal[2] += dz*f[i][0] - dx*f[i][2];
foriginal[3] += dx*f[i][1] - dy*f[i][0];
f[i][0] += fx;
f[i][1] += fy;
f[i][2] += fz;
}
}
/* ---------------------------------------------------------------------- */
void FixAddTorque::post_force_respa(int vflag, int ilevel, int iloop)
{
if (ilevel == nlevels_respa-1) post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixAddTorque::min_post_force(int vflag)
{
post_force(vflag);
}
/* ----------------------------------------------------------------------
potential energy of added torque
------------------------------------------------------------------------- */
double FixAddTorque::compute_scalar()
{
// only sum across procs one time
if (force_flag == 0) {
MPI_Allreduce(foriginal,foriginal_all,4,MPI_DOUBLE,MPI_SUM,world);
force_flag = 1;
}
return foriginal_all[0];
}
/* ----------------------------------------------------------------------
return components of total torque on fix group before torque was changed
------------------------------------------------------------------------- */
double FixAddTorque::compute_vector(int n)
{
// only sum across procs one time
if (force_flag == 0) {
MPI_Allreduce(foriginal,foriginal_all,4,MPI_DOUBLE,MPI_SUM,world);
force_flag = 1;
}
return foriginal_all[n+1];
}
diff --git a/src/USER-MISC/fix_imd.cpp b/src/USER-MISC/fix_imd.cpp
index 69379c0f5..87c950d00 100644
--- a/src/USER-MISC/fix_imd.cpp
+++ b/src/USER-MISC/fix_imd.cpp
@@ -1,1476 +1,1476 @@
/* ----------------------------------------------------------------------
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 "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"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(_MSC_VER) || defined(__MINGW32_VERSION)
#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>
/* re-usable integer hash table code with static linkage. */
/** 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);
/* adapted sort for in-place sorting of map indices. */
static void id_sort(int *idmap, int left, int right);
/************************************************************************
* 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));
}
}
/************************************************************************
* integer list sort code:
************************************************************************/
/* sort for integer map. initial call id_sort(idmap, 0, natoms - 1); */
static 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);
}
/********** 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: 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 2: 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;
using namespace FixConst;
/* 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(FLERR,"Illegal fix imd command");
imd_port = atoi(arg[3]);
if (imd_port < 1024)
error->all(FLERR,"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(FLERR,"Unknown fix imd parameter");
}
++argsdone; ++argsdone;
}
/* sanity check on parameters */
if (imd_trate < 1)
error->all(FLERR,"Illegal fix imd parameter. trate < 1.");
bigint n = group->count(igroup);
if (n > MAXSMALLINT) error->all(FLERR,"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;
msgdata = NULL;
msglen = 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(FLERR,"LAMMPS Terminated on error in IMD.");
/* storage required to communicate a single coordinate or force. */
size_one = sizeof(struct commdata);
#if defined(LAMMPS_ASYNC_IMD)
/* set up for i/o worker thread on MPI rank 0.*/
if (me == 0) {
if (screen)
fputs("Using fix imd with asynchronous I/O.\n",screen);
if (logfile)
fputs("Using fix imd with asynchronous I/O.\n",logfile);
/* set up mutex and condition variable for i/o thread */
/* hold mutex before creating i/o thread to keep it waiting. */
pthread_mutex_init(&read_mutex, NULL);
pthread_mutex_init(&write_mutex, NULL);
pthread_cond_init(&write_cond, NULL);
pthread_mutex_lock(&write_mutex);
buf_has_data=0;
pthread_mutex_unlock(&write_mutex);
/* set up and launch i/o thread */
pthread_attr_init(&iot_attr);
pthread_attr_setdetachstate(&iot_attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&iothread, &iot_attr, &fix_imd_ioworker, this);
}
#endif
}
/*********************************
* Clean up on deleting the fix. *
*********************************/
FixIMD::~FixIMD()
{
#if defined(LAMMPS_ASYNC_IMD)
if (me == 0) {
pthread_mutex_lock(&write_mutex);
buf_has_data=-1;
pthread_cond_signal(&write_cond);
pthread_mutex_unlock(&write_mutex);
pthread_join(iothread, NULL);
/* cleanup */
pthread_attr_destroy(&iot_attr);
pthread_mutex_destroy(&write_mutex);
pthread_cond_destroy(&write_cond);
}
#endif
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 (strstr(update->integrate_style,"respa"))
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. Transfer rate %d.\n",imd_port, imd_trate);
else
fprintf(screen,"Waiting for IMD connection on port %d. Transfer rate %d.\n",imd_port, imd_trate);
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 = (void *) 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(FLERR,"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;
}
/* worker threads for asynchronous i/o */
#if defined(LAMMPS_ASYNC_IMD)
/* c bindings wrapper */
void *fix_imd_ioworker(void *t)
{
FixIMD *imd=(FixIMD *)t;
imd->ioworker();
return NULL;
}
/* the real i/o worker thread */
void FixIMD::ioworker()
{
while (1) {
pthread_mutex_lock(&write_mutex);
if (buf_has_data < 0) {
/* master told us to go away */
fprintf(screen,"Asynchronous I/O thread is exiting.\n");
buf_has_data=0;
pthread_mutex_unlock(&write_mutex);
pthread_exit(NULL);
} else if (buf_has_data > 0) {
/* send coordinate data, if client is able to accept */
if (clientsock && imdsock_selwrite(clientsock,0)) {
imd_writen(clientsock, msgdata, msglen);
}
delete[] msgdata;
buf_has_data=0;
pthread_mutex_unlock(&write_mutex);
} else {
/* nothing to write out yet. wait on condition. */
pthread_cond_wait(&write_cond, &write_mutex);
pthread_mutex_unlock(&write_mutex);
}
}
}
#endif
/* ---------------------------------------------------------------------- */
/* 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(FLERR,"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;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
int *mask = atom->mask;
struct commdata *buf;
if (me == 0) {
/* 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->destroy(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. */
memory->destroy(force_buf);
force_buf = (void *) 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;
}
}
}
/* 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(FLERR,"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);
}
/* 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] += imd_fscale*buf[j].x;
f[i][1] += imd_fscale*buf[j].y;
f[i][2] += imd_fscale*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. */
msglen = 3*sizeof(float)*num_coords+IMDHEADERSIZE;
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;
double xy = domain->xy;
double xz = domain->xz;
double yz = domain->yz;
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) {
- int ix = (image[i] & 1023) - 512;
- int iy = (image[i] >> 10 & 1023) - 512;
- int iz = (image[i] >> 20) - 512;
+ int ix = (image[i] & IMGMASK) - IMGMAX;
+ int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ int iz = (image[i] >> IMG2BITS) - IMGMAX;
if (domain->triclinic) {
recvcoord[j] = x[i][0] + ix * xprd + iy * xy + iz * xz;
recvcoord[j+1] = x[i][1] + iy * yprd + iz * yz;
recvcoord[j+2] = x[i][2] + iz * zprd;
} else {
recvcoord[j] = x[i][0] + ix * xprd;
recvcoord[j+1] = x[i][1] + iy * yprd;
recvcoord[j+2] = x[i][2] + iz * 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. */
#if defined(LAMMPS_ASYNC_IMD)
/* wake up i/o worker thread and release lock on i/o buffer
* we can go back to our MD and let the i/o thread do the rest */
buf_has_data=1;
pthread_cond_signal(&write_cond);
pthread_mutex_unlock(&write_mutex);
#else
/* send coordinate data, if client is able to accept */
if (clientsock && imdsock_selwrite(clientsock,0)) {
imd_writen(clientsock, msgdata, msglen);
}
delete[] msgdata;
#endif
} else {
/* copy coordinate data into communication buffer */
nme = 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 (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;
+ int ix = (image[i] & IMGMASK) - IMGMAX;
+ int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ int iz = (image[i] >> IMG2BITS) - IMGMAX;
if (domain->triclinic) {
buf[nme].tag = tag[i];
buf[nme].x = x[i][0] + ix * xprd + iy * xy + iz * xz;
buf[nme].y = x[i][1] + iy * yprd + iz * yz;
buf[nme].z = x[i][2] + iz * zprd;
} else {
buf[nme].tag = tag[i];
buf[nme].x = x[i][0] + ix * xprd;
buf[nme].y = x[i][1] + iy * yprd;
buf[nme].z = x[i][2] + iz * 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);
}
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. */
/***************************************************************************/
/* 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) || defined(__MINGW32_VERSION)
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;
#define _SOCKLEN_TYPE unsigned int
#elif defined(SOCKLEN_T)
SOCKLEN_T len;
#define _SOCKLEN_TYPE SOCKLEN_T
#elif defined(_POSIX_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) || defined(__linux)
socklen_t len;
#define _SOCKLEN_TYPE socklen_t
#else
#define _SOCKLEN_TYPE int
int len;
#endif
len = sizeof(s->addr);
rc = accept(s->sd, (struct sockaddr *) &s->addr, ( _SOCKLEN_TYPE * ) &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) || defined(__MINGW32_VERSION)
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) || defined(__MINGW32_VERSION)
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) || defined(__MINGW32_VERSION)
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) || defined(__MINGW32_VERSION)
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);
}
// 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/USER-MISC/improper_cossq.cpp b/src/USER-MISC/improper_cossq.cpp
index 9bd5be609..1614deaed 100644
--- a/src/USER-MISC/improper_cossq.cpp
+++ b/src/USER-MISC/improper_cossq.cpp
@@ -1,316 +1,313 @@
/* ----------------------------------------------------------------------
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: Georgios G. Vogiatzis (CoMSE, NTU Athens),
gvog@chemeng.ntua.gr
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "improper_cossq.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"
#include "math_const.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
ImproperCossq::ImproperCossq(LAMMPS *lmp) : Improper(lmp) {}
/* ---------------------------------------------------------------------- */
ImproperCossq::~ImproperCossq()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(chi);
}
}
/* ---------------------------------------------------------------------- */
void ImproperCossq::compute(int eflag, int vflag)
{
int i1,i2,i3,i4,m,n,type;
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z ;
double eimproper,f1[3],f2[3],f3[3],f4[3];
double rjisq, rji, rlksq, rlk, cosphi, angfac;
double cjiji, clkji, clklk, cfact1, cfact2, cfact3;
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++) {
/* Ask the improper list for the atom types. */
i1 = improperlist[n][0];
i2 = improperlist[n][1];
i3 = improperlist[n][2];
i4 = improperlist[n][3];
type = improperlist[n][4];
/* separation vector between i1 and i2, (i2-i1) */
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);
rjisq = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z ;
rji = sqrt(rjisq);
/* separation vector between i2 and i3 (i3-i2) */
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);
/* separation vector between i3 and i4, (i4-i3) */
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);
rlksq = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z ;
rlk = sqrt(rlksq);
cosphi = (vb3x*vb1x + vb3y*vb1y + vb3z*vb1z)/(rji * rlk);
/* Check that cos(phi) is in the correct limits. */
if (cosphi > 1.0 + TOLERANCE || cosphi < (-1.0 - TOLERANCE))
{
int me;
MPI_Comm_rank(world,&me);
if (screen) {
char str[128];
sprintf(str,"Improper problem: %d " BIGINT_FORMAT " %d %d %d %d",
me,update->ntimestep,atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",me,x[i2][0],x[i2][1],x[i2][2]);
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]);
}
}
/* Apply corrections to round-off errors. */
if (cosphi > 1.0) cosphi -= SMALL;
if (cosphi < -1.0) cosphi += SMALL;
/* Calculate the angle: */
double torangle = acos(cosphi);
cosphi = cos(torangle - chi[type]);
if (eflag) eimproper = 0.5 * k[type] * cosphi * cosphi;
/*
printf("The tags: %d-%d-%d-%d, of type %d .\n",atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4],type);
printf("The ji vector: %f, %f, %f.\nThe lk vector: %f, %f, %f.\n", vb1x,vb1y,vb1z,vb3x,vb3y,vb3z);
printf("The cosine of the angle: %-1.16e.\n", cosphi);
printf("The energy of the improper: %-1.16e with prefactor %-1.16e.\n", eimproper, 0.5*k[type]);
*/
/* Work out forces. */
angfac = - k[type] * cosphi;
cjiji = rjisq;
clklk = rlksq;
/*CLKJI = RXLK * RXJI + RYLK * RYJI + RZLK * RZJI */
clkji = vb3x*vb1x + vb3y*vb1y + vb3z*vb1z;
/*CFACT1 = CLKLK * CJIJI
CFACT1 = SQRT(CFACT1)
CFACT1 = ANGFAC / CFACT1*/
cfact1 = angfac / sqrt(clklk * cjiji);
/*CFACT2 = CLKJI / CLKLK*/
cfact2 = clkji / clklk;
/*CFACT3 = CLKJI / CJIJI*/
cfact3 = clkji / cjiji;
/*FIX = -RXLK + CFACT3 * RXJI
FIY = -RYLK + CFACT3 * RYJI
FIZ = -RZLK + CFACT3 * RZJI*/
f1[0] = - vb3x + cfact3 * vb1x;
f1[1] = - vb3y + cfact3 * vb1y;
f1[2] = - vb3z + cfact3 * vb1z;
/*FJX = -FIX
FJY = -FIY
FJZ = -FIZ*/
f2[0] = - f1[0];
f2[1] = - f1[1];
f2[2] = - f1[2];
/*FKX = CFACT2 * RXLK - RXJI
FKY = CFACT2 * RYLK - RYJI
FKZ = CFACT2 * RZLK - RZJI*/
f3[0] = cfact2 * vb3x - vb1x;
f3[1] = cfact2 * vb3y - vb1y;
f3[2] = cfact2 * vb3z - vb1z;
/*FLX = -FKX
FLY = -FKY
FLZ = -FKZ*/
f4[0] = - f3[0];
f4[1] = - f3[1];
f4[2] = - f3[2];
/*FIX = FIX * CFACT1
FIY = FIY * CFACT1
FIZ = FIZ * CFACT1*/
f1[0] *= cfact1;
f1[1] *= cfact1;
f1[2] *= cfact1;
/*FJX = FJX * CFACT1
FJY = FJY * CFACT1
FJZ = FJZ * CFACT1*/
f2[0] *= cfact1;
f2[1] *= cfact1;
f2[2] *= cfact1;
/*FKX = FKX * CFACT1
FKY = FKY * CFACT1
FKZ = FKZ * CFACT1*/
f3[0] *= cfact1;
f3[1] *= cfact1;
f3[2] *= cfact1;
/*FLX = FLX * CFACT1
FLY = FLY * CFACT1
FLZ = FLZ * CFACT1*/
f4[0] *= cfact1;
f4[1] *= cfact1;
f4[2] *= cfact1;
/* 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 ImproperCossq::allocate()
{
allocated = 1;
int n = atom->nimpropertypes;
memory->create(k,n+1,"improper:k");
memory->create(chi,n+1,"improper:chi");
memory->create(setflag,n+1,"improper:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one type
------------------------------------------------------------------------- */
void ImproperCossq::coeff(int narg, char **arg)
{
/* Check whether there exist sufficient number of arguments.
0: type of improper to be applied to
1: energetic constant
2: equilibrium angle in degrees */
if (narg != 3) error->all(FLERR,"Incorrect args for cossq 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]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
chi[i] = ((chi_one * MY_PI)/180.0);
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for improper coefficients");
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void ImproperCossq::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 ImproperCossq::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/USER-MISC/improper_ring.cpp b/src/USER-MISC/improper_ring.cpp
index 0afbb197c..fbbe9dd75 100644
--- a/src/USER-MISC/improper_ring.cpp
+++ b/src/USER-MISC/improper_ring.cpp
@@ -1,343 +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 author: Georgios G. Vogiatzis (CoMSE, NTU Athens),
gvog@chemeng.ntua.gr
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Description: This file implements the improper potential introduced
by Destree et al., in Equation 9 of:
- M. Destree, F. Laupretre, A. Lyulin, and J.-P.
Ryckaert, J. Chem. Phys. 112, 9632 (2000),
and subsequently referred in:
- A.V. Lyulin, M.A.J Michels, Macromolecules, 35, 1463,
(2002)
This potential does not affect small amplitude vibrations
but is used in an ad hoc way to prevent the onset of
accidentially large amplitude fluctuations leading to
the occurrence of a planar conformation of the three
bonds i, i + 1 and i', an intermediate conformation
toward the chiral inversion of a methine carbon.
In the "Impropers" section of data file four atoms:
i, j, k and l are specified with i,j and l lying on the
backbone of the chain and k specifying the chirality
of j.
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "improper_ring.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
ImproperRing::ImproperRing(LAMMPS *lmp) : Improper(lmp) {}
/* ---------------------------------------------------------------------- */
ImproperRing::~ImproperRing()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(k);
memory->destroy(chi);
}
}
/* ---------------------------------------------------------------------- */
void ImproperRing::compute(int eflag, int vflag)
{
/* Be careful!: "chi" is the equilibrium angle in radians. */
int i1,i2,i3,i4,n,type;
double eimproper ;
/* Compatibility variables. */
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z;
double f1[3], f3[3], f4[3];
/* Actual computation variables. */
int at1[3], at2[3], at3[3], icomb;
double bvec1x[3], bvec1y[3], bvec1z[3],
bvec2x[3], bvec2y[3], bvec2z[3],
bvec1n[3], bvec2n[3], bend_angle[3];
double angle_summer, angfac, cfact1, cfact2, cfact3;
double cjiji, ckjji, ckjkj, fix, fiy, fiz, fjx, fjy, fjz, fkx, fky, fkz;
eimproper = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
/* References to simulation data. */
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;
/* A description of the potential can be found in
Macromolecules 35, pp. 1463-1472 (2002). */
for (n = 0; n < nimproperlist; n++)
{
/* Take the ids of the atoms contributing to the improper potential. */
i1 = improperlist[n][0]; /* Atom "1" of Figure 1 from the above reference.*/
i2 = improperlist[n][1]; /* Atom "2" ... */
i3 = improperlist[n][2]; /* Atom "3" ... */
i4 = improperlist[n][3]; /* Atom "9" ... */
type = improperlist[n][4];
/* Calculate the necessary variables for LAMMPS implementation.
if (evflag) ev_tally(i1,i2,i3,i4,nlocal,newton_bond,eimproper,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
Although, they are irrelevant to the calculation of the potential, we keep
them for maximal compatibility. */
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);
/* Pass the atom tags to form the necessary combinations. */
at1[0] = i1; at2[0] = i2; at3[0] = i4; /* ids: 1-2-9 */
at1[1] = i1; at2[1] = i2; at3[1] = i3; /* ids: 1-2-3 */
at1[2] = i4; at2[2] = i2; at3[2] = i3; /* ids: 9-2-3 */
/* Initialize the sum of the angles differences. */
angle_summer = 0.0;
/* Take a loop over the three angles, defined by each triad: */
for (icomb = 0; icomb < 3; icomb ++)
{
/* Bond vector connecting the first and the second atom. */
bvec1x[icomb] = x[at2[icomb]][0] - x[at1[icomb]][0];
bvec1y[icomb] = x[at2[icomb]][1] - x[at1[icomb]][1];
bvec1z[icomb] = x[at2[icomb]][2] - x[at1[icomb]][2];
- domain -> minimum_image(bvec1x[icomb], bvec1y[icomb], bvec1z[icomb]);
/* also calculate the norm of the vector: */
bvec1n[icomb] = sqrt( bvec1x[icomb]*bvec1x[icomb]
+ bvec1y[icomb]*bvec1y[icomb]
+ bvec1z[icomb]*bvec1z[icomb]);
/* Bond vector connecting the second and the third atom. */
bvec2x[icomb] = x[at3[icomb]][0] - x[at2[icomb]][0];
bvec2y[icomb] = x[at3[icomb]][1] - x[at2[icomb]][1];
bvec2z[icomb] = x[at3[icomb]][2] - x[at2[icomb]][2];
- domain -> minimum_image(bvec2x[icomb], bvec2y[icomb], bvec2z[icomb]);
/* also calculate the norm of the vector: */
bvec2n[icomb] = sqrt( bvec2x[icomb]*bvec2x[icomb]
+ bvec2y[icomb]*bvec2y[icomb]
+ bvec2z[icomb]*bvec2z[icomb]);
/* Calculate the bending angle of the atom triad: */
bend_angle[icomb] = ( bvec2x[icomb]*bvec1x[icomb]
+ bvec2y[icomb]*bvec1y[icomb]
+ bvec2z[icomb]*bvec1z[icomb]);
bend_angle[icomb] /= (bvec1n[icomb] * bvec2n[icomb]);
if (bend_angle[icomb] > 1.0) bend_angle[icomb] -= SMALL;
if (bend_angle[icomb] < -1.0) bend_angle[icomb] += SMALL;
/* Append the current angle to the sum of angle differences. */
angle_summer += (bend_angle[icomb] - chi[type]);
}
if (eflag) eimproper = (1.0/6.0) *k[type] * pow(angle_summer,6.0);
/*
printf("The tags: %d-%d-%d-%d, of type %d .\n",atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4],type);
// printf("The coordinates of the first: %f, %f, %f.\n", x[i1][0], x[i1][1], x[i1][2]);
// printf("The coordinates of the second: %f, %f, %f.\n", x[i2][0], x[i2][1], x[i2][2]);
// printf("The coordinates of the third: %f, %f, %f.\n", x[i3][0], x[i3][1], x[i3][2]);
// printf("The coordinates of the fourth: %f, %f, %f.\n", x[i4][0], x[i4][1], x[i4][2]);
printf("The angles are: %f / %f / %f equilibrium: %f.\n", bend_angle[0], bend_angle[1], bend_angle[2],chi[type]);
printf("The energy of the improper: %f with prefactor %f.\n", eimproper,(1.0/6.0)*k[type]);
printf("The sum of the angles: %f.\n", angle_summer);
*/
/* Force calculation acting on all atoms.
Calculate the derivatives of the potential. */
angfac = k[type] * pow(angle_summer,5.0);
f1[0] = 0.0; f1[1] = 0.0; f1[2] = 0.0;
f3[0] = 0.0; f3[1] = 0.0; f3[2] = 0.0;
f4[0] = 0.0; f4[1] = 0.0; f4[2] = 0.0;
/* Take a loop over the three angles, defined by each triad: */
for (icomb = 0; icomb < 3; icomb ++)
{
/* Calculate the squares of the distances. */
cjiji = bvec1n[icomb] * bvec1n[icomb]; ckjkj = bvec2n[icomb] * bvec2n[icomb];
ckjji = bvec2x[icomb] * bvec1x[icomb]
+ bvec2y[icomb] * bvec1y[icomb]
+ bvec2z[icomb] * bvec1z[icomb] ;
cfact1 = angfac / (sqrt(ckjkj * cjiji));
cfact2 = ckjji / ckjkj;
cfact3 = ckjji / cjiji;
/* Calculate the force acted on the thrid atom of the angle. */
fkx = cfact2 * bvec2x[icomb] - bvec1x[icomb];
fky = cfact2 * bvec2y[icomb] - bvec1y[icomb];
fkz = cfact2 * bvec2z[icomb] - bvec1z[icomb];
/* Calculate the force acted on the first atom of the angle. */
fix = bvec2x[icomb] - cfact3 * bvec1x[icomb];
fiy = bvec2y[icomb] - cfact3 * bvec1y[icomb];
fiz = bvec2z[icomb] - cfact3 * bvec1z[icomb];
/* Finally, calculate the force acted on the middle atom of the angle.*/
fjx = - fix - fkx; fjy = - fiy - fky; fjz = - fiz - fkz;
/* Consider the appropriate scaling of the forces: */
fix *= cfact1; fiy *= cfact1; fiz *= cfact1;
fjx *= cfact1; fjy *= cfact1; fjz *= cfact1;
fkx *= cfact1; fky *= cfact1; fkz *= cfact1;
if (at1[icomb] == i1) {f1[0] += fix; f1[1] += fiy; f1[2] += fiz;}
else if (at2[icomb] == i1) {f1[0] += fjx; f1[1] += fjy; f1[2] += fjz;}
else if (at3[icomb] == i1) {f1[0] += fkx; f1[1] += fky; f1[2] += fkz;}
if (at1[icomb] == i3) {f3[0] += fix; f3[1] += fiy; f3[2] += fiz;}
else if (at2[icomb] == i3) {f3[0] += fjx; f3[1] += fjy; f3[2] += fjz;}
else if (at3[icomb] == i3) {f3[0] += fkx; f3[1] += fky; f3[2] += fkz;}
if (at1[icomb] == i4) {f4[0] += fix; f4[1] += fiy; f4[2] += fiz;}
else if (at2[icomb] == i4) {f4[0] += fjx; f4[1] += fjy; f4[2] += fjz;}
else if (at3[icomb] == i4) {f4[0] += fkx; f4[1] += fky; f4[2] += fkz;}
/* Store the contribution to the global arrays: */
/* Take the id of the atom from the at1[icomb] element, i1 = at1[icomb]. */
if (newton_bond || at1[icomb] < nlocal) {
f[at1[icomb]][0] += fix;
f[at1[icomb]][1] += fiy;
f[at1[icomb]][2] += fiz;
}
/* Take the id of the atom from the at2[icomb] element, i2 = at2[icomb]. */
if (newton_bond || at2[icomb] < nlocal) {
f[at2[icomb]][0] += fjx;
f[at2[icomb]][1] += fjy;
f[at2[icomb]][2] += fjz;
}
/* Take the id of the atom from the at3[icomb] element, i3 = at3[icomb]. */
if (newton_bond || at3[icomb] < nlocal) {
f[at3[icomb]][0] += fkx;
f[at3[icomb]][1] += fky;
f[at3[icomb]][2] += fkz;
}
}
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 ImproperRing::allocate()
{
allocated = 1;
int n = atom->nimpropertypes;
memory->create(k,n+1,"improper:k");
memory->create(chi,n+1,"improper:chi");
memory->create(setflag,n+1,"improper:setflag");
for (int i = 1; i <= n; i++) setflag[i] = 0;
}
/* ----------------------------------------------------------------------
set coeffs for one type
------------------------------------------------------------------------- */
void ImproperRing ::coeff(int narg, char **arg)
{
/* Check whether there exist sufficient number of arguments.
0: type of improper to be applied to
1: energetic constant
2: equilibrium angle in degrees */
if (narg != 3) error->all(FLERR,"Incorrect args for RING 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]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
/* Read the k parameter in kcal/mol. */
k[i] = k_one;
/* "chi_one" stores the equilibrium angle in degrees.
Convert it to radians and store its cosine. */
chi[i] = cos((chi_one/180.0)*MY_PI);
setflag[i] = 1;
count++;
}
if (count == 0) error->all(FLERR,"Incorrect args for improper coefficients");
}
/* ----------------------------------------------------------------------
proc 0 writes out coeffs to restart file
------------------------------------------------------------------------- */
void ImproperRing ::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 ImproperRing::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/USER-MOLFILE/dump_molfile.cpp b/src/USER-MOLFILE/dump_molfile.cpp
index 6a32ac8b1..1d0188430 100644
--- a/src/USER-MOLFILE/dump_molfile.cpp
+++ b/src/USER-MOLFILE/dump_molfile.cpp
@@ -1,461 +1,461 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "dump_molfile.h"
#include "domain.h"
#include "atom.h"
#include "comm.h"
#include "update.h"
#include "output.h"
#include "group.h"
#include "memory.h"
#include "error.h"
#include "molfile_interface.h"
using namespace LAMMPS_NS;
typedef MolfileInterface MFI;
// syntax:
// dump <id> <groupid> molfile <every> <filename> <type> [<path>]
// path defaults to "." -> will look for .so files in CWD.
//
// XXX: potential change: add more options and make them optional
// path <path>
// template <file> <type> (import name and topology information from file)
// bonds <yes|no> (write out bond information)
// topology <yes|no> (write out all topology information)
/* ---------------------------------------------------------------------- */
DumpMolfile::DumpMolfile(LAMMPS *lmp, int narg, char **arg)
: Dump(lmp, narg, arg)
{
if (narg < 6) error->all(FLERR,"Illegal dump molfile command");
if (binary || compressed || multiproc)
error->all(FLERR,"Invalid dump molfile filename");
// required settings
sort_flag = 1;
sortcol = 0;
// storage for collected information
size_one = 4;
if (atom->molecule_flag) ++size_one;
if (atom->q_flag) ++size_one;
if (atom->rmass_flag) ++size_one;
if (atom->radius_flag) ++size_one;
need_structure = 0;
unwrap_flag = 0;
velocity_flag = 0;
topology_flag = 0;
ntotal = 0;
me = comm->me;
coords = vels = masses = charges = radiuses = NULL;
types = molids = NULL;
ntypes = atom->ntypes;
typenames = NULL;
// allocate global array for atom coords
bigint n = group->count(igroup);
if (n > MAXSMALLINT/sizeof(float))
error->all(FLERR,"Too many atoms for dump molfile");
if (n < 1)
error->all(FLERR,"Not enough atoms for dump molfile");
natoms = static_cast<int>(n);
if (me == 0) {
memory->create(types,natoms,"dump:types");
memory->create(coords,3*natoms,"dump:coords");
if (atom->molecule_flag) memory->create(molids,natoms,"dump:molids");
if (atom->q_flag) memory->create(charges,natoms,"dump:charges");
if (atom->rmass_flag) memory->create(masses,natoms,"dump:masses");
if (atom->radius_flag) memory->create(radiuses,natoms,"dump:radiuses");
mf = new MolfileInterface(arg[5],MFI::M_WRITE);
const char *path = (const char *) ".";
if (narg > 6)
path=arg[6];
if (mf->find_plugin(path)!= MFI::E_MATCH)
error->one(FLERR,"No suitable molfile plugin found");
if (screen)
fprintf(screen,"Dump '%s' uses molfile plugin: %s\n",
id, mf->get_plugin_name());
if (logfile)
fprintf(logfile,"Dump '%s' uses molfile plugin: %s\n",
id,mf->get_plugin_name());
}
}
/* ---------------------------------------------------------------------- */
DumpMolfile::~DumpMolfile()
{
if (me == 0) {
mf->close();
memory->destroy(types);
memory->destroy(coords);
memory->destroy(vels);
memory->destroy(masses);
memory->destroy(charges);
memory->destroy(radiuses);
delete mf;
}
if (typenames) {
for (int i = 1; i <= ntypes; i++)
delete [] typenames[i];
delete [] typenames;
typenames = NULL;
}
}
/* ---------------------------------------------------------------------- */
void DumpMolfile::init_style()
{
if (sort_flag == 0 || sortcol != 0)
error->all(FLERR,"Dump molfile requires sorting by atom ID");
if (me == 0) {
/* initialize typenames array to numeric types by default */
if (typenames == NULL) {
typenames = new char*[ntypes+1];
for (int itype = 1; itype <= ntypes; itype++) {
/* a 32-bit int can be maximally 10 digits plus sign */
typenames[itype] = new char[12];
sprintf(typenames[itype],"%d",itype);
}
}
// open single file, one time only
if (multifile == 0) openfile();
}
}
/* ---------------------------------------------------------------------- */
void DumpMolfile::write()
{
// simulation box dimensions
if (domain->triclinic == 1) {
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]);
cell[0] = alen;
cell[1] = blen;
cell[2] = clen;
cell[3] = (90.0 - asin((h[5]*h[4] + h[1]*h[3]) / blen/clen)); // alpha
cell[4] = (90.0 - asin((h[0]*h[4]) / alen/clen)); // beta
cell[5] = (90.0 - asin((h[0]*h[5]) / alen/blen)); // gamma
} else {
cell[0] = domain->xprd;
cell[1] = domain->yprd;
cell[2] = domain->zprd;
cell[3] = cell[4] = cell[5] = 90.0f;
}
// 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;
MPI_Allreduce(&bnme,&ntotal,1,MPI_LMP_BIGINT,MPI_SUM,world);
MPI_Allreduce(&nme,&nmax,1,MPI_INT,MPI_MAX,world);
// for single file output, the number of atoms must not change.
if (natoms != ntotal) {
if (multifile == 0) {
error->all(FLERR,"Single file molfile dump needs constant #atoms");
} else {
natoms = ntotal;
}
}
ntotal = 0;
// if file per timestep, open new file
if (multifile) openfile();
// 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(FLERR,"Too much per-proc info for dump");
maxbuf = nmax;
memory->destroy(buf);
memory->create(buf,maxbuf*size_one,"dump:buf");
}
if (nmax > maxids) {
maxids = nmax;
memory->destroy(ids);
memory->create(ids,maxids,"dump:ids");
}
pack(ids);
sort();
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);
}
} else {
MPI_Recv(&tmp,0,MPI_INT,0,0,world,&status);
MPI_Rsend(buf,nme*size_one,MPI_DOUBLE,0,0,world);
}
}
/* ---------------------------------------------------------------------- */
void DumpMolfile::openfile()
{
// single file, already opened, so just return
if (singlefile_opened) return;
if (multifile == 0) singlefile_opened = 1;
need_structure = 1;
if (me == 0) {
// close open file, if needed.
if (mf->is_open()) mf->close();
// if one file per timestep, replace '*' with current timestep
char *filecurrent = new char[strlen(filename) + 16];
if (multifile == 0) {
strcpy(filecurrent,filename);
} else {
char *ptr = strchr(filename,'*');
char *p1 = filename;
char *p2 = filecurrent;
while (p1 != ptr)
*p2++ = *p1++;
if (padflag == 0) {
sprintf(p2,BIGINT_FORMAT "%s",update->ntimestep,ptr+1);
} else {
char bif[8],pad[16];
strcpy(bif,BIGINT_FORMAT);
sprintf(pad,"%%0%d%s%%s",padflag,&bif[1]);
sprintf(p2,pad,update->ntimestep,ptr+1);
}
}
if (mf->open(filecurrent,&natoms))
error->one(FLERR,"Cannot open dump file");
delete[] filecurrent;
}
}
/* ---------------------------------------------------------------------- */
void DumpMolfile::pack(int *ids)
{
int m,n;
int *tag = atom->tag;
int *type = atom->type;
double **x = atom->x;
- int *image = atom->image;
+ tagint *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;
+ int ix = (image[i] & IMGMASK) - IMGMAX;
+ int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ int iz = (image[i] >> IMG2BITS) - IMGMAX;
buf[m++] = type[i];
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;
}
if (atom->molecule_flag) buf[m++] = atom->molecule[i];
if (atom->q_flag) buf[m++] = atom->q[i];
if (atom->rmass_flag) buf[m++] = atom->mass[i];
if (atom->radius_flag) buf[m++] = atom->radius[i];
ids[n++] = tag[i];
}
}
} else {
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
buf[m++] = type[i];
buf[m++] = x[i][0];
buf[m++] = x[i][1];
buf[m++] = x[i][2];
if (atom->molecule_flag) buf[m++] = atom->molecule[i];
if (atom->q_flag) buf[m++] = atom->q[i];
if (atom->rmass_flag) buf[m++] = atom->mass[i];
if (atom->radius_flag) buf[m++] = atom->radius[i];
ids[n++] = tag[i];
}
}
}
/* ---------------------------------------------------------------------- */
void DumpMolfile::write_data(int n, double *mybuf)
{
if (me == 0) {
// copy buf atom coords into global arrays
int m = 0;
for (int i = 0; i < n; i++) {
types[ntotal] = static_cast<int>(mybuf[m++]);
coords[3*ntotal + 0] = mybuf[m++];
coords[3*ntotal + 1] = mybuf[m++];
coords[3*ntotal + 2] = mybuf[m++];
if (atom->molecule_flag) molids[ntotal] = static_cast<int>(mybuf[m++]);
if (atom->q_flag) charges[ntotal] = mybuf[m++];
if (atom->rmass_flag) masses[ntotal] = mybuf[m++];
if (atom->radius_flag) radiuses[ntotal] = mybuf[m++];
++ntotal;
}
// if last chunk of atoms in this snapshot, write global arrays to file
if (ntotal == natoms) {
ntotal = 0;
if (need_structure) {
mf->property(MFI::P_NAME,types,typenames);
if (atom->molecule_flag)
mf->property(MFI::P_RESI,molids);
if (atom->rmass_flag) {
mf->property(MFI::P_MASS,masses);
} else {
mf->property(MFI::P_MASS,types,atom->mass);
}
if (atom->q_flag)
mf->property(MFI::P_CHRG,charges);
if (atom->radius_flag)
mf->property(MFI::P_RADS,radiuses);
// update/write structure information in plugin
mf->structure();
need_structure = 0;
}
double simtime = update->ntimestep * update->dt;
mf->timestep(coords,NULL,cell,&simtime);
}
}
}
/* ---------------------------------------------------------------------- */
int DumpMolfile::modify_param(int narg, char **arg)
{
if (strcmp(arg[0],"unwrap") == 0) {
if (narg < 2) error->all(FLERR,"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(FLERR,"Illegal dump_modify command");
return 2;
} else if (strcmp(arg[0],"element") == 0) {
if (narg < ntypes+1)
error->all(FLERR, "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++) {
int n = strlen(arg[itype]) + 1;
typenames[itype] = new char[n];
strcpy(typenames[itype],arg[itype]);
}
return ntypes+1;
}
return 0;
}
/* ----------------------------------------------------------------------
return # of bytes of allocated memory in buf and global coords array
------------------------------------------------------------------------- */
bigint DumpMolfile::memory_usage()
{
bigint bytes = Dump::memory_usage();
bytes += memory->usage(coords,natoms*3);
bytes += sizeof(MFI);
return bytes;
}
diff --git a/src/USER-OMP/angle_charmm_omp.cpp b/src/USER-OMP/angle_charmm_omp.cpp
index 1efe62d4d..4cc86dd11 100644
--- a/src/USER-OMP/angle_charmm_omp.cpp
+++ b/src/USER-OMP/angle_charmm_omp.cpp
@@ -1,199 +1,196 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_charmm_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "math_const.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCharmmOMP::AngleCharmmOMP(class LAMMPS *lmp)
: AngleCharmm(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleCharmmOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void AngleCharmmOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double dtheta,tk;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
double delxUB,delyUB,delzUB,rsqUB,rUB,dr,rk,forceUB;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// Urey-Bradley bond
delxUB = x[i3][0] - x[i1][0];
delyUB = x[i3][1] - x[i1][1];
delzUB = x[i3][2] - x[i1][2];
- domain->minimum_image(delxUB,delyUB,delzUB);
rsqUB = delxUB*delxUB + delyUB*delyUB + delzUB*delzUB;
rUB = sqrt(rsqUB);
// Urey-Bradley force & energy
dr = rUB - r_ub[type];
rk = k_ub[type] * dr;
if (rUB > 0.0) forceUB = -2.0*rk/rUB;
else forceUB = 0.0;
if (EFLAG) eangle = rk*dr;
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
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;
s = 1.0/s;
// harmonic force & energy
dtheta = acos(c) - theta0[type];
tk = k[type] * dtheta;
if (EFLAG) eangle += tk*dtheta;
a = -2.0 * tk * s;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2 - delxUB*forceUB;
f1[1] = a11*dely1 + a12*dely2 - delyUB*forceUB;
f1[2] = a11*delz1 + a12*delz2 - delzUB*forceUB;
f3[0] = a22*delx2 + a12*delx1 + delxUB*forceUB;
f3[1] = a22*dely2 + a12*dely1 + delyUB*forceUB;
f3[2] = a22*delz2 + a12*delz1 + delzUB*forceUB;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2,thr);
}
}
diff --git a/src/USER-OMP/angle_class2_omp.cpp b/src/USER-OMP/angle_class2_omp.cpp
index 0dbd0cbfd..ef887a93e 100644
--- a/src/USER-OMP/angle_class2_omp.cpp
+++ b/src/USER-OMP/angle_class2_omp.cpp
@@ -1,242 +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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_class2_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "math_const.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleClass2OMP::AngleClass2OMP(class LAMMPS *lmp)
: AngleClass2(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleClass2OMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void AngleClass2OMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double dtheta,dtheta2,dtheta3,dtheta4,de_angle;
double dr1,dr2,tk1,tk2,aa1,aa2,aa11,aa12,aa21,aa22;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22,b1,b2;
double vx11,vx12,vy11,vy12,vz11,vz12,vx21,vx22,vy21,vy22,vz21,vz22;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
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;
s = 1.0/s;
// force & energy for angle term
dtheta = acos(c) - theta0[type];
dtheta2 = dtheta*dtheta;
dtheta3 = dtheta2*dtheta;
dtheta4 = dtheta3*dtheta;
de_angle = 2.0*k2[type]*dtheta + 3.0*k3[type]*dtheta2 +
4.0*k4[type]*dtheta3;
a = -de_angle*s;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
if (EFLAG) eangle = k2[type]*dtheta2 + k3[type]*dtheta3 + k4[type]*dtheta4;
// force & energy for bond-bond term
dr1 = r1 - bb_r1[type];
dr2 = r2 - bb_r2[type];
tk1 = bb_k[type] * dr1;
tk2 = bb_k[type] * dr2;
f1[0] -= delx1*tk2/r1;
f1[1] -= dely1*tk2/r1;
f1[2] -= delz1*tk2/r1;
f3[0] -= delx2*tk1/r2;
f3[1] -= dely2*tk1/r2;
f3[2] -= delz2*tk1/r2;
if (EFLAG) eangle += bb_k[type]*dr1*dr2;
// force & energy for bond-angle term
aa1 = s * dr1 * ba_k1[type];
aa2 = s * dr2 * ba_k2[type];
aa11 = aa1 * c / rsq1;
aa12 = -aa1 / (r1 * r2);
aa21 = aa2 * c / rsq1;
aa22 = -aa2 / (r1 * r2);
vx11 = (aa11 * delx1) + (aa12 * delx2);
vx12 = (aa21 * delx1) + (aa22 * delx2);
vy11 = (aa11 * dely1) + (aa12 * dely2);
vy12 = (aa21 * dely1) + (aa22 * dely2);
vz11 = (aa11 * delz1) + (aa12 * delz2);
vz12 = (aa21 * delz1) + (aa22 * delz2);
aa11 = aa1 * c / rsq2;
aa21 = aa2 * c / rsq2;
vx21 = (aa11 * delx2) + (aa12 * delx1);
vx22 = (aa21 * delx2) + (aa22 * delx1);
vy21 = (aa11 * dely2) + (aa12 * dely1);
vy22 = (aa21 * dely2) + (aa22 * dely1);
vz21 = (aa11 * delz2) + (aa12 * delz1);
vz22 = (aa21 * delz2) + (aa22 * delz1);
b1 = ba_k1[type] * dtheta / r1;
b2 = ba_k2[type] * dtheta / r2;
f1[0] -= vx11 + b1*delx1 + vx12;
f1[1] -= vy11 + b1*dely1 + vy12;
f1[2] -= vz11 + b1*delz1 + vz12;
f3[0] -= vx21 + b2*delx2 + vx22;
f3[1] -= vy21 + b2*dely2 + vy22;
f3[2] -= vz21 + b2*delz2 + vz22;
if (EFLAG) eangle += ba_k1[type]*dr1*dtheta + ba_k2[type]*dr2*dtheta;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2,thr);
}
}
diff --git a/src/USER-OMP/angle_cosine_delta_omp.cpp b/src/USER-OMP/angle_cosine_delta_omp.cpp
index 5ba57d20b..caf259b15 100644
--- a/src/USER-OMP/angle_cosine_delta_omp.cpp
+++ b/src/USER-OMP/angle_cosine_delta_omp.cpp
@@ -1,191 +1,189 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_cosine_delta_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "math_const.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosineDeltaOMP::AngleCosineDeltaOMP(class LAMMPS *lmp)
: AngleCosineDelta(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleCosineDeltaOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void AngleCosineDeltaOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2,theta,dtheta,dcostheta,tk;
double eangle,f1[3],f3[3];
double rsq1,rsq2,r1,r2,c,a,cot,a11,a12,a22,b11,b12,b22,c0,s0,s;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
theta = acos(c);
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
s = 1.0/s;
cot = c/s;
// force & energy
dtheta = theta - theta0[type];
dcostheta = cos(dtheta);
tk = k[type] * (1.0-dcostheta);
if (EFLAG) eangle = tk;
a = -k[type];
// expand dtheta for cos and sin contribution to force
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
b11 = -a*c*cot / rsq1;
b12 = a*cot / (r1*r2);
b22 = -a*c*cot / rsq2;
c0 = cos(theta0[type]);
s0 = sin(theta0[type]);
f1[0] = (a11*delx1 + a12*delx2)*c0 + (b11*delx1 + b12*delx2)*s0;
f1[1] = (a11*dely1 + a12*dely2)*c0 + (b11*dely1 + b12*dely2)*s0;
f1[2] = (a11*delz1 + a12*delz2)*c0 + (b11*delz1 + b12*delz2)*s0;
f3[0] = (a22*delx2 + a12*delx1)*c0 + (b22*delx2 + b12*delx1)*s0;
f3[1] = (a22*dely2 + a12*dely1)*c0 + (b22*dely2 + b12*dely1)*s0;
f3[2] = (a22*delz2 + a12*delz1)*c0 + (b22*delz2 + b12*delz1)*s0;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2,thr);
}
}
diff --git a/src/USER-OMP/angle_cosine_omp.cpp b/src/USER-OMP/angle_cosine_omp.cpp
index a773f94c5..51d3494a4 100644
--- a/src/USER-OMP/angle_cosine_omp.cpp
+++ b/src/USER-OMP/angle_cosine_omp.cpp
@@ -1,168 +1,166 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_cosine_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "math_const.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosineOMP::AngleCosineOMP(class LAMMPS *lmp)
: AngleCosine(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleCosineOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void AngleCosineOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double rsq1,rsq2,r1,r2,c,a,a11,a12,a22;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// c = cosine of angle
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// force & energy
if (EFLAG) eangle = k[type]*(1.0+c);
a = k[type];
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2,thr);
}
}
diff --git a/src/USER-OMP/angle_cosine_periodic_omp.cpp b/src/USER-OMP/angle_cosine_periodic_omp.cpp
index a86b68611..6c5932e70 100644
--- a/src/USER-OMP/angle_cosine_periodic_omp.cpp
+++ b/src/USER-OMP/angle_cosine_periodic_omp.cpp
@@ -1,206 +1,204 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_cosine_periodic_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "math_const.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosinePeriodicOMP::AngleCosinePeriodicOMP(class LAMMPS *lmp)
: AngleCosinePeriodic(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleCosinePeriodicOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void AngleCosinePeriodicOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i,i1,i2,i3,n,m,type,b_factor;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
double tn,tn_1,tn_2,un,un_1,un_2;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// c = cosine of angle
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
m = multiplicity[type];
b_factor = b[type];
// cos(n*x) = Tn(cos(x))
// Tn(x) = Chebyshev polynomials of the first kind: T_0 = 1, T_1 = x, ...
// recurrence relationship:
// Tn(x) = 2*x*T[n-1](x) - T[n-2](x) where T[-1](x) = 0
// also, dTn(x)/dx = n*U[n-1](x)
// where Un(x) = 2*x*U[n-1](x) - U[n-2](x) and U[-1](x) = 0
// finally need to handle special case for n = 1
tn = 1.0;
tn_1 = 1.0;
tn_2 = 0.0;
un = 1.0;
un_1 = 2.0;
un_2 = 0.0;
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
s = 1.0/s;
// force & energy
tn_2 = c;
for (i = 1; i <= m; i++) {
tn = 2*c*tn_1 - tn_2;
tn_2 = tn_1;
tn_1 = tn;
}
for (i = 2; i <= m; i++) {
un = 2*c*un_1 - un_2;
un_2 = un_1;
un_1 = un;
}
tn = b_factor*pow(-1.0,(double)m)*tn;
un = b_factor*pow(-1.0,(double)m)*m*un;
if (EFLAG) eangle = 2*k[type]*(1.0 - tn);
a = -k[type]*un;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2,thr);
}
}
diff --git a/src/USER-OMP/angle_cosine_shift_exp_omp.cpp b/src/USER-OMP/angle_cosine_shift_exp_omp.cpp
index 81cd8ecad..18af91cf7 100644
--- a/src/USER-OMP/angle_cosine_shift_exp_omp.cpp
+++ b/src/USER-OMP/angle_cosine_shift_exp_omp.cpp
@@ -1,189 +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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_cosine_shift_exp_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "math_const.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosineShiftExpOMP::AngleCosineShiftExpOMP(class LAMMPS *lmp)
: AngleCosineShiftExp(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleCosineShiftExpOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void AngleCosineShiftExpOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3],ff;
double rsq1,rsq2,r1,r2,c,s,a11,a12,a22;
double exp2,aa,uumin,cccpsss,cssmscc;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// c = cosine of angle
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// C= sine of angle
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
// force & energy
aa=a[type];
uumin=umin[type];
cccpsss = c*cost[type]+s*sint[type];
cssmscc = c*sint[type]-s*cost[type];
if (doExpansion[type])
{ // |a|<0.01 so use expansions relative precision <1e-5
// std::cout << "Using expansion\n";
if (EFLAG) eangle = -0.125*(1+cccpsss)*(4+aa*(cccpsss-1))*uumin;
ff=0.25*uumin*cssmscc*(2+aa*cccpsss)/s;
}
else
{
// std::cout << "Not using expansion\n";
exp2=exp(0.5*aa*(1+cccpsss));
if (EFLAG) eangle = opt1[type]*(1-exp2);
ff=0.5*a[type]*opt1[type]*exp2*cssmscc/s;
}
a11 = ff*c/ rsq1;
a12 = -ff / (r1*r2);
a22 = ff*c/ rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2,thr);
}
}
diff --git a/src/USER-OMP/angle_cosine_shift_omp.cpp b/src/USER-OMP/angle_cosine_shift_omp.cpp
index 2c830cf39..a7f40fee8 100644
--- a/src/USER-OMP/angle_cosine_shift_omp.cpp
+++ b/src/USER-OMP/angle_cosine_shift_omp.cpp
@@ -1,174 +1,172 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_cosine_shift_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "math_const.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosineShiftOMP::AngleCosineShiftOMP(class LAMMPS *lmp)
: AngleCosineShift(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleCosineShiftOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void AngleCosineShiftOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double f1[3],f3[3];
double rsq1,rsq2,r1,r2,c,s,cps,a11,a12,a22;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
double eangle = 0.0;
for (n = nfrom; n < nto; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// c = cosine of angle
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// C= sine of angle
s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
// force & energy
const double kcos=kcost[type];
const double ksin=ksint[type];
if (EFLAG) eangle = -k[type]-kcos*c-ksin*s;
cps = c/s; // NOTE absorbed one c
a11 = (-kcos +ksin*cps )*c/ rsq1;
a12 = ( kcos -ksin*cps ) / (r1*r2);
a22 = (-kcos +ksin*cps )*c/ rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2,thr);
}
}
diff --git a/src/USER-OMP/angle_cosine_squared_omp.cpp b/src/USER-OMP/angle_cosine_squared_omp.cpp
index ccdaf2bdb..e8eaff6b2 100644
--- a/src/USER-OMP/angle_cosine_squared_omp.cpp
+++ b/src/USER-OMP/angle_cosine_squared_omp.cpp
@@ -1,173 +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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_cosine_squared_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "math_const.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleCosineSquaredOMP::AngleCosineSquaredOMP(class LAMMPS *lmp)
: AngleCosineSquared(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleCosineSquaredOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void AngleCosineSquaredOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double dcostheta,tk;
double rsq1,rsq2,r1,r2,c,a,a11,a12,a22;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// force & energy
dcostheta = c - cos(theta0[type]);
tk = k[type] * dcostheta;
if (EFLAG) eangle = tk*dcostheta;
a = 2.0 * tk;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2,thr);
}
}
diff --git a/src/USER-OMP/angle_dipole_omp.cpp b/src/USER-OMP/angle_dipole_omp.cpp
index f9cbc6f51..025ffcd16 100644
--- a/src/USER-OMP/angle_dipole_omp.cpp
+++ b/src/USER-OMP/angle_dipole_omp.cpp
@@ -1,126 +1,125 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_dipole_omp.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "math_const.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleDipoleOMP::AngleDipoleOMP(class LAMMPS *lmp)
: AngleDipole(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleDipoleOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
if (!force->newton_bond)
error->all(FLERR,"'newton' flag for bonded interactions must be 'on'");
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (eflag)
eval<1>(ifrom, ito, thr);
else
eval<0>(ifrom, ito, thr);
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EFLAG>
void AngleDipoleOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int iRef,iDip,iDummy,n,type;
double delx,dely,delz;
double eangle,tangle;
double r,cosGamma,deltaGamma,kdg,rmu;
const double * const * const x = atom->x; // position vector
const double * const * const mu = atom->mu; // point-dipole components and moment magnitude
double * const * const torque = thr->get_torque();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
const double f1[3] = {0.0, 0.0, 0.0};
const double f3[3] = {0.0, 0.0, 0.0};
for (n = nfrom; n < nto; n++) {
iDip = anglelist[n][0]; // dipole whose orientation is to be restrained
iRef = anglelist[n][1]; // reference atom toward which dipole will point
iDummy = anglelist[n][2]; // dummy atom - irrelevant to the interaction
type = anglelist[n][3];
delx = x[iRef][0] - x[iDip][0];
dely = x[iRef][1] - x[iDip][1];
delz = x[iRef][2] - x[iDip][2];
- domain->minimum_image(delx,dely,delz);
r = sqrt(delx*delx + dely*dely + delz*delz);
rmu = r * mu[iDip][3];
cosGamma = (mu[iDip][0]*delx+mu[iDip][1]*dely+mu[iDip][2]*delz) / rmu;
deltaGamma = cosGamma - cos(gamma0[type]);
kdg = k[type] * deltaGamma;
if (EFLAG) eangle = kdg * deltaGamma; // energy
tangle = 2.0 * kdg / rmu;
torque[iDip][0] += tangle * (dely*mu[iDip][2] - delz*mu[iDip][1]);
torque[iDip][1] += tangle * (delz*mu[iDip][0] - delx*mu[iDip][2]);
torque[iDip][2] += tangle * (delx*mu[iDip][1] - dely*mu[iDip][0]);
if (EFLAG) // tally energy (virial=0 because force=0)
ev_tally_thr(this,iRef,iDip,iDummy,nlocal,/* NEWTON_BOND */ 1,
eangle,f1,f3,0.0,0.0,0.0,0.0,0.0,0.0,thr);
}
}
diff --git a/src/USER-OMP/angle_harmonic_omp.cpp b/src/USER-OMP/angle_harmonic_omp.cpp
index b6ff1a1dd..c30f830b7 100644
--- a/src/USER-OMP/angle_harmonic_omp.cpp
+++ b/src/USER-OMP/angle_harmonic_omp.cpp
@@ -1,177 +1,175 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_harmonic_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "math_const.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleHarmonicOMP::AngleHarmonicOMP(class LAMMPS *lmp)
: AngleHarmonic(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleHarmonicOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void AngleHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double dtheta,tk;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
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;
s = 1.0/s;
// force & energy
dtheta = acos(c) - theta0[type];
tk = k[type] * dtheta;
if (EFLAG) eangle = tk*dtheta;
a = -2.0 * tk * s;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2,thr);
}
}
diff --git a/src/USER-OMP/angle_sdk_omp.cpp b/src/USER-OMP/angle_sdk_omp.cpp
index 43e0049e1..bd780e0fe 100644
--- a/src/USER-OMP/angle_sdk_omp.cpp
+++ b/src/USER-OMP/angle_sdk_omp.cpp
@@ -1,233 +1,230 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_sdk_omp.h"
#include "atom.h"
#include "neighbor.h"
#include "domain.h"
#include "comm.h"
#include "force.h"
#include "math_const.h"
#include <math.h>
#include "lj_sdk_common.h"
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
using namespace LJSDKParms;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleSDKOMP::AngleSDKOMP(class LAMMPS *lmp)
: AngleSDK(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleSDKOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void AngleSDKOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2,delx3,dely3,delz3;
double eangle,f1[3],f3[3],e13,f13;
double dtheta,tk;
double rsq1,rsq2,rsq3,r1,r2,c,s,a,a11,a12,a22;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
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;
s = 1.0/s;
// 1-3 LJ interaction.
// we only want to use the repulsive part,
// and it can be scaled (or off).
// so this has to be done here and not in the
// general non-bonded code.
f13 = e13 = delx3 = dely3 = delz3 = 0.0;
if (repflag) {
delx3 = x[i1][0] - x[i3][0];
dely3 = x[i1][1] - x[i3][1];
delz3 = x[i1][2] - x[i3][2];
- domain->minimum_image(delx3,dely3,delz3);
rsq3 = delx3*delx3 + dely3*dely3 + delz3*delz3;
const int type1 = atom->type[i1];
const int type3 = atom->type[i3];
if (rsq3 < rminsq[type1][type3]) {
const int ljt = lj_type[type1][type3];
const double r2inv = 1.0/rsq3;
if (ljt == LJ12_4) {
const double r4inv=r2inv*r2inv;
f13 = r4inv*(lj1[type1][type3]*r4inv*r4inv - lj2[type1][type3]);
if (EFLAG) e13 = r4inv*(lj3[type1][type3]*r4inv*r4inv - lj4[type1][type3]);
} else if (ljt == LJ9_6) {
const double r3inv = r2inv*sqrt(r2inv);
const double r6inv = r3inv*r3inv;
f13 = r6inv*(lj1[type1][type3]*r3inv - lj2[type1][type3]);
if (EFLAG) e13 = r6inv*(lj3[type1][type3]*r3inv - lj4[type1][type3]);
} else if (ljt == LJ12_6) {
const double r6inv = r2inv*r2inv*r2inv;
f13 = r6inv*(lj1[type1][type3]*r6inv - lj2[type1][type3]);
if (EFLAG) e13 = r6inv*(lj3[type1][type3]*r6inv - lj4[type1][type3]);
}
// make sure energy is 0.0 at the cutoff.
if (EFLAG) e13 -= emin[type1][type3];
f13 *= r2inv;
}
}
// force & energy
dtheta = acos(c) - theta0[type];
tk = k[type] * dtheta;
if (EFLAG) eangle = tk*dtheta;
a = -2.0 * tk * s;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of the 3 atoms
if (NEWTON_BOND || i1 < nlocal) {
f[i1][0] += f1[0] + f13*delx3;
f[i1][1] += f1[1] + f13*dely3;
f[i1][2] += f1[2] + f13*delz3;
}
if (NEWTON_BOND || i2 < nlocal) {
f[i2][0] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0] - f13*delx3;
f[i3][1] += f3[1] - f13*dely3;
f[i3][2] += f3[2] - f13*delz3;
}
if (EVFLAG) {
ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2,thr);
if (repflag) ev_tally13_thr(this,i1,i3,nlocal,NEWTON_BOND,
e13,f13,delx3,dely3,delz3,thr);
}
}
}
diff --git a/src/USER-OMP/angle_table_omp.cpp b/src/USER-OMP/angle_table_omp.cpp
index 8eb73b4c2..15c32c894 100644
--- a/src/USER-OMP/angle_table_omp.cpp
+++ b/src/USER-OMP/angle_table_omp.cpp
@@ -1,177 +1,175 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "angle_table_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "math_const.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
AngleTableOMP::AngleTableOMP(class LAMMPS *lmp)
: AngleTable(lmp), ThrOMP(lmp,THR_ANGLE)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void AngleTableOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nanglelist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void AngleTableOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,i3,n,type;
double eangle,f1[3],f3[3];
double delx1,dely1,delz1,delx2,dely2,delz2;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
double theta,u,mdu; //mdu: minus du, -du/dx=f
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const anglelist = neighbor->anglelist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = anglelist[n][0];
i2 = anglelist[n][1];
i3 = anglelist[n][2];
type = anglelist[n][3];
// 1st bond
delx1 = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2];
- domain->minimum_image(delx1,dely1,delz1);
rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1;
r1 = sqrt(rsq1);
// 2nd bond
delx2 = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2];
- domain->minimum_image(delx2,dely2,delz2);
rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2;
r2 = sqrt(rsq2);
// angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
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;
s = 1.0/s;
// tabulated force & energy
theta = acos(c);
uf_lookup(type,theta,u,mdu);
if (EFLAG) eangle = u;
a = mdu * s;
a11 = a*c / rsq1;
a12 = -a / (r1*r2);
a22 = a*c / rsq2;
f1[0] = a11*delx1 + a12*delx2;
f1[1] = a11*dely1 + a12*dely2;
f1[2] = a11*delz1 + a12*delz2;
f3[0] = a22*delx2 + a12*delx1;
f3[1] = a22*dely2 + a12*dely1;
f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 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] -= f1[0] + f3[0];
f[i2][1] -= f1[1] + f3[1];
f[i2][2] -= f1[2] + f3[2];
}
if (NEWTON_BOND || i3 < nlocal) {
f[i3][0] += f3[0];
f[i3][1] += f3[1];
f[i3][2] += f3[2];
}
if (EVFLAG) ev_tally_thr(this,i1,i2,i3,nlocal,NEWTON_BOND,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2,thr);
}
}
diff --git a/src/USER-OMP/bond_class2_omp.cpp b/src/USER-OMP/bond_class2_omp.cpp
index a31ac2e3a..580d9b980 100644
--- a/src/USER-OMP/bond_class2_omp.cpp
+++ b/src/USER-OMP/bond_class2_omp.cpp
@@ -1,133 +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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "bond_class2_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondClass2OMP::BondClass2OMP(class LAMMPS *lmp)
: BondClass2(lmp), ThrOMP(lmp,THR_BOND)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void BondClass2OMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nbondlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void BondClass2OMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,dr2,dr3,dr4,de_bond;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const bondlist = neighbor->bondlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
dr = r - r0[type];
dr2 = dr*dr;
dr3 = dr2*dr;
dr4 = dr3*dr;
// force & energy
de_bond = 2.0*k2[type]*dr + 3.0*k3[type]*dr2 + 4.0*k4[type]*dr3;
if (r > 0.0) fbond = -de_bond/r;
else fbond = 0.0;
if (EFLAG) ebond = k2[type]*dr2 + k3[type]*dr3 + k4[type]*dr4;
// 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_thr(this,i1,i2,nlocal,NEWTON_BOND,
ebond,fbond,delx,dely,delz,thr);
}
}
diff --git a/src/USER-OMP/bond_fene_expand_omp.cpp b/src/USER-OMP/bond_fene_expand_omp.cpp
index 39c43d978..4706ef823 100644
--- a/src/USER-OMP/bond_fene_expand_omp.cpp
+++ b/src/USER-OMP/bond_fene_expand_omp.cpp
@@ -1,163 +1,162 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "bond_fene_expand_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "error.h"
#include "update.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondFENEExpandOMP::BondFENEExpandOMP(class LAMMPS *lmp)
: BondFENEExpand(lmp), ThrOMP(lmp,THR_BOND)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void BondFENEExpandOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nbondlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void BondFENEExpandOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r0sq,rlogarg,sr2,sr6;
double r,rshift,rshiftsq;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const bondlist = neighbor->bondlist;
const int nlocal = atom->nlocal;
const int tid = thr->get_tid();
for (n = nfrom; n < nto; 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);
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: " BIGINT_FORMAT " %d %d %g",
update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
error->warning(FLERR,str,0);
if (check_error_thr((rlogarg <= -3.0),tid,FLERR,"Bad FENE bond"))
return;
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_thr(this,i1,i2,nlocal,NEWTON_BOND,
ebond,fbond,delx,dely,delz,thr);
}
}
diff --git a/src/USER-OMP/bond_fene_omp.cpp b/src/USER-OMP/bond_fene_omp.cpp
index 72596d186..34f90ea3a 100644
--- a/src/USER-OMP/bond_fene_omp.cpp
+++ b/src/USER-OMP/bond_fene_omp.cpp
@@ -1,159 +1,158 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "bond_fene_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "error.h"
#include "update.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondFENEOMP::BondFENEOMP(class LAMMPS *lmp)
: BondFENE(lmp), ThrOMP(lmp,THR_BOND)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void BondFENEOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nbondlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void BondFENEOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r0sq,rlogarg,sr2,sr6;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const bondlist = neighbor->bondlist;
const int nlocal = atom->nlocal;
const int tid = thr->get_tid();
for (n = nfrom; n < nto; 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);
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: " BIGINT_FORMAT " %d %d %g",
update->ntimestep,atom->tag[i1],atom->tag[i2],sqrt(rsq));
error->warning(FLERR,str,0);
if (check_error_thr((rlogarg <= -3.0),tid,FLERR,"Bad FENE bond"))
return;
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_thr(this,i1,i2,nlocal,NEWTON_BOND,
ebond,fbond,delx,dely,delz,thr);
}
}
diff --git a/src/USER-OMP/bond_harmonic_omp.cpp b/src/USER-OMP/bond_harmonic_omp.cpp
index 9c8c6d2c7..dc8bab1c5 100644
--- a/src/USER-OMP/bond_harmonic_omp.cpp
+++ b/src/USER-OMP/bond_harmonic_omp.cpp
@@ -1,129 +1,128 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "bond_harmonic_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondHarmonicOMP::BondHarmonicOMP(class LAMMPS *lmp)
: BondHarmonic(lmp), ThrOMP(lmp,THR_BOND)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void BondHarmonicOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nbondlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void BondHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,rk;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const bondlist = neighbor->bondlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
dr = r - r0[type];
rk = k[type] * dr;
// force & energy
if (r > 0.0) fbond = -2.0*rk/r;
else fbond = 0.0;
if (EFLAG) ebond = rk*dr;
// 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_thr(this,i1,i2,nlocal,NEWTON_BOND,
ebond,fbond,delx,dely,delz,thr);
}
}
diff --git a/src/USER-OMP/bond_harmonic_shift_cut_omp.cpp b/src/USER-OMP/bond_harmonic_shift_cut_omp.cpp
index de2c72e89..6ea5f6c2c 100644
--- a/src/USER-OMP/bond_harmonic_shift_cut_omp.cpp
+++ b/src/USER-OMP/bond_harmonic_shift_cut_omp.cpp
@@ -1,132 +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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "bond_harmonic_shift_cut_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondHarmonicShiftCutOMP::BondHarmonicShiftCutOMP(class LAMMPS *lmp)
: BondHarmonicShiftCut(lmp), ThrOMP(lmp,THR_BOND)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void BondHarmonicShiftCutOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nbondlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void BondHarmonicShiftCutOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,rk;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const bondlist = neighbor->bondlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
if (r>r1[type]) continue;
dr = r - r0[type];
rk = k[type] * dr;
// force & energy
if (r > 0.0) fbond = -2.0*rk/r;
else fbond = 0.0;
- if (EFLAG) ebond = k[type]*(dr*dr -(r0[type]-r1[type])*(r0[type]-r1[type]) );
+ if (EFLAG)
+ ebond = k[type]*(dr*dr -(r0[type]-r1[type])*(r0[type]-r1[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_thr(this,i1,i2,nlocal,NEWTON_BOND,
ebond,fbond,delx,dely,delz,thr);
}
}
diff --git a/src/USER-OMP/bond_harmonic_shift_omp.cpp b/src/USER-OMP/bond_harmonic_shift_omp.cpp
index 2d566f771..2f6f1d37b 100644
--- a/src/USER-OMP/bond_harmonic_shift_omp.cpp
+++ b/src/USER-OMP/bond_harmonic_shift_omp.cpp
@@ -1,129 +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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "bond_harmonic_shift_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondHarmonicShiftOMP::BondHarmonicShiftOMP(class LAMMPS *lmp)
: BondHarmonicShift(lmp), ThrOMP(lmp,THR_BOND)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void BondHarmonicShiftOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nbondlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void BondHarmonicShiftOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,rk;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const bondlist = neighbor->bondlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
dr = r - r0[type];
rk = k[type] * dr;
// force & energy
if (r > 0.0) fbond = -2.0*rk/r;
else fbond = 0.0;
- if (EFLAG) ebond = k[type]*(dr*dr -(r0[type]-r1[type])*(r0[type]-r1[type]) );
+ if (EFLAG)
+ ebond = k[type]*(dr*dr -(r0[type]-r1[type])*(r0[type]-r1[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_thr(this,i1,i2,nlocal,NEWTON_BOND,
ebond,fbond,delx,dely,delz,thr);
}
}
diff --git a/src/USER-OMP/bond_morse_omp.cpp b/src/USER-OMP/bond_morse_omp.cpp
index 0a91857c8..21063c636 100644
--- a/src/USER-OMP/bond_morse_omp.cpp
+++ b/src/USER-OMP/bond_morse_omp.cpp
@@ -1,130 +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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "bond_morse_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondMorseOMP::BondMorseOMP(class LAMMPS *lmp)
: BondMorse(lmp), ThrOMP(lmp,THR_BOND)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void BondMorseOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nbondlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void BondMorseOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,ralpha;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const bondlist = neighbor->bondlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
dr = r - r0[type];
ralpha = exp(-alpha[type]*dr);
// force & energy
if (r > 0.0) fbond = -2.0*d0[type]*alpha[type]*(1-ralpha)*ralpha/r;
else fbond = 0.0;
if (EFLAG) ebond = d0[type]*(1-ralpha)*(1-ralpha);
// 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_thr(this,i1,i2,nlocal,NEWTON_BOND,
ebond,fbond,delx,dely,delz,thr);
}
}
diff --git a/src/USER-OMP/bond_nonlinear_omp.cpp b/src/USER-OMP/bond_nonlinear_omp.cpp
index 46eed4760..9e61ca321 100644
--- a/src/USER-OMP/bond_nonlinear_omp.cpp
+++ b/src/USER-OMP/bond_nonlinear_omp.cpp
@@ -1,130 +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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "bond_nonlinear_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondNonlinearOMP::BondNonlinearOMP(class LAMMPS *lmp)
: BondNonlinear(lmp), ThrOMP(lmp,THR_BOND)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void BondNonlinearOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nbondlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void BondNonlinearOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r,dr,drsq,lamdasq,denom,denomsq;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const bondlist = neighbor->bondlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
dr = r - r0[type];
drsq = dr*dr;
lamdasq = lamda[type]*lamda[type];
denom = lamdasq - drsq;
denomsq = denom*denom;
// force & energy
fbond = -epsilon[type]/r * 2.0*dr*lamdasq/denomsq;
if (EFLAG) ebond = epsilon[type] * drsq / denom;
// 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_thr(this,i1,i2,nlocal,NEWTON_BOND,
ebond,fbond,delx,dely,delz,thr);
}
}
diff --git a/src/USER-OMP/bond_quartic_omp.cpp b/src/USER-OMP/bond_quartic_omp.cpp
index d07ee9aca..79d7621a6 100644
--- a/src/USER-OMP/bond_quartic_omp.cpp
+++ b/src/USER-OMP/bond_quartic_omp.cpp
@@ -1,198 +1,197 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "bond_quartic_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include "pair.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondQuarticOMP::BondQuarticOMP(class LAMMPS *lmp)
: BondQuartic(lmp), ThrOMP(lmp,THR_BOND)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void BondQuarticOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
// insure pair->ev_tally() will use 1-4 virial contribution
if (vflag_global == 2)
force->pair->vflag_either = force->pair->vflag_global = 1;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nbondlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void BondQuarticOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,n,m,type,itype,jtype;
double delx,dely,delz,ebond,fbond,evdwl,fpair;
double r,rsq,dr,r2,ra,rb,sr2,sr6;
ebond = evdwl = 0.0;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
int * const * const bondlist = neighbor->bondlist;
const double * const * const cutsq = force->pair->cutsq;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
// skip bond if already broken
if (bondlist[n][2] <= 0) continue;
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);
rsq = delx*delx + dely*dely + delz*delz;
// if bond breaks, set type to 0
// both in temporary bondlist and permanent bond_type
// if this proc owns both atoms,
// negate bond_type twice if other atom stores it
// if other proc owns 2nd atom, other proc will also break bond
if (rsq > rc[type]*rc[type]) {
bondlist[n][2] = 0;
for (m = 0; m < atom->num_bond[i1]; m++)
if (atom->bond_atom[i1][m] == atom->tag[i2])
atom->bond_type[i1][m] = 0;
if (i2 < atom->nlocal)
for (m = 0; m < atom->num_bond[i2]; m++)
if (atom->bond_atom[i2][m] == atom->tag[i1])
atom->bond_type[i2][m] = 0;
continue;
}
// quartic bond
// 1st portion is from quartic term
// 2nd portion is from LJ term cut at 2^(1/6) with eps = sigma = 1.0
r = sqrt(rsq);
dr = r - rc[type];
r2 = dr*dr;
ra = dr - b1[type];
rb = dr - b2[type];
fbond = -k[type]/r * (r2*(ra+rb) + 2.0*dr*ra*rb);
if (rsq < TWO_1_3) {
sr2 = 1.0/rsq;
sr6 = sr2*sr2*sr2;
fbond += 48.0*sr6*(sr6-0.5)/rsq;
}
if (EFLAG) {
ebond = k[type]*r2*ra*rb + u0[type];
if (rsq < TWO_1_3) ebond += 4.0*sr6*(sr6-1.0) + 1.0;
}
// 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_thr(this,i1,i2,nlocal,NEWTON_BOND,ebond,fbond,delx,dely,delz,thr);
// subtract out pairwise contribution from 2 atoms via pair->single()
// required since special_bond = 1,1,1
// tally energy/virial in pair, using newton_bond as newton flag
itype = atom->type[i1];
jtype = atom->type[i2];
if (rsq < cutsq[itype][jtype]) {
evdwl = -force->pair->single(i1,i2,itype,jtype,rsq,1.0,1.0,fpair);
fpair = -fpair;
if (NEWTON_BOND || i1 < nlocal) {
f[i1][0] += delx*fpair;
f[i1][1] += dely*fpair;
f[i1][2] += delz*fpair;
}
if (NEWTON_BOND || i2 < nlocal) {
f[i2][0] -= delx*fpair;
f[i2][1] -= dely*fpair;
f[i2][2] -= delz*fpair;
}
if (EVFLAG) ev_tally_thr(force->pair,i1,i2,nlocal,NEWTON_BOND,
evdwl,0.0,fpair,delx,dely,delz,thr);
}
}
}
diff --git a/src/USER-OMP/bond_table_omp.cpp b/src/USER-OMP/bond_table_omp.cpp
index fefadfc44..318499131 100644
--- a/src/USER-OMP/bond_table_omp.cpp
+++ b/src/USER-OMP/bond_table_omp.cpp
@@ -1,127 +1,126 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "bond_table_omp.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "neighbor.h"
#include "domain.h"
#include <math.h>
#include "suffix.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondTableOMP::BondTableOMP(class LAMMPS *lmp)
: BondTable(lmp), ThrOMP(lmp,THR_BOND)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void BondTableOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nbondlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void BondTableOMP::eval(int nfrom, int nto, ThrData * const thr)
{
int i1,i2,n,type;
double delx,dely,delz,ebond,fbond;
double rsq,r;
double u,mdu;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const bondlist = neighbor->bondlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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);
rsq = delx*delx + dely*dely + delz*delz;
r = sqrt(rsq);
// force & energy
uf_lookup(type,r,u,mdu);
fbond = mdu/r;
ebond = u;
// 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_thr(this,i1,i2,nlocal,NEWTON_BOND,
ebond,fbond,delx,dely,delz,thr);
}
}
diff --git a/src/USER-OMP/dihedral_charmm_omp.cpp b/src/USER-OMP/dihedral_charmm_omp.cpp
index fbebfbaaa..b069af43c 100644
--- a/src/USER-OMP/dihedral_charmm_omp.cpp
+++ b/src/USER-OMP/dihedral_charmm_omp.cpp
@@ -1,327 +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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "dihedral_charmm_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "pair.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
DihedralCharmmOMP::DihedralCharmmOMP(class LAMMPS *lmp)
: DihedralCharmm(lmp), ThrOMP(lmp,THR_DIHEDRAL|THR_CHARMM)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void DihedralCharmmOMP::compute(int eflag, int vflag)
{
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;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void DihedralCharmmOMP::eval(int nfrom, int nto, ThrData * const thr)
{
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 = 0.0;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const double * const q = atom->q;
const int * const atomtype = atom->type;
const int * const * const dihedrallist = neighbor->dihedrallist;
const double qqrd2e = force->qqrd2e;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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 = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
ddf1 = 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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
// 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) ev_tally_thr(force->pair,i1,i4,nlocal,NEWTON_BOND,
evdwl,ecoul,fpair,delx,dely,delz,thr);
}
}
}
diff --git a/src/USER-OMP/dihedral_class2_omp.cpp b/src/USER-OMP/dihedral_class2_omp.cpp
index 0d150851c..d21c2869e 100644
--- a/src/USER-OMP/dihedral_class2_omp.cpp
+++ b/src/USER-OMP/dihedral_class2_omp.cpp
@@ -1,535 +1,531 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "dihedral_class2_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.0000001
/* ---------------------------------------------------------------------- */
DihedralClass2OMP::DihedralClass2OMP(class LAMMPS *lmp)
: DihedralClass2(lmp), ThrOMP(lmp,THR_DIHEDRAL)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void DihedralClass2OMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void DihedralClass2OMP::eval(int nfrom, int nto, ThrData * const thr)
{
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;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const dihedrallist = neighbor->dihedrallist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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 = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,
fabcd[0],fabcd[2],fabcd[3],
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp b/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp
index 15f4dd97c..ecb1a85fa 100644
--- a/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp
+++ b/src/USER-OMP/dihedral_cosine_shift_exp_omp.cpp
@@ -1,266 +1,262 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "dihedral_cosine_shift_exp_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
DihedralCosineShiftExpOMP::DihedralCosineShiftExpOMP(class LAMMPS *lmp)
: DihedralCosineShiftExp(lmp), ThrOMP(lmp,THR_DIHEDRAL)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void DihedralCosineShiftExpOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void DihedralCosineShiftExpOMP::eval(int nfrom, int nto, ThrData * const thr)
{
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 ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv;
double df,fg,hg,fga,hgb,gaa,gbb;
double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz;
double c,s,sx2,sy2,sz2;
double cccpsss,cssmscc,exp2;
edihedral = 0.0;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const dihedrallist = neighbor->dihedrallist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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 = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
double aa=a[type];
double uumin=umin[type];
cccpsss = c*cost[type]+s*sint[type];
cssmscc = c*sint[type]-s*cost[type];
if (doExpansion[type]) {
// |a|<0.001 so use expansions relative precision <1e-5
if (EFLAG) edihedral = -0.125*(1+cccpsss)*(4+aa*(cccpsss-1))*uumin;
df=0.5*uumin*( cssmscc + 0.5*aa*cccpsss);
} else {
exp2=exp(0.5*aa*(1+cccpsss));
if (EFLAG) edihedral = opt1[type]*(1-exp2);
df= 0.5*opt1[type]*aa* ( exp2*cssmscc );
}
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;
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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/dihedral_harmonic_omp.cpp b/src/USER-OMP/dihedral_harmonic_omp.cpp
index 11023ee36..e3b94c8f9 100644
--- a/src/USER-OMP/dihedral_harmonic_omp.cpp
+++ b/src/USER-OMP/dihedral_harmonic_omp.cpp
@@ -1,273 +1,269 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "dihedral_harmonic_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
DihedralHarmonicOMP::DihedralHarmonicOMP(class LAMMPS *lmp)
: DihedralHarmonic(lmp), ThrOMP(lmp,THR_DIHEDRAL)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void DihedralHarmonicOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void DihedralHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr)
{
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;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const dihedrallist = neighbor->dihedrallist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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 = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
ddf1 = 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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/dihedral_helix_omp.cpp b/src/USER-OMP/dihedral_helix_omp.cpp
index a869367bd..fd7025cdb 100644
--- a/src/USER-OMP/dihedral_helix_omp.cpp
+++ b/src/USER-OMP/dihedral_helix_omp.cpp
@@ -1,286 +1,282 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "dihedral_helix_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "math_const.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define TOLERANCE 0.05
#define SMALL 0.001
#define SMALLER 0.00001
/* ---------------------------------------------------------------------- */
DihedralHelixOMP::DihedralHelixOMP(class LAMMPS *lmp)
: DihedralHelix(lmp), ThrOMP(lmp,THR_DIHEDRAL)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void DihedralHelixOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void DihedralHelixOMP::eval(int nfrom, int nto, ThrData * const thr)
{
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,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;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const dihedrallist = neighbor->dihedrallist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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 = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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;
pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv +
cphi[type]*sin(phi + MY_PI4)*siinv;
if (EFLAG) edihedral = aphi[type]*(1.0 - c) + bphi[type]*(1.0 + cos(3.0*phi)) +
cphi[type]*(1.0 + cos(phi + MY_PI4));
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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
index a40bdba95..a68bebfdf 100644
--- a/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
+++ b/src/USER-OMP/dihedral_multi_harmonic_omp.cpp
@@ -1,273 +1,269 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "dihedral_multi_harmonic_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
DihedralMultiHarmonicOMP::DihedralMultiHarmonicOMP(class LAMMPS *lmp)
: DihedralMultiHarmonic(lmp), ThrOMP(lmp,THR_DIHEDRAL)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void DihedralMultiHarmonicOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void DihedralMultiHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr)
{
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,pd,a,a11,a22;
double a33,a12,a13,a23,sx2,sy2,sz2;
double s2,sin2;
edihedral = 0.0;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const dihedrallist = neighbor->dihedrallist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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 = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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 = sum (i=1,5) a_i * c**(i-1)
// pd = dp/dc
pd = a2[type] + c*(2.0*a3[type] + c*(3.0*a4[type] + c*4.0*a5[type]));
if (EFLAG)
edihedral = a1[type] + c*(a2[type] + c*(a3[type] + c*(a4[type] + c*a5[type])));
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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/dihedral_opls_omp.cpp b/src/USER-OMP/dihedral_opls_omp.cpp
index 30b805611..3810dc198 100644
--- a/src/USER-OMP/dihedral_opls_omp.cpp
+++ b/src/USER-OMP/dihedral_opls_omp.cpp
@@ -1,289 +1,285 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "dihedral_opls_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
#define SMALLER 0.00001
/* ---------------------------------------------------------------------- */
DihedralOPLSOMP::DihedralOPLSOMP(class LAMMPS *lmp)
: DihedralOPLS(lmp), ThrOMP(lmp,THR_DIHEDRAL)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void DihedralOPLSOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->ndihedrallist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void DihedralOPLSOMP::eval(int nfrom, int nto, ThrData * const thr)
{
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,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;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const dihedrallist = neighbor->dihedrallist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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 = comm->me;
if (screen) {
char str[128];
sprintf(str,"Dihedral problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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 = 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;
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 = 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));
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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,edihedral,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/improper_class2_omp.cpp b/src/USER-OMP/improper_class2_omp.cpp
index 0a4758f55..08f4a21e0 100644
--- a/src/USER-OMP/improper_class2_omp.cpp
+++ b/src/USER-OMP/improper_class2_omp.cpp
@@ -1,704 +1,698 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "improper_class2_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
ImproperClass2OMP::ImproperClass2OMP(class LAMMPS *lmp)
: ImproperClass2(lmp), ThrOMP(lmp,THR_IMPROPER)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void ImproperClass2OMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nimproperlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void ImproperClass2OMP::eval(int nfrom, int nto, ThrData * const thr)
{
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;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const improperlist = neighbor->improperlist;
const int nlocal = atom->nlocal;
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;
}
for (n = nfrom; n < nto; 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 = comm->me;
if (screen) {
char str[128];
sprintf(str,
"Improper problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me, thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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
ddelr[0][0] = 1.0;
ddelr[0][1] = -1.0;
ddelr[0][2] = 0.0;
ddelr[0][3] = 0.0;
ddelr[1][0] = 0.0;
ddelr[1][1] = -1.0;
ddelr[1][2] = 1.0;
ddelr[1][3] = 0.0;
ddelr[2][0] = 0.0;
ddelr[2][1] = -1.0;
ddelr[2][2] = 0.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_thr(this,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],thr);
}
// compute angle-angle interactions
angleangle_thr<EVFLAG, EFLAG, NEWTON_BOND>(nfrom,nto,thr);
}
/* ----------------------------------------------------------------------
angle-angle interactions within improper
------------------------------------------------------------------------- */
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void ImproperClass2OMP::angleangle_thr(int nfrom, int nto, ThrData * const thr)
{
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];
eimproper = 0.0;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const improperlist = neighbor->improperlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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];
dthABD = thetaABD - aa_theta0_2[type];
dthCBD = thetaCBD - 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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,eimproper,
fabcd[0],fabcd[2],fabcd[3],delxAB,delyAB,delzAB,
delxBC,delyBC,delzBC,delxBD,delyBD,delzBD,thr);
}
}
diff --git a/src/USER-OMP/improper_cossq_omp.cpp b/src/USER-OMP/improper_cossq_omp.cpp
index 1e1b53eaf..c49cd0b3c 100644
--- a/src/USER-OMP/improper_cossq_omp.cpp
+++ b/src/USER-OMP/improper_cossq_omp.cpp
@@ -1,270 +1,267 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "improper_cossq_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
ImproperCossqOMP::ImproperCossqOMP(class LAMMPS *lmp)
: ImproperCossq(lmp), ThrOMP(lmp,THR_IMPROPER)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void ImproperCossqOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nimproperlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void ImproperCossqOMP::eval(int nfrom, int nto, ThrData * const thr)
{
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 rjisq, rji, rlksq, rlk, cosphi, angfac;
double cjiji, clkji, clklk, cfact1, cfact2, cfact3;
eimproper = 0.0;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const improperlist = neighbor->improperlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; n++) {
i1 = improperlist[n][0];
i2 = improperlist[n][1];
i3 = improperlist[n][2];
i4 = improperlist[n][3];
type = improperlist[n][4];
/* separation vector between i1 and i2, (i2-i1) */
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);
rjisq = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z ;
rji = sqrt(rjisq);
/* separation vector between i2 and i3 (i3-i2) */
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);
/* separation vector between i3 and i4, (i4-i3) */
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);
rlksq = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z ;
rlk = sqrt(rlksq);
cosphi = (vb3x*vb1x + vb3y*vb1y + vb3z*vb1z)/(rji * rlk);
/* Check that cos(phi) is in the correct limits. */
if (cosphi > 1.0 + TOLERANCE || cosphi < (-1.0 - TOLERANCE)) {
int me = comm->me;
if (screen) {
char str[128];
sprintf(str,"Improper problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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]);
}
/* Apply corrections to round-off errors. */
if (cosphi > 1.0) cosphi -= SMALL;
if (cosphi < -1.0) cosphi += SMALL;
/* Calculate the angle: */
double torangle = acos(cosphi);
cosphi = cos(torangle - chi[type]);
if (EFLAG) eimproper = 0.5 * k[type] * cosphi * cosphi;
/*
printf("The tags: %d-%d-%d-%d, of type %d .\n",atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4],type);
printf("The ji vector: %f, %f, %f.\nThe lk vector: %f, %f, %f.\n", vb1x,vb1y,vb1z,vb3x,vb3y,vb3z);
printf("The cosine of the angle: %-1.16e.\n", cosphi);
printf("The energy of the improper: %-1.16e with prefactor %-1.16e.\n", eimproper, 0.5*k[type]);
*/
/* Work out forces. */
angfac = - k[type] * cosphi;
cjiji = rjisq;
clklk = rlksq;
/*CLKJI = RXLK * RXJI + RYLK * RYJI + RZLK * RZJI */
clkji = vb3x*vb1x + vb3y*vb1y + vb3z*vb1z;
/*CFACT1 = CLKLK * CJIJI
CFACT1 = SQRT(CFACT1)
CFACT1 = ANGFAC / CFACT1*/
cfact1 = angfac / sqrt(clklk * cjiji);
/*CFACT2 = CLKJI / CLKLK*/
cfact2 = clkji / clklk;
/*CFACT3 = CLKJI / CJIJI*/
cfact3 = clkji / cjiji;
/*FIX = -RXLK + CFACT3 * RXJI
FIY = -RYLK + CFACT3 * RYJI
FIZ = -RZLK + CFACT3 * RZJI*/
f1[0] = - vb3x + cfact3 * vb1x;
f1[1] = - vb3y + cfact3 * vb1y;
f1[2] = - vb3z + cfact3 * vb1z;
/*FJX = -FIX
FJY = -FIY
FJZ = -FIZ*/
f2[0] = - f1[0];
f2[1] = - f1[1];
f2[2] = - f1[2];
/*FKX = CFACT2 * RXLK - RXJI
FKY = CFACT2 * RYLK - RYJI
FKZ = CFACT2 * RZLK - RZJI*/
f3[0] = cfact2 * vb3x - vb1x;
f3[1] = cfact2 * vb3y - vb1y;
f3[2] = cfact2 * vb3z - vb1z;
/*FLX = -FKX
FLY = -FKY
FLZ = -FKZ*/
f4[0] = - f3[0];
f4[1] = - f3[1];
f4[2] = - f3[2];
/*FIX = FIX * CFACT1
FIY = FIY * CFACT1
FIZ = FIZ * CFACT1*/
f1[0] *= cfact1;
f1[1] *= cfact1;
f1[2] *= cfact1;
/*FJX = FJX * CFACT1
FJY = FJY * CFACT1
FJZ = FJZ * CFACT1*/
f2[0] *= cfact1;
f2[1] *= cfact1;
f2[2] *= cfact1;
/*FKX = FKX * CFACT1
FKY = FKY * CFACT1
FKZ = FKZ * CFACT1*/
f3[0] *= cfact1;
f3[1] *= cfact1;
f3[2] *= cfact1;
/*FLX = FLX * CFACT1
FLY = FLY * CFACT1
FLZ = FLZ * CFACT1*/
f4[0] *= cfact1;
f4[1] *= cfact1;
f4[2] *= cfact1;
/* 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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,eimproper,f1,f3,f4,
-vb1x,-vb1y,-vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
}
diff --git a/src/USER-OMP/improper_cvff_omp.cpp b/src/USER-OMP/improper_cvff_omp.cpp
index fd8b4aca1..819a22b66 100644
--- a/src/USER-OMP/improper_cvff_omp.cpp
+++ b/src/USER-OMP/improper_cvff_omp.cpp
@@ -1,302 +1,298 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "improper_cvff_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
ImproperCvffOMP::ImproperCvffOMP(class LAMMPS *lmp)
: ImproperCvff(lmp), ThrOMP(lmp,THR_IMPROPER)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void ImproperCvffOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nimproperlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void ImproperCvffOMP::eval(int nfrom, int nto, ThrData * const thr)
{
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;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const improperlist = neighbor->improperlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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 = comm->me;
if (screen) {
char str[128];
sprintf(str,"Improper problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,eimproper,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/improper_harmonic_omp.cpp b/src/USER-OMP/improper_harmonic_omp.cpp
index 77f1a1c59..4ac8351a8 100644
--- a/src/USER-OMP/improper_harmonic_omp.cpp
+++ b/src/USER-OMP/improper_harmonic_omp.cpp
@@ -1,243 +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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "improper_harmonic_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
ImproperHarmonicOMP::ImproperHarmonicOMP(class LAMMPS *lmp)
: ImproperHarmonic(lmp), ThrOMP(lmp,THR_IMPROPER)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void ImproperHarmonicOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nimproperlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void ImproperHarmonicOMP::eval(int nfrom, int nto, ThrData * const thr)
{
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;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const improperlist = neighbor->improperlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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 = comm->me;
if (screen) {
char str[128];
sprintf(str,"Improper problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,eimproper,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/improper_ring_omp.cpp b/src/USER-OMP/improper_ring_omp.cpp
index 6f8a73c41..78b15a045 100644
--- a/src/USER-OMP/improper_ring_omp.cpp
+++ b/src/USER-OMP/improper_ring_omp.cpp
@@ -1,266 +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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "improper_ring_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
ImproperRingOMP::ImproperRingOMP(class LAMMPS *lmp)
: ImproperRing(lmp), ThrOMP(lmp,THR_IMPROPER)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void ImproperRingOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nimproperlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void ImproperRingOMP::eval(int nfrom, int nto, ThrData * const thr)
{
/* Be careful!: "chi" is the equilibrium angle in radians. */
int i1,i2,i3,i4,n,type;
double eimproper;
/* Compatibility variables. */
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z;
double f1[3], f3[3], f4[3];
/* Actual computation variables. */
int at1[3], at2[3], at3[3], icomb;
double bvec1x[3], bvec1y[3], bvec1z[3],
bvec2x[3], bvec2y[3], bvec2z[3],
bvec1n[3], bvec2n[3], bend_angle[3];
double angle_summer, angfac, cfact1, cfact2, cfact3;
double cjiji, ckjji, ckjkj, fix, fiy, fiz, fjx, fjy, fjz, fkx, fky, fkz;
eimproper = 0.0;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const improperlist = neighbor->improperlist;
const int nlocal = atom->nlocal;
/* A description of the potential can be found in
Macromolecules 35, pp. 1463-1472 (2002). */
for (n = nfrom; n < nto; n++) {
/* Take the ids of the atoms contributing to the improper potential. */
i1 = improperlist[n][0]; /* Atom "1" of Figure 1 from the above reference.*/
i2 = improperlist[n][1]; /* Atom "2" ... */
i3 = improperlist[n][2]; /* Atom "3" ... */
i4 = improperlist[n][3]; /* Atom "9" ... */
type = improperlist[n][4];
/* Calculate the necessary variables for LAMMPS implementation.
if (evflag) ev_tally(i1,i2,i3,i4,nlocal,newton_bond,eimproper,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
Although, they are irrelevant to the calculation of the potential, we keep
them for maximal compatibility. */
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);
/* Pass the atom tags to form the necessary combinations. */
at1[0] = i1; at2[0] = i2; at3[0] = i4; /* ids: 1-2-9 */
at1[1] = i1; at2[1] = i2; at3[1] = i3; /* ids: 1-2-3 */
at1[2] = i4; at2[2] = i2; at3[2] = i3; /* ids: 9-2-3 */
/* Initialize the sum of the angles differences. */
angle_summer = 0.0;
/* Take a loop over the three angles, defined by each triad: */
for (icomb = 0; icomb < 3; icomb ++) {
/* Bond vector connecting the first and the second atom. */
bvec1x[icomb] = x[at2[icomb]][0] - x[at1[icomb]][0];
bvec1y[icomb] = x[at2[icomb]][1] - x[at1[icomb]][1];
bvec1z[icomb] = x[at2[icomb]][2] - x[at1[icomb]][2];
- domain -> minimum_image(bvec1x[icomb], bvec1y[icomb], bvec1z[icomb]);
/* also calculate the norm of the vector: */
bvec1n[icomb] = sqrt( bvec1x[icomb]*bvec1x[icomb]
+ bvec1y[icomb]*bvec1y[icomb]
+ bvec1z[icomb]*bvec1z[icomb]);
/* Bond vector connecting the second and the third atom. */
bvec2x[icomb] = x[at3[icomb]][0] - x[at2[icomb]][0];
bvec2y[icomb] = x[at3[icomb]][1] - x[at2[icomb]][1];
bvec2z[icomb] = x[at3[icomb]][2] - x[at2[icomb]][2];
- domain -> minimum_image(bvec2x[icomb], bvec2y[icomb], bvec2z[icomb]);
/* also calculate the norm of the vector: */
bvec2n[icomb] = sqrt( bvec2x[icomb]*bvec2x[icomb]
+ bvec2y[icomb]*bvec2y[icomb]
+ bvec2z[icomb]*bvec2z[icomb]);
/* Calculate the bending angle of the atom triad: */
bend_angle[icomb] = ( bvec2x[icomb]*bvec1x[icomb]
+ bvec2y[icomb]*bvec1y[icomb]
+ bvec2z[icomb]*bvec1z[icomb]);
bend_angle[icomb] /= (bvec1n[icomb] * bvec2n[icomb]);
if (bend_angle[icomb] > 1.0) bend_angle[icomb] -= SMALL;
if (bend_angle[icomb] < -1.0) bend_angle[icomb] += SMALL;
/* Append the current angle to the sum of angle differences. */
angle_summer += (bend_angle[icomb] - chi[type]);
}
if (EFLAG) eimproper = (1.0/6.0) *k[type] * pow(angle_summer,6.0);
/*
printf("The tags: %d-%d-%d-%d, of type %d .\n",atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4],type);
// printf("The coordinates of the first: %f, %f, %f.\n", x[i1][0], x[i1][1], x[i1][2]);
// printf("The coordinates of the second: %f, %f, %f.\n", x[i2][0], x[i2][1], x[i2][2]);
// printf("The coordinates of the third: %f, %f, %f.\n", x[i3][0], x[i3][1], x[i3][2]);
// printf("The coordinates of the fourth: %f, %f, %f.\n", x[i4][0], x[i4][1], x[i4][2]);
printf("The angles are: %f / %f / %f equilibrium: %f.\n", bend_angle[0], bend_angle[1], bend_angle[2],chi[type]);
printf("The energy of the improper: %f with prefactor %f.\n", eimproper,(1.0/6.0)*k[type]);
printf("The sum of the angles: %f.\n", angle_summer);
*/
/* Force calculation acting on all atoms.
Calculate the derivatives of the potential. */
angfac = k[type] * pow(angle_summer,5.0);
f1[0] = 0.0; f1[1] = 0.0; f1[2] = 0.0;
f3[0] = 0.0; f3[1] = 0.0; f3[2] = 0.0;
f4[0] = 0.0; f4[1] = 0.0; f4[2] = 0.0;
/* Take a loop over the three angles, defined by each triad: */
for (icomb = 0; icomb < 3; icomb ++)
{
/* Calculate the squares of the distances. */
cjiji = bvec1n[icomb] * bvec1n[icomb]; ckjkj = bvec2n[icomb] * bvec2n[icomb];
ckjji = bvec2x[icomb] * bvec1x[icomb]
+ bvec2y[icomb] * bvec1y[icomb]
+ bvec2z[icomb] * bvec1z[icomb] ;
cfact1 = angfac / (sqrt(ckjkj * cjiji));
cfact2 = ckjji / ckjkj;
cfact3 = ckjji / cjiji;
/* Calculate the force acted on the thrid atom of the angle. */
fkx = cfact2 * bvec2x[icomb] - bvec1x[icomb];
fky = cfact2 * bvec2y[icomb] - bvec1y[icomb];
fkz = cfact2 * bvec2z[icomb] - bvec1z[icomb];
/* Calculate the force acted on the first atom of the angle. */
fix = bvec2x[icomb] - cfact3 * bvec1x[icomb];
fiy = bvec2y[icomb] - cfact3 * bvec1y[icomb];
fiz = bvec2z[icomb] - cfact3 * bvec1z[icomb];
/* Finally, calculate the force acted on the middle atom of the angle.*/
fjx = - fix - fkx; fjy = - fiy - fky; fjz = - fiz - fkz;
/* Consider the appropriate scaling of the forces: */
fix *= cfact1; fiy *= cfact1; fiz *= cfact1;
fjx *= cfact1; fjy *= cfact1; fjz *= cfact1;
fkx *= cfact1; fky *= cfact1; fkz *= cfact1;
if (at1[icomb] == i1) {f1[0] += fix; f1[1] += fiy; f1[2] += fiz;}
else if (at2[icomb] == i1) {f1[0] += fjx; f1[1] += fjy; f1[2] += fjz;}
else if (at3[icomb] == i1) {f1[0] += fkx; f1[1] += fky; f1[2] += fkz;}
if (at1[icomb] == i3) {f3[0] += fix; f3[1] += fiy; f3[2] += fiz;}
else if (at2[icomb] == i3) {f3[0] += fjx; f3[1] += fjy; f3[2] += fjz;}
else if (at3[icomb] == i3) {f3[0] += fkx; f3[1] += fky; f3[2] += fkz;}
if (at1[icomb] == i4) {f4[0] += fix; f4[1] += fiy; f4[2] += fiz;}
else if (at2[icomb] == i4) {f4[0] += fjx; f4[1] += fjy; f4[2] += fjz;}
else if (at3[icomb] == i4) {f4[0] += fkx; f4[1] += fky; f4[2] += fkz;}
/* Store the contribution to the global arrays: */
/* Take the id of the atom from the at1[icomb] element, i1 = at1[icomb]. */
if (NEWTON_BOND || at1[icomb] < nlocal) {
f[at1[icomb]][0] += fix;
f[at1[icomb]][1] += fiy;
f[at1[icomb]][2] += fiz;
}
/* Take the id of the atom from the at2[icomb] element, i2 = at2[icomb]. */
if (NEWTON_BOND || at2[icomb] < nlocal) {
f[at2[icomb]][0] += fjx;
f[at2[icomb]][1] += fjy;
f[at2[icomb]][2] += fjz;
}
/* Take the id of the atom from the at3[icomb] element, i3 = at3[icomb]. */
if (NEWTON_BOND || at3[icomb] < nlocal) {
f[at3[icomb]][0] += fkx;
f[at3[icomb]][1] += fky;
f[at3[icomb]][2] += fkz;
}
}
if (EVFLAG)
ev_tally_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,eimproper,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-OMP/improper_umbrella_omp.cpp b/src/USER-OMP/improper_umbrella_omp.cpp
index ebc1fc299..9a64da1fb 100644
--- a/src/USER-OMP/improper_umbrella_omp.cpp
+++ b/src/USER-OMP/improper_umbrella_omp.cpp
@@ -1,259 +1,256 @@
/* ----------------------------------------------------------------------
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: Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#include "math.h"
#include "improper_umbrella_omp.h"
#include "atom.h"
#include "comm.h"
#include "neighbor.h"
#include "domain.h"
#include "force.h"
#include "update.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
#define TOLERANCE 0.05
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
ImproperUmbrellaOMP::ImproperUmbrellaOMP(class LAMMPS *lmp)
: ImproperUmbrella(lmp), ThrOMP(lmp,THR_IMPROPER)
{
suffix_flag |= Suffix::OMP;
}
/* ---------------------------------------------------------------------- */
void ImproperUmbrellaOMP::compute(int eflag, int vflag)
{
if (eflag || vflag) {
ev_setup(eflag,vflag);
} else evflag = 0;
const int nall = atom->nlocal + atom->nghost;
const int nthreads = comm->nthreads;
const int inum = neighbor->nimproperlist;
#if defined(_OPENMP)
#pragma omp parallel default(none) shared(eflag,vflag)
#endif
{
int ifrom, ito, tid;
loop_setup_thr(ifrom, ito, tid, inum, nthreads);
ThrData *thr = fix->get_thr(tid);
ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
if (evflag) {
if (eflag) {
if (force->newton_bond) eval<1,1,1>(ifrom, ito, thr);
else eval<1,1,0>(ifrom, ito, thr);
} else {
if (force->newton_bond) eval<1,0,1>(ifrom, ito, thr);
else eval<1,0,0>(ifrom, ito, thr);
}
} else {
if (force->newton_bond) eval<0,0,1>(ifrom, ito, thr);
else eval<0,0,0>(ifrom, ito, thr);
}
reduce_thr(this, eflag, vflag, thr);
} // end of omp parallel region
}
template <int EVFLAG, int EFLAG, int NEWTON_BOND>
void ImproperUmbrellaOMP::eval(int nfrom, int nto, ThrData * const thr)
{
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;
const double * const * const x = atom->x;
double * const * const f = thr->get_f();
const int * const * const improperlist = neighbor->improperlist;
const int nlocal = atom->nlocal;
for (n = nfrom; n < nto; 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 = comm->me;
if (screen) {
char str[128];
sprintf(str,"Improper problem: %d/%d " BIGINT_FORMAT " %d %d %d %d",
me,thr->get_tid(),update->ntimestep,
atom->tag[i1],atom->tag[i2],atom->tag[i3],atom->tag[i4]);
error->warning(FLERR,str,0);
fprintf(screen," 1st atom: %d %g %g %g\n",
me,x[i1][0],x[i1][1],x[i1][2]);
fprintf(screen," 2nd atom: %d %g %g %g\n",
me,x[i2][0],x[i2][1],x[i2][2]);
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_thr(this,i1,i2,i3,i4,nlocal,NEWTON_BOND,eimproper,f1,f3,f4,
vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,thr);
}
}
diff --git a/src/USER-SPH/atom_vec_meso.cpp b/src/USER-SPH/atom_vec_meso.cpp
index 4bf403dae..6ca52f0f8 100644
--- a/src/USER-SPH/atom_vec_meso.cpp
+++ b/src/USER-SPH/atom_vec_meso.cpp
@@ -1,869 +1,870 @@
/* ----------------------------------------------------------------------
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_meso.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define DELTA 10000
/* ---------------------------------------------------------------------- */
AtomVecMeso::AtomVecMeso(LAMMPS *lmp, int narg, char **arg) :
- AtomVec(lmp, narg, arg) {
- molecular = 0;
- mass_type = 1;
-
- comm_x_only = 0; // we communicate not only x forward but also vest ...
- comm_f_only = 0; // we also communicate de and drho in reverse direction
- size_forward = 8; // 3 + rho + e + vest[3], that means we may only communicate 5 in hybrid
- size_reverse = 5; // 3 + drho + de
- size_border = 12; // 6 + rho + e + vest[3] + cv
- size_velocity = 3;
- size_data_atom = 8;
- size_data_vel = 4;
- xcol_data = 6;
-
- atom->e_flag = 1;
- atom->rho_flag = 1;
- atom->cv_flag = 1;
- atom->vest_flag = 1;
+ AtomVec(lmp, narg, arg) {
+ molecular = 0;
+ mass_type = 1;
+
+ comm_x_only = 0; // we communicate not only x forward but also vest ...
+ comm_f_only = 0; // we also communicate de and drho in reverse direction
+ size_forward = 8; // 3 + rho + e + vest[3], that means we may only communicate 5 in hybrid
+ size_reverse = 5; // 3 + drho + de
+ size_border = 12; // 6 + rho + e + vest[3] + cv
+ size_velocity = 3;
+ size_data_atom = 8;
+ size_data_vel = 4;
+ xcol_data = 6;
+
+ atom->e_flag = 1;
+ atom->rho_flag = 1;
+ atom->cv_flag = 1;
+ atom->vest_flag = 1;
}
/* ----------------------------------------------------------------------
- grow atom arrays
- n = 0 grows arrays by DELTA
- n > 0 allocates arrays to size n
- ------------------------------------------------------------------------- */
+ grow atom arrays
+ n = 0 grows arrays by DELTA
+ n > 0 allocates arrays to size n
+ ------------------------------------------------------------------------- */
void AtomVecMeso::grow(int n) {
- if (n == 0)
- nmax += DELTA;
- else
- nmax = n;
- atom->nmax = nmax;
- if (nmax < 0 || nmax > MAXSMALLINT)
- error->one(FLERR,"Per-processor system is too big");
-
- tag = memory->grow(atom->tag, nmax, "atom:tag");
- type = memory->grow(atom->type, nmax, "atom:type");
- mask = memory->grow(atom->mask, nmax, "atom:mask");
- image = memory->grow(atom->image, nmax, "atom:image");
- x = memory->grow(atom->x, nmax, 3, "atom:x");
- v = memory->grow(atom->v, nmax, 3, "atom:v");
- f = memory->grow(atom->f, nmax*comm->nthreads, 3, "atom:f");
-
- rho = memory->grow(atom->rho, nmax, "atom:rho");
- drho = memory->grow(atom->drho, nmax*comm->nthreads, "atom:drho");
- e = memory->grow(atom->e, nmax, "atom:e");
- de = memory->grow(atom->de, nmax*comm->nthreads, "atom:de");
- vest = memory->grow(atom->vest, nmax, 3, "atom:vest");
- cv = memory->grow(atom->cv, nmax, "atom:cv");
-
- if (atom->nextra_grow)
- for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
- modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
+ if (n == 0)
+ nmax += DELTA;
+ else
+ nmax = n;
+ atom->nmax = nmax;
+ if (nmax < 0 || nmax > MAXSMALLINT)
+ error->one(FLERR,"Per-processor system is too big");
+
+ tag = memory->grow(atom->tag, nmax, "atom:tag");
+ type = memory->grow(atom->type, nmax, "atom:type");
+ mask = memory->grow(atom->mask, nmax, "atom:mask");
+ image = memory->grow(atom->image, nmax, "atom:image");
+ x = memory->grow(atom->x, nmax, 3, "atom:x");
+ v = memory->grow(atom->v, nmax, 3, "atom:v");
+ f = memory->grow(atom->f, nmax*comm->nthreads, 3, "atom:f");
+
+ rho = memory->grow(atom->rho, nmax, "atom:rho");
+ drho = memory->grow(atom->drho, nmax*comm->nthreads, "atom:drho");
+ e = memory->grow(atom->e, nmax, "atom:e");
+ de = memory->grow(atom->de, nmax*comm->nthreads, "atom:de");
+ vest = memory->grow(atom->vest, nmax, 3, "atom:vest");
+ cv = memory->grow(atom->cv, nmax, "atom:cv");
+
+ 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
- ------------------------------------------------------------------------- */
+ reset local array ptrs
+ ------------------------------------------------------------------------- */
void AtomVecMeso::grow_reset() {
- tag = atom->tag;
- type = atom->type;
- mask = atom->mask;
- image = atom->image;
- x = atom->x;
- v = atom->v;
- f = atom->f;
- rho = atom->rho;
- drho = atom->drho;
- e = atom->e;
- de = atom->de;
- vest = atom->vest;
- cv = atom->cv;
+ tag = atom->tag;
+ type = atom->type;
+ mask = atom->mask;
+ image = atom->image;
+ x = atom->x;
+ v = atom->v;
+ f = atom->f;
+ rho = atom->rho;
+ drho = atom->drho;
+ e = atom->e;
+ de = atom->de;
+ vest = atom->vest;
+ cv = atom->cv;
}
/* ---------------------------------------------------------------------- */
void AtomVecMeso::copy(int i, int j, int delflag) {
- //printf("in AtomVecMeso::copy\n");
- 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];
-
- rho[j] = rho[i];
- drho[j] = drho[i];
- e[j] = e[i];
- de[j] = de[i];
- cv[j] = cv[i];
- vest[j][0] = vest[i][0];
- vest[j][1] = vest[i][1];
- vest[j][2] = vest[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);
+ //printf("in AtomVecMeso::copy\n");
+ 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];
+
+ rho[j] = rho[i];
+ drho[j] = drho[i];
+ e[j] = e[i];
+ de[j] = de[i];
+ cv[j] = cv[i];
+ vest[j][0] = vest[i][0];
+ vest[j][1] = vest[i][1];
+ vest[j][2] = vest[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 AtomVecMeso::pack_comm_hybrid(int n, int *list, double *buf) {
- //printf("in AtomVecMeso::pack_comm_hybrid\n");
- int i, j, m;
-
- m = 0;
- for (i = 0; i < n; i++) {
- j = list[i];
- buf[m++] = rho[j];
- buf[m++] = e[j];
- buf[m++] = vest[j][0];
- buf[m++] = vest[j][1];
- buf[m++] = vest[j][2];
- }
- return m;
+ //printf("in AtomVecMeso::pack_comm_hybrid\n");
+ int i, j, m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = rho[j];
+ buf[m++] = e[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecMeso::unpack_comm_hybrid(int n, int first, double *buf) {
- //printf("in AtomVecMeso::unpack_comm_hybrid\n");
- int i, m, last;
-
- m = 0;
- last = first + n;
- for (i = first; i < last; i++) {
- rho[i] = buf[m++];
- e[i] = buf[m++];
- vest[i][0] = buf[m++];
- vest[i][1] = buf[m++];
- vest[i][2] = buf[m++];
- }
- return m;
+ //printf("in AtomVecMeso::unpack_comm_hybrid\n");
+ int i, m, last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ rho[i] = buf[m++];
+ e[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+ return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecMeso::pack_border_hybrid(int n, int *list, double *buf) {
- //printf("in AtomVecMeso::pack_border_hybrid\n");
- int i, j, m;
-
- m = 0;
- for (i = 0; i < n; i++) {
- j = list[i];
- buf[m++] = rho[j];
- buf[m++] = e[j];
- buf[m++] = vest[j][0];
- buf[m++] = vest[j][1];
- buf[m++] = vest[j][2];
- }
- return m;
+ //printf("in AtomVecMeso::pack_border_hybrid\n");
+ int i, j, m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ buf[m++] = rho[j];
+ buf[m++] = e[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecMeso::unpack_border_hybrid(int n, int first, double *buf) {
- //printf("in AtomVecMeso::unpack_border_hybrid\n");
- int i, m, last;
-
- m = 0;
- last = first + n;
- for (i = first; i < last; i++) {
- rho[i] = buf[m++];
- e[i] = buf[m++];
- vest[i][0] = buf[m++];
- vest[i][1] = buf[m++];
- vest[i][2] = buf[m++];
- }
- return m;
+ //printf("in AtomVecMeso::unpack_border_hybrid\n");
+ int i, m, last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ rho[i] = buf[m++];
+ e[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
+ return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecMeso::pack_reverse_hybrid(int n, int first, double *buf) {
- //printf("in AtomVecMeso::pack_reverse_hybrid\n");
- int i, m, last;
-
- m = 0;
- last = first + n;
- for (i = first; i < last; i++) {
- buf[m++] = drho[i];
- buf[m++] = de[i];
- }
- return m;
+ //printf("in AtomVecMeso::pack_reverse_hybrid\n");
+ int i, m, last;
+
+ m = 0;
+ last = first + n;
+ for (i = first; i < last; i++) {
+ buf[m++] = drho[i];
+ buf[m++] = de[i];
+ }
+ return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecMeso::unpack_reverse_hybrid(int n, int *list, double *buf) {
- //printf("in AtomVecMeso::unpack_reverse_hybrid\n");
- int i, j, m;
-
- m = 0;
- for (i = 0; i < n; i++) {
- j = list[i];
- drho[j] += buf[m++];
- de[j] += buf[m++];
- }
- return m;
+ //printf("in AtomVecMeso::unpack_reverse_hybrid\n");
+ int i, j, m;
+
+ m = 0;
+ for (i = 0; i < n; i++) {
+ j = list[i];
+ drho[j] += buf[m++];
+ de[j] += buf[m++];
+ }
+ return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecMeso::pack_comm(int n, int *list, double *buf, int pbc_flag,
- int *pbc) {
- //printf("in AtomVecMeso::pack_comm\n");
- 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++] = rho[j];
- buf[m++] = e[j];
- buf[m++] = vest[j][0];
- buf[m++] = vest[j][1];
- buf[m++] = vest[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++] = rho[j];
- buf[m++] = e[j];
- buf[m++] = vest[j][0];
- buf[m++] = vest[j][1];
- buf[m++] = vest[j][2];
- }
- }
- return m;
+ int *pbc) {
+ //printf("in AtomVecMeso::pack_comm\n");
+ 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++] = rho[j];
+ buf[m++] = e[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[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++] = rho[j];
+ buf[m++] = e[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+ return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecMeso::pack_comm_vel(int n, int *list, double *buf, int pbc_flag,
- int *pbc) {
- //printf("in AtomVecMeso::pack_comm_vel\n");
- 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++] = rho[j];
- buf[m++] = e[j];
- buf[m++] = vest[j][0];
- buf[m++] = vest[j][1];
- buf[m++] = vest[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++] = rho[j];
- buf[m++] = e[j];
- buf[m++] = vest[j][0];
- buf[m++] = vest[j][1];
- buf[m++] = vest[j][2];
- }
- }
- return m;
+ int *pbc) {
+ //printf("in AtomVecMeso::pack_comm_vel\n");
+ 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++] = rho[j];
+ buf[m++] = e[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[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++] = rho[j];
+ buf[m++] = e[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+ return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecMeso::unpack_comm(int n, int first, double *buf) {
- //printf("in AtomVecMeso::unpack_comm\n");
- 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++];
- rho[i] = buf[m++];
- e[i] = buf[m++];
- vest[i][0] = buf[m++];
- vest[i][1] = buf[m++];
- vest[i][2] = buf[m++];
- }
+ //printf("in AtomVecMeso::unpack_comm\n");
+ 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++];
+ rho[i] = buf[m++];
+ e[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
}
/* ---------------------------------------------------------------------- */
void AtomVecMeso::unpack_comm_vel(int n, int first, double *buf) {
- //printf("in AtomVecMeso::unpack_comm_vel\n");
- 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++];
- rho[i] = buf[m++];
- e[i] = buf[m++];
- vest[i][0] = buf[m++];
- vest[i][1] = buf[m++];
- vest[i][2] = buf[m++];
- }
+ //printf("in AtomVecMeso::unpack_comm_vel\n");
+ 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++];
+ rho[i] = buf[m++];
+ e[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
}
/* ---------------------------------------------------------------------- */
int AtomVecMeso::pack_reverse(int n, int first, double *buf) {
- //printf("in AtomVecMeso::pack_reverse\n");
- 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++] = drho[i];
- buf[m++] = de[i];
- }
- return m;
+ //printf("in AtomVecMeso::pack_reverse\n");
+ 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++] = drho[i];
+ buf[m++] = de[i];
+ }
+ return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecMeso::unpack_reverse(int n, int *list, double *buf) {
- //printf("in AtomVecMeso::unpack_reverse\n");
- 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++];
- drho[j] += buf[m++];
- de[j] += buf[m++];
- }
+ //printf("in AtomVecMeso::unpack_reverse\n");
+ 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++];
+ drho[j] += buf[m++];
+ de[j] += buf[m++];
+ }
}
/* ---------------------------------------------------------------------- */
int AtomVecMeso::pack_border(int n, int *list, double *buf, int pbc_flag,
- int *pbc) {
- //printf("in AtomVecMeso::pack_border\n");
- 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++] = rho[j];
- buf[m++] = e[j];
- buf[m++] = cv[j];
- buf[m++] = vest[j][0];
- buf[m++] = vest[j][1];
- buf[m++] = vest[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++] = rho[j];
- buf[m++] = e[j];
- buf[m++] = cv[j];
- buf[m++] = vest[j][0];
- buf[m++] = vest[j][1];
- buf[m++] = vest[j][2];
- }
- }
- return m;
+ int *pbc) {
+ //printf("in AtomVecMeso::pack_border\n");
+ 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++] = rho[j];
+ buf[m++] = e[j];
+ buf[m++] = cv[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[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++] = rho[j];
+ buf[m++] = e[j];
+ buf[m++] = cv[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+ return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecMeso::pack_border_vel(int n, int *list, double *buf, int pbc_flag,
- int *pbc) {
- //printf("in AtomVecMeso::pack_border_vel\n");
- 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++] = rho[j];
- buf[m++] = e[j];
- buf[m++] = cv[j];
- buf[m++] = vest[j][0];
- buf[m++] = vest[j][1];
- buf[m++] = vest[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++] = rho[j];
- buf[m++] = e[j];
- buf[m++] = cv[j];
- buf[m++] = vest[j][0];
- buf[m++] = vest[j][1];
- buf[m++] = vest[j][2];
- }
- }
- return m;
+ int *pbc) {
+ //printf("in AtomVecMeso::pack_border_vel\n");
+ 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++] = rho[j];
+ buf[m++] = e[j];
+ buf[m++] = cv[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[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++] = rho[j];
+ buf[m++] = e[j];
+ buf[m++] = cv[j];
+ buf[m++] = vest[j][0];
+ buf[m++] = vest[j][1];
+ buf[m++] = vest[j][2];
+ }
+ }
+ return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecMeso::unpack_border(int n, int first, double *buf) {
- //printf("in AtomVecMeso::unpack_border\n");
- 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++]);
- rho[i] = buf[m++];
- e[i] = buf[m++];
- cv[i] = buf[m++];
- vest[i][0] = buf[m++];
- vest[i][1] = buf[m++];
- vest[i][2] = buf[m++];
- }
+ //printf("in AtomVecMeso::unpack_border\n");
+ 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++]);
+ rho[i] = buf[m++];
+ e[i] = buf[m++];
+ cv[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[i][2] = buf[m++];
+ }
}
/* ---------------------------------------------------------------------- */
void AtomVecMeso::unpack_border_vel(int n, int first, double *buf) {
- //printf("in AtomVecMeso::unpack_border_vel\n");
- 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++];
- rho[i] = buf[m++];
- e[i] = buf[m++];
- cv[i] = buf[m++];
- vest[i][0] = buf[m++];
- vest[i][1] = buf[m++];
- vest[i][2] = buf[m++];
- }
+ //printf("in AtomVecMeso::unpack_border_vel\n");
+ 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++];
+ rho[i] = buf[m++];
+ e[i] = buf[m++];
+ cv[i] = buf[m++];
+ vest[i][0] = buf[m++];
+ vest[i][1] = buf[m++];
+ vest[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
- ------------------------------------------------------------------------- */
+ pack data for atom I for sending to another proc
+ xyz must be 1st 3 values, so comm::exchange() can test on them
+ ------------------------------------------------------------------------- */
int AtomVecMeso::pack_exchange(int i, double *buf) {
- //printf("in AtomVecMeso::pack_exchange\n");
- 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++] = rho[i];
- buf[m++] = e[i];
- buf[m++] = cv[i];
- buf[m++] = vest[i][0];
- buf[m++] = vest[i][1];
- buf[m++] = vest[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;
+ //printf("in AtomVecMeso::pack_exchange\n");
+ 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];
+ *((tagint *) &buf[m++]) = image[i];
+ buf[m++] = rho[i];
+ buf[m++] = e[i];
+ buf[m++] = cv[i];
+ buf[m++] = vest[i][0];
+ buf[m++] = vest[i][1];
+ buf[m++] = vest[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 AtomVecMeso::unpack_exchange(double *buf) {
- //printf("in AtomVecMeso::unpack_exchange\n");
- 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++]);
- rho[nlocal] = buf[m++];
- e[nlocal] = buf[m++];
- cv[nlocal] = buf[m++];
- vest[nlocal][0] = buf[m++];
- vest[nlocal][1] = buf[m++];
- vest[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;
+ //printf("in AtomVecMeso::unpack_exchange\n");
+ 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] = *((tagint *) &buf[m++]);
+ rho[nlocal] = buf[m++];
+ e[nlocal] = buf[m++];
+ cv[nlocal] = buf[m++];
+ vest[nlocal][0] = buf[m++];
+ vest[nlocal][1] = buf[m++];
+ vest[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
- ------------------------------------------------------------------------- */
+ size of restart data for all atoms owned by this proc
+ include extra data stored by fixes
+ ------------------------------------------------------------------------- */
int AtomVecMeso::size_restart() {
- int i;
-
- int nlocal = atom->nlocal;
- int n = 17 * nlocal; // 11 + rho + e + cv + vest[3]
-
- 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;
+ int i;
+
+ int nlocal = atom->nlocal;
+ int n = 17 * nlocal; // 11 + rho + e + cv + vest[3]
+
+ 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
- ------------------------------------------------------------------------- */
+ 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 AtomVecMeso::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++] = rho[i];
- buf[m++] = e[i];
- buf[m++] = cv[i];
- buf[m++] = vest[i][0];
- buf[m++] = vest[i][1];
- buf[m++] = vest[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;
+ 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];
+ *((tagint *) &buf[m++]) = image[i];
+ buf[m++] = v[i][0];
+ buf[m++] = v[i][1];
+ buf[m++] = v[i][2];
+ buf[m++] = rho[i];
+ buf[m++] = e[i];
+ buf[m++] = cv[i];
+ buf[m++] = vest[i][0];
+ buf[m++] = vest[i][1];
+ buf[m++] = vest[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
- ------------------------------------------------------------------------- */
+ unpack data for one atom from restart file including extra quantities
+ ------------------------------------------------------------------------- */
int AtomVecMeso::unpack_restart(double *buf) {
- int nlocal = atom->nlocal;
- if (nlocal == nmax) {
- grow(0);
- if (atom->nextra_store)
- memory->grow(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++];
- rho[nlocal] = buf[m++];
- e[nlocal] = buf[m++];
- cv[nlocal] = buf[m++];
- vest[nlocal][0] = buf[m++];
- vest[nlocal][1] = buf[m++];
- vest[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;
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax) {
+ grow(0);
+ if (atom->nextra_store)
+ memory->grow(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] = *((tagint *) &buf[m++]);
+ v[nlocal][0] = buf[m++];
+ v[nlocal][1] = buf[m++];
+ v[nlocal][2] = buf[m++];
+ rho[nlocal] = buf[m++];
+ e[nlocal] = buf[m++];
+ cv[nlocal] = buf[m++];
+ vest[nlocal][0] = buf[m++];
+ vest[nlocal][1] = buf[m++];
+ vest[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
- ------------------------------------------------------------------------- */
+ create one atom of itype at coord
+ set other values to defaults
+ ------------------------------------------------------------------------- */
void AtomVecMeso::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;
- rho[nlocal] = 0.0;
- e[nlocal] = 0.0;
- cv[nlocal] = 1.0;
- vest[nlocal][0] = 0.0;
- vest[nlocal][1] = 0.0;
- vest[nlocal][2] = 0.0;
- de[nlocal] = 0.0;
- drho[nlocal] = 0.0;
-
- atom->nlocal++;
+ 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] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+ rho[nlocal] = 0.0;
+ e[nlocal] = 0.0;
+ cv[nlocal] = 1.0;
+ vest[nlocal][0] = 0.0;
+ vest[nlocal][1] = 0.0;
+ vest[nlocal][2] = 0.0;
+ de[nlocal] = 0.0;
+ drho[nlocal] = 0.0;
+
+ atom->nlocal++;
}
/* ----------------------------------------------------------------------
- unpack one line from Atoms section of data file
- initialize other atom quantities
- ------------------------------------------------------------------------- */
-
-void AtomVecMeso::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(FLERR,"Invalid atom ID in Atoms section of data file");
-
- type[nlocal] = atoi(values[1]);
- if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
- error->one(FLERR,"Invalid atom type in Atoms section of data file");
-
- rho[nlocal] = atof(values[2]);
- e[nlocal] = atof(values[3]);
- cv[nlocal] = atof(values[4]);
-
- x[nlocal][0] = coord[0];
- x[nlocal][1] = coord[1];
- x[nlocal][2] = coord[2];
-
- //printf("rho=%f, e=%f, cv=%f, x=%f\n", rho[nlocal], e[nlocal], cv[nlocal], x[nlocal][0]);
-
- image[nlocal] = imagetmp;
-
- mask[nlocal] = 1;
- v[nlocal][0] = 0.0;
- v[nlocal][1] = 0.0;
- v[nlocal][2] = 0.0;
-
- vest[nlocal][0] = 0.0;
- vest[nlocal][1] = 0.0;
- vest[nlocal][2] = 0.0;
-
- de[nlocal] = 0.0;
- drho[nlocal] = 0.0;
-
- atom->nlocal++;
+ unpack one line from Atoms section of data file
+ initialize other atom quantities
+ ------------------------------------------------------------------------- */
+
+void AtomVecMeso::data_atom(double *coord, tagint imagetmp, char **values) {
+ int nlocal = atom->nlocal;
+ if (nlocal == nmax)
+ grow(0);
+
+ tag[nlocal] = atoi(values[0]);
+ if (tag[nlocal] <= 0)
+ error->one(FLERR,"Invalid atom ID in Atoms section of data file");
+
+ type[nlocal] = atoi(values[1]);
+ if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
+ error->one(FLERR,"Invalid atom type in Atoms section of data file");
+
+ rho[nlocal] = atof(values[2]);
+ e[nlocal] = atof(values[3]);
+ cv[nlocal] = atof(values[4]);
+
+ x[nlocal][0] = coord[0];
+ x[nlocal][1] = coord[1];
+ x[nlocal][2] = coord[2];
+
+ //printf("rho=%f, e=%f, cv=%f, x=%f\n", rho[nlocal], e[nlocal], cv[nlocal], x[nlocal][0]);
+
+ image[nlocal] = imagetmp;
+
+ mask[nlocal] = 1;
+ v[nlocal][0] = 0.0;
+ v[nlocal][1] = 0.0;
+ v[nlocal][2] = 0.0;
+
+ vest[nlocal][0] = 0.0;
+ vest[nlocal][1] = 0.0;
+ vest[nlocal][2] = 0.0;
+
+ de[nlocal] = 0.0;
+ drho[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
- ------------------------------------------------------------------------- */
+ unpack hybrid quantities from one line in Atoms section of data file
+ initialize other atom quantities for this sub-style
+ ------------------------------------------------------------------------- */
int AtomVecMeso::data_atom_hybrid(int nlocal, char **values) {
-
- rho[nlocal] = atof(values[0]);
- e[nlocal] = atof(values[1]);
- cv[nlocal] = atof(values[2]);
-
- return 3;
+
+ rho[nlocal] = atof(values[0]);
+ e[nlocal] = atof(values[1]);
+ cv[nlocal] = atof(values[2]);
+
+ return 3;
}
/* ----------------------------------------------------------------------
- return # of bytes of allocated memory
- ------------------------------------------------------------------------- */
+ return # of bytes of allocated memory
+ ------------------------------------------------------------------------- */
bigint AtomVecMeso::memory_usage() {
- bigint bytes = 0;
-
- if (atom->memcheck("tag"))
- bytes += memory->usage(tag, nmax);
- if (atom->memcheck("type"))
- bytes += memory->usage(type, nmax);
- if (atom->memcheck("mask"))
- bytes += memory->usage(mask, nmax);
- if (atom->memcheck("image"))
- bytes += memory->usage(image, nmax);
- if (atom->memcheck("x"))
- bytes += memory->usage(x, nmax, 3);
- if (atom->memcheck("v"))
- bytes += memory->usage(v, nmax, 3);
- if (atom->memcheck("f"))
- bytes += memory->usage(f, nmax*comm->nthreads, 3);
- if (atom->memcheck("rho"))
- bytes += memory->usage(rho, nmax);
- if (atom->memcheck("drho"))
- bytes += memory->usage(drho, nmax*comm->nthreads);
- if (atom->memcheck("e"))
- bytes += memory->usage(e, nmax);
- if (atom->memcheck("de"))
- bytes += memory->usage(de, nmax*comm->nthreads);
- if (atom->memcheck("cv"))
- bytes += memory->usage(cv, nmax);
- if (atom->memcheck("vest"))
- bytes += memory->usage(vest, nmax);
-
- return bytes;
+ bigint bytes = 0;
+
+ if (atom->memcheck("tag"))
+ bytes += memory->usage(tag, nmax);
+ if (atom->memcheck("type"))
+ bytes += memory->usage(type, nmax);
+ if (atom->memcheck("mask"))
+ bytes += memory->usage(mask, nmax);
+ if (atom->memcheck("image"))
+ bytes += memory->usage(image, nmax);
+ if (atom->memcheck("x"))
+ bytes += memory->usage(x, nmax, 3);
+ if (atom->memcheck("v"))
+ bytes += memory->usage(v, nmax, 3);
+ if (atom->memcheck("f"))
+ bytes += memory->usage(f, nmax*comm->nthreads, 3);
+ if (atom->memcheck("rho"))
+ bytes += memory->usage(rho, nmax);
+ if (atom->memcheck("drho"))
+ bytes += memory->usage(drho, nmax*comm->nthreads);
+ if (atom->memcheck("e"))
+ bytes += memory->usage(e, nmax);
+ if (atom->memcheck("de"))
+ bytes += memory->usage(de, nmax*comm->nthreads);
+ if (atom->memcheck("cv"))
+ bytes += memory->usage(cv, nmax);
+ if (atom->memcheck("vest"))
+ bytes += memory->usage(vest, nmax);
+
+ return bytes;
}
diff --git a/src/USER-SPH/atom_vec_meso.h b/src/USER-SPH/atom_vec_meso.h
index 69eb44c66..201cc5e32 100644
--- a/src/USER-SPH/atom_vec_meso.h
+++ b/src/USER-SPH/atom_vec_meso.h
@@ -1,74 +1,75 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(meso,AtomVecMeso)
#else
#ifndef LMP_ATOM_VEC_MESO_H
#define LMP_ATOM_VEC_MESO_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecMeso : public AtomVec {
public:
AtomVecMeso(class LAMMPS *, int, char **);
~AtomVecMeso() {}
void grow(int);
void grow_reset();
void copy(int, int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int pack_reverse(int, int, double *);
void unpack_reverse(int, int *, double *);
int pack_comm_hybrid(int, int *, double *);
int unpack_comm_hybrid(int, int, double *);
int pack_border_hybrid(int, int *, double *);
int unpack_border_hybrid(int, int, double *);
int pack_reverse_hybrid(int, int, double *);
int unpack_reverse_hybrid(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
bigint memory_usage();
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
double *rho, *drho, *e, *de, *cv;
double **vest; // estimated velocity during force computation
};
}
#endif
#endif
diff --git a/src/XTC/dump_xtc.cpp b/src/XTC/dump_xtc.cpp
index 2ff16b388..4dd5e66dd 100644
--- a/src/XTC/dump_xtc.cpp
+++ b/src/XTC/dump_xtc.cpp
@@ -1,1191 +1,1191 @@
/* ----------------------------------------------------------------------
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(FLERR,"Illegal dump xtc command");
if (binary || compressed || multifile || multiproc)
error->all(FLERR,"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
bigint n = group->count(igroup);
if (n > MAXSMALLINT/3/sizeof(float))
error->all(FLERR,"Too many atoms for dump xtc");
natoms = static_cast<int> (n);
memory->create(coords,3*natoms,"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->destroy(coords);
if (me == 0) {
xdrclose(&xd);
xdrfreebuf();
}
}
/* ---------------------------------------------------------------------- */
void DumpXTC::init_style()
{
if (sort_flag == 0 || sortcol != 0)
error->all(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"Cannot open dump file");
}
/* ---------------------------------------------------------------------- */
void DumpXTC::write_header(bigint nbig)
{
if (nbig > MAXSMALLINT) error->all(FLERR,"Too many atoms for dump xtc");
int n = nbig;
if (update->ntimestep > MAXSMALLINT)
error->all(FLERR,"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->destroy(coords);
memory->create(coords,3*natoms,"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,&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);
}
}
/* ---------------------------------------------------------------------- */
void DumpXTC::pack(int *ids)
{
int m,n;
int *tag = atom->tag;
double **x = atom->x;
- int *image = atom->image;
+ tagint *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;
+ int ix = (image[i] & IMGMASK) - IMGMAX;
+ int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ int iz = (image[i] >> IMG2BITS) - IMGMAX;
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)
{
// 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(FLERR,"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(FLERR,"Illegal dump_modify command");
return 2;
} else if (strcmp(arg[0],"precision") == 0) {
if (narg < 2) error->all(FLERR,"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(FLERR,"Illegal dump_modify command");
return 2;
}
return 0;
}
/* ----------------------------------------------------------------------
return # of bytes of allocated memory in buf and global coords array
------------------------------------------------------------------------- */
bigint DumpXTC::memory_usage()
{
bigint bytes = Dump::memory_usage();
bytes += memory->usage(coords,natoms*3);
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,
+ 80, 101, 128, 161, 203, 256, 322, 406, IMGMAX, 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/atom.cpp b/src/atom.cpp
index 7d4564359..75203efdb 100644
--- a/src/atom.cpp
+++ b/src/atom.cpp
@@ -1,1687 +1,1454 @@
/* ----------------------------------------------------------------------
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 "limits.h"
#include "atom.h"
#include "style_atom.h"
#include "atom_vec.h"
#include "atom_vec_ellipsoid.h"
#include "comm.h"
#include "neighbor.h"
#include "force.h"
#include "modify.h"
#include "fix.h"
#include "output.h"
#include "thermo.h"
#include "update.h"
#include "domain.h"
#include "group.h"
#include "accelerator_cuda.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define DELTA 1
#define DELTA_MEMSTR 1024
#define EPSILON 1.0e-6
#define CUDA_CHUNK 3000
/* ---------------------------------------------------------------------- */
Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
{
natoms = 0;
nlocal = nghost = nmax = 0;
ntypes = 0;
nbondtypes = nangletypes = ndihedraltypes = nimpropertypes = 0;
nbonds = nangles = ndihedrals = nimpropers = 0;
bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0;
extra_bond_per_atom = 0;
firstgroupname = NULL;
sortfreq = 1000;
nextsort = 0;
userbinsize = 0.0;
maxbin = maxnext = 0;
binhead = NULL;
next = permute = NULL;
// initialize atom arrays
// customize by adding new array
- tag = type = mask = image = NULL;
+ tag = type = mask = NULL;
+ image = NULL;
x = v = f = NULL;
molecule = NULL;
q = NULL;
mu = NULL;
omega = angmom = torque = NULL;
radius = rmass = NULL;
vfrac = s0 = NULL;
x0 = NULL;
ellipsoid = line = tri = NULL;
spin = NULL;
eradius = ervel = erforce = NULL;
cs = csforce = vforce = ervelforce = NULL;
etag = NULL;
rho = drho = NULL;
e = de = NULL;
cv = NULL;
vest = NULL;
maxspecial = 1;
nspecial = NULL;
special = NULL;
num_bond = NULL;
bond_type = bond_atom = NULL;
num_angle = NULL;
angle_type = angle_atom1 = angle_atom2 = angle_atom3 = NULL;
num_dihedral = NULL;
dihedral_type = dihedral_atom1 = dihedral_atom2 = NULL;
dihedral_atom3 = dihedral_atom4 = NULL;
num_improper = NULL;
improper_type = improper_atom1 = improper_atom2 = NULL;
improper_atom3 = improper_atom4 = NULL;
// initialize atom style and array existence flags
// customize by adding new flag
sphere_flag = ellipsoid_flag = line_flag = tri_flag = 0;
peri_flag = electron_flag = 0;
wavepacket_flag = sph_flag = 0;
molecule_flag = q_flag = mu_flag = 0;
rmass_flag = radius_flag = omega_flag = torque_flag = angmom_flag = 0;
vfrac_flag = spin_flag = eradius_flag = ervel_flag = erforce_flag = 0;
cs_flag = csforce_flag = vforce_flag = ervelforce_flag= etag_flag = 0;
rho_flag = e_flag = cv_flag = vest_flag = 0;
// ntype-length arrays
mass = NULL;
mass_setflag = NULL;
// callback lists & extra restart info
nextra_grow = nextra_restart = 0;
extra_grow = extra_restart = NULL;
nextra_grow_max = nextra_restart_max = 0;
nextra_store = 0;
extra = NULL;
- // default mapping values and hash table primes
+ // default mapping values
tag_enable = 1;
map_style = 0;
map_tag_max = 0;
map_nhash = 0;
-
- nprimes = 38;
- primes = new int[nprimes];
- int plist[] = {5041,10007,20011,30011,40009,50021,60013,70001,80021,
- 90001,100003,110017,120011,130003,140009,150001,160001,
- 170003,180001,190027,200003,210011,220009,230003,240007,
- 250007,260003,270001,280001,290011,300007,310019,320009,
- 330017,340007,350003,362881,3628801};
- for (int i = 0; i < nprimes; i++) primes[i] = plist[i];
+
+ smax = 0;
+ sametag = NULL;
+ map_array = NULL;
+ map_bucket = NULL;
+ map_hash = NULL;
// default atom style = atomic
atom_style = NULL;
avec = NULL;
create_avec("atomic",0,NULL,lmp->suffix);
}
/* ---------------------------------------------------------------------- */
Atom::~Atom()
{
delete [] atom_style;
delete avec;
delete [] firstgroupname;
memory->destroy(binhead);
memory->destroy(next);
memory->destroy(permute);
// delete atom arrays
// customize by adding new array
memory->destroy(tag);
memory->destroy(type);
memory->destroy(mask);
memory->destroy(image);
memory->destroy(x);
memory->destroy(v);
memory->destroy(f);
memory->destroy(q);
memory->destroy(mu);
memory->destroy(omega);
memory->destroy(angmom);
memory->destroy(torque);
memory->destroy(radius);
memory->destroy(rmass);
memory->destroy(vfrac);
memory->destroy(s0);
memory->destroy(x0);
memory->destroy(ellipsoid);
memory->destroy(line);
memory->destroy(tri);
memory->destroy(spin);
memory->destroy(eradius);
memory->destroy(ervel);
memory->destroy(erforce);
memory->destroy(molecule);
memory->destroy(nspecial);
memory->destroy(special);
memory->destroy(num_bond);
memory->destroy(bond_type);
memory->destroy(bond_atom);
memory->destroy(num_angle);
memory->destroy(angle_type);
memory->destroy(angle_atom1);
memory->destroy(angle_atom2);
memory->destroy(angle_atom3);
memory->destroy(num_dihedral);
memory->destroy(dihedral_type);
memory->destroy(dihedral_atom1);
memory->destroy(dihedral_atom2);
memory->destroy(dihedral_atom3);
memory->destroy(dihedral_atom4);
memory->destroy(num_improper);
memory->destroy(improper_type);
memory->destroy(improper_atom1);
memory->destroy(improper_atom2);
memory->destroy(improper_atom3);
memory->destroy(improper_atom4);
// delete per-type arrays
delete [] mass;
delete [] mass_setflag;
// delete extra arrays
memory->destroy(extra_grow);
memory->destroy(extra_restart);
memory->destroy(extra);
// delete mapping data structures
+ memory->destroy(sametag);
map_delete();
- delete [] primes;
}
/* ----------------------------------------------------------------------
copy modify settings from old Atom class to current Atom class
------------------------------------------------------------------------- */
void Atom::settings(Atom *old)
{
map_style = old->map_style;
}
/* ----------------------------------------------------------------------
create an AtomVec style
called from input script, restart file, replicate
------------------------------------------------------------------------- */
void Atom::create_avec(const char *style, int narg, char **arg, char *suffix)
{
delete [] atom_style;
if (avec) delete avec;
// unset atom style and array existence flags
// may have been set by old avec
// customize by adding new flag
sphere_flag = ellipsoid_flag = line_flag = tri_flag = 0;
peri_flag = electron_flag = 0;
molecule_flag = q_flag = mu_flag = 0;
rmass_flag = radius_flag = omega_flag = torque_flag = angmom_flag = 0;
vfrac_flag = spin_flag = eradius_flag = ervel_flag = erforce_flag = 0;
int sflag;
avec = new_avec(style,narg,arg,suffix,sflag);
if (sflag) {
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
int n = strlen(estyle) + 1;
atom_style = new char[n];
strcpy(atom_style,estyle);
} else {
int n = strlen(style) + 1;
atom_style = new char[n];
strcpy(atom_style,style);
}
// if molecular system, default is to have array map
molecular = avec->molecular;
if (map_style == 0 && molecular) map_style = 1;
}
/* ----------------------------------------------------------------------
generate an AtomVec class, first with suffix appended
------------------------------------------------------------------------- */
AtomVec *Atom::new_avec(const char *style, int narg, char **arg,
char *suffix, int &sflag)
{
if (suffix && lmp->suffix_enable) {
sflag = 1;
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
if (0) return NULL;
#define ATOM_CLASS
#define AtomStyle(key,Class) \
else if (strcmp(estyle,#key) == 0) return new Class(lmp,narg,arg);
#include "style_atom.h"
#undef AtomStyle
#undef ATOM_CLASS
}
sflag = 0;
if (0) return NULL;
#define ATOM_CLASS
#define AtomStyle(key,Class) \
else if (strcmp(style,#key) == 0) return new Class(lmp,narg,arg);
#include "style_atom.h"
#undef ATOM_CLASS
else error->all(FLERR,"Invalid atom style");
return NULL;
}
/* ---------------------------------------------------------------------- */
void Atom::init()
{
// delete extra array since it doesn't persist past first run
if (nextra_store) {
memory->destroy(extra);
extra = NULL;
nextra_store = 0;
}
// check arrays that are atom type in length
check_mass();
// setup of firstgroup
if (firstgroupname) {
firstgroup = group->find(firstgroupname);
if (firstgroup < 0)
error->all(FLERR,"Could not find atom_modify first group ID");
} else firstgroup = -1;
// init AtomVec
avec->init();
}
/* ---------------------------------------------------------------------- */
void Atom::setup()
{
// setup bins for sorting
// cannot do this in init() because uses neighbor cutoff
if (sortfreq > 0) setup_sort_bins();
}
/* ----------------------------------------------------------------------
return ptr to AtomVec class if matches style or to matching hybrid sub-class
return NULL if no match
------------------------------------------------------------------------- */
AtomVec *Atom::style_match(const char *style)
{
if (strcmp(atom_style,style) == 0) return avec;
else if (strcmp(atom_style,"hybrid") == 0) {
AtomVecHybrid *avec_hybrid = (AtomVecHybrid *) avec;
for (int i = 0; i < avec_hybrid->nstyles; i++)
if (strcmp(avec_hybrid->keywords[i],style) == 0)
return avec_hybrid->styles[i];
}
return NULL;
}
/* ----------------------------------------------------------------------
modify parameters of the atom style
some options can only be invoked before simulation box is defined
first and sort options cannot be used together
------------------------------------------------------------------------- */
void Atom::modify_params(int narg, char **arg)
{
if (narg == 0) error->all(FLERR,"Illegal atom_modify command");
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"map") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal atom_modify command");
if (strcmp(arg[iarg+1],"array") == 0) map_style = 1;
else if (strcmp(arg[iarg+1],"hash") == 0) map_style = 2;
else error->all(FLERR,"Illegal atom_modify command");
if (domain->box_exist)
error->all(FLERR,
"Atom_modify map command after simulation box is defined");
iarg += 2;
} else if (strcmp(arg[iarg],"first") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal atom_modify command");
if (strcmp(arg[iarg+1],"all") == 0) {
delete [] firstgroupname;
firstgroupname = NULL;
} else {
int n = strlen(arg[iarg+1]) + 1;
firstgroupname = new char[n];
strcpy(firstgroupname,arg[iarg+1]);
sortfreq = 0;
}
iarg += 2;
} else if (strcmp(arg[iarg],"sort") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal atom_modify command");
sortfreq = atoi(arg[iarg+1]);
userbinsize = atof(arg[iarg+2]);
if (sortfreq < 0 || userbinsize < 0.0)
error->all(FLERR,"Illegal atom_modify command");
if (sortfreq >= 0 && firstgroupname)
error->all(FLERR,"Atom_modify sort and first options "
"cannot be used together");
iarg += 3;
} else error->all(FLERR,"Illegal atom_modify command");
}
}
-/* ----------------------------------------------------------------------
- allocate and initialize array or hash table for global -> local map
- set map_tag_max = largest atom ID (may be larger than natoms)
- for array option:
- array length = 1 to largest tag of any atom
- set entire array to -1 as initial values
- for hash option:
- map_nhash = length of hash table
- map_nbucket = # of hash buckets, prime larger than map_nhash
- so buckets will only be filled with 0 or 1 atoms on average
-------------------------------------------------------------------------- */
-
-void Atom::map_init()
-{
- map_delete();
-
- if (tag_enable == 0)
- error->all(FLERR,"Cannot create an atom map unless atoms have IDs");
-
- int max = 0;
- for (int i = 0; i < nlocal; i++) max = MAX(max,tag[i]);
- MPI_Allreduce(&max,&map_tag_max,1,MPI_INT,MPI_MAX,world);
-
- if (map_style == 1) {
- memory->create(map_array,map_tag_max+1,"atom:map_array");
- for (int i = 0; i <= map_tag_max; i++) map_array[i] = -1;
-
- } else {
-
- // map_nhash = max of atoms/proc or total atoms, times 2, at least 1000
-
- int nper = static_cast<int> (natoms/comm->nprocs);
- map_nhash = MAX(nper,nmax);
- if (map_nhash > natoms) map_nhash = static_cast<int> (natoms);
- if (comm->nprocs > 1) map_nhash *= 2;
- map_nhash = MAX(map_nhash,1000);
-
- // map_nbucket = prime just larger than map_nhash
-
- int n = map_nhash/10000;
- n = MIN(n,nprimes-1);
- map_nbucket = primes[n];
- if (map_nbucket < map_nhash && n < nprimes-1) map_nbucket = primes[n+1];
-
- // set all buckets to empty
- // set hash to map_nhash in length
- // put all hash entries in free list and point them to each other
-
- map_bucket = new int[map_nbucket];
- for (int i = 0; i < map_nbucket; i++) map_bucket[i] = -1;
-
- map_hash = new HashElem[map_nhash];
- map_nused = 0;
- map_free = 0;
- for (int i = 0; i < map_nhash; i++) map_hash[i].next = i+1;
- map_hash[map_nhash-1].next = -1;
- }
-}
-
-/* ----------------------------------------------------------------------
- clear global -> local map for all of my own and ghost atoms
- for hash table option:
- global ID may not be in table if image atom was already cleared
-------------------------------------------------------------------------- */
-
-void Atom::map_clear()
-{
- if (map_style == 1) {
- int nall = nlocal + nghost;
- for (int i = 0; i < nall; i++) map_array[tag[i]] = -1;
-
- } else {
- int previous,global,ibucket,index;
- int nall = nlocal + nghost;
- for (int i = 0; i < nall; i++) {
-
- // search for key
- // if don't find it, done
-
- previous = -1;
- global = tag[i];
- ibucket = global % map_nbucket;
- index = map_bucket[ibucket];
- while (index > -1) {
- if (map_hash[index].global == global) break;
- previous = index;
- index = map_hash[index].next;
- }
- if (index == -1) continue;
-
- // delete the hash entry and add it to free list
- // special logic if entry is 1st in the bucket
-
- if (previous == -1) map_bucket[ibucket] = map_hash[index].next;
- else map_hash[previous].next = map_hash[index].next;
-
- map_hash[index].next = map_free;
- map_free = index;
- map_nused--;
- }
- }
-}
-
-/* ----------------------------------------------------------------------
- set global -> local map for all of my own and ghost atoms
- loop in reverse order so that nearby images take precedence over far ones
- and owned atoms take precedence over images
- this enables valid lookups of bond topology atoms
- for hash table option:
- if hash table too small, re-init
- global ID may already be in table if image atom was set
-------------------------------------------------------------------------- */
-
-void Atom::map_set()
-{
- if (map_style == 1) {
- int nall = nlocal + nghost;
- for (int i = nall-1; i >= 0 ; i--) map_array[tag[i]] = i;
-
- } else {
- int previous,global,ibucket,index;
- int nall = nlocal + nghost;
- if (nall > map_nhash) map_init();
-
- for (int i = nall-1; i >= 0 ; i--) {
-
- // search for key
- // if found it, just overwrite local value with index
-
- previous = -1;
- global = tag[i];
- ibucket = global % map_nbucket;
- index = map_bucket[ibucket];
- while (index > -1) {
- if (map_hash[index].global == global) break;
- previous = index;
- index = map_hash[index].next;
- }
- if (index > -1) {
- map_hash[index].local = i;
- continue;
- }
-
- // take one entry from free list
- // add the new global/local pair as entry at end of bucket list
- // special logic if this entry is 1st in bucket
-
- index = map_free;
- map_free = map_hash[map_free].next;
- if (previous == -1) map_bucket[ibucket] = index;
- else map_hash[previous].next = index;
- map_hash[index].global = global;
- map_hash[index].local = i;
- map_hash[index].next = -1;
- map_nused++;
- }
- }
-}
-
-/* ----------------------------------------------------------------------
- set global to local map for one atom
- for hash table option:
- global ID may already be in table if atom was already set
-------------------------------------------------------------------------- */
-
-void Atom::map_one(int global, int local)
-{
- if (map_style == 1) map_array[global] = local;
-
- else {
- // search for key
- // if found it, just overwrite local value with index
-
- int previous = -1;
- int ibucket = global % map_nbucket;
- int index = map_bucket[ibucket];
- while (index > -1) {
- if (map_hash[index].global == global) break;
- previous = index;
- index = map_hash[index].next;
- }
- if (index > -1) {
- map_hash[index].local = local;
- return;
- }
-
- // take one entry from free list
- // add the new global/local pair as entry at end of bucket list
- // special logic if this entry is 1st in bucket
-
- index = map_free;
- map_free = map_hash[map_free].next;
- if (previous == -1) map_bucket[ibucket] = index;
- else map_hash[previous].next = index;
- map_hash[index].global = global;
- map_hash[index].local = local;
- map_hash[index].next = -1;
- map_nused++;
- }
-}
-
-/* ----------------------------------------------------------------------
- free the array or hash table for global to local mapping
-------------------------------------------------------------------------- */
-
-void Atom::map_delete()
-{
- if (map_style == 1) {
- if (map_tag_max) memory->destroy(map_array);
- } else {
- if (map_nhash) {
- delete [] map_bucket;
- delete [] map_hash;
- }
- map_nhash = 0;
- }
- map_tag_max = 0;
-}
-
-/* ----------------------------------------------------------------------
- lookup global ID in hash table, return local index
-------------------------------------------------------------------------- */
-
-int Atom::map_find_hash(int global)
-{
- int local = -1;
- int index = map_bucket[global % map_nbucket];
- while (index > -1) {
- if (map_hash[index].global == global) {
- local = map_hash[index].local;
- break;
- }
- index = map_hash[index].next;
- }
- return local;
-}
-
/* ----------------------------------------------------------------------
add unique tags to any atoms with tag = 0
new tags are grouped by proc and start after max current tag
called after creating new atoms
------------------------------------------------------------------------- */
void Atom::tag_extend()
{
// maxtag_all = max tag for all atoms
int maxtag = 0;
for (int i = 0; i < nlocal; i++) maxtag = MAX(maxtag,tag[i]);
int maxtag_all;
MPI_Allreduce(&maxtag,&maxtag_all,1,MPI_INT,MPI_MAX,world);
// notag = # of atoms I own with no tag (tag = 0)
// notag_sum = # of total atoms on procs <= me with no tag
int notag = 0;
for (int i = 0; i < nlocal; i++) if (tag[i] == 0) notag++;
int notag_sum;
MPI_Scan(&notag,&notag_sum,1,MPI_INT,MPI_SUM,world);
// itag = 1st new tag that my untagged atoms should use
int itag = maxtag_all + notag_sum - notag + 1;
for (int i = 0; i < nlocal; i++) if (tag[i] == 0) tag[i] = itag++;
}
/* ----------------------------------------------------------------------
check that atom IDs span range from 1 to Natoms
return 0 if mintag != 1 or maxtag != Natoms
return 1 if OK
doesn't actually check if all tag values are used
------------------------------------------------------------------------- */
int Atom::tag_consecutive()
{
- int idmin = MAXTAGINT;
+ // change this when allow tagint = bigint
+ //int idmin = MAXTAGINT;
+ int idmin = MAXSMALLINT;
int idmax = 0;
for (int i = 0; i < nlocal; i++) {
idmin = MIN(idmin,tag[i]);
idmax = MAX(idmax,tag[i]);
}
int idminall,idmaxall;
MPI_Allreduce(&idmin,&idminall,1,MPI_INT,MPI_MIN,world);
MPI_Allreduce(&idmax,&idmaxall,1,MPI_INT,MPI_MAX,world);
if (idminall != 1 || idmaxall != static_cast<int> (natoms)) return 0;
return 1;
}
/* ----------------------------------------------------------------------
count and return words in a single line
make copy of line before using strtok so as not to change line
trim anything from '#' onward
------------------------------------------------------------------------- */
int Atom::count_words(const char *line)
{
int n = strlen(line) + 1;
char *copy;
memory->create(copy,n,"atom:copy");
strcpy(copy,line);
char *ptr;
if (ptr = strchr(copy,'#')) *ptr = '\0';
if (strtok(copy," \t\n\r\f") == NULL) {
memory->destroy(copy);
return 0;
}
n = 1;
while (strtok(NULL," \t\n\r\f")) n++;
memory->destroy(copy);
return n;
}
/* ----------------------------------------------------------------------
unpack n lines from Atom section of data file
call style-specific routine to parse line
------------------------------------------------------------------------- */
void Atom::data_atoms(int n, char *buf)
{
- int m,imagedata,xptr,iptr;
+ int m,xptr,iptr;
+ tagint imagedata;
double xdata[3],lamda[3];
double *coord;
char *next;
next = strchr(buf,'\n');
*next = '\0';
int nwords = count_words(buf);
*next = '\n';
if (nwords != avec->size_data_atom && nwords != avec->size_data_atom + 3)
error->all(FLERR,"Incorrect atom format in data file");
char **values = new char*[nwords];
// set bounds for my proc
// if periodic and I am lo/hi proc, adjust bounds by EPSILON
// insures all data atoms will be owned even with round-off
int triclinic = domain->triclinic;
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] += epsilon[0];
}
if (domain->yperiodic) {
if (comm->myloc[1] == 0) sublo[1] -= epsilon[1];
if (comm->myloc[1] == comm->procgrid[1]-1) subhi[1] += epsilon[1];
}
if (domain->zperiodic) {
if (comm->myloc[2] == 0) sublo[2] -= epsilon[2];
if (comm->myloc[2] == comm->procgrid[2]-1) subhi[2] += epsilon[2];
}
// xptr = which word in line starts xyz coords
// iptr = which word in line starts ix,iy,iz image flags
xptr = avec->xcol_data - 1;
int imageflag = 0;
if (nwords > avec->size_data_atom) imageflag = 1;
if (imageflag) iptr = nwords - 3;
// loop over lines of atom data
// tokenize the line into values
// extract xyz coords and image flags
// remap atom into simulation box
// if atom is in my sub-domain, unpack its values
for (int i = 0; i < n; i++) {
next = strchr(buf,'\n');
values[0] = strtok(buf," \t\n\r\f");
if (values[0] == NULL)
error->all(FLERR,"Incorrect atom format in data file");
for (m = 1; m < nwords; m++) {
values[m] = strtok(NULL," \t\n\r\f");
if (values[m] == NULL)
error->all(FLERR,"Incorrect atom format in data file");
}
if (imageflag)
- imagedata = ((atoi(values[iptr+2]) + 512 & 1023) << 20) |
- ((atoi(values[iptr+1]) + 512 & 1023) << 10) |
- (atoi(values[iptr]) + 512 & 1023);
- else imagedata = (512 << 20) | (512 << 10) | 512;
+ imagedata =
+ (((tagint) atoi(values[iptr+2]) + IMGMAX & IMGMASK) << IMG2BITS) |
+ (((tagint) atoi(values[iptr+1]) + IMGMASK & IMGMASK) << IMGBITS) |
+ (atoi(values[iptr]) + IMGMASK & IMGMASK);
+ else imagedata = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
xdata[0] = atof(values[xptr]);
xdata[1] = atof(values[xptr+1]);
xdata[2] = atof(values[xptr+2]);
domain->remap(xdata,imagedata);
if (triclinic) {
domain->x2lamda(xdata,lamda);
coord = lamda;
} else coord = xdata;
if (coord[0] >= sublo[0] && coord[0] < subhi[0] &&
coord[1] >= sublo[1] && coord[1] < subhi[1] &&
coord[2] >= sublo[2] && coord[2] < subhi[2])
avec->data_atom(xdata,imagedata,values);
buf = next + 1;
}
delete [] values;
}
/* ----------------------------------------------------------------------
unpack n lines from Velocity section of data file
check that atom IDs are > 0 and <= map_tag_max
call style-specific routine to parse line
------------------------------------------------------------------------- */
void Atom::data_vels(int n, char *buf)
{
int j,m,tagdata;
char *next;
next = strchr(buf,'\n');
*next = '\0';
int nwords = count_words(buf);
*next = '\n';
if (nwords != avec->size_data_vel)
error->all(FLERR,"Incorrect velocity format in data file");
char **values = new char*[nwords];
// loop over lines of atom velocities
// tokenize the line into values
// if I own atom tag, unpack its values
for (int i = 0; i < n; i++) {
next = strchr(buf,'\n');
values[0] = strtok(buf," \t\n\r\f");
for (j = 1; j < nwords; j++)
values[j] = strtok(NULL," \t\n\r\f");
tagdata = atoi(values[0]);
if (tagdata <= 0 || tagdata > map_tag_max)
error->one(FLERR,"Invalid atom ID in Velocities section of data file");
if ((m = map(tagdata)) >= 0) avec->data_vel(m,&values[1]);
buf = next + 1;
}
delete [] values;
}
/* ----------------------------------------------------------------------
unpack n lines from atom-style specific section of data file
check that atom IDs are > 0 and <= map_tag_max
call style-specific routine to parse line
------------------------------------------------------------------------- */
void Atom::data_bonus(int n, char *buf, AtomVec *avec_bonus)
{
int j,m,tagdata;
char *next;
next = strchr(buf,'\n');
*next = '\0';
int nwords = count_words(buf);
*next = '\n';
if (nwords != avec_bonus->size_data_bonus)
error->all(FLERR,"Incorrect bonus data format in data file");
char **values = new char*[nwords];
// loop over lines of bonus atom data
// tokenize the line into values
// if I own atom tag, unpack its values
for (int i = 0; i < n; i++) {
next = strchr(buf,'\n');
values[0] = strtok(buf," \t\n\r\f");
for (j = 1; j < nwords; j++)
values[j] = strtok(NULL," \t\n\r\f");
tagdata = atoi(values[0]);
if (tagdata <= 0 || tagdata > map_tag_max)
error->one(FLERR,"Invalid atom ID in Bonus section of data file");
// ok to call child's data_atom_bonus() method thru parent avec_bonus,
// since data_bonus() was called with child ptr, and method is virtual
if ((m = map(tagdata)) >= 0) avec_bonus->data_atom_bonus(m,&values[1]);
buf = next + 1;
}
delete [] values;
}
/* ----------------------------------------------------------------------
check that atom IDs are > 0 and <= map_tag_max
------------------------------------------------------------------------- */
void Atom::data_bonds(int n, char *buf)
{
int m,tmp,itype,atom1,atom2;
char *next;
int newton_bond = force->newton_bond;
for (int i = 0; i < n; i++) {
next = strchr(buf,'\n');
*next = '\0';
sscanf(buf,"%d %d %d %d",&tmp,&itype,&atom1,&atom2);
if (atom1 <= 0 || atom1 > map_tag_max ||
atom2 <= 0 || atom2 > map_tag_max)
error->one(FLERR,"Invalid atom ID in Bonds section of data file");
if (itype <= 0 || itype > nbondtypes)
error->one(FLERR,"Invalid bond type in Bonds section of data file");
if ((m = map(atom1)) >= 0) {
bond_type[m][num_bond[m]] = itype;
bond_atom[m][num_bond[m]] = atom2;
num_bond[m]++;
}
if (newton_bond == 0) {
if ((m = map(atom2)) >= 0) {
bond_type[m][num_bond[m]] = itype;
bond_atom[m][num_bond[m]] = atom1;
num_bond[m]++;
}
}
buf = next + 1;
}
}
/* ----------------------------------------------------------------------
check that atom IDs are > 0 and <= map_tag_max
------------------------------------------------------------------------- */
void Atom::data_angles(int n, char *buf)
{
int m,tmp,itype,atom1,atom2,atom3;
char *next;
int newton_bond = force->newton_bond;
for (int i = 0; i < n; i++) {
next = strchr(buf,'\n');
*next = '\0';
sscanf(buf,"%d %d %d %d %d",&tmp,&itype,&atom1,&atom2,&atom3);
if (atom1 <= 0 || atom1 > map_tag_max ||
atom2 <= 0 || atom2 > map_tag_max ||
atom3 <= 0 || atom3 > map_tag_max)
error->one(FLERR,"Invalid atom ID in Angles section of data file");
if (itype <= 0 || itype > nangletypes)
error->one(FLERR,"Invalid angle type in Angles section of data file");
if ((m = map(atom2)) >= 0) {
angle_type[m][num_angle[m]] = itype;
angle_atom1[m][num_angle[m]] = atom1;
angle_atom2[m][num_angle[m]] = atom2;
angle_atom3[m][num_angle[m]] = atom3;
num_angle[m]++;
}
if (newton_bond == 0) {
if ((m = map(atom1)) >= 0) {
angle_type[m][num_angle[m]] = itype;
angle_atom1[m][num_angle[m]] = atom1;
angle_atom2[m][num_angle[m]] = atom2;
angle_atom3[m][num_angle[m]] = atom3;
num_angle[m]++;
}
if ((m = map(atom3)) >= 0) {
angle_type[m][num_angle[m]] = itype;
angle_atom1[m][num_angle[m]] = atom1;
angle_atom2[m][num_angle[m]] = atom2;
angle_atom3[m][num_angle[m]] = atom3;
num_angle[m]++;
}
}
buf = next + 1;
}
}
/* ----------------------------------------------------------------------
check that atom IDs are > 0 and <= map_tag_max
------------------------------------------------------------------------- */
void Atom::data_dihedrals(int n, char *buf)
{
int m,tmp,itype,atom1,atom2,atom3,atom4;
char *next;
int newton_bond = force->newton_bond;
for (int i = 0; i < n; i++) {
next = strchr(buf,'\n');
*next = '\0';
sscanf(buf,"%d %d %d %d %d %d",&tmp,&itype,&atom1,&atom2,&atom3,&atom4);
if (atom1 <= 0 || atom1 > map_tag_max ||
atom2 <= 0 || atom2 > map_tag_max ||
atom3 <= 0 || atom3 > map_tag_max ||
atom4 <= 0 || atom4 > map_tag_max)
error->one(FLERR,"Invalid atom ID in Dihedrals section of data file");
if (itype <= 0 || itype > ndihedraltypes)
error->one(FLERR,
"Invalid dihedral type in Dihedrals section of data file");
if ((m = map(atom2)) >= 0) {
dihedral_type[m][num_dihedral[m]] = itype;
dihedral_atom1[m][num_dihedral[m]] = atom1;
dihedral_atom2[m][num_dihedral[m]] = atom2;
dihedral_atom3[m][num_dihedral[m]] = atom3;
dihedral_atom4[m][num_dihedral[m]] = atom4;
num_dihedral[m]++;
}
if (newton_bond == 0) {
if ((m = map(atom1)) >= 0) {
dihedral_type[m][num_dihedral[m]] = itype;
dihedral_atom1[m][num_dihedral[m]] = atom1;
dihedral_atom2[m][num_dihedral[m]] = atom2;
dihedral_atom3[m][num_dihedral[m]] = atom3;
dihedral_atom4[m][num_dihedral[m]] = atom4;
num_dihedral[m]++;
}
if ((m = map(atom3)) >= 0) {
dihedral_type[m][num_dihedral[m]] = itype;
dihedral_atom1[m][num_dihedral[m]] = atom1;
dihedral_atom2[m][num_dihedral[m]] = atom2;
dihedral_atom3[m][num_dihedral[m]] = atom3;
dihedral_atom4[m][num_dihedral[m]] = atom4;
num_dihedral[m]++;
}
if ((m = map(atom4)) >= 0) {
dihedral_type[m][num_dihedral[m]] = itype;
dihedral_atom1[m][num_dihedral[m]] = atom1;
dihedral_atom2[m][num_dihedral[m]] = atom2;
dihedral_atom3[m][num_dihedral[m]] = atom3;
dihedral_atom4[m][num_dihedral[m]] = atom4;
num_dihedral[m]++;
}
}
buf = next + 1;
}
}
/* ----------------------------------------------------------------------
check that atom IDs are > 0 and <= map_tag_max
------------------------------------------------------------------------- */
void Atom::data_impropers(int n, char *buf)
{
int m,tmp,itype,atom1,atom2,atom3,atom4;
char *next;
int newton_bond = force->newton_bond;
for (int i = 0; i < n; i++) {
next = strchr(buf,'\n');
*next = '\0';
sscanf(buf,"%d %d %d %d %d %d",&tmp,&itype,&atom1,&atom2,&atom3,&atom4);
if (atom1 <= 0 || atom1 > map_tag_max ||
atom2 <= 0 || atom2 > map_tag_max ||
atom3 <= 0 || atom3 > map_tag_max ||
atom4 <= 0 || atom4 > map_tag_max)
error->one(FLERR,"Invalid atom ID in Impropers section of data file");
if (itype <= 0 || itype > nimpropertypes)
error->one(FLERR,
"Invalid improper type in Impropers section of data file");
if ((m = map(atom2)) >= 0) {
improper_type[m][num_improper[m]] = itype;
improper_atom1[m][num_improper[m]] = atom1;
improper_atom2[m][num_improper[m]] = atom2;
improper_atom3[m][num_improper[m]] = atom3;
improper_atom4[m][num_improper[m]] = atom4;
num_improper[m]++;
}
if (newton_bond == 0) {
if ((m = map(atom1)) >= 0) {
improper_type[m][num_improper[m]] = itype;
improper_atom1[m][num_improper[m]] = atom1;
improper_atom2[m][num_improper[m]] = atom2;
improper_atom3[m][num_improper[m]] = atom3;
improper_atom4[m][num_improper[m]] = atom4;
num_improper[m]++;
}
if ((m = map(atom3)) >= 0) {
improper_type[m][num_improper[m]] = itype;
improper_atom1[m][num_improper[m]] = atom1;
improper_atom2[m][num_improper[m]] = atom2;
improper_atom3[m][num_improper[m]] = atom3;
improper_atom4[m][num_improper[m]] = atom4;
num_improper[m]++;
}
if ((m = map(atom4)) >= 0) {
improper_type[m][num_improper[m]] = itype;
improper_atom1[m][num_improper[m]] = atom1;
improper_atom2[m][num_improper[m]] = atom2;
improper_atom3[m][num_improper[m]] = atom3;
improper_atom4[m][num_improper[m]] = atom4;
num_improper[m]++;
}
}
buf = next + 1;
}
}
/* ----------------------------------------------------------------------
allocate arrays of length ntypes
only done after ntypes is set
------------------------------------------------------------------------- */
void Atom::allocate_type_arrays()
{
if (avec->mass_type) {
mass = new double[ntypes+1];
mass_setflag = new int[ntypes+1];
for (int itype = 1; itype <= ntypes; itype++) mass_setflag[itype] = 0;
}
}
/* ----------------------------------------------------------------------
set a mass and flag it as set
called from reading of data file
------------------------------------------------------------------------- */
void Atom::set_mass(const char *str)
{
if (mass == NULL) error->all(FLERR,"Cannot set mass for this atom style");
int itype;
double mass_one;
int n = sscanf(str,"%d %lg",&itype,&mass_one);
if (n != 2) error->all(FLERR,"Invalid mass line in data file");
if (itype < 1 || itype > ntypes)
error->all(FLERR,"Invalid type for mass set");
mass[itype] = mass_one;
mass_setflag[itype] = 1;
if (mass[itype] <= 0.0) error->all(FLERR,"Invalid mass value");
}
/* ----------------------------------------------------------------------
set a mass and flag it as set
called from EAM pair routine
------------------------------------------------------------------------- */
void Atom::set_mass(int itype, double value)
{
if (mass == NULL) error->all(FLERR,"Cannot set mass for this atom style");
if (itype < 1 || itype > ntypes)
error->all(FLERR,"Invalid type for mass set");
mass[itype] = value;
mass_setflag[itype] = 1;
if (mass[itype] <= 0.0) error->all(FLERR,"Invalid mass value");
}
/* ----------------------------------------------------------------------
set one or more masses and flag them as set
called from reading of input script
------------------------------------------------------------------------- */
void Atom::set_mass(int narg, char **arg)
{
if (mass == NULL) error->all(FLERR,"Cannot set mass for this atom style");
int lo,hi;
force->bounds(arg[0],ntypes,lo,hi);
if (lo < 1 || hi > ntypes) error->all(FLERR,"Invalid type for mass set");
for (int itype = lo; itype <= hi; itype++) {
mass[itype] = atof(arg[1]);
mass_setflag[itype] = 1;
if (mass[itype] <= 0.0) error->all(FLERR,"Invalid mass value");
}
}
/* ----------------------------------------------------------------------
set all masses as read in from restart file
------------------------------------------------------------------------- */
void Atom::set_mass(double *values)
{
for (int itype = 1; itype <= ntypes; itype++) {
mass[itype] = values[itype];
mass_setflag[itype] = 1;
}
}
/* ----------------------------------------------------------------------
check that all masses have been set
------------------------------------------------------------------------- */
void Atom::check_mass()
{
if (mass == NULL) return;
for (int itype = 1; itype <= ntypes; itype++)
if (mass_setflag[itype] == 0) error->all(FLERR,"All masses are not set");
}
/* ----------------------------------------------------------------------
check that radii of all particles of itype are the same
return 1 if true, else return 0
also return the radius value for that type
------------------------------------------------------------------------- */
int Atom::radius_consistency(int itype, double &rad)
{
double value = -1.0;
int flag = 0;
for (int i = 0; i < nlocal; i++) {
if (type[i] != itype) continue;
if (value < 0.0) value = radius[i];
else if (value != radius[i]) flag = 1;
}
int flagall;
MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
if (flagall) return 0;
MPI_Allreduce(&value,&rad,1,MPI_DOUBLE,MPI_MAX,world);
return 1;
}
/* ----------------------------------------------------------------------
check that shape of all particles of itype are the same
return 1 if true, else return 0
also return the 3 shape params for itype
------------------------------------------------------------------------- */
int Atom::shape_consistency(int itype,
double &shapex, double &shapey, double &shapez)
{
double zero[3] = {0.0, 0.0, 0.0};
double one[3] = {-1.0, -1.0, -1.0};
double *shape;
AtomVecEllipsoid *avec_ellipsoid =
(AtomVecEllipsoid *) style_match("ellipsoid");
AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int flag = 0;
for (int i = 0; i < nlocal; i++) {
if (type[i] != itype) continue;
if (ellipsoid[i] < 0) shape = zero;
else shape = bonus[ellipsoid[i]].shape;
if (one[0] < 0.0) {
one[0] = shape[0];
one[1] = shape[1];
one[2] = shape[2];
} else if (one[0] != shape[0] || one[1] != shape[1] || one[2] != shape[2])
flag = 1;
}
int flagall;
MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
if (flagall) return 0;
double oneall[3];
MPI_Allreduce(one,oneall,3,MPI_DOUBLE,MPI_MAX,world);
shapex = oneall[0];
shapey = oneall[1];
shapez = oneall[2];
return 1;
}
/* ----------------------------------------------------------------------
reorder owned atoms so those in firstgroup appear first
called by comm->exchange() if atom_modify first group is set
only owned atoms exist at this point, no ghost atoms
------------------------------------------------------------------------- */
void Atom::first_reorder()
{
// insure there is one extra atom location at end of arrays for swaps
if (nlocal == nmax) avec->grow(0);
// loop over owned atoms
// nfirst = index of first atom not in firstgroup
// when find firstgroup atom out of place, swap it with atom nfirst
int bitmask = group->bitmask[firstgroup];
nfirst = 0;
while (nfirst < nlocal && mask[nfirst] & bitmask) nfirst++;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & bitmask && i > nfirst) {
avec->copy(i,nlocal,0);
avec->copy(nfirst,i,0);
avec->copy(nlocal,nfirst,0);
while (nfirst < nlocal && mask[nfirst] & bitmask) nfirst++;
}
}
}
/* ----------------------------------------------------------------------
perform spatial sort of atoms within my sub-domain
always called between comm->exchange() and comm->borders()
don't have to worry about clearing/setting atom->map since done in comm
------------------------------------------------------------------------- */
void Atom::sort()
{
int i,m,n,ix,iy,iz,ibin,empty;
// set next timestep for sorting to take place
nextsort = (update->ntimestep/sortfreq)*sortfreq + sortfreq;
// download data from GPU if necessary
if (lmp->cuda && !lmp->cuda->oncpu) lmp->cuda->downloadAll();
// re-setup sort bins if needed
if (domain->box_change) setup_sort_bins();
if (nbins == 1) return;
// reallocate per-atom vectors if needed
if (nlocal > maxnext) {
memory->destroy(next);
memory->destroy(permute);
maxnext = atom->nmax;
memory->create(next,maxnext,"atom:next");
memory->create(permute,maxnext,"atom:permute");
}
// insure there is one extra atom location at end of arrays for swaps
if (nlocal == nmax) avec->grow(0);
// bin atoms in reverse order so linked list will be in forward order
for (i = 0; i < nbins; i++) binhead[i] = -1;
for (i = nlocal-1; i >= 0; i--) {
ix = static_cast<int> ((x[i][0]-bboxlo[0])*bininvx);
iy = static_cast<int> ((x[i][1]-bboxlo[1])*bininvy);
iz = static_cast<int> ((x[i][2]-bboxlo[2])*bininvz);
ix = MAX(ix,0);
iy = MAX(iy,0);
iz = MAX(iz,0);
ix = MIN(ix,nbinx-1);
iy = MIN(iy,nbiny-1);
iz = MIN(iz,nbinz-1);
ibin = iz*nbiny*nbinx + iy*nbinx + ix;
next[i] = binhead[ibin];
binhead[ibin] = i;
}
// permute = desired permutation of atoms
// permute[I] = J means Ith new atom will be Jth old atom
n = 0;
for (m = 0; m < nbins; m++) {
i = binhead[m];
while (i >= 0) {
permute[n++] = i;
i = next[i];
}
}
// current = current permutation, just reuse next vector
// current[I] = J means Ith current atom is Jth old atom
int *current = next;
for (i = 0; i < nlocal; i++) current[i] = i;
// reorder local atom list, when done, current = permute
// perform "in place" using copy() to extra atom location at end of list
// inner while loop processes one cycle of the permutation
// copy before inner-loop moves an atom to end of atom list
// copy after inner-loop moves atom at end of list back into list
// empty = location in atom list that is currently empty
for (i = 0; i < nlocal; i++) {
if (current[i] == permute[i]) continue;
avec->copy(i,nlocal,0);
empty = i;
while (permute[empty] != i) {
avec->copy(permute[empty],empty,0);
empty = current[empty] = permute[empty];
}
avec->copy(nlocal,empty,0);
current[empty] = permute[empty];
}
// upload data back to GPU if necessary
if (lmp->cuda && !lmp->cuda->oncpu) lmp->cuda->uploadAll();
// sanity check that current = permute
//int flag = 0;
//for (i = 0; i < nlocal; i++)
// if (current[i] != permute[i]) flag = 1;
//int flagall;
//MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
//if (flagall) error->all(FLERR,"Atom sort did not operate correctly");
}
/* ----------------------------------------------------------------------
setup bins for spatial sorting of atoms
------------------------------------------------------------------------- */
void Atom::setup_sort_bins()
{
// binsize:
// user setting if explicitly set
// 1/2 of neighbor cutoff for non-CUDA
// CUDA_CHUNK atoms/proc for CUDA
// check if neighbor cutoff = 0.0
double binsize;
if (userbinsize > 0.0) binsize = userbinsize;
else if (!lmp->cuda) binsize = 0.5 * neighbor->cutneighmax;
else {
if (domain->dimension == 3) {
double vol = (domain->boxhi[0]-domain->boxlo[0]) *
(domain->boxhi[1]-domain->boxlo[1]) *
(domain->boxhi[2]-domain->boxlo[2]);
binsize = pow(1.0*CUDA_CHUNK/natoms*vol,1.0/3.0);
} else {
double area = (domain->boxhi[0]-domain->boxlo[0]) *
(domain->boxhi[1]-domain->boxlo[1]);
binsize = pow(1.0*CUDA_CHUNK/natoms*area,1.0/2.0);
}
}
if (binsize == 0.0) error->all(FLERR,"Atom sorting has bin size = 0.0");
double bininv = 1.0/binsize;
// nbin xyz = local bins
// bbox lo/hi = bounding box of my sub-domain
if (domain->triclinic)
domain->bbox(domain->sublo_lamda,domain->subhi_lamda,bboxlo,bboxhi);
else {
bboxlo[0] = domain->sublo[0];
bboxlo[1] = domain->sublo[1];
bboxlo[2] = domain->sublo[2];
bboxhi[0] = domain->subhi[0];
bboxhi[1] = domain->subhi[1];
bboxhi[2] = domain->subhi[2];
}
nbinx = static_cast<int> ((bboxhi[0]-bboxlo[0]) * bininv);
nbiny = static_cast<int> ((bboxhi[1]-bboxlo[1]) * bininv);
nbinz = static_cast<int> ((bboxhi[2]-bboxlo[2]) * bininv);
if (domain->dimension == 2) nbinz = 1;
if (nbinx == 0) nbinx = 1;
if (nbiny == 0) nbiny = 1;
if (nbinz == 0) nbinz = 1;
bininvx = nbinx / (bboxhi[0]-bboxlo[0]);
bininvy = nbiny / (bboxhi[1]-bboxlo[1]);
bininvz = nbinz / (bboxhi[2]-bboxlo[2]);
if (1.0*nbinx*nbiny*nbinz > INT_MAX)
error->one(FLERR,"Too many atom sorting bins");
nbins = nbinx*nbiny*nbinz;
// reallocate per-bin memory if needed
if (nbins > maxbin) {
memory->destroy(binhead);
maxbin = nbins;
memory->create(binhead,maxbin,"atom:binhead");
}
}
/* ----------------------------------------------------------------------
register a callback to a fix so it can manage atom-based arrays
happens when fix is created
flag = 0 for grow, 1 for restart
------------------------------------------------------------------------- */
void Atom::add_callback(int flag)
{
int ifix;
// find the fix
// if find NULL ptr:
// it's this one, since it is being replaced and has just been deleted
// at this point in re-creation
// if don't find NULL ptr:
// i is set to nfix = new one currently being added at end of list
for (ifix = 0; ifix < modify->nfix; ifix++)
if (modify->fix[ifix] == NULL) break;
// add callback to lists, reallocating if necessary
if (flag == 0) {
if (nextra_grow == nextra_grow_max) {
nextra_grow_max += DELTA;
memory->grow(extra_grow,nextra_grow_max,"atom:extra_grow");
}
extra_grow[nextra_grow] = ifix;
nextra_grow++;
} else if (flag == 1) {
if (nextra_restart == nextra_restart_max) {
nextra_restart_max += DELTA;
memory->grow(extra_restart,nextra_restart_max,"atom:extra_restart");
}
extra_restart[nextra_restart] = ifix;
nextra_restart++;
}
}
/* ----------------------------------------------------------------------
unregister a callback to a fix
happens when fix is deleted, called by its destructor
flag = 0 for grow, 1 for restart
------------------------------------------------------------------------- */
void Atom::delete_callback(const char *id, int flag)
{
int ifix;
for (ifix = 0; ifix < modify->nfix; ifix++)
if (strcmp(id,modify->fix[ifix]->id) == 0) break;
// compact the list of callbacks
if (flag == 0) {
int match;
for (match = 0; match < nextra_grow; match++)
if (extra_grow[match] == ifix) break;
for (int i = match; i < nextra_grow-1; i++)
extra_grow[i] = extra_grow[i+1];
nextra_grow--;
} else if (flag == 1) {
int match;
for (match = 0; match < nextra_grow; match++)
if (extra_restart[match] == ifix) break;
for (int i = ifix; i < nextra_restart-1; i++)
extra_restart[i] = extra_restart[i+1];
nextra_restart--;
}
}
/* ----------------------------------------------------------------------
decrement ptrs in callback lists to fixes beyond the deleted ifix
happens after fix is deleted
------------------------------------------------------------------------- */
void Atom::update_callback(int ifix)
{
for (int i = 0; i < nextra_grow; i++)
if (extra_grow[i] > ifix) extra_grow[i]--;
for (int i = 0; i < nextra_restart; i++)
if (extra_restart[i] > ifix) extra_restart[i]--;
}
/* ----------------------------------------------------------------------
return a pointer to a named internal variable
if don't recognize name, return NULL
customize by adding names
------------------------------------------------------------------------- */
void *Atom::extract(char *name)
{
if (strcmp(name,"id") == 0) return (void *) tag;
if (strcmp(name,"type") == 0) return (void *) type;
if (strcmp(name,"mask") == 0) return (void *) mask;
if (strcmp(name,"x") == 0) return (void *) x;
if (strcmp(name,"v") == 0) return (void *) v;
if (strcmp(name,"f") == 0) return (void *) f;
if (strcmp(name,"mass") == 0) return (void *) mass;
if (strcmp(name,"rmass") == 0) return (void *) rmass;
return NULL;
}
/* ----------------------------------------------------------------------
return # of bytes of allocated memory
call to avec tallies per-atom vectors
add in global to local mapping storage
------------------------------------------------------------------------- */
bigint Atom::memory_usage()
{
memlength = DELTA_MEMSTR;
memory->create(memstr,memlength,"atom:memstr");
memstr[0] = '\0';
bigint bytes = avec->memory_usage();
memory->destroy(memstr);
+ bytes += smax*sizeof(int);
if (map_style == 1)
bytes += memory->usage(map_array,map_tag_max+1);
else if (map_style == 2) {
bytes += map_nbucket*sizeof(int);
bytes += map_nhash*sizeof(HashElem);
}
if (maxnext) {
bytes += memory->usage(next,maxnext);
bytes += memory->usage(permute,maxnext);
}
return bytes;
}
/* ----------------------------------------------------------------------
accumulate per-atom vec names in memstr, padded by spaces
return 1 if padded str is not already in memlist, else 0
------------------------------------------------------------------------- */
int Atom::memcheck(const char *str)
{
int n = strlen(str) + 3;
char *padded = new char[n];
strcpy(padded," ");
strcat(padded,str);
strcat(padded," ");
if (strstr(memstr,padded)) {
delete [] padded;
return 0;
}
if (strlen(memstr) + n >= memlength) {
memlength += DELTA_MEMSTR;
memory->grow(memstr,memlength,"atom:memstr");
}
strcat(memstr,padded);
delete [] padded;
return 1;
}
diff --git a/src/atom.h b/src/atom.h
index 1f821c40f..8fadef6a4 100644
--- a/src/atom.h
+++ b/src/atom.h
@@ -1,369 +1,369 @@
/* -*- c++ -*- ----------------------------------------------------------
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"
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
// natoms may not be current if atoms lost
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;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
int *molecule;
double *q,**mu;
double **omega,**angmom,**torque;
double *radius,*rmass,*vfrac,*s0;
double **x0;
int *ellipsoid,*line,*tri;
int *spin;
double *eradius,*ervel,*erforce,*ervelforce;
double *cs,*csforce,*vforce;
int *etag;
double *rho, *drho;
double *e, *de;
double **vest;
double *cv;
int **nspecial; // 0,1,2 = cummulative # of 1-2,1-3,1-4 neighs
int **special; // IDs of 1-2,1-3,1-4 neighs of each atom
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;
// atom style and per-atom array existence flags
// customize by adding new flag
int sphere_flag,ellipsoid_flag,line_flag,tri_flag,peri_flag,electron_flag;
int wavepacket_flag,sph_flag;
int molecule_flag,q_flag,mu_flag;
int rmass_flag,radius_flag,omega_flag,torque_flag,angmom_flag;
int vfrac_flag,spin_flag,eradius_flag,ervel_flag,erforce_flag;
int cs_flag,csforce_flag,vforce_flag,ervelforce_flag,etag_flag;
int rho_flag,e_flag,cv_flag,vest_flag;
// extra peratom info in restart file destined for fix & diag
double **extra;
// per-type arrays
double *mass;
int *mass_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
bigint nextsort; // next timestep to sort on
+ // indices of atoms with same ID
+
+ int *sametag; // sametag[I] = next atom with same ID, -1 if no more
+
// functions
Atom(class LAMMPS *);
~Atom();
void settings(class Atom *);
void create_avec(const char *, int, char **, char *suffix = NULL);
class AtomVec *new_avec(const char *, int, char **, char *, int &);
void init();
void setup();
class AtomVec *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_bonus(int, char *, class AtomVec *);
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();
int radius_consistency(int, double &);
int shape_consistency(int, double &, double &, double &);
void first_reorder();
void sort();
void add_callback(int);
void delete_callback(const char *, int);
void update_callback(int);
void *extract(char *);
inline int* get_map_array() {return map_array;};
inline int get_map_size() {return map_tag_max+1;};
bigint 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;
+ int map_tag_max; // size of map_array
+ int *map_array; // direct map of length max atom ID + 1
+ int smax; // max size of sametag
struct HashElem {
int global; // key to search on = global ID
int local; // value associated with key = local index
int next; // next entry in this bucket, -1 if last
};
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();
+ int next_prime(int);
};
}
#endif
/* ERROR/WARNING messages:
E: Invalid atom style
The choice of atom style is unknown.
E: Could not find atom_modify first group ID
Self-explanatory.
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Atom_modify map command after simulation box is defined
The atom_modify map command cannot be used after a read_data,
read_restart, or create_box command.
E: Atom_modify sort and first options cannot be used together
Self-explanatory.
-E: Cannot create an atom map unless atoms have IDs
-
-The simulation requires a mapping from global atom IDs to local atoms,
-but the atoms that have been defined have no IDs.
-
E: Incorrect atom format in data file
Number of values per atom line in the data file is not consistent with
the atom style.
E: Incorrect velocity format in data file
Each atom style defines a format for the Velocity section
of the data file. The read-in lines do not match.
E: Invalid atom ID in Velocities section of data file
Atom IDs must be positive integers and within range of defined
atoms.
E: Incorrect bonus data format in data file
See the read_data doc page for a description of how various kinds of
bonus data must be formatted for certain atom styles.
E: Invalid atom ID in Bonus section of data file
Atom IDs must be positive integers and within range of defined
atoms.
E: Invalid atom ID in Bonds section of data file
Atom IDs must be positive integers and within range of defined
atoms.
E: Invalid bond type in Bonds section of data file
Bond type must be positive integer and within range of specified bond
types.
E: Invalid atom ID in Angles section of data file
Atom IDs must be positive integers and within range of defined
atoms.
E: Invalid angle type in Angles section of data file
Angle type must be positive integer and within range of specified angle
types.
E: Invalid atom ID in Dihedrals section of data file
Atom IDs must be positive integers and within range of defined
atoms.
E: Invalid dihedral type in Dihedrals section of data file
Dihedral type must be positive integer and within range of specified
dihedral types.
E: Invalid atom ID in Impropers section of data file
Atom IDs must be positive integers and within range of defined
atoms.
E: Invalid improper type in Impropers section of data file
Improper type must be positive integer and within range of specified
improper types.
E: Cannot set mass for this atom style
This atom style does not support mass settings for each atom type.
Instead they are defined on a per-atom basis in the data file.
E: Invalid mass line in data file
Self-explanatory.
E: Invalid type for mass set
Mass command must set a type from 1-N where N is the number of atom
types.
E: Invalid mass value
Self-explanatory.
E: All masses are not set
For atom styles that define masses for each atom type, all masses must
be set in the data file or by the mass command before running a
simulation. They must also be set before using the velocity
command.
E: Atom sort did not operate correctly
This is an internal LAMMPS error. Please report it to the
developers.
E: Atom sorting has bin size = 0.0
The neighbor cutoff is being used as the bin size, but it is zero.
Thus you must explicitly list a bin size in the atom_modify sort
command or turn off sorting.
E: Too many atom sorting bins
This is likely due to an immense simulation box that has blown up
to a large size.
*/
diff --git a/src/atom_map.cpp b/src/atom_map.cpp
new file mode 100644
index 000000000..33caa8706
--- /dev/null
+++ b/src/atom_map.cpp
@@ -0,0 +1,298 @@
+/* ----------------------------------------------------------------------
+ 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 "atom.h"
+#include "comm.h"
+#include "memory.h"
+#include "error.h"
+
+using namespace LAMMPS_NS;
+
+#define EXTRA 1000
+
+/* ----------------------------------------------------------------------
+ allocate and initialize array or hash table for global -> local map
+ set map_tag_max = largest atom ID (may be larger than natoms)
+ for array option:
+ array length = 1 to largest tag of any atom
+ set entire array to -1 as initial values
+ for hash option:
+ map_nhash = length of hash table
+ map_nbucket = # of hash buckets, prime larger than map_nhash
+ so buckets will only be filled with 0 or 1 atoms on average
+------------------------------------------------------------------------- */
+
+void Atom::map_init()
+{
+ map_delete();
+
+ if (tag_enable == 0)
+ error->all(FLERR,"Cannot create an atom map unless atoms have IDs");
+
+ int max = 0;
+ for (int i = 0; i < nlocal; i++) max = MAX(max,tag[i]);
+ MPI_Allreduce(&max,&map_tag_max,1,MPI_INT,MPI_MAX,world);
+
+ memory->destroy(sametag);
+ smax = nlocal + nghost + EXTRA;
+ memory->create(sametag,smax,"atom:sametag");
+
+ if (map_style == 1) {
+ memory->create(map_array,map_tag_max+1,"atom:map_array");
+ for (int i = 0; i <= map_tag_max; i++) map_array[i] = -1;
+
+ } else {
+
+ // map_nhash = max # of atoms that can be hashed on this proc
+ // set to max of ave atoms/proc or atoms I can store
+ // multiply by 2, require at least 1000
+ // doubling means hash table will be re-init only rarely
+
+ int nper = static_cast<int> (natoms/comm->nprocs);
+ map_nhash = MAX(nper,nmax);
+ map_nhash *= 2;
+ map_nhash = MAX(map_nhash,1000);
+
+ // map_nbucket = prime just larger than map_nhash
+
+ map_nbucket = next_prime(map_nhash);
+
+ // set all buckets to empty
+ // set hash to map_nhash in length
+ // put all hash entries in free list and point them to each other
+
+ map_bucket = new int[map_nbucket];
+ for (int i = 0; i < map_nbucket; i++) map_bucket[i] = -1;
+
+ map_hash = new HashElem[map_nhash];
+ map_nused = 0;
+ map_free = 0;
+ for (int i = 0; i < map_nhash; i++) map_hash[i].next = i+1;
+ map_hash[map_nhash-1].next = -1;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ clear global -> local map for all of my own and ghost atoms
+ for hash table option:
+ global ID may not be in table if image atom was already cleared
+------------------------------------------------------------------------- */
+
+void Atom::map_clear()
+{
+ if (map_style == 1) {
+ int nall = nlocal + nghost;
+ for (int i = 0; i < nall; i++) {
+ sametag[i] = -1;
+ map_array[tag[i]] = -1;
+ }
+
+ } else {
+ int previous,global,ibucket,index;
+ int nall = nlocal + nghost;
+ for (int i = 0; i < nall; i++) {
+ sametag[i] = -1;
+
+ // search for key
+ // if don't find it, done
+
+ previous = -1;
+ global = tag[i];
+ ibucket = global % map_nbucket;
+ index = map_bucket[ibucket];
+ while (index > -1) {
+ if (map_hash[index].global == global) break;
+ previous = index;
+ index = map_hash[index].next;
+ }
+ if (index == -1) continue;
+
+ // delete the hash entry and add it to free list
+ // special logic if entry is 1st in the bucket
+
+ if (previous == -1) map_bucket[ibucket] = map_hash[index].next;
+ else map_hash[previous].next = map_hash[index].next;
+
+ map_hash[index].next = map_free;
+ map_free = index;
+ map_nused--;
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set global -> local map for all of my own and ghost atoms
+ loop in reverse order so that nearby images take precedence over far ones
+ and owned atoms take precedence over images
+ this enables valid lookups of bond topology atoms
+ for hash table option:
+ if hash table too small, re-init
+ global ID may already be in table if image atom was set
+------------------------------------------------------------------------- */
+
+void Atom::map_set()
+{
+ int nall = nlocal + nghost;
+ if (nall > smax) {
+ smax = nall + EXTRA;
+ memory->destroy(sametag);
+ memory->create(sametag,smax,"atom:sametag");
+ }
+
+ if (map_style == 1) {
+ for (int i = nall-1; i >= 0 ; i--) {
+ sametag[i] = map_array[tag[i]];
+ map_array[tag[i]] = i;
+ }
+
+ } else {
+ int previous,global,ibucket,index;
+ if (nall > map_nhash) map_init();
+
+ for (int i = nall-1; i >= 0 ; i--) {
+ sametag[i] = map_find_hash(tag[i]);
+
+ // search for key
+ // if found it, just overwrite local value with index
+
+ previous = -1;
+ global = tag[i];
+ ibucket = global % map_nbucket;
+ index = map_bucket[ibucket];
+ while (index > -1) {
+ if (map_hash[index].global == global) break;
+ previous = index;
+ index = map_hash[index].next;
+ }
+ if (index > -1) {
+ map_hash[index].local = i;
+ continue;
+ }
+
+ // take one entry from free list
+ // add the new global/local pair as entry at end of bucket list
+ // special logic if this entry is 1st in bucket
+
+ index = map_free;
+ map_free = map_hash[map_free].next;
+ if (previous == -1) map_bucket[ibucket] = index;
+ else map_hash[previous].next = index;
+ map_hash[index].global = global;
+ map_hash[index].local = i;
+ map_hash[index].next = -1;
+ map_nused++;
+ }
+ }
+}
+
+/* ----------------------------------------------------------------------
+ set global to local map for one atom
+ for hash table option:
+ global ID may already be in table if atom was already set
+ called by Special class
+------------------------------------------------------------------------- */
+
+void Atom::map_one(int global, int local)
+{
+ if (map_style == 1) map_array[global] = local;
+ else {
+ // search for key
+ // if found it, just overwrite local value with index
+
+ int previous = -1;
+ int ibucket = global % map_nbucket;
+ int index = map_bucket[ibucket];
+ while (index > -1) {
+ if (map_hash[index].global == global) break;
+ previous = index;
+ index = map_hash[index].next;
+ }
+ if (index > -1) {
+ map_hash[index].local = local;
+ return;
+ }
+
+ // take one entry from free list
+ // add the new global/local pair as entry at end of bucket list
+ // special logic if this entry is 1st in bucket
+
+ index = map_free;
+ map_free = map_hash[map_free].next;
+ if (previous == -1) map_bucket[ibucket] = index;
+ else map_hash[previous].next = index;
+ map_hash[index].global = global;
+ map_hash[index].local = local;
+ map_hash[index].next = -1;
+ map_nused++;
+ }
+}
+
+/* ----------------------------------------------------------------------
+ free the array or hash table for global to local mapping
+------------------------------------------------------------------------- */
+
+void Atom::map_delete()
+{
+ if (map_style == 1) {
+ if (map_tag_max) memory->destroy(map_array);
+ } else {
+ if (map_nhash) {
+ delete [] map_bucket;
+ delete [] map_hash;
+ }
+ map_nhash = 0;
+ }
+ map_tag_max = 0;
+}
+
+/* ----------------------------------------------------------------------
+ lookup global ID in hash table, return local index
+ called by map() in atom.h
+------------------------------------------------------------------------- */
+
+int Atom::map_find_hash(int global)
+{
+ int local = -1;
+ int index = map_bucket[global % map_nbucket];
+ while (index > -1) {
+ if (map_hash[index].global == global) {
+ local = map_hash[index].local;
+ break;
+ }
+ index = map_hash[index].next;
+ }
+ return local;
+}
+
+/* ----------------------------------------------------------------------
+ return next prime larger than n
+------------------------------------------------------------------------- */
+
+int Atom::next_prime(int n)
+{
+ int factor;
+
+ int nprime = n+1;
+ if (nprime % 2 == 0) nprime++;
+ int root = static_cast<int> (sqrt(1.0*n)) + 2;
+
+ while (nprime <= MAXSMALLINT) {
+ for (factor = 3; factor < root; factor++)
+ if (nprime % factor == 0) break;
+ if (factor == root) return nprime;
+ nprime += 2;
+ }
+
+ return MAXSMALLINT;
+}
diff --git a/src/atom_vec.h b/src/atom_vec.h
index b6ff39911..2904e9580 100644
--- a/src/atom_vec.h
+++ b/src/atom_vec.h
@@ -1,105 +1,105 @@
/* -*- c++ -*- ----------------------------------------------------------
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_VEC_H
#define LMP_ATOM_VEC_H
#include "pointers.h"
namespace LAMMPS_NS {
class AtomVec : protected Pointers {
public:
int molecular; // 0 = atomic, 1 = molecular system
int bonds_allow,angles_allow; // 1 if bonds, angles are used
int dihedrals_allow,impropers_allow; // 1 if dihedrals, impropers used
int mass_type; // 1 if per-type masses
int dipole_type; // 1 if per-type dipole moments
int comm_x_only; // 1 if only exchange x in forward comm
int comm_f_only; // 1 if only exchange f in reverse comm
int size_forward; // # of values per atom in comm
int size_reverse; // # in reverse comm
int size_border; // # in border comm
int size_velocity; // # of velocity based quantities
int size_data_atom; // number of values in Atom line
int size_data_vel; // number of values in Velocity line
int size_data_bonus; // number of values in Bonus line
int xcol_data; // column (1-N) where x is in Atom line
int cudable; // 1 if atom style is CUDA-enabled
int *maxsend; // CUDA-specific variable
AtomVec(class LAMMPS *, int, char **);
virtual ~AtomVec() {}
virtual void init();
virtual void grow(int) = 0;
virtual void grow_reset() = 0;
virtual void copy(int, int, int) = 0;
virtual void clear_bonus() {}
virtual int pack_comm(int, int *, double *, int, int *) = 0;
virtual int pack_comm_vel(int, int *, double *, int, int *) = 0;
virtual int pack_comm_hybrid(int, int *, double *) {return 0;}
virtual void unpack_comm(int, int, double *) = 0;
virtual void unpack_comm_vel(int, int, double *) = 0;
virtual int unpack_comm_hybrid(int, int, double *) {return 0;}
virtual int pack_reverse(int, int, double *) = 0;
virtual int pack_reverse_hybrid(int, int, double *) {return 0;}
virtual void unpack_reverse(int, int *, double *) = 0;
virtual int unpack_reverse_hybrid(int, int *, double *) {return 0;}
virtual int pack_border(int, int *, double *, int, int *) = 0;
virtual int pack_border_vel(int, int *, double *, int, int *) = 0;
virtual int pack_border_hybrid(int, int *, double *) {return 0;}
virtual void unpack_border(int, int, double *) = 0;
virtual void unpack_border_vel(int, int, double *) = 0;
virtual int unpack_border_hybrid(int, int, double *) {return 0;}
virtual int pack_exchange(int, double *) = 0;
virtual int unpack_exchange(double *) = 0;
virtual int size_restart() = 0;
virtual int pack_restart(int, double *) = 0;
virtual int unpack_restart(double *) = 0;
virtual void create_atom(int, double *) = 0;
- virtual void data_atom(double *, int, char **) = 0;
+ virtual void data_atom(double *, tagint, char **) = 0;
virtual void data_atom_bonus(int, char **) {}
virtual int data_atom_hybrid(int, char **) {return 0;}
virtual void data_vel(int, char **);
virtual int data_vel_hybrid(int, char **) {return 0;}
virtual bigint memory_usage() = 0;
protected:
int nmax; // local copy of atom->nmax
int deform_vremap; // local copy of domain properties
int deform_groupbit;
double *h_rate;
};
}
#endif
/* ERROR/WARNING messages:
E: USER-CUDA package requires a cuda enabled atom_style
Self-explanatory.
*/
diff --git a/src/atom_vec_atomic.cpp b/src/atom_vec_atomic.cpp
index 080a32c23..f9fe188e1 100644
--- a/src/atom_vec_atomic.cpp
+++ b/src/atom_vec_atomic.cpp
@@ -1,635 +1,636 @@
/* ----------------------------------------------------------------------
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
+ 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 "atom.h"
#include "comm.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
+ 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(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
if (atom->nextra_grow)
- for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ 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;
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecAtomic::copy(int i, int j, int delflag)
{
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++)
+ 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 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 pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz,dvx,dvy,dvz;
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;
}
if (!deform_vremap) {
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];
+ 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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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;
- if (mask[i] & deform_groupbit) {
- buf[m++] = v[j][0] + dvx;
- buf[m++] = v[j][1] + dvy;
- buf[m++] = v[j][2] + dvz;
- } else {
- buf[m++] = v[j][0];
- buf[m++] = v[j][1];
- buf[m++] = v[j][2];
- }
+ j = list[i];
+ buf[m++] = x[j][0] + dx;
+ buf[m++] = x[j][1] + dy;
+ buf[m++] = x[j][2] + dz;
+ if (mask[i] & deform_groupbit) {
+ buf[m++] = v[j][0] + dvx;
+ buf[m++] = v[j][1] + dvy;
+ buf[m++] = v[j][2] + dvz;
+ } else {
+ 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 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 pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz,dvx,dvy,dvz;
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];
}
if (!deform_vremap) {
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];
+ 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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
- if (mask[i] & deform_groupbit) {
- buf[m++] = v[j][0] + dvx;
- buf[m++] = v[j][1] + dvy;
- buf[m++] = v[j][2] + dvz;
- } else {
- buf[m++] = v[j][0];
- buf[m++] = v[j][1];
- buf[m++] = v[j][2];
- }
+ 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];
+ if (mask[i] & deform_groupbit) {
+ buf[m++] = v[j][0] + dvx;
+ buf[m++] = v[j][1] + dvy;
+ buf[m++] = v[j][2] + dvz;
+ } else {
+ 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
+ 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];
+ *((tagint *) &buf[m++]) = image[i];
if (atom->nextra_grow)
- for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ 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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
if (atom->nextra_grow)
- for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+ for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
m += modify->fix[atom->extra_grow[iextra]]->
- unpack_exchange(nlocal,&buf[m]);
+ 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 (int iextra = 0; iextra < atom->nextra_restart; iextra++)
for (i = 0; i < nlocal; i++)
- n += modify->fix[atom->extra_restart[iextra]]->size_restart(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
+ 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];
+ *((tagint *) &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++)
+ 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)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
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)
+void AtomVecAtomic::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
type[nlocal] = atoi(values[1]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
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
+ return # of bytes of allocated memory
------------------------------------------------------------------------- */
bigint AtomVecAtomic::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
return bytes;
}
diff --git a/src/atom_vec_atomic.h b/src/atom_vec_atomic.h
index 2455bae6d..d84a1ce70 100644
--- a/src/atom_vec_atomic.h
+++ b/src/atom_vec_atomic.h
@@ -1,78 +1,79 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(atomic,AtomVecAtomic)
#else
#ifndef LMP_ATOM_VEC_ATOMIC_H
#define LMP_ATOM_VEC_ATOMIC_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecAtomic : public AtomVec {
public:
AtomVecAtomic(class LAMMPS *, int, char **);
virtual ~AtomVecAtomic() {}
void grow(int);
void grow_reset();
void copy(int, int, int);
virtual int pack_comm(int, int *, double *, int, int *);
virtual int pack_comm_vel(int, int *, double *, int, int *);
virtual void unpack_comm(int, int, double *);
virtual void unpack_comm_vel(int, int, double *);
int pack_reverse(int, int, double *);
void unpack_reverse(int, int *, double *);
virtual int pack_border(int, int *, double *, int, int *);
virtual int pack_border_vel(int, int *, double *, int, int *);
virtual void unpack_border(int, int, double *);
virtual void unpack_border_vel(int, int, double *);
virtual int pack_exchange(int, double *);
virtual int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
bigint memory_usage();
protected:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
*/
diff --git a/src/atom_vec_charge.cpp b/src/atom_vec_charge.cpp
index b9ec7a185..07fa400d8 100644
--- a/src/atom_vec_charge.cpp
+++ b/src/atom_vec_charge.cpp
@@ -1,702 +1,703 @@
/* ----------------------------------------------------------------------
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 "atom.h"
#include "comm.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(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
q = memory->grow(atom->q,nmax,"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;
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecCharge::copy(int i, int j, int delflag)
{
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,dvx,dvy,dvz;
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;
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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;
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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,dvx,dvy,dvz;
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];
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
buf[m++] = v[j][0];
buf[m++] = v[j][1];
buf[m++] = v[j][2];
}
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecCharge::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = q[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
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_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++)
q[i] = buf[m++];
return 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 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];
+ *((tagint *) &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++]);
+ image[nlocal] = *((tagint *) &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];
+ *((tagint *) &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)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
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)
+void AtomVecCharge::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
type[nlocal] = atoi(values[1]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
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
------------------------------------------------------------------------- */
bigint AtomVecCharge::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("q")) bytes += memory->usage(q,nmax);
return bytes;
}
diff --git a/src/atom_vec_charge.h b/src/atom_vec_charge.h
index de96582f3..37c95b2e8 100644
--- a/src/atom_vec_charge.h
+++ b/src/atom_vec_charge.h
@@ -1,82 +1,83 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(charge,AtomVecCharge)
#else
#ifndef LMP_ATOM_VEC_CHARGE_H
#define LMP_ATOM_VEC_CHARGE_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecCharge : public AtomVec {
public:
AtomVecCharge(class LAMMPS *, int, char **);
virtual ~AtomVecCharge() {}
void grow(int);
void grow_reset();
void copy(int, int, int);
virtual int pack_comm(int, int *, double *, int, int *);
virtual int pack_comm_vel(int, int *, double *, int, int *);
virtual void unpack_comm(int, int, double *);
virtual void unpack_comm_vel(int, int, double *);
int pack_reverse(int, int, double *);
void unpack_reverse(int, int *, double *);
virtual int pack_border(int, int *, double *, int, int *);
virtual int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
virtual void unpack_border(int, int, double *);
virtual void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
virtual int pack_exchange(int, double *);
virtual int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
bigint memory_usage();
protected:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
double *q;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
*/
diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp
index fc0396ec6..da6bb87cc 100644
--- a/src/atom_vec_ellipsoid.cpp
+++ b/src/atom_vec_ellipsoid.cpp
@@ -1,1258 +1,1259 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Mike Brown (SNL)
------------------------------------------------------------------------- */
#include "stdlib.h"
#include "atom_vec_ellipsoid.h"
#include "math_extra.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define DELTA 10000
#define DELTA_BONUS 10000
/* ---------------------------------------------------------------------- */
AtomVecEllipsoid::AtomVecEllipsoid(LAMMPS *lmp, int narg, char **arg) :
AtomVec(lmp, narg, arg)
{
molecular = 0;
comm_x_only = comm_f_only = 0;
size_forward = 7;
size_reverse = 6;
size_border = 14;
size_velocity = 6;
size_data_atom = 7;
size_data_vel = 7;
size_data_bonus = 8;
xcol_data = 5;
atom->ellipsoid_flag = 1;
atom->rmass_flag = atom->angmom_flag = atom->torque_flag = 1;
nlocal_bonus = nghost_bonus = nmax_bonus = 0;
bonus = NULL;
}
/* ---------------------------------------------------------------------- */
AtomVecEllipsoid::~AtomVecEllipsoid()
{
memory->sfree(bonus);
}
/* ----------------------------------------------------------------------
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(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
rmass = memory->grow(atom->rmass,nmax,"atom:rmass");
angmom = memory->grow(atom->angmom,nmax,3,"atom:angmom");
torque = memory->grow(atom->torque,nmax*comm->nthreads,3,"atom:torque");
ellipsoid = memory->grow(atom->ellipsoid,nmax,"atom:ellipsoid");
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;
rmass = atom->rmass; angmom = atom->angmom; torque = atom->torque;
}
/* ----------------------------------------------------------------------
grow bonus data structure
------------------------------------------------------------------------- */
void AtomVecEllipsoid::grow_bonus()
{
nmax_bonus += DELTA_BONUS;
if (nmax_bonus < 0 || nmax_bonus > MAXSMALLINT)
error->one(FLERR,"Per-processor system is too big");
bonus = (Bonus *) memory->srealloc(bonus,nmax_bonus*sizeof(Bonus),
"atom:bonus");
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecEllipsoid::copy(int i, int j, int delflag)
{
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];
rmass[j] = rmass[i];
angmom[j][0] = angmom[i][0];
angmom[j][1] = angmom[i][1];
angmom[j][2] = angmom[i][2];
// if delflag and atom J has bonus data, then delete it
if (delflag && ellipsoid[j] >= 0) {
copy_bonus(nlocal_bonus-1,ellipsoid[j]);
nlocal_bonus--;
}
// if atom I has bonus data and not deleting I, repoint I's bonus to J
if (ellipsoid[i] >= 0 && i != j) bonus[ellipsoid[i]].ilocal = j;
ellipsoid[j] = ellipsoid[i];
if (atom->nextra_grow)
for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
}
/* ----------------------------------------------------------------------
copy bonus data from I to J, effectively deleting the J entry
insure index pointers between per-atom and bonus data are updated
------------------------------------------------------------------------- */
void AtomVecEllipsoid::copy_bonus(int i, int j)
{
memcpy(&bonus[j],&bonus[i],sizeof(Bonus));
ellipsoid[bonus[j].ilocal] = j;
}
/* ----------------------------------------------------------------------
clear ghost info in bonus data
called before ghosts are recommunicated in comm and irregular
------------------------------------------------------------------------- */
void AtomVecEllipsoid::clear_bonus()
{
nghost_bonus = 0;
}
/* ----------------------------------------------------------------------
set shape values in bonus data for particle I
oriented aligned with xyz axes
this may create or delete entry in bonus data
------------------------------------------------------------------------- */
void AtomVecEllipsoid::set_shape(int i,
double shapex, double shapey, double shapez)
{
if (ellipsoid[i] < 0) {
if (shapex == 0.0 && shapey == 0.0 && shapez == 0.0) return;
if (nlocal_bonus == nmax_bonus) grow_bonus();
double *shape = bonus[nlocal_bonus].shape;
double *quat = bonus[nlocal_bonus].quat;
shape[0] = shapex;
shape[1] = shapey;
shape[2] = shapez;
quat[0] = 1.0;
quat[1] = 0.0;
quat[2] = 0.0;
quat[3] = 0.0;
bonus[nlocal_bonus].ilocal = i;
ellipsoid[i] = nlocal_bonus++;
} else if (shapex == 0.0 && shapey == 0.0 && shapez == 0.0) {
copy_bonus(nlocal_bonus-1,ellipsoid[i]);
nlocal_bonus--;
ellipsoid[i] = -1;
} else {
double *shape = bonus[ellipsoid[i]].shape;
shape[0] = shapex;
shape[1] = shapey;
shape[2] = shapez;
}
}
/* ---------------------------------------------------------------------- */
int AtomVecEllipsoid::pack_comm(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz;
double *quat;
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];
if (ellipsoid[j] >= 0) {
quat = bonus[ellipsoid[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[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;
if (ellipsoid[j] >= 0) {
quat = bonus[ellipsoid[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[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,dvx,dvy,dvz;
double *quat;
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];
if (ellipsoid[j] >= 0) {
quat = bonus[ellipsoid[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[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;
}
if (!deform_vremap) {
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;
if (ellipsoid[j] >= 0) {
quat = bonus[ellipsoid[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[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 {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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;
if (ellipsoid[j] >= 0) {
quat = bonus[ellipsoid[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
}
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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_hybrid(int n, int *list, double *buf)
{
int i,j,m;
double *quat;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
if (ellipsoid[j] >= 0) {
quat = bonus[ellipsoid[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecEllipsoid::unpack_comm(int n, int first, double *buf)
{
int i,m,last;
double *quat;
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++];
if (ellipsoid[i] >= 0) {
quat = bonus[ellipsoid[i]].quat;
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
}
}
}
/* ---------------------------------------------------------------------- */
void AtomVecEllipsoid::unpack_comm_vel(int n, int first, double *buf)
{
int i,m,last;
double *quat;
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++];
if (ellipsoid[i] >= 0) {
quat = bonus[ellipsoid[i]].quat;
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[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_hybrid(int n, int first, double *buf)
{
int i,m,last;
double *quat;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
if (ellipsoid[i] >= 0) {
quat = bonus[ellipsoid[i]].quat;
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecEllipsoid::pack_reverse(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = f[i][0];
buf[m++] = f[i][1];
buf[m++] = f[i][2];
buf[m++] = torque[i][0];
buf[m++] = torque[i][1];
buf[m++] = torque[i][2];
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecEllipsoid::pack_reverse_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = torque[i][0];
buf[m++] = torque[i][1];
buf[m++] = torque[i][2];
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecEllipsoid::unpack_reverse(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
f[j][0] += buf[m++];
f[j][1] += buf[m++];
f[j][2] += buf[m++];
torque[j][0] += buf[m++];
torque[j][1] += buf[m++];
torque[j][2] += buf[m++];
}
}
/* ---------------------------------------------------------------------- */
int AtomVecEllipsoid::unpack_reverse_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
torque[j][0] += buf[m++];
torque[j][1] += buf[m++];
torque[j][2] += buf[m++];
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecEllipsoid::pack_border(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz;
double *shape,*quat;
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];
if (ellipsoid[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
shape = bonus[ellipsoid[j]].shape;
quat = bonus[ellipsoid[j]].quat;
buf[m++] = shape[0];
buf[m++] = shape[1];
buf[m++] = shape[2];
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[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];
if (ellipsoid[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
shape = bonus[ellipsoid[j]].shape;
quat = bonus[ellipsoid[j]].quat;
buf[m++] = shape[0];
buf[m++] = shape[1];
buf[m++] = shape[2];
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[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,dvx,dvy,dvz;
double *shape,*quat;
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];
if (ellipsoid[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
shape = bonus[ellipsoid[j]].shape;
quat = bonus[ellipsoid[j]].quat;
buf[m++] = shape[0];
buf[m++] = shape[1];
buf[m++] = shape[2];
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[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];
}
if (!deform_vremap) {
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];
if (ellipsoid[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
quat = bonus[ellipsoid[j]].quat;
buf[m++] = shape[0];
buf[m++] = shape[1];
buf[m++] = shape[2];
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[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 {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (ellipsoid[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
shape = bonus[ellipsoid[j]].shape;
quat = bonus[ellipsoid[j]].quat;
buf[m++] = shape[0];
buf[m++] = shape[1];
buf[m++] = shape[2];
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
}
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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_hybrid(int n, int *list, double *buf)
{
int i,j,m;
double *shape,*quat;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
if (ellipsoid[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
shape = bonus[ellipsoid[j]].shape;
quat = bonus[ellipsoid[j]].quat;
buf[m++] = shape[0];
buf[m++] = shape[1];
buf[m++] = shape[2];
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecEllipsoid::unpack_border(int n, int first, double *buf)
{
int i,j,m,last;
double *shape,*quat;
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++]);
ellipsoid[i] = static_cast<int> (buf[m++]);
if (ellipsoid[i] == 0) ellipsoid[i] = -1;
else {
j = nlocal_bonus + nghost_bonus;
if (j == nmax_bonus) grow_bonus();
shape = bonus[j].shape;
quat = bonus[j].quat;
shape[0] = buf[m++];
shape[1] = buf[m++];
shape[2] = buf[m++];
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
bonus[j].ilocal = i;
ellipsoid[i] = j;
nghost_bonus++;
}
}
}
/* ---------------------------------------------------------------------- */
void AtomVecEllipsoid::unpack_border_vel(int n, int first, double *buf)
{
int i,j,m,last;
double *shape,*quat;
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++]);
ellipsoid[i] = static_cast<int> (buf[m++]);
if (ellipsoid[i] == 0) ellipsoid[i] = -1;
else {
if (j == nmax_bonus) grow_bonus();
shape = bonus[j].shape;
quat = bonus[j].quat;
shape[0] = buf[m++];
shape[1] = buf[m++];
shape[2] = buf[m++];
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
bonus[j].ilocal = i;
ellipsoid[i] = j;
nghost_bonus++;
}
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_hybrid(int n, int first, double *buf)
{
int i,j,m,last;
double *shape,*quat;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
ellipsoid[i] = static_cast<int> (buf[m++]);
if (ellipsoid[i] == 0) ellipsoid[i] = -1;
else {
j = nlocal_bonus + nghost_bonus;
if (j == nmax_bonus) grow_bonus();
shape = bonus[j].shape;
quat = bonus[j].quat;
shape[0] = buf[m++];
shape[1] = buf[m++];
shape[2] = buf[m++];
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
bonus[j].ilocal = i;
ellipsoid[i] = j;
nghost_bonus++;
}
}
return m;
}
/* ----------------------------------------------------------------------
pack data for atom I for sending to another proc
xyz must be 1st 3 values, so comm::exchange() can test on them
------------------------------------------------------------------------- */
int AtomVecEllipsoid::pack_exchange(int i, double *buf)
{
int m = 1;
buf[m++] = x[i][0];
buf[m++] = x[i][1];
buf[m++] = x[i][2];
buf[m++] = v[i][0];
buf[m++] = v[i][1];
buf[m++] = v[i][2];
buf[m++] = tag[i];
buf[m++] = type[i];
buf[m++] = mask[i];
- buf[m++] = image[i];
+ *((tagint *) &buf[m++]) = image[i];
buf[m++] = rmass[i];
buf[m++] = angmom[i][0];
buf[m++] = angmom[i][1];
buf[m++] = angmom[i][2];
if (ellipsoid[i] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
int j = ellipsoid[i];
double *shape = bonus[j].shape;
double *quat = bonus[j].quat;
buf[m++] = shape[0];
buf[m++] = shape[1];
buf[m++] = shape[2];
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
}
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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
rmass[nlocal] = buf[m++];
angmom[nlocal][0] = buf[m++];
angmom[nlocal][1] = buf[m++];
angmom[nlocal][2] = buf[m++];
ellipsoid[nlocal] = static_cast<int> (buf[m++]);
if (ellipsoid[nlocal] == 0) ellipsoid[nlocal] = -1;
else {
if (nlocal_bonus == nmax_bonus) grow_bonus();
double *shape = bonus[nlocal_bonus].shape;
double *quat = bonus[nlocal_bonus].quat;
shape[0] = buf[m++];
shape[1] = buf[m++];
shape[2] = buf[m++];
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
bonus[nlocal_bonus].ilocal = nlocal;
ellipsoid[nlocal] = nlocal_bonus++;
}
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 n = 0;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++)
if (ellipsoid[i] >= 0) n += 23;
else n += 16;
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 bonus data
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];
+ *((tagint *) &buf[m++]) = image[i];
buf[m++] = v[i][0];
buf[m++] = v[i][1];
buf[m++] = v[i][2];
buf[m++] = rmass[i];
buf[m++] = angmom[i][0];
buf[m++] = angmom[i][1];
buf[m++] = angmom[i][2];
if (ellipsoid[i] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
int j = ellipsoid[i];
buf[m++] = bonus[j].shape[0];
buf[m++] = bonus[j].shape[1];
buf[m++] = bonus[j].shape[2];
buf[m++] = bonus[j].quat[0];
buf[m++] = bonus[j].quat[1];
buf[m++] = bonus[j].quat[2];
buf[m++] = bonus[j].quat[3];
}
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 bonus data
------------------------------------------------------------------------- */
int AtomVecEllipsoid::unpack_restart(double *buf)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) {
grow(0);
if (atom->nextra_store)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
v[nlocal][0] = buf[m++];
v[nlocal][1] = buf[m++];
v[nlocal][2] = buf[m++];
rmass[nlocal] = buf[m++];
angmom[nlocal][0] = buf[m++];
angmom[nlocal][1] = buf[m++];
angmom[nlocal][2] = buf[m++];
ellipsoid[nlocal] = static_cast<int> (buf[m++]);
if (ellipsoid[nlocal] == 0) ellipsoid[nlocal] = -1;
else {
if (nlocal_bonus == nmax_bonus) grow_bonus();
double *shape = bonus[nlocal_bonus].shape;
double *quat = bonus[nlocal_bonus].quat;
shape[0] = buf[m++];
shape[1] = buf[m++];
shape[2] = buf[m++];
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
bonus[nlocal_bonus].ilocal = nlocal;
ellipsoid[nlocal] = nlocal_bonus++;
}
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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
v[nlocal][0] = 0.0;
v[nlocal][1] = 0.0;
v[nlocal][2] = 0.0;
rmass[nlocal] = 1.0;
angmom[nlocal][0] = 0.0;
angmom[nlocal][1] = 0.0;
angmom[nlocal][2] = 0.0;
ellipsoid[nlocal] = -1;
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)
+void AtomVecEllipsoid::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
type[nlocal] = atoi(values[1]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
ellipsoid[nlocal] = atoi(values[2]);
if (ellipsoid[nlocal] == 0) ellipsoid[nlocal] = -1;
else if (ellipsoid[nlocal] == 1) ellipsoid[nlocal] = 0;
else error->one(FLERR,"Invalid atom type in Atoms section of data file");
rmass[nlocal] = atof(values[3]);
if (rmass[nlocal] <= 0.0)
error->one(FLERR,"Invalid density 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;
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)
{
ellipsoid[nlocal] = atoi(values[0]);
if (ellipsoid[nlocal] == 0) ellipsoid[nlocal] = -1;
else if (ellipsoid[nlocal] == 1) ellipsoid[nlocal] = 0;
else error->one(FLERR,"Invalid atom type in Atoms section of data file");
rmass[nlocal] = atof(values[1]);
if (rmass[nlocal] <= 0.0)
error->one(FLERR,"Invalid density in Atoms section of data file");
return 2;
}
/* ----------------------------------------------------------------------
unpack one line from Ellipsoids section of data file
------------------------------------------------------------------------- */
void AtomVecEllipsoid::data_atom_bonus(int m, char **values)
{
if (ellipsoid[m])
error->one(FLERR,"Assigning ellipsoid parameters to non-ellipsoid atom");
if (nlocal_bonus == nmax_bonus) grow_bonus();
double *shape = bonus[nlocal_bonus].shape;
shape[0] = 0.5 * atof(values[0]);
shape[1] = 0.5 * atof(values[1]);
shape[2] = 0.5 * atof(values[2]);
if (shape[0] <= 0.0 || shape[1] <= 0.0 || shape[2] <= 0.0)
error->one(FLERR,"Invalid shape in Ellipsoids section of data file");
double *quat = bonus[nlocal_bonus].quat;
quat[0] = atof(values[3]);
quat[1] = atof(values[4]);
quat[2] = atof(values[5]);
quat[3] = atof(values[6]);
MathExtra::qnormalize(quat);
// reset ellipsoid mass
// previously stored density in rmass
rmass[m] *= 4.0*MY_PI/3.0 * shape[0]*shape[1]*shape[2];
bonus[nlocal_bonus].ilocal = m;
ellipsoid[m] = nlocal_bonus++;
}
/* ----------------------------------------------------------------------
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
------------------------------------------------------------------------- */
bigint AtomVecEllipsoid::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax);
if (atom->memcheck("angmom")) bytes += memory->usage(angmom,nmax,3);
if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax*comm->nthreads,3);
if (atom->memcheck("ellipsoid")) bytes += memory->usage(ellipsoid,nmax);
bytes += nmax_bonus*sizeof(Bonus);
return bytes;
}
diff --git a/src/atom_vec_ellipsoid.h b/src/atom_vec_ellipsoid.h
index e57ae9596..3b254911f 100755
--- a/src/atom_vec_ellipsoid.h
+++ b/src/atom_vec_ellipsoid.h
@@ -1,123 +1,124 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(ellipsoid,AtomVecEllipsoid)
#else
#ifndef LMP_ATOM_VEC_ELLIPSOID_H
#define LMP_ATOM_VEC_ELLIPSOID_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecEllipsoid : public AtomVec {
public:
struct Bonus {
double shape[3];
double quat[4];
int ilocal;
};
struct Bonus *bonus;
AtomVecEllipsoid(class LAMMPS *, int, char **);
~AtomVecEllipsoid();
void grow(int);
void grow_reset();
void copy(int, int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
int pack_comm_hybrid(int, int *, double *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int unpack_comm_hybrid(int, int, double *);
int pack_reverse(int, int, double *);
int pack_reverse_hybrid(int, int, double *);
void unpack_reverse(int, int *, double *);
int unpack_reverse_hybrid(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
void data_vel(int, char **);
int data_vel_hybrid(int, char **);
bigint memory_usage();
// manipulate Bonus data structure for extra atom info
void clear_bonus();
void data_atom_bonus(int, char **);
// unique to AtomVecEllipsoid
void set_shape(int, double, double, double);
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
double *rmass;
double **angmom,**torque;
int *ellipsoid;
int nlocal_bonus,nghost_bonus,nmax_bonus;
void grow_bonus();
void copy_bonus(int, int);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
E: Invalid density in Atoms section of data file
Density value cannot be <= 0.0.
E: Assigning ellipsoid parameters to non-ellipsoid atom
Self-explanatory.
E: Invalid shape in Ellipsoids section of data file
Self-explanatory.
*/
diff --git a/src/atom_vec_hybrid.cpp b/src/atom_vec_hybrid.cpp
index fc93450c8..05351cf76 100644
--- a/src/atom_vec_hybrid.cpp
+++ b/src/atom_vec_hybrid.cpp
@@ -1,875 +1,875 @@
/* ----------------------------------------------------------------------
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 "atom.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define DELTA 10000
/* ---------------------------------------------------------------------- */
AtomVecHybrid::AtomVecHybrid(LAMMPS *lmp, int narg, char **arg) :
AtomVec(lmp, narg, arg)
{
int i,k,dummy;
if (narg < 1) error->all(FLERR,"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(FLERR,"Atom style hybrid cannot use same atom style twice");
if (strcmp(arg[i],"hybrid") == 0)
error->all(FLERR,"Atom style hybrid cannot have hybrid as an argument");
styles[i] = atom->new_avec(arg[i],0,NULL,NULL,dummy);
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);
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;
}
/* ---------------------------------------------------------------------- */
void AtomVecHybrid::init()
{
AtomVec::init();
for (int k = 0; k < nstyles; k++) styles[k]->init();
}
/* ----------------------------------------------------------------------
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(FLERR,"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 atom I info to atom J for all sub-styles
------------------------------------------------------------------------- */
void AtomVecHybrid::copy(int i, int j, int delflag)
{
int tmp = atom->nextra_grow;
atom->nextra_grow = 0;
for (int k = 0; k < nstyles; k++) styles[k]->copy(i,j,delflag);
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);
}
/* ---------------------------------------------------------------------- */
void AtomVecHybrid::clear_bonus()
{
for (int k = 0; k < nstyles; k++) styles[k]->clear_bonus();
}
/* ---------------------------------------------------------------------- */
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];
}
} 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;
}
}
// pack sub-style contributions as contiguous chunks
for (k = 0; k < nstyles; k++)
m += styles[k]->pack_comm_hybrid(n,list,&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,dvx,dvy,dvz;
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];
}
}
} 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;
}
if (!deform_vremap) {
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];
}
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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;
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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];
}
}
}
}
// pack sub-style contributions as contiguous chunks
for (k = 0; k < nstyles; k++)
m += styles[k]->pack_comm_hybrid(n,list,&buf[m]);
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecHybrid::unpack_comm(int n, int first, double *buf)
{
int i,k,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++];
}
// unpack sub-style contributions as contiguous chunks
for (k = 0; k < nstyles; k++)
m += styles[k]->unpack_comm_hybrid(n,first,&buf[m]);
}
/* ---------------------------------------------------------------------- */
void AtomVecHybrid::unpack_comm_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++) {
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++];
}
}
// unpack sub-style contributions as contiguous chunks
for (k = 0; k < nstyles; k++)
m += styles[k]->unpack_comm_hybrid(n,first,&buf[m]);
}
/* ---------------------------------------------------------------------- */
int AtomVecHybrid::pack_reverse(int n, int first, double *buf)
{
int i,k,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];
}
// pack sub-style contributions as contiguous chunks
for (k = 0; k < nstyles; k++)
m += styles[k]->pack_reverse_hybrid(n,first,&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++];
}
// unpack sub-style contributions as contiguous chunks
for (k = 0; k < nstyles; k++)
m += styles[k]->unpack_reverse_hybrid(n,list,&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];
}
} 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];
}
}
// pack sub-style contributions as contiguous chunks
for (k = 0; k < nstyles; k++)
m += styles[k]->pack_border_hybrid(n,list,&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,dvx,dvy,dvz;
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];
}
}
} 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];
}
if (!deform_vremap) {
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];
}
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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];
}
}
}
}
// pack sub-style contributions as contiguous chunks
for (k = 0; k < nstyles; k++)
m += styles[k]->pack_border_hybrid(n,list,&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++]);
}
// unpack sub-style contributions as contiguous chunks
for (k = 0; k < nstyles; k++)
m += styles[k]->unpack_border_hybrid(n,first,&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++];
}
}
// unpack sub-style contributions as contiguous chunks
for (k = 0; k < nstyles; k++)
m += styles[k]->unpack_border_hybrid(n,first,&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,m;
int tmp = atom->nextra_grow;
atom->nextra_grow = 0;
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 k,m;
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
int tmp = atom->nextra_grow;
atom->nextra_grow = 0;
m = 0;
for (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)
memory->grow(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)
+void AtomVecHybrid::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
type[nlocal] = atoi(values[1]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
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
------------------------------------------------------------------------- */
bigint AtomVecHybrid::memory_usage()
{
bigint bytes = 0;
for (int k = 0; k < nstyles; k++) bytes += styles[k]->memory_usage();
return bytes;
}
diff --git a/src/atom_vec_hybrid.h b/src/atom_vec_hybrid.h
index 671137c3f..aea900bbe 100644
--- a/src/atom_vec_hybrid.h
+++ b/src/atom_vec_hybrid.h
@@ -1,101 +1,102 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(hybrid,AtomVecHybrid)
#else
#ifndef LMP_ATOM_VEC_HYBRID_H
#define LMP_ATOM_VEC_HYBRID_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecHybrid : public AtomVec {
public:
int nstyles;
class AtomVec **styles;
char **keywords;
AtomVecHybrid(class LAMMPS *, int, char **);
~AtomVecHybrid();
void init();
void grow(int);
void grow_reset();
void copy(int, int, int);
void clear_bonus();
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int pack_reverse(int, int, double *);
void unpack_reverse(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **) {return 0;}
void data_vel(int, char **);
bigint memory_usage();
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
double **omega,**angmom;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Atom style hybrid cannot use same atom style twice
Self-explanatory.
E: Atom style hybrid cannot have hybrid as an argument
Self-explanatory.
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
*/
diff --git a/src/atom_vec_line.cpp b/src/atom_vec_line.cpp
index 55997b990..e1a3bc4be 100644
--- a/src/atom_vec_line.cpp
+++ b/src/atom_vec_line.cpp
@@ -1,1168 +1,1169 @@
/* ----------------------------------------------------------------------
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_line.h"
#include "atom.h"
#include "comm.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
#define DELTA_BONUS 10000
#define EPSILON 0.001
/* ---------------------------------------------------------------------- */
AtomVecLine::AtomVecLine(LAMMPS *lmp, int narg, char **arg) :
AtomVec(lmp, narg, arg)
{
molecular = 0;
comm_x_only = comm_f_only = 0;
size_forward = 4;
size_reverse = 6;
size_border = 10;
size_velocity = 6;
size_data_atom = 8;
size_data_vel = 7;
size_data_bonus = 5;
xcol_data = 6;
atom->line_flag = 1;
atom->molecule_flag = atom->rmass_flag = 1;
atom->omega_flag = atom->torque_flag = 1;
nlocal_bonus = nghost_bonus = nmax_bonus = 0;
bonus = NULL;
}
/* ---------------------------------------------------------------------- */
AtomVecLine::~AtomVecLine()
{
memory->sfree(bonus);
}
/* ---------------------------------------------------------------------- */
void AtomVecLine::init()
{
AtomVec::init();
if (domain->dimension != 2)
error->all(FLERR,"Atom_style line can only be used in 2d simulations");
}
/* ----------------------------------------------------------------------
grow atom arrays
n = 0 grows arrays by DELTA
n > 0 allocates arrays to size n
------------------------------------------------------------------------- */
void AtomVecLine::grow(int n)
{
if (n == 0) nmax += DELTA;
else nmax = n;
atom->nmax = nmax;
if (nmax < 0 || nmax > MAXSMALLINT)
error->one(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
molecule = memory->grow(atom->molecule,nmax,"atom:molecule");
rmass = memory->grow(atom->rmass,nmax,"atom:rmass");
omega = memory->grow(atom->omega,nmax,3,"atom:omega");
torque = memory->grow(atom->torque,nmax*comm->nthreads,3,"atom:torque");
line = memory->grow(atom->line,nmax,"atom:line");
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 AtomVecLine::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; rmass = atom->rmass;
omega = atom->omega; torque = atom->torque;
}
/* ----------------------------------------------------------------------
grow bonus data structure
------------------------------------------------------------------------- */
void AtomVecLine::grow_bonus()
{
nmax_bonus += DELTA_BONUS;
if (nmax_bonus < 0 || nmax_bonus > MAXSMALLINT)
error->one(FLERR,"Per-processor system is too big");
bonus = (Bonus *) memory->srealloc(bonus,nmax_bonus*sizeof(Bonus),
"atom:bonus");
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecLine::copy(int i, int j, int delflag)
{
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];
rmass[j] = rmass[i];
omega[j][0] = omega[i][0];
omega[j][1] = omega[i][1];
omega[j][2] = omega[i][2];
// if delflag and atom J has bonus data, then delete it
if (delflag && line[j] >= 0) {
copy_bonus(nlocal_bonus-1,line[j]);
nlocal_bonus--;
}
// if atom I has bonus data and not deleting I, repoint I's bonus to J
if (line[i] >= 0 && i != j) bonus[line[i]].ilocal = j;
line[j] = line[i];
if (atom->nextra_grow)
for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
}
/* ----------------------------------------------------------------------
copy bonus data from I to J, effectively deleting the J entry
insure index pointers between per-atom and bonus data are updated
------------------------------------------------------------------------- */
void AtomVecLine::copy_bonus(int i, int j)
{
memcpy(&bonus[j],&bonus[i],sizeof(Bonus));
line[bonus[j].ilocal] = j;
}
/* ----------------------------------------------------------------------
clear ghost info in bonus data
called before ghosts are recommunicated in comm and irregular
------------------------------------------------------------------------- */
void AtomVecLine::clear_bonus()
{
nghost_bonus = 0;
}
/* ----------------------------------------------------------------------
set length value in bonus data for particle I
oriented along x axis
this may create or delete entry in bonus data
------------------------------------------------------------------------- */
void AtomVecLine::set_length(int i, double value)
{
if (line[i] < 0) {
if (value == 0.0) return;
if (nlocal_bonus == nmax_bonus) grow_bonus();
bonus[nlocal_bonus].length = value;
bonus[nlocal_bonus].theta = 0.0;
bonus[nlocal_bonus].ilocal = i;
line[i] = nlocal_bonus++;
} else if (value == 0.0) {
copy_bonus(nlocal_bonus-1,line[i]);
nlocal_bonus--;
line[i] = -1;
} else bonus[line[i]].length = value;
}
/* ---------------------------------------------------------------------- */
int AtomVecLine::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];
if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
}
} 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;
if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecLine::pack_comm_vel(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz,dvx,dvy,dvz;
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];
if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
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;
}
if (!deform_vremap) {
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;
if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
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 {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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;
if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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 AtomVecLine::pack_comm_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
if (line[j] >= 0) buf[m++] = bonus[line[j]].theta;
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecLine::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++];
if (line[i] >= 0) bonus[line[i]].theta = buf[m++];
}
}
/* ---------------------------------------------------------------------- */
void AtomVecLine::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++];
if (line[i] >= 0) bonus[line[i]].theta = 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 AtomVecLine::unpack_comm_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++)
if (line[i] >= 0) bonus[line[i]].theta = buf[m++];
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecLine::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 AtomVecLine::pack_reverse_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = torque[i][0];
buf[m++] = torque[i][1];
buf[m++] = torque[i][2];
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecLine::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 AtomVecLine::unpack_reverse_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
torque[j][0] += buf[m++];
torque[j][1] += buf[m++];
torque[j][2] += buf[m++];
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecLine::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];
if (line[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
buf[m++] = bonus[line[j]].length;
buf[m++] = bonus[line[j]].theta;
}
}
} 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];
if (line[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
buf[m++] = bonus[line[j]].length;
buf[m++] = bonus[line[j]].theta;
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecLine::pack_border_vel(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz,dvx,dvy,dvz;
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];
if (line[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
buf[m++] = bonus[line[j]].length;
buf[m++] = bonus[line[j]].theta;
}
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];
}
if (!deform_vremap) {
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];
if (line[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
buf[m++] = bonus[line[j]].length;
buf[m++] = bonus[line[j]].theta;
}
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 {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (line[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
buf[m++] = bonus[line[j]].length;
buf[m++] = bonus[line[j]].theta;
}
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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 AtomVecLine::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = molecule[j];
if (line[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
buf[m++] = bonus[line[j]].length;
buf[m++] = bonus[line[j]].theta;
}
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecLine::unpack_border(int n, int first, double *buf)
{
int i,j,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++]);
line[i] = static_cast<int> (buf[m++]);
if (line[i] == 0) line[i] = -1;
else {
j = nlocal_bonus + nghost_bonus;
if (j == nmax_bonus) grow_bonus();
bonus[j].length = buf[m++];
bonus[j].theta = buf[m++];
bonus[j].ilocal = i;
line[i] = j;
nghost_bonus++;
}
}
}
/* ---------------------------------------------------------------------- */
void AtomVecLine::unpack_border_vel(int n, int first, double *buf)
{
int i,j,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++]);
line[i] = static_cast<int> (buf[m++]);
if (line[i] == 0) line[i] = -1;
else {
j = nlocal_bonus + nghost_bonus;
if (j == nmax_bonus) grow_bonus();
bonus[j].length = buf[m++];
bonus[j].theta = buf[m++];
bonus[j].ilocal = i;
line[i] = j;
nghost_bonus++;
}
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 AtomVecLine::unpack_border_hybrid(int n, int first, double *buf)
{
int i,j,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
molecule[i] = static_cast<int> (buf[m++]);
line[i] = static_cast<int> (buf[m++]);
if (line[i] == 0) line[i] = -1;
else {
j = nlocal_bonus + nghost_bonus;
if (j == nmax_bonus) grow_bonus();
bonus[j].length = buf[m++];
bonus[j].theta = buf[m++];
bonus[j].ilocal = i;
line[i] = j;
nghost_bonus++;
}
}
return 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 AtomVecLine::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];
+ *((tagint *) &buf[m++]) = image[i];
buf[m++] = molecule[i];
buf[m++] = rmass[i];
buf[m++] = omega[i][0];
buf[m++] = omega[i][1];
buf[m++] = omega[i][2];
if (line[i] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
int j = line[i];
buf[m++] = bonus[j].length;
buf[m++] = bonus[j].theta;
}
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 AtomVecLine::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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
molecule[nlocal] = static_cast<int> (buf[m++]);
rmass[nlocal] = buf[m++];
omega[nlocal][0] = buf[m++];
omega[nlocal][1] = buf[m++];
omega[nlocal][2] = buf[m++];
line[nlocal] = static_cast<int> (buf[m++]);
if (line[nlocal] == 0) line[nlocal] = -1;
else {
if (nlocal_bonus == nmax_bonus) grow_bonus();
bonus[nlocal_bonus].length = buf[m++];
bonus[nlocal_bonus].theta = buf[m++];
bonus[nlocal_bonus].ilocal = nlocal;
line[nlocal] = nlocal_bonus++;
}
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 AtomVecLine::size_restart()
{
int i;
int n = 0;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++)
if (line[i] >= 0) n += 19;
else n += 17;
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 AtomVecLine::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];
+ *((tagint *) &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++] = rmass[i];
buf[m++] = omega[i][0];
buf[m++] = omega[i][1];
buf[m++] = omega[i][2];
if (line[i] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
int j = line[i];
buf[m++] = bonus[j].length;
buf[m++] = bonus[j].theta;
}
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 AtomVecLine::unpack_restart(double *buf)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) {
grow(0);
if (atom->nextra_store)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
v[nlocal][0] = buf[m++];
v[nlocal][1] = buf[m++];
v[nlocal][2] = buf[m++];
molecule[nlocal] = static_cast<int> (buf[m++]);
rmass[nlocal] = buf[m++];
omega[nlocal][0] = buf[m++];
omega[nlocal][1] = buf[m++];
omega[nlocal][2] = buf[m++];
line[nlocal] = static_cast<int> (buf[m++]);
if (line[nlocal] == 0) line[nlocal] = -1;
else {
if (nlocal_bonus == nmax_bonus) grow_bonus();
bonus[nlocal_bonus].length = buf[m++];
bonus[nlocal_bonus].theta = buf[m++];
bonus[nlocal_bonus].ilocal = nlocal;
line[nlocal] = nlocal_bonus++;
}
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 AtomVecLine::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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
v[nlocal][0] = 0.0;
v[nlocal][1] = 0.0;
v[nlocal][2] = 0.0;
molecule[nlocal] = 0;
rmass[nlocal] = 1.0;
omega[nlocal][0] = 0.0;
omega[nlocal][1] = 0.0;
omega[nlocal][2] = 0.0;
line[nlocal] = -1;
atom->nlocal++;
}
/* ----------------------------------------------------------------------
unpack one line from Atoms section of data file
initialize other atom quantities
------------------------------------------------------------------------- */
-void AtomVecLine::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecLine::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
molecule[nlocal] = atoi(values[1]);
type[nlocal] = atoi(values[2]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
line[nlocal] = atoi(values[3]);
if (line[nlocal] == 0) line[nlocal] = -1;
else if (line[nlocal] == 1) line[nlocal] = 0;
else error->one(FLERR,"Invalid atom type in Atoms section of data file");
rmass[nlocal] = atof(values[4]);
if (rmass[nlocal] <= 0.0)
error->one(FLERR,"Invalid density 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 hybrid quantities from one line in Atoms section of data file
initialize other atom quantities for this sub-style
------------------------------------------------------------------------- */
int AtomVecLine::data_atom_hybrid(int nlocal, char **values)
{
molecule[nlocal] = atoi(values[0]);
line[nlocal] = atoi(values[1]);
if (line[nlocal] == 0) line[nlocal] = -1;
else if (line[nlocal] == 1) line[nlocal] = 0;
else error->one(FLERR,"Invalid atom type in Atoms section of data file");
rmass[nlocal] = atof(values[2]);
if (rmass[nlocal] <= 0.0)
error->one(FLERR,"Invalid density in Atoms section of data file");
return 3;
}
/* ----------------------------------------------------------------------
unpack one line from Lines section of data file
------------------------------------------------------------------------- */
void AtomVecLine::data_atom_bonus(int m, char **values)
{
if (line[m]) error->one(FLERR,"Assigning line parameters to non-line atom");
if (nlocal_bonus == nmax_bonus) grow_bonus();
double x1 = atof(values[0]);
double y1 = atof(values[1]);
double x2 = atof(values[2]);
double y2 = atof(values[3]);
double dx = x2 - x1;
double dy = y2 - y1;
double length = sqrt(dx*dx + dy*dy);
bonus[nlocal_bonus].length = length;
if (dy >= 0.0) bonus[nlocal_bonus].theta = acos(dx/length);
else bonus[nlocal_bonus].theta = -acos(dx/length);
double xc = 0.5*(x1+x2);
double yc = 0.5*(y1+y2);
dx = xc - x[m][0];
dy = yc - x[m][1];
double delta = sqrt(dx*dx + dy*dy);
if (delta/length > EPSILON)
error->one(FLERR,"Inconsistent line segment in data file");
x[m][0] = xc;
x[m][1] = yc;
// reset line mass
// previously stored density in rmass
rmass[m] *= length;
bonus[nlocal_bonus].ilocal = m;
line[m] = nlocal_bonus++;
}
/* ----------------------------------------------------------------------
unpack one line from Velocities section of data file
------------------------------------------------------------------------- */
void AtomVecLine::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 AtomVecLine::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
------------------------------------------------------------------------- */
bigint AtomVecLine::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax);
if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax);
if (atom->memcheck("omega")) bytes += memory->usage(omega,nmax,3);
if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax*comm->nthreads,3);
if (atom->memcheck("line")) bytes += memory->usage(line,nmax);
bytes += nmax_bonus*sizeof(Bonus);
return bytes;
}
/* ----------------------------------------------------------------------
check consistency of internal Bonus data structure
n = # of atoms in regular structure to check against
------------------------------------------------------------------------- */
/*
void AtomVecLine::consistency_check(int n, char *str)
{
int iflag = 0;
int count = 0;
for (int i = 0; i < n; i++) {
if (line[i] >= 0) {
count++;
if (line[i] >= nlocal_bonus) iflag++;
if (bonus[line[i]].ilocal != i) iflag++;
//if (comm->me == 1 && update->ntimestep == 873)
// printf("CCHK %s: %d %d: %d %d: %d %d\n",
// str,i,n,line[i],nlocal_bonus,bonus[line[i]].ilocal,iflag);
}
}
if (iflag) {
printf("BAD vecline ptrs: %s: %d %d: %d\n",str,comm->me,
update->ntimestep,iflag);
MPI_Abort(world,1);
}
if (count != nlocal_bonus) {
char msg[128];
printf("BAD vecline count: %s: %d %d: %d %d\n",
str,comm->me,update->ntimestep,count,nlocal_bonus);
MPI_Abort(world,1);
}
}
*/
diff --git a/src/atom_vec_line.h b/src/atom_vec_line.h
index 0b8daf5b1..761c7da5f 100644
--- a/src/atom_vec_line.h
+++ b/src/atom_vec_line.h
@@ -1,130 +1,131 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(line,AtomVecLine)
#else
#ifndef LMP_ATOM_VEC_LINE_H
#define LMP_ATOM_VEC_LINE_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecLine : public AtomVec {
public:
struct Bonus {
double length,theta;
int ilocal;
};
struct Bonus *bonus;
AtomVecLine(class LAMMPS *, int, char **);
~AtomVecLine();
void init();
void grow(int);
void grow_reset();
void copy(int, int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
int pack_comm_hybrid(int, int *, double *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int unpack_comm_hybrid(int, int, double *);
int pack_reverse(int, int, double *);
int pack_reverse_hybrid(int, int, double *);
void unpack_reverse(int, int *, double *);
int unpack_reverse_hybrid(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
void data_vel(int, char **);
int data_vel_hybrid(int, char **);
bigint memory_usage();
// manipulate Bonus data structure for extra atom info
void clear_bonus();
void data_atom_bonus(int, char **);
// unique to AtomVecLine
void set_length(int, double);
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
int *molecule;
double *rmass;
double **omega,**torque;
int *line;
int nlocal_bonus,nghost_bonus,nmax_bonus;
void grow_bonus();
void copy_bonus(int, int);
// void consistency_check(int, char *);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Atom_style line can only be used in 2d simulations
Self-explanatory.
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
E: Invalid density in Atoms section of data file
Density value cannot be <= 0.0.
E: Assigning line parameters to non-line atom
Self-explanatory.
E: Inconsistent line segment in data file
The end points of the line segment are not equal distances from the
center point which is the atom coordinate.
*/
diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp
index f77a7e091..5d085c0cf 100644
--- a/src/atom_vec_sphere.cpp
+++ b/src/atom_vec_sphere.cpp
@@ -1,1058 +1,1059 @@
/* ----------------------------------------------------------------------
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_sphere.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "modify.h"
#include "force.h"
#include "fix.h"
#include "fix_adapt.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define DELTA 10000
/* ---------------------------------------------------------------------- */
AtomVecSphere::AtomVecSphere(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->sphere_flag = 1;
atom->radius_flag = atom->rmass_flag = atom->omega_flag =
atom->torque_flag = 1;
}
/* ---------------------------------------------------------------------- */
void AtomVecSphere::init()
{
AtomVec::init();
// set radvary if particle diameters are time-varying due to fix adapt
radvary = 0;
comm_x_only = 1;
size_forward = 3;
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;
comm_x_only = 0;
size_forward = 5;
}
}
}
/* ----------------------------------------------------------------------
grow atom arrays
n = 0 grows arrays by DELTA
n > 0 allocates arrays to size n
------------------------------------------------------------------------- */
void AtomVecSphere::grow(int n)
{
if (n == 0) nmax += DELTA;
else nmax = n;
atom->nmax = nmax;
if (nmax < 0 || nmax > MAXSMALLINT)
error->one(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
radius = memory->grow(atom->radius,nmax,"atom:radius");
rmass = memory->grow(atom->rmass,nmax,"atom:rmass");
omega = memory->grow(atom->omega,nmax,3,"atom:omega");
torque = memory->grow(atom->torque,nmax*comm->nthreads,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 AtomVecSphere::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; rmass = atom->rmass;
omega = atom->omega; torque = atom->torque;
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
------------------------------------------------------------------------- */
void AtomVecSphere::copy(int i, int j, int delflag)
{
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];
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 AtomVecSphere::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 AtomVecSphere::pack_comm_vel(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz,dvx,dvy,dvz;
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;
}
if (!deform_vremap) {
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 {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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;
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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;
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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++] = radius[j];
buf[m++] = rmass[j];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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 AtomVecSphere::pack_comm_hybrid(int n, int *list, double *buf)
{
int i,j,m;
if (radvary == 0) return 0;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = radius[j];
buf[m++] = rmass[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecSphere::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 AtomVecSphere::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 AtomVecSphere::unpack_comm_hybrid(int n, int first, double *buf)
{
int i,m,last;
if (radvary == 0) return 0;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
radius[i] = buf[m++];
rmass[i] = buf[m++];
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecSphere::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 AtomVecSphere::pack_reverse_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = torque[i][0];
buf[m++] = torque[i][1];
buf[m++] = torque[i][2];
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecSphere::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 AtomVecSphere::unpack_reverse_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
torque[j][0] += buf[m++];
torque[j][1] += buf[m++];
torque[j][2] += buf[m++];
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecSphere::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 AtomVecSphere::pack_border_vel(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz,dvx,dvy,dvz;
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];
}
if (!deform_vremap) {
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];
}
} else {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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 AtomVecSphere::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = radius[j];
buf[m++] = rmass[j];
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecSphere::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 AtomVecSphere::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 AtomVecSphere::unpack_border_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
radius[i] = buf[m++];
rmass[i] = buf[m++];
}
return 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 AtomVecSphere::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];
+ *((tagint *) &buf[m++]) = image[i];
buf[m++] = radius[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 AtomVecSphere::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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
radius[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 AtomVecSphere::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 AtomVecSphere::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];
+ *((tagint *) &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++] = rmass[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 AtomVecSphere::unpack_restart(double *buf)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) {
grow(0);
if (atom->nextra_store)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
v[nlocal][0] = buf[m++];
v[nlocal][1] = buf[m++];
v[nlocal][2] = buf[m++];
radius[nlocal] = buf[m++];
rmass[nlocal] = 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 AtomVecSphere::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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
v[nlocal][0] = 0.0;
v[nlocal][1] = 0.0;
v[nlocal][2] = 0.0;
radius[nlocal] = 0.5;
rmass[nlocal] = 4.0*MY_PI/3.0 * radius[nlocal]*radius[nlocal]*radius[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 AtomVecSphere::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecSphere::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
type[nlocal] = atoi(values[1]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
radius[nlocal] = 0.5 * atof(values[2]);
if (radius[nlocal] < 0.0)
error->one(FLERR,"Invalid radius in Atoms section of data file");
double density = atof(values[3]);
if (density <= 0.0)
error->one(FLERR,"Invalid density in Atoms section of data file");
if (radius[nlocal] == 0.0) rmass[nlocal] = density;
else
rmass[nlocal] = 4.0*MY_PI/3.0 *
radius[nlocal]*radius[nlocal]*radius[nlocal] * density;
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 AtomVecSphere::data_atom_hybrid(int nlocal, char **values)
{
radius[nlocal] = 0.5 * atof(values[0]);
if (radius[nlocal] < 0.0)
error->one(FLERR,"Invalid radius in Atoms section of data file");
double density = atof(values[1]);
if (density <= 0.0)
error->one(FLERR,"Invalid density in Atoms section of data file");
if (radius[nlocal] == 0.0) rmass[nlocal] = density;
else
rmass[nlocal] = 4.0*MY_PI/3.0 *
radius[nlocal]*radius[nlocal]*radius[nlocal] * density;
return 2;
}
/* ----------------------------------------------------------------------
unpack one line from Velocities section of data file
------------------------------------------------------------------------- */
void AtomVecSphere::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 AtomVecSphere::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
------------------------------------------------------------------------- */
bigint AtomVecSphere::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("radius")) bytes += memory->usage(radius,nmax);
if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax);
if (atom->memcheck("omega")) bytes += memory->usage(omega,nmax,3);
if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax*comm->nthreads,3);
return bytes;
}
diff --git a/src/atom_vec_sphere.h b/src/atom_vec_sphere.h
index 704171883..3d080ff86 100644
--- a/src/atom_vec_sphere.h
+++ b/src/atom_vec_sphere.h
@@ -1,99 +1,100 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(sphere,AtomVecSphere)
#else
#ifndef LMP_ATOM_VEC_SPHERE_H
#define LMP_ATOM_VEC_SPHERE_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecSphere : public AtomVec {
public:
AtomVecSphere(class LAMMPS *, int, char **);
~AtomVecSphere() {}
void init();
void grow(int);
void grow_reset();
void copy(int, int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
int pack_comm_hybrid(int, int *, double *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int unpack_comm_hybrid(int, int, double *);
int pack_reverse(int, int, double *);
int pack_reverse_hybrid(int, int, double *);
void unpack_reverse(int, int *, double *);
int unpack_reverse_hybrid(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
void data_vel(int, char **);
int data_vel_hybrid(int, char **);
bigint memory_usage();
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
double *radius,*density,*rmass;
double **omega,**torque;
int radvary;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
E: Invalid radius in Atoms section of data file
Radius must be >= 0.0.
E: Invalid density in Atoms section of data file
Density value cannot be <= 0.0.
*/
diff --git a/src/atom_vec_tri.cpp b/src/atom_vec_tri.cpp
index 283718ef9..7cfe3d1e7 100644
--- a/src/atom_vec_tri.cpp
+++ b/src/atom_vec_tri.cpp
@@ -1,1563 +1,1564 @@
/* ----------------------------------------------------------------------
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_tri.h"
#include "math_extra.h"
#include "atom.h"
#include "comm.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
#define DELTA_BONUS 10000
#define EPSILON 0.001
/* ---------------------------------------------------------------------- */
AtomVecTri::AtomVecTri(LAMMPS *lmp, int narg, char **arg) :
AtomVec(lmp, narg, arg)
{
molecular = 0;
comm_x_only = comm_f_only = 0;
size_forward = 7;
size_reverse = 6;
size_border = 24;
size_velocity = 6;
size_data_atom = 8;
size_data_vel = 7;
size_data_bonus = 10;
xcol_data = 6;
atom->tri_flag = 1;
atom->molecule_flag = atom->rmass_flag = 1;
atom->angmom_flag = atom->torque_flag = 1;
nlocal_bonus = nghost_bonus = nmax_bonus = 0;
bonus = NULL;
}
/* ---------------------------------------------------------------------- */
AtomVecTri::~AtomVecTri()
{
memory->sfree(bonus);
}
/* ---------------------------------------------------------------------- */
void AtomVecTri::init()
{
AtomVec::init();
if (domain->dimension != 3)
error->all(FLERR,"Atom_style tri can only be used in 3d simulations");
}
/* ----------------------------------------------------------------------
grow atom arrays
n = 0 grows arrays by DELTA
n > 0 allocates arrays to size n
------------------------------------------------------------------------- */
void AtomVecTri::grow(int n)
{
if (n == 0) nmax += DELTA;
else nmax = n;
atom->nmax = nmax;
if (nmax < 0 || nmax > MAXSMALLINT)
error->one(FLERR,"Per-processor system is too big");
tag = memory->grow(atom->tag,nmax,"atom:tag");
type = memory->grow(atom->type,nmax,"atom:type");
mask = memory->grow(atom->mask,nmax,"atom:mask");
image = memory->grow(atom->image,nmax,"atom:image");
x = memory->grow(atom->x,nmax,3,"atom:x");
v = memory->grow(atom->v,nmax,3,"atom:v");
f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
molecule = memory->grow(atom->molecule,nmax,"atom:molecule");
rmass = memory->grow(atom->rmass,nmax,"atom:rmass");
angmom = memory->grow(atom->angmom,nmax,3,"atom:angmom");
torque = memory->grow(atom->torque,nmax*comm->nthreads,3,"atom:torque");
tri = memory->grow(atom->tri,nmax,"atom:tri");
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 AtomVecTri::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; rmass = atom->rmass;
angmom = atom->angmom; torque = atom->torque;
}
/* ----------------------------------------------------------------------
grow bonus data structure
------------------------------------------------------------------------- */
void AtomVecTri::grow_bonus()
{
nmax_bonus += DELTA_BONUS;
if (nmax_bonus < 0 || nmax_bonus > MAXSMALLINT)
error->one(FLERR,"Per-processor system is too big");
bonus = (Bonus *) memory->srealloc(bonus,nmax_bonus*sizeof(Bonus),
"atom:bonus");
}
/* ----------------------------------------------------------------------
copy atom I info to atom J
if delflag and atom J has bonus data, then delete it
------------------------------------------------------------------------- */
void AtomVecTri::copy(int i, int j, int delflag)
{
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];
rmass[j] = rmass[i];
angmom[j][0] = angmom[i][0];
angmom[j][1] = angmom[i][1];
angmom[j][2] = angmom[i][2];
// if delflag and atom J has bonus data, then delete it
if (delflag && tri[j] >= 0) {
copy_bonus(nlocal_bonus-1,tri[j]);
nlocal_bonus--;
}
// if atom I has bonus data and not deleting I, repoint I's bonus to J
if (tri[i] >= 0 && i != j) bonus[tri[i]].ilocal = j;
tri[j] = tri[i];
if (atom->nextra_grow)
for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
}
/* ----------------------------------------------------------------------
copy bonus data from I to J, effectively deleting the J entry
insure index pointers between per-atom and bonus data are updated
------------------------------------------------------------------------- */
void AtomVecTri::copy_bonus(int i, int j)
{
memcpy(&bonus[j],&bonus[i],sizeof(Bonus));
tri[bonus[j].ilocal] = j;
}
/* ----------------------------------------------------------------------
clear ghost info in bonus data
called before ghosts are recommunicated in comm and irregular
------------------------------------------------------------------------- */
void AtomVecTri::clear_bonus()
{
nghost_bonus = 0;
}
/* ----------------------------------------------------------------------
set equilateral tri of size in bonus data for particle I
oriented symmetrically in xy plane
this may create or delete entry in bonus data
------------------------------------------------------------------------- */
void AtomVecTri::set_equilateral(int i, double size)
{
if (tri[i] < 0) {
if (size == 0.0) return;
if (nlocal_bonus == nmax_bonus) grow_bonus();
double *quat = bonus[nlocal_bonus].quat;
double *c1 = bonus[nlocal_bonus].c1;
double *c2 = bonus[nlocal_bonus].c2;
double *c3 = bonus[nlocal_bonus].c3;
double *inertia = bonus[nlocal_bonus].inertia;
quat[0] = 1.0;
quat[1] = 0.0;
quat[2] = 0.0;
quat[3] = 0.0;
c1[0] = -size/2.0;
c1[1] = -sqrt(3.0)/2.0 * size / 3.0;
c1[2] = 0.0;
c2[0] = size/2.0;
c2[1] = -sqrt(3.0)/2.0 * size / 3.0;
c2[2] = 0.0;
c3[0] = 0.0;
c3[1] = sqrt(3.0)/2.0 * size * 2.0/3.0;
c3[2] = 0.0;
inertia[0] = sqrt(3.0)/96.0 * size*size*size*size;
inertia[1] = sqrt(3.0)/96.0 * size*size*size*size;
inertia[2] = sqrt(3.0)/48.0 * size*size*size*size;
bonus[nlocal_bonus].ilocal = i;
tri[i] = nlocal_bonus++;
} else if (size == 0.0) {
copy_bonus(nlocal_bonus-1,tri[i]);
nlocal_bonus--;
tri[i] = -1;
} else {
double *c1 = bonus[tri[i]].c1;
double *c2 = bonus[tri[i]].c2;
double *c3 = bonus[tri[i]].c3;
double *inertia = bonus[tri[i]].inertia;
c1[0] = -size/2.0;
c1[1] = -sqrt(3.0)/2.0 * size / 3.0;
c1[2] = 0.0;
c2[0] = size/2.0;
c2[1] = -sqrt(3.0)/2.0 * size / 3.0;
c2[2] = 0.0;
c3[0] = 0.0;
c3[1] = sqrt(3.0)/2.0 * size * 2.0/3.0;
c3[2] = 0.0;
inertia[0] = sqrt(3.0)/96.0 * size*size*size*size;
inertia[1] = sqrt(3.0)/96.0 * size*size*size*size;
inertia[2] = sqrt(3.0)/48.0 * size*size*size*size;
}
}
/* ---------------------------------------------------------------------- */
int AtomVecTri::pack_comm(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz;
double *quat;
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];
if (tri[j] >= 0) {
quat = bonus[tri[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[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;
if (tri[j] >= 0) {
quat = bonus[tri[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecTri::pack_comm_vel(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz,dvx,dvy,dvz;
double *quat;
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];
if (tri[j] >= 0) {
quat = bonus[tri[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[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;
}
if (!deform_vremap) {
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;
if (tri[j] >= 0) {
quat = bonus[tri[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[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 {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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;
if (tri[j] >= 0) {
quat = bonus[tri[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
}
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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 AtomVecTri::pack_comm_hybrid(int n, int *list, double *buf)
{
int i,j,m;
double *quat;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
if (tri[j] >= 0) {
quat = bonus[tri[j]].quat;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecTri::unpack_comm(int n, int first, double *buf)
{
int i,m,last;
double *quat;
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++];
if (tri[i] >= 0) {
quat = bonus[tri[i]].quat;
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
}
}
}
/* ---------------------------------------------------------------------- */
void AtomVecTri::unpack_comm_vel(int n, int first, double *buf)
{
int i,m,last;
double *quat;
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++];
if (tri[i] >= 0) {
quat = bonus[tri[i]].quat;
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[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 AtomVecTri::unpack_comm_hybrid(int n, int first, double *buf)
{
int i,m,last;
double *quat;
m = 0;
last = first + n;
for (i = first; i < last; i++)
if (tri[i] >= 0) {
quat = bonus[tri[i]].quat;
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecTri::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 AtomVecTri::pack_reverse_hybrid(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = torque[i][0];
buf[m++] = torque[i][1];
buf[m++] = torque[i][2];
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecTri::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 AtomVecTri::unpack_reverse_hybrid(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
torque[j][0] += buf[m++];
torque[j][1] += buf[m++];
torque[j][2] += buf[m++];
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecTri::pack_border(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz;
double *quat,*c1,*c2,*c3,*inertia;
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];
if (tri[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
quat = bonus[tri[j]].quat;
c1 = bonus[tri[j]].c1;
c2 = bonus[tri[j]].c2;
c3 = bonus[tri[j]].c3;
inertia = bonus[tri[j]].inertia;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
buf[m++] = c1[0];
buf[m++] = c1[1];
buf[m++] = c1[2];
buf[m++] = c2[0];
buf[m++] = c2[1];
buf[m++] = c2[2];
buf[m++] = c3[0];
buf[m++] = c3[1];
buf[m++] = c3[2];
buf[m++] = inertia[0];
buf[m++] = inertia[1];
buf[m++] = inertia[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];
if (tri[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
quat = bonus[tri[j]].quat;
c1 = bonus[tri[j]].c1;
c2 = bonus[tri[j]].c2;
c3 = bonus[tri[j]].c3;
inertia = bonus[tri[j]].inertia;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
buf[m++] = c1[0];
buf[m++] = c1[1];
buf[m++] = c1[2];
buf[m++] = c2[0];
buf[m++] = c2[1];
buf[m++] = c2[2];
buf[m++] = c3[0];
buf[m++] = c3[1];
buf[m++] = c3[2];
buf[m++] = inertia[0];
buf[m++] = inertia[1];
buf[m++] = inertia[2];
}
}
}
return m;
}
/* ---------------------------------------------------------------------- */
int AtomVecTri::pack_border_vel(int n, int *list, double *buf,
int pbc_flag, int *pbc)
{
int i,j,m;
double dx,dy,dz,dvx,dvy,dvz;
double *quat,*c1,*c2,*c3,*inertia;
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];
if (tri[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
quat = bonus[tri[j]].quat;
c1 = bonus[tri[j]].c1;
c2 = bonus[tri[j]].c2;
c3 = bonus[tri[j]].c3;
inertia = bonus[tri[j]].inertia;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
buf[m++] = c1[0];
buf[m++] = c1[1];
buf[m++] = c1[2];
buf[m++] = c2[0];
buf[m++] = c2[1];
buf[m++] = c2[2];
buf[m++] = c3[0];
buf[m++] = c3[1];
buf[m++] = c3[2];
buf[m++] = inertia[0];
buf[m++] = inertia[1];
buf[m++] = inertia[2];
}
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];
}
if (!deform_vremap) {
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];
if (tri[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
quat = bonus[tri[j]].quat;
c1 = bonus[tri[j]].c1;
c2 = bonus[tri[j]].c2;
c3 = bonus[tri[j]].c3;
inertia = bonus[tri[j]].inertia;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
buf[m++] = c1[0];
buf[m++] = c1[1];
buf[m++] = c1[2];
buf[m++] = c2[0];
buf[m++] = c2[1];
buf[m++] = c2[2];
buf[m++] = c3[0];
buf[m++] = c3[1];
buf[m++] = c3[2];
buf[m++] = inertia[0];
buf[m++] = inertia[1];
buf[m++] = inertia[2];
}
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 {
dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
dvz = pbc[2]*h_rate[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];
if (tri[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
quat = bonus[tri[j]].quat;
c1 = bonus[tri[j]].c1;
c2 = bonus[tri[j]].c2;
c3 = bonus[tri[j]].c3;
inertia = bonus[tri[j]].inertia;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
buf[m++] = c1[0];
buf[m++] = c1[1];
buf[m++] = c1[2];
buf[m++] = c2[0];
buf[m++] = c2[1];
buf[m++] = c2[2];
buf[m++] = c3[0];
buf[m++] = c3[1];
buf[m++] = c3[2];
buf[m++] = inertia[0];
buf[m++] = inertia[1];
buf[m++] = inertia[2];
}
if (mask[i] & deform_groupbit) {
buf[m++] = v[j][0] + dvx;
buf[m++] = v[j][1] + dvy;
buf[m++] = v[j][2] + dvz;
} else {
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 AtomVecTri::pack_border_hybrid(int n, int *list, double *buf)
{
int i,j,m;
double *quat,*c1,*c2,*c3,*inertia;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
buf[m++] = molecule[j];
if (tri[j] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
quat = bonus[tri[j]].quat;
c1 = bonus[tri[j]].c1;
c2 = bonus[tri[j]].c2;
c3 = bonus[tri[j]].c3;
inertia = bonus[tri[j]].inertia;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
buf[m++] = c1[0];
buf[m++] = c1[1];
buf[m++] = c1[2];
buf[m++] = c2[0];
buf[m++] = c2[1];
buf[m++] = c2[2];
buf[m++] = c3[0];
buf[m++] = c3[1];
buf[m++] = c3[2];
buf[m++] = inertia[0];
buf[m++] = inertia[1];
buf[m++] = inertia[2];
}
}
return m;
}
/* ---------------------------------------------------------------------- */
void AtomVecTri::unpack_border(int n, int first, double *buf)
{
int i,j,m,last;
double *quat,*c1,*c2,*c3,*inertia;
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++]);
tri[i] = static_cast<int> (buf[m++]);
if (tri[i] == 0) tri[i] = -1;
else {
j = nlocal_bonus + nghost_bonus;
if (j == nmax_bonus) grow_bonus();
quat = bonus[j].quat;
c1 = bonus[j].c1;
c2 = bonus[j].c2;
c3 = bonus[j].c3;
inertia = bonus[j].inertia;
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
c1[0] = buf[m++];
c1[1] = buf[m++];
c1[2] = buf[m++];
c2[0] = buf[m++];
c2[1] = buf[m++];
c2[2] = buf[m++];
c3[0] = buf[m++];
c3[1] = buf[m++];
c3[2] = buf[m++];
inertia[0] = buf[m++];
inertia[1] = buf[m++];
inertia[2] = buf[m++];
bonus[j].ilocal = i;
tri[i] = j;
nghost_bonus++;
}
}
}
/* ---------------------------------------------------------------------- */
void AtomVecTri::unpack_border_vel(int n, int first, double *buf)
{
int i,j,m,last;
double *quat,*c1,*c2,*c3,*inertia;
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++]);
tri[i] = static_cast<int> (buf[m++]);
if (tri[i] == 0) tri[i] = -1;
else {
j = nlocal_bonus + nghost_bonus;
if (j == nmax_bonus) grow_bonus();
quat = bonus[j].quat;
c1 = bonus[j].c1;
c2 = bonus[j].c2;
c3 = bonus[j].c3;
inertia = bonus[j].inertia;
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
c1[0] = buf[m++];
c1[1] = buf[m++];
c1[2] = buf[m++];
c2[0] = buf[m++];
c2[1] = buf[m++];
c2[2] = buf[m++];
c3[0] = buf[m++];
c3[1] = buf[m++];
c3[2] = buf[m++];
inertia[0] = buf[m++];
inertia[1] = buf[m++];
inertia[2] = buf[m++];
bonus[j].ilocal = i;
tri[i] = j;
nghost_bonus++;
}
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 AtomVecTri::unpack_border_hybrid(int n, int first, double *buf)
{
int i,j,m,last;
double *quat,*c1,*c2,*c3,*inertia;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
molecule[i] = static_cast<int> (buf[m++]);
tri[i] = static_cast<int> (buf[m++]);
if (tri[i] == 0) tri[i] = -1;
else {
j = nlocal_bonus + nghost_bonus;
if (j == nmax_bonus) grow_bonus();
quat = bonus[j].quat;
c1 = bonus[j].c1;
c2 = bonus[j].c2;
c3 = bonus[j].c3;
inertia = bonus[j].inertia;
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
c1[0] = buf[m++];
c1[1] = buf[m++];
c1[2] = buf[m++];
c2[0] = buf[m++];
c2[1] = buf[m++];
c2[2] = buf[m++];
c3[0] = buf[m++];
c3[1] = buf[m++];
c3[2] = buf[m++];
inertia[0] = buf[m++];
inertia[1] = buf[m++];
inertia[2] = buf[m++];
bonus[j].ilocal = i;
tri[i] = j;
nghost_bonus++;
}
}
return 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 AtomVecTri::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];
+ *((tagint *) &buf[m++]) = image[i];
buf[m++] = molecule[i];
buf[m++] = rmass[i];
buf[m++] = angmom[i][0];
buf[m++] = angmom[i][1];
buf[m++] = angmom[i][2];
if (tri[i] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
int j = tri[i];
double *quat = bonus[j].quat;
double *c1 = bonus[j].c1;
double *c2 = bonus[j].c2;
double *c3 = bonus[j].c3;
double *inertia = bonus[j].inertia;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
buf[m++] = c1[0];
buf[m++] = c1[1];
buf[m++] = c1[2];
buf[m++] = c2[0];
buf[m++] = c2[1];
buf[m++] = c2[2];
buf[m++] = c3[0];
buf[m++] = c3[1];
buf[m++] = c3[2];
buf[m++] = inertia[0];
buf[m++] = inertia[1];
buf[m++] = inertia[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 AtomVecTri::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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
molecule[nlocal] = static_cast<int> (buf[m++]);
rmass[nlocal] = buf[m++];
angmom[nlocal][0] = buf[m++];
angmom[nlocal][1] = buf[m++];
angmom[nlocal][2] = buf[m++];
tri[nlocal] = static_cast<int> (buf[m++]);
if (tri[nlocal] == 0) tri[nlocal] = -1;
else {
if (nlocal_bonus == nmax_bonus) grow_bonus();
double *quat = bonus[nlocal_bonus].quat;
double *c1 = bonus[nlocal_bonus].c1;
double *c2 = bonus[nlocal_bonus].c2;
double *c3 = bonus[nlocal_bonus].c3;
double *inertia = bonus[nlocal_bonus].inertia;
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
c1[0] = buf[m++];
c1[1] = buf[m++];
c1[2] = buf[m++];
c2[0] = buf[m++];
c2[1] = buf[m++];
c2[2] = buf[m++];
c3[0] = buf[m++];
c3[1] = buf[m++];
c3[2] = buf[m++];
inertia[0] = buf[m++];
inertia[1] = buf[m++];
inertia[2] = buf[m++];
bonus[nlocal_bonus].ilocal = nlocal;
tri[nlocal] = nlocal_bonus++;
}
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 AtomVecTri::size_restart()
{
int i;
int n = 0;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++)
if (tri[i] >= 0) n += 33;
else n += 17;
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 AtomVecTri::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];
+ *((tagint *) &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++] = rmass[i];
buf[m++] = angmom[i][0];
buf[m++] = angmom[i][1];
buf[m++] = angmom[i][2];
if (tri[i] < 0) buf[m++] = 0;
else {
buf[m++] = 1;
int j = tri[i];
double *quat = bonus[j].quat;
double *c1 = bonus[j].c1;
double *c2 = bonus[j].c2;
double *c3 = bonus[j].c3;
double *inertia = bonus[j].inertia;
buf[m++] = quat[0];
buf[m++] = quat[1];
buf[m++] = quat[2];
buf[m++] = quat[3];
buf[m++] = c1[0];
buf[m++] = c1[1];
buf[m++] = c1[2];
buf[m++] = c2[0];
buf[m++] = c2[1];
buf[m++] = c2[2];
buf[m++] = c3[0];
buf[m++] = c3[1];
buf[m++] = c3[2];
buf[m++] = inertia[0];
buf[m++] = inertia[1];
buf[m++] = inertia[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 AtomVecTri::unpack_restart(double *buf)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) {
grow(0);
if (atom->nextra_store)
memory->grow(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++]);
+ image[nlocal] = *((tagint *) &buf[m++]);
v[nlocal][0] = buf[m++];
v[nlocal][1] = buf[m++];
v[nlocal][2] = buf[m++];
molecule[nlocal] = static_cast<int> (buf[m++]);
rmass[nlocal] = buf[m++];
angmom[nlocal][0] = buf[m++];
angmom[nlocal][1] = buf[m++];
angmom[nlocal][2] = buf[m++];
tri[nlocal] = static_cast<int> (buf[m++]);
if (tri[nlocal] == 0) tri[nlocal] = -1;
else {
if (nlocal_bonus == nmax_bonus) grow_bonus();
double *quat = bonus[nlocal_bonus].quat;
double *c1 = bonus[nlocal_bonus].c1;
double *c2 = bonus[nlocal_bonus].c2;
double *c3 = bonus[nlocal_bonus].c3;
double *inertia = bonus[nlocal_bonus].inertia;
quat[0] = buf[m++];
quat[1] = buf[m++];
quat[2] = buf[m++];
quat[3] = buf[m++];
c1[0] = buf[m++];
c1[1] = buf[m++];
c1[2] = buf[m++];
c2[0] = buf[m++];
c2[1] = buf[m++];
c2[2] = buf[m++];
c3[0] = buf[m++];
c3[1] = buf[m++];
c3[2] = buf[m++];
inertia[0] = buf[m++];
inertia[1] = buf[m++];
inertia[2] = buf[m++];
bonus[nlocal_bonus].ilocal = nlocal;
tri[nlocal] = nlocal_bonus++;
}
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 AtomVecTri::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;
+ image[nlocal] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMAX << IMGBITS) | IMGMAX;
v[nlocal][0] = 0.0;
v[nlocal][1] = 0.0;
v[nlocal][2] = 0.0;
molecule[nlocal] = 0;
rmass[nlocal] = 1.0;
angmom[nlocal][0] = 0.0;
angmom[nlocal][1] = 0.0;
angmom[nlocal][2] = 0.0;
tri[nlocal] = -1;
atom->nlocal++;
}
/* ----------------------------------------------------------------------
unpack one tri from Atoms section of data file
initialize other atom quantities
------------------------------------------------------------------------- */
-void AtomVecTri::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecTri::data_atom(double *coord, tagint imagetmp, char **values)
{
int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0);
tag[nlocal] = atoi(values[0]);
if (tag[nlocal] <= 0)
error->one(FLERR,"Invalid atom ID in Atoms section of data file");
molecule[nlocal] = atoi(values[1]);
type[nlocal] = atoi(values[2]);
if (type[nlocal] <= 0 || type[nlocal] > atom->ntypes)
error->one(FLERR,"Invalid atom type in Atoms section of data file");
tri[nlocal] = atoi(values[3]);
if (tri[nlocal] == 0) tri[nlocal] = -1;
else if (tri[nlocal] == 1) tri[nlocal] = 0;
else error->one(FLERR,"Invalid atom type in Atoms section of data file");
rmass[nlocal] = atof(values[4]);
if (rmass[nlocal] <= 0.0)
error->one(FLERR,"Invalid density 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;
angmom[nlocal][0] = 0.0;
angmom[nlocal][1] = 0.0;
angmom[nlocal][2] = 0.0;
atom->nlocal++;
}
/* ----------------------------------------------------------------------
unpack hybrid quantities from one tri in Atoms section of data file
initialize other atom quantities for this sub-style
------------------------------------------------------------------------- */
int AtomVecTri::data_atom_hybrid(int nlocal, char **values)
{
molecule[nlocal] = atoi(values[0]);
tri[nlocal] = atoi(values[1]);
if (tri[nlocal] == 0) tri[nlocal] = -1;
else if (tri[nlocal] == 1) tri[nlocal] = 0;
else error->one(FLERR,"Invalid atom type in Atoms section of data file");
rmass[nlocal] = atof(values[2]);
if (rmass[nlocal] <= 0.0)
error->one(FLERR,"Invalid density in Atoms section of data file");
return 3;
}
/* ----------------------------------------------------------------------
unpack one tri from Tris section of data file
------------------------------------------------------------------------- */
void AtomVecTri::data_atom_bonus(int m, char **values)
{
if (tri[m]) error->one(FLERR,"Assigning tri parameters to non-tri atom");
if (nlocal_bonus == nmax_bonus) grow_bonus();
double c1[3],c2[3],c3[3];
c1[0] = atof(values[0]);
c1[1] = atof(values[1]);
c1[2] = atof(values[2]);
c2[0] = atof(values[3]);
c2[1] = atof(values[4]);
c2[2] = atof(values[5]);
c3[0] = atof(values[6]);
c3[1] = atof(values[7]);
c3[2] = atof(values[8]);
// check for duplicate points
if (c1[0] == c2[0] && c1[1] == c2[1] && c1[2] == c2[2])
error->one(FLERR,"Invalid shape in Triangles section of data file");
if (c1[0] == c3[0] && c1[1] == c3[1] && c1[2] == c3[2])
error->one(FLERR,"Invalid shape in Triangles section of data file");
if (c2[0] == c3[0] && c2[1] == c3[1] && c2[2] == c3[2])
error->one(FLERR,"Invalid shape in Triangles section of data file");
// size = length of one edge
double c2mc1[2],c3mc1[3];
MathExtra::sub3(c2,c1,c2mc1);
MathExtra::sub3(c3,c1,c3mc1);
double size = MAX(MathExtra::len3(c2mc1),MathExtra::len3(c3mc1));
// centroid = 1/3 of sum of vertices
double centroid[3];
centroid[0] = (c1[0]+c2[0]+c3[0]) / 3.0;
centroid[1] = (c1[1]+c2[1]+c3[1]) / 3.0;
centroid[2] = (c1[2]+c2[2]+c3[2]) / 3.0;
double dx = centroid[0] - x[m][0];
double dy = centroid[1] - x[m][1];
double dz = centroid[2] - x[m][2];
double delta = sqrt(dx*dx + dy*dy + dz*dz);
if (delta/size > EPSILON)
error->one(FLERR,"Inconsistent triangle in data file");
x[m][0] = centroid[0];
x[m][1] = centroid[1];
x[m][2] = centroid[2];
// reset tri mass
// previously stored density in rmass
// tri area = 0.5 len(U x V), where U,V are edge vectors from one vertex
double norm[3];
MathExtra::cross3(c2mc1,c3mc1,norm);
double area = 0.5 * MathExtra::len3(norm);
rmass[m] *= area;
// inertia = inertia tensor of triangle as 6-vector in Voigt notation
double inertia[6];
MathExtra::inertia_triangle(c1,c2,c3,rmass[m],inertia);
// diagonalize inertia tensor via Jacobi rotations
// bonus[].inertia = 3 eigenvalues = principal moments of inertia
// evectors and exzy_space = 3 evectors = principal axes of triangle
double tensor[3][3],evectors[3][3];
tensor[0][0] = inertia[0];
tensor[1][1] = inertia[1];
tensor[2][2] = inertia[2];
tensor[1][2] = tensor[2][1] = inertia[3];
tensor[0][2] = tensor[2][0] = inertia[4];
tensor[0][1] = tensor[1][0] = inertia[5];
int ierror = MathExtra::jacobi(tensor,bonus[nlocal_bonus].inertia,evectors);
if (ierror) error->one(FLERR,"Insufficient Jacobi rotations for triangle");
double ex_space[3],ey_space[3],ez_space[3];
ex_space[0] = evectors[0][0];
ex_space[1] = evectors[1][0];
ex_space[2] = evectors[2][0];
ey_space[0] = evectors[0][1];
ey_space[1] = evectors[1][1];
ey_space[2] = evectors[2][1];
ez_space[0] = evectors[0][2];
ez_space[1] = evectors[1][2];
ez_space[2] = evectors[2][2];
// enforce 3 orthogonal vectors as a right-handed coordinate system
// flip 3rd vector if needed
MathExtra::cross3(ex_space,ey_space,norm);
if (MathExtra::dot3(norm,ez_space) < 0.0) MathExtra::negate3(ez_space);
// create initial quaternion
MathExtra::exyz_to_q(ex_space,ey_space,ez_space,bonus[nlocal_bonus].quat);
// bonus c1,c2,c3 = displacement of c1,c2,c3 from centroid
// in basis of principal axes
double disp[3];
MathExtra::sub3(c1,centroid,disp);
MathExtra::transpose_matvec(ex_space,ey_space,ez_space,
disp,bonus[nlocal_bonus].c1);
MathExtra::sub3(c2,centroid,disp);
MathExtra::transpose_matvec(ex_space,ey_space,ez_space,
disp,bonus[nlocal_bonus].c2);
MathExtra::sub3(c3,centroid,disp);
MathExtra::transpose_matvec(ex_space,ey_space,ez_space,
disp,bonus[nlocal_bonus].c3);
bonus[nlocal_bonus].ilocal = m;
tri[m] = nlocal_bonus++;
}
/* ----------------------------------------------------------------------
unpack one tri from Velocities section of data file
------------------------------------------------------------------------- */
void AtomVecTri::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 tri in Velocities section of data file
------------------------------------------------------------------------- */
int AtomVecTri::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
------------------------------------------------------------------------- */
bigint AtomVecTri::memory_usage()
{
bigint bytes = 0;
if (atom->memcheck("tag")) bytes += memory->usage(tag,nmax);
if (atom->memcheck("type")) bytes += memory->usage(type,nmax);
if (atom->memcheck("mask")) bytes += memory->usage(mask,nmax);
if (atom->memcheck("image")) bytes += memory->usage(image,nmax);
if (atom->memcheck("x")) bytes += memory->usage(x,nmax,3);
if (atom->memcheck("v")) bytes += memory->usage(v,nmax,3);
if (atom->memcheck("f")) bytes += memory->usage(f,nmax*comm->nthreads,3);
if (atom->memcheck("molecule")) bytes += memory->usage(molecule,nmax);
if (atom->memcheck("rmass")) bytes += memory->usage(rmass,nmax);
if (atom->memcheck("angmom")) bytes += memory->usage(angmom,nmax,3);
if (atom->memcheck("torque")) bytes += memory->usage(torque,nmax*comm->nthreads,3);
if (atom->memcheck("tri")) bytes += memory->usage(tri,nmax);
bytes += nmax_bonus*sizeof(Bonus);
return bytes;
}
diff --git a/src/atom_vec_tri.h b/src/atom_vec_tri.h
index 5ef6b17dc..d96d4d4ad 100644
--- a/src/atom_vec_tri.h
+++ b/src/atom_vec_tri.h
@@ -1,140 +1,141 @@
/* -*- c++ -*- ----------------------------------------------------------
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 ATOM_CLASS
AtomStyle(tri,AtomVecTri)
#else
#ifndef LMP_ATOM_VEC_TRI_H
#define LMP_ATOM_VEC_TRI_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecTri : public AtomVec {
public:
struct Bonus {
double quat[4];
double c1[3],c2[3],c3[3];
double inertia[3];
int ilocal;
};
struct Bonus *bonus;
AtomVecTri(class LAMMPS *, int, char **);
~AtomVecTri();
void init();
void grow(int);
void grow_reset();
void copy(int, int, int);
int pack_comm(int, int *, double *, int, int *);
int pack_comm_vel(int, int *, double *, int, int *);
int pack_comm_hybrid(int, int *, double *);
void unpack_comm(int, int, double *);
void unpack_comm_vel(int, int, double *);
int unpack_comm_hybrid(int, int, double *);
int pack_reverse(int, int, double *);
int pack_reverse_hybrid(int, int, double *);
void unpack_reverse(int, int *, double *);
int unpack_reverse_hybrid(int, int *, double *);
int pack_border(int, int *, double *, int, int *);
int pack_border_vel(int, int *, double *, int, int *);
int pack_border_hybrid(int, int *, double *);
void unpack_border(int, int, double *);
void unpack_border_vel(int, int, double *);
int unpack_border_hybrid(int, int, double *);
int pack_exchange(int, double *);
int unpack_exchange(double *);
int size_restart();
int pack_restart(int, double *);
int unpack_restart(double *);
void create_atom(int, double *);
- void data_atom(double *, int, char **);
+ void data_atom(double *, tagint, char **);
int data_atom_hybrid(int, char **);
void data_vel(int, char **);
int data_vel_hybrid(int, char **);
bigint memory_usage();
// manipulate Bonus data structure for extra atom info
void clear_bonus();
void data_atom_bonus(int, char **);
// unique to AtomVecTri
void set_equilateral(int, double);
private:
- int *tag,*type,*mask,*image;
+ int *tag,*type,*mask;
+ tagint *image;
double **x,**v,**f;
int *molecule;
double *rmass;
double **angmom,**torque;
int *tri;
int nlocal_bonus,nghost_bonus,nmax_bonus;
void grow_bonus();
void copy_bonus(int, int);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Atom_style tri can only be used in 3d simulations
Self-explanatory.
E: Per-processor system is too big
The number of owned atoms plus ghost atoms on a single
processor must fit in 32-bit integer.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Invalid atom type in Atoms section of data file
Atom types must range from 1 to specified # of types.
E: Invalid density in Atoms section of data file
Density value cannot be <= 0.0.
E: Assigning tri parameters to non-tri atom
Self-explanatory.
E: Invalid shape in Triangles section of data file
Two or more of the triangle corners are duplicate points.
E: Inconsistent triangle in data file
The centroid of the triangle as defined by the corner points is not
the atom coordinate.
E: Insufficient Jacobi rotations for triangle
The calculation of the intertia tensor of the triangle failed. This
should not happen if it is a reasonably shaped triangle.
*/
diff --git a/src/balance.h b/src/balance.h
index fa9a4ac8a..bec0e0ec0 100644
--- a/src/balance.h
+++ b/src/balance.h
@@ -1,115 +1,116 @@
/* ----------------------------------------------------------------------
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 COMMAND_CLASS
CommandStyle(balance,Balance)
#else
#ifndef LMP_BALANCE_H
#define LMP_BALANCE_H
#include "stdio.h"
#include "pointers.h"
namespace LAMMPS_NS {
class Balance : protected Pointers {
public:
Balance(class LAMMPS *);
~Balance();
void command(int, char **);
void dynamic_setup(char *, int, double);
int dynamic();
double imbalance_nlocal(int &);
void dumpout(bigint, FILE *);
private:
int me,nprocs;
int xflag,yflag,zflag; // xyz LB flags
double *user_xsplit,*user_ysplit,*user_zsplit; // params for xyz LB
int dflag; // dynamic LB flag
int nitermax; // params for dynamic LB
double thresh;
char bstr[4];
int ndim; // length of balance string bstr
int *bdim; // XYZ for each character in bstr
bigint *count; // counts for slices in one dim
bigint *onecount; // work vector of counts in one dim
bigint *sum; // cummulative count for slices in one dim
bigint *target; // target sum for slices in one dim
double *lo,*hi; // lo/hi split coords that bound each target
bigint *losum,*hisum; // cummulative counts at lo/hi coords
int rho; // 0 for geometric recursion
// 1 for density weighted recursion
int *proccount; // particle count per processor
int *allproccount;
int outflag; // for output of balance results to file
FILE *fp;
int firststep;
void static_setup(char *);
double imbalance_splits(int &);
void tally(int, int, double *);
int adjust(int, double *);
void old_adjust(int, int, bigint *, double *);
int binary(double, int, double *);
void debug_output(int, int, int, double *);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Balance command before simulation box is defined
The balance command cannot be used before a read_data, read_restart,
or create_box command.
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
+E: Cannot open balance output file
+
+Self-explanatory.
+
E: Cannot balance in z dimension for 2d simulation
Self-explanatory.
E: Balance dynamic string is invalid
The string can only contain the characters "x", "y", or "z".
-E: Balance dynamic string is invalid for 2d simulation
-
-The string cannot contain the letter "z".
-
E: Lost atoms via balance: original %ld current %ld
This should not occur. Report the problem to the developers.
-E: Cannot open balance output file
+E: Balance produced bad splits
-This error message can only occur if debug options
-are uncommented in src/balance.cpp.
+This should not occur. It means two or more cutting plane locations
+are on top of each other or out of order. Report the problem to the
+developers.
*/
diff --git a/src/change_box.cpp b/src/change_box.cpp
index 3a8717db9..cded3e25d 100644
--- a/src/change_box.cpp
+++ b/src/change_box.cpp
@@ -1,472 +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 "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "change_box.h"
#include "atom.h"
#include "modify.h"
#include "fix.h"
#include "domain.h"
#include "lattice.h"
#include "comm.h"
#include "irregular.h"
#include "output.h"
#include "group.h"
#include "error.h"
using namespace LAMMPS_NS;
enum{XYZ=0,TILT,BOUNDARY,ORTHO,TRICLINIC,SET,REMAP};
enum{FINAL=0,DELTA,SCALE};
enum{X=0,Y,Z,YZ,XZ,XY};
/* ---------------------------------------------------------------------- */
ChangeBox::ChangeBox(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
void ChangeBox::command(int narg, char **arg)
{
int i;
if (domain->box_exist == 0)
error->all(FLERR,"Change_box command before simulation box is defined");
if (narg < 2) error->all(FLERR,"Illegal change_box command");
if (modify->nfix_restart_peratom)
error->all(FLERR,"Cannot change_box after "
"reading restart file with per-atom info");
if (comm->me == 0 && screen) fprintf(screen,"Changing box ...\n");
// group
int igroup = group->find(arg[0]);
if (igroup == -1) error->all(FLERR,"Could not find change_box group ID");
int groupbit = group->bitmask[igroup];
// parse operation arguments
// allocate ops to max possible length
// volume option does not increment nops
int dimension = domain->dimension;
ops = new Operation[narg-1];
memset(ops,0,(narg-1)*sizeof(Operation));
nops = 0;
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 (iarg+2 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].style = XYZ;
if (strcmp(arg[iarg],"x") == 0) ops[nops].dim = X;
else if (strcmp(arg[iarg],"y") == 0) ops[nops].dim = Y;
else if (strcmp(arg[iarg],"z") == 0) ops[nops].dim = Z;
if (dimension == 2 && ops[nops].dim == Z)
error->all(FLERR,"Cannot change_box in z dimension for 2d simulation");
if (strcmp(arg[iarg+1],"final") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].flavor = FINAL;
ops[nops].flo = atof(arg[iarg+2]);
ops[nops].fhi = atof(arg[iarg+3]);
ops[nops].vdim1 = ops[nops].vdim2 = -1;
nops++;
iarg += 4;
} else if (strcmp(arg[iarg+1],"delta") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].flavor = DELTA;
ops[nops].dlo = atof(arg[iarg+2]);
ops[nops].dhi = atof(arg[iarg+3]);
ops[nops].vdim1 = ops[nops].vdim2 = -1;
nops++;
iarg += 4;
} else if (strcmp(arg[iarg+1],"scale") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].flavor = SCALE;
ops[nops].scale = atof(arg[iarg+2]);
ops[nops].vdim1 = ops[nops].vdim2 = -1;
nops++;
iarg += 3;
} else if (strcmp(arg[iarg+1],"volume") == 0) {
if (nops == 0 || ops[nops-1].style != XYZ ||
ops[nops].dim == ops[nops-1].dim)
error->all(FLERR,"Change_box volume used incorrectly");
if (ops[nops-1].vdim2 >= 0)
error->all(FLERR,"Change_box volume used incorrectly");
else if (ops[nops-1].vdim1 >= 0) ops[nops-1].vdim2 = ops[nops].dim;
else ops[nops-1].vdim1 = ops[nops].dim;
iarg += 2;
} else error->all(FLERR,"Illegal change_box command");
} else if (strcmp(arg[iarg],"xy") == 0 || strcmp(arg[iarg],"xz") == 0 ||
strcmp(arg[iarg],"yz") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].style = TILT;
if (strcmp(arg[iarg],"xy") == 0) ops[nops].dim = XY;
else if (strcmp(arg[iarg],"xz") == 0) ops[nops].dim = XZ;
else if (strcmp(arg[iarg],"yz") == 0) ops[nops].dim = YZ;
if (dimension == 2 && (ops[nops].dim == XZ || ops[nops].dim == YZ))
error->all(FLERR,"Cannot change_box in xz or yz for 2d simulation");
if (strcmp(arg[iarg+1],"final") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].flavor = FINAL;
ops[nops].ftilt = atof(arg[iarg+2]);
nops++;
iarg += 3;
} else if (strcmp(arg[iarg+1],"delta") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].flavor = DELTA;
ops[nops].dtilt = atof(arg[iarg+2]);
nops++;
iarg += 3;
} else error->all(FLERR,"Illegal change_box command");
} else if (strcmp(arg[iarg],"boundary") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].style = BOUNDARY;
ops[nops].boundindex = iarg+1;
nops++;
iarg += 4;
} else if (strcmp(arg[iarg],"ortho") == 0) {
if (iarg+1 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].style = ORTHO;
nops++;
iarg += 1;
} else if (strcmp(arg[iarg],"triclinic") == 0) {
if (iarg+1 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].style = TRICLINIC;
nops++;
iarg += 1;
} else if (strcmp(arg[iarg],"set") == 0) {
if (iarg+1 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].style = SET;
nops++;
iarg += 1;
} else if (strcmp(arg[iarg],"remap") == 0) {
if (iarg+1 > narg) error->all(FLERR,"Illegal change_box command");
ops[nops].style = REMAP;
nops++;
iarg += 1;
} else break;
}
if (nops == 0) error->all(FLERR,"Illegal change_box command");
// read options from end of input line
options(narg-iarg,&arg[iarg]);
// compute scale factors if FINAL,DELTA used since they have distance units
int flag = 0;
for (int i = 0; i < nops; i++)
if (ops[i].style == FINAL || ops[i].style == DELTA) flag = 1;
if (flag && scaleflag && domain->lattice == NULL)
error->all(FLERR,"Use of change_box with undefined lattice");
if (flag && scaleflag) {
scale[0] = domain->lattice->xlattice;
scale[1] = domain->lattice->ylattice;
scale[2] = domain->lattice->zlattice;
}
else scale[0] = scale[1] = scale[2] = 1.0;
// perform sequence of operations
// first insure atoms are in current box & update box via shrink-wrap
// no exchange() since doesn't matter if atoms are assigned to correct procs
// save current box state so can remap atoms from it, if requested
if (domain->triclinic) domain->x2lamda(atom->nlocal);
domain->pbc();
domain->reset_box();
if (domain->triclinic) domain->lamda2x(atom->nlocal);
save_box_state();
for (int i = 0; i < nops; i++) {
if (ops[i].style == XYZ) {
double volume;
if (domain->dimension == 2) volume = domain->xprd * domain->yprd;
else volume = domain->xprd * domain->yprd * domain->zprd;
if (ops[i].flavor == FINAL) {
domain->boxlo[ops[i].dim] = scale[ops[i].dim]*ops[i].flo;
domain->boxhi[ops[i].dim] = scale[ops[i].dim]*ops[i].fhi;
if (ops[i].vdim1 >= 0)
volume_preserve(ops[i].vdim1,ops[i].vdim2,volume);
domain->set_initial_box();
domain->set_global_box();
domain->set_local_box();
domain->print_box(" ");
} else if (ops[i].flavor == DELTA) {
domain->boxlo[ops[i].dim] += scale[ops[i].dim]*ops[i].dlo;
domain->boxhi[ops[i].dim] += scale[ops[i].dim]*ops[i].dhi;
if (ops[i].vdim1 >= 0)
volume_preserve(ops[i].vdim1,ops[i].vdim2,volume);
domain->set_initial_box();
domain->set_global_box();
domain->set_local_box();
domain->print_box(" ");
} else if (ops[i].flavor == SCALE) {
double mid = 0.5 *
(domain->boxlo[ops[i].dim] + domain->boxhi[ops[i].dim]);
double delta = domain->boxlo[ops[i].dim] - mid;
domain->boxlo[ops[i].dim] = mid + ops[i].scale*delta;
delta = domain->boxhi[ops[i].dim] - mid;
domain->boxhi[ops[i].dim] = mid + ops[i].scale*delta;
if (ops[i].vdim1 >= 0)
volume_preserve(ops[i].vdim1,ops[i].vdim2,volume);
domain->set_initial_box();
domain->set_global_box();
domain->set_local_box();
domain->print_box(" ");
}
} else if (ops[i].style == TILT) {
if (domain->triclinic == 0)
error->all(FLERR,"Cannot change box tilt factors for orthogonal box");
if (ops[i].flavor == FINAL) {
if (ops[i].dim == XY) domain->xy = scale[X]*ops[i].ftilt;
else if (ops[i].dim == XZ) domain->xz = scale[X]*ops[i].ftilt;
else if (ops[i].dim == YZ) domain->yz = scale[Y]*ops[i].ftilt;
domain->set_initial_box();
domain->set_global_box();
domain->set_local_box();
domain->print_box(" ");
} else if (ops[i].flavor == DELTA) {
if (ops[i].dim == XY) domain->xy += scale[X]*ops[i].dtilt;
else if (ops[i].dim == XZ) domain->xz += scale[X]*ops[i].dtilt;
else if (ops[i].dim == YZ) domain->yz += scale[Y]*ops[i].dtilt;
domain->set_initial_box();
domain->set_global_box();
domain->set_local_box();
domain->print_box(" ");
}
} else if (ops[i].style == BOUNDARY) {
domain->set_boundary(3,&arg[ops[i].boundindex],1);
if (domain->dimension == 2 && domain->zperiodic == 0)
error->all(FLERR,
"Cannot change box z boundary to "
"nonperiodic for a 2d simulation");
domain->set_initial_box();
domain->set_global_box();
domain->set_local_box();
} else if (ops[i].style == ORTHO) {
if (domain->xy != 0.0 || domain->yz != 0.0 || domain->xz != 0.0)
error->all(FLERR,
"Cannot change box to orthogonal when tilt is non-zero");
if (output->ndump)
error->all(FLERR,
"Cannot change box ortho/triclinic with dumps defined");
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->no_change_box)
error->all(FLERR,
"Cannot change box ortho/triclinic with "
"certain fixes defined");
domain->triclinic = 0;
domain->set_initial_box();
domain->set_global_box();
domain->set_local_box();
domain->print_box(" ");
} else if (ops[i].style == TRICLINIC) {
if (output->ndump)
error->all(FLERR,
"Cannot change box ortho/triclinic with dumps defined");
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->no_change_box)
error->all(FLERR,
"Cannot change box ortho/triclinic with "
"certain fixes defined");
domain->triclinic = 1;
domain->set_lamda_box();
domain->set_initial_box();
domain->set_global_box();
domain->set_local_box();
domain->print_box(" ");
} else if (ops[i].style == SET) {
save_box_state();
} else if (ops[i].style == REMAP) {
// convert atoms to lamda coords, using last box state
// convert atoms back to box coords, using current box state
// save current box state
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],boxlo,h_inv);
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit)
domain->lamda2x(x[i],x[i]);
save_box_state();
}
}
// clean up
delete [] ops;
// apply shrink-wrap boundary conditions
if (domain->nonperiodic == 2) domain->reset_box();
// 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;
+ tagint *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_LMP_BIGINT,MPI_SUM,world);
if (natoms != atom->natoms && comm->me == 0) {
char str[128];
sprintf(str,"Lost atoms via change_box: original " BIGINT_FORMAT
" current " BIGINT_FORMAT,atom->natoms,natoms);
error->warning(FLERR,str);
}
}
/* ----------------------------------------------------------------------
parse optional parameters
------------------------------------------------------------------------- */
void ChangeBox::options(int narg, char **arg)
{
if (narg < 0) error->all(FLERR,"Illegal change_box command");
scaleflag = 1;
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal change_box command");
if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
else error->all(FLERR,"Illegal change_box command");
iarg += 2;
} else error->all(FLERR,"Illegal change_box command");
}
}
/* ----------------------------------------------------------------------
save current box state for converting atoms to lamda coords
------------------------------------------------------------------------- */
void ChangeBox::save_box_state()
{
boxlo[0] = domain->boxlo[0];
boxlo[1] = domain->boxlo[1];
boxlo[2] = domain->boxlo[2];
for (int i = 0; i < 6; i++)
h_inv[i] = domain->h_inv[i];
}
/* ----------------------------------------------------------------------
oldvol = box volume before dim3 changed
newvol = box volume after dim3 changed
reset box lengths of dim1/2 to preserve old volume
------------------------------------------------------------------------- */
void ChangeBox::volume_preserve(int dim1, int dim2, double oldvol)
{
// invoke set_initial_box()
// in case change by caller to dim3 was invalid or on shrink-wrapped dim
domain->set_initial_box();
// calculate newvol using boxlo/hi since xyz prd are not yet reset
double newvol;
if (domain->dimension == 2) {
newvol = domain->boxhi[0] - domain->boxlo[0];
newvol *= domain->boxhi[1] - domain->boxlo[1];
} else {
newvol = domain->boxhi[0] - domain->boxlo[0];
newvol *= domain->boxhi[1] - domain->boxlo[1];
newvol *= domain->boxhi[2] - domain->boxlo[2];
}
double scale = oldvol/newvol;
double mid,delta;
// change dim1 only
if (dim2 < 0) {
mid = 0.5 * (domain->boxlo[dim1] + domain->boxhi[dim1]);
delta = domain->boxlo[dim1] - mid;
domain->boxlo[dim1] = mid + scale*delta;
delta = domain->boxhi[dim1] - mid;
domain->boxhi[dim1] = mid + scale*delta;
// change dim1 and dim2, keeping their relative aspect ratio constant
// both are scaled by sqrt(scale)
} else {
mid = 0.5 * (domain->boxlo[dim1] + domain->boxhi[dim1]);
delta = domain->boxlo[dim1] - mid;
domain->boxlo[dim1] = mid + sqrt(scale)*delta;
delta = domain->boxhi[dim1] - mid;
domain->boxhi[dim1] = mid + sqrt(scale)*delta;
mid = 0.5 * (domain->boxlo[dim2] + domain->boxhi[dim2]);
delta = domain->boxlo[dim2] - mid;
domain->boxlo[dim2] = mid + sqrt(scale)*delta;
delta = domain->boxhi[dim2] - mid;
domain->boxhi[dim2] = mid + sqrt(scale)*delta;
}
}
diff --git a/src/compute_com_molecule.cpp b/src/compute_com_molecule.cpp
index 2b52919f8..80e745f05 100644
--- a/src/compute_com_molecule.cpp
+++ b/src/compute_com_molecule.cpp
@@ -1,154 +1,154 @@
/* ----------------------------------------------------------------------
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 "compute_com_molecule.h"
#include "atom.h"
#include "update.h"
#include "domain.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeCOMMolecule::ComputeCOMMolecule(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg != 3) error->all(FLERR,"Illegal compute com/molecule command");
if (atom->molecular == 0)
error->all(FLERR,"Compute com/molecule requires molecular atom style");
array_flag = 1;
size_array_cols = 3;
extarray = 0;
// setup molecule-based data
nmolecules = molecules_in_group(idlo,idhi);
size_array_rows = nmolecules;
memory->create(massproc,nmolecules,"com/molecule:massproc");
memory->create(masstotal,nmolecules,"com/molecule:masstotal");
memory->create(com,nmolecules,3,"com/molecule:com");
memory->create(comall,nmolecules,3,"com/molecule:comall");
array = comall;
// compute masstotal for each molecule
int *mask = atom->mask;
int *molecule = atom->molecule;
int *type = atom->type;
double *mass = atom->mass;
double *rmass = atom->rmass;
int nlocal = atom->nlocal;
int i,imol;
double massone;
for (i = 0; i < nmolecules; i++) massproc[i] = 0.0;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
imol = molecule[i];
if (molmap) imol = molmap[imol-idlo];
else imol--;
massproc[imol] += massone;
}
MPI_Allreduce(massproc,masstotal,nmolecules,MPI_DOUBLE,MPI_SUM,world);
}
/* ---------------------------------------------------------------------- */
ComputeCOMMolecule::~ComputeCOMMolecule()
{
memory->destroy(massproc);
memory->destroy(masstotal);
memory->destroy(com);
memory->destroy(comall);
}
/* ---------------------------------------------------------------------- */
void ComputeCOMMolecule::init()
{
int ntmp = molecules_in_group(idlo,idhi);
if (ntmp != nmolecules)
error->all(FLERR,"Molecule count changed in compute com/molecule");
}
/* ---------------------------------------------------------------------- */
void ComputeCOMMolecule::compute_array()
{
int i,imol;
double xbox,ybox,zbox;
double massone;
invoked_array = update->ntimestep;
for (i = 0; i < nmolecules; i++)
com[i][0] = com[i][1] = com[i][2] = 0.0;
double **x = atom->x;
int *mask = atom->mask;
int *molecule = atom->molecule;
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
double *mass = atom->mass;
double *rmass = atom->rmass;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
imol = molecule[i];
if (molmap) imol = molmap[imol-idlo];
else imol--;
com[imol][0] += (x[i][0] + xbox*xprd) * massone;
com[imol][1] += (x[i][1] + ybox*yprd) * massone;
com[imol][2] += (x[i][2] + zbox*zprd) * massone;
}
MPI_Allreduce(&com[0][0],&comall[0][0],3*nmolecules,
MPI_DOUBLE,MPI_SUM,world);
for (i = 0; i < nmolecules; i++) {
comall[i][0] /= masstotal[i];
comall[i][1] /= masstotal[i];
comall[i][2] /= masstotal[i];
}
}
/* ----------------------------------------------------------------------
memory usage of local data
------------------------------------------------------------------------- */
double ComputeCOMMolecule::memory_usage()
{
double bytes = 2*nmolecules * sizeof(double);
if (molmap) bytes += (idhi-idlo+1) * sizeof(int);
bytes += 2*nmolecules*3 * sizeof(double);
return bytes;
}
diff --git a/src/compute_displace_atom.cpp b/src/compute_displace_atom.cpp
index f34e74c91..b89acd7f5 100644
--- a/src/compute_displace_atom.cpp
+++ b/src/compute_displace_atom.cpp
@@ -1,160 +1,160 @@
/* ----------------------------------------------------------------------
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 "string.h"
#include "compute_displace_atom.h"
#include "atom.h"
#include "update.h"
#include "group.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeDisplaceAtom::ComputeDisplaceAtom(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg != 3) error->all(FLERR,"Illegal compute displace/atom command");
peratom_flag = 1;
size_peratom_cols = 4;
// create a new fix store/state style
// id = compute-ID + store_state, fix group = compute group
int n = strlen(id) + strlen("_store_state") + 1;
id_fix = new char[n];
strcpy(id_fix,id);
strcat(id_fix,"_store_state");
char **newarg = new char*[7];
newarg[0] = id_fix;
newarg[1] = group->names[igroup];
newarg[2] = (char *) "store/state";
newarg[3] = (char *) "0";
newarg[4] = (char *) "xu";
newarg[5] = (char *) "yu";
newarg[6] = (char *) "zu";
modify->add_fix(7,newarg);
delete [] newarg;
nmax = 0;
displace = NULL;
}
/* ---------------------------------------------------------------------- */
ComputeDisplaceAtom::~ComputeDisplaceAtom()
{
// check nfix in case all fixes have already been deleted
if (modify->nfix) modify->delete_fix(id_fix);
delete [] id_fix;
memory->destroy(displace);
}
/* ---------------------------------------------------------------------- */
void ComputeDisplaceAtom::init()
{
// set fix which stores original atom coords
int ifix = modify->find_fix(id_fix);
if (ifix < 0) error->all(FLERR,"Could not find compute displace/atom fix ID");
fix = modify->fix[ifix];
}
/* ---------------------------------------------------------------------- */
void ComputeDisplaceAtom::compute_peratom()
{
invoked_peratom = update->ntimestep;
// grow local displacement array if necessary
if (atom->nlocal > nmax) {
memory->destroy(displace);
nmax = atom->nmax;
memory->create(displace,nmax,4,"displace/atom:displace");
array_atom = displace;
}
// dx,dy,dz = displacement of atom from original position
// original unwrapped position is stored by fix
// for triclinic, need to unwrap current atom coord via h matrix
double **xoriginal = fix->array_atom;
double **x = atom->x;
int *mask = atom->mask;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
double *h = domain->h;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
int xbox,ybox,zbox;
double dx,dy,dz;
if (domain->triclinic == 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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + xbox*xprd - xoriginal[i][0];
dy = x[i][1] + ybox*yprd - xoriginal[i][1];
dz = x[i][2] + zbox*zprd - xoriginal[i][2];
displace[i][0] = dx;
displace[i][1] = dy;
displace[i][2] = dz;
displace[i][3] = sqrt(dx*dx + dy*dy + dz*dz);
} else displace[i][0] = displace[i][1] =
displace[i][2] = displace[i][3] = 0.0;
} 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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox - xoriginal[i][0];
dy = x[i][1] + h[1]*ybox + h[3]*zbox - xoriginal[i][1];
dz = x[i][2] + h[2]*zbox - xoriginal[i][2];
displace[i][0] = dx;
displace[i][1] = dy;
displace[i][2] = dz;
displace[i][3] = sqrt(dx*dx + dy*dy + dz*dz);
} else displace[i][0] = displace[i][1] =
displace[i][2] = displace[i][3] = 0.0;
}
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double ComputeDisplaceAtom::memory_usage()
{
double bytes = nmax*4 * sizeof(double);
return bytes;
}
diff --git a/src/compute_group_group.h b/src/compute_group_group.h
index 918bce7b1..c881b08cb 100644
--- a/src/compute_group_group.h
+++ b/src/compute_group_group.h
@@ -1,77 +1,89 @@
/* -*- c++ -*- ----------------------------------------------------------
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 COMPUTE_CLASS
ComputeStyle(group/group,ComputeGroupGroup)
#else
#ifndef LMP_COMPUTE_GROUP_GROUP_H
#define LMP_COMPUTE_GROUP_GROUP_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeGroupGroup : public Compute {
public:
ComputeGroupGroup(class LAMMPS *, int, char **);
~ComputeGroupGroup();
void init();
void init_list(int, class NeighList *);
double compute_scalar();
void compute_vector();
private:
char *group2;
int jgroup,jgroupbit,othergroupbit;
double **cutsq;
double e_self,e_correction;
int pairflag,kspaceflag,boundaryflag;
class Pair *pair;
class NeighList *list;
class KSpace *kspace;
void pair_contribution();
void kspace_contribution();
void kspace_correction();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Compute group/group group ID does not exist
Self-explanatory.
E: No pair style defined for compute group/group
Cannot calculate group interactions without a pair style defined.
E: Pair style does not support compute group/group
The pair_style does not have a single() function, so it cannot be
invokded by the compute group/group command.
+E: No Kspace style defined for compute group/group
+
+Self-explanatory.
+
+E: Kspace style does not support compute group/group
+
+Self-explanatory.
+
+W: Both groups in compute group/group have a net charge; the Kspace boundary correction to energy will be non-zero
+
+Self-explantory.
+
*/
diff --git a/src/compute_gyration.cpp b/src/compute_gyration.cpp
index 551cfc85b..fb650f4bf 100644
--- a/src/compute_gyration.cpp
+++ b/src/compute_gyration.cpp
@@ -1,117 +1,116 @@
/* ----------------------------------------------------------------------
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 "compute_gyration.h"
#include "update.h"
#include "atom.h"
#include "group.h"
#include "domain.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeGyration::ComputeGyration(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg != 3) error->all(FLERR,"Illegal compute gyration command");
scalar_flag = vector_flag = 1;
size_vector = 6;
extscalar = 0;
extvector = 0;
vector = new double[6];
}
/* ---------------------------------------------------------------------- */
ComputeGyration::~ComputeGyration()
{
delete [] vector;
}
/* ---------------------------------------------------------------------- */
void ComputeGyration::init()
{
masstotal = group->mass(igroup);
}
/* ---------------------------------------------------------------------- */
double ComputeGyration::compute_scalar()
{
invoked_scalar = update->ntimestep;
double xcm[3];
group->xcm(igroup,masstotal,xcm);
scalar = group->gyration(igroup,masstotal,xcm);
return scalar;
}
/* ----------------------------------------------------------------------
compute the radius-of-gyration tensor of group of atoms
around center-of-mass cm
must unwrap atoms to compute Rg tensor correctly
------------------------------------------------------------------------- */
void ComputeGyration::compute_vector()
{
invoked_vector = update->ntimestep;
- double masstotal;
double xcm[3];
group->xcm(igroup,masstotal,xcm);
double **x = atom->x;
int *mask = atom->mask;
int *type = atom->type;
- int *image = atom->image;
+ tagint *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[6];
rg[0] = rg[1] = rg[2] = rg[3] = rg[4] = rg[5] = 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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = (x[i][0] + xbox*xprd) - xcm[0];
dy = (x[i][1] + ybox*yprd) - xcm[1];
dz = (x[i][2] + zbox*zprd) - xcm[2];
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
rg[0] += dx*dx * massone;
rg[1] += dy*dy * massone;
rg[2] += dz*dz * massone;
rg[3] += dx*dy * massone;
rg[4] += dx*dz * massone;
rg[5] += dy*dz * massone;
}
MPI_Allreduce(rg,vector,6,MPI_DOUBLE,MPI_SUM,world);
if (masstotal == 0.0) return;
for (int i = 0; i < 6; i++) vector[i] /= masstotal;
}
diff --git a/src/compute_gyration_molecule.cpp b/src/compute_gyration_molecule.cpp
index 412a64e2e..92c5da07c 100644
--- a/src/compute_gyration_molecule.cpp
+++ b/src/compute_gyration_molecule.cpp
@@ -1,291 +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.
------------------------------------------------------------------------- */
#include "math.h"
#include "string.h"
#include "compute_gyration_molecule.h"
#include "atom.h"
#include "update.h"
#include "domain.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeGyrationMolecule::ComputeGyrationMolecule(LAMMPS *lmp,
int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg < 3) error->all(FLERR,"Illegal compute gyration/molecule command");
if (atom->molecular == 0)
error->all(FLERR,"Compute gyration/molecule requires molecular atom style");
tensor = 0;
int iarg = 3;
while (iarg < narg) {
if (strcmp(arg[iarg],"tensor") == 0) {
tensor = 1;
iarg++;
} else error->all(FLERR,"Illegal compute gyration/molecule command");
}
// setup molecule-based data
nmolecules = molecules_in_group(idlo,idhi);
memory->create(massproc,nmolecules,"gyration/molecule:massproc");
memory->create(masstotal,nmolecules,"gyration/molecule:masstotal");
memory->create(com,nmolecules,3,"gyration/molecule:com");
memory->create(comall,nmolecules,3,"gyration/molecule:comall");
rg = vector = NULL;
rgt = array = NULL;
if (tensor) {
memory->create(rgt,nmolecules,6,"gyration/molecule:rgt");
memory->create(array,nmolecules,6,"gyration/molecule:array");
array_flag = 1;
size_array_rows = nmolecules;
size_array_cols = 6;
extarray = 0;
} else {
memory->create(rg,nmolecules,"gyration/molecule:rg");
memory->create(vector,nmolecules,"gyration/molecule:vector");
vector_flag = 1;
size_vector = nmolecules;
extvector = 0;
}
// compute masstotal for each molecule
int *mask = atom->mask;
int *molecule = atom->molecule;
int *type = atom->type;
double *mass = atom->mass;
double *rmass = atom->rmass;
int nlocal = atom->nlocal;
int i,imol;
double massone;
for (i = 0; i < nmolecules; i++) massproc[i] = 0.0;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
imol = molecule[i];
if (molmap) imol = molmap[imol-idlo];
else imol--;
massproc[imol] += massone;
}
MPI_Allreduce(massproc,masstotal,nmolecules,MPI_DOUBLE,MPI_SUM,world);
}
/* ---------------------------------------------------------------------- */
ComputeGyrationMolecule::~ComputeGyrationMolecule()
{
memory->destroy(massproc);
memory->destroy(masstotal);
memory->destroy(com);
memory->destroy(comall);
memory->destroy(rg);
memory->destroy(rgt);
}
/* ---------------------------------------------------------------------- */
void ComputeGyrationMolecule::init()
{
int ntmp = molecules_in_group(idlo,idhi);
if (ntmp != nmolecules)
error->all(FLERR,"Molecule count changed in compute gyration/molecule");
}
/* ---------------------------------------------------------------------- */
void ComputeGyrationMolecule::compute_vector()
{
int i,imol;
double xbox,ybox,zbox,dx,dy,dz;
double massone;
invoked_array = update->ntimestep;
molcom();
for (i = 0; i < nmolecules; i++) rg[i] = 0.0;
double **x = atom->x;
int *mask = atom->mask;
int *molecule = atom->molecule;
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
double *mass = atom->mass;
double *rmass = atom->rmass;
int nlocal = atom->nlocal;
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
imol = molecule[i];
if (molmap) imol = molmap[imol-idlo];
else imol--;
dx = (x[i][0] + xbox*xprd) - comall[imol][0];
dy = (x[i][1] + ybox*yprd) - comall[imol][1];
dz = (x[i][2] + zbox*zprd) - comall[imol][2];
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
rg[imol] += (dx*dx + dy*dy + dz*dz) * massone;
}
MPI_Allreduce(rg,vector,nmolecules,MPI_DOUBLE,MPI_SUM,world);
for (i = 0; i < nmolecules; i++) vector[i] = sqrt(vector[i]/masstotal[i]);
}
/* ---------------------------------------------------------------------- */
void ComputeGyrationMolecule::compute_array()
{
int i,j,imol;
double xbox,ybox,zbox,dx,dy,dz;
double massone;
invoked_array = update->ntimestep;
molcom();
for (i = 0; i < nmolecules; i++)
for (j = 0; j < 6; j++)
rgt[i][j] = 0.0;
double **x = atom->x;
int *mask = atom->mask;
int *molecule = atom->molecule;
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
double *mass = atom->mass;
double *rmass = atom->rmass;
int nlocal = atom->nlocal;
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
imol = molecule[i];
if (molmap) imol = molmap[imol-idlo];
else imol--;
dx = (x[i][0] + xbox*xprd) - comall[imol][0];
dy = (x[i][1] + ybox*yprd) - comall[imol][1];
dz = (x[i][2] + zbox*zprd) - comall[imol][2];
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
rgt[imol][0] += dx*dx * massone;
rgt[imol][1] += dy*dy * massone;
rgt[imol][2] += dz*dz * massone;
rgt[imol][3] += dx*dy * massone;
rgt[imol][4] += dx*dz * massone;
rgt[imol][5] += dy*dz * massone;
}
if (nmolecules)
MPI_Allreduce(&rgt[0][0],&array[0][0],nmolecules*6,
MPI_DOUBLE,MPI_SUM,world);
for (i = 0; i < nmolecules; i++)
for (j = 0; j < 6; j++)
array[i][j] /= masstotal[i];
}
/* ----------------------------------------------------------------------
calculate per-molecule COM
------------------------------------------------------------------------- */
void ComputeGyrationMolecule::molcom()
{
int i,imol;
double xbox,ybox,zbox,dx,dy,dz;
double massone;
for (i = 0; i < nmolecules; i++)
com[i][0] = com[i][1] = com[i][2] = 0.0;
double **x = atom->x;
int *mask = atom->mask;
int *molecule = atom->molecule;
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
double *mass = atom->mass;
double *rmass = atom->rmass;
int nlocal = atom->nlocal;
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
imol = molecule[i];
if (molmap) imol = molmap[imol-idlo];
else imol--;
com[imol][0] += (x[i][0] + xbox*xprd) * massone;
com[imol][1] += (x[i][1] + ybox*yprd) * massone;
com[imol][2] += (x[i][2] + zbox*zprd) * massone;
}
MPI_Allreduce(&com[0][0],&comall[0][0],3*nmolecules,
MPI_DOUBLE,MPI_SUM,world);
for (i = 0; i < nmolecules; i++) {
comall[i][0] /= masstotal[i];
comall[i][1] /= masstotal[i];
comall[i][2] /= masstotal[i];
}
}
/* ----------------------------------------------------------------------
memory usage of local data
------------------------------------------------------------------------- */
double ComputeGyrationMolecule::memory_usage()
{
double bytes = 2*nmolecules * sizeof(double);
if (molmap) bytes += (idhi-idlo+1) * sizeof(int);
bytes += 2*nmolecules*3 * sizeof(double);
if (tensor) bytes += 2*6*nmolecules * sizeof(double);
else bytes += 2*nmolecules * sizeof(double);
return bytes;
}
diff --git a/src/compute_msd.cpp b/src/compute_msd.cpp
index 9941abe42..c77da886b 100644
--- a/src/compute_msd.cpp
+++ b/src/compute_msd.cpp
@@ -1,189 +1,189 @@
/* ----------------------------------------------------------------------
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 "compute_msd.h"
#include "atom.h"
#include "update.h"
#include "group.h"
#include "domain.h"
#include "modify.h"
#include "fix.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeMSD::ComputeMSD(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg < 3) error->all(FLERR,"Illegal compute msd command");
vector_flag = 1;
size_vector = 4;
extvector = 0;
// optional args
comflag = 0;
int iarg = 3;
while (iarg < narg) {
if (strcmp(arg[iarg],"com") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal compute msd command");
if (strcmp(arg[iarg+1],"no") == 0) comflag = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) comflag = 1;
else error->all(FLERR,"Illegal compute msd command");
iarg += 2;
} else error->all(FLERR,"Illegal compute msd command");
}
// create a new fix store/state style with or without com keyword
// id = compute-ID + store_state, fix group = compute group
int n = strlen(id) + strlen("_store_state") + 1;
id_fix = new char[n];
strcpy(id_fix,id);
strcat(id_fix,"_store_state");
char **newarg = new char*[9];
newarg[0] = id_fix;
newarg[1] = group->names[igroup];
newarg[2] = (char *) "store/state";
newarg[3] = (char *) "0";
newarg[4] = (char *) "xu";
newarg[5] = (char *) "yu";
newarg[6] = (char *) "zu";
newarg[7] = (char *) "com";
newarg[8] = (char *) "yes";
if (comflag) modify->add_fix(9,newarg);
else modify->add_fix(7,newarg);
delete [] newarg;
vector = new double[4];
}
/* ---------------------------------------------------------------------- */
ComputeMSD::~ComputeMSD()
{
// check nfix in case all fixes have already been deleted
if (modify->nfix) modify->delete_fix(id_fix);
delete [] id_fix;
delete [] vector;
}
/* ---------------------------------------------------------------------- */
void ComputeMSD::init()
{
// set fix which stores original atom coords
int ifix = modify->find_fix(id_fix);
if (ifix < 0) error->all(FLERR,"Could not find compute msd fix ID");
fix = modify->fix[ifix];
// nmsd = # of atoms in group
int *mask = atom->mask;
int nlocal = atom->nlocal;
nmsd = 0;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) nmsd++;
int nmsd_all;
MPI_Allreduce(&nmsd,&nmsd_all,1,MPI_INT,MPI_SUM,world);
nmsd = nmsd_all;
masstotal = group->mass(igroup);
}
/* ---------------------------------------------------------------------- */
void ComputeMSD::compute_vector()
{
invoked_vector = update->ntimestep;
// cm = current center of mass
double cm[3];
if (comflag) group->xcm(igroup,masstotal,cm);
else cm[0] = cm[1] = cm[2] = 0.0;
// dx,dy,dz = displacement of atom from original position
// original unwrapped position is stored by fix
// relative to center of mass if comflag is set
// for triclinic, need to unwrap current atom coord via h matrix
double **xoriginal = fix->array_atom;
double **x = atom->x;
int *mask = atom->mask;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
double *h = domain->h;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
double dx,dy,dz;
int xbox,ybox,zbox;
double msd[4];
msd[0] = msd[1] = msd[2] = msd[3] = 0.0;
if (domain->triclinic == 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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + xbox*xprd - cm[0] - xoriginal[i][0];
dy = x[i][1] + ybox*yprd - cm[1] - xoriginal[i][1];
dz = x[i][2] + zbox*zprd - cm[2] - xoriginal[i][2];
msd[0] += dx*dx;
msd[1] += dy*dy;
msd[2] += dz*dz;
msd[3] += dx*dx + dy*dy + dz*dz;
}
} 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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox -
cm[0] - xoriginal[i][0];
dy = x[i][1] + h[1]*ybox + h[3]*zbox - cm[1] - xoriginal[i][1];
dz = x[i][2] + h[2]*zbox - cm[2] - xoriginal[i][2];
msd[0] += dx*dx;
msd[1] += dy*dy;
msd[2] += dz*dz;
msd[3] += dx*dx + dy*dy + dz*dz;
}
}
MPI_Allreduce(msd,vector,4,MPI_DOUBLE,MPI_SUM,world);
if (nmsd) {
vector[0] /= nmsd;
vector[1] /= nmsd;
vector[2] /= nmsd;
vector[3] /= nmsd;
}
}
diff --git a/src/compute_msd_molecule.cpp b/src/compute_msd_molecule.cpp
index bd4e9960f..c98cca8e1 100644
--- a/src/compute_msd_molecule.cpp
+++ b/src/compute_msd_molecule.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 "compute_msd_molecule.h"
#include "atom.h"
#include "update.h"
#include "domain.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeMSDMolecule::ComputeMSDMolecule(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg != 3) error->all(FLERR,"Illegal compute msd/molecule command");
if (atom->molecular == 0)
error->all(FLERR,"Compute msd/molecule requires molecular atom style");
array_flag = 1;
size_array_cols = 4;
extarray = 0;
// setup molecule-based data and initial COM positions
nmolecules = molecules_in_group(idlo,idhi);
size_array_rows = nmolecules;
memory->create(massproc,nmolecules,"msd/molecule:massproc");
memory->create(masstotal,nmolecules,"msd/molecule:masstotal");
memory->create(com,nmolecules,3,"msd/molecule:com");
memory->create(comall,nmolecules,3,"msd/molecule:comall");
memory->create(cominit,nmolecules,3,"msd/molecule:cominit");
memory->create(msd,nmolecules,4,"msd/molecule:msd");
array = msd;
// compute masstotal for each molecule
int *mask = atom->mask;
int *molecule = atom->molecule;
int *type = atom->type;
double *mass = atom->mass;
double *rmass = atom->rmass;
int nlocal = atom->nlocal;
int i,imol;
double massone;
for (i = 0; i < nmolecules; i++) massproc[i] = 0.0;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
imol = molecule[i];
if (molmap) imol = molmap[imol-idlo];
else imol--;
massproc[imol] += massone;
}
MPI_Allreduce(massproc,masstotal,nmolecules,MPI_DOUBLE,MPI_SUM,world);
// compute initial COM for each molecule
firstflag = 1;
compute_array();
for (i = 0; i < nmolecules; i++) {
cominit[i][0] = comall[i][0];
cominit[i][1] = comall[i][1];
cominit[i][2] = comall[i][2];
}
firstflag = 0;
}
/* ---------------------------------------------------------------------- */
ComputeMSDMolecule::~ComputeMSDMolecule()
{
memory->destroy(massproc);
memory->destroy(masstotal);
memory->destroy(com);
memory->destroy(comall);
memory->destroy(cominit);
memory->destroy(msd);
}
/* ---------------------------------------------------------------------- */
void ComputeMSDMolecule::init()
{
int ntmp = molecules_in_group(idlo,idhi);
if (ntmp != nmolecules)
error->all(FLERR,"Molecule count changed in compute msd/molecule");
}
/* ---------------------------------------------------------------------- */
void ComputeMSDMolecule::compute_array()
{
int i,imol;
double xbox,ybox,zbox,dx,dy,dz;
double massone;
invoked_array = update->ntimestep;
// compute current COM positions
for (i = 0; i < nmolecules; i++)
com[i][0] = com[i][1] = com[i][2] = 0.0;
double **x = atom->x;
int *mask = atom->mask;
int *molecule = atom->molecule;
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
double *mass = atom->mass;
double *rmass = atom->rmass;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
imol = molecule[i];
if (molmap) imol = molmap[imol-idlo];
else imol--;
com[imol][0] += (x[i][0] + xbox*xprd) * massone;
com[imol][1] += (x[i][1] + ybox*yprd) * massone;
com[imol][2] += (x[i][2] + zbox*zprd) * massone;
}
MPI_Allreduce(&com[0][0],&comall[0][0],3*nmolecules,
MPI_DOUBLE,MPI_SUM,world);
for (i = 0; i < nmolecules; i++) {
comall[i][0] /= masstotal[i];
comall[i][1] /= masstotal[i];
comall[i][2] /= masstotal[i];
}
// MSD is difference between current and initial COM
// cominit does not yet exist when called from constructor
if (firstflag) return;
for (i = 0; i < nmolecules; i++) {
dx = comall[i][0] - cominit[i][0];
dy = comall[i][1] - cominit[i][1];
dz = comall[i][2] - cominit[i][2];
msd[i][0] = dx*dx;
msd[i][1] = dy*dy;
msd[i][2] = dz*dz;
msd[i][3] = dx*dx + dy*dy + dz*dz;
}
}
/* ----------------------------------------------------------------------
memory usage of local data
------------------------------------------------------------------------- */
double ComputeMSDMolecule::memory_usage()
{
double bytes = 2*nmolecules * sizeof(double);
if (molmap) bytes += (idhi-idlo+1) * sizeof(int);
bytes += 2*nmolecules*3 * sizeof(double);
bytes += nmolecules*4 * sizeof(double);
return bytes;
}
diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp
index 4336c890a..cce33ddb5 100644
--- a/src/compute_property_atom.cpp
+++ b/src/compute_property_atom.cpp
@@ -1,1587 +1,1587 @@
/* ----------------------------------------------------------------------
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 "string.h"
#include "compute_property_atom.h"
#include "math_extra.h"
#include "atom.h"
#include "atom_vec_ellipsoid.h"
#include "atom_vec_line.h"
#include "atom_vec_tri.h"
#include "update.h"
#include "domain.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg < 4) error->all(FLERR,"Illegal compute property/atom command");
peratom_flag = 1;
nvalues = narg - 3;
if (nvalues == 1) size_peratom_cols = 0;
else size_peratom_cols = nvalues;
// parse input values
// customize a new keyword by adding to if statement
pack_choice = new FnPtrPack[nvalues];
int i;
for (int iarg = 3; iarg < narg; iarg++) {
i = iarg-3;
if (strcmp(arg[iarg],"id") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_id;
} else if (strcmp(arg[iarg],"mol") == 0) {
if (!atom->molecule_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_molecule;
} else if (strcmp(arg[iarg],"type") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_type;
} else if (strcmp(arg[iarg],"mass") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_mass;
} else if (strcmp(arg[iarg],"x") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_x;
} else if (strcmp(arg[iarg],"y") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_y;
} else if (strcmp(arg[iarg],"z") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_z;
} else if (strcmp(arg[iarg],"xs") == 0) {
if (domain->triclinic)
pack_choice[i] = &ComputePropertyAtom::pack_xs_triclinic;
else pack_choice[i] = &ComputePropertyAtom::pack_xs;
} else if (strcmp(arg[iarg],"ys") == 0) {
if (domain->triclinic)
pack_choice[i] = &ComputePropertyAtom::pack_ys_triclinic;
else pack_choice[i] = &ComputePropertyAtom::pack_ys;
} else if (strcmp(arg[iarg],"zs") == 0) {
if (domain->triclinic)
pack_choice[i] = &ComputePropertyAtom::pack_zs_triclinic;
else pack_choice[i] = &ComputePropertyAtom::pack_zs;
} else if (strcmp(arg[iarg],"xu") == 0) {
if (domain->triclinic)
pack_choice[i] = &ComputePropertyAtom::pack_xu_triclinic;
else pack_choice[i] = &ComputePropertyAtom::pack_xu;
} else if (strcmp(arg[iarg],"yu") == 0) {
if (domain->triclinic)
pack_choice[i] = &ComputePropertyAtom::pack_yu_triclinic;
else pack_choice[i] = &ComputePropertyAtom::pack_yu;
} else if (strcmp(arg[iarg],"zu") == 0) {
if (domain->triclinic)
pack_choice[i] = &ComputePropertyAtom::pack_zu_triclinic;
else pack_choice[i] = &ComputePropertyAtom::pack_zu;
} else if (strcmp(arg[iarg],"ix") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_ix;
} else if (strcmp(arg[iarg],"iy") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_iy;
} else if (strcmp(arg[iarg],"iz") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_iz;
} else if (strcmp(arg[iarg],"vx") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_vx;
} else if (strcmp(arg[iarg],"vy") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_vy;
} else if (strcmp(arg[iarg],"vz") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_vz;
} else if (strcmp(arg[iarg],"fx") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_fx;
} else if (strcmp(arg[iarg],"fy") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_fy;
} else if (strcmp(arg[iarg],"fz") == 0) {
pack_choice[i] = &ComputePropertyAtom::pack_fz;
} else if (strcmp(arg[iarg],"q") == 0) {
if (!atom->q_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_q;
} else if (strcmp(arg[iarg],"mux") == 0) {
if (!atom->mu_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_mux;
} else if (strcmp(arg[iarg],"muy") == 0) {
if (!atom->mu_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_muy;
} else if (strcmp(arg[iarg],"muz") == 0) {
if (!atom->mu_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_muz;
} else if (strcmp(arg[iarg],"mu") == 0) {
if (!atom->mu_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_mu;
} else if (strcmp(arg[iarg],"radius") == 0) {
if (!atom->radius_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_radius;
} else if (strcmp(arg[iarg],"diameter") == 0) {
if (!atom->radius_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_diameter;
} else if (strcmp(arg[iarg],"omegax") == 0) {
if (!atom->omega_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_omegax;
} else if (strcmp(arg[iarg],"omegay") == 0) {
if (!atom->omega_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_omegay;
} else if (strcmp(arg[iarg],"omegaz") == 0) {
if (!atom->omega_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_omegaz;
} else if (strcmp(arg[iarg],"angmomx") == 0) {
if (!atom->angmom_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_angmomx;
} else if (strcmp(arg[iarg],"angmomy") == 0) {
if (!atom->angmom_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_angmomy;
} else if (strcmp(arg[iarg],"angmomz") == 0) {
if (!atom->angmom_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_angmomz;
} else if (strcmp(arg[iarg],"shapex") == 0) {
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_shapex;
} else if (strcmp(arg[iarg],"shapey") == 0) {
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_shapey;
} else if (strcmp(arg[iarg],"shapez") == 0) {
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_shapez;
} else if (strcmp(arg[iarg],"quatw") == 0) {
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_quatw;
} else if (strcmp(arg[iarg],"quati") == 0) {
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_quati;
} else if (strcmp(arg[iarg],"quatj") == 0) {
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_quatj;
} else if (strcmp(arg[iarg],"quatk") == 0) {
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_quatk;
} else if (strcmp(arg[iarg],"tqx") == 0) {
if (!atom->torque_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_tqx;
} else if (strcmp(arg[iarg],"tqy") == 0) {
if (!atom->torque_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_tqy;
} else if (strcmp(arg[iarg],"tqz") == 0) {
if (!atom->torque_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_tqz;
} else if (strcmp(arg[iarg],"spin") == 0) {
if (!atom->spin_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_spin;
} else if (strcmp(arg[iarg],"eradius") == 0) {
if (!atom->eradius_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_eradius;
} else if (strcmp(arg[iarg],"ervel") == 0) {
if (!atom->ervel_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_ervel;
} else if (strcmp(arg[iarg],"erforce") == 0) {
if (!atom->erforce_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_erforce;
} else if (strcmp(arg[iarg],"end1x") == 0) {
avec_line = (AtomVecLine *) atom->style_match("line");
if (!avec_line) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_end1x;
} else if (strcmp(arg[iarg],"end1y") == 0) {
avec_line = (AtomVecLine *) atom->style_match("line");
if (!avec_line) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_end1y;
} else if (strcmp(arg[iarg],"end1z") == 0) {
avec_line = (AtomVecLine *) atom->style_match("line");
if (!avec_line) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_end1z;
} else if (strcmp(arg[iarg],"end2x") == 0) {
avec_line = (AtomVecLine *) atom->style_match("line");
if (!avec_line) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_end2x;
} else if (strcmp(arg[iarg],"end2y") == 0) {
avec_line = (AtomVecLine *) atom->style_match("line");
if (!avec_line) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_end2y;
} else if (strcmp(arg[iarg],"end2z") == 0) {
avec_line = (AtomVecLine *) atom->style_match("line");
if (!avec_line) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_end2z;
} else if (strcmp(arg[iarg],"corner1x") == 0) {
avec_tri = (AtomVecTri *) atom->style_match("tri");
if (!avec_tri) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_corner1x;
} else if (strcmp(arg[iarg],"corner1y") == 0) {
avec_tri = (AtomVecTri *) atom->style_match("tri");
if (!avec_tri) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_corner1y;
} else if (strcmp(arg[iarg],"corner1z") == 0) {
avec_tri = (AtomVecTri *) atom->style_match("tri");
if (!avec_tri) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_corner1z;
} else if (strcmp(arg[iarg],"corner2x") == 0) {
avec_tri = (AtomVecTri *) atom->style_match("tri");
if (!avec_tri) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_corner2x;
} else if (strcmp(arg[iarg],"corner2y") == 0) {
avec_tri = (AtomVecTri *) atom->style_match("tri");
if (!avec_tri) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_corner2y;
} else if (strcmp(arg[iarg],"corner2z") == 0) {
avec_tri = (AtomVecTri *) atom->style_match("tri");
if (!avec_tri) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_corner2z;
} else if (strcmp(arg[iarg],"corner3x") == 0) {
avec_tri = (AtomVecTri *) atom->style_match("tri");
if (!avec_tri) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_corner3x;
} else if (strcmp(arg[iarg],"corner3y") == 0) {
avec_tri = (AtomVecTri *) atom->style_match("tri");
if (!avec_tri) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_corner3y;
} else if (strcmp(arg[iarg],"corner3z") == 0) {
avec_tri = (AtomVecTri *) atom->style_match("tri");
if (!avec_tri) error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_corner3z;
} else error->all(FLERR,"Invalid keyword in compute property/atom command");
}
nmax = 0;
vector = NULL;
array = NULL;
}
/* ---------------------------------------------------------------------- */
ComputePropertyAtom::~ComputePropertyAtom()
{
delete [] pack_choice;
memory->destroy(vector);
memory->destroy(array);
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::compute_peratom()
{
invoked_peratom = update->ntimestep;
// grow vector or array if necessary
if (atom->nlocal > nmax) {
nmax = atom->nmax;
if (nvalues == 1) {
memory->destroy(vector);
memory->create(vector,nmax,"property/atom:vector");
vector_atom = vector;
} else {
memory->destroy(array);
memory->create(array,nmax,nvalues,"property/atom:array");
array_atom = array;
}
}
// fill vector or array with per-atom values
if (nvalues == 1) {
buf = vector;
(this->*pack_choice[0])(0);
} else {
buf = &array[0][0];
for (int n = 0; n < nvalues; n++)
(this->*pack_choice[n])(n);
}
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double ComputePropertyAtom::memory_usage()
{
double bytes = nmax*nvalues * sizeof(double);
return bytes;
}
/* ----------------------------------------------------------------------
one method for every keyword compute property/atom can output
the atom property is packed into buf starting at n with stride nvalues
customize a new keyword by adding a method
------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_id(int n)
{
int *tag = atom->tag;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = tag[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_molecule(int n)
{
int *molecule = atom->molecule;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = molecule[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_type(int n)
{
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = type[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_mass(int n)
{
int *type = atom->type;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (rmass) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = rmass[i];
else buf[n] = 0.0;
n += nvalues;
}
} else {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = mass[type[i]];
else buf[n] = 0.0;
n += nvalues;
}
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_x(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = x[i][0];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_y(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = x[i][1];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_z(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = x[i][2];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_xs(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double boxxlo = domain->boxlo[0];
double invxprd = 1.0/domain->xprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = (x[i][0] - boxxlo) * invxprd;
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_ys(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double boxylo = domain->boxlo[1];
double invyprd = 1.0/domain->yprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = (x[i][1] - boxylo) * invyprd;
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_zs(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double boxzlo = domain->boxlo[2];
double invzprd = 1.0/domain->zprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = (x[i][2] - boxzlo) * invzprd;
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_xs_triclinic(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
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]);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_ys_triclinic(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = h_inv[1]*(x[i][1]-boxlo[1]) + h_inv[3]*(x[i][2]-boxlo[2]);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_zs_triclinic(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
buf[n] = h_inv[2]*(x[i][2]-boxlo[2]);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_xu(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
- buf[n] = x[i][0] + ((image[i] & 1023) - 512) * xprd;
+ buf[n] = x[i][0] + ((image[i] & IMGMASK) - IMGMAX) * xprd;
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_yu(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double yprd = domain->yprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
- buf[n] = x[i][1] + ((image[i] >> 10 & 1023) - 512) * yprd;
+ buf[n] = x[i][1] + ((image[i] >> IMGBITS & IMGMASK) - IMGMAX) * yprd;
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_zu(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double zprd = domain->zprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
- buf[n] = x[i][2] + ((image[i] >> 20) - 512) * zprd;
+ buf[n] = x[i][2] + ((image[i] >> IMG2BITS) - IMGMAX) * zprd;
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_xu_triclinic(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *h = domain->h;
int xbox,ybox,zbox;
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
buf[n] = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_yu_triclinic(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *h = domain->h;
int ybox,zbox;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
buf[n] = x[i][1] + h[1]*ybox + h[3]*zbox;
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_zu_triclinic(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *h = domain->h;
int zbox;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
- zbox = (image[i] >> 20) - 512;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
buf[n] = x[i][2] + h[2]*zbox;
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_ix(int n)
{
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
- if (mask[i] & groupbit) buf[n] = (image[i] & 1023) - 512;
+ if (mask[i] & groupbit) buf[n] = (image[i] & IMGMASK) - IMGMAX;
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_iy(int n)
{
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
- if (mask[i] & groupbit) buf[n] = (image[i] >> 10 & 1023) - 512;
+ if (mask[i] & groupbit) buf[n] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_iz(int n)
{
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
- if (mask[i] & groupbit) buf[n] = (image[i] >> 20) - 512;
+ if (mask[i] & groupbit) buf[n] = (image[i] >> IMG2BITS) - IMGMAX;
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_vx(int n)
{
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = v[i][0];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_vy(int n)
{
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = v[i][1];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_vz(int n)
{
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = v[i][2];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_fx(int n)
{
double **f = atom->f;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = f[i][0];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_fy(int n)
{
double **f = atom->f;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = f[i][1];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_fz(int n)
{
double **f = atom->f;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = f[i][2];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_q(int n)
{
double *q = atom->q;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = q[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_mux(int n)
{
double **mu = atom->mu;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = mu[i][0];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_muy(int n)
{
double **mu = atom->mu;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = mu[i][1];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_muz(int n)
{
double **mu = atom->mu;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = mu[i][2];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_mu(int n)
{
double **mu = atom->mu;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = mu[i][3];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_radius(int n)
{
double *radius = atom->radius;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = radius[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_diameter(int n)
{
double *radius = atom->radius;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = 2.0*radius[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_omegax(int n)
{
double **omega = atom->omega;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = omega[i][0];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_omegay(int n)
{
double **omega = atom->omega;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = omega[i][1];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_omegaz(int n)
{
double **omega = atom->omega;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = omega[i][2];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_angmomx(int n)
{
double **angmom = atom->angmom;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = angmom[i][0];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_angmomy(int n)
{
double **angmom = atom->angmom;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = angmom[i][1];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_angmomz(int n)
{
double **angmom = atom->angmom;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = angmom[i][2];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_shapex(int n)
{
AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && ellipsoid[i] >= 0)
buf[n] = bonus[ellipsoid[i]].shape[0];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_shapey(int n)
{
AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && ellipsoid[i] >= 0)
buf[n] = bonus[ellipsoid[i]].shape[1];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_shapez(int n)
{
AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && ellipsoid[i] >= 0)
buf[n] = bonus[ellipsoid[i]].shape[2];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_quatw(int n)
{
AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && ellipsoid[i] >= 0)
buf[n] = bonus[ellipsoid[i]].quat[0];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_quati(int n)
{
AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && ellipsoid[i] >= 0)
buf[n] = bonus[ellipsoid[i]].quat[1];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_quatj(int n)
{
AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && ellipsoid[i] >= 0)
buf[n] = bonus[ellipsoid[i]].quat[2];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_quatk(int n)
{
AtomVecEllipsoid::Bonus *bonus = avec_ellipsoid->bonus;
int *ellipsoid = atom->ellipsoid;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && ellipsoid[i] >= 0)
buf[n] = bonus[ellipsoid[i]].quat[3];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_tqx(int n)
{
double **torque = atom->torque;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = torque[i][0];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_tqy(int n)
{
double **torque = atom->torque;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = torque[i][1];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_tqz(int n)
{
double **torque = atom->torque;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = torque[i][2];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_spin(int n)
{
int *spin = atom->spin;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = spin[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_eradius(int n)
{
double *eradius = atom->eradius;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = eradius[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_ervel(int n)
{
double *ervel = atom->ervel;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = ervel[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_erforce(int n)
{
double *erforce = atom->erforce;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = erforce[i];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_end1x(int n)
{
AtomVecLine::Bonus *bonus = avec_line->bonus;
int *line = atom->line;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && line[i] >= 0)
buf[n] = x[i][0] - 0.5*bonus[line[i]].length*cos(bonus[line[i]].theta);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_end1y(int n)
{
AtomVecLine::Bonus *bonus = avec_line->bonus;
int *line = atom->line;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && line[i] >= 0)
buf[n] = x[i][1] - 0.5*bonus[line[i]].length*sin(bonus[line[i]].theta);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_end1z(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = x[i][2];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_end2x(int n)
{
AtomVecLine::Bonus *bonus = avec_line->bonus;
int *line = atom->line;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && line[i] >= 0)
buf[n] = x[i][0] + 0.5*bonus[line[i]].length*cos(bonus[line[i]].theta);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_end2y(int n)
{
AtomVecLine::Bonus *bonus = avec_line->bonus;
int *line = atom->line;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && line[i] >= 0)
buf[n] = x[i][1] + 0.5*bonus[line[i]].length*sin(bonus[line[i]].theta);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_end2z(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = x[i][2];
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_corner1x(int n)
{
AtomVecTri::Bonus *bonus = avec_tri->bonus;
int *tri = atom->tri;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double p[3][3],c[3];
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && tri[i] >= 0) {
MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
MathExtra::matvec(p,bonus[tri[i]].c1,c);
buf[n] = x[i][0] + c[0];
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_corner1y(int n)
{
AtomVecTri::Bonus *bonus = avec_tri->bonus;
int *tri = atom->tri;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double p[3][3],c[3];
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && tri[i] >= 0) {
MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
MathExtra::matvec(p,bonus[tri[i]].c1,c);
buf[n] = x[i][1] + c[1];
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_corner1z(int n)
{
AtomVecTri::Bonus *bonus = avec_tri->bonus;
int *tri = atom->tri;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double p[3][3],c[3];
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && tri[i] >= 0) {
MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
MathExtra::matvec(p,bonus[tri[i]].c1,c);
buf[n] = x[i][2] + c[2];
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_corner2x(int n)
{
AtomVecTri::Bonus *bonus = avec_tri->bonus;
int *tri = atom->tri;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double p[3][3],c[3];
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && tri[i] >= 0) {
MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
MathExtra::matvec(p,bonus[tri[i]].c2,c);
buf[n] = x[i][0] + c[0];
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_corner2y(int n)
{
AtomVecTri::Bonus *bonus = avec_tri->bonus;
int *tri = atom->tri;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double p[3][3],c[3];
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && tri[i] >= 0) {
MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
MathExtra::matvec(p,bonus[tri[i]].c2,c);
buf[n] = x[i][1] + c[1];
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_corner2z(int n)
{
AtomVecTri::Bonus *bonus = avec_tri->bonus;
int *tri = atom->tri;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double p[3][3],c[3];
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && tri[i] >= 0) {
MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
MathExtra::matvec(p,bonus[tri[i]].c2,c);
buf[n] = x[i][2] + c[2];
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_corner3x(int n)
{
AtomVecTri::Bonus *bonus = avec_tri->bonus;
int *tri = atom->tri;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double p[3][3],c[3];
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && tri[i] >= 0) {
MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
MathExtra::matvec(p,bonus[tri[i]].c3,c);
buf[n] = x[i][0] + c[0];
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_corner3y(int n)
{
AtomVecTri::Bonus *bonus = avec_tri->bonus;
int *tri = atom->tri;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double p[3][3],c[3];
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && tri[i] >= 0) {
MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
MathExtra::matvec(p,bonus[tri[i]].c3,c);
buf[n] = x[i][1] + c[1];
} else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_corner3z(int n)
{
AtomVecTri::Bonus *bonus = avec_tri->bonus;
int *tri = atom->tri;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double p[3][3],c[3];
for (int i = 0; i < nlocal; i++) {
if ((mask[i] & groupbit) && tri[i] >= 0) {
MathExtra::quat_to_mat(bonus[tri[i]].quat,p);
MathExtra::matvec(p,bonus[tri[i]].c3,c);
buf[n] = x[i][2] + c[2];
} else buf[n] = 0.0;
n += nvalues;
}
}
diff --git a/src/compute_stress_atom.cpp b/src/compute_stress_atom.cpp
index d18d264e7..19a5c31a8 100644
--- a/src/compute_stress_atom.cpp
+++ b/src/compute_stress_atom.cpp
@@ -1,301 +1,306 @@
/* ----------------------------------------------------------------------
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 "compute_stress_atom.h"
#include "atom.h"
#include "update.h"
#include "comm.h"
#include "force.h"
#include "pair.h"
#include "bond.h"
#include "angle.h"
#include "dihedral.h"
#include "improper.h"
#include "kspace.h"
#include "modify.h"
#include "fix.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeStressAtom::ComputeStressAtom(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg)
{
if (narg < 3) error->all(FLERR,"Illegal compute stress/atom command");
peratom_flag = 1;
size_peratom_cols = 6;
pressatomflag = 1;
timeflag = 1;
comm_reverse = 6;
if (narg == 3) {
keflag = 1;
pairflag = 1;
bondflag = angleflag = dihedralflag = improperflag = 1;
kspaceflag = 1;
fixflag = 1;
} else {
keflag = 0;
pairflag = 0;
bondflag = angleflag = dihedralflag = improperflag = 0;
kspaceflag = 0;
fixflag = 0;
int iarg = 3;
while (iarg < narg) {
if (strcmp(arg[iarg],"ke") == 0) keflag = 1;
else if (strcmp(arg[iarg],"pair") == 0) pairflag = 1;
else if (strcmp(arg[iarg],"bond") == 0) bondflag = 1;
else if (strcmp(arg[iarg],"angle") == 0) angleflag = 1;
else if (strcmp(arg[iarg],"dihedral") == 0) dihedralflag = 1;
else if (strcmp(arg[iarg],"improper") == 0) improperflag = 1;
else if (strcmp(arg[iarg],"kspace") == 0) kspaceflag = 1;
else if (strcmp(arg[iarg],"fix") == 0) fixflag = 1;
else if (strcmp(arg[iarg],"virial") == 0) {
pairflag = 1;
bondflag = angleflag = dihedralflag = improperflag = 1;
kspaceflag = fixflag = 1;
} else error->all(FLERR,"Illegal compute stress/atom command");
iarg++;
}
}
nmax = 0;
stress = NULL;
}
/* ---------------------------------------------------------------------- */
ComputeStressAtom::~ComputeStressAtom()
{
memory->destroy(stress);
}
/* ---------------------------------------------------------------------- */
void ComputeStressAtom::compute_peratom()
{
int i,j;
double onemass;
invoked_peratom = update->ntimestep;
if (update->vflag_atom != invoked_peratom)
error->all(FLERR,"Per-atom virial was not tallied on needed timestep");
// grow local stress array if necessary
// needs to be atom->nmax in length
if (atom->nmax > nmax) {
memory->destroy(stress);
nmax = atom->nmax;
memory->create(stress,nmax,6,"stress/atom:stress");
array_atom = stress;
}
// npair includes ghosts if either newton flag is set
// b/c some bonds/dihedrals call pair::ev_tally with pairwise info
// nbond includes ghosts if newton_bond is set
// ntotal includes ghosts if either newton flag is set
int nlocal = atom->nlocal;
int npair = nlocal;
int nbond = nlocal;
int ntotal = nlocal;
if (force->newton) npair += atom->nghost;
if (force->newton_bond) nbond += atom->nghost;
if (force->newton) ntotal += atom->nghost;
// clear local stress array
for (i = 0; i < ntotal; i++)
for (j = 0; j < 6; j++)
stress[i][j] = 0.0;
// add in per-atom contributions from each force
if (pairflag && force->pair) {
double **vatom = force->pair->vatom;
for (i = 0; i < npair; i++)
for (j = 0; j < 6; j++)
stress[i][j] += vatom[i][j];
}
if (bondflag && force->bond) {
double **vatom = force->bond->vatom;
for (i = 0; i < nbond; i++)
for (j = 0; j < 6; j++)
stress[i][j] += vatom[i][j];
}
if (angleflag && force->angle) {
double **vatom = force->angle->vatom;
for (i = 0; i < nbond; i++)
for (j = 0; j < 6; j++)
stress[i][j] += vatom[i][j];
}
if (dihedralflag && force->dihedral) {
double **vatom = force->dihedral->vatom;
for (i = 0; i < nbond; i++)
for (j = 0; j < 6; j++)
stress[i][j] += vatom[i][j];
}
if (improperflag && force->improper) {
double **vatom = force->improper->vatom;
for (i = 0; i < nbond; i++)
for (j = 0; j < 6; j++)
stress[i][j] += vatom[i][j];
}
// add in per-atom contributions from relevant fixes
+ // skip if vatom = NULL
+ // possible during setup phase if fix has not initialized its vatom yet
+ // e.g. fix ave/spatial defined before fix shake,
+ // and fix ave/spatial uses a per-atom stress from this compute as input
if (fixflag) {
for (int ifix = 0; ifix < modify->nfix; ifix++)
if (modify->fix[ifix]->virial_flag) {
double **vatom = modify->fix[ifix]->vatom;
- for (i = 0; i < nlocal; i++)
- for (j = 0; j < 6; j++)
- stress[i][j] += vatom[i][j];
+ if (vatom)
+ for (i = 0; i < nlocal; i++)
+ for (j = 0; j < 6; j++)
+ stress[i][j] += vatom[i][j];
}
}
// communicate ghost atom virials between neighbor procs
if (force->newton) comm->reverse_comm_compute(this);
// KSpace contribution is already per local atom
if (kspaceflag && force->kspace) {
double **vatom = force->kspace->vatom;
for (i = 0; i < nlocal; i++)
for (j = 0; j < 6; j++)
stress[i][j] += vatom[i][j];
}
// zero virial of atoms not in group
// only do this after comm since ghost contributions must be included
int *mask = atom->mask;
for (i = 0; i < nlocal; i++)
if (!(mask[i] & groupbit)) {
stress[i][0] = 0.0;
stress[i][1] = 0.0;
stress[i][2] = 0.0;
stress[i][3] = 0.0;
stress[i][4] = 0.0;
stress[i][5] = 0.0;
}
// include kinetic energy term for each atom in group
// mvv2e converts mv^2 to energy
if (keflag) {
double **v = atom->v;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *type = atom->type;
double mvv2e = force->mvv2e;
if (rmass) {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
onemass = mvv2e * rmass[i];
stress[i][0] += onemass*v[i][0]*v[i][0];
stress[i][1] += onemass*v[i][1]*v[i][1];
stress[i][2] += onemass*v[i][2]*v[i][2];
stress[i][3] += onemass*v[i][0]*v[i][1];
stress[i][4] += onemass*v[i][0]*v[i][2];
stress[i][5] += onemass*v[i][1]*v[i][2];
}
} else {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
onemass = mvv2e * mass[type[i]];
stress[i][0] += onemass*v[i][0]*v[i][0];
stress[i][1] += onemass*v[i][1]*v[i][1];
stress[i][2] += onemass*v[i][2]*v[i][2];
stress[i][3] += onemass*v[i][0]*v[i][1];
stress[i][4] += onemass*v[i][0]*v[i][2];
stress[i][5] += onemass*v[i][1]*v[i][2];
}
}
}
// convert to stress*volume units = -pressure*volume
double nktv2p = -force->nktv2p;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
stress[i][0] *= nktv2p;
stress[i][1] *= nktv2p;
stress[i][2] *= nktv2p;
stress[i][3] *= nktv2p;
stress[i][4] *= nktv2p;
stress[i][5] *= nktv2p;
}
}
/* ---------------------------------------------------------------------- */
int ComputeStressAtom::pack_reverse_comm(int n, int first, double *buf)
{
int i,m,last;
m = 0;
last = first + n;
for (i = first; i < last; i++) {
buf[m++] = stress[i][0];
buf[m++] = stress[i][1];
buf[m++] = stress[i][2];
buf[m++] = stress[i][3];
buf[m++] = stress[i][4];
buf[m++] = stress[i][5];
}
return 6;
}
/* ---------------------------------------------------------------------- */
void ComputeStressAtom::unpack_reverse_comm(int n, int *list, double *buf)
{
int i,j,m;
m = 0;
for (i = 0; i < n; i++) {
j = list[i];
stress[j][0] += buf[m++];
stress[j][1] += buf[m++];
stress[j][2] += buf[m++];
stress[j][3] += buf[m++];
stress[j][4] += buf[m++];
stress[j][5] += buf[m++];
}
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double ComputeStressAtom::memory_usage()
{
double bytes = nmax*6 * sizeof(double);
return bytes;
}
diff --git a/src/create_atoms.cpp b/src/create_atoms.cpp
index 347347d26..1f493c605 100644
--- a/src/create_atoms.cpp
+++ b/src/create_atoms.cpp
@@ -1,482 +1,484 @@
/* ----------------------------------------------------------------------
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 "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};
/* ---------------------------------------------------------------------- */
CreateAtoms::CreateAtoms(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
void CreateAtoms::command(int narg, char **arg)
{
if (domain->box_exist == 0)
error->all(FLERR,"Create_atoms command before simulation box is defined");
if (modify->nfix_restart_peratom)
error->all(FLERR,"Cannot create_atoms after "
"reading restart file with per-atom info");
// parse arguments
if (narg < 2) error->all(FLERR,"Illegal create_atoms command");
itype = atoi(arg[0]);
if (itype <= 0 || itype > atom->ntypes)
error->all(FLERR,"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(FLERR,"Illegal create_atoms command");
nregion = domain->find_region(arg[2]);
if (nregion == -1) error->all(FLERR,
"Create_atoms region ID does not exist");
iarg = 3;;
} else if (strcmp(arg[1],"single") == 0) {
style = SINGLE;
if (narg < 5) error->all(FLERR,"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(FLERR,"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(FLERR,
"Create_atoms region ID does not exist");
}
iarg = 5;
} else error->all(FLERR,"Illegal create_atoms command");
// process optional keywords
int scaleflag = 1;
remapflag = 0;
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(FLERR,"Illegal create_atoms command");
if (domain->lattice == NULL)
error->all(FLERR,"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(FLERR,"Illegal create_atoms command");
basistype[ibasis-1] = itype;
iarg += 3;
} else if (strcmp(arg[iarg],"remap") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal create_atoms command");
if (strcmp(arg[iarg+1],"yes") == 0) remapflag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) remapflag = 0;
else error->all(FLERR,"Illegal create_atoms command");
iarg += 2;
} else if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"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(FLERR,"Illegal create_atoms command");
iarg += 2;
} else error->all(FLERR,"Illegal create_atoms command");
}
// error checks
if (style == RANDOM) {
if (nrandom < 0) error->all(FLERR,"Illegal create_atoms command");
if (seed <= 0) error->all(FLERR,"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(FLERR,"Cannot create atoms with undefined lattice");
} else if (scaleflag == 1) {
if (domain->lattice == NULL)
error->all(FLERR,"Cannot create atoms with undefined lattice");
xone[0] *= domain->lattice->xlattice;
xone[1] *= domain->lattice->ylattice;
xone[2] *= domain->lattice->zlattice;
}
// set bounds for my proc in sublo[3] & subhi[3]
// 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
triclinic = domain->triclinic;
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;
}
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];
}
// add atoms in one of 3 ways
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_LMP_BIGINT,MPI_SUM,world);
if (atom->natoms < 0 || atom->natoms > MAXBIGINT)
error->all(FLERR,"Too many total atoms");
// print status
if (comm->me == 0) {
if (screen)
fprintf(screen,"Created " BIGINT_FORMAT " atoms\n",
atom->natoms-natoms_previous);
if (logfile)
fprintf(logfile,"Created " BIGINT_FORMAT " atoms\n",
atom->natoms-natoms_previous);
}
// reset simulation now that more atoms are defined
// add tags for newly created atoms if possible
// if global map exists, reset it
- if (atom->natoms > MAXTAGINT) atom->tag_enable = 0;
- if (atom->natoms <= MAXTAGINT) atom->tag_extend();
+ // change these to MAXTAGINT when allow tagint = bigint
+ if (atom->natoms > MAXSMALLINT) atom->tag_enable = 0;
+ if (atom->natoms <= MAXSMALLINT) atom->tag_extend();
if (atom->map_style) {
atom->nghost = 0;
atom->map_init();
atom->map_set();
}
// if a molecular system, set nspecial to 0 for new atoms
// NOTE: 31May12, don't think this is needed, avec->create_atom() does it
//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()
{
// remap atom if requested
if (remapflag) {
- int imagetmp = (512 << 20) | (512 << 10) | 512;
+ tagint imagetmp = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMASK << IMGBITS) | IMGMAX;
domain->remap(xone,imagetmp);
}
// if triclinic, convert to lamda coords (0-1)
double lamda[3],*coord;
if (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 *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 (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);
boxlo = domain->boxlo_lamda;
boxhi = domain->boxhi_lamda;
}
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);
}
// 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
if (xlo > xhi || ylo > yhi || zlo > zhi)
error->all(FLERR,"No overlap of box and region for create_atoms");
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 (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
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--;
// 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/create_atoms.h b/src/create_atoms.h
index a1728694e..bd312a14f 100644
--- a/src/create_atoms.h
+++ b/src/create_atoms.h
@@ -1,88 +1,92 @@
/* -*- c++ -*- ----------------------------------------------------------
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 COMMAND_CLASS
CommandStyle(create_atoms,CreateAtoms)
#else
#ifndef LMP_CREATE_ATOMS_H
#define LMP_CREATE_ATOMS_H
#include "pointers.h"
namespace LAMMPS_NS {
class CreateAtoms : protected Pointers {
public:
CreateAtoms(class LAMMPS *);
void command(int, char **);
private:
int itype,style,nregion,nbasis,nrandom,seed;
int *basistype;
double xone[3];
int remapflag;
int triclinic;
double sublo[3],subhi[3]; // epsilon-extended proc sub-box for adding atoms
void add_single();
void add_random();
void add_lattice();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Create_atoms command before simulation box is defined
The create_atoms command cannot be used before a read_data,
read_restart, or create_box command.
E: Cannot create_atoms after reading restart file with per-atom info
The per-atom info was stored to be used when by a fix that you
may re-define. If you add atoms before re-defining the fix, then
there will not be a correct amount of per-atom info.
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Invalid atom type in create_atoms command
The create_box command specified the range of valid atom types.
An invalid type is being requested.
E: Create_atoms region ID does not exist
A region ID used in the create_atoms command does not exist.
E: Cannot create atoms with undefined lattice
Must use the lattice command before using the create_atoms
command.
E: Too many total atoms
See the setting for bigint in the src/lmptype.h file.
+E: No overlap of box and region for create_atoms
+
+Self-explanatory.
+
*/
diff --git a/src/displace_atoms.cpp b/src/displace_atoms.cpp
index 8e2a49320..3fb1a48fd 100644
--- a/src/displace_atoms.cpp
+++ b/src/displace_atoms.cpp
@@ -1,240 +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 "lmptype.h"
#include "mpi.h"
#include "stdlib.h"
#include "string.h"
#include "displace_atoms.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};
/* ---------------------------------------------------------------------- */
DisplaceAtoms::DisplaceAtoms(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
void DisplaceAtoms::command(int narg, char **arg)
{
int i;
if (domain->box_exist == 0)
error->all(FLERR,"Displace_atoms command before simulation box is defined");
if (narg < 2) error->all(FLERR,"Illegal displace_atoms command");
if (modify->nfix_restart_peratom)
error->all(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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;
+ tagint *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_LMP_BIGINT,MPI_SUM,world);
if (natoms != atom->natoms && comm->me == 0) {
char str[128];
sprintf(str,"Lost atoms via displace_atoms: original " BIGINT_FORMAT
" current " BIGINT_FORMAT,atom->natoms,natoms);
error->warning(FLERR,str);
}
}
/* ----------------------------------------------------------------------
parse optional parameters at end of displace_atoms input line
------------------------------------------------------------------------- */
void DisplaceAtoms::options(int narg, char **arg)
{
if (narg < 0) error->all(FLERR,"Illegal displace_atoms command");
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"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(FLERR,"Illegal displace_atoms command");
iarg += 2;
} else error->all(FLERR,"Illegal displace_atoms command");
}
}
diff --git a/src/domain.cpp b/src/domain.cpp
index c5a4b72d2..ebc5e3b4a 100644
--- a/src/domain.cpp
+++ b/src/domain.cpp
@@ -1,1483 +1,1507 @@
/* ----------------------------------------------------------------------
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 (triclinic) : Pieter in 't Veld (SNL)
------------------------------------------------------------------------- */
#include "mpi.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "math.h"
#include "domain.h"
#include "style_region.h"
#include "atom.h"
#include "force.h"
#include "update.h"
#include "modify.h"
#include "fix.h"
#include "fix_deform.h"
#include "region.h"
#include "lattice.h"
#include "comm.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
#define BIG 1.0e20
#define SMALL 1.0e-4
#define DELTA 1
#define BONDSTRETCH 1.1
enum{NO_REMAP,X_REMAP,V_REMAP}; // same as fix_deform.cpp
/* ----------------------------------------------------------------------
default is periodic
------------------------------------------------------------------------- */
Domain::Domain(LAMMPS *lmp) : Pointers(lmp)
{
box_exist = 0;
dimension = 3;
nonperiodic = 0;
xperiodic = yperiodic = zperiodic = 1;
periodicity[0] = xperiodic;
periodicity[1] = yperiodic;
periodicity[2] = zperiodic;
boundary[0][0] = boundary[0][1] = 0;
boundary[1][0] = boundary[1][1] = 0;
boundary[2][0] = boundary[2][1] = 0;
triclinic = 0;
boxlo[0] = boxlo[1] = boxlo[2] = -0.5;
boxhi[0] = boxhi[1] = boxhi[2] = 0.5;
xy = xz = yz = 0.0;
h[3] = h[4] = h[5] = 0.0;
h_inv[3] = h_inv[4] = h_inv[5] = 0.0;
h_rate[0] = h_rate[1] = h_rate[2] =
h_rate[3] = h_rate[4] = h_rate[5] = 0.0;
h_ratelo[0] = h_ratelo[1] = h_ratelo[2] = 0.0;
prd_lamda[0] = prd_lamda[1] = prd_lamda[2] = 1.0;
prd_half_lamda[0] = prd_half_lamda[1] = prd_half_lamda[2] = 0.5;
boxlo_lamda[0] = boxlo_lamda[1] = boxlo_lamda[2] = 0.0;
boxhi_lamda[0] = boxhi_lamda[1] = boxhi_lamda[2] = 1.0;
lattice = NULL;
nregion = maxregion = 0;
regions = NULL;
}
/* ---------------------------------------------------------------------- */
Domain::~Domain()
{
delete lattice;
for (int i = 0; i < nregion; i++) delete regions[i];
memory->sfree(regions);
}
/* ---------------------------------------------------------------------- */
void Domain::init()
{
// set box_change if box dimensions/shape ever changes
// due to shrink-wrapping, fixes that change volume (npt, vol/rescale, etc)
box_change = 0;
if (nonperiodic == 2) box_change = 1;
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->box_change) box_change = 1;
// check for fix deform
deform_flag = deform_vremap = deform_groupbit = 0;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"deform") == 0) {
deform_flag = 1;
if (((FixDeform *) modify->fix[i])->remapflag == V_REMAP) {
deform_vremap = 1;
deform_groupbit = modify->fix[i]->groupbit;
}
}
// region inits
for (int i = 0; i < nregion; i++) regions[i]->init();
}
/* ----------------------------------------------------------------------
set initial global box
assumes boxlo/hi and triclinic tilts are already set
------------------------------------------------------------------------- */
void Domain::set_initial_box()
{
// error checks for orthogonal and triclinic domains
if (boxlo[0] >= boxhi[0] || boxlo[1] >= boxhi[1] || boxlo[2] >= boxhi[2])
error->one(FLERR,"Box bounds are invalid");
// error check on triclinic tilt factors
if (triclinic) {
if (domain->dimension == 2 && (xz != 0.0 || yz != 0.0))
error->all(FLERR,"Cannot skew triclinic box in z for 2d simulation");
if (fabs(xy/(boxhi[0]-boxlo[0])) > 0.5)
error->all(FLERR,"Triclinic box skew is too large");
if (fabs(xz/(boxhi[0]-boxlo[0])) > 0.5)
error->all(FLERR,"Triclinic box skew is too large");
if (fabs(yz/(boxhi[1]-boxlo[1])) > 0.5)
error->all(FLERR,"Triclinic box skew is too large");
}
// set small based on box size and SMALL
// this works for any unit system
small[0] = SMALL * (boxhi[0] - boxlo[0]);
small[1] = SMALL * (boxhi[1] - boxlo[1]);
small[2] = SMALL * (boxhi[2] - boxlo[2]);
// adjust box lo/hi for shrink-wrapped dims
if (boundary[0][0] == 2) boxlo[0] -= small[0];
else if (boundary[0][0] == 3) minxlo = boxlo[0];
if (boundary[0][1] == 2) boxhi[0] += small[0];
else if (boundary[0][1] == 3) minxhi = boxhi[0];
if (boundary[1][0] == 2) boxlo[1] -= small[1];
else if (boundary[1][0] == 3) minylo = boxlo[1];
if (boundary[1][1] == 2) boxhi[1] += small[1];
else if (boundary[1][1] == 3) minyhi = boxhi[1];
if (boundary[2][0] == 2) boxlo[2] -= small[2];
else if (boundary[2][0] == 3) minzlo = boxlo[2];
if (boundary[2][1] == 2) boxhi[2] += small[2];
else if (boundary[2][1] == 3) minzhi = boxhi[2];
}
/* ----------------------------------------------------------------------
set global box params
assumes boxlo/hi and triclinic tilts are already set
------------------------------------------------------------------------- */
void Domain::set_global_box()
{
prd[0] = xprd = boxhi[0] - boxlo[0];
prd[1] = yprd = boxhi[1] - boxlo[1];
prd[2] = zprd = boxhi[2] - boxlo[2];
h[0] = xprd;
h[1] = yprd;
h[2] = zprd;
h_inv[0] = 1.0/h[0];
h_inv[1] = 1.0/h[1];
h_inv[2] = 1.0/h[2];
prd_half[0] = xprd_half = 0.5*xprd;
prd_half[1] = yprd_half = 0.5*yprd;
prd_half[2] = zprd_half = 0.5*zprd;
if (triclinic) {
h[3] = yz;
h[4] = xz;
h[5] = xy;
h_inv[3] = -h[3] / (h[1]*h[2]);
h_inv[4] = (h[3]*h[5] - h[1]*h[4]) / (h[0]*h[1]*h[2]);
h_inv[5] = -h[5] / (h[0]*h[1]);
boxlo_bound[0] = MIN(boxlo[0],boxlo[0]+xy);
boxlo_bound[0] = MIN(boxlo_bound[0],boxlo_bound[0]+xz);
boxlo_bound[1] = MIN(boxlo[1],boxlo[1]+yz);
boxlo_bound[2] = boxlo[2];
boxhi_bound[0] = MAX(boxhi[0],boxhi[0]+xy);
boxhi_bound[0] = MAX(boxhi_bound[0],boxhi_bound[0]+xz);
boxhi_bound[1] = MAX(boxhi[1],boxhi[1]+yz);
boxhi_bound[2] = boxhi[2];
}
}
/* ----------------------------------------------------------------------
set lamda box params
assumes global box is defined and proc assignment has been made
uses comm->xyz_split to define subbox boundaries in consistent manner
------------------------------------------------------------------------- */
void Domain::set_lamda_box()
{
int *myloc = comm->myloc;
double *xsplit = comm->xsplit;
double *ysplit = comm->ysplit;
double *zsplit = comm->zsplit;
sublo_lamda[0] = xsplit[myloc[0]];
subhi_lamda[0] = xsplit[myloc[0]+1];
sublo_lamda[1] = ysplit[myloc[1]];
subhi_lamda[1] = ysplit[myloc[1]+1];
sublo_lamda[2] = zsplit[myloc[2]];
subhi_lamda[2] = zsplit[myloc[2]+1];
}
/* ----------------------------------------------------------------------
set local subbox params for orthogonal boxes
assumes global box is defined and proc assignment has been made
uses comm->xyz_split to define subbox boundaries in consistent manner
insure subhi[max] = boxhi
------------------------------------------------------------------------- */
void Domain::set_local_box()
{
int *myloc = comm->myloc;
int *procgrid = comm->procgrid;
double *xsplit = comm->xsplit;
double *ysplit = comm->ysplit;
double *zsplit = comm->zsplit;
if (triclinic == 0) {
sublo[0] = boxlo[0] + xprd*xsplit[myloc[0]];
if (myloc[0] < procgrid[0]-1)
subhi[0] = boxlo[0] + xprd*xsplit[myloc[0]+1];
else subhi[0] = boxhi[0];
sublo[1] = boxlo[1] + yprd*ysplit[myloc[1]];
if (myloc[1] < procgrid[1]-1)
subhi[1] = boxlo[1] + yprd*ysplit[myloc[1]+1];
else subhi[1] = boxhi[1];
sublo[2] = boxlo[2] + zprd*zsplit[myloc[2]];
if (myloc[2] < procgrid[2]-1)
subhi[2] = boxlo[2] + zprd*zsplit[myloc[2]+1];
else subhi[2] = boxhi[2];
}
}
/* ----------------------------------------------------------------------
reset global & local boxes due to global box boundary changes
if shrink-wrapped, determine atom extent and reset boxlo/hi
for triclinic, atoms must be in lamda coords (0-1) before reset_box is called
------------------------------------------------------------------------- */
void Domain::reset_box()
{
// perform shrink-wrapping
// compute extent of atoms on this proc
// for triclinic, this is done in lamda space
if (nonperiodic == 2) {
double extent[3][2],all[3][2];
extent[2][0] = extent[1][0] = extent[0][0] = BIG;
extent[2][1] = extent[1][1] = extent[0][1] = -BIG;
double **x = atom->x;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
extent[0][0] = MIN(extent[0][0],x[i][0]);
extent[0][1] = MAX(extent[0][1],x[i][0]);
extent[1][0] = MIN(extent[1][0],x[i][1]);
extent[1][1] = MAX(extent[1][1],x[i][1]);
extent[2][0] = MIN(extent[2][0],x[i][2]);
extent[2][1] = MAX(extent[2][1],x[i][2]);
}
// compute extent across all procs
// flip sign of MIN to do it in one Allreduce MAX
extent[0][0] = -extent[0][0];
extent[1][0] = -extent[1][0];
extent[2][0] = -extent[2][0];
MPI_Allreduce(extent,all,6,MPI_DOUBLE,MPI_MAX,world);
// for triclinic, convert back to box coords before changing box
if (triclinic) lamda2x(atom->nlocal);
// in shrink-wrapped dims, set box by atom extent
// if minimum set, enforce min box size settings
// for triclinic, convert lamda extent to box coords, then set box lo/hi
// decided NOT to do the next comment - don't want to sneakily change tilt
// for triclinic, adjust tilt factors if 2nd dim is shrink-wrapped,
// so that displacement in 1st dim stays the same
if (triclinic == 0) {
if (xperiodic == 0) {
if (boundary[0][0] == 2) boxlo[0] = -all[0][0] - small[0];
else if (boundary[0][0] == 3)
boxlo[0] = MIN(-all[0][0]-small[0],minxlo);
if (boundary[0][1] == 2) boxhi[0] = all[0][1] + small[0];
else if (boundary[0][1] == 3) boxhi[0] = MAX(all[0][1]+small[0],minxhi);
if (boxlo[0] > boxhi[0]) error->all(FLERR,"Illegal simulation box");
}
if (yperiodic == 0) {
if (boundary[1][0] == 2) boxlo[1] = -all[1][0] - small[1];
else if (boundary[1][0] == 3)
boxlo[1] = MIN(-all[1][0]-small[1],minylo);
if (boundary[1][1] == 2) boxhi[1] = all[1][1] + small[1];
else if (boundary[1][1] == 3) boxhi[1] = MAX(all[1][1]+small[1],minyhi);
if (boxlo[1] > boxhi[1]) error->all(FLERR,"Illegal simulation box");
}
if (zperiodic == 0) {
if (boundary[2][0] == 2) boxlo[2] = -all[2][0] - small[2];
else if (boundary[2][0] == 3)
boxlo[2] = MIN(-all[2][0]-small[2],minzlo);
if (boundary[2][1] == 2) boxhi[2] = all[2][1] + small[2];
else if (boundary[2][1] == 3) boxhi[2] = MAX(all[2][1]+small[2],minzhi);
if (boxlo[2] > boxhi[2]) error->all(FLERR,"Illegal simulation box");
}
} else {
double lo[3],hi[3];
if (xperiodic == 0) {
lo[0] = -all[0][0]; lo[1] = 0.0; lo[2] = 0.0;
lamda2x(lo,lo);
hi[0] = all[0][1]; hi[1] = 0.0; hi[2] = 0.0;
lamda2x(hi,hi);
if (boundary[0][0] == 2) boxlo[0] = lo[0] - small[0];
else if (boundary[0][0] == 3) boxlo[0] = MIN(lo[0]-small[0],minxlo);
if (boundary[0][1] == 2) boxhi[0] = hi[0] + small[0];
else if (boundary[0][1] == 3) boxhi[0] = MAX(hi[0]+small[0],minxhi);
if (boxlo[0] > boxhi[0]) error->all(FLERR,"Illegal simulation box");
}
if (yperiodic == 0) {
lo[0] = 0.0; lo[1] = -all[1][0]; lo[2] = 0.0;
lamda2x(lo,lo);
hi[0] = 0.0; hi[1] = all[1][1]; hi[2] = 0.0;
lamda2x(hi,hi);
if (boundary[1][0] == 2) boxlo[1] = lo[1] - small[1];
else if (boundary[1][0] == 3) boxlo[1] = MIN(lo[1]-small[1],minylo);
if (boundary[1][1] == 2) boxhi[1] = hi[1] + small[1];
else if (boundary[1][1] == 3) boxhi[1] = MAX(hi[1]+small[1],minyhi);
if (boxlo[1] > boxhi[1]) error->all(FLERR,"Illegal simulation box");
//xy *= (boxhi[1]-boxlo[1]) / yprd;
}
if (zperiodic == 0) {
lo[0] = 0.0; lo[1] = 0.0; lo[2] = -all[2][0];
lamda2x(lo,lo);
hi[0] = 0.0; hi[1] = 0.0; hi[2] = all[2][1];
lamda2x(hi,hi);
if (boundary[2][0] == 2) boxlo[2] = lo[2] - small[2];
else if (boundary[2][0] == 3) boxlo[2] = MIN(lo[2]-small[2],minzlo);
if (boundary[2][1] == 2) boxhi[2] = hi[2] + small[2];
else if (boundary[2][1] == 3) boxhi[2] = MAX(hi[2]+small[2],minzhi);
if (boxlo[2] > boxhi[2]) error->all(FLERR,"Illegal simulation box");
//xz *= (boxhi[2]-boxlo[2]) / xprd;
//yz *= (boxhi[2]-boxlo[2]) / yprd;
}
}
}
// reset box whether shrink-wrapping or not
set_global_box();
set_local_box();
// if shrink-wrapped & triclinic, re-convert to lamda coords for new box
// re-invoke pbc() b/c x2lamda result can be outside [0,1] due to roundoff
if (nonperiodic == 2 && triclinic) {
x2lamda(atom->nlocal);
pbc();
}
}
/* ----------------------------------------------------------------------
enforce PBC and modify box image flags for each atom
called every reneighboring and by other commands that change atoms
resulting coord must satisfy lo <= coord < hi
MAX is important since coord - prd < lo can happen when coord = hi
if fix deform, remap velocity of fix group atoms by box edge velocities
for triclinic, atoms must be in lamda coords (0-1) before pbc is called
image = 10 bits for each dimension
increment/decrement in wrap-around fashion
------------------------------------------------------------------------- */
void Domain::pbc()
{
- int i,idim,otherdims;
+ int i;
+ tagint idim,otherdims;
double *lo,*hi,*period;
int nlocal = atom->nlocal;
double **x = atom->x;
double **v = atom->v;
int *mask = atom->mask;
- int *image = atom->image;
+ tagint *image = atom->image;
if (triclinic == 0) {
lo = boxlo;
hi = boxhi;
period = prd;
} else {
lo = boxlo_lamda;
hi = boxhi_lamda;
period = prd_lamda;
}
for (i = 0; i < nlocal; i++) {
if (xperiodic) {
if (x[i][0] < lo[0]) {
x[i][0] += period[0];
if (deform_vremap && mask[i] & deform_groupbit) v[i][0] += h_rate[0];
- idim = image[i] & 1023;
+ idim = image[i] & IMGMASK;
otherdims = image[i] ^ idim;
idim--;
- idim &= 1023;
+ idim &= IMGMASK;
image[i] = otherdims | idim;
}
if (x[i][0] >= hi[0]) {
x[i][0] -= period[0];
x[i][0] = MAX(x[i][0],lo[0]);
if (deform_vremap && mask[i] & deform_groupbit) v[i][0] -= h_rate[0];
- idim = image[i] & 1023;
+ idim = image[i] & IMGMASK;
otherdims = image[i] ^ idim;
idim++;
- idim &= 1023;
+ idim &= IMGMASK;
image[i] = otherdims | idim;
}
}
if (yperiodic) {
if (x[i][1] < lo[1]) {
x[i][1] += period[1];
if (deform_vremap && mask[i] & deform_groupbit) {
v[i][0] += h_rate[5];
v[i][1] += h_rate[1];
}
- idim = (image[i] >> 10) & 1023;
- otherdims = image[i] ^ (idim << 10);
+ idim = (image[i] >> IMGBITS) & IMGMASK;
+ otherdims = image[i] ^ (idim << IMGBITS);
idim--;
- idim &= 1023;
- image[i] = otherdims | (idim << 10);
+ idim &= IMGMASK;
+ image[i] = otherdims | (idim << IMGBITS);
}
if (x[i][1] >= hi[1]) {
x[i][1] -= period[1];
x[i][1] = MAX(x[i][1],lo[1]);
if (deform_vremap && mask[i] & deform_groupbit) {
v[i][0] -= h_rate[5];
v[i][1] -= h_rate[1];
}
- idim = (image[i] >> 10) & 1023;
- otherdims = image[i] ^ (idim << 10);
+ idim = (image[i] >> IMGBITS) & IMGMASK;
+ otherdims = image[i] ^ (idim << IMGBITS);
idim++;
- idim &= 1023;
- image[i] = otherdims | (idim << 10);
+ idim &= IMGMASK;
+ image[i] = otherdims | (idim << IMGBITS);
}
}
if (zperiodic) {
if (x[i][2] < lo[2]) {
x[i][2] += period[2];
if (deform_vremap && mask[i] & deform_groupbit) {
v[i][0] += h_rate[4];
v[i][1] += h_rate[3];
v[i][2] += h_rate[2];
}
- idim = image[i] >> 20;
- otherdims = image[i] ^ (idim << 20);
+ idim = image[i] >> IMG2BITS;
+ otherdims = image[i] ^ (idim << IMG2BITS);
idim--;
- idim &= 1023;
- image[i] = otherdims | (idim << 20);
+ idim &= IMGMASK;
+ image[i] = otherdims | (idim << IMG2BITS);
}
if (x[i][2] >= hi[2]) {
x[i][2] -= period[2];
x[i][2] = MAX(x[i][2],lo[2]);
if (deform_vremap && mask[i] & deform_groupbit) {
v[i][0] -= h_rate[4];
v[i][1] -= h_rate[3];
v[i][2] -= h_rate[2];
}
- idim = image[i] >> 20;
- otherdims = image[i] ^ (idim << 20);
+ idim = image[i] >> IMG2BITS;
+ otherdims = image[i] ^ (idim << IMG2BITS);
idim++;
- idim &= 1023;
- image[i] = otherdims | (idim << 20);
+ idim &= IMGMASK;
+ image[i] = otherdims | (idim << IMG2BITS);
}
}
}
}
/* ----------------------------------------------------------------------
check that no pair of atoms in a bonded interaction
are further apart than half a periodic box length
------------------------------------------------------------------------- */
void Domain::box_too_small_check()
{
int i,j,k;
// only need to check if system is molecluar and some dimension is periodic
if (!atom->molecular) return;
if (!xperiodic && !yperiodic && (dimension == 2 || !zperiodic)) return;
// maxbondall = longest current bond length
// NOTE: if box is tiny (less than 2 * bond-length),
// the check itself may compute bad bond lengths
// not sure how to account for that extreme case
int *num_bond = atom->num_bond;
int **bond_atom = atom->bond_atom;
double **x = atom->x;
int nlocal = atom->nlocal;
double delx,dely,delz,rsq,r;
double maxbondme = 0.0;
for (i = 0; i < nlocal; i++)
for (j = 0; j < num_bond[i]; j++) {
k = atom->map(bond_atom[i][j]);
if (k == -1) error->one(FLERR,"Bond atom missing in box size check");
delx = x[i][0] - x[k][0];
dely = x[i][1] - x[k][1];
delz = x[i][2] - x[k][2];
domain->minimum_image(delx,dely,delz);
rsq = delx*delx + dely*dely + delz*delz;
maxbondme = MAX(maxbondme,rsq);
}
double maxbondall;
MPI_Allreduce(&maxbondme,&maxbondall,1,MPI_DOUBLE,MPI_MAX,world);
maxbondall = sqrt(maxbondall);
// maxdelta = furthest apart 2 atoms in a bonded interaction can be
// include BONDSTRETCH factor to account for dynamics
double maxdelta = maxbondall * BONDSTRETCH;
if (atom->nangles) maxdelta = 2.0 * maxbondall * BONDSTRETCH;
if (atom->ndihedrals) maxdelta = 3.0 * maxbondall * BONDSTRETCH;
// maxdelta cannot be more than half a periodic box length,
// else when use minimg() in bond/angle/dihdral compute,
// could calculate incorrect distance between 2 atoms
int flag = 0;
if (xperiodic && maxdelta > xprd_half) flag = 1;
if (yperiodic && maxdelta > yprd_half) flag = 1;
if (dimension == 3 && zperiodic && maxdelta > zprd_half) flag = 1;
if (flag)
error->all(FLERR,
"Bond/angle/dihedral extent > half of periodic box length");
}
-/* ----------------------------------------------------------------------
- minimum image convention check
- return 1 if any distance > 1/2 of box size
-------------------------------------------------------------------------- */
-
-int Domain::minimum_image_check(double dx, double dy, double dz)
-{
- if (xperiodic && fabs(dx) > xprd_half) return 1;
- if (yperiodic && fabs(dy) > yprd_half) return 1;
- if (zperiodic && fabs(dz) > zprd_half) return 1;
- return 0;
-}
-
/* ----------------------------------------------------------------------
minimum image convention
use 1/2 of box size as test
for triclinic, also add/subtract tilt factors in other dims as needed
------------------------------------------------------------------------- */
void Domain::minimum_image(double &dx, double &dy, double &dz)
{
if (triclinic == 0) {
if (xperiodic) {
if (fabs(dx) > xprd_half) {
if (dx < 0.0) dx += xprd;
else dx -= xprd;
}
}
if (yperiodic) {
if (fabs(dy) > yprd_half) {
if (dy < 0.0) dy += yprd;
else dy -= yprd;
}
}
if (zperiodic) {
if (fabs(dz) > zprd_half) {
if (dz < 0.0) dz += zprd;
else dz -= zprd;
}
}
} else {
if (zperiodic) {
if (fabs(dz) > zprd_half) {
if (dz < 0.0) {
dz += zprd;
dy += yz;
dx += xz;
} else {
dz -= zprd;
dy -= yz;
dx -= xz;
}
}
}
if (yperiodic) {
if (fabs(dy) > yprd_half) {
if (dy < 0.0) {
dy += yprd;
dx += xy;
} else {
dy -= yprd;
dx -= xy;
}
}
}
if (xperiodic) {
if (fabs(dx) > xprd_half) {
if (dx < 0.0) dx += xprd;
else dx -= xprd;
}
}
}
}
/* ----------------------------------------------------------------------
minimum image convention
use 1/2 of box size as test
for triclinic, also add/subtract tilt factors in other dims as needed
------------------------------------------------------------------------- */
void Domain::minimum_image(double *delta)
{
if (triclinic == 0) {
if (xperiodic) {
if (fabs(delta[0]) > xprd_half) {
if (delta[0] < 0.0) delta[0] += xprd;
else delta[0] -= xprd;
}
}
if (yperiodic) {
if (fabs(delta[1]) > yprd_half) {
if (delta[1] < 0.0) delta[1] += yprd;
else delta[1] -= yprd;
}
}
if (zperiodic) {
if (fabs(delta[2]) > zprd_half) {
if (delta[2] < 0.0) delta[2] += zprd;
else delta[2] -= zprd;
}
}
} else {
if (zperiodic) {
if (fabs(delta[2]) > zprd_half) {
if (delta[2] < 0.0) {
delta[2] += zprd;
delta[1] += yz;
delta[0] += xz;
} else {
delta[2] -= zprd;
delta[1] -= yz;
delta[0] -= xz;
}
}
}
if (yperiodic) {
if (fabs(delta[1]) > yprd_half) {
if (delta[1] < 0.0) {
delta[1] += yprd;
delta[0] += xy;
} else {
delta[1] -= yprd;
delta[0] -= xy;
}
}
}
if (xperiodic) {
if (fabs(delta[0]) > xprd_half) {
if (delta[0] < 0.0) delta[0] += xprd;
else delta[0] -= xprd;
}
}
}
}
+/* ----------------------------------------------------------------------
+ return local index of atom J or any of its images that is closest to atom I
+ if J is not a valid index like -1, just return it
+------------------------------------------------------------------------- */
+
+int Domain::closest_image(int i, int j)
+{
+ if (j < 0) return j;
+
+ int *sametag = atom->sametag;
+ double **x = atom->x;
+ double *xi = x[i];
+
+ int closest = j;
+ double delx = xi[0] - x[j][0];
+ double dely = xi[1] - x[j][1];
+ double delz = xi[2] - x[j][2];
+ double rsqmin = delx*delx + dely*dely + delz*delz;
+ double rsq;
+
+ while (sametag[j] >= 0) {
+ j = sametag[j];
+ delx = xi[0] - x[j][0];
+ dely = xi[1] - x[j][1];
+ delz = xi[2] - x[j][2];
+ rsq = delx*delx + dely*dely + delz*delz;
+ if (rsq < rsqmin) {
+ rsqmin = rsq;
+ closest = j;
+ }
+ }
+ return closest;
+}
+
/* ----------------------------------------------------------------------
find and return Xj image = periodic image of Xj that is closest to Xi
for triclinic, add/subtract tilt factors in other dims as needed
------------------------------------------------------------------------- */
void Domain::closest_image(const double * const xi, const double * const xj,
double * const xjimage)
{
double dx = xj[0] - xi[0];
double dy = xj[1] - xi[1];
double dz = xj[2] - xi[2];
if (triclinic == 0) {
if (xperiodic) {
if (dx < 0.0) {
while (dx < 0.0) dx += xprd;
if (dx > xprd_half) dx -= xprd;
} else {
while (dx > 0.0) dx -= xprd;
if (dx < -xprd_half) dx += xprd;
}
}
if (yperiodic) {
if (dy < 0.0) {
while (dy < 0.0) dy += yprd;
if (dy > yprd_half) dy -= yprd;
} else {
while (dy > 0.0) dy -= yprd;
if (dy < -yprd_half) dy += yprd;
}
}
if (zperiodic) {
if (dz < 0.0) {
while (dz < 0.0) dz += zprd;
if (dz > zprd_half) dz -= zprd;
} else {
while (dz > 0.0) dz -= zprd;
if (dz < -zprd_half) dz += zprd;
}
}
} else {
if (zperiodic) {
if (dz < 0.0) {
while (dz < 0.0) {
dz += zprd;
dy += yz;
dx += xz;
}
if (dz > zprd_half) {
dz -= zprd;
dy -= yz;
dx -= xz;
}
} else {
while (dz > 0.0) {
dz -= zprd;
dy -= yz;
dx -= xz;
}
if (dz < -zprd_half) {
dz += zprd;
dy += yz;
dx += xz;
}
}
}
if (yperiodic) {
if (dy < 0.0) {
while (dy < 0.0) {
dy += yprd;
dx += xy;
}
if (dy > yprd_half) {
dy -= yprd;
dx -= xy;
}
} else {
while (dy > 0.0) {
dy -= yprd;
dx -= xy;
}
if (dy < -yprd_half) {
dy += yprd;
dx += xy;
}
}
}
if (xperiodic) {
if (dx < 0.0) {
while (dx < 0.0) dx += xprd;
if (dx > xprd_half) dx -= xprd;
} else {
while (dx > 0.0) dx -= xprd;
if (dx < -xprd_half) dx += xprd;
}
}
}
xjimage[0] = xi[0] + dx;
xjimage[1] = xi[1] + dy;
xjimage[2] = xi[2] + dz;
}
/* ----------------------------------------------------------------------
remap the point into the periodic box no matter how far away
adjust 3 image flags encoded in image accordingly
resulting coord must satisfy lo <= coord < hi
MAX is important since coord - prd < lo can happen when coord = hi
for triclinic, point is converted to lamda coords (0-1) before doing remap
image = 10 bits for each dimension
increment/decrement in wrap-around fashion
------------------------------------------------------------------------- */
-void Domain::remap(double *x, int &image)
+void Domain::remap(double *x, tagint &image)
{
double *lo,*hi,*period,*coord;
double lamda[3];
+ tagint idim,otherdims;
if (triclinic == 0) {
lo = boxlo;
hi = boxhi;
period = prd;
coord = x;
} else {
lo = boxlo_lamda;
hi = boxhi_lamda;
period = prd_lamda;
x2lamda(x,lamda);
coord = lamda;
}
if (xperiodic) {
while (coord[0] < lo[0]) {
coord[0] += period[0];
- int idim = image & 1023;
- int otherdims = image ^ idim;
+ idim = image & IMGMASK;
+ otherdims = image ^ idim;
idim--;
- idim &= 1023;
+ idim &= IMGMASK;
image = otherdims | idim;
}
while (coord[0] >= hi[0]) {
coord[0] -= period[0];
- int idim = image & 1023;
- int otherdims = image ^ idim;
+ idim = image & IMGMASK;
+ otherdims = image ^ idim;
idim++;
- idim &= 1023;
+ idim &= IMGMASK;
image = otherdims | idim;
}
coord[0] = MAX(coord[0],lo[0]);
}
if (yperiodic) {
while (coord[1] < lo[1]) {
coord[1] += period[1];
- int idim = (image >> 10) & 1023;
- int otherdims = image ^ (idim << 10);
+ idim = (image >> IMGBITS) & IMGMASK;
+ otherdims = image ^ (idim << IMGBITS);
idim--;
- idim &= 1023;
- image = otherdims | (idim << 10);
+ idim &= IMGMASK;
+ image = otherdims | (idim << IMGBITS);
}
while (coord[1] >= hi[1]) {
coord[1] -= period[1];
- int idim = (image >> 10) & 1023;
- int otherdims = image ^ (idim << 10);
+ idim = (image >> IMGBITS) & IMGMASK;
+ otherdims = image ^ (idim << IMGBITS);
idim++;
- idim &= 1023;
- image = otherdims | (idim << 10);
+ idim &= IMGMASK;
+ image = otherdims | (idim << IMGBITS);
}
coord[1] = MAX(coord[1],lo[1]);
}
if (zperiodic) {
while (coord[2] < lo[2]) {
coord[2] += period[2];
- int idim = image >> 20;
- int otherdims = image ^ (idim << 20);
+ idim = image >> IMG2BITS;
+ otherdims = image ^ (idim << IMG2BITS);
idim--;
- idim &= 1023;
- image = otherdims | (idim << 20);
+ idim &= IMGMASK;
+ image = otherdims | (idim << IMG2BITS);
}
while (coord[2] >= hi[2]) {
coord[2] -= period[2];
- int idim = image >> 20;
- int otherdims = image ^ (idim << 20);
+ idim = image >> IMG2BITS;
+ otherdims = image ^ (idim << IMG2BITS);
idim++;
- idim &= 1023;
- image = otherdims | (idim << 20);
+ idim &= IMGMASK;
+ image = otherdims | (idim << IMG2BITS);
}
coord[2] = MAX(coord[2],lo[2]);
}
if (triclinic) lamda2x(coord,x);
}
/* ----------------------------------------------------------------------
remap the point into the periodic box no matter how far away
no image flag calculation
resulting coord must satisfy lo <= coord < hi
MAX is important since coord - prd < lo can happen when coord = hi
for triclinic, point is converted to lamda coords (0-1) before remap
------------------------------------------------------------------------- */
void Domain::remap(double *x)
{
double *lo,*hi,*period,*coord;
double lamda[3];
if (triclinic == 0) {
lo = boxlo;
hi = boxhi;
period = prd;
coord = x;
} else {
lo = boxlo_lamda;
hi = boxhi_lamda;
period = prd_lamda;
x2lamda(x,lamda);
coord = lamda;
}
if (xperiodic) {
while (coord[0] < lo[0]) coord[0] += period[0];
while (coord[0] >= hi[0]) coord[0] -= period[0];
coord[0] = MAX(coord[0],lo[0]);
}
if (yperiodic) {
while (coord[1] < lo[1]) coord[1] += period[1];
while (coord[1] >= hi[1]) coord[1] -= period[1];
coord[1] = MAX(coord[1],lo[1]);
}
if (zperiodic) {
while (coord[2] < lo[2]) coord[2] += period[2];
while (coord[2] >= hi[2]) coord[2] -= period[2];
coord[2] = MAX(coord[2],lo[2]);
}
if (triclinic) lamda2x(coord,x);
}
/* ----------------------------------------------------------------------
remap xnew to be within half box length of xold
do it directly, not iteratively, in case is far away
for triclinic, both points are converted to lamda coords (0-1) before remap
------------------------------------------------------------------------- */
void Domain::remap_near(double *xnew, double *xold)
{
int n;
double *coordnew,*coordold,*period,*half;
double lamdanew[3],lamdaold[3];
if (triclinic == 0) {
period = prd;
half = prd_half;
coordnew = xnew;
coordold = xold;
} else {
period = prd_lamda;
half = prd_half_lamda;
x2lamda(xnew,lamdanew);
coordnew = lamdanew;
x2lamda(xold,lamdaold);
coordold = lamdaold;
}
// iterative form
// if (xperiodic) {
// while (xnew[0]-xold[0] > half[0]) xnew[0] -= period[0];
// while (xold[0]-xnew[0] > half[0]) xnew[0] += period[0];
// }
if (xperiodic) {
if (coordnew[0]-coordold[0] > period[0]) {
n = static_cast<int> ((coordnew[0]-coordold[0])/period[0]);
xnew[0] -= n*period[0];
}
while (xnew[0]-xold[0] > half[0]) xnew[0] -= period[0];
if (xold[0]-xnew[0] > period[0]) {
n = static_cast<int> ((xold[0]-xnew[0])/period[0]);
xnew[0] += n*period[0];
}
while (xold[0]-xnew[0] > half[0]) xnew[0] += period[0];
}
if (yperiodic) {
if (coordnew[1]-coordold[1] > period[1]) {
n = static_cast<int> ((coordnew[1]-coordold[1])/period[1]);
xnew[1] -= n*period[1];
}
while (xnew[1]-xold[1] > half[1]) xnew[1] -= period[1];
if (xold[1]-xnew[1] > period[1]) {
n = static_cast<int> ((xold[1]-xnew[1])/period[1]);
xnew[1] += n*period[1];
}
while (xold[1]-xnew[1] > half[1]) xnew[1] += period[1];
}
if (zperiodic) {
if (coordnew[2]-coordold[2] > period[2]) {
n = static_cast<int> ((coordnew[2]-coordold[2])/period[2]);
xnew[2] -= n*period[2];
}
while (xnew[2]-xold[2] > half[2]) xnew[2] -= period[2];
if (xold[2]-xnew[2] > period[2]) {
n = static_cast<int> ((xold[2]-xnew[2])/period[2]);
xnew[2] += n*period[2];
}
while (xold[2]-xnew[2] > half[2]) xnew[2] += period[2];
}
if (triclinic) {
lamda2x(coordnew,xnew);
lamda2x(coordold,xold);
}
}
/* ----------------------------------------------------------------------
unmap the point via image flags
x overwritten with result, don't reset image flag
for triclinic, use h[] to add in tilt factors in other dims as needed
------------------------------------------------------------------------- */
-void Domain::unmap(double *x, int image)
+void Domain::unmap(double *x, tagint image)
{
- int xbox = (image & 1023) - 512;
- int ybox = (image >> 10 & 1023) - 512;
- int zbox = (image >> 20) - 512;
+ int xbox = (image & IMGMASK) - IMGMAX;
+ int ybox = (image >> IMGBITS & IMGMASK) - IMGMAX;
+ int zbox = (image >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
x[0] += xbox*xprd;
x[1] += ybox*yprd;
x[2] += zbox*zprd;
} else {
x[0] += h[0]*xbox + h[5]*ybox + h[4]*zbox;
x[1] += h[1]*ybox + h[3]*zbox;
x[2] += h[2]*zbox;
}
}
/* ----------------------------------------------------------------------
unmap the point via image flags
result returned in y, don't reset image flag
for triclinic, use h[] to add in tilt factors in other dims as needed
------------------------------------------------------------------------- */
-void Domain::unmap(double *x, int image, double *y)
+void Domain::unmap(double *x, tagint image, double *y)
{
- int xbox = (image & 1023) - 512;
- int ybox = (image >> 10 & 1023) - 512;
- int zbox = (image >> 20) - 512;
+ int xbox = (image & IMGMASK) - IMGMAX;
+ int ybox = (image >> IMGBITS & IMGMASK) - IMGMAX;
+ int zbox = (image >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
y[0] = x[0] + xbox*xprd;
y[1] = x[1] + ybox*yprd;
y[2] = x[2] + zbox*zprd;
} else {
y[0] = x[0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
y[1] = x[1] + h[1]*ybox + h[3]*zbox;
y[2] = x[2] + h[2]*zbox;
}
}
/* ----------------------------------------------------------------------
adjust image flags due to triclinic box flip
flip operation is changing box vectors A,B,C to new A',B',C'
A' = A (A does not change)
B' = B + mA (B shifted by A)
C' = C + pB + nA (C shifted by B and/or A)
this requires the image flags change from (a,b,c) to (a',b',c')
so that x_unwrap for each atom is same before/after
x_unwrap_before = xlocal + aA + bB + cC
x_unwrap_after = xlocal + a'A' + b'B' + c'C'
this requires:
c' = c
b' = b - cp
a' = a - (b-cp)m - cn = a - b'm - cn
in other words, for xy flip, change in x flag depends on current y flag
this is b/c the xy flip dramatically changes which tiled image of
simulation box an unwrapped point maps to
------------------------------------------------------------------------- */
void Domain::image_flip(int m, int n, int p)
{
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
- int xbox = (image[i] & 1023) - 512;
- int ybox = (image[i] >> 10 & 1023) - 512;
- int zbox = (image[i] >> 20) - 512;
+ int xbox = (image[i] & IMGMASK) - IMGMAX;
+ int ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ int zbox = (image[i] >> IMG2BITS) - IMGMAX;
ybox -= p*zbox;
xbox -= m*ybox + n*zbox;
- image[i] = ((zbox + 512 & 1023) << 20) |
- ((ybox + 512 & 1023) << 10) | (xbox + 512 & 1023);
+ image[i] = ((zbox + (tagint) IMGMAX & IMGMASK) << IMG2BITS) |
+ ((ybox + (tagint) IMGMAX & IMGMASK) << IMGBITS) |
+ (xbox + IMGMAX & IMGMASK);
}
}
/* ----------------------------------------------------------------------
create a lattice
delete it if style = none
------------------------------------------------------------------------- */
void Domain::set_lattice(int narg, char **arg)
{
if (lattice) delete lattice;
lattice = new Lattice(lmp,narg,arg);
if (lattice->style == 0) {
delete lattice;
lattice = NULL;
}
}
/* ----------------------------------------------------------------------
create a new region
------------------------------------------------------------------------- */
void Domain::add_region(int narg, char **arg)
{
if (narg < 2) error->all(FLERR,"Illegal region command");
if (strcmp(arg[1],"delete") == 0) {
delete_region(narg,arg);
return;
}
if (find_region(arg[0]) >= 0) error->all(FLERR,"Reuse of region ID");
// extend Region list if necessary
if (nregion == maxregion) {
maxregion += DELTA;
regions = (Region **)
memory->srealloc(regions,maxregion*sizeof(Region *),"domain:regions");
}
// create the Region
if (strcmp(arg[1],"none") == 0) error->all(FLERR,"Invalid region style");
#define REGION_CLASS
#define RegionStyle(key,Class) \
else if (strcmp(arg[1],#key) == 0) \
regions[nregion] = new Class(lmp,narg,arg);
#include "style_region.h"
#undef REGION_CLASS
else error->all(FLERR,"Invalid region style");
nregion++;
}
/* ----------------------------------------------------------------------
delete a region
------------------------------------------------------------------------- */
void Domain::delete_region(int narg, char **arg)
{
if (narg != 2) error->all(FLERR,"Illegal region command");
int iregion = find_region(arg[0]);
if (iregion == -1) error->all(FLERR,"Delete region ID does not exist");
delete regions[iregion];
regions[iregion] = regions[nregion-1];
nregion--;
}
/* ----------------------------------------------------------------------
return region index if name matches existing region ID
return -1 if no such region
------------------------------------------------------------------------- */
int Domain::find_region(char *name)
{
for (int iregion = 0; iregion < nregion; iregion++)
if (strcmp(name,regions[iregion]->id) == 0) return iregion;
return -1;
}
/* ----------------------------------------------------------------------
(re)set boundary settings
flag = 0, called from the input script
flag = 1, called from change box command
------------------------------------------------------------------------- */
void Domain::set_boundary(int narg, char **arg, int flag)
{
if (narg != 3) error->all(FLERR,"Illegal boundary command");
char c;
for (int idim = 0; idim < 3; idim++)
for (int iside = 0; iside < 2; iside++) {
if (iside == 0) c = arg[idim][0];
else if (iside == 1 && strlen(arg[idim]) == 1) c = arg[idim][0];
else c = arg[idim][1];
if (c == 'p') boundary[idim][iside] = 0;
else if (c == 'f') boundary[idim][iside] = 1;
else if (c == 's') boundary[idim][iside] = 2;
else if (c == 'm') boundary[idim][iside] = 3;
else {
if (flag == 0) error->all(FLERR,"Illegal boundary command");
if (flag == 1) error->all(FLERR,"Illegal change_box command");
}
}
for (int idim = 0; idim < 3; idim++)
if ((boundary[idim][0] == 0 && boundary[idim][1]) ||
(boundary[idim][0] && boundary[idim][1] == 0))
error->all(FLERR,"Both sides of boundary must be periodic");
if (boundary[0][0] == 0) xperiodic = 1;
else xperiodic = 0;
if (boundary[1][0] == 0) yperiodic = 1;
else yperiodic = 0;
if (boundary[2][0] == 0) zperiodic = 1;
else zperiodic = 0;
periodicity[0] = xperiodic;
periodicity[1] = yperiodic;
periodicity[2] = zperiodic;
nonperiodic = 0;
if (xperiodic == 0 || yperiodic == 0 || zperiodic == 0) {
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) nonperiodic = 2;
}
}
/* ----------------------------------------------------------------------
print box info, orthogonal or triclinic
------------------------------------------------------------------------- */
void Domain::print_box(const char *str)
{
if (comm->me == 0) {
if (screen) {
if (triclinic == 0)
fprintf(screen,"%sorthogonal box = (%g %g %g) to (%g %g %g)\n",
str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2]);
else {
char *format = (char *)
"%striclinic box = (%g %g %g) to (%g %g %g) with tilt (%g %g %g)\n";
fprintf(screen,format,
str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2],
xy,xz,yz);
}
}
if (logfile) {
if (triclinic == 0)
fprintf(logfile,"%sorthogonal box = (%g %g %g) to (%g %g %g)\n",
str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2]);
else {
char *format = (char *)
"%striclinic box = (%g %g %g) to (%g %g %g) with tilt (%g %g %g)\n";
fprintf(logfile,format,
str,boxlo[0],boxlo[1],boxlo[2],boxhi[0],boxhi[1],boxhi[2],
xy,xz,yz);
}
}
}
}
/* ----------------------------------------------------------------------
format boundary string for output
assume str is 9 chars or more in length
------------------------------------------------------------------------- */
void Domain::boundary_string(char *str)
{
int m = 0;
for (int idim = 0; idim < 3; idim++) {
for (int iside = 0; iside < 2; iside++) {
if (boundary[idim][iside] == 0) str[m++] = 'p';
else if (boundary[idim][iside] == 1) str[m++] = 'f';
else if (boundary[idim][iside] == 2) str[m++] = 's';
else if (boundary[idim][iside] == 3) str[m++] = 'm';
}
str[m++] = ' ';
}
str[8] = '\0';
}
/* ----------------------------------------------------------------------
convert triclinic 0-1 lamda coords to box coords for all N atoms
x = H lamda + x0;
------------------------------------------------------------------------- */
void Domain::lamda2x(int n)
{
double **x = atom->x;
for (int i = 0; i < n; i++) {
x[i][0] = h[0]*x[i][0] + h[5]*x[i][1] + h[4]*x[i][2] + boxlo[0];
x[i][1] = h[1]*x[i][1] + h[3]*x[i][2] + boxlo[1];
x[i][2] = h[2]*x[i][2] + boxlo[2];
}
}
/* ----------------------------------------------------------------------
convert box coords to triclinic 0-1 lamda coords for all N atoms
lamda = H^-1 (x - x0)
------------------------------------------------------------------------- */
void Domain::x2lamda(int n)
{
double delta[3];
double **x = atom->x;
for (int i = 0; i < n; i++) {
delta[0] = x[i][0] - boxlo[0];
delta[1] = x[i][1] - boxlo[1];
delta[2] = x[i][2] - boxlo[2];
x[i][0] = h_inv[0]*delta[0] + h_inv[5]*delta[1] + h_inv[4]*delta[2];
x[i][1] = h_inv[1]*delta[1] + h_inv[3]*delta[2];
x[i][2] = h_inv[2]*delta[2];
}
}
/* ----------------------------------------------------------------------
convert triclinic 0-1 lamda coords to box coords for one atom
x = H lamda + x0;
lamda and x can point to same 3-vector
------------------------------------------------------------------------- */
void Domain::lamda2x(double *lamda, double *x)
{
x[0] = h[0]*lamda[0] + h[5]*lamda[1] + h[4]*lamda[2] + boxlo[0];
x[1] = h[1]*lamda[1] + h[3]*lamda[2] + boxlo[1];
x[2] = h[2]*lamda[2] + boxlo[2];
}
/* ----------------------------------------------------------------------
convert box coords to triclinic 0-1 lamda coords for one atom
lamda = H^-1 (x - x0)
x and lamda can point to same 3-vector
------------------------------------------------------------------------- */
void Domain::x2lamda(double *x, double *lamda)
{
double delta[3];
delta[0] = x[0] - boxlo[0];
delta[1] = x[1] - boxlo[1];
delta[2] = x[2] - boxlo[2];
lamda[0] = h_inv[0]*delta[0] + h_inv[5]*delta[1] + h_inv[4]*delta[2];
lamda[1] = h_inv[1]*delta[1] + h_inv[3]*delta[2];
lamda[2] = h_inv[2]*delta[2];
}
/* ----------------------------------------------------------------------
convert box coords to triclinic 0-1 lamda coords for one atom
use my_boxlo & my_h_inv stored by caller for previous state of box
lamda = H^-1 (x - x0)
x and lamda can point to same 3-vector
------------------------------------------------------------------------- */
void Domain::x2lamda(double *x, double *lamda,
double *my_boxlo, double *my_h_inv)
{
double delta[3];
delta[0] = x[0] - my_boxlo[0];
delta[1] = x[1] - my_boxlo[1];
delta[2] = x[2] - my_boxlo[2];
lamda[0] = my_h_inv[0]*delta[0] + my_h_inv[5]*delta[1] + my_h_inv[4]*delta[2];
lamda[1] = my_h_inv[1]*delta[1] + my_h_inv[3]*delta[2];
lamda[2] = my_h_inv[2]*delta[2];
}
/* ----------------------------------------------------------------------
convert 8 lamda corner pts of lo/hi box to box coords
return bboxlo/hi = bounding box around 8 corner pts in box coords
------------------------------------------------------------------------- */
void Domain::bbox(double *lo, double *hi, double *bboxlo, double *bboxhi)
{
double x[3];
bboxlo[0] = bboxlo[1] = bboxlo[2] = BIG;
bboxhi[0] = bboxhi[1] = bboxhi[2] = -BIG;
x[0] = lo[0]; x[1] = lo[1]; x[2] = lo[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = hi[0]; x[1] = lo[1]; x[2] = lo[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = lo[0]; x[1] = hi[1]; x[2] = lo[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = hi[0]; x[1] = hi[1]; x[2] = lo[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = lo[0]; x[1] = lo[1]; x[2] = hi[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = hi[0]; x[1] = lo[1]; x[2] = hi[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = lo[0]; x[1] = hi[1]; x[2] = hi[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
x[0] = hi[0]; x[1] = hi[1]; x[2] = hi[2];
lamda2x(x,x);
bboxlo[0] = MIN(bboxlo[0],x[0]); bboxhi[0] = MAX(bboxhi[0],x[0]);
bboxlo[1] = MIN(bboxlo[1],x[1]); bboxhi[1] = MAX(bboxhi[1],x[1]);
bboxlo[2] = MIN(bboxlo[2],x[2]); bboxhi[2] = MAX(bboxhi[2],x[2]);
}
/* ----------------------------------------------------------------------
compute 8 corner pts of triclinic box
8 are ordered with x changing fastest, then y, finally z
could be more efficient if just coded with xy,yz,xz explicitly
------------------------------------------------------------------------- */
void Domain::box_corners()
{
corners[0][0] = 0.0; corners[0][1] = 0.0; corners[0][2] = 0.0;
lamda2x(corners[0],corners[0]);
corners[1][0] = 1.0; corners[1][1] = 0.0; corners[1][2] = 0.0;
lamda2x(corners[1],corners[1]);
corners[2][0] = 0.0; corners[2][1] = 1.0; corners[2][2] = 0.0;
lamda2x(corners[2],corners[2]);
corners[3][0] = 1.0; corners[3][1] = 1.0; corners[3][2] = 0.0;
lamda2x(corners[3],corners[3]);
corners[4][0] = 0.0; corners[4][1] = 0.0; corners[4][2] = 1.0;
lamda2x(corners[4],corners[4]);
corners[5][0] = 1.0; corners[5][1] = 0.0; corners[5][2] = 1.0;
lamda2x(corners[5],corners[5]);
corners[6][0] = 0.0; corners[6][1] = 1.0; corners[6][2] = 1.0;
lamda2x(corners[6],corners[6]);
corners[7][0] = 1.0; corners[7][1] = 1.0; corners[7][2] = 1.0;
lamda2x(corners[7],corners[7]);
}
diff --git a/src/domain.h b/src/domain.h
index 465536e3d..6881e0a3d 100644
--- a/src/domain.h
+++ b/src/domain.h
@@ -1,176 +1,203 @@
/* -*- c++ -*- ----------------------------------------------------------
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_DOMAIN_H
#define LMP_DOMAIN_H
+#include "math.h"
#include "pointers.h"
namespace LAMMPS_NS {
class Domain : protected Pointers {
public:
int box_exist; // 0 = not yet created, 1 = exists
int dimension; // 2 = 2d, 3 = 3d
int nonperiodic; // 0 = periodic in all 3 dims
// 1 = periodic or fixed in all 6
// 2 = shrink-wrap in any of 6
int xperiodic,yperiodic,zperiodic; // 0 = non-periodic, 1 = periodic
int periodicity[3]; // xyz periodicity as array
int boundary[3][2]; // settings for 6 boundaries
// 0 = periodic
// 1 = fixed non-periodic
// 2 = shrink-wrap non-periodic
// 3 = shrink-wrap non-per w/ min
int triclinic; // 0 = orthog box, 1 = triclinic
// orthogonal box
double xprd,yprd,zprd; // global box dimensions
double xprd_half,yprd_half,zprd_half; // half dimensions
double prd[3]; // array form of dimensions
double prd_half[3]; // array form of half dimensions
// triclinic box
// xprd,xprd_half,prd,prd_half =
// same as if untilted
double prd_lamda[3]; // lamda box = (1,1,1)
double prd_half_lamda[3]; // lamda half box = (0.5,0.5,0.5)
double boxlo[3],boxhi[3]; // orthogonal box global bounds
// triclinic box
// boxlo/hi = same as if untilted
double boxlo_lamda[3],boxhi_lamda[3]; // lamda box = (0,1)
double boxlo_bound[3],boxhi_bound[3]; // bounding box of tilted domain
double corners[8][3]; // 8 corner points
// orthogonal box & triclinic box
double minxlo,minxhi; // minimum size of global box
double minylo,minyhi; // when shrink-wrapping
double minzlo,minzhi; // tri only possible for non-skew dims
// orthogonal box
double sublo[3],subhi[3]; // sub-box bounds on this proc
// triclinic box
// sublo/hi = undefined
double sublo_lamda[3],subhi_lamda[3]; // bounds of subbox in lamda
// triclinic box
double xy,xz,yz; // 3 tilt factors
double h[6],h_inv[6]; // shape matrix in Voigt notation
double h_rate[6],h_ratelo[3]; // rate of box size/shape change
int box_change; // 1 if box bounds ever change, 0 if fixed
int deform_flag; // 1 if fix deform exist, else 0
int deform_vremap; // 1 if fix deform remaps v, else 0
int deform_groupbit; // atom group to perform v remap for
class Lattice *lattice; // user-defined lattice
int nregion; // # of defined Regions
int maxregion; // max # list can hold
class Region **regions; // list of defined Regions
Domain(class LAMMPS *);
virtual ~Domain();
virtual void init();
void set_initial_box();
virtual void set_global_box();
virtual void set_lamda_box();
virtual void set_local_box();
virtual void reset_box();
virtual void pbc();
void box_too_small_check();
- int minimum_image_check(double, double, double);
void minimum_image(double &, double &, double &);
void minimum_image(double *);
+ int closest_image(int, int);
void closest_image(const double * const, const double * const,
double * const);
- void remap(double *, int &);
+ void remap(double *, tagint &);
void remap(double *);
void remap_near(double *, double *);
- void unmap(double *, int);
- void unmap(double *, int, double *);
+ void unmap(double *, tagint);
+ void unmap(double *, tagint, double *);
void image_flip(int, int, int);
void set_lattice(int, char **);
void add_region(int, char **);
void delete_region(int, char **);
int find_region(char *);
void set_boundary(int, char **, int);
void print_box(const char *);
void boundary_string(char *);
virtual void lamda2x(int);
virtual void x2lamda(int);
void lamda2x(double *, double *);
void x2lamda(double *, double *);
void x2lamda(double *, double *, double *, double *);
void bbox(double *, double *, double *, double *);
void box_corners();
+ // minimum image convention check
+ // return 1 if any distance > 1/2 of box size
+ // inline since called from neighbor build inner loop
+
+ inline int minimum_image_check(double dx, double dy, double dz) {
+ if (xperiodic && fabs(dx) > xprd_half) return 1;
+ if (yperiodic && fabs(dy) > yprd_half) return 1;
+ if (zperiodic && fabs(dz) > zprd_half) return 1;
+ return 0;
+ }
+
private:
double small[3]; // fractions of box lengths
};
}
#endif
/* ERROR/WARNING messages:
E: Box bounds are invalid
The box boundaries specified in the read_data file are invalid. The
lo value must be less than the hi value for all 3 dimensions.
E: Cannot skew triclinic box in z for 2d simulation
Self-explanatory.
E: Triclinic box skew is too large
The displacement in a skewed direction must be less than half the box
length in that dimension. E.g. the xy tilt must be between -half and
+half of the x box length.
E: Illegal simulation box
The lower bound of the simulation box is greater than the upper bound.
+E: Bond atom missing in box size check
+
+The 2nd atoms needed to compute a particular bond is missing on this
+processor. Typically this is because the pairwise cutoff is set too
+short or the bond has blown apart and an atom is too far away.
+
+E: Bond/angle/dihedral extent > half of periodic box length
+
+This is a restriction because LAMMPS can be confused about which image
+of an atom in the bonded interaction is the correct one to use.
+"Extent" in this context means the maximum end-to-end length of the
+bond/angle/dihedral. LAMMPS computes this by taking the maximum bond
+length, multiplying by the number of bonds in the interaction (e.g. 3
+for a dihedral) and adding a small amount of stretch.
+
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Reuse of region ID
A region ID cannot be used twice.
E: Invalid region style
The choice of region style is unknown.
E: Delete region ID does not exist
Self-explanatory.
E: Both sides of boundary must be periodic
Cannot specify a boundary as periodic only on the lo or hi side. Must
be periodic on both sides.
*/
diff --git a/src/dump_atom.cpp b/src/dump_atom.cpp
index 42ddf8f19..5641b4ea5 100644
--- a/src/dump_atom.cpp
+++ b/src/dump_atom.cpp
@@ -1,429 +1,429 @@
/* ----------------------------------------------------------------------
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(FLERR,"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 boundary string
domain->boundary_string(boundstr);
// setup column string
if (scale_flag == 0 && image_flag == 0)
columns = (char *) "id type x y z";
else if (scale_flag == 0 && image_flag == 1)
columns = (char *) "id type x y z ix iy iz";
else if (scale_flag == 1 && image_flag == 0)
columns = (char *) "id type xs ys zs";
else if (scale_flag == 1 && image_flag == 1)
columns = (char *) "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(FLERR,"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(FLERR,"Illegal dump_modify command");
return 2;
} else if (strcmp(arg[0],"image") == 0) {
if (narg < 2) error->all(FLERR,"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(FLERR,"Illegal dump_modify command");
return 2;
}
return 0;
}
/* ---------------------------------------------------------------------- */
void DumpAtom::write_header(bigint ndump)
{
if (multiproc) (this->*header_choice)(ndump);
else if (me == 0) (this->*header_choice)(ndump);
}
/* ---------------------------------------------------------------------- */
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(bigint ndump)
{
fwrite(&update->ntimestep,sizeof(bigint),1,fp);
fwrite(&ndump,sizeof(bigint),1,fp);
fwrite(&domain->triclinic,sizeof(int),1,fp);
fwrite(&domain->boundary[0][0],6*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(bigint ndump)
{
fwrite(&update->ntimestep,sizeof(bigint),1,fp);
fwrite(&ndump,sizeof(bigint),1,fp);
fwrite(&domain->triclinic,sizeof(int),1,fp);
fwrite(&domain->boundary[0][0],6*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(bigint ndump)
{
fprintf(fp,"ITEM: TIMESTEP\n");
fprintf(fp,BIGINT_FORMAT "\n",update->ntimestep);
fprintf(fp,"ITEM: NUMBER OF ATOMS\n");
fprintf(fp,BIGINT_FORMAT "\n",ndump);
fprintf(fp,"ITEM: BOX BOUNDS %s\n",boundstr);
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(bigint ndump)
{
fprintf(fp,"ITEM: TIMESTEP\n");
fprintf(fp,BIGINT_FORMAT "\n",update->ntimestep);
fprintf(fp,"ITEM: NUMBER OF ATOMS\n");
fprintf(fp,BIGINT_FORMAT "\n",ndump);
fprintf(fp,"ITEM: BOX BOUNDS xy xz yz %s\n",boundstr);
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;
+ tagint *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;
+ buf[m++] = (image[i] & IMGMASK) - IMGMAX;
+ buf[m++] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ buf[m++] = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ buf[m++] = (image[i] & IMGMASK) - IMGMAX;
+ buf[m++] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ buf[m++] = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ buf[m++] = (image[i] & IMGMASK) - IMGMAX;
+ buf[m++] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ buf[m++] = (image[i] >> IMG2BITS) - IMGMAX;
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_custom.cpp b/src/dump_custom.cpp
index 32c51d5e3..5c5c951ee 100644
--- a/src/dump_custom.cpp
+++ b/src/dump_custom.cpp
@@ -1,2411 +1,2411 @@
/* ----------------------------------------------------------------------
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
// also customize compute_atom_property.cpp
enum{ID,MOL,TYPE,ELEMENT,MASS,
X,Y,Z,XS,YS,ZS,XSTRI,YSTRI,ZSTRI,XU,YU,ZU,XUTRI,YUTRI,ZUTRI,
XSU,YSU,ZSU,XSUTRI,YSUTRI,ZSUTRI,
IX,IY,IZ,
VX,VY,VZ,FX,FY,FZ,
Q,MUX,MUY,MUZ,MU,RADIUS,DIAMETER,
OMEGAX,OMEGAY,OMEGAZ,ANGMOMX,ANGMOMY,ANGMOMZ,
TQX,TQY,TQZ,SPIN,ERADIUS,ERVEL,ERFORCE,
COMPUTE,FIX,VARIABLE};
enum{LT,LE,GT,GE,EQ,NEQ};
enum{INT,DOUBLE,STRING};
#define INVOKED_PERATOM 8
/* ---------------------------------------------------------------------- */
DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) :
Dump(lmp, narg, arg)
{
if (narg == 5) error->all(FLERR,"No dump custom arguments specified");
clearstep = 1;
nevery = atoi(arg[3]);
// size_one may be shrunk below if additional optional args exist
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
memory->create(field2index,nfield,"dump:field2index");
memory->create(argindex,nfield,"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
// ioptional = start of additional optional args
// only dump image style processes optional args
ioptional = parse_fields(narg,arg);
if (ioptional < narg && strcmp(style,"image") != 0)
error->all(FLERR,"Invalid attribute in dump custom command");
size_one = nfield = ioptional - 5;
// atom selection arrays
maxlocal = 0;
choose = NULL;
dchoose = NULL;
clist = NULL;
// element names
ntypes = atom->ntypes;
typenames = 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) strcat(format_default,"%d ");
else if (vtype[i] == DOUBLE) strcat(format_default,"%g ");
else if (vtype[i] == STRING) strcat(format_default,"%s ");
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->destroy(field2index);
memory->destroy(argindex);
delete [] idregion;
memory->destroy(thresh_array);
memory->destroy(thresh_op);
memory->destroy(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->destroy(vbuf[i]);
delete [] vbuf;
memory->destroy(choose);
memory->destroy(dchoose);
memory->destroy(clist);
if (typenames) {
for (int i = 1; i <= ntypes; i++) delete [] typenames[i];
delete [] typenames;
}
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);
// default for element names = C
if (typenames == NULL) {
typenames = new char*[ntypes+1];
for (int itype = 1; itype <= ntypes; itype++) {
typenames[itype] = new char[2];
strcpy(typenames[itype],"C");
}
}
// 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 boundary string
domain->boundary_string(boundstr);
// 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(FLERR,"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(FLERR,"Could not find dump custom fix ID");
fix[i] = modify->fix[ifix];
if (nevery % modify->fix[ifix]->peratom_freq)
error->all(FLERR,"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(FLERR,"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(FLERR,"Region ID for dump custom does not exist");
}
// open single file, one time only
if (multifile == 0) openfile();
}
/* ---------------------------------------------------------------------- */
void DumpCustom::write_header(bigint ndump)
{
if (multiproc) (this->*header_choice)(ndump);
else if (me == 0) (this->*header_choice)(ndump);
}
/* ---------------------------------------------------------------------- */
void DumpCustom::header_binary(bigint ndump)
{
fwrite(&update->ntimestep,sizeof(bigint),1,fp);
fwrite(&ndump,sizeof(bigint),1,fp);
fwrite(&domain->triclinic,sizeof(int),1,fp);
fwrite(&domain->boundary[0][0],6*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(bigint ndump)
{
fwrite(&update->ntimestep,sizeof(bigint),1,fp);
fwrite(&ndump,sizeof(bigint),1,fp);
fwrite(&domain->triclinic,sizeof(int),1,fp);
fwrite(&domain->boundary[0][0],6*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(bigint ndump)
{
fprintf(fp,"ITEM: TIMESTEP\n");
fprintf(fp,BIGINT_FORMAT "\n",update->ntimestep);
fprintf(fp,"ITEM: NUMBER OF ATOMS\n");
fprintf(fp,BIGINT_FORMAT "\n",ndump);
fprintf(fp,"ITEM: BOX BOUNDS %s\n",boundstr);
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(bigint ndump)
{
fprintf(fp,"ITEM: TIMESTEP\n");
fprintf(fp,BIGINT_FORMAT "\n",update->ntimestep);
fprintf(fp,"ITEM: NUMBER OF ATOMS\n");
fprintf(fp,BIGINT_FORMAT "\n",ndump);
fprintf(fp,"ITEM: BOX BOUNDS xy xz yz %s\n",boundstr);
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->destroy(choose);
memory->destroy(dchoose);
memory->destroy(clist);
memory->create(choose,maxlocal,"dump:choose");
memory->create(dchoose,maxlocal,"dump:dchoose");
memory->create(clist,maxlocal,"dump:clist");
for (i = 0; i < nvariable; i++) {
memory->destroy(vbuf[i]);
memory->create(vbuf[i],maxlocal,"dump:vbuf");
}
}
// invoke Computes for per-atom quantities
if (ncompute) {
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;
// 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;
}
// 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;
}
// 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(FLERR,
"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] == ELEMENT) {
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;
+ tagint *image = atom->image;
double xprd = domain->xprd;
for (i = 0; i < nlocal; i++)
- dchoose[i] = x[i][0] + ((image[i] & 1023) - 512) * xprd;
+ dchoose[i] = x[i][0] + ((image[i] & IMGMASK) - IMGMAX) * xprd;
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == YU) {
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double yprd = domain->yprd;
for (i = 0; i < nlocal; i++)
- dchoose[i] = x[i][1] + ((image[i] >> 10 & 1023) - 512) * yprd;
+ dchoose[i] = x[i][1] + ((image[i] >> IMGBITS & IMGMASK) - IMGMAX) * yprd;
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == ZU) {
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double zprd = domain->zprd;
for (i = 0; i < nlocal; i++)
- dchoose[i] = x[i][2] + ((image[i] >> 20) - 512) * zprd;
+ dchoose[i] = x[i][2] + ((image[i] >> IMG2BITS) - IMGMAX) * zprd;
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == XUTRI) {
double **x = atom->x;
- int *image = atom->image;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *image = atom->image;
double *h = domain->h;
int zbox;
for (i = 0; i < nlocal; i++) {
- zbox = (image[i] >> 20) - 512;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dchoose[i] = x[i][2] + h[2]*zbox;
}
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == XSU) {
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double boxxlo = domain->boxlo[0];
double invxprd = 1.0/domain->xprd;
for (i = 0; i < nlocal; i++)
- dchoose[i] = (x[i][0] - boxxlo) * invxprd + (image[i] & 1023) - 512;
+ dchoose[i] = (x[i][0] - boxxlo) * invxprd + (image[i] & IMGMASK) - IMGMAX;
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == YSU) {
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double boxylo = domain->boxlo[1];
double invyprd = 1.0/domain->yprd;
for (i = 0; i < nlocal; i++)
dchoose[i] =
- (x[i][1] - boxylo) * invyprd + (image[i] >> 10 & 1023) - 512;
+ (x[i][1] - boxylo) * invyprd + (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == ZSU) {
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double boxzlo = domain->boxlo[2];
double invzprd = 1.0/domain->zprd;
for (i = 0; i < nlocal; i++)
- dchoose[i] = (x[i][2] - boxzlo) * invzprd + (image[i] >> 20) - 512;
+ dchoose[i] = (x[i][2] - boxzlo) * invzprd + (image[i] >> IMG2BITS) - IMGMAX;
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == XSUTRI) {
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
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]) +
- (image[i] & 1023) - 512;
+ (image[i] & IMGMASK) - IMGMAX;
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == YSUTRI) {
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
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]) +
- (image[i] >> 10 & 1023) - 512;
+ (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == ZSUTRI) {
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
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]) +
- (image[i] >> 20) - 512;
+ (image[i] >> IMG2BITS) - IMGMAX;
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == IX) {
- int *image = atom->image;
+ tagint *image = atom->image;
for (i = 0; i < nlocal; i++)
- dchoose[i] = (image[i] & 1023) - 512;
+ dchoose[i] = (image[i] & IMGMASK) - IMGMAX;
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == IY) {
- int *image = atom->image;
+ tagint *image = atom->image;
for (i = 0; i < nlocal; i++)
- dchoose[i] = (image[i] >> 10 & 1023) - 512;
+ dchoose[i] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == IZ) {
- int *image = atom->image;
+ tagint *image = atom->image;
for (i = 0; i < nlocal; i++)
- dchoose[i] = (image[i] >> 20) - 512;
+ dchoose[i] = (image[i] >> IMG2BITS) - IMGMAX;
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(FLERR,
"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(FLERR,
"Threshhold for an atom property that isn't allocated");
ptr = &atom->mu[0][0];
nstride = 4;
} else if (thresh_array[ithresh] == MUY) {
if (!atom->mu_flag)
error->all(FLERR,
"Threshhold for an atom property that isn't allocated");
ptr = &atom->mu[0][1];
nstride = 4;
} else if (thresh_array[ithresh] == MUZ) {
if (!atom->mu_flag)
error->all(FLERR,
"Threshhold for an atom property that isn't allocated");
ptr = &atom->mu[0][2];
nstride = 4;
} else if (thresh_array[ithresh] == MU) {
if (!atom->mu_flag)
error->all(FLERR,
"Threshhold for an atom property that isn't allocated");
ptr = &atom->mu[0][3];
nstride = 4;
} else if (thresh_array[ithresh] == RADIUS) {
if (!atom->radius_flag)
error->all(FLERR,
"Threshhold for an atom property that isn't allocated");
ptr = atom->radius;
nstride = 1;
} else if (thresh_array[ithresh] == DIAMETER) {
if (!atom->radius_flag)
error->all(FLERR,
"Threshhold for an atom property that isn't allocated");
double *radius = atom->radius;
for (i = 0; i < nlocal; i++) dchoose[i] = 2.0*radius[i];
ptr = dchoose;
nstride = 1;
} else if (thresh_array[ithresh] == OMEGAX) {
if (!atom->omega_flag)
error->all(FLERR,
"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(FLERR,
"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(FLERR,
"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(FLERR,
"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(FLERR,
"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(FLERR,
"Threshhold for an atom property that isn't allocated");
ptr = &atom->angmom[0][2];
nstride = 3;
} else if (thresh_array[ithresh] == TQX) {
if (!atom->torque_flag)
error->all(FLERR,
"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(FLERR,
"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(FLERR,
"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(FLERR,
"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(FLERR,
"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(FLERR,
"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(FLERR,
"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;
} else if (thresh_op[ithresh] == LE) {
for (i = 0; i < nlocal; i++, ptr += nstride)
if (choose[i] && *ptr > value) choose[i] = 0;
} else if (thresh_op[ithresh] == GT) {
for (i = 0; i < nlocal; i++, ptr += nstride)
if (choose[i] && *ptr <= value) choose[i] = 0;
} else if (thresh_op[ithresh] == GE) {
for (i = 0; i < nlocal; i++, ptr += nstride)
if (choose[i] && *ptr < value) choose[i] = 0;
} else if (thresh_op[ithresh] == EQ) {
for (i = 0; i < nlocal; i++, ptr += nstride)
if (choose[i] && *ptr != value) choose[i] = 0;
} else if (thresh_op[ithresh] == NEQ) {
for (i = 0; i < nlocal; i++, ptr += nstride)
if (choose[i] && *ptr == value) choose[i] = 0;
}
}
}
// compress choose flags into clist
// nchoose = # of selected atoms
// clist[i] = local index of each selected atom
nchoose = 0;
for (i = 0; i < nlocal; i++)
if (choose[i]) clist[nchoose++] = i;
return nchoose;
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack(int *ids)
{
for (int n = 0; n < size_one; n++) (this->*pack_choice[n])(n);
if (ids) {
int *tag = atom->tag;
for (int i = 0; i < nchoose; i++)
ids[i] = tag[clist[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 if (vtype[j] == DOUBLE) fprintf(fp,vformat[j],mybuf[m]);
else if (vtype[j] == STRING)
fprintf(fp,vformat[j],typenames[(int) mybuf[m]]);
m++;
}
fprintf(fp,"\n");
}
}
/* ---------------------------------------------------------------------- */
int 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(FLERR,"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],"element") == 0) {
pack_choice[i] = &DumpCustom::pack_type;
vtype[i] = STRING;
} 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],"xsu") == 0) {
if (domain->triclinic) pack_choice[i] = &DumpCustom::pack_xsu_triclinic;
else pack_choice[i] = &DumpCustom::pack_xsu;
vtype[i] = DOUBLE;
} else if (strcmp(arg[iarg],"ysu") == 0) {
if (domain->triclinic) pack_choice[i] = &DumpCustom::pack_ysu_triclinic;
else pack_choice[i] = &DumpCustom::pack_ysu;
vtype[i] = DOUBLE;
} else if (strcmp(arg[iarg],"zsu") == 0) {
if (domain->triclinic) pack_choice[i] = &DumpCustom::pack_zsu_triclinic;
else pack_choice[i] = &DumpCustom::pack_zsu;
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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"Dumping an atom property that isn't allocated");
pack_choice[i] = &DumpCustom::pack_muz;
vtype[i] = DOUBLE;
} else if (strcmp(arg[iarg],"mu") == 0) {
if (!atom->mu_flag)
error->all(FLERR,"Dumping an atom property that isn't allocated");
pack_choice[i] = &DumpCustom::pack_mu;
vtype[i] = DOUBLE;
} else if (strcmp(arg[iarg],"radius") == 0) {
if (!atom->radius_flag)
error->all(FLERR,"Dumping an atom property that isn't allocated");
pack_choice[i] = &DumpCustom::pack_radius;
vtype[i] = DOUBLE;
} else if (strcmp(arg[iarg],"diameter") == 0) {
if (!atom->radius_flag)
error->all(FLERR,"Dumping an atom property that isn't allocated");
pack_choice[i] = &DumpCustom::pack_diameter;
vtype[i] = DOUBLE;
} else if (strcmp(arg[iarg],"omegax") == 0) {
if (!atom->omega_flag)
error->all(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"Dumping an atom property that isn't allocated");
pack_choice[i] = &DumpCustom::pack_angmomz;
vtype[i] = DOUBLE;
} else if (strcmp(arg[iarg],"tqx") == 0) {
if (!atom->torque_flag)
error->all(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"Could not find dump custom compute ID");
if (modify->compute[n]->peratom_flag == 0)
error->all(FLERR,"Dump custom compute does not compute per-atom info");
if (argindex[i] == 0 && modify->compute[n]->size_peratom_cols > 0)
error->all(FLERR,"Dump custom compute does not calculate per-atom vector");
if (argindex[i] > 0 && modify->compute[n]->size_peratom_cols == 0)
error->all(FLERR,"Dump custom compute does not calculate per-atom array");
if (argindex[i] > 0 &&
argindex[i] > modify->compute[n]->size_peratom_cols)
error->all(FLERR,"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(FLERR,"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(FLERR,"Could not find dump custom fix ID");
if (modify->fix[n]->peratom_flag == 0)
error->all(FLERR,"Dump custom fix does not compute per-atom info");
if (argindex[i] == 0 && modify->fix[n]->size_peratom_cols > 0)
error->all(FLERR,"Dump custom fix does not compute per-atom vector");
if (argindex[i] > 0 && modify->fix[n]->size_peratom_cols == 0)
error->all(FLERR,"Dump custom fix does not compute per-atom array");
if (argindex[i] > 0 &&
argindex[i] > modify->fix[n]->size_peratom_cols)
error->all(FLERR,"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(FLERR,"Could not find dump custom variable name");
if (input->variable->atomstyle(n) == 0)
error->all(FLERR,"Dump custom variable is not atom-style variable");
field2index[i] = add_variable(suffix);
delete [] suffix;
} else return iarg;
}
return narg;
}
/* ----------------------------------------------------------------------
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(FLERR,"Illegal dump_modify command");
if (strcmp(arg[1],"none") == 0) iregion = -1;
else {
iregion = domain->find_region(arg[1]);
if (iregion == -1)
error->all(FLERR,"Dump_modify region ID does not exist");
int n = strlen(arg[1]) + 1;
idregion = new char[n];
strcpy(idregion,arg[1]);
}
return 2;
}
if (strcmp(arg[0],"element") == 0) {
if (narg < ntypes+1)
error->all(FLERR,"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++) {
int n = strlen(arg[itype]) + 1;
typenames[itype] = new char[n];
strcpy(typenames[itype],arg[itype]);
}
return ntypes+1;
}
if (strcmp(arg[0],"thresh") == 0) {
if (narg < 2) error->all(FLERR,"Illegal dump_modify command");
if (strcmp(arg[1],"none") == 0) {
if (nthresh) {
memory->destroy(thresh_array);
memory->destroy(thresh_op);
memory->destroy(thresh_value);
thresh_array = NULL;
thresh_op = NULL;
thresh_value = NULL;
}
nthresh = 0;
return 2;
}
if (narg < 4) error->all(FLERR,"Illegal dump_modify command");
// grow threshhold arrays
memory->grow(thresh_array,nthresh+1,"dump:thresh_array");
memory->grow(thresh_op,(nthresh+1),"dump:thresh_op");
memory->grow(thresh_value,(nthresh+1),"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],"xsu") == 0 && domain->triclinic == 0)
thresh_array[nthresh] = XSU;
else if (strcmp(arg[1],"xsu") == 0 && domain->triclinic == 1)
thresh_array[nthresh] = XSUTRI;
else if (strcmp(arg[1],"ysu") == 0 && domain->triclinic == 0)
thresh_array[nthresh] = YSU;
else if (strcmp(arg[1],"ysu") == 0 && domain->triclinic == 1)
thresh_array[nthresh] = YSUTRI;
else if (strcmp(arg[1],"zsu") == 0 && domain->triclinic == 0)
thresh_array[nthresh] = ZSU;
else if (strcmp(arg[1],"zsu") == 0 && domain->triclinic == 1)
thresh_array[nthresh] = ZSUTRI;
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],"mu") == 0) thresh_array[nthresh] = MU;
else if (strcmp(arg[1],"radius") == 0) thresh_array[nthresh] = RADIUS;
else if (strcmp(arg[1],"diameter") == 0) thresh_array[nthresh] = DIAMETER;
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],"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;
memory->grow(field2index,nfield+nthresh+1,"dump:field2index");
memory->grow(argindex,nfield+nthresh+1,"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(FLERR,"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(FLERR,"Could not find dump modify compute ID");
if (modify->compute[n]->peratom_flag == 0)
error->all(FLERR,
"Dump modify compute ID does not compute per-atom info");
if (argindex[nfield+nthresh] == 0 &&
modify->compute[n]->size_peratom_cols > 0)
error->all(FLERR,
"Dump modify compute ID does not compute per-atom vector");
if (argindex[nfield+nthresh] > 0 &&
modify->compute[n]->size_peratom_cols == 0)
error->all(FLERR,
"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(FLERR,"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;
memory->grow(field2index,nfield+nthresh+1,"dump:field2index");
memory->grow(argindex,nfield+nthresh+1,"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(FLERR,"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(FLERR,"Could not find dump modify fix ID");
if (modify->fix[n]->peratom_flag == 0)
error->all(FLERR,"Dump modify fix ID does not compute per-atom info");
if (argindex[nfield+nthresh] == 0 &&
modify->fix[n]->size_peratom_cols > 0)
error->all(FLERR,"Dump modify fix ID does not compute per-atom vector");
if (argindex[nfield+nthresh] > 0 &&
modify->fix[n]->size_peratom_cols == 0)
error->all(FLERR,"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(FLERR,"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;
memory->grow(field2index,nfield+nthresh+1,"dump:field2index");
memory->grow(argindex,nfield+nthresh+1,"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(FLERR,"Could not find dump modify variable name");
if (input->variable->atomstyle(n) == 0)
error->all(FLERR,"Dump modify variable is not atom-style variable");
field2index[nfield+nthresh] = add_variable(suffix);
delete [] suffix;
} else error->all(FLERR,"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(FLERR,"Invalid dump_modify threshhold operator");
// set threshhold value
thresh_value[nthresh] = atof(arg[3]);
nthresh++;
return 4;
}
return 0;
}
/* ----------------------------------------------------------------------
return # of bytes of allocated memory in buf, choose, variable arrays
------------------------------------------------------------------------- */
bigint DumpCustom::memory_usage()
{
bigint bytes = Dump::memory_usage();
bytes += memory->usage(choose,maxlocal);
bytes += memory->usage(dchoose,maxlocal);
bytes += memory->usage(clist,maxlocal);
bytes += memory->usage(vbuf,nvariable,maxlocal);
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];
if (index == 0) {
for (int i = 0; i < nchoose; i++) {
buf[n] = vector[clist[i]];
n += size_one;
}
} else {
index--;
for (int i = 0; i < nchoose; i++) {
buf[n] = array[clist[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];
if (index == 0) {
for (int i = 0; i < nchoose; i++) {
buf[n] = vector[clist[i]];
n += size_one;
}
} else {
index--;
for (int i = 0; i < nchoose; i++) {
buf[n] = array[clist[i]][index];
n += size_one;
}
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_variable(int n)
{
double *vector = vbuf[field2index[n]];
for (int i = 0; i < nchoose; i++) {
buf[n] = vector[clist[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;
for (int i = 0; i < nchoose; i++) {
buf[n] = tag[clist[i]];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_molecule(int n)
{
int *molecule = atom->molecule;
for (int i = 0; i < nchoose; i++) {
buf[n] = molecule[clist[i]];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_type(int n)
{
int *type = atom->type;
for (int i = 0; i < nchoose; i++) {
buf[n] = type[clist[i]];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_mass(int n)
{
int *type = atom->type;
double *mass = atom->mass;
double *rmass = atom->rmass;
if (rmass) {
for (int i = 0; i < nchoose; i++) {
buf[n] = rmass[clist[i]];
n += size_one;
}
} else {
for (int i = 0; i < nchoose; i++) {
buf[n] = mass[type[clist[i]]];
n += size_one;
}
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_x(int n)
{
double **x = atom->x;
for (int i = 0; i < nchoose; i++) {
buf[n] = x[clist[i]][0];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_y(int n)
{
double **x = atom->x;
for (int i = 0; i < nchoose; i++) {
buf[n] = x[clist[i]][1];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_z(int n)
{
double **x = atom->x;
for (int i = 0; i < nchoose; i++) {
buf[n] = x[clist[i]][2];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_xs(int n)
{
double **x = atom->x;
double boxxlo = domain->boxlo[0];
double invxprd = 1.0/domain->xprd;
for (int i = 0; i < nchoose; i++) {
buf[n] = (x[clist[i]][0] - boxxlo) * invxprd;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_ys(int n)
{
double **x = atom->x;
double boxylo = domain->boxlo[1];
double invyprd = 1.0/domain->yprd;
for (int i = 0; i < nchoose; i++) {
buf[n] = (x[clist[i]][1] - boxylo) * invyprd;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_zs(int n)
{
double **x = atom->x;
double boxzlo = domain->boxlo[2];
double invzprd = 1.0/domain->zprd;
for (int i = 0; i < nchoose; i++) {
buf[n] = (x[clist[i]][2] - boxzlo) * invzprd;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_xs_triclinic(int n)
{
int j;
double **x = atom->x;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
buf[n] = h_inv[0]*(x[j][0]-boxlo[0]) + h_inv[5]*(x[j][1]-boxlo[1]) +
h_inv[4]*(x[j][2]-boxlo[2]);
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_ys_triclinic(int n)
{
int j;
double **x = atom->x;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
buf[n] = h_inv[1]*(x[j][1]-boxlo[1]) + h_inv[3]*(x[j][2]-boxlo[2]);
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_zs_triclinic(int n)
{
double **x = atom->x;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nchoose; i++) {
buf[n] = h_inv[2]*(x[clist[i]][2]-boxlo[2]);
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_xu(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double xprd = domain->xprd;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
- buf[n] = x[j][0] + ((image[j] & 1023) - 512) * xprd;
+ buf[n] = x[j][0] + ((image[j] & IMGMASK) - IMGMAX) * xprd;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_yu(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double yprd = domain->yprd;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
- buf[n] = x[j][1] + ((image[j] >> 10 & 1023) - 512) * yprd;
+ buf[n] = x[j][1] + ((image[j] >> IMGBITS & IMGMASK) - IMGMAX) * yprd;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_zu(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double zprd = domain->zprd;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
- buf[n] = x[j][2] + ((image[j] >> 20) - 512) * zprd;
+ buf[n] = x[j][2] + ((image[j] >> IMG2BITS) - IMGMAX) * zprd;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_xu_triclinic(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double *h = domain->h;
int xbox,ybox,zbox;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
- xbox = (image[j] & 1023) - 512;
- ybox = (image[j] >> 10 & 1023) - 512;
- zbox = (image[j] >> 20) - 512;
+ xbox = (image[j] & IMGMASK) - IMGMAX;
+ ybox = (image[j] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[j] >> IMG2BITS) - IMGMAX;
buf[n] = x[j][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_yu_triclinic(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double *h = domain->h;
int ybox,zbox;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
- ybox = (image[j] >> 10 & 1023) - 512;
- zbox = (image[j] >> 20) - 512;
+ ybox = (image[j] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[j] >> IMG2BITS) - IMGMAX;
buf[n] = x[j][1] + h[1]*ybox + h[3]*zbox;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_zu_triclinic(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double *h = domain->h;
int zbox;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
- zbox = (image[j] >> 20) - 512;
+ zbox = (image[j] >> IMG2BITS) - IMGMAX;
buf[n] = x[j][2] + h[2]*zbox;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_xsu(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double boxxlo = domain->boxlo[0];
double invxprd = 1.0/domain->xprd;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
- buf[n] = (x[j][0] - boxxlo) * invxprd + (image[j] & 1023) - 512;
+ buf[n] = (x[j][0] - boxxlo) * invxprd + (image[j] & IMGMASK) - IMGMAX;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_ysu(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double boxylo = domain->boxlo[1];
double invyprd = 1.0/domain->yprd;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
- buf[n] = (x[j][1] - boxylo) * invyprd + (image[j] >> 10 & 1023) - 512;
+ buf[n] = (x[j][1] - boxylo) * invyprd + (image[j] >> IMGBITS & IMGMASK) - IMGMAX;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_zsu(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double boxzlo = domain->boxlo[2];
double invzprd = 1.0/domain->zprd;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
- buf[n] = (x[j][2] - boxzlo) * invzprd + (image[j] >> 20) - 512;
+ buf[n] = (x[j][2] - boxzlo) * invzprd + (image[j] >> IMG2BITS) - IMGMAX;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_xsu_triclinic(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
buf[n] = h_inv[0]*(x[j][0]-boxlo[0]) + h_inv[5]*(x[j][1]-boxlo[1]) +
- h_inv[4]*(x[j][2]-boxlo[2]) + (image[j] & 1023) - 512;
+ h_inv[4]*(x[j][2]-boxlo[2]) + (image[j] & IMGMASK) - IMGMAX;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_ysu_triclinic(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
buf[n] = h_inv[1]*(x[j][1]-boxlo[1]) + h_inv[3]*(x[j][2]-boxlo[2]) +
- (image[j] >> 10 & 1023) - 512;
+ (image[j] >> IMGBITS & IMGMASK) - IMGMAX;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_zsu_triclinic(int n)
{
int j;
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nchoose; i++) {
j = clist[i];
- buf[n] = h_inv[2]*(x[j][2]-boxlo[2]) + (image[j] >> 20) - 512;
+ buf[n] = h_inv[2]*(x[j][2]-boxlo[2]) + (image[j] >> IMG2BITS) - IMGMAX;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_ix(int n)
{
- int *image = atom->image;
+ tagint *image = atom->image;
for (int i = 0; i < nchoose; i++) {
- buf[n] = (image[clist[i]] & 1023) - 512;
+ buf[n] = (image[clist[i]] & IMGMASK) - IMGMAX;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_iy(int n)
{
- int *image = atom->image;
+ tagint *image = atom->image;
for (int i = 0; i < nchoose; i++) {
- buf[n] = (image[clist[i]] >> 10 & 1023) - 512;
+ buf[n] = (image[clist[i]] >> IMGBITS & IMGMASK) - IMGMAX;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_iz(int n)
{
- int *image = atom->image;
+ tagint *image = atom->image;
for (int i = 0; i < nchoose; i++) {
- buf[n] = (image[clist[i]] >> 20) - 512;
+ buf[n] = (image[clist[i]] >> IMG2BITS) - IMGMAX;
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_vx(int n)
{
double **v = atom->v;
for (int i = 0; i < nchoose; i++) {
buf[n] = v[clist[i]][0];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_vy(int n)
{
double **v = atom->v;
for (int i = 0; i < nchoose; i++) {
buf[n] = v[clist[i]][1];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_vz(int n)
{
double **v = atom->v;
for (int i = 0; i < nchoose; i++) {
buf[n] = v[clist[i]][2];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_fx(int n)
{
double **f = atom->f;
for (int i = 0; i < nchoose; i++) {
buf[n] = f[clist[i]][0];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_fy(int n)
{
double **f = atom->f;
for (int i = 0; i < nchoose; i++) {
buf[n] = f[clist[i]][1];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_fz(int n)
{
double **f = atom->f;
for (int i = 0; i < nchoose; i++) {
buf[n] = f[clist[i]][2];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_q(int n)
{
double *q = atom->q;
for (int i = 0; i < nchoose; i++) {
buf[n] = q[clist[i]];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_mux(int n)
{
double **mu = atom->mu;
for (int i = 0; i < nchoose; i++) {
buf[n] = mu[clist[i]][0];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_muy(int n)
{
double **mu = atom->mu;
for (int i = 0; i < nchoose; i++) {
buf[n] = mu[clist[i]][1];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_muz(int n)
{
double **mu = atom->mu;
for (int i = 0; i < nchoose; i++) {
buf[n] = mu[clist[i]][2];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_mu(int n)
{
double **mu = atom->mu;
for (int i = 0; i < nchoose; i++) {
buf[n] = mu[clist[i]][3];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_radius(int n)
{
double *radius = atom->radius;
for (int i = 0; i < nchoose; i++) {
buf[n] = radius[clist[i]];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_diameter(int n)
{
double *radius = atom->radius;
for (int i = 0; i < nchoose; i++) {
buf[n] = 2.0*radius[clist[i]];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_omegax(int n)
{
double **omega = atom->omega;
for (int i = 0; i < nchoose; i++) {
buf[n] = omega[clist[i]][0];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_omegay(int n)
{
double **omega = atom->omega;
for (int i = 0; i < nchoose; i++) {
buf[n] = omega[clist[i]][1];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_omegaz(int n)
{
double **omega = atom->omega;
for (int i = 0; i < nchoose; i++) {
buf[n] = omega[clist[i]][2];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_angmomx(int n)
{
double **angmom = atom->angmom;
for (int i = 0; i < nchoose; i++) {
buf[n] = angmom[clist[i]][0];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_angmomy(int n)
{
double **angmom = atom->angmom;
for (int i = 0; i < nchoose; i++) {
buf[n] = angmom[clist[i]][1];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_angmomz(int n)
{
double **angmom = atom->angmom;
for (int i = 0; i < nchoose; i++) {
buf[n] = angmom[clist[i]][2];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_tqx(int n)
{
double **torque = atom->torque;
for (int i = 0; i < nchoose; i++) {
buf[n] = torque[clist[i]][0];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_tqy(int n)
{
double **torque = atom->torque;
for (int i = 0; i < nchoose; i++) {
buf[n] = torque[clist[i]][1];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_tqz(int n)
{
double **torque = atom->torque;
for (int i = 0; i < nchoose; i++) {
buf[n] = torque[clist[i]][2];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_spin(int n)
{
int *spin = atom->spin;
for (int i = 0; i < nchoose; i++) {
buf[n] = spin[clist[i]];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_eradius(int n)
{
double *eradius = atom->eradius;
for (int i = 0; i < nchoose; i++) {
buf[n] = eradius[clist[i]];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_ervel(int n)
{
double *ervel = atom->ervel;
for (int i = 0; i < nchoose; i++) {
buf[n] = ervel[clist[i]];
n += size_one;
}
}
/* ---------------------------------------------------------------------- */
void DumpCustom::pack_erforce(int n)
{
double *erforce = atom->erforce;
for (int i = 0; i < nchoose; i++) {
buf[n] = erforce[clist[i]];
n += size_one;
}
}
diff --git a/src/dump_dcd.cpp b/src/dump_dcd.cpp
index a758f1a6e..ca08a1da0 100644
--- a/src/dump_dcd.cpp
+++ b/src/dump_dcd.cpp
@@ -1,355 +1,355 @@
/* ----------------------------------------------------------------------
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 "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(FLERR,"Illegal dump dcd command");
if (binary || compressed || multifile || multiproc)
error->all(FLERR,"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 = group->count(igroup);
if (n > MAXSMALLINT/sizeof(float)) error->all(FLERR,"Too many atoms for dump dcd");
natoms = static_cast<int> (n);
memory->create(coords,3*natoms,"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->destroy(coords);
}
/* ---------------------------------------------------------------------- */
void DumpDCD::init_style()
{
if (sort_flag == 0 || sortcol != 0)
error->all(FLERR,"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(FLERR,"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(FLERR,"Cannot change dump_modify every for dump dcd");
}
/* ---------------------------------------------------------------------- */
void DumpDCD::openfile()
{
if (me == 0) {
fp = fopen(filename,"wb");
if (fp == NULL) error->one(FLERR,"Cannot open dump file");
}
}
/* ---------------------------------------------------------------------- */
void DumpDCD::write_header(bigint n)
{
if (n != natoms) error->all(FLERR,"Dump dcd of non-matching # of atoms");
if (update->ntimestep > MAXSMALLINT)
error->all(FLERR,"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);
}
}
/* ---------------------------------------------------------------------- */
void DumpDCD::pack(int *ids)
{
int m,n;
int *tag = atom->tag;
double **x = atom->x;
- int *image = atom->image;
+ tagint *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;
+ int ix = (image[i] & IMGMASK) - IMGMAX;
+ int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ int iz = (image[i] >> IMG2BITS) - IMGMAX;
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(FLERR,"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(FLERR,"Illegal dump_modify command");
return 2;
}
return 0;
}
/* ----------------------------------------------------------------------
return # of bytes of allocated memory in buf and global coords array
------------------------------------------------------------------------- */
bigint DumpDCD::memory_usage()
{
bigint bytes = Dump::memory_usage();
bytes += memory->usage(coords,natoms*3);
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,ntimestep); // START = timestep of first snapshot
fwrite_int32(fp,nevery_save); // SKIP = interval between snapshots
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 %H:%M",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/fix.cpp b/src/fix.cpp
index 50b30869d..822a2d1fc 100644
--- a/src/fix.cpp
+++ b/src/fix.cpp
@@ -1,180 +1,180 @@
/* ----------------------------------------------------------------------
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 "ctype.h"
#include "fix.h"
#include "atom.h"
#include "group.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
Fix::Fix(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
{
// fix 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(FLERR,"Fix ID must be alphanumeric or underscore characters");
igroup = group->find(arg[1]);
if (igroup == -1) error->all(FLERR,"Could not find fix group ID");
groupbit = group->bitmask[igroup];
n = strlen(arg[2]) + 1;
style = new char[n];
strcpy(style,arg[2]);
restart_global = 0;
restart_peratom = 0;
force_reneighbor = 0;
box_change = 0;
box_change_size = 0;
box_change_shape = 0;
thermo_energy = 0;
rigid_flag = 0;
virial_flag = 0;
no_change_box = 0;
time_integrate = 0;
time_depend = 0;
create_attribute = 0;
restart_pbc = 0;
cudable_comm = 0;
scalar_flag = vector_flag = array_flag = 0;
peratom_flag = local_flag = 0;
comm_forward = comm_reverse = 0;
maxvatom = 0;
vatom = NULL;
}
/* ---------------------------------------------------------------------- */
Fix::~Fix()
{
delete [] id;
delete [] style;
memory->destroy(vatom);
}
/* ----------------------------------------------------------------------
process params common to all fixes here
if unknown param, call modify_param specific to the fix
------------------------------------------------------------------------- */
void Fix::modify_params(int narg, char **arg)
{
if (narg == 0) error->all(FLERR,"Illegal fix_modify command");
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"energy") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix_modify command");
if (strcmp(arg[iarg+1],"no") == 0) thermo_energy = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) thermo_energy = 1;
else error->all(FLERR,"Illegal fix_modify command");
iarg += 2;
} else {
int n = modify_param(narg-iarg,&arg[iarg]);
if (n == 0) error->all(FLERR,"Illegal fix_modify command");
iarg += n;
}
}
}
/* ----------------------------------------------------------------------
setup for virial computation
see integrate::ev_set() for values of vflag (0-6)
------------------------------------------------------------------------- */
void Fix::v_setup(int vflag)
{
int i,n;
evflag = 1;
vflag_global = vflag % 4;
vflag_atom = vflag / 4;
// reallocate per-atom array if necessary
if (vflag_atom && atom->nlocal > maxvatom) {
maxvatom = atom->nmax;
memory->destroy(vatom);
- memory->create(vatom,maxvatom,6,"bond:vatom");
+ memory->create(vatom,maxvatom,6,"fix:vatom");
}
// zero accumulators
if (vflag_global) for (i = 0; i < 6; i++) virial[i] = 0.0;
if (vflag_atom) {
n = atom->nlocal;
for (i = 0; i < n; i++) {
vatom[i][0] = 0.0;
vatom[i][1] = 0.0;
vatom[i][2] = 0.0;
vatom[i][3] = 0.0;
vatom[i][4] = 0.0;
vatom[i][5] = 0.0;
}
}
}
/* ----------------------------------------------------------------------
tally virial into global and per-atom accumulators
v = total virial for the interaction involving total atoms
n = # of local atoms involved, with local indices in list
increment global virial by n/total fraction
increment per-atom virial of each atom in list by 1/total fraction
assumes other procs will tally left-over fractions
------------------------------------------------------------------------- */
void Fix::v_tally(int n, int *list, double total, double *v)
{
int m;
if (vflag_global) {
double fraction = n/total;
virial[0] += fraction*v[0];
virial[1] += fraction*v[1];
virial[2] += fraction*v[2];
virial[3] += fraction*v[3];
virial[4] += fraction*v[4];
virial[5] += fraction*v[5];
}
if (vflag_atom) {
double fraction = 1.0/total;
for (int i = 0; i < n; i++) {
m = list[i];
vatom[m][0] += fraction*v[0];
vatom[m][1] += fraction*v[1];
vatom[m][2] += fraction*v[2];
vatom[m][3] += fraction*v[3];
vatom[m][4] += fraction*v[4];
vatom[m][5] += fraction*v[5];
}
}
}
diff --git a/src/fix_addforce.cpp b/src/fix_addforce.cpp
index cb1e7ca1a..2523c7cc0 100644
--- a/src/fix_addforce.cpp
+++ b/src/fix_addforce.cpp
@@ -1,365 +1,365 @@
/* ----------------------------------------------------------------------
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 "fix_addforce.h"
#include "atom.h"
#include "update.h"
#include "modify.h"
#include "domain.h"
#include "region.h"
#include "respa.h"
#include "input.h"
#include "variable.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
enum{NONE,CONSTANT,EQUAL,ATOM};
/* ---------------------------------------------------------------------- */
FixAddForce::FixAddForce(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 6) error->all(FLERR,"Illegal fix addforce command");
scalar_flag = 1;
vector_flag = 1;
size_vector = 3;
global_freq = 1;
extscalar = 1;
extvector = 1;
xstr = ystr = zstr = NULL;
if (strstr(arg[3],"v_") == arg[3]) {
int n = strlen(&arg[3][2]) + 1;
xstr = new char[n];
strcpy(xstr,&arg[3][2]);
} else {
xvalue = atof(arg[3]);
xstyle = CONSTANT;
}
if (strstr(arg[4],"v_") == arg[4]) {
int n = strlen(&arg[4][2]) + 1;
ystr = new char[n];
strcpy(ystr,&arg[4][2]);
} else {
yvalue = atof(arg[4]);
ystyle = CONSTANT;
}
if (strstr(arg[5],"v_") == arg[5]) {
int n = strlen(&arg[5][2]) + 1;
zstr = new char[n];
strcpy(zstr,&arg[5][2]);
} else {
zvalue = atof(arg[5]);
zstyle = CONSTANT;
}
// optional args
iregion = -1;
idregion = NULL;
estr = NULL;
int iarg = 6;
while (iarg < narg) {
if (strcmp(arg[iarg],"region") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix addforce command");
iregion = domain->find_region(arg[iarg+1]);
if (iregion == -1)
error->all(FLERR,"Region ID for fix addforce 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],"energy") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix addforce command");
if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) {
int n = strlen(&arg[iarg+1][2]) + 1;
estr = new char[n];
strcpy(estr,&arg[iarg+1][2]);
} else error->all(FLERR,"Illegal fix addforce command");
iarg += 2;
} else error->all(FLERR,"Illegal fix addforce command");
}
force_flag = 0;
foriginal[0] = foriginal[1] = foriginal[2] = foriginal[3] = 0.0;
maxatom = 0;
sforce = NULL;
}
/* ---------------------------------------------------------------------- */
FixAddForce::~FixAddForce()
{
delete [] xstr;
delete [] ystr;
delete [] zstr;
delete [] estr;
delete [] idregion;
memory->destroy(sforce);
}
/* ---------------------------------------------------------------------- */
int FixAddForce::setmask()
{
int mask = 0;
mask |= POST_FORCE;
mask |= THERMO_ENERGY;
mask |= POST_FORCE_RESPA;
mask |= MIN_POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixAddForce::init()
{
// check variables
if (xstr) {
xvar = input->variable->find(xstr);
if (xvar < 0)
error->all(FLERR,"Variable name for fix addforce does not exist");
if (input->variable->equalstyle(xvar)) xstyle = EQUAL;
else if (input->variable->atomstyle(xvar)) xstyle = ATOM;
else error->all(FLERR,"Variable for fix addforce is invalid style");
}
if (ystr) {
yvar = input->variable->find(ystr);
if (yvar < 0)
error->all(FLERR,"Variable name for fix addforce does not exist");
if (input->variable->equalstyle(yvar)) ystyle = EQUAL;
else if (input->variable->atomstyle(yvar)) ystyle = ATOM;
else error->all(FLERR,"Variable for fix addforce is invalid style");
}
if (zstr) {
zvar = input->variable->find(zstr);
if (zvar < 0)
error->all(FLERR,"Variable name for fix addforce does not exist");
if (input->variable->equalstyle(zvar)) zstyle = EQUAL;
else if (input->variable->atomstyle(zvar)) zstyle = ATOM;
else error->all(FLERR,"Variable for fix addforce is invalid style");
}
if (estr) {
evar = input->variable->find(estr);
if (evar < 0)
error->all(FLERR,"Variable name for fix addforce does not exist");
if (input->variable->atomstyle(evar)) estyle = ATOM;
else error->all(FLERR,"Variable for fix addforce is invalid style");
} else estyle = NONE;
// set index and check validity of region
if (iregion >= 0) {
iregion = domain->find_region(idregion);
if (iregion == -1)
error->all(FLERR,"Region ID for fix addforce does not exist");
}
if (xstyle == ATOM || ystyle == ATOM || zstyle == ATOM)
varflag = ATOM;
else if (xstyle == EQUAL || ystyle == EQUAL || zstyle == EQUAL)
varflag = EQUAL;
else varflag = CONSTANT;
if (varflag == CONSTANT && estyle != NONE)
error->all(FLERR,"Cannot use variable energy with "
"constant force in fix addforce");
if ((varflag == EQUAL || varflag == ATOM) &&
update->whichflag == 2 && estyle == NONE)
error->all(FLERR,"Must use variable energy with fix addforce");
if (strstr(update->integrate_style,"respa"))
nlevels_respa = ((Respa *) update->integrate)->nlevels;
}
/* ---------------------------------------------------------------------- */
void FixAddForce::setup(int vflag)
{
if (strstr(update->integrate_style,"verlet"))
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 FixAddForce::min_setup(int vflag)
{
post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixAddForce::post_force(int vflag)
{
int xbox,ybox,zbox;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
double **x = atom->x;
double **f = atom->f;
int *mask = atom->mask;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
// reallocate sforce array if necessary
if ((varflag == ATOM || estyle == ATOM) && nlocal > maxatom) {
maxatom = atom->nmax;
memory->destroy(sforce);
memory->create(sforce,maxatom,4,"addforce:sforce");
}
// foriginal[0] = "potential energy" for added force
// foriginal[123] = force on atoms before extra force added
foriginal[0] = foriginal[1] = foriginal[2] = foriginal[3] = 0.0;
force_flag = 0;
// constant force
// potential energy = - x dot f in unwrapped coords
if (varflag == CONSTANT) {
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (iregion >= 0 &&
!domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
continue;
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
foriginal[0] -= xvalue * (x[i][0]+xbox*xprd) +
yvalue * (x[i][1]+ybox*yprd) + zvalue * (x[i][2]+zbox*zprd);
foriginal[1] += f[i][0];
foriginal[2] += f[i][1];
foriginal[3] += f[i][2];
f[i][0] += xvalue;
f[i][1] += yvalue;
f[i][2] += zvalue;
}
// variable force, wrap with clear/add
// potential energy = evar if defined, else 0.0
// wrap with clear/add
} else {
modify->clearstep_compute();
if (xstyle == EQUAL) xvalue = input->variable->compute_equal(xvar);
else if (xstyle == ATOM && sforce)
input->variable->compute_atom(xvar,igroup,&sforce[0][0],4,0);
if (ystyle == EQUAL) yvalue = input->variable->compute_equal(yvar);
else if (ystyle == ATOM && sforce)
input->variable->compute_atom(yvar,igroup,&sforce[0][1],4,0);
if (zstyle == EQUAL) zvalue = input->variable->compute_equal(zvar);
else if (zstyle == ATOM && sforce)
input->variable->compute_atom(zvar,igroup,&sforce[0][2],4,0);
if (estyle == ATOM && sforce)
input->variable->compute_atom(evar,igroup,&sforce[0][3],4,0);
modify->addstep_compute(update->ntimestep + 1);
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (iregion >= 0 &&
!domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
continue;
if (estyle == ATOM) foriginal[0] += sforce[i][3];
foriginal[1] += f[i][0];
foriginal[2] += f[i][1];
foriginal[3] += f[i][2];
if (xstyle == ATOM) f[i][0] += sforce[i][0];
else if (xstyle) f[i][0] += xvalue;
if (ystyle == ATOM) f[i][1] += sforce[i][1];
else if (ystyle) f[i][1] += yvalue;
if (zstyle == ATOM) f[i][2] += sforce[i][2];
else if (zstyle) f[i][2] += zvalue;
}
}
}
/* ---------------------------------------------------------------------- */
void FixAddForce::post_force_respa(int vflag, int ilevel, int iloop)
{
if (ilevel == nlevels_respa-1) post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixAddForce::min_post_force(int vflag)
{
post_force(vflag);
}
/* ----------------------------------------------------------------------
potential energy of added force
------------------------------------------------------------------------- */
double FixAddForce::compute_scalar()
{
// only sum across procs one time
if (force_flag == 0) {
MPI_Allreduce(foriginal,foriginal_all,4,MPI_DOUBLE,MPI_SUM,world);
force_flag = 1;
}
return foriginal_all[0];
}
/* ----------------------------------------------------------------------
return components of total force on fix group before force was changed
------------------------------------------------------------------------- */
double FixAddForce::compute_vector(int n)
{
// only sum across procs one time
if (force_flag == 0) {
MPI_Allreduce(foriginal,foriginal_all,4,MPI_DOUBLE,MPI_SUM,world);
force_flag = 1;
}
return foriginal_all[n+1];
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double FixAddForce::memory_usage()
{
double bytes = 0.0;
if (varflag == ATOM) bytes = atom->nmax*4 * sizeof(double);
return bytes;
}
diff --git a/src/fix_ave_atom.h b/src/fix_ave_atom.h
index 6765ec0a8..436c36173 100644
--- a/src/fix_ave_atom.h
+++ b/src/fix_ave_atom.h
@@ -1,121 +1,126 @@
/* -*- c++ -*- ----------------------------------------------------------
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"
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 *);
void reset_timestep(bigint);
private:
int nvalues;
int nrepeat,irepeat;
bigint nvalid;
int *which,*argindex,*value2index;
char **ids;
double **array;
bigint nextvalid();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Compute ID for fix ave/atom does not exist
Self-explanatory.
E: Fix ave/atom compute does not calculate per-atom values
A compute used by fix ave/atom must generate per-atom values.
E: Fix ave/atom compute does not calculate a per-atom vector
A compute used by fix ave/atom must generate per-atom values.
E: Fix ave/atom compute does not calculate a per-atom array
Self-explanatory.
E: Fix ave/atom compute array is accessed out-of-range
Self-explanatory.
E: Fix ID for fix ave/atom does not exist
Self-explanatory.
E: Fix ave/atom fix does not calculate per-atom values
A fix used by fix ave/atom must generate per-atom values.
E: Fix ave/atom fix does not calculate a per-atom vector
A fix used by fix ave/atom must generate per-atom values.
E: Fix ave/atom fix does not calculate a per-atom array
Self-explanatory.
E: Fix ave/atom fix array is accessed out-of-range
Self-explanatory.
E: Fix for fix ave/atom not computed at compatible time
Fixes generate their values on specific timesteps. Fix ave/atom is
requesting a value on a non-allowed timestep.
E: Variable name for fix ave/atom does not exist
Self-explanatory.
E: Fix ave/atom variable is not atom-style variable
A variable used by fix ave/atom must generate per-atom values.
+E: Fix ave/atom missed timestep
+
+You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging.
+
*/
diff --git a/src/fix_ave_correlate.h b/src/fix_ave_correlate.h
index ee6a6f4c5..8a76674d8 100644
--- a/src/fix_ave_correlate.h
+++ b/src/fix_ave_correlate.h
@@ -1,130 +1,135 @@
/* -*- c++ -*- ----------------------------------------------------------
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"
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);
void reset_timestep(bigint);
private:
int me,nvalues;
int nrepeat,nfreq;
bigint nvalid;
int *which,*argindex,*value2index;
char **ids;
FILE *fp;
int type,ave,startstep,overwrite;
double prefactor;
char *title1,*title2,*title3;
long filepos;
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();
bigint nextvalid();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Cannot open fix ave/correlate file %s
The specified file cannot be opened. Check that the path and name are
correct.
E: Compute ID for fix ave/correlate does not exist
Self-explanatory.
E: Fix ave/correlate compute does not calculate a scalar
Self-explanatory.
E: Fix ave/correlate compute does not calculate a vector
Self-explanatory.
E: Fix ave/correlate compute vector is accessed out-of-range
The index for the vector is out of bounds.
E: Fix ID for fix ave/correlate does not exist
Self-explanatory.
E: Fix ave/correlate fix does not calculate a scalar
Self-explanatory.
E: Fix ave/correlate fix does not calculate a vector
Self-explanatory.
E: Fix ave/correlate fix vector is accessed out-of-range
The index for the vector is out of bounds.
E: Fix for fix ave/correlate not computed at compatible time
Fixes generate their values on specific timesteps. Fix ave/correlate
is requesting a value on a non-allowed timestep.
E: Variable name for fix ave/correlate does not exist
Self-explanatory.
E: Fix ave/correlate variable is not equal-style variable
Self-explanatory.
+E: Fix ave/correlate missed timestep
+
+You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging.
+
*/
diff --git a/src/fix_ave_histo.h b/src/fix_ave_histo.h
index 467c5c60c..87eb21d0f 100644
--- a/src/fix_ave_histo.h
+++ b/src/fix_ave_histo.h
@@ -1,222 +1,227 @@
/* -*- c++ -*- ----------------------------------------------------------
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"
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);
void reset_timestep(bigint);
private:
int me,nvalues;
int nrepeat,nfreq,irepeat;
bigint nvalid;
int *which,*argindex,*value2index;
char **ids;
FILE *fp;
double lo,hi,binsize,bininv;
int kind,beyond,overwrite;
long filepos;
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);
bigint nextvalid();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Compute ID for fix ave/histo does not exist
Self-explanatory.
E: Fix ID for fix ave/histo does not exist
Self-explanatory.
E: Fix ave/histo input is invalid compute
Self-explanatory.
E: Fix ave/histo input is invalid fix
Self-explanatory.
E: Fix ave/histo input is invalid variable
Self-explanatory.
E: Fix ave/histo inputs are not all global, peratom, or local
All inputs in a single fix ave/histo command must be of the
same style.
E: Fix ave/histo cannot input per-atom values in scalar mode
Self-explanatory.
E: Fix ave/histo cannot input local values in scalar mode
Self-explanatory.
E: Fix ave/histo compute does not calculate a global scalar
Self-explanatory.
E: Fix ave/histo compute does not calculate a global vector
Self-explanatory.
E: Fix ave/histo compute vector is accessed out-of-range
Self-explanatory.
E: Fix ave/histo compute does not calculate a global array
Self-explanatory.
E: Fix ave/histo compute array is accessed out-of-range
Self-explanatory.
E: Fix ave/histo compute does not calculate per-atom values
Self-explanatory.
E: Fix ave/histo compute does not calculate a per-atom vector
Self-explanatory.
E: Fix ave/histo compute does not calculate a per-atom array
Self-explanatory.
E: Fix ave/histo compute does not calculate local values
Self-explanatory.
E: Fix ave/histo compute does not calculate a local vector
Self-explanatory.
E: Fix ave/histo compute does not calculate a local array
Self-explanatory.
E: Fix ave/histo fix does not calculate a global scalar
Self-explanatory.
E: Fix ave/histo fix does not calculate a global vector
Self-explanatory.
E: Fix ave/histo fix vector is accessed out-of-range
Self-explanatory.
E: Fix for fix ave/histo not computed at compatible time
Fixes generate their values on specific timesteps. Fix ave/histo is
requesting a value on a non-allowed timestep.
E: Fix ave/histo fix does not calculate a global array
Self-explanatory.
E: Fix ave/histo fix array is accessed out-of-range
Self-explanatory.
E: Fix ave/histo fix does not calculate per-atom values
Self-explanatory.
E: Fix ave/histo fix does not calculate a per-atom vector
Self-explanatory.
E: Fix ave/histo fix does not calculate a per-atom array
Self-explanatory.
E: Fix ave/histo fix does not calculate local values
Self-explanatory.
E: Fix ave/histo fix does not calculate a local vector
Self-explanatory.
E: Fix ave/histo fix does not calculate a local array
Self-explanatory.
E: Variable name for fix ave/histo does not exist
Self-explanatory.
E: Cannot open fix ave/histo file %s
The specified file cannot be opened. Check that the path and name are
correct.
+E: Fix ave/histo missed timestep
+
+You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging.
+
*/
diff --git a/src/fix_ave_spatial.h b/src/fix_ave_spatial.h
index d560fba6a..f0a97f1b5 100644
--- a/src/fix_ave_spatial.h
+++ b/src/fix_ave_spatial.h
@@ -1,178 +1,183 @@
/* -*- c++ -*- ----------------------------------------------------------
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"
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();
void reset_timestep(bigint);
private:
int me,nvalues;
int nrepeat,nfreq,irepeat;
bigint nvalid;
int ndim,normflag,regionflag,iregion,overwrite;
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;
long filepos;
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();
bigint nextvalid();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Cannot use fix ave/spatial z for 2 dimensional model
Self-explanatory.
E: Same dimension twice in fix ave/spatial
Self-explanatory.
E: Region ID for fix ave/spatial does not exist
Self-explanatory.
E: Cannot open fix ave/spatial file %s
The specified file cannot be opened. Check that the path and name are
correct.
E: Compute ID for fix ave/spatial does not exist
Self-explanatory.
E: Fix ave/spatial compute does not calculate per-atom values
A compute used by fix ave/spatial must generate per-atom values.
E: Fix ave/spatial compute does not calculate a per-atom vector
A compute used by fix ave/spatial must generate per-atom values.
E: Fix ave/spatial compute does not calculate a per-atom array
Self-explanatory.
E: Fix ave/spatial compute vector is accessed out-of-range
The index for the vector is out of bounds.
E: Fix ID for fix ave/spatial does not exist
Self-explanatory.
E: Fix ave/spatial fix does not calculate per-atom values
A fix used by fix ave/spatial must generate per-atom values.
E: Fix ave/spatial fix does not calculate a per-atom vector
A fix used by fix ave/spatial must generate per-atom values.
E: Fix ave/spatial fix does not calculate a per-atom array
Self-explanatory.
E: Fix ave/spatial fix vector is accessed out-of-range
The index for the vector is out of bounds.
E: Variable name for fix ave/spatial does not exist
Self-explanatory.
E: Fix ave/spatial variable is not atom-style variable
A variable used by fix ave/spatial must generate per-atom values.
E: Fix ave/spatial for triclinic boxes requires units reduced
Self-explanatory.
E: Use of fix ave/spatial with undefined lattice
A lattice must be defined to use fix ave/spatial with units = lattice.
E: Fix ave/spatial settings invalid with changing box
If the ave setting is "running" or "window" and the box size/shape
changes during the simulation, then the units setting must be
"reduced", else the number of bins may change.
E: Fix for fix ave/spatial not computed at compatible time
Fixes generate their values on specific timesteps. Fix ave/spatial is
requesting a value on a non-allowed timestep.
+E: Fix ave/spatial missed timestep
+
+You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging.
+
*/
diff --git a/src/fix_ave_time.h b/src/fix_ave_time.h
index 6e1a8fe61..97bda2371 100644
--- a/src/fix_ave_time.h
+++ b/src/fix_ave_time.h
@@ -1,169 +1,174 @@
/* -*- c++ -*- ----------------------------------------------------------
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"
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);
void reset_timestep(bigint);
private:
int me,nvalues;
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,overwrite;
int *offlist;
char *title1,*title2,*title3;
long filepos;
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(bigint);
void invoke_vector(bigint);
void options(int, char **);
void allocate_values(int);
bigint nextvalid();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Compute ID for fix ave/time does not exist
Self-explanatory.
E: Fix ID for fix ave/time does not exist
Self-explanatory.
E: Invalid fix ave/time off column
Self-explantory.
E: Fix ave/time compute does not calculate a scalar
Self-explantory.
E: Fix ave/time compute does not calculate a vector
Self-explantory.
E: Fix ave/time compute vector is accessed out-of-range
The index for the vector is out of bounds.
E: Fix ave/time compute does not calculate an array
Self-explanatory.
E: Fix ave/time compute array is accessed out-of-range
An index for the array is out of bounds.
E: Fix ave/time fix does not calculate a scalar
Self-explanatory.
E: Fix ave/time fix does not calculate a vector
Self-explanatory.
E: Fix ave/time fix vector is accessed out-of-range
The index for the vector is out of bounds.
E: Fix for fix ave/time not computed at compatible time
Fixes generate their values on specific timesteps. Fix ave/time
is requesting a value on a non-allowed timestep.
E: Fix ave/time fix does not calculate an array
Self-explanatory.
E: Fix ave/time fix array is accessed out-of-range
An index for the array is out of bounds.
E: Variable name for fix ave/time does not exist
Self-explanatory.
E: Fix ave/time variable is not equal-style variable
Self-explanatory.
E: Fix ave/time cannot use variable with vector mode
Variables produce scalar values.
E: Fix ave/time columns are inconsistent lengths
Self-explanatory.
E: Fix ave/time cannot set output array intensive/extensive from these inputs
One of more of the vector inputs has individual elements which are
flagged as intensive or extensive. Such an input cannot be flagged as
all intensive/extensive when turned into an array by fix ave/time.
E: Cannot open fix ave/time file %s
The specified file cannot be opened. Check that the path and name are
correct.
+E: Fix ave/time missed timestep
+
+You cannot reset the timestep to a value beyond where the fix
+expects to next perform averaging.
+
*/
diff --git a/src/fix_aveforce.cpp b/src/fix_aveforce.cpp
index 7fa07b299..eef2d95f3 100644
--- a/src/fix_aveforce.cpp
+++ b/src/fix_aveforce.cpp
@@ -1,312 +1,316 @@
/* ----------------------------------------------------------------------
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 "fix_aveforce.h"
#include "atom.h"
#include "update.h"
#include "modify.h"
#include "domain.h"
#include "region.h"
#include "respa.h"
#include "input.h"
#include "variable.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
enum{NONE,CONSTANT,EQUAL};
/* ---------------------------------------------------------------------- */
FixAveForce::FixAveForce(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 6) error->all(FLERR,"Illegal fix aveforce command");
vector_flag = 1;
size_vector = 3;
global_freq = 1;
extvector = 1;
xstr = ystr = zstr = NULL;
if (strstr(arg[3],"v_") == arg[3]) {
int n = strlen(&arg[3][2]) + 1;
xstr = new char[n];
strcpy(xstr,&arg[3][2]);
} else if (strcmp(arg[3],"NULL") == 0) {
xstyle = NONE;
} else {
xvalue = atof(arg[3]);
xstyle = CONSTANT;
}
if (strstr(arg[4],"v_") == arg[4]) {
int n = strlen(&arg[4][2]) + 1;
ystr = new char[n];
strcpy(ystr,&arg[4][2]);
} else if (strcmp(arg[4],"NULL") == 0) {
ystyle = NONE;
} else {
yvalue = atof(arg[4]);
ystyle = CONSTANT;
}
if (strstr(arg[5],"v_") == arg[5]) {
int n = strlen(&arg[5][2]) + 1;
zstr = new char[n];
strcpy(zstr,&arg[5][2]);
} else if (strcmp(arg[5],"NULL") == 0) {
zstyle = NONE;
} else {
zvalue = atof(arg[5]);
zstyle = CONSTANT;
}
// optional args
iregion = -1;
idregion = NULL;
int iarg = 6;
while (iarg < narg) {
if (strcmp(arg[iarg],"region") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix aveforce command");
iregion = domain->find_region(arg[iarg+1]);
if (iregion == -1)
error->all(FLERR,"Region ID for fix aveforce does not exist");
int n = strlen(arg[iarg+1]) + 1;
idregion = new char[n];
strcpy(idregion,arg[iarg+1]);
iarg += 2;
} else error->all(FLERR,"Illegal fix aveforce command");
}
foriginal_all[0] = foriginal_all[1] =
foriginal_all[2] = foriginal_all[3] = 0.0;
}
/* ---------------------------------------------------------------------- */
FixAveForce::~FixAveForce()
{
delete [] xstr;
delete [] ystr;
delete [] zstr;
delete [] idregion;
}
/* ---------------------------------------------------------------------- */
int FixAveForce::setmask()
{
int mask = 0;
mask |= POST_FORCE;
mask |= POST_FORCE_RESPA;
mask |= MIN_POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixAveForce::init()
{
// check variables
if (xstr) {
xvar = input->variable->find(xstr);
- if (xvar < 0) error->all(FLERR,"Variable name for fix aveforce does not exist");
+ if (xvar < 0)
+ error->all(FLERR,"Variable name for fix aveforce does not exist");
if (input->variable->equalstyle(xvar)) xstyle = EQUAL;
else error->all(FLERR,"Variable for fix aveforce is invalid style");
}
if (ystr) {
yvar = input->variable->find(ystr);
- if (yvar < 0) error->all(FLERR,"Variable name for fix aveforce does not exist");
+ if (yvar < 0)
+ error->all(FLERR,"Variable name for fix aveforce does not exist");
if (input->variable->equalstyle(yvar)) ystyle = EQUAL;
else error->all(FLERR,"Variable for fix aveforce is invalid style");
}
if (zstr) {
zvar = input->variable->find(zstr);
- if (zvar < 0) error->all(FLERR,"Variable name for fix aveforce does not exist");
+ if (zvar < 0)
+ error->all(FLERR,"Variable name for fix aveforce does not exist");
if (input->variable->equalstyle(zvar)) zstyle = EQUAL;
else error->all(FLERR,"Variable for fix aveforce is invalid style");
}
// set index and check validity of region
if (iregion >= 0) {
iregion = domain->find_region(idregion);
- if (iregion == -1) error->all(FLERR,"Region ID for fix aveforce does not exist");
+ if (iregion == -1)
+ error->all(FLERR,"Region ID for fix aveforce does not exist");
}
if (xstyle == EQUAL || ystyle == EQUAL || zstyle == EQUAL) varflag = EQUAL;
else varflag = CONSTANT;
if (strstr(update->integrate_style,"respa"))
nlevels_respa = ((Respa *) update->integrate)->nlevels;
}
/* ---------------------------------------------------------------------- */
void FixAveForce::setup(int vflag)
{
if (strstr(update->integrate_style,"verlet"))
post_force(vflag);
else
for (int ilevel = 0; ilevel < nlevels_respa; ilevel++) {
((Respa *) update->integrate)->copy_flevel_f(ilevel);
post_force_respa(vflag,ilevel,0);
((Respa *) update->integrate)->copy_f_flevel(ilevel);
}
}
/* ---------------------------------------------------------------------- */
void FixAveForce::min_setup(int vflag)
{
post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixAveForce::post_force(int vflag)
{
// sum forces on participating atoms
double **x = atom->x;
double **f = atom->f;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double foriginal[4];
foriginal[0] = foriginal[1] = foriginal[2] = foriginal[3] = 0.0;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (iregion >= 0 &&
!domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
continue;
foriginal[0] += f[i][0];
foriginal[1] += f[i][1];
foriginal[2] += f[i][2];
foriginal[3] += 1.0;
}
// average the force on participating atoms
// add in requested amount, computed via variable evaluation if necessary
// wrap variable evaluation with clear/add
MPI_Allreduce(foriginal,foriginal_all,4,MPI_DOUBLE,MPI_SUM,world);
int ncount = static_cast<int> (foriginal_all[3]);
if (ncount == 0) return;
if (varflag == EQUAL) {
modify->clearstep_compute();
if (xstyle == EQUAL) xvalue = input->variable->compute_equal(xvar);
if (ystyle == EQUAL) yvalue = input->variable->compute_equal(yvar);
if (zstyle == EQUAL) zvalue = input->variable->compute_equal(zvar);
modify->addstep_compute(update->ntimestep + 1);
}
double fave[3];
fave[0] = foriginal_all[0]/ncount + xvalue;
fave[1] = foriginal_all[1]/ncount + yvalue;
fave[2] = foriginal_all[2]/ncount + zvalue;
// set force of all participating atoms to same value
// only for active dimensions
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (iregion >= 0 &&
!domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
continue;
if (xstyle) f[i][0] = fave[0];
if (ystyle) f[i][1] = fave[1];
if (zstyle) f[i][2] = fave[2];
}
}
/* ---------------------------------------------------------------------- */
void FixAveForce::post_force_respa(int vflag, int ilevel, int iloop)
{
// ave + extra force on outermost level
// just ave on inner levels
if (ilevel == nlevels_respa-1) post_force(vflag);
else {
double **x = atom->x;
double **f = atom->f;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double foriginal[4];
foriginal[0] = foriginal[1] = foriginal[2] = foriginal[3] = 0.0;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (iregion >= 0 &&
!domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
continue;
foriginal[0] += f[i][0];
foriginal[1] += f[i][1];
foriginal[2] += f[i][2];
foriginal[3] += 1.0;
}
MPI_Allreduce(foriginal,foriginal_all,4,MPI_DOUBLE,MPI_SUM,world);
int ncount = static_cast<int> (foriginal_all[3]);
if (ncount == 0) return;
double fave[3];
fave[0] = foriginal_all[0]/ncount;
fave[1] = foriginal_all[1]/ncount;
fave[2] = foriginal_all[2]/ncount;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (iregion >= 0 &&
!domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
continue;
if (xstyle) f[i][0] = fave[0];
if (ystyle) f[i][1] = fave[1];
if (zstyle) f[i][2] = fave[2];
}
}
}
/* ---------------------------------------------------------------------- */
void FixAveForce::min_post_force(int vflag)
{
post_force(vflag);
}
/* ----------------------------------------------------------------------
return components of total force on fix group before force was changed
------------------------------------------------------------------------- */
double FixAveForce::compute_vector(int n)
{
return foriginal_all[n];
}
diff --git a/src/fix_balance.h b/src/fix_balance.h
index 61cd88cf7..a236328d7 100644
--- a/src/fix_balance.h
+++ b/src/fix_balance.h
@@ -1,83 +1,91 @@
/* ----------------------------------------------------------------------
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(balance,FixBalance)
#else
#ifndef LMP_FIX_BALANCE_H
#define LMP_FIX_BALANCE_H
#include "stdio.h"
#include "fix.h"
namespace LAMMPS_NS {
class FixBalance : public Fix {
public:
FixBalance(class LAMMPS *, int, char **);
~FixBalance();
int setmask();
void init();
void setup(int);
void setup_pre_exchange();
void pre_exchange();
void pre_neighbor();
double compute_scalar();
double compute_vector(int);
double memory_usage();
private:
int nevery,nitermax;
char bstr[3];
double thresh;
FILE *fp;
double imbnow; // current imbalance factor
double imbprev; // imbalance factor before last rebalancing
double imbfinal; // imbalance factor after last rebalancing
int maxperproc; // max atoms on any processor
int itercount; // iteration count of last call to Balance
int kspace_flag; // 1 if KSpace solver defined
int pending;
class Balance *balance;
class Irregular *irregular;
void rebalance();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Fix balance string is invalid
The string can only contain the characters "x", "y", or "z".
E: Fix balance string is invalid for 2d simulation
The string cannot contain the letter "z".
+E: Cannot open fix balance output file
+
+Self-explanatory.
+
+E: Cannot yet use fix balance with PPPM
+
+This is a current limitation of LAMMPS.
+
*/
diff --git a/src/fix_deform.cpp b/src/fix_deform.cpp
index 56a24723d..d972d0057 100644
--- a/src/fix_deform.cpp
+++ b/src/fix_deform.cpp
@@ -1,981 +1,981 @@
/* ----------------------------------------------------------------------
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 "string.h"
#include "stdlib.h"
#include "math.h"
#include "fix_deform.h"
#include "atom.h"
#include "update.h"
#include "comm.h"
#include "irregular.h"
#include "domain.h"
#include "lattice.h"
#include "force.h"
#include "modify.h"
#include "math_const.h"
#include "kspace.h"
#include "input.h"
#include "variable.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
using namespace MathConst;
enum{NONE,FINAL,DELTA,SCALE,VEL,ERATE,TRATE,VOLUME,WIGGLE,VARIABLE};
enum{ONE_FROM_ONE,ONE_FROM_TWO,TWO_FROM_ONE};
// same as domain.cpp, fix_nvt_sllod.cpp, compute_temp_deform.cpp
enum{NO_REMAP,X_REMAP,V_REMAP};
/* ---------------------------------------------------------------------- */
FixDeform::FixDeform(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
{
if (narg < 4) error->all(FLERR,"Illegal fix deform command");
box_change = 1;
no_change_box = 1;
nevery = atoi(arg[3]);
if (nevery <= 0) error->all(FLERR,"Illegal fix deform command");
// 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;
set[0].hstr = set[1].hstr = set[2].hstr =
set[3].hstr = set[4].hstr = set[5].hstr = NULL;
set[0].hratestr = set[1].hratestr = set[2].hratestr =
set[3].hratestr = set[4].hratestr = set[5].hratestr = NULL;
// parse arguments
triclinic = domain->triclinic;
int index;
int iarg = 4;
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(FLERR,"Illegal fix deform command");
if (strcmp(arg[iarg+1],"final") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix deform 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(FLERR,"Illegal fix deform 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(FLERR,"Illegal fix deform command");
set[index].style = SCALE;
set[index].scale = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"vel") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command");
set[index].style = VEL;
set[index].vel = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"erate") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command");
set[index].style = ERATE;
set[index].rate = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"trate") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command");
set[index].style = TRATE;
set[index].rate = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"volume") == 0) {
set[index].style = VOLUME;
iarg += 2;
} else if (strcmp(arg[iarg+1],"wiggle") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix deform command");
set[index].style = WIGGLE;
set[index].amplitude = atof(arg[iarg+2]);
set[index].tperiod = atof(arg[iarg+3]);
if (set[index].tperiod <= 0.0)
error->all(FLERR,"Illegal fix deform command");
iarg += 4;
} else if (strcmp(arg[iarg+1],"variable") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix deform command");
set[index].style = VARIABLE;
if (strstr(arg[iarg+2],"v_") != arg[iarg+2])
error->all(FLERR,"Illegal fix deform command");
if (strstr(arg[iarg+3],"v_") != arg[iarg+3])
error->all(FLERR,"Illegal fix deform command");
delete [] set[index].hstr;
delete [] set[index].hratestr;
int n = strlen(&arg[iarg+2][2]) + 1;
set[index].hstr = new char[n];
strcpy(set[index].hstr,&arg[iarg+2][2]);
n = strlen(&arg[iarg+3][2]) + 1;
set[index].hratestr = new char[n];
strcpy(set[index].hratestr,&arg[iarg+3][2]);
iarg += 4;
} else error->all(FLERR,"Illegal fix deform command");
} else if (strcmp(arg[iarg],"xy") == 0 ||
strcmp(arg[iarg],"xz") == 0 ||
strcmp(arg[iarg],"yz") == 0) {
if (triclinic == 0)
error->all(FLERR,"Fix deform 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(FLERR,"Illegal fix deform command");
if (strcmp(arg[iarg+1],"final") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform 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(FLERR,"Illegal fix deform command");
set[index].style = DELTA;
set[index].dtilt = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"vel") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command");
set[index].style = VEL;
set[index].vel = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"erate") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command");
set[index].style = ERATE;
set[index].rate = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"trate") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal fix deform command");
set[index].style = TRATE;
set[index].rate = atof(arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg+1],"wiggle") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix deform command");
set[index].style = WIGGLE;
set[index].amplitude = atof(arg[iarg+2]);
set[index].tperiod = atof(arg[iarg+3]);
if (set[index].tperiod <= 0.0)
error->all(FLERR,"Illegal fix deform command");
iarg += 4;
} else if (strcmp(arg[iarg+1],"variable") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix deform command");
set[index].style = VARIABLE;
if (strstr(arg[iarg+2],"v_") != arg[iarg+2])
error->all(FLERR,"Illegal fix deform command");
if (strstr(arg[iarg+3],"v_") != arg[iarg+3])
error->all(FLERR,"Illegal fix deform command");
delete [] set[index].hstr;
delete [] set[index].hratestr;
int n = strlen(&arg[iarg+2][2]) + 1;
set[index].hstr = new char[n];
strcpy(set[index].hstr,&arg[iarg+2][2]);
n = strlen(&arg[iarg+3][2]) + 1;
set[index].hratestr = new char[n];
strcpy(set[index].hratestr,&arg[iarg+3][2]);
iarg += 4;
} else error->all(FLERR,"Illegal fix deform command");
} else break;
}
// read options from end of input line
// no x remap effectively moves atoms within box, so set restart_pbc
options(narg-iarg,&arg[iarg]);
if (remapflag != X_REMAP) restart_pbc = 1;
// setup dimflags used by other classes to check for volume-change conflicts
for (int i = 0; i < 6; i++)
if (set[i].style == NONE) dimflag[i] = 0;
else dimflag[i] = 1;
if (dimflag[0] || dimflag[1] || dimflag[2]) box_change_size = 1;
if (dimflag[3] || dimflag[4] || dimflag[5]) box_change_shape = 1;
// no tensile deformation on shrink-wrapped dims
// b/c shrink wrap will change box-length
if (set[0].style &&
(domain->boundary[0][0] >= 2 || domain->boundary[0][1] >= 2))
error->all(FLERR,"Cannot use fix deform on a shrink-wrapped boundary");
if (set[1].style &&
(domain->boundary[1][0] >= 2 || domain->boundary[1][1] >= 2))
error->all(FLERR,"Cannot use fix deform on a shrink-wrapped boundary");
if (set[2].style &&
(domain->boundary[2][0] >= 2 || domain->boundary[2][1] >= 2))
error->all(FLERR,"Cannot use fix deform on a shrink-wrapped boundary");
// no tilt deformation on shrink-wrapped 2nd dim
// b/c shrink wrap will change tilt factor in domain::reset_box()
if (set[3].style &&
(domain->boundary[2][0] >= 2 || domain->boundary[2][1] >= 2))
error->all(FLERR,"Cannot use fix deform tilt on a shrink-wrapped 2nd dim");
if (set[4].style &&
(domain->boundary[2][0] >= 2 || domain->boundary[2][1] >= 2))
error->all(FLERR,"Cannot use fix deform tilt on a shrink-wrapped 2nd dim");
if (set[4].style &&
(domain->boundary[1][0] >= 2 || domain->boundary[1][1] >= 2))
error->all(FLERR,"Cannot use fix deform tilt on a shrink-wrapped 2nd dim");
// apply scaling to FINAL,DELTA,VEL,WIGGLE since they have dist/vel units
int flag = 0;
for (int i = 0; i < 6; i++)
if (set[i].style == FINAL || set[i].style == DELTA ||
set[i].style == VEL || set[i].style == WIGGLE) flag = 1;
if (flag && scaleflag && domain->lattice == NULL)
error->all(FLERR,"Use of fix deform 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];
} else if (set[i].style == VEL) {
set[i].vel *= map[i];
} else if (set[i].style == WIGGLE) {
set[i].amplitude *= 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];
else if (set[i].style == VEL) set[i].vel *= map[i];
else if (set[i].style == WIGGLE) set[i].amplitude *= map[i];
}
// for VOLUME, setup links to other dims
// fixed, dynamic1, dynamic2
for (int i = 0; i < 3; i++) {
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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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].dynamic1 = other1;
set[i].dynamic2 = other2;
}
}
// set varflag
varflag = 0;
for (int i = 0; i < 6; i++)
if (set[i].style == VARIABLE) varflag = 1;
// set initial values at time fix deform is issued
for (int i = 0; i < 3; i++) {
set[i].lo_initial = domain->boxlo[i];
set[i].hi_initial = domain->boxhi[i];
set[i].vol_initial = domain->xprd * domain->yprd * domain->zprd;
}
for (int i = 3; i < 6; i++) {
if (i == 5) set[i].tilt_initial = domain->xy;
else if (i == 4) set[i].tilt_initial = domain->xz;
else if (i == 3) set[i].tilt_initial = domain->yz;
}
// reneighboring only forced if flips can occur due to shape changes
if (set[3].style || set[4].style || set[5].style) force_reneighbor = 1;
next_reneighbor = -1;
nrigid = 0;
rfix = NULL;
flip = 0;
if (force_reneighbor) irregular = new Irregular(lmp);
else irregular = NULL;
TWOPI = 2.0*MY_PI;
}
/* ---------------------------------------------------------------------- */
FixDeform::~FixDeform()
{
for (int i = 0; i < 6; i++) {
delete [] set[i].hstr;
delete [] set[i].hratestr;
}
delete [] set;
delete [] rfix;
delete irregular;
// reset domain's h_rate = 0.0, since this fix may have made it non-zero
double *h_rate = domain->h_rate;
double *h_ratelo = domain->h_ratelo;
h_rate[0] = h_rate[1] = h_rate[2] =
h_rate[3] = h_rate[4] = h_rate[5] = 0.0;
h_ratelo[0] = h_ratelo[1] = h_ratelo[2] = 0.0;
}
/* ---------------------------------------------------------------------- */
int FixDeform::setmask()
{
int mask = 0;
if (force_reneighbor) mask |= PRE_EXCHANGE;
mask |= END_OF_STEP;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixDeform::init()
{
// error if more than one fix deform
// domain, fix nvt/sllod, compute temp/deform only work on single h_rate
int count = 0;
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"deform") == 0) count++;
if (count > 1) error->all(FLERR,"More than one fix deform");
// Kspace setting
if (force->kspace) kspace_flag = 1;
else kspace_flag = 0;
// elapsed time for entire simulation, including multiple runs if defined
double delt = (update->endstep - update->beginstep) * update->dt;
// check variables for VARIABLE style
for (int i = 0; i < 6; i++) {
if (set[i].style != VARIABLE) continue;
set[i].hvar = input->variable->find(set[i].hstr);
if (set[i].hvar < 0)
error->all(FLERR,"Variable name for fix deform does not exist");
if (!input->variable->equalstyle(set[i].hvar))
error->all(FLERR,"Variable for fix deform is invalid style");
set[i].hratevar = input->variable->find(set[i].hratestr);
if (set[i].hratevar < 0)
error->all(FLERR,"Variable name for fix deform does not exist");
if (!input->variable->equalstyle(set[i].hratevar))
error->all(FLERR,"Variable for fix deform is invalid style");
}
// set start/stop values for box size and shape
// if single run, start is current values
// if multiple runs enabled via run start/stop settings,
// start is value when fix deform was issued
// if VARIABLE or NONE, no need to set
for (int i = 0; i < 3; i++) {
if (update->firststep == update->beginstep) {
set[i].lo_start = domain->boxlo[i];
set[i].hi_start = domain->boxhi[i];
set[i].vol_start = domain->xprd * domain->yprd * domain->zprd;
} else {
set[i].lo_start = set[i].lo_initial;
set[i].hi_start = set[i].hi_initial;
set[i].vol_start = set[i].vol_initial;
}
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);
} else if (set[i].style == VEL) {
set[i].lo_stop = set[i].lo_start - 0.5*delt*set[i].vel;
set[i].hi_stop = set[i].hi_start + 0.5*delt*set[i].vel;
} else if (set[i].style == ERATE) {
set[i].lo_stop = set[i].lo_start -
0.5*delt*set[i].rate * (set[i].hi_start-set[i].lo_start);
set[i].hi_stop = set[i].hi_start +
0.5*delt*set[i].rate * (set[i].hi_start-set[i].lo_start);
if (set[i].hi_stop <= set[i].lo_stop)
error->all(FLERR,"Final box dimension due to fix deform is < 0.0");
} else if (set[i].style == TRATE) {
set[i].lo_stop = 0.5*(set[i].lo_start+set[i].hi_start) -
0.5*((set[i].hi_start-set[i].lo_start) * exp(set[i].rate*delt));
set[i].hi_stop = 0.5*(set[i].lo_start+set[i].hi_start) +
0.5*((set[i].hi_start-set[i].lo_start) * exp(set[i].rate*delt));
} else if (set[i].style == WIGGLE) {
set[i].lo_stop = set[i].lo_start -
0.5*set[i].amplitude * sin(TWOPI*delt/set[i].tperiod);
set[i].hi_stop = set[i].hi_start +
0.5*set[i].amplitude * sin(TWOPI*delt/set[i].tperiod);
}
}
for (int i = 3; i < 6; i++) {
if (update->firststep == update->beginstep) {
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;
} else set[i].tilt_start = set[i].tilt_initial;
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;
} else if (set[i].style == VEL) {
set[i].tilt_stop = set[i].tilt_start + delt*set[i].vel;
} else if (set[i].style == ERATE) {
if (i == 3) set[i].tilt_stop = set[i].tilt_start +
delt*set[i].rate * (set[2].hi_start-set[2].lo_start);
if (i == 4) set[i].tilt_stop = set[i].tilt_start +
delt*set[i].rate * (set[2].hi_start-set[2].lo_start);
if (i == 5) set[i].tilt_stop = set[i].tilt_start +
delt*set[i].rate * (set[1].hi_start-set[1].lo_start);
} else if (set[i].style == TRATE) {
set[i].tilt_stop = set[i].tilt_start * exp(set[i].rate*delt);
} else if (set[i].style == WIGGLE) {
set[i].tilt_stop = set[i].tilt_start +
set[i].amplitude * sin(TWOPI*delt/set[i].tperiod);
// compute min/max for WIGGLE = extrema tilt factor will ever reach
if (set[i].amplitude >= 0.0) {
if (delt < 0.25*set[i].tperiod) {
set[i].tilt_min = set[i].tilt_start;
set[i].tilt_max = set[i].tilt_start +
set[i].amplitude*sin(TWOPI*delt/set[i].tperiod);
} else if (delt < 0.5*set[i].tperiod) {
set[i].tilt_min = set[i].tilt_start;
set[i].tilt_max = set[i].tilt_start + set[i].amplitude;
} else if (delt < 0.75*set[i].tperiod) {
set[i].tilt_min = set[i].tilt_start -
set[i].amplitude*sin(TWOPI*delt/set[i].tperiod);
set[i].tilt_max = set[i].tilt_start + set[i].amplitude;
} else {
set[i].tilt_min = set[i].tilt_start - set[i].amplitude;
set[i].tilt_max = set[i].tilt_start + set[i].amplitude;
}
} else {
if (delt < 0.25*set[i].tperiod) {
set[i].tilt_min = set[i].tilt_start -
set[i].amplitude*sin(TWOPI*delt/set[i].tperiod);
set[i].tilt_max = set[i].tilt_start;
} else if (delt < 0.5*set[i].tperiod) {
set[i].tilt_min = set[i].tilt_start - set[i].amplitude;
set[i].tilt_max = set[i].tilt_start;
} else if (delt < 0.75*set[i].tperiod) {
set[i].tilt_min = set[i].tilt_start - set[i].amplitude;
set[i].tilt_max = set[i].tilt_start +
set[i].amplitude*sin(TWOPI*delt/set[i].tperiod);
} else {
set[i].tilt_min = set[i].tilt_start - set[i].amplitude;
set[i].tilt_max = set[i].tilt_start + set[i].amplitude;
}
}
}
}
// if using tilt TRATE, then initial tilt must be non-zero
for (int i = 3; i < 6; i++)
if (set[i].style == TRATE && set[i].tilt_start == 0.0)
error->all(FLERR,"Cannot use fix deform trate on a box with zero tilt");
// if yz changes and will cause box flip, then xy cannot be changing
// yz = [3], xy = [5]
// this is b/c the flips would induce continuous changes in xz
// in order to keep the edge vectors of the flipped shape matrix
// an integer combination of the edge vectors of the unflipped shape matrix
// VARIABLE for yz is error, since no way to calculate if box flip occurs
// WIGGLE lo/hi flip test is on min/max oscillation limit, not tilt_stop
if (set[3].style && set[5].style) {
int flag = 0;
double lo,hi;
if (set[3].style == VARIABLE)
error->all(FLERR,"Fix deform cannot use yz variable with xy");
if (set[3].style == WIGGLE) {
lo = set[3].tilt_min;
hi = set[3].tilt_max;
} else lo = hi = set[3].tilt_stop;
if (lo/(set[1].hi_start-set[1].lo_start) < -0.5 ||
hi/(set[1].hi_start-set[1].lo_start) > 0.5) flag = 1;
if (set[1].style) {
if (lo/(set[1].hi_stop-set[1].lo_stop) < -0.5 ||
hi/(set[1].hi_stop-set[1].lo_stop) > 0.5) flag = 1;
}
if (flag) error->all(FLERR,"Fix deform is changing yz too much with xy");
}
// set domain->h_rate values for use by domain and other fixes/computes
// initialize all rates to 0.0
// cannot set here for TRATE,VOLUME,WIGGLE,VARIABLE since not constant
h_rate = domain->h_rate;
h_ratelo = domain->h_ratelo;
for (int i = 0; i < 3; i++) {
h_rate[i] = h_ratelo[i] = 0.0;
if (set[i].style == FINAL || set[i].style == DELTA ||
set[i].style == SCALE || set[i].style == VEL ||
set[i].style == ERATE) {
double dlo_dt,dhi_dt;
if (delt != 0.0) {
dlo_dt = (set[i].lo_stop - set[i].lo_start) / delt;
dhi_dt = (set[i].hi_stop - set[i].hi_start) / delt;
} else dlo_dt = dhi_dt = 0.0;
h_rate[i] = dhi_dt - dlo_dt;
h_ratelo[i] = dlo_dt;
}
}
for (int i = 3; i < 6; i++) {
h_rate[i] = 0.0;
if (set[i].style == FINAL || set[i].style == DELTA ||
set[i].style == VEL || set[i].style == ERATE) {
if (delt != 0.0)
h_rate[i] = (set[i].tilt_stop - set[i].tilt_start) / delt;
else h_rate[i] = 0.0;
}
}
// detect if any rigid fixes exist so rigid bodies can be rescaled
// rfix[] = indices to each fix rigid
delete [] rfix;
nrigid = 0;
rfix = NULL;
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->rigid_flag) nrigid++;
if (nrigid) {
rfix = new int[nrigid];
nrigid = 0;
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->rigid_flag) rfix[nrigid++] = i;
}
}
/* ----------------------------------------------------------------------
box flipped on previous step
reset box tilts for flipped config and create new box in domain
image_flip() adjusts image flags due to box shape change induced by flip
remap() puts atoms outside the new box back into the new box
perform irregular on atoms in lamda coords to migrate atoms to new procs
important that image_flip comes before remap, since remap may change
image flags to new values, making eqs in doc of Domain:image_flip incorrect
------------------------------------------------------------------------- */
void FixDeform::pre_exchange()
{
if (flip == 0) return;
domain->yz = set[3].tilt_target = set[3].tilt_flip;
domain->xz = set[4].tilt_target = set[4].tilt_flip;
domain->xy = set[5].tilt_target = set[5].tilt_flip;
domain->set_global_box();
domain->set_local_box();
domain->image_flip(flipxy,flipxz,flipyz);
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) domain->remap(x[i],image[i]);
domain->x2lamda(atom->nlocal);
irregular->migrate_atoms();
domain->lamda2x(atom->nlocal);
flip = 0;
}
/* ---------------------------------------------------------------------- */
void FixDeform::end_of_step()
{
int i;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
// wrap variable evaluations with clear/add
if (varflag) modify->clearstep_compute();
// set new box size
// for NONE, target is current box size
// for TRATE, set target directly based on current time, also set h_rate
// for WIGGLE, set target directly based on current time, also set h_rate
// for VARIABLE, set target directly via variable eval, also set h_rate
// for others except VOLUME, target is linear value between start and stop
for (i = 0; i < 3; i++) {
if (set[i].style == NONE) {
set[i].lo_target = domain->boxlo[i];
set[i].hi_target = domain->boxhi[i];
} else if (set[i].style == TRATE) {
double delt = (update->ntimestep - update->beginstep) * update->dt;
set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) -
0.5*((set[i].hi_start-set[i].lo_start) * exp(set[i].rate*delt));
set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) +
0.5*((set[i].hi_start-set[i].lo_start) * exp(set[i].rate*delt));
h_rate[i] = set[i].rate * domain->h[i];
h_ratelo[i] = -0.5*h_rate[i];
} else if (set[i].style == WIGGLE) {
double delt = (update->ntimestep - update->beginstep) * update->dt;
set[i].lo_target = set[i].lo_start -
0.5*set[i].amplitude * sin(TWOPI*delt/set[i].tperiod);
set[i].hi_target = set[i].hi_start +
0.5*set[i].amplitude * sin(TWOPI*delt/set[i].tperiod);
h_rate[i] = TWOPI/set[i].tperiod * set[i].amplitude *
cos(TWOPI*delt/set[i].tperiod);
h_ratelo[i] = -0.5*h_rate[i];
} else if (set[i].style == VARIABLE) {
double del = input->variable->compute_equal(set[i].hvar);
set[i].lo_target = set[i].lo_start - 0.5*del;
set[i].hi_target = set[i].hi_start + 0.5*del;
h_rate[i] = input->variable->compute_equal(set[i].hratevar);
h_ratelo[i] = -0.5*h_rate[i];
} else if (set[i].style != VOLUME) {
set[i].lo_target = set[i].lo_start +
delta*(set[i].lo_stop - set[i].lo_start);
set[i].hi_target = set[i].hi_start +
delta*(set[i].hi_stop - set[i].hi_start);
}
}
// set new box size for VOLUME dims that are linked to other dims
// NOTE: still need to set h_rate for these dims
for (int i = 0; i < 3; i++) {
if (set[i].style != VOLUME) continue;
if (set[i].substyle == ONE_FROM_ONE) {
set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) -
0.5*(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].fixed].hi_start-set[set[i].fixed].lo_start));
set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) +
0.5*(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].fixed].hi_start-set[set[i].fixed].lo_start));
} else if (set[i].substyle == ONE_FROM_TWO) {
set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) -
0.5*(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].dynamic2].hi_target -
set[set[i].dynamic2].lo_target));
set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) +
0.5*(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].dynamic2].hi_target -
set[set[i].dynamic2].lo_target));
} else if (set[i].substyle == TWO_FROM_ONE) {
set[i].lo_target = 0.5*(set[i].lo_start+set[i].hi_start) -
0.5*sqrt(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].fixed].hi_start -
set[set[i].fixed].lo_start) *
(set[i].hi_start - set[i].lo_start));
set[i].hi_target = 0.5*(set[i].lo_start+set[i].hi_start) +
0.5*sqrt(set[i].vol_start /
(set[set[i].dynamic1].hi_target -
set[set[i].dynamic1].lo_target) /
(set[set[i].fixed].hi_start -
set[set[i].fixed].lo_start) *
(set[i].hi_start - set[i].lo_start));
}
}
// for triclinic, set new box shape
// for NONE, target is current tilt
// for TRATE, set target directly based on current time. also set h_rate
// for WIGGLE, set target directly based on current time. also set h_rate
// for VARIABLE, set target directly via variable eval. also set h_rate
// for other styles, target is linear value between start and stop values
if (triclinic) {
double *h = domain->h;
for (i = 3; i < 6; i++) {
if (set[i].style == NONE) {
if (i == 5) set[i].tilt_target = domain->xy;
else if (i == 4) set[i].tilt_target = domain->xz;
else if (i == 3) set[i].tilt_target = domain->yz;
} else if (set[i].style == TRATE) {
double delt = (update->ntimestep - update->beginstep) * update->dt;
set[i].tilt_target = set[i].tilt_start * exp(set[i].rate*delt);
h_rate[i] = set[i].rate * domain->h[i];
} else if (set[i].style == WIGGLE) {
double delt = (update->ntimestep - update->beginstep) * update->dt;
set[i].tilt_target = set[i].tilt_start +
set[i].amplitude * sin(TWOPI*delt/set[i].tperiod);
h_rate[i] = TWOPI/set[i].tperiod * set[i].amplitude *
cos(TWOPI*delt/set[i].tperiod);
} else if (set[i].style == VARIABLE) {
double delta_tilt = input->variable->compute_equal(set[i].hvar);
set[i].tilt_target = set[i].tilt_start + delta_tilt;
h_rate[i] = input->variable->compute_equal(set[i].hratevar);
} else {
set[i].tilt_target = set[i].tilt_start +
delta*(set[i].tilt_stop - set[i].tilt_start);
}
// tilt_target can be large positive or large negative value
// add/subtract box lengths until tilt_target is closest to current value
int idenom;
if (i == 5) idenom = 0;
else if (i == 4) idenom = 0;
else if (i == 3) idenom = 1;
double denom = set[idenom].hi_target - set[idenom].lo_target;
double current = h[i]/h[idenom];
while (set[i].tilt_target/denom - current > 0.0)
set[i].tilt_target -= denom;
while (set[i].tilt_target/denom - current < 0.0)
set[i].tilt_target += denom;
if (fabs(set[i].tilt_target/denom - 1.0 - current) <
fabs(set[i].tilt_target/denom - current))
set[i].tilt_target -= denom;
}
}
if (varflag) modify->addstep_compute(update->ntimestep + nevery);
// if any tilt ratios exceed 0.5, set flip = 1 and compute new tilt values
// do not flip in x or y if non-periodic (can tilt but not flip)
// this is b/c the box length would be changed (dramatically) by flip
// if yz tilt exceeded, adjust C vector by one B vector
// if xz tilt exceeded, adjust C vector by one A vector
// if xy tilt exceeded, adjust B vector by one A vector
// check yz first since it may change xz, then xz check comes after
// flip is performed on next timestep, before reneighboring in pre-exchange()
if (triclinic) {
double xprd = set[0].hi_target - set[0].lo_target;
double yprd = set[1].hi_target - set[1].lo_target;
double xprdinv = 1.0 / xprd;
double yprdinv = 1.0 / yprd;
if (set[3].tilt_target*yprdinv < -0.5 ||
set[3].tilt_target*yprdinv > 0.5 ||
set[4].tilt_target*xprdinv < -0.5 ||
set[4].tilt_target*xprdinv > 0.5 ||
set[5].tilt_target*xprdinv < -0.5 ||
set[5].tilt_target*xprdinv > 0.5) {
set[3].tilt_flip = set[3].tilt_target;
set[4].tilt_flip = set[4].tilt_target;
set[5].tilt_flip = set[5].tilt_target;
flipxy = flipxz = flipyz = 0;
if (domain->yperiodic) {
if (set[3].tilt_flip*yprdinv < -0.5) {
set[3].tilt_flip += yprd;
set[4].tilt_flip += set[5].tilt_flip;
flipyz = 1;
} else if (set[3].tilt_flip*yprdinv > 0.5) {
set[3].tilt_flip -= yprd;
set[4].tilt_flip -= set[5].tilt_flip;
flipyz = -1;
}
}
if (domain->xperiodic) {
if (set[4].tilt_flip*xprdinv < -0.5) {
set[4].tilt_flip += xprd;
flipxz = 1;
}
if (set[4].tilt_flip*xprdinv > 0.5) {
set[4].tilt_flip -= xprd;
flipxz = -1;
}
if (set[5].tilt_flip*xprdinv < -0.5) {
set[5].tilt_flip += xprd;
flipxy = 1;
}
if (set[5].tilt_flip*xprdinv > 0.5) {
set[5].tilt_flip -= xprd;
flipxy = -1;
}
}
flip = 0;
if (flipxy || flipxz || flipyz) flip = 1;
if (flip) next_reneighbor = update->ntimestep + 1;
}
}
// convert atoms and rigid bodies 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]);
if (nrigid)
for (i = 0; i < nrigid; i++)
modify->fix[rfix[i]]->deform(0);
}
// reset global and local box to new size/shape
// only if deform fix is controlling the dimension
if (set[0].style) {
domain->boxlo[0] = set[0].lo_target;
domain->boxhi[0] = set[0].hi_target;
}
if (set[1].style) {
domain->boxlo[1] = set[1].lo_target;
domain->boxhi[1] = set[1].hi_target;
}
if (set[2].style) {
domain->boxlo[2] = set[2].lo_target;
domain->boxhi[2] = set[2].hi_target;
}
if (triclinic) {
if (set[3].style) domain->yz = set[3].tilt_target;
if (set[4].style) domain->xz = set[4].tilt_target;
if (set[5].style) domain->xy = set[5].tilt_target;
}
domain->set_global_box();
domain->set_local_box();
// convert atoms and rigid bodies 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]);
if (nrigid)
for (i = 0; i < nrigid; i++)
modify->fix[rfix[i]]->deform(1);
}
// redo KSpace coeffs since box has changed
if (kspace_flag) force->kspace->setup();
}
/* ---------------------------------------------------------------------- */
void FixDeform::options(int narg, char **arg)
{
if (narg < 0) error->all(FLERR,"Illegal fix deform command");
remapflag = X_REMAP;
scaleflag = 1;
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"remap") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix deform command");
if (strcmp(arg[iarg+1],"x") == 0) remapflag = X_REMAP;
else if (strcmp(arg[iarg+1],"v") == 0) remapflag = V_REMAP;
else if (strcmp(arg[iarg+1],"none") == 0) remapflag = NO_REMAP;
else error->all(FLERR,"Illegal fix deform command");
iarg += 2;
} else if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix deform command");
if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
else error->all(FLERR,"Illegal fix deform command");
iarg += 2;
} else error->all(FLERR,"Illegal fix deform command");
}
}
diff --git a/src/fix_gravity.h b/src/fix_gravity.h
index aef344caf..f37a5bb41 100644
--- a/src/fix_gravity.h
+++ b/src/fix_gravity.h
@@ -1,73 +1,81 @@
/* -*- c++ -*- ----------------------------------------------------------
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(gravity,FixGravity)
#else
#ifndef LMP_FIX_GRAVITY_H
#define LMP_FIX_GRAVITY_H
#include "fix.h"
namespace LAMMPS_NS {
class FixGravity : public Fix {
friend class FixPour;
public:
FixGravity(class LAMMPS *, int, char **);
~FixGravity();
int setmask();
void init();
void setup(int);
virtual void post_force(int);
virtual void post_force_respa(int, int, int);
double compute_scalar();
protected:
int style;
double magnitude;
double vert,phi,theta;
double xdir,ydir,zdir;
double xgrav,ygrav,zgrav,xacc,yacc,zacc;
double degree2rad;
int nlevels_respa;
int time_origin;
int eflag;
double egrav,egrav_all;
int varflag;
int mstyle,vstyle,pstyle,tstyle,xstyle,ystyle,zstyle;
int mvar,vvar,pvar,tvar,xvar,yvar,zvar;
char *mstr,*vstr,*pstr,*tstr,*xstr,*ystr,*zstr;
void set_acceleration();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
+E: Variable name for fix gravity does not exist
+
+Self-explanatory.
+
+E: Variable for fix gravity is invalid style
+
+Only equal-style variables can be used.
+
*/
diff --git a/src/fix_momentum.cpp b/src/fix_momentum.cpp
index 590a55dbc..69e06aeae 100644
--- a/src/fix_momentum.cpp
+++ b/src/fix_momentum.cpp
@@ -1,143 +1,143 @@
/* ----------------------------------------------------------------------
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_momentum.h"
#include "atom.h"
#include "domain.h"
#include "group.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ----------------------------------------------------------------------
Contributing author: Naveen Michaud-Agrawal (Johns Hopkins U)
------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
FixMomentum::FixMomentum(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 4) error->all(FLERR,"Illegal fix momentum command");
nevery = atoi(arg[3]);
if (nevery <= 0) error->all(FLERR,"Illegal fix momentum command");
linear = angular = 0;
int iarg = 4;
while (iarg < narg) {
if (strcmp(arg[iarg],"linear") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix momentum command");
linear = 1;
xflag = atoi(arg[iarg+1]);
yflag = atoi(arg[iarg+2]);
zflag = atoi(arg[iarg+3]);
iarg += 4;
} else if (strcmp(arg[iarg],"angular") == 0) {
angular = 1;
iarg += 1;
} else error->all(FLERR,"Illegal fix momentum command");
}
if (linear == 0 && angular == 0)
error->all(FLERR,"Illegal fix momentum command");
if (linear)
if (xflag < 0 || xflag > 1 || yflag < 0 || yflag > 1 ||
zflag < 0 || zflag > 1) error->all(FLERR,"Illegal fix momentum command");
// cannot have 0 atoms in group
if (group->count(igroup) == 0)
error->all(FLERR,"Fix momentum group has no atoms");
}
/* ---------------------------------------------------------------------- */
int FixMomentum::setmask()
{
int mask = 0;
mask |= END_OF_STEP;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixMomentum::init()
{
masstotal = group->mass(igroup);
}
/* ---------------------------------------------------------------------- */
void FixMomentum::end_of_step()
{
if (linear) {
double vcm[3];
group->vcm(igroup,masstotal,vcm);
// adjust velocities by vcm to zero linear momentum
// only adjust a component if flag is set
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (xflag) v[i][0] -= vcm[0];
if (yflag) v[i][1] -= vcm[1];
if (zflag) v[i][2] -= vcm[2];
}
}
if (angular) {
double xcm[3],angmom[3],inertia[3][3],omega[3];
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;
+ tagint *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 (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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
}
}
}
diff --git a/src/fix_move.cpp b/src/fix_move.cpp
index 0740fdf4f..d1bc5456e 100644
--- a/src/fix_move.cpp
+++ b/src/fix_move.cpp
@@ -1,1016 +1,1016 @@
/* ----------------------------------------------------------------------
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 "math.h"
#include "fix_move.h"
#include "atom.h"
#include "group.h"
#include "update.h"
#include "modify.h"
#include "force.h"
#include "domain.h"
#include "lattice.h"
#include "comm.h"
#include "respa.h"
#include "input.h"
#include "variable.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
using namespace MathConst;
enum{LINEAR,WIGGLE,ROTATE,VARIABLE};
enum{EQUAL,ATOM};
/* ---------------------------------------------------------------------- */
FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 4) error->all(FLERR,"Illegal fix move command");
restart_global = 1;
restart_peratom = 1;
peratom_flag = 1;
size_peratom_cols = 3;
peratom_freq = 1;
time_integrate = 1;
create_attribute = 1;
// parse args
int iarg;
xvarstr = yvarstr = zvarstr = NULL;
vxvarstr = vyvarstr = vzvarstr = NULL;
if (strcmp(arg[3],"linear") == 0) {
if (narg < 7) error->all(FLERR,"Illegal fix move command");
iarg = 7;
mstyle = LINEAR;
if (strcmp(arg[4],"NULL") == 0) vxflag = 0;
else {
vxflag = 1;
vx = atof(arg[4]);
}
if (strcmp(arg[5],"NULL") == 0) vyflag = 0;
else {
vyflag = 1;
vy = atof(arg[5]);
}
if (strcmp(arg[6],"NULL") == 0) vzflag = 0;
else {
vzflag = 1;
vz = atof(arg[6]);
}
} else if (strcmp(arg[3],"wiggle") == 0) {
if (narg < 8) error->all(FLERR,"Illegal fix move command");
iarg = 8;
mstyle = WIGGLE;
if (strcmp(arg[4],"NULL") == 0) axflag = 0;
else {
axflag = 1;
ax = atof(arg[4]);
}
if (strcmp(arg[5],"NULL") == 0) ayflag = 0;
else {
ayflag = 1;
ay = atof(arg[5]);
}
if (strcmp(arg[6],"NULL") == 0) azflag = 0;
else {
azflag = 1;
az = atof(arg[6]);
}
period = atof(arg[7]);
} else if (strcmp(arg[3],"rotate") == 0) {
if (narg < 11) error->all(FLERR,"Illegal fix move command");
iarg = 11;
mstyle = ROTATE;
point[0] = atof(arg[4]);
point[1] = atof(arg[5]);
point[2] = atof(arg[6]);
axis[0] = atof(arg[7]);
axis[1] = atof(arg[8]);
axis[2] = atof(arg[9]);
period = atof(arg[10]);
} else if (strcmp(arg[3],"variable") == 0) {
if (narg < 10) error->all(FLERR,"Illegal fix move command");
iarg = 10;
mstyle = VARIABLE;
if (strcmp(arg[4],"NULL") == 0) xvarstr = NULL;
else if (strstr(arg[4],"v_") == arg[4]) {
int n = strlen(&arg[4][2]) + 1;
xvarstr = new char[n];
strcpy(xvarstr,&arg[4][2]);
} else error->all(FLERR,"Illegal fix move command");
if (strcmp(arg[5],"NULL") == 0) yvarstr = NULL;
else if (strstr(arg[5],"v_") == arg[5]) {
int n = strlen(&arg[5][2]) + 1;
yvarstr = new char[n];
strcpy(yvarstr,&arg[5][2]);
} else error->all(FLERR,"Illegal fix move command");
if (strcmp(arg[6],"NULL") == 0) zvarstr = NULL;
else if (strstr(arg[6],"v_") == arg[6]) {
int n = strlen(&arg[6][2]) + 1;
zvarstr = new char[n];
strcpy(zvarstr,&arg[6][2]);
} else error->all(FLERR,"Illegal fix move command");
if (strcmp(arg[7],"NULL") == 0) vxvarstr = NULL;
else if (strstr(arg[7],"v_") == arg[7]) {
int n = strlen(&arg[7][2]) + 1;
vxvarstr = new char[n];
strcpy(vxvarstr,&arg[7][2]);
} else error->all(FLERR,"Illegal fix move command");
if (strcmp(arg[8],"NULL") == 0) vyvarstr = NULL;
else if (strstr(arg[8],"v_") == arg[8]) {
int n = strlen(&arg[8][2]) + 1;
vyvarstr = new char[n];
strcpy(vyvarstr,&arg[8][2]);
} else error->all(FLERR,"Illegal fix move command");
if (strcmp(arg[9],"NULL") == 0) vzvarstr = NULL;
else if (strstr(arg[9],"v_") == arg[9]) {
int n = strlen(&arg[9][2]) + 1;
vzvarstr = new char[n];
strcpy(vzvarstr,&arg[9][2]);
} else error->all(FLERR,"Illegal fix move command");
} else error->all(FLERR,"Illegal fix move command");
// optional args
int scaleflag = 1;
while (iarg < narg) {
if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix move command");
if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
else error->all(FLERR,"Illegal fix move command");
iarg += 2;
} else error->all(FLERR,"Illegal fix move command");
}
// error checks and warnings
if (domain->dimension == 2) {
if (mstyle == LINEAR && vzflag && vz != 0.0)
error->all(FLERR,"Fix move cannot set linear z motion for 2d problem");
if (mstyle == WIGGLE && azflag && az != 0.0)
error->all(FLERR,"Fix move cannot set wiggle z motion for 2d problem");
if (mstyle == ROTATE && (axis[0] != 0.0 || axis[1] != 0.0))
error->all(FLERR,
"Fix move cannot rotate aroung non z-axis for 2d problem");
if (mstyle == VARIABLE && (zvarstr || vzvarstr))
error->all(FLERR,
"Fix move cannot define z or vz variable for 2d problem");
}
if (atom->angmom_flag && comm->me == 0)
error->warning(FLERR,"Fix move does not update angular momentum");
if (atom->ellipsoid_flag && comm->me == 0)
error->warning(FLERR,"Fix move does not update quaternions");
// setup scaling and apply scaling factors to velocity & amplitude
if ((mstyle == LINEAR || mstyle == WIGGLE || mstyle == ROTATE) &&
scaleflag) {
if (domain->lattice == NULL)
error->all(FLERR,"Use of fix move 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;
if (mstyle == LINEAR) {
if (vxflag) vx *= xscale;
if (vyflag) vy *= yscale;
if (vzflag) vz *= zscale;
} else if (mstyle == WIGGLE) {
if (axflag) ax *= xscale;
if (ayflag) ay *= yscale;
if (azflag) az *= zscale;
} else if (mstyle == ROTATE) {
point[0] *= xscale;
point[1] *= yscale;
point[2] *= zscale;
}
}
// set omega_rotate from period
if (mstyle == WIGGLE || mstyle == ROTATE) omega_rotate = 2.0*MY_PI / period;
// runit = unit vector along rotation axis
if (mstyle == ROTATE) {
double len = sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]);
if (len == 0.0)
error->all(FLERR,"Fix move cannot have 0 length rotation vector");
runit[0] = axis[0]/len;
runit[1] = axis[1]/len;
runit[2] = axis[2]/len;
}
// set omega_flag if particles store omega
omega_flag = atom->omega_flag;
// perform initial allocation of atom-based array
// register with Atom class
xoriginal = NULL;
grow_arrays(atom->nmax);
atom->add_callback(0);
atom->add_callback(1);
maxatom = 0;
displace = velocity = NULL;
// xoriginal = initial unwrapped positions of atoms
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) domain->unmap(x[i],image[i],xoriginal[i]);
else xoriginal[i][0] = xoriginal[i][1] = xoriginal[i][2] = 0.0;
}
time_origin = update->ntimestep;
}
/* ---------------------------------------------------------------------- */
FixMove::~FixMove()
{
// unregister callbacks to this fix from Atom class
atom->delete_callback(id,0);
atom->delete_callback(id,1);
// delete locally stored arrays
memory->destroy(xoriginal);
memory->destroy(displace);
memory->destroy(velocity);
delete [] xvarstr;
delete [] yvarstr;
delete [] zvarstr;
delete [] vxvarstr;
delete [] vyvarstr;
delete [] vzvarstr;
}
/* ---------------------------------------------------------------------- */
int FixMove::setmask()
{
int mask = 0;
mask |= INITIAL_INTEGRATE;
mask |= INITIAL_INTEGRATE_RESPA;
mask |= FINAL_INTEGRATE;
mask |= FINAL_INTEGRATE_RESPA;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixMove::init()
{
dt = update->dt;
dtv = update->dt;
dtf = 0.5 * update->dt * force->ftm2v;
// set indices and style of all variables
if (mstyle == VARIABLE) {
if (xvarstr) {
xvar = input->variable->find(xvarstr);
if (xvar < 0) error->all(FLERR,
"Variable name for fix move does not exist");
if (input->variable->equalstyle(xvar)) xvarstyle = EQUAL;
else if (input->variable->atomstyle(xvar)) xvarstyle = ATOM;
else error->all(FLERR,"Variable for fix move is invalid style");
}
if (yvarstr) {
yvar = input->variable->find(yvarstr);
if (yvar < 0) error->all(FLERR,
"Variable name for fix move does not exist");
if (input->variable->equalstyle(yvar)) yvarstyle = EQUAL;
else if (input->variable->atomstyle(yvar)) yvarstyle = ATOM;
else error->all(FLERR,"Variable for fix move is invalid style");
}
if (zvarstr) {
zvar = input->variable->find(zvarstr);
if (zvar < 0) error->all(FLERR,
"Variable name for fix move does not exist");
if (input->variable->equalstyle(zvar)) zvarstyle = EQUAL;
else if (input->variable->atomstyle(zvar)) zvarstyle = ATOM;
else error->all(FLERR,"Variable for fix move is invalid style");
}
if (vxvarstr) {
vxvar = input->variable->find(vxvarstr);
if (vxvar < 0) error->all(FLERR,
"Variable name for fix move does not exist");
if (input->variable->equalstyle(vxvar)) vxvarstyle = EQUAL;
else if (input->variable->atomstyle(vxvar)) vxvarstyle = ATOM;
else error->all(FLERR,"Variable for fix move is invalid style");
}
if (vyvarstr) {
vyvar = input->variable->find(vyvarstr);
if (vyvar < 0) error->all(FLERR,
"Variable name for fix move does not exist");
if (input->variable->equalstyle(vyvar)) vyvarstyle = EQUAL;
else if (input->variable->atomstyle(vyvar)) vyvarstyle = ATOM;
else error->all(FLERR,"Variable for fix move is invalid style");
}
if (vzvarstr) {
vzvar = input->variable->find(vzvarstr);
if (vzvar < 0) error->all(FLERR,
"Variable name for fix move does not exist");
if (input->variable->equalstyle(vzvar)) vzvarstyle = EQUAL;
else if (input->variable->atomstyle(vzvar)) vzvarstyle = ATOM;
else error->all(FLERR,"Variable for fix move is invalid style");
}
displaceflag = velocityflag = 0;
if (xvarstr && xvarstyle == ATOM) displaceflag = 1;
if (yvarstr && yvarstyle == ATOM) displaceflag = 1;
if (zvarstr && zvarstyle == ATOM) displaceflag = 1;
if (vxvarstr && vxvarstyle == ATOM) velocityflag = 1;
if (vyvarstr && vyvarstyle == ATOM) velocityflag = 1;
if (vzvarstr && vzvarstyle == ATOM) velocityflag = 1;
}
if (strstr(update->integrate_style,"respa"))
nlevels_respa = ((Respa *) update->integrate)->nlevels;
}
/* ----------------------------------------------------------------------
set x,v of particles
------------------------------------------------------------------------- */
void FixMove::initial_integrate(int vflag)
{
double dtfm;
double xold[3],a[3],b[3],c[3],d[3],disp[3];
double ddotr,dx,dy,dz;
double delta = (update->ntimestep - time_origin) * dt;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
// for linear: X = X0 + V*dt
if (mstyle == LINEAR) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
xold[0] = x[i][0];
xold[1] = x[i][1];
xold[2] = x[i][2];
if (vxflag) {
v[i][0] = vx;
x[i][0] = xoriginal[i][0] + vx*delta;
} else if (rmass) {
dtfm = dtf / rmass[i];
v[i][0] += dtfm * f[i][0];
x[i][0] += dtv * v[i][0];
} else {
dtfm = dtf / mass[type[i]];
v[i][0] += dtfm * f[i][0];
x[i][0] += dtv * v[i][0];
}
if (vyflag) {
v[i][1] = vy;
x[i][1] = xoriginal[i][1] + vy*delta;
} else if (rmass) {
dtfm = dtf / rmass[i];
v[i][1] += dtfm * f[i][1];
x[i][1] += dtv * v[i][1];
} else {
dtfm = dtf / mass[type[i]];
v[i][1] += dtfm * f[i][1];
x[i][1] += dtv * v[i][1];
}
if (vzflag) {
v[i][2] = vz;
x[i][2] = xoriginal[i][2] + vz*delta;
} else if (rmass) {
dtfm = dtf / rmass[i];
v[i][2] += dtfm * f[i][2];
x[i][2] += dtv * v[i][2];
} else {
dtfm = dtf / mass[type[i]];
v[i][2] += dtfm * f[i][2];
x[i][2] += dtv * v[i][2];
}
domain->remap_near(x[i],xold);
}
}
// for wiggle: X = X0 + A sin(w*dt)
} else if (mstyle == WIGGLE) {
double arg = omega_rotate * delta;
double sine = sin(arg);
double cosine = cos(arg);
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
xold[0] = x[i][0];
xold[1] = x[i][1];
xold[2] = x[i][2];
if (axflag) {
v[i][0] = ax*omega_rotate*cosine;
x[i][0] = xoriginal[i][0] + ax*sine;
} else if (rmass) {
dtfm = dtf / rmass[i];
v[i][0] += dtfm * f[i][0];
x[i][0] += dtv * v[i][0];
} else {
dtfm = dtf / mass[type[i]];
v[i][0] += dtfm * f[i][0];
x[i][0] += dtv * v[i][0];
}
if (ayflag) {
v[i][1] = ay*omega_rotate*cosine;
x[i][1] = xoriginal[i][1] + ay*sine;
} else if (rmass) {
dtfm = dtf / rmass[i];
v[i][1] += dtfm * f[i][1];
x[i][1] += dtv * v[i][1];
} else {
dtfm = dtf / mass[type[i]];
v[i][1] += dtfm * f[i][1];
x[i][1] += dtv * v[i][1];
}
if (azflag) {
v[i][2] = az*omega_rotate*cosine;
x[i][2] = xoriginal[i][2] + az*sine;
} else if (rmass) {
dtfm = dtf / rmass[i];
v[i][2] += dtfm * f[i][2];
x[i][2] += dtv * v[i][2];
} else {
dtfm = dtf / mass[type[i]];
v[i][2] += dtfm * f[i][2];
x[i][2] += dtv * v[i][2];
}
domain->remap_near(x[i],xold);
}
}
// for rotate by right-hand rule around omega:
// P = point = vector = point of rotation
// R = vector = axis of rotation
// w = omega of rotation (from period)
// X0 = xoriginal = initial coord of atom
// R0 = runit = unit vector for R
// D = X0 - P = vector from P to X0
// C = (D dot R0) R0 = projection of atom coord onto R line
// A = D - C = vector from R line to X0
// B = R0 cross A = vector perp to A in plane of rotation
// A,B define plane of circular rotation around R line
// X = P + C + A cos(w*dt) + B sin(w*dt)
// V = w R0 cross (A cos(w*dt) + B sin(w*dt))
} else if (mstyle == ROTATE) {
double arg = omega_rotate * delta;
double sine = sin(arg);
double cosine = cos(arg);
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
xold[0] = x[i][0];
xold[1] = x[i][1];
xold[2] = x[i][2];
d[0] = xoriginal[i][0] - point[0];
d[1] = xoriginal[i][1] - point[1];
d[2] = xoriginal[i][2] - point[2];
ddotr = d[0]*runit[0] + d[1]*runit[1] + d[2]*runit[2];
c[0] = ddotr*runit[0];
c[1] = ddotr*runit[1];
c[2] = ddotr*runit[2];
a[0] = d[0] - c[0];
a[1] = d[1] - c[1];
a[2] = d[2] - c[2];
b[0] = runit[1]*a[2] - runit[2]*a[1];
b[1] = runit[2]*a[0] - runit[0]*a[2];
b[2] = runit[0]*a[1] - runit[1]*a[0];
disp[0] = a[0]*cosine + b[0]*sine;
disp[1] = a[1]*cosine + b[1]*sine;
disp[2] = a[2]*cosine + b[2]*sine;
x[i][0] = point[0] + c[0] + disp[0];
x[i][1] = point[1] + c[1] + disp[1];
x[i][2] = point[2] + c[2] + disp[2];
v[i][0] = omega_rotate * (runit[1]*disp[2] - runit[2]*disp[1]);
v[i][1] = omega_rotate * (runit[2]*disp[0] - runit[0]*disp[2]);
v[i][2] = omega_rotate * (runit[0]*disp[1] - runit[1]*disp[0]);
if (omega_flag) {
omega[i][0] = omega_rotate*runit[0];
omega[i][1] = omega_rotate*runit[1];
omega[i][2] = omega_rotate*runit[2];
}
domain->remap_near(x[i],xold);
}
}
// for variable: compute x,v from variables
} else if (mstyle == VARIABLE) {
// reallocate displace and velocity arrays as necessary
if ((displaceflag || velocityflag) && nlocal > maxatom) {
maxatom = atom->nmax;
if (displaceflag) {
memory->destroy(displace);
memory->create(displace,maxatom,3,"move:displace");
}
if (velocityflag) {
memory->destroy(velocity);
memory->create(velocity,maxatom,3,"move:velocity");
}
}
// pre-compute variable values, wrap with clear/add
modify->clearstep_compute();
if (xvarstr) {
if (xvarstyle == EQUAL) dx = input->variable->compute_equal(xvar);
else if (displace)
input->variable->compute_atom(xvar,igroup,&displace[0][0],3,0);
}
if (yvarstr) {
if (yvarstyle == EQUAL) dy = input->variable->compute_equal(yvar);
else if (displace)
input->variable->compute_atom(yvar,igroup,&displace[0][1],3,0);
}
if (zvarstr) {
if (zvarstyle == EQUAL) dz = input->variable->compute_equal(zvar);
else if (displace)
input->variable->compute_atom(zvar,igroup,&displace[0][2],3,0);
}
if (vxvarstr) {
if (vxvarstyle == EQUAL) vx = input->variable->compute_equal(vxvar);
else if (velocity)
input->variable->compute_atom(vxvar,igroup,&velocity[0][0],3,0);
}
if (vyvarstr) {
if (vyvarstyle == EQUAL) vy = input->variable->compute_equal(vyvar);
else if (velocity)
input->variable->compute_atom(vyvar,igroup,&velocity[0][1],3,0);
}
if (vzvarstr) {
if (vzvarstyle == EQUAL) vz = input->variable->compute_equal(vzvar);
else if (velocity)
input->variable->compute_atom(vzvar,igroup,&velocity[0][2],3,0);
}
modify->addstep_compute(update->ntimestep + 1);
// update x,v
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
xold[0] = x[i][0];
xold[1] = x[i][1];
xold[2] = x[i][2];
if (xvarstr && vxvarstr) {
if (vxvarstyle == EQUAL) v[i][0] = vx;
else v[i][0] = velocity[i][0];
if (xvarstyle == EQUAL) x[i][0] = xoriginal[i][0] + dx;
else x[i][0] = xoriginal[i][0] + displace[i][0];
} else if (xvarstr) {
if (xvarstyle == EQUAL) x[i][0] = xoriginal[i][0] + dx;
else x[i][0] = xoriginal[i][0] + displace[i][0];
} else if (vxvarstr) {
if (vxvarstyle == EQUAL) v[i][0] = vx;
else v[i][0] = velocity[i][0];
if (rmass) {
dtfm = dtf / rmass[i];
x[i][0] += dtv * v[i][0];
} else {
dtfm = dtf / mass[type[i]];
x[i][0] += dtv * v[i][0];
}
} else {
if (rmass) {
dtfm = dtf / rmass[i];
v[i][0] += dtfm * f[i][0];
x[i][0] += dtv * v[i][0];
} else {
dtfm = dtf / mass[type[i]];
v[i][0] += dtfm * f[i][0];
x[i][0] += dtv * v[i][0];
}
}
if (yvarstr && vyvarstr) {
if (vyvarstyle == EQUAL) v[i][1] = vy;
else v[i][1] = velocity[i][1];
if (yvarstyle == EQUAL) x[i][1] = xoriginal[i][1] + dy;
else x[i][1] = xoriginal[i][1] + displace[i][1];
} else if (yvarstr) {
if (yvarstyle == EQUAL) x[i][1] = xoriginal[i][1] + dy;
else x[i][1] = xoriginal[i][1] + displace[i][1];
} else if (vyvarstr) {
if (vyvarstyle == EQUAL) v[i][1] = vy;
else v[i][1] = velocity[i][1];
if (rmass) {
dtfm = dtf / rmass[i];
x[i][1] += dtv * v[i][1];
} else {
dtfm = dtf / mass[type[i]];
x[i][1] += dtv * v[i][1];
}
} else {
if (rmass) {
dtfm = dtf / rmass[i];
v[i][1] += dtfm * f[i][1];
x[i][1] += dtv * v[i][1];
} else {
dtfm = dtf / mass[type[i]];
v[i][1] += dtfm * f[i][1];
x[i][1] += dtv * v[i][1];
}
}
if (zvarstr && vzvarstr) {
if (vzvarstyle == EQUAL) v[i][2] = vz;
else v[i][2] = velocity[i][2];
if (zvarstyle == EQUAL) x[i][2] = xoriginal[i][2] + dz;
else x[i][2] = xoriginal[i][2] + displace[i][2];
} else if (zvarstr) {
if (zvarstyle == EQUAL) x[i][2] = xoriginal[i][2] + dz;
else x[i][2] = xoriginal[i][2] + displace[i][2];
} else if (vzvarstr) {
if (vzvarstyle == EQUAL) v[i][2] = vz;
else v[i][2] = velocity[i][2];
if (rmass) {
dtfm = dtf / rmass[i];
x[i][2] += dtv * v[i][2];
} else {
dtfm = dtf / mass[type[i]];
x[i][2] += dtv * v[i][2];
}
} else {
if (rmass) {
dtfm = dtf / rmass[i];
v[i][2] += dtfm * f[i][2];
x[i][2] += dtv * v[i][2];
} else {
dtfm = dtf / mass[type[i]];
v[i][2] += dtfm * f[i][2];
x[i][2] += dtv * v[i][2];
}
}
domain->remap_near(x[i],xold);
}
}
}
}
/* ----------------------------------------------------------------------
final NVE of particles with NULL components
------------------------------------------------------------------------- */
void FixMove::final_integrate()
{
double dtfm;
int xflag = 1;
if (mstyle == LINEAR && vxflag) xflag = 0;
else if (mstyle == WIGGLE && axflag) xflag = 0;
else if (mstyle == ROTATE) xflag = 0;
else if (mstyle == VARIABLE && (xvarstr || vxvarstr)) xflag = 0;
int yflag = 1;
if (mstyle == LINEAR && vyflag) yflag = 0;
else if (mstyle == WIGGLE && ayflag) yflag = 0;
else if (mstyle == ROTATE) yflag = 0;
else if (mstyle == VARIABLE && (yvarstr || vyvarstr)) yflag = 0;
int zflag = 1;
if (mstyle == LINEAR && vzflag) zflag = 0;
else if (mstyle == WIGGLE && azflag) zflag = 0;
else if (mstyle == ROTATE) zflag = 0;
else if (mstyle == VARIABLE && (zvarstr || vzvarstr)) zflag = 0;
double **v = atom->v;
double **f = atom->f;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
if (xflag)
if (rmass) {
dtfm = dtf / rmass[i];
v[i][0] += dtfm * f[i][0];
} else {
dtfm = dtf / mass[type[i]];
v[i][0] += dtfm * f[i][0];
}
if (yflag)
if (rmass) {
dtfm = dtf / rmass[i];
v[i][1] += dtfm * f[i][1];
} else {
dtfm = dtf / mass[type[i]];
v[i][1] += dtfm * f[i][1];
}
if (zflag)
if (rmass) {
dtfm = dtf / rmass[i];
v[i][2] += dtfm * f[i][2];
} else {
dtfm = dtf / mass[type[i]];
v[i][2] += dtfm * f[i][2];
}
}
}
}
/* ---------------------------------------------------------------------- */
void FixMove::initial_integrate_respa(int vflag, int ilevel, int iloop)
{
// outermost level - update v and x
// all other levels - nothing
if (ilevel == nlevels_respa-1) initial_integrate(vflag);
}
/* ---------------------------------------------------------------------- */
void FixMove::final_integrate_respa(int ilevel, int iloop)
{
if (ilevel == nlevels_respa-1) final_integrate();
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double FixMove::memory_usage()
{
double bytes = atom->nmax*3 * sizeof(double);
if (displaceflag) bytes += atom->nmax*3 * sizeof(double);
if (velocityflag) bytes += atom->nmax*3 * sizeof(double);
return bytes;
}
/* ----------------------------------------------------------------------
pack entire state of Fix into one write
------------------------------------------------------------------------- */
void FixMove::write_restart(FILE *fp)
{
int n = 0;
double list[1];
list[n++] = time_origin;
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 FixMove::restart(char *buf)
{
int n = 0;
double *list = (double *) buf;
time_origin = static_cast<int> (list[n++]);
}
/* ----------------------------------------------------------------------
allocate atom-based array
------------------------------------------------------------------------- */
void FixMove::grow_arrays(int nmax)
{
memory->grow(xoriginal,nmax,3,"move:xoriginal");
array_atom = xoriginal;
}
/* ----------------------------------------------------------------------
copy values within local atom-based array
------------------------------------------------------------------------- */
void FixMove::copy_arrays(int i, int j)
{
xoriginal[j][0] = xoriginal[i][0];
xoriginal[j][1] = xoriginal[i][1];
xoriginal[j][2] = xoriginal[i][2];
}
/* ----------------------------------------------------------------------
initialize one atom's array values, called when atom is created
------------------------------------------------------------------------- */
void FixMove::set_arrays(int i)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
// particle not in group
if (!(mask[i] & groupbit)) {
xoriginal[i][0] = xoriginal[i][1] = xoriginal[i][2] = 0.0;
return;
}
// current time still equal fix creation time
if (update->ntimestep == time_origin) {
domain->unmap(x[i],image[i],xoriginal[i]);
return;
}
// backup particle to time_origin
if (mstyle == VARIABLE)
error->all(FLERR,"Cannot add atoms to fix move variable");
domain->unmap(x[i],image[i],xoriginal[i]);
double delta = (update->ntimestep - time_origin) * update->dt;
if (mstyle == LINEAR) {
if (vxflag) xoriginal[i][0] -= vx * delta;
if (vyflag) xoriginal[i][1] -= vy * delta;
if (vzflag) xoriginal[i][2] -= vz * delta;
} else if (mstyle == WIGGLE) {
double arg = omega_rotate * delta;
double sine = sin(arg);
if (axflag) xoriginal[i][0] -= ax*sine;
if (ayflag) xoriginal[i][1] -= ay*sine;
if (azflag) xoriginal[i][2] -= az*sine;
} else if (mstyle == ROTATE) {
double a[3],b[3],c[3],d[3],disp[3],ddotr;
double arg = - omega_rotate * delta;
double sine = sin(arg);
double cosine = cos(arg);
d[0] = x[i][0] - point[0];
d[1] = x[i][1] - point[1];
d[2] = x[i][2] - point[2];
ddotr = d[0]*runit[0] + d[1]*runit[1] + d[2]*runit[2];
c[0] = ddotr*runit[0];
c[1] = ddotr*runit[1];
c[2] = ddotr*runit[2];
a[0] = d[0] - c[0];
a[1] = d[1] - c[1];
a[2] = d[2] - c[2];
b[0] = runit[1]*a[2] - runit[2]*a[1];
b[1] = runit[2]*a[0] - runit[0]*a[2];
b[2] = runit[0]*a[1] - runit[1]*a[0];
disp[0] = a[0]*cosine + b[0]*sine;
disp[1] = a[1]*cosine + b[1]*sine;
disp[2] = a[2]*cosine + b[2]*sine;
xoriginal[i][0] = point[0] + c[0] + disp[0];
xoriginal[i][1] = point[1] + c[1] + disp[1];
xoriginal[i][2] = point[2] + c[2] + disp[2];
}
}
/* ----------------------------------------------------------------------
pack values in local atom-based array for exchange with another proc
------------------------------------------------------------------------- */
int FixMove::pack_exchange(int i, double *buf)
{
buf[0] = xoriginal[i][0];
buf[1] = xoriginal[i][1];
buf[2] = xoriginal[i][2];
return 3;
}
/* ----------------------------------------------------------------------
unpack values in local atom-based array from exchange with another proc
------------------------------------------------------------------------- */
int FixMove::unpack_exchange(int nlocal, double *buf)
{
xoriginal[nlocal][0] = buf[0];
xoriginal[nlocal][1] = buf[1];
xoriginal[nlocal][2] = buf[2];
return 3;
}
/* ----------------------------------------------------------------------
pack values in local atom-based arrays for restart file
------------------------------------------------------------------------- */
int FixMove::pack_restart(int i, double *buf)
{
buf[0] = 4;
buf[1] = xoriginal[i][0];
buf[2] = xoriginal[i][1];
buf[3] = xoriginal[i][2];
return 4;
}
/* ----------------------------------------------------------------------
unpack values from atom->extra array to restart the fix
------------------------------------------------------------------------- */
void FixMove::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++;
xoriginal[nlocal][0] = extra[nlocal][m++];
xoriginal[nlocal][1] = extra[nlocal][m++];
xoriginal[nlocal][2] = extra[nlocal][m++];
}
/* ----------------------------------------------------------------------
maxsize of any atom's restart data
------------------------------------------------------------------------- */
int FixMove::maxsize_restart()
{
return 4;
}
/* ----------------------------------------------------------------------
size of atom nlocal's restart data
------------------------------------------------------------------------- */
int FixMove::size_restart(int nlocal)
{
return 4;
}
/* ---------------------------------------------------------------------- */
void FixMove::reset_dt()
{
error->all(FLERR,"Resetting timestep is not allowed with fix move");
}
diff --git a/src/fix_nh.cpp b/src/fix_nh.cpp
index 6548045ff..64a393232 100644
--- a/src/fix_nh.cpp
+++ b/src/fix_nh.cpp
@@ -1,2257 +1,2257 @@
/* ----------------------------------------------------------------------
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), Aidan Thompson (SNL)
------------------------------------------------------------------------- */
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include "fix_nh.h"
#include "math_extra.h"
#include "atom.h"
#include "force.h"
#include "group.h"
#include "comm.h"
#include "irregular.h"
#include "modify.h"
#include "fix_deform.h"
#include "compute.h"
#include "kspace.h"
#include "update.h"
#include "respa.h"
#include "domain.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
#define DELTAFLIP 0.1
#define TILTMAX 1.5
enum{NOBIAS,BIAS};
enum{NONE,XYZ,XY,YZ,XZ};
enum{ISO,ANISO,TRICLINIC};
/* ----------------------------------------------------------------------
NVT,NPH,NPT integrators for improved Nose-Hoover equations of motion
---------------------------------------------------------------------- */
FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
{
if (narg < 4) error->all(FLERR,"Illegal fix nvt/npt/nph command");
restart_global = 1;
time_integrate = 1;
scalar_flag = 1;
vector_flag = 1;
global_freq = 1;
extscalar = 1;
extvector = 0;
// default values
pcouple = NONE;
drag = 0.0;
allremap = 1;
id_dilate = NULL;
mtchain = mpchain = 3;
nc_tchain = nc_pchain = 1;
mtk_flag = 1;
deviatoric_flag = 0;
nreset_h0 = 0;
eta_mass_flag = 1;
omega_mass_flag = 0;
etap_mass_flag = 0;
// turn on tilt factor scaling, whenever applicable
dimension = domain->dimension;
scaleyz = scalexz = scalexy = 0;
if (domain->yperiodic && domain->xy != 0.0) scalexy = 1;
if (domain->zperiodic && dimension == 3) {
if (domain->yz != 0.0) scaleyz = 1;
if (domain->xz != 0.0) scalexz = 1;
}
// set fixed-point to default = center of cell
fixedpoint[0] = 0.5*(domain->boxlo[0]+domain->boxhi[0]);
fixedpoint[1] = 0.5*(domain->boxlo[1]+domain->boxhi[1]);
fixedpoint[2] = 0.5*(domain->boxlo[2]+domain->boxhi[2]);
// used by FixNVTSllod to preserve non-default value
mtchain_default_flag = 1;
tstat_flag = 0;
double t_period = 0.0;
double p_period[6];
for (int i = 0; i < 6; i++) {
p_start[i] = p_stop[i] = p_period[i] = p_target[i] = 0.0;
p_flag[i] = 0;
}
// process keywords
int iarg = 3;
while (iarg < narg) {
if (strcmp(arg[iarg],"temp") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
tstat_flag = 1;
t_start = atof(arg[iarg+1]);
t_target = t_start;
t_stop = atof(arg[iarg+2]);
t_period = atof(arg[iarg+3]);
if (t_start < 0.0 || t_stop <= 0.0)
error->all(FLERR,
"Target temperature for fix nvt/npt/nph cannot be 0.0");
iarg += 4;
} else if (strcmp(arg[iarg],"iso") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
pcouple = XYZ;
p_start[0] = p_start[1] = p_start[2] = atof(arg[iarg+1]);
p_stop[0] = p_stop[1] = p_stop[2] = atof(arg[iarg+2]);
p_period[0] = p_period[1] = p_period[2] = atof(arg[iarg+3]);
p_flag[0] = p_flag[1] = p_flag[2] = 1;
if (dimension == 2) {
p_start[2] = p_stop[2] = p_period[2] = 0.0;
p_flag[2] = 0;
}
iarg += 4;
} else if (strcmp(arg[iarg],"aniso") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
pcouple = NONE;
p_start[0] = p_start[1] = p_start[2] = atof(arg[iarg+1]);
p_stop[0] = p_stop[1] = p_stop[2] = atof(arg[iarg+2]);
p_period[0] = p_period[1] = p_period[2] = atof(arg[iarg+3]);
p_flag[0] = p_flag[1] = p_flag[2] = 1;
if (dimension == 2) {
p_start[2] = p_stop[2] = p_period[2] = 0.0;
p_flag[2] = 0;
}
iarg += 4;
} else if (strcmp(arg[iarg],"tri") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
pcouple = NONE;
scalexy = scalexz = scaleyz = 0;
p_start[0] = p_start[1] = p_start[2] = atof(arg[iarg+1]);
p_stop[0] = p_stop[1] = p_stop[2] = atof(arg[iarg+2]);
p_period[0] = p_period[1] = p_period[2] = atof(arg[iarg+3]);
p_flag[0] = p_flag[1] = p_flag[2] = 1;
p_start[3] = p_start[4] = p_start[5] = 0.0;
p_stop[3] = p_stop[4] = p_stop[5] = 0.0;
p_period[3] = p_period[4] = p_period[5] = atof(arg[iarg+3]);
p_flag[3] = p_flag[4] = p_flag[5] = 1;
if (dimension == 2) {
p_start[2] = p_stop[2] = p_period[2] = 0.0;
p_flag[2] = 0;
p_start[3] = p_stop[3] = p_period[3] = 0.0;
p_flag[3] = 0;
p_start[4] = p_stop[4] = p_period[4] = 0.0;
p_flag[4] = 0;
}
iarg += 4;
} else if (strcmp(arg[iarg],"x") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
p_start[0] = atof(arg[iarg+1]);
p_stop[0] = atof(arg[iarg+2]);
p_period[0] = atof(arg[iarg+3]);
p_flag[0] = 1;
deviatoric_flag = 1;
iarg += 4;
} else if (strcmp(arg[iarg],"y") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
p_start[1] = atof(arg[iarg+1]);
p_stop[1] = atof(arg[iarg+2]);
p_period[1] = atof(arg[iarg+3]);
p_flag[1] = 1;
deviatoric_flag = 1;
iarg += 4;
} else if (strcmp(arg[iarg],"z") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
p_start[2] = atof(arg[iarg+1]);
p_stop[2] = atof(arg[iarg+2]);
p_period[2] = atof(arg[iarg+3]);
p_flag[2] = 1;
deviatoric_flag = 1;
iarg += 4;
if (dimension == 2)
error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation");
} else if (strcmp(arg[iarg],"yz") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
scaleyz = 0;
p_start[3] = atof(arg[iarg+1]);
p_stop[3] = atof(arg[iarg+2]);
p_period[3] = atof(arg[iarg+3]);
p_flag[3] = 1;
deviatoric_flag = 1;
iarg += 4;
if (dimension == 2)
error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation");
} else if (strcmp(arg[iarg],"xz") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
scalexz = 0;
p_start[4] = atof(arg[iarg+1]);
p_stop[4] = atof(arg[iarg+2]);
p_period[4] = atof(arg[iarg+3]);
p_flag[4] = 1;
deviatoric_flag = 1;
iarg += 4;
if (dimension == 2)
error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation");
} else if (strcmp(arg[iarg],"xy") == 0) {
scalexy = 0;
if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
p_start[5] = atof(arg[iarg+1]);
p_stop[5] = atof(arg[iarg+2]);
p_period[5] = atof(arg[iarg+3]);
p_flag[5] = 1;
deviatoric_flag = 1;
iarg += 4;
} else if (strcmp(arg[iarg],"couple") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
if (strcmp(arg[iarg+1],"xyz") == 0) pcouple = XYZ;
else if (strcmp(arg[iarg+1],"xy") == 0) pcouple = XY;
else if (strcmp(arg[iarg+1],"yz") == 0) pcouple = YZ;
else if (strcmp(arg[iarg+1],"xz") == 0) pcouple = XZ;
else if (strcmp(arg[iarg+1],"none") == 0) pcouple = NONE;
else error->all(FLERR,"Illegal fix nvt/npt/nph command");
iarg += 2;
} else if (strcmp(arg[iarg],"drag") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
drag = atof(arg[iarg+1]);
if (drag < 0.0) error->all(FLERR,"Illegal fix nvt/npt/nph command");
iarg += 2;
} else if (strcmp(arg[iarg],"dilate") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
if (strcmp(arg[iarg+1],"all") == 0) allremap = 1;
else {
allremap = 0;
delete [] id_dilate;
int n = strlen(arg[iarg+2]) + 1;
id_dilate = new char[n];
strcpy(id_dilate,arg[iarg+2]);
int idilate = group->find(id_dilate);
if (idilate == -1)
error->all(FLERR,"Fix nvt/npt/nph dilate group ID does not exist");
}
iarg += 2;
} else if (strcmp(arg[iarg],"tchain") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
mtchain = atoi(arg[iarg+1]);
// used by FixNVTSllod to preserve non-default value
mtchain_default_flag = 0;
if (mtchain < 1) error->all(FLERR,"Illegal fix nvt/npt/nph command");
iarg += 2;
} else if (strcmp(arg[iarg],"pchain") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
mpchain = atoi(arg[iarg+1]);
if (mpchain < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command");
iarg += 2;
} else if (strcmp(arg[iarg],"mtk") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
if (strcmp(arg[iarg+1],"yes") == 0) mtk_flag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) mtk_flag = 0;
else error->all(FLERR,"Illegal fix nvt/npt/nph command");
iarg += 2;
} else if (strcmp(arg[iarg],"tloop") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
nc_tchain = atoi(arg[iarg+1]);
if (nc_tchain < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command");
iarg += 2;
} else if (strcmp(arg[iarg],"ploop") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
nc_pchain = atoi(arg[iarg+1]);
if (nc_pchain < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command");
iarg += 2;
} else if (strcmp(arg[iarg],"nreset") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
nreset_h0 = atoi(arg[iarg+1]);
if (nreset_h0 < 0) error->all(FLERR,"Illegal fix nvt/npt/nph command");
iarg += 2;
} else if (strcmp(arg[iarg],"scalexy") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
if (strcmp(arg[iarg+1],"yes") == 0) scalexy = 1;
else if (strcmp(arg[iarg+1],"no") == 0) scalexy = 0;
else error->all(FLERR,"Illegal fix nvt/npt/nph command");
iarg += 2;
} else if (strcmp(arg[iarg],"scalexz") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
if (strcmp(arg[iarg+1],"yes") == 0) scalexz = 1;
else if (strcmp(arg[iarg+1],"no") == 0) scalexz = 0;
else error->all(FLERR,"Illegal fix nvt/npt/nph command");
iarg += 2;
} else if (strcmp(arg[iarg],"scaleyz") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
if (strcmp(arg[iarg+1],"yes") == 0) scaleyz = 1;
else if (strcmp(arg[iarg+1],"no") == 0) scaleyz = 0;
else error->all(FLERR,"Illegal fix nvt/npt/nph command");
iarg += 2;
} else if (strcmp(arg[iarg],"fixedpoint") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix nvt/npt/nph command");
fixedpoint[0] = atof(arg[iarg+1]);
fixedpoint[1] = atof(arg[iarg+2]);
fixedpoint[2] = atof(arg[iarg+3]);
iarg += 4;
} else error->all(FLERR,"Illegal fix nvt/npt/nph command");
}
// error checks
if (dimension == 2 && (p_flag[2] || p_flag[3] || p_flag[4]))
error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation");
if (dimension == 2 && (pcouple == YZ || pcouple == XZ))
error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation");
if (dimension == 2 && (scalexz == 1 || scaleyz == 1 ))
error->all(FLERR,"Invalid fix nvt/npt/nph command for a 2d simulation");
if (pcouple == XYZ && (p_flag[0] == 0 || p_flag[1] == 0))
error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings");
if (pcouple == XYZ && dimension == 3 && p_flag[2] == 0)
error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings");
if (pcouple == XY && (p_flag[0] == 0 || p_flag[1] == 0))
error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings");
if (pcouple == YZ && (p_flag[1] == 0 || p_flag[2] == 0))
error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings");
if (pcouple == XZ && (p_flag[0] == 0 || p_flag[2] == 0))
error->all(FLERR,"Invalid fix nvt/npt/nph command pressure settings");
// require periodicity in tensile dimension
if (p_flag[0] && domain->xperiodic == 0)
error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension");
if (p_flag[1] && domain->yperiodic == 0)
error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension");
if (p_flag[2] && domain->zperiodic == 0)
error->all(FLERR,"Cannot use fix nvt/npt/nph on a non-periodic dimension");
// require periodicity in 2nd dim of off-diagonal tilt component
if (p_flag[3] && domain->zperiodic == 0)
error->all(FLERR,
"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension");
if (p_flag[4] && domain->zperiodic == 0)
error->all(FLERR,
"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension");
if (p_flag[5] && domain->yperiodic == 0)
error->all(FLERR,
"Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension");
if (scaleyz == 1 && domain->zperiodic == 0)
error->all(FLERR,"Cannot use fix nvt/npt/nph "
"with yz dynamics when z is non-periodic dimension");
if (scalexz == 1 && domain->zperiodic == 0)
error->all(FLERR,"Cannot use fix nvt/npt/nph "
"with xz dynamics when z is non-periodic dimension");
if (scalexy == 1 && domain->yperiodic == 0)
error->all(FLERR,"Cannot use fix nvt/npt/nph "
"with xy dynamics when y is non-periodic dimension");
if (p_flag[3] && scaleyz == 1)
error->all(FLERR,"Cannot use fix nvt/npt/nph with "
"both yz dynamics and yz scaling");
if (p_flag[4] && scalexz == 1)
error->all(FLERR,"Cannot use fix nvt/npt/nph with "
"both xz dynamics and xz scaling");
if (p_flag[5] && scalexy == 1)
error->all(FLERR,"Cannot use fix nvt/npt/nph with "
"both xy dynamics and xy scaling");
if (!domain->triclinic && (p_flag[3] || p_flag[4] || p_flag[5]))
error->all(FLERR,"Can not specify Pxy/Pxz/Pyz in "
"fix nvt/npt/nph with non-triclinic box");
if (pcouple == XYZ && dimension == 3 &&
(p_start[0] != p_start[1] || p_start[0] != p_start[2] ||
p_stop[0] != p_stop[1] || p_stop[0] != p_stop[2] ||
p_period[0] != p_period[1] || p_period[0] != p_period[2]))
error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings");
if (pcouple == XYZ && dimension == 2 &&
(p_start[0] != p_start[1] || p_stop[0] != p_stop[1] ||
p_period[0] != p_period[1]))
error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings");
if (pcouple == XY &&
(p_start[0] != p_start[1] || p_stop[0] != p_stop[1] ||
p_period[0] != p_period[1]))
error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings");
if (pcouple == YZ &&
(p_start[1] != p_start[2] || p_stop[1] != p_stop[2] ||
p_period[1] != p_period[2]))
error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings");
if (pcouple == XZ &&
(p_start[0] != p_start[2] || p_stop[0] != p_stop[2] ||
p_period[0] != p_period[2]))
error->all(FLERR,"Invalid fix nvt/npt/nph pressure settings");
if ((tstat_flag && t_period <= 0.0) ||
(p_flag[0] && p_period[0] <= 0.0) ||
(p_flag[1] && p_period[1] <= 0.0) ||
(p_flag[2] && p_period[2] <= 0.0) ||
(p_flag[3] && p_period[3] <= 0.0) ||
(p_flag[4] && p_period[4] <= 0.0) ||
(p_flag[5] && p_period[5] <= 0.0))
error->all(FLERR,"Fix nvt/npt/nph damping parameters must be > 0.0");
// set pstat_flag and box change and restart_pbc variables
pstat_flag = 0;
for (int i = 0; i < 6; i++)
if (p_flag[i]) pstat_flag = 1;
if (pstat_flag) {
box_change = 1;
if (p_flag[0] || p_flag[1] || p_flag[2]) box_change_size = 1;
if (p_flag[3] || p_flag[4] || p_flag[5]) box_change_shape = 1;
no_change_box = 1;
if (allremap == 0) restart_pbc = 1;
}
// pstyle = TRICLINIC if any off-diagonal term is controlled -> 6 dof
// else pstyle = ISO if XYZ coupling or XY coupling in 2d -> 1 dof
// else pstyle = ANISO -> 3 dof
if (p_flag[3] || p_flag[4] || p_flag[5]) pstyle = TRICLINIC;
else if (pcouple == XYZ || (dimension == 2 && pcouple == XY)) pstyle = ISO;
else pstyle = ANISO;
// reneighboring only forced if flips will occur due to shape changes
if (p_flag[3] || p_flag[4] || p_flag[5]) force_reneighbor = 1;
if (scaleyz || scalexz || scalexy) force_reneighbor = 1;
// convert input periods to frequencies
t_freq = 0.0;
p_freq[0] = p_freq[1] = p_freq[2] = p_freq[3] = p_freq[4] = p_freq[5] = 0.0;
if (tstat_flag) t_freq = 1.0 / t_period;
if (p_flag[0]) p_freq[0] = 1.0 / p_period[0];
if (p_flag[1]) p_freq[1] = 1.0 / p_period[1];
if (p_flag[2]) p_freq[2] = 1.0 / p_period[2];
if (p_flag[3]) p_freq[3] = 1.0 / p_period[3];
if (p_flag[4]) p_freq[4] = 1.0 / p_period[4];
if (p_flag[5]) p_freq[5] = 1.0 / p_period[5];
// Nose/Hoover temp and pressure init
size_vector = 0;
if (tstat_flag) {
int ich;
eta = new double[mtchain];
// add one extra dummy thermostat, set to zero
eta_dot = new double[mtchain+1];
eta_dot[mtchain] = 0.0;
eta_dotdot = new double[mtchain];
for (ich = 0; ich < mtchain; ich++) {
eta[ich] = eta_dot[ich] = eta_dotdot[ich] = 0.0;
}
eta_mass = new double[mtchain];
size_vector += 2*2*mtchain;
}
if (pstat_flag) {
omega[0] = omega[1] = omega[2] = 0.0;
omega_dot[0] = omega_dot[1] = omega_dot[2] = 0.0;
omega_mass[0] = omega_mass[1] = omega_mass[2] = 0.0;
omega[3] = omega[4] = omega[5] = 0.0;
omega_dot[3] = omega_dot[4] = omega_dot[5] = 0.0;
omega_mass[3] = omega_mass[4] = omega_mass[5] = 0.0;
if (pstyle == ISO) size_vector += 2*2*1;
else if (pstyle == ANISO) size_vector += 2*2*3;
else if (pstyle == TRICLINIC) size_vector += 2*2*6;
if (mpchain) {
int ich;
etap = new double[mpchain];
// add one extra dummy thermostat, set to zero
etap_dot = new double[mpchain+1];
etap_dot[mpchain] = 0.0;
etap_dotdot = new double[mpchain];
for (ich = 0; ich < mpchain; ich++) {
etap[ich] = etap_dot[ich] =
etap_dotdot[ich] = 0.0;
}
etap_mass = new double[mpchain];
size_vector += 2*2*mpchain;
}
if (deviatoric_flag) size_vector += 1;
}
nrigid = 0;
rfix = NULL;
if (force_reneighbor) irregular = new Irregular(lmp);
else irregular = NULL;
// initialize vol0,t0 to zero to signal uninitialized
// values then assigned in init(), if necessary
vol0 = t0 = 0.0;
}
/* ---------------------------------------------------------------------- */
FixNH::~FixNH()
{
delete [] id_dilate;
delete [] rfix;
delete irregular;
// delete temperature and pressure if fix created them
if (tflag) modify->delete_compute(id_temp);
delete [] id_temp;
if (tstat_flag) {
delete [] eta;
delete [] eta_dot;
delete [] eta_dotdot;
delete [] eta_mass;
}
if (pstat_flag) {
if (pflag) modify->delete_compute(id_press);
delete [] id_press;
if (mpchain) {
delete [] etap;
delete [] etap_dot;
delete [] etap_dotdot;
delete [] etap_mass;
}
}
}
/* ---------------------------------------------------------------------- */
int FixNH::setmask()
{
int mask = 0;
mask |= INITIAL_INTEGRATE;
mask |= FINAL_INTEGRATE;
mask |= THERMO_ENERGY;
mask |= INITIAL_INTEGRATE_RESPA;
mask |= FINAL_INTEGRATE_RESPA;
if (force_reneighbor) mask |= PRE_EXCHANGE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixNH::init()
{
// recheck that dilate group has not been deleted
if (allremap == 0) {
int idilate = group->find(id_dilate);
if (idilate == -1)
error->all(FLERR,"Fix nvt/npt/nph dilate group ID does not exist");
dilate_group_bit = group->bitmask[idilate];
}
// ensure no conflict with fix deform
if (pstat_flag)
for (int i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"deform") == 0) {
int *dimflag = ((FixDeform *) modify->fix[i])->dimflag;
if ((p_flag[0] && dimflag[0]) || (p_flag[1] && dimflag[1]) ||
(p_flag[2] && dimflag[2]) || (p_flag[3] && dimflag[3]) ||
(p_flag[4] && dimflag[4]) || (p_flag[5] && dimflag[5]))
error->all(FLERR,"Cannot use fix npt and fix deform on "
"same component of stress tensor");
}
// set temperature and pressure ptrs
int icompute = modify->find_compute(id_temp);
if (icompute < 0)
error->all(FLERR,"Temperature ID for fix nvt/nph/npt does not exist");
temperature = modify->compute[icompute];
if (temperature->tempbias) which = BIAS;
else which = NOBIAS;
if (pstat_flag) {
icompute = modify->find_compute(id_press);
if (icompute < 0)
error->all(FLERR,"Pressure ID for fix npt/nph does not exist");
pressure = modify->compute[icompute];
}
// set timesteps and frequencies
dtv = update->dt;
dtf = 0.5 * update->dt * force->ftm2v;
dthalf = 0.5 * update->dt;
dt4 = 0.25 * update->dt;
dt8 = 0.125 * update->dt;
dto = dthalf;
p_freq_max = 0.0;
if (pstat_flag) {
p_freq_max = MAX(p_freq[0],p_freq[1]);
p_freq_max = MAX(p_freq_max,p_freq[2]);
if (pstyle == TRICLINIC) {
p_freq_max = MAX(p_freq_max,p_freq[3]);
p_freq_max = MAX(p_freq_max,p_freq[4]);
p_freq_max = MAX(p_freq_max,p_freq[5]);
}
pdrag_factor = 1.0 - (update->dt * p_freq_max * drag / nc_pchain);
}
if (tstat_flag)
tdrag_factor = 1.0 - (update->dt * t_freq * drag / nc_tchain);
// tally the number of dimensions that are barostatted
// set initial volume and reference cell, if not already done
if (pstat_flag) {
pdim = p_flag[0] + p_flag[1] + p_flag[2];
if (vol0 == 0.0) {
if (dimension == 3) vol0 = domain->xprd * domain->yprd * domain->zprd;
else vol0 = domain->xprd * domain->yprd;
h0_inv[0] = domain->h_inv[0];
h0_inv[1] = domain->h_inv[1];
h0_inv[2] = domain->h_inv[2];
h0_inv[3] = domain->h_inv[3];
h0_inv[4] = domain->h_inv[4];
h0_inv[5] = domain->h_inv[5];
}
}
boltz = force->boltz;
nktv2p = force->nktv2p;
if (force->kspace) kspace_flag = 1;
else kspace_flag = 0;
if (strstr(update->integrate_style,"respa")) {
nlevels_respa = ((Respa *) update->integrate)->nlevels;
step_respa = ((Respa *) update->integrate)->step;
dto = 0.5*step_respa[0];
}
// detect if any rigid fixes exist so rigid bodies move when box is remapped
// rfix[] = indices to each fix rigid
delete [] rfix;
nrigid = 0;
rfix = NULL;
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->rigid_flag) nrigid++;
if (nrigid) {
rfix = new int[nrigid];
nrigid = 0;
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->rigid_flag) rfix[nrigid++] = i;
}
}
/* ----------------------------------------------------------------------
compute T,P before integrator starts
------------------------------------------------------------------------- */
void FixNH::setup(int vflag)
{
// initialize some quantities that were not available earlier
tdof = temperature->dof;
// t_target is needed by NPH and NPT in compute_scalar()
// If no thermostat or using fix nphug,
// t_target must be defined by other means.
if (tstat_flag && strcmp(style,"nphug") != 0) {
compute_temp_target();
} else if (pstat_flag) {
// t0 = reference temperature for masses
// cannot be done in init() b/c temperature cannot be called there
// is b/c Modify::init() inits computes after fixes due to dof dependence
// guesstimate a unit-dependent t0 if actual T = 0.0
// if it was read in from a restart file, leave it be
if (t0 == 0.0) {
t0 = temperature->compute_scalar();
if (t0 == 0.0) {
if (strcmp(update->unit_style,"lj") == 0) t0 = 1.0;
else t0 = 300.0;
}
}
t_target = t0;
}
if (pstat_flag) compute_press_target();
t_current = temperature->compute_scalar();
if (pstat_flag) {
if (pstyle == ISO) pressure->compute_scalar();
else pressure->compute_vector();
couple();
pressure->addstep(update->ntimestep+1);
}
// masses and initial forces on thermostat variables
if (tstat_flag) {
eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq);
for (int ich = 1; ich < mtchain; ich++)
eta_mass[ich] = boltz * t_target / (t_freq*t_freq);
for (int ich = 1; ich < mtchain; ich++) {
eta_dotdot[ich] = (eta_mass[ich-1]*eta_dot[ich-1]*eta_dot[ich-1] -
boltz * t_target) / eta_mass[ich];
}
}
// masses and initial forces on barostat variables
if (pstat_flag) {
double kt = boltz * t_target;
double nkt = atom->natoms * kt;
for (int i = 0; i < 3; i++)
if (p_flag[i])
omega_mass[i] = nkt/(p_freq[i]*p_freq[i]);
if (pstyle == TRICLINIC) {
for (int i = 3; i < 6; i++)
if (p_flag[i]) omega_mass[i] = nkt/(p_freq[i]*p_freq[i]);
}
// masses and initial forces on barostat thermostat variables
if (mpchain) {
etap_mass[0] = boltz * t_target / (p_freq_max*p_freq_max);
for (int ich = 1; ich < mpchain; ich++)
etap_mass[ich] = boltz * t_target / (p_freq_max*p_freq_max);
for (int ich = 1; ich < mpchain; ich++)
etap_dotdot[ich] =
(etap_mass[ich-1]*etap_dot[ich-1]*etap_dot[ich-1] -
boltz * t_target) / etap_mass[ich];
}
}
}
/* ----------------------------------------------------------------------
1st half of Verlet update
------------------------------------------------------------------------- */
void FixNH::initial_integrate(int vflag)
{
// update eta_press_dot
if (pstat_flag && mpchain) nhc_press_integrate();
// update eta_dot
if (tstat_flag) {
compute_temp_target();
nhc_temp_integrate();
}
// need to recompute pressure to account for change in KE
// t_current is up-to-date, but compute_temperature is not
// compute appropriately coupled elements of mvv_current
if (pstat_flag) {
if (pstyle == ISO) {
temperature->compute_scalar();
pressure->compute_scalar();
} else {
temperature->compute_vector();
pressure->compute_vector();
}
couple();
pressure->addstep(update->ntimestep+1);
}
if (pstat_flag) {
compute_press_target();
nh_omega_dot();
nh_v_press();
}
nve_v();
// remap simulation box by 1/2 step
if (pstat_flag) remap();
nve_x();
// remap simulation box by 1/2 step
// redo KSpace coeffs since volume has changed
if (pstat_flag) {
remap();
if (kspace_flag) force->kspace->setup();
}
}
/* ----------------------------------------------------------------------
2nd half of Verlet update
------------------------------------------------------------------------- */
void FixNH::final_integrate()
{
nve_v();
if (pstat_flag) nh_v_press();
// compute new T,P
// compute appropriately coupled elements of mvv_current
t_current = temperature->compute_scalar();
if (pstat_flag) {
if (pstyle == ISO) pressure->compute_scalar();
else pressure->compute_vector();
couple();
pressure->addstep(update->ntimestep+1);
}
if (pstat_flag) nh_omega_dot();
// update eta_dot
// update eta_press_dot
if (tstat_flag) nhc_temp_integrate();
if (pstat_flag && mpchain) nhc_press_integrate();
}
/* ---------------------------------------------------------------------- */
void FixNH::initial_integrate_respa(int vflag, int ilevel, int iloop)
{
// set timesteps by level
dtv = step_respa[ilevel];
dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
dthalf = 0.5 * step_respa[ilevel];
// outermost level - update eta_dot and omega_dot, apply to v
// all other levels - NVE update of v
// x,v updates only performed for atoms in group
if (ilevel == nlevels_respa-1) {
// update eta_press_dot
if (pstat_flag && mpchain) nhc_press_integrate();
// update eta_dot
if (tstat_flag) {
compute_temp_target();
nhc_temp_integrate();
}
// recompute pressure to account for change in KE
// t_current is up-to-date, but compute_temperature is not
// compute appropriately coupled elements of mvv_current
if (pstat_flag) {
if (pstyle == ISO) {
temperature->compute_scalar();
pressure->compute_scalar();
} else {
temperature->compute_vector();
pressure->compute_vector();
}
couple();
pressure->addstep(update->ntimestep+1);
}
if (pstat_flag) {
compute_press_target();
nh_omega_dot();
nh_v_press();
}
nve_v();
} else nve_v();
// innermost level - also update x only for atoms in group
// if barostat, perform 1/2 step remap before and after
if (ilevel == 0) {
if (pstat_flag) remap();
nve_x();
if (pstat_flag) remap();
}
// if barostat, redo KSpace coeffs at outermost level,
// since volume has changed
if (ilevel == nlevels_respa-1 && kspace_flag && pstat_flag)
force->kspace->setup();
}
/* ---------------------------------------------------------------------- */
void FixNH::final_integrate_respa(int ilevel, int iloop)
{
// set timesteps by level
dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
dthalf = 0.5 * step_respa[ilevel];
// outermost level - update eta_dot and omega_dot, apply via final_integrate
// all other levels - NVE update of v
if (ilevel == nlevels_respa-1) final_integrate();
else nve_v();
}
/* ---------------------------------------------------------------------- */
void FixNH::couple()
{
double *tensor = pressure->vector;
if (pstyle == ISO)
p_current[0] = p_current[1] = p_current[2] = pressure->scalar;
else if (pcouple == XYZ) {
double ave = 1.0/3.0 * (tensor[0] + tensor[1] + tensor[2]);
p_current[0] = p_current[1] = p_current[2] = ave;
} else if (pcouple == XY) {
double ave = 0.5 * (tensor[0] + tensor[1]);
p_current[0] = p_current[1] = ave;
p_current[2] = tensor[2];
} else if (pcouple == YZ) {
double ave = 0.5 * (tensor[1] + tensor[2]);
p_current[1] = p_current[2] = ave;
p_current[0] = tensor[0];
} else if (pcouple == XZ) {
double ave = 0.5 * (tensor[0] + tensor[2]);
p_current[0] = p_current[2] = ave;
p_current[1] = tensor[1];
} else {
p_current[0] = tensor[0];
p_current[1] = tensor[1];
p_current[2] = tensor[2];
}
// switch order from xy-xz-yz to Voigt
if (pstyle == TRICLINIC) {
p_current[3] = tensor[5];
p_current[4] = tensor[4];
p_current[5] = tensor[3];
}
}
/* ----------------------------------------------------------------------
change box size
remap all atoms or dilate group atoms depending on allremap flag
if rigid bodies exist, scale rigid body centers-of-mass
------------------------------------------------------------------------- */
void FixNH::remap()
{
int i;
double oldlo,oldhi;
double expfac;
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *h = domain->h;
// omega is not used, except for book-keeping
for (int i = 0; i < 6; i++) omega[i] += dto*omega_dot[i];
// convert pertinent atoms and rigid bodies to lamda coords
if (allremap) domain->x2lamda(nlocal);
else {
for (i = 0; i < nlocal; i++)
if (mask[i] & dilate_group_bit)
domain->x2lamda(x[i],x[i]);
}
if (nrigid)
for (i = 0; i < nrigid; i++)
modify->fix[rfix[i]]->deform(0);
// reset global and local box to new size/shape
// this operation corresponds to applying the
// translate and scale operations
// corresponding to the solution of the following ODE:
//
// h_dot = omega_dot * h
//
// where h_dot, omega_dot and h are all upper-triangular
// 3x3 tensors. In Voigt notation, the elements of the
// RHS product tensor are:
// h_dot = [0*0, 1*1, 2*2, 1*3+3*2, 0*4+5*3+4*2, 0*5+5*1]
//
// Ordering of operations preserves time symmetry.
double dto2 = dto/2.0;
double dto4 = dto/4.0;
double dto8 = dto/8.0;
// off-diagonal components, first half
if (pstyle == TRICLINIC) {
if (p_flag[4]) {
expfac = exp(dto8*omega_dot[0]);
h[4] *= expfac;
h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]);
h[4] *= expfac;
}
if (p_flag[3]) {
expfac = exp(dto4*omega_dot[1]);
h[3] *= expfac;
h[3] += dto2*(omega_dot[3]*h[2]);
h[3] *= expfac;
}
if (p_flag[5]) {
expfac = exp(dto4*omega_dot[0]);
h[5] *= expfac;
h[5] += dto2*(omega_dot[5]*h[1]);
h[5] *= expfac;
}
if (p_flag[4]) {
expfac = exp(dto8*omega_dot[0]);
h[4] *= expfac;
h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]);
h[4] *= expfac;
}
}
// scale diagonal components
// scale tilt factors with cell, if set
if (p_flag[0]) {
oldlo = domain->boxlo[0];
oldhi = domain->boxhi[0];
expfac = exp(dto*omega_dot[0]);
domain->boxlo[0] = (oldlo-fixedpoint[0])*expfac + fixedpoint[0];
domain->boxhi[0] = (oldhi-fixedpoint[0])*expfac + fixedpoint[0];
}
if (p_flag[1]) {
oldlo = domain->boxlo[1];
oldhi = domain->boxhi[1];
expfac = exp(dto*omega_dot[1]);
domain->boxlo[1] = (oldlo-fixedpoint[1])*expfac + fixedpoint[1];
domain->boxhi[1] = (oldhi-fixedpoint[1])*expfac + fixedpoint[1];
if (scalexy) h[5] *= expfac;
}
if (p_flag[2]) {
oldlo = domain->boxlo[2];
oldhi = domain->boxhi[2];
expfac = exp(dto*omega_dot[2]);
domain->boxlo[2] = (oldlo-fixedpoint[2])*expfac + fixedpoint[2];
domain->boxhi[2] = (oldhi-fixedpoint[2])*expfac + fixedpoint[2];
if (scalexz) h[4] *= expfac;
if (scaleyz) h[3] *= expfac;
}
// off-diagonal components, second half
if (pstyle == TRICLINIC) {
if (p_flag[4]) {
expfac = exp(dto8*omega_dot[0]);
h[4] *= expfac;
h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]);
h[4] *= expfac;
}
if (p_flag[3]) {
expfac = exp(dto4*omega_dot[1]);
h[3] *= expfac;
h[3] += dto2*(omega_dot[3]*h[2]);
h[3] *= expfac;
}
if (p_flag[5]) {
expfac = exp(dto4*omega_dot[0]);
h[5] *= expfac;
h[5] += dto2*(omega_dot[5]*h[1]);
h[5] *= expfac;
}
if (p_flag[4]) {
expfac = exp(dto8*omega_dot[0]);
h[4] *= expfac;
h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]);
h[4] *= expfac;
}
}
domain->yz = h[3];
domain->xz = h[4];
domain->xy = h[5];
// tilt factor to cell length ratio can not exceed TILTMAX in one step
if (domain->yz < -TILTMAX*domain->yprd ||
domain->yz > TILTMAX*domain->yprd ||
domain->xz < -TILTMAX*domain->xprd ||
domain->xz > TILTMAX*domain->xprd ||
domain->xy < -TILTMAX*domain->xprd ||
domain->xy > TILTMAX*domain->xprd)
error->all(FLERR,"Fix npt/nph has tilted box too far in one step - "
"periodic cell is too far from equilibrium state");
domain->set_global_box();
domain->set_local_box();
// convert pertinent atoms and rigid bodies back to box coords
if (allremap) domain->lamda2x(nlocal);
else {
for (i = 0; i < nlocal; i++)
if (mask[i] & dilate_group_bit)
domain->lamda2x(x[i],x[i]);
}
if (nrigid)
for (i = 0; i < nrigid; i++)
modify->fix[rfix[i]]->deform(1);
}
/* ----------------------------------------------------------------------
pack entire state of Fix into one write
------------------------------------------------------------------------- */
void FixNH::write_restart(FILE *fp)
{
int nsize = size_restart_global();
double *list;
memory->create(list,nsize,"nh:list");
int n = pack_restart_data(list);
if (comm->me == 0) {
int size = nsize * sizeof(double);
fwrite(&size,sizeof(int),1,fp);
fwrite(list,sizeof(double),nsize,fp);
}
memory->destroy(list);
}
/* ----------------------------------------------------------------------
calculate the number of data to be packed
------------------------------------------------------------------------- */
int FixNH::size_restart_global()
{
int nsize = 2;
if (tstat_flag) nsize += 1 + 2*mtchain;
if (pstat_flag) {
nsize += 16 + 2*mpchain;
if (deviatoric_flag) nsize += 6;
}
return nsize;
}
/* ----------------------------------------------------------------------
pack restart data
------------------------------------------------------------------------- */
int FixNH::pack_restart_data(double *list)
{
int n = 0;
list[n++] = tstat_flag;
if (tstat_flag) {
list[n++] = mtchain;
for (int ich = 0; ich < mtchain; ich++)
list[n++] = eta[ich];
for (int ich = 0; ich < mtchain; ich++)
list[n++] = eta_dot[ich];
}
list[n++] = pstat_flag;
if (pstat_flag) {
list[n++] = omega[0];
list[n++] = omega[1];
list[n++] = omega[2];
list[n++] = omega[3];
list[n++] = omega[4];
list[n++] = omega[5];
list[n++] = omega_dot[0];
list[n++] = omega_dot[1];
list[n++] = omega_dot[2];
list[n++] = omega_dot[3];
list[n++] = omega_dot[4];
list[n++] = omega_dot[5];
list[n++] = vol0;
list[n++] = t0;
list[n++] = mpchain;
if (mpchain) {
for (int ich = 0; ich < mpchain; ich++)
list[n++] = etap[ich];
for (int ich = 0; ich < mpchain; ich++)
list[n++] = etap_dot[ich];
}
list[n++] = deviatoric_flag;
if (deviatoric_flag) {
list[n++] = h0_inv[0];
list[n++] = h0_inv[1];
list[n++] = h0_inv[2];
list[n++] = h0_inv[3];
list[n++] = h0_inv[4];
list[n++] = h0_inv[5];
}
}
return n;
}
/* ----------------------------------------------------------------------
use state info from restart file to restart the Fix
------------------------------------------------------------------------- */
void FixNH::restart(char *buf)
{
int n = 0;
double *list = (double *) buf;
int flag = static_cast<int> (list[n++]);
if (flag) {
int m = static_cast<int> (list[n++]);
if (tstat_flag && m == mtchain) {
for (int ich = 0; ich < mtchain; ich++)
eta[ich] = list[n++];
for (int ich = 0; ich < mtchain; ich++)
eta_dot[ich] = list[n++];
} else n += 2*m;
}
flag = static_cast<int> (list[n++]);
if (flag) {
omega[0] = list[n++];
omega[1] = list[n++];
omega[2] = list[n++];
omega[3] = list[n++];
omega[4] = list[n++];
omega[5] = list[n++];
omega_dot[0] = list[n++];
omega_dot[1] = list[n++];
omega_dot[2] = list[n++];
omega_dot[3] = list[n++];
omega_dot[4] = list[n++];
omega_dot[5] = list[n++];
vol0 = list[n++];
t0 = list[n++];
int m = static_cast<int> (list[n++]);
if (pstat_flag && m == mpchain) {
for (int ich = 0; ich < mpchain; ich++)
etap[ich] = list[n++];
for (int ich = 0; ich < mpchain; ich++)
etap_dot[ich] = list[n++];
} else n+=2*m;
flag = static_cast<int> (list[n++]);
if (flag) {
h0_inv[0] = list[n++];
h0_inv[1] = list[n++];
h0_inv[2] = list[n++];
h0_inv[3] = list[n++];
h0_inv[4] = list[n++];
h0_inv[5] = list[n++];
}
}
}
/* ---------------------------------------------------------------------- */
int FixNH::modify_param(int narg, char **arg)
{
if (strcmp(arg[0],"temp") == 0) {
if (narg < 2) error->all(FLERR,"Illegal fix_modify command");
if (tflag) {
modify->delete_compute(id_temp);
tflag = 0;
}
delete [] id_temp;
int n = strlen(arg[1]) + 1;
id_temp = new char[n];
strcpy(id_temp,arg[1]);
int icompute = modify->find_compute(arg[1]);
if (icompute < 0)
error->all(FLERR,"Could not find fix_modify temperature ID");
temperature = modify->compute[icompute];
if (temperature->tempflag == 0)
error->all(FLERR,
"Fix_modify temperature ID does not compute temperature");
if (temperature->igroup != 0 && comm->me == 0)
error->warning(FLERR,"Temperature for fix modify is not for group all");
// reset id_temp of pressure to new temperature ID
if (pstat_flag) {
icompute = modify->find_compute(id_press);
if (icompute < 0)
error->all(FLERR,"Pressure ID for fix modify does not exist");
modify->compute[icompute]->reset_extra_compute_fix(id_temp);
}
return 2;
} else if (strcmp(arg[0],"press") == 0) {
if (narg < 2) error->all(FLERR,"Illegal fix_modify command");
if (!pstat_flag) error->all(FLERR,"Illegal fix_modify command");
if (pflag) {
modify->delete_compute(id_press);
pflag = 0;
}
delete [] id_press;
int n = strlen(arg[1]) + 1;
id_press = new char[n];
strcpy(id_press,arg[1]);
int icompute = modify->find_compute(arg[1]);
if (icompute < 0) error->all(FLERR,"Could not find fix_modify pressure ID");
pressure = modify->compute[icompute];
if (pressure->pressflag == 0)
error->all(FLERR,"Fix_modify pressure ID does not compute pressure");
return 2;
}
return 0;
}
/* ---------------------------------------------------------------------- */
double FixNH::compute_scalar()
{
int i;
double volume;
double energy;
double kt = boltz * t_target;
double lkt_press = kt;
int ich;
if (dimension == 3) volume = domain->xprd * domain->yprd * domain->zprd;
else volume = domain->xprd * domain->yprd;
energy = 0.0;
// thermostat chain energy is equivalent to Eq. (2) in
// Martyna, Tuckerman, Tobias, Klein, Mol Phys, 87, 1117
// Sum(0.5*p_eta_k^2/Q_k,k=1,M) + L*k*T*eta_1 + Sum(k*T*eta_k,k=2,M),
// where L = tdof
// M = mtchain
// p_eta_k = Q_k*eta_dot[k-1]
// Q_1 = L*k*T/t_freq^2
// Q_k = k*T/t_freq^2, k > 1
if (tstat_flag) {
energy += ke_target * eta[0] + 0.5*eta_mass[0]*eta_dot[0]*eta_dot[0];
for (ich = 1; ich < mtchain; ich++)
energy += kt * eta[ich] + 0.5*eta_mass[ich]*eta_dot[ich]*eta_dot[ich];
}
// barostat energy is equivalent to Eq. (8) in
// Martyna, Tuckerman, Tobias, Klein, Mol Phys, 87, 1117
// Sum(0.5*p_omega^2/W + P*V),
// where N = natoms
// p_omega = W*omega_dot
// W = N*k*T/p_freq^2
// sum is over barostatted dimensions
if (pstat_flag) {
for (i = 0; i < 3; i++)
if (p_flag[i])
energy += 0.5*omega_dot[i]*omega_dot[i]*omega_mass[i] +
p_hydro*(volume-vol0) / (pdim*nktv2p);
if (pstyle == TRICLINIC) {
for (i = 3; i < 6; i++)
if (p_flag[i])
energy += 0.5*omega_dot[i]*omega_dot[i]*omega_mass[i];
}
// extra contributions from thermostat chain for barostat
if (mpchain) {
energy += lkt_press * etap[0] + 0.5*etap_mass[0]*etap_dot[0]*etap_dot[0];
for (ich = 1; ich < mpchain; ich++)
energy += kt * etap[ich] +
0.5*etap_mass[ich]*etap_dot[ich]*etap_dot[ich];
}
// extra contribution from strain energy
if (deviatoric_flag) energy += compute_strain_energy();
}
return energy;
}
/* ----------------------------------------------------------------------
return a single element of the following vectors, in this order:
eta[tchain], eta_dot[tchain], omega[ndof], omega_dot[ndof]
etap[pchain], etap_dot[pchain], PE_eta[tchain], KE_eta_dot[tchain]
PE_omega[ndof], KE_omega_dot[ndof], PE_etap[pchain], KE_etap_dot[pchain]
PE_strain[1]
if no thermostat exists, related quantities are omitted from the list
if no barostat exists, related quantities are omitted from the list
ndof = 1,3,6 degrees of freedom for pstyle = ISO,ANISO,TRI
------------------------------------------------------------------------- */
double FixNH::compute_vector(int n)
{
int ilen;
if (tstat_flag) {
ilen = mtchain;
if (n < ilen) return eta[n];
n -= ilen;
ilen = mtchain;
if (n < ilen) return eta_dot[n];
n -= ilen;
}
if (pstat_flag) {
if (pstyle == ISO) {
ilen = 1;
if (n < ilen) return omega[n];
n -= ilen;
} else if (pstyle == ANISO) {
ilen = 3;
if (n < ilen) return omega[n];
n -= ilen;
} else {
ilen = 6;
if (n < ilen) return omega[n];
n -= ilen;
}
if (pstyle == ISO) {
ilen = 1;
if (n < ilen) return omega_dot[n];
n -= ilen;
} else if (pstyle == ANISO) {
ilen = 3;
if (n < ilen) return omega_dot[n];
n -= ilen;
} else {
ilen = 6;
if (n < ilen) return omega_dot[n];
n -= ilen;
}
if (mpchain) {
ilen = mpchain;
if (n < ilen) return etap[n];
n -= ilen;
ilen = mpchain;
if (n < ilen) return etap_dot[n];
n -= ilen;
}
}
double volume;
double kt = boltz * t_target;
double lkt_press = kt;
int ich;
if (dimension == 3) volume = domain->xprd * domain->yprd * domain->zprd;
else volume = domain->xprd * domain->yprd;
if (tstat_flag) {
ilen = mtchain;
if (n < ilen) {
ich = n;
if (ich == 0)
return ke_target * eta[0];
else
return kt * eta[ich];
}
n -= ilen;
ilen = mtchain;
if (n < ilen) {
ich = n;
if (ich == 0)
return 0.5*eta_mass[0]*eta_dot[0]*eta_dot[0];
else
return 0.5*eta_mass[ich]*eta_dot[ich]*eta_dot[ich];
}
n -= ilen;
}
if (pstat_flag) {
if (pstyle == ISO) {
ilen = 1;
if (n < ilen)
return p_hydro*(volume-vol0) / nktv2p;
n -= ilen;
} else if (pstyle == ANISO) {
ilen = 3;
if (n < ilen)
if (p_flag[n])
return p_hydro*(volume-vol0) / (pdim*nktv2p);
else
return 0.0;
n -= ilen;
} else {
ilen = 6;
if (n < ilen)
if (n > 2) return 0.0;
else if (p_flag[n])
return p_hydro*(volume-vol0) / (pdim*nktv2p);
else
return 0.0;
n -= ilen;
}
if (pstyle == ISO) {
ilen = 1;
if (n < ilen)
return pdim*0.5*omega_dot[n]*omega_dot[n]*omega_mass[n];
n -= ilen;
} else if (pstyle == ANISO) {
ilen = 3;
if (n < ilen)
if (p_flag[n])
return 0.5*omega_dot[n]*omega_dot[n]*omega_mass[n];
else return 0.0;
n -= ilen;
} else {
ilen = 6;
if (n < ilen)
if (p_flag[n])
return 0.5*omega_dot[n]*omega_dot[n]*omega_mass[n];
else return 0.0;
n -= ilen;
}
if (mpchain) {
ilen = mpchain;
if (n < ilen) {
ich = n;
if (ich == 0) return lkt_press * etap[0];
else return kt * etap[ich];
}
n -= ilen;
ilen = mpchain;
if (n < ilen) {
ich = n;
if (ich == 0)
return 0.5*etap_mass[0]*etap_dot[0]*etap_dot[0];
else
return 0.5*etap_mass[ich]*etap_dot[ich]*etap_dot[ich];
}
n -= ilen;
}
if (deviatoric_flag) {
ilen = 1;
if (n < ilen)
return compute_strain_energy();
n -= ilen;
}
}
return 0.0;
}
/* ---------------------------------------------------------------------- */
void FixNH::reset_target(double t_new)
{
t_target = t_start = t_stop = t_new;
}
/* ---------------------------------------------------------------------- */
void FixNH::reset_dt()
{
dtv = update->dt;
dtf = 0.5 * update->dt * force->ftm2v;
dthalf = 0.5 * update->dt;
dt4 = 0.25 * update->dt;
dt8 = 0.125 * update->dt;
dto = dthalf;
// If using respa, then remap is performed in innermost level
if (strstr(update->integrate_style,"respa"))
dto = 0.5*step_respa[0];
if (pstat_flag)
pdrag_factor = 1.0 - (update->dt * p_freq_max * drag / nc_pchain);
if (tstat_flag)
tdrag_factor = 1.0 - (update->dt * t_freq * drag / nc_tchain);
}
/* ----------------------------------------------------------------------
extract thermostat properties
------------------------------------------------------------------------- */
void *FixNH::extract(const char *str, int &dim)
{
dim=0;
if (strcmp(str,"t_target") == 0) {
return &t_target;
}
return NULL;
}
/* ----------------------------------------------------------------------
perform half-step update of chain thermostat variables
------------------------------------------------------------------------- */
void FixNH::nhc_temp_integrate()
{
int ich;
double expfac;
double kecurrent = tdof * boltz * t_current;
// Update masses, to preserve initial freq, if flag set
if (eta_mass_flag) {
eta_mass[0] = tdof * boltz * t_target / (t_freq*t_freq);
for (int ich = 1; ich < mtchain; ich++)
eta_mass[ich] = boltz * t_target / (t_freq*t_freq);
}
if (eta_mass[0] > 0.0)
eta_dotdot[0] = (kecurrent - ke_target)/eta_mass[0];
else eta_dotdot[0] = 0.0;
double ncfac = 1.0/nc_tchain;
for (int iloop = 0; iloop < nc_tchain; iloop++) {
for (ich = mtchain-1; ich > 0; ich--) {
expfac = exp(-ncfac*dt8*eta_dot[ich+1]);
eta_dot[ich] *= expfac;
eta_dot[ich] += eta_dotdot[ich] * ncfac*dt4;
eta_dot[ich] *= tdrag_factor;
eta_dot[ich] *= expfac;
}
expfac = exp(-ncfac*dt8*eta_dot[1]);
eta_dot[0] *= expfac;
eta_dot[0] += eta_dotdot[0] * ncfac*dt4;
eta_dot[0] *= tdrag_factor;
eta_dot[0] *= expfac;
factor_eta = exp(-ncfac*dthalf*eta_dot[0]);
nh_v_temp();
// rescale temperature due to velocity scaling
// should not be necessary to explicitly recompute the temperature
t_current *= factor_eta*factor_eta;
kecurrent = tdof * boltz * t_current;
if (eta_mass[0] > 0.0)
eta_dotdot[0] = (kecurrent - ke_target)/eta_mass[0];
else eta_dotdot[0] = 0.0;
for (ich = 0; ich < mtchain; ich++)
eta[ich] += ncfac*dthalf*eta_dot[ich];
eta_dot[0] *= expfac;
eta_dot[0] += eta_dotdot[0] * ncfac*dt4;
eta_dot[0] *= expfac;
for (ich = 1; ich < mtchain; ich++) {
expfac = exp(-ncfac*dt8*eta_dot[ich+1]);
eta_dot[ich] *= expfac;
eta_dotdot[ich] = (eta_mass[ich-1]*eta_dot[ich-1]*eta_dot[ich-1]
- boltz * t_target)/eta_mass[ich];
eta_dot[ich] += eta_dotdot[ich] * ncfac*dt4;
eta_dot[ich] *= expfac;
}
}
}
/* ----------------------------------------------------------------------
perform half-step update of chain thermostat variables for barostat
scale barostat velocities
------------------------------------------------------------------------- */
void FixNH::nhc_press_integrate()
{
int ich,i;
double expfac,factor_etap,kecurrent;
double kt = boltz * t_target;
double lkt_press = kt;
// Update masses, to preserve initial freq, if flag set
if (omega_mass_flag) {
double nkt = atom->natoms * kt;
for (int i = 0; i < 3; i++)
if (p_flag[i])
omega_mass[i] = nkt/(p_freq[i]*p_freq[i]);
if (pstyle == TRICLINIC) {
for (int i = 3; i < 6; i++)
if (p_flag[i]) omega_mass[i] = nkt/(p_freq[i]*p_freq[i]);
}
}
if (etap_mass_flag) {
if (mpchain) {
etap_mass[0] = boltz * t_target / (p_freq_max*p_freq_max);
for (int ich = 1; ich < mpchain; ich++)
etap_mass[ich] = boltz * t_target / (p_freq_max*p_freq_max);
for (int ich = 1; ich < mpchain; ich++)
etap_dotdot[ich] =
(etap_mass[ich-1]*etap_dot[ich-1]*etap_dot[ich-1] -
boltz * t_target) / etap_mass[ich];
}
}
kecurrent = 0.0;
for (i = 0; i < 3; i++)
if (p_flag[i]) kecurrent += omega_mass[i]*omega_dot[i]*omega_dot[i];
if (pstyle == TRICLINIC) {
for (i = 3; i < 6; i++)
if (p_flag[i]) kecurrent += omega_mass[i]*omega_dot[i]*omega_dot[i];
}
etap_dotdot[0] = (kecurrent - lkt_press)/etap_mass[0];
double ncfac = 1.0/nc_pchain;
for (int iloop = 0; iloop < nc_pchain; iloop++) {
for (ich = mpchain-1; ich > 0; ich--) {
expfac = exp(-ncfac*dt8*etap_dot[ich+1]);
etap_dot[ich] *= expfac;
etap_dot[ich] += etap_dotdot[ich] * ncfac*dt4;
etap_dot[ich] *= pdrag_factor;
etap_dot[ich] *= expfac;
}
expfac = exp(-ncfac*dt8*etap_dot[1]);
etap_dot[0] *= expfac;
etap_dot[0] += etap_dotdot[0] * ncfac*dt4;
etap_dot[0] *= pdrag_factor;
etap_dot[0] *= expfac;
for (ich = 0; ich < mpchain; ich++)
etap[ich] += ncfac*dthalf*etap_dot[ich];
factor_etap = exp(-ncfac*dthalf*etap_dot[0]);
for (i = 0; i < 3; i++)
if (p_flag[i]) omega_dot[i] *= factor_etap;
if (pstyle == TRICLINIC) {
for (i = 3; i < 6; i++)
if (p_flag[i]) omega_dot[i] *= factor_etap;
}
kecurrent = 0.0;
for (i = 0; i < 3; i++)
if (p_flag[i]) kecurrent += omega_mass[i]*omega_dot[i]*omega_dot[i];
if (pstyle == TRICLINIC) {
for (i = 3; i < 6; i++)
if (p_flag[i]) kecurrent += omega_mass[i]*omega_dot[i]*omega_dot[i];
}
etap_dotdot[0] = (kecurrent - lkt_press)/etap_mass[0];
etap_dot[0] *= expfac;
etap_dot[0] += etap_dotdot[0] * ncfac*dt4;
etap_dot[0] *= expfac;
for (ich = 1; ich < mpchain; ich++) {
expfac = exp(-ncfac*dt8*etap_dot[ich+1]);
etap_dot[ich] *= expfac;
etap_dotdot[ich] =
(etap_mass[ich-1]*etap_dot[ich-1]*etap_dot[ich-1] - boltz*t_target) /
etap_mass[ich];
etap_dot[ich] += etap_dotdot[ich] * ncfac*dt4;
etap_dot[ich] *= expfac;
}
}
}
/* ----------------------------------------------------------------------
perform half-step barostat scaling of velocities
-----------------------------------------------------------------------*/
void FixNH::nh_v_press()
{
double factor[3];
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (igroup == atom->firstgroup) nlocal = atom->nfirst;
factor[0] = exp(-dt4*(omega_dot[0]+mtk_term2));
factor[1] = exp(-dt4*(omega_dot[1]+mtk_term2));
factor[2] = exp(-dt4*(omega_dot[2]+mtk_term2));
if (which == NOBIAS) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
v[i][0] *= factor[0];
v[i][1] *= factor[1];
v[i][2] *= factor[2];
if (pstyle == TRICLINIC) {
v[i][0] += -dthalf*(v[i][1]*omega_dot[5] + v[i][2]*omega_dot[4]);
v[i][1] += -dthalf*v[i][2]*omega_dot[3];
}
v[i][0] *= factor[0];
v[i][1] *= factor[1];
v[i][2] *= factor[2];
}
}
} else if (which == BIAS) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
temperature->remove_bias(i,v[i]);
v[i][0] *= factor[0];
v[i][1] *= factor[1];
v[i][2] *= factor[2];
if (pstyle == TRICLINIC) {
v[i][0] += -dthalf*(v[i][1]*omega_dot[5] + v[i][2]*omega_dot[4]);
v[i][1] += -dthalf*v[i][2]*omega_dot[3];
}
v[i][0] *= factor[0];
v[i][1] *= factor[1];
v[i][2] *= factor[2];
temperature->restore_bias(i,v[i]);
}
}
}
}
/* ----------------------------------------------------------------------
perform half-step update of velocities
-----------------------------------------------------------------------*/
void FixNH::nve_v()
{
double dtfm;
double **v = atom->v;
double **f = atom->f;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (igroup == atom->firstgroup) nlocal = atom->nfirst;
if (rmass) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
dtfm = dtf / rmass[i];
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++) {
if (mask[i] & groupbit) {
dtfm = dtf / mass[type[i]];
v[i][0] += dtfm*f[i][0];
v[i][1] += dtfm*f[i][1];
v[i][2] += dtfm*f[i][2];
}
}
}
}
/* ----------------------------------------------------------------------
perform full-step update of positions
-----------------------------------------------------------------------*/
void FixNH::nve_x()
{
double **x = atom->x;
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (igroup == atom->firstgroup) nlocal = atom->nfirst;
// x update by full step only for atoms in group
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
x[i][0] += dtv * v[i][0];
x[i][1] += dtv * v[i][1];
x[i][2] += dtv * v[i][2];
}
}
}
/* ----------------------------------------------------------------------
perform half-step thermostat scaling of velocities
-----------------------------------------------------------------------*/
void FixNH::nh_v_temp()
{
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (igroup == atom->firstgroup) nlocal = atom->nfirst;
if (which == NOBIAS) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
v[i][0] *= factor_eta;
v[i][1] *= factor_eta;
v[i][2] *= factor_eta;
}
}
} else if (which == BIAS) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
temperature->remove_bias(i,v[i]);
v[i][0] *= factor_eta;
v[i][1] *= factor_eta;
v[i][2] *= factor_eta;
temperature->restore_bias(i,v[i]);
}
}
}
}
/* ----------------------------------------------------------------------
compute sigma tensor
needed whenever p_target or h0_inv changes
-----------------------------------------------------------------------*/
void FixNH::compute_sigma()
{
// if nreset_h0 > 0, reset vol0 and h0_inv
// every nreset_h0 timesteps
if (nreset_h0 > 0) {
int delta = update->ntimestep - update->beginstep;
if (delta % nreset_h0 == 0) {
if (dimension == 3) vol0 = domain->xprd * domain->yprd * domain->zprd;
else vol0 = domain->xprd * domain->yprd;
h0_inv[0] = domain->h_inv[0];
h0_inv[1] = domain->h_inv[1];
h0_inv[2] = domain->h_inv[2];
h0_inv[3] = domain->h_inv[3];
h0_inv[4] = domain->h_inv[4];
h0_inv[5] = domain->h_inv[5];
}
}
// generate upper-triangular half of
// sigma = vol0*h0inv*(p_target-p_hydro)*h0inv^t
// units of sigma are are PV/L^2 e.g. atm.A
//
// [ 0 5 4 ] [ 0 5 4 ] [ 0 5 4 ] [ 0 - - ]
// [ 5 1 3 ] = [ - 1 3 ] [ 5 1 3 ] [ 5 1 - ]
// [ 4 3 2 ] [ - - 2 ] [ 4 3 2 ] [ 4 3 2 ]
sigma[0] =
vol0*(h0_inv[0]*((p_target[0]-p_hydro)*h0_inv[0] +
p_target[5]*h0_inv[5]+p_target[4]*h0_inv[4]) +
h0_inv[5]*(p_target[5]*h0_inv[0] +
(p_target[1]-p_hydro)*h0_inv[5]+p_target[3]*h0_inv[4]) +
h0_inv[4]*(p_target[4]*h0_inv[0]+p_target[3]*h0_inv[5] +
(p_target[2]-p_hydro)*h0_inv[4]));
sigma[1] =
vol0*(h0_inv[1]*((p_target[1]-p_hydro)*h0_inv[1] +
p_target[3]*h0_inv[3]) +
h0_inv[3]*(p_target[3]*h0_inv[1] +
(p_target[2]-p_hydro)*h0_inv[3]));
sigma[2] =
vol0*(h0_inv[2]*((p_target[2]-p_hydro)*h0_inv[2]));
sigma[3] =
vol0*(h0_inv[1]*(p_target[3]*h0_inv[2]) +
h0_inv[3]*((p_target[2]-p_hydro)*h0_inv[2]));
sigma[4] =
vol0*(h0_inv[0]*(p_target[4]*h0_inv[2]) +
h0_inv[5]*(p_target[3]*h0_inv[2]) +
h0_inv[4]*((p_target[2]-p_hydro)*h0_inv[2]));
sigma[5] =
vol0*(h0_inv[0]*(p_target[5]*h0_inv[1]+p_target[4]*h0_inv[3]) +
h0_inv[5]*((p_target[1]-p_hydro)*h0_inv[1]+p_target[3]*h0_inv[3]) +
h0_inv[4]*(p_target[3]*h0_inv[1]+(p_target[2]-p_hydro)*h0_inv[3]));
}
/* ----------------------------------------------------------------------
compute strain energy
-----------------------------------------------------------------------*/
double FixNH::compute_strain_energy()
{
// compute strain energy = 0.5*Tr(sigma*h*h^t) in energy units
double* h = domain->h;
double d0,d1,d2;
d0 =
sigma[0]*(h[0]*h[0]+h[5]*h[5]+h[4]*h[4]) +
sigma[5]*( h[1]*h[5]+h[3]*h[4]) +
sigma[4]*( h[2]*h[4]);
d1 =
sigma[5]*( h[5]*h[1]+h[4]*h[3]) +
sigma[1]*( h[1]*h[1]+h[3]*h[3]) +
sigma[3]*( h[2]*h[3]);
d2 =
sigma[4]*( h[4]*h[2]) +
sigma[3]*( h[3]*h[2]) +
sigma[2]*( h[2]*h[2]);
double energy = 0.5*(d0+d1+d2)/nktv2p;
return energy;
}
/* ----------------------------------------------------------------------
compute deviatoric barostat force = h*sigma*h^t
-----------------------------------------------------------------------*/
void FixNH::compute_deviatoric()
{
// generate upper-triangular part of h*sigma*h^t
// units of fdev are are PV, e.g. atm*A^3
// [ 0 5 4 ] [ 0 5 4 ] [ 0 5 4 ] [ 0 - - ]
// [ 5 1 3 ] = [ - 1 3 ] [ 5 1 3 ] [ 5 1 - ]
// [ 4 3 2 ] [ - - 2 ] [ 4 3 2 ] [ 4 3 2 ]
double* h = domain->h;
fdev[0] =
h[0]*(sigma[0]*h[0]+sigma[5]*h[5]+sigma[4]*h[4]) +
h[5]*(sigma[5]*h[0]+sigma[1]*h[5]+sigma[3]*h[4]) +
h[4]*(sigma[4]*h[0]+sigma[3]*h[5]+sigma[2]*h[4]);
fdev[1] =
h[1]*( sigma[1]*h[1]+sigma[3]*h[3]) +
h[3]*( sigma[3]*h[1]+sigma[2]*h[3]);
fdev[2] =
h[2]*( sigma[2]*h[2]);
fdev[3] =
h[1]*( sigma[3]*h[2]) +
h[3]*( sigma[2]*h[2]);
fdev[4] =
h[0]*( sigma[4]*h[2]) +
h[5]*( sigma[3]*h[2]) +
h[4]*( sigma[2]*h[2]);
fdev[5] =
h[0]*( sigma[5]*h[1]+sigma[4]*h[3]) +
h[5]*( sigma[1]*h[1]+sigma[3]*h[3]) +
h[4]*( sigma[3]*h[1]+sigma[2]*h[3]);
}
/* ----------------------------------------------------------------------
compute target temperature and kinetic energy
-----------------------------------------------------------------------*/
void FixNH::compute_temp_target()
{
double delta = update->ntimestep - update->beginstep;
if (update->endstep > update->beginstep)
delta /= update->endstep - update->beginstep;
else delta = 0.0;
t_target = t_start + delta * (t_stop-t_start);
ke_target = tdof * boltz * t_target;
}
/* ----------------------------------------------------------------------
compute hydrostatic target pressure
-----------------------------------------------------------------------*/
void FixNH::compute_press_target()
{
double delta = update->ntimestep - update->beginstep;
if (update->endstep > update->beginstep)
delta /= update->endstep - update->beginstep;
else delta = 0.0;
p_hydro = 0.0;
for (int i = 0; i < 3; i++)
if (p_flag[i]) {
p_target[i] = p_start[i] + delta * (p_stop[i]-p_start[i]);
p_hydro += p_target[i];
}
p_hydro /= pdim;
if (pstyle == TRICLINIC)
for (int i = 3; i < 6; i++)
p_target[i] = p_start[i] + delta * (p_stop[i]-p_start[i]);
// if deviatoric, recompute sigma each time p_target changes
if (deviatoric_flag) compute_sigma();
}
/* ----------------------------------------------------------------------
update omega_dot, omega
-----------------------------------------------------------------------*/
void FixNH::nh_omega_dot()
{
double f_omega,volume;
if (dimension == 3) volume = domain->xprd*domain->yprd*domain->zprd;
else volume = domain->xprd*domain->yprd;
if (deviatoric_flag) compute_deviatoric();
mtk_term1 = 0.0;
if (mtk_flag)
if (pstyle == ISO) {
mtk_term1 = tdof * boltz * t_current;
mtk_term1 /= pdim * atom->natoms;
} else {
double *mvv_current = temperature->vector;
for (int i = 0; i < 3; i++)
if (p_flag[i])
mtk_term1 += mvv_current[i];
mtk_term1 /= pdim * atom->natoms;
}
for (int i = 0; i < 3; i++)
if (p_flag[i]) {
f_omega = (p_current[i]-p_hydro)*volume /
(omega_mass[i] * nktv2p) + mtk_term1 / omega_mass[i];
if (deviatoric_flag) f_omega -= fdev[i]/(omega_mass[i] * nktv2p);
omega_dot[i] += f_omega*dthalf;
omega_dot[i] *= pdrag_factor;
}
mtk_term2 = 0.0;
if (mtk_flag) {
for (int i = 0; i < 3; i++)
if (p_flag[i])
mtk_term2 += omega_dot[i];
mtk_term2 /= pdim * atom->natoms;
}
if (pstyle == TRICLINIC) {
for (int i = 3; i < 6; i++) {
if (p_flag[i]) {
f_omega = p_current[i]*volume/(omega_mass[i] * nktv2p);
if (deviatoric_flag)
f_omega -= fdev[i]/(omega_mass[i] * nktv2p);
omega_dot[i] += f_omega*dthalf;
omega_dot[i] *= pdrag_factor;
}
}
}
}
/* ----------------------------------------------------------------------
if any tilt ratios exceed 0.5, set flip = 1 and compute new tilt values
do not flip in x or y if non-periodic (can tilt but not flip)
this is b/c the box length would be changed (dramatically) by flip
if yz tilt exceeded, adjust C vector by one B vector
if xz tilt exceeded, adjust C vector by one A vector
if xy tilt exceeded, adjust B vector by one A vector
check yz first since it may change xz, then xz check comes after
if any flip occurs, create new box in domain
image_flip() adjusts image flags due to box shape change induced by flip
remap() puts atoms outside the new box back into the new box
perform irregular on atoms in lamda coords to migrate atoms to new procs
important that image_flip comes before remap, since remap may change
image flags to new values, making eqs in doc of Domain:image_flip incorrect
------------------------------------------------------------------------- */
void FixNH::pre_exchange()
{
double xprd = domain->xprd;
double yprd = domain->yprd;
// flip is triggered when tilt exceeds 0.5 by an amount DELTAFLIP
// this avoids immediate re-flipping due to tilt oscillations
double xtiltmax = (0.5+DELTAFLIP)*xprd;
double ytiltmax = (0.5+DELTAFLIP)*yprd;
int flipxy,flipxz,flipyz;
flipxy = flipxz = flipyz = 0;
if (domain->yperiodic) {
if (domain->yz < -ytiltmax) {
domain->yz += yprd;
domain->xz += domain->xy;
flipyz = 1;
} else if (domain->yz >= ytiltmax) {
domain->yz -= yprd;
domain->xz -= domain->xy;
flipyz = -1;
}
}
if (domain->xperiodic) {
if (domain->xz < -xtiltmax) {
domain->xz += xprd;
flipxz = 1;
} else if (domain->xz >= xtiltmax) {
domain->xz -= xprd;
flipxz = -1;
}
if (domain->xy < -xtiltmax) {
domain->xy += xprd;
flipxy = 1;
} else if (domain->xy >= xtiltmax) {
domain->xy -= xprd;
flipxy = -1;
}
}
int flip = 0;
if (flipxy || flipxz || flipyz) flip = 1;
if (flip) {
domain->set_global_box();
domain->set_local_box();
domain->image_flip(flipxy,flipxz,flipyz);
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) domain->remap(x[i],image[i]);
domain->x2lamda(atom->nlocal);
irregular->migrate_atoms();
domain->lamda2x(atom->nlocal);
}
}
diff --git a/src/fix_nh.h b/src/fix_nh.h
index 819260c1d..d95815fa3 100644
--- a/src/fix_nh.h
+++ b/src/fix_nh.h
@@ -1,252 +1,256 @@
/* -*- c++ -*- ----------------------------------------------------------
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_NH_H
#define LMP_FIX_NH_H
#include "fix.h"
namespace LAMMPS_NS {
class FixNH : public Fix {
public:
FixNH(class LAMMPS *, int, char **);
virtual ~FixNH();
int setmask();
virtual void init();
virtual void setup(int);
virtual void initial_integrate(int);
virtual void final_integrate();
void initial_integrate_respa(int, int, int);
void final_integrate_respa(int, int);
void pre_exchange();
double compute_scalar();
virtual double compute_vector(int);
void write_restart(FILE *);
virtual int pack_restart_data(double *); // pack restart data
virtual void restart(char *);
int modify_param(int, char **);
void reset_target(double);
void reset_dt();
virtual void *extract(const char*,int &);
protected:
int dimension,which;
double dtv,dtf,dthalf,dt4,dt8,dto;
double boltz,nktv2p,tdof;
double vol0; // reference volume
double t0; // reference temperature
// used for barostat mass
double t_start,t_stop;
double t_current,t_target,ke_target;
double t_freq;
int tstat_flag; // 1 if control T
int pstat_flag; // 1 if control P
int pstyle,pcouple,allremap;
int p_flag[6]; // 1 if control P on this dim, 0 if not
double p_start[6],p_stop[6];
double p_freq[6],p_target[6];
double omega[6],omega_dot[6];
double omega_mass[6];
double p_current[6];
double drag,tdrag_factor; // drag factor on particle thermostat
double pdrag_factor; // drag factor on barostat
int kspace_flag; // 1 if KSpace invoked, 0 if not
int nrigid; // number of rigid fixes
int dilate_group_bit; // mask for dilation group
int *rfix; // indices of rigid fixes
char *id_dilate; // group name to dilate
class Irregular *irregular; // for migrating atoms after box flips
int nlevels_respa;
double *step_respa;
char *id_temp,*id_press;
class Compute *temperature,*pressure;
int tflag,pflag;
double *eta,*eta_dot; // chain thermostat for particles
double *eta_dotdot;
double *eta_mass;
int mtchain; // length of chain
int mtchain_default_flag; // 1 = mtchain is default
double *etap; // chain thermostat for barostat
double *etap_dot;
double *etap_dotdot;
double *etap_mass;
int mpchain; // length of chain
int mtk_flag; // 0 if using Hoover barostat
int pdim; // number of barostatted dims
double p_freq_max; // maximum barostat frequency
double p_hydro; // hydrostatic target pressure
int nc_tchain,nc_pchain;
double factor_eta;
double sigma[6]; // scaled target stress
double fdev[6]; // deviatoric force on barostat
int deviatoric_flag; // 0 if target stress tensor is hydrostatic
double h0_inv[6]; // h_inv of reference (zero strain) box
int nreset_h0; // interval for resetting h0
double mtk_term1,mtk_term2; // Martyna-Tobias-Klein corrections
int eta_mass_flag; // 1 if eta_mass updated, 0 if not.
int omega_mass_flag; // 1 if omega_mass updated, 0 if not.
int etap_mass_flag; // 1 if etap_mass updated, 0 if not.
int scaleyz; // 1 if yz scaled with lz
int scalexz; // 1 if xz scaled with lz
int scalexy; // 1 if xy scaled with ly
double fixedpoint[3]; // Location of dilation fixed-point
void couple();
void remap();
void nhc_temp_integrate();
void nhc_press_integrate();
virtual void nve_x(); // may be overwritten by child classes
virtual void nve_v();
virtual void nh_v_press();
virtual void nh_v_temp();
virtual void compute_temp_target();
virtual int size_restart_global();
void compute_sigma();
void compute_deviatoric();
double compute_strain_energy();
void compute_press_target();
void nh_omega_dot();
};
}
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Target temperature for fix nvt/npt/nph cannot be 0.0
Self-explanatory.
E: Invalid fix nvt/npt/nph command for a 2d simulation
Cannot control z dimension in a 2d model.
+E: Fix nvt/npt/nph dilate group ID does not exist
+
+Self-explanatory.
+
E: Invalid fix nvt/npt/nph command pressure settings
If multiple dimensions are coupled, those dimensions must be
specified.
E: Cannot use fix nvt/npt/nph on a non-periodic dimension
When specifying a diagonal pressure component, the dimension must be
periodic.
E: Cannot use fix nvt/npt/nph on a 2nd non-periodic dimension
When specifying an off-diagonal pressure component, the 2nd of the two
dimensions must be periodic. E.g. if the xy component is specified,
then the y dimension must be periodic.
E: Cannot use fix nvt/npt/nph with yz dynamics when z is non-periodic dimension
The 2nd dimension in the barostatted tilt factor must be periodic.
E: Cannot use fix nvt/npt/nph with xz dynamics when z is non-periodic dimension
The 2nd dimension in the barostatted tilt factor must be periodic.
E: Cannot use fix nvt/npt/nph with xy dynamics when y is non-periodic dimension
The 2nd dimension in the barostatted tilt factor must be periodic.
E: Cannot use fix nvt/npt/nph with both yz dynamics and yz scaling
Self-explanatory.
E: Cannot use fix nvt/npt/nph with both xz dynamics and xz scaling
Self-explanatory.
E: Cannot use fix nvt/npt/nph with both xy dynamics and xy scaling
Self-explanatory.
E: Can not specify Pxy/Pxz/Pyz in fix nvt/npt/nph with non-triclinic box
Only triclinic boxes can be used with off-diagonal pressure components.
See the region prism command for details.
E: Invalid fix nvt/npt/nph pressure settings
Settings for coupled dimensions must be the same.
E: Fix nvt/npt/nph damping parameters must be > 0.0
Self-explanatory.
E: Cannot use fix npt and fix deform on same component of stress tensor
This would be changing the same box dimension twice.
E: Temperature ID for fix nvt/nph/npt does not exist
Self-explanatory.
E: Pressure ID for fix npt/nph does not exist
Self-explanatory.
E: Fix npt/nph has tilted box too far in one step - periodic cell is too far from equilibrium state
Self-explanatory. The change in the box tilt is too extreme
on a short timescale.
E: Could not find fix_modify temperature ID
The compute ID for computing temperature does not exist.
E: Fix_modify temperature ID does not compute temperature
The compute ID assigned to the fix must compute temperature.
W: Temperature for fix modify is not for group all
The temperature compute is being used with a pressure calculation
which does operate on group all, so this may be inconsistent.
E: Pressure ID for fix modify does not exist
Self-explanatory.
E: Could not find fix_modify pressure ID
The compute ID for computing pressure does not exist.
E: Fix_modify pressure ID does not compute pressure
The compute ID assigned to the fix must compute pressure.
*/
diff --git a/src/fix_orient_fcc.cpp b/src/fix_orient_fcc.cpp
index 5f8193c10..d1ba81bf8 100644
--- a/src/fix_orient_fcc.cpp
+++ b/src/fix_orient_fcc.cpp
@@ -1,592 +1,592 @@
/* ----------------------------------------------------------------------
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 "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
using namespace MathConst;
#define BIG 1000000000
/* ---------------------------------------------------------------------- */
FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
MPI_Comm_rank(world,&me);
if (narg != 11) error->all(FLERR,"Illegal fix orient/fcc command");
scalar_flag = 1;
global_freq = 1;
extscalar = 1;
peratom_flag = 1;
size_peratom_cols = 2;
peratom_freq = 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(FLERR,"Illegal fix orient/fcc command");
// initializations
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 line[IMGMAX];
char *result;
int count;
FILE *infile = fopen(xifilename,"r");
if (infile == NULL) error->one(FLERR,"Fix orient/fcc file open failed");
for (int i = 0; i < 6; i++) {
- result = fgets(line,512,infile);
+ result = fgets(line,IMGMAX,infile);
if (!result) error->one(FLERR,"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(FLERR,"Fix orient/fcc file read failed");
}
fclose(infile);
infile = fopen(chifilename,"r");
if (infile == NULL) error->one(FLERR,"Fix orient/fcc file open failed");
for (int i = 0; i < 6; i++) {
- result = fgets(line,512,infile);
+ result = fgets(line,IMGMAX,infile);
if (!result) error->one(FLERR,"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(FLERR,"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;
nmax = atom->nmax;
nbr = (Nbr *) memory->smalloc(nmax*sizeof(Nbr),"orient/fcc:nbr");
memory->create(order,nmax,2,"orient/fcc:order");
array_atom = order;
// zero the array since a variable may access it before first run
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) order[i][0] = order[i][1] = 0.0;
}
/* ---------------------------------------------------------------------- */
FixOrientFCC::~FixOrientFCC()
{
delete [] xifilename;
delete [] chifilename;
memory->sfree(nbr);
memory->destroy(order);
}
/* ---------------------------------------------------------------------- */
int FixOrientFCC::setmask()
{
int mask = 0;
mask |= POST_FORCE;
mask |= THERMO_ENERGY;
mask |= POST_FORCE_RESPA;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixOrientFCC::init()
{
if (strstr(update->integrate_style,"respa"))
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 (strstr(update->integrate_style,"verlet"))
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 and order data structures are adequate size
if (nall > nmax) {
nmax = nall;
memory->destroy(nbr);
memory->destroy(order);
nbr = (Nbr *) memory->smalloc(nmax*sizeof(Nbr),"orient/fcc:nbr");
memory->create(order,nmax,2,"orient/fcc:order");
array_atom = order;
}
// 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];
j &= NEIGHMASK;
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;
order[i][0] = xi_total;
// compute potential derivative to xi
if (xi_total < xi0) {
nbr[i].duxi = 0.0;
edelta = 0.0;
order[i][1] = 0.0;
} else if (xi_total > xi1) {
nbr[i].duxi = 0.0;
edelta = Vxi;
order[i][1] = 1.0;
} else {
omega = MY_PI2*(xi_total-xi0) / (xi1-xi0);
nbr[i].duxi = MY_PI*Vxi*sin(2.0*omega) / (2.0*(xi1-xi0));
edelta = Vxi*(1 - cos(2.0*omega)) / 2.0;
order[i][1] = omega / MY_PI2;
}
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(FLERR,"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 " BIGINT_FORMAT ": " BIGINT_FORMAT
" atoms have %d neighbors\n",
update->ntimestep,atom->natoms,total);
if (logfile) fprintf(logfile,
"orient step " BIGINT_FORMAT ": " BIGINT_FORMAT
" atoms have %d neighbors\n",
update->ntimestep,atom->natoms,total);
if (screen)
fprintf(screen," neighs: min = %d, max = %d, ave = %g\n",
min,max,ave);
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()
{
double added_energy_total;
MPI_Allreduce(&added_energy,&added_energy_total,1,MPI_DOUBLE,MPI_SUM,world);
return added_energy_total;
}
/* ---------------------------------------------------------------------- */
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++] = 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++] = 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 = nmax * sizeof(Nbr);
bytes += 2*nmax * sizeof(double);
return bytes;
}
diff --git a/src/fix_restrain.h b/src/fix_restrain.h
index 0a12a1f40..0a5669a7e 100644
--- a/src/fix_restrain.h
+++ b/src/fix_restrain.h
@@ -1,82 +1,94 @@
/* -*- c++ -*- ----------------------------------------------------------
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(restrain,FixRestrain)
#else
#ifndef LMP_FIX_RESTRAIN_H
#define LMP_FIX_RESTRAIN_H
#include "fix.h"
namespace LAMMPS_NS {
class FixRestrain : public Fix {
public:
FixRestrain(class LAMMPS *, int, char **);
~FixRestrain();
int setmask();
void init();
void setup(int);
void min_setup(int);
void post_force(int);
void post_force_respa(int, int, int);
void min_post_force(int);
double compute_scalar();
private:
int nlevels_respa;
int nrestrain,maxrestrain;
int *rstyle;
int **ids;
double *kstart,*kstop,*target;
double *cos_target,*sin_target;
double energy,energy_all;
void restrain_bond(int);
void restrain_angle(int);
void restrain_dihedral(int);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Fix restrain requires an atom map, see atom_modify
Self-explanatory.
+E: Restrain atoms %d %d missing on proc %d at step %ld
+
+The 2 atoms in a restrain bond specified by the fix restrain
+command are not all accessible to a processor. This probably means an
+atom has moved too far.
+
+E: Restrain atoms %d %d %d missing on proc %d at step %ld
+
+The 3 atoms in a restrain angle specified by the fix restrain
+command are not all accessible to a processor. This probably means an
+atom has moved too far.
+
E: Restrain atoms %d %d %d %d missing on proc %d at step %ld
The 4 atoms in a restrain dihedral specified by the fix restrain
command are not all accessible to a processor. This probably means an
atom has moved too far.
W: Restrain problem: %d %ld %d %d %d %d
Conformation of the 4 listed dihedral atoms is extreme; you may want
to check your simulation geometry.
*/
diff --git a/src/fix_rigid.cpp b/src/fix_rigid.cpp
index 6de2d0ed7..1a5afbb37 100644
--- a/src/fix_rigid.cpp
+++ b/src/fix_rigid.cpp
@@ -1,2293 +1,2295 @@
/* ----------------------------------------------------------------------
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 "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "fix_rigid.h"
#include "math_extra.h"
#include "atom.h"
#include "atom_vec_ellipsoid.h"
#include "atom_vec_line.h"
#include "atom_vec_tri.h"
#include "domain.h"
#include "update.h"
#include "respa.h"
#include "modify.h"
#include "group.h"
#include "comm.h"
#include "random_mars.h"
#include "force.h"
#include "output.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
using namespace MathConst;
enum{SINGLE,MOLECULE,GROUP};
#define MAXLINE 256
#define CHUNK 1024
#define ATTRIBUTE_PERBODY 11
#define TOLERANCE 1.0e-6
#define EPSILON 1.0e-7
#define SINERTIA 0.4 // moment of inertia prefactor for sphere
#define EINERTIA 0.4 // moment of inertia prefactor for ellipsoid
#define LINERTIA (1.0/12.0) // moment of inertia prefactor for line segment
/* ---------------------------------------------------------------------- */
FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
int i,ibody;
scalar_flag = 1;
extscalar = 0;
time_integrate = 1;
rigid_flag = 1;
virial_flag = 1;
create_attribute = 1;
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
// perform initial allocation of atom-based arrays
// register with Atom class
extended = orientflag = dorientflag = 0;
body = NULL;
displace = NULL;
eflags = NULL;
orient = NULL;
dorient = NULL;
grow_arrays(atom->nmax);
atom->add_callback(0);
// parse args for rigid body specification
// set nbody and body[i] for each atom
if (narg < 4) error->all(FLERR,"Illegal fix rigid command");
int iarg;
mol2body = NULL;
// single rigid body
// nbody = 1
// all atoms in fix group are part of body
if (strcmp(arg[3],"single") == 0) {
rstyle = SINGLE;
iarg = 4;
nbody = 1;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++) {
body[i] = -1;
if (mask[i] & groupbit) body[i] = 0;
}
// each molecule in fix group is a rigid body
// maxmol = largest molecule #
// ncount = # of atoms in each molecule (have to sum across procs)
// nbody = # of non-zero ncount values
// use nall as incremented ptr to set body[] values for each atom
} else if (strcmp(arg[3],"molecule") == 0) {
rstyle = MOLECULE;
iarg = 4;
if (atom->molecule_flag == 0)
error->all(FLERR,"Fix rigid molecule requires atom attribute molecule");
int *mask = atom->mask;
int *molecule = atom->molecule;
int nlocal = atom->nlocal;
maxmol = -1;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) maxmol = MAX(maxmol,molecule[i]);
int itmp;
MPI_Allreduce(&maxmol,&itmp,1,MPI_INT,MPI_MAX,world);
maxmol = itmp;
int *ncount;
memory->create(ncount,maxmol+1,"rigid:ncount");
for (i = 0; i <= maxmol; i++) ncount[i] = 0;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) ncount[molecule[i]]++;
memory->create(mol2body,maxmol+1,"rigid:ncount");
MPI_Allreduce(ncount,mol2body,maxmol+1,MPI_INT,MPI_SUM,world);
nbody = 0;
for (i = 0; i <= maxmol; i++)
if (mol2body[i]) mol2body[i] = nbody++;
else mol2body[i] = -1;
for (i = 0; i < nlocal; i++) {
body[i] = -1;
if (mask[i] & groupbit) body[i] = mol2body[molecule[i]];
}
memory->destroy(ncount);
// each listed group is a rigid body
// check if all listed groups exist
// an atom must belong to fix group and listed group to be in rigid body
// error if atom belongs to more than 1 rigid body
} else if (strcmp(arg[3],"group") == 0) {
if (narg < 5) error->all(FLERR,"Illegal fix rigid command");
rstyle = GROUP;
nbody = atoi(arg[4]);
if (nbody <= 0) error->all(FLERR,"Illegal fix rigid command");
if (narg < 5+nbody) error->all(FLERR,"Illegal fix rigid command");
iarg = 5+nbody;
int *igroups = new int[nbody];
for (ibody = 0; ibody < nbody; ibody++) {
igroups[ibody] = group->find(arg[5+ibody]);
if (igroups[ibody] == -1)
error->all(FLERR,"Could not find fix rigid group ID");
}
int *mask = atom->mask;
int nlocal = atom->nlocal;
int flag = 0;
for (i = 0; i < nlocal; i++) {
body[i] = -1;
if (mask[i] & groupbit)
for (ibody = 0; ibody < nbody; ibody++)
if (mask[i] & group->bitmask[igroups[ibody]]) {
if (body[i] >= 0) flag = 1;
body[i] = ibody;
}
}
int flagall;
MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world);
if (flagall)
error->all(FLERR,"One or more atoms belong to multiple rigid bodies");
delete [] igroups;
} else error->all(FLERR,"Illegal fix rigid command");
// error check on nbody
if (nbody == 0) error->all(FLERR,"No rigid bodies defined");
// create all nbody-length arrays
memory->create(nrigid,nbody,"rigid:nrigid");
memory->create(masstotal,nbody,"rigid:masstotal");
memory->create(xcm,nbody,3,"rigid:xcm");
memory->create(vcm,nbody,3,"rigid:vcm");
memory->create(fcm,nbody,3,"rigid:fcm");
memory->create(inertia,nbody,3,"rigid:inertia");
memory->create(ex_space,nbody,3,"rigid:ex_space");
memory->create(ey_space,nbody,3,"rigid:ey_space");
memory->create(ez_space,nbody,3,"rigid:ez_space");
memory->create(angmom,nbody,3,"rigid:angmom");
memory->create(omega,nbody,3,"rigid:omega");
memory->create(torque,nbody,3,"rigid:torque");
memory->create(quat,nbody,4,"rigid:quat");
memory->create(imagebody,nbody,"rigid:imagebody");
memory->create(fflag,nbody,3,"rigid:fflag");
memory->create(tflag,nbody,3,"rigid:tflag");
memory->create(langextra,nbody,6,"rigid:langextra");
memory->create(sum,nbody,6,"rigid:sum");
memory->create(all,nbody,6,"rigid:all");
memory->create(remapflag,nbody,4,"rigid:remapflag");
// initialize force/torque flags to default = 1.0
// for 2d: fz, tx, ty = 0.0
array_flag = 1;
size_array_rows = nbody;
size_array_cols = 15;
global_freq = 1;
extarray = 0;
for (i = 0; i < nbody; i++) {
fflag[i][0] = fflag[i][1] = fflag[i][2] = 1.0;
tflag[i][0] = tflag[i][1] = tflag[i][2] = 1.0;
if (domain->dimension == 2) fflag[i][2] = tflag[i][0] = tflag[i][1] = 0.0;
}
// parse optional args
int seed;
langflag = 0;
tempflag = 0;
pressflag = 0;
t_chain = 10;
t_iter = 1;
t_order = 3;
p_chain = 10;
infile = NULL;
while (iarg < narg) {
if (strcmp(arg[iarg],"force") == 0) {
if (iarg+5 > narg) error->all(FLERR,"Illegal fix rigid command");
int mlo,mhi;
force->bounds(arg[iarg+1],nbody,mlo,mhi);
double xflag,yflag,zflag;
if (strcmp(arg[iarg+2],"off") == 0) xflag = 0.0;
else if (strcmp(arg[iarg+2],"on") == 0) xflag = 1.0;
else error->all(FLERR,"Illegal fix rigid command");
if (strcmp(arg[iarg+3],"off") == 0) yflag = 0.0;
else if (strcmp(arg[iarg+3],"on") == 0) yflag = 1.0;
else error->all(FLERR,"Illegal fix rigid command");
if (strcmp(arg[iarg+4],"off") == 0) zflag = 0.0;
else if (strcmp(arg[iarg+4],"on") == 0) zflag = 1.0;
else error->all(FLERR,"Illegal fix rigid command");
if (domain->dimension == 2 && zflag == 1.0)
error->all(FLERR,"Fix rigid z force cannot be on for 2d simulation");
int count = 0;
for (int m = mlo; m <= mhi; m++) {
fflag[m-1][0] = xflag;
fflag[m-1][1] = yflag;
fflag[m-1][2] = zflag;
count++;
}
if (count == 0) error->all(FLERR,"Illegal fix rigid command");
iarg += 5;
} else if (strcmp(arg[iarg],"torque") == 0) {
if (iarg+5 > narg) error->all(FLERR,"Illegal fix rigid command");
int mlo,mhi;
force->bounds(arg[iarg+1],nbody,mlo,mhi);
double xflag,yflag,zflag;
if (strcmp(arg[iarg+2],"off") == 0) xflag = 0.0;
else if (strcmp(arg[iarg+2],"on") == 0) xflag = 1.0;
else error->all(FLERR,"Illegal fix rigid command");
if (strcmp(arg[iarg+3],"off") == 0) yflag = 0.0;
else if (strcmp(arg[iarg+3],"on") == 0) yflag = 1.0;
else error->all(FLERR,"Illegal fix rigid command");
if (strcmp(arg[iarg+4],"off") == 0) zflag = 0.0;
else if (strcmp(arg[iarg+4],"on") == 0) zflag = 1.0;
else error->all(FLERR,"Illegal fix rigid command");
if (domain->dimension == 2 && (xflag == 1.0 || yflag == 1.0))
error->all(FLERR,"Fix rigid xy torque cannot be on for 2d simulation");
int count = 0;
for (int m = mlo; m <= mhi; m++) {
tflag[m-1][0] = xflag;
tflag[m-1][1] = yflag;
tflag[m-1][2] = zflag;
count++;
}
if (count == 0) error->all(FLERR,"Illegal fix rigid command");
iarg += 5;
} else if (strcmp(arg[iarg],"langevin") == 0) {
if (iarg+5 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid") != 0 && strcmp(style,"rigid/nve") != 0)
error->all(FLERR,"Illegal fix rigid command");
langflag = 1;
t_start = atof(arg[iarg+1]);
t_stop = atof(arg[iarg+2]);
t_period = atof(arg[iarg+3]);
seed = atoi(arg[iarg+4]);
if (t_period <= 0.0)
error->all(FLERR,"Fix rigid langevin period must be > 0.0");
if (seed <= 0) error->all(FLERR,"Illegal fix rigid command");
iarg += 5;
} else if (strcmp(arg[iarg],"temp") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/nvt") != 0 && strcmp(style,"rigid/npt") != 0)
error->all(FLERR,"Illegal fix rigid command");
tempflag = 1;
t_start = atof(arg[iarg+1]);
t_stop = atof(arg[iarg+2]);
t_period = atof(arg[iarg+3]);
iarg += 4;
} else if (strcmp(arg[iarg],"press") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/npt") != 0)
error->all(FLERR,"Illegal fix rigid command");
pressflag = 1;
p_start = atof(arg[iarg+1]);
p_stop = atof(arg[iarg+2]);
p_period = atof(arg[iarg+3]);
iarg += 4;
} else if (strcmp(arg[iarg],"tparam") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/nvt") != 0)
error->all(FLERR,"Illegal fix rigid command");
t_chain = atoi(arg[iarg+1]);
t_iter = atoi(arg[iarg+2]);
t_order = atoi(arg[iarg+3]);
iarg += 4;
} else if (strcmp(arg[iarg],"pparam") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/npt") != 0)
error->all(FLERR,"Illegal fix rigid command");
p_chain = atoi(arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"infile") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix rigid command");
delete [] infile;
int n = strlen(arg[iarg+1]) + 1;
infile = new char[n];
strcpy(infile,arg[iarg+1]);
iarg += 2;
} else error->all(FLERR,"Illegal fix rigid command");
}
t_target = t_start;
// initialize Marsaglia RNG with processor-unique seed
if (langflag) random = new RanMars(lmp,seed + me);
else random = NULL;
// initialize vector output quantities in case accessed before run
for (i = 0; i < nbody; i++) {
xcm[i][0] = xcm[i][1] = xcm[i][2] = 0.0;
vcm[i][0] = vcm[i][1] = vcm[i][2] = 0.0;
fcm[i][0] = fcm[i][1] = fcm[i][2] = 0.0;
torque[i][0] = torque[i][1] = torque[i][2] = 0.0;
}
// nrigid[n] = # of atoms in Nth rigid body
// error if one or zero atoms
int *ncount = new int[nbody];
for (ibody = 0; ibody < nbody; ibody++) ncount[ibody] = 0;
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++)
if (body[i] >= 0) ncount[body[i]]++;
MPI_Allreduce(ncount,nrigid,nbody,MPI_INT,MPI_SUM,world);
delete [] ncount;
for (ibody = 0; ibody < nbody; ibody++)
if (nrigid[ibody] <= 1) error->all(FLERR,"One or zero atoms in rigid body");
// bitmasks for properties of extended particles
POINT = 1;
SPHERE = 2;
ELLIPSOID = 4;
LINE = 8;
TRIANGLE = 16;
DIPOLE = 32;
OMEGA = 64;
ANGMOM = 128;
TORQUE = 256;
MINUSPI = -MY_PI;
TWOPI = 2.0*MY_PI;
// atom style pointers to particles that store extra info
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
avec_line = (AtomVecLine *) atom->style_match("line");
avec_tri = (AtomVecTri *) atom->style_match("tri");
// print statistics
int nsum = 0;
for (ibody = 0; ibody < nbody; ibody++) nsum += nrigid[ibody];
if (me == 0) {
if (screen) fprintf(screen,"%d rigid bodies with %d atoms\n",nbody,nsum);
if (logfile) fprintf(logfile,"%d rigid bodies with %d atoms\n",nbody,nsum);
}
// firstflag = 1 triggers one-time initialization of rigid body attributes
firstflag = 1;
}
/* ---------------------------------------------------------------------- */
FixRigid::~FixRigid()
{
// unregister callbacks to this fix from Atom class
atom->delete_callback(id,0);
delete random;
delete [] infile;
memory->destroy(mol2body);
// delete locally stored arrays
memory->destroy(body);
memory->destroy(displace);
memory->destroy(eflags);
memory->destroy(orient);
memory->destroy(dorient);
// delete nbody-length arrays
memory->destroy(nrigid);
memory->destroy(masstotal);
memory->destroy(xcm);
memory->destroy(vcm);
memory->destroy(fcm);
memory->destroy(inertia);
memory->destroy(ex_space);
memory->destroy(ey_space);
memory->destroy(ez_space);
memory->destroy(angmom);
memory->destroy(omega);
memory->destroy(torque);
memory->destroy(quat);
memory->destroy(imagebody);
memory->destroy(fflag);
memory->destroy(tflag);
memory->destroy(langextra);
memory->destroy(sum);
memory->destroy(all);
memory->destroy(remapflag);
}
/* ---------------------------------------------------------------------- */
int FixRigid::setmask()
{
int mask = 0;
mask |= INITIAL_INTEGRATE;
mask |= FINAL_INTEGRATE;
if (langflag) mask |= POST_FORCE;
mask |= PRE_NEIGHBOR;
mask |= INITIAL_INTEGRATE_RESPA;
mask |= FINAL_INTEGRATE_RESPA;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixRigid::init()
{
int i,ibody;
triclinic = domain->triclinic;
// warn if more than one rigid fix
int count = 0;
for (i = 0; i < modify->nfix; i++)
if (strcmp(modify->fix[i]->style,"rigid") == 0) count++;
if (count > 1 && me == 0) error->warning(FLERR,"More than one fix rigid");
// error if npt,nph fix comes before rigid 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,"rigid") == 0)
error->all(FLERR,"Rigid fix must come before NPT/NPH fix");
}
// timestep info
dtv = update->dt;
dtf = 0.5 * update->dt * force->ftm2v;
dtq = 0.5 * update->dt;
if (strstr(update->integrate_style,"respa"))
step_respa = ((Respa *) update->integrate)->step;
// one-time initialization of rigid body attributes
// extended flags, masstotal, COM, inertia tensor
if (firstflag) setup_bodies();
firstflag = 0;
// temperature scale factor
double ndof = 0.0;
for (ibody = 0; ibody < nbody; ibody++) {
ndof += fflag[ibody][0] + fflag[ibody][1] + fflag[ibody][2];
ndof += tflag[ibody][0] + tflag[ibody][1] + tflag[ibody][2];
}
if (ndof > 0.0) tfactor = force->mvv2e / (ndof * force->boltz);
else tfactor = 0.0;
}
/* ---------------------------------------------------------------------- */
void FixRigid::setup(int vflag)
{
int i,n,ibody;
double massone,radone;
// vcm = velocity of center-of-mass of each rigid body
// fcm = force on center-of-mass of each rigid body
double **v = atom->v;
double **f = atom->f;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
int nlocal = atom->nlocal;
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
sum[ibody][0] += v[i][0] * massone;
sum[ibody][1] += v[i][1] * massone;
sum[ibody][2] += v[i][2] * massone;
sum[ibody][3] += f[i][0];
sum[ibody][4] += f[i][1];
sum[ibody][5] += f[i][2];
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
for (ibody = 0; ibody < nbody; ibody++) {
vcm[ibody][0] = all[ibody][0]/masstotal[ibody];
vcm[ibody][1] = all[ibody][1]/masstotal[ibody];
vcm[ibody][2] = all[ibody][2]/masstotal[ibody];
fcm[ibody][0] = all[ibody][3];
fcm[ibody][1] = all[ibody][4];
fcm[ibody][2] = all[ibody][5];
}
// angmom = angular momentum of each rigid body
// torque = torque on each rigid body
- int *image = atom->image;
+ tagint *image = atom->image;
double **x = atom->x;
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 (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
int xbox,ybox,zbox;
double xunwrap,yunwrap,zunwrap,dx,dy,dz;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
xunwrap = x[i][0] + xbox*xprd;
yunwrap = x[i][1] + ybox*yprd;
zunwrap = x[i][2] + zbox*zprd;
} else {
xunwrap = x[i][0] + xbox*xprd + ybox*xy + zbox*xz;
yunwrap = x[i][1] + ybox*yprd + zbox*yz;
zunwrap = x[i][2] + zbox*zprd;
}
dx = xunwrap - xcm[ibody][0];
dy = yunwrap - xcm[ibody][1];
dz = zunwrap - xcm[ibody][2];
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
sum[ibody][0] += dy * massone*v[i][2] - dz * massone*v[i][1];
sum[ibody][1] += dz * massone*v[i][0] - dx * massone*v[i][2];
sum[ibody][2] += dx * massone*v[i][1] - dy * massone*v[i][0];
sum[ibody][3] += dy * f[i][2] - dz * f[i][1];
sum[ibody][4] += dz * f[i][0] - dx * f[i][2];
sum[ibody][5] += dx * f[i][1] - dy * f[i][0];
}
// extended particles add their rotation/torque to angmom/torque of body
if (extended) {
AtomVecLine::Bonus *lbonus;
if (avec_line) lbonus = avec_line->bonus;
double **omega_one = atom->omega;
double **angmom_one = atom->angmom;
double **torque_one = atom->torque;
double *radius = atom->radius;
int *line = atom->line;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
if (eflags[i] & OMEGA) {
if (eflags[i] & SPHERE) {
radone = radius[i];
sum[ibody][0] += SINERTIA*rmass[i] * radone*radone * omega_one[i][0];
sum[ibody][1] += SINERTIA*rmass[i] * radone*radone * omega_one[i][1];
sum[ibody][2] += SINERTIA*rmass[i] * radone*radone * omega_one[i][2];
} else if (eflags[i] & LINE) {
radone = lbonus[line[i]].length;
sum[ibody][2] += LINERTIA*rmass[i] * radone*radone * omega_one[i][2];
}
}
if (eflags[i] & ANGMOM) {
sum[ibody][0] += angmom_one[i][0];
sum[ibody][1] += angmom_one[i][1];
sum[ibody][2] += angmom_one[i][2];
}
if (eflags[i] & TORQUE) {
sum[ibody][3] += torque_one[i][0];
sum[ibody][4] += torque_one[i][1];
sum[ibody][5] += torque_one[i][2];
}
}
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
for (ibody = 0; ibody < nbody; ibody++) {
angmom[ibody][0] = all[ibody][0];
angmom[ibody][1] = all[ibody][1];
angmom[ibody][2] = all[ibody][2];
torque[ibody][0] = all[ibody][3];
torque[ibody][1] = all[ibody][4];
torque[ibody][2] = all[ibody][5];
}
// zero langextra in case Langevin thermostat not used
// no point to calling post_force() here since langextra
// is only added to fcm/torque in final_integrate()
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) langextra[ibody][i] = 0.0;
// virial setup before call to set_v
if (vflag) v_setup(vflag);
else evflag = 0;
// set velocities from angmom & omega
for (ibody = 0; ibody < nbody; ibody++)
MathExtra::angmom_to_omega(angmom[ibody],ex_space[ibody],ey_space[ibody],
ez_space[ibody],inertia[ibody],omega[ibody]);
set_v();
// guesstimate virial as 2x the set_v contribution
if (vflag_global)
for (n = 0; n < 6; n++) virial[n] *= 2.0;
if (vflag_atom) {
for (i = 0; i < nlocal; i++)
for (n = 0; n < 6; n++)
vatom[i][n] *= 2.0;
}
}
/* ---------------------------------------------------------------------- */
void FixRigid::initial_integrate(int vflag)
{
double dtfm;
for (int ibody = 0; ibody < nbody; ibody++) {
// update vcm by 1/2 step
dtfm = dtf / masstotal[ibody];
vcm[ibody][0] += dtfm * fcm[ibody][0] * fflag[ibody][0];
vcm[ibody][1] += dtfm * fcm[ibody][1] * fflag[ibody][1];
vcm[ibody][2] += dtfm * fcm[ibody][2] * fflag[ibody][2];
// update xcm by full step
xcm[ibody][0] += dtv * vcm[ibody][0];
xcm[ibody][1] += dtv * vcm[ibody][1];
xcm[ibody][2] += dtv * vcm[ibody][2];
// update angular momentum by 1/2 step
angmom[ibody][0] += dtf * torque[ibody][0] * tflag[ibody][0];
angmom[ibody][1] += dtf * torque[ibody][1] * tflag[ibody][1];
angmom[ibody][2] += dtf * torque[ibody][2] * tflag[ibody][2];
// compute omega at 1/2 step from angmom at 1/2 step and current q
// update quaternion a full step via Richardson iteration
// returns new normalized quaternion, also updated omega at 1/2 step
// update ex,ey,ez to reflect new quaternion
MathExtra::angmom_to_omega(angmom[ibody],ex_space[ibody],ey_space[ibody],
ez_space[ibody],inertia[ibody],omega[ibody]);
MathExtra::richardson(quat[ibody],angmom[ibody],omega[ibody],
inertia[ibody],dtq);
MathExtra::q_to_exyz(quat[ibody],
ex_space[ibody],ey_space[ibody],ez_space[ibody]);
}
// virial setup before call to set_xv
if (vflag) v_setup(vflag);
else evflag = 0;
// set coords/orient and velocity/rotation of atoms in rigid bodies
// from quarternion and omega
set_xv();
}
/* ----------------------------------------------------------------------
apply Langevin thermostat to all 6 DOF of rigid bodies
computed by proc 0, broadcast to other procs
unlike fix langevin, this stores extra force in extra arrays,
which are added in when final_integrate() calculates a new fcm/torque
------------------------------------------------------------------------- */
void FixRigid::post_force(int vflag)
{
if (me == 0) {
double gamma1,gamma2;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
t_target = t_start + delta * (t_stop-t_start);
double tsqrt = sqrt(t_target);
double boltz = force->boltz;
double dt = update->dt;
double mvv2e = force->mvv2e;
double ftm2v = force->ftm2v;
for (int i = 0; i < nbody; i++) {
gamma1 = -masstotal[i] / t_period / ftm2v;
gamma2 = sqrt(masstotal[i]) * tsqrt *
sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
langextra[i][0] = gamma1*vcm[i][0] + gamma2*(random->uniform()-0.5);
langextra[i][1] = gamma1*vcm[i][1] + gamma2*(random->uniform()-0.5);
langextra[i][2] = gamma1*vcm[i][2] + gamma2*(random->uniform()-0.5);
gamma1 = -1.0 / t_period / ftm2v;
gamma2 = tsqrt * sqrt(24.0*boltz/t_period/dt/mvv2e) / ftm2v;
langextra[i][3] = inertia[i][0]*gamma1*omega[i][0] +
sqrt(inertia[i][0])*gamma2*(random->uniform()-0.5);
langextra[i][4] = inertia[i][1]*gamma1*omega[i][1] +
sqrt(inertia[i][1])*gamma2*(random->uniform()-0.5);
langextra[i][5] = inertia[i][2]*gamma1*omega[i][2] +
sqrt(inertia[i][2])*gamma2*(random->uniform()-0.5);
}
}
MPI_Bcast(&langextra[0][0],6*nbody,MPI_DOUBLE,0,world);
}
/* ---------------------------------------------------------------------- */
void FixRigid::final_integrate()
{
int i,ibody;
double dtfm,xy,xz,yz;
// sum over atoms to get force and torque on rigid body
- int *image = atom->image;
+ tagint *image = atom->image;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
if (triclinic) {
xy = domain->xy;
xz = domain->xz;
yz = domain->yz;
}
int xbox,ybox,zbox;
double xunwrap,yunwrap,zunwrap,dx,dy,dz;
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
sum[ibody][0] += f[i][0];
sum[ibody][1] += f[i][1];
sum[ibody][2] += f[i][2];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
xunwrap = x[i][0] + xbox*xprd;
yunwrap = x[i][1] + ybox*yprd;
zunwrap = x[i][2] + zbox*zprd;
} else {
xunwrap = x[i][0] + xbox*xprd + ybox*xy + zbox*xz;
yunwrap = x[i][1] + ybox*yprd + zbox*yz;
zunwrap = x[i][2] + zbox*zprd;
}
dx = xunwrap - xcm[ibody][0];
dy = yunwrap - xcm[ibody][1];
dz = zunwrap - xcm[ibody][2];
sum[ibody][3] += dy*f[i][2] - dz*f[i][1];
sum[ibody][4] += dz*f[i][0] - dx*f[i][2];
sum[ibody][5] += dx*f[i][1] - dy*f[i][0];
}
// extended particles add their torque to torque of body
if (extended) {
double **torque_one = atom->torque;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
if (eflags[i] & TORQUE) {
sum[ibody][3] += torque_one[i][0];
sum[ibody][4] += torque_one[i][1];
sum[ibody][5] += torque_one[i][2];
}
}
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
// update vcm and angmom
// include Langevin thermostat forces
// fflag,tflag = 0 for some dimensions in 2d
for (ibody = 0; ibody < nbody; ibody++) {
fcm[ibody][0] = all[ibody][0] + langextra[ibody][0];
fcm[ibody][1] = all[ibody][1] + langextra[ibody][1];
fcm[ibody][2] = all[ibody][2] + langextra[ibody][2];
torque[ibody][0] = all[ibody][3] + langextra[ibody][3];
torque[ibody][1] = all[ibody][4] + langextra[ibody][4];
torque[ibody][2] = all[ibody][5] + langextra[ibody][5];
// update vcm by 1/2 step
dtfm = dtf / masstotal[ibody];
vcm[ibody][0] += dtfm * fcm[ibody][0] * fflag[ibody][0];
vcm[ibody][1] += dtfm * fcm[ibody][1] * fflag[ibody][1];
vcm[ibody][2] += dtfm * fcm[ibody][2] * fflag[ibody][2];
// update angular momentum by 1/2 step
angmom[ibody][0] += dtf * torque[ibody][0] * tflag[ibody][0];
angmom[ibody][1] += dtf * torque[ibody][1] * tflag[ibody][1];
angmom[ibody][2] += dtf * torque[ibody][2] * tflag[ibody][2];
MathExtra::angmom_to_omega(angmom[ibody],ex_space[ibody],ey_space[ibody],
ez_space[ibody],inertia[ibody],omega[ibody]);
}
// set velocity/rotation of atoms in rigid bodies
// virial is already setup from initial_integrate
set_v();
}
/* ----------------------------------------------------------------------
apply evolution operators to quat, quat momentum
see Miller paper cited in fix rigid/nvt and fix rigid/npt
------------------------------------------------------------------------- */
void FixRigid::no_squish_rotate(int k, double *p, double *q,
double *inertia, double dt)
{
double phi,c_phi,s_phi,kp[4],kq[4];
// apply permuation operator on p and q, get kp and kq
if (k == 1) {
kq[0] = -q[1]; kp[0] = -p[1];
kq[1] = q[0]; kp[1] = p[0];
kq[2] = q[3]; kp[2] = p[3];
kq[3] = -q[2]; kp[3] = -p[2];
} else if (k == 2) {
kq[0] = -q[2]; kp[0] = -p[2];
kq[1] = -q[3]; kp[1] = -p[3];
kq[2] = q[0]; kp[2] = p[0];
kq[3] = q[1]; kp[3] = p[1];
} else if (k == 3) {
kq[0] = -q[3]; kp[0] = -p[3];
kq[1] = q[2]; kp[1] = p[2];
kq[2] = -q[1]; kp[2] = -p[1];
kq[3] = q[0]; kp[3] = p[0];
}
// obtain phi, cosines and sines
phi = p[0]*kq[0] + p[1]*kq[1] + p[2]*kq[2] + p[3]*kq[3];
if (fabs(inertia[k-1]) < 1e-6) phi *= 0.0;
else phi /= 4.0 * inertia[k-1];
c_phi = cos(dt * phi);
s_phi = sin(dt * phi);
// advance p and q
p[0] = c_phi*p[0] + s_phi*kp[0];
p[1] = c_phi*p[1] + s_phi*kp[1];
p[2] = c_phi*p[2] + s_phi*kp[2];
p[3] = c_phi*p[3] + s_phi*kp[3];
q[0] = c_phi*q[0] + s_phi*kq[0];
q[1] = c_phi*q[1] + s_phi*kq[1];
q[2] = c_phi*q[2] + s_phi*kq[2];
q[3] = c_phi*q[3] + s_phi*kq[3];
}
/* ---------------------------------------------------------------------- */
void FixRigid::initial_integrate_respa(int vflag, int ilevel, int iloop)
{
dtv = step_respa[ilevel];
dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
dtq = 0.5 * step_respa[ilevel];
if (ilevel == 0) initial_integrate(vflag);
else final_integrate();
}
/* ---------------------------------------------------------------------- */
void FixRigid::final_integrate_respa(int ilevel, int iloop)
{
dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
final_integrate();
}
/* ----------------------------------------------------------------------
remap xcm of each rigid body back into periodic simulation box
done during pre_neighbor so will be after call to pbc()
and after fix_deform::pre_exchange() may have flipped box
use domain->remap() in case xcm is far away from box
due to 1st definition of rigid body or due to box flip
if don't do this, then atoms of a body which drifts far away
from a triclinic box will be remapped back into box
with huge displacements when the box tilt changes via set_x()
adjust image flag of body and image flags of all atoms in body
------------------------------------------------------------------------- */
void FixRigid::pre_neighbor()
{
- int original,oldimage,newimage;
+ tagint original,oldimage,newimage;
for (int ibody = 0; ibody < nbody; ibody++) {
original = imagebody[ibody];
domain->remap(xcm[ibody],imagebody[ibody]);
if (original == imagebody[ibody]) remapflag[ibody][3] = 0;
else {
- oldimage = original & 1023;
- newimage = imagebody[ibody] & 1023;
+ oldimage = original & IMGMASK;
+ newimage = imagebody[ibody] & IMGMASK;
remapflag[ibody][0] = newimage - oldimage;
- oldimage = (original >> 10) & 1023;
- newimage = (imagebody[ibody] >> 10) & 1023;
+ oldimage = (original >> IMGBITS) & IMGMASK;
+ newimage = (imagebody[ibody] >> IMGBITS) & IMGMASK;
remapflag[ibody][1] = newimage - oldimage;
- oldimage = original >> 20;
- newimage = imagebody[ibody] >> 20;
+ oldimage = original >> IMG2BITS;
+ newimage = imagebody[ibody] >> IMG2BITS;
remapflag[ibody][2] = newimage - oldimage;
remapflag[ibody][3] = 1;
}
}
// adjust image flags of any atom in a rigid body whose xcm was remapped
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
- int ibody,idim,otherdims;
+ int ibody;
+ tagint idim,otherdims;
for (int i = 0; i < nlocal; i++) {
if (body[i] == -1) continue;
if (remapflag[body[i]][3] == 0) continue;
ibody = body[i];
if (remapflag[ibody][0]) {
- idim = image[i] & 1023;
+ idim = image[i] & IMGMASK;
otherdims = image[i] ^ idim;
idim -= remapflag[ibody][0];
- idim &= 1023;
+ idim &= IMGMASK;
image[i] = otherdims | idim;
}
if (remapflag[ibody][1]) {
- idim = (image[i] >> 10) & 1023;
- otherdims = image[i] ^ (idim << 10);
+ idim = (image[i] >> IMGBITS) & IMGMASK;
+ otherdims = image[i] ^ (idim << IMGBITS);
idim -= remapflag[ibody][1];
- idim &= 1023;
- image[i] = otherdims | (idim << 10);
+ idim &= IMGMASK;
+ image[i] = otherdims | (idim << IMGBITS);
}
if (remapflag[ibody][2]) {
- idim = image[i] >> 20;
- otherdims = image[i] ^ (idim << 20);
+ idim = image[i] >> IMG2BITS;
+ otherdims = image[i] ^ (idim << IMG2BITS);
idim -= remapflag[ibody][2];
- idim &= 1023;
- image[i] = otherdims | (idim << 20);
+ idim &= IMGMASK;
+ image[i] = otherdims | (idim << IMG2BITS);
}
}
}
/* ----------------------------------------------------------------------
count # of degrees-of-freedom removed by fix_rigid for atoms in igroup
------------------------------------------------------------------------- */
int FixRigid::dof(int igroup)
{
int groupbit = group->bitmask[igroup];
// nall = # of point particles in each rigid body
// mall = # of finite-size particles in each rigid body
// particles must also be in temperature group
int *mask = atom->mask;
int nlocal = atom->nlocal;
int *ncount = new int[nbody];
int *mcount = new int[nbody];
for (int ibody = 0; ibody < nbody; ibody++)
ncount[ibody] = mcount[ibody] = 0;
for (int i = 0; i < nlocal; i++)
if (body[i] >= 0 && mask[i] & groupbit) {
if (extended && eflags[i]) mcount[body[i]]++;
else ncount[body[i]]++;
}
int *nall = new int[nbody];
int *mall = new int[nbody];
MPI_Allreduce(ncount,nall,nbody,MPI_INT,MPI_SUM,world);
MPI_Allreduce(mcount,mall,nbody,MPI_INT,MPI_SUM,world);
// warn if nall+mall != nrigid for any body included in temperature group
int flag = 0;
for (int ibody = 0; ibody < nbody; ibody++) {
if (nall[ibody]+mall[ibody] > 0 &&
nall[ibody]+mall[ibody] != nrigid[ibody]) flag = 1;
}
if (flag && me == 0)
error->warning(FLERR,"Computing temperature of portions of rigid bodies");
// remove appropriate DOFs for each rigid body wholly in temperature group
// N = # of point particles in body
// M = # of finite-size particles in body
// 3d body has 3N + 6M dof to start with
// 2d body has 2N + 3M dof to start with
// 3d point-particle body with all non-zero I should have 6 dof, remove 3N-6
// 3d point-particle body (linear) with a 0 I should have 5 dof, remove 3N-5
// 2d point-particle body should have 3 dof, remove 2N-3
// 3d body with any finite-size M should have 6 dof, remove (3N+6M) - 6
// 2d body with any finite-size M should have 3 dof, remove (2N+3M) - 3
int n = 0;
if (domain->dimension == 3) {
for (int ibody = 0; ibody < nbody; ibody++)
if (nall[ibody]+mall[ibody] == nrigid[ibody]) {
n += 3*nall[ibody] + 6*mall[ibody] - 6;
if (inertia[ibody][0] == 0.0 || inertia[ibody][1] == 0.0 ||
inertia[ibody][2] == 0.0) n++;
}
} else if (domain->dimension == 2) {
for (int ibody = 0; ibody < nbody; ibody++)
if (nall[ibody]+mall[ibody] == nrigid[ibody])
n += 2*nall[ibody] + 3*mall[ibody] - 3;
}
delete [] ncount;
delete [] mcount;
delete [] nall;
delete [] mall;
return n;
}
/* ----------------------------------------------------------------------
adjust xcm of each rigid body due to box deformation
called by various fixes that change box size/shape
flag = 0/1 means map from box to lamda coords or vice versa
------------------------------------------------------------------------- */
void FixRigid::deform(int flag)
{
if (flag == 0)
for (int ibody = 0; ibody < nbody; ibody++)
domain->x2lamda(xcm[ibody],xcm[ibody]);
else
for (int ibody = 0; ibody < nbody; ibody++)
domain->lamda2x(xcm[ibody],xcm[ibody]);
}
/* ----------------------------------------------------------------------
set space-frame coords and velocity of each atom in each rigid body
set orientation and rotation of extended particles
x = Q displace + Xcm, mapped back to periodic box
v = Vcm + (W cross (x - Xcm))
------------------------------------------------------------------------- */
void FixRigid::set_xv()
{
int ibody,itype;
int xbox,ybox,zbox;
double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone;
double xy,xz,yz;
double ione[3],exone[3],eyone[3],ezone[3],vr[6],p[3][3];
- int *image = atom->image;
+ tagint *image = atom->image;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
if (triclinic) {
xy = domain->xy;
xz = domain->xz;
yz = domain->yz;
}
// set x and v of each atom
for (int i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
// save old positions and velocities for virial
if (evflag) {
if (triclinic == 0) {
x0 = x[i][0] + xbox*xprd;
x1 = x[i][1] + ybox*yprd;
x2 = x[i][2] + zbox*zprd;
} else {
x0 = x[i][0] + xbox*xprd + ybox*xy + zbox*xz;
x1 = x[i][1] + ybox*yprd + zbox*yz;
x2 = x[i][2] + zbox*zprd;
}
v0 = v[i][0];
v1 = v[i][1];
v2 = v[i][2];
}
// x = displacement from center-of-mass, based on body orientation
// v = vcm + omega around center-of-mass
MathExtra::matvec(ex_space[ibody],ey_space[ibody],
ez_space[ibody],displace[i],x[i]);
v[i][0] = omega[ibody][1]*x[i][2] - omega[ibody][2]*x[i][1] +
vcm[ibody][0];
v[i][1] = omega[ibody][2]*x[i][0] - omega[ibody][0]*x[i][2] +
vcm[ibody][1];
v[i][2] = omega[ibody][0]*x[i][1] - omega[ibody][1]*x[i][0] +
vcm[ibody][2];
// add center of mass to displacement
// map back into periodic box via xbox,ybox,zbox
// for triclinic, add in box tilt factors as well
if (triclinic == 0) {
x[i][0] += xcm[ibody][0] - xbox*xprd;
x[i][1] += xcm[ibody][1] - ybox*yprd;
x[i][2] += xcm[ibody][2] - zbox*zprd;
} else {
x[i][0] += xcm[ibody][0] - xbox*xprd - ybox*xy - zbox*xz;
x[i][1] += xcm[ibody][1] - ybox*yprd - zbox*yz;
x[i][2] += xcm[ibody][2] - zbox*zprd;
}
// virial = unwrapped coords dotted into body constraint force
// body constraint force = implied force due to v change minus f external
// assume f does not include forces internal to body
// 1/2 factor b/c final_integrate contributes other half
// assume per-atom contribution is due to constraint force on that atom
if (evflag) {
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
fc0 = massone*(v[i][0] - v0)/dtf - f[i][0];
fc1 = massone*(v[i][1] - v1)/dtf - f[i][1];
fc2 = massone*(v[i][2] - v2)/dtf - f[i][2];
vr[0] = 0.5*x0*fc0;
vr[1] = 0.5*x1*fc1;
vr[2] = 0.5*x2*fc2;
vr[3] = 0.5*x0*fc1;
vr[4] = 0.5*x0*fc2;
vr[5] = 0.5*x1*fc2;
v_tally(1,&i,1.0,vr);
}
}
// set orientation, omega, angmom of each extended particle
if (extended) {
double theta_body,theta;
double *shape,*quatatom,*inertiaatom;
AtomVecEllipsoid::Bonus *ebonus;
if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus;
AtomVecLine::Bonus *lbonus;
if (avec_line) lbonus = avec_line->bonus;
AtomVecTri::Bonus *tbonus;
if (avec_tri) tbonus = avec_tri->bonus;
double **omega_one = atom->omega;
double **angmom_one = atom->angmom;
double **mu = atom->mu;
int *ellipsoid = atom->ellipsoid;
int *line = atom->line;
int *tri = atom->tri;
for (int i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
if (eflags[i] & SPHERE) {
omega_one[i][0] = omega[ibody][0];
omega_one[i][1] = omega[ibody][1];
omega_one[i][2] = omega[ibody][2];
} else if (eflags[i] & ELLIPSOID) {
shape = ebonus[ellipsoid[i]].shape;
quatatom = ebonus[ellipsoid[i]].quat;
MathExtra::quatquat(quat[ibody],orient[i],quatatom);
MathExtra::qnormalize(quatatom);
ione[0] = EINERTIA*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]);
ione[1] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]);
ione[2] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]);
MathExtra::q_to_exyz(quatatom,exone,eyone,ezone);
MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,ione,
angmom_one[i]);
} else if (eflags[i] & LINE) {
if (quat[ibody][3] >= 0.0) theta_body = 2.0*acos(quat[ibody][0]);
else theta_body = -2.0*acos(quat[ibody][0]);
theta = orient[i][0] + theta_body;
while (theta <= MINUSPI) theta += TWOPI;
while (theta > MY_PI) theta -= TWOPI;
lbonus[line[i]].theta = theta;
omega_one[i][0] = omega[ibody][0];
omega_one[i][1] = omega[ibody][1];
omega_one[i][2] = omega[ibody][2];
} else if (eflags[i] & TRIANGLE) {
inertiaatom = tbonus[tri[i]].inertia;
quatatom = tbonus[tri[i]].quat;
MathExtra::quatquat(quat[ibody],orient[i],quatatom);
MathExtra::qnormalize(quatatom);
MathExtra::q_to_exyz(quatatom,exone,eyone,ezone);
MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,
inertiaatom,angmom_one[i]);
}
if (eflags[i] & DIPOLE) {
MathExtra::quat_to_mat(quat[ibody],p);
MathExtra::matvec(p,dorient[i],mu[i]);
MathExtra::snormalize3(mu[i][3],mu[i],mu[i]);
}
}
}
}
/* ----------------------------------------------------------------------
set space-frame velocity of each atom in a rigid body
set omega and angmom of extended particles
v = Vcm + (W cross (x - Xcm))
------------------------------------------------------------------------- */
void FixRigid::set_v()
{
int ibody,itype;
int xbox,ybox,zbox;
double dx,dy,dz;
double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone;
double xy,xz,yz;
double ione[3],exone[3],eyone[3],ezone[3],delta[3],vr[6];
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
if (triclinic) {
xy = domain->xy;
xz = domain->xz;
yz = domain->yz;
}
// set v of each atom
for (int i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
MathExtra::matvec(ex_space[ibody],ey_space[ibody],
ez_space[ibody],displace[i],delta);
// save old velocities for virial
if (evflag) {
v0 = v[i][0];
v1 = v[i][1];
v2 = v[i][2];
}
v[i][0] = omega[ibody][1]*delta[2] - omega[ibody][2]*delta[1] +
vcm[ibody][0];
v[i][1] = omega[ibody][2]*delta[0] - omega[ibody][0]*delta[2] +
vcm[ibody][1];
v[i][2] = omega[ibody][0]*delta[1] - omega[ibody][1]*delta[0] +
vcm[ibody][2];
// virial = unwrapped coords dotted into body constraint force
// body constraint force = implied force due to v change minus f external
// assume f does not include forces internal to body
// 1/2 factor b/c initial_integrate contributes other half
// assume per-atom contribution is due to constraint force on that atom
if (evflag) {
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
fc0 = massone*(v[i][0] - v0)/dtf - f[i][0];
fc1 = massone*(v[i][1] - v1)/dtf - f[i][1];
fc2 = massone*(v[i][2] - v2)/dtf - f[i][2];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
x0 = x[i][0] + xbox*xprd;
x1 = x[i][1] + ybox*yprd;
x2 = x[i][2] + zbox*zprd;
} else {
x0 = x[i][0] + xbox*xprd + ybox*xy + zbox*xz;
x1 = x[i][1] + ybox*yprd + zbox*yz;
x2 = x[i][2] + zbox*zprd;
}
vr[0] = 0.5*x0*fc0;
vr[1] = 0.5*x1*fc1;
vr[2] = 0.5*x2*fc2;
vr[3] = 0.5*x0*fc1;
vr[4] = 0.5*x0*fc2;
vr[5] = 0.5*x1*fc2;
v_tally(1,&i,1.0,vr);
}
}
// set omega, angmom of each extended particle
if (extended) {
double *shape,*quatatom,*inertiaatom;
AtomVecEllipsoid::Bonus *ebonus;
if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus;
AtomVecTri::Bonus *tbonus;
if (avec_tri) tbonus = avec_tri->bonus;
double **omega_one = atom->omega;
double **angmom_one = atom->angmom;
int *ellipsoid = atom->ellipsoid;
int *tri = atom->tri;
for (int i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
if (eflags[i] & SPHERE) {
omega_one[i][0] = omega[ibody][0];
omega_one[i][1] = omega[ibody][1];
omega_one[i][2] = omega[ibody][2];
} else if (eflags[i] & ELLIPSOID) {
shape = ebonus[ellipsoid[i]].shape;
quatatom = ebonus[ellipsoid[i]].quat;
ione[0] = EINERTIA*rmass[i] * (shape[1]*shape[1] + shape[2]*shape[2]);
ione[1] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[2]*shape[2]);
ione[2] = EINERTIA*rmass[i] * (shape[0]*shape[0] + shape[1]*shape[1]);
MathExtra::q_to_exyz(quatatom,exone,eyone,ezone);
MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,ione,
angmom_one[i]);
} else if (eflags[i] & LINE) {
omega_one[i][0] = omega[ibody][0];
omega_one[i][1] = omega[ibody][1];
omega_one[i][2] = omega[ibody][2];
} else if (eflags[i] & TRIANGLE) {
inertiaatom = tbonus[tri[i]].inertia;
quatatom = tbonus[tri[i]].quat;
MathExtra::q_to_exyz(quatatom,exone,eyone,ezone);
MathExtra::omega_to_angmom(omega[ibody],exone,eyone,ezone,
inertiaatom,angmom_one[i]);
}
}
}
}
/* ----------------------------------------------------------------------
one-time initialization of rigid body attributes
extended flags, masstotal, center-of-mass
Cartesian and diagonalized inertia tensor
read per-body attributes from infile if specified
------------------------------------------------------------------------- */
void FixRigid::setup_bodies()
{
int i,itype,ibody;
// extended = 1 if any particle in a rigid body is finite size
// or has a dipole moment
extended = orientflag = dorientflag = 0;
AtomVecEllipsoid::Bonus *ebonus;
if (avec_ellipsoid) ebonus = avec_ellipsoid->bonus;
AtomVecLine::Bonus *lbonus;
if (avec_line) lbonus = avec_line->bonus;
AtomVecTri::Bonus *tbonus;
if (avec_tri) tbonus = avec_tri->bonus;
double **mu = atom->mu;
double *radius = atom->radius;
double *rmass = atom->rmass;
double *mass = atom->mass;
int *ellipsoid = atom->ellipsoid;
int *line = atom->line;
int *tri = atom->tri;
int *type = atom->type;
int nlocal = atom->nlocal;
if (atom->radius_flag || atom->ellipsoid_flag || atom->line_flag ||
atom->tri_flag || atom->mu_flag) {
int flag = 0;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
if (radius && radius[i] > 0.0) flag = 1;
if (ellipsoid && ellipsoid[i] >= 0) flag = 1;
if (line && line[i] >= 0) flag = 1;
if (tri && tri[i] >= 0) flag = 1;
if (mu && mu[i][3] > 0.0) flag = 1;
}
MPI_Allreduce(&flag,&extended,1,MPI_INT,MPI_MAX,world);
}
// grow extended arrays and set extended flags for each particle
// orientflag = 4 if any particle stores ellipsoid or tri orientation
// orientflag = 1 if any particle stores line orientation
// dorientflag = 1 if any particle stores dipole orientation
if (extended) {
if (atom->ellipsoid_flag) orientflag = 4;
if (atom->line_flag) orientflag = 1;
if (atom->tri_flag) orientflag = 4;
if (atom->mu_flag) dorientflag = 1;
grow_arrays(atom->nmax);
for (i = 0; i < nlocal; i++) {
eflags[i] = 0;
if (body[i] < 0) continue;
// set to POINT or SPHERE or ELLIPSOID or LINE
if (radius && radius[i] > 0.0) {
eflags[i] |= SPHERE;
eflags[i] |= OMEGA;
eflags[i] |= TORQUE;
} else if (ellipsoid && ellipsoid[i] >= 0) {
eflags[i] |= ELLIPSOID;
eflags[i] |= ANGMOM;
eflags[i] |= TORQUE;
} else if (line && line[i] >= 0) {
eflags[i] |= LINE;
eflags[i] |= OMEGA;
eflags[i] |= TORQUE;
} else if (tri && tri[i] >= 0) {
eflags[i] |= TRIANGLE;
eflags[i] |= ANGMOM;
eflags[i] |= TORQUE;
} else eflags[i] |= POINT;
// set DIPOLE if atom->mu and mu[3] > 0.0
if (atom->mu_flag && mu[i][3] > 0.0)
eflags[i] |= DIPOLE;
}
}
// compute masstotal & center-of-mass of each rigid body
// error if image flag is not 0 in a non-periodic dim
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *periodicity = domain->periodicity;
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 (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
int xbox,ybox,zbox;
double massone,xunwrap,yunwrap,zunwrap;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
if ((xbox && !periodicity[0]) || (ybox && !periodicity[1]) ||
(zbox && !periodicity[2]))
error->one(FLERR,"Fix rigid atom has non-zero image flag "
"in a non-periodic dimension");
if (triclinic == 0) {
xunwrap = x[i][0] + xbox*xprd;
yunwrap = x[i][1] + ybox*yprd;
zunwrap = x[i][2] + zbox*zprd;
} else {
xunwrap = x[i][0] + xbox*xprd + ybox*xy + zbox*xz;
yunwrap = x[i][1] + ybox*yprd + zbox*yz;
zunwrap = x[i][2] + zbox*zprd;
}
sum[ibody][0] += xunwrap * massone;
sum[ibody][1] += yunwrap * massone;
sum[ibody][2] += zunwrap * massone;
sum[ibody][3] += massone;
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
for (ibody = 0; ibody < nbody; ibody++) {
masstotal[ibody] = all[ibody][3];
xcm[ibody][0] = all[ibody][0]/masstotal[ibody];
xcm[ibody][1] = all[ibody][1]/masstotal[ibody];
xcm[ibody][2] = all[ibody][2]/masstotal[ibody];
}
// overwrite masstotal and center-of-mass with file values
// inbody[i] = 0/1 if Ith rigid body is initialized by file
int *inbody;
if (infile) {
memory->create(inbody,nbody,"rigid:inbody");
for (ibody = 0; ibody < nbody; ibody++) inbody[ibody] = 0;
readfile(0,masstotal,xcm,inbody);
}
// set image flags for each rigid body to default values
// then remap the xcm of each body back into simulation box if needed
for (ibody = 0; ibody < nbody; ibody++)
- imagebody[ibody] = (512 << 20) | (512 << 10) | 512;
+ imagebody[ibody] = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMASK << IMGBITS) | IMGMAX;
pre_neighbor();
// compute 6 moments of inertia of each body in Cartesian reference frame
// dx,dy,dz = coords relative to center-of-mass
// symmetric 3x3 inertia tensor stored in Voigt notation as 6-vector
double dx,dy,dz,rad;
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
xunwrap = x[i][0] + xbox*xprd;
yunwrap = x[i][1] + ybox*yprd;
zunwrap = x[i][2] + zbox*zprd;
} else {
xunwrap = x[i][0] + xbox*xprd + ybox*xy + zbox*xz;
yunwrap = x[i][1] + ybox*yprd + zbox*yz;
zunwrap = x[i][2] + zbox*zprd;
}
dx = xunwrap - xcm[ibody][0];
dy = yunwrap - xcm[ibody][1];
dz = zunwrap - xcm[ibody][2];
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
sum[ibody][0] += massone * (dy*dy + dz*dz);
sum[ibody][1] += massone * (dx*dx + dz*dz);
sum[ibody][2] += massone * (dx*dx + dy*dy);
sum[ibody][3] -= massone * dy*dz;
sum[ibody][4] -= massone * dx*dz;
sum[ibody][5] -= massone * dx*dy;
}
// extended particles may contribute extra terms to moments of inertia
if (extended) {
double ivec[6];
double *shape,*quatatom,*inertiaatom;
double length,theta;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
if (eflags[i] & SPHERE) {
sum[ibody][0] += SINERTIA*massone * radius[i]*radius[i];
sum[ibody][1] += SINERTIA*massone * radius[i]*radius[i];
sum[ibody][2] += SINERTIA*massone * radius[i]*radius[i];
} else if (eflags[i] & ELLIPSOID) {
shape = ebonus[ellipsoid[i]].shape;
quatatom = ebonus[ellipsoid[i]].quat;
MathExtra::inertia_ellipsoid(shape,quatatom,massone,ivec);
sum[ibody][0] += ivec[0];
sum[ibody][1] += ivec[1];
sum[ibody][2] += ivec[2];
sum[ibody][3] += ivec[3];
sum[ibody][4] += ivec[4];
sum[ibody][5] += ivec[5];
} else if (eflags[i] & LINE) {
length = lbonus[line[i]].length;
theta = lbonus[line[i]].theta;
MathExtra::inertia_line(length,theta,massone,ivec);
sum[ibody][0] += ivec[0];
sum[ibody][1] += ivec[1];
sum[ibody][2] += ivec[2];
sum[ibody][3] += ivec[3];
sum[ibody][4] += ivec[4];
sum[ibody][5] += ivec[5];
} else if (eflags[i] & TRIANGLE) {
inertiaatom = tbonus[tri[i]].inertia;
quatatom = tbonus[tri[i]].quat;
MathExtra::inertia_triangle(inertiaatom,quatatom,massone,ivec);
sum[ibody][0] += ivec[0];
sum[ibody][1] += ivec[1];
sum[ibody][2] += ivec[2];
sum[ibody][3] += ivec[3];
sum[ibody][4] += ivec[4];
sum[ibody][5] += ivec[5];
}
}
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
// overwrite Cartesian inertia tensor with file values
if (infile) readfile(1,NULL,all,inbody);
// diagonalize inertia tensor for each body via Jacobi rotations
// inertia = 3 eigenvalues = principal moments of inertia
// evectors and exzy_space = 3 evectors = principal axes of rigid body
int ierror;
double cross[3];
double tensor[3][3],evectors[3][3];
for (ibody = 0; ibody < nbody; ibody++) {
tensor[0][0] = all[ibody][0];
tensor[1][1] = all[ibody][1];
tensor[2][2] = all[ibody][2];
tensor[1][2] = tensor[2][1] = all[ibody][3];
tensor[0][2] = tensor[2][0] = all[ibody][4];
tensor[0][1] = tensor[1][0] = all[ibody][5];
ierror = MathExtra::jacobi(tensor,inertia[ibody],evectors);
if (ierror) error->all(FLERR,
"Insufficient Jacobi rotations for rigid body");
ex_space[ibody][0] = evectors[0][0];
ex_space[ibody][1] = evectors[1][0];
ex_space[ibody][2] = evectors[2][0];
ey_space[ibody][0] = evectors[0][1];
ey_space[ibody][1] = evectors[1][1];
ey_space[ibody][2] = evectors[2][1];
ez_space[ibody][0] = evectors[0][2];
ez_space[ibody][1] = evectors[1][2];
ez_space[ibody][2] = evectors[2][2];
// if any principal moment < scaled EPSILON, set to 0.0
double max;
max = MAX(inertia[ibody][0],inertia[ibody][1]);
max = MAX(max,inertia[ibody][2]);
if (inertia[ibody][0] < EPSILON*max) inertia[ibody][0] = 0.0;
if (inertia[ibody][1] < EPSILON*max) inertia[ibody][1] = 0.0;
if (inertia[ibody][2] < EPSILON*max) inertia[ibody][2] = 0.0;
// enforce 3 evectors as a right-handed coordinate system
// flip 3rd vector if needed
MathExtra::cross3(ex_space[ibody],ey_space[ibody],cross);
if (MathExtra::dot3(cross,ez_space[ibody]) < 0.0)
MathExtra::negate3(ez_space[ibody]);
// create initial quaternion
MathExtra::exyz_to_q(ex_space[ibody],ey_space[ibody],ez_space[ibody],
quat[ibody]);
}
// displace = initial atom coords in basis of principal axes
// set displace = 0.0 for atoms not in any rigid body
// for extended particles, set their orientation wrt to rigid body
double qc[4],delta[3];
double *quatatom;
double theta_body;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) {
displace[i][0] = displace[i][1] = displace[i][2] = 0.0;
continue;
}
ibody = body[i];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
xunwrap = x[i][0] + xbox*xprd;
yunwrap = x[i][1] + ybox*yprd;
zunwrap = x[i][2] + zbox*zprd;
} else {
xunwrap = x[i][0] + xbox*xprd + ybox*xy + zbox*xz;
yunwrap = x[i][1] + ybox*yprd + zbox*yz;
zunwrap = x[i][2] + zbox*zprd;
}
delta[0] = xunwrap - xcm[ibody][0];
delta[1] = yunwrap - xcm[ibody][1];
delta[2] = zunwrap - xcm[ibody][2];
MathExtra::transpose_matvec(ex_space[ibody],ey_space[ibody],
ez_space[ibody],delta,displace[i]);
if (extended) {
if (eflags[i] & ELLIPSOID) {
quatatom = ebonus[ellipsoid[i]].quat;
MathExtra::qconjugate(quat[ibody],qc);
MathExtra::quatquat(qc,quatatom,orient[i]);
MathExtra::qnormalize(orient[i]);
} else if (eflags[i] & LINE) {
if (quat[ibody][3] >= 0.0) theta_body = 2.0*acos(quat[ibody][0]);
else theta_body = -2.0*acos(quat[ibody][0]);
orient[i][0] = lbonus[line[i]].theta - theta_body;
while (orient[i][0] <= MINUSPI) orient[i][0] += TWOPI;
while (orient[i][0] > MY_PI) orient[i][0] -= TWOPI;
if (orientflag == 4) orient[i][1] = orient[i][2] = orient[i][3] = 0.0;
} else if (eflags[i] & TRIANGLE) {
quatatom = tbonus[tri[i]].quat;
MathExtra::qconjugate(quat[ibody],qc);
MathExtra::quatquat(qc,quatatom,orient[i]);
MathExtra::qnormalize(orient[i]);
} else if (orientflag == 4) {
orient[i][0] = orient[i][1] = orient[i][2] = orient[i][3] = 0.0;
} else if (orientflag == 1)
orient[i][0] = 0.0;
if (eflags[i] & DIPOLE) {
MathExtra::transpose_matvec(ex_space[ibody],ey_space[ibody],
ez_space[ibody],mu[i],dorient[i]);
MathExtra::snormalize3(mu[i][3],dorient[i],dorient[i]);
} else if (dorientflag)
dorient[i][0] = dorient[i][1] = dorient[i][2] = 0.0;
}
}
// test for valid principal moments & axes
// recompute moments of inertia around new axes
// 3 diagonal moments should equal principal moments
// 3 off-diagonal moments should be 0.0
// extended particles may contribute extra terms to moments of inertia
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
sum[ibody][0] += massone *
(displace[i][1]*displace[i][1] + displace[i][2]*displace[i][2]);
sum[ibody][1] += massone *
(displace[i][0]*displace[i][0] + displace[i][2]*displace[i][2]);
sum[ibody][2] += massone *
(displace[i][0]*displace[i][0] + displace[i][1]*displace[i][1]);
sum[ibody][3] -= massone * displace[i][1]*displace[i][2];
sum[ibody][4] -= massone * displace[i][0]*displace[i][2];
sum[ibody][5] -= massone * displace[i][0]*displace[i][1];
}
if (extended) {
double ivec[6];
double *shape,*inertiaatom;
double length;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
if (eflags[i] & SPHERE) {
sum[ibody][0] += SINERTIA*massone * radius[i]*radius[i];
sum[ibody][1] += SINERTIA*massone * radius[i]*radius[i];
sum[ibody][2] += SINERTIA*massone * radius[i]*radius[i];
} else if (eflags[i] & ELLIPSOID) {
shape = ebonus[ellipsoid[i]].shape;
MathExtra::inertia_ellipsoid(shape,orient[i],massone,ivec);
sum[ibody][0] += ivec[0];
sum[ibody][1] += ivec[1];
sum[ibody][2] += ivec[2];
sum[ibody][3] += ivec[3];
sum[ibody][4] += ivec[4];
sum[ibody][5] += ivec[5];
} else if (eflags[i] & LINE) {
length = lbonus[line[i]].length;
MathExtra::inertia_line(length,orient[i][0],massone,ivec);
sum[ibody][0] += ivec[0];
sum[ibody][1] += ivec[1];
sum[ibody][2] += ivec[2];
sum[ibody][3] += ivec[3];
sum[ibody][4] += ivec[4];
sum[ibody][5] += ivec[5];
} else if (eflags[i] & TRIANGLE) {
inertiaatom = tbonus[tri[i]].inertia;
MathExtra::inertia_triangle(inertiaatom,orient[i],massone,ivec);
sum[ibody][0] += ivec[0];
sum[ibody][1] += ivec[1];
sum[ibody][2] += ivec[2];
sum[ibody][3] += ivec[3];
sum[ibody][4] += ivec[4];
sum[ibody][5] += ivec[5];
}
}
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
// error check that re-computed momemts of inertia match diagonalized ones
// do not do test for bodies with params read from infile
double norm;
for (ibody = 0; ibody < nbody; ibody++) {
if (infile && inbody[ibody]) continue;
if (inertia[ibody][0] == 0.0) {
if (fabs(all[ibody][0]) > TOLERANCE)
error->all(FLERR,"Fix rigid: Bad principal moments");
} else {
if (fabs((all[ibody][0]-inertia[ibody][0])/inertia[ibody][0]) >
TOLERANCE) error->all(FLERR,"Fix rigid: Bad principal moments");
}
if (inertia[ibody][1] == 0.0) {
if (fabs(all[ibody][1]) > TOLERANCE)
error->all(FLERR,"Fix rigid: Bad principal moments");
} else {
if (fabs((all[ibody][1]-inertia[ibody][1])/inertia[ibody][1]) >
TOLERANCE) error->all(FLERR,"Fix rigid: Bad principal moments");
}
if (inertia[ibody][2] == 0.0) {
if (fabs(all[ibody][2]) > TOLERANCE)
error->all(FLERR,"Fix rigid: Bad principal moments");
} else {
if (fabs((all[ibody][2]-inertia[ibody][2])/inertia[ibody][2]) >
TOLERANCE) error->all(FLERR,"Fix rigid: Bad principal moments");
}
norm = (inertia[ibody][0] + inertia[ibody][1] + inertia[ibody][2]) / 3.0;
if (fabs(all[ibody][3]/norm) > TOLERANCE ||
fabs(all[ibody][4]/norm) > TOLERANCE ||
fabs(all[ibody][5]/norm) > TOLERANCE)
error->all(FLERR,"Fix rigid: Bad principal moments");
}
if (infile) memory->destroy(inbody);
}
/* ----------------------------------------------------------------------
read per rigid body info from user-provided file
which = 0 to read total mass and center-of-mass, store in vec and array
which = 1 to read 6 moments of inertia, store in array
flag inbody = 0 for bodies whose info is read from file
nlines = # of lines of rigid body info
one line = rigid-ID mass xcm ycm zcm ixx iyy izz ixy ixz iyz
------------------------------------------------------------------------- */
void FixRigid::readfile(int which, double *vec, double **array, int *inbody)
{
int i,j,m,nchunk,id;
int nlines;
FILE *fp;
char *eof,*start,*next,*buf;
char line[MAXLINE];
if (me == 0) {
fp = fopen(infile,"r");
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open fix rigid infile %s",infile);
error->one(FLERR,str);
}
while (1) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of fix rigid file");
start = &line[strspn(line," \t\n\v\f\r")];
if (*start != '\0' && *start != '#') break;
}
sscanf(line,"%d",&nlines);
}
MPI_Bcast(&nlines,1,MPI_INT,0,world);
char *buffer = new char[CHUNK*MAXLINE];
char **values = new char*[ATTRIBUTE_PERBODY];
int nread = 0;
while (nread < nlines) {
if (nlines-nread > CHUNK) nchunk = CHUNK;
else nchunk = nlines-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(FLERR,"Unexpected end of fix rigid file");
m += strlen(&buffer[m]);
}
m++;
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
buf = buffer;
next = strchr(buf,'\n');
*next = '\0';
int nwords = atom->count_words(buf);
*next = '\n';
if (nwords != ATTRIBUTE_PERBODY)
error->all(FLERR,"Incorrect rigid body format in fix rigid file");
// loop over lines of rigid body attributes
// tokenize the line into values
// id = rigid body ID
// use ID as-is for SINGLE, as mol-ID for MOLECULE, as-is for GROUP
// for which = 0, store mass/com in vec/array
// for which = 1, store interia tensor array, invert 3,4,5 values to Voigt
for (int i = 0; i < nchunk; i++) {
next = strchr(buf,'\n');
values[0] = strtok(buf," \t\n\r\f");
for (j = 1; j < nwords; j++)
values[j] = strtok(NULL," \t\n\r\f");
id = atoi(values[0]);
if (rstyle == MOLECULE) {
if (id <= 0 || id > maxmol)
error->all(FLERR,"Invalid rigid body ID in fix rigid file");
id = mol2body[id];
} else id--;
if (id < 0 || id >= nbody)
error->all(FLERR,"Invalid rigid body ID in fix rigid file");
inbody[id] = 1;
if (which == 0) {
vec[id] = atof(values[1]);
array[id][0] = atof(values[2]);
array[id][1] = atof(values[3]);
array[id][2] = atof(values[4]);
} else {
array[id][0] = atof(values[5]);
array[id][1] = atof(values[6]);
array[id][2] = atof(values[7]);
array[id][5] = atof(values[8]);
array[id][4] = atof(values[9]);
array[id][3] = atof(values[10]);
}
buf = next + 1;
}
nread += nchunk;
}
if (me == 0) fclose(fp);
delete [] buffer;
delete [] values;
}
/* ----------------------------------------------------------------------
memory usage of local atom-based arrays
------------------------------------------------------------------------- */
double FixRigid::memory_usage()
{
int nmax = atom->nmax;
double bytes = nmax * sizeof(int);
bytes += nmax*3 * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
if (extended) {
bytes += nmax * sizeof(int);
if (orientflag) bytes = nmax*orientflag * sizeof(double);
if (dorientflag) bytes = nmax*3 * sizeof(double);
}
return bytes;
}
/* ----------------------------------------------------------------------
allocate local atom-based arrays
------------------------------------------------------------------------- */
void FixRigid::grow_arrays(int nmax)
{
memory->grow(body,nmax,"rigid:body");
memory->grow(displace,nmax,3,"rigid:displace");
if (extended) {
memory->grow(eflags,nmax,"rigid:eflags");
if (orientflag) memory->grow(orient,nmax,orientflag,"rigid:orient");
if (dorientflag) memory->grow(dorient,nmax,3,"rigid:dorient");
}
}
/* ----------------------------------------------------------------------
copy values within local atom-based arrays
------------------------------------------------------------------------- */
void FixRigid::copy_arrays(int i, int j)
{
body[j] = body[i];
displace[j][0] = displace[i][0];
displace[j][1] = displace[i][1];
displace[j][2] = displace[i][2];
if (extended) {
eflags[j] = eflags[i];
for (int k = 0; k < orientflag; k++)
orient[j][k] = orient[i][k];
if (dorientflag) {
dorient[j][0] = dorient[i][0];
dorient[j][1] = dorient[i][1];
dorient[j][2] = dorient[i][2];
}
}
}
/* ----------------------------------------------------------------------
initialize one atom's array values, called when atom is created
------------------------------------------------------------------------- */
void FixRigid::set_arrays(int i)
{
body[i] = -1;
displace[i][0] = 0.0;
displace[i][1] = 0.0;
displace[i][2] = 0.0;
}
/* ----------------------------------------------------------------------
pack values in local atom-based arrays for exchange with another proc
------------------------------------------------------------------------- */
int FixRigid::pack_exchange(int i, double *buf)
{
buf[0] = body[i];
buf[1] = displace[i][0];
buf[2] = displace[i][1];
buf[3] = displace[i][2];
if (!extended) return 4;
int m = 4;
buf[m++] = eflags[i];
for (int j = 0; j < orientflag; j++)
buf[m++] = orient[i][j];
if (dorientflag) {
buf[m++] = dorient[i][0];
buf[m++] = dorient[i][1];
buf[m++] = dorient[i][2];
}
return m;
}
/* ----------------------------------------------------------------------
unpack values in local atom-based arrays from exchange with another proc
------------------------------------------------------------------------- */
int FixRigid::unpack_exchange(int nlocal, double *buf)
{
body[nlocal] = static_cast<int> (buf[0]);
displace[nlocal][0] = buf[1];
displace[nlocal][1] = buf[2];
displace[nlocal][2] = buf[3];
if (!extended) return 4;
int m = 4;
eflags[nlocal] = static_cast<int> (buf[m++]);
for (int j = 0; j < orientflag; j++)
orient[nlocal][j] = buf[m++];
if (dorientflag) {
dorient[nlocal][0] = buf[m++];
dorient[nlocal][1] = buf[m++];
dorient[nlocal][2] = buf[m++];
}
return m;
}
/* ---------------------------------------------------------------------- */
void FixRigid::reset_dt()
{
dtv = update->dt;
dtf = 0.5 * update->dt * force->ftm2v;
dtq = 0.5 * update->dt;
}
/* ----------------------------------------------------------------------
return temperature of collection of rigid bodies
non-active DOF are removed by fflag/tflag and in tfactor
------------------------------------------------------------------------- */
double FixRigid::compute_scalar()
{
double wbody[3],rot[3][3];
double t = 0.0;
for (int i = 0; i < nbody; i++) {
t += masstotal[i] * (fflag[i][0]*vcm[i][0]*vcm[i][0] +
fflag[i][1]*vcm[i][1]*vcm[i][1] + \
fflag[i][2]*vcm[i][2]*vcm[i][2]);
// wbody = angular velocity in body frame
MathExtra::quat_to_mat(quat[i],rot);
MathExtra::transpose_matvec(rot,angmom[i],wbody);
if (inertia[i][0] == 0.0) wbody[0] = 0.0;
else wbody[0] /= inertia[i][0];
if (inertia[i][1] == 0.0) wbody[1] = 0.0;
else wbody[1] /= inertia[i][1];
if (inertia[i][2] == 0.0) wbody[2] = 0.0;
else wbody[2] /= inertia[i][2];
t += tflag[i][0]*inertia[i][0]*wbody[0]*wbody[0] +
tflag[i][1]*inertia[i][1]*wbody[1]*wbody[1] +
tflag[i][2]*inertia[i][2]*wbody[2]*wbody[2];
}
t *= tfactor;
return t;
}
/* ----------------------------------------------------------------------
extract thermostat properties
------------------------------------------------------------------------- */
void *FixRigid::extract(const char *str, int &dim)
{
dim=0;
if (strcmp(str,"t_target") == 0) {
return &t_target;
}
return NULL;
}
/* ----------------------------------------------------------------------
return attributes of a rigid body
15 values per body
xcm = 0,1,2; vcm = 3,4,5; fcm = 6,7,8; torque = 9,10,11; image = 12,13,14
------------------------------------------------------------------------- */
double FixRigid::compute_array(int i, int j)
{
if (j < 3) return xcm[i][j];
if (j < 6) return vcm[i][j-3];
if (j < 9) return fcm[i][j-6];
if (j < 12) return torque[i][j-9];
- if (j == 12) return (imagebody[i] & 1023) - 512;
- if (j == 13) return (imagebody[i] >> 10 & 1023) - 512;
- return (imagebody[i] >> 20) - 512;
+ if (j == 12) return (imagebody[i] & IMGMASK) - IMGMAX;
+ if (j == 13) return (imagebody[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ return (imagebody[i] >> IMG2BITS) - IMGMAX;
}
diff --git a/src/fix_rigid.h b/src/fix_rigid.h
index 26cfbf752..3888d88bd 100644
--- a/src/fix_rigid.h
+++ b/src/fix_rigid.h
@@ -1,208 +1,226 @@
/* -*- c++ -*- ----------------------------------------------------------
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(rigid,FixRigid)
#else
#ifndef LMP_FIX_RIGID_H
#define LMP_FIX_RIGID_H
#include "fix.h"
namespace LAMMPS_NS {
class FixRigid : public Fix {
public:
// public so that granular pair styles can access them
int *body; // which body each atom is part of (-1 if none)
double *masstotal; // total mass of each rigid body
FixRigid(class LAMMPS *, int, char **);
virtual ~FixRigid();
virtual int setmask();
virtual void init();
virtual void setup(int);
virtual void initial_integrate(int);
void post_force(int);
virtual void final_integrate();
void initial_integrate_respa(int, int, int);
void final_integrate_respa(int, int);
virtual double compute_scalar();
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 *);
void pre_neighbor();
int dof(int);
void deform(int);
void reset_dt();
virtual void *extract(const char*,int &);
double compute_array(int, int);
protected:
int me,nprocs;
double dtv,dtf,dtq;
double *step_respa;
int triclinic;
double MINUSPI,TWOPI;
int rstyle; // SINGLE,MOLECULE,GROUP
int firstflag; // 1 for first-time setup of rigid bodies
char *infile; // file to read rigid body attributes from
int nbody; // # of rigid bodies
int *nrigid; // # of atoms in each rigid body
int *mol2body; // convert mol-ID to rigid body index
int maxmol; // size of mol2body = max mol-ID
double **xcm; // coords of center-of-mass of each rigid body
double **vcm; // velocity of center-of-mass of each
double **fcm; // force on center-of-mass of each
double **inertia; // 3 principal components of inertia of each
double **ex_space,**ey_space,**ez_space;
// principal axes of each in space coords
double **angmom; // angular momentum of each in space coords
double **omega; // angular velocity of each in space coords
double **torque; // torque on each rigid body in space coords
double **quat; // quaternion of each rigid body
- int *imagebody; // image flags of xcm of each rigid body
+ tagint *imagebody; // image flags of xcm of each rigid body
double **fflag; // flag for on/off of center-of-mass force
double **tflag; // flag for on/off of center-of-mass torque
double **langextra; // Langevin thermostat forces and torques
double **displace; // displacement of each atom in body coords
double **sum,**all; // work vectors for each rigid body
int **remapflag; // PBC remap flags for each rigid body
int extended; // 1 if any particles have extended attributes
int orientflag; // 1 if particles store spatial orientation
int dorientflag; // 1 if particles store dipole orientation
int *eflags; // flags for extended particles
double **orient; // orientation vector of particle wrt rigid body
double **dorient; // orientation of dipole mu wrt rigid body
double tfactor; // scale factor on temperature of rigid bodies
int langflag; // 0/1 = no/yes Langevin thermostat
int tempflag; // NVT settings
double t_start,t_stop,t_target;
double t_period,t_freq;
int t_chain,t_iter,t_order;
int pressflag; // NPT settings
double p_start,p_stop;
double p_period,p_freq;
int p_chain;
class RanMars *random;
class AtomVecEllipsoid *avec_ellipsoid;
class AtomVecLine *avec_line;
class AtomVecTri *avec_tri;
int POINT,SPHERE,ELLIPSOID,LINE,TRIANGLE,DIPOLE; // bitmasks for eflags
int OMEGA,ANGMOM,TORQUE;
void no_squish_rotate(int, double *, double *, double *, double);
void set_xv();
void set_v();
void setup_bodies();
void readfile(int, double *, double **, int *);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Fix rigid molecule requires atom attribute molecule
Self-explanatory.
E: Could not find fix rigid group ID
A group ID used in the fix rigid command does not exist.
E: One or more atoms belong to multiple rigid bodies
Two or more rigid bodies defined by the fix rigid command cannot
contain the same atom.
E: No rigid bodies defined
The fix specification did not end up defining any rigid bodies.
E: Fix rigid z force cannot be on for 2d simulation
Self-explanatory.
E: Fix rigid xy torque cannot be on for 2d simulation
Self-explanatory.
E: Fix rigid langevin period must be > 0.0
Self-explanatory.
E: One or zero atoms in rigid body
Any rigid body defined by the fix rigid command must contain 2 or more
atoms.
W: More than one fix rigid
It is not efficient to use fix rigid more than once.
E: Rigid fix must come before NPT/NPH fix
NPT/NPH fix must be defined in input script after all rigid fixes,
else the rigid fix contribution to the pressure virial is
incorrect.
+W: Computing temperature of portions of rigid bodies
+
+The group defined by the temperature compute does not encompass all
+the atoms in one or more rigid bodies, so the change in
+degrees-of-freedom for the atoms in those partial rigid bodies will
+not be accounted for.
+
E: Fix rigid atom has non-zero image flag in a non-periodic dimension
You cannot set image flags for non-periodic dimensions.
E: Insufficient Jacobi rotations for rigid body
Eigensolve for rigid body was not sufficiently accurate.
E: Fix rigid: Bad principal moments
The principal moments of inertia computed for a rigid body
are not within the required tolerances.
-W: Computing temperature of portions of rigid bodies
+E: Cannot open fix rigid infile %s
-The group defined by the temperature compute does not encompass all
-the atoms in one or more rigid bodies, so the change in
-degrees-of-freedom for the atoms in those partial rigid bodies will
-not be accounted for.
+The specified file cannot be opened. Check that the path and name are
+correct.
+
+E: Unexpected end of fix rigid file
+
+A read operation from the file failed.
+
+E: Incorrect rigid body format in fix rigid file
+
+The number of fields per line is not what expected.
+
+E: Invalid rigid body ID in fix rigid file
+
+The ID does not match the number or an existing ID of rigid bodies
+that are defined by the fix rigid command.
*/
diff --git a/src/fix_rigid_nve.cpp b/src/fix_rigid_nve.cpp
index cd04526d8..019fed287 100644
--- a/src/fix_rigid_nve.cpp
+++ b/src/fix_rigid_nve.cpp
@@ -1,281 +1,281 @@
/* ----------------------------------------------------------------------
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: Tony Sheh (U Michigan), Trung Dac Nguyen (U Michigan)
references: Kamberaj et al., J. Chem. Phys. 122, 224114 (2005)
Miller et al., J Chem Phys. 116, 8649-8659
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "string.h"
#include "fix_rigid_nve.h"
#include "math_extra.h"
#include "atom.h"
#include "domain.h"
#include "update.h"
#include "modify.h"
#include "group.h"
#include "comm.h"
#include "force.h"
#include "output.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixRigidNVE::FixRigidNVE(LAMMPS *lmp, int narg, char **arg) :
FixRigid(lmp, narg, arg)
{
memory->create(conjqm,nbody,4,"rigid/nve:conjqm");
}
/* ---------------------------------------------------------------------- */
FixRigidNVE::~FixRigidNVE()
{
memory->destroy(conjqm);
}
/* ---------------------------------------------------------------------- */
void FixRigidNVE::setup(int vflag)
{
FixRigid::setup(vflag);
double mbody[3];
for (int ibody = 0; ibody < nbody; ibody++) {
MathExtra::transpose_matvec(ex_space[ibody],ey_space[ibody],ez_space[ibody],
angmom[ibody],mbody);
MathExtra::quatvec(quat[ibody],mbody,conjqm[ibody]);
conjqm[ibody][0] *= 2.0;
conjqm[ibody][1] *= 2.0;
conjqm[ibody][2] *= 2.0;
conjqm[ibody][3] *= 2.0;
}
}
/* ----------------------------------------------------------------------
perform preforce velocity Verlet integration
see Kamberaj paper for step references
------------------------------------------------------------------------- */
void FixRigidNVE::initial_integrate(int vflag)
{
double dtfm,mbody[3],tbody[3],fquat[4];
double dtf2 = dtf * 2.0;
for (int ibody = 0; ibody < nbody; ibody++) {
// step 1.1 - update vcm by 1/2 step
dtfm = dtf / masstotal[ibody];
vcm[ibody][0] += dtfm * fcm[ibody][0] * fflag[ibody][0];
vcm[ibody][1] += dtfm * fcm[ibody][1] * fflag[ibody][1];
vcm[ibody][2] += dtfm * fcm[ibody][2] * fflag[ibody][2];
// step 1.2 - update xcm by full step
xcm[ibody][0] += dtv * vcm[ibody][0];
xcm[ibody][1] += dtv * vcm[ibody][1];
xcm[ibody][2] += dtv * vcm[ibody][2];
// step 1.3 - apply torque (body coords) to quaternion momentum
torque[ibody][0] *= tflag[ibody][0];
torque[ibody][1] *= tflag[ibody][1];
torque[ibody][2] *= tflag[ibody][2];
MathExtra::transpose_matvec(ex_space[ibody],ey_space[ibody],ez_space[ibody],
torque[ibody],tbody);
MathExtra::quatvec(quat[ibody],tbody,fquat);
conjqm[ibody][0] += dtf2 * fquat[0];
conjqm[ibody][1] += dtf2 * fquat[1];
conjqm[ibody][2] += dtf2 * fquat[2];
conjqm[ibody][3] += dtf2 * fquat[3];
// step 1.4 to 1.13 - use no_squish rotate to update p and q
no_squish_rotate(3,conjqm[ibody],quat[ibody],inertia[ibody],dtq);
no_squish_rotate(2,conjqm[ibody],quat[ibody],inertia[ibody],dtq);
no_squish_rotate(1,conjqm[ibody],quat[ibody],inertia[ibody],dtv);
no_squish_rotate(2,conjqm[ibody],quat[ibody],inertia[ibody],dtq);
no_squish_rotate(3,conjqm[ibody],quat[ibody],inertia[ibody],dtq);
// update exyz_space
// transform p back to angmom
// update angular velocity
MathExtra::q_to_exyz(quat[ibody],ex_space[ibody],ey_space[ibody],
ez_space[ibody]);
MathExtra::invquatvec(quat[ibody],conjqm[ibody],mbody);
MathExtra::matvec(ex_space[ibody],ey_space[ibody],ez_space[ibody],
mbody,angmom[ibody]);
angmom[ibody][0] *= 0.5;
angmom[ibody][1] *= 0.5;
angmom[ibody][2] *= 0.5;
MathExtra::angmom_to_omega(angmom[ibody],ex_space[ibody],ey_space[ibody],
ez_space[ibody],inertia[ibody],omega[ibody]);
}
// virial setup before call to set_xv
if (vflag) v_setup(vflag);
else evflag = 0;
// set coords/orient and velocity/rotation of atoms in rigid bodies
// from quarternion and omega
set_xv();
}
/* ---------------------------------------------------------------------- */
void FixRigidNVE::final_integrate()
{
int i,ibody;
double dtfm,xy,xz,yz;
// sum over atoms to get force and torque on rigid body
- int *image = atom->image;
+ tagint *image = atom->image;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
if (triclinic) {
xy = domain->xy;
xz = domain->xz;
yz = domain->yz;
}
int xbox,ybox,zbox;
double xunwrap,yunwrap,zunwrap,dx,dy,dz;
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
sum[ibody][0] += f[i][0];
sum[ibody][1] += f[i][1];
sum[ibody][2] += f[i][2];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
xunwrap = x[i][0] + xbox*xprd;
yunwrap = x[i][1] + ybox*yprd;
zunwrap = x[i][2] + zbox*zprd;
} else {
xunwrap = x[i][0] + xbox*xprd + ybox*xy + zbox*xz;
yunwrap = x[i][1] + ybox*yprd + zbox*yz;
zunwrap = x[i][2] + zbox*zprd;
}
dx = xunwrap - xcm[ibody][0];
dy = yunwrap - xcm[ibody][1];
dz = zunwrap - xcm[ibody][2];
sum[ibody][3] += dy*f[i][2] - dz*f[i][1];
sum[ibody][4] += dz*f[i][0] - dx*f[i][2];
sum[ibody][5] += dx*f[i][1] - dy*f[i][0];
}
// extended particles add their torque to torque of body
if (extended) {
double **torque_one = atom->torque;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
if (eflags[i] & TORQUE) {
sum[ibody][3] += torque_one[i][0];
sum[ibody][4] += torque_one[i][1];
sum[ibody][5] += torque_one[i][2];
}
}
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
// update vcm and angmom
// include Langevin thermostat forces
// fflag,tflag = 0 for some dimensions in 2d
double mbody[3],tbody[3],fquat[4];
double dtf2 = dtf * 2.0;
for (ibody = 0; ibody < nbody; ibody++) {
fcm[ibody][0] = all[ibody][0] + langextra[ibody][0];
fcm[ibody][1] = all[ibody][1] + langextra[ibody][1];
fcm[ibody][2] = all[ibody][2] + langextra[ibody][2];
torque[ibody][0] = all[ibody][3] + langextra[ibody][3];
torque[ibody][1] = all[ibody][4] + langextra[ibody][4];
torque[ibody][2] = all[ibody][5] + langextra[ibody][5];
// update vcm by 1/2 step
dtfm = dtf / masstotal[ibody];
vcm[ibody][0] += dtfm * fcm[ibody][0] * fflag[ibody][0];
vcm[ibody][1] += dtfm * fcm[ibody][1] * fflag[ibody][1];
vcm[ibody][2] += dtfm * fcm[ibody][2] * fflag[ibody][2];
// update conjqm, then transform to angmom, set velocity again
// virial is already setup from initial_integrate
torque[ibody][0] *= tflag[ibody][0];
torque[ibody][1] *= tflag[ibody][1];
torque[ibody][2] *= tflag[ibody][2];
MathExtra::transpose_matvec(ex_space[ibody],ey_space[ibody],ez_space[ibody],
torque[ibody],tbody);
MathExtra::quatvec(quat[ibody],tbody,fquat);
conjqm[ibody][0] += dtf2 * fquat[0];
conjqm[ibody][1] += dtf2 * fquat[1];
conjqm[ibody][2] += dtf2 * fquat[2];
conjqm[ibody][3] += dtf2 * fquat[3];
MathExtra::invquatvec(quat[ibody],conjqm[ibody],mbody);
MathExtra::matvec(ex_space[ibody],ey_space[ibody],ez_space[ibody],
mbody,angmom[ibody]);
angmom[ibody][0] *= 0.5;
angmom[ibody][1] *= 0.5;
angmom[ibody][2] *= 0.5;
MathExtra::angmom_to_omega(angmom[ibody],ex_space[ibody],ey_space[ibody],
ez_space[ibody],inertia[ibody],omega[ibody]);
}
// set velocity/rotation of atoms in rigid bodies
// virial is already setup from initial_integrate
set_v();
}
diff --git a/src/fix_rigid_nvt.cpp b/src/fix_rigid_nvt.cpp
index a02ab5466..459898323 100644
--- a/src/fix_rigid_nvt.cpp
+++ b/src/fix_rigid_nvt.cpp
@@ -1,716 +1,716 @@
/* ----------------------------------------------------------------------
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: Tony Sheh (U Michigan), Trung Dac Nguyen (U Michigan)
references: Kamberaj et al., J. Chem. Phys. 122, 224114 (2005)
Miller et al., J Chem Phys. 116, 8649-8659
------------------------------------------------------------------------- */
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "fix_rigid_nvt.h"
#include "math_extra.h"
#include "atom.h"
#include "domain.h"
#include "update.h"
#include "modify.h"
#include "group.h"
#include "comm.h"
#include "force.h"
#include "output.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixRigidNVT::FixRigidNVT(LAMMPS *lmp, int narg, char **arg) :
FixRigid(lmp, narg, arg)
{
// other settings are made by FixRigid parent
scalar_flag = 1;
restart_global = 1;
extscalar = 1;
// error checking
// convert input period to frequency
if (tempflag == 0)
error->all(FLERR,"Did not set temp for fix rigid/nvt");
if (t_start < 0.0 || t_stop <= 0.0)
error->all(FLERR,"Target temperature for fix rigid/nvt cannot be 0.0");
if (t_period <= 0.0) error->all(FLERR,"Fix rigid/nvt period must be > 0.0");
t_freq = 1.0 / t_period;
if (t_chain < 1) error->all(FLERR,"Illegal fix_modify command");
if (t_iter < 1) error->all(FLERR,"Illegal fix_modify command");
if (t_order != 3 && t_order != 5)
error->all(FLERR,"Fix_modify order must be 3 or 5");
allocate_chain();
allocate_order();
memory->create(conjqm,nbody,4,"nve_rigid:conjqm");
// one-time initialize of thermostat variables
eta_t[0] = eta_r[0] = 0.0;
eta_dot_t[0] = eta_dot_r[0] = 0.0;
f_eta_t[0] = f_eta_r[0] = 0.0;
for (int i = 1; i < t_chain; i++) {
eta_t[i] = eta_r[i] = 0.0;
eta_dot_t[i] = eta_dot_r[i] = 0.0;
}
}
/* ---------------------------------------------------------------------- */
FixRigidNVT::~FixRigidNVT()
{
deallocate_chain();
deallocate_order();
memory->destroy(conjqm);
}
/* ---------------------------------------------------------------------- */
int FixRigidNVT::setmask()
{
int mask = 0;
mask |= INITIAL_INTEGRATE;
mask |= FINAL_INTEGRATE;
mask |= PRE_NEIGHBOR;
mask |= THERMO_ENERGY;
mask |= INITIAL_INTEGRATE_RESPA;
mask |= FINAL_INTEGRATE_RESPA;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixRigidNVT::init()
{
FixRigid::init();
// initialize thermostats
// set timesteps, constants
// store Yoshida-Suzuki integrator parameters
dtv = update->dt;
dtf = 0.5 * update->dt * force->ftm2v;
dtq = 0.5 * update->dt;
boltz = force->boltz;
nf_t = nf_r = domain->dimension * nbody;
for (int ibody = 0; ibody < nbody; ibody++)
for (int k = 0; k < domain->dimension; k++)
if (fabs(inertia[ibody][k]) < 1e-6) nf_r--;
// see Table 1 in Kamberaj et al
if (t_order == 3) {
w[0] = 1.0 / (2.0 - pow(2.0, 1.0/3.0));
w[1] = 1.0 - 2.0*w[0];
w[2] = w[0];
} else if (t_order == 5) {
w[0] = 1.0 / (4.0 - pow(4.0, 1.0/3.0));
w[1] = w[0];
w[2] = 1.0 - 4.0 * w[0];
w[3] = w[0];
w[4] = w[0];
}
// initialize thermostat settings
t_target = t_start;
double kt = boltz * t_target;
double t_mass = kt / (t_freq*t_freq);
q_t[0] = nf_t * t_mass;
q_r[0] = nf_r * t_mass;
for (int i = 1; i < t_chain; i++)
q_t[i] = q_r[i] = t_mass;
// initialize thermostat chain positions, velocites, forces
for (int i = 1; i < t_chain; i++) {
f_eta_t[i] = q_t[i-1] * eta_dot_t[i-1] * eta_dot_t[i-1] - kt;
f_eta_r[i] = q_r[i-1] * eta_dot_r[i-1] * eta_dot_r[i-1] - kt;
}
}
/* ---------------------------------------------------------------------- */
void FixRigidNVT::setup(int vflag)
{
FixRigid::setup(vflag);
t_target = t_start;
double mbody[3];
for (int ibody = 0; ibody < nbody; ibody++) {
MathExtra::transpose_matvec(ex_space[ibody],ey_space[ibody],ez_space[ibody],
angmom[ibody],mbody);
MathExtra::quatvec(quat[ibody],mbody,conjqm[ibody]);
conjqm[ibody][0] *= 2.0;
conjqm[ibody][1] *= 2.0;
conjqm[ibody][2] *= 2.0;
conjqm[ibody][3] *= 2.0;
}
}
/* ----------------------------------------------------------------------
perform preforce velocity Verlet integration
see Kamberaj paper for step references
------------------------------------------------------------------------- */
void FixRigidNVT::initial_integrate(int vflag)
{
double tmp,akin_t,akin_r,scale_t,scale_r;
double dtfm,mbody[3],tbody[3],fquat[4];
double dtf2 = dtf * 2.0;
double delta = update->ntimestep - update->beginstep;
delta /= update->endstep - update->beginstep;
t_target = t_start + delta * (t_stop - t_start);
// intialize velocity scale for translation and rotation
akin_t = akin_r = 0.0;
tmp = -1.0 * dtq * eta_dot_t[0];
scale_t = exp(tmp);
tmp = -1.0 * dtq * eta_dot_r[0];
scale_r = exp(tmp);
for (int ibody = 0; ibody < nbody; ibody++) {
// step 1.1 - update vcm by 1/2 step
dtfm = dtf / masstotal[ibody];
vcm[ibody][0] += dtfm * fcm[ibody][0] * fflag[ibody][0];
vcm[ibody][1] += dtfm * fcm[ibody][1] * fflag[ibody][1];
vcm[ibody][2] += dtfm * fcm[ibody][2] * fflag[ibody][2];
vcm[ibody][0] *= scale_t;
vcm[ibody][1] *= scale_t;
vcm[ibody][2] *= scale_t;
tmp = vcm[ibody][0]*vcm[ibody][0] + vcm[ibody][1]*vcm[ibody][1] +
vcm[ibody][2]*vcm[ibody][2];
akin_t += masstotal[ibody]*tmp;
// step 1.2 - update xcm by full step
xcm[ibody][0] += dtv * vcm[ibody][0];
xcm[ibody][1] += dtv * vcm[ibody][1];
xcm[ibody][2] += dtv * vcm[ibody][2];
torque[ibody][0] *= tflag[ibody][0];
torque[ibody][1] *= tflag[ibody][1];
torque[ibody][2] *= tflag[ibody][2];
// step 1.3 - apply torque (body coords) to quaternion momentum
MathExtra::transpose_matvec(ex_space[ibody],ey_space[ibody],ez_space[ibody],
torque[ibody],tbody);
MathExtra::quatvec(quat[ibody],tbody,fquat);
conjqm[ibody][0] += dtf2 * fquat[0];
conjqm[ibody][1] += dtf2 * fquat[1];
conjqm[ibody][2] += dtf2 * fquat[2];
conjqm[ibody][3] += dtf2 * fquat[3];
conjqm[ibody][0] *= scale_r;
conjqm[ibody][1] *= scale_r;
conjqm[ibody][2] *= scale_r;
conjqm[ibody][3] *= scale_r;
// step 1.4 to 1.8 - use no_squish rotate to update p (i.e. conjqm) and q
no_squish_rotate(3,conjqm[ibody],quat[ibody],inertia[ibody],dtq);
no_squish_rotate(2,conjqm[ibody],quat[ibody],inertia[ibody],dtq);
no_squish_rotate(1,conjqm[ibody],quat[ibody],inertia[ibody],dtv);
no_squish_rotate(2,conjqm[ibody],quat[ibody],inertia[ibody],dtq);
no_squish_rotate(3,conjqm[ibody],quat[ibody],inertia[ibody],dtq);
// update the exyz_space from new quaternion
// transform p back to angmom
// update angular velocity
MathExtra::q_to_exyz(quat[ibody],ex_space[ibody],ey_space[ibody],
ez_space[ibody]);
MathExtra::invquatvec(quat[ibody],conjqm[ibody],mbody);
MathExtra::matvec(ex_space[ibody],ey_space[ibody],ez_space[ibody],
mbody,angmom[ibody]);
angmom[ibody][0] *= 0.5;
angmom[ibody][1] *= 0.5;
angmom[ibody][2] *= 0.5;
MathExtra::angmom_to_omega(angmom[ibody],ex_space[ibody],ey_space[ibody],
ez_space[ibody],inertia[ibody],omega[ibody]);
akin_r += angmom[ibody][0]*omega[ibody][0] +
angmom[ibody][1]*omega[ibody][1] + angmom[ibody][2]*omega[ibody][2];
}
// update thermostat chains
update_nhcp(akin_t,akin_r);
// virial setup before call to set_xv
if (vflag) v_setup(vflag);
else evflag = 0;
// set coords/orient and velocity/rotation of atoms in rigid bodies
// from quarternion and omega
set_xv();
}
/* ---------------------------------------------------------------------- */
void FixRigidNVT::final_integrate()
{
int i,ibody;
double tmp,scale_t,scale_r;
double dtfm,xy,xz,yz;
// compute velocity scales for translation and rotation
tmp = -1.0 * dtq * eta_dot_t[0];
scale_t = exp(tmp);
tmp = -1.0 * dtq * eta_dot_r[0];
scale_r = exp(tmp);
// sum over atoms to get force and torque on rigid body
- int *image = atom->image;
+ tagint *image = atom->image;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
if (triclinic) {
xy = domain->xy;
xz = domain->xz;
yz = domain->yz;
}
int xbox,ybox,zbox;
double xunwrap,yunwrap,zunwrap,dx,dy,dz;
for (ibody = 0; ibody < nbody; ibody++)
for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
sum[ibody][0] += f[i][0];
sum[ibody][1] += f[i][1];
sum[ibody][2] += f[i][2];
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
xunwrap = x[i][0] + xbox*xprd;
yunwrap = x[i][1] + ybox*yprd;
zunwrap = x[i][2] + zbox*zprd;
} else {
xunwrap = x[i][0] + xbox*xprd + ybox*xy + zbox*xz;
yunwrap = x[i][1] + ybox*yprd + zbox*yz;
zunwrap = x[i][2] + zbox*zprd;
}
dx = xunwrap - xcm[ibody][0];
dy = yunwrap - xcm[ibody][1];
dz = zunwrap - xcm[ibody][2];
sum[ibody][3] += dy*f[i][2] - dz*f[i][1];
sum[ibody][4] += dz*f[i][0] - dx*f[i][2];
sum[ibody][5] += dx*f[i][1] - dy*f[i][0];
}
// extended particles add their torque to torque of body
if (extended) {
double **torque_one = atom->torque;
for (i = 0; i < nlocal; i++) {
if (body[i] < 0) continue;
ibody = body[i];
if (eflags[i] & TORQUE) {
sum[ibody][3] += torque_one[i][0];
sum[ibody][4] += torque_one[i][1];
sum[ibody][5] += torque_one[i][2];
}
}
}
MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
double mbody[3],tbody[3],fquat[4];
double dtf2 = dtf * 2.0;
for (ibody = 0; ibody < nbody; ibody++) {
fcm[ibody][0] = all[ibody][0];
fcm[ibody][1] = all[ibody][1];
fcm[ibody][2] = all[ibody][2];
torque[ibody][0] = all[ibody][3];
torque[ibody][1] = all[ibody][4];
torque[ibody][2] = all[ibody][5];
// 2.5-2.6 update vcm by 1/2 step
dtfm = dtf / masstotal[ibody];
vcm[ibody][0] *= scale_t;
vcm[ibody][1] *= scale_t;
vcm[ibody][2] *= scale_t;
vcm[ibody][0] += dtfm * fcm[ibody][0] * fflag[ibody][0];
vcm[ibody][1] += dtfm * fcm[ibody][1] * fflag[ibody][1];
vcm[ibody][2] += dtfm * fcm[ibody][2] * fflag[ibody][2];
// 2.1-2.4 update conjqm, angular momentum and angular velocity
// apply body torque flags
torque[ibody][0] *= tflag[ibody][0];
torque[ibody][1] *= tflag[ibody][1];
torque[ibody][2] *= tflag[ibody][2];
// convert torque to the body frame
MathExtra::transpose_matvec(ex_space[ibody],ey_space[ibody],ez_space[ibody],
torque[ibody],tbody);
// compute "force" for quaternion
MathExtra::quatvec(quat[ibody],tbody,fquat);
// update the conjugate quaternion momentum (conjqm)
conjqm[ibody][0] = scale_r * conjqm[ibody][0] + dtf2 * fquat[0];
conjqm[ibody][1] = scale_r * conjqm[ibody][1] + dtf2 * fquat[1];
conjqm[ibody][2] = scale_r * conjqm[ibody][2] + dtf2 * fquat[2];
conjqm[ibody][3] = scale_r * conjqm[ibody][3] + dtf2 * fquat[3];
// compute angular momentum in the body frame
// then convert to the space-fixed frame
MathExtra::invquatvec(quat[ibody],conjqm[ibody],mbody);
MathExtra::matvec(ex_space[ibody],ey_space[ibody],ez_space[ibody],
mbody,angmom[ibody]);
angmom[ibody][0] *= 0.5;
angmom[ibody][1] *= 0.5;
angmom[ibody][2] *= 0.5;
// compute new angular velocity
MathExtra::angmom_to_omega(angmom[ibody],ex_space[ibody],ey_space[ibody],
ez_space[ibody],inertia[ibody],omega[ibody]);
}
// set velocity/rotation of atoms in rigid bodies
// virial is already setup from initial_integrate
set_v();
}
/* ---------------------------------------------------------------------- */
void FixRigidNVT::update_nhcp(double akin_t, double akin_r)
{
int i,j,k;
double kt,gfkt_t,gfkt_r,tmp,ms,s,s2;
kt = boltz * t_target;
gfkt_t = nf_t * kt;
gfkt_r = nf_r * kt;
akin_t *= force->mvv2e;
akin_r *= force->mvv2e;
// update thermostat masses
double t_mass = boltz * t_target / (t_freq * t_freq);
q_t[0] = nf_t * t_mass;
q_r[0] = nf_r * t_mass;
for (i = 1; i < t_chain; i++)
q_t[i] = q_r[i] = t_mass;
// update order/timestep dependent coefficients
for (i = 0; i < t_order; i++) {
wdti1[i] = w[i] * dtv / t_iter;
wdti2[i] = wdti1[i] / 2.0;
wdti4[i] = wdti1[i] / 4.0;
}
// update force of thermostats coupled to particles
f_eta_t[0] = (akin_t - gfkt_t) / q_t[0];
f_eta_r[0] = (akin_r - gfkt_r) / q_r[0];
// multiple timestep iteration
for (i = 0; i < t_iter; i++) {
for (j = 0; j < t_order; j++) {
// update thermostat velocities half step
eta_dot_t[t_chain-1] += wdti2[j] * f_eta_t[t_chain-1];
eta_dot_r[t_chain-1] += wdti2[j] * f_eta_r[t_chain-1];
for (k = 1; k < t_chain; k++) {
tmp = wdti4[j] * eta_dot_t[t_chain-k];
ms = maclaurin_series(tmp);
s = exp(-1.0 * tmp);
s2 = s * s;
eta_dot_t[t_chain-k-1] = eta_dot_t[t_chain-k-1] * s2 +
wdti2[j] * f_eta_t[t_chain-k-1] * s * ms;
tmp = wdti4[j] * eta_dot_r[t_chain-k];
ms = maclaurin_series(tmp);
s = exp(-1.0 * tmp);
s2 = s * s;
eta_dot_r[t_chain-k-1] = eta_dot_r[t_chain-k-1] * s2 +
wdti2[j] * f_eta_r[t_chain-k-1] * s * ms;
}
// update thermostat positions a full step
for (k = 0; k < t_chain; k++) {
eta_t[k] += wdti1[j] * eta_dot_t[k];
eta_r[k] += wdti1[j] * eta_dot_r[k];
}
// update thermostat forces
for (k = 1; k < t_chain; k++) {
f_eta_t[k] = q_t[k-1] * eta_dot_t[k-1] * eta_dot_t[k-1] - kt;
f_eta_t[k] /= q_t[k];
f_eta_r[k] = q_r[k-1] * eta_dot_r[k-1] * eta_dot_r[k-1] - kt;
f_eta_r[k] /= q_r[k];
}
// update thermostat velocities a full step
for (k = 0; k < t_chain-1; k++) {
tmp = wdti4[j] * eta_dot_t[k+1];
ms = maclaurin_series(tmp);
s = exp(-1.0 * tmp);
s2 = s * s;
eta_dot_t[k] = eta_dot_t[k] * s2 + wdti2[j] * f_eta_t[k] * s * ms;
tmp = q_t[k] * eta_dot_t[k] * eta_dot_t[k] - kt;
f_eta_t[k+1] = tmp / q_t[k+1];
tmp = wdti4[j] * eta_dot_r[k+1];
ms = maclaurin_series(tmp);
s = exp(-1.0 * tmp);
s2 = s * s;
eta_dot_r[k] = eta_dot_r[k] * s2 + wdti2[j] * f_eta_r[k] * s * ms;
tmp = q_r[k] * eta_dot_r[k] * eta_dot_r[k] - kt;
f_eta_r[k+1] = tmp / q_r[k+1];
}
eta_dot_t[t_chain-1] += wdti2[j] * f_eta_t[t_chain-1];
eta_dot_r[t_chain-1] += wdti2[j] * f_eta_r[t_chain-1];
}
}
}
/* ----------------------------------------------------------------------
pack entire state of Fix into one write
------------------------------------------------------------------------- */
void FixRigidNVT::write_restart(FILE *fp)
{
int n = 0;
double *list = new double[1+6*t_chain];
list[n++] = t_chain;
for (int i = 0; i < t_chain; i++) {
list[n++] = eta_t[i];
list[n++] = eta_r[i];
list[n++] = eta_dot_t[i];
list[n++] = eta_dot_r[i];
list[n++] = f_eta_t[i];
list[n++] = f_eta_r[i];
}
if (comm->me == 0) {
int size = (1 + 6*t_chain)*sizeof(double);
fwrite(&size,sizeof(int),1,fp);
fwrite(list,sizeof(double),1+6*t_chain,fp);
}
delete list;
}
/* ----------------------------------------------------------------------
compute kinetic energy in the extended Hamiltonian
conserved quantity = sum of returned energy and potential energy
-----------------------------------------------------------------------*/
double FixRigidNVT::compute_scalar()
{
int i,k,ibody;
double kt = boltz * t_target;
double energy,ke_t,ke_q,tmp,Pkq[4];
// compute the kinetic parts of H_NVE in Kameraj et al (JCP 2005, pp 224114)
// translational kinetic energy
ke_t = 0.0;
for (ibody = 0; ibody < nbody; ibody++)
ke_t += 0.5 * masstotal[ibody] * (vcm[ibody][0]*vcm[ibody][0] +
vcm[ibody][1]*vcm[ibody][1] +
vcm[ibody][2]*vcm[ibody][2]);
// rotational kinetic energy
ke_q = 0.0;
for (ibody = 0; ibody < nbody; ibody++) {
for (k = 1; k < 4; k++) {
if (k == 1) {
Pkq[0] = -quat[ibody][1];
Pkq[1] = quat[ibody][0];
Pkq[2] = quat[ibody][3];
Pkq[3] = -quat[ibody][2];
} else if (k == 2) {
Pkq[0] = -quat[ibody][2];
Pkq[1] = -quat[ibody][3];
Pkq[2] = quat[ibody][0];
Pkq[3] = quat[ibody][1];
} else if (k == 3) {
Pkq[0] = -quat[ibody][3];
Pkq[1] = quat[ibody][2];
Pkq[2] = -quat[ibody][1];
Pkq[3] = quat[ibody][0];
}
tmp = conjqm[ibody][0]*Pkq[0] + conjqm[ibody][1]*Pkq[1] +
conjqm[ibody][2]*Pkq[2] + conjqm[ibody][3]*Pkq[3];
tmp *= tmp;
if (fabs(inertia[ibody][k-1]) < 1e-6) tmp = 0.0;
else tmp /= (8.0 * inertia[ibody][k-1]);
ke_q += tmp;
}
}
energy = ke_t + ke_q;
// thermostat chain energy: from equation 12 in Kameraj et al (JCP 2005)
energy += kt * (nf_t * eta_t[0] + nf_r * eta_r[0]);
for (i = 1; i < t_chain; i++)
energy += kt * (eta_t[i] + eta_r[i]);
for (i = 0; i < t_chain; i++) {
energy += 0.5 * q_t[i] * (eta_dot_t[i] * eta_dot_t[i]);
energy += 0.5 * q_r[i] * (eta_dot_r[i] * eta_dot_r[i]);
}
return energy;
}
/* ----------------------------------------------------------------------
use state info from restart file to restart the Fix
------------------------------------------------------------------------- */
void FixRigidNVT::restart(char *buf)
{
int n = 0;
double *list = (double *) buf;
int t_chain_prev = static_cast<int> (list[n++]);
if (t_chain_prev != t_chain)
error->all(FLERR,"Cannot restart fix rigid/nvt with different # of chains");
for (int i = 0; i < t_chain; i++) {
eta_t[i] = list[n++];
eta_r[i] = list[n++];
eta_dot_t[i] = list[n++];
eta_dot_r[i] = list[n++];
f_eta_t[i] = list[n++];
f_eta_r[i] = list[n++];
}
}
/* ---------------------------------------------------------------------- */
void FixRigidNVT::reset_target(double t_new)
{
t_start = t_stop = t_new;
}
/* ---------------------------------------------------------------------- */
void FixRigidNVT::allocate_chain()
{
q_t = new double[t_chain];
q_r = new double[t_chain];
eta_t = new double[t_chain];
eta_r = new double[t_chain];
eta_dot_t = new double[t_chain];
eta_dot_r = new double[t_chain];
f_eta_t = new double[t_chain];
f_eta_r = new double[t_chain];
}
/* ---------------------------------------------------------------------- */
void FixRigidNVT::allocate_order()
{
w = new double[t_order];
wdti1 = new double[t_order];
wdti2 = new double[t_order];
wdti4 = new double[t_order];
}
/* ---------------------------------------------------------------------- */
void FixRigidNVT::deallocate_chain()
{
delete [] q_t;
delete [] q_r;
delete [] eta_t;
delete [] eta_r;
delete [] eta_dot_t;
delete [] eta_dot_r;
delete [] f_eta_t;
delete [] f_eta_r;
}
/* ---------------------------------------------------------------------- */
void FixRigidNVT::deallocate_order()
{
delete [] w;
delete [] wdti1;
delete [] wdti2;
delete [] wdti4;
}
diff --git a/src/fix_shake.cpp b/src/fix_shake.cpp
index a4ec615b1..554b96c98 100644
--- a/src/fix_shake.cpp
+++ b/src/fix_shake.cpp
@@ -1,2428 +1,2429 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
#include "fix_shake.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 "math_const.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
using namespace MathConst;
#define BIG 1.0e20
#define MASSDELTA 0.1
/* ---------------------------------------------------------------------- */
FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
virial_flag = 1;
create_attribute = 1;
// error check
if (atom->molecular == 0)
error->all(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"Invalid atom mass for fix shake");
- if (nmass == atom->ntypes) error->all(FLERR,"Too many masses for fix shake");
+ if (nmass == atom->ntypes)
+ error->all(FLERR,"Too many masses for fix shake");
mass_list[nmass++] = massone;
} else error->all(FLERR,"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->destroy(shake_flag);
memory->destroy(shake_atom);
memory->destroy(shake_type);
memory->destroy(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->destroy(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(FLERR,"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(FLERR,"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(FLERR,"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 (strstr(update->integrate_style,"respa")) {
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(FLERR,"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(FLERR,"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(FLERR,"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
bigint ntimestep = update->ntimestep;
if (output_every) {
next_output = ntimestep + output_every;
if (ntimestep % output_every != 0)
next_output = (ntimestep/output_every)*output_every + output_every;
} else next_output = -1;
// half timestep constraint on pre-step, full timestep thereafter
if (strstr(update->integrate_style,"verlet")) {
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->destroy(list);
memory->create(list,maxlist,"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 " BIGINT_FORMAT,
shake_atom[i][0],shake_atom[i][1],me,update->ntimestep);
error->one(FLERR,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 "
BIGINT_FORMAT,
shake_atom[i][0],shake_atom[i][1],shake_atom[i][2],
me,update->ntimestep);
error->one(FLERR,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 "
BIGINT_FORMAT,
shake_atom[i][0],shake_atom[i][1],
shake_atom[i][2],shake_atom[i][3],
me,update->ntimestep);
error->one(FLERR,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,*nshake;
memory->create(npartner,nlocal,"shake:npartner");
memory->create(nshake,nlocal,"shake:nshake");
int **partner_tag,**partner_mask,**partner_type,**partner_massflag;
int ** partner_bondtype,**partner_shake,**partner_nshake;
memory->create(partner_tag,nlocal,max,"shake:partner_tag");
memory->create(partner_mask,nlocal,max,"shake:partner_mask");
memory->create(partner_type,nlocal,max,"shake:partner_type");
memory->create(partner_massflag,nlocal,max,"shake:partner_massflag");
memory->create(partner_bondtype,nlocal,max,"shake:partner_bondtype");
memory->create(partner_shake,nlocal,max,"shake:partner_shake");
memory->create(partner_nshake,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(FLERR,"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(FLERR,"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(FLERR,"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->destroy(npartner);
memory->destroy(nshake);
memory->destroy(partner_tag);
memory->destroy(partner_mask);
memory->destroy(partner_type);
memory->destroy(partner_massflag);
memory->destroy(partner_bondtype);
memory->destroy(partner_shake);
memory->destroy(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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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/MY_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) {
if (screen) {
fprintf(screen,
"SHAKE stats (type/ave/delta) on step " BIGINT_FORMAT "\n",
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 " BIGINT_FORMAT "\n",
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)
{
memory->grow(shake_flag,nmax,"shake:shake_flag");
memory->grow(shake_atom,nmax,4,"shake:shake_atom");
memory->grow(shake_type,nmax,3,"shake:shake_type");
memory->destroy(xshake);
memory->create(xshake,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 (strstr(update->integrate_style,"verlet")) {
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_spring_rg.cpp b/src/fix_spring_rg.cpp
index 785fd40e3..e17aa8966 100644
--- a/src/fix_spring_rg.cpp
+++ b/src/fix_spring_rg.cpp
@@ -1,139 +1,139 @@
/* ----------------------------------------------------------------------
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)
Paul Crozier (SNL)
------------------------------------------------------------------------- */
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "fix_spring_rg.h"
#include "atom.h"
#include "update.h"
#include "group.h"
#include "respa.h"
#include "domain.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixSpringRG::FixSpringRG(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg != 5) error->all(FLERR,"Illegal fix spring/rg command");
k = atof(arg[3]);
rg0_flag = 0;
if (strcmp(arg[4],"NULL") == 0) rg0_flag = 1;
else rg0 = atof(arg[4]);
}
/* ---------------------------------------------------------------------- */
int FixSpringRG::setmask()
{
int mask = 0;
mask |= POST_FORCE;
mask |= POST_FORCE_RESPA;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixSpringRG::init()
{
masstotal = group->mass(igroup);
// if rg0 was specified as NULL, compute current Rg
// only occurs on 1st run
if (rg0_flag) {
double xcm[3];
group->xcm(igroup,masstotal,xcm);
rg0 = group->gyration(igroup,masstotal,xcm);
rg0_flag = 0;
}
if (strstr(update->integrate_style,"respa"))
nlevels_respa = ((Respa *) update->integrate)->nlevels;
}
/* ---------------------------------------------------------------------- */
void FixSpringRG::setup(int vflag)
{
if (strstr(update->integrate_style,"verlet"))
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 FixSpringRG::post_force(int vflag)
{
// compute current Rg and center-of-mass
double xcm[3];
group->xcm(igroup,masstotal,xcm);
double rg = group->gyration(igroup,masstotal,xcm);
// apply restoring force to atoms in group
// f = -k*(r-r0)*mass/masstotal
double dx,dy,dz,term1;
double **f = atom->f;
double **x = atom->x;
int *mask = atom->mask;
int *type = atom->type;
- int *image = atom->image;
+ tagint *image = atom->image;
double *mass = atom->mass;
int nlocal = atom->nlocal;
double massfrac;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
int xbox,ybox,zbox;
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
term1 = 2.0 * k * (1.0 - rg0/rg);
- xbox = (image[i] & 1023) - 512;
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = (x[i][0] + xbox*xprd) - xcm[0];
dy = (x[i][1] + ybox*yprd) - xcm[1];
dz = (x[i][2] + zbox*zprd) - xcm[2];
massfrac = mass[type[i]]/masstotal;
f[i][0] -= term1*dx*massfrac;
f[i][1] -= term1*dy*massfrac;
f[i][2] -= term1*dz*massfrac;
}
}
/* ---------------------------------------------------------------------- */
void FixSpringRG::post_force_respa(int vflag, int ilevel, int iloop)
{
if (ilevel == nlevels_respa-1) post_force(vflag);
}
diff --git a/src/fix_spring_self.cpp b/src/fix_spring_self.cpp
index 675a53e49..fb2120d4c 100644
--- a/src/fix_spring_self.cpp
+++ b/src/fix_spring_self.cpp
@@ -1,318 +1,318 @@
/* ----------------------------------------------------------------------
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 University)
------------------------------------------------------------------------- */
#include "stdlib.h"
#include "string.h"
#include "fix_spring_self.h"
#include "atom.h"
#include "update.h"
#include "domain.h"
#include "respa.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
/* ---------------------------------------------------------------------- */
FixSpringSelf::FixSpringSelf(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if ((narg < 4) || (narg > 5))
error->all(FLERR,"Illegal fix spring/self command");
restart_peratom = 1;
scalar_flag = 1;
global_freq = 1;
extscalar = 1;
k = atof(arg[3]);
if (k <= 0.0) error->all(FLERR,"Illegal fix spring/self command");
xflag = yflag = zflag = 1;
if (narg == 5) {
if (strcmp(arg[4],"xyz") == 0) {
; /* default */
} else if (strcmp(arg[4],"xy") == 0) {
zflag = 0;
} else if (strcmp(arg[4],"xz") == 0) {
yflag = 0;
} else if (strcmp(arg[4],"yz") == 0) {
xflag = 0;
} else if (strcmp(arg[4],"x") == 0) {
yflag = zflag = 0;
} else if (strcmp(arg[4],"y") == 0) {
xflag = zflag = 0;
} else if (strcmp(arg[4],"z") == 0) {
xflag = yflag = 0;
} else error->all(FLERR,"Illegal fix spring/self command");
}
// perform initial allocation of atom-based array
// register with Atom class
xoriginal = NULL;
grow_arrays(atom->nmax);
atom->add_callback(0);
atom->add_callback(1);
// xoriginal = initial unwrapped positions of atoms
double **x = atom->x;
int *mask = atom->mask;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
int xbox,ybox,zbox;
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
xoriginal[i][0] = x[i][0] + xbox*xprd;
xoriginal[i][1] = x[i][1] + ybox*yprd;
xoriginal[i][2] = x[i][2] + zbox*zprd;
} else xoriginal[i][0] = xoriginal[i][1] = xoriginal[i][2] = 0.0;
}
espring = 0.0;
}
/* ---------------------------------------------------------------------- */
FixSpringSelf::~FixSpringSelf()
{
// unregister callbacks to this fix from Atom class
atom->delete_callback(id,0);
atom->delete_callback(id,1);
// delete locally stored array
memory->destroy(xoriginal);
}
/* ---------------------------------------------------------------------- */
int FixSpringSelf::setmask()
{
int mask = 0;
mask |= POST_FORCE;
mask |= THERMO_ENERGY;
mask |= POST_FORCE_RESPA;
mask |= MIN_POST_FORCE;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixSpringSelf::init()
{
if (strstr(update->integrate_style,"respa"))
nlevels_respa = ((Respa *) update->integrate)->nlevels;
}
/* ---------------------------------------------------------------------- */
void FixSpringSelf::setup(int vflag)
{
if (strstr(update->integrate_style,"verlet"))
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 FixSpringSelf::min_setup(int vflag)
{
post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixSpringSelf::post_force(int vflag)
{
double **x = atom->x;
double **f = atom->f;
int *mask = atom->mask;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
double yprd = domain->yprd;
double zprd = domain->zprd;
int xbox,ybox,zbox;
double dx,dy,dz;
espring = 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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
dx = x[i][0] + xbox*xprd - xoriginal[i][0];
dy = x[i][1] + ybox*yprd - xoriginal[i][1];
dz = x[i][2] + zbox*zprd - xoriginal[i][2];
if (!xflag) dx = 0.0;
if (!yflag) dy = 0.0;
if (!zflag) dz = 0.0;
f[i][0] -= k*dx;
f[i][1] -= k*dy;
f[i][2] -= k*dz;
espring += k * (dx*dx + dy*dy + dz*dz);
}
espring *= 0.5;
}
/* ---------------------------------------------------------------------- */
void FixSpringSelf::post_force_respa(int vflag, int ilevel, int iloop)
{
if (ilevel == nlevels_respa-1) post_force(vflag);
}
/* ---------------------------------------------------------------------- */
void FixSpringSelf::min_post_force(int vflag)
{
post_force(vflag);
}
/* ----------------------------------------------------------------------
energy of stretched springs
------------------------------------------------------------------------- */
double FixSpringSelf::compute_scalar()
{
double all;
MPI_Allreduce(&espring,&all,1,MPI_DOUBLE,MPI_SUM,world);
return all;
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double FixSpringSelf::memory_usage()
{
double bytes = atom->nmax*3 * sizeof(double);
return bytes;
}
/* ----------------------------------------------------------------------
allocate atom-based array
------------------------------------------------------------------------- */
void FixSpringSelf::grow_arrays(int nmax)
{
memory->grow(xoriginal,nmax,3,"fix_spring/self:xoriginal");
}
/* ----------------------------------------------------------------------
copy values within local atom-based array
------------------------------------------------------------------------- */
void FixSpringSelf::copy_arrays(int i, int j)
{
xoriginal[j][0] = xoriginal[i][0];
xoriginal[j][1] = xoriginal[i][1];
xoriginal[j][2] = xoriginal[i][2];
}
/* ----------------------------------------------------------------------
pack values in local atom-based array for exchange with another proc
------------------------------------------------------------------------- */
int FixSpringSelf::pack_exchange(int i, double *buf)
{
buf[0] = xoriginal[i][0];
buf[1] = xoriginal[i][1];
buf[2] = xoriginal[i][2];
return 3;
}
/* ----------------------------------------------------------------------
unpack values in local atom-based array from exchange with another proc
------------------------------------------------------------------------- */
int FixSpringSelf::unpack_exchange(int nlocal, double *buf)
{
xoriginal[nlocal][0] = buf[0];
xoriginal[nlocal][1] = buf[1];
xoriginal[nlocal][2] = buf[2];
return 3;
}
/* ----------------------------------------------------------------------
pack values in local atom-based arrays for restart file
------------------------------------------------------------------------- */
int FixSpringSelf::pack_restart(int i, double *buf)
{
buf[0] = 4;
buf[1] = xoriginal[i][0];
buf[2] = xoriginal[i][1];
buf[3] = xoriginal[i][2];
return 4;
}
/* ----------------------------------------------------------------------
unpack values from atom->extra array to restart the fix
------------------------------------------------------------------------- */
void FixSpringSelf::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++;
xoriginal[nlocal][0] = extra[nlocal][m++];
xoriginal[nlocal][1] = extra[nlocal][m++];
xoriginal[nlocal][2] = extra[nlocal][m++];
}
/* ----------------------------------------------------------------------
maxsize of any atom's restart data
------------------------------------------------------------------------- */
int FixSpringSelf::maxsize_restart()
{
return 4;
}
/* ----------------------------------------------------------------------
size of atom nlocal's restart data
------------------------------------------------------------------------- */
int FixSpringSelf::size_restart(int nlocal)
{
return 4;
}
diff --git a/src/fix_store_state.cpp b/src/fix_store_state.cpp
index 1444d6784..0302260c6 100644
--- a/src/fix_store_state.cpp
+++ b/src/fix_store_state.cpp
@@ -1,1259 +1,1259 @@
/* ----------------------------------------------------------------------
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_store_state.h"
#include "atom.h"
#include "domain.h"
#include "update.h"
#include "group.h"
#include "modify.h"
#include "compute.h"
#include "fix.h"
#include "input.h"
#include "variable.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace FixConst;
enum{KEYWORD,COMPUTE,FIX,VARIABLE};
#define INVOKED_PERATOM 8
/* ---------------------------------------------------------------------- */
FixStoreState::FixStoreState(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 5) error->all(FLERR,"Illegal fix store/state command");
restart_peratom = 1;
peratom_freq = 1;
nevery = atoi(arg[3]);
if (nevery < 0) error->all(FLERR,"Illegal fix store/state command");
// parse values until one isn't recognized
// customize a new keyword by adding to if statement
pack_choice = new FnPtrPack[narg-4];
which = new int[narg-4];
argindex = new int[narg-4];
ids = new char*[narg-4];
value2index = new int[narg-4];
nvalues = 0;
cfv_any = 0;
int iarg = 4;
while (iarg < narg) {
which[nvalues] = KEYWORD;
ids[nvalues] = NULL;
if (strcmp(arg[iarg],"id") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_id;
} else if (strcmp(arg[iarg],"mol") == 0) {
if (!atom->molecule_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_molecule;
} else if (strcmp(arg[iarg],"type") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_type;
} else if (strcmp(arg[iarg],"mass") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_mass;
} else if (strcmp(arg[iarg],"x") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_x;
} else if (strcmp(arg[iarg],"y") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_y;
} else if (strcmp(arg[iarg],"z") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_z;
} else if (strcmp(arg[iarg],"xs") == 0) {
if (domain->triclinic)
pack_choice[nvalues++] = &FixStoreState::pack_xs_triclinic;
else pack_choice[nvalues++] = &FixStoreState::pack_xs;
} else if (strcmp(arg[iarg],"ys") == 0) {
if (domain->triclinic)
pack_choice[nvalues++] = &FixStoreState::pack_ys_triclinic;
else pack_choice[nvalues++] = &FixStoreState::pack_ys;
} else if (strcmp(arg[iarg],"zs") == 0) {
if (domain->triclinic)
pack_choice[nvalues++] = &FixStoreState::pack_zs_triclinic;
else pack_choice[nvalues++] = &FixStoreState::pack_zs;
} else if (strcmp(arg[iarg],"xu") == 0) {
if (domain->triclinic)
pack_choice[nvalues++] = &FixStoreState::pack_xu_triclinic;
else pack_choice[nvalues++] = &FixStoreState::pack_xu;
} else if (strcmp(arg[iarg],"yu") == 0) {
if (domain->triclinic)
pack_choice[nvalues++] = &FixStoreState::pack_yu_triclinic;
else pack_choice[nvalues++] = &FixStoreState::pack_yu;
} else if (strcmp(arg[iarg],"zu") == 0) {
if (domain->triclinic)
pack_choice[nvalues++] = &FixStoreState::pack_zu_triclinic;
else pack_choice[nvalues++] = &FixStoreState::pack_zu;
} else if (strcmp(arg[iarg],"ix") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_ix;
} else if (strcmp(arg[iarg],"iy") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_iy;
} else if (strcmp(arg[iarg],"iz") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_iz;
} else if (strcmp(arg[iarg],"vx") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_vx;
} else if (strcmp(arg[iarg],"vy") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_vy;
} else if (strcmp(arg[iarg],"vz") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_vz;
} else if (strcmp(arg[iarg],"fx") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_fx;
} else if (strcmp(arg[iarg],"fy") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_fy;
} else if (strcmp(arg[iarg],"fz") == 0) {
pack_choice[nvalues++] = &FixStoreState::pack_fz;
} else if (strcmp(arg[iarg],"q") == 0) {
if (!atom->q_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_q;
} else if (strcmp(arg[iarg],"mux") == 0) {
if (!atom->mu_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_mux;
} else if (strcmp(arg[iarg],"muy") == 0) {
if (!atom->mu_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_muy;
} else if (strcmp(arg[iarg],"muz") == 0) {
if (!atom->mu_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_muz;
} else if (strcmp(arg[iarg],"radius") == 0) {
if (!atom->radius_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_radius;
} else if (strcmp(arg[iarg],"omegax") == 0) {
if (!atom->omega_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_omegax;
} else if (strcmp(arg[iarg],"omegay") == 0) {
if (!atom->omega_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_omegay;
} else if (strcmp(arg[iarg],"omegaz") == 0) {
if (!atom->omega_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_omegaz;
} else if (strcmp(arg[iarg],"angmomx") == 0) {
if (!atom->angmom_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_angmomx;
} else if (strcmp(arg[iarg],"angmomy") == 0) {
if (!atom->angmom_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_angmomy;
} else if (strcmp(arg[iarg],"angmomz") == 0) {
if (!atom->angmom_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_angmomz;
} else if (strcmp(arg[iarg],"tqx") == 0) {
if (!atom->torque_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_tqx;
} else if (strcmp(arg[iarg],"tqy") == 0) {
if (!atom->torque_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_tqy;
} else if (strcmp(arg[iarg],"tqz") == 0) {
if (!atom->torque_flag)
error->all(FLERR,"Fix store/state for atom property that isn't allocated");
pack_choice[nvalues++] = &FixStoreState::pack_tqz;
} else if (strncmp(arg[iarg],"c_",2) == 0 ||
strncmp(arg[iarg],"f_",2) == 0 ||
strncmp(arg[iarg],"v_",2) == 0) {
cfv_any = 1;
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(FLERR,"Illegal fix store/state 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
comflag = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"com") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix store/state command");
if (strcmp(arg[iarg+1],"no") == 0) comflag = 0;
else if (strcmp(arg[iarg+1],"yes") == 0) comflag = 1;
else error->all(FLERR,"Illegal fix store/state command");
iarg += 2;
} else error->all(FLERR,"Illegal fix store/state command");
}
// error check
for (int i = 0; i < nvalues; i++) {
if (which[i] == COMPUTE) {
int icompute = modify->find_compute(ids[i]);
if (icompute < 0)
error->all(FLERR,"Compute ID for fix store/state does not exist");
if (modify->compute[icompute]->peratom_flag == 0)
error->all(FLERR,"Fix store/state compute "
"does not calculate per-atom values");
if (argindex[i] == 0 &&
modify->compute[icompute]->size_peratom_cols != 0)
error->all(FLERR,"Fix store/state compute does not "
"calculate a per-atom vector");
if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0)
error->all(FLERR,"Fix store/state compute does not "
"calculate a per-atom array");
if (argindex[i] &&
argindex[i] > modify->compute[icompute]->size_peratom_cols)
error->all(FLERR,"Fix store/state compute array is accessed out-of-range");
} else if (which[i] == FIX) {
int ifix = modify->find_fix(ids[i]);
if (ifix < 0)
error->all(FLERR,"Fix ID for fix store/state does not exist");
if (modify->fix[ifix]->peratom_flag == 0)
error->all(FLERR,"Fix store/state fix does not calculate per-atom values");
if (argindex[i] == 0 && modify->fix[ifix]->size_peratom_cols != 0)
error->all(FLERR,"Fix store/state fix does not calculate a per-atom vector");
if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0)
error->all(FLERR,"Fix store/state fix does not calculate a per-atom array");
if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols)
error->all(FLERR,"Fix store/state fix array is accessed out-of-range");
if (nevery % modify->fix[ifix]->peratom_freq)
error->all(FLERR,"Fix for fix store/state not computed at compatible time");
} else if (which[i] == VARIABLE) {
int ivariable = input->variable->find(ids[i]);
if (ivariable < 0)
error->all(FLERR,"Variable name for fix store/state does not exist");
if (input->variable->atomstyle(ivariable) == 0)
error->all(FLERR,"Fix store/state 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
values = NULL;
grow_arrays(atom->nmax);
atom->add_callback(0);
atom->add_callback(1);
// 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++)
values[i][m] = 0.0;
// store current values for keywords but not for compute, fix, variable
kflag = 1;
cfv_flag = 0;
end_of_step();
firstflag = 1;
}
/* ---------------------------------------------------------------------- */
FixStoreState::~FixStoreState()
{
// unregister callbacks to this fix from Atom class
atom->delete_callback(id,0);
atom->delete_callback(id,1);
delete [] which;
delete [] argindex;
for (int m = 0; m < nvalues; m++) delete [] ids[m];
delete [] ids;
delete [] value2index;
delete [] pack_choice;
memory->destroy(values);
}
/* ---------------------------------------------------------------------- */
int FixStoreState::setmask()
{
int mask = 0;
if (nevery) mask |= END_OF_STEP;
return mask;
}
/* ---------------------------------------------------------------------- */
void FixStoreState::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(FLERR,"Compute ID for fix store/state does not exist");
value2index[m] = icompute;
} else if (which[m] == FIX) {
int ifix = modify->find_fix(ids[m]);
if (ifix < 0)
error->all(FLERR,"Fix ID for fix store/state does not exist");
value2index[m] = ifix;
} else if (which[m] == VARIABLE) {
int ivariable = input->variable->find(ids[m]);
if (ivariable < 0)
error->all(FLERR,"Variable name for fix store/state does not exist");
value2index[m] = ivariable;
}
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::setup(int vflag)
{
// if first invocation, store current values for compute, fix, variable
if (firstflag) {
kflag = 0;
cfv_flag = 1;
end_of_step();
firstflag = 0;
kflag = cfv_flag = 1;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::end_of_step()
{
int i,j,n;
// compute com if comflag set
if (comflag) {
double masstotal = group->mass(igroup);
group->xcm(igroup,masstotal,cm);
}
// if any compute/fix/variable and nevery, wrap with clear/add
if (cfv_any && nevery) modify->clearstep_compute();
// fill vector or array with per-atom values
if (values) vbuf = &values[0][0];
else vbuf = NULL;
for (int m = 0; m < nvalues; m++) {
if (which[m] == KEYWORD && kflag) (this->*pack_choice[m])(m);
else if (cfv_flag) {
n = value2index[m];
j = argindex[m];
int *mask = atom->mask;
int nlocal = atom->nlocal;
// invoke compute if not previously invoked
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) values[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) values[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) values[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) values[i][m] += fix_array[i][jm1];
}
// evaluate atom-style variable
} else if (which[m] == VARIABLE)
input->variable->compute_atom(n,igroup,&values[0][m],nvalues,0);
}
}
// if any compute/fix/variable and nevery, wrap with clear/add
if (cfv_any && nevery) {
int nextstep = (update->ntimestep/nevery)*nevery + nevery;
modify->addstep_compute(nextstep);
}
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double FixStoreState::memory_usage()
{
double bytes = atom->nmax*nvalues * sizeof(double);
return bytes;
}
/* ----------------------------------------------------------------------
allocate atom-based array
------------------------------------------------------------------------- */
void FixStoreState::grow_arrays(int nmax)
{
memory->grow(values,nmax,nvalues,"store/state:values");
if (nvalues == 1) {
if (nmax) vector_atom = &values[0][0];
else vector_atom = NULL;
} else array_atom = values;
}
/* ----------------------------------------------------------------------
copy values within local atom-based array
------------------------------------------------------------------------- */
void FixStoreState::copy_arrays(int i, int j)
{
for (int m = 0; m < nvalues; m++) values[j][m] = values[i][m];
}
/* ----------------------------------------------------------------------
pack values in local atom-based array for exchange with another proc
------------------------------------------------------------------------- */
int FixStoreState::pack_exchange(int i, double *buf)
{
for (int m = 0; m < nvalues; m++) buf[m] = values[i][m];
return nvalues;
}
/* ----------------------------------------------------------------------
unpack values in local atom-based array from exchange with another proc
------------------------------------------------------------------------- */
int FixStoreState::unpack_exchange(int nlocal, double *buf)
{
for (int m = 0; m < nvalues; m++) values[nlocal][m] = buf[m];
return nvalues;
}
/* ----------------------------------------------------------------------
pack values in local atom-based arrays for restart file
------------------------------------------------------------------------- */
int FixStoreState::pack_restart(int i, double *buf)
{
buf[0] = nvalues+1;
for (int m = 0; m < nvalues; m++) buf[m+1] = values[i][m];
return nvalues+1;
}
/* ----------------------------------------------------------------------
unpack values from atom->extra array to restart the fix
------------------------------------------------------------------------- */
void FixStoreState::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++;
for (int i = 0; i < nvalues; i++) values[nlocal][i] = extra[nlocal][m++];
}
/* ----------------------------------------------------------------------
maxsize of any atom's restart data
------------------------------------------------------------------------- */
int FixStoreState::maxsize_restart()
{
return nvalues+1;
}
/* ----------------------------------------------------------------------
size of atom nlocal's restart data
------------------------------------------------------------------------- */
int FixStoreState::size_restart(int nlocal)
{
return nvalues+1;
}
/* ----------------------------------------------------------------------
one method for every keyword fix store/state can archive
the atom property is packed into buf starting at n with stride nvalues
customize a new keyword by adding a method
------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_id(int n)
{
int *tag = atom->tag;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = tag[i];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_molecule(int n)
{
int *molecule = atom->molecule;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = molecule[i];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_type(int n)
{
int *type = atom->type;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = type[i];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_mass(int n)
{
int *type = atom->type;
double *mass = atom->mass;
double *rmass = atom->rmass;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (rmass) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = rmass[i];
else vbuf[n] = 0.0;
n += nvalues;
}
} else {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = mass[type[i]];
else vbuf[n] = 0.0;
n += nvalues;
}
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_x(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = x[i][0];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_y(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = x[i][1];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_z(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = x[i][2];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_xs(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double boxxlo = domain->boxlo[0];
double invxprd = 1.0/domain->xprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = (x[i][0] - boxxlo) * invxprd;
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_ys(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double boxylo = domain->boxlo[1];
double invyprd = 1.0/domain->yprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = (x[i][1] - boxylo) * invyprd;
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_zs(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double boxzlo = domain->boxlo[2];
double invzprd = 1.0/domain->zprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = (x[i][2] - boxzlo) * invzprd;
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_xs_triclinic(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
vbuf[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]);
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_ys_triclinic(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
vbuf[n] = h_inv[1]*(x[i][1]-boxlo[1]) + h_inv[3]*(x[i][2]-boxlo[2]);
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_zs_triclinic(int n)
{
double **x = atom->x;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *boxlo = domain->boxlo;
double *h_inv = domain->h_inv;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit)
vbuf[n] = h_inv[2]*(x[i][2]-boxlo[2]);
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_xu(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
- vbuf[n] = x[i][0] + ((image[i] & 1023) - 512) * xprd;
+ vbuf[n] = x[i][0] + ((image[i] & IMGMASK) - IMGMAX) * xprd;
if (comflag) vbuf[n] -= cm[0];
} else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_yu(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double yprd = domain->yprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
- vbuf[n] = x[i][1] + ((image[i] >> 10 & 1023) - 512) * yprd;
+ vbuf[n] = x[i][1] + ((image[i] >> IMGBITS & IMGMASK) - IMGMAX) * yprd;
if (comflag) vbuf[n] -= cm[1];
} else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_zu(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double zprd = domain->zprd;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
- vbuf[n] = x[i][2] + ((image[i] >> 20) - 512) * zprd;
+ vbuf[n] = x[i][2] + ((image[i] >> IMG2BITS) - IMGMAX) * zprd;
if (comflag) vbuf[n] -= cm[2];
} else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_xu_triclinic(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *h = domain->h;
int xbox,ybox,zbox;
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
vbuf[n] = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
if (comflag) vbuf[n] -= cm[0];
} else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_yu_triclinic(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *h = domain->h;
int ybox,zbox;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
- ybox = (image[i] >> 10 & 1023) - 512;
- zbox = (image[i] >> 20) - 512;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
vbuf[n] = x[i][1] + h[1]*ybox + h[3]*zbox;
if (comflag) vbuf[n] -= cm[1];
} else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_zu_triclinic(int n)
{
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
double *h = domain->h;
int zbox;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
- zbox = (image[i] >> 20) - 512;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
vbuf[n] = x[i][2] + h[2]*zbox;
if (comflag) vbuf[n] -= cm[2];
} else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_ix(int n)
{
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
- if (mask[i] & groupbit) vbuf[n] = (image[i] & 1023) - 512;
+ if (mask[i] & groupbit) vbuf[n] = (image[i] & IMGMASK) - IMGMAX;
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_iy(int n)
{
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
- if (mask[i] & groupbit) vbuf[n] = (image[i] >> 10 & 1023) - 512;
+ if (mask[i] & groupbit) vbuf[n] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_iz(int n)
{
- int *image = atom->image;
+ tagint *image = atom->image;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
- if (mask[i] & groupbit) vbuf[n] = (image[i] >> 20) - 512;
+ if (mask[i] & groupbit) vbuf[n] = (image[i] >> IMG2BITS) - IMGMAX;
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_vx(int n)
{
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = v[i][0];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_vy(int n)
{
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = v[i][1];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_vz(int n)
{
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = v[i][2];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_fx(int n)
{
double **f = atom->f;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = f[i][0];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_fy(int n)
{
double **f = atom->f;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = f[i][1];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_fz(int n)
{
double **f = atom->f;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = f[i][2];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_q(int n)
{
double *q = atom->q;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = q[i];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_mux(int n)
{
double **mu = atom->mu;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = mu[i][0];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_muy(int n)
{
double **mu = atom->mu;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = mu[i][1];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_muz(int n)
{
double **mu = atom->mu;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = mu[i][2];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_radius(int n)
{
double *radius = atom->radius;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = radius[i];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_omegax(int n)
{
double **omega = atom->omega;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = omega[i][0];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_omegay(int n)
{
double **omega = atom->omega;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = omega[i][1];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_omegaz(int n)
{
double **omega = atom->omega;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = omega[i][2];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_angmomx(int n)
{
double **angmom = atom->angmom;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = angmom[i][0];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_angmomy(int n)
{
double **angmom = atom->angmom;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = angmom[i][1];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_angmomz(int n)
{
double **angmom = atom->angmom;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = angmom[i][2];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_tqx(int n)
{
double **torque = atom->torque;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = torque[i][0];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_tqy(int n)
{
double **torque = atom->torque;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = torque[i][1];
else vbuf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void FixStoreState::pack_tqz(int n)
{
double **torque = atom->torque;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) vbuf[n] = torque[i][2];
else vbuf[n] = 0.0;
n += nvalues;
}
}
diff --git a/src/fix_temp_berendsen.h b/src/fix_temp_berendsen.h
index 8fa2d4a3a..2b4a22a8c 100644
--- a/src/fix_temp_berendsen.h
+++ b/src/fix_temp_berendsen.h
@@ -1,90 +1,102 @@
/* -*- c++ -*- ----------------------------------------------------------
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(temp/berendsen,FixTempBerendsen)
#else
#ifndef LMP_FIX_TEMP_BERENDSEN_H
#define LMP_FIX_TEMP_BERENDSEN_H
#include "fix.h"
namespace LAMMPS_NS {
class FixTempBerendsen : public Fix {
public:
FixTempBerendsen(class LAMMPS *, int, char **);
~FixTempBerendsen();
int setmask();
void init();
void end_of_step();
int modify_param(int, char **);
void reset_target(double);
double compute_scalar();
virtual void *extract(const char *, int &);
private:
int which;
double t_start,t_stop,t_period,t_target;
double energy;
int tstyle,tvar;
char *tstr;
char *id_temp;
class Compute *temperature;
int tflag;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Fix temp/berendsen period must be > 0.0
Self-explanatory.
+E: Variable name for fix temp/berendsen does not exist
+
+Self-explanatory.
+
+E: Variable for fix temp/berendsen is invalid style
+
+Only equal-style variables can be used.
+
E: Temperature ID for fix temp/berendsen does not exist
Self-explanatory.
E: Computed temperature for fix temp/berendsen cannot be 0.0
Self-explanatory.
+E: Fix temp/berendsen variable returned negative temperature
+
+Self-explanatory.
+
E: Could not find fix_modify temperature ID
The compute ID for computing temperature does not exist.
E: Fix_modify temperature ID does not compute temperature
The compute ID assigned to the fix must compute temperature.
W: Group for fix_modify temp != fix group
The fix_modify command is specifying a temperature computation that
computes a temperature on a different group of atoms than the fix
itself operates on. This is probably not what you want to do.
*/
diff --git a/src/fix_temp_rescale.h b/src/fix_temp_rescale.h
index 3b4e4cb2c..20f4686f3 100644
--- a/src/fix_temp_rescale.h
+++ b/src/fix_temp_rescale.h
@@ -1,87 +1,99 @@
/* -*- c++ -*- ----------------------------------------------------------
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(temp/rescale,FixTempRescale)
#else
#ifndef LMP_FIX_TEMP_RESCALE_H
#define LMP_FIX_TEMP_RESCALE_H
#include "fix.h"
namespace LAMMPS_NS {
class FixTempRescale : public Fix {
public:
FixTempRescale(class LAMMPS *, int, char **);
virtual ~FixTempRescale();
int setmask();
void init();
virtual void end_of_step();
int modify_param(int, char **);
void reset_target(double);
double compute_scalar();
virtual void *extract(const char *, int &);
protected:
int which;
double t_start,t_stop,t_window,t_target;
double fraction,energy,efactor;
int tstyle,tvar;
char *tstr;
char *id_temp;
class Compute *temperature;
int tflag;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
+E: Variable name for fix temp/rescale does not exist
+
+Self-explanatory.
+
+E: Variable for fix temp/rescale is invalid style
+
+Only equal-style variables can be used.
+
E: Temperature ID for fix temp/rescale does not exist
Self-explanatory.
E: Computed temperature for fix temp/rescale cannot be 0.0
Cannot rescale the temperature to a new value if the current
temperature is 0.0.
+E: Fix temp/rescale variable returned negative temperature
+
+Self-explanatory.
+
E: Could not find fix_modify temperature ID
The compute ID for computing temperature does not exist.
E: Fix_modify temperature ID does not compute temperature
The compute ID assigned to the fix must compute temperature.
W: Group for fix_modify temp != fix group
The fix_modify command is specifying a temperature computation that
computes a temperature on a different group of atoms than the fix
itself operates on. This is probably not what you want to do.
*/
diff --git a/src/fix_tmd.cpp b/src/fix_tmd.cpp
index 1e5ec70e7..71efd01bd 100644
--- a/src/fix_tmd.cpp
+++ b/src/fix_tmd.cpp
@@ -1,563 +1,563 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdlib.h"
#include "string.h"
#include "fix_tmd.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;
using namespace FixConst;
#define CHUNK 1000
#define MAXLINE 256
/* ---------------------------------------------------------------------- */
FixTMD::FixTMD(LAMMPS *lmp, int narg, char **arg) :
Fix(lmp, narg, arg)
{
if (narg < 6) error->all(FLERR,"Illegal fix tmd command");
rho_stop = atof(arg[3]);
nfileevery = atoi(arg[5]);
if (rho_stop < 0 || nfileevery < 0)
error->all(FLERR,"Illegal fix tmd command");
if (nfileevery && narg != 7) error->all(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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(xf);
memory->destroy(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(FLERR,"Fix tmd must come after integration fixes");
// timesteps
dtv = update->dt;
dtf = update->dt * force->ftm2v;
if (strstr(update->integrate_style,"respa"))
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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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,
BIGINT_FORMAT " %g %g %g %g %g %g %g\n",
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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)
{
memory->grow(xf,nmax,3,"fix_tmd:xf");
memory->grow(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(FLERR,"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(FLERR,"Incorrect format in TMD target file");
imageflag = 1;
firstline = 0;
} else error->all(FLERR,"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(FLERR,"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(FLERR,"Cannot open gzipped file");
#endif
}
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open file %s",file);
error->one(FLERR,str);
}
}
/* ---------------------------------------------------------------------- */
void FixTMD::reset_dt()
{
dtv = update->dt;
dtf = update->dt * force->ftm2v;
}
diff --git a/src/group.cpp b/src/group.cpp
index dfccc77f4..e15891d3a 100644
--- a/src/group.cpp
+++ b/src/group.cpp
@@ -1,1468 +1,1468 @@
/* ----------------------------------------------------------------------
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 "string.h"
#include "stdlib.h"
#include "group.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
/* ----------------------------------------------------------------------
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(FLERR,"Group command before simulation box is defined");
if (narg < 2) error->all(FLERR,"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(FLERR,"Could not find group delete group ID");
if (igroup == 0) error->all(FLERR,"Cannot delete group all");
for (i = 0; i < modify->nfix; i++)
if (modify->fix[i]->igroup == igroup)
error->all(FLERR,"Cannot delete group currently used by a fix");
for (i = 0; i < modify->ncompute; i++)
if (modify->compute[i]->igroup == igroup)
error->all(FLERR,"Cannot delete group currently used by a compute");
for (i = 0; i < output->ndump; i++)
if (output->dump[i]->igroup == igroup)
error->all(FLERR,"Cannot delete group currently used by a dump");
if (atom->firstgroupname && strcmp(arg[0],atom->firstgroupname) == 0)
error->all(FLERR,
"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(FLERR,"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
// init all regions via domain->init() to insure region can perform match()
if (strcmp(arg[1],"region") == 0) {
if (narg != 3) error->all(FLERR,"Illegal group command");
int iregion = domain->find_region(arg[2]);
if (iregion == -1) error->all(FLERR,"Group region ID does not exist");
domain->init();
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(FLERR,"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(FLERR,"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(FLERR,"Illegal group command");
bound1 = atoi(arg[3]);
bound2 = -1;
if (condition == BETWEEN) {
if (narg != 5) error->all(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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_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_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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMAX;
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/kspace.cpp b/src/kspace.cpp
index b0b345bdf..397c2067c 100644
--- a/src/kspace.cpp
+++ b/src/kspace.cpp
@@ -1,189 +1,221 @@
/* ----------------------------------------------------------------------
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 "kspace.h"
#include "atom.h"
#include "comm.h"
#include "force.h"
+#include "pair.h"
#include "memory.h"
#include "error.h"
#include "suffix.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
KSpace::KSpace(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
{
energy = 0.0;
virial[0] = virial[1] = virial[2] = virial[3] = virial[4] = virial[5] = 0.0;
compute_flag = 1;
group_group_enable = 0;
order = 5;
gridflag = 0;
gewaldflag = 0;
slabflag = 0;
differentiation_flag = 0;
slab_volfactor = 1;
suffix_flag = Suffix::NONE;
accuracy_absolute = -1.0;
two_charge_force = force->qqr2e *
(force->qelectron * force->qelectron) /
(force->angstrom * force->angstrom);
maxeatom = maxvatom = 0;
eatom = NULL;
vatom = NULL;
}
/* ---------------------------------------------------------------------- */
KSpace::~KSpace()
{
memory->destroy(eatom);
memory->destroy(vatom);
}
/* ---------------------------------------------------------------------- */
void KSpace::compute_dummy(int eflag, int vflag)
{
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = evflag_atom = eflag_global = vflag_global =
eflag_atom = vflag_atom = 0;
}
/* ----------------------------------------------------------------------
setup for energy, virial computation
see integrate::ev_set() for values of eflag (0-3) and vflag (0-6)
------------------------------------------------------------------------- */
void KSpace::ev_setup(int eflag, int vflag)
{
int i,n;
evflag = 1;
eflag_either = eflag;
eflag_global = eflag % 2;
eflag_atom = eflag / 2;
vflag_either = vflag;
vflag_global = vflag % 4;
vflag_atom = vflag / 4;
if (eflag_atom || vflag_atom) evflag_atom = 1;
else evflag_atom = 0;
// reallocate per-atom arrays if necessary
if (eflag_atom && atom->nlocal > maxeatom) {
maxeatom = atom->nmax;
memory->destroy(eatom);
memory->create(eatom,maxeatom,"kspace:eatom");
}
if (vflag_atom && atom->nlocal > maxvatom) {
maxvatom = atom->nmax;
memory->destroy(vatom);
memory->create(vatom,maxvatom,6,"kspace:vatom");
}
// zero accumulators
if (eflag_global) energy = 0.0;
if (vflag_global) for (i = 0; i < 6; i++) virial[i] = 0.0;
if (eflag_atom) {
n = atom->nlocal;
for (i = 0; i < n; i++) eatom[i] = 0.0;
}
if (vflag_atom) {
n = atom->nlocal;
for (i = 0; i < n; i++) {
vatom[i][0] = 0.0;
vatom[i][1] = 0.0;
vatom[i][2] = 0.0;
vatom[i][3] = 0.0;
vatom[i][4] = 0.0;
vatom[i][5] = 0.0;
}
}
}
+/* ----------------------------------------------------------------------
+ estimate the accuracy of the short-range coulomb tables
+------------------------------------------------------------------------- */
+
+double KSpace::estimate_table_accuracy(double spr)
+{
+ double table_accuracy = 0.0;
+ int nctb = force->pair->ncoultablebits;
+ if (nctb) {
+ double empirical_precision[17];
+ empirical_precision[6] = 2.12E-04;
+ empirical_precision[7] = 4.97E-05;
+ empirical_precision[8] = 1.24E-05;
+ empirical_precision[9] = 3.04E-06;
+ empirical_precision[10] = 8.51E-07;
+ empirical_precision[11] = 1.85E-07;
+ empirical_precision[12] = 5.87E-08;
+ empirical_precision[13] = 2.81E-08;
+ empirical_precision[14] = 2.20E-08;
+ empirical_precision[15] = 2.13E-08;
+ empirical_precision[16] = 2.11E-08;
+ if (nctb <= 6) table_accuracy = empirical_precision[6];
+ else if (nctb <= 16) table_accuracy = empirical_precision[nctb];
+ else table_accuracy = empirical_precision[16];
+ table_accuracy *= two_charge_force;
+ if (table_accuracy > spr)
+ error->warning(FLERR,"For better accuracy use 'pair_modify table 0'");
+ }
+ return table_accuracy;
+}
+
/* ----------------------------------------------------------------------
modify parameters of the KSpace style
------------------------------------------------------------------------- */
void KSpace::modify_params(int narg, char **arg)
{
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"mesh") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal kspace_modify command");
nx_pppm = atoi(arg[iarg+1]);
ny_pppm = atoi(arg[iarg+2]);
nz_pppm = atoi(arg[iarg+3]);
if (nx_pppm == 0 && ny_pppm == 0 && nz_pppm == 0) gridflag = 0;
else gridflag = 1;
iarg += 4;
} else if (strcmp(arg[iarg],"order") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal kspace_modify command");
order = atoi(arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"force") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal kspace_modify command");
accuracy_absolute = atof(arg[iarg+1]);
iarg += 2;
} else if (strcmp(arg[iarg],"gewald") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal kspace_modify command");
g_ewald = atof(arg[iarg+1]);
if (g_ewald == 0.0) gewaldflag = 0;
else gewaldflag = 1;
iarg += 2;
} else if (strcmp(arg[iarg],"slab") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal kspace_modify command");
slab_volfactor = atof(arg[iarg+1]);
iarg += 2;
if (slab_volfactor <= 1.0)
error->all(FLERR,"Bad kspace_modify slab parameter");
if (slab_volfactor < 2.0 && comm->me == 0)
error->warning(FLERR,"Kspace_modify slab param < 2.0 may "
"cause unphysical behavior");
slabflag = 1;
} else if (strcmp(arg[iarg],"compute") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal kspace_modify command");
if (strcmp(arg[iarg+1],"yes") == 0) compute_flag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) compute_flag = 0;
else error->all(FLERR,"Illegal kspace_modify command");
iarg += 2;
} else if (strcmp(arg[iarg],"diff") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal kspace_modify command");
if (strcmp(arg[iarg+1],"ad") == 0) differentiation_flag = 1;
else if (strcmp(arg[iarg+1],"ik") == 0) differentiation_flag = 0;
else error->all(FLERR, "Illegal kspace_modify command");
iarg += 2;
} else error->all(FLERR,"Illegal kspace_modify command");
}
}
/* ---------------------------------------------------------------------- */
void *KSpace::extract(const char *str)
{
if (strcmp(str,"scale") == 0) return (void *) &scale;
return NULL;
}
diff --git a/src/kspace.h b/src/kspace.h
index c5ea971d4..eeb586a28 100644
--- a/src/kspace.h
+++ b/src/kspace.h
@@ -1,96 +1,102 @@
/* -*- c++ -*- ----------------------------------------------------------
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_KSPACE_H
#define LMP_KSPACE_H
#include "pointers.h"
namespace LAMMPS_NS {
class KSpace : protected Pointers {
friend class ThrOMP;
friend class FixOMP;
public:
double energy; // accumulated energy
double virial[6]; // accumlated virial
double *eatom,**vatom; // accumulated per-atom energy/virial
double e2group; // accumulated group-group energy
double f2group[3]; // accumulated group-group force
double g_ewald;
int nx_pppm,ny_pppm,nz_pppm;
int group_group_enable; // 1 if style supports group/group calculation
int compute_flag; // 0 if skip compute()
KSpace(class LAMMPS *, int, char **);
virtual ~KSpace();
void modify_params(int, char **);
void *extract(const char *);
void compute_dummy(int, int);
// general child-class methods
virtual void init() = 0;
virtual void setup() = 0;
virtual void compute(int, int) = 0;
virtual void compute_group_group(int, int, int) {};
virtual void timing(int, double &, double &) {}
virtual double memory_usage() {return 0.0;}
protected:
int gridflag,gewaldflag,differentiation_flag;
int order;
int slabflag;
int suffix_flag; // suffix compatibility flag
double scale;
double slab_volfactor;
double accuracy; // accuracy of KSpace solver (force units)
double accuracy_absolute; // user-specifed accuracy in force units
double accuracy_relative; // user-specified dimensionless accuracy
// accurary = acc_rel * two_charge_force
double two_charge_force; // force in user units of two point
// charges separated by 1 Angstrom
int evflag,evflag_atom;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
int maxeatom,maxvatom;
void ev_setup(int, int);
+ double estimate_table_accuracy(double);
};
}
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Bad kspace_modify slab parameter
Kspace_modify value for the slab/volume keyword must be >= 2.0.
W: Kspace_modify slab param < 2.0 may cause unphysical behavior
The kspace_modify slab parameter should be larger to insure periodic
grids padded with empty space do not overlap.
+W: For better accuracy use 'pair_modify table 0'
+
+The user-specified force accuracy cannot be achieved unless the table
+feature is disabled by using 'pair_modify table 0'.
+
*/
diff --git a/src/lmptype.h b/src/lmptype.h
index 5eca877ec..7a4288b0e 100644
--- a/src/lmptype.h
+++ b/src/lmptype.h
@@ -1,152 +1,168 @@
-/* ----------------------------------------------------------------------
+/* -*- c++ -*- ----------------------------------------------------------
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
+ 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 on-procesor system (nlocal, nmax, 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
// bigint can be 32-bit or 64-bit int, must be >= tagint
// MPI_LMP_TAGINT = MPI data type corresponding to a tagint
// MPI_LMP_BIGINT = MPI data type corresponding to a bigint
#ifndef LMP_LMPTYPE_H
#define LMP_LMPTYPE_H
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include "limits.h"
#include "stdint.h"
#include "inttypes.h"
// grrr - IBM Power6 does not provide this def in their system header files
#ifndef PRId64
#define PRId64 "ld"
#endif
namespace LAMMPS_NS {
// reserve 2 hi bits in molecular system neigh list for special bonds flag
// max local + ghost atoms per processor = 2^30 - 1
#define SBBITS 30
#define NEIGHMASK 0x3FFFFFFF
// default to 32-bit smallint and tagint, 64-bit bigint
#if !defined(LAMMPS_SMALLSMALL) && !defined(LAMMPS_BIGBIG)
#define LAMMPS_SMALLBIG
#endif
// allow user override of LONGLONG to LONG, necessary for some machines/MPI
#ifdef LAMMPS_LONGLONG_TO_LONG
#define MPI_LL MPI_LONG
#define ATOLL atoll
#else
#define MPI_LL MPI_LONG_LONG
#define ATOLL atol
#endif
// for atomic problems that exceed 2 billion (2^31) atoms
// 32-bit smallint and tagint, 64-bit bigint
#ifdef LAMMPS_SMALLBIG
typedef int smallint;
typedef int tagint;
typedef int64_t bigint;
#define MAXSMALLINT INT_MAX
#define MAXTAGINT INT_MAX
#define MAXBIGINT INT64_MAX
#define MPI_LMP_TAGINT MPI_INT
#define MPI_LMP_BIGINT MPI_LL
#define TAGINT_FORMAT "%d"
#define BIGINT_FORMAT "%" PRId64
#define ATOTAGINT atoi
#define ATOBIGINT ATOLL
+#define IMGMASK 1023
+#define IMGMAX 512
+#define IMGBITS 10
+#define IMG2BITS 20
+
#endif
// for molecular problems that exceed 2 billion (2^31) atoms
+// or problems where atoms wrap around the periodic box more than 512 times
// 32-bit smallint, 64-bit tagint and bigint
#ifdef LAMMPS_BIGBIG
typedef int smallint;
typedef int64_t tagint;
typedef int64_t bigint;
#define MAXSMALLINT INT_MAX
#define MAXTAGINT INT64_MAX
#define MAXBIGINT INT64_MAX
#define MPI_LMP_TAGINT MPI_LL
#define MPI_LMP_BIGINT MPI_LL
#define TAGINT_FORMAT "%" PRId64
#define BIGINT_FORMAT "%" PRId64
#define ATOTAGINT ATOLL
#define ATOBIGINT ATOLL
+#define IMGMASK 2097151
+#define IMGMAX 1048576
+#define IMGBITS 21
+#define IMG2BITS 42
+
#endif
// for machines that do not support 64-bit ints
// 32-bit smallint and tagint and bigint
#ifdef LAMMPS_SMALLSMALL
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 ATOTAGINT atoi
#define ATOBIGINT atoi
+#define IMGMASK 1023
+#define IMGMAX 512
+#define IMGBITS 10
+#define IMG2BITS 20
+
#endif
}
// settings to enable LAMMPS to build under Windows
#ifdef _WIN32
#include "lmpwindows.h"
#endif
#endif
diff --git a/src/modify.h b/src/modify.h
index 421bc84ff..95a63dd56 100644
--- a/src/modify.h
+++ b/src/modify.h
@@ -1,204 +1,204 @@
/* -*- c++ -*- ----------------------------------------------------------
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"
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 *);
virtual ~Modify();
virtual void init();
virtual void setup(int);
virtual void setup_pre_exchange();
virtual void setup_pre_force(int);
virtual void initial_integrate(int);
virtual void post_integrate();
void pre_decide();
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 double thermo_energy();
virtual 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 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 **, char *suffix = NULL);
void modify_fix(int, char **);
void delete_fix(const char *);
int find_fix(const char *);
void add_compute(int, char **, char *suffix = NULL);
void modify_compute(int, char **);
void delete_compute(const char *);
int find_compute(const char *);
void clearstep_compute();
void addstep_compute(bigint);
void addstep_compute_all(bigint);
void write_restart(FILE *);
int read_restart(FILE *);
void restart_deallocate();
bigint memory_usage();
protected:
// 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
/* ERROR/WARNING messages:
W: One or more atoms are time integrated more than once
This is probably an error since you typically do not want to
advance the positions or velocities of an atom more than once
per timestep.
-E: Fix command before simulation box is defined
-
-The fix command cannot be used before a read_data, read_restart, or
-create_box command.
-
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
+E: Fix command before simulation box is defined
+
+The fix command cannot be used before a read_data, read_restart, or
+create_box command.
+
E: Could not find fix group ID
A group ID used in the fix command does not exist.
E: Replacing a fix, but new style != old style
A fix ID can be used a 2nd time, but only if the style matches the
previous fix. In this case it is assumed you with to reset a fix's
parameters. This error may mean you are mistakenly re-using a fix ID
when you do not intend to.
W: Replacing a fix, but new group != old group
The ID and style of a fix match for a fix you are changing with a fix
command, but the new group you are specifying does not match the old
group.
E: Invalid fix style
The choice of fix style is unknown.
E: Could not find fix_modify ID
A fix ID used in the fix_modify command does not exist.
E: Could not find fix ID to delete
Self-explanatory.
E: Reuse of compute ID
A compute ID cannot be used twice.
E: Invalid compute style
Self-explanatory.
E: Could not find compute_modify ID
Self-explanatory.
E: Could not find compute ID to delete
Self-explanatory.
*/
diff --git a/src/neigh_bond.cpp b/src/neigh_bond.cpp
index df95e272c..4840c1963 100644
--- a/src/neigh_bond.cpp
+++ b/src/neigh_bond.cpp
@@ -1,387 +1,418 @@
/* ----------------------------------------------------------------------
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 "atom.h"
#include "force.h"
#include "update.h"
+#include "domain.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define BONDDELTA 10000
+// bondlist, anglelist, dihedrallist, improperlist
+// no longer store atom->map() of the bond partners
+// instead store domain->closest_image() of the bond partners of atom I
+// this enables distances between list atoms to be calculated
+// w/out invoking domain->minimium_image(), e.g. in bond->compute()
+
/* ---------------------------------------------------------------------- */
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 " BIGINT_FORMAT,
tag[i],bond_atom[i][m],me,update->ntimestep);
error->one(FLERR,str);
}
+ atom1 = domain->closest_image(i,atom1);
if (newton_bond || i < atom1) {
if (nbondlist == maxbond) {
maxbond += BONDDELTA;
memory->grow(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 " BIGINT_FORMAT,
tag[i],bond_atom[i][m],me,update->ntimestep);
error->one(FLERR,str);
}
+ atom1 = domain->closest_image(i,atom1);
if (newton_bond || i < atom1) {
if (nbondlist == maxbond) {
maxbond += BONDDELTA;
memory->grow(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 "
BIGINT_FORMAT,
angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m],
me,update->ntimestep);
error->one(FLERR,str);
}
+ atom1 = domain->closest_image(i,atom1);
+ atom2 = domain->closest_image(i,atom2);
+ atom3 = domain->closest_image(i,atom3);
if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) {
if (nanglelist == maxangle) {
maxangle += BONDDELTA;
memory->grow(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 "
BIGINT_FORMAT,
angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m],
me,update->ntimestep);
error->one(FLERR,str);
}
+ atom1 = domain->closest_image(i,atom1);
+ atom2 = domain->closest_image(i,atom2);
+ atom3 = domain->closest_image(i,atom3);
if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) {
if (nanglelist == maxangle) {
maxangle += BONDDELTA;
memory->grow(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 "
BIGINT_FORMAT,
dihedral_atom1[i][m],dihedral_atom2[i][m],
dihedral_atom3[i][m],dihedral_atom4[i][m],
me,update->ntimestep);
error->one(FLERR,str);
}
+ atom1 = domain->closest_image(i,atom1);
+ atom2 = domain->closest_image(i,atom2);
+ atom3 = domain->closest_image(i,atom3);
+ atom4 = domain->closest_image(i,atom4);
if (newton_bond ||
(i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) {
if (ndihedrallist == maxdihedral) {
maxdihedral += BONDDELTA;
memory->grow(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 "
BIGINT_FORMAT,
dihedral_atom1[i][m],dihedral_atom2[i][m],
dihedral_atom3[i][m],dihedral_atom4[i][m],
me,update->ntimestep);
error->one(FLERR,str);
}
+ atom1 = domain->closest_image(i,atom1);
+ atom2 = domain->closest_image(i,atom2);
+ atom3 = domain->closest_image(i,atom3);
+ atom4 = domain->closest_image(i,atom4);
if (newton_bond ||
(i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) {
if (ndihedrallist == maxdihedral) {
maxdihedral += BONDDELTA;
memory->grow(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 "
BIGINT_FORMAT,
improper_atom1[i][m],improper_atom2[i][m],
improper_atom3[i][m],improper_atom4[i][m],
me,update->ntimestep);
error->one(FLERR,str);
}
+ atom1 = domain->closest_image(i,atom1);
+ atom2 = domain->closest_image(i,atom2);
+ atom3 = domain->closest_image(i,atom3);
+ atom4 = domain->closest_image(i,atom4);
if (newton_bond ||
(i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) {
if (nimproperlist == maximproper) {
maximproper += BONDDELTA;
memory->grow(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 "
BIGINT_FORMAT,
improper_atom1[i][m],improper_atom2[i][m],
improper_atom3[i][m],improper_atom4[i][m],
me,update->ntimestep);
error->one(FLERR,str);
}
+ atom1 = domain->closest_image(i,atom1);
+ atom2 = domain->closest_image(i,atom2);
+ atom3 = domain->closest_image(i,atom3);
+ atom4 = domain->closest_image(i,atom4);
if (newton_bond ||
(i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) {
if (nimproperlist == maximproper) {
maximproper += BONDDELTA;
memory->grow(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/neigh_bond.h b/src/neigh_bond.h
index ea85736f7..1cf7c80a4 100644
--- a/src/neigh_bond.h
+++ b/src/neigh_bond.h
@@ -1,44 +1,43 @@
/* -*- c++ -*- ----------------------------------------------------------
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.
------------------------------------------------------------------------- */
/* ERROR/WARNING messages:
E: Bond atoms %d %d missing on proc %d at step %ld
-One or both of 2 atoms needed to compute a particular bond are
-missing on this processor. Typically this is because the pairwise
-cutoff is set too short or the bond has blown apart and an atom is
-too far away.
+The 2nd atom needed to compute a particular bond is missing on this
+processor. Typically this is because the pairwise cutoff is set too
+short or the bond has blown apart and an atom is too far away.
E: Angle atoms %d %d %d missing on proc %d at step %ld
One or more of 3 atoms needed to compute a particular angle are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the angle has blown apart and an atom is
too far away.
E: Dihedral atoms %d %d %d %d missing on proc %d at step %ld
One or more of 4 atoms needed to compute a particular dihedral are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the dihedral has blown apart and an atom is
too far away.
E: Improper atoms %d %d %d %d missing on proc %d at step %ld
One or more of 4 atoms needed to compute a particular improper are
missing on this processor. Typically this is because the pairwise
cutoff is set too short or the improper has blown apart and an atom is
too far away.
*/
diff --git a/src/neighbor.h b/src/neighbor.h
index 5b14b706e..17d3b6bc1 100644
--- a/src/neighbor.h
+++ b/src/neighbor.h
@@ -1,390 +1,386 @@
/* -*- c++ -*- ----------------------------------------------------------
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_NEIGHBOR_H
#define LMP_NEIGHBOR_H
#include "pointers.h"
namespace LAMMPS_NS {
class Neighbor : protected Pointers {
friend class Cuda;
public:
int style; // 0,1,2 = nsq, bin, multi
int every; // build every this many steps
int delay; // delay build for this many steps
int dist_check; // 0 = always build, 1 = only if 1/2 dist
int ago; // how many steps ago neighboring occurred
int pgsize; // size of neighbor page
int oneatom; // max # of neighbors for one atom
int includegroup; // only build pairwise lists for this group
int build_once; // 1 if only build lists once per run
int cudable; // GPU <-> CPU communication flag for CUDA
double skin; // skin distance
double cutneighmin; // min neighbor cutoff for all type pairs
double cutneighmax; // max neighbor cutoff for all type pairs
double *cuttype; // for each type, max neigh cut w/ others
int ncalls; // # of times build has been called
int ndanger; // # of dangerous builds
int nrequest; // requests for pairwise neighbor lists
class NeighRequest **requests; // from Pair, Fix, Compute, Command classes
int maxrequest;
int old_style; // previous run info to avoid
int old_nrequest; // re-creation of pairwise neighbor lists
int old_triclinic;
class NeighRequest **old_requests;
int nlist; // pairwise neighbor lists
class NeighList **lists;
int nbondlist; // list of bonds to compute
int **bondlist;
int nanglelist; // list of angles to compute
int **anglelist;
int ndihedrallist; // list of dihedrals to compute
int **dihedrallist;
int nimproperlist; // list of impropers to compute
int **improperlist;
Neighbor(class LAMMPS *);
virtual ~Neighbor();
virtual void init();
int request(void *); // another class requests a neighbor list
void print_lists_of_lists(); // debug print out
int decide(); // decide whether to build or not
virtual int check_distance(); // check max distance moved since last build
void setup_bins(); // setup bins based on box and cutoff
virtual void build(); // create all neighbor lists (pair,bond)
void build_one(int); // create a single neighbor list
void set(int, char **); // set neighbor style and skin distance
void modify_params(int, char**); // modify parameters that control builds
bigint memory_usage();
int exclude_setting();
protected:
int me,nprocs;
int maxatom; // size of atom-based NeighList arrays
int maxbond,maxangle,maxdihedral,maximproper; // size of bond lists
int maxwt; // max weighting factor applied + 1
int must_check; // 1 if must check other classes to reneigh
int restart_check; // 1 if restart enabled, 0 if no
int fix_check; // # of fixes that induce reneigh
int *fixchecklist; // which fixes to check
double **cutneighsq; // neighbor cutneigh sq for each type pair
double **cutneighghostsq; // neighbor cutnsq for each ghost type pair
double cutneighmaxsq; // cutneighmax squared
double *cuttypesq; // cuttype squared
double triggersq; // trigger = build when atom moves this dist
double **xhold; // atom coords at last neighbor build
int maxhold; // size of xhold array
int boxcheck; // 1 if need to store box size
double boxlo_hold[3],boxhi_hold[3]; // box size at last neighbor build
double corners_hold[8][3]; // box corners at last neighbor build
int nbinx,nbiny,nbinz; // # of global bins
int *bins; // ptr to next atom in each bin
int maxbin; // size of bins array
int *binhead; // ptr to 1st atom in each bin
int maxhead; // size of binhead array
int mbins; // # of local bins and offset
int mbinx,mbiny,mbinz;
int mbinxlo,mbinylo,mbinzlo;
int binsizeflag; // user-chosen bin size
double binsize_user;
double binsizex,binsizey,binsizez; // actual bin sizes and inverse sizes
double bininvx,bininvy,bininvz;
int sx,sy,sz,smax; // bin stencil extents
int dimension; // 2/3 for 2d/3d
int triclinic; // 0 if domain is orthog, 1 if triclinic
int newton_pair; // 0 if newton off, 1 if on for pairwise
double *bboxlo,*bboxhi; // ptrs to full domain bounding box
double (*corners)[3]; // ptr to 8 corners of triclinic box
double inner[2],middle[2]; // rRESPA cutoffs for extra lists
double cut_inner_sq; // outer cutoff for inner neighbor list
double cut_middle_sq; // outer cutoff for middle neighbor list
double cut_middle_inside_sq; // inner cutoff for middle neighbor list
int special_flag[4]; // flags for 1-2, 1-3, 1-4 neighbors
int anyghostlist; // 1 if any non-occasional list
// stores neighbors of ghosts
int exclude; // 0 if no type/group exclusions, 1 if yes
int nex_type; // # of entries in type exclusion list
int maxex_type; // max # in type list
int *ex1_type,*ex2_type; // pairs of types to exclude
int **ex_type; // 2d array of excluded type pairs
int nex_group; // # of entries in group exclusion list
int maxex_group; // max # in group list
int *ex1_group,*ex2_group; // pairs of group #'s to exclude
int *ex1_bit,*ex2_bit; // pairs of group bits to exclude
int nex_mol; // # of entries in molecule exclusion list
int maxex_mol; // max # in molecule list
int *ex_mol_group; // molecule group #'s to exclude
int *ex_mol_bit; // molecule group bits to exclude
int nblist,nglist,nslist; // # of pairwise neigh lists of various kinds
int *blist; // lists to build every reneighboring
int *glist; // lists to grow atom arrays every reneigh
int *slist; // lists to grow stencil arrays every reneigh
void bin_atoms(); // bin all atoms
double bin_distance(int, int, int); // distance between binx
int coord2bin(double *); // mapping atom coord to a bin
int coord2bin(double *, int &, int &, int&); // ditto
int exclusion(int, int, int,
int, int *, int *) const; // test for pair exclusion
virtual void choose_build(int, class NeighRequest *);
void choose_stencil(int, class NeighRequest *);
// pairwise build functions
typedef void (Neighbor::*PairPtr)(class NeighList *);
PairPtr *pair_build;
void half_nsq_no_newton(class NeighList *);
void half_nsq_no_newton_ghost(class NeighList *);
void half_nsq_newton(class NeighList *);
void half_bin_no_newton(class NeighList *);
void half_bin_no_newton_ghost(class NeighList *);
void half_bin_newton(class NeighList *);
void half_bin_newton_tri(class NeighList *);
void half_multi_no_newton(class NeighList *);
void half_multi_newton(class NeighList *);
void half_multi_newton_tri(class NeighList *);
void full_nsq(class NeighList *);
void full_nsq_ghost(class NeighList *);
void full_bin(class NeighList *);
void full_bin_ghost(class NeighList *);
void full_multi(class NeighList *);
void half_from_full_no_newton(class NeighList *);
void half_from_full_newton(class NeighList *);
void skip_from(class NeighList *);
void skip_from_granular(class NeighList *);
void skip_from_respa(class NeighList *);
void copy_from(class NeighList *);
void granular_nsq_no_newton(class NeighList *);
void granular_nsq_newton(class NeighList *);
void granular_bin_no_newton(class NeighList *);
void granular_bin_newton(class NeighList *);
void granular_bin_newton_tri(class NeighList *);
void respa_nsq_no_newton(class NeighList *);
void respa_nsq_newton(class NeighList *);
void respa_bin_no_newton(class NeighList *);
void respa_bin_newton(class NeighList *);
void respa_bin_newton_tri(class NeighList *);
// OpenMP multi-threaded neighbor list build versions
#include "accelerator_omp.h"
// pairwise stencil creation functions
typedef void (Neighbor::*StencilPtr)(class NeighList *, int, int, int);
StencilPtr *stencil_create;
void stencil_half_bin_2d_no_newton(class NeighList *, int, int, int);
void stencil_half_ghost_bin_2d_no_newton(class NeighList *, int, int, int);
void stencil_half_bin_3d_no_newton(class NeighList *, int, int, int);
void stencil_half_ghost_bin_3d_no_newton(class NeighList *, int, int, int);
void stencil_half_bin_2d_newton(class NeighList *, int, int, int);
void stencil_half_bin_3d_newton(class NeighList *, int, int, int);
void stencil_half_bin_2d_newton_tri(class NeighList *, int, int, int);
void stencil_half_bin_3d_newton_tri(class NeighList *, int, int, int);
void stencil_half_multi_2d_no_newton(class NeighList *, int, int, int);
void stencil_half_multi_3d_no_newton(class NeighList *, int, int, int);
void stencil_half_multi_2d_newton(class NeighList *, int, int, int);
void stencil_half_multi_3d_newton(class NeighList *, int, int, int);
void stencil_half_multi_2d_newton_tri(class NeighList *, int, int, int);
void stencil_half_multi_3d_newton_tri(class NeighList *, int, int, int);
void stencil_full_bin_2d(class NeighList *, int, int, int);
void stencil_full_ghost_bin_2d(class NeighList *, int, int, int);
void stencil_full_bin_3d(class NeighList *, int, int, int);
void stencil_full_ghost_bin_3d(class NeighList *, int, int, int);
void stencil_full_multi_2d(class NeighList *, int, int, int);
void stencil_full_multi_3d(class NeighList *, int, int, int);
// topology build functions
typedef void (Neighbor::*BondPtr)(); // ptrs to topology build functions
BondPtr bond_build; // ptr to bond list functions
void bond_all(); // bond list with all bonds
void bond_partial(); // exclude certain bonds
BondPtr angle_build; // ptr to angle list functions
void angle_all(); // angle list with all angles
void angle_partial(); // exclude certain angles
BondPtr dihedral_build; // ptr to dihedral list functions
void dihedral_all(); // dihedral list with all dihedrals
void dihedral_partial(); // exclude certain dihedrals
BondPtr improper_build; // ptr to improper list functions
void improper_all(); // improper list with all impropers
void improper_partial(); // exclude certain impropers
// find_special: determine if atom j is in special list of atom i
// if it is not, return 0
// if it is and special flag is 0 (both coeffs are 0.0), return -1
// if it is and special flag is 1 (both coeffs are 1.0), return 0
// if it is and special flag is 2 (otherwise), return 1,2,3
// for which level of neighbor it is (and which coeff it maps to)
inline int find_special(const int *list, const int *nspecial,
const int tag) const {
const int n1 = nspecial[0];
const int n2 = nspecial[1];
const int n3 = nspecial[2];
for (int i = 0; i < n3; i++) {
if (list[i] == tag) {
if (i < n1) {
if (special_flag[1] == 0) return -1;
else if (special_flag[1] == 1) return 0;
else return 1;
} else if (i < n2) {
if (special_flag[2] == 0) return -1;
else if (special_flag[2] == 1) return 0;
else return 2;
} else {
if (special_flag[3] == 0) return -1;
else if (special_flag[3] == 1) return 0;
else return 3;
}
}
}
return 0;
};
};
}
#endif
/* ERROR/WARNING messages:
E: Neighbor delay must be 0 or multiple of every setting
The delay and every parameters set via the neigh_modify command are
inconsistent. If the delay setting is non-zero, then it must be a
multiple of the every setting.
E: Neighbor page size must be >= 10x the one atom setting
This is required to prevent wasting too much memory.
E: Invalid atom type in neighbor exclusion list
Atom types must range from 1 to Ntypes inclusive.
E: Neighbor include group not allowed with ghost neighbors
This is a current restriction within LAMMPS.
E: Neighbor multi not yet enabled for ghost neighbors
This is a current restriction within LAMMPS.
E: Neighbor multi not yet enabled for granular
Self-explanatory.
E: Neighbor multi not yet enabled for rRESPA
Self-explanatory.
-E: Neighbors of ghost atoms only allowed for full neighbor lists
-
-This is a current restriction within LAMMPS.
-
E: Too many local+ghost atoms for neighbor list
The number of nlocal + nghost atoms on a processor
is limited by the size of a 32-bit integer with 2 bits
removed for masking 1-2, 1-3, 1-4 neighbors.
W: Building an occasional neighobr list when atoms may have moved too far
This can cause LAMMPS to crash when the neighbor list is built.
The solution is to check for building the regular neighbor lists
more frequently.
E: Domain too large for neighbor bins
The domain has become extremely large so that neighbor bins cannot be
used. Most likely, one or more atoms have been blown out of the
simulation box to a great distance.
E: Cannot use neighbor bins - box size << cutoff
Too many neighbor bins will be created. This typically happens when
the simulation box is very small in some dimension, compared to the
neighbor cutoff. Use the "nsq" style instead of "bin" style.
E: Too many neighbor bins
This is likely due to an immense simulation box that has blown up
to a large size.
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Invalid group ID in neigh_modify command
A group ID used in the neigh_modify command does not exist.
E: Neigh_modify include group != atom_modify first group
Self-explanatory.
E: Neigh_modify exclude molecule requires atom attribute molecule
Self-explanatory.
*/
diff --git a/src/output.cpp b/src/output.cpp
index af08f20ab..61f9adc58 100644
--- a/src/output.cpp
+++ b/src/output.cpp
@@ -1,768 +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 "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 "accelerator_cuda.h"
#include "memory.h"
#include "error.h"
using namespace LAMMPS_NS;
#define DELTA 1
/* ----------------------------------------------------------------------
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,lmp->suffix);
newarg[0] = (char *) "thermo_press";
newarg[1] = (char *) "all";
newarg[2] = (char *) "pressure";
newarg[3] = (char *) "thermo_temp";
modify->add_compute(4,newarg,lmp->suffix);
newarg[0] = (char *) "thermo_pe";
newarg[1] = (char *) "all";
newarg[2] = (char *) "pe";
modify->add_compute(3,newarg,lmp->suffix);
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_flag = restart_flag_single = restart_flag_double = 0;
last_restart = -1;
restart1 = restart2a = restart2b = NULL;
var_restart_single = var_restart_double = NULL;
restart = NULL;
}
/* ----------------------------------------------------------------------
free all memory
------------------------------------------------------------------------- */
Output::~Output()
{
if (thermo) delete thermo;
delete [] var_thermo;
memory->destroy(every_dump);
memory->destroy(next_dump);
memory->destroy(last_dump);
for (int i = 0; i < ndump; i++) delete [] var_dump[i];
memory->sfree(var_dump);
memory->destroy(ivar_dump);
for (int i = 0; i < ndump; i++) delete dump[i];
memory->sfree(dump);
delete [] restart1;
delete [] restart2a;
delete [] restart2b;
delete [] var_restart_single;
delete [] var_restart_double;
delete restart;
}
/* ---------------------------------------------------------------------- */
void Output::init()
{
thermo->init();
if (var_thermo) {
ivar_thermo = input->variable->find(var_thermo);
if (ivar_thermo < 0)
error->all(FLERR,"Variable name for thermo every does not exist");
if (!input->variable->equalstyle(ivar_thermo))
error->all(FLERR,"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(FLERR,"Variable name for dump every does not exist");
if (!input->variable->equalstyle(ivar_dump[i]))
error->all(FLERR,"Variable for dump every is invalid style");
}
if (restart_flag_single && restart_every_single == 0) {
ivar_restart_single = input->variable->find(var_restart_single);
if (ivar_restart_single < 0)
error->all(FLERR,"Variable name for restart does not exist");
if (!input->variable->equalstyle(ivar_restart_single))
error->all(FLERR,"Variable for restart is invalid style");
}
if (restart_flag_double && restart_every_double == 0) {
ivar_restart_double = input->variable->find(var_restart_double);
if (ivar_restart_double < 0)
error->all(FLERR,"Variable name for restart does not exist");
if (!input->variable->equalstyle(ivar_restart_double))
error->all(FLERR,"Variable for restart 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
memflag = 0/1 for printing out memory usage
------------------------------------------------------------------------- */
void Output::setup(int memflag)
{
bigint ntimestep = update->ntimestep;
// perform dump at start of run only if:
// current timestep is multiple of every and last dump not >= this step
// this is first run after dump created and firstflag is set
// note that variable freq will not write unless triggered by firstflag
// set next_dump to multiple of every or variable value
// set next_dump_any to smallest next_dump
// wrap dumps that invoke computes and variable eval with clear/add
// if dump not written now, use addstep_compute_all() since don't know
// what computes the dump write would invoke
// if no dumps, set next_dump_any to last+1 so will not influence next
int writeflag;
if (ndump && update->restrict_output == 0) {
for (int idump = 0; idump < ndump; idump++) {
if (dump[idump]->clearstep || every_dump[idump] == 0)
modify->clearstep_compute();
writeflag = 0;
if (every_dump[idump] && ntimestep % every_dump[idump] == 0 &&
- last_dump[idump] < ntimestep) writeflag = 1;
+ 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 {
bigint nextdump = static_cast<bigint>
(input->variable->compute_equal(ivar_dump[idump]));
if (nextdump <= ntimestep)
error->all(FLERR,"Dump every variable returned a bad timestep");
next_dump[idump] = nextdump;
}
if (dump[idump]->clearstep || every_dump[idump] == 0) {
if (writeflag) modify->addstep_compute(next_dump[idump]);
else modify->addstep_compute_all(next_dump[idump]);
}
if (idump) next_dump_any = MIN(next_dump_any,next_dump[idump]);
else next_dump_any = next_dump[0];
}
} else next_dump_any = update->laststep + 1;
// do not write restart files at start of run
// set next_restart values to multiple of every or variable value
// wrap variable eval with clear/add
// if no restarts, set next_restart to last+1 so will not influence next
if (restart_flag && update->restrict_output == 0) {
if (restart_flag_single) {
if (restart_every_single)
next_restart_single =
(ntimestep/restart_every_single)*restart_every_single +
restart_every_single;
else {
bigint nextrestart = static_cast<bigint>
(input->variable->compute_equal(ivar_restart_single));
if (nextrestart <= ntimestep)
error->all(FLERR,"Restart variable returned a bad timestep");
next_restart_single = nextrestart;
}
} else next_restart_single = update->laststep + 1;
if (restart_flag_double) {
if (restart_every_double)
next_restart_double =
(ntimestep/restart_every_double)*restart_every_double +
restart_every_double;
else {
bigint nextrestart = static_cast<bigint>
(input->variable->compute_equal(ivar_restart_double));
if (nextrestart <= ntimestep)
error->all(FLERR,"Restart variable returned a bad timestep");
next_restart_double = nextrestart;
}
} else next_restart_double = update->laststep + 1;
next_restart = MIN(next_restart_single,next_restart_double);
} else next_restart = update->laststep + 1;
// print memory usage unless being called between multiple runs
if (memflag) memory_usage();
// set next_thermo to multiple of every or variable eval if var defined
// insure thermo output on 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 (var_thermo) {
next_thermo = static_cast<bigint>
(input->variable->compute_equal(ivar_thermo));
if (next_thermo <= ntimestep)
error->all(FLERR,"Thermo every variable returned a bad timestep");
} else if (thermo_every) {
next_thermo = (ntimestep/thermo_every)*thermo_every + thermo_every;
next_thermo = MIN(next_thermo,update->laststep);
} else next_thermo = update->laststep;
modify->addstep_compute(next_thermo);
// next = next timestep any output will be done
next = MIN(next_dump_any,next_restart);
next = MIN(next,next_thermo);
}
/* ----------------------------------------------------------------------
perform all output for this timestep
only perform output if next matches current step and last output doesn't
do dump/restart before thermo so thermo CPU time will include them
------------------------------------------------------------------------- */
void Output::write(bigint ntimestep)
{
// next_dump does not force output on last step of run
// wrap dumps that invoke computes or eval of variable with clear/add
// download data from GPU if necessary
if (next_dump_any == ntimestep) {
if (lmp->cuda && !lmp->cuda->oncpu) lmp->cuda->downloadAll();
for (int idump = 0; idump < ndump; idump++) {
- if (next_dump[idump] == ntimestep && last_dump[idump] < ntimestep) {
+ if (next_dump[idump] == ntimestep) {
if (dump[idump]->clearstep || every_dump[idump] == 0)
modify->clearstep_compute();
- dump[idump]->write();
- last_dump[idump] = ntimestep;
+ if (last_dump[idump] != ntimestep) {
+ dump[idump]->write();
+ last_dump[idump] = ntimestep;
+ }
if (every_dump[idump]) next_dump[idump] += every_dump[idump];
else {
bigint nextdump = static_cast<bigint>
(input->variable->compute_equal(ivar_dump[idump]));
if (nextdump <= ntimestep)
error->all(FLERR,"Dump every variable returned a bad timestep");
next_dump[idump] = nextdump;
}
if (dump[idump]->clearstep || every_dump[idump] == 0)
modify->addstep_compute(next_dump[idump]);
}
if (idump) next_dump_any = MIN(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
// download data from GPU if necessary
// eval of variable may invoke computes so wrap with clear/add
- if (next_restart == ntimestep && last_restart != ntimestep) {
+ if (next_restart == ntimestep) {
if (lmp->cuda && !lmp->cuda->oncpu) lmp->cuda->downloadAll();
if (next_restart_single == ntimestep) {
char *file = new char[strlen(restart1) + 16];
char *ptr = strchr(restart1,'*');
*ptr = '\0';
sprintf(file,"%s" BIGINT_FORMAT "%s",restart1,ntimestep,ptr+1);
*ptr = '*';
- restart->write(file);
+ if (last_restart != ntimestep) restart->write(file);
delete [] file;
if (restart_every_single) next_restart_single += restart_every_single;
else {
modify->clearstep_compute();
bigint nextrestart = static_cast<bigint>
(input->variable->compute_equal(ivar_restart_single));
if (nextrestart <= ntimestep)
error->all(FLERR,"Restart variable returned a bad timestep");
next_restart_single = nextrestart;
modify->addstep_compute(next_restart_single);
}
}
if (next_restart_double == ntimestep) {
- if (restart_toggle == 0) {
- restart->write(restart2a);
- restart_toggle = 1;
- } else {
- restart->write(restart2b);
- restart_toggle = 0;
+ if (last_restart != ntimestep) {
+ if (restart_toggle == 0) {
+ restart->write(restart2a);
+ restart_toggle = 1;
+ } else {
+ restart->write(restart2b);
+ restart_toggle = 0;
+ }
}
if (restart_every_double) next_restart_double += restart_every_double;
else {
modify->clearstep_compute();
bigint nextrestart = static_cast<bigint>
(input->variable->compute_equal(ivar_restart_double));
if (nextrestart <= ntimestep)
error->all(FLERR,"Restart variable returned a bad timestep");
next_restart_double = nextrestart;
modify->addstep_compute(next_restart_double);
}
}
last_restart = ntimestep;
next_restart = MIN(next_restart_single,next_restart_double);
}
// 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) {
+ if (next_thermo == ntimestep) {
modify->clearstep_compute();
- thermo->compute(1);
+ if (last_thermo != ntimestep) thermo->compute(1);
last_thermo = ntimestep;
if (var_thermo) {
next_thermo = static_cast<bigint>
(input->variable->compute_equal(ivar_thermo));
if (next_thermo <= ntimestep)
error->all(FLERR,"Thermo every variable returned a bad timestep");
} else if (thermo_every) next_thermo += thermo_every;
else next_thermo = update->laststep;
next_thermo = MIN(next_thermo,update->laststep);
modify->addstep_compute(next_thermo);
}
// next = next timestep any output will be done
next = MIN(next_dump_any,next_restart);
next = MIN(next,next_thermo);
}
/* ----------------------------------------------------------------------
force a snapshot to be written for all dumps
+ called from PRD and TAD
------------------------------------------------------------------------- */
void Output::write_dump(bigint ntimestep)
{
for (int idump = 0; idump < ndump; idump++) {
dump[idump]->write();
last_dump[idump] = ntimestep;
}
}
/* ----------------------------------------------------------------------
force restart file(s) to be written
called from PRD and TAD
------------------------------------------------------------------------- */
void Output::write_restart(bigint ntimestep)
{
if (restart_flag_single) {
char *file = new char[strlen(restart1) + 16];
char *ptr = strchr(restart1,'*');
*ptr = '\0';
sprintf(file,"%s" BIGINT_FORMAT "%s",restart1,ntimestep,ptr+1);
*ptr = '*';
restart->write(file);
delete [] file;
}
if (restart_flag_double) {
if (restart_toggle == 0) {
restart->write(restart2a);
restart_toggle = 1;
} else {
restart->write(restart2b);
restart_toggle = 0;
}
}
last_restart = ntimestep;
}
/* ----------------------------------------------------------------------
timestep is being changed, called by update->reset_timestep()
reset next timestep values for dumps, restart, thermo output
reset to smallest value >= new timestep
if next timestep set by varaible evaluation,
eval for ntimestep-1, so current ntimestep can be returned if needed
no guarantee that variable can be evaluated for ntimestep-1
if it depends on computes, but live with that rare case for now
------------------------------------------------------------------------- */
void Output::reset_timestep(bigint ntimestep)
{
for (int idump = 0; idump < ndump; idump++) {
if (every_dump[idump]) {
next_dump[idump] = (ntimestep/every_dump[idump])*every_dump[idump];
if (next_dump[idump] < ntimestep) next_dump[idump] += every_dump[idump];
} else {
modify->clearstep_compute();
update->ntimestep--;
bigint nextdump = static_cast<bigint>
(input->variable->compute_equal(ivar_dump[idump]));
if (nextdump < ntimestep)
error->all(FLERR,"Dump every variable returned a bad timestep");
update->ntimestep++;
next_dump[idump] = nextdump;
modify->addstep_compute(next_dump[idump]);
}
if (idump) next_dump_any = MIN(next_dump_any,next_dump[idump]);
else next_dump_any = next_dump[0];
}
if (restart_flag_single) {
if (restart_every_single) {
next_restart_single =
(ntimestep/restart_every_single)*restart_every_single;
if (next_restart_single < ntimestep)
next_restart_single += restart_every_single;
} else {
modify->clearstep_compute();
update->ntimestep--;
bigint nextrestart = static_cast<bigint>
(input->variable->compute_equal(ivar_restart_single));
if (nextrestart < ntimestep)
error->all(FLERR,"Restart variable returned a bad timestep");
update->ntimestep++;
next_restart_single = nextrestart;
modify->addstep_compute(next_restart_single);
}
} else next_restart_single = update->laststep + 1;
if (restart_flag_double) {
if (restart_every_double) {
next_restart_double =
(ntimestep/restart_every_double)*restart_every_double;
if (next_restart_double < ntimestep)
next_restart_double += restart_every_double;
} else {
modify->clearstep_compute();
update->ntimestep--;
bigint nextrestart = static_cast<bigint>
(input->variable->compute_equal(ivar_restart_double));
if (nextrestart < ntimestep)
error->all(FLERR,"Restart variable returned a bad timestep");
update->ntimestep++;
next_restart_double = nextrestart;
modify->addstep_compute(next_restart_double);
}
} else next_restart_double = update->laststep + 1;
next_restart = MIN(next_restart_single,next_restart_double);
if (var_thermo) {
modify->clearstep_compute();
update->ntimestep--;
next_thermo = static_cast<bigint>
(input->variable->compute_equal(ivar_thermo));
if (next_thermo < ntimestep)
error->all(FLERR,"Thermo every variable returned a bad timestep");
update->ntimestep++;
next_thermo = MIN(next_thermo,update->laststep);
modify->addstep_compute(next_thermo);
} else if (thermo_every) {
next_thermo = (ntimestep/thermo_every)*thermo_every;
if (next_thermo < ntimestep) next_thermo += thermo_every;
next_thermo = MIN(next_thermo,update->laststep);
} else next_thermo = update->laststep;
next = MIN(next_dump_any,next_restart);
next = MIN(next,next_thermo);
}
/* ----------------------------------------------------------------------
add a Dump to list of Dumps
------------------------------------------------------------------------- */
void Output::add_dump(int narg, char **arg)
{
if (narg < 5) error->all(FLERR,"Illegal dump command");
// error checks
for (int idump = 0; idump < ndump; idump++)
if (strcmp(arg[0],dump[idump]->id) == 0)
error->all(FLERR,"Reuse of dump ID");
int igroup = group->find(arg[1]);
if (igroup == -1) error->all(FLERR,"Could not find dump group ID");
if (atoi(arg[3]) <= 0) error->all(FLERR,"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");
memory->grow(every_dump,max_dump,"output:every_dump");
memory->grow(next_dump,max_dump,"output:next_dump");
memory->grow(last_dump,max_dump,"output:last_dump");
var_dump = (char **)
memory->srealloc(var_dump,max_dump*sizeof(char *),"output:var_dump");
memory->grow(ivar_dump,max_dump,"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(FLERR,"Invalid dump style");
every_dump[ndump] = atoi(arg[3]);
if (every_dump[ndump] <= 0) error->all(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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--;
}
/* ----------------------------------------------------------------------
set thermo output frequency from input script
------------------------------------------------------------------------- */
void Output::set_thermo(int narg, char **arg)
{
if (narg != 1) error->all(FLERR,"Illegal thermo command");
if (strstr(arg[0],"v_") == arg[0]) {
delete [] var_thermo;
int n = strlen(&arg[0][2]) + 1;
var_thermo = new char[n];
strcpy(var_thermo,&arg[0][2]);
} else {
thermo_every = atoi(arg[0]);
if (thermo_every < 0) error->all(FLERR,"Illegal thermo command");
}
}
/* ----------------------------------------------------------------------
new Thermo style
------------------------------------------------------------------------- */
void Output::create_thermo(int narg, char **arg)
{
if (narg < 1) error->all(FLERR,"Illegal thermo_style command");
// don't allow this so that dipole style can safely allocate inertia vector
if (domain->box_exist == 0)
error->all(FLERR,"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(FLERR,"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 for single or double output files
if only one filename and it contains no "*", then append ".*"
------------------------------------------------------------------------- */
void Output::create_restart(int narg, char **arg)
{
if (narg < 1) error->all(FLERR,"Illegal restart command");
int every = 0;
int varflag = 0;
if (strstr(arg[0],"v_") == arg[0]) varflag = 1;
else every = atoi(arg[0]);
if (!varflag && every == 0) {
if (narg != 1) error->all(FLERR,"Illegal restart command");
restart_flag = restart_flag_single = restart_flag_double = 0;
last_restart = -1;
delete restart;
restart = NULL;
delete [] restart1;
delete [] restart2a;
delete [] restart2b;
restart1 = restart2a = restart2b = NULL;
delete [] var_restart_single;
delete [] var_restart_double;
var_restart_single = var_restart_double = NULL;
return;
}
if (narg != 2 && narg != 3) error->all(FLERR,"Illegal restart command");
if (narg == 2) {
restart_flag = restart_flag_single = 1;
if (varflag) {
delete [] var_restart_single;
int n = strlen(&arg[0][2]) + 1;
var_restart_single = new char[n];
strcpy(var_restart_single,&arg[0][2]);
restart_every_single = 0;
} else restart_every_single = every;
int n = strlen(arg[1]) + 3;
restart1 = new char[n];
strcpy(restart1,arg[1]);
if (strchr(restart1,'*') == NULL) strcat(restart1,".*");
}
if (narg == 3) {
restart_flag = restart_flag_double = 1;
if (varflag) {
delete [] var_restart_double;
int n = strlen(&arg[0][2]) + 1;
var_restart_double = new char[n];
strcpy(var_restart_double,&arg[0][2]);
restart_every_double = 0;
} else restart_every_double = every;
restart_toggle = 0;
int n = strlen(arg[1]) + 3;
restart2a = new char[n];
strcpy(restart2a,arg[1]);
n = strlen(arg[2]) + 1;
restart2b = new char[n];
strcpy(restart2b,arg[2]);
}
if (restart == NULL) restart = new WriteRestart(lmp);
}
/* ----------------------------------------------------------------------
sum and print memory usage
result is only memory on proc 0, not averaged across procs
------------------------------------------------------------------------- */
void Output::memory_usage()
{
bigint bytes = 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++) 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 c77a24e24..d994240d5 100644
--- a/src/output.h
+++ b/src/output.h
@@ -1,153 +1,165 @@
/* -*- c++ -*- ----------------------------------------------------------
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"
namespace LAMMPS_NS {
class Output : protected Pointers {
public:
bigint next; // next timestep for any kind of output
bigint next_thermo; // next timestep for thermo output
int thermo_every; // output freq for thermo, 0 if first/last only
bigint last_thermo; // last timestep thermo was output
char *var_thermo; // variable name for thermo freq, NULL if every
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
bigint next_dump_any; // next timestep for any Dump
int *every_dump; // write freq for each Dump, 0 if var
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 restart_flag; // 1 if any restart files are written
int restart_flag_single; // 1 if single restart files are written
int restart_flag_double; // 1 if double restart files are written
bigint next_restart; // next timestep to write any restart file
bigint next_restart_single; // next timestep to write a single restart file
bigint next_restart_double; // next timestep to write a double restart file
int restart_every_single; // single restart file write freq, 0 if var
int restart_every_double; // double restart file write freq, 0 if var
bigint last_restart; // last timestep any restart file was output
int restart_toggle; // 0 if use restart2a as prefix, 1 if restart2b
char *var_restart_single; // variable name for single restart freq
char *var_restart_double; // variable name for double restart freq
int ivar_restart_single; // index of var_restart_single
int ivar_restart_double; // index of var_restart_double
char *restart1; // name single restart file
char *restart2a,*restart2b; // names of double restart files
class WriteRestart *restart; // class for writing restart files
Output(class LAMMPS *);
~Output();
void init();
void setup(int memflag = 1); // initial output before run/min
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 reset_timestep(bigint); // reset next timestep for all output
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 set_thermo(int, char **); // set thermo output freqquency
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
/* ERROR/WARNING messages:
E: Variable name for thermo every does not exist
Self-explanatory.
E: Variable for thermo every is invalid style
Only equal-style variables can be used.
E: Variable name for dump every does not exist
Self-explanatory.
E: Variable for dump every is invalid style
Only equal-style variables can be used.
+E: Variable name for restart does not exist
+
+Self-explanatory.
+
+E: Variable for restart is invalid style
+
+Only equal-style variables can be used.
+
E: Dump every variable returned a bad timestep
The variable must return a timestep greater than the current timestep.
+E: Restart variable returned a bad timestep
+
+The variable must return a timestep greater than the current timestep.
+
E: Thermo every variable returned a bad timestep
The variable must return a timestep greater than the current timestep.
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Reuse of dump ID
A dump ID cannot be used twice.
E: Could not find dump group ID
A group ID used in the dump command does not exist.
E: Invalid dump frequency
Dump frequency must be 1 or greater.
E: Invalid dump style
The choice of dump style is unknown.
E: Cound not find dump_modify ID
Self-explanatory.
E: Could not find undump ID
A dump ID used in the undump command does not exist.
E: Thermo_style command before simulation box is defined
The thermo_style command cannot be used before a read_data,
read_restart, or create_box command.
W: New thermo_style command, previous thermo_modify settings will be lost
If a thermo_style command is used after a thermo_modify command, the
settings changed by the thermo_modify command will be reset to their
default values. This is because the thermo_modify commmand acts on
the currently defined thermo style, and a thermo_style command creates
a new style.
*/
diff --git a/src/pair.h b/src/pair.h
index 2c67e9bdb..e854041d2 100644
--- a/src/pair.h
+++ b/src/pair.h
@@ -1,262 +1,263 @@
/* -*- c++ -*- ----------------------------------------------------------
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_PAIR_H
#define LMP_PAIR_H
#include "pointers.h"
namespace LAMMPS_NS {
class Pair : protected Pointers {
friend class AngleSDK;
friend class AngleSDKOMP;
friend class BondQuartic;
friend class BondQuarticOMP;
friend class DihedralCharmm;
friend class DihedralCharmmOMP;
friend class FixGPU;
friend class FixOMP;
friend class ThrOMP;
public:
double eng_vdwl,eng_coul; // accumulated energies
double virial[6]; // accumulated virial
double *eatom,**vatom; // accumulated per-atom energy/virial
double cutforce; // max cutoff for all atom pairs
double **cutsq; // cutoff sq for each atom pair
int **setflag; // 0/1 = whether each i,j has been set
int comm_forward; // size of forward communication (0 if none)
int comm_reverse; // size of reverse communication (0 if none)
int comm_reverse_off; // size of reverse comm even if newton off
int single_enable; // 1 if single() routine exists
int restartinfo; // 1 if pair style writes restart info
int respa_enable; // 1 if inner/middle/outer rRESPA routines
int one_coeff; // 1 if allows only one coeff * * call
int no_virial_fdotr_compute; // 1 if does not invoke virial_fdotr_compute()
int ghostneigh; // 1 if pair style needs neighbors of ghosts
double **cutghost; // cutoff for each ghost pair
int tail_flag; // pair_modify flag for LJ tail correction
double etail,ptail; // energy/pressure tail corrections
double etail_ij,ptail_ij;
int evflag; // energy,virial settings
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
+
+ int ncoultablebits; // size of Coulomb table
int nextra; // # of extra quantities pair style calculates
double *pvector; // vector of extra pair quantities
int single_extra; // number of extra single values calculated
double *svector; // vector of extra single quantities
class NeighList *list; // standard neighbor list used by most pairs
class NeighList *listhalf; // half list used by some pairs
class NeighList *listfull; // full list used by some pairs
class NeighList *listgranhistory; // granular history list used by some pairs
class NeighList *listinner; // rRESPA lists used by some pairs
class NeighList *listmiddle;
class NeighList *listouter;
int compute_flag; // 0 if skip compute()
Pair(class LAMMPS *);
virtual ~Pair();
// top-level Pair methods
void init();
void reinit();
double mix_energy(double, double, double, double);
double mix_distance(double, double);
void write_file(int, char **);
void init_bitmap(double, double, int, int &, int &, int &, int &);
virtual void modify_params(int, char **);
void compute_dummy(int, int);
// need to be public, so can be called by pair_style reaxc
void v_tally(int, double *, double *);
void ev_tally(int, int, int, int, double, double, double,
double, double, double);
void ev_tally3(int, int, int, double, double,
double *, double *, double *, double *);
void v_tally3(int, int, int, double *, double *, double *, double *);
void v_tally4(int, int, int, int, double *, double *, double *,
double *, double *, double *);
void ev_tally_xyz(int, int, int, int, double, double,
double, double, double, double, double, double);
// general child-class methods
virtual void compute(int, int) = 0;
virtual void compute_inner() {}
virtual void compute_middle() {}
virtual void compute_outer(int, int) {}
virtual double single(int, int, int, int,
double, double, double, double &) {return 0.0;}
virtual void settings(int, char **) = 0;
virtual void coeff(int, char **) = 0;
virtual void init_style();
virtual void init_list(int, class NeighList *);
virtual double init_one(int, int) {return 0.0;}
virtual void write_restart(FILE *) {}
virtual void read_restart(FILE *) {}
virtual void write_restart_settings(FILE *) {}
virtual void read_restart_settings(FILE *) {}
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 memory_usage();
// specific child-class methods for certain Pair styles
virtual void *extract(const char *, int &) {return NULL;}
virtual void swap_eam(double *, double **) {}
virtual void reset_dt() {}
virtual void min_xf_pointers(int, double **, double **) {}
virtual void min_xf_get(int) {}
virtual void min_x_set(int) {}
protected:
enum{GEOMETRIC,ARITHMETIC,SIXTHPOWER}; // mixing options
int allocated; // 0/1 = whether arrays are allocated
int suffix_flag; // suffix compatibility flag
// pair_modify settings
int offset_flag,mix_flag; // flags for offset and mixing
- int ncoultablebits; // size of Coulomb table
double tabinner; // inner cutoff for Coulomb table
// custom data type for accessing Coulomb tables
typedef union {int i; float f;} union_int_float_t;
double THIRD;
int vflag_fdotr;
int maxeatom,maxvatom;
virtual void ev_setup(int, int);
void ev_unset();
void ev_tally_full(int, double, double, double, double, double, double);
void ev_tally_xyz_full(int, double, double,
double, double, double, double, double, double);
void ev_tally4(int, int, int, int, double,
double *, double *, double *, double *, double *, double *);
void ev_tally_list(int, int *, double, double *);
void v_tally2(int, int, double, double *);
void v_tally_tensor(int, int, int, int,
double, double, double, double, double, double);
void virial_fdotr_compute();
inline int sbmask(int j) {
return j >> SBBITS & 3;
}
};
}
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Too many total bits for bitmapped lookup table
Table size specified via pair_modify command is too large. Note that
a value of N generates a 2^N size table.
E: Cannot have both pair_modify shift and tail set to yes
These 2 options are contradictory.
E: Cannot use pair tail corrections with 2d simulations
The correction factors are only currently defined for 3d systems.
W: Using pair tail corrections with nonperiodic system
This is probably a bogus thing to do, since tail corrections are
computed by integrating the density of a periodic system out to
infinity.
E: All pair coeffs are not set
All pair coefficients must be set in the data file or by the
pair_coeff command before running a simulation.
E: Pair style does not support pair_write
The pair style does not have a single() function, so it can
not be invoked by pair write.
E: Invalid atom types in pair_write command
Atom types must range from 1 to Ntypes inclusive.
E: Invalid style in pair_write command
Self-explanatory. Check the input script.
E: Invalid cutoffs in pair_write command
Inner cutoff must be larger than 0.0 and less than outer cutoff.
E: Cannot open pair_write file
The specified output file for pair energies and forces cannot be
opened. Check that the path and name are correct.
E: Bitmapped lookup tables require int/float be same size
Cannot use pair tables on this machine, because of word sizes. Use
the pair_modify command with table 0 instead.
W: Table inner cutoff >= outer cutoff
You specified an inner cutoff for a Coulombic table that is longer
than the global cutoff. Probably not what you wanted.
E: Too many exponent bits for lookup table
Table size specified via pair_modify command does not work with your
machine's floating point representation.
E: Too many mantissa bits for lookup table
Table size specified via pair_modify command does not work with your
machine's floating point representation.
E: Too few bits for lookup table
Table size specified via pair_modify command does not work with your
machine's floating point representation.
*/
diff --git a/src/read_data.cpp b/src/read_data.cpp
index 23c423c70..a691eb562 100644
--- a/src/read_data.cpp
+++ b/src/read_data.cpp
@@ -1,1562 +1,1562 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "string.h"
#include "stdlib.h"
#include "ctype.h"
#include "read_data.h"
#include "atom.h"
#include "atom_vec.h"
#include "atom_vec_ellipsoid.h"
#include "atom_vec_line.h"
#include "atom_vec_tri.h"
#include "comm.h"
#include "update.h"
#include "modify.h"
#include "fix.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
// customize for new sections
#define NSECTIONS 23 // change when add to header::section_keywords
/* ---------------------------------------------------------------------- */
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;
// customize for new sections
// pointers to atom styles that store extra info
nellipsoids = 0;
avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid");
nlines = 0;
avec_line = (AtomVecLine *) atom->style_match("line");
ntris = 0;
avec_tri = (AtomVecTri *) atom->style_match("tri");
}
/* ---------------------------------------------------------------------- */
ReadData::~ReadData()
{
delete [] line;
delete [] keyword;
delete [] buffer;
memory->sfree(arg);
}
/* ---------------------------------------------------------------------- */
void ReadData::command(int narg, char **arg)
{
if (narg < 1) error->all(FLERR,"Illegal read_data command");
if (domain->box_exist)
error->all(FLERR,"Cannot read_data after simulation box is defined");
if (domain->dimension == 2 && domain->zperiodic == 0)
error->all(FLERR,"Cannot run 2d simulation with nonperiodic Z dimension");
// fixes that process data file info
nfix = 0;
fix_index = NULL;
fix_header = NULL;
fix_section = NULL;
int iarg = 1;
while (iarg < narg) {
if (strcmp(arg[iarg],"fix") == 0) {
if (iarg+4 > narg)
error->all(FLERR,"Illegal read_data command");
memory->grow(fix_index,nfix+1,"read_data:fix_index");
fix_header = (char **)
memory->srealloc(fix_header,(nfix+1)*sizeof(char *),
"read_data:fix_header");
fix_section = (char **)
memory->srealloc(fix_section,(nfix+1)*sizeof(char *),
"read_data:fix_section");
fix_index[nfix] = modify->find_fix(arg[iarg+1]);
if (fix_index[nfix] < 0)
- error->all(FLERR,"Fix ID for Read_data does not exist");
+ error->all(FLERR,"Fix ID for read_data does not exist");
int n = strlen(arg[iarg+2]) + 1;
fix_header[nfix] = new char[n];
strcpy(fix_header[nfix],arg[iarg+2]);
n = strlen(arg[iarg+3]) + 1;
fix_section[nfix] = new char[n];
strcpy(fix_section[nfix],arg[iarg+3]);
nfix++;
iarg += 4;
} else error->all(FLERR,"Illegal read_data command");
}
// scan data file to determine max topology needed per atom
// allocate initial topology arrays
if (atom->molecular) {
if (me == 0) {
if (screen) fprintf(screen,"Scanning data file ...\n");
open(arg[0]);
header(0);
scan(atom->bond_per_atom,atom->angle_per_atom,
atom->dihedral_per_atom,atom->improper_per_atom);
if (compressed) pclose(fp);
else fclose(fp);
atom->bond_per_atom += atom->extra_bond_per_atom;
}
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_proc_grid();
domain->set_local_box();
// customize for new sections
// read rest of file in free format
int atomflag = 0;
while (strlen(keyword)) {
// allow special fixes first chance to match and process the section
// if fix matches, continue to next section
if (nfix) {
for (n = 0; n < nfix; n++)
if (strstr(line,fix_section[n])) {
bigint nlines =
modify->fix[fix_index[n]]->read_data_skip_lines(keyword);
fix(n,keyword,nlines);
parse_keyword(0,1);
break;
}
if (n < nfix) continue;
}
if (strcmp(keyword,"Atoms") == 0) {
atoms();
atomflag = 1;
} else if (strcmp(keyword,"Velocities") == 0) {
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Velocities");
velocities();
} else if (strcmp(keyword,"Ellipsoids") == 0) {
if (!avec_ellipsoid)
error->all(FLERR,"Invalid data file section: Ellipsoids");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Ellipsoids");
bonus(nellipsoids,(AtomVec *) avec_ellipsoid,"ellipsoids");
} else if (strcmp(keyword,"Lines") == 0) {
if (!avec_line)
error->all(FLERR,"Invalid data file section: Lines");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Lines");
bonus(nlines,(AtomVec *) avec_line,"lines");
} else if (strcmp(keyword,"Triangles") == 0) {
if (!avec_tri)
error->all(FLERR,"Invalid data file section: Triangles");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Triangles");
bonus(ntris,(AtomVec *) avec_tri,"triangles");
} else if (strcmp(keyword,"Bonds") == 0) {
if (atom->avec->bonds_allow == 0)
error->all(FLERR,"Invalid data file section: Bonds");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Bonds");
bonds();
} else if (strcmp(keyword,"Angles") == 0) {
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Invalid data file section: Angles");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Angles");
angles();
} else if (strcmp(keyword,"Dihedrals") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: Dihedrals");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Dihedrals");
dihedrals();
} else if (strcmp(keyword,"Impropers") == 0) {
if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Invalid data file section: Impropers");
if (atomflag == 0) error->all(FLERR,"Must read Atoms before Impropers");
impropers();
} else if (strcmp(keyword,"Masses") == 0) {
mass();
} else if (strcmp(keyword,"Pair Coeffs") == 0) {
if (force->pair == NULL)
error->all(FLERR,"Must define pair_style before Pair Coeffs");
paircoeffs();
} else if (strcmp(keyword,"Bond Coeffs") == 0) {
if (atom->avec->bonds_allow == 0)
error->all(FLERR,"Invalid data file section: Bond Coeffs");
if (force->bond == NULL)
error->all(FLERR,"Must define bond_style before Bond Coeffs");
bondcoeffs();
} else if (strcmp(keyword,"Angle Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Invalid data file section: Angle Coeffs");
if (force->angle == NULL)
error->all(FLERR,"Must define angle_style before Angle Coeffs");
anglecoeffs(0);
} else if (strcmp(keyword,"Dihedral Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: Dihedral Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,"Must define dihedral_style before Dihedral Coeffs");
dihedralcoeffs(0);
} else if (strcmp(keyword,"Improper Coeffs") == 0) {
if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Invalid data file section: Improper Coeffs");
if (force->improper == NULL)
error->all(FLERR,"Must define improper_style before Improper Coeffs");
impropercoeffs(0);
} else if (strcmp(keyword,"BondBond Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Invalid data file section: BondBond Coeffs");
if (force->angle == NULL)
error->all(FLERR,"Must define angle_style before BondBond Coeffs");
anglecoeffs(1);
} else if (strcmp(keyword,"BondAngle Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Invalid data file section: BondAngle Coeffs");
if (force->angle == NULL)
error->all(FLERR,"Must define angle_style before BondAngle Coeffs");
anglecoeffs(2);
} else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before "
"MiddleBondTorsion Coeffs");
dihedralcoeffs(1);
} else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before EndBondTorsion Coeffs");
dihedralcoeffs(2);
} else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before AngleTorsion Coeffs");
dihedralcoeffs(3);
} else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,
"Must define dihedral_style before "
"AngleAngleTorsion Coeffs");
dihedralcoeffs(4);
} else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Invalid data file section: BondBond13 Coeffs");
if (force->dihedral == NULL)
error->all(FLERR,"Must define dihedral_style before BondBond13 Coeffs");
dihedralcoeffs(5);
} else if (strcmp(keyword,"AngleAngle Coeffs") == 0) {
if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Invalid data file section: AngleAngle Coeffs");
if (force->improper == NULL)
error->all(FLERR,"Must define improper_style before AngleAngle Coeffs");
impropercoeffs(1);
} else {
char str[128];
sprintf(str,"Unknown identifier in data file: %s",keyword);
error->all(FLERR,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(FLERR,"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;
// customize for new sections
const char *section_keywords[NSECTIONS] =
{"Atoms","Velocities","Ellipsoids","Lines","Triangles",
"Bonds","Angles","Dihedrals","Impropers",
"Masses","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(FLERR,"Unexpected end of data file");
}
// customize for new header lines
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;
// allow special fixes first chance to match and process the line
// if fix matches, continue to next header line
if (nfix) {
for (n = 0; n < nfix; n++)
if (strstr(line,fix_header[n])) {
modify->fix[fix_index[n]]->read_data_header(line);
break;
}
if (n < nfix) continue;
}
// search line for header keyword and set corresponding variable
if (strstr(line,"atoms")) sscanf(line,BIGINT_FORMAT,&atom->natoms);
// check for these first
// otherwise "triangles" will be matched as "angles"
else if (strstr(line,"ellipsoids")) {
if (!avec_ellipsoid && me == 0)
error->one(FLERR,"No ellipsoids allowed with this atom style");
sscanf(line,BIGINT_FORMAT,&nellipsoids);
} else if (strstr(line,"lines")) {
if (!avec_line && me == 0)
error->one(FLERR,"No lines allowed with this atom style");
sscanf(line,BIGINT_FORMAT,&nlines);
} else if (strstr(line,"triangles")) {
if (!avec_tri && me == 0)
error->one(FLERR,"No triangles allowed with this atom style");
sscanf(line,BIGINT_FORMAT,&ntris);
}
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 (me == 0) error->one(FLERR,"System in data file is too big");
}
// check that exiting string is a valid section keyword
parse_keyword(1,flag);
for (n = 0; n < NSECTIONS; n++)
if (strcmp(keyword,section_keywords[n]) == 0) break;
if (n == NSECTIONS && me == 0) {
char str[128];
sprintf(str,"Unknown identifier in data file: %s",keyword);
error->one(FLERR,str);
}
// error check on consistency of header values
if ((atom->nbonds || atom->nbondtypes) &&
atom->avec->bonds_allow == 0 && me == 0)
error->one(FLERR,"No bonds allowed with this atom style");
if ((atom->nangles || atom->nangletypes) &&
atom->avec->angles_allow == 0 && me == 0)
error->one(FLERR,"No angles allowed with this atom style");
if ((atom->ndihedrals || atom->ndihedraltypes) &&
atom->avec->dihedrals_allow == 0 && me == 0)
error->one(FLERR,"No dihedrals allowed with this atom style");
if ((atom->nimpropers || atom->nimpropertypes) &&
atom->avec->impropers_allow == 0 && me == 0)
error->one(FLERR,"No impropers allowed with this atom style");
if (atom->nbonds > 0 && atom->nbondtypes <= 0 && me == 0)
error->one(FLERR,"Bonds defined but no bond types");
if (atom->nangles > 0 && atom->nangletypes <= 0 && me == 0)
error->one(FLERR,"Angles defined but no angle types");
if (atom->ndihedrals > 0 && atom->ndihedraltypes <= 0 && me == 0)
error->one(FLERR,"Dihedrals defined but no dihedral types");
if (atom->nimpropers > 0 && atom->nimpropertypes <= 0 && me == 0)
error->one(FLERR,"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(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
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_LMP_BIGINT,MPI_SUM,world);
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " atoms\n",natoms);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms);
}
if (natoms != atom->natoms)
error->all(FLERR,"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(FLERR,"Invalid atom ID in Atoms section of data file");
flag = 0;
for (int i = 0; i < nlocal; i++)
if (tag[i] > 0) flag = 1;
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world);
if (flag_all == 0) atom->tag_enable = 0;
if (atom->tag_enable) {
flag = 0;
for (int i = 0; i < nlocal; i++)
if (tag[i] == 0) flag = 1;
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
if (flag_all)
error->all(FLERR,"Invalid atom ID in Atoms section of data file");
}
// 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(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
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," " BIGINT_FORMAT " velocities\n",natoms);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " velocities\n",natoms);
}
}
/* ----------------------------------------------------------------------
read all bonus data
to find atoms, must build atom map if not a molecular system
------------------------------------------------------------------------- */
void ReadData::bonus(bigint nbonus, AtomVec *ptr, const char *type)
{
int i,m,nchunk;
int mapflag = 0;
if (atom->map_style == 0) {
mapflag = 1;
atom->map_style = 1;
atom->map_init();
atom->map_set();
}
bigint nread = 0;
bigint natoms = nbonus;
while (nread < natoms) {
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(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
atom->data_bonus(nchunk,buffer,ptr);
nread += nchunk;
}
if (mapflag) {
atom->map_delete();
atom->map_style = 0;
}
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " %s\n",natoms,type);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " %s\n",natoms,type);
}
}
/* ---------------------------------------------------------------------- */
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(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
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_LMP_BIGINT,MPI_SUM,world);
int factor = 1;
if (!force->newton_bond) factor = 2;
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " bonds\n",sum/factor);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " bonds\n",sum/factor);
}
if (sum != factor*atom->nbonds)
error->all(FLERR,"Bonds assigned incorrectly");
}
/* ---------------------------------------------------------------------- */
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(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
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_LMP_BIGINT,MPI_SUM,world);
int factor = 1;
if (!force->newton_bond) factor = 3;
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " angles\n",sum/factor);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " angles\n",sum/factor);
}
if (sum != factor*atom->nangles)
error->all(FLERR,"Angles assigned incorrectly");
}
/* ---------------------------------------------------------------------- */
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(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
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_LMP_BIGINT,MPI_SUM,world);
int factor = 1;
if (!force->newton_bond) factor = 4;
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " dihedrals\n",sum/factor);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " dihedrals\n",sum/factor);
}
if (sum != factor*atom->ndihedrals)
error->all(FLERR,"Dihedrals assigned incorrectly");
}
/* ---------------------------------------------------------------------- */
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(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
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_LMP_BIGINT,MPI_SUM,world);
int factor = 1;
if (!force->newton_bond) factor = 4;
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " impropers\n",sum/factor);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " impropers\n",sum/factor);
}
if (sum != factor*atom->nimpropers)
error->all(FLERR,"Impropers assigned incorrectly");
}
/* ---------------------------------------------------------------------- */
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(FLERR,"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::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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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;
}
/* ----------------------------------------------------------------------
read fix section, pass lines to fix to process
n = index of fix
------------------------------------------------------------------------- */
void ReadData::fix(int ifix, char *line, bigint nlines)
{
int i,m,nchunk;
bigint nread = 0;
while (nread < nlines) {
if (nlines-nread > CHUNK) nchunk = CHUNK;
else nchunk = nlines-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(FLERR,"Unexpected end of data file");
m += strlen(&buffer[m]);
}
m++;
}
MPI_Bcast(&m,1,MPI_INT,0,world);
MPI_Bcast(buffer,m,MPI_CHAR,0,world);
modify->fix[ifix]->read_data_section(line,nchunk,buffer);
nread += nchunk;
}
}
/* ----------------------------------------------------------------------
proc 0 scans the data file for topology maximums
------------------------------------------------------------------------- */
void ReadData::scan(int &bond_per_atom, int &angle_per_atom,
int &dihedral_per_atom, int &improper_per_atom)
{
int i,tmp1,tmp2,atom1,atom2,atom3,atom4;
char *eof;
if (atom->natoms > MAXSMALLINT)
error->one(FLERR,"Molecular data file has too many atoms");
// customize for new sections
int natoms = static_cast<int> (atom->natoms);
bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0;
int ellipsoid_flag = 0;
int line_flag = 0;
int tri_flag = 0;
// customize for new sections
// allocate topology counting vector
// initially, array length = 1 to natoms
// will grow via reallocate() if atom IDs > natoms
int cmax = natoms + 1;
int *count;
memory->create(count,cmax,"read_data:count");
while (strlen(keyword)) {
// allow special fixes first chance to match and process the section
// if fix matches, continue to next section
if (nfix) {
for (i = 0; i < nfix; i++) {
printf("LINE SECTION %s %s\n",line,fix_section[i]);
if (strstr(line,fix_section[i])) {
int n = modify->fix[fix_index[i]]->read_data_skip_lines(keyword);
printf("NLINES SKIP %d\n",n);
skip_lines(n);
parse_keyword(0,0);
break;
}
}
if (i < nfix) continue;
}
if (strcmp(keyword,"Masses") == 0) skip_lines(atom->ntypes);
else if (strcmp(keyword,"Atoms") == 0) skip_lines(natoms);
else if (strcmp(keyword,"Velocities") == 0) skip_lines(natoms);
else if (strcmp(keyword,"Ellipsoids") == 0) {
if (!avec_ellipsoid)
error->one(FLERR,"Invalid data file section: Ellipsoids");
ellipsoid_flag = 1;
skip_lines(nellipsoids);
} else if (strcmp(keyword,"Lines") == 0) {
if (!avec_line) error->one(FLERR,"Invalid data file section: Lines");
line_flag = 1;
skip_lines(nlines);
} else if (strcmp(keyword,"Triangles") == 0) {
if (!avec_tri) error->one(FLERR,"Invalid data file section: Triangles");
tri_flag = 1;
skip_lines(ntris);
} else if (strcmp(keyword,"Pair Coeffs") == 0) {
if (force->pair == NULL)
error->one(FLERR,"Must define pair_style before Pair Coeffs");
skip_lines(atom->ntypes);
} else if (strcmp(keyword,"Bond Coeffs") == 0) {
if (atom->avec->bonds_allow == 0)
error->one(FLERR,"Invalid data file section: Bond Coeffs");
if (force->bond == NULL)
error->one(FLERR,"Must define bond_style before Bond Coeffs");
skip_lines(atom->nbondtypes);
} else if (strcmp(keyword,"Angle Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->one(FLERR,"Invalid data file section: Angle Coeffs");
if (force->angle == NULL)
error->one(FLERR,"Must define angle_style before Angle Coeffs");
skip_lines(atom->nangletypes);
} else if (strcmp(keyword,"Dihedral Coeffs") == 0) {
skip_lines(atom->ndihedraltypes);
if (atom->avec->dihedrals_allow == 0)
error->one(FLERR,"Invalid data file section: Dihedral Coeffs");
if (force->dihedral == NULL)
error->one(FLERR,"Must define dihedral_style before Dihedral Coeffs");
} else if (strcmp(keyword,"Improper Coeffs") == 0) {
if (atom->avec->impropers_allow == 0)
error->one(FLERR,"Invalid data file section: Improper Coeffs");
if (force->improper == NULL)
error->one(FLERR,"Must define improper_style before Improper Coeffs");
skip_lines(atom->nimpropertypes);
} else if (strcmp(keyword,"BondBond Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->one(FLERR,"Invalid data file section: BondBond Coeffs");
if (force->angle == NULL)
error->one(FLERR,"Must define angle_style before BondBond Coeffs");
skip_lines(atom->nangletypes);
} else if (strcmp(keyword,"BondAngle Coeffs") == 0) {
if (atom->avec->angles_allow == 0)
error->one(FLERR,"Invalid data file section: BondAngle Coeffs");
if (force->angle == NULL)
error->one(FLERR,"Must define angle_style before BondAngle Coeffs");
skip_lines(atom->nangletypes);
} else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->one(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs");
if (force->dihedral == NULL)
error->one(FLERR,
"Must define dihedral_style before "
"MiddleBondTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->one(FLERR,"Invalid data file section: EndBondTorsion Coeffs");
if (force->dihedral == NULL)
error->one(FLERR,
"Must define dihedral_style before EndBondTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->one(FLERR,"Invalid data file section: AngleTorsion Coeffs");
if (force->dihedral == NULL)
error->one(FLERR,
"Must define dihedral_style before AngleTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->one(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs");
if (force->dihedral == NULL)
error->one(FLERR,
"Must define dihedral_style before "
"AngleAngleTorsion Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"BondBond13 Coeffs") == 0) {
if (atom->avec->dihedrals_allow == 0)
error->one(FLERR,"Invalid data file section: BondBond13 Coeffs");
if (force->dihedral == NULL)
error->one(FLERR,"Must define dihedral_style before BondBond13 Coeffs");
skip_lines(atom->ndihedraltypes);
} else if (strcmp(keyword,"AngleAngle Coeffs") == 0) {
if (atom->avec->impropers_allow == 0)
error->one(FLERR,"Invalid data file section: AngleAngle Coeffs");
if (force->improper == NULL)
error->one(FLERR,"Must define improper_style before AngleAngle Coeffs");
skip_lines(atom->nimpropertypes);
} else if (strcmp(keyword,"Bonds") == 0) {
for (i = 1; i < cmax; i++) count[i] = 0;
if (force->newton_bond)
for (i = 0; i < atom->nbonds; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2);
if (atom1 >= cmax) cmax = reallocate(&count,cmax,atom1);
count[atom1]++;
}
else
for (i = 0; i < atom->nbonds; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2);
int amax = MAX(atom1,atom2);
if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
count[atom1]++;
count[atom2]++;
}
for (i = 1; i < cmax; i++) bond_per_atom = MAX(bond_per_atom,count[i]);
if (screen) fprintf(screen," %d = max bonds/atom\n",bond_per_atom);
if (logfile) fprintf(logfile," %d = max bonds/atom\n",bond_per_atom);
} else if (strcmp(keyword,"Angles") == 0) {
for (i = 1; i < cmax; i++) count[i] = 0;
if (force->newton_bond)
for (i = 0; i < atom->nangles; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3);
if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
count[atom2]++;
}
else
for (i = 0; i < atom->nangles; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3);
int amax = MAX(atom1,atom2);
amax = MAX(amax,atom3);
if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
count[atom1]++;
count[atom2]++;
count[atom3]++;
}
for (i = 1; i < cmax; i++) angle_per_atom = MAX(angle_per_atom,count[i]);
if (screen) fprintf(screen," %d = max angles/atom\n",angle_per_atom);
if (logfile) fprintf(logfile," %d = max angles/atom\n",angle_per_atom);
} else if (strcmp(keyword,"Dihedrals") == 0) {
for (i = 1; i < cmax; i++) count[i] = 0;
if (force->newton_bond)
for (i = 0; i < atom->ndihedrals; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d %d",
&tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
count[atom2]++;
}
else
for (i = 0; i < atom->ndihedrals; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d %d",
&tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
int amax = MAX(atom1,atom2);
amax = MAX(amax,atom3);
amax = MAX(amax,atom4);
if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
count[atom1]++;
count[atom2]++;
count[atom3]++;
count[atom4]++;
}
for (i = 1; i < cmax; i++)
dihedral_per_atom = MAX(dihedral_per_atom,count[i]);
if (screen)
fprintf(screen," %d = max dihedrals/atom\n",dihedral_per_atom);
if (logfile)
fprintf(logfile," %d = max dihedrals/atom\n",dihedral_per_atom);
} else if (strcmp(keyword,"Impropers") == 0) {
for (i = 1; i < cmax; i++) count[i] = 0;
if (force->newton_bond)
for (i = 0; i < atom->nimpropers; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d %d",
&tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2);
count[atom2]++;
}
else
for (i = 0; i < atom->nimpropers; i++) {
eof = fgets(line,MAXLINE,fp);
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
sscanf(line,"%d %d %d %d %d %d",
&tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4);
int amax = MAX(atom1,atom2);
amax = MAX(amax,atom3);
amax = MAX(amax,atom4);
if (amax >= cmax) cmax = reallocate(&count,cmax,amax);
count[atom1]++;
count[atom2]++;
count[atom3]++;
count[atom4]++;
}
for (i = 1; i < cmax; i++)
improper_per_atom = MAX(improper_per_atom,count[i]);
if (screen)
fprintf(screen," %d = max impropers/atom\n",improper_per_atom);
if (logfile)
fprintf(logfile," %d = max impropers/atom\n",improper_per_atom);
} else {
char str[128];
sprintf(str,"Unknown identifier in data file: %s",keyword);
error->one(FLERR,str);
}
parse_keyword(0,0);
}
// free topology counting vector
memory->destroy(count);
// error check that topology was specified in file
if ((atom->nbonds && !bond_per_atom) ||
(atom->nangles && !angle_per_atom) ||
(atom->ndihedrals && !dihedral_per_atom) ||
(atom->nimpropers && !improper_per_atom))
error->one(FLERR,"Needed topology not in data file");
// customize for new sections
// error check that Bonus sections were speficied in file
if (nellipsoids && !ellipsoid_flag)
error->one(FLERR,"Needed bonus data not in data file");
if (nlines && !line_flag)
error->one(FLERR,"Needed bonus data not in data file");
if (ntris && !tri_flag)
error->one(FLERR,"Needed bonus data not in data file");
}
/* ----------------------------------------------------------------------
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;
memory->grow(count,amax+1,"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(FLERR,"Cannot open gzipped file");
#endif
}
if (fp == NULL) {
char str[128];
sprintf(str,"Cannot open file %s",file);
error->one(FLERR,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(FLERR,"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 extra arg for class2 angle/dihedral/improper
if 2nd word starts with letter, then is hybrid style, add addstr after it
else add addstr before 2nd word
if dupflag, duplicate 1st word, so pair_coeff "2" becomes "2 2"
------------------------------------------------------------------------- */
void ReadData::parse_coeffs(char *line, const 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");
}
if (addstr && narg == 1 && !islower(word[0])) arg[narg++] = (char *) addstr;
arg[narg++] = word;
if (addstr && narg == 2 && islower(word[0])) arg[narg++] = (char *) addstr;
if (dupflag && narg == 1) arg[narg++] = word;
word = strtok(NULL," \t\n\r\f");
}
}
diff --git a/src/read_data.h b/src/read_data.h
index 64832243d..bb900b92b 100644
--- a/src/read_data.h
+++ b/src/read_data.h
@@ -1,398 +1,402 @@
/* -*- c++ -*- ----------------------------------------------------------
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 COMMAND_CLASS
CommandStyle(read_data,ReadData)
#else
#ifndef LMP_READ_DATA_H
#define LMP_READ_DATA_H
#include "stdio.h"
#include "pointers.h"
namespace LAMMPS_NS {
class ReadData : protected Pointers {
public:
ReadData(class LAMMPS *);
~ReadData();
void command(int, char **);
private:
char *line,*keyword,*buffer;
FILE *fp;
char **arg;
int me,narg,maxarg,compressed;
int nfix; // # of extra fixes that process/store info in data file
int *fix_index;
char **fix_header;
char **fix_section;
bigint nellipsoids;
class AtomVecEllipsoid *avec_ellipsoid;
bigint nlines;
class AtomVecLine *avec_line;
bigint ntris;
class AtomVecTri *avec_tri;
void open(char *);
void scan(int &, int &, int &, int &);
int reallocate(int **, int, int);
void header(int);
void parse_keyword(int, int);
void skip_lines(int);
void parse_coeffs(char *, const char *, int);
void atoms();
void velocities();
void bonus(bigint, class AtomVec *, const char *);
void bonds();
void angles();
void dihedrals();
void impropers();
void mass();
void paircoeffs();
void bondcoeffs();
void anglecoeffs(int);
void dihedralcoeffs(int);
void impropercoeffs(int);
void fix(int, char *, bigint);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Cannot read_data after simulation box is defined
The read_data command cannot be used after a read_data,
read_restart, or create_box command.
E: Cannot run 2d simulation with nonperiodic Z dimension
Use the boundary command to make the z dimension periodic in order to
run a 2d simulation.
+E: Fix ID for read_data does not exist
+
+Self-explanatory.
+
E: Must read Atoms before Velocities
The Atoms section of a data file must come before a Velocities
section.
E: Invalid data file section: Ellipsoids
Atom style does not allow ellipsoids.
E: Must read Atoms before Ellipsoids
The Atoms section of a data file must come before a Ellipsoids
section.
E: Invalid data file section: Lines
Atom style does not allow lines.
E: Must read Atoms before Lines
The Atoms section of a data file must come before a Lines section.
E: Invalid data file section: Triangles
Atom style does not allow triangles.
E: Must read Atoms before Triangles
The Atoms section of a data file must come before a Triangles section.
E: Invalid data file section: Bonds
Atom style does not allow bonds.
E: Must read Atoms before Bonds
The Atoms section of a data file must come before a Bonds section.
E: Invalid data file section: Angles
Atom style does not allow angles.
E: Must read Atoms before Angles
The Atoms section of a data file must come before an Angles section.
E: Invalid data file section: Dihedrals
Atom style does not allow dihedrals.
E: Must read Atoms before Dihedrals
The Atoms section of a data file must come before a Dihedrals section.
E: Invalid data file section: Impropers
Atom style does not allow impropers.
E: Must read Atoms before Impropers
The Atoms section of a data file must come before an Impropers
section.
E: Must define pair_style before Pair Coeffs
Must use a pair_style command before reading a data file that defines
Pair Coeffs.
E: Invalid data file section: Bond Coeffs
Atom style does not allow bonds.
E: Must define bond_style before Bond Coeffs
Must use a bond_style command before reading a data file that
defines Bond Coeffs.
E: Invalid data file section: Angle Coeffs
Atom style does not allow angles.
E: Must define angle_style before Angle Coeffs
Must use an angle_style command before reading a data file that
defines Angle Coeffs.
E: Invalid data file section: Dihedral Coeffs
Atom style does not allow dihedrals.
E: Must define dihedral_style before Dihedral Coeffs
Must use a dihedral_style command before reading a data file that
defines Dihedral Coeffs.
E: Invalid data file section: Improper Coeffs
Atom style does not allow impropers.
E: Must define improper_style before Improper Coeffs
Must use an improper_style command before reading a data file that
defines Improper Coeffs.
E: Invalid data file section: BondBond Coeffs
Atom style does not allow angles.
E: Must define angle_style before BondBond Coeffs
Must use an angle_style command before reading a data file that
defines Angle Coeffs.
E: Invalid data file section: BondAngle Coeffs
Atom style does not allow angles.
E: Must define angle_style before BondAngle Coeffs
Must use an angle_style command before reading a data file that
defines Angle Coeffs.
E: Invalid data file section: MiddleBondTorsion Coeffs
Atom style does not allow dihedrals.
E: Must define dihedral_style before MiddleBondTorsion Coeffs
Must use a dihedral_style command before reading a data file that
defines MiddleBondTorsion Coeffs.
E: Invalid data file section: EndBondTorsion Coeffs
Atom style does not allow dihedrals.
E: Must define dihedral_style before EndBondTorsion Coeffs
Must use a dihedral_style command before reading a data file that
defines EndBondTorsion Coeffs.
E: Invalid data file section: AngleTorsion Coeffs
Atom style does not allow dihedrals.
E: Must define dihedral_style before AngleTorsion Coeffs
Must use a dihedral_style command before reading a data file that
defines AngleTorsion Coeffs.
E: Invalid data file section: AngleAngleTorsion Coeffs
Atom style does not allow dihedrals.
E: Must define dihedral_style before AngleAngleTorsion Coeffs
Must use a dihedral_style command before reading a data file that
defines AngleAngleTorsion Coeffs.
E: Invalid data file section: BondBond13 Coeffs
Atom style does not allow dihedrals.
E: Must define dihedral_style before BondBond13 Coeffs
Must use a dihedral_style command before reading a data file that
defines BondBond13 Coeffs.
E: Invalid data file section: AngleAngle Coeffs
Atom style does not allow impropers.
E: Must define improper_style before AngleAngle Coeffs
Must use an improper_style command before reading a data file that
defines AngleAngle Coeffs.
E: Unknown identifier in data file: %s
A section of the data file cannot be read by LAMMPS.
E: No atoms in data file
The header of the data file indicated that atoms would be included,
but they were not present.
E: Unexpected end of data file
LAMMPS hit the end of the data file while attempting to read a
section. Something is wrong with the format of the data file.
E: No ellipsoids allowed with this atom style
Self-explanatory. Check data file.
E: No lines allowed with this atom style
Self-explanatory. Check data file.
E: No triangles allowed with this atom style
Self-explanatory. Check data file.
E: System in data file is too big
See the setting for bigint in the src/lmptype.h file.
E: No bonds allowed with this atom style
Self-explanatory. Check data file.
E: No angles allowed with this atom style
Self-explanatory. Check data file.
E: No dihedrals allowed with this atom style
Self-explanatory. Check data file.
E: No impropers allowed with this atom style
Self-explanatory. Check data file.
E: Bonds defined but no bond types
The data file header lists bonds but no bond types.
E: Angles defined but no angle types
The data file header lists angles but no angle types.
E: Dihedrals defined but no dihedral types
The data file header lists dihedrals but no dihedral types.
E: Impropers defined but no improper types
The data file header lists improper but no improper types.
E: Did not assign all atoms correctly
Atoms read in from a data file were not assigned correctly to
processors. This is likely due to some atom coordinates being
outside a non-periodic simulation box.
E: Invalid atom ID in Atoms section of data file
Atom IDs must be positive integers.
E: Bonds assigned incorrectly
Bonds read in from the data file were not assigned correctly to atoms.
This means there is something invalid about the topology definitions.
E: Angles assigned incorrectly
Angles read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions.
E: Dihedrals assigned incorrectly
Dihedrals read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions.
E: Impropers assigned incorrectly
Impropers read in from the data file were not assigned correctly to
atoms. This means there is something invalid about the topology
definitions.
E: Molecular data file has too many atoms
These kids of data files are currently limited to a number
of atoms that fits in a 32-bit integer.
E: Needed topology not in data file
The header of the data file indicated that bonds or angles or
dihedrals or impropers would be included, but they were not present.
E: Needed bonus data not in data file
Some atom styles require bonus data. See the read_data doc page for
details.
E: Cannot open gzipped file
LAMMPS is attempting to open a gzipped version of the specified file
but was unsuccessful. Check that the path and name are correct.
E: Cannot open file %s
The specified file cannot be opened. Check that the path and name are
correct.
*/
diff --git a/src/read_dump.cpp b/src/read_dump.cpp
index c04c7e659..150bff546 100644
--- a/src/read_dump.cpp
+++ b/src/read_dump.cpp
@@ -1,881 +1,884 @@
/* ----------------------------------------------------------------------
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: Timothy Sirk (ARL)
------------------------------------------------------------------------- */
#include "lmptype.h"
#include "mpi.h"
#include "string.h"
#include "stdlib.h"
#include "read_dump.h"
#include "reader.h"
#include "style_reader.h"
#include "atom.h"
#include "atom_vec.h"
#include "update.h"
#include "modify.h"
#include "fix.h"
#include "domain.h"
#include "comm.h"
#include "irregular.h"
#include "error.h"
#include "memory.h"
using namespace LAMMPS_NS;
#define CHUNK 1024
#define EPSILON 1.0e-6
enum{ID,TYPE,X,Y,Z,VX,VY,VZ,IX,IY,IZ};
enum{UNSET,UNSCALED,SCALED};
/* ---------------------------------------------------------------------- */
ReadDump::ReadDump(LAMMPS *lmp) : Pointers(lmp)
{
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
dimension = domain->dimension;
triclinic = domain->triclinic;
nfile = 0;
files = NULL;
nfield = 0;
fieldtype = NULL;
fieldlabel = NULL;
fields = NULL;
int n = strlen("native") + 1;
readerstyle = new char[n];
strcpy(readerstyle,"native");
reader = NULL;
fp = NULL;
}
/* ---------------------------------------------------------------------- */
ReadDump::~ReadDump()
{
for (int i = 0; i < nfile; i++) delete [] files[i];
delete [] files;
for (int i = 0; i < nfield; i++) delete [] fieldlabel[i];
delete [] fieldlabel;
delete [] fieldtype;
delete [] readerstyle;
memory->destroy(fields);
delete reader;
}
/* ---------------------------------------------------------------------- */
void ReadDump::command(int narg, char **arg)
{
if (narg < 2) error->all(FLERR,"Illegal read_dump command");
store_files(1,&arg[0]);
bigint nstep = ATOBIGINT(arg[1]);
int nremain = narg - 2;
if (nremain) nremain = fields_and_keywords(nremain,&arg[narg-nremain]);
else nremain = fields_and_keywords(0,NULL);
if (nremain) setup_reader(nremain,&arg[narg-nremain]);
else setup_reader(0,NULL);
// find the snapshot and read/bcast/process header info
if (me == 0 && screen) fprintf(screen,"Scanning dump file ...\n");
bigint ntimestep = seek(nstep,1);
if (ntimestep < 0)
error->all(FLERR,"Dump file does not contain requested snapshot");
header(1);
// reset timestep to nstep
update->reset_timestep(nstep);
// counters
// read in the snapshot and reset system
if (me == 0 && screen)
fprintf(screen,"Reading snapshot from dump file ...\n");
bigint natoms_prev = atom->natoms;
atoms();
if (me == 0) reader->close_file();
// print out stats
bigint npurge_all,nreplace_all,ntrim_all,nadd_all;
bigint tmp;
tmp = npurge;
MPI_Allreduce(&tmp,&npurge_all,1,MPI_LMP_BIGINT,MPI_SUM,world);
tmp = nreplace;
MPI_Allreduce(&tmp,&nreplace_all,1,MPI_LMP_BIGINT,MPI_SUM,world);
tmp = ntrim;
MPI_Allreduce(&tmp,&ntrim_all,1,MPI_LMP_BIGINT,MPI_SUM,world);
tmp = nadd;
MPI_Allreduce(&tmp,&nadd_all,1,MPI_LMP_BIGINT,MPI_SUM,world);
domain->print_box(" ");
if (me == 0) {
if (screen) {
fprintf(screen," " BIGINT_FORMAT " atoms before read\n",natoms_prev);
fprintf(screen," " BIGINT_FORMAT " atoms in snapshot\n",nsnapatoms);
fprintf(screen," " BIGINT_FORMAT " atoms purged\n",npurge_all);
fprintf(screen," " BIGINT_FORMAT " atoms replaced\n",nreplace_all);
fprintf(screen," " BIGINT_FORMAT " atoms trimmed\n",ntrim_all);
fprintf(screen," " BIGINT_FORMAT " atoms added\n",nadd_all);
fprintf(screen," " BIGINT_FORMAT " atoms after read\n",atom->natoms);
}
if (logfile) {
fprintf(logfile," " BIGINT_FORMAT " atoms before read\n",natoms_prev);
fprintf(logfile," " BIGINT_FORMAT " atoms in snapshot\n",nsnapatoms);
fprintf(logfile," " BIGINT_FORMAT " atoms purged\n",npurge_all);
fprintf(logfile," " BIGINT_FORMAT " atoms replaced\n",nreplace_all);
fprintf(logfile," " BIGINT_FORMAT " atoms trimmed\n",ntrim_all);
fprintf(logfile," " BIGINT_FORMAT " atoms added\n",nadd_all);
fprintf(logfile," " BIGINT_FORMAT " atoms after read\n",atom->natoms);
}
}
}
/* ---------------------------------------------------------------------- */
void ReadDump::store_files(int nstr, char **str)
{
nfile = nstr;
files = new char*[nfile];
for (int i = 0; i < nfile; i++) {
int n = strlen(str[i]) + 1;
files[i] = new char[n];
strcpy(files[i],str[i]);
}
}
/* ---------------------------------------------------------------------- */
void ReadDump::setup_reader(int narg, char **arg)
{
// allocate snapshot field buffer
memory->create(fields,CHUNK,nfield,"read_dump:fields");
// create reader class
// match readerstyle to options in style_reader.h
if (0) return; // dummy line to enable else-if macro expansion
#define READER_CLASS
#define ReaderStyle(key,Class) \
else if (strcmp(readerstyle,#key) == 0) reader = new Class(lmp);
#include "style_reader.h"
#undef READER_CLASS
// unrecognized style
else error->all(FLERR,"Invalid dump reader style");
// pass any arguments to reader
if (narg > 0) reader->settings(narg,arg);
}
/* ----------------------------------------------------------------------
seek Nrequest timestep in one or more dump files
if exact = 1, must find exactly Nrequest
if exact = 0, find first step >= Nrequest
return matching ntimestep or -1 if did not find a match
------------------------------------------------------------------------- */
bigint ReadDump::seek(bigint nrequest, int exact)
{
int ifile,eofflag;
bigint ntimestep;
if (me == 0) {
// exit file loop when dump timestep >= nrequest
// or files exhausted
for (ifile = 0; ifile < nfile; ifile++) {
ntimestep = -1;
reader->open_file(files[ifile]);
while (1) {
eofflag = reader->read_time(ntimestep);
if (eofflag) break;
if (ntimestep >= nrequest) break;
reader->skip();
}
if (ntimestep >= nrequest) break;
reader->close_file();
}
currentfile = ifile;
if (ntimestep < nrequest) ntimestep = -1;
if (exact && ntimestep != nrequest) ntimestep = -1;
if (ntimestep < 0) reader->close_file();
}
MPI_Bcast(&ntimestep,1,MPI_LMP_BIGINT,0,world);
return ntimestep;
}
/* ----------------------------------------------------------------------
find next matching snapshot in one or more dump files
Ncurrent = current timestep from last snapshot
Nlast = match no timestep bigger than Nlast
Nevery = only match timesteps that are a multiple of Nevery
Nskip = skip every this many timesteps
return matching ntimestep or -1 if did not find a match
------------------------------------------------------------------------- */
bigint ReadDump::next(bigint ncurrent, bigint nlast, int nevery, int nskip)
{
int ifile,eofflag;
bigint ntimestep;
if (me == 0) {
// exit file loop when dump timestep matches all criteria
// or files exhausted
int iskip = 0;
for (ifile = currentfile; ifile < nfile; ifile++) {
ntimestep = -1;
if (ifile != currentfile) reader->open_file(files[ifile]);
while (1) {
eofflag = reader->read_time(ntimestep);
if (iskip == nskip) iskip = 0;
iskip++;
if (eofflag) break;
if (ntimestep <= ncurrent) break;
if (ntimestep > nlast) break;
if (nevery && ntimestep % nevery) reader->skip();
else if (iskip < nskip) reader->skip();
else break;
}
if (eofflag) reader->close_file();
else break;
}
currentfile = ifile;
if (eofflag) ntimestep = -1;
if (ntimestep <= ncurrent) ntimestep = -1;
if (ntimestep > nlast) ntimestep = -1;
if (ntimestep < 0) reader->close_file();
}
MPI_Bcast(&ntimestep,1,MPI_LMP_BIGINT,0,world);
return ntimestep;
}
/* ----------------------------------------------------------------------
read and broadcast and store snapshot header info
set nsnapatoms = # of atoms in snapshot
set yindex,zindex
------------------------------------------------------------------------- */
void ReadDump::header(int fieldinfo)
{
int triclinic_snap;
int fieldflag,xflag,yflag,zflag;
if (me == 0)
nsnapatoms = reader->read_header(box,triclinic_snap,
fieldinfo,nfield,fieldtype,fieldlabel,
scaledflag,fieldflag,xflag,yflag,zflag);
MPI_Bcast(&nsnapatoms,1,MPI_LMP_BIGINT,0,world);
MPI_Bcast(&triclinic_snap,1,MPI_INT,0,world);
MPI_Bcast(&box[0][0],9,MPI_DOUBLE,0,world);
// local copy of snapshot box parameters
// used in xfield,yfield,zfield when converting dump atom to absolute coords
xlo = box[0][0];
xhi = box[0][1];
ylo = box[1][0];
yhi = box[1][1];
zlo = box[2][0];
zhi = box[2][1];
xprd = xhi - xlo;
yprd = yhi - ylo;
zprd = zhi - zlo;
if (triclinic_snap) {
xy = box[0][2];
xz = box[1][2];
yz = box[2][2];
}
// done if not checking fields
if (!fieldinfo) return;
MPI_Bcast(&fieldflag,1,MPI_INT,0,world);
MPI_Bcast(&xflag,1,MPI_INT,0,world);
MPI_Bcast(&yflag,1,MPI_INT,0,world);
MPI_Bcast(&zflag,1,MPI_INT,0,world);
// error check on current vs new box and fields
// triclinic_snap < 0 means no box info in file
if (triclinic_snap < 0 && boxflag > 0)
error->all(FLERR,"No box information in dump. You have to use 'box no'");
if (triclinic_snap >= 0) {
if ((triclinic_snap && !triclinic) ||
(!triclinic_snap && triclinic))
error->one(FLERR,"Read_dump triclinic status does not match simulation");
}
// error check field and scaling info
if (fieldflag < 0)
error->one(FLERR,"Read_dump field not found in dump file");
// set overall scaling of coordinates
// error if x,y,z scaling are not the same
scaled = MAX(xflag,yflag);
scaled = MAX(zflag,scaled);
if ((xflag != UNSET && xflag != scaled) ||
(yflag != UNSET && yflag != scaled) ||
(zflag != UNSET && zflag != scaled))
error->one(FLERR,"Read_dump x,y,z fields do not have consistent scaling");
// scaled, triclinic coords require all 3 x,y,z fields, to perform unscaling
// set yindex,zindex = column index of Y and Z fields in fields array
// needed for unscaling to absolute coords in xfield(), yfield(), zfield()
if (scaled == SCALED && triclinic == 1) {
int flag = 0;
if (xflag != scaled) flag = 1;
if (yflag != scaled) flag = 1;
if (dimension == 3 && zflag != scaled) flag = 1;
if (flag)
error->one(FLERR,"All read_dump x,y,z fields must be specified for "
"scaled, triclinic coords");
for (int i = 0; i < nfield; i++) {
if (fieldtype[i] == Y) yindex = i;
if (fieldtype[i] == Z) zindex = i;
}
}
}
/* ---------------------------------------------------------------------- */
void ReadDump::atoms()
{
// initialize counters
npurge = nreplace = ntrim = nadd = 0;
// if purgeflag set, delete all current atoms
if (purgeflag) {
if (atom->map_style) atom->map_clear();
npurge = atom->nlocal;
atom->nlocal = atom->nghost = 0;
atom->natoms = 0;
}
// to match existing atoms to dump atoms:
// must build map if not a molecular system
int mapflag = 0;
if (atom->map_style == 0) {
mapflag = 1;
atom->map_style = 1;
atom->map_init();
atom->map_set();
}
// uflag[i] = 1 for each owned atom appearing in dump
// ucflag = similar flag for each chunk atom, used in process_atoms()
int nlocal = atom->nlocal;
memory->create(uflag,nlocal,"read_dump:uflag");
for (int i = 0; i < nlocal; i++) uflag[i] = 0;
memory->create(ucflag,CHUNK,"read_dump:ucflag");
memory->create(ucflag_all,CHUNK,"read_dump:ucflag");
// read, broadcast, and process atoms from snapshot in chunks
addproc = -1;
int nchunk;
bigint nread = 0;
while (nread < nsnapatoms) {
nchunk = MIN(nsnapatoms-nread,CHUNK);
if (me == 0) reader->read_atoms(nchunk,nfield,fields);
MPI_Bcast(&fields[0][0],nchunk*nfield,MPI_DOUBLE,0,world);
process_atoms(nchunk);
nread += nchunk;
}
// if addflag set, add tags to new atoms if possible
if (addflag) {
bigint nblocal = atom->nlocal;
MPI_Allreduce(&nblocal,&atom->natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
if (atom->natoms < 0 || atom->natoms > MAXBIGINT)
error->all(FLERR,"Too many total atoms");
- if (atom->natoms > MAXTAGINT) atom->tag_enable = 0;
- if (atom->natoms <= MAXTAGINT) atom->tag_extend();
+ // change these to MAXTAGINT when allow tagint = bigint
+ if (atom->natoms > MAXSMALLINT) atom->tag_enable = 0;
+ if (atom->natoms <= MAXSMALLINT) atom->tag_extend();
}
// if trimflag set, delete atoms not replaced by snapshot atoms
if (trimflag) {
delete_atoms();
bigint nblocal = atom->nlocal;
MPI_Allreduce(&nblocal,&atom->natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
}
// can now delete uflag arrays
memory->destroy(uflag);
memory->destroy(ucflag);
memory->destroy(ucflag_all);
// delete atom map if created it above
// else reinitialize map for current atoms
// do this before migrating atoms to new procs via Irregular
if (mapflag) {
atom->map_delete();
atom->map_style = 0;
} else {
atom->nghost = 0;
atom->map_init();
atom->map_set();
}
// overwrite simulation box with dump snapshot box if requested
// reallocate processors to box
if (boxflag) {
domain->boxlo[0] = xlo;
domain->boxhi[0] = xhi;
domain->boxlo[1] = ylo;
domain->boxhi[1] = yhi;
if (dimension == 3) {
domain->boxlo[2] = zlo;
domain->boxhi[2] = zhi;
}
if (triclinic) {
domain->xy = xy;
if (dimension == 3) {
domain->xz = xz;
domain->yz = yz;
}
}
domain->set_initial_box();
domain->set_global_box();
comm->set_proc_grid(0);
domain->set_local_box();
}
// move atoms back inside simulation box and to new processors
// use remap() instead of pbc() in case atoms moved a long distance
// adjust image flags of all atoms (old and new) based on current box
// use irregular() in case atoms moved a long distance
double **x = atom->x;
- int *image = atom->image;
+ tagint *image = atom->image;
nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) domain->remap(x[i],image[i]);
if (triclinic) domain->x2lamda(atom->nlocal);
domain->reset_box();
Irregular *irregular = new Irregular(lmp);
irregular->migrate_atoms();
delete irregular;
if (triclinic) domain->lamda2x(atom->nlocal);
}
/* ----------------------------------------------------------------------
process arg list for dump file fields and optional keywords
------------------------------------------------------------------------- */
int ReadDump::fields_and_keywords(int narg, char **arg)
{
// per-field vectors, leave space for ID and TYPE
fieldtype = new int[narg+2];
fieldlabel = new char*[narg+2];
// add id and type fields as needed
// scan ahead to see if "add yes" keyword/value is used
// requires extra "type" field from from dump file
int iarg;
for (iarg = 0; iarg < narg; iarg++)
if (strcmp(arg[iarg],"add") == 0)
if (iarg < narg-1 && strcmp(arg[iarg+1],"yes") == 0) break;
nfield = 0;
fieldtype[nfield++] = ID;
if (iarg < narg) fieldtype[nfield++] = TYPE;
// parse fields
iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"x") == 0) fieldtype[nfield++] = X;
else if (strcmp(arg[iarg],"y") == 0) fieldtype[nfield++] = Y;
else if (strcmp(arg[iarg],"z") == 0) fieldtype[nfield++] = Z;
else if (strcmp(arg[iarg],"vx") == 0) fieldtype[nfield++] = VX;
else if (strcmp(arg[iarg],"vy") == 0) fieldtype[nfield++] = VY;
else if (strcmp(arg[iarg],"vz") == 0) fieldtype[nfield++] = VZ;
else if (strcmp(arg[iarg],"ix") == 0) fieldtype[nfield++] = IX;
else if (strcmp(arg[iarg],"iy") == 0) fieldtype[nfield++] = IY;
else if (strcmp(arg[iarg],"iz") == 0) fieldtype[nfield++] = IZ;
else break;
iarg++;
}
// check for no fields
if (fieldtype[nfield-1] == ID || fieldtype[nfield-1] == TYPE)
error->all(FLERR,"Illegal read_dump command");
if (dimension == 2) {
for (int i = 0; i < nfield; i++)
if (fieldtype[i] == Z || fieldtype[i] == VZ || fieldtype[i] == IZ)
error->all(FLERR,"Illegal read_dump command");
}
for (int i = 0; i < nfield; i++)
for (int j = i+1; j < nfield; j++)
if (fieldtype[i] == fieldtype[j])
error->all(FLERR,"Duplicate fields in read_dump command");
// parse optional args
boxflag = 1;
replaceflag = 1;
purgeflag = 0;
trimflag = 0;
addflag = 0;
for (int i = 0; i < nfield; i++) fieldlabel[i] = NULL;
scaledflag = UNSCALED;
while (iarg < narg) {
if (strcmp(arg[iarg],"box") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal read_dump command");
if (strcmp(arg[iarg+1],"yes") == 0) boxflag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) boxflag = 0;
else error->all(FLERR,"Illegal read_dump command");
iarg += 2;
} else if (strcmp(arg[iarg],"replace") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal read_dump command");
if (strcmp(arg[iarg+1],"yes") == 0) replaceflag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) replaceflag = 0;
else error->all(FLERR,"Illegal read_dump command");
iarg += 2;
} else if (strcmp(arg[iarg],"purge") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal read_dump command");
if (strcmp(arg[iarg+1],"yes") == 0) purgeflag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) purgeflag = 0;
else error->all(FLERR,"Illegal read_dump command");
iarg += 2;
} else if (strcmp(arg[iarg],"trim") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal read_dump command");
if (strcmp(arg[iarg+1],"yes") == 0) trimflag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) trimflag = 0;
else error->all(FLERR,"Illegal read_dump command");
iarg += 2;
} else if (strcmp(arg[iarg],"add") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal read_dump command");
if (strcmp(arg[iarg+1],"yes") == 0) addflag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) addflag = 0;
else error->all(FLERR,"Illegal read_dump command");
iarg += 2;
} else if (strcmp(arg[iarg],"label") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal read_dump command");
int i;
for (i = 0; i < nfield; i++)
if (fieldlabel[i] && strcmp(arg[iarg+1],fieldlabel[i]) == 0) break;
if (i == nfield) error->all(FLERR,"Illegal read_dump command");
int n = strlen(arg[iarg+2]) + 1;
fieldlabel[i] = new char[n];
strcpy(fieldlabel[i],arg[iarg+2]);
iarg += 3;
} else if (strcmp(arg[iarg],"scaled") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal read_dump command");
if (strcmp(arg[iarg+1],"yes") == 0) scaledflag = SCALED;
else if (strcmp(arg[iarg+1],"no") == 0) scaledflag = UNSCALED;
else error->all(FLERR,"Illegal read_dump command");
iarg += 2;
} else if (strcmp(arg[iarg],"format") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal read_dump command");
delete [] readerstyle;
int n = strlen(arg[iarg+1]) + 1;
readerstyle = new char[n];
strcpy(readerstyle,arg[iarg+1]);
iarg += 2;
break;
} else error->all(FLERR,"Illegal read_dump command");
}
if (purgeflag && (replaceflag || trimflag))
error->all(FLERR,"If read_dump purges it cannot replace or trim");
return narg-iarg;
}
/* ----------------------------------------------------------------------
process each of N atoms in chunk read from dump file
if in replace mode and atom ID matches current atom,
overwrite atom info with fields from dump file
if in add mode and atom ID does not match any current atom,
create new atom with dump file field values,
and assign to a proc in round-robin manner
use round-robin method, b/c atom coords may not be inside simulation box
------------------------------------------------------------------------- */
void ReadDump::process_atoms(int n)
{
int i,m,ifield,itype;
int xbox,ybox,zbox;
double **x = atom->x;
double **v = atom->v;
- int *image = atom->image;
+ tagint *image = atom->image;
int nlocal = atom->nlocal;
for (i = 0; i < n; i++) {
ucflag[i] = 0;
// map() call is invalid if purged all atoms
// setting m = -1 forces new atom not to match
if (!purgeflag) m = atom->map(static_cast<int> (fields[i][0]));
else m = -1;
if (m < 0 || m >= nlocal) continue;
ucflag[i] = 1;
uflag[m] = 1;
if (replaceflag) {
nreplace++;
// current image flags
- xbox = (image[m] & 1023) - 512;
- ybox = (image[m] >> 10 & 1023) - 512;
- zbox = (image[m] >> 20) - 512;
+ xbox = (image[m] & IMGMASK) - IMGMAX;
+ ybox = (image[m] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[m] >> IMG2BITS) - IMGMAX;
// overwrite atom attributes with field info
// start from field 1 since 0 = id, 1 will be skipped if type
for (ifield = 1; ifield < nfield; ifield++) {
switch (fieldtype[ifield]) {
case X:
x[m][0] = xfield(i,ifield);
break;
case Y:
x[m][1] = yfield(i,ifield);
break;
case Z:
x[m][2] = zfield(i,ifield);
break;
case VX:
v[m][0] = fields[i][ifield];
break;
case VY:
v[m][1] = fields[i][ifield];
break;
case VZ:
v[m][2] = fields[i][ifield];
break;
case IX:
xbox = static_cast<int> (fields[i][ifield]);
break;
case IY:
ybox = static_cast<int> (fields[i][ifield]);
break;
case IZ:
zbox = static_cast<int> (fields[i][ifield]);
break;
}
}
// replace image flag in case changed by ix,iy,iz fields
- image[m] = (xbox << 20) | (ybox << 10) | zbox;
+ image[m] = ((tagint) xbox << IMG2BITS) |
+ ((tagint) ybox << IMGBITS) | zbox;
}
}
// create any atoms in chunk that no processor owned
// add atoms in round-robin sequence on processors
// cannot do it geometrically b/c dump coords may not be in simulation box
if (!addflag) return;
MPI_Allreduce(ucflag,ucflag_all,n,MPI_INT,MPI_SUM,world);
int nlocal_previous = atom->nlocal;
double one[3];
for (i = 0; i < n; i++) {
if (ucflag_all[i]) continue;
// each processor adds every Pth atom
addproc++;
if (addproc == nprocs) addproc = 0;
if (addproc != me) continue;
// create type and coord fields from dump file
// coord = 0.0 unless corresponding dump file field was specified
one[0] = one[1] = one[2] = 0.0;
for (ifield = 1; ifield < nfield; ifield++) {
switch (fieldtype[ifield]) {
case TYPE:
itype = static_cast<int> (fields[i][ifield]);
break;
case X:
one[0] = xfield(i,ifield);
break;
case Y:
one[1] = yfield(i,ifield);
break;
case Z:
one[2] = zfield(i,ifield);
break;
}
}
// create the atom on proc that owns it
// reset v,image ptrs in case they are reallocated
atom->avec->create_atom(itype,one);
nadd++;
v = atom->v;
image = atom->image;
m = atom->nlocal;
// set atom attributes from other dump file fields
- // xyzbox = 512 is default value set by create_atom()
+ // xyzbox = IMGMAX is default value set by create_atom()
- xbox = ybox = zbox = 512;
+ xbox = ybox = zbox = IMGMAX;
for (ifield = 1; ifield < nfield; ifield++) {
switch (fieldtype[ifield]) {
case VX:
v[m][0] = fields[i][ifield];
break;
case VY:
v[m][1] = fields[i][ifield];
break;
case VZ:
v[m][2] = fields[i][ifield];
break;
case IX:
xbox = static_cast<int> (fields[i][ifield]);
break;
case IY:
ybox = static_cast<int> (fields[i][ifield]);
break;
case IZ:
zbox = static_cast<int> (fields[i][ifield]);
break;
}
// replace image flag in case changed by ix,iy,iz fields
- image[m] = (xbox << 20) | (ybox << 10) | zbox;
+ image[m] = ((tagint) xbox << IMG2BITS) |
+ ((tagint) ybox << IMGBITS) | zbox;
}
}
// invoke set_arrays() for fixes that need initialization of new atoms
// same as in CreateAtoms
nlocal = atom->nlocal;
for (m = 0; m < modify->nfix; m++) {
Fix *fix = modify->fix[m];
if (fix->create_attribute)
for (i = nlocal_previous; i < nlocal; i++)
fix->set_arrays(i);
}
}
/* ----------------------------------------------------------------------
delete atoms not flagged as replaced by dump atoms
------------------------------------------------------------------------- */
void ReadDump::delete_atoms()
{
AtomVec *avec = atom->avec;
int nlocal = atom->nlocal;
int i = 0;
while (i < nlocal) {
if (uflag[i] == 0) {
avec->copy(nlocal-1,i,1);
uflag[i] = uflag[nlocal-1];
nlocal--;
ntrim++;
} else i++;
}
atom->nlocal = nlocal;
}
/* ----------------------------------------------------------------------
convert XYZ fields in dump file into absolute, unscaled coordinates
depends on scaled vs unscaled and triclinic vs orthogonal
does not depend on wrapped vs unwrapped
------------------------------------------------------------------------- */
double ReadDump::xfield(int i, int j)
{
if (scaled == UNSCALED) return fields[i][j];
else if (!triclinic) return fields[i][j]*xprd + xlo;
else if (dimension == 2)
return xprd*fields[i][j] + xy*fields[i][yindex] + xlo;
return xprd*fields[i][j] + xy*fields[i][yindex] + xz*fields[i][zindex] + xlo;
}
double ReadDump::yfield(int i, int j)
{
if (scaled == UNSCALED) return fields[i][j];
else if (!triclinic) return fields[i][j]*yprd + ylo;
else if (dimension == 2) return yprd*fields[i][j] + ylo;
return yprd*fields[i][j] + yz*fields[i][zindex] + ylo;
}
double ReadDump::zfield(int i, int j)
{
if (scaled == UNSCALED) return fields[i][j];
return fields[i][j]*zprd + zlo;
}
diff --git a/src/read_dump.h b/src/read_dump.h
index fd3a0c798..0ed9ca559 100644
--- a/src/read_dump.h
+++ b/src/read_dump.h
@@ -1,93 +1,147 @@
/* -*- c++ -*- ----------------------------------------------------------
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.
Contributed by Timothy Sirk
------------------------------------------------------------------------- */
#ifdef COMMAND_CLASS
CommandStyle(read_dump,ReadDump)
#else
#ifndef LMP_READ_DUMP_H
#define LMP_READ_DUMP_H
#include "stdio.h"
#include "pointers.h"
namespace LAMMPS_NS {
class ReadDump : protected Pointers {
public:
ReadDump(class LAMMPS *);
~ReadDump();
void command(int, char **);
void store_files(int, char **);
void setup_reader(int, char **);
bigint seek(bigint, int);
void header(int);
bigint next(bigint, bigint, int, int);
void atoms();
int fields_and_keywords(int, char **);
private:
int me,nprocs;
FILE *fp;
int dimension;
int triclinic;
int nfile; // # of dump files to process
char **files; // list of file names
int currentfile; // currently open file
int boxflag; // overwrite simulation with dump file box params
int replaceflag,addflag; // flags for processing dump snapshot atoms
int trimflag,purgeflag;
int scaledflag; // user setting for coordinate scaling
int scaled; // actual setting for coordinate scaling
char *readerstyle; // style of dump files to read
int nfield; // # of fields to extract from dump file
int *fieldtype; // type of each field = X,VY,IZ,etc
char **fieldlabel; // user specified label for field
double **fields; // per-atom field values
double box[3][3]; // dump file box parameters
double xlo,xhi,ylo,yhi,zlo,zhi,xy,xz,yz; // dump snapshot box params
double xprd,yprd,zprd;
bigint nsnapatoms; // # of atoms in dump file shapshot
int npurge,nreplace,ntrim,nadd; // stats on processed atoms
int addproc; // proc that should add next atom
int yindex,zindex; // field index for Y,Z coords
int *uflag; // set to 1 if snapshot atom matches owned atom
int *ucflag,*ucflag_all; // set to 1 if snapshot chunk atom was processed
class Reader *reader; // class that reads dump file
void process_atoms(int);
void delete_atoms();
double xfield(int, int);
double yfield(int, int);
double zfield(int, int);
};
}
#endif
#endif
+
+/* ERROR/WARNING messages:
+
+E: Illegal ... command
+
+Self-explanatory. Check the input script syntax and compare to the
+documentation for the command. You can use -echo screen as a
+command-line option when running LAMMPS to see the offending line.
+
+E: Dump file does not contain requested snapshot
+
+Self-explanatory.
+
+E: Invalid dump reader style
+
+Self-explanatory.
+
+E: No box information in dump. You have to use 'box no'
+
+Self-explanatory.
+
+E: Read_dump triclinic status does not match simulation
+
+Both the dump snapshot and the current LAMMPS simulation must
+be using either an orthogonal or triclinic box.
+
+E: Read_dump field not found in dump file
+
+Self-explanatory.
+
+E: Read_dump x,y,z fields do not have consistent scaling
+
+Self-explanatory.
+
+E: All read_dump x,y,z fields must be specified for scaled, triclinic coords
+
+For triclinic boxes and scaled coordinates you must specify all 3 of
+the x,y,z fields, else LAMMPS cannot reconstruct the unscaled
+coordinates.
+
+E: Too many total atoms
+
+See the setting for bigint in the src/lmptype.h file.
+
+E: Duplicate fields in read_dump command
+
+Self-explanatory.
+
+E: If read_dump purges it cannot replace or trim
+
+These operations are not compatible. See the read_dump doc
+page for details.
+
+*/
diff --git a/src/reader.h b/src/reader.h
index 1c53562cf..8801970d2 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -1,46 +1,60 @@
/* -*- c++ -*- ----------------------------------------------------------
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.
Contributed by Timothy Sirk
------------------------------------------------------------------------- */
#ifndef LMP_READER_H
#define LMP_READER_H
#include "pointers.h"
namespace LAMMPS_NS {
class Reader : protected Pointers {
public:
Reader(class LAMMPS *);
virtual ~Reader() {}
virtual void settings(int, char**) {};
virtual int read_time(bigint &) = 0;
virtual void skip() = 0;
virtual bigint read_header(double [3][3], int &, int, int, int *, char **,
int, int &, int &, int &, int &) = 0;
virtual void read_atoms(int, int, double **) = 0;
virtual void open_file(const char *);
virtual void close_file();
protected:
FILE *fp; // pointer to opened file or pipe
int compressed; // flag for dump file compression
};
}
#endif
+
+/* ERROR/WARNING messages:
+
+E: Cannot open gzipped file
+
+LAMMPS is attempting to open a gzipped version of the specified file
+but was unsuccessful. Check that the path and name are correct.
+
+E: Cannot open file %s
+
+The specified file cannot be opened. Check that the path and name are
+correct.
+
+*/
diff --git a/src/reader_native.h b/src/reader_native.h
index 63d957d25..ba147da13 100644
--- a/src/reader_native.h
+++ b/src/reader_native.h
@@ -1,54 +1,66 @@
/* -*- c++ -*- ----------------------------------------------------------
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.
Contributed by Timothy Sirk
------------------------------------------------------------------------- */
#ifdef READER_CLASS
ReaderStyle(native,ReaderNative)
#else
#ifndef LMP_READER_NATIVE_H
#define LMP_READER_NATIVE_H
#include "reader.h"
namespace LAMMPS_NS {
class ReaderNative : public Reader {
public:
ReaderNative(class LAMMPS *);
~ReaderNative();
int read_time(bigint &);
void skip();
bigint read_header(double [3][3], int &, int, int, int *, char **,
int, int &, int &, int &, int &);
void read_atoms(int, int, double **);
private:
char *line; // line read from dump file
int nwords; // # of per-atom columns in dump file
char **words; // ptrs to values in parsed per-atom line
int *fieldindex; //
int find_label(const char *, int, char **);
void read_lines(int);
};
}
#endif
#endif
+
+/* ERROR/WARNING messages:
+
+E: Dump file is incorrectly formatted
+
+Self-explanatory.
+
+E: Unexpected end of dump file
+
+A read operation from the file failed.
+
+*/
diff --git a/src/reader_xyz.h b/src/reader_xyz.h
index cdd760b5c..ad4b56c39 100644
--- a/src/reader_xyz.h
+++ b/src/reader_xyz.h
@@ -1,54 +1,66 @@
/* -*- c++ -*- ----------------------------------------------------------
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.
Contributed by Axel Kohlmeyer (Temple U)
------------------------------------------------------------------------- */
#ifdef READER_CLASS
ReaderStyle(xyz,ReaderXYZ)
#else
#ifndef LMP_READER_XYZ_H
#define LMP_READER_XYZ_H
#include "reader.h"
namespace LAMMPS_NS {
class ReaderXYZ : public Reader {
public:
ReaderXYZ(class LAMMPS *);
~ReaderXYZ();
int read_time(bigint &);
void skip();
bigint read_header(double [3][3], int &, int, int, int *, char **,
int, int &, int &, int &, int &);
void read_atoms(int, int, double **);
private:
char *line; // line read from dump file
bigint nstep; // current (time) step number
bigint natoms; // current number of atoms
bigint nid; // current atom id.
int *fieldindex; // mapping of input fields to dump
void read_lines(int);
};
}
#endif
#endif
+
+/* ERROR/WARNING messages:
+
+E: Dump file is incorrectly formatted
+
+Self-explanatory.
+
+E: Unexpected end of dump file
+
+A read operation from the file failed.
+
+*/
diff --git a/src/region.cpp b/src/region.cpp
index 56e8e8c80..a9d27e1a3 100644
--- a/src/region.cpp
+++ b/src/region.cpp
@@ -1,385 +1,386 @@
/* ----------------------------------------------------------------------
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 "region.h"
#include "update.h"
#include "domain.h"
#include "lattice.h"
#include "input.h"
#include "variable.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
Region::Region(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
{
int n = strlen(arg[0]) + 1;
id = new char[n];
strcpy(id,arg[0]);
n = strlen(arg[1]) + 1;
style = new char[n];
strcpy(style,arg[1]);
xstr = ystr = zstr = tstr = NULL;
dx = dy = dz = 0.0;
laststep = -1;
}
/* ---------------------------------------------------------------------- */
Region::~Region()
{
delete [] id;
delete [] style;
delete [] xstr;
delete [] ystr;
delete [] zstr;
delete [] tstr;
}
/* ---------------------------------------------------------------------- */
void Region::init()
{
if (xstr) {
xvar = input->variable->find(xstr);
if (xvar < 0) error->all(FLERR,"Variable name for region does not exist");
if (!input->variable->equalstyle(xvar))
error->all(FLERR,"Variable for region is invalid style");
}
if (ystr) {
yvar = input->variable->find(ystr);
if (yvar < 0) error->all(FLERR,"Variable name for region does not exist");
if (!input->variable->equalstyle(yvar))
error->all(FLERR,"Variable for region is not equal style");
}
if (zstr) {
zvar = input->variable->find(zstr);
if (zvar < 0) error->all(FLERR,"Variable name for region does not exist");
if (!input->variable->equalstyle(zvar))
error->all(FLERR,"Variable for region is not equal style");
}
if (tstr) {
tvar = input->variable->find(tstr);
if (tvar < 0) error->all(FLERR,"Variable name for region does not exist");
if (!input->variable->equalstyle(tvar))
error->all(FLERR,"Variable for region is not equal style");
}
}
/* ----------------------------------------------------------------------
return 1 if region is dynamic, 0 if static
only primitive regions define it here
union/intersect regions have their own dynamic_check()
------------------------------------------------------------------------- */
int Region::dynamic_check()
{
return dynamic;
}
/* ----------------------------------------------------------------------
determine if point x,y,z is a match to region volume
XOR computes 0 if 2 args are the same, 1 if different
note that inside() returns 1 for points on surface of region
thus point on surface of exterior region will not match
if region is dynamic, apply inverse transform to x,y,z
unmove first, then unrotate, so don't have to change rotation point
------------------------------------------------------------------------- */
int Region::match(double x, double y, double z)
{
if (dynamic) inverse_transform(x,y,z);
return !(inside(x,y,z) ^ interior);
}
/* ----------------------------------------------------------------------
generate list of contact points for interior or exterior regions
if region is dynamic:
before: inverse transform x,y,z (unmove, then unrotate)
after: forward transform contact point xs,yx,zs (rotate, then move),
then reset contact delx,dely,delz based on new contact point
no need to do this if no rotation since delxyz doesn't change
------------------------------------------------------------------------- */
int Region::surface(double x, double y, double z, double cutoff)
{
int ncontact;
double xs,ys,zs;
double xnear[3],xorig[3];
if (dynamic) {
xorig[0] = x;
xorig[1] = y;
xorig[2] = z;
inverse_transform(x,y,z);
}
xnear[0] = x;
xnear[1] = y;
xnear[2] = z;
if (interior) ncontact = surface_interior(xnear,cutoff);
else ncontact = surface_exterior(xnear,cutoff);
if (rotateflag && ncontact) {
for (int i = 0; i < ncontact; i++) {
xs = xnear[0] - contact[i].delx;
ys = xnear[1] - contact[i].dely;
zs = xnear[2] - contact[i].delz;
forward_transform(xs,ys,zs);
contact[i].delx = xorig[0] - xs;
contact[i].dely = xorig[1] - ys;
contact[i].delz = xorig[2] - zs;
}
}
return ncontact;
}
/* ----------------------------------------------------------------------
add a single contact at Nth location in contact array
x = particle position
xp,yp,zp = region surface point
------------------------------------------------------------------------- */
void Region::add_contact(int n, double *x, double xp, double yp, double zp)
{
double delx = x[0] - xp;
double dely = x[1] - yp;
double delz = x[2] - zp;
contact[n].r = sqrt(delx*delx + dely*dely + delz*delz);
contact[n].delx = delx;
contact[n].dely = dely;
contact[n].delz = delz;
}
/* ----------------------------------------------------------------------
transform a point x,y,z in region space to moved space
rotate first (around original P), then displace
------------------------------------------------------------------------- */
void Region::forward_transform(double &x, double &y, double &z)
{
if (rotateflag) {
if (update->ntimestep != laststep)
theta = input->variable->compute_equal(tvar);
rotate(x,y,z,theta);
}
if (moveflag) {
if (update->ntimestep != laststep) {
if (xstr) dx = input->variable->compute_equal(xvar);
if (ystr) dy = input->variable->compute_equal(yvar);
if (zstr) dz = input->variable->compute_equal(zvar);
}
x += dx;
y += dy;
z += dz;
}
laststep = update->ntimestep;
}
/* ----------------------------------------------------------------------
transform a point x,y,z in moved space back to region space
undisplace first, then unrotate (around original P)
------------------------------------------------------------------------- */
void Region::inverse_transform(double &x, double &y, double &z)
{
if (moveflag) {
if (update->ntimestep != laststep) {
if (xstr) dx = input->variable->compute_equal(xvar);
if (ystr) dy = input->variable->compute_equal(yvar);
if (zstr) dz = input->variable->compute_equal(zvar);
}
x -= dx;
y -= dy;
z -= dz;
}
if (rotateflag) {
if (update->ntimestep != laststep)
theta = input->variable->compute_equal(tvar);
rotate(x,y,z,-theta);
}
laststep = update->ntimestep;
}
/* ----------------------------------------------------------------------
rotate x,y,z by angle via right-hand rule around point and runit normal
sign of angle determines whether rotating forward/backward in time
return updated x,y,z
P = point = vector = point of rotation
R = vector = axis of rotation
w = omega of rotation (from period)
X0 = x,y,z = initial coord of atom
R0 = runit = unit vector for R
C = (X0 dot R0) R0 = projection of atom coord onto R
D = X0 - P = vector from P to X0
A = D - C = vector from R line to X0
B = R0 cross A = vector perp to A in plane of rotation
A,B define plane of circular rotation around R line
x,y,z = P + C + A cos(w*dt) + B sin(w*dt)
------------------------------------------------------------------------- */
void Region::rotate(double &x, double &y, double &z, double angle)
{
double a[3],b[3],c[3],d[3],disp[3];
double sine = sin(angle);
double cosine = cos(angle);
double x0dotr = x*runit[0] + y*runit[1] + z*runit[2];
c[0] = x0dotr * runit[0];
c[1] = x0dotr * runit[1];
c[2] = x0dotr * runit[2];
d[0] = x - point[0];
d[1] = y - point[1];
d[2] = z - point[2];
a[0] = d[0] - c[0];
a[1] = d[1] - c[1];
a[2] = d[2] - c[2];
b[0] = runit[1]*a[2] - runit[2]*a[1];
b[1] = runit[2]*a[0] - runit[0]*a[2];
b[2] = runit[0]*a[1] - runit[1]*a[0];
disp[0] = a[0]*cosine + b[0]*sine;
disp[1] = a[1]*cosine + b[1]*sine;
disp[2] = a[2]*cosine + b[2]*sine;
x = point[0] + c[0] + disp[0];
y = point[1] + c[1] + disp[1];
z = point[2] + c[2] + disp[2];
}
/* ----------------------------------------------------------------------
parse optional parameters at end of region input line
------------------------------------------------------------------------- */
void Region::options(int narg, char **arg)
{
if (narg < 0) error->all(FLERR,"Illegal region command");
// option defaults
interior = 1;
scaleflag = 1;
moveflag = rotateflag = 0;
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal region command");
if (strcmp(arg[iarg+1],"box") == 0) scaleflag = 0;
else if (strcmp(arg[iarg+1],"lattice") == 0) scaleflag = 1;
else error->all(FLERR,"Illegal region command");
iarg += 2;
} else if (strcmp(arg[iarg],"side") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal region command");
if (strcmp(arg[iarg+1],"in") == 0) interior = 1;
else if (strcmp(arg[iarg+1],"out") == 0) interior = 0;
else error->all(FLERR,"Illegal region command");
iarg += 2;
} else if (strcmp(arg[iarg],"move") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal region command");
if (strcmp(arg[iarg+1],"NULL") != 0) {
if (strstr(arg[iarg+1],"v_") != arg[iarg+1])
error->all(FLERR,"Illegal region command");
int n = strlen(&arg[iarg+1][2]) + 1;
xstr = new char[n];
strcpy(xstr,&arg[iarg+1][2]);
}
if (strcmp(arg[iarg+2],"NULL") != 0) {
if (strstr(arg[iarg+2],"v_") != arg[iarg+2])
error->all(FLERR,"Illegal region command");
int n = strlen(&arg[iarg+2][2]) + 1;
ystr = new char[n];
strcpy(ystr,&arg[iarg+2][2]);
}
if (strcmp(arg[iarg+3],"NULL") != 0) {
if (strstr(arg[iarg+3],"v_") != arg[iarg+3])
error->all(FLERR,"Illegal region command");
int n = strlen(&arg[iarg+3][2]) + 1;
zstr = new char[n];
strcpy(zstr,&arg[iarg+3][2]);
}
moveflag = 1;
iarg += 4;
} else if (strcmp(arg[iarg],"rotate") == 0) {
if (iarg+8 > narg) error->all(FLERR,"Illegal region command");
if (strstr(arg[iarg+1],"v_") != arg[iarg+1])
error->all(FLERR,"Illegal region command");
int n = strlen(&arg[iarg+1][2]) + 1;
tstr = new char[n];
strcpy(tstr,&arg[iarg+1][2]);
point[0] = atof(arg[iarg+2]);
point[1] = atof(arg[iarg+3]);
point[2] = atof(arg[iarg+4]);
axis[0] = atof(arg[iarg+5]);
axis[1] = atof(arg[iarg+6]);
axis[2] = atof(arg[iarg+7]);
rotateflag = 1;
iarg += 8;
} else error->all(FLERR,"Illegal region command");
}
// error check
if ((moveflag || rotateflag) &&
(strcmp(style,"union") == 0 || strcmp(style,"intersect") == 0))
error->all(FLERR,"Region union or intersect cannot be dynamic");
// setup scaling
if (scaleflag && domain->lattice == NULL)
error->all(FLERR,"Use of region with undefined lattice");
if (scaleflag) {
xscale = domain->lattice->xlattice;
yscale = domain->lattice->ylattice;
zscale = domain->lattice->zlattice;
}
else xscale = yscale = zscale = 1.0;
if (rotateflag) {
point[0] *= xscale;
point[1] *= yscale;
point[2] *= zscale;
}
// runit = unit vector along rotation axis
if (rotateflag) {
double len = sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]);
if (len == 0.0)
error->all(FLERR,"Region cannot have 0 length rotation vector");
runit[0] = axis[0]/len;
runit[1] = axis[1]/len;
runit[2] = axis[2]/len;
}
if (moveflag || rotateflag) dynamic = 1;
else dynamic = 0;
- // initialize variables
+ // initialize option variables in case region is used between runs
+
init();
}
diff --git a/src/replicate.cpp b/src/replicate.cpp
index 90101668b..0110659c5 100644
--- a/src/replicate.cpp
+++ b/src/replicate.cpp
@@ -1,403 +1,406 @@
/* ----------------------------------------------------------------------
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 "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
/* ---------------------------------------------------------------------- */
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(FLERR,"Replicate command before simulation box is defined");
if (narg != 3) error->all(FLERR,"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(FLERR,"Illegal replicate command");
if (domain->dimension == 2 && nz != 1)
error->all(FLERR,"Cannot replicate 2d simulation in z dimension");
if ((nx > 1 && domain->xperiodic == 0) ||
(ny > 1 && domain->yperiodic == 0) ||
(nz > 1 && domain->zperiodic == 0)) {
if (comm->me == 0)
error->warning(FLERR,"Replicating in a non-periodic dimension");
}
if (atom->nextra_grow || atom->nextra_restart || atom->nextra_store)
error->all(FLERR,"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;
memory->create(buf,max_size,"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 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))
+ // change these 2 to MAXTAGINT when allow tagint = bigint
+ if (atom->molecular && (nrep*old->natoms < 0 || nrep*old->natoms > MAXSMALLINT))
error->all(FLERR,"Replicated molecular system atom IDs are too big");
- if (nrep*old->natoms < 0 || nrep*old->natoms > MAXTAGINT)
+ if (nrep*old->natoms < 0 || nrep*old->natoms > MAXSMALLINT)
atom->tag_enable = 0;
if (atom->tag_enable == 0)
for (int i = 0; i < atom->nlocal; i++)
atom->tag[i] = 0;
if (nrep*old->natoms < 0 || nrep*old->natoms > MAXBIGINT ||
nrep*old->nbonds < 0 || nrep*old->nbonds > MAXBIGINT ||
nrep*old->nangles < 0 || nrep*old->nangles > MAXBIGINT ||
nrep*old->ndihedrals < 0 || nrep*old->ndihedrals > MAXBIGINT ||
nrep*old->nimpropers < 0 || nrep*old->nimpropers > MAXBIGINT)
error->all(FLERR,"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_proc_grid();
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];
}
}
// 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 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] += epsilon[0];
}
if (domain->yperiodic) {
if (comm->myloc[1] == 0) sublo[1] -= epsilon[1];
if (comm->myloc[1] == comm->procgrid[1]-1) subhi[1] += epsilon[1];
}
if (domain->zperiodic) {
if (comm->myloc[2] == 0) sublo[2] -= epsilon[2];
if (comm->myloc[2] == comm->procgrid[2]-1) subhi[2] += epsilon[2];
}
// 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;
+ int ix,iy,iz,atom_offset,mol_offset;
+ tagint image;
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;
+ image = ((tagint) IMGMAX << IMG2BITS) |
+ ((tagint) IMGMASK << IMGBITS) | IMGMAX;
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]);
}
}
}
}
}
// free communication buffer and old atom class
memory->destroy(buf);
delete old;
// check that all atoms were assigned to procs
bigint natoms;
bigint nblocal = atom->nlocal;
MPI_Allreduce(&nblocal,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world);
if (me == 0) {
if (screen) fprintf(screen," " BIGINT_FORMAT " atoms\n",natoms);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms);
}
if (natoms != atom->natoms)
error->all(FLERR,"Replicate did not assign all atoms correctly");
if (me == 0) {
if (atom->nbonds) {
if (screen) fprintf(screen," " BIGINT_FORMAT " bonds\n",atom->nbonds);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " bonds\n",atom->nbonds);
}
if (atom->nangles) {
if (screen) fprintf(screen," " BIGINT_FORMAT " angles\n",
atom->nangles);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " angles\n",
atom->nangles);
}
if (atom->ndihedrals) {
if (screen) fprintf(screen," " BIGINT_FORMAT " dihedrals\n",
atom->ndihedrals);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " dihedrals\n",
atom->ndihedrals);
}
if (atom->nimpropers) {
if (screen) fprintf(screen," " BIGINT_FORMAT " impropers\n",
atom->nimpropers);
if (logfile) fprintf(logfile," " BIGINT_FORMAT " impropers\n",
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/rerun.h b/src/rerun.h
index 2cca80824..ae47fe617 100644
--- a/src/rerun.h
+++ b/src/rerun.h
@@ -1,36 +1,55 @@
/* ----------------------------------------------------------------------
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 COMMAND_CLASS
CommandStyle(rerun,Rerun)
#else
#ifndef LMP_RERUN_H
#define LMP_RERUN_H
#include "pointers.h"
namespace LAMMPS_NS {
class Rerun : protected Pointers {
public:
Rerun(class LAMMPS *);
void command(int, char **);
};
}
#endif
#endif
+
+/* ERROR/WARNING messages:
+
+E: Illegal ... command
+
+Self-explanatory. Check the input script syntax and compare to the
+documentation for the command. You can use -echo screen as a
+command-line option when running LAMMPS to see the offending line.
+
+E: Rerun command before simulation box is defined
+
+The rerun command cannot be used before a read_data, read_restart, or
+create_box command.
+
+E: Rerun dump file does not contain requested snapshot
+
+Self-explanatory.
+
+*/
diff --git a/src/respa.h b/src/respa.h
index b5f5fbba1..85c200432 100644
--- a/src/respa.h
+++ b/src/respa.h
@@ -1,129 +1,138 @@
/* -*- c++ -*- ----------------------------------------------------------
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 INTEGRATE_CLASS
IntegrateStyle(respa,Respa)
#else
#ifndef LMP_RESPA_H
#define LMP_RESPA_H
#include "integrate.h"
namespace LAMMPS_NS {
class Respa : public Integrate {
public:
// public so Fixes, Pairs, Neighbor can see them
int nlevels; // number of rRESPA levels
// 0 = innermost level, nlevels-1 = outermost level
double *step; // timestep at each level
int *loop; // sub-cycling factor at each level
double cutoff[4]; // cutoff[0] and cutoff[1] = between inner and middle
// cutoff[2] and cutoff[3] = between middle and outer
// if no middle then 0,1 = 2,3
int level_bond,level_angle,level_dihedral; // level to compute forces at
int level_improper,level_pair,level_kspace;
int level_inner,level_middle,level_outer;
Respa(class LAMMPS *, int, char **);
~Respa();
void init();
void setup();
void setup_minimal(int);
void run(int);
void cleanup();
void reset_dt();
void copy_f_flevel(int);
void copy_flevel_f(int);
private:
int triclinic; // 0 if domain is orthog, 1 if triclinic
int torqueflag,erforceflag;
int e_flag,rho_flag;
int *newton; // newton flag at each level
class FixRespa *fix_respa; // Fix to store the force level array
void recurse(int);
void force_clear(int);
void sum_flevel_f();
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Respa levels must be >= 1
Self-explanatory.
E: Cannot set both respa pair and inner/middle/outer
In the rRESPA integrator, you must compute pairwise potentials either
all together (pair), or in pieces (inner/middle/outer). You can't do
both.
E: Must set both respa inner and outer
Cannot use just the inner or outer option with respa without using the
other.
E: Cannot set respa middle without inner/outer
In the rRESPA integrator, you must define both a inner and outer
setting in order to use a middle setting.
E: Invalid order of forces within respa levels
For respa, ordering of force computations within respa levels must
obey certain rules. E.g. bonds cannot be compute less frequently than
angles, pairwise forces cannot be computed less frequently than
kspace, etc.
W: One or more respa levels compute no forces
This is computationally inefficient.
E: Respa inner cutoffs are invalid
The first cutoff must be <= the second cutoff.
E: Respa middle cutoffs are invalid
The first cutoff must be <= the second cutoff.
W: No fixes defined, atoms won't move
If you are not using a fix like nve, nvt, npt then atom velocities and
coordinates will not be updated during timestepping.
+W: Fix shake with rRESPA computes invalid pressures
+
+This is a known bug in LAMMPS that has not yet been fixed. If you use
+SHAKE with rRESPA and perform a constant volume simulation (e.g. using
+fix npt) this only affects the output pressure, not the dynamics of
+the simulation. If you use SHAKE with rRESPA and perform a constant
+pressure simulation (e.g. using fix npt) then you will be
+equilibrating to the wrong volume.
+
E: Pair style does not support rRESPA inner/middle/outer
You are attempting to use rRESPA options with a pair style that
does not support them.
*/
diff --git a/src/set.cpp b/src/set.cpp
index eaa34538b..4105f4a2f 100644
--- a/src/set.cpp
+++ b/src/set.cpp
@@ -1,775 +1,776 @@
/* ----------------------------------------------------------------------
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 "set.h"
#include "atom.h"
#include "atom_vec.h"
#include "atom_vec_ellipsoid.h"
#include "atom_vec_line.h"
#include "atom_vec_tri.h"
#include "domain.h"
#include "region.h"
#include "group.h"
#include "comm.h"
#include "neighbor.h"
#include "force.h"
#include "pair.h"
#include "random_park.h"
#include "math_extra.h"
#include "math_const.h"
#include "error.h"
using namespace LAMMPS_NS;
using namespace MathConst;
enum{ATOM_SELECT,MOL_SELECT,TYPE_SELECT,GROUP_SELECT,REGION_SELECT};
enum{TYPE,TYPE_FRACTION,MOLECULE,X,Y,Z,CHARGE,MASS,SHAPE,LENGTH,TRI,
DIPOLE,DIPOLE_RANDOM,QUAT,QUAT_RANDOM,THETA,ANGMOM,
DIAMETER,DENSITY,VOLUME,IMAGE,BOND,ANGLE,DIHEDRAL,IMPROPER,
MESO_E,MESO_CV,MESO_RHO};
#define BIG INT_MAX
/* ---------------------------------------------------------------------- */
void Set::command(int narg, char **arg)
{
if (domain->box_exist == 0)
error->all(FLERR,"Set command before simulation box is defined");
if (atom->natoms == 0)
error->all(FLERR,"Set command with no atoms existing");
if (narg < 3) error->all(FLERR,"Illegal set command");
// style and ID info
if (strcmp(arg[0],"atom") == 0) style = ATOM_SELECT;
else if (strcmp(arg[0],"mol") == 0) style = MOL_SELECT;
else if (strcmp(arg[0],"type") == 0) style = TYPE_SELECT;
else if (strcmp(arg[0],"group") == 0) style = GROUP_SELECT;
else if (strcmp(arg[0],"region") == 0) style = REGION_SELECT;
else error->all(FLERR,"Illegal set command");
int n = strlen(arg[1]) + 1;
id = new char[n];
strcpy(id,arg[1]);
select = NULL;
// loop over keyword/value pairs
// call appropriate routine to reset attributes
if (comm->me == 0 && screen) fprintf(screen,"Setting atom values ...\n");
int allcount,origarg;
int iarg = 2;
while (iarg < narg) {
count = 0;
origarg = iarg;
if (strcmp(arg[iarg],"type") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
ivalue = atoi(arg[iarg+1]);
if (ivalue <= 0 || ivalue > atom->ntypes)
error->all(FLERR,"Invalid value in set command");
set(TYPE);
iarg += 2;
} else if (strcmp(arg[iarg],"type/fraction") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal set command");
newtype = atoi(arg[iarg+1]);
fraction = atof(arg[iarg+2]);
ivalue = atoi(arg[iarg+3]);
if (newtype <= 0 || newtype > atom->ntypes)
error->all(FLERR,"Invalid value in set command");
if (fraction < 0.0 || fraction > 1.0)
error->all(FLERR,"Invalid value in set command");
if (ivalue <= 0)
error->all(FLERR,"Invalid random number seed in set command");
setrandom(TYPE_FRACTION);
iarg += 4;
} else if (strcmp(arg[iarg],"mol") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
ivalue = atoi(arg[iarg+1]);
if (!atom->molecule_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
set(MOLECULE);
iarg += 2;
} else if (strcmp(arg[iarg],"x") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
set(X);
iarg += 2;
} else if (strcmp(arg[iarg],"y") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
set(Y);
iarg += 2;
} else if (strcmp(arg[iarg],"z") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
set(Z);
iarg += 2;
} else if (strcmp(arg[iarg],"charge") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
if (!atom->q_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
set(CHARGE);
iarg += 2;
} else if (strcmp(arg[iarg],"mass") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
if (!atom->rmass_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (dvalue <= 0.0) error->all(FLERR,"Invalid mass in set command");
set(MASS);
iarg += 2;
} else if (strcmp(arg[iarg],"shape") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal set command");
xvalue = atof(arg[iarg+1]);
yvalue = atof(arg[iarg+2]);
zvalue = atof(arg[iarg+3]);
if (!atom->ellipsoid_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (xvalue < 0.0 || yvalue < 0.0 || zvalue < 0.0)
error->all(FLERR,"Invalid shape in set command");
if (xvalue > 0.0 || yvalue > 0.0 || zvalue > 0.0) {
if (xvalue == 0.0 || yvalue == 0.0 || zvalue == 0.0)
error->one(FLERR,"Invalid shape in set command");
}
set(SHAPE);
iarg += 4;
} else if (strcmp(arg[iarg],"length") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
if (!atom->line_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (dvalue < 0.0) error->all(FLERR,"Invalid length in set command");
set(LENGTH);
iarg += 2;
} else if (strcmp(arg[iarg],"tri") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
if (!atom->tri_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (dvalue < 0.0) error->all(FLERR,"Invalid length in set command");
set(TRI);
iarg += 2;
} else if (strcmp(arg[iarg],"dipole") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal set command");
xvalue = atof(arg[iarg+1]);
yvalue = atof(arg[iarg+2]);
zvalue = atof(arg[iarg+3]);
if (!atom->mu_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
set(DIPOLE);
iarg += 4;
} else if (strcmp(arg[iarg],"dipole/random") == 0) {
if (iarg+3 > narg) error->all(FLERR,"Illegal set command");
ivalue = atoi(arg[iarg+1]);
dvalue = atof(arg[iarg+2]);
if (!atom->mu_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (ivalue <= 0)
error->all(FLERR,"Invalid random number seed in set command");
if (dvalue <= 0.0)
error->all(FLERR,"Invalid dipole length in set command");
setrandom(DIPOLE_RANDOM);
iarg += 3;
} else if (strcmp(arg[iarg],"quat") == 0) {
if (iarg+5 > narg) error->all(FLERR,"Illegal set command");
xvalue = atof(arg[iarg+1]);
yvalue = atof(arg[iarg+2]);
zvalue = atof(arg[iarg+3]);
wvalue = atof(arg[iarg+4]);
if (!atom->ellipsoid_flag && !atom->tri_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
set(QUAT);
iarg += 5;
} else if (strcmp(arg[iarg],"quat/random") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
ivalue = atoi(arg[iarg+1]);
if (!atom->ellipsoid_flag && !atom->tri_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (ivalue <= 0)
error->all(FLERR,"Invalid random number seed in set command");
setrandom(QUAT_RANDOM);
iarg += 2;
} else if (strcmp(arg[iarg],"theta") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
dvalue *= MY_PI/180.0;
if (!atom->line_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
set(THETA);
iarg += 2;
} else if (strcmp(arg[iarg],"angmom") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal set command");
xvalue = atof(arg[iarg+1]);
yvalue = atof(arg[iarg+2]);
zvalue = atof(arg[iarg+3]);
if (!atom->ellipsoid_flag && !atom->tri_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
set(ANGMOM);
iarg += 4;
} else if (strcmp(arg[iarg],"diameter") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
if (!atom->radius_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (dvalue < 0.0) error->all(FLERR,"Invalid diameter in set command");
set(DIAMETER);
iarg += 2;
} else if (strcmp(arg[iarg],"density") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
if (!atom->rmass_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
set(DENSITY);
iarg += 2;
} else if (strcmp(arg[iarg],"volume") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
if (!atom->vfrac_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
set(VOLUME);
iarg += 2;
} else if (strcmp(arg[iarg],"image") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal set command");
ximageflag = yimageflag = zimageflag = 0;
if (strcmp(arg[iarg+1],"NULL") != 0) {
ximageflag = 1;
ximage = atoi(arg[iarg+1]);
}
if (strcmp(arg[iarg+2],"NULL") != 0) {
yimageflag = 1;
yimage = atoi(arg[iarg+2]);
}
if (strcmp(arg[iarg+3],"NULL") != 0) {
zimageflag = 1;
zimage = atoi(arg[iarg+3]);
}
if (ximageflag && ximage && !domain->xperiodic)
error->all(FLERR,
"Cannot set non-zero image flag for non-periodic dimension");
if (yimageflag && yimage && !domain->yperiodic)
error->all(FLERR,
"Cannot set non-zero image flag for non-periodic dimension");
if (zimageflag && zimage && !domain->zperiodic)
error->all(FLERR,
"Cannot set non-zero image flag for non-periodic dimension");
set(IMAGE);
iarg += 4;
} else if (strcmp(arg[iarg],"bond") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
ivalue = atoi(arg[iarg+1]);
if (atom->avec->bonds_allow == 0)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (ivalue <= 0 || ivalue > atom->nbondtypes)
error->all(FLERR,"Invalid value in set command");
topology(BOND);
iarg += 2;
} else if (strcmp(arg[iarg],"angle") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
ivalue = atoi(arg[iarg+1]);
if (atom->avec->angles_allow == 0)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (ivalue <= 0 || ivalue > atom->nangletypes)
error->all(FLERR,"Invalid value in set command");
topology(ANGLE);
iarg += 2;
} else if (strcmp(arg[iarg],"dihedral") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
ivalue = atoi(arg[iarg+1]);
if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (ivalue <= 0 || ivalue > atom->ndihedraltypes)
error->all(FLERR,"Invalid value in set command");
topology(DIHEDRAL);
iarg += 2;
} else if (strcmp(arg[iarg],"improper") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
ivalue = atoi(arg[iarg+1]);
if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Cannot set this attribute for this atom style");
if (ivalue <= 0 || ivalue > atom->nimpropertypes)
error->all(FLERR,"Invalid value in set command");
topology(IMPROPER);
iarg += 2;
} else if (strcmp(arg[iarg],"meso_e") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
if (!atom->e_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
set(MESO_E);
iarg += 2;
} else if (strcmp(arg[iarg],"meso_cv") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
if (!atom->cv_flag)
error->all(FLERR,"Cannot set this attribute for this atom style");
set(MESO_CV);
iarg += 2;
} else if (strcmp(arg[iarg],"meso_rho") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal set command");
dvalue = atof(arg[iarg+1]);
if (!atom->rho_flag)
error->all(FLERR,"Cannot set meso_rho for this atom style");
set(MESO_RHO);
iarg += 2;
} else error->all(FLERR,"Illegal set command");
// statistics
MPI_Allreduce(&count,&allcount,1,MPI_INT,MPI_SUM,world);
if (comm->me == 0) {
if (screen) fprintf(screen," %d settings made for %s\n",
allcount,arg[origarg]);
if (logfile) fprintf(logfile," %d settings made for %s\n",
allcount,arg[origarg]);
}
}
// free local memory
delete [] id;
delete [] select;
}
/* ----------------------------------------------------------------------
select atoms according to ATOM, MOLECULE, TYPE, GROUP, REGION style
n = nlocal or nlocal+nghost depending on keyword
------------------------------------------------------------------------- */
void Set::selection(int n)
{
delete [] select;
select = new int[n];
int nlo,nhi;
if (style == ATOM_SELECT) {
if (atom->tag_enable == 0)
error->all(FLERR,"Cannot use set atom with no atom IDs defined");
force->bounds(id,BIG,nlo,nhi);
int *tag = atom->tag;
for (int i = 0; i < n; i++)
if (tag[i] >= nlo && tag[i] <= nhi) select[i] = 1;
else select[i] = 0;
} else if (style == MOL_SELECT) {
if (atom->molecule_flag == 0)
error->all(FLERR,"Cannot use set mol with no molecule IDs defined");
if (strcmp(id,"0") == 0) nlo = nhi = 0;
else force->bounds(id,BIG,nlo,nhi);
int *molecule = atom->molecule;
for (int i = 0; i < n; i++)
if (molecule[i] >= nlo && molecule[i] <= nhi) select[i] = 1;
else select[i] = 0;
} else if (style == TYPE_SELECT) {
force->bounds(id,atom->ntypes,nlo,nhi);
int *type = atom->type;
for (int i = 0; i < n; i++)
if (type[i] >= nlo && type[i] <= nhi) select[i] = 1;
else select[i] = 0;
} else if (style == GROUP_SELECT) {
int igroup = group->find(id);
if (igroup == -1) error->all(FLERR,"Could not find set group ID");
int groupbit = group->bitmask[igroup];
int *mask = atom->mask;
for (int i = 0; i < n; i++)
if (mask[i] & groupbit) select[i] = 1;
else select[i] = 0;
} else if (style == REGION_SELECT) {
int iregion = domain->find_region(id);
if (iregion == -1) error->all(FLERR,"Set region ID does not exist");
double **x = atom->x;
for (int i = 0; i < n; i++)
if (domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
select[i] = 1;
else select[i] = 0;
}
}
/* ----------------------------------------------------------------------
set an owned atom property directly
------------------------------------------------------------------------- */
void Set::set(int keyword)
{
AtomVecEllipsoid *avec_ellipsoid =
(AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecLine *avec_line = (AtomVecLine *) atom->style_match("line");
AtomVecTri *avec_tri = (AtomVecTri *) atom->style_match("tri");
selection(atom->nlocal);
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (!select[i]) continue;
if (keyword == TYPE) atom->type[i] = ivalue;
else if (keyword == MOLECULE) atom->molecule[i] = ivalue;
else if (keyword == X) atom->x[i][0] = dvalue;
else if (keyword == Y) atom->x[i][1] = dvalue;
else if (keyword == Z) atom->x[i][2] = dvalue;
else if (keyword == CHARGE) atom->q[i] = dvalue;
else if (keyword == MASS) atom->rmass[i] = dvalue;
else if (keyword == DIAMETER) atom->radius[i] = 0.5 * dvalue;
else if (keyword == VOLUME) atom->vfrac[i] = dvalue;
else if (keyword == MESO_E) atom->e[i] = dvalue;
else if (keyword == MESO_CV) atom->cv[i] = dvalue;
else if (keyword == MESO_RHO) atom->rho[i] = dvalue;
// set shape of ellipsoidal particle
else if (keyword == SHAPE)
avec_ellipsoid->set_shape(i,0.5*xvalue,0.5*yvalue,0.5*zvalue);
// set length of line particle
else if (keyword == LENGTH)
avec_line->set_length(i,dvalue);
// set corners of tri particle
else if (keyword == TRI)
avec_tri->set_equilateral(i,dvalue);
// set rmass via density
// if radius > 0.0, treat as sphere
// if shape > 0.0, treat as ellipsoid
// if length > 0.0, treat as line
// if area > 0.0, treat as tri
// else set rmass to density directly
else if (keyword == DENSITY) {
if (atom->radius_flag && atom->radius[i] > 0.0)
atom->rmass[i] = 4.0*MY_PI/3.0 *
atom->radius[i]*atom->radius[i]*atom->radius[i] * dvalue;
else if (atom->ellipsoid_flag && atom->ellipsoid[i] >= 0) {
double *shape = avec_ellipsoid->bonus[atom->ellipsoid[i]].shape;
atom->rmass[i] = 4.0*MY_PI/3.0 * shape[0]*shape[1]*shape[2] * dvalue;
} else if (atom->line_flag && atom->line[i] >= 0) {
double length = avec_line->bonus[atom->line[i]].length;
atom->rmass[i] = length * dvalue;
} else if (atom->tri_flag && atom->tri[i] >= 0) {
double *c1 = avec_tri->bonus[atom->tri[i]].c1;
double *c2 = avec_tri->bonus[atom->tri[i]].c2;
double *c3 = avec_tri->bonus[atom->tri[i]].c3;
double c2mc1[2],c3mc1[3];
MathExtra::sub3(c2,c1,c2mc1);
MathExtra::sub3(c3,c1,c3mc1);
double norm[3];
MathExtra::cross3(c2mc1,c3mc1,norm);
double area = 0.5 * MathExtra::len3(norm);
atom->rmass[i] = area * dvalue;
} else atom->rmass[i] = dvalue;
// reset any or all of 3 image flags
} else if (keyword == IMAGE) {
- int xbox = (atom->image[i] & 1023) - 512;
- int ybox = (atom->image[i] >> 10 & 1023) - 512;
- int zbox = (atom->image[i] >> 20) - 512;
+ int xbox = (atom->image[i] & IMGMASK) - IMGMAX;
+ int ybox = (atom->image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ int zbox = (atom->image[i] >> IMG2BITS) - IMGMAX;
if (ximageflag) xbox = ximage;
if (yimageflag) ybox = yimage;
if (zimageflag) zbox = zimage;
- atom->image[i] = ((zbox + 512 & 1023) << 20) |
- ((ybox + 512 & 1023) << 10) | (xbox + 512 & 1023);
+ atom->image[i] = ((zbox + (tagint) IMGMAX & IMGMASK) << IMG2BITS) |
+ ((ybox + (tagint) IMGMAX & IMGMASK) << IMGBITS) |
+ (xbox + IMGMAX & IMGMASK);
// set dipole moment
} else if (keyword == DIPOLE) {
double **mu = atom->mu;
mu[i][0] = xvalue;
mu[i][1] = yvalue;
mu[i][2] = zvalue;
mu[i][3] = sqrt(mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] +
mu[i][2]*mu[i][2]);
// set quaternion orientation of ellipsoid or tri particle
} else if (keyword == QUAT) {
double *quat;
if (avec_ellipsoid && atom->ellipsoid[i] >= 0)
quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat;
else if (avec_tri && atom->tri[i] >= 0)
quat = avec_tri->bonus[atom->tri[i]].quat;
else
error->one(FLERR,"Cannot set quaternion for atom that has none");
double theta2 = MY_PI2 * wvalue/180.0;
double sintheta2 = sin(theta2);
quat[0] = cos(theta2);
quat[1] = xvalue * sintheta2;
quat[2] = yvalue * sintheta2;
quat[3] = zvalue * sintheta2;
MathExtra::qnormalize(quat);
// set theta of line particle
} else if (keyword == THETA) {
if (atom->line[i] < 0)
error->one(FLERR,"Cannot set theta for atom that is not a line");
avec_line->bonus[atom->line[i]].theta = dvalue;
// set angmom of ellipsoidal or tri particle
} else if (keyword == ANGMOM) {
atom->angmom[i][0] = xvalue;
atom->angmom[i][1] = yvalue;
atom->angmom[i][2] = zvalue;
}
count++;
}
}
/* ----------------------------------------------------------------------
set an owned atom property randomly
set seed based on atom tag
make atom result independent of what proc owns it
------------------------------------------------------------------------- */
void Set::setrandom(int keyword)
{
int i;
AtomVecEllipsoid *avec_ellipsoid =
(AtomVecEllipsoid *) atom->style_match("ellipsoid");
AtomVecLine *avec_line = (AtomVecLine *) atom->style_match("line");
AtomVecTri *avec_tri = (AtomVecTri *) atom->style_match("tri");
selection(atom->nlocal);
RanPark *random = new RanPark(lmp,1);
double **x = atom->x;
int seed = ivalue;
// set fraction of atom types to newtype
if (keyword == TYPE_FRACTION) {
int nlocal = atom->nlocal;
for (i = 0; i < nlocal; i++)
if (select[i]) {
random->reset(seed,x[i]);
if (random->uniform() > fraction) continue;
atom->type[i] = newtype;
count++;
}
// set dipole moments to random orientations in 3d or 2d
// dipole length is determined by dipole type array
} else if (keyword == DIPOLE_RANDOM) {
double **mu = atom->mu;
int nlocal = atom->nlocal;
double msq,scale;
if (domain->dimension == 3) {
for (i = 0; i < nlocal; i++)
if (select[i]) {
random->reset(seed,x[i]);
mu[i][0] = random->uniform() - 0.5;
mu[i][1] = random->uniform() - 0.5;
mu[i][2] = random->uniform() - 0.5;
msq = mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1] + mu[i][2]*mu[i][2];
scale = dvalue/sqrt(msq);
mu[i][0] *= scale;
mu[i][1] *= scale;
mu[i][2] *= scale;
mu[i][3] = dvalue;
count++;
}
} else {
for (i = 0; i < nlocal; i++)
if (select[i]) {
random->reset(seed,x[i]);
mu[i][0] = random->uniform() - 0.5;
mu[i][1] = random->uniform() - 0.5;
mu[i][2] = 0.0;
msq = mu[i][0]*mu[i][0] + mu[i][1]*mu[i][1];
scale = dvalue/sqrt(msq);
mu[i][0] *= scale;
mu[i][1] *= scale;
mu[i][3] = dvalue;
count++;
}
}
// set quaternions to random orientations in 3d or 2d
} else if (keyword == QUAT_RANDOM) {
int *ellipsoid = atom->ellipsoid;
int *tri = atom->tri;
int nlocal = atom->nlocal;
double *quat;
if (domain->dimension == 3) {
double s,t1,t2,theta1,theta2;
for (i = 0; i < nlocal; i++)
if (select[i]) {
if (avec_ellipsoid && atom->ellipsoid[i] >= 0)
quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat;
else if (avec_tri && atom->tri[i] >= 0)
quat = avec_tri->bonus[atom->tri[i]].quat;
else
error->one(FLERR,"Cannot set quaternion for atom that has none");
random->reset(seed,x[i]);
s = random->uniform();
t1 = sqrt(1.0-s);
t2 = sqrt(s);
theta1 = 2.0*MY_PI*random->uniform();
theta2 = 2.0*MY_PI*random->uniform();
quat[0] = cos(theta2)*t2;
quat[1] = sin(theta1)*t1;
quat[2] = cos(theta1)*t1;
quat[3] = sin(theta2)*t2;
count++;
}
} else {
double theta2;
for (i = 0; i < nlocal; i++)
if (select[i]) {
if (avec_ellipsoid && atom->ellipsoid[i] >= 0)
quat = avec_ellipsoid->bonus[atom->ellipsoid[i]].quat;
else
error->one(FLERR,"Cannot set quaternion for atom that has none");
random->reset(seed,x[i]);
theta2 = MY_PI*random->uniform();
quat[0] = cos(theta2);
quat[1] = 0.0;
quat[2] = 0.0;
quat[3] = sin(theta2);
count++;
}
}
}
delete random;
}
/* ---------------------------------------------------------------------- */
void Set::topology(int keyword)
{
int m,atom1,atom2,atom3,atom4;
// border swap to acquire ghost atom info
// enforce PBC before in case atoms are outside box
// init entire system since comm->exchange is done
// comm::init needs neighbor::init needs pair::init needs kspace::init, etc
if (comm->me == 0 && screen) fprintf(screen," system init for set ...\n");
lmp->init();
if (domain->triclinic) domain->x2lamda(atom->nlocal);
domain->pbc();
domain->reset_box();
comm->setup();
comm->exchange();
comm->borders();
if (domain->triclinic) domain->lamda2x(atom->nlocal+atom->nghost);
// select both owned and ghost atoms
selection(atom->nlocal + atom->nghost);
// for BOND, each of 2 atoms must be in group
if (keyword == BOND) {
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
for (m = 0; m < atom->num_bond[i]; m++) {
atom1 = atom->map(atom->bond_atom[i][m]);
if (atom1 == -1) error->one(FLERR,"Bond atom missing in set command");
if (select[i] && select[atom1]) {
atom->bond_type[i][m] = ivalue;
count++;
}
}
}
// for ANGLE, each of 3 atoms must be in group
if (keyword == ANGLE) {
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
for (m = 0; m < atom->num_angle[i]; m++) {
atom1 = atom->map(atom->angle_atom1[i][m]);
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(FLERR,"Angle atom missing in set command");
if (select[atom1] && select[atom2] && select[atom3]) {
atom->angle_type[i][m] = ivalue;
count++;
}
}
}
// for DIHEDRAL, each of 4 atoms must be in group
if (keyword == DIHEDRAL) {
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
for (m = 0; m < atom->num_dihedral[i]; m++) {
atom1 = atom->map(atom->dihedral_atom1[i][m]);
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(FLERR,"Dihedral atom missing in set command");
if (select[atom1] && select[atom2] && select[atom3] && select[atom4]) {
atom->dihedral_type[i][m] = ivalue;
count++;
}
}
}
// for IMPROPER, each of 4 atoms must be in group
if (keyword == IMPROPER) {
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++)
for (m = 0; m < atom->num_improper[i]; m++) {
atom1 = atom->map(atom->improper_atom1[i][m]);
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(FLERR,"Improper atom missing in set command");
if (select[atom1] && select[atom2] && select[atom3] && select[atom4]) {
atom->improper_type[i][m] = ivalue;
count++;
}
}
}
}
diff --git a/src/update.cpp b/src/update.cpp
index 1eda53689..b502822c8 100644
--- a/src/update.cpp
+++ b/src/update.cpp
@@ -1,413 +1,413 @@
/* ----------------------------------------------------------------------
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 "integrate.h"
#include "min.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)
{
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");
integrate_style = NULL;
integrate = NULL;
minimize_style = NULL;
minimize = NULL;
if (lmp->cuda) {
str = (char *) "verlet/cuda";
create_integrate(1,&str,NULL);
} else {
str = (char *) "verlet";
create_integrate(1,&str,NULL);
}
str = (char *) "cg";
create_minimize(1,&str);
}
/* ---------------------------------------------------------------------- */
Update::~Update()
{
delete [] unit_style;
delete [] integrate_style;
delete integrate;
delete [] minimize_style;
delete minimize;
}
/* ---------------------------------------------------------------------- */
void Update::init()
{
// if USER-CUDA mode is enabled:
// integrate/minimize style must be CUDA variant
if (whichflag == 1 && lmp->cuda)
if (strstr(integrate_style,"cuda") == NULL)
error->all(FLERR,"USER-CUDA mode requires CUDA variant of run style");
if (whichflag == 2 && lmp->cuda)
if (strstr(minimize_style,"cuda") == NULL)
error->all(FLERR,"USER-CUDA mode requires CUDA variant of min style");
// 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->hplanck = 0.18292026; // using LJ parameters for argon
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;
force->e_mass = 0.0; // not yet set
force->hhmrr2e = 0.0;
force->mvh2r = 0.0;
force->angstrom = 1.0;
force->femtosecond = 1.0;
force->qelectron = 1.0;
dt = 0.005;
neighbor->skin = 0.3;
} else if (strcmp(style,"real") == 0) {
force->boltz = 0.0019872067;
force->hplanck = 95.306976368;
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;
force->e_mass = 1.0/1836.1527556560675;
force->hhmrr2e = 0.0957018663603261;
force->mvh2r = 1.5339009481951;
force->angstrom = 1.0;
force->femtosecond = 1.0;
force->qelectron = 1.0;
dt = 1.0;
neighbor->skin = 2.0;
} else if (strcmp(style,"metal") == 0) {
force->boltz = 8.617343e-5;
force->hplanck = 4.135667403e-3;
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;
force->e_mass = 0.0; // not yet set
force->hhmrr2e = 0.0;
force->mvh2r = 0.0;
force->angstrom = 1.0;
force->femtosecond = 1.0e-3;
force->qelectron = 1.0;
dt = 0.001;
neighbor->skin = 2.0;
} else if (strcmp(style,"si") == 0) {
force->boltz = 1.3806504e-23;
force->hplanck = 6.62606896e-34;
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;
force->e_mass = 0.0; // not yet set
force->hhmrr2e = 0.0;
force->mvh2r = 0.0;
force->angstrom = 1.0e-10;
force->femtosecond = 1.0e-15;
force->qelectron = 1.6021765e-19;
dt = 1.0e-8;
neighbor->skin = 0.001;
} else if (strcmp(style,"cgs") == 0) {
force->boltz = 1.3806504e-16;
force->hplanck = 6.62606896e-27;
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;
force->e_mass = 0.0; // not yet set
force->hhmrr2e = 0.0;
force->mvh2r = 0.0;
force->angstrom = 1.0e-8;
force->femtosecond = 1.0e-15;
force->qelectron = 4.8032044e-10;
dt = 1.0e-8;
neighbor->skin = 0.1;
} else if (strcmp(style,"electron") == 0) {
force->boltz = 3.16681534e-6;
force->hplanck = 0.1519829846;
force->mvv2e = 1.06657236;
force->ftm2v = 0.937582899;
force->mv2d = 1.0;
force->nktv2p = 2.94210108e13;
force->qqr2e = 1.0;
force->qe2f = 1.94469051e-10;
force->vxmu2f = 3.39893149e1;
force->xxt2kmu = 3.13796367e-2;
force->e_mass = 0.0; // not yet set
force->hhmrr2e = 0.0;
force->mvh2r = 0.0;
force->angstrom = 1.88972612;
force->femtosecond = 0.0241888428;
force->qelectron = 1.0;
dt = 0.001;
neighbor->skin = 2.0;
} else error->all(FLERR,"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, char *suffix)
{
if (narg < 1) error->all(FLERR,"Illegal run_style command");
delete [] integrate_style;
delete integrate;
int sflag;
new_integrate(arg[0],narg-1,&arg[1],suffix,sflag);
if (sflag) {
char estyle[256];
sprintf(estyle,"%s/%s",arg[0],suffix);
int n = strlen(estyle) + 1;
integrate_style = new char[n];
strcpy(integrate_style,estyle);
} else {
int n = strlen(arg[0]) + 1;
integrate_style = new char[n];
strcpy(integrate_style,arg[0]);
}
}
/* ----------------------------------------------------------------------
create the Integrate style, first with suffix appended
------------------------------------------------------------------------- */
void Update::new_integrate(char *style, int narg, char **arg,
char *suffix, int &sflag)
{
int success = 0;
if (suffix && lmp->suffix_enable) {
sflag = 1;
char estyle[256];
sprintf(estyle,"%s/%s",style,suffix);
success = 1;
if (0) return;
#define INTEGRATE_CLASS
#define IntegrateStyle(key,Class) \
else if (strcmp(estyle,#key) == 0) integrate = new Class(lmp,narg,arg);
#include "style_integrate.h"
#undef IntegrateStyle
#undef INTEGRATE_CLASS
else success = 0;
}
if (!success) {
sflag = 0;
if (0) return;
#define INTEGRATE_CLASS
#define IntegrateStyle(key,Class) \
else if (strcmp(style,#key) == 0) integrate = new Class(lmp,narg,arg);
#include "style_integrate.h"
#undef IntegrateStyle
#undef INTEGRATE_CLASS
else error->all(FLERR,"Illegal integrate style");
}
}
/* ---------------------------------------------------------------------- */
void Update::create_minimize(int narg, char **arg)
{
if (narg != 1) error->all(FLERR,"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(FLERR,"Illegal min_style command");
int n = strlen(arg[0]) + 1;
minimize_style = new char[n];
strcpy(minimize_style,arg[0]);
}
/* ----------------------------------------------------------------------
reset timestep as called from input script
------------------------------------------------------------------------- */
void Update::reset_timestep(int narg, char **arg)
{
if (narg != 1) error->all(FLERR,"Illegal reset_timestep command");
bigint newstep = ATOBIGINT(arg[0]);
reset_timestep(newstep);
}
/* ----------------------------------------------------------------------
reset timestep
trigger reset of timestep for output and for fixes that require it
do not allow any timestep-dependent fixes 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
- called from input script and rerun command
+ called from rerun command and input script (indirectly)
------------------------------------------------------------------------- */
void Update::reset_timestep(bigint newstep)
{
ntimestep = newstep;
if (ntimestep < 0) error->all(FLERR,"Timestep must be >= 0");
if (ntimestep > MAXBIGINT) error->all(FLERR,"Too big a timestep");
output->reset_timestep(ntimestep);
for (int i = 0; i < modify->nfix; i++) {
if (modify->fix[i]->time_depend)
error->all(FLERR,
"Cannot reset timestep with a time-dependent fix defined");
modify->fix[i]->reset_timestep(ntimestep);
}
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();
// NOTE: 7Jun12, adding rerun command, don't think this is required
//for (int i = 0; i < domain->nregion; i++)
// if (domain->regions[i]->dynamic_check())
// error->all(FLERR,"Cannot reset timestep with a dynamic region defined");
}
/* ----------------------------------------------------------------------
memory usage of update and integrate/minimize
------------------------------------------------------------------------- */
bigint Update::memory_usage()
{
bigint bytes = 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 d79016d17..f94ac92d9 100644
--- a/src/update.h
+++ b/src/update.h
@@ -1,116 +1,105 @@
/* -*- c++ -*- ----------------------------------------------------------
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"
namespace LAMMPS_NS {
class Update : protected Pointers {
public:
double dt; // timestep
double etol,ftol; // minimizer tolerances on energy/force
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
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
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 **, char *);
void create_minimize(int, char **);
void reset_timestep(int, char **);
void reset_timestep(bigint);
bigint memory_usage();
private:
void new_integrate(char *, int, char **, char *, int &);
};
}
#endif
/* ERROR/WARNING messages:
E: USER-CUDA mode requires CUDA variant of run style
CUDA mode is enabled, so the run style must include a cuda suffix.
E: USER-CUDA mode requires CUDA variant of min style
CUDA mode is enabled, so the min style must include a cuda suffix.
E: Illegal ... command
Self-explanatory. Check the input script syntax and compare to the
documentation for the command. You can use -echo screen as a
command-line option when running LAMMPS to see the offending line.
E: Illegal integrate style
Self-explanatory.
-E: Cannot reset timestep with dump file already written to
+E: Timestep must be >= 0
-Changing the timestep will confuse when a dump file is written. Use
-the undump command, then restart the dump file.
+Specified timestep is invalid.
-E: Cannot reset timestep with restart file already written
+E: Too big a timestep
-Changing the timestep will confuse when a restart file is written.
-Use the "restart 0" command to turn off restarts, then start them
-again.
+Specified timestep is too large.
E: Cannot reset timestep with a time-dependent fix defined
You cannot reset the timestep when a fix that keeps track of elapsed
time is in place.
E: Cannot reset timestep with a dynamic region defined
Dynamic regions (see the region command) have a time dependence.
Thus you cannot change the timestep when one or more of these
are defined.
-E: Timestep must be >= 0
-
-Specified timestep is invalid.
-
-E: Too big a timestep
-
-Specified timestep is too large.
-
*/
diff --git a/src/velocity.cpp b/src/velocity.cpp
index fa3712bbb..bd6683317 100644
--- a/src/velocity.cpp
+++ b/src/velocity.cpp
@@ -1,802 +1,802 @@
/* ----------------------------------------------------------------------
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 "lmptype.h"
#include "mpi.h"
#include "math.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "velocity.h"
#include "atom.h"
#include "update.h"
#include "domain.h"
#include "lattice.h"
#include "input.h"
#include "variable.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};
enum{NONE,CONSTANT,EQUAL,ATOM};
#define WARMUP 100
#define SMALL 0.001
/* ---------------------------------------------------------------------- */
Velocity::Velocity(LAMMPS *lmp) : Pointers(lmp) {}
/* ---------------------------------------------------------------------- */
void Velocity::command(int narg, char **arg)
{
if (narg < 2) error->all(FLERR,"Illegal velocity command");
if (domain->box_exist == 0)
error->all(FLERR,"Velocity command before simulation box is defined");
if (atom->natoms == 0)
error->all(FLERR,"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(FLERR,"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(FLERR,"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]);
// 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(const char *extgroup)
{
igroup = group->find(extgroup);
if (igroup == -1) error->all(FLERR,"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(FLERR,"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(FLERR,"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(vhold,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 > MAXSMALLINT)
error->all(FLERR,"Too big a problem to use velocity create loop all");
if (atom->tag_enable == 0)
error->all(FLERR,
"Cannot use velocity create loop all unless atoms have IDs");
if (atom->tag_consecutive() == 0)
error->all(FLERR,
"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(vhold);
delete random;
if (tflag) delete temperature;
}
/* ---------------------------------------------------------------------- */
void Velocity::set(int narg, char **arg)
{
int xstyle,ystyle,zstyle,varflag;
double vx,vy,vz;
char *xstr,*ystr,*zstr;
int xvar,yvar,zvar;
// parse 3 args
xstyle = ystyle = zstyle = CONSTANT;
xstr = ystr = zstr = NULL;
if (strstr(arg[0],"v_") == arg[0]) {
int n = strlen(&arg[0][2]) + 1;
xstr = new char[n];
strcpy(xstr,&arg[0][2]);
} else if (strcmp(arg[0],"NULL") == 0) xstyle = NONE;
else vx = atof(arg[0]);
if (strstr(arg[1],"v_") == arg[1]) {
int n = strlen(&arg[1][2]) + 1;
ystr = new char[n];
strcpy(ystr,&arg[1][2]);
} else if (strcmp(arg[1],"NULL") == 0) ystyle = NONE;
else vy = atof(arg[1]);
if (strstr(arg[2],"v_") == arg[2]) {
int n = strlen(&arg[2][2]) + 1;
zstr = new char[n];
strcpy(zstr,&arg[2][2]);
} else if (strcmp(arg[2],"NULL") == 0) zstyle = NONE;
else vz = atof(arg[2]);
// set and apply scale factors
xscale = yscale = zscale = 1.0;
if (xstyle && !xstr) {
if (scale_flag && domain->lattice == NULL)
error->all(FLERR,"Use of velocity with undefined lattice");
if (scale_flag) xscale = domain->lattice->xlattice;
vx *= xscale;
}
if (ystyle && !ystr) {
if (scale_flag && domain->lattice == NULL)
error->all(FLERR,"Use of velocity with undefined lattice");
if (scale_flag) yscale = domain->lattice->ylattice;
vy *= yscale;
}
if (zstyle && !zstr) {
if (scale_flag && domain->lattice == NULL)
error->all(FLERR,"Use of velocity with undefined lattice");
if (scale_flag) zscale = domain->lattice->zlattice;
vz *= zscale;
}
// check variables
if (xstr) {
xvar = input->variable->find(xstr);
if (xvar < 0)
error->all(FLERR,"Variable name for velocity set does not exist");
if (input->variable->equalstyle(xvar)) xstyle = EQUAL;
else if (input->variable->atomstyle(xvar)) xstyle = ATOM;
else error->all(FLERR,"Variable for velocity set is invalid style");
}
if (ystr) {
yvar = input->variable->find(ystr);
if (yvar < 0)
error->all(FLERR,"Variable name for velocity set does not exist");
if (input->variable->equalstyle(yvar)) ystyle = EQUAL;
else if (input->variable->atomstyle(yvar)) ystyle = ATOM;
else error->all(FLERR,"Variable for velocity set is invalid style");
}
if (zstr) {
zvar = input->variable->find(zstr);
if (zvar < 0)
error->all(FLERR,"Variable name for velocity set does not exist");
if (input->variable->equalstyle(zvar)) zstyle = EQUAL;
else if (input->variable->atomstyle(zvar)) zstyle = ATOM;
else error->all(FLERR,"Variable for velocity set is invalid style");
}
if (xstyle == ATOM || ystyle == ATOM || zstyle == ATOM)
varflag = ATOM;
else if (xstyle == EQUAL || ystyle == EQUAL || zstyle == EQUAL)
varflag = EQUAL;
else varflag = CONSTANT;
// error check for 2d models
if (domain->dimension == 2) {
if (zstyle == CONSTANT && vz != 0.0)
error->all(FLERR,"Cannot set non-zero z velocity for 2d simulation");
if (zstyle == EQUAL || zstyle == ATOM)
error->all(FLERR,"Cannot set variable z velocity for 2d simulation");
}
// allocate vfield array if necessary
double **vfield = NULL;
if (varflag == ATOM) memory->create(vfield,atom->nlocal,3,"velocity:vfield");
// set velocities via constants
double **v = atom->v;
int *mask = atom->mask;
int nlocal = atom->nlocal;
if (varflag == CONSTANT) {
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) {
if (sum_flag == 0) {
if (xstyle) v[i][0] = vx;
if (ystyle) v[i][1] = vy;
if (zstyle) v[i][2] = vz;
} else {
if (xstyle) v[i][0] += vx;
if (ystyle) v[i][1] += vy;
if (zstyle) v[i][2] += vz;
}
}
}
// set velocities via variables
} else {
if (xstyle == EQUAL) vx = input->variable->compute_equal(xvar);
else if (xstyle == ATOM && vfield)
input->variable->compute_atom(xvar,igroup,&vfield[0][0],3,0);
if (ystyle == EQUAL) vy = input->variable->compute_equal(yvar);
else if (ystyle == ATOM && vfield)
input->variable->compute_atom(yvar,igroup,&vfield[0][1],3,0);
if (zstyle == EQUAL) vz = input->variable->compute_equal(zvar);
else if (zstyle == ATOM && vfield)
input->variable->compute_atom(zvar,igroup,&vfield[0][2],3,0);
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
if (sum_flag == 0) {
if (xstyle == ATOM) v[i][0] = vfield[i][0];
else if (xstyle) v[i][0] = vx;
if (ystyle == ATOM) v[i][1] = vfield[i][1];
else if (ystyle) v[i][1] = vy;
if (zstyle == ATOM) v[i][2] = vfield[i][2];
else if (zstyle) v[i][2] = vz;
} else {
if (xstyle == ATOM) v[i][0] += vfield[i][0];
else if (xstyle) v[i][0] += vx;
if (ystyle == ATOM) v[i][1] += vfield[i][1];
else if (ystyle) v[i][1] += vy;
if (zstyle == ATOM) v[i][2] += vfield[i][2];
else if (zstyle) v[i][2] += vz;
}
}
}
// clean up
delete [] xstr;
delete [] ystr;
delete [] zstr;
memory->destroy(vfield);
}
/* ----------------------------------------------------------------------
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(FLERR,"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)
{
// set scale factors
if (scale_flag && domain->lattice == NULL)
error->all(FLERR,"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;
// parse args
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(FLERR,"Illegal velocity command");
if (v_dim == 2 && domain->dimension == 2)
error->all(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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(FLERR,"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;
+ tagint *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;
+ xbox = (image[i] & IMGMASK) - IMGMAX;
+ ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+ zbox = (image[i] >> IMG2BITS) - IMGMASK;
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(FLERR,"Illegal velocity command");
int iarg = 0;
while (iarg < narg) {
if (strcmp(arg[iarg],"dist") == 0) {
if (iarg+2 > narg) error->all(FLERR,"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(FLERR,"Illegal velocity command");
iarg += 2;
} else if (strcmp(arg[iarg],"sum") == 0) {
if (iarg+2 > narg) error->all(FLERR,"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(FLERR,"Illegal velocity command");
iarg += 2;
} else if (strcmp(arg[iarg],"mom") == 0) {
if (iarg+2 > narg) error->all(FLERR,"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(FLERR,"Illegal velocity command");
iarg += 2;
} else if (strcmp(arg[iarg],"rot") == 0) {
if (iarg+2 > narg) error->all(FLERR,"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(FLERR,"Illegal velocity command");
iarg += 2;
} else if (strcmp(arg[iarg],"temp") == 0) {
if (iarg+2 > narg) error->all(FLERR,"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(FLERR,"Could not find velocity temperature ID");
temperature = modify->compute[icompute];
if (temperature->tempflag == 0)
error->all(FLERR,
"Velocity temperature ID does not compute temperature");
iarg += 2;
} else if (strcmp(arg[iarg],"loop") == 0) {
if (iarg+2 > narg) error->all(FLERR,"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(FLERR,"Illegal velocity command");
iarg += 2;
} else if (strcmp(arg[iarg],"units") == 0) {
if (iarg+2 > narg) error->all(FLERR,"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(FLERR,"Illegal velocity command");
iarg += 2;
} else error->all(FLERR,"Illegal velocity command");
}
}
diff --git a/src/version.h b/src/version.h
index 99351866e..58c6b7f3d 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define LAMMPS_VERSION "29 Jun 2012"
+#define LAMMPS_VERSION "2 Jul 2012"

Event Timeline