Merge branch 'master' into lammps-icms
This commit is contained in:
BIN
doc/Eqs/pair_mie.jpg
Normal file
BIN
doc/Eqs/pair_mie.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
10
doc/Eqs/pair_mie.tex
Normal file
10
doc/Eqs/pair_mie.tex
Normal file
@ -0,0 +1,10 @@
|
||||
\documentstyle[12pt]{article}
|
||||
|
||||
\begin{document}
|
||||
|
||||
$$
|
||||
E = C \epsilon \left[ \left(\frac{\sigma}{r}\right)^{\gamma_{rep}} - \left(\frac{\sigma}{r}\right)^{\gamma_{att}} \right]
|
||||
\qquad r < r_c
|
||||
$$
|
||||
|
||||
\end{document}
|
||||
BIN
doc/Eqs/pair_mie2.jpg
Normal file
BIN
doc/Eqs/pair_mie2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
9
doc/Eqs/pair_mie2.tex
Normal file
9
doc/Eqs/pair_mie2.tex
Normal file
@ -0,0 +1,9 @@
|
||||
\documentstyle[12pt]{article}
|
||||
|
||||
\begin{document}
|
||||
|
||||
$$
|
||||
C = \left(\frac{\gamma_{rep}}{\gamma_{rep}-\gamma_{att}}\right) \left(\frac{\gamma_{rep}}{\gamma_{att}}\right)^{\left(\frac{\gamma_{att}}{\gamma_{rep}-\gamma_{att}}\right)}
|
||||
$$
|
||||
|
||||
\end{document}
|
||||
@ -433,10 +433,11 @@ potentials. Click on the style itself for a full description:
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lj_long.html">lj/long/coul/long</A></TD><TD ><A HREF = "pair_lj.html">lj/cut/tip4p/long</A></TD><TD ><A HREF = "pair_lj_long.html">lj/long/tip4p/long</A></TD><TD ><A HREF = "pair_lj_expand.html">lj/expand</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_gromacs.html">lj/gromacs</A></TD><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></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lj96.html">lj96/cut</A></TD><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></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lubricateU.html">lubricateU/poly</A></TD><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></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_peri.html">peri/pmb</A></TD><TD ><A HREF = "pair_reax.html">reax</A></TD><TD ><A HREF = "pair_airebo.html">rebo</A></TD><TD ><A HREF = "pair_resquared.html">resquared</A></TD></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_soft.html">soft</A></TD><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></TR>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_tersoff_zbl.html">tersoff/zbl</A></TD><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>
|
||||
<TR ALIGN="center"><TD ><A HREF = "pair_lubricateU.html">lubricateU/poly</A></TD><TD ><A HREF = "pair_meam.html">meam</A></TD><TD ><A HREF = "pair_mie.html">mie/cut</A></TD><TD ><A HREF = "pair_morse.html">morse</A></TD></TR>
|
||||
<TR ALIGN="center"><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><TD ><A HREF = "pair_airebo.html">rebo</A></TD></TR>
|
||||
<TR ALIGN="center"><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><TD ><A HREF = "pair_table.html">table</A></TD></TR>
|
||||
<TR ALIGN="center"><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><TD ><A HREF = "pair_yukawa.html">yukawa</A></TD></TR>
|
||||
<TR ALIGN="center"><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
|
||||
|
||||
@ -692,6 +692,7 @@ potentials. Click on the style itself for a full description:
|
||||
"lubricateU"_pair_lubricateU.html,
|
||||
"lubricateU/poly"_pair_lubricateU.html,
|
||||
"meam"_pair_meam.html,
|
||||
"mie/cut"_pair_mie.html,
|
||||
"morse"_pair_morse.html,
|
||||
"peri/lps"_pair_peri.html,
|
||||
"peri/pmb"_pair_peri.html,
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
<P><B>Examples:</B>
|
||||
</P>
|
||||
<PRE>dihedral_style fourier
|
||||
dihedral_coeff 3 -0.846200 3 0 7.578800 1 0 0.138000 2 -180
|
||||
dihedral_coeff 3 -0.846200 3 0.0 7.578800 1 0 0.138000 2 -180.0
|
||||
</PRE>
|
||||
<P><B>Description:</B>
|
||||
</P>
|
||||
@ -31,15 +31,15 @@ dihedral_coeff 3 -0.846200 3 0 7.578800 1 0 0.138000 2 -180
|
||||
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
|
||||
or <A HREF = "read_restart.html">read_restart</A> commands:
|
||||
</P>
|
||||
<P>m (integer >=1)
|
||||
K1 (energy)
|
||||
n1 (integer >= 0)
|
||||
d1 (integer value of degrees)
|
||||
....
|
||||
Km (energy)
|
||||
nm (integer >= 0)
|
||||
dm (integer value of degrees)
|
||||
</P>
|
||||
<UL><LI>m (integer >=1)
|
||||
<LI>K1 (energy)
|
||||
<LI>n1 (integer >= 0)
|
||||
<LI>d1 (degrees)
|
||||
<LI>....
|
||||
<LI>Km (energy)
|
||||
<LI>nm (integer >= 0)
|
||||
<LI>dm (degrees)
|
||||
</UL>
|
||||
<HR>
|
||||
|
||||
<P><B>Restrictions:</B>
|
||||
|
||||
@ -15,7 +15,7 @@ dihedral_style fourier :pre
|
||||
[Examples:]
|
||||
|
||||
dihedral_style fourier
|
||||
dihedral_coeff 3 -0.846200 3 0 7.578800 1 0 0.138000 2 -180 :pre
|
||||
dihedral_coeff 3 -0.846200 3 0.0 7.578800 1 0 0.138000 2 -180.0 :pre
|
||||
|
||||
[Description:]
|
||||
|
||||
@ -31,11 +31,11 @@ or "read_restart"_read_restart.html commands:
|
||||
m (integer >=1)
|
||||
K1 (energy)
|
||||
n1 (integer >= 0)
|
||||
d1 (integer value of degrees)
|
||||
d1 (degrees)
|
||||
....
|
||||
Km (energy)
|
||||
nm (integer >= 0)
|
||||
dm (integer value of degrees)
|
||||
dm (degrees) :ul
|
||||
|
||||
:line
|
||||
|
||||
|
||||
@ -33,9 +33,9 @@ dihedral_coeff 100.0 80.0
|
||||
the data file or restart files read by the <A HREF = "read_data.html">read_data</A>
|
||||
or <A HREF = "read_restart.html">read_restart</A> commands:
|
||||
</P>
|
||||
<P>K (energy)
|
||||
phi0 (degrees)
|
||||
</P>
|
||||
<UL><LI>K (energy)
|
||||
<LI>phi0 (degrees)
|
||||
</UL>
|
||||
<HR>
|
||||
|
||||
<P><B>Restrictions:</B>
|
||||
|
||||
@ -31,7 +31,7 @@ the data file or restart files read by the "read_data"_read_data.html
|
||||
or "read_restart"_read_restart.html commands:
|
||||
|
||||
K (energy)
|
||||
phi0 (degrees)
|
||||
phi0 (degrees) :ul
|
||||
|
||||
:line
|
||||
|
||||
|
||||
@ -308,12 +308,14 @@ minimization converges. Note that this means a dump will not be
|
||||
performed on the initial timestep after the dump command is invoked,
|
||||
if the current timestep is not a multiple of N. This behavior can be
|
||||
changed via the <A HREF = "dump_modify.html">dump_modify first</A> command, which
|
||||
can be useful if the dump command is invoked after a minimization
|
||||
can also be useful if the dump command is invoked after a minimization
|
||||
ended on an arbitrary timestep. N can be changed between runs by
|
||||
using the <A HREF = "dump_modify.html">dump_modify every</A> command (not allowed
|
||||
for <I>dcd</I> style). The <A HREF = "dump_modify.html">dump_modify every</A> command
|
||||
also allows a variable to be used to determine the sequence of
|
||||
timesteps on which dump files are written.
|
||||
timesteps on which dump files are written. In this mode a dump on the
|
||||
first timestep of a run will also not be written unless the
|
||||
<A HREF = "dump_modify.html">dump_modify first</A> command is used.
|
||||
</P>
|
||||
<P>The specified filename determines how the dump file(s) is written.
|
||||
The default is to write one large text file, which is opened when the
|
||||
|
||||
@ -296,12 +296,14 @@ minimization converges. Note that this means a dump will not be
|
||||
performed on the initial timestep after the dump command is invoked,
|
||||
if the current timestep is not a multiple of N. This behavior can be
|
||||
changed via the "dump_modify first"_dump_modify.html command, which
|
||||
can be useful if the dump command is invoked after a minimization
|
||||
can also be useful if the dump command is invoked after a minimization
|
||||
ended on an arbitrary timestep. N can be changed between runs by
|
||||
using the "dump_modify every"_dump_modify.html command (not allowed
|
||||
for {dcd} style). The "dump_modify every"_dump_modify.html command
|
||||
also allows a variable to be used to determine the sequence of
|
||||
timesteps on which dump files are written.
|
||||
timesteps on which dump files are written. In this mode a dump on the
|
||||
first timestep of a run will also not be written unless the
|
||||
"dump_modify first"_dump_modify.html command is used.
|
||||
|
||||
The specified filename determines how the dump file(s) is written.
|
||||
The default is to write one large text file, which is opened when the
|
||||
|
||||
@ -365,16 +365,22 @@ which should be specified as v_name, where name is the variable name.
|
||||
</P>
|
||||
<P>In this case, the variable is evaluated at the beginning of a run to
|
||||
determine the next timestep at which a dump snapshot will be written
|
||||
out. On that timestep, the variable will be evaluated again to
|
||||
out. On that timestep the variable will be evaluated again to
|
||||
determine the next timestep, etc. Thus the variable should return
|
||||
timestep values. See the stagger() and logfreq() and stride() math
|
||||
functions for <A HREF = "variable.html">equal-style variables</A>, as examples of
|
||||
useful functions to use in this context. Other similar math functions
|
||||
could easily be added as options for <A HREF = "variable.html">equal-style
|
||||
variables</A>. When using the variable option with the
|
||||
<I>every</I> keyword, you also need to use the <I>first</I> option if you want
|
||||
an initial snapshot written to the dump file. The <I>every</I> keyword
|
||||
cannot be used with the dump <I>dcd</I> style.
|
||||
variables</A>. Also see the next() function, which allows
|
||||
use of a file-style variable which reads successive values from a
|
||||
file, each time the variable is evaluated. Used with the <I>every</I>
|
||||
keyword, if the file contains a list of ascending timesteps, you can
|
||||
output snapshots whenever you wish.
|
||||
</P>
|
||||
<P>Note that when using the variable option with the <I>every</I> keyword, you
|
||||
need to use the <I>first</I> option if you want an initial snapshot written
|
||||
to the dump file. The <I>every</I> keyword cannot be used with the dump
|
||||
<I>dcd</I> style.
|
||||
</P>
|
||||
<P>For example, the following commands will
|
||||
write snapshots at timesteps 0,10,20,30,100,200,300,1000,2000,etc:
|
||||
@ -383,6 +389,25 @@ write snapshots at timesteps 0,10,20,30,100,200,300,1000,2000,etc:
|
||||
dump 1 all atom 100 tmp.dump
|
||||
dump_modify 1 every v_s first yes
|
||||
</PRE>
|
||||
<P>The following commands would write snapshots at the timesteps listed
|
||||
in file tmp.times:
|
||||
</P>
|
||||
<PRE>variable f file tmp.times
|
||||
variable s equal next(f)
|
||||
dump 1 all atom 100 tmp.dump
|
||||
dump_modify 1 every v_s
|
||||
</PRE>
|
||||
<P>IMPORTANT NOTE: When using a file-style variable with the <I>every</I>
|
||||
keyword, the file of timesteps must list a first timestep that is
|
||||
beyond the current timestep (e.g. it cannot be 0). And it must list
|
||||
one or more timesteps beyond the length of the run you perform. This
|
||||
is because the dump command will generate an error if the next
|
||||
timestep it reads from the file is not a value greater than the
|
||||
current timestep. Thus if you wanted output on steps 0,15,100 of a
|
||||
100-timestep run, the file should contain the values 15,100,101 and
|
||||
you should also use the dump_modify first command. Any final value >
|
||||
100 could be used in place of 101.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<P>The <I>first</I> keyword determines whether a dump snapshot is written on
|
||||
|
||||
@ -358,16 +358,22 @@ which should be specified as v_name, where name is the variable name.
|
||||
|
||||
In this case, the variable is evaluated at the beginning of a run to
|
||||
determine the next timestep at which a dump snapshot will be written
|
||||
out. On that timestep, the variable will be evaluated again to
|
||||
out. On that timestep the variable will be evaluated again to
|
||||
determine the next timestep, etc. Thus the variable should return
|
||||
timestep values. See the stagger() and logfreq() and stride() math
|
||||
functions for "equal-style variables"_variable.html, as examples of
|
||||
useful functions to use in this context. Other similar math functions
|
||||
could easily be added as options for "equal-style
|
||||
variables"_variable.html. When using the variable option with the
|
||||
{every} keyword, you also need to use the {first} option if you want
|
||||
an initial snapshot written to the dump file. The {every} keyword
|
||||
cannot be used with the dump {dcd} style.
|
||||
variables"_variable.html. Also see the next() function, which allows
|
||||
use of a file-style variable which reads successive values from a
|
||||
file, each time the variable is evaluated. Used with the {every}
|
||||
keyword, if the file contains a list of ascending timesteps, you can
|
||||
output snapshots whenever you wish.
|
||||
|
||||
Note that when using the variable option with the {every} keyword, you
|
||||
need to use the {first} option if you want an initial snapshot written
|
||||
to the dump file. The {every} keyword cannot be used with the dump
|
||||
{dcd} style.
|
||||
|
||||
For example, the following commands will
|
||||
write snapshots at timesteps 0,10,20,30,100,200,300,1000,2000,etc:
|
||||
@ -376,6 +382,25 @@ variable s equal logfreq(10,3,10)
|
||||
dump 1 all atom 100 tmp.dump
|
||||
dump_modify 1 every v_s first yes :pre
|
||||
|
||||
The following commands would write snapshots at the timesteps listed
|
||||
in file tmp.times:
|
||||
|
||||
variable f file tmp.times
|
||||
variable s equal next(f)
|
||||
dump 1 all atom 100 tmp.dump
|
||||
dump_modify 1 every v_s :pre
|
||||
|
||||
IMPORTANT NOTE: When using a file-style variable with the {every}
|
||||
keyword, the file of timesteps must list a first timestep that is
|
||||
beyond the current timestep (e.g. it cannot be 0). And it must list
|
||||
one or more timesteps beyond the length of the run you perform. This
|
||||
is because the dump command will generate an error if the next
|
||||
timestep it reads from the file is not a value greater than the
|
||||
current timestep. Thus if you wanted output on steps 0,15,100 of a
|
||||
100-timestep run, the file should contain the values 15,100,101 and
|
||||
you should also use the dump_modify first command. Any final value >
|
||||
100 could be used in place of 101.
|
||||
|
||||
:line
|
||||
|
||||
The {first} keyword determines whether a dump snapshot is written on
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
<LI>M = number of MC displacements to attempt every N steps
|
||||
|
||||
<LI>type = atom type of exchanged particles
|
||||
<LI>type = atom type or molecule ID of exchanged gas
|
||||
|
||||
<LI>seed = random # seed (positive integer)
|
||||
|
||||
@ -42,19 +42,20 @@
|
||||
<PRE> <I>molecule</I> value = <I>no</I> or <I>yes</I>
|
||||
<I>region</I> value = region-ID
|
||||
region-ID = ID of region to use as an exchange/move volume
|
||||
<I>maxangle</I> value = maximum molecular rotation angle (degrees)
|
||||
</PRE>
|
||||
|
||||
</UL>
|
||||
<P><B>Examples:</B>
|
||||
</P>
|
||||
<PRE>fix 2 all gcmc 10 1000 1000 2 29494 298.0 -0.5 0.01
|
||||
fix 3 all gcmc 10 100 100 1 3456543 3.0 -2.5 0.1 molecule yes
|
||||
fix 4 all gcmc 1 10 10 1 123456543 300.0 -12.5 1.0 region disk
|
||||
<PRE>fix 2 gas gcmc 10 1000 1000 2 29494 298.0 -0.5 0.01
|
||||
fix 3 Kr gcmc 10 100 100 1 3456543 3.0 -2.5 0.1 molecule yes maxrot 180
|
||||
fix 4 my_gas gcmc 1 10 10 1 123456543 300.0 -12.5 1.0 region disk
|
||||
</PRE>
|
||||
<P><B>Description:</B>
|
||||
</P>
|
||||
<P>This fix performs grand canonical Monte Carlo (GCMC) exchanges of
|
||||
particles of the given type with an imaginary ideal gas reservoir at
|
||||
atoms or molecules of the given type with an imaginary ideal gas reservoir at
|
||||
the specified T and chemical potential (mu) as discussed in
|
||||
<A HREF = "#Frenkel">(Frenkel)</A>. If used with the <A HREF = "fix_nh.html">fix nvt</A> command,
|
||||
simulations in the grand canonical enemble (muVT, constant chemical
|
||||
@ -62,29 +63,40 @@ potential, constant volume, and constant temperature) can be
|
||||
performed. Specific uses include computing isotherms in microporous
|
||||
materials, or computing vapor-liquid coexistence curves.
|
||||
</P>
|
||||
<P>Perform up to X exchanges of particles of the given type between the
|
||||
simulation domain and the imaginary reservoir every N timesteps. Also
|
||||
perform M Monte Carlo displacements of particles of the given type
|
||||
within the simulation domain. M should typically be chosen to be
|
||||
approximately equal to the expected number of particles of the given
|
||||
type within the domain, which will result in roughly one MC
|
||||
translation per particle per MC cycle.
|
||||
<P>Perform up to X exchanges of gas atoms or molecules of the given type
|
||||
between the simulation domain and the imaginary reservoir every N
|
||||
timesteps. Also perform M Monte Carlo displacements or rotations
|
||||
(for molecules) of gas of the given type within the simulation domain.
|
||||
M should typically be chosen to be approximately equal to the expected
|
||||
number of gas atoms or molecules of the given type within the domain,
|
||||
which will result in roughly one MC translation per atom or molecule
|
||||
per MC cycle.
|
||||
</P>
|
||||
<P>This fix cannot be used to perform MC displacements of particles other
|
||||
than the exchanged type. All particles in the simulation domain can be
|
||||
moved using regular time integration displacements, e.g. via
|
||||
<A HREF = "fix_nvt.html">fix_nvt</A>, resulting in a hybrid GCMC+MD simulation.
|
||||
<P>For MC moves of molecular gasses, rotations and translations are each
|
||||
attempted with 50% probability. For MC moves of atomic gasses,
|
||||
translations are attempted 100% of the time. For MC exchanges of either
|
||||
molecular or atomic gasses, deletions and insertions are each attempted
|
||||
with 50% probability.
|
||||
</P>
|
||||
<P>This fix cannot be used to perform MC insertions of gas atoms or
|
||||
molecules other than the exchanged type, but MC deletions, translations,
|
||||
and rotations can be performed on any atom/molecule in the fix group.
|
||||
All atoms in the simulation domain can be moved using regular time
|
||||
integration displacements, e.g. via <A HREF = "fix_nvt.html">fix_nvt</A>, resulting
|
||||
in a hybrid GCMC+MD simulation. A smaller-than-usual timestep size
|
||||
may be needed when running such a hybrid simulation, especially if
|
||||
the inserted molecules are not well equilibrated.
|
||||
</P>
|
||||
<P>This command may optionally use the <I>region</I> keyword to define an
|
||||
exchange and move volume. The specified region must have been
|
||||
previously defined with a <A HREF = "region.html">region</A> command. It must be
|
||||
defined with side = <I>in</I>. Insertion attempts occur only within the
|
||||
specified region. Move and deletion attempt candidates are selected
|
||||
from particles within the region. If no candidate can be found within
|
||||
the specified region after randomly selecting candidates 1000 times,
|
||||
the move or deletion attempt is considered a failure. Moves must start
|
||||
within the specified region, but may move the particle slightly
|
||||
outside of the region.
|
||||
from gas atoms or molecules within the region. If no candidate can be
|
||||
found within the specified region after randomly selecting candidates
|
||||
1000 times, the move or deletion attempt is considered a failure. Moves
|
||||
must start within the specified region, but may move the atom or molecule
|
||||
slightly outside of the region.
|
||||
</P>
|
||||
<P>If used with <A HREF = "fix_nvt.html">fix_nvt</A>, the temperature of the imaginary
|
||||
reservoir, T, should be set to be equivalent to the target temperature
|
||||
@ -95,17 +107,16 @@ will not be in thermal equilibrium with the simulation domain.
|
||||
invoked, so you should not set N to be too small. However, periodic
|
||||
rebuilds are necessary in order to avoid dangerous rebuilds and missed
|
||||
interactions. Specifically, avoid performing so many MC displacements
|
||||
per timestep that a particle can move beyond the neighbor list skin
|
||||
per timestep that atoms can move beyond the neighbor list skin
|
||||
distance. See the <A HREF = "neighbor.html">neighbor</A> command for details.
|
||||
</P>
|
||||
<P>When a particle is to be inserted, its coordinates are chosen as a
|
||||
random position within the current simulation domain, and its velocity
|
||||
is randomly chosen from the specified temperature distribution given
|
||||
by T.
|
||||
</P>
|
||||
<P>Exchanged particles have the specified atom type and are assigned to
|
||||
two groups: the default group "all" and the group specified in the fix
|
||||
gcmc command (which can also be "all").
|
||||
<P>When an atom or molecule is to be inserted, its center-of-mass
|
||||
coordinates are chosen as a random position within the current
|
||||
simulation domain, and new atom velocities are randomly chosen
|
||||
from the specified temperature distribution given by T. Relative
|
||||
coordinates for atoms in a molecule are taken from the template
|
||||
molecule provided by the user. A random initial rotation is used in the
|
||||
case of molecule insertions.
|
||||
</P>
|
||||
<P>If the setting for the <I>molecule</I> keyword is <I>no</I>, then only single
|
||||
atoms are exchanged. In this case, you should ensure you do not
|
||||
@ -116,7 +127,28 @@ non-zero molecule ID, but does not check for this at the time of
|
||||
deletion.
|
||||
</P>
|
||||
<P>If the setting for the <I>molecule</I> keyword is <I>yes</I>, entire molecules
|
||||
are exchanged. This feature is not yet supported.
|
||||
are exchanged. The user must supply a model molecule in the data
|
||||
file to use as a template for exchanges, and that molecule's number
|
||||
must be given in the fix GCMC command as the "type" of the exchanged
|
||||
gas. The model molecule can then be immediately deleted using the
|
||||
<A HREF = "delete_atoms.html">delete_atoms</A> command.
|
||||
</P>
|
||||
<P>Optionally, users may specify the maximum rotation angle for
|
||||
molecular rotations using the <I>maxangle</I> keyword and specifying
|
||||
the angle in degrees. The specified angle will apply to all three
|
||||
Euler angles used internally to define the rotation matrix for
|
||||
molecular rotations. The max angle can be set to zero, but rotations
|
||||
will be pointless. Note that the default is ten degrees for each
|
||||
Euler angle.
|
||||
</P>
|
||||
<P>For atomic gasses, inserted atoms have the specified atom type, but
|
||||
deleted atoms are any atoms that have been inserted or that belong
|
||||
to the user-specified fix group. For molecular gasses, exchanged
|
||||
molecules use the same atom types as in the template molecule
|
||||
supplied by the user. In both cases, exchanged
|
||||
atoms/molecules are assigned to two groups: the default group "all"
|
||||
and the group specified in the fix gcmc command (which can also be
|
||||
"all").
|
||||
</P>
|
||||
<P>Use of this fix typically will cause the number of atoms to fluctuate,
|
||||
therefore, you will want to use the
|
||||
@ -150,10 +182,12 @@ values are the following global cummulative quantities:
|
||||
</P>
|
||||
<UL><LI>1 = displacement attempts
|
||||
<LI>2 = displacement successes
|
||||
<LI>3 = deletion attempts
|
||||
<LI>4 = deletion successes
|
||||
<LI>5 = insertion attempts
|
||||
<LI>6 = insertion successes
|
||||
<LI>3 = insertion attempts
|
||||
<LI>4 = insertion successes
|
||||
<LI>5 = deletion attempts
|
||||
<LI>6 = deletion successes
|
||||
<LI>7 = rotation attempts
|
||||
<LI>8 = rotation successes
|
||||
</UL>
|
||||
<P>The vector values calculated by this fix are "extensive".
|
||||
</P>
|
||||
@ -170,9 +204,6 @@ LAMMPS</A> section for more info.
|
||||
<P>Do not set "neigh_modify once yes" or else this fix will never be
|
||||
called. Reneighboring is required.
|
||||
</P>
|
||||
<P>You cannot currently exchange charged particles or molecules with a
|
||||
net charge.
|
||||
</P>
|
||||
<P>Only pairwise interactions, as defined by the
|
||||
<A HREF = "pair_style.html">pair_style</A> command, are included in this
|
||||
calculation. Long-range interactions due to a
|
||||
@ -183,14 +214,25 @@ this fix. For example, 3-body potentials, such as
|
||||
be used. <A HREF = "pair_eam.html">EAM</A> potentials for metals only include the
|
||||
pair potential portion of the EAM interaction, not the embedding term.
|
||||
</P>
|
||||
<P>Can be run in parallel, but aspects of the GCMC part will not scale
|
||||
well in parallel. Only usable for 3D simulations with orthogonal
|
||||
simulation cells.
|
||||
</P>
|
||||
<P>Note that very lengthy simulations involving insertions/deletions of
|
||||
billions of gas molecules may run out of atom or molecule IDs and
|
||||
trigger an error, so it is better to run multiple shorter-duration
|
||||
simulations. Likewise, very large molecules have not been tested
|
||||
and may turn out to be problematic.
|
||||
</P>
|
||||
<P><B>Related commands:</B>
|
||||
</P>
|
||||
<P><A HREF = "fix_nvt.html">fix_nvt</A>, <A HREF = "neighbor.html">neighbor</A>,
|
||||
<A HREF = "fix_deposit.html">fix_deposit</A>, <A HREF = "fix_evaporate.html">fix_evaporate</A>
|
||||
<A HREF = "fix_deposit.html">fix_deposit</A>, <A HREF = "fix_evaporate.html">fix_evaporate</A>,
|
||||
<A HREF = "delete_atoms.html">delete_atoms</A>
|
||||
</P>
|
||||
<P><B>Default:</B>
|
||||
</P>
|
||||
<P>The option defaults are molecule = no.
|
||||
<P>The option defaults are molecule = no, maxangle = 10.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
|
||||
124
doc/fix_gcmc.txt
124
doc/fix_gcmc.txt
@ -17,7 +17,7 @@ gcmc = style name of this fix command :l
|
||||
N = invoke this fix every N steps :l
|
||||
X = number of exchanges to attempt every N steps :l
|
||||
M = number of MC displacements to attempt every N steps :l
|
||||
type = atom type of exchanged particles :l
|
||||
type = atom type or molecule ID of exchanged gas :l
|
||||
seed = random # seed (positive integer) :l
|
||||
T = temperature of the ideal gas reservoir (temperature units) :l
|
||||
mu = chemical potential of the ideal gas reservoir (energy units) :l
|
||||
@ -26,19 +26,20 @@ zero or more keyword/value pairs may be appended to args :l
|
||||
keyword = {molecule} or {region} :l
|
||||
{molecule} value = {no} or {yes}
|
||||
{region} value = region-ID
|
||||
region-ID = ID of region to use as an exchange/move volume :pre
|
||||
region-ID = ID of region to use as an exchange/move volume
|
||||
{maxangle} value = maximum molecular rotation angle (degrees) :pre
|
||||
:ule
|
||||
|
||||
[Examples:]
|
||||
|
||||
fix 2 all gcmc 10 1000 1000 2 29494 298.0 -0.5 0.01
|
||||
fix 3 all gcmc 10 100 100 1 3456543 3.0 -2.5 0.1 molecule yes
|
||||
fix 4 all gcmc 1 10 10 1 123456543 300.0 -12.5 1.0 region disk :pre
|
||||
fix 2 gas gcmc 10 1000 1000 2 29494 298.0 -0.5 0.01
|
||||
fix 3 Kr gcmc 10 100 100 1 3456543 3.0 -2.5 0.1 molecule yes maxrot 180
|
||||
fix 4 my_gas gcmc 1 10 10 1 123456543 300.0 -12.5 1.0 region disk :pre
|
||||
|
||||
[Description:]
|
||||
|
||||
This fix performs grand canonical Monte Carlo (GCMC) exchanges of
|
||||
particles of the given type with an imaginary ideal gas reservoir at
|
||||
atoms or molecules of the given type with an imaginary ideal gas reservoir at
|
||||
the specified T and chemical potential (mu) as discussed in
|
||||
"(Frenkel)"_#Frenkel. If used with the "fix nvt"_fix_nh.html command,
|
||||
simulations in the grand canonical enemble (muVT, constant chemical
|
||||
@ -46,29 +47,40 @@ potential, constant volume, and constant temperature) can be
|
||||
performed. Specific uses include computing isotherms in microporous
|
||||
materials, or computing vapor-liquid coexistence curves.
|
||||
|
||||
Perform up to X exchanges of particles of the given type between the
|
||||
simulation domain and the imaginary reservoir every N timesteps. Also
|
||||
perform M Monte Carlo displacements of particles of the given type
|
||||
within the simulation domain. M should typically be chosen to be
|
||||
approximately equal to the expected number of particles of the given
|
||||
type within the domain, which will result in roughly one MC
|
||||
translation per particle per MC cycle.
|
||||
Perform up to X exchanges of gas atoms or molecules of the given type
|
||||
between the simulation domain and the imaginary reservoir every N
|
||||
timesteps. Also perform M Monte Carlo displacements or rotations
|
||||
(for molecules) of gas of the given type within the simulation domain.
|
||||
M should typically be chosen to be approximately equal to the expected
|
||||
number of gas atoms or molecules of the given type within the domain,
|
||||
which will result in roughly one MC translation per atom or molecule
|
||||
per MC cycle.
|
||||
|
||||
This fix cannot be used to perform MC displacements of particles other
|
||||
than the exchanged type. All particles in the simulation domain can be
|
||||
moved using regular time integration displacements, e.g. via
|
||||
"fix_nvt"_fix_nvt.html, resulting in a hybrid GCMC+MD simulation.
|
||||
For MC moves of molecular gasses, rotations and translations are each
|
||||
attempted with 50% probability. For MC moves of atomic gasses,
|
||||
translations are attempted 100% of the time. For MC exchanges of either
|
||||
molecular or atomic gasses, deletions and insertions are each attempted
|
||||
with 50% probability.
|
||||
|
||||
This fix cannot be used to perform MC insertions of gas atoms or
|
||||
molecules other than the exchanged type, but MC deletions, translations,
|
||||
and rotations can be performed on any atom/molecule in the fix group.
|
||||
All atoms in the simulation domain can be moved using regular time
|
||||
integration displacements, e.g. via "fix_nvt"_fix_nvt.html, resulting
|
||||
in a hybrid GCMC+MD simulation. A smaller-than-usual timestep size
|
||||
may be needed when running such a hybrid simulation, especially if
|
||||
the inserted molecules are not well equilibrated.
|
||||
|
||||
This command may optionally use the {region} keyword to define an
|
||||
exchange and move volume. The specified region must have been
|
||||
previously defined with a "region"_region.html command. It must be
|
||||
defined with side = {in}. Insertion attempts occur only within the
|
||||
specified region. Move and deletion attempt candidates are selected
|
||||
from particles within the region. If no candidate can be found within
|
||||
the specified region after randomly selecting candidates 1000 times,
|
||||
the move or deletion attempt is considered a failure. Moves must start
|
||||
within the specified region, but may move the particle slightly
|
||||
outside of the region.
|
||||
from gas atoms or molecules within the region. If no candidate can be
|
||||
found within the specified region after randomly selecting candidates
|
||||
1000 times, the move or deletion attempt is considered a failure. Moves
|
||||
must start within the specified region, but may move the atom or molecule
|
||||
slightly outside of the region.
|
||||
|
||||
If used with "fix_nvt"_fix_nvt.html, the temperature of the imaginary
|
||||
reservoir, T, should be set to be equivalent to the target temperature
|
||||
@ -79,17 +91,16 @@ Note that neighbor lists are re-built every timestep that this fix is
|
||||
invoked, so you should not set N to be too small. However, periodic
|
||||
rebuilds are necessary in order to avoid dangerous rebuilds and missed
|
||||
interactions. Specifically, avoid performing so many MC displacements
|
||||
per timestep that a particle can move beyond the neighbor list skin
|
||||
per timestep that atoms can move beyond the neighbor list skin
|
||||
distance. See the "neighbor"_neighbor.html command for details.
|
||||
|
||||
When a particle is to be inserted, its coordinates are chosen as a
|
||||
random position within the current simulation domain, and its velocity
|
||||
is randomly chosen from the specified temperature distribution given
|
||||
by T.
|
||||
|
||||
Exchanged particles have the specified atom type and are assigned to
|
||||
two groups: the default group "all" and the group specified in the fix
|
||||
gcmc command (which can also be "all").
|
||||
When an atom or molecule is to be inserted, its center-of-mass
|
||||
coordinates are chosen as a random position within the current
|
||||
simulation domain, and new atom velocities are randomly chosen
|
||||
from the specified temperature distribution given by T. Relative
|
||||
coordinates for atoms in a molecule are taken from the template
|
||||
molecule provided by the user. A random initial rotation is used in the
|
||||
case of molecule insertions.
|
||||
|
||||
If the setting for the {molecule} keyword is {no}, then only single
|
||||
atoms are exchanged. In this case, you should ensure you do not
|
||||
@ -100,7 +111,28 @@ non-zero molecule ID, but does not check for this at the time of
|
||||
deletion.
|
||||
|
||||
If the setting for the {molecule} keyword is {yes}, entire molecules
|
||||
are exchanged. This feature is not yet supported.
|
||||
are exchanged. The user must supply a model molecule in the data
|
||||
file to use as a template for exchanges, and that molecule's number
|
||||
must be given in the fix GCMC command as the "type" of the exchanged
|
||||
gas. The model molecule can then be immediately deleted using the
|
||||
"delete_atoms"_delete_atoms.html command.
|
||||
|
||||
Optionally, users may specify the maximum rotation angle for
|
||||
molecular rotations using the {maxangle} keyword and specifying
|
||||
the angle in degrees. The specified angle will apply to all three
|
||||
Euler angles used internally to define the rotation matrix for
|
||||
molecular rotations. The max angle can be set to zero, but rotations
|
||||
will be pointless. Note that the default is ten degrees for each
|
||||
Euler angle.
|
||||
|
||||
For atomic gasses, inserted atoms have the specified atom type, but
|
||||
deleted atoms are any atoms that have been inserted or that belong
|
||||
to the user-specified fix group. For molecular gasses, exchanged
|
||||
molecules use the same atom types as in the template molecule
|
||||
supplied by the user. In both cases, exchanged
|
||||
atoms/molecules are assigned to two groups: the default group "all"
|
||||
and the group specified in the fix gcmc command (which can also be
|
||||
"all").
|
||||
|
||||
Use of this fix typically will cause the number of atoms to fluctuate,
|
||||
therefore, you will want to use the
|
||||
@ -134,10 +166,12 @@ values are the following global cummulative quantities:
|
||||
|
||||
1 = displacement attempts
|
||||
2 = displacement successes
|
||||
3 = deletion attempts
|
||||
4 = deletion successes
|
||||
5 = insertion attempts
|
||||
6 = insertion successes :ul
|
||||
3 = insertion attempts
|
||||
4 = insertion successes
|
||||
5 = deletion attempts
|
||||
6 = deletion successes
|
||||
7 = rotation attempts
|
||||
8 = rotation successes :ul
|
||||
|
||||
The vector values calculated by this fix are "extensive".
|
||||
|
||||
@ -154,9 +188,6 @@ LAMMPS"_Section_start.html#start_3 section for more info.
|
||||
Do not set "neigh_modify once yes" or else this fix will never be
|
||||
called. Reneighboring is required.
|
||||
|
||||
You cannot currently exchange charged particles or molecules with a
|
||||
net charge.
|
||||
|
||||
Only pairwise interactions, as defined by the
|
||||
"pair_style"_pair_style.html command, are included in this
|
||||
calculation. Long-range interactions due to a
|
||||
@ -167,14 +198,25 @@ this fix. For example, 3-body potentials, such as
|
||||
be used. "EAM"_pair_eam.html potentials for metals only include the
|
||||
pair potential portion of the EAM interaction, not the embedding term.
|
||||
|
||||
Can be run in parallel, but aspects of the GCMC part will not scale
|
||||
well in parallel. Only usable for 3D simulations with orthogonal
|
||||
simulation cells.
|
||||
|
||||
Note that very lengthy simulations involving insertions/deletions of
|
||||
billions of gas molecules may run out of atom or molecule IDs and
|
||||
trigger an error, so it is better to run multiple shorter-duration
|
||||
simulations. Likewise, very large molecules have not been tested
|
||||
and may turn out to be problematic.
|
||||
|
||||
[Related commands:]
|
||||
|
||||
"fix_nvt"_fix_nvt.html, "neighbor"_neighbor.html,
|
||||
"fix_deposit"_fix_deposit.html, "fix_evaporate"_fix_evaporate.html
|
||||
"fix_deposit"_fix_deposit.html, "fix_evaporate"_fix_evaporate.html,
|
||||
"delete_atoms"_delete_atoms.html
|
||||
|
||||
[Default:]
|
||||
|
||||
The option defaults are molecule = no.
|
||||
The option defaults are molecule = no, maxangle = 10.
|
||||
|
||||
:line
|
||||
|
||||
|
||||
@ -91,9 +91,17 @@ number.
|
||||
swaps is computed by the fix and can be output. Dividing this
|
||||
quantity by time and the cross-sectional area of the simulation box
|
||||
yields a heat flux. The ratio of heat flux to the slope of the
|
||||
temperature profile is the thermal conductivity of the fluid,
|
||||
in appopriate units. See the <A HREF = "#Muller-Plathe">Muller-Plathe paper</A> for
|
||||
details.
|
||||
temperature profile is proportional to the thermal conductivity of the
|
||||
fluid, in appropriate units. See the <A HREF = "#Muller-Plathe">Muller-Plathe
|
||||
paper</A> for details.
|
||||
</P>
|
||||
<P>IMPORTANT NOTE: If your system is periodic in the direction of the
|
||||
heat flux, then the flux is going in 2 directions. This means the
|
||||
effective heat flux in one direction is reduced by a factor of 2. You
|
||||
will see this in the equations for thermal conductivity (kappa) in the
|
||||
Muller-Plathe paper. LAMMPS is simply tallying kinetic energy which
|
||||
does not account for whether or not your system is periodic; you must
|
||||
use the value appropriately to yield a kappa for your system.
|
||||
</P>
|
||||
<P>IMPORTANT NOTE: After equilibration, if the temperature gradient you
|
||||
observe is not linear, then you are likely swapping energy too
|
||||
|
||||
@ -81,9 +81,17 @@ As described below, the total kinetic energy transferred by these
|
||||
swaps is computed by the fix and can be output. Dividing this
|
||||
quantity by time and the cross-sectional area of the simulation box
|
||||
yields a heat flux. The ratio of heat flux to the slope of the
|
||||
temperature profile is the thermal conductivity of the fluid,
|
||||
in appopriate units. See the "Muller-Plathe paper"_#Muller-Plathe for
|
||||
details.
|
||||
temperature profile is proportional to the thermal conductivity of the
|
||||
fluid, in appropriate units. See the "Muller-Plathe
|
||||
paper"_#Muller-Plathe for details.
|
||||
|
||||
IMPORTANT NOTE: If your system is periodic in the direction of the
|
||||
heat flux, then the flux is going in 2 directions. This means the
|
||||
effective heat flux in one direction is reduced by a factor of 2. You
|
||||
will see this in the equations for thermal conductivity (kappa) in the
|
||||
Muller-Plathe paper. LAMMPS is simply tallying kinetic energy which
|
||||
does not account for whether or not your system is periodic; you must
|
||||
use the value appropriately to yield a kappa for your system.
|
||||
|
||||
IMPORTANT NOTE: After equilibration, if the temperature gradient you
|
||||
observe is not linear, then you are likely swapping energy too
|
||||
|
||||
@ -92,9 +92,17 @@ sense. This is why <I>Nbin</I> is restricted to being an even number.
|
||||
swaps is computed by the fix and can be output. Dividing this
|
||||
quantity by time and the cross-sectional area of the simulation box
|
||||
yields a momentum flux. The ratio of momentum flux to the slope of
|
||||
the shear velocity profile is the viscosity of the fluid, in
|
||||
appopriate units. See the <A HREF = "#Muller-Plathe">Muller-Plathe paper</A> for
|
||||
details.
|
||||
the shear velocity profile is proportional to the viscosity of the
|
||||
fluid, in appropriate units. See the <A HREF = "#Muller-Plathe">Muller-Plathe
|
||||
paper</A> for details.
|
||||
</P>
|
||||
<P>IMPORTANT NOTE: If your system is periodic in the direction of the
|
||||
momentum flux, then the flux is going in 2 directions. This means the
|
||||
effective momentum flux in one direction is reduced by a factor of 2.
|
||||
You will see this in the equations for viscosity in the Muller-Plathe
|
||||
paper. LAMMPS is simply tallying momentum which does not account for
|
||||
whether or not your system is periodic; you must use the value
|
||||
appropriately to yield a viscosity for your system.
|
||||
</P>
|
||||
<P>IMPORTANT NOTE: After equilibration, if the velocity profile you
|
||||
observe is not linear, then you are likely swapping momentum too
|
||||
|
||||
@ -81,9 +81,17 @@ As described below, the total momentum transferred by these velocity
|
||||
swaps is computed by the fix and can be output. Dividing this
|
||||
quantity by time and the cross-sectional area of the simulation box
|
||||
yields a momentum flux. The ratio of momentum flux to the slope of
|
||||
the shear velocity profile is the viscosity of the fluid, in
|
||||
appopriate units. See the "Muller-Plathe paper"_#Muller-Plathe for
|
||||
details.
|
||||
the shear velocity profile is proportional to the viscosity of the
|
||||
fluid, in appropriate units. See the "Muller-Plathe
|
||||
paper"_#Muller-Plathe for details.
|
||||
|
||||
IMPORTANT NOTE: If your system is periodic in the direction of the
|
||||
momentum flux, then the flux is going in 2 directions. This means the
|
||||
effective momentum flux in one direction is reduced by a factor of 2.
|
||||
You will see this in the equations for viscosity in the Muller-Plathe
|
||||
paper. LAMMPS is simply tallying momentum which does not account for
|
||||
whether or not your system is periodic; you must use the value
|
||||
appropriately to yield a viscosity for your system.
|
||||
|
||||
IMPORTANT NOTE: After equilibration, if the velocity profile you
|
||||
observe is not linear, then you are likely swapping momentum too
|
||||
|
||||
@ -59,11 +59,4 @@ section for more info on packages.
|
||||
</P>
|
||||
<P><B>Default:</B> none
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<A NAME = "Mayo"></A>
|
||||
|
||||
<P><B>(Mayo)</B> Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909
|
||||
(1990),
|
||||
</P>
|
||||
</HTML>
|
||||
|
||||
@ -56,8 +56,3 @@ section for more info on packages.
|
||||
|
||||
[Default:] none
|
||||
|
||||
:line
|
||||
|
||||
:link(Mayo)
|
||||
[(Mayo)] Mayo, Olfason, Goddard III, J Phys Chem, 94, 8897-8909
|
||||
(1990),
|
||||
|
||||
@ -122,21 +122,22 @@ It should be used with <A HREF = "pair_style.html">pair styles</A> with a
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<P>The <I>pppm/disp</I> and <I>pppm/disp/tip4p</I> styles add a long-range
|
||||
dispersion sum option for 1/r^6 potentials, similar to the
|
||||
<I>ewald/disp</I> style. The 1/r^6 capability means that Lennard-Jones or
|
||||
Buckingham potentials can be used without a cutoff, i.e. they become
|
||||
full long-range potentials.
|
||||
<P>The <I>pppm/disp</I> and <I>pppm/disp/tip4p</I> styles add a mesh-based long-range
|
||||
dispersion sum option for 1/r^6 potentials <A HREF = "#Isele-Holder">(Isele-Holder)</A>,
|
||||
similar to the <I>ewald/disp</I> style. The 1/r^6 capability means
|
||||
that Lennard-Jones or Buckingham potentials can be used without a cutoff,
|
||||
i.e. they become full long-range potentials.
|
||||
</P>
|
||||
<P>For these styles, it is currently recommended that you set the
|
||||
dispersion mesh size and other parameters explicitly via the
|
||||
<A HREF = "kspace_modify.html">kspace_modify</A> command, rather than let LAMMPS set
|
||||
them automatically. For example, a set of parameters that works well
|
||||
for TIP4P water models is a LJ cutoff of 10 Angstrom, interpolation
|
||||
order = 5 (the default), grid spacing = 4.17 Angstroms, and Ewald
|
||||
parameter = 0.28. These parameters work well for the <I>ik</I>
|
||||
differentiation. For the <I>ad</I> setting, a smaller grid is needed,
|
||||
e.g. 3 Angstroms.
|
||||
for surface systems when using real units is a LJ cutoff of 10 Angstrom,
|
||||
interpolation order = 5 (the default), grid spacing = 4.17 Angstroms,
|
||||
and Ewald parameter = 0.28. These parameters work well for the <I>ik</I>
|
||||
differentiation. For the <I>ad</I> setting, a smaller grid spacing is needed,
|
||||
e.g. 3 Angstroms. Further information on the influence of the parameters
|
||||
and how to choose them is described in <A HREF = "#Isele-Holder">(Isele-Holder)</A>.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
@ -282,6 +283,10 @@ Adam Hilger, NY (1989).
|
||||
|
||||
<P><B>(Veld)</B> In 't Veld, Ismail, Grest, J Chem Phys, in press (2007).
|
||||
</P>
|
||||
<A NAME = "Isele-Holder"></A>
|
||||
|
||||
<P><B>(Isele-Holder)</B> Isele-Holder, Mitchell, Ismail, J Chem Phys, 137, 174107 (2012).
|
||||
</P>
|
||||
<A NAME = "Hardy"></A>
|
||||
|
||||
<P><B>(Hardy)</B> David Hardy thesis: Multilevel Summation for the Fast
|
||||
|
||||
@ -115,21 +115,22 @@ It should be used with "pair styles"_pair_style.html with a
|
||||
|
||||
:line
|
||||
|
||||
The {pppm/disp} and {pppm/disp/tip4p} styles add a long-range
|
||||
dispersion sum option for 1/r^6 potentials, similar to the
|
||||
{ewald/disp} style. The 1/r^6 capability means that Lennard-Jones or
|
||||
Buckingham potentials can be used without a cutoff, i.e. they become
|
||||
full long-range potentials.
|
||||
The {pppm/disp} and {pppm/disp/tip4p} styles add a mesh-based long-range
|
||||
dispersion sum option for 1/r^6 potentials "(Isele-Holder)"_#Isele-Holder,
|
||||
similar to the {ewald/disp} style. The 1/r^6 capability means
|
||||
that Lennard-Jones or Buckingham potentials can be used without a cutoff,
|
||||
i.e. they become full long-range potentials.
|
||||
|
||||
For these styles, it is currently recommended that you set the
|
||||
dispersion mesh size and other parameters explicitly via the
|
||||
"kspace_modify"_kspace_modify.html command, rather than let LAMMPS set
|
||||
them automatically. For example, a set of parameters that works well
|
||||
for TIP4P water models is a LJ cutoff of 10 Angstrom, interpolation
|
||||
order = 5 (the default), grid spacing = 4.17 Angstroms, and Ewald
|
||||
parameter = 0.28. These parameters work well for the {ik}
|
||||
differentiation. For the {ad} setting, a smaller grid is needed,
|
||||
e.g. 3 Angstroms.
|
||||
for surface systems when using real units is a LJ cutoff of 10 Angstrom,
|
||||
interpolation order = 5 (the default), grid spacing = 4.17 Angstroms,
|
||||
and Ewald parameter = 0.28. These parameters work well for the {ik}
|
||||
differentiation. For the {ad} setting, a smaller grid spacing is needed,
|
||||
e.g. 3 Angstroms. Further information on the influence of the parameters
|
||||
and how to choose them is described in "(Isele-Holder)"_#Isele-Holder.
|
||||
|
||||
:line
|
||||
|
||||
@ -268,6 +269,9 @@ Adam Hilger, NY (1989).
|
||||
:link(Veld)
|
||||
[(Veld)] In 't Veld, Ismail, Grest, J Chem Phys, in press (2007).
|
||||
|
||||
:link(Isele-Holder)
|
||||
[(Isele-Holder)] Isele-Holder, Mitchell, Ismail, J Chem Phys, 137, 174107 (2012).
|
||||
|
||||
:link(Hardy)
|
||||
[(Hardy)] David Hardy thesis: Multilevel Summation for the Fast
|
||||
Evaluation of Forces for the Simulation of Biomolecules, University of
|
||||
|
||||
@ -38,14 +38,15 @@ be used in an input script command as $a or $z. If it is multiple
|
||||
letters, it can be used as ${myTemp}.
|
||||
</P>
|
||||
<P>If multiple variables are used as arguments to the <I>next</I> command,
|
||||
then all must be of the same variable style: <I>index</I>, <I>loop</I>,
|
||||
then all must be of the same variable style: <I>index</I>, <I>loop</I>, <I>file</I>,
|
||||
<I>universe</I>, or <I>uloop</I>. An exception is that <I>universe</I>- and
|
||||
<I>uloop</I>-style variables can be mixed in the same <I>next</I> command.
|
||||
</P>
|
||||
<P>All the variables specified with the next command are incremented by
|
||||
one value from their respective list or values. <I>String-</I> or <I>atom</I>-
|
||||
or <I>equal</I>- or <I>world</I>-style variables cannot be used with the the
|
||||
next command, since they only store a single value.
|
||||
one value from their respective list of values. A <I>file</I>-style variable
|
||||
reads the next line from its associated file. <I>String-</I> or <I>atom</I>- or
|
||||
<I>equal</I>- or <I>world</I>-style variables cannot be used with the the next
|
||||
command, since they only store a single value.
|
||||
</P>
|
||||
<P>When any of the variables in the next command has no more values, a
|
||||
flag is set that causes the input script to skip the next
|
||||
@ -53,18 +54,19 @@ flag is set that causes the input script to skip the next
|
||||
a next command to exit. As explained in the <A HREF = "variable.html">variable</A>
|
||||
command, the variable that has exhausted its values is also deleted.
|
||||
This allows it to be used and re-defined later in the input script.
|
||||
<I>File</I>-style variables are exhausted when the end-of-file is reached.
|
||||
</P>
|
||||
<P>When the next command is used with <I>index</I>- or <I>loop</I>-style variables,
|
||||
the next value is assigned to the variable for all processors. When
|
||||
the next command is used with <I>universe</I>- or <I>uloop</I>-style variables,
|
||||
the next value is assigned to whichever processor partition executes
|
||||
the command first. All processors in the partition are assigned the
|
||||
same value. Running LAMMPS on multiple partitions of processors via
|
||||
the "-partition" command-line switch is described in <A HREF = "Section_start.html#start_7">this
|
||||
section</A> of the manual. <I>Universe</I>- and
|
||||
<I>uloop</I>-style variables are incremented using the files
|
||||
"tmp.lammps.variable" and "tmp.lammps.variable.lock" which you will
|
||||
see in your directory during such a LAMMPS run.
|
||||
<P>When the next command is used with <I>index</I>- or <I>loop</I>-style or
|
||||
<I>file</I>-style variables, the next value is assigned to the variable for
|
||||
all processors. When the next command is used with <I>universe</I>- or
|
||||
<I>uloop</I>-style variables, the next value is assigned to whichever
|
||||
processor partition executes the command first. All processors in the
|
||||
partition are assigned the same value. Running LAMMPS on multiple
|
||||
partitions of processors via the "-partition" command-line switch is
|
||||
described in <A HREF = "Section_start.html#start_7">this section</A> of the manual.
|
||||
<I>Universe</I>- and <I>uloop</I>-style variables are incremented using the
|
||||
files "tmp.lammps.variable" and "tmp.lammps.variable.lock" which you
|
||||
will see in your directory during such a LAMMPS run.
|
||||
</P>
|
||||
<P>Here is an example of running a series of simulations using the next
|
||||
command with an <I>index</I>-style variable. If this input script is named
|
||||
|
||||
32
doc/next.txt
32
doc/next.txt
@ -35,14 +35,15 @@ be used in an input script command as $a or $z. If it is multiple
|
||||
letters, it can be used as $\{myTemp\}.
|
||||
|
||||
If multiple variables are used as arguments to the {next} command,
|
||||
then all must be of the same variable style: {index}, {loop},
|
||||
then all must be of the same variable style: {index}, {loop}, {file},
|
||||
{universe}, or {uloop}. An exception is that {universe}- and
|
||||
{uloop}-style variables can be mixed in the same {next} command.
|
||||
|
||||
All the variables specified with the next command are incremented by
|
||||
one value from their respective list or values. {String-} or {atom}-
|
||||
or {equal}- or {world}-style variables cannot be used with the the
|
||||
next command, since they only store a single value.
|
||||
one value from their respective list of values. A {file}-style variable
|
||||
reads the next line from its associated file. {String-} or {atom}- or
|
||||
{equal}- or {world}-style variables cannot be used with the the next
|
||||
command, since they only store a single value.
|
||||
|
||||
When any of the variables in the next command has no more values, a
|
||||
flag is set that causes the input script to skip the next
|
||||
@ -50,18 +51,19 @@ flag is set that causes the input script to skip the next
|
||||
a next command to exit. As explained in the "variable"_variable.html
|
||||
command, the variable that has exhausted its values is also deleted.
|
||||
This allows it to be used and re-defined later in the input script.
|
||||
{File}-style variables are exhausted when the end-of-file is reached.
|
||||
|
||||
When the next command is used with {index}- or {loop}-style variables,
|
||||
the next value is assigned to the variable for all processors. When
|
||||
the next command is used with {universe}- or {uloop}-style variables,
|
||||
the next value is assigned to whichever processor partition executes
|
||||
the command first. All processors in the partition are assigned the
|
||||
same value. Running LAMMPS on multiple partitions of processors via
|
||||
the "-partition" command-line switch is described in "this
|
||||
section"_Section_start.html#start_7 of the manual. {Universe}- and
|
||||
{uloop}-style variables are incremented using the files
|
||||
"tmp.lammps.variable" and "tmp.lammps.variable.lock" which you will
|
||||
see in your directory during such a LAMMPS run.
|
||||
When the next command is used with {index}- or {loop}-style or
|
||||
{file}-style variables, the next value is assigned to the variable for
|
||||
all processors. When the next command is used with {universe}- or
|
||||
{uloop}-style variables, the next value is assigned to whichever
|
||||
processor partition executes the command first. All processors in the
|
||||
partition are assigned the same value. Running LAMMPS on multiple
|
||||
partitions of processors via the "-partition" command-line switch is
|
||||
described in "this section"_Section_start.html#start_7 of the manual.
|
||||
{Universe}- and {uloop}-style variables are incremented using the
|
||||
files "tmp.lammps.variable" and "tmp.lammps.variable.lock" which you
|
||||
will see in your directory during such a LAMMPS run.
|
||||
|
||||
Here is an example of running a series of simulations using the next
|
||||
command with an {index}-style variable. If this input script is named
|
||||
|
||||
@ -153,6 +153,7 @@ section of <A HREF = "Section_commands.html#cmd_5">this page</A>.
|
||||
<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_mie.html">pair_style mie/cut</A> - Mie potential
|
||||
<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
|
||||
|
||||
@ -150,6 +150,7 @@ section of "this page"_Section_commands.html#cmd_5.
|
||||
"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 mie/cut"_pair_mie.html - Mie potential
|
||||
"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
|
||||
|
||||
105
doc/pair_mie.html
Normal file
105
doc/pair_mie.html
Normal file
@ -0,0 +1,105 @@
|
||||
<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 mie/cut command
|
||||
</H3>
|
||||
<P><B>Syntax:</B>
|
||||
</P>
|
||||
<PRE>pair_style mie/cut cutoff
|
||||
</PRE>
|
||||
<UL><LI>cutoff = global cutoff for mie/cut interactions (distance units)
|
||||
</UL>
|
||||
<P><B>Examples:</B>
|
||||
</P>
|
||||
<PRE>pair_style mie/cut 10.0
|
||||
pair_coeff 1 1 0.72 3.40 23.00 6.66
|
||||
pair_coeff 2 2 0.30 3.55 12.65 6.00
|
||||
pair_coeff 1 2 0.46 3.32 16.90 6.31
|
||||
</PRE>
|
||||
<P><B>Description:</B>
|
||||
</P>
|
||||
<P>The <I>mie/cut</I> style computes the Mie potential, given by
|
||||
</P>
|
||||
<CENTER><IMG SRC = "Eqs/pair_mie.jpg">
|
||||
</CENTER>
|
||||
<P>Rc is the cutoff and C is a function that depends on the repulsive and
|
||||
attractive exponents, given by:
|
||||
</P>
|
||||
<CENTER><IMG SRC = "Eqs/pair_mie2.jpg">
|
||||
</CENTER>
|
||||
<P>Note that for 12/6 exponents, C is equal to 4 and the formula is the
|
||||
same as the standard Lennard-Jones potential.
|
||||
</P>
|
||||
<P>The following coefficients must be defined for each pair of atoms
|
||||
types via the <A HREF = "pair_coeff.html">pair_coeff</A> command as in the examples
|
||||
above, or in the data file or restart files read by the
|
||||
<A HREF = "read_data.html">read_data</A> or <A HREF = "read_restart.html">read_restart</A>
|
||||
commands, or by mixing as described below:
|
||||
</P>
|
||||
<UL><LI>epsilon (energy units)
|
||||
<LI>sigma (distance units)
|
||||
<LI>gammaR
|
||||
<LI>gammaA
|
||||
<LI>cutoff (distance units)
|
||||
</UL>
|
||||
<P>The last coefficient is optional. If not specified, the global
|
||||
cutoff specified in the pair_style command is used.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<P><B>Mixing, shift, table, tail correction, restart, rRESPA info</B>:
|
||||
</P>
|
||||
<P>For atom type pairs I,J and I != J, the epsilon and sigma coefficients
|
||||
and cutoff distance for all of the mie/cut pair styles can be mixed.
|
||||
If not explicity defined, both the repulsive and attractive gamma
|
||||
exponents for different atoms will be calculated following the same
|
||||
mixing rule defined for distances. The default mix value is
|
||||
<I>geometric</I>. See the "pair_modify" command for details.
|
||||
</P>
|
||||
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> shift
|
||||
option for the energy of the pair interaction.
|
||||
</P>
|
||||
<P>This pair style supports the <A HREF = "pair_modify.html">pair_modify</A> tail
|
||||
option for adding a long-range tail correction to the energy and
|
||||
pressure of the pair interaction.
|
||||
</P>
|
||||
<P>This pair style writes its information to <A HREF = "restart.html">binary restart
|
||||
files</A>, so pair_style and pair_coeff commands do not need
|
||||
to be specified in an input script that reads a restart file.
|
||||
</P>
|
||||
<P>This pair style supports the use of the <I>inner</I>, <I>middle</I>, and <I>outer</I>
|
||||
keywords of the <A HREF = "run_style.html">run_style respa</A> command, meaning the
|
||||
pairwise forces can be partitioned by distance at different levels of
|
||||
the rRESPA hierarchy. See the <A HREF = "run_style.html">run_style</A> command for
|
||||
details.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<P><B>Restrictions:</B> none
|
||||
</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 = "Mie"></A>
|
||||
|
||||
<P><B>(Mie)</B> G. Mie, Ann Phys, 316, 657 (1903).
|
||||
</P>
|
||||
<A NAME = "Avendano"></A>
|
||||
|
||||
<P><B>(Avendano)</B> C. Avendano, T. Lafitte, A. Galindo, C. S. Adjiman,
|
||||
G. Jackson, E. Muller, J Phys Chem B, 115, 11154 (2011).
|
||||
</P>
|
||||
</HTML>
|
||||
100
doc/pair_mie.txt
Normal file
100
doc/pair_mie.txt
Normal file
@ -0,0 +1,100 @@
|
||||
"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 mie/cut command :h3
|
||||
|
||||
[Syntax:]
|
||||
|
||||
pair_style mie/cut cutoff :pre
|
||||
|
||||
cutoff = global cutoff for mie/cut interactions (distance units) :ul
|
||||
|
||||
[Examples:]
|
||||
|
||||
pair_style mie/cut 10.0
|
||||
pair_coeff 1 1 0.72 3.40 23.00 6.66
|
||||
pair_coeff 2 2 0.30 3.55 12.65 6.00
|
||||
pair_coeff 1 2 0.46 3.32 16.90 6.31 :pre
|
||||
|
||||
[Description:]
|
||||
|
||||
The {mie/cut} style computes the Mie potential, given by
|
||||
|
||||
:c,image(Eqs/pair_mie.jpg)
|
||||
|
||||
Rc is the cutoff and C is a function that depends on the repulsive and
|
||||
attractive exponents, given by:
|
||||
|
||||
:c,image(Eqs/pair_mie2.jpg)
|
||||
|
||||
Note that for 12/6 exponents, C is equal to 4 and the formula is the
|
||||
same as the standard Lennard-Jones potential.
|
||||
|
||||
The following coefficients must be defined for each pair of atoms
|
||||
types via the "pair_coeff"_pair_coeff.html command as in the examples
|
||||
above, or in the data file or restart files read by the
|
||||
"read_data"_read_data.html or "read_restart"_read_restart.html
|
||||
commands, or by mixing as described below:
|
||||
|
||||
epsilon (energy units)
|
||||
sigma (distance units)
|
||||
gammaR
|
||||
gammaA
|
||||
cutoff (distance units) :ul
|
||||
|
||||
The last coefficient is optional. If not specified, the global
|
||||
cutoff specified in the pair_style command is used.
|
||||
|
||||
:line
|
||||
|
||||
[Mixing, shift, table, tail correction, restart, rRESPA info]:
|
||||
|
||||
For atom type pairs I,J and I != J, the epsilon and sigma coefficients
|
||||
and cutoff distance for all of the mie/cut pair styles can be mixed.
|
||||
If not explicity defined, both the repulsive and attractive gamma
|
||||
exponents for different atoms will be calculated following the same
|
||||
mixing rule defined for distances. The default mix value is
|
||||
{geometric}. See the "pair_modify" command for details.
|
||||
|
||||
This pair style supports the "pair_modify"_pair_modify.html shift
|
||||
option for the energy of the pair interaction.
|
||||
|
||||
This pair style supports the "pair_modify"_pair_modify.html tail
|
||||
option for adding a long-range tail correction to the energy and
|
||||
pressure of the pair interaction.
|
||||
|
||||
This pair style writes its information to "binary restart
|
||||
files"_restart.html, so pair_style and pair_coeff commands do not need
|
||||
to be specified in an input script that reads a restart file.
|
||||
|
||||
This pair style supports the use of the {inner}, {middle}, and {outer}
|
||||
keywords of the "run_style respa"_run_style.html command, meaning the
|
||||
pairwise forces can be partitioned by distance at different levels of
|
||||
the rRESPA hierarchy. See the "run_style"_run_style.html command for
|
||||
details.
|
||||
|
||||
:line
|
||||
|
||||
[Restrictions:] none
|
||||
|
||||
[Related commands:]
|
||||
|
||||
"pair_coeff"_pair_coeff.html
|
||||
|
||||
[Default:] none
|
||||
|
||||
:line
|
||||
|
||||
:link(Mie)
|
||||
[(Mie)] G. Mie, Ann Phys, 316, 657 (1903).
|
||||
|
||||
:link(Avendano)
|
||||
[(Avendano)] C. Avendano, T. Lafitte, A. Galindo, C. S. Adjiman,
|
||||
G. Jackson, E. Muller, J Phys Chem B, 115, 11154 (2011).
|
||||
|
||||
|
||||
@ -302,7 +302,8 @@ appropriate units if your simulation doesn't use "real" units.
|
||||
</P>
|
||||
<P><B>Default:</B>
|
||||
</P>
|
||||
<P>The keyword defaults are checkqeq = yes, lgvdw = no, safezone = 1.2, mincap = 50.
|
||||
<P>The keyword defaults are checkqeq = yes, lgvdw = no, safezone = 1.2,
|
||||
mincap = 50.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
@ -313,8 +314,8 @@ Journal of Physical Chemistry A, 112, 1040-1053 (2008).
|
||||
</P>
|
||||
<A NAME = "Aktulga"></A>
|
||||
|
||||
<P><B>(Aktulga)</B> Aktulga, Fogarty, Pandit, Grama, Parallel Computing, to
|
||||
appear (2011).
|
||||
<P><B>(Aktulga)</B> Aktulga, Fogarty, Pandit, Grama, Parallel Computing, 38,
|
||||
245-259 (2012).
|
||||
</P>
|
||||
<A NAME = "Liu_2011"></A>
|
||||
|
||||
|
||||
@ -296,7 +296,8 @@ appropriate units if your simulation doesn't use "real" units.
|
||||
|
||||
[Default:]
|
||||
|
||||
The keyword defaults are checkqeq = yes, lgvdw = no, safezone = 1.2, mincap = 50.
|
||||
The keyword defaults are checkqeq = yes, lgvdw = no, safezone = 1.2,
|
||||
mincap = 50.
|
||||
|
||||
:line
|
||||
|
||||
@ -305,8 +306,8 @@ The keyword defaults are checkqeq = yes, lgvdw = no, safezone = 1.2, mincap = 50
|
||||
Journal of Physical Chemistry A, 112, 1040-1053 (2008).
|
||||
|
||||
:link(Aktulga)
|
||||
[(Aktulga)] Aktulga, Fogarty, Pandit, Grama, Parallel Computing, to
|
||||
appear (2011).
|
||||
[(Aktulga)] Aktulga, Fogarty, Pandit, Grama, Parallel Computing, 38,
|
||||
245-259 (2012).
|
||||
|
||||
:link(Liu_2011)
|
||||
[(Liu)] L. Liu, Y. Liu, S. V. Zybin, H. Sun and W. A. Goddard, Journal
|
||||
|
||||
@ -155,6 +155,7 @@ section of <A HREF = "Section_commands.html#cmd_5">this page</A>.
|
||||
<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_mie.html">pair_style mie/cut</A> - Mie potential
|
||||
<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
|
||||
|
||||
@ -152,6 +152,7 @@ section of "this page"_Section_commands.html#cmd_5.
|
||||
"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 mie/cut"_pair_mie.html - Mie potential
|
||||
"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
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
</PRE>
|
||||
<UL><LI>name = name of variable to define
|
||||
|
||||
<LI>style = <I>delete</I> or <I>index</I> or <I>loop</I> or <I>world</I> or <I>universe</I> or <I>uloop</I> or <I>string</I> or <I>equal</I> or <I>atom</I>
|
||||
<LI>style = <I>delete</I> or <I>index</I> or <I>loop</I> or <I>world</I> or <I>universe</I> or <I>uloop</I> or <I>string</I> or <I>file</I> or <I>equal</I> or <I>atom</I>
|
||||
|
||||
<PRE> <I>delete</I> = no args
|
||||
<I>index</I> args = one or more strings
|
||||
@ -39,6 +39,7 @@
|
||||
N = integer size of loop
|
||||
pad = all values will be same length, e.g. 001, 002, ..., 100
|
||||
<I>string</I> arg = one string
|
||||
<I>file</I> arg = filename
|
||||
<I>equal</I> or <I>atom</I> args = one formula containing numbers, thermo keywords, math operations, group functions, atom values and vectors, compute/fix/variable references
|
||||
numbers = 0.0, 100, -5.4, 2.8e-4, etc
|
||||
constants = PI
|
||||
@ -59,7 +60,7 @@
|
||||
bound(group,xmin,region), gyration(group,region), ke(group,reigon),
|
||||
angmom(group,dim,region), torque(group,dim,region),
|
||||
inertia(group,dimdim,region), omega(group,dim,region)
|
||||
special functions = sum(x), min(x), max(x), ave(x), trap(x), gmask(x), rmask(x), grmask(x,y)
|
||||
special functions = sum(x), min(x), max(x), ave(x), trap(x), gmask(x), rmask(x), grmask(x,y), next(x)
|
||||
atom value = mass[i], type[i], x[i], y[i], z[i], vx[i], vy[i], vz[i], fx[i], fy[i], fz[i]
|
||||
atom vector = mass, type, x, y, z, vx, vy, vz, fx, fy, fz
|
||||
compute references = c_ID, c_ID[i], c_ID[i][j]
|
||||
@ -79,6 +80,7 @@ variable b equal xcm(mol1,x)/2.0
|
||||
variable b equal c_myTemp
|
||||
variable b atom x*y/vol
|
||||
variable foo string myfile
|
||||
variable f file values.txt
|
||||
variable temp world 300.0 310.0 320.0 ${Tfinal}
|
||||
variable x universe 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
variable x uloop 15 pad
|
||||
@ -154,13 +156,13 @@ the variable's string. The variable name can be referenced as $x if
|
||||
the name "x" is a single character, or as ${LoopVar} if the name
|
||||
"LoopVar" is one or more characters.
|
||||
</P>
|
||||
<P>As described below, for variable styles <I>index</I>, <I>loop</I>, <I>universe</I>,
|
||||
and <I>uloop</I>, which string is assigned to a variable can be incremented
|
||||
via the <A HREF = "next.html">next</A> command. When there are no more strings to
|
||||
assign, the variable is exhausted and a flag is set that causes the
|
||||
next <A HREF = "jump.html">jump</A> command encountered in the input script to be
|
||||
skipped. This enables the construction of simple loops in the input
|
||||
script that are iterated over and then exited from.
|
||||
<P>As described below, for variable styles <I>index</I>, <I>loop</I>, <I>file</I>,
|
||||
<I>universe</I>, and <I>uloop</I>, which string is assigned to a variable can be
|
||||
incremented via the <A HREF = "next.html">next</A> command. When there are no more
|
||||
strings to assign, the variable is exhausted and a flag is set that
|
||||
causes the next <A HREF = "jump.html">jump</A> command encountered in the input
|
||||
script to be skipped. This enables the construction of simple loops
|
||||
in the input script that are iterated over and then exited from.
|
||||
</P>
|
||||
<P>As explained above, an exhausted variable can be re-used in an input
|
||||
script. The <I>delete</I> style also removes the variable, the same as if
|
||||
@ -235,6 +237,32 @@ strings are the integers from 1 to N. This allows generation of long
|
||||
list of runs (e.g. 1000) without having to list N strings in the input
|
||||
script.
|
||||
</P>
|
||||
<P>For the <I>string</I> style, a single string is assigned to the variable.
|
||||
The only difference between this and using the <I>index</I> style with a
|
||||
single string is that a variable with <I>string</I> style can be redefined.
|
||||
E.g. by another command later in the input script, or if the script is
|
||||
read again in a loop.
|
||||
</P>
|
||||
<P>For the <I>file</I> style, a filename is provided which contains a list of
|
||||
strings to assign to the variable, one per line. The strings can be
|
||||
numeric values if desired; see the discussion of the next() function
|
||||
below for equal-style variables, which will convert the string of a
|
||||
file-style variable into a numeric value in a formula.
|
||||
</P>
|
||||
<P>When a file-style variable is defined, the file is opened and the
|
||||
string on the first line is read and stored with the variable. This
|
||||
means the variable can then be evaluated as many times as desired and
|
||||
will return that string. There are two ways to cause the next string
|
||||
from the file to be read: use the <A HREF = "next.html">next</A> command or the
|
||||
next() function in an equal- or atom-style variable, as discussed
|
||||
below.
|
||||
</P>
|
||||
<P>The rules for formatting the file are as follows. A comment character
|
||||
"#" can be used anywhere on a line; text starting with the comment
|
||||
character is stripped. Blank lines are skipped. The first "word" of
|
||||
a non-blank line, delimited by white space, is the "string" assigned
|
||||
to the variable.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<P>For the <I>equal</I> and <I>atom</I> styles, a single string is specified which
|
||||
@ -279,7 +307,7 @@ references to other variables.
|
||||
<TR><TD >Math functions</TD><TD > sqrt(x), exp(x), ln(x), log(x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x), ramp(x,y), stagger(x,y), logfreq(x,y,z), stride(x,y,z), vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z)</TD></TR>
|
||||
<TR><TD >Group functions</TD><TD > count(ID), mass(ID), charge(ID), xcm(ID,dim), vcm(ID,dim), fcm(ID,dim), bound(ID,dir), gyration(ID), ke(ID), angmom(ID,dim), torque(ID,dim), inertia(ID,dimdim), omega(ID,dim)</TD></TR>
|
||||
<TR><TD >Region functions</TD><TD > count(ID,IDR), mass(ID,IDR), charge(ID,IDR), xcm(ID,dim,IDR), vcm(ID,dim,IDR), fcm(ID,dim,IDR), bound(ID,dir,IDR), gyration(ID,IDR), ke(ID,IDR), angmom(ID,dim,IDR), torque(ID,dim,IDR), inertia(ID,dimdim,IDR), omega(ID,dim,IDR)</TD></TR>
|
||||
<TR><TD >Special functions</TD><TD > sum(x), min(x), max(x), ave(x), trap(x), gmask(x), rmask(x), grmask(x,y)</TD></TR>
|
||||
<TR><TD >Special functions</TD><TD > sum(x), min(x), max(x), ave(x), trap(x), gmask(x), rmask(x), grmask(x,y), next(x)</TD></TR>
|
||||
<TR><TD >Atom values</TD><TD > mass[i], type[i], x[i], y[i], z[i], vx[i], vy[i], vz[i], fx[i], fy[i], fz[i]</TD></TR>
|
||||
<TR><TD >Atom vectors</TD><TD > mass, type, x, y, z, vx, vy, vz, fx, fy, fz</TD></TR>
|
||||
<TR><TD >Compute references</TD><TD > c_ID, c_ID[i], c_ID[i][j]</TD></TR>
|
||||
@ -559,6 +587,20 @@ and the second is a region ID. It can only be used in atom-style
|
||||
variables. It returns a 1 for atoms that are in both the group and
|
||||
region, and a 0 for atoms that are not in both.
|
||||
</P>
|
||||
<P>The next(x) function takes 1 argument which is a variable ID (not
|
||||
"v_foo", just "foo"). It must be for a file-style variable. Each
|
||||
time the next() function is invoked (i.e. each time the equal-style or
|
||||
atom-style variable is evaluated), the current string value stored by
|
||||
the file-style variable is converted to a numeric value returned by
|
||||
the function, and the next value from the file is read and stored.
|
||||
Note that if the line previously read from the file was not a numeric
|
||||
string, then it will typically evaluate to 0.0, which is likely not
|
||||
what you want. Since the file-style variable reads and stores the
|
||||
first line of the file when it is defined in the input script, this is
|
||||
the value that will be returned the first time the next() function is
|
||||
invoked. If next() is invoked more times than there are lines in the
|
||||
file, the value for the last line is repeatedly returned.
|
||||
</P>
|
||||
<HR>
|
||||
|
||||
<H4>Atom Values and Vectors
|
||||
@ -649,20 +691,26 @@ the doc pages for individual fix commands for details.
|
||||
|
||||
<H4>Variable References
|
||||
</H4>
|
||||
<P>Variable references access quantities calulated by other variables,
|
||||
which will cause those variables to be evaluated. The name in the
|
||||
reference should be replaced by the name of a variable defined
|
||||
elsewhere in the input script. As discussed on this doc page,
|
||||
atom-style variables generate a per-atom vector of values; all other
|
||||
variable styles generate a global scalar value. An equal-style
|
||||
variable can only use scalar values, which means another equal-style
|
||||
variable or an element of an atom-style variable. Atom-style
|
||||
variables can use the same scalar values. They can also use other
|
||||
atom-style variables.
|
||||
<P>Variable references access quantities stored or calculated by other
|
||||
variables, which will cause those variables to be evaluated. The name
|
||||
in the reference should be replaced by the name of a variable defined
|
||||
elsewhere in the input script.
|
||||
</P>
|
||||
<P>As discussed on this doc page, equal-style variables generate a global
|
||||
scalar numeric value; atom-style variables generate a per-atom vector
|
||||
of numeric values; all other variables store a string. The formula
|
||||
for an equal-style variable can use any style of variable except an
|
||||
atom-style (unless only a single value from the atom-style variable is
|
||||
accessed via a subscript). If a string-storing variable is used,
|
||||
the string is converted to a numeric value. Note that this
|
||||
will typically produce a 0.0 if the string is not a numeric string,
|
||||
which is likely not what you want. The formula for an atom-style
|
||||
variable can use any style of variable, including other atom-style
|
||||
variables.
|
||||
</P>
|
||||
<P>Examples of different kinds of variable references are as follows.
|
||||
There is no ambiguity as to what a reference means, since variables
|
||||
produce only a global scalar or a per-atom vectors, never both.
|
||||
produce only a global scalar or a per-atom vector, never both.
|
||||
</P>
|
||||
<DIV ALIGN=center><TABLE BORDER=1 >
|
||||
<TR><TD >v_name</TD><TD > scalar, or per-atom vector</TD></TR>
|
||||
|
||||
@ -13,7 +13,7 @@ variable command :h3
|
||||
variable name style args ... :pre
|
||||
|
||||
name = name of variable to define :ulb,l
|
||||
style = {delete} or {index} or {loop} or {world} or {universe} or {uloop} or {string} or {equal} or {atom} :l
|
||||
style = {delete} or {index} or {loop} or {world} or {universe} or {uloop} or {string} or {file} or {equal} or {atom} :l
|
||||
{delete} = no args
|
||||
{index} args = one or more strings
|
||||
{loop} args = N
|
||||
@ -34,6 +34,7 @@ style = {delete} or {index} or {loop} or {world} or {universe} or {uloop} or {st
|
||||
N = integer size of loop
|
||||
pad = all values will be same length, e.g. 001, 002, ..., 100
|
||||
{string} arg = one string
|
||||
{file} arg = filename
|
||||
{equal} or {atom} args = one formula containing numbers, thermo keywords, math operations, group functions, atom values and vectors, compute/fix/variable references
|
||||
numbers = 0.0, 100, -5.4, 2.8e-4, etc
|
||||
constants = PI
|
||||
@ -54,7 +55,7 @@ style = {delete} or {index} or {loop} or {world} or {universe} or {uloop} or {st
|
||||
bound(group,xmin,region), gyration(group,region), ke(group,reigon),
|
||||
angmom(group,dim,region), torque(group,dim,region),
|
||||
inertia(group,dimdim,region), omega(group,dim,region)
|
||||
special functions = sum(x), min(x), max(x), ave(x), trap(x), gmask(x), rmask(x), grmask(x,y)
|
||||
special functions = sum(x), min(x), max(x), ave(x), trap(x), gmask(x), rmask(x), grmask(x,y), next(x)
|
||||
atom value = mass\[i\], type\[i\], x\[i\], y\[i\], z\[i\], vx\[i\], vy\[i\], vz\[i\], fx\[i\], fy\[i\], fz\[i\]
|
||||
atom vector = mass, type, x, y, z, vx, vy, vz, fx, fy, fz
|
||||
compute references = c_ID, c_ID\[i\], c_ID\[i\]\[j\]
|
||||
@ -73,6 +74,7 @@ variable b equal xcm(mol1,x)/2.0
|
||||
variable b equal c_myTemp
|
||||
variable b atom x*y/vol
|
||||
variable foo string myfile
|
||||
variable f file values.txt
|
||||
variable temp world 300.0 310.0 320.0 $\{Tfinal\}
|
||||
variable x universe 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
variable x uloop 15 pad
|
||||
@ -148,13 +150,13 @@ the variable's string. The variable name can be referenced as $x if
|
||||
the name "x" is a single character, or as $\{LoopVar\} if the name
|
||||
"LoopVar" is one or more characters.
|
||||
|
||||
As described below, for variable styles {index}, {loop}, {universe},
|
||||
and {uloop}, which string is assigned to a variable can be incremented
|
||||
via the "next"_next.html command. When there are no more strings to
|
||||
assign, the variable is exhausted and a flag is set that causes the
|
||||
next "jump"_jump.html command encountered in the input script to be
|
||||
skipped. This enables the construction of simple loops in the input
|
||||
script that are iterated over and then exited from.
|
||||
As described below, for variable styles {index}, {loop}, {file},
|
||||
{universe}, and {uloop}, which string is assigned to a variable can be
|
||||
incremented via the "next"_next.html command. When there are no more
|
||||
strings to assign, the variable is exhausted and a flag is set that
|
||||
causes the next "jump"_jump.html command encountered in the input
|
||||
script to be skipped. This enables the construction of simple loops
|
||||
in the input script that are iterated over and then exited from.
|
||||
|
||||
As explained above, an exhausted variable can be re-used in an input
|
||||
script. The {delete} style also removes the variable, the same as if
|
||||
@ -229,6 +231,32 @@ strings are the integers from 1 to N. This allows generation of long
|
||||
list of runs (e.g. 1000) without having to list N strings in the input
|
||||
script.
|
||||
|
||||
For the {string} style, a single string is assigned to the variable.
|
||||
The only difference between this and using the {index} style with a
|
||||
single string is that a variable with {string} style can be redefined.
|
||||
E.g. by another command later in the input script, or if the script is
|
||||
read again in a loop.
|
||||
|
||||
For the {file} style, a filename is provided which contains a list of
|
||||
strings to assign to the variable, one per line. The strings can be
|
||||
numeric values if desired; see the discussion of the next() function
|
||||
below for equal-style variables, which will convert the string of a
|
||||
file-style variable into a numeric value in a formula.
|
||||
|
||||
When a file-style variable is defined, the file is opened and the
|
||||
string on the first line is read and stored with the variable. This
|
||||
means the variable can then be evaluated as many times as desired and
|
||||
will return that string. There are two ways to cause the next string
|
||||
from the file to be read: use the "next"_next.html command or the
|
||||
next() function in an equal- or atom-style variable, as discussed
|
||||
below.
|
||||
|
||||
The rules for formatting the file are as follows. A comment character
|
||||
"#" can be used anywhere on a line; text starting with the comment
|
||||
character is stripped. Blank lines are skipped. The first "word" of
|
||||
a non-blank line, delimited by white space, is the "string" assigned
|
||||
to the variable.
|
||||
|
||||
:line
|
||||
|
||||
For the {equal} and {atom} styles, a single string is specified which
|
||||
@ -279,7 +307,7 @@ Region functions: count(ID,IDR), mass(ID,IDR), charge(ID,IDR), \
|
||||
bound(ID,dir,IDR), gyration(ID,IDR), ke(ID,IDR), \
|
||||
angmom(ID,dim,IDR), torque(ID,dim,IDR), \
|
||||
inertia(ID,dimdim,IDR), omega(ID,dim,IDR)
|
||||
Special functions: sum(x), min(x), max(x), ave(x), trap(x), gmask(x), rmask(x), grmask(x,y)
|
||||
Special functions: sum(x), min(x), max(x), ave(x), trap(x), gmask(x), rmask(x), grmask(x,y), next(x)
|
||||
Atom values: mass\[i\], type\[i\], x\[i\], y\[i\], z\[i\], \
|
||||
vx\[i\], vy\[i\], vz\[i\], fx\[i\], fy\[i\], fz\[i\]
|
||||
Atom vectors: mass, type, x, y, z, vx, vy, vz, fx, fy, fz
|
||||
@ -559,6 +587,20 @@ and the second is a region ID. It can only be used in atom-style
|
||||
variables. It returns a 1 for atoms that are in both the group and
|
||||
region, and a 0 for atoms that are not in both.
|
||||
|
||||
The next(x) function takes 1 argument which is a variable ID (not
|
||||
"v_foo", just "foo"). It must be for a file-style variable. Each
|
||||
time the next() function is invoked (i.e. each time the equal-style or
|
||||
atom-style variable is evaluated), the current string value stored by
|
||||
the file-style variable is converted to a numeric value returned by
|
||||
the function, and the next value from the file is read and stored.
|
||||
Note that if the line previously read from the file was not a numeric
|
||||
string, then it will typically evaluate to 0.0, which is likely not
|
||||
what you want. Since the file-style variable reads and stores the
|
||||
first line of the file when it is defined in the input script, this is
|
||||
the value that will be returned the first time the next() function is
|
||||
invoked. If next() is invoked more times than there are lines in the
|
||||
file, the value for the last line is repeatedly returned.
|
||||
|
||||
:line
|
||||
|
||||
Atom Values and Vectors :h4
|
||||
@ -645,20 +687,26 @@ the doc pages for individual fix commands for details.
|
||||
|
||||
Variable References :h4
|
||||
|
||||
Variable references access quantities calulated by other variables,
|
||||
which will cause those variables to be evaluated. The name in the
|
||||
reference should be replaced by the name of a variable defined
|
||||
elsewhere in the input script. As discussed on this doc page,
|
||||
atom-style variables generate a per-atom vector of values; all other
|
||||
variable styles generate a global scalar value. An equal-style
|
||||
variable can only use scalar values, which means another equal-style
|
||||
variable or an element of an atom-style variable. Atom-style
|
||||
variables can use the same scalar values. They can also use other
|
||||
atom-style variables.
|
||||
Variable references access quantities stored or calculated by other
|
||||
variables, which will cause those variables to be evaluated. The name
|
||||
in the reference should be replaced by the name of a variable defined
|
||||
elsewhere in the input script.
|
||||
|
||||
As discussed on this doc page, equal-style variables generate a global
|
||||
scalar numeric value; atom-style variables generate a per-atom vector
|
||||
of numeric values; all other variables store a string. The formula
|
||||
for an equal-style variable can use any style of variable except an
|
||||
atom-style (unless only a single value from the atom-style variable is
|
||||
accessed via a subscript). If a string-storing variable is used,
|
||||
the string is converted to a numeric value. Note that this
|
||||
will typically produce a 0.0 if the string is not a numeric string,
|
||||
which is likely not what you want. The formula for an atom-style
|
||||
variable can use any style of variable, including other atom-style
|
||||
variables.
|
||||
|
||||
Examples of different kinds of variable references are as follows.
|
||||
There is no ambiguity as to what a reference means, since variables
|
||||
produce only a global scalar or a per-atom vectors, never both.
|
||||
produce only a global scalar or a per-atom vector, never both.
|
||||
|
||||
v_name: scalar, or per-atom vector
|
||||
v_name\[I\]: atom I's value in per-atom vector :tb(s=:)
|
||||
|
||||
@ -153,7 +153,7 @@ class lammps:
|
||||
def gather_atoms(self,name,type,count):
|
||||
natoms = self.lib.lammps_get_natoms(self.lmp)
|
||||
if type == 0:
|
||||
data = ((count*natoms)*c_double)()
|
||||
data = ((count*natoms)*c_int)()
|
||||
self.lib.lammps_gather_atoms(self.lmp,name,type,count,data)
|
||||
elif type == 1:
|
||||
data = ((count*natoms)*c_double)()
|
||||
|
||||
@ -42,6 +42,7 @@ using namespace MathConst;
|
||||
PairLJClass2CoulLong::PairLJClass2CoulLong(LAMMPS *lmp) : Pair(lmp)
|
||||
{
|
||||
ewaldflag = pppmflag = 1;
|
||||
ftable = NULL;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -68,8 +69,9 @@ PairLJClass2CoulLong::~PairLJClass2CoulLong()
|
||||
|
||||
void PairLJClass2CoulLong::compute(int eflag, int vflag)
|
||||
{
|
||||
int i,j,ii,jj,inum,jnum,itype,jtype;
|
||||
int i,j,ii,jj,inum,jnum,itable,itype,jtype;
|
||||
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
|
||||
double fraction,table;
|
||||
double rsq,r,rinv,r2inv,r3inv,r6inv,forcecoul,forcelj;
|
||||
double grij,expm2,prefactor,t,erfc;
|
||||
double factor_coul,factor_lj;
|
||||
@ -122,6 +124,7 @@ void PairLJClass2CoulLong::compute(int eflag, int vflag)
|
||||
r2inv = 1.0/rsq;
|
||||
|
||||
if (rsq < cut_coulsq) {
|
||||
if (!ncoultablebits || rsq <= tabinnersq) {
|
||||
r = sqrt(rsq);
|
||||
grij = g_ewald * r;
|
||||
expm2 = exp(-grij*grij);
|
||||
@ -130,6 +133,20 @@ void PairLJClass2CoulLong::compute(int eflag, int vflag)
|
||||
prefactor = qqrd2e * qtmp*q[j]/r;
|
||||
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
|
||||
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
|
||||
} else {
|
||||
union_int_float_t rsq_lookup;
|
||||
rsq_lookup.f = rsq;
|
||||
itable = rsq_lookup.i & ncoulmask;
|
||||
itable >>= ncoulshiftbits;
|
||||
fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
|
||||
table = ftable[itable] + fraction*dftable[itable];
|
||||
forcecoul = qtmp*q[j] * table;
|
||||
if (factor_coul < 1.0) {
|
||||
table = ctable[itable] + fraction*dctable[itable];
|
||||
prefactor = qtmp*q[j] * table;
|
||||
forcecoul -= (1.0-factor_coul)*prefactor;
|
||||
}
|
||||
}
|
||||
} else forcecoul = 0.0;
|
||||
|
||||
if (rsq < cut_ljsq[itype][jtype]) {
|
||||
@ -152,7 +169,12 @@ void PairLJClass2CoulLong::compute(int eflag, int vflag)
|
||||
|
||||
if (eflag) {
|
||||
if (rsq < cut_coulsq) {
|
||||
if (!ncoultablebits || rsq <= tabinnersq)
|
||||
ecoul = prefactor*erfc;
|
||||
else {
|
||||
table = etable[itable] + fraction*detable[itable];
|
||||
ecoul = qtmp*q[j] * table;
|
||||
}
|
||||
if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
|
||||
} else ecoul = 0.0;
|
||||
if (rsq < cut_ljsq[itype][jtype]) {
|
||||
@ -273,6 +295,9 @@ void PairLJClass2CoulLong::init_style()
|
||||
if (force->kspace == NULL)
|
||||
error->all(FLERR,"Pair style requires a KSpace style");
|
||||
g_ewald = force->kspace->g_ewald;
|
||||
|
||||
// setup force tables
|
||||
if (ncoultablebits) init_tables(cut_coul,NULL);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -400,6 +425,8 @@ void PairLJClass2CoulLong::write_restart_settings(FILE *fp)
|
||||
fwrite(&offset_flag,sizeof(int),1,fp);
|
||||
fwrite(&mix_flag,sizeof(int),1,fp);
|
||||
fwrite(&tail_flag,sizeof(int),1,fp);
|
||||
fwrite(&ncoultablebits,sizeof(int),1,fp);
|
||||
fwrite(&tabinner,sizeof(double),1,fp);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -414,12 +441,16 @@ void PairLJClass2CoulLong::read_restart_settings(FILE *fp)
|
||||
fread(&offset_flag,sizeof(int),1,fp);
|
||||
fread(&mix_flag,sizeof(int),1,fp);
|
||||
fread(&tail_flag,sizeof(int),1,fp);
|
||||
fread(&ncoultablebits,sizeof(int),1,fp);
|
||||
fread(&tabinner,sizeof(double),1,fp);
|
||||
}
|
||||
MPI_Bcast(&cut_lj_global,1,MPI_DOUBLE,0,world);
|
||||
MPI_Bcast(&cut_coul,1,MPI_DOUBLE,0,world);
|
||||
MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
|
||||
MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
|
||||
MPI_Bcast(&tail_flag,1,MPI_INT,0,world);
|
||||
MPI_Bcast(&ncoultablebits,1,MPI_INT,0,world);
|
||||
MPI_Bcast(&tabinner,1,MPI_DOUBLE,0,world);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -430,10 +461,12 @@ double PairLJClass2CoulLong::single(int i, int j, int itype, int jtype,
|
||||
double &fforce)
|
||||
{
|
||||
double r2inv,r,rinv,r3inv,r6inv,grij,expm2,t,erfc,prefactor;
|
||||
double forcecoul,forcelj,phicoul,philj;
|
||||
double fraction,table,forcecoul,forcelj,phicoul,philj;
|
||||
int itable;
|
||||
|
||||
r2inv = 1.0/rsq;
|
||||
if (rsq < cut_coulsq) {
|
||||
if (!ncoultablebits || rsq <= tabinnersq) {
|
||||
r = sqrt(rsq);
|
||||
grij = g_ewald * r;
|
||||
expm2 = exp(-grij*grij);
|
||||
@ -442,6 +475,20 @@ double PairLJClass2CoulLong::single(int i, int j, int itype, int jtype,
|
||||
prefactor = force->qqrd2e * atom->q[i]*atom->q[j]/r;
|
||||
forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
|
||||
if (factor_coul < 1.0) forcecoul -= (1.0-factor_coul)*prefactor;
|
||||
} else {
|
||||
union_int_float_t rsq_lookup;
|
||||
rsq_lookup.f = rsq;
|
||||
itable = rsq_lookup.i & ncoulmask;
|
||||
itable >>= ncoulshiftbits;
|
||||
fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
|
||||
table = ftable[itable] + fraction*dftable[itable];
|
||||
forcecoul = atom->q[i]*atom->q[j] * table;
|
||||
if (factor_coul < 1.0) {
|
||||
table = ctable[itable] + fraction*dctable[itable];
|
||||
prefactor = atom->q[i]*atom->q[j] * table;
|
||||
forcecoul -= (1.0-factor_coul)*prefactor;
|
||||
}
|
||||
}
|
||||
} else forcecoul = 0.0;
|
||||
if (rsq < cut_ljsq[itype][jtype]) {
|
||||
rinv = sqrt(r2inv);
|
||||
@ -453,7 +500,12 @@ double PairLJClass2CoulLong::single(int i, int j, int itype, int jtype,
|
||||
|
||||
double eng = 0.0;
|
||||
if (rsq < cut_coulsq) {
|
||||
if (!ncoultablebits || rsq <= tabinnersq)
|
||||
phicoul = prefactor*erfc;
|
||||
else {
|
||||
table = etable[itable] + fraction*detable[itable];
|
||||
phicoul = atom->q[i]*atom->q[j] * table;
|
||||
}
|
||||
if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor;
|
||||
eng += phicoul;
|
||||
}
|
||||
|
||||
@ -303,6 +303,7 @@ void PairDipoleSFGPU::cpu_compute(int start, int inum, int eflag, int vflag,
|
||||
if (mu[i][3] > 0.0 && q[j] != 0.0) {
|
||||
r3inv = r2inv*rinv;
|
||||
r5inv = r3inv*r2inv;
|
||||
pidotr = mu[i][0]*delx + mu[i][1]*dely + mu[i][2]*delz;
|
||||
rcutcoul2inv=1.0/cut_coulsq[itype][jtype];
|
||||
pre1 = 3.0 * q[j] * r5inv * pidotr * (1-rsq*rcutcoul2inv);
|
||||
pqfac = 1.0 - 3.0*rsq*rcutcoul2inv +
|
||||
@ -320,6 +321,7 @@ void PairDipoleSFGPU::cpu_compute(int start, int inum, int eflag, int vflag,
|
||||
if (mu[j][3] > 0.0 && qtmp != 0.0) {
|
||||
r3inv = r2inv*rinv;
|
||||
r5inv = r3inv*r2inv;
|
||||
pjdotr = mu[j][0]*delx + mu[j][1]*dely + mu[j][2]*delz;
|
||||
rcutcoul2inv=1.0/cut_coulsq[itype][jtype];
|
||||
pre1 = 3.0 * qtmp * r5inv * pjdotr * (1-rsq*rcutcoul2inv);
|
||||
qpfac = 1.0 - 3.0*rsq*rcutcoul2inv +
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "pppm_gpu.h"
|
||||
#include "atom.h"
|
||||
#include "comm.h"
|
||||
#include "commgrid.h"
|
||||
#include "neighbor.h"
|
||||
#include "force.h"
|
||||
#include "pair.h"
|
||||
@ -48,6 +49,9 @@ using namespace MathConst;
|
||||
#define LARGE 10000.0
|
||||
#define EPS_HOC 1.0e-7
|
||||
|
||||
enum{REVERSE_RHO};
|
||||
enum{FORWARD_IK,FORWARD_AD,FORWARD_IK_PERATOM,FORWARD_AD_PERATOM};
|
||||
|
||||
#ifdef FFT_SINGLE
|
||||
#define ZEROF 0.0f
|
||||
#define ONEF 1.0f
|
||||
@ -56,7 +60,7 @@ using namespace MathConst;
|
||||
#define ONEF 1.0
|
||||
#endif
|
||||
|
||||
// External functions from cuda library for atom decomposition
|
||||
// external functions from cuda library for atom decomposition
|
||||
|
||||
#ifdef FFT_SINGLE
|
||||
#define PPPM_GPU_API(api) pppm_gpu_ ## api ## _f
|
||||
@ -111,10 +115,35 @@ PPPMGPU::~PPPMGPU()
|
||||
|
||||
void PPPMGPU::init()
|
||||
{
|
||||
// PPPM init manages all arrays except density_brick_gpu and vd_brick
|
||||
// thru its deallocate(), allocate()
|
||||
// NOTE: could free density_brick and vdxyz_brick after PPPM allocates them,
|
||||
// before allocating db_gpu and vd_brick down below, if don't need,
|
||||
// if do this, make sure to set them to NULL
|
||||
// NOTE: delete/realloc of cg necessary b/c packing 4 values per grid pt,
|
||||
// not 3 as PPPM does - probably a better way to account for this
|
||||
// in PPPM::init()
|
||||
|
||||
destroy_3d_offset(density_brick_gpu,nzlo_out,nylo_out);
|
||||
destroy_3d_offset(vd_brick,nzlo_out,nylo_out);
|
||||
density_brick_gpu = vd_brick = NULL;
|
||||
|
||||
PPPM::init();
|
||||
|
||||
if (differentiation_flag == 0) {
|
||||
delete cg;
|
||||
int (*procneigh)[2] = comm->procneigh;
|
||||
cg = new CommGrid(lmp,world,4,1,
|
||||
nxlo_in,nxhi_in,nylo_in,nyhi_in,nzlo_in,nzhi_in,
|
||||
nxlo_out,nxhi_out,nylo_out,nyhi_out,nzlo_out,nzhi_out,
|
||||
procneigh[0][0],procneigh[0][1],procneigh[1][0],
|
||||
procneigh[1][1],procneigh[2][0],procneigh[2][1]);
|
||||
}
|
||||
|
||||
// unsupported option
|
||||
|
||||
if (differentiation_flag == 1)
|
||||
error->all(FLERR,"Cannot (yet) do analytic differentiation with pppm/gpu.");
|
||||
error->all(FLERR,"Cannot (yet) do analytic differentiation with pppm/gpu");
|
||||
|
||||
if (strcmp(update->integrate_style,"verlet/split") == 0) {
|
||||
kspace_split=true;
|
||||
@ -142,6 +171,8 @@ void PPPMGPU::init()
|
||||
|
||||
GPU_EXTRA::check_flag(success,error,world);
|
||||
|
||||
// allocate density_brick_gpu and vd_brick
|
||||
|
||||
density_brick_gpu =
|
||||
create_3d_offset(nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"pppm:density_brick_gpu",h_brick,1);
|
||||
@ -149,7 +180,7 @@ void PPPMGPU::init()
|
||||
create_3d_offset(nzlo_out,nzhi_out,nylo_out,nyhi_out,
|
||||
nxlo_out,nxhi_out,"pppm:vd_brick",data,4);
|
||||
|
||||
poisson_time=0;
|
||||
poisson_time = 0.0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -164,10 +195,8 @@ void PPPMGPU::compute(int eflag, int vflag)
|
||||
if (atom->nlocal > old_nlocal) {
|
||||
nago=0;
|
||||
old_nlocal = atom->nlocal;
|
||||
} else
|
||||
nago=1;
|
||||
} else
|
||||
nago=neighbor->ago;
|
||||
} else nago = 1;
|
||||
} else nago = neighbor->ago;
|
||||
|
||||
// set energy/virial flags
|
||||
// invoke allocate_peratom() if needed for first time
|
||||
@ -217,6 +246,7 @@ void PPPMGPU::compute(int eflag, int vflag)
|
||||
// to fully sum contribution in their 3d bricks
|
||||
// remap from 3d decomposition to FFT decomposition
|
||||
|
||||
cg->reverse_comm(this,REVERSE_RHO);
|
||||
brick2fft();
|
||||
|
||||
// compute potential gradient on my FFT grid and
|
||||
@ -225,10 +255,20 @@ void PPPMGPU::compute(int eflag, int vflag)
|
||||
|
||||
poisson();
|
||||
|
||||
// all procs communicate E-field values to fill ghost cells
|
||||
// surrounding their 3d bricks
|
||||
// all procs communicate E-field values
|
||||
// to fill ghost cells surrounding their 3d bricks
|
||||
|
||||
fillbrick();
|
||||
if (differentiation_flag == 1) cg->forward_comm(this,FORWARD_AD);
|
||||
else cg->forward_comm(this,FORWARD_IK);
|
||||
|
||||
// extra per-atom energy/virial communication
|
||||
|
||||
if (evflag_atom) {
|
||||
if (differentiation_flag == 1 && vflag_atom)
|
||||
cg_peratom->forward_comm(this,FORWARD_AD_PERATOM);
|
||||
else if (differentiation_flag == 0)
|
||||
cg_peratom->forward_comm(this,FORWARD_IK_PERATOM);
|
||||
}
|
||||
|
||||
poisson_time += MPI_Wtime()-t3;
|
||||
|
||||
@ -237,11 +277,10 @@ void PPPMGPU::compute(int eflag, int vflag)
|
||||
FFT_SCALAR qscale = force->qqrd2e * scale;
|
||||
PPPM_GPU_API(interp)(qscale);
|
||||
|
||||
// Compute per-atom energy/virial on host if requested
|
||||
// per-atom energy/virial
|
||||
// energy includes self-energy correction
|
||||
|
||||
if (evflag_atom) {
|
||||
fillbrick_peratom();
|
||||
fieldforce_peratom();
|
||||
double *q = atom->q;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
@ -293,246 +332,13 @@ void PPPMGPU::compute(int eflag, int vflag)
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
allocate memory that depends on # of K-vectors and order
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PPPMGPU::allocate()
|
||||
{
|
||||
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(drho1d,3,-order/2,order/2,"pppm:drho1d");
|
||||
memory->create2d_offset(rho_coeff,order,(1-order)/2,order/2,"pppm:rho_coeff");
|
||||
memory->create2d_offset(drho_coeff,order,(1-order)/2,order/2,
|
||||
"pppm:drho_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);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
deallocate memory that depends on # of K-vectors and order
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PPPMGPU::deallocate()
|
||||
{
|
||||
destroy_3d_offset(density_brick_gpu,nzlo_out,nylo_out);
|
||||
destroy_3d_offset(vd_brick,nzlo_out,nylo_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(drho1d,-order/2);
|
||||
memory->destroy2d_offset(rho_coeff,(1-order)/2);
|
||||
memory->destroy2d_offset(drho_coeff,(1-order)/2);
|
||||
|
||||
delete fft1;
|
||||
delete fft2;
|
||||
delete remap;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
ghost-swap to accumulate full density in brick decomposition
|
||||
remap density from 3d brick decomposition to FFT decomposition
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PPPMGPU::brick2fft()
|
||||
{
|
||||
int i,n,ix,iy,iz;
|
||||
MPI_Request request;
|
||||
MPI_Status status;
|
||||
int n,ix,iy,iz;
|
||||
|
||||
// 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_gpu[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_gpu[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_gpu[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_gpu[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_gpu[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_gpu[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_gpu[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_gpu[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_gpu[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_gpu[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_gpu[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_gpu[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
|
||||
@ -546,216 +352,6 @@ void PPPMGPU::brick2fft()
|
||||
remap->perform(density_fft,density_fft,work1);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Same as base class - needed to call GPU version of fillbrick_.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PPPMGPU::fillbrick()
|
||||
{
|
||||
if (differentiation_flag == 1) fillbrick_ad();
|
||||
else fillbrick_ik();
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
ghost-swap to fill ghost cells of my brick with field values
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PPPMGPU::fillbrick_ik()
|
||||
{
|
||||
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;
|
||||
int x_lo = nxlo_in * 4;
|
||||
int x_hi = nxhi_in * 4 + 1;
|
||||
for (iz = nzhi_in-nzhi_ghost+1; iz <= nzhi_in; iz++)
|
||||
for (iy = nylo_in; iy <= nyhi_in; iy++)
|
||||
for (ix = x_lo; ix < x_hi; ix+=4) {
|
||||
buf1[n++] = vd_brick[iz][iy][ix];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+1];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+2];
|
||||
}
|
||||
|
||||
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 = x_lo; ix < x_hi; ix+=4) {
|
||||
vd_brick[iz][iy][ix] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+1] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+2] = 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 = x_lo; ix < x_hi; ix+=4) {
|
||||
buf1[n++] = vd_brick[iz][iy][ix];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+1];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+2];
|
||||
}
|
||||
|
||||
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 = x_lo; ix < x_hi; ix+=4) {
|
||||
vd_brick[iz][iy][ix] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+1] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+2] = 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 = x_lo; ix < x_hi; ix+=4) {
|
||||
buf1[n++] = vd_brick[iz][iy][ix];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+1];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+2];
|
||||
}
|
||||
|
||||
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 = x_lo; ix < x_hi; ix+=4) {
|
||||
vd_brick[iz][iy][ix] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+1] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+2] = 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 = x_lo; ix < x_hi; ix+=4) {
|
||||
buf1[n++] = vd_brick[iz][iy][ix];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+1];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+2];
|
||||
}
|
||||
|
||||
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 = x_lo; ix < x_hi; ix+=4) {
|
||||
vd_brick[iz][iy][ix] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+1] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+2] = 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;
|
||||
x_lo = (nxhi_in-nxhi_ghost+1) * 4;
|
||||
for (iz = nzlo_out; iz <= nzhi_out; iz++)
|
||||
for (iy = nylo_out; iy <= nyhi_out; iy++)
|
||||
for (ix = x_lo; ix < x_hi; ix+=4) {
|
||||
buf1[n++] = vd_brick[iz][iy][ix];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+1];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+2];
|
||||
}
|
||||
|
||||
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;
|
||||
x_lo = nxlo_out * 4;
|
||||
x_hi = nxlo_in * 4;
|
||||
for (iz = nzlo_out; iz <= nzhi_out; iz++)
|
||||
for (iy = nylo_out; iy <= nyhi_out; iy++)
|
||||
for (ix = x_lo; ix < x_hi; ix+=4) {
|
||||
vd_brick[iz][iy][ix] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+1] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+2] = 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;
|
||||
x_lo = x_hi;
|
||||
x_hi = (nxlo_in+nxlo_ghost) * 4;
|
||||
for (iz = nzlo_out; iz <= nzhi_out; iz++)
|
||||
for (iy = nylo_out; iy <= nyhi_out; iy++)
|
||||
for (ix = x_lo; ix < x_hi; ix+=4) {
|
||||
buf1[n++] = vd_brick[iz][iy][ix];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+1];
|
||||
buf1[n++] = vd_brick[iz][iy][ix+2];
|
||||
}
|
||||
|
||||
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;
|
||||
x_lo = (nxhi_in + 1) * 4;
|
||||
x_hi = nxhi_out * 4 + 1;
|
||||
for (iz = nzlo_out; iz <= nzhi_out; iz++)
|
||||
for (iy = nylo_out; iy <= nyhi_out; iy++)
|
||||
for (ix = x_lo; ix < x_hi; ix+=4) {
|
||||
vd_brick[iz][iy][ix] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+1] = buf2[n++];
|
||||
vd_brick[iz][iy][ix+2] = buf2[n++];
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Same code as base class - necessary to call GPU version of poisson_ik
|
||||
------------------------------------------------------------------------- */
|
||||
@ -892,7 +488,149 @@ void PPPMGPU::poisson_ik()
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Create array using offsets from pinned memory allocation
|
||||
pack own values to buf to send to another proc
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PPPMGPU::pack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
if (flag == FORWARD_IK) {
|
||||
int offset;
|
||||
FFT_SCALAR *src = &vd_brick[nzlo_out][nylo_out][4*nxlo_out];
|
||||
for (int i = 0; i < nlist; i++) {
|
||||
offset = 4*list[i];
|
||||
buf[n++] = src[offset++];
|
||||
buf[n++] = src[offset++];
|
||||
buf[n++] = src[offset];
|
||||
}
|
||||
} else if (flag == FORWARD_AD) {
|
||||
FFT_SCALAR *src = &u_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
for (int i = 0; i < nlist; i++)
|
||||
buf[i] = src[list[i]];
|
||||
} else if (flag == FORWARD_IK_PERATOM) {
|
||||
FFT_SCALAR *esrc = &u_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v0src = &v0_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v1src = &v1_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v2src = &v2_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v3src = &v3_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v4src = &v4_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v5src = &v5_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
for (int i = 0; i < nlist; i++) {
|
||||
if (eflag_atom) buf[n++] = esrc[list[i]];
|
||||
if (vflag_atom) {
|
||||
buf[n++] = v0src[list[i]];
|
||||
buf[n++] = v1src[list[i]];
|
||||
buf[n++] = v2src[list[i]];
|
||||
buf[n++] = v3src[list[i]];
|
||||
buf[n++] = v4src[list[i]];
|
||||
buf[n++] = v5src[list[i]];
|
||||
}
|
||||
}
|
||||
} else if (flag == FORWARD_AD_PERATOM) {
|
||||
FFT_SCALAR *v0src = &v0_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v1src = &v1_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v2src = &v2_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v3src = &v3_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v4src = &v4_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v5src = &v5_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
for (int i = 0; i < nlist; i++) {
|
||||
buf[n++] = v0src[list[i]];
|
||||
buf[n++] = v1src[list[i]];
|
||||
buf[n++] = v2src[list[i]];
|
||||
buf[n++] = v3src[list[i]];
|
||||
buf[n++] = v4src[list[i]];
|
||||
buf[n++] = v5src[list[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
unpack another proc's own values from buf and set own ghost values
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PPPMGPU::unpack_forward(int flag, FFT_SCALAR *buf, int nlist, int *list)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
if (flag == FORWARD_IK) {
|
||||
int offset;
|
||||
FFT_SCALAR *dest = &vdx_brick[nzlo_out][nylo_out][4*nxlo_out];
|
||||
for (int i = 0; i < nlist; i++) {
|
||||
offset = 4*list[i];
|
||||
dest[offset++] = buf[n++];
|
||||
dest[offset++] = buf[n++];
|
||||
dest[offset] = buf[n++];
|
||||
}
|
||||
} else if (flag == FORWARD_AD) {
|
||||
FFT_SCALAR *dest = &u_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
for (int i = 0; i < nlist; i++)
|
||||
dest[list[i]] = buf[n++];
|
||||
} else if (flag == FORWARD_IK_PERATOM) {
|
||||
FFT_SCALAR *esrc = &u_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v0src = &v0_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v1src = &v1_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v2src = &v2_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v3src = &v3_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v4src = &v4_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v5src = &v5_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
for (int i = 0; i < nlist; i++) {
|
||||
if (eflag_atom) esrc[list[i]] = buf[n++];
|
||||
if (vflag_atom) {
|
||||
v0src[list[i]] = buf[n++];
|
||||
v1src[list[i]] = buf[n++];
|
||||
v2src[list[i]] = buf[n++];
|
||||
v3src[list[i]] = buf[n++];
|
||||
v4src[list[i]] = buf[n++];
|
||||
v5src[list[i]] = buf[n++];
|
||||
}
|
||||
}
|
||||
} else if (flag == FORWARD_AD_PERATOM) {
|
||||
FFT_SCALAR *v0src = &v0_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v1src = &v1_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v2src = &v2_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v3src = &v3_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v4src = &v4_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
FFT_SCALAR *v5src = &v5_brick[nzlo_out][nylo_out][nxlo_out];
|
||||
for (int i = 0; i < nlist; i++) {
|
||||
v0src[list[i]] = buf[n++];
|
||||
v1src[list[i]] = buf[n++];
|
||||
v2src[list[i]] = buf[n++];
|
||||
v3src[list[i]] = buf[n++];
|
||||
v4src[list[i]] = buf[n++];
|
||||
v5src[list[i]] = buf[n++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
pack ghost values into buf to send to another proc
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PPPMGPU::pack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list)
|
||||
{
|
||||
if (flag == REVERSE_RHO) {
|
||||
FFT_SCALAR *src = &density_brick_gpu[nzlo_out][nylo_out][nxlo_out];
|
||||
for (int i = 0; i < nlist; i++)
|
||||
buf[i] = src[list[i]];
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
unpack another proc's ghost values from buf and add to own values
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PPPMGPU::unpack_reverse(int flag, FFT_SCALAR *buf, int nlist, int *list)
|
||||
{
|
||||
if (flag == REVERSE_RHO) {
|
||||
FFT_SCALAR *dest = &density_brick_gpu[nzlo_out][nylo_out][nxlo_out];
|
||||
for (int i = 0; i < nlist; i++)
|
||||
dest[list[i]] += buf[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
create array using offsets from pinned memory allocation
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
FFT_SCALAR ***PPPMGPU::create_3d_offset(int n1lo, int n1hi, int n2lo, int n2hi,
|
||||
@ -942,19 +680,11 @@ void PPPMGPU::destroy_3d_offset(FFT_SCALAR ***array, int n1_offset,
|
||||
|
||||
double PPPMGPU::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(double);
|
||||
double bytes = PPPM::memory_usage();
|
||||
|
||||
if (peratom_allocate_flag) {
|
||||
bytes += 7 * nbrick * sizeof(FFT_SCALAR);
|
||||
bytes += 2 * nbuf_peratom * sizeof(FFT_SCALAR);
|
||||
}
|
||||
// NOTE: add tallying here for density_brick_gpu and vd_brick
|
||||
// could subtract out density_brick and vdxyz_brick if freed them above
|
||||
// it the net efffect is zero, do nothing
|
||||
|
||||
return bytes + PPPM_GPU_API(bytes)();
|
||||
}
|
||||
|
||||
@ -35,20 +35,19 @@ class PPPMGPU : public PPPM {
|
||||
double memory_usage();
|
||||
|
||||
protected:
|
||||
|
||||
FFT_SCALAR ***density_brick_gpu, ***vd_brick;
|
||||
bool kspace_split, im_real_space;
|
||||
int old_nlocal;
|
||||
double poisson_time;
|
||||
|
||||
void allocate();
|
||||
void deallocate();
|
||||
void brick2fft();
|
||||
void fillbrick();
|
||||
void fillbrick_ik();
|
||||
void poisson();
|
||||
void poisson_ik();
|
||||
|
||||
int old_nlocal;
|
||||
double poisson_time;
|
||||
void pack_forward(int, FFT_SCALAR *, int, int *);
|
||||
void unpack_forward(int, FFT_SCALAR *, int, int *);
|
||||
void pack_reverse(int, FFT_SCALAR *, int, int *);
|
||||
void unpack_reverse(int, FFT_SCALAR *, int, int *);
|
||||
|
||||
FFT_SCALAR ***create_3d_offset(int, int, int, int, int, int, const char *,
|
||||
FFT_SCALAR *, int);
|
||||
|
||||
@ -41,7 +41,7 @@ class PairGranHookeHistory : public Pair {
|
||||
void write_restart_settings(FILE *);
|
||||
void read_restart_settings(FILE *);
|
||||
void reset_dt();
|
||||
double single(int, int, int, int, double, double, double, double &);
|
||||
virtual double single(int, int, int, int, double, double, double, double &);
|
||||
int pack_comm(int, int *, double *, int, int *);
|
||||
void unpack_comm(int, int, double *);
|
||||
void *extract(const char *, int &);
|
||||
|
||||
@ -314,14 +314,18 @@ struct fft_plan_3d {
|
||||
|
||||
// function prototypes
|
||||
|
||||
extern "C" {
|
||||
void fft_3d(FFT_DATA *, FFT_DATA *, int, struct fft_plan_3d *);
|
||||
struct fft_plan_3d *fft_3d_create_plan(MPI_Comm, int, int, int,
|
||||
int, int, int, int, int, int, int, int, int, int, int, int,
|
||||
int, int, int, int, int,
|
||||
int, int, int, int, int, int, int,
|
||||
int, int, int *);
|
||||
void fft_3d_destroy_plan(struct fft_plan_3d *);
|
||||
void factor(int, int *, int *);
|
||||
void bifactor(int, int *, int *);
|
||||
void fft_1d_only(FFT_DATA *, int, int, struct fft_plan_3d *);
|
||||
}
|
||||
|
||||
/* ERROR/WARNING messages:
|
||||
|
||||
*/
|
||||
|
||||
@ -158,6 +158,7 @@ void PairBornCoulLong::compute(int eflag, int vflag)
|
||||
} else forcecoul = 0.0;
|
||||
|
||||
if (rsq < cut_ljsq[itype][jtype]) {
|
||||
r = sqrt(rsq);
|
||||
r6inv = r2inv*r2inv*r2inv;
|
||||
rexp = exp((sigma[itype][jtype]-r)*rhoinv[itype][jtype]);
|
||||
forceborn = born1[itype][jtype]*r*rexp - born2[itype][jtype]*r6inv
|
||||
@ -381,7 +382,8 @@ void PairBornCoulLong::init_style()
|
||||
neighbor->request(this);
|
||||
|
||||
// setup force tables
|
||||
if (ncoultablebits) init_tables(cut_coul,cut_respa);
|
||||
|
||||
if (ncoultablebits) init_tables(cut_coul,NULL);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
@ -150,6 +150,7 @@ void PairBuckCoulLong::compute(int eflag, int vflag)
|
||||
} else forcecoul = 0.0;
|
||||
|
||||
if (rsq < cut_ljsq[itype][jtype]) {
|
||||
r = sqrt(rsq);
|
||||
r6inv = r2inv*r2inv*r2inv;
|
||||
rexp = exp(-r*rhoinv[itype][jtype]);
|
||||
forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv;
|
||||
@ -358,7 +359,8 @@ void PairBuckCoulLong::init_style()
|
||||
neighbor->request(this);
|
||||
|
||||
// setup force tables
|
||||
if (ncoultablebits) init_tables(cut_coul,cut_respa);
|
||||
|
||||
if (ncoultablebits) init_tables(cut_coul,NULL);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
@ -240,15 +240,6 @@ void PairCoulLong::init_style()
|
||||
|
||||
cut_coulsq = cut_coul * cut_coul;
|
||||
|
||||
// set & error check interior rRESPA cutoffs
|
||||
|
||||
if (strstr(update->integrate_style,"respa") &&
|
||||
((Respa *) update->integrate)->level_inner >= 0) {
|
||||
cut_respa = ((Respa *) update->integrate)->cutoff;
|
||||
if (cut_coul < cut_respa[3])
|
||||
error->all(FLERR,"Pair cutoff < Respa interior cutoff");
|
||||
} else cut_respa = NULL;
|
||||
|
||||
// insure use of KSpace long-range solver, set g_ewald
|
||||
|
||||
if (force->kspace == NULL)
|
||||
@ -257,7 +248,7 @@ void PairCoulLong::init_style()
|
||||
|
||||
// setup force tables
|
||||
|
||||
if (ncoultablebits) init_tables(cut_coul,cut_respa);
|
||||
if (ncoultablebits) init_tables(cut_coul,NULL);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
@ -150,10 +150,10 @@ class PPPM : public KSpace {
|
||||
|
||||
// grid communication
|
||||
|
||||
void pack_forward(int, FFT_SCALAR *, int, int *);
|
||||
void unpack_forward(int, FFT_SCALAR *, int, int *);
|
||||
void pack_reverse(int, FFT_SCALAR *, int, int *);
|
||||
void unpack_reverse(int, FFT_SCALAR *, int, int *);
|
||||
virtual void pack_forward(int, FFT_SCALAR *, int, int *);
|
||||
virtual void unpack_forward(int, FFT_SCALAR *, int, int *);
|
||||
virtual void pack_reverse(int, FFT_SCALAR *, int, int *);
|
||||
virtual void unpack_reverse(int, FFT_SCALAR *, int, int *);
|
||||
|
||||
// group-group interactions
|
||||
|
||||
|
||||
1167
src/MC/fix_gcmc.cpp
1167
src/MC/fix_gcmc.cpp
File diff suppressed because it is too large
Load Diff
@ -32,49 +32,77 @@ class FixGCMC : public Fix {
|
||||
int setmask();
|
||||
void init();
|
||||
void pre_exchange();
|
||||
void attempt_move();
|
||||
void attempt_deletion();
|
||||
void attempt_insertion();
|
||||
double energy(int, double *);
|
||||
void attempt_atomic_translation();
|
||||
void attempt_atomic_deletion();
|
||||
void attempt_atomic_insertion();
|
||||
void attempt_molecule_translation();
|
||||
void attempt_molecule_rotation();
|
||||
void attempt_molecule_deletion();
|
||||
void attempt_molecule_insertion();
|
||||
double energy(int, int, int, double *);
|
||||
int pick_random_gas_atom();
|
||||
int pick_random_gas_atom_in_region();
|
||||
int pick_random_gas_molecule();
|
||||
int pick_random_gas_molecule_in_region();
|
||||
double molecule_energy(int);
|
||||
void get_rotation_matrix(double, double *);
|
||||
void get_model_molecule();
|
||||
void update_gas_atoms_list();
|
||||
double compute_vector(int);
|
||||
double memory_usage();
|
||||
void write_restart(FILE *);
|
||||
void restart(char *);
|
||||
|
||||
private:
|
||||
int ntype,nevery,seed;
|
||||
int rotation_group,rotation_groupbit;
|
||||
int rotation_inversegroupbit;
|
||||
int ngcmc_type,nevery,seed;
|
||||
int ncycles,nexchanges,nmcmoves;
|
||||
int ngas; // # of gas molecules (or atoms) on all procs
|
||||
int ngas_local; // # of gas molecules (or atoms) on this proc
|
||||
int ngas_before; // # of gas molecules (or atoms) on procs < this proc
|
||||
int ngas; // # of gas atoms on all procs
|
||||
int ngas_local; // # of gas atoms on this proc
|
||||
int ngas_before; // # of gas atoms on procs < this proc
|
||||
int molflag; // 0 = atomic, 1 = molecular system
|
||||
int regionflag; // 0 = anywhere, 1 = specific region
|
||||
int iregion; // exchange/move region
|
||||
char *idregion; // exchange/move region id
|
||||
int regionflag; // 0 = anywhere in box, 1 = specific region
|
||||
int iregion; // GCMC region
|
||||
char *idregion; // GCMC region id
|
||||
|
||||
double nmove_attempts;
|
||||
double nmove_successes;
|
||||
double ndel_attempts;
|
||||
double ndel_successes;
|
||||
double ninsert_attempts;
|
||||
double ninsert_successes;
|
||||
int maxmol; // largest molecule tag across all existing atoms
|
||||
int natoms_per_molecule; // number of atoms in each gas molecule
|
||||
|
||||
int nmax;
|
||||
double ntranslation_attempts;
|
||||
double ntranslation_successes;
|
||||
double nrotation_attempts;
|
||||
double nrotation_successes;
|
||||
double ndeletion_attempts;
|
||||
double ndeletion_successes;
|
||||
double ninsertion_attempts;
|
||||
double ninsertion_successes;
|
||||
|
||||
int gcmc_nmax;
|
||||
int max_region_attempts;
|
||||
double gas_mass;
|
||||
double reservoir_temperature;
|
||||
double chemical_potential;
|
||||
double displace;
|
||||
double max_rotation_angle;
|
||||
double beta,zz,sigma,volume;
|
||||
double xlo,xhi,ylo,yhi,zlo,zhi;
|
||||
double region_xlo,region_xhi,region_ylo,region_yhi,region_zlo,region_zhi;
|
||||
double region_volume;
|
||||
double *sublo,*subhi;
|
||||
int *local_gas_list;
|
||||
double **cutsq;
|
||||
double **atom_coord;
|
||||
double *model_atom_buf;
|
||||
tagint imagetmp;
|
||||
|
||||
class Pair *pair;
|
||||
|
||||
class RanPark *random_equal;
|
||||
class RanPark *random_unequal;
|
||||
|
||||
class Atom *model_atom;
|
||||
|
||||
void options(int, char **);
|
||||
};
|
||||
|
||||
@ -100,26 +128,68 @@ E: Cannot do GCMC on atoms in atom_modify first group
|
||||
This is a restriction due to the way atoms are organized in a list to
|
||||
enable the atom_modify first command.
|
||||
|
||||
W: Fix GCMC may delete atom with non-zero molecule ID
|
||||
E: Fix GCMC cannot exchange individual atoms belonging to a molecule
|
||||
|
||||
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.
|
||||
This is an error since you should not delete only one atom of a molecule.
|
||||
The user has specified atomic (non-molecular) gas exchanges, but an atom
|
||||
belonging to a molecule could be deleted.
|
||||
|
||||
E: Fix GCMC molecule command requires atom attribute molecule
|
||||
E: All mol IDs should be set for fix GCMC group atoms
|
||||
|
||||
The molecule flag is on, yet not all molecule ids in the fix group have
|
||||
been set to non-zero positive values by the user. This is an error since
|
||||
all atoms in the fix GCMC group are eligible for deletion, rotation, and
|
||||
translation and therefore must have valid molecule ids.
|
||||
|
||||
E: Cannot use fix GCMC in a 2d simulation
|
||||
|
||||
Fix GCMC is set up to run in 3d only. No 2d simulations with fix GCMC
|
||||
are allowed.
|
||||
|
||||
E: Cannot use fix GCMC with a triclinic box
|
||||
|
||||
Fix GCMC is set up to run with othogonal boxes only. Simulations with
|
||||
triclinic boxes and fix GCMC are not allowed.
|
||||
|
||||
E: Fix GCMC molecule command requires that atoms have molecule attributes
|
||||
|
||||
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.
|
||||
|
||||
E: Fix GCMC molecule feature does not yet work
|
||||
E: Fix GCMC could not find any atoms in the user-supplied template molecule
|
||||
|
||||
Fix GCMC cannot (yet) be used to exchange molecules, only atoms.
|
||||
When using the molecule option with fix GCMC, the user must supply a
|
||||
template molecule in the usual LAMMPS data file with its molecule id
|
||||
specified in the fix GCMC command as the "type" of the exchanged gas.
|
||||
|
||||
E: Fix GCMC incompatible with given pair_style
|
||||
|
||||
Some pair_styles do not provide single-atom energies, which are needed
|
||||
by fix GCMC.
|
||||
|
||||
E: Fix GCMC incorrect number of atoms per molecule
|
||||
|
||||
The number of atoms in each gas molecule was not computed correctly.
|
||||
|
||||
E: Illegal fix GCMC gas mass <= 0
|
||||
|
||||
The computed mass of the designated gas molecule or atom type was less
|
||||
than or equal to zero.
|
||||
|
||||
E: Fix GCMC ran out of available molecule IDs
|
||||
|
||||
This is a code limitation where more than MAXSMALLINT (usually around
|
||||
two billion) molecules have been created. The code needs to be
|
||||
modified to either allow molecule ID recycling or use bigger ints for
|
||||
molecule IDs. A work-around is to run shorter simulations.
|
||||
|
||||
W: Fix GCMC fix group should be all
|
||||
|
||||
Fix GCMC will ignore the fix group specified by the user. User should
|
||||
set the fix group to "all". Fix GCMC will overwrite the user-specified
|
||||
fix group with a group consisting of all GCMC gas atoms.
|
||||
|
||||
E: Fix GCMC region does not support a bounding box
|
||||
|
||||
Not all regions represent bounded volumes. You cannot use
|
||||
@ -129,7 +199,7 @@ E: Fix GCMC region cannot be dynamic
|
||||
|
||||
Only static regions can be used with fix GCMC.
|
||||
|
||||
E: Deposition region extends outside simulation box
|
||||
E: Fix GCMC region extends outside simulation box
|
||||
|
||||
Self-explanatory.
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing author: Loukas D. Peristeras (Scienomics SARL)
|
||||
[ based on angle_cosine_quared.cpp Naveen Michaud-Agrawal (Johns Hopkins U)]
|
||||
[ based on angle_cosine_squared.cpp Naveen Michaud-Agrawal (Johns Hopkins U)]
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "math.h"
|
||||
|
||||
@ -104,26 +104,22 @@ void DihedralFourier::compute(int eflag, int vflag)
|
||||
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;
|
||||
@ -283,12 +279,12 @@ void DihedralFourier::allocate()
|
||||
memory->create(nterms,n+1,"dihedral:nterms");
|
||||
k = new double * [n+1];
|
||||
multiplicity = new int * [n+1];
|
||||
shift = new int * [n+1];
|
||||
shift = new double * [n+1];
|
||||
cos_shift = new double * [n+1];
|
||||
sin_shift = new double * [n+1];
|
||||
for (int i = 1; i <= n; i++) {
|
||||
k[i] = cos_shift[i] = sin_shift[i] = 0;
|
||||
multiplicity[i] = shift[i] = 0;
|
||||
k[i] = shift[i] = cos_shift[i] = sin_shift[i] = 0;
|
||||
multiplicity[i] = 0;
|
||||
}
|
||||
|
||||
memory->create(setflag,n+1,"dihedral:setflag");
|
||||
@ -313,7 +309,7 @@ void DihedralFourier::coeff(int narg, char **arg)
|
||||
|
||||
double k_one;
|
||||
int multiplicity_one;
|
||||
int shift_one;
|
||||
double shift_one;
|
||||
int nterms_one = force->inumeric(arg[1]);
|
||||
|
||||
if (nterms_one < 1)
|
||||
@ -327,14 +323,14 @@ void DihedralFourier::coeff(int narg, char **arg)
|
||||
nterms[i] = nterms_one;
|
||||
k[i] = new double [nterms_one];
|
||||
multiplicity[i] = new int [nterms_one];
|
||||
shift[i] = new int [nterms_one];
|
||||
shift[i] = new double [nterms_one];
|
||||
cos_shift[i] = new double [nterms_one];
|
||||
sin_shift[i] = new double [nterms_one];
|
||||
for (int j = 0; j<nterms_one; j++) {
|
||||
int offset = 1+3*j;
|
||||
k_one = force->numeric(arg[offset+1]);
|
||||
multiplicity_one = force->inumeric(arg[offset+2]);
|
||||
shift_one = force->inumeric(arg[offset+3]);
|
||||
shift_one = force->numeric(arg[offset+3]);
|
||||
k[i][j] = k_one;
|
||||
multiplicity[i][j] = multiplicity_one;
|
||||
shift[i][j] = shift_one;
|
||||
@ -359,7 +355,7 @@ void DihedralFourier::write_restart(FILE *fp)
|
||||
for(int i = 1; i <= atom->ndihedraltypes; i++) {
|
||||
fwrite(k[i],sizeof(double),nterms[i],fp);
|
||||
fwrite(multiplicity[i],sizeof(int),nterms[i],fp);
|
||||
fwrite(shift[i],sizeof(int),nterms[i],fp);
|
||||
fwrite(shift[i],sizeof(double),nterms[i],fp);
|
||||
}
|
||||
|
||||
}
|
||||
@ -381,7 +377,7 @@ void DihedralFourier::read_restart(FILE *fp)
|
||||
for (int i=1; i<=atom->ndihedraltypes; i++) {
|
||||
k[i] = new double [nterms[i]];
|
||||
multiplicity[i] = new int [nterms[i]];
|
||||
shift[i] = new int [nterms[i]];
|
||||
shift[i] = new double [nterms[i]];
|
||||
cos_shift[i] = new double [nterms[i]];
|
||||
sin_shift[i] = new double [nterms[i]];
|
||||
}
|
||||
@ -390,14 +386,14 @@ void DihedralFourier::read_restart(FILE *fp)
|
||||
for (int i=1; i<=atom->ndihedraltypes; i++) {
|
||||
fread(k[i],sizeof(double),nterms[i],fp);
|
||||
fread(multiplicity[i],sizeof(int),nterms[i],fp);
|
||||
fread(shift[i],sizeof(int),nterms[i],fp);
|
||||
fread(shift[i],sizeof(double),nterms[i],fp);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=1; i<=atom->ndihedraltypes; i++) {
|
||||
MPI_Bcast(k[i],nterms[i],MPI_DOUBLE,0,world);
|
||||
MPI_Bcast(multiplicity[i],nterms[i],MPI_INT,0,world);
|
||||
MPI_Bcast(shift[i],nterms[i],MPI_INT,0,world);
|
||||
MPI_Bcast(shift[i],nterms[i],MPI_DOUBLE,0,world);
|
||||
}
|
||||
|
||||
for (int i=1; i <= atom->ndihedraltypes; i++) {
|
||||
|
||||
@ -35,8 +35,8 @@ class DihedralFourier : public Dihedral {
|
||||
void read_restart(FILE *);
|
||||
|
||||
protected:
|
||||
double **k,**cos_shift,**sin_shift;
|
||||
int **multiplicity,**shift;
|
||||
double **k,**cos_shift,**sin_shift,**shift;
|
||||
int **multiplicity;
|
||||
int *nterms;
|
||||
int implicit,weightflag;
|
||||
|
||||
|
||||
@ -159,7 +159,7 @@ void DihedralNHarmonic::compute(int eflag, int vflag)
|
||||
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);
|
||||
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",
|
||||
|
||||
@ -78,21 +78,18 @@ void ImproperFourier::compute(int eflag, int vflag)
|
||||
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);
|
||||
|
||||
addone(i1,i2,i3,i4, type,evflag,eflag,
|
||||
vb1x, vb1y, vb1z,
|
||||
@ -165,10 +162,14 @@ void ImproperFourier::addone(const int &i1,const int &i2,const int &i3,const int
|
||||
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]);
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -37,7 +37,6 @@ NeighRequest::NeighRequest(LAMMPS *lmp) : Pointers(lmp)
|
||||
gran = granhistory = 0;
|
||||
respainner = respamiddle = respaouter = 0;
|
||||
half_from_full = 0;
|
||||
ghost = 0;
|
||||
|
||||
// default is every reneighboring
|
||||
// default is use newton_pair setting in force
|
||||
|
||||
@ -760,7 +760,7 @@ void Output::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();
|
||||
for (int i = 0; i < ndump; i++) bytes += dump[i]->memory_usage();
|
||||
|
||||
double mbytes = bytes/1024.0/1024.0;
|
||||
|
||||
|
||||
743
src/pair_mie_cut.cpp
Normal file
743
src/pair_mie_cut.cpp
Normal file
@ -0,0 +1,743 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain rights in this software. This software is distributed under
|
||||
the GNU General Public License.
|
||||
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Contributing author: Cassiano Aimoli (aimoli@gmail.com)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "math.h"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "pair_mie_cut.h"
|
||||
#include "atom.h"
|
||||
#include "comm.h"
|
||||
#include "force.h"
|
||||
#include "neighbor.h"
|
||||
#include "neigh_list.h"
|
||||
#include "neigh_request.h"
|
||||
#include "update.h"
|
||||
#include "integrate.h"
|
||||
#include "respa.h"
|
||||
#include "math_const.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace MathConst;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
PairMIECut::PairMIECut(LAMMPS *lmp) : Pair(lmp)
|
||||
{
|
||||
respa_enable = 1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
PairMIECut::~PairMIECut()
|
||||
{
|
||||
if (allocated) {
|
||||
memory->destroy(setflag);
|
||||
memory->destroy(cutsq);
|
||||
|
||||
memory->destroy(cut);
|
||||
memory->destroy(epsilon);
|
||||
memory->destroy(sigma);
|
||||
memory->destroy(gamR);
|
||||
memory->destroy(gamA);
|
||||
memory->destroy(Cmie);
|
||||
memory->destroy(mie1);
|
||||
memory->destroy(mie2);
|
||||
memory->destroy(mie3);
|
||||
memory->destroy(mie4);
|
||||
memory->destroy(offset);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::compute(int eflag, int vflag)
|
||||
{
|
||||
int i,j,ii,jj,inum,jnum,itype,jtype;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
|
||||
double rsq,r2inv,rgamR,rgamA,forcemie,factor_mie;
|
||||
int *ilist,*jlist,*numneigh,**firstneigh;
|
||||
|
||||
evdwl = 0.0;
|
||||
if (eflag || vflag) ev_setup(eflag,vflag);
|
||||
else evflag = vflag_fdotr = 0;
|
||||
|
||||
double **x = atom->x;
|
||||
double **f = atom->f;
|
||||
int *type = atom->type;
|
||||
int nlocal = atom->nlocal;
|
||||
double *special_mie = force->special_lj;
|
||||
int newton_pair = force->newton_pair;
|
||||
|
||||
inum = list->inum;
|
||||
ilist = list->ilist;
|
||||
numneigh = list->numneigh;
|
||||
firstneigh = list->firstneigh;
|
||||
|
||||
// loop over neighbors of my atoms
|
||||
|
||||
for (ii = 0; ii < inum; ii++) {
|
||||
i = ilist[ii];
|
||||
xtmp = x[i][0];
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
itype = type[i];
|
||||
jlist = firstneigh[i];
|
||||
jnum = numneigh[i];
|
||||
|
||||
for (jj = 0; jj < jnum; jj++) {
|
||||
j = jlist[jj];
|
||||
factor_mie = special_mie[sbmask(j)];
|
||||
j &= NEIGHMASK;
|
||||
|
||||
delx = xtmp - x[j][0];
|
||||
dely = ytmp - x[j][1];
|
||||
delz = ztmp - x[j][2];
|
||||
rsq = delx*delx + dely*dely + delz*delz;
|
||||
jtype = type[j];
|
||||
|
||||
if (rsq < cutsq[itype][jtype]) {
|
||||
r2inv = 1.0/rsq;
|
||||
rgamA = pow(r2inv,(gamA[itype][jtype]/2.0));
|
||||
rgamR = pow(r2inv,(gamR[itype][jtype]/2.0));
|
||||
forcemie = (mie1[itype][jtype]*rgamR - mie2[itype][jtype]*rgamA);
|
||||
fpair = factor_mie*forcemie*r2inv;
|
||||
|
||||
f[i][0] += delx*fpair;
|
||||
f[i][1] += dely*fpair;
|
||||
f[i][2] += delz*fpair;
|
||||
if (newton_pair || j < nlocal) {
|
||||
f[j][0] -= delx*fpair;
|
||||
f[j][1] -= dely*fpair;
|
||||
f[j][2] -= delz*fpair;
|
||||
}
|
||||
|
||||
if (eflag) {
|
||||
evdwl = (mie3[itype][jtype]*rgamR - mie4[itype][jtype]*rgamA) -
|
||||
offset[itype][jtype];
|
||||
evdwl *= factor_mie;
|
||||
}
|
||||
|
||||
if (evflag) ev_tally(i,j,nlocal,newton_pair,
|
||||
evdwl,0.0,fpair,delx,dely,delz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vflag_fdotr) virial_fdotr_compute();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::compute_inner()
|
||||
{
|
||||
int i,j,ii,jj,inum,jnum,itype,jtype;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,fpair;
|
||||
double rsq,r2inv,rgamR,rgamA,forcemie,factor_mie,rsw;
|
||||
int *ilist,*jlist,*numneigh,**firstneigh;
|
||||
|
||||
double **x = atom->x;
|
||||
double **f = atom->f;
|
||||
int *type = atom->type;
|
||||
int nlocal = atom->nlocal;
|
||||
double *special_mie = force->special_lj;
|
||||
int newton_pair = force->newton_pair;
|
||||
|
||||
inum = listinner->inum;
|
||||
ilist = listinner->ilist;
|
||||
numneigh = listinner->numneigh;
|
||||
firstneigh = listinner->firstneigh;
|
||||
|
||||
double cut_out_on = cut_respa[0];
|
||||
double cut_out_off = cut_respa[1];
|
||||
|
||||
double cut_out_diff = cut_out_off - cut_out_on;
|
||||
double cut_out_on_sq = cut_out_on*cut_out_on;
|
||||
double cut_out_off_sq = cut_out_off*cut_out_off;
|
||||
|
||||
// loop over neighbors of my atoms
|
||||
|
||||
for (ii = 0; ii < inum; ii++) {
|
||||
i = ilist[ii];
|
||||
xtmp = x[i][0];
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
itype = type[i];
|
||||
jlist = firstneigh[i];
|
||||
jnum = numneigh[i];
|
||||
|
||||
for (jj = 0; jj < jnum; jj++) {
|
||||
j = jlist[jj];
|
||||
factor_mie = special_mie[sbmask(j)];
|
||||
j &= NEIGHMASK;
|
||||
|
||||
delx = xtmp - x[j][0];
|
||||
dely = ytmp - x[j][1];
|
||||
delz = ztmp - x[j][2];
|
||||
rsq = delx*delx + dely*dely + delz*delz;
|
||||
|
||||
if (rsq < cut_out_off_sq) {
|
||||
r2inv = 1.0/rsq;
|
||||
rgamA = pow(r2inv,(gamA[itype][jtype]/2.0));
|
||||
rgamR = pow(r2inv,(gamR[itype][jtype]/2.0));
|
||||
jtype = type[j];
|
||||
forcemie = (mie1[itype][jtype]*rgamR - mie2[itype][jtype]*rgamA);
|
||||
fpair = factor_mie*forcemie*r2inv;
|
||||
if (rsq > cut_out_on_sq) {
|
||||
rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
|
||||
fpair *= 1.0 - rsw*rsw*(3.0 - 2.0*rsw);
|
||||
}
|
||||
|
||||
f[i][0] += delx*fpair;
|
||||
f[i][1] += dely*fpair;
|
||||
f[i][2] += delz*fpair;
|
||||
if (newton_pair || j < nlocal) {
|
||||
f[j][0] -= delx*fpair;
|
||||
f[j][1] -= dely*fpair;
|
||||
f[j][2] -= delz*fpair;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::compute_middle()
|
||||
{
|
||||
int i,j,ii,jj,inum,jnum,itype,jtype;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,fpair;
|
||||
double rsq,r2inv,rgamR,rgamA,forcemie,factor_mie,rsw;
|
||||
int *ilist,*jlist,*numneigh,**firstneigh;
|
||||
|
||||
double **x = atom->x;
|
||||
double **f = atom->f;
|
||||
int *type = atom->type;
|
||||
int nlocal = atom->nlocal;
|
||||
double *special_mie = force->special_lj;
|
||||
int newton_pair = force->newton_pair;
|
||||
|
||||
inum = listmiddle->inum;
|
||||
ilist = listmiddle->ilist;
|
||||
numneigh = listmiddle->numneigh;
|
||||
firstneigh = listmiddle->firstneigh;
|
||||
|
||||
double cut_in_off = cut_respa[0];
|
||||
double cut_in_on = cut_respa[1];
|
||||
double cut_out_on = cut_respa[2];
|
||||
double cut_out_off = cut_respa[3];
|
||||
|
||||
double cut_in_diff = cut_in_on - cut_in_off;
|
||||
double cut_out_diff = cut_out_off - cut_out_on;
|
||||
double cut_in_off_sq = cut_in_off*cut_in_off;
|
||||
double cut_in_on_sq = cut_in_on*cut_in_on;
|
||||
double cut_out_on_sq = cut_out_on*cut_out_on;
|
||||
double cut_out_off_sq = cut_out_off*cut_out_off;
|
||||
|
||||
// loop over neighbors of my atoms
|
||||
|
||||
for (ii = 0; ii < inum; ii++) {
|
||||
i = ilist[ii];
|
||||
xtmp = x[i][0];
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
itype = type[i];
|
||||
jlist = firstneigh[i];
|
||||
jnum = numneigh[i];
|
||||
|
||||
for (jj = 0; jj < jnum; jj++) {
|
||||
j = jlist[jj];
|
||||
factor_mie = special_mie[sbmask(j)];
|
||||
j &= NEIGHMASK;
|
||||
|
||||
delx = xtmp - x[j][0];
|
||||
dely = ytmp - x[j][1];
|
||||
delz = ztmp - x[j][2];
|
||||
rsq = delx*delx + dely*dely + delz*delz;
|
||||
|
||||
if (rsq < cut_out_off_sq && rsq > cut_in_off_sq) {
|
||||
r2inv = 1.0/rsq;
|
||||
rgamA = pow(r2inv,(gamA[itype][jtype]/2.0));
|
||||
rgamR = pow(r2inv,(gamR[itype][jtype]/2.0));
|
||||
jtype = type[j];
|
||||
forcemie = (mie1[itype][jtype]*rgamR - mie2[itype][jtype]*rgamA);
|
||||
fpair = factor_mie*forcemie*r2inv;
|
||||
if (rsq < cut_in_on_sq) {
|
||||
rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff;
|
||||
fpair *= rsw*rsw*(3.0 - 2.0*rsw);
|
||||
}
|
||||
if (rsq > cut_out_on_sq) {
|
||||
rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
|
||||
fpair *= 1.0 + rsw*rsw*(2.0*rsw - 3.0);
|
||||
}
|
||||
|
||||
f[i][0] += delx*fpair;
|
||||
f[i][1] += dely*fpair;
|
||||
f[i][2] += delz*fpair;
|
||||
if (newton_pair || j < nlocal) {
|
||||
f[j][0] -= delx*fpair;
|
||||
f[j][1] -= dely*fpair;
|
||||
f[j][2] -= delz*fpair;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::compute_outer(int eflag, int vflag)
|
||||
{
|
||||
int i,j,ii,jj,inum,jnum,itype,jtype;
|
||||
double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
|
||||
double rsq,r2inv,rgamR,rgamA,forcemie,factor_mie,rsw;
|
||||
int *ilist,*jlist,*numneigh,**firstneigh;
|
||||
|
||||
evdwl = 0.0;
|
||||
if (eflag || vflag) ev_setup(eflag,vflag);
|
||||
else evflag = 0;
|
||||
|
||||
double **x = atom->x;
|
||||
double **f = atom->f;
|
||||
int *type = atom->type;
|
||||
int nlocal = atom->nlocal;
|
||||
double *special_mie = force->special_lj;
|
||||
int newton_pair = force->newton_pair;
|
||||
|
||||
inum = listouter->inum;
|
||||
ilist = listouter->ilist;
|
||||
numneigh = listouter->numneigh;
|
||||
firstneigh = listouter->firstneigh;
|
||||
|
||||
double cut_in_off = cut_respa[2];
|
||||
double cut_in_on = cut_respa[3];
|
||||
|
||||
double cut_in_diff = cut_in_on - cut_in_off;
|
||||
double cut_in_off_sq = cut_in_off*cut_in_off;
|
||||
double cut_in_on_sq = cut_in_on*cut_in_on;
|
||||
|
||||
// loop over neighbors of my atoms
|
||||
|
||||
for (ii = 0; ii < inum; ii++) {
|
||||
i = ilist[ii];
|
||||
xtmp = x[i][0];
|
||||
ytmp = x[i][1];
|
||||
ztmp = x[i][2];
|
||||
itype = type[i];
|
||||
jlist = firstneigh[i];
|
||||
jnum = numneigh[i];
|
||||
|
||||
for (jj = 0; jj < jnum; jj++) {
|
||||
j = jlist[jj];
|
||||
factor_mie = special_mie[sbmask(j)];
|
||||
j &= NEIGHMASK;
|
||||
|
||||
delx = xtmp - x[j][0];
|
||||
dely = ytmp - x[j][1];
|
||||
delz = ztmp - x[j][2];
|
||||
rsq = delx*delx + dely*dely + delz*delz;
|
||||
jtype = type[j];
|
||||
|
||||
if (rsq < cutsq[itype][jtype]) {
|
||||
if (rsq > cut_in_off_sq) {
|
||||
r2inv = 1.0/rsq;
|
||||
rgamA = pow(r2inv,(gamA[itype][jtype]/2.0));
|
||||
rgamR = pow(r2inv,(gamR[itype][jtype]/2.0));
|
||||
forcemie = (mie1[itype][jtype]*rgamR - mie2[itype][jtype]*rgamA);
|
||||
fpair = factor_mie*forcemie*r2inv;
|
||||
if (rsq < cut_in_on_sq) {
|
||||
rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff;
|
||||
fpair *= rsw*rsw*(3.0 - 2.0*rsw);
|
||||
}
|
||||
|
||||
f[i][0] += delx*fpair;
|
||||
f[i][1] += dely*fpair;
|
||||
f[i][2] += delz*fpair;
|
||||
if (newton_pair || j < nlocal) {
|
||||
f[j][0] -= delx*fpair;
|
||||
f[j][1] -= dely*fpair;
|
||||
f[j][2] -= delz*fpair;
|
||||
}
|
||||
}
|
||||
|
||||
if (eflag) {
|
||||
r2inv = 1.0/rsq;
|
||||
rgamA = pow(r2inv,(gamA[itype][jtype]/2.0));
|
||||
rgamR = pow(r2inv,(gamR[itype][jtype]/2.0));
|
||||
evdwl = (mie3[itype][jtype]*rgamR - mie4[itype][jtype]*rgamA) -
|
||||
offset[itype][jtype];
|
||||
evdwl *= factor_mie;
|
||||
}
|
||||
|
||||
if (vflag) {
|
||||
if (rsq <= cut_in_off_sq) {
|
||||
r2inv = 1.0/rsq;
|
||||
rgamA = pow(r2inv,(gamA[itype][jtype]/2.0));
|
||||
rgamR = pow(r2inv,(gamR[itype][jtype]/2.0));
|
||||
forcemie = (mie1[itype][jtype]*rgamR - mie2[itype][jtype]*rgamA);
|
||||
fpair = factor_mie*forcemie*r2inv;
|
||||
} else if (rsq < cut_in_on_sq)
|
||||
fpair = factor_mie*forcemie*r2inv;
|
||||
}
|
||||
|
||||
if (evflag) ev_tally(i,j,nlocal,newton_pair,
|
||||
evdwl,0.0,fpair,delx,dely,delz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
allocate all arrays
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::allocate()
|
||||
{
|
||||
allocated = 1;
|
||||
int n = atom->ntypes;
|
||||
|
||||
memory->create(setflag,n+1,n+1,"pair:setflag");
|
||||
for (int i = 1; i <= n; i++)
|
||||
for (int j = i; j <= n; j++)
|
||||
setflag[i][j] = 0;
|
||||
|
||||
memory->create(cutsq,n+1,n+1,"pair:cutsq");
|
||||
|
||||
memory->create(cut,n+1,n+1,"pair:cut");
|
||||
memory->create(epsilon,n+1,n+1,"pair:epsilon");
|
||||
memory->create(sigma,n+1,n+1,"pair:sigma");
|
||||
memory->create(gamR,n+1,n+1,"pair:gamR");
|
||||
memory->create(gamA,n+1,n+1,"pair:gamA");
|
||||
memory->create(Cmie,n+1,n+1,"pair:Cmie");
|
||||
memory->create(mie1,n+1,n+1,"pair:mie1");
|
||||
memory->create(mie2,n+1,n+1,"pair:mie2");
|
||||
memory->create(mie3,n+1,n+1,"pair:mie3");
|
||||
memory->create(mie4,n+1,n+1,"pair:mie4");
|
||||
memory->create(offset,n+1,n+1,"pair:offset");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
global settings
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::settings(int narg, char **arg)
|
||||
{
|
||||
if (narg != 1) error->all(FLERR,"Illegal pair_style command");
|
||||
|
||||
cut_global = force->numeric(arg[0]);
|
||||
|
||||
// reset cutoffs that have been explicitly set
|
||||
|
||||
if (allocated) {
|
||||
int i,j;
|
||||
for (i = 1; i <= atom->ntypes; i++)
|
||||
for (j = i+1; j <= atom->ntypes; j++)
|
||||
if (setflag[i][j]) cut[i][j] = cut_global;
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
set coeffs for one or more type pairs
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::coeff(int narg, char **arg)
|
||||
{
|
||||
if (narg < 6 || narg > 7)
|
||||
error->all(FLERR,"Incorrect args for pair coefficients");
|
||||
if (!allocated) allocate();
|
||||
|
||||
int ilo,ihi,jlo,jhi;
|
||||
force->bounds(arg[0],atom->ntypes,ilo,ihi);
|
||||
force->bounds(arg[1],atom->ntypes,jlo,jhi);
|
||||
|
||||
double epsilon_one = force->numeric(arg[2]);
|
||||
double sigma_one = force->numeric(arg[3]);
|
||||
double gamR_one = force->numeric(arg[4]);
|
||||
double gamA_one = force->numeric(arg[5]);
|
||||
|
||||
double cut_one = cut_global;
|
||||
if (narg == 7) cut_one = force->numeric(arg[6]);
|
||||
|
||||
int count = 0;
|
||||
for (int i = ilo; i <= ihi; i++) {
|
||||
for (int j = MAX(jlo,i); j <= jhi; j++) {
|
||||
epsilon[i][j] = epsilon_one;
|
||||
sigma[i][j] = sigma_one;
|
||||
gamR[i][j] = gamR_one;
|
||||
gamA[i][j] = gamA_one;
|
||||
cut[i][j] = cut_one;
|
||||
setflag[i][j] = 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
init specific to this pair style
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::init_style()
|
||||
{
|
||||
// request regular or rRESPA neighbor lists
|
||||
|
||||
int irequest;
|
||||
|
||||
if (update->whichflag == 1 && strstr(update->integrate_style,"respa")) {
|
||||
int respa = 0;
|
||||
if (((Respa *) update->integrate)->level_inner >= 0) respa = 1;
|
||||
if (((Respa *) update->integrate)->level_middle >= 0) respa = 2;
|
||||
|
||||
if (respa == 0) irequest = neighbor->request(this);
|
||||
else if (respa == 1) {
|
||||
irequest = neighbor->request(this);
|
||||
neighbor->requests[irequest]->id = 1;
|
||||
neighbor->requests[irequest]->half = 0;
|
||||
neighbor->requests[irequest]->respainner = 1;
|
||||
irequest = neighbor->request(this);
|
||||
neighbor->requests[irequest]->id = 3;
|
||||
neighbor->requests[irequest]->half = 0;
|
||||
neighbor->requests[irequest]->respaouter = 1;
|
||||
} else {
|
||||
irequest = neighbor->request(this);
|
||||
neighbor->requests[irequest]->id = 1;
|
||||
neighbor->requests[irequest]->half = 0;
|
||||
neighbor->requests[irequest]->respainner = 1;
|
||||
irequest = neighbor->request(this);
|
||||
neighbor->requests[irequest]->id = 2;
|
||||
neighbor->requests[irequest]->half = 0;
|
||||
neighbor->requests[irequest]->respamiddle = 1;
|
||||
irequest = neighbor->request(this);
|
||||
neighbor->requests[irequest]->id = 3;
|
||||
neighbor->requests[irequest]->half = 0;
|
||||
neighbor->requests[irequest]->respaouter = 1;
|
||||
}
|
||||
|
||||
} else irequest = neighbor->request(this);
|
||||
|
||||
// set rRESPA cutoffs
|
||||
|
||||
if (strstr(update->integrate_style,"respa") &&
|
||||
((Respa *) update->integrate)->level_inner >= 0)
|
||||
cut_respa = ((Respa *) update->integrate)->cutoff;
|
||||
else cut_respa = NULL;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
neighbor callback to inform pair style of neighbor list to use
|
||||
regular or rRESPA
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::init_list(int id, NeighList *ptr)
|
||||
{
|
||||
if (id == 0) list = ptr;
|
||||
else if (id == 1) listinner = ptr;
|
||||
else if (id == 2) listmiddle = ptr;
|
||||
else if (id == 3) listouter = ptr;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
init for one type pair i,j and corresponding j,i
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double PairMIECut::init_one(int i, int j)
|
||||
{
|
||||
if (setflag[i][j] == 0) {
|
||||
epsilon[i][j] = mix_energy(epsilon[i][i],epsilon[j][j],
|
||||
sigma[i][i],sigma[j][j]);
|
||||
sigma[i][j] = mix_distance(sigma[i][i],sigma[j][j]);
|
||||
gamR[i][j] = mix_distance(gamR[i][i],gamR[j][j]);
|
||||
gamA[i][j] = mix_distance(gamA[i][i],gamA[j][j]);
|
||||
cut[i][j] = mix_distance(cut[i][i],cut[j][j]);
|
||||
}
|
||||
|
||||
gamA[j][i] = gamA[i][j];
|
||||
gamR[j][i] = gamR[i][j];
|
||||
Cmie[i][j] = (gamR[i][j]/(gamR[i][j]-gamA[i][j]) *
|
||||
pow((gamR[i][j]/gamA[i][j]),
|
||||
(gamA[i][j]/(gamR[i][j]-gamA[i][j]))));
|
||||
mie1[i][j] = Cmie[i][j] * gamR[i][j]* epsilon[i][j] *
|
||||
pow(sigma[i][j],gamR[i][j]);
|
||||
mie2[i][j] = Cmie[i][j] * gamA[i][j] * epsilon[i][j] *
|
||||
pow(sigma[i][j],gamA[i][j]);
|
||||
mie3[i][j] = Cmie[i][j] * epsilon[i][j] * pow(sigma[i][j],gamR[i][j]);
|
||||
mie4[i][j] = Cmie[i][j] * epsilon[i][j] * pow(sigma[i][j],gamA[i][j]);
|
||||
|
||||
if (offset_flag) {
|
||||
double ratio = sigma[i][j] / cut[i][j];
|
||||
offset[i][j] = Cmie[i][j] * epsilon[i][j] *
|
||||
(pow(ratio,gamR[i][j]) - pow(ratio,gamA[i][j]));
|
||||
} else offset[i][j] = 0.0;
|
||||
|
||||
mie1[j][i] = mie1[i][j];
|
||||
mie2[j][i] = mie2[i][j];
|
||||
mie3[j][i] = mie3[i][j];
|
||||
mie4[j][i] = mie4[i][j];
|
||||
offset[j][i] = offset[i][j];
|
||||
|
||||
// check interior rRESPA cutoff
|
||||
|
||||
if (cut_respa && cut[i][j] < cut_respa[3])
|
||||
error->all(FLERR,"Pair cutoff < Respa interior cutoff");
|
||||
|
||||
// compute I,J contribution to long-range tail correction
|
||||
// count total # of atoms of type I and J via Allreduce
|
||||
|
||||
if (tail_flag) {
|
||||
int *type = atom->type;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
double count[2],all[2];
|
||||
count[0] = count[1] = 0.0;
|
||||
for (int k = 0; k < nlocal; k++) {
|
||||
if (type[k] == i) count[0] += 1.0;
|
||||
if (type[k] == j) count[1] += 1.0;
|
||||
}
|
||||
MPI_Allreduce(count,all,2,MPI_DOUBLE,MPI_SUM,world);
|
||||
|
||||
double siggamA = pow(sigma[i][j],gamA[i][j]);
|
||||
double siggamR = pow(sigma[i][j],gamR[i][j]);
|
||||
double rcgamA = pow(cut[i][j],(gamA[i][j]-3.0));
|
||||
double rcgamR = pow(cut[i][j],(gamR[i][j]-3.0));
|
||||
etail_ij = Cmie[i][j]*2.0*MY_PI*all[0]*all[1]*epsilon[i][j]*
|
||||
(siggamR/((gamR[i][j]-3.0)*rcgamR)-siggamA/((gamA[i][j]-3.0)*rcgamA));
|
||||
ptail_ij = Cmie[i][j]*2.0*MY_PI*all[0]*all[1]*epsilon[i][j]/3.0*
|
||||
((gamR[i][j]/(gamR[i][j]-3.0))*siggamR/rcgamR-
|
||||
(gamA[i][j]/(gamA[i][j]-3.0))*siggamA/rcgamA);
|
||||
}
|
||||
|
||||
return cut[i][j];
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
proc 0 writes to restart file
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::write_restart(FILE *fp)
|
||||
{
|
||||
write_restart_settings(fp);
|
||||
|
||||
int i,j;
|
||||
for (i = 1; i <= atom->ntypes; i++)
|
||||
for (j = i; j <= atom->ntypes; j++) {
|
||||
fwrite(&setflag[i][j],sizeof(int),1,fp);
|
||||
if (setflag[i][j]) {
|
||||
fwrite(&epsilon[i][j],sizeof(double),1,fp);
|
||||
fwrite(&sigma[i][j],sizeof(double),1,fp);
|
||||
fwrite(&gamR[i][j],sizeof(double),1,fp);
|
||||
fwrite(&gamA[i][j],sizeof(double),1,fp);
|
||||
fwrite(&cut[i][j],sizeof(double),1,fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
proc 0 reads from restart file, bcasts
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::read_restart(FILE *fp)
|
||||
{
|
||||
read_restart_settings(fp);
|
||||
allocate();
|
||||
|
||||
int i,j;
|
||||
int me = comm->me;
|
||||
for (i = 1; i <= atom->ntypes; i++)
|
||||
for (j = i; j <= atom->ntypes; j++) {
|
||||
if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
|
||||
MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
|
||||
if (setflag[i][j]) {
|
||||
if (me == 0) {
|
||||
fread(&epsilon[i][j],sizeof(double),1,fp);
|
||||
fread(&sigma[i][j],sizeof(double),1,fp);
|
||||
fread(&gamR[i][j],sizeof(double),1,fp);
|
||||
fread(&gamA[i][j],sizeof(double),1,fp);
|
||||
fread(&cut[i][j],sizeof(double),1,fp);
|
||||
}
|
||||
MPI_Bcast(&epsilon[i][j],1,MPI_DOUBLE,0,world);
|
||||
MPI_Bcast(&sigma[i][j],1,MPI_DOUBLE,0,world);
|
||||
MPI_Bcast(&gamR[i][j],1,MPI_DOUBLE,0,world);
|
||||
MPI_Bcast(&gamA[i][j],1,MPI_DOUBLE,0,world);
|
||||
MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
proc 0 writes to restart file
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::write_restart_settings(FILE *fp)
|
||||
{
|
||||
fwrite(&cut_global,sizeof(double),1,fp);
|
||||
fwrite(&offset_flag,sizeof(int),1,fp);
|
||||
fwrite(&mix_flag,sizeof(int),1,fp);
|
||||
fwrite(&tail_flag,sizeof(int),1,fp);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
proc 0 reads from restart file, bcasts
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void PairMIECut::read_restart_settings(FILE *fp)
|
||||
{
|
||||
int me = comm->me;
|
||||
if (me == 0) {
|
||||
fread(&cut_global,sizeof(double),1,fp);
|
||||
fread(&offset_flag,sizeof(int),1,fp);
|
||||
fread(&mix_flag,sizeof(int),1,fp);
|
||||
fread(&tail_flag,sizeof(int),1,fp);
|
||||
}
|
||||
MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
|
||||
MPI_Bcast(&offset_flag,1,MPI_INT,0,world);
|
||||
MPI_Bcast(&mix_flag,1,MPI_INT,0,world);
|
||||
MPI_Bcast(&tail_flag,1,MPI_INT,0,world);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
double PairMIECut::single(int i, int j, int itype, int jtype, double rsq,
|
||||
double factor_coul, double factor_mie,
|
||||
double &fforce)
|
||||
{
|
||||
double r2inv,rgamR,rgamA,forcemie,phimie;
|
||||
|
||||
r2inv = 1.0/rsq;
|
||||
rgamA = pow(r2inv,(gamA[itype][jtype]/2.0));
|
||||
rgamR = pow(r2inv,(gamR[itype][jtype]/2.0));
|
||||
forcemie = (mie1[itype][jtype]*rgamR - mie2[itype][jtype]*rgamA);
|
||||
fforce = factor_mie*forcemie*r2inv;
|
||||
|
||||
phimie = (mie3[itype][jtype]*rgamR - mie4[itype][jtype]*rgamA) -
|
||||
offset[itype][jtype];
|
||||
return factor_mie*phimie;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void *PairMIECut::extract(const char *str, int &dim)
|
||||
{
|
||||
dim = 2;
|
||||
if (strcmp(str,"epsilon") == 0) return (void *) epsilon;
|
||||
if (strcmp(str,"sigma") == 0) return (void *) sigma;
|
||||
if (strcmp(str,"gamR") == 0) return (void *) gamR;
|
||||
if (strcmp(str,"gamA") == 0) return (void *) gamA;
|
||||
return NULL;
|
||||
}
|
||||
81
src/pair_mie_cut.h
Normal file
81
src/pair_mie_cut.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
http://lammps.sandia.gov, Sandia National Laboratories
|
||||
Steve Plimpton, sjplimp@sandia.gov
|
||||
|
||||
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||
certain 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(mie/cut,PairMIECut)
|
||||
|
||||
#else
|
||||
|
||||
#ifndef LMP_PAIR_MIE_CUT_H
|
||||
#define LMP_PAIR_MIE_CUT_H
|
||||
|
||||
#include "pair.h"
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class PairMIECut : public Pair {
|
||||
public:
|
||||
PairMIECut(class LAMMPS *);
|
||||
virtual ~PairMIECut();
|
||||
virtual void compute(int, int);
|
||||
void settings(int, char **);
|
||||
void coeff(int, char **);
|
||||
void init_style();
|
||||
void init_list(int, class NeighList *);
|
||||
double init_one(int, int);
|
||||
void write_restart(FILE *);
|
||||
void read_restart(FILE *);
|
||||
void write_restart_settings(FILE *);
|
||||
void read_restart_settings(FILE *);
|
||||
double single(int, int, int, int, double, double, double, double &);
|
||||
void *extract(const char *, int &);
|
||||
|
||||
void compute_inner();
|
||||
void compute_middle();
|
||||
void compute_outer(int, int);
|
||||
|
||||
protected:
|
||||
double cut_global;
|
||||
double **cut;
|
||||
double **epsilon,**sigma;
|
||||
double **gamR,**gamA,**Cmie;
|
||||
double **mie1,**mie2,**mie3,**mie4,**offset;
|
||||
double *cut_respa;
|
||||
|
||||
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.
|
||||
|
||||
E: Incorrect args for pair coefficients
|
||||
|
||||
Self-explanatory. Check the input script or data file.
|
||||
|
||||
E: Pair cutoff < Respa interior cutoff
|
||||
|
||||
One or more pairwise cutoffs are too short to use with the specified
|
||||
rRESPA cutoffs.
|
||||
|
||||
*/
|
||||
@ -552,6 +552,7 @@ void ReadData::atoms()
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buffer[m]);
|
||||
}
|
||||
if (buffer[m-1] != '\n') strcpy(&buffer[m++],"\n");
|
||||
m++;
|
||||
}
|
||||
MPI_Bcast(&m,1,MPI_INT,0,world);
|
||||
@ -644,6 +645,7 @@ void ReadData::velocities()
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buffer[m]);
|
||||
}
|
||||
if (buffer[m-1] != '\n') strcpy(&buffer[m++],"\n");
|
||||
m++;
|
||||
}
|
||||
MPI_Bcast(&m,1,MPI_INT,0,world);
|
||||
@ -695,6 +697,7 @@ void ReadData::bonus(bigint nbonus, AtomVec *ptr, const char *type)
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buffer[m]);
|
||||
}
|
||||
if (buffer[m-1] != '\n') strcpy(&buffer[m++],"\n");
|
||||
m++;
|
||||
}
|
||||
MPI_Bcast(&m,1,MPI_INT,0,world);
|
||||
@ -734,6 +737,7 @@ void ReadData::bonds()
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buffer[m]);
|
||||
}
|
||||
if (buffer[m-1] != '\n') strcpy(&buffer[m++],"\n");
|
||||
m++;
|
||||
}
|
||||
MPI_Bcast(&m,1,MPI_INT,0,world);
|
||||
@ -780,6 +784,7 @@ void ReadData::angles()
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buffer[m]);
|
||||
}
|
||||
if (buffer[m-1] != '\n') strcpy(&buffer[m++],"\n");
|
||||
m++;
|
||||
}
|
||||
MPI_Bcast(&m,1,MPI_INT,0,world);
|
||||
@ -826,6 +831,7 @@ void ReadData::dihedrals()
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buffer[m]);
|
||||
}
|
||||
if (buffer[m-1] != '\n') strcpy(&buffer[m++],"\n");
|
||||
m++;
|
||||
}
|
||||
MPI_Bcast(&m,1,MPI_INT,0,world);
|
||||
@ -872,6 +878,7 @@ void ReadData::impropers()
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buffer[m]);
|
||||
}
|
||||
if (buffer[m-1] != '\n') strcpy(&buffer[m++],"\n");
|
||||
m++;
|
||||
}
|
||||
MPI_Bcast(&m,1,MPI_INT,0,world);
|
||||
@ -914,6 +921,7 @@ void ReadData::mass()
|
||||
eof = fgets(&buf[m],MAXLINE,fp);
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buf[m]);
|
||||
if (buf[m-1] != '\n') strcpy(&buf[m++],"\n");
|
||||
buf[m-1] = '\0';
|
||||
}
|
||||
}
|
||||
@ -943,6 +951,7 @@ void ReadData::paircoeffs()
|
||||
eof = fgets(&buf[m],MAXLINE,fp);
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buf[m]);
|
||||
if (buf[m-1] != '\n') strcpy(&buf[m++],"\n");
|
||||
buf[m-1] = '\0';
|
||||
}
|
||||
}
|
||||
@ -974,6 +983,7 @@ void ReadData::bondcoeffs()
|
||||
eof = fgets(&buf[m],MAXLINE,fp);
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buf[m]);
|
||||
if (buf[m-1] != '\n') strcpy(&buf[m++],"\n");
|
||||
buf[m-1] = '\0';
|
||||
}
|
||||
}
|
||||
@ -1005,6 +1015,7 @@ void ReadData::anglecoeffs(int which)
|
||||
eof = fgets(&buf[m],MAXLINE,fp);
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buf[m]);
|
||||
if (buf[m-1] != '\n') strcpy(&buf[m++],"\n");
|
||||
buf[m-1] = '\0';
|
||||
}
|
||||
}
|
||||
@ -1038,6 +1049,7 @@ void ReadData::dihedralcoeffs(int which)
|
||||
eof = fgets(&buf[m],MAXLINE,fp);
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buf[m]);
|
||||
if (buf[m-1] != '\n') strcpy(&buf[m++],"\n");
|
||||
buf[m-1] = '\0';
|
||||
}
|
||||
}
|
||||
@ -1074,6 +1086,7 @@ void ReadData::impropercoeffs(int which)
|
||||
eof = fgets(&buf[m],MAXLINE,fp);
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buf[m]);
|
||||
if (buf[m-1] != '\n') strcpy(&buf[m++],"\n");
|
||||
buf[m-1] = '\0';
|
||||
}
|
||||
}
|
||||
@ -1113,6 +1126,7 @@ void ReadData::fix(int ifix, char *line, bigint nlines)
|
||||
if (eof == NULL) error->one(FLERR,"Unexpected end of data file");
|
||||
m += strlen(&buffer[m]);
|
||||
}
|
||||
if (buffer[m-1] != '\n') strcpy(&buffer[m++],"\n");
|
||||
m++;
|
||||
}
|
||||
MPI_Bcast(&m,1,MPI_INT,0,world);
|
||||
|
||||
@ -1490,7 +1490,7 @@ void Thermo::compute_spcpu()
|
||||
|
||||
void Thermo::compute_atoms()
|
||||
{
|
||||
bivalue = natoms;
|
||||
bivalue = atom->natoms;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
186
src/variable.cpp
186
src/variable.cpp
@ -39,10 +39,11 @@ using namespace MathConst;
|
||||
|
||||
#define VARDELTA 4
|
||||
#define MAXLEVEL 4
|
||||
#define MAXLINE 256
|
||||
|
||||
#define MYROUND(a) (( a-floor(a) ) >= .5) ? ceil(a) : floor(a)
|
||||
|
||||
enum{INDEX,LOOP,WORLD,UNIVERSE,ULOOP,STRING,EQUAL,ATOM};
|
||||
enum{INDEX,LOOP,WORLD,UNIVERSE,ULOOP,STRING,FILEVAR,EQUAL,ATOM};
|
||||
enum{ARG,OP};
|
||||
|
||||
// customize by adding a function
|
||||
@ -56,7 +57,7 @@ enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,UNARY,
|
||||
|
||||
// customize by adding a special function
|
||||
|
||||
enum{SUM,XMIN,XMAX,AVE,TRAP};
|
||||
enum{SUM,XMIN,XMAX,AVE,TRAP,NEXT};
|
||||
|
||||
#define INVOKED_SCALAR 1
|
||||
#define INVOKED_VECTOR 2
|
||||
@ -77,6 +78,7 @@ Variable::Variable(LAMMPS *lmp) : Pointers(lmp)
|
||||
num = NULL;
|
||||
which = NULL;
|
||||
pad = NULL;
|
||||
reader = NULL;
|
||||
data = NULL;
|
||||
|
||||
eval_in_progress = NULL;
|
||||
@ -101,6 +103,7 @@ Variable::~Variable()
|
||||
{
|
||||
for (int i = 0; i < nvar; i++) {
|
||||
delete [] names[i];
|
||||
delete reader[i];
|
||||
if (style[i] == LOOP || style[i] == ULOOP) delete [] data[i][0];
|
||||
else for (int j = 0; j < num[i]; j++) delete [] data[i][j];
|
||||
delete [] data[i];
|
||||
@ -110,6 +113,7 @@ Variable::~Variable()
|
||||
memory->destroy(num);
|
||||
memory->destroy(which);
|
||||
memory->destroy(pad);
|
||||
memory->sfree(reader);
|
||||
memory->sfree(data);
|
||||
|
||||
memory->destroy(eval_in_progress);
|
||||
@ -245,7 +249,8 @@ void Variable::set(int narg, char **arg)
|
||||
for (int jvar = 0; jvar < nvar; jvar++)
|
||||
if (num[jvar] && (style[jvar] == UNIVERSE || style[jvar] == ULOOP) &&
|
||||
num[nvar] != num[jvar])
|
||||
error->all(FLERR,"All universe/uloop variables must have same # of values");
|
||||
error->all(FLERR,
|
||||
"All universe/uloop variables must have same # of values");
|
||||
|
||||
// STRING
|
||||
// remove pre-existing var if also style STRING (allows it to be reset)
|
||||
@ -267,6 +272,23 @@ void Variable::set(int narg, char **arg)
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
copy(1,&arg[2],data[nvar]);
|
||||
|
||||
// FILEVAR for strings or numbers
|
||||
// which = 1st value
|
||||
|
||||
} else if (strcmp(arg[1],"file") == 0) {
|
||||
if (narg != 3) error->all(FLERR,"Illegal variable command");
|
||||
if (find(arg[0]) >= 0) return;
|
||||
if (nvar == maxvar) grow();
|
||||
style[nvar] = FILEVAR;
|
||||
num[nvar] = 1;
|
||||
which[nvar] = 0;
|
||||
pad[nvar] = 0;
|
||||
data[nvar] = new char*[num[nvar]];
|
||||
data[nvar][0] = new char[MAXLINE];
|
||||
reader[nvar] = new VarReader(lmp,arg[2]);
|
||||
int flag = reader[nvar]->read(data[nvar][0]);
|
||||
if (flag) error->all(FLERR,"File variable could not read value");
|
||||
|
||||
// EQUAL
|
||||
// remove pre-existing var if also style EQUAL (allows it to be reset)
|
||||
// num = 2, which = 1st value
|
||||
@ -385,6 +407,17 @@ int Variable::next(int narg, char **arg)
|
||||
}
|
||||
}
|
||||
|
||||
} else if (istyle == FILEVAR) {
|
||||
|
||||
for (int iarg = 0; iarg < narg; iarg++) {
|
||||
ivar = find(arg[iarg]);
|
||||
int done = reader[ivar]->read(data[ivar][0]);
|
||||
if (done) {
|
||||
flag = 1;
|
||||
remove(ivar);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (istyle == UNIVERSE || istyle == ULOOP) {
|
||||
|
||||
// wait until lock file can be created and owned by proc 0 of this world
|
||||
@ -445,7 +478,8 @@ char *Variable::retrieve(char *name)
|
||||
|
||||
char *str;
|
||||
if (style[ivar] == INDEX || style[ivar] == WORLD ||
|
||||
style[ivar] == UNIVERSE || style[ivar] == STRING) {
|
||||
style[ivar] == UNIVERSE || style[ivar] == STRING ||
|
||||
style[ivar] == FILEVAR) {
|
||||
str = data[ivar][which[ivar]];
|
||||
} else if (style[ivar] == LOOP || style[ivar] == ULOOP) {
|
||||
char result[16];
|
||||
@ -575,6 +609,7 @@ void Variable::remove(int n)
|
||||
num[i-1] = num[i];
|
||||
which[i-1] = which[i];
|
||||
pad[i-1] = pad[i];
|
||||
reader[i-1] = reader[i];
|
||||
data[i-1] = data[i];
|
||||
}
|
||||
nvar--;
|
||||
@ -586,14 +621,20 @@ void Variable::remove(int n)
|
||||
|
||||
void Variable::grow()
|
||||
{
|
||||
int old = maxvar;
|
||||
maxvar += VARDELTA;
|
||||
names = (char **)
|
||||
memory->srealloc(names,maxvar*sizeof(char *),"var:names");
|
||||
names = (char **) memory->srealloc(names,maxvar*sizeof(char *),"var:names");
|
||||
memory->grow(style,maxvar,"var:style");
|
||||
memory->grow(num,maxvar,"var:num");
|
||||
memory->grow(which,maxvar,"var:which");
|
||||
memory->grow(pad,maxvar,"var:pad");
|
||||
|
||||
reader = (VarReader **)
|
||||
memory->srealloc(reader,maxvar*sizeof(VarReader *),"var:reader");
|
||||
for (int i = old; i < maxvar; i++) reader[i] = NULL;
|
||||
|
||||
data = (char ***) memory->srealloc(data,maxvar*sizeof(char **),"var:data");
|
||||
|
||||
memory->grow(eval_in_progress,maxvar,"var:eval_in_progress");
|
||||
for (int i = 0; i < maxvar; i++) eval_in_progress[i] = 0;
|
||||
}
|
||||
@ -743,14 +784,16 @@ double Variable::evaluate(char *str, Tree **tree)
|
||||
|
||||
if (strncmp(word,"c_",2) == 0) {
|
||||
if (domain->box_exist == 0)
|
||||
error->all(FLERR,"Variable evaluation before simulation box is defined");
|
||||
error->all(FLERR,
|
||||
"Variable evaluation before simulation box is defined");
|
||||
|
||||
n = strlen(word) - 2 + 1;
|
||||
char *id = new char[n];
|
||||
strcpy(id,&word[2]);
|
||||
|
||||
int icompute = modify->find_compute(id);
|
||||
if (icompute < 0) error->all(FLERR,"Invalid compute ID in variable formula");
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Invalid compute ID in variable formula");
|
||||
Compute *compute = modify->compute[icompute];
|
||||
delete [] id;
|
||||
|
||||
@ -2826,7 +2869,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
|
||||
if (strcmp(word,"sum") && strcmp(word,"min") && strcmp(word,"max") &&
|
||||
strcmp(word,"ave") && strcmp(word,"trap") && strcmp(word,"gmask") &&
|
||||
strcmp(word,"rmask") && strcmp(word,"grmask"))
|
||||
strcmp(word,"rmask") && strcmp(word,"grmask") && strcmp(word,"next"))
|
||||
return 0;
|
||||
|
||||
// parse contents for arg1,arg2,arg3 separated by commas
|
||||
@ -2872,7 +2915,8 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
else if (strcmp(word,"ave") == 0) method = AVE;
|
||||
else if (strcmp(word,"trap") == 0) method = TRAP;
|
||||
|
||||
if (narg != 1) error->all(FLERR,"Invalid special function in variable formula");
|
||||
if (narg != 1)
|
||||
error->all(FLERR,"Invalid special function in variable formula");
|
||||
|
||||
Compute *compute = NULL;
|
||||
Fix *fix = NULL;
|
||||
@ -2887,12 +2931,14 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
} else index = 0;
|
||||
|
||||
int icompute = modify->find_compute(&arg1[2]);
|
||||
if (icompute < 0) error->all(FLERR,"Invalid compute ID in variable formula");
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Invalid compute ID in variable formula");
|
||||
compute = modify->compute[icompute];
|
||||
if (index == 0 && compute->vector_flag) {
|
||||
if (update->whichflag == 0) {
|
||||
if (compute->invoked_vector != update->ntimestep)
|
||||
error->all(FLERR,"Compute used in variable between runs is not current");
|
||||
error->all(FLERR,
|
||||
"Compute used in variable between runs is not current");
|
||||
} else if (!(compute->invoked_flag & INVOKED_VECTOR)) {
|
||||
compute->compute_vector();
|
||||
compute->invoked_flag |= INVOKED_VECTOR;
|
||||
@ -2961,7 +3007,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
else if (method == XMAX) value = MAX(value,vec[j]);
|
||||
else if (method == AVE) value += vec[j];
|
||||
else if (method == TRAP) {
|
||||
if (i > 0 && i < nvec-1) value += vec[j];
|
||||
if (i > 1 && i < nvec-1) value += vec[j];
|
||||
else value += 0.5*vec[j];
|
||||
}
|
||||
j += nstride;
|
||||
@ -2978,7 +3024,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
else if (method == XMAX) value = MAX(value,one);
|
||||
else if (method == AVE) value += one;
|
||||
else if (method == TRAP) {
|
||||
if (i > 1 && i < nvec) value += one;
|
||||
if (i > 1 && i < nvec-1) value += one;
|
||||
else value += 0.5*one;
|
||||
}
|
||||
}
|
||||
@ -2986,10 +3032,6 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
|
||||
if (method == AVE) value /= nvec;
|
||||
|
||||
delete [] arg1;
|
||||
delete [] arg2;
|
||||
delete [] arg3;
|
||||
|
||||
// save value in tree or on argstack
|
||||
|
||||
if (tree) {
|
||||
@ -3005,7 +3047,8 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
} else if (strcmp(word,"gmask") == 0) {
|
||||
if (tree == NULL)
|
||||
error->all(FLERR,"Gmask function in equal-style variable formula");
|
||||
if (narg != 1) error->all(FLERR,"Invalid special function in variable formula");
|
||||
if (narg != 1)
|
||||
error->all(FLERR,"Invalid special function in variable formula");
|
||||
|
||||
int igroup = group->find(arg1);
|
||||
if (igroup == -1)
|
||||
@ -3020,7 +3063,8 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
} else if (strcmp(word,"rmask") == 0) {
|
||||
if (tree == NULL)
|
||||
error->all(FLERR,"Rmask function in equal-style variable formula");
|
||||
if (narg != 1) error->all(FLERR,"Invalid special function in variable formula");
|
||||
if (narg != 1)
|
||||
error->all(FLERR,"Invalid special function in variable formula");
|
||||
|
||||
int iregion = region_function(arg1);
|
||||
|
||||
@ -3033,7 +3077,8 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
} else if (strcmp(word,"grmask") == 0) {
|
||||
if (tree == NULL)
|
||||
error->all(FLERR,"Grmask function in equal-style variable formula");
|
||||
if (narg != 2) error->all(FLERR,"Invalid special function in variable formula");
|
||||
if (narg != 2)
|
||||
error->all(FLERR,"Invalid special function in variable formula");
|
||||
|
||||
int igroup = group->find(arg1);
|
||||
if (igroup == -1)
|
||||
@ -3046,8 +3091,37 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
|
||||
newtree->ivalue2 = iregion;
|
||||
newtree->left = newtree->middle = newtree->right = NULL;
|
||||
treestack[ntreestack++] = newtree;
|
||||
|
||||
// file variable special function
|
||||
|
||||
} else if (strcmp(word,"next") == 0) {
|
||||
if (narg != 1)
|
||||
error->all(FLERR,"Invalid special function in variable formula");
|
||||
|
||||
int ivar = find(arg1);
|
||||
if (ivar == -1)
|
||||
error->all(FLERR,"Variable ID in variable formula does not exist");
|
||||
if (style[ivar] != FILEVAR)
|
||||
error->all(FLERR,"Invalid variable in special function next");
|
||||
|
||||
double value = atof(data[ivar][0]);
|
||||
reader[ivar]->read(data[ivar][0]);
|
||||
|
||||
// save value in tree or on argstack
|
||||
|
||||
if (tree) {
|
||||
Tree *newtree = new Tree();
|
||||
newtree->type = VALUE;
|
||||
newtree->value = value;
|
||||
newtree->left = newtree->middle = newtree->right = NULL;
|
||||
treestack[ntreestack++] = newtree;
|
||||
} else argstack[nargstack++] = value;
|
||||
}
|
||||
|
||||
delete [] arg1;
|
||||
delete [] arg2;
|
||||
delete [] arg3;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -3067,7 +3141,8 @@ void Variable::peratom2global(int flag, char *word,
|
||||
double *argstack, int &nargstack)
|
||||
{
|
||||
if (atom->map_style == 0)
|
||||
error->all(FLERR,"Indexed per-atom vector in variable formula without atom map");
|
||||
error->all(FLERR,
|
||||
"Indexed per-atom vector in variable formula without atom map");
|
||||
|
||||
int index = atom->map(id);
|
||||
|
||||
@ -3210,7 +3285,8 @@ double Variable::numeric(char *str)
|
||||
if (isdigit(str[i])) continue;
|
||||
if (str[i] == '-' || str[i] == '+' || str[i] == '.') continue;
|
||||
if (str[i] == 'e' || str[i] == 'E') continue;
|
||||
error->all(FLERR,"Expected floating point parameter in variable definition");
|
||||
error->all(FLERR,
|
||||
"Expected floating point parameter in variable definition");
|
||||
}
|
||||
|
||||
return atof(str);
|
||||
@ -3296,7 +3372,8 @@ double Variable::evaluate_boolean(char *str)
|
||||
// ----------------
|
||||
|
||||
else if (onechar == '(') {
|
||||
if (expect == OP) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (expect == OP)
|
||||
error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
expect = OP;
|
||||
|
||||
char *contents;
|
||||
@ -3314,7 +3391,8 @@ double Variable::evaluate_boolean(char *str)
|
||||
// ----------------
|
||||
|
||||
} else if (isdigit(onechar) || onechar == '.' || onechar == '-') {
|
||||
if (expect == OP) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (expect == OP)
|
||||
error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
expect = OP;
|
||||
|
||||
// istop = end of number, including scientific notation
|
||||
@ -3383,7 +3461,8 @@ double Variable::evaluate_boolean(char *str)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (expect == ARG) error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
if (expect == ARG)
|
||||
error->all(FLERR,"Invalid Boolean syntax in if command");
|
||||
expect = ARG;
|
||||
|
||||
// evaluate stack as deep as possible while respecting precedence
|
||||
@ -3516,3 +3595,58 @@ unsigned int Variable::data_mask(char *str)
|
||||
|
||||
return datamask;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
class to read variable values from a file, line by line
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
VarReader::VarReader(LAMMPS *lmp, char *file) : Pointers(lmp)
|
||||
{
|
||||
MPI_Comm_rank(world,&me);
|
||||
|
||||
if (me == 0) {
|
||||
fp = fopen(file,"r");
|
||||
if (fp == NULL) {
|
||||
char str[128];
|
||||
sprintf(str,"Cannot open file variable file %s",file);
|
||||
error->one(FLERR,str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
VarReader::~VarReader()
|
||||
{
|
||||
if (me == 0) fclose(fp);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
read next value from file into str
|
||||
strip comments, skip blank lines
|
||||
return 0 if successful, 1 if end-of-file
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int VarReader::read(char *str)
|
||||
{
|
||||
int n;
|
||||
char *ptr;
|
||||
|
||||
if (me == 0) {
|
||||
while (1) {
|
||||
if (fgets(str,MAXLINE,fp) == NULL) n = 0;
|
||||
else n = strlen(str);
|
||||
if (n == 0) break; // end of file
|
||||
str[n-1] = '\0'; // strip newline
|
||||
if (ptr = strchr(str,'#')) *ptr = '\0'; // strip comment
|
||||
if (strtok(str," \t\n\r\f") == NULL) continue; // skip if blank
|
||||
n = strlen(str) + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MPI_Bcast(&n,1,MPI_INT,0,world);
|
||||
if (n == 0) return 1;
|
||||
MPI_Bcast(str,n,MPI_CHAR,0,world);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#ifndef LMP_VARIABLE_H
|
||||
#define LMP_VARIABLE_H
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "pointers.h"
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
@ -45,7 +46,9 @@ class Variable : protected Pointers {
|
||||
int *num; // # of values for each variable
|
||||
int *which; // next available value for each variable
|
||||
int *pad; // 1 = pad loop/uloop variables with 0s, 0 = no pad
|
||||
class VarReader **reader; // variable that reads lines from file
|
||||
char ***data; // str value of each variable's values
|
||||
|
||||
int *eval_in_progress; // flag if evaluation of variable is in progress
|
||||
|
||||
class RanMars *randomequal; // random number generator for equal-style vars
|
||||
@ -90,6 +93,17 @@ class Variable : protected Pointers {
|
||||
void print_tree(Tree *, int);
|
||||
};
|
||||
|
||||
class VarReader : protected Pointers {
|
||||
public:
|
||||
VarReader(class LAMMPS *, char *);
|
||||
~VarReader();
|
||||
int read(char *);
|
||||
|
||||
private:
|
||||
int me;
|
||||
FILE *fp;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -331,7 +331,7 @@ void Verlet::cleanup()
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
clear force on own & ghost atoms
|
||||
setup and clear other arrays as needed
|
||||
clear other arrays as needed
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Verlet::force_clear()
|
||||
|
||||
@ -1 +1 @@
|
||||
#define LAMMPS_VERSION "28 Oct 2012"
|
||||
#define LAMMPS_VERSION "21 Nov 2012"
|
||||
|
||||
Reference in New Issue
Block a user