Merge remote-tracking branch 'github/develop' into distributed-grids
This commit is contained in:
@ -24,6 +24,7 @@ Available topics in mostly chronological order are:
|
||||
- `Use of "override" instead of "virtual"`_
|
||||
- `Simplified and more compact neighbor list requests`_
|
||||
- `Split of fix STORE into fix STORE/GLOBAL and fix STORE/PERATOM`_
|
||||
- `Use Output::get_dump_by_id() instead of Output::find_dump()`_
|
||||
|
||||
----
|
||||
|
||||
@ -382,3 +383,43 @@ New:
|
||||
FixStoreGlobal *fix = dynamic_cast<FixStoreGlobal *>(modify->get_fix_by_id(id_fix));
|
||||
|
||||
This change is **required** or else the code will not compile.
|
||||
|
||||
Use Output::get_dump_by_id() instead of Output::find_dump()
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionchanged:: TBD
|
||||
|
||||
The accessor function to individual dump style instances has been changed
|
||||
from ``Output::find_dump()`` returning the index of the dump instance in
|
||||
the list of dumps to ``Output::get_dump_by_id()`` returning a pointer to
|
||||
the dump directly. Example:
|
||||
|
||||
Old:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
int idump = output->find_dump(arg[iarg+1]);
|
||||
if (idump < 0)
|
||||
error->all(FLERR,"Dump ID in hyper command does not exist");
|
||||
memory->grow(dumplist,ndump+1,"hyper:dumplist");
|
||||
dumplist[ndump++] = idump;
|
||||
|
||||
[...]
|
||||
|
||||
if (dumpflag)
|
||||
for (int idump = 0; idump < ndump; idump++)
|
||||
output->dump[dumplist[idump]]->write();
|
||||
|
||||
New:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
auto idump = output->get_dump_by_id(arg[iarg+1]);
|
||||
if (!idump) error->all(FLERR,"Dump ID {} in hyper command does not exist", arg[iarg+1]);
|
||||
dumplist.emplace_back(idump);
|
||||
|
||||
[...]
|
||||
|
||||
if (dumpflag) for (auto idump : dumplist) idump->write();
|
||||
|
||||
This change is **required** or else the code will not compile.
|
||||
|
||||
@ -33,12 +33,14 @@ Syntax
|
||||
*m* value = one or more mass values
|
||||
|
||||
* zero or more keyword/value pairs may be appended
|
||||
* keyword = *mol*
|
||||
* keyword = *mol* or *kbond*
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
*mol* value = template-ID
|
||||
template-ID = ID of molecule template specified in a separate :doc:`molecule <molecule>` command
|
||||
*kbond* value = force constant
|
||||
force constant = force constant used to apply a restraint force when used during minimization
|
||||
|
||||
Examples
|
||||
""""""""
|
||||
@ -56,7 +58,10 @@ Description
|
||||
|
||||
Apply bond and angle constraints to specified bonds and angles in the
|
||||
simulation by either the SHAKE or RATTLE algorithms. This typically
|
||||
enables a longer timestep.
|
||||
enables a longer timestep. The SHAKE or RATTLE algorithms, however, can
|
||||
*only* be applied during molecular dynamics runs. When this fix is used
|
||||
during a minimization, the constraints are *approximated* by strong
|
||||
harmonic restraints.
|
||||
|
||||
**SHAKE vs RATTLE:**
|
||||
|
||||
@ -90,7 +95,7 @@ The SHAKE algorithm satisfies the first condition, i.e. the sites at
|
||||
time *n+1* will have the desired separations Dij immediately after the
|
||||
coordinates are integrated. If we also enforce the second condition,
|
||||
the velocity components along the bonds will vanish. RATTLE satisfies
|
||||
both conditions. As implemented in LAMMPS, fix rattle uses fix shake
|
||||
both conditions. As implemented in LAMMPS, *fix rattle* uses fix shake
|
||||
for satisfying the coordinate constraints. Therefore the settings and
|
||||
optional keywords are the same for both fixes, and all the information
|
||||
below about SHAKE is also relevant for RATTLE.
|
||||
@ -139,30 +144,47 @@ for.
|
||||
|
||||
.. note::
|
||||
|
||||
This command works by using the current forces on atoms to
|
||||
calculate an additional constraint force which when added will leave
|
||||
the atoms in positions that satisfy the SHAKE constraints (e.g. bond
|
||||
length) after the next time integration step. If you define fixes
|
||||
(e.g. :doc:`fix efield <fix_efield>`) that add additional force to the
|
||||
atoms after fix shake operates, then this fix will not take them into
|
||||
account and the time integration will typically not satisfy the SHAKE
|
||||
constraints. The solution for this is to make sure that fix shake is
|
||||
defined in your input script after any other fixes which add or change
|
||||
forces (to atoms that fix shake operates on).
|
||||
This command works by using the current forces on atoms to calculate
|
||||
an additional constraint force which when added will leave the atoms
|
||||
in positions that satisfy the SHAKE constraints (e.g. bond length)
|
||||
after the next time integration step. If you define fixes
|
||||
(e.g. :doc:`fix efield <fix_efield>`) that add additional force to
|
||||
the atoms after *fix shake* operates, then this fix will not take them
|
||||
into account and the time integration will typically not satisfy the
|
||||
SHAKE constraints. The solution for this is to make sure that fix
|
||||
shake is defined in your input script after any other fixes which add
|
||||
or change forces (to atoms that *fix shake* operates on).
|
||||
|
||||
----------
|
||||
|
||||
The *mol* keyword should be used when other commands, such as :doc:`fix deposit <fix_deposit>` or :doc:`fix pour <fix_pour>`, add molecules
|
||||
The *mol* keyword should be used when other commands, such as :doc:`fix
|
||||
deposit <fix_deposit>` or :doc:`fix pour <fix_pour>`, add molecules
|
||||
on-the-fly during a simulation, and you wish to constrain the new
|
||||
molecules via SHAKE. You specify a *template-ID* previously defined
|
||||
using the :doc:`molecule <molecule>` command, which reads a file that
|
||||
defines the molecule. You must use the same *template-ID* that the
|
||||
command adding molecules uses. The coordinates, atom types, special
|
||||
bond restrictions, and SHAKE info can be specified in the molecule
|
||||
file. See the :doc:`molecule <molecule>` command for details. The only
|
||||
bond restrictions, and SHAKE info can be specified in the molecule file.
|
||||
See the :doc:`molecule <molecule>` command for details. The only
|
||||
settings required to be in this file (by this command) are the SHAKE
|
||||
info of atoms in the molecule.
|
||||
|
||||
The *kbond* keyword sets the restraint force constant when *fix shake*
|
||||
or fix rattle are used during minimization. In that case the constraint
|
||||
algorithms are *not* applied and restraint forces are used instead to
|
||||
maintain the geometries similar to the constraints. How well the
|
||||
geometries are maintained and how quickly a minimization converges,
|
||||
depends largely on the force constant *kbond*: larger values will reduce
|
||||
the deviation from the desired geometry, but can also lead to slower
|
||||
convergence of the minimization or lead to instabilities depending on
|
||||
the minimization algorithm requiring to reduce the value of
|
||||
:doc:`timestep <timestep>`. Even though the restraints will not
|
||||
preserve the bond lengths and angles as closely as the constraints
|
||||
during the MD, they are generally close enough so that the constraints
|
||||
will be fulfilled to the desired accuracy within a few MD steps
|
||||
following the minimization. The default value for *kbond* depends on the
|
||||
:doc:`units <units>` setting and is 1.0e6*k_B.
|
||||
|
||||
----------
|
||||
|
||||
.. include:: accel_styles.rst
|
||||
@ -177,10 +199,10 @@ LAMMPS closely follows (:ref:`Andersen (1983) <Andersen3>`).
|
||||
|
||||
.. note::
|
||||
|
||||
The fix rattle command modifies forces and velocities and thus
|
||||
The *fix rattle* command modifies forces and velocities and thus
|
||||
should be defined after all other integration fixes in your input
|
||||
script. If you define other fixes that modify velocities or forces
|
||||
after fix rattle operates, then fix rattle will not take them into
|
||||
after *fix rattle* operates, then *fix rattle* will not take them into
|
||||
account and the overall time integration will typically not satisfy
|
||||
the RATTLE constraints. You can check whether the constraints work
|
||||
correctly by setting the value of RATTLE_DEBUG in src/fix_rattle.cpp
|
||||
@ -194,19 +216,32 @@ Restart, fix_modify, output, run start/stop, minimize info
|
||||
No information about these fixes is written to :doc:`binary restart
|
||||
files <restart>`.
|
||||
|
||||
The :doc:`fix_modify <fix_modify>` *virial* option is supported by
|
||||
these fixes to add the contribution due to the added forces on atoms
|
||||
to both the global pressure and per-atom stress of the system via the
|
||||
:doc:`compute pressure <compute_pressure>` and :doc:`compute
|
||||
stress/atom <compute_stress_atom>` commands. The former can be
|
||||
accessed by :doc:`thermodynamic output <thermo_style>`. The default
|
||||
setting for this fix is :doc:`fix_modify virial yes <fix_modify>`.
|
||||
Both fix *shake* and fix *rattle* behave differently during a minimization
|
||||
in comparison to a molecular dynamics run:
|
||||
|
||||
- When used during a minimization, the SHAKE or RATTLE constraint
|
||||
algorithms themselves are **not** applied. Instead the constraints
|
||||
are replaced by harmonic restraint forces. The energy and virial
|
||||
contributions due to the restraint forces are tallied into global and
|
||||
per-atom accumulators. The total restraint energy is also accessible
|
||||
as a global scalar property of the fix.
|
||||
|
||||
- During molecular dynamics runs, however, the fixes do apply the
|
||||
requested SHAKE or RATTLE constraint algorithms.
|
||||
|
||||
The :doc:`fix_modify <fix_modify>` *virial* option is supported by
|
||||
these fixes to add the contribution due to the added constraint forces
|
||||
on atoms to both the global pressure and per-atom stress of the system
|
||||
via the :doc:`compute pressure <compute_pressure>` and :doc:`compute
|
||||
stress/atom <compute_stress_atom>` commands. The former can be
|
||||
accessed by :doc:`thermodynamic output <thermo_style>`.
|
||||
|
||||
The default setting for this fix is :doc:`fix_modify virial yes
|
||||
<fix_modify>`. No global or per-atom quantities are stored by these
|
||||
fixes for access by various :doc:`output commands <Howto_output>` during
|
||||
an MD run. No parameter of these fixes can be used with the
|
||||
*start/stop* keywords of the :doc:`run <run>` command.
|
||||
|
||||
No global or per-atom quantities are stored by these fixes for access
|
||||
by various :doc:`output commands <Howto_output>`. No parameter of
|
||||
these fixes can be used with the *start/stop* keywords of the
|
||||
:doc:`run <run>` command. These fixes are not invoked during
|
||||
:doc:`energy minimization <minimize>`.
|
||||
|
||||
Restrictions
|
||||
""""""""""""
|
||||
@ -224,21 +259,27 @@ which can lead to poor energy conservation. You can test for this in
|
||||
your system by running a constant NVE simulation with a particular set
|
||||
of SHAKE parameters and monitoring the energy versus time.
|
||||
|
||||
SHAKE or RATTLE should not be used to constrain an angle at 180
|
||||
degrees (e.g. linear CO2 molecule). This causes numeric difficulties.
|
||||
You can use :doc:`fix rigid or fix rigid/small <fix_rigid>` instead to
|
||||
make a linear molecule rigid.
|
||||
SHAKE or RATTLE should not be used to constrain an angle at 180 degrees
|
||||
(e.g. a linear CO2 molecule). This causes a divergence when solving the
|
||||
constraint equations numerically. You can use :doc:`fix rigid or fix
|
||||
rigid/small <fix_rigid>` instead to make a linear molecule rigid.
|
||||
|
||||
When used during minimization choosing a too large value of the *kbond*
|
||||
can make minimization very inefficient and also cause stability problems
|
||||
with some minimization algorithms. Sometimes those can be avoided by
|
||||
reducing the :doc:`timestep <timestep>`.
|
||||
|
||||
Related commands
|
||||
""""""""""""""""
|
||||
|
||||
none
|
||||
`fix rigid <fix_rigid>`, `fix ehex <fix_ehex>`,
|
||||
`fix nve/manifold/rattle <fix_nve_manifold_rattle>`
|
||||
|
||||
|
||||
Default
|
||||
"""""""
|
||||
|
||||
none
|
||||
kbond = 1.0e9*k_B
|
||||
|
||||
----------
|
||||
|
||||
|
||||
@ -32,30 +32,51 @@ Description
|
||||
Perform an energy minimization of the system, by iteratively adjusting
|
||||
atom coordinates. Iterations are terminated when one of the stopping
|
||||
criteria is satisfied. At that point the configuration will hopefully
|
||||
be in local potential energy minimum. More precisely, the
|
||||
be in a local potential energy minimum. More precisely, the
|
||||
configuration should approximate a critical point for the objective
|
||||
function (see below), which may or may not be a local minimum.
|
||||
|
||||
The minimization algorithm used is set by the
|
||||
:doc:`min_style <min_style>` command. Other options are set by the
|
||||
:doc:`min_modify <min_modify>` command. Minimize commands can be
|
||||
interspersed with :doc:`run <run>` commands to alternate between
|
||||
relaxation and dynamics. The minimizers bound the distance atoms move
|
||||
in one iteration, so that you can relax systems with highly overlapped
|
||||
atoms (large energies and forces) by pushing the atoms off of each
|
||||
other.
|
||||
The minimization algorithm used is set by the :doc:`min_style
|
||||
<min_style>` command. Other options are set by the :doc:`min_modify
|
||||
<min_modify>` command. Minimize commands can be interspersed with
|
||||
:doc:`run <run>` commands to alternate between relaxation and dynamics.
|
||||
The minimizers bound the distance atoms may move in one iteration, so
|
||||
that you can relax systems with highly overlapped atoms (large energies
|
||||
and forces) by pushing the atoms off of each other.
|
||||
|
||||
Alternate means of relaxing a system are to run dynamics with a small
|
||||
or :doc:`limited timestep <fix_nve_limit>`. Or dynamics can be run
|
||||
using :doc:`fix viscous <fix_viscous>` to impose a damping force that
|
||||
slowly drains all kinetic energy from the system. The :doc:`pair_style soft <pair_soft>` potential can be used to un-overlap atoms while
|
||||
running dynamics.
|
||||
un-overlap atoms while running dynamics.
|
||||
.. admonition:: Neighbor list update settings
|
||||
:class: note
|
||||
|
||||
The distance that atoms can move during individual minimization steps
|
||||
can be quite large, especially at the beginning of a minimization.
|
||||
Thus `neighbor list settings <neigh_modify>` of *every = 1* and
|
||||
*delay = 0* are **required**. This may be combined with either
|
||||
*check = no* (always update the neighbor list) or *check = yes* (only
|
||||
update the neighbor list if at least one atom has moved more than
|
||||
half the `neighbor list skin <neighbor>` distance since the last
|
||||
reneighboring). Using *check = yes* is recommended since it avoids
|
||||
unneeded reneighboring steps when the system is closer to the minimum
|
||||
and thus atoms move only small distances. Using *check = no* may
|
||||
be required for debugging or when coupling LAMMPS with external
|
||||
codes that require a predictable sequence of neighbor list updates.
|
||||
|
||||
If the settings are **not** *every = 1* and *delay = 0*, LAMMPS
|
||||
will temporarily apply a `neigh_modify every 1 delay 0 check yes
|
||||
<neigh_modify>` setting during the minimization and restore the
|
||||
original setting at the end of the minimization. A corresponding
|
||||
message will be printed to the screen and log file, if this happens.
|
||||
|
||||
Alternate means of relaxing a system are to run dynamics with a small or
|
||||
:doc:`limited timestep <fix_nve_limit>`. Or dynamics can be run using
|
||||
:doc:`fix viscous <fix_viscous>` to impose a damping force that slowly
|
||||
drains all kinetic energy from the system. The :doc:`pair_style soft
|
||||
<pair_soft>` potential can be used to un-overlap atoms while running
|
||||
dynamics.
|
||||
|
||||
Note that you can minimize some atoms in the system while holding the
|
||||
coordinates of other atoms fixed by applying :doc:`fix setforce
|
||||
<fix_setforce>` to the other atoms. See a fuller discussion of using
|
||||
fixes while minimizing below.
|
||||
coordinates of other atoms fixed by applying :doc:`fix setforce 0.0 0.0
|
||||
0.0 <fix_setforce>` to the other atoms. See a more detailed discussion
|
||||
of :ref:`using fixes while minimizing below <fix_minimize>`.
|
||||
|
||||
The :doc:`minimization styles <min_style>` *cg*, *sd*, and *hftn*
|
||||
involves an outer iteration loop which sets the search direction along
|
||||
@ -74,10 +95,11 @@ they require a :doc:`timestep <timestep>` be defined.
|
||||
|
||||
.. note::
|
||||
|
||||
The damped dynamic minimizers use whatever timestep you have
|
||||
defined via the :doc:`timestep <timestep>` command. Often they
|
||||
will converge more quickly if you use a timestep about 10x larger
|
||||
than you would normally use for dynamics simulations.
|
||||
The damped dynamic minimizer algorithms will use the timestep you
|
||||
have defined via the :doc:`timestep <timestep>` command or its
|
||||
default value. Often they will converge more quickly if you use a
|
||||
timestep about 10x larger than you would normally use for regular
|
||||
molecular dynamics simulations.
|
||||
|
||||
----------
|
||||
|
||||
@ -210,34 +232,42 @@ The iterations and force evaluation values are what is checked by the
|
||||
|
||||
.. note::
|
||||
|
||||
There are several force fields in LAMMPS which have
|
||||
discontinuities or other approximations which may prevent you from
|
||||
performing an energy minimization to high tolerances. For example,
|
||||
you should use a :doc:`pair style <pair_style>` that goes to 0.0 at the
|
||||
cutoff distance when performing minimization (even if you later change
|
||||
it when running dynamics). If you do not do this, the total energy of
|
||||
There are several force fields in LAMMPS which have discontinuities
|
||||
or other approximations which may prevent you from performing an
|
||||
energy minimization to tight tolerances. For example, you should use
|
||||
a :doc:`pair style <pair_style>` that goes to 0.0 at the cutoff
|
||||
distance when performing minimization (even if you later change it
|
||||
when running dynamics). If you do not do this, the total energy of
|
||||
the system will have discontinuities when the relative distance
|
||||
between any pair of atoms changes from cutoff+epsilon to
|
||||
cutoff-epsilon and the minimizer may behave poorly. Some of the
|
||||
many-body potentials use splines and other internal cutoffs that
|
||||
inherently have this problem. The :doc:`long-range Coulombic styles <kspace_style>` (PPPM, Ewald) are approximate to within the
|
||||
user-specified tolerance, which means their energy and forces may not
|
||||
agree to a higher precision than the Kspace-specified tolerance. In
|
||||
all these cases, the minimizer may give up and stop before finding a
|
||||
minimum to the specified energy or force tolerance.
|
||||
between any pair of atoms changes from cutoff *plus* epsilon to
|
||||
cutoff *minus* epsilon and the minimizer may thus behave poorly.
|
||||
Some of the many-body potentials use splines and other internal
|
||||
cutoffs that inherently have this problem. The :doc:`long-range
|
||||
Coulombic styles <kspace_style>` (PPPM, Ewald) are approximate to
|
||||
within the user-specified tolerance, which means their energy and
|
||||
forces may not agree to a higher precision than the Kspace-specified
|
||||
tolerance. This agreement is further reduced when using tabulation
|
||||
to speed up the computation of the real-space part of the Coulomb
|
||||
interactions, which is enabled by default. In all these cases, the
|
||||
minimizer may give up and stop before finding a minimum to the
|
||||
specified energy or force tolerance.
|
||||
|
||||
Note that a cutoff Lennard-Jones potential (and others) can be shifted
|
||||
so that its energy is 0.0 at the cutoff via the
|
||||
:doc:`pair_modify <pair_modify>` command. See the doc pages for
|
||||
individual :doc:`pair styles <pair_style>` for details. Note that
|
||||
Coulombic potentials always have a cutoff, unless versions with a
|
||||
long-range component are used (e.g. :doc:`pair_style lj/cut/coul/long <pair_lj_cut_coul>`). The CHARMM potentials go to 0.0 at
|
||||
the cutoff (e.g. :doc:`pair_style lj/charmm/coul/charmm <pair_charmm>`),
|
||||
as do the GROMACS potentials (e.g. :doc:`pair_style lj/gromacs <pair_gromacs>`).
|
||||
so that its energy is 0.0 at the cutoff via the :doc:`pair_modify
|
||||
<pair_modify>` command. See the doc pages for individual :doc:`pair
|
||||
styles <pair_style>` for details. Note that most Coulombic potentials
|
||||
have a cutoff, unless versions with a long-range component are used
|
||||
(e.g. :doc:`pair_style lj/cut/coul/long <pair_lj_cut_coul>`) or some
|
||||
other damping/smoothing schemes are used. The CHARMM potentials go to
|
||||
0.0 at the cutoff (e.g. :doc:`pair_style lj/charmm/coul/charmm
|
||||
<pair_charmm>`), as do the GROMACS potentials (e.g. :doc:`pair_style
|
||||
lj/gromacs <pair_gromacs>`).
|
||||
|
||||
If a soft potential (:doc:`pair_style soft <pair_soft>`) is used the
|
||||
Astop value is used for the prefactor (no time dependence).
|
||||
|
||||
.. _fix_minimize:
|
||||
|
||||
The :doc:`fix box/relax <fix_box_relax>` command can be used to apply an
|
||||
external pressure to the simulation box and allow it to shrink/expand
|
||||
during the minimization.
|
||||
|
||||
@ -13,6 +13,7 @@ Accelrys
|
||||
acceptor
|
||||
Acceptor
|
||||
acceptors
|
||||
accessor
|
||||
accomx
|
||||
accomy
|
||||
accomz
|
||||
@ -1623,6 +1624,7 @@ kb
|
||||
kB
|
||||
kbit
|
||||
kbits
|
||||
kbond
|
||||
kcal
|
||||
kcl
|
||||
Kd
|
||||
|
||||
@ -53,8 +53,7 @@ enum{GORDON1,GORDON2};
|
||||
void PairAmoeba::induce()
|
||||
{
|
||||
bool done;
|
||||
int i,j,m,itype;
|
||||
int iter,maxiter;
|
||||
int i,j,m,itype,iter;
|
||||
double polmin;
|
||||
double eps,epsold;
|
||||
double epsd,epsp;
|
||||
@ -159,7 +158,6 @@ void PairAmoeba::induce()
|
||||
|
||||
if (poltyp == MUTUAL) {
|
||||
done = false;
|
||||
maxiter = 100;
|
||||
iter = 0;
|
||||
polmin = 0.00000001;
|
||||
eps = 100.0;
|
||||
|
||||
@ -37,7 +37,7 @@ using namespace LAMMPS_NS;
|
||||
using namespace MathConst;
|
||||
|
||||
static const char cite_compute_saed_c[] =
|
||||
"compute_saed command: doi:10.1088/0965-0393/21/5/055020\n\n"
|
||||
"compute saed command: doi:10.1088/0965-0393/21/5/055020\n\n"
|
||||
"@Article{Coleman13,\n"
|
||||
" author = {S. P. Coleman and D. E. Spearot and L. Capolungo},\n"
|
||||
" title = {Virtual Diffraction Analysis of {Ni} [010] Symmetric Tilt Grain Boundaries},\n"
|
||||
|
||||
@ -38,7 +38,7 @@ using namespace LAMMPS_NS;
|
||||
using namespace MathConst;
|
||||
|
||||
static const char cite_compute_xrd_c[] =
|
||||
"compute_xrd command: doi:10.1088/0965-0393/21/5/055020\n\n"
|
||||
"compute xrd command: doi:10.1088/0965-0393/21/5/055020\n\n"
|
||||
"@Article{Coleman13,\n"
|
||||
" author = {S. P. Coleman and D. E. Spearot and L. Capolungo},\n"
|
||||
" title = {Virtual Diffraction Analysis of {Ni} [010] Symmetric Tilt Grain Boundaries},\n"
|
||||
|
||||
@ -73,7 +73,7 @@ DumpH5MD::DumpH5MD(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg)
|
||||
format_default = nullptr;
|
||||
flush_flag = 0;
|
||||
unwrap_flag = 0;
|
||||
datafile_from_dump = -1;
|
||||
other_dump = nullptr;
|
||||
author_name = nullptr;
|
||||
|
||||
every_dump = utils::inumeric(FLERR,arg[3],false,lmp);
|
||||
@ -141,11 +141,8 @@ DumpH5MD::DumpH5MD(LAMMPS *lmp, int narg, char **arg) : Dump(lmp, narg, arg)
|
||||
}
|
||||
if (box_is_set||create_group_is_set)
|
||||
error->all(FLERR, "Cannot set file_from in dump h5md after box or create_group");
|
||||
int idump;
|
||||
for (idump = 0; idump < output->ndump; idump++)
|
||||
if (strcmp(arg[iarg+1],output->dump[idump]->id) == 0) break;
|
||||
if (idump == output->ndump) error->all(FLERR,"Cound not find dump_modify ID");
|
||||
datafile_from_dump = idump;
|
||||
other_dump = dynamic_cast<DumpH5MD *>(output->get_dump_by_id(arg[iarg+1]));
|
||||
if (!other_dump) error->all(FLERR,"Cound not find dump_modify H5MD dump ID {}", arg[iarg+1]);
|
||||
do_box=false;
|
||||
create_group=false;
|
||||
iarg+=2;
|
||||
@ -262,7 +259,7 @@ void DumpH5MD::openfile()
|
||||
}
|
||||
|
||||
if (me == 0) {
|
||||
if (datafile_from_dump<0) {
|
||||
if (!other_dump) {
|
||||
if (author_name==nullptr) {
|
||||
datafile = h5md_create_file(filename, "N/A", nullptr, "lammps", LAMMPS_VERSION);
|
||||
} else {
|
||||
@ -296,8 +293,6 @@ void DumpH5MD::openfile()
|
||||
h5md_write_string_attribute(particles_data.group, "charge", "type", "effective");
|
||||
}
|
||||
} else {
|
||||
DumpH5MD* other_dump;
|
||||
other_dump=(DumpH5MD*)output->dump[datafile_from_dump];
|
||||
datafile = other_dump->datafile;
|
||||
group_name_length = strlen(group->names[igroup]);
|
||||
group_name = new char[group_name_length];
|
||||
|
||||
@ -35,9 +35,9 @@ class DumpH5MD : public Dump {
|
||||
int natoms, ntotal;
|
||||
int unwrap_flag; // 1 if atom coords are unwrapped, 0 if no
|
||||
h5md_file datafile;
|
||||
int datafile_from_dump;
|
||||
h5md_particles_group particles_data;
|
||||
char *author_name;
|
||||
DumpH5MD *other_dump;
|
||||
|
||||
bool do_box;
|
||||
bool create_group;
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
static constexpr const char *const cite_openkim =
|
||||
"OpenKIM: https://doi.org/10.1007/s11837-011-0102-6\n\n"
|
||||
"OpenKIM Project: doi:10.1007/s11837-011-0102-6\n\n"
|
||||
"@Article{tadmor:elliott:2011,\n"
|
||||
" author = {E. B. Tadmor and R. S. Elliott and J. P. Sethna and R. E. Miller "
|
||||
"and C. A. Becker},\n"
|
||||
@ -85,7 +85,7 @@ static constexpr const char *const cite_openkim =
|
||||
"}\n\n";
|
||||
|
||||
static constexpr const char *const cite_openkim_query =
|
||||
"OpenKIM query: https://doi.org/10.1063/5.0014267\n\n"
|
||||
"OpenKIM query: doi:10.1063/5.0014267\n\n"
|
||||
"@Article{karls:bierbaum:2020,\n"
|
||||
" author = {D. S. Karls and M. Bierbaum and A. A. Alemi and R. S. Elliott "
|
||||
"and J. P. Sethna and E. B. Tadmor},\n"
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
static constexpr const char *const cite_openkim =
|
||||
"OpenKIM: https://doi.org/10.1007/s11837-011-0102-6\n\n"
|
||||
"OpenKIM Project: doi:10.1007/s11837-011-0102-6\n\n"
|
||||
"@Article{tadmor:elliott:2011,\n"
|
||||
" author = {E. B. Tadmor and R. S. Elliott and J. P. Sethna and R. E. Miller "
|
||||
"and C. A. Becker},\n"
|
||||
|
||||
@ -125,19 +125,19 @@ void CommKokkos::init()
|
||||
if (force->pair && (force->pair->execution_space == Host))
|
||||
check_reverse += force->pair->comm_reverse;
|
||||
|
||||
for (int i = 0; i < modify->nfix; i++) {
|
||||
check_forward += modify->fix[i]->comm_forward;
|
||||
check_reverse += modify->fix[i]->comm_reverse;
|
||||
for (const auto &fix : modify->get_fix_list()) {
|
||||
check_forward += fix->comm_forward;
|
||||
check_reverse += fix->comm_reverse;
|
||||
}
|
||||
|
||||
for (int i = 0; i < modify->ncompute; i++) {
|
||||
check_forward += modify->compute[i]->comm_forward;
|
||||
check_reverse += modify->compute[i]->comm_reverse;
|
||||
for (const auto &compute : modify->get_compute_list()) {
|
||||
check_forward += compute->comm_forward;
|
||||
check_reverse += compute->comm_reverse;
|
||||
}
|
||||
|
||||
for (int i = 0; i < output->ndump; i++) {
|
||||
check_forward += output->dump[i]->comm_forward;
|
||||
check_reverse += output->dump[i]->comm_reverse;
|
||||
for (const auto &dump : output->get_dump_list()) {
|
||||
check_forward += dump->comm_forward;
|
||||
check_reverse += dump->comm_reverse;
|
||||
}
|
||||
|
||||
if (force->newton == 0) check_reverse = 0;
|
||||
|
||||
@ -12,12 +12,8 @@
|
||||
See the README file in the top-level LAMMPS directory.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include <mpi.h>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include "fix_shake_kokkos.h"
|
||||
|
||||
#include "fix_rattle.h"
|
||||
#include "atom_kokkos.h"
|
||||
#include "atom_vec.h"
|
||||
@ -38,6 +34,9 @@
|
||||
#include "kokkos.h"
|
||||
#include "atom_masks.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace FixConst;
|
||||
using namespace MathConst;
|
||||
@ -181,6 +180,16 @@ void FixShakeKokkos<DeviceType>::init()
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
run setup for minimization.
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
template<class DeviceType>
|
||||
void FixShakeKokkos<DeviceType>::min_setup(int /*vflag*/)
|
||||
{
|
||||
error->all(FLERR, "Cannot yet use fix {} during minimization with Kokkos", style);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
build list of SHAKE clusters to constrain
|
||||
if one or more atoms in cluster are on this proc,
|
||||
@ -193,6 +202,7 @@ void FixShakeKokkos<DeviceType>::pre_neighbor()
|
||||
// local copies of atom quantities
|
||||
// used by SHAKE until next re-neighboring
|
||||
|
||||
ebond = 0.0;
|
||||
x = atom->x;
|
||||
v = atom->v;
|
||||
f = atom->f;
|
||||
@ -292,7 +302,7 @@ void FixShakeKokkos<DeviceType>::pre_neighbor()
|
||||
|
||||
if (h_error_flag() == 1) {
|
||||
error->one(FLERR,"Shake atoms missing on proc "
|
||||
"{} at step {}",me,update->ntimestep);
|
||||
"{} at step {}",comm->me,update->ntimestep);
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,6 +313,7 @@ void FixShakeKokkos<DeviceType>::pre_neighbor()
|
||||
template<class DeviceType>
|
||||
void FixShakeKokkos<DeviceType>::post_force(int vflag)
|
||||
{
|
||||
ebond = 0.0;
|
||||
copymode = 1;
|
||||
|
||||
d_x = atomKK->k_x.view<DeviceType>();
|
||||
@ -341,7 +352,7 @@ void FixShakeKokkos<DeviceType>::post_force(int vflag)
|
||||
// communicate results if necessary
|
||||
|
||||
unconstrained_update();
|
||||
if (nprocs > 1) comm->forward_comm(this);
|
||||
if (comm->nprocs > 1) comm->forward_comm(this);
|
||||
k_xshake.sync<DeviceType>();
|
||||
|
||||
// virial setup
|
||||
@ -1702,7 +1713,7 @@ void FixShakeKokkos<DeviceType>::correct_coordinates(int vflag) {
|
||||
|
||||
double **xtmp = xshake;
|
||||
xshake = x;
|
||||
if (nprocs > 1) {
|
||||
if (comm->nprocs > 1) {
|
||||
forward_comm_device = 0;
|
||||
comm->forward_comm(this);
|
||||
forward_comm_device = 1;
|
||||
|
||||
@ -51,6 +51,7 @@ class FixShakeKokkos : public FixShake, public KokkosBase {
|
||||
FixShakeKokkos(class LAMMPS *, int, char **);
|
||||
~FixShakeKokkos() override;
|
||||
void init() override;
|
||||
void min_setup(int) override;
|
||||
void pre_neighbor() override;
|
||||
void post_force(int) override;
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ class PairSRPREACT : public PairSRP {
|
||||
private:
|
||||
char *idbreak;
|
||||
char *idcreate;
|
||||
bool bond_create, bond_break;
|
||||
bool bond_break, bond_create;
|
||||
};
|
||||
} // namespace LAMMPS_NS
|
||||
#endif
|
||||
|
||||
@ -231,10 +231,12 @@ void DumpCustomMPIIO::init_style()
|
||||
// lo priority = line, medium priority = int/float, hi priority = column
|
||||
|
||||
auto words = utils::split_words(format);
|
||||
if ((int) words.size() < nfield) error->all(FLERR, "Dump_modify format line is too short");
|
||||
if ((int) words.size() < nfield)
|
||||
error->all(FLERR, "Dump_modify format line is too short: {}", format);
|
||||
|
||||
int i = 0;
|
||||
for (const auto &word : words) {
|
||||
if (i >= nfield) break;
|
||||
delete[] vformat[i];
|
||||
|
||||
if (format_column_user[i])
|
||||
|
||||
@ -827,12 +827,11 @@ void FixReaxFFSpecies::WritePos(int Nmole, int Nspec)
|
||||
|
||||
void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec)
|
||||
{
|
||||
int i, j, m, n, k, itype, cid;
|
||||
int i, j, m, n, itype, cid;
|
||||
int ndel, ndelone, count, count_tmp;
|
||||
int *Nameall;
|
||||
int *mask = atom->mask;
|
||||
double localmass, totalmass;
|
||||
double **spec_atom = f_SPECBOND->array_atom;
|
||||
std::string species_str;
|
||||
|
||||
AtomVec *avec = atom->avec;
|
||||
|
||||
@ -39,7 +39,7 @@ enum{NOHYPER,GLOBAL,LOCAL};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
Hyper::Hyper(LAMMPS *lmp) : Command(lmp), dumplist(nullptr) {}
|
||||
Hyper::Hyper(LAMMPS *_lmp) : Command(_lmp) {}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
perform hyperdynamics simulation
|
||||
@ -177,9 +177,7 @@ void Hyper::command(int narg, char **arg)
|
||||
|
||||
fix_event->store_state_quench();
|
||||
quench(1);
|
||||
if (dumpflag)
|
||||
for (int idump = 0; idump < ndump; idump++)
|
||||
output->dump[dumplist[idump]]->write();
|
||||
if (dumpflag) for (auto idump : dumplist) idump->write();
|
||||
fix_event->store_event();
|
||||
if (hyperenable) fix_hyper->build_bond_list(0);
|
||||
fix_event->restore_state_quench();
|
||||
@ -208,9 +206,7 @@ void Hyper::command(int narg, char **arg)
|
||||
nevent++;
|
||||
nevent_atoms += ecount;
|
||||
|
||||
if (dumpflag)
|
||||
for (int idump = 0; idump < ndump; idump++)
|
||||
output->dump[dumplist[idump]]->write();
|
||||
if (dumpflag) for (auto idump : dumplist) idump->write();
|
||||
fix_event->store_event();
|
||||
if (hyperenable) fix_hyper->build_bond_list(ecount);
|
||||
|
||||
@ -345,7 +341,6 @@ void Hyper::command(int narg, char **arg)
|
||||
|
||||
delete [] id_fix;
|
||||
delete [] id_compute;
|
||||
memory->destroy(dumplist);
|
||||
delete finish;
|
||||
modify->delete_fix("hyper_event");
|
||||
|
||||
@ -444,8 +439,6 @@ void Hyper::options(int narg, char **arg)
|
||||
maxiter = 40;
|
||||
maxeval = 50;
|
||||
dumpflag = 0;
|
||||
ndump = 0;
|
||||
dumplist = nullptr;
|
||||
rebond = 0;
|
||||
|
||||
int iarg = 0;
|
||||
@ -462,11 +455,9 @@ void Hyper::options(int narg, char **arg)
|
||||
} else if (strcmp(arg[iarg],"dump") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal hyper command");
|
||||
dumpflag = 1;
|
||||
int idump = output->find_dump(arg[iarg+1]);
|
||||
if (idump < 0)
|
||||
error->all(FLERR,"Dump ID in hyper command does not exist");
|
||||
memory->grow(dumplist,ndump+1,"hyper:dumplist");
|
||||
dumplist[ndump++] = idump;
|
||||
auto idump = output->get_dump_by_id(arg[iarg+1]);
|
||||
if (!idump) error->all(FLERR,"Dump ID {} in hyper command does not exist", arg[iarg+1]);
|
||||
dumplist.emplace_back(idump);
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"rebond") == 0) {
|
||||
|
||||
@ -35,8 +35,8 @@ class Hyper : public Command {
|
||||
int t_event;
|
||||
double etol, ftol;
|
||||
int maxiter, maxeval;
|
||||
int stepmode, dumpflag, ndump, rebond;
|
||||
int *dumplist;
|
||||
int stepmode, dumpflag, rebond;
|
||||
std::vector<class Dump *> dumplist;
|
||||
|
||||
int neigh_every, neigh_delay, neigh_dist_check;
|
||||
int quench_reneighbor;
|
||||
|
||||
@ -81,7 +81,7 @@ FixRattle::~FixRattle()
|
||||
{
|
||||
memory->destroy(vp);
|
||||
|
||||
if (RATTLE_DEBUG) {
|
||||
#if RATTLE_DEBUG
|
||||
|
||||
// communicate maximum distance error
|
||||
|
||||
@ -91,13 +91,11 @@ FixRattle::~FixRattle()
|
||||
MPI_Reduce(&derr_max, &global_derr_max, 1 , MPI_DOUBLE, MPI_MAX, 0, world);
|
||||
MPI_Reduce(&verr_max, &global_verr_max, 1 , MPI_DOUBLE, MPI_MAX, 0, world);
|
||||
|
||||
MPI_Comm_rank (world, &npid); // Find out process rank
|
||||
|
||||
if (npid == 0 && screen) {
|
||||
if (comm->me == 0 && screen) {
|
||||
fprintf(screen, "RATTLE: Maximum overall relative position error ( (r_ij-d_ij)/d_ij ): %.10g\n", global_derr_max);
|
||||
fprintf(screen, "RATTLE: Maximum overall absolute velocity error (r_ij * v_ij): %.10g\n", global_verr_max);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -110,7 +108,10 @@ int FixRattle::setmask()
|
||||
mask |= POST_FORCE_RESPA;
|
||||
mask |= FINAL_INTEGRATE;
|
||||
mask |= FINAL_INTEGRATE_RESPA;
|
||||
if (RATTLE_DEBUG) mask |= END_OF_STEP;
|
||||
mask |= MIN_POST_FORCE;
|
||||
#if RATTLE_DEBUG
|
||||
mask |= END_OF_STEP;
|
||||
#endif
|
||||
return mask;
|
||||
}
|
||||
|
||||
@ -156,7 +157,7 @@ void FixRattle::post_force(int vflag)
|
||||
|
||||
// communicate the unconstrained velocities
|
||||
|
||||
if (nprocs > 1) {
|
||||
if (comm->nprocs > 1) {
|
||||
comm_mode = VP;
|
||||
comm->forward_comm(this);
|
||||
}
|
||||
@ -188,7 +189,7 @@ void FixRattle::post_force_respa(int vflag, int ilevel, int /*iloop*/)
|
||||
|
||||
// communicate the unconstrained velocities
|
||||
|
||||
if (nprocs > 1) {
|
||||
if (comm->nprocs > 1) {
|
||||
comm_mode = VP;
|
||||
comm->forward_comm(this);
|
||||
}
|
||||
@ -718,7 +719,7 @@ void FixRattle::unpack_forward_comm(int n, int first, double *buf)
|
||||
|
||||
void FixRattle::shake_end_of_step(int vflag) {
|
||||
|
||||
if (nprocs > 1) {
|
||||
if (comm->nprocs > 1) {
|
||||
comm_mode = V;
|
||||
comm->forward_comm(this);
|
||||
}
|
||||
@ -738,7 +739,6 @@ void FixRattle::correct_coordinates(int vflag) {
|
||||
FixShake::correct_coordinates(vflag);
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
Remove the velocity component along any bond.
|
||||
------------------------------------------------------------------------- */
|
||||
@ -759,7 +759,7 @@ void FixRattle::correct_velocities() {
|
||||
|
||||
// communicate the unconstrained velocities
|
||||
|
||||
if (nprocs > 1) {
|
||||
if (comm->nprocs > 1) {
|
||||
comm_mode = VP;
|
||||
comm->forward_comm(this);
|
||||
}
|
||||
@ -776,7 +776,6 @@ void FixRattle::correct_velocities() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
DEBUGGING methods
|
||||
The functions below allow you to check whether the
|
||||
@ -788,15 +787,15 @@ void FixRattle::correct_velocities() {
|
||||
|
||||
void FixRattle::end_of_step()
|
||||
{
|
||||
if (nprocs > 1) {
|
||||
if (comm->nprocs > 1) {
|
||||
comm_mode = V;
|
||||
comm->forward_comm(this);
|
||||
}
|
||||
if (!check_constraints(v, RATTLE_TEST_POS, RATTLE_TEST_VEL) && RATTLE_RAISE_ERROR) {
|
||||
#if RATTLE_RAISE_ERROR
|
||||
if (!check_constraints(v, RATTLE_TEST_POS, RATTLE_TEST_VEL))
|
||||
error->one(FLERR, "Rattle failed ");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
@ -812,7 +811,6 @@ bool FixRattle::check_constraints(double **v, bool checkr, bool checkv)
|
||||
else if (shake_flag[m] == 4) ret = check4(v,m,checkr,checkv);
|
||||
else ret = check3angle(v,m,checkr,checkv);
|
||||
i++;
|
||||
if (!RATTLE_RAISE_ERROR) ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -834,14 +832,10 @@ bool FixRattle::check2(double **v, int m, bool checkr, bool checkv)
|
||||
MathExtra::sub3(v[i1],v[i0],v01);
|
||||
|
||||
stat = !(checkr && (fabs(sqrt(MathExtra::dot3(r01,r01)) - bond1) > tol));
|
||||
if (!stat)
|
||||
error->one(FLERR,"Coordinate constraints are not satisfied "
|
||||
"up to desired tolerance ");
|
||||
if (!stat) error->one(FLERR,"Coordinate constraints are not satisfied up to desired tolerance ");
|
||||
|
||||
stat = !(checkv && (fabs(MathExtra::dot3(r01,v01)) > tol));
|
||||
if (!stat)
|
||||
error->one(FLERR,"Velocity constraints are not satisfied "
|
||||
"up to desired tolerance ");
|
||||
if (!stat) error->one(FLERR,"Velocity constraints are not satisfied up to desired tolerance ");
|
||||
return stat;
|
||||
}
|
||||
|
||||
@ -871,15 +865,11 @@ bool FixRattle::check3(double **v, int m, bool checkr, bool checkv)
|
||||
|
||||
stat = !(checkr && (fabs(sqrt(MathExtra::dot3(r01,r01)) - bond1) > tol ||
|
||||
fabs(sqrt(MathExtra::dot3(r02,r02))-bond2) > tol));
|
||||
if (!stat)
|
||||
error->one(FLERR,"Coordinate constraints are not satisfied "
|
||||
"up to desired tolerance ");
|
||||
if (!stat) error->one(FLERR,"Coordinate constraints are not satisfied up to desired tolerance ");
|
||||
|
||||
stat = !(checkv && (fabs(MathExtra::dot3(r01,v01)) > tol ||
|
||||
fabs(MathExtra::dot3(r02,v02)) > tol));
|
||||
if (!stat)
|
||||
error->one(FLERR,"Velocity constraints are not satisfied "
|
||||
"up to desired tolerance ");
|
||||
if (!stat) error->one(FLERR,"Velocity constraints are not satisfied up to desired tolerance ");
|
||||
return stat;
|
||||
}
|
||||
|
||||
@ -914,16 +904,12 @@ bool FixRattle::check4(double **v, int m, bool checkr, bool checkv)
|
||||
stat = !(checkr && (fabs(sqrt(MathExtra::dot3(r01,r01)) - bond1) > tol ||
|
||||
fabs(sqrt(MathExtra::dot3(r02,r02))-bond2) > tol ||
|
||||
fabs(sqrt(MathExtra::dot3(r03,r03))-bond3) > tol));
|
||||
if (!stat)
|
||||
error->one(FLERR,"Coordinate constraints are not satisfied "
|
||||
"up to desired tolerance ");
|
||||
if (!stat) error->one(FLERR,"Coordinate constraints are not satisfied up to desired tolerance ");
|
||||
|
||||
stat = !(checkv && (fabs(MathExtra::dot3(r01,v01)) > tol ||
|
||||
fabs(MathExtra::dot3(r02,v02)) > tol ||
|
||||
fabs(MathExtra::dot3(r03,v03)) > tol));
|
||||
if (!stat)
|
||||
error->one(FLERR,"Velocity constraints are not satisfied "
|
||||
"up to desired tolerance ");
|
||||
if (!stat) error->one(FLERR,"Velocity constraints are not satisfied up to desired tolerance ");
|
||||
return stat;
|
||||
}
|
||||
|
||||
@ -954,25 +940,19 @@ bool FixRattle::check3angle(double **v, int m, bool checkr, bool checkv)
|
||||
MathExtra::sub3(v[i2],v[i0],v02);
|
||||
MathExtra::sub3(v[i2],v[i1],v12);
|
||||
|
||||
|
||||
|
||||
double db1 = fabs(sqrt(MathExtra::dot3(r01,r01)) - bond1);
|
||||
double db2 = fabs(sqrt(MathExtra::dot3(r02,r02))-bond2);
|
||||
double db12 = fabs(sqrt(MathExtra::dot3(r12,r12))-bond12);
|
||||
|
||||
|
||||
stat = !(checkr && (db1 > tol ||
|
||||
db2 > tol ||
|
||||
db12 > tol));
|
||||
stat = !(checkr && (db1 > tol || db2 > tol || db12 > tol));
|
||||
|
||||
if (derr_max < db1/bond1) derr_max = db1/bond1;
|
||||
if (derr_max < db2/bond2) derr_max = db2/bond2;
|
||||
if (derr_max < db12/bond12) derr_max = db12/bond12;
|
||||
|
||||
|
||||
if (!stat && RATTLE_RAISE_ERROR)
|
||||
error->one(FLERR,"Coordinate constraints are not satisfied "
|
||||
"up to desired tolerance ");
|
||||
#if RATTLE_RAISE_ERROR
|
||||
if (!stat) error->one(FLERR,"Coordinate constraints are not satisfied up to desired tolerance ");
|
||||
#endif
|
||||
|
||||
double dv1 = fabs(MathExtra::dot3(r01,v01));
|
||||
double dv2 = fabs(MathExtra::dot3(r02,v02));
|
||||
@ -982,16 +962,10 @@ bool FixRattle::check3angle(double **v, int m, bool checkr, bool checkv)
|
||||
if (verr_max < dv2) verr_max = dv2;
|
||||
if (verr_max < dv12) verr_max = dv12;
|
||||
|
||||
stat = !(checkv && (dv1 > tol || dv2 > tol || dv12> tol));
|
||||
|
||||
stat = !(checkv && (dv1 > tol ||
|
||||
dv2 > tol ||
|
||||
dv12> tol));
|
||||
|
||||
|
||||
if (!stat && RATTLE_RAISE_ERROR)
|
||||
error->one(FLERR,"Velocity constraints are not satisfied "
|
||||
"up to desired tolerance!");
|
||||
|
||||
|
||||
#if RATTLE_RAISE_ERROR
|
||||
if (!stat) error->one(FLERR,"Velocity constraints are not satisfied up to desired tolerance!");
|
||||
#endif
|
||||
return stat;
|
||||
}
|
||||
|
||||
@ -41,8 +41,8 @@ using namespace MathConst;
|
||||
|
||||
#define RVOUS 1 // 0 for irregular, 1 for all2all
|
||||
|
||||
#define BIG 1.0e20
|
||||
#define MASSDELTA 0.1
|
||||
static constexpr double BIG = 1.0e20;
|
||||
static constexpr double MASSDELTA = 0.1;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
@ -52,26 +52,31 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) :
|
||||
loop_respa(nullptr), step_respa(nullptr), x(nullptr), v(nullptr), f(nullptr), ftmp(nullptr),
|
||||
vtmp(nullptr), mass(nullptr), rmass(nullptr), type(nullptr), shake_flag(nullptr),
|
||||
shake_atom(nullptr), shake_type(nullptr), xshake(nullptr), nshake(nullptr), list(nullptr),
|
||||
b_count(nullptr), b_count_all(nullptr), b_atom(nullptr), b_atom_all(nullptr), b_ave(nullptr), b_max(nullptr),
|
||||
b_min(nullptr), b_ave_all(nullptr), b_max_all(nullptr), b_min_all(nullptr), a_count(nullptr),
|
||||
b_count(nullptr), b_count_all(nullptr), b_ave(nullptr), b_max(nullptr), b_min(nullptr),
|
||||
b_ave_all(nullptr), b_max_all(nullptr), b_min_all(nullptr), a_count(nullptr),
|
||||
a_count_all(nullptr), a_ave(nullptr), a_max(nullptr), a_min(nullptr), a_ave_all(nullptr),
|
||||
a_max_all(nullptr), a_min_all(nullptr), atommols(nullptr), onemols(nullptr)
|
||||
{
|
||||
MPI_Comm_rank(world,&me);
|
||||
MPI_Comm_size(world,&nprocs);
|
||||
|
||||
energy_global_flag = energy_peratom_flag = 1;
|
||||
virial_global_flag = virial_peratom_flag = 1;
|
||||
thermo_virial = 1;
|
||||
thermo_energy = thermo_virial = 1;
|
||||
create_attribute = 1;
|
||||
dof_flag = 1;
|
||||
scalar_flag = 1;
|
||||
stores_ids = 1;
|
||||
centroidstressflag = CENTROID_AVAIL;
|
||||
next_output = -1;
|
||||
|
||||
// to avoid uninitialized access
|
||||
vflag_post_force = 0;
|
||||
eflag_pre_reverse = 0;
|
||||
ebond = 0.0;
|
||||
|
||||
// error check
|
||||
|
||||
molecular = atom->molecular;
|
||||
if (molecular == Atom::ATOMIC)
|
||||
error->all(FLERR,"Cannot use fix shake with non-molecular system");
|
||||
error->all(FLERR,"Cannot use fix {} with non-molecular system", style);
|
||||
|
||||
// perform initial allocation of atom-based arrays
|
||||
// register with Atom class
|
||||
@ -92,8 +97,9 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) :
|
||||
comm_forward = 3;
|
||||
|
||||
// parse SHAKE args
|
||||
auto mystyle = fmt::format("fix {}",style);
|
||||
|
||||
if (narg < 8) error->all(FLERR,"Illegal fix shake command");
|
||||
if (narg < 8) utils::missing_cmd_args(FLERR,mystyle, error);
|
||||
|
||||
tolerance = utils::numeric(FLERR,arg[3],false,lmp);
|
||||
max_iter = utils::inumeric(FLERR,arg[4],false,lmp);
|
||||
@ -133,49 +139,55 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) :
|
||||
else if (mode == 'b') {
|
||||
int i = utils::inumeric(FLERR,arg[next],false,lmp);
|
||||
if (i < 1 || i > atom->nbondtypes)
|
||||
error->all(FLERR,"Invalid bond type index for fix shake");
|
||||
error->all(FLERR,"Invalid bond type index for {}", mystyle);
|
||||
bond_flag[i] = 1;
|
||||
|
||||
} else if (mode == 'a') {
|
||||
int i = utils::inumeric(FLERR,arg[next],false,lmp);
|
||||
if (i < 1 || i > atom->nangletypes)
|
||||
error->all(FLERR,"Invalid angle type index for fix shake");
|
||||
error->all(FLERR,"Invalid angle type index for {}", mystyle);
|
||||
angle_flag[i] = 1;
|
||||
|
||||
} else if (mode == 't') {
|
||||
int i = utils::inumeric(FLERR,arg[next],false,lmp);
|
||||
if (i < 1 || i > atom->ntypes)
|
||||
error->all(FLERR,"Invalid atom type index for fix shake");
|
||||
error->all(FLERR,"Invalid atom type index for {}", mystyle);
|
||||
type_flag[i] = 1;
|
||||
|
||||
} else if (mode == 'm') {
|
||||
double massone = utils::numeric(FLERR,arg[next],false,lmp);
|
||||
if (massone == 0.0) error->all(FLERR,"Invalid atom mass for fix shake");
|
||||
if (massone == 0.0) error->all(FLERR,"Invalid atom mass for {}", mystyle);
|
||||
if (nmass == atom->ntypes)
|
||||
error->all(FLERR,"Too many masses for fix shake");
|
||||
error->all(FLERR,"Too many masses for {}", mystyle);
|
||||
mass_list[nmass++] = massone;
|
||||
|
||||
} else error->all(FLERR,"Illegal fix shake command");
|
||||
} else error->all(FLERR,"Unknown {} command option: {}", mystyle, arg[next]);
|
||||
next++;
|
||||
}
|
||||
|
||||
// parse optional args
|
||||
|
||||
onemols = nullptr;
|
||||
kbond = 1.0e6*force->boltz;
|
||||
|
||||
int iarg = next;
|
||||
while (iarg < narg) {
|
||||
if (strcmp(arg[next],"mol") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix shake command");
|
||||
if (strcmp(arg[iarg],"mol") == 0) {
|
||||
if (iarg+2 > narg) utils::missing_cmd_args(FLERR,mystyle+" mol",error);
|
||||
int imol = atom->find_molecule(arg[iarg+1]);
|
||||
if (imol == -1)
|
||||
error->all(FLERR,"Molecule template ID for fix shake does not exist");
|
||||
if (atom->molecules[imol]->nset > 1 && comm->me == 0)
|
||||
error->warning(FLERR,"Molecule template for fix shake has multiple molecules");
|
||||
error->all(FLERR,"Molecule template ID {} for {} does not exist", mystyle, arg[iarg+1]);
|
||||
if ((atom->molecules[imol]->nset > 1) && (comm->me == 0))
|
||||
error->warning(FLERR,"Molecule template for {} has multiple molecules", mystyle);
|
||||
onemols = &atom->molecules[imol];
|
||||
nmol = onemols[0]->nset;
|
||||
iarg += 2;
|
||||
} else error->all(FLERR,"Illegal fix shake command");
|
||||
} else if (strcmp(arg[iarg],"kbond") == 0) {
|
||||
if (iarg+2 > narg) utils::missing_cmd_args(FLERR,mystyle+" kbond",error);
|
||||
kbond = utils::numeric(FLERR, arg[iarg+1], false, lmp);
|
||||
if (kbond < 0) error->all(FLERR,"Illegal {} kbond value {}. Must be >= 0.0", mystyle, kbond);
|
||||
iarg += 2;
|
||||
} else error->all(FLERR,"Unknown {} command option: {}", mystyle, arg[iarg]);
|
||||
}
|
||||
|
||||
// error check for Molecule template
|
||||
@ -183,7 +195,7 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) :
|
||||
if (onemols) {
|
||||
for (int i = 0; i < nmol; i++)
|
||||
if (onemols[i]->shakeflag == 0)
|
||||
error->all(FLERR,"Fix shake molecule template must have shake info");
|
||||
error->all(FLERR,"Fix {} molecule template must have shake info", style);
|
||||
}
|
||||
|
||||
// allocate bond and angle distance arrays, indexed from 1 to n
|
||||
@ -197,8 +209,6 @@ FixShake::FixShake(LAMMPS *lmp, int narg, char **arg) :
|
||||
int nb = atom->nbondtypes + 1;
|
||||
b_count = new int[nb];
|
||||
b_count_all = new int[nb];
|
||||
b_atom = new int[nb];
|
||||
b_atom_all = new int[nb];
|
||||
b_ave = new double[nb];
|
||||
b_ave_all = new double[nb];
|
||||
b_max = new double[nb];
|
||||
@ -291,8 +301,6 @@ FixShake::~FixShake()
|
||||
if (output_every) {
|
||||
delete[] b_count;
|
||||
delete[] b_count_all;
|
||||
delete[] b_atom;
|
||||
delete[] b_atom_all;
|
||||
delete[] b_ave;
|
||||
delete[] b_ave_all;
|
||||
delete[] b_max;
|
||||
@ -321,6 +329,9 @@ int FixShake::setmask()
|
||||
mask |= PRE_NEIGHBOR;
|
||||
mask |= POST_FORCE;
|
||||
mask |= POST_FORCE_RESPA;
|
||||
mask |= MIN_PRE_REVERSE;
|
||||
mask |= MIN_POST_FORCE;
|
||||
mask |= POST_RUN;
|
||||
return mask;
|
||||
}
|
||||
|
||||
@ -335,28 +346,24 @@ void FixShake::init()
|
||||
double rsq,angle;
|
||||
|
||||
// error if more than one shake fix
|
||||
auto pattern = fmt::format("^{}",style);
|
||||
|
||||
int count = 0;
|
||||
for (i = 0; i < modify->nfix; i++)
|
||||
if (strcmp(modify->fix[i]->style,"shake") == 0) count++;
|
||||
if (count > 1) error->all(FLERR,"More than one fix shake");
|
||||
if (modify->get_fix_by_style(pattern).size() > 1)
|
||||
error->all(FLERR,"More than one fix {} instance",style);
|
||||
|
||||
// cannot use with minimization since SHAKE turns off bonds
|
||||
// that should contribute to potential energy
|
||||
|
||||
if (update->whichflag == 2)
|
||||
error->all(FLERR,"Fix shake cannot be used with minimization");
|
||||
if ((comm->me == 0) && (update->whichflag == 2))
|
||||
error->warning(FLERR,"Using fix {} with minimization.\n Substituting constraints with "
|
||||
"harmonic restraint forces using kbond={:.4g}", style, kbond);
|
||||
|
||||
// error if npt,nph fix comes before shake fix
|
||||
|
||||
for (i = 0; i < modify->nfix; i++) {
|
||||
if (strcmp(modify->fix[i]->style,"npt") == 0) break;
|
||||
if (strcmp(modify->fix[i]->style,"nph") == 0) break;
|
||||
}
|
||||
if (i < modify->nfix) {
|
||||
for (int j = i; j < modify->nfix; j++)
|
||||
if (strcmp(modify->fix[j]->style,"shake") == 0)
|
||||
error->all(FLERR,"Shake fix must come before NPT/NPH fix");
|
||||
// error if a fix changing the box comes before shake fix
|
||||
bool boxflag = false;
|
||||
for (auto ifix : modify->get_fix_list()) {
|
||||
if (boxflag && utils::strmatch(ifix->style,pattern))
|
||||
error->all(FLERR,"Fix {} must come before any box changing fix", style);
|
||||
if (ifix->box_change) boxflag = true;
|
||||
}
|
||||
|
||||
// if rRESPA, find associated fix that must exist
|
||||
@ -379,7 +386,7 @@ void FixShake::init()
|
||||
// set equilibrium bond distances
|
||||
|
||||
if (force->bond == nullptr)
|
||||
error->all(FLERR,"Bond potential must be defined for SHAKE");
|
||||
error->all(FLERR,"Bond style must be defined for fix {}",style);
|
||||
for (i = 1; i <= atom->nbondtypes; i++)
|
||||
bond_distance[i] = force->bond->equilibrium_distance(i);
|
||||
|
||||
@ -390,7 +397,7 @@ void FixShake::init()
|
||||
for (i = 1; i <= atom->nangletypes; i++) {
|
||||
if (angle_flag[i] == 0) continue;
|
||||
if (force->angle == nullptr)
|
||||
error->all(FLERR,"Angle potential must be defined for SHAKE");
|
||||
error->all(FLERR,"Angle style must be defined for fix {}",style);
|
||||
|
||||
// scan all atoms for a SHAKE angle cluster
|
||||
// extract bond types for the 2 bonds in the cluster
|
||||
@ -417,7 +424,7 @@ void FixShake::init()
|
||||
// error check for any bond types that are not the same
|
||||
|
||||
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world);
|
||||
if (flag_all) error->all(FLERR,"Shake angles have different bond types");
|
||||
if (flag_all) error->all(FLERR,"Fix {} angles have different bond types", style);
|
||||
|
||||
// insure all procs have bond types
|
||||
|
||||
@ -494,6 +501,23 @@ void FixShake::setup(int vflag)
|
||||
shake_end_of_step(vflag);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
during minimization fix SHAKE adds strong bond forces
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixShake::min_setup(int vflag)
|
||||
{
|
||||
pre_neighbor();
|
||||
min_post_force(vflag);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void FixShake::setup_pre_reverse(int eflag, int vflag)
|
||||
{
|
||||
min_pre_reverse(eflag,vflag);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
build list of SHAKE clusters to constrain
|
||||
if one or more atoms in cluster are on this proc,
|
||||
@ -502,6 +526,7 @@ void FixShake::setup(int vflag)
|
||||
|
||||
void FixShake::pre_neighbor()
|
||||
{
|
||||
ebond = 0.0;
|
||||
int atom1,atom2,atom3,atom4;
|
||||
|
||||
// local copies of atom quantities
|
||||
@ -533,19 +558,17 @@ void FixShake::pre_neighbor()
|
||||
atom1 = atom->map(shake_atom[i][0]);
|
||||
atom2 = atom->map(shake_atom[i][1]);
|
||||
if (atom1 == -1 || atom2 == -1)
|
||||
error->one(FLERR,"Shake atoms {} {} missing on proc "
|
||||
"{} at step {}",shake_atom[i][0],
|
||||
shake_atom[i][1],me,update->ntimestep);
|
||||
error->one(FLERR,"Shake atoms {} {} missing on proc {} at step {}",shake_atom[i][0],
|
||||
shake_atom[i][1],comm->me,update->ntimestep);
|
||||
if (i <= atom1 && i <= atom2) list[nlist++] = i;
|
||||
} else if (shake_flag[i] % 2 == 1) {
|
||||
atom1 = atom->map(shake_atom[i][0]);
|
||||
atom2 = atom->map(shake_atom[i][1]);
|
||||
atom3 = atom->map(shake_atom[i][2]);
|
||||
if (atom1 == -1 || atom2 == -1 || atom3 == -1)
|
||||
error->one(FLERR,"Shake atoms {} {} {} missing on proc "
|
||||
"{} at step {}",shake_atom[i][0],
|
||||
error->one(FLERR,"Shake atoms {} {} {} missing on proc {} at step {}",shake_atom[i][0],
|
||||
shake_atom[i][1],shake_atom[i][2],
|
||||
me,update->ntimestep);
|
||||
comm->me,update->ntimestep);
|
||||
if (i <= atom1 && i <= atom2 && i <= atom3) list[nlist++] = i;
|
||||
} else {
|
||||
atom1 = atom->map(shake_atom[i][0]);
|
||||
@ -553,10 +576,9 @@ void FixShake::pre_neighbor()
|
||||
atom3 = atom->map(shake_atom[i][2]);
|
||||
atom4 = atom->map(shake_atom[i][3]);
|
||||
if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1)
|
||||
error->one(FLERR,"Shake atoms {} {} {} {} missing on "
|
||||
"proc {} at step {}",shake_atom[i][0],
|
||||
error->one(FLERR,"Shake atoms {} {} {} {} missing on proc {} at step {}",shake_atom[i][0],
|
||||
shake_atom[i][1],shake_atom[i][2],
|
||||
shake_atom[i][3],me,update->ntimestep);
|
||||
shake_atom[i][3],comm->me,update->ntimestep);
|
||||
if (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)
|
||||
list[nlist++] = i;
|
||||
}
|
||||
@ -575,11 +597,13 @@ void FixShake::post_force(int vflag)
|
||||
// communicate results if necessary
|
||||
|
||||
unconstrained_update();
|
||||
if (nprocs > 1) comm->forward_comm(this);
|
||||
if (comm->nprocs > 1) comm->forward_comm(this);
|
||||
|
||||
// virial setup
|
||||
|
||||
v_init(vflag);
|
||||
int eflag = eflag_pre_reverse;
|
||||
ev_init(eflag, vflag);
|
||||
ebond = 0.0;
|
||||
|
||||
// loop over clusters to add constraint forces
|
||||
|
||||
@ -619,7 +643,7 @@ void FixShake::post_force_respa(int vflag, int ilevel, int iloop)
|
||||
// communicate results if necessary
|
||||
|
||||
unconstrained_update_respa(ilevel);
|
||||
if (nprocs > 1) comm->forward_comm(this);
|
||||
if (comm->nprocs > 1) comm->forward_comm(this);
|
||||
|
||||
// virial setup only needed on last iteration of innermost level
|
||||
// and if pressure is requested
|
||||
@ -644,6 +668,59 @@ void FixShake::post_force_respa(int vflag, int ilevel, int iloop)
|
||||
vflag_post_force = vflag;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
store eflag so it can be used in min_post_force
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixShake::min_pre_reverse(int eflag, int /*vflag*/)
|
||||
{
|
||||
eflag_pre_reverse = eflag;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
substitute shake constraints with very strong bonds
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixShake::min_post_force(int vflag)
|
||||
{
|
||||
if (output_every) {
|
||||
bigint ntimestep = update->ntimestep;
|
||||
if (next_output == ntimestep) stats();
|
||||
|
||||
next_output = ntimestep + output_every;
|
||||
if (ntimestep % output_every != 0)
|
||||
next_output = (ntimestep/output_every)*output_every + output_every;
|
||||
} else next_output = -1;
|
||||
|
||||
int eflag = eflag_pre_reverse;
|
||||
ev_init(eflag, vflag);
|
||||
|
||||
x = atom->x;
|
||||
f = atom->f;
|
||||
nlocal = atom->nlocal;
|
||||
ebond = 0.0;
|
||||
|
||||
// loop over shake clusters to add restraint forces
|
||||
|
||||
for (int i = 0; i < nlist; i++) {
|
||||
int m = list[i];
|
||||
if (shake_flag[m] == 2) {
|
||||
bond_force(shake_atom[m][0], shake_atom[m][1], bond_distance[shake_type[m][0]]);
|
||||
} else if (shake_flag[m] == 3) {
|
||||
bond_force(shake_atom[m][0], shake_atom[m][1], bond_distance[shake_type[m][0]]);
|
||||
bond_force(shake_atom[m][0], shake_atom[m][2], bond_distance[shake_type[m][1]]);
|
||||
} else if (shake_flag[m] == 4) {
|
||||
bond_force(shake_atom[m][0], shake_atom[m][1], bond_distance[shake_type[m][0]]);
|
||||
bond_force(shake_atom[m][0], shake_atom[m][2], bond_distance[shake_type[m][1]]);
|
||||
bond_force(shake_atom[m][0], shake_atom[m][3], bond_distance[shake_type[m][2]]);
|
||||
} else {
|
||||
bond_force(shake_atom[m][0], shake_atom[m][1], bond_distance[shake_type[m][0]]);
|
||||
bond_force(shake_atom[m][0], shake_atom[m][2], bond_distance[shake_type[m][1]]);
|
||||
bond_force(shake_atom[m][1], shake_atom[m][2], angle_distance[shake_type[m][2]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
count # of degrees-of-freedom removed by SHAKE for atoms in igroup
|
||||
------------------------------------------------------------------------- */
|
||||
@ -690,10 +767,7 @@ void FixShake::find_clusters()
|
||||
tagint tagprev;
|
||||
double massone;
|
||||
|
||||
if ((me == 0) && screen) {
|
||||
if (!rattle) fputs("Finding SHAKE clusters ...\n",screen);
|
||||
else fputs("Finding RATTLE clusters ...\n",screen);
|
||||
}
|
||||
if (comm->me == 0) utils::logmesg(lmp, "Finding {} clusters ...\n",utils::uppercase(style));
|
||||
atommols = atom->avec->onemols;
|
||||
|
||||
tagint *tag = atom->tag;
|
||||
@ -805,7 +879,7 @@ void FixShake::find_clusters()
|
||||
}
|
||||
|
||||
MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world);
|
||||
if (flag_all) error->all(FLERR,"Did not find fix shake partner info");
|
||||
if (flag_all) error->all(FLERR,"Did not find fix {} partner info", style);
|
||||
|
||||
// -----------------------------------------------------
|
||||
// identify SHAKEable bonds
|
||||
@ -1015,7 +1089,7 @@ void FixShake::find_clusters()
|
||||
tmp = count4;
|
||||
MPI_Allreduce(&tmp,&count4,1,MPI_INT,MPI_SUM,world);
|
||||
|
||||
if (me == 0) {
|
||||
if (comm->me == 0) {
|
||||
utils::logmesg(lmp,"{:>8} = # of size 2 clusters\n"
|
||||
"{:>8} = # of size 3 clusters\n"
|
||||
"{:>8} = # of size 4 clusters\n"
|
||||
@ -1043,8 +1117,8 @@ void FixShake::atom_owners()
|
||||
// one datum for each owned atom: datum = owning proc, atomID
|
||||
|
||||
for (int i = 0; i < nlocal; i++) {
|
||||
proclist[i] = tag[i] % nprocs;
|
||||
idbuf[i].me = me;
|
||||
proclist[i] = tag[i] % comm->nprocs;
|
||||
idbuf[i].me = comm->me;
|
||||
idbuf[i].atomID = tag[i];
|
||||
}
|
||||
|
||||
@ -1089,7 +1163,7 @@ void FixShake::partner_info(int *npartner, tagint **partner_tag,
|
||||
// set values in 4 partner arrays for all partner atoms I own
|
||||
// also setup input buf to rendezvous comm
|
||||
// input datums = pair of bonded atoms where I do not own partner
|
||||
// owning proc for each datum = partner_tag % nprocs
|
||||
// owning proc for each datum = partner_tag % comm->nprocs
|
||||
// datum: atomID = partner_tag (off-proc), partnerID = tag (on-proc)
|
||||
// 4 values for my owned atom
|
||||
|
||||
@ -1127,7 +1201,7 @@ void FixShake::partner_info(int *npartner, tagint **partner_tag,
|
||||
}
|
||||
|
||||
} else {
|
||||
proclist[nsend] = partner_tag[i][j] % nprocs;
|
||||
proclist[nsend] = partner_tag[i][j] % comm->nprocs;
|
||||
inbuf[nsend].atomID = partner_tag[i][j];
|
||||
inbuf[nsend].partnerID = tag[i];
|
||||
inbuf[nsend].mask = mask[i];
|
||||
@ -1217,7 +1291,7 @@ void FixShake::nshake_info(int *npartner, tagint **partner_tag,
|
||||
// set partner_nshake for all partner atoms I own
|
||||
// also setup input buf to rendezvous comm
|
||||
// input datums = pair of bonded atoms where I do not own partner
|
||||
// owning proc for each datum = partner_tag % nprocs
|
||||
// owning proc for each datum = partner_tag % comm->nprocs
|
||||
// datum: atomID = partner_tag (off-proc), partnerID = tag (on-proc)
|
||||
// nshake value for my owned atom
|
||||
|
||||
@ -1231,7 +1305,7 @@ void FixShake::nshake_info(int *npartner, tagint **partner_tag,
|
||||
if (m >= 0 && m < nlocal) {
|
||||
partner_nshake[i][j] = nshake[m];
|
||||
} else {
|
||||
proclist[nsend] = partner_tag[i][j] % nprocs;
|
||||
proclist[nsend] = partner_tag[i][j] % comm->nprocs;
|
||||
inbuf[nsend].atomID = partner_tag[i][j];
|
||||
inbuf[nsend].partnerID = tag[i];
|
||||
inbuf[nsend].nshake = nshake[i];
|
||||
@ -1295,7 +1369,7 @@ void FixShake::shake_info(int *npartner, tagint **partner_tag,
|
||||
// set 3 shake arrays for all partner atoms I own
|
||||
// also setup input buf to rendezvous comm
|
||||
// input datums = partner atom where I do not own partner
|
||||
// owning proc for each datum = partner_tag % nprocs
|
||||
// owning proc for each datum = partner_tag % comm->nprocs
|
||||
// datum: atomID = partner_tag (off-proc)
|
||||
// values in 3 shake arrays
|
||||
|
||||
@ -1317,7 +1391,7 @@ void FixShake::shake_info(int *npartner, tagint **partner_tag,
|
||||
shake_type[m][2] = shake_type[i][2];
|
||||
|
||||
} else {
|
||||
proclist[nsend] = partner_tag[i][j] % nprocs;
|
||||
proclist[nsend] = partner_tag[i][j] % comm->nprocs;
|
||||
inbuf[nsend].atomID = partner_tag[i][j];
|
||||
inbuf[nsend].shake_flag = shake_flag[i];
|
||||
inbuf[nsend].shake_atom[0] = shake_atom[i][0];
|
||||
@ -2451,13 +2525,66 @@ void FixShake::shake3angle(int m)
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
apply bond force for minimization
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixShake::bond_force(tagint id1, tagint id2, double length)
|
||||
{
|
||||
int i1 = atom->map(id1);
|
||||
int i2 = atom->map(id2);
|
||||
|
||||
if ((i1 < 0) || (i2 < 0)) return;
|
||||
|
||||
// distance vec between atoms, with PBC
|
||||
|
||||
double delx = x[i1][0] - x[i2][0];
|
||||
double dely = x[i1][1] - x[i2][1];
|
||||
double delz = x[i1][2] - x[i2][2];
|
||||
domain->minimum_image(delx, dely, delz);
|
||||
|
||||
// compute and apply force
|
||||
|
||||
const double r = sqrt(delx * delx + dely * dely + delz * delz);
|
||||
const double dr = r - length;
|
||||
const double rk = kbond * dr;
|
||||
const double fbond = (r > 0.0) ? -2.0 * rk / r : 0.0;
|
||||
const double eb = rk*dr;
|
||||
int list[2];
|
||||
int nlist = 0;
|
||||
|
||||
if (i1 < nlocal) {
|
||||
f[i1][0] += delx * fbond;
|
||||
f[i1][1] += dely * fbond;
|
||||
f[i1][2] += delz * fbond;
|
||||
list[nlist++] = i1;
|
||||
ebond += 0.5*eb;
|
||||
}
|
||||
if (i2 < nlocal) {
|
||||
f[i2][0] -= delx * fbond;
|
||||
f[i2][1] -= dely * fbond;
|
||||
f[i2][2] -= delz * fbond;
|
||||
list[nlist++] = i2;
|
||||
ebond += 0.5*eb;
|
||||
}
|
||||
if (evflag) {
|
||||
double v[6];
|
||||
v[0] = 0.5 * delx * delx * fbond;
|
||||
v[1] = 0.5 * dely * dely * fbond;
|
||||
v[2] = 0.5 * delz * delz * fbond;
|
||||
v[3] = 0.5 * delx * dely * fbond;
|
||||
v[4] = 0.5 * delx * delz * fbond;
|
||||
v[5] = 0.5 * dely * delz * fbond;
|
||||
ev_tally(nlist, list, 2.0, eb, v);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
print-out bond & angle statistics
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void FixShake::stats()
|
||||
{
|
||||
int i,j,m,n,iatom,jatom,katom;
|
||||
double delx,dely,delz;
|
||||
double r,r1,r2,r3,angle;
|
||||
|
||||
@ -2466,13 +2593,12 @@ void FixShake::stats()
|
||||
int nb = atom->nbondtypes + 1;
|
||||
int na = atom->nangletypes + 1;
|
||||
|
||||
for (i = 0; i < nb; i++) {
|
||||
for (int i = 0; i < nb; i++) {
|
||||
b_count[i] = 0;
|
||||
b_ave[i] = b_max[i] = 0.0;
|
||||
b_min[i] = BIG;
|
||||
b_atom[i] = -1;
|
||||
}
|
||||
for (i = 0; i < na; i++) {
|
||||
for (int i = 0; i < na; i++) {
|
||||
a_count[i] = 0;
|
||||
a_ave[i] = a_max[i] = 0.0;
|
||||
a_min[i] = BIG;
|
||||
@ -2484,25 +2610,26 @@ void FixShake::stats()
|
||||
double **x = atom->x;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
for (i = 0; i < nlocal; i++) {
|
||||
if (shake_flag[i] == 0) continue;
|
||||
for (int ii = 0; ii < nlist; ++ii) {
|
||||
int i = list[ii];
|
||||
int n = shake_flag[i];
|
||||
if (n == 0) continue;
|
||||
|
||||
// bond stats
|
||||
|
||||
n = shake_flag[i];
|
||||
if (n == 1) n = 3;
|
||||
iatom = atom->map(shake_atom[i][0]);
|
||||
for (j = 1; j < n; j++) {
|
||||
jatom = atom->map(shake_atom[i][j]);
|
||||
int iatom = atom->map(shake_atom[i][0]);
|
||||
for (int j = 1; j < n; j++) {
|
||||
int jatom = atom->map(shake_atom[i][j]);
|
||||
if (jatom >= nlocal) continue;
|
||||
delx = x[iatom][0] - x[jatom][0];
|
||||
dely = x[iatom][1] - x[jatom][1];
|
||||
delz = x[iatom][2] - x[jatom][2];
|
||||
domain->minimum_image(delx,dely,delz);
|
||||
r = sqrt(delx*delx + dely*dely + delz*delz);
|
||||
|
||||
m = shake_type[i][j-1];
|
||||
r = sqrt(delx*delx + dely*dely + delz*delz);
|
||||
int m = shake_type[i][j-1];
|
||||
b_count[m]++;
|
||||
b_atom[m] = n;
|
||||
b_ave[m] += r;
|
||||
b_max[m] = MAX(b_max[m],r);
|
||||
b_min[m] = MIN(b_min[m],r);
|
||||
@ -2511,9 +2638,13 @@ void FixShake::stats()
|
||||
// angle stats
|
||||
|
||||
if (shake_flag[i] == 1) {
|
||||
iatom = atom->map(shake_atom[i][0]);
|
||||
jatom = atom->map(shake_atom[i][1]);
|
||||
katom = atom->map(shake_atom[i][2]);
|
||||
int iatom = atom->map(shake_atom[i][0]);
|
||||
int jatom = atom->map(shake_atom[i][1]);
|
||||
int katom = atom->map(shake_atom[i][2]);
|
||||
int n = 0;
|
||||
if (iatom < nlocal) ++n;
|
||||
if (jatom < nlocal) ++n;
|
||||
if (katom < nlocal) ++n;
|
||||
|
||||
delx = x[iatom][0] - x[jatom][0];
|
||||
dely = x[iatom][1] - x[jatom][1];
|
||||
@ -2535,9 +2666,9 @@ void FixShake::stats()
|
||||
|
||||
angle = acos((r1*r1 + r2*r2 - r3*r3) / (2.0*r1*r2));
|
||||
angle *= 180.0/MY_PI;
|
||||
m = shake_type[i][2];
|
||||
a_count[m]++;
|
||||
a_ave[m] += angle;
|
||||
int m = shake_type[i][2];
|
||||
a_count[m] += n;
|
||||
a_ave[m] += n*angle;
|
||||
a_max[m] = MAX(a_max[m],angle);
|
||||
a_min[m] = MIN(a_min[m],angle);
|
||||
}
|
||||
@ -2546,7 +2677,6 @@ void FixShake::stats()
|
||||
// sum across all procs
|
||||
|
||||
MPI_Allreduce(b_count,b_count_all,nb,MPI_INT,MPI_SUM,world);
|
||||
MPI_Allreduce(b_atom,b_atom_all,nb,MPI_INT,MPI_MAX,world);
|
||||
MPI_Allreduce(b_ave,b_ave_all,nb,MPI_DOUBLE,MPI_SUM,world);
|
||||
MPI_Allreduce(b_max,b_max_all,nb,MPI_DOUBLE,MPI_MAX,world);
|
||||
MPI_Allreduce(b_min,b_min_all,nb,MPI_DOUBLE,MPI_MIN,world);
|
||||
@ -2558,16 +2688,17 @@ void FixShake::stats()
|
||||
|
||||
// print stats only for non-zero counts
|
||||
|
||||
if (me == 0) {
|
||||
if (comm->me == 0) {
|
||||
const int width = log10((MAX(MAX(1,nb),na)))+2;
|
||||
auto mesg = fmt::format("SHAKE stats (type/ave/delta/count) on step {}\n", update->ntimestep);
|
||||
for (i = 1; i < nb; i++) {
|
||||
auto mesg = fmt::format("{} stats (type/ave/delta/count) on step {}\n",
|
||||
utils::uppercase(style), update->ntimestep);
|
||||
for (int i = 1; i < nb; i++) {
|
||||
const auto bcnt = b_count_all[i];
|
||||
if (bcnt)
|
||||
mesg += fmt::format("Bond: {:>{}d} {:<9.6} {:<11.6} {:>8d}\n",i,width,
|
||||
b_ave_all[i]/bcnt,b_max_all[i]-b_min_all[i],bcnt/b_atom_all[i]);
|
||||
b_ave_all[i]/bcnt,b_max_all[i]-b_min_all[i],bcnt);
|
||||
}
|
||||
for (i = 1; i < na; i++) {
|
||||
for (int i = 1; i < na; i++) {
|
||||
const auto acnt = a_count_all[i];
|
||||
if (acnt)
|
||||
mesg += fmt::format("Angle: {:>{}d} {:<9.6} {:<11.6} {:>8d}\n",i,width,
|
||||
@ -3005,6 +3136,26 @@ void *FixShake::extract(const char *str, int &dim)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
energy due to restraint forces
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
double FixShake::compute_scalar()
|
||||
{
|
||||
double all;
|
||||
MPI_Allreduce(&ebond, &all, 1, MPI_DOUBLE, MPI_SUM, world);
|
||||
return all;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
print shake stats at the end of a minimization
|
||||
------------------------------------------------------------------------- */
|
||||
void FixShake::post_run()
|
||||
{
|
||||
if ((update->whichflag == 2) && (output_every > 0)) stats();
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
add coordinate constraining forces
|
||||
this method is called at the end of a timestep
|
||||
@ -3109,7 +3260,7 @@ void FixShake::correct_coordinates(int vflag) {
|
||||
|
||||
double **xtmp = xshake;
|
||||
xshake = x;
|
||||
if (nprocs > 1) {
|
||||
if (comm->nprocs > 1) {
|
||||
comm->forward_comm(this);
|
||||
}
|
||||
xshake = xtmp;
|
||||
|
||||
@ -34,9 +34,14 @@ class FixShake : public Fix {
|
||||
int setmask() override;
|
||||
void init() override;
|
||||
void setup(int) override;
|
||||
void setup_pre_reverse(int, int) override;
|
||||
void min_setup(int) override;
|
||||
void pre_neighbor() override;
|
||||
void post_force(int) override;
|
||||
void post_force_respa(int, int, int) override;
|
||||
void min_pre_reverse(int, int) override;
|
||||
void min_post_force(int) override;
|
||||
void post_run() override;
|
||||
|
||||
double memory_usage() override;
|
||||
void grow_arrays(int) override;
|
||||
@ -57,11 +62,12 @@ class FixShake : public Fix {
|
||||
int dof(int) override;
|
||||
void reset_dt() override;
|
||||
void *extract(const char *, int &) override;
|
||||
double compute_scalar() override;
|
||||
|
||||
protected:
|
||||
int vflag_post_force; // store the vflag of last post_force call
|
||||
int eflag_pre_reverse; // store the eflag of last pre_reverse call
|
||||
int respa; // 0 = vel. Verlet, 1 = respa
|
||||
int me, nprocs;
|
||||
int rattle; // 0 = SHAKE, 1 = RATTLE
|
||||
double tolerance; // SHAKE tolerance
|
||||
int max_iter; // max # of SHAKE iterations
|
||||
@ -76,6 +82,8 @@ class FixShake : public Fix {
|
||||
|
||||
int molecular; // copy of atom->molecular
|
||||
double *bond_distance, *angle_distance; // constraint distances
|
||||
double kbond; // force constant for restraint
|
||||
double ebond; // energy of bond restraints
|
||||
|
||||
class FixRespa *fix_respa; // rRESPA fix needed by SHAKE
|
||||
int nlevels_respa; // copies of needed rRESPA variables
|
||||
@ -108,8 +116,7 @@ class FixShake : public Fix {
|
||||
int nlist, maxlist; // size and max-size of list
|
||||
|
||||
// stat quantities
|
||||
int *b_count, *b_count_all, *b_atom,
|
||||
*b_atom_all; // counts for each bond type, atoms in bond cluster
|
||||
int *b_count, *b_count_all; // counts for each bond type, atoms in bond cluster
|
||||
double *b_ave, *b_max, *b_min; // ave/max/min dist for each bond type
|
||||
double *b_ave_all, *b_max_all, *b_min_all; // MPI summing arrays
|
||||
int *a_count, *a_count_all; // ditto for angle types
|
||||
@ -133,6 +140,7 @@ class FixShake : public Fix {
|
||||
void shake3(int);
|
||||
void shake4(int);
|
||||
void shake3angle(int);
|
||||
void bond_force(tagint, tagint, double);
|
||||
void stats();
|
||||
int bondtype_findset(int, tagint, tagint, int);
|
||||
int angletype_findset(int, tagint, tagint, int);
|
||||
|
||||
@ -1232,8 +1232,6 @@ void PairSMTBQ::tabqeq()
|
||||
double aCoeff,bCoeff,rcoupe,nang;
|
||||
|
||||
int n = atom->ntypes;
|
||||
int nlocal = atom->nlocal;
|
||||
int nghost = atom->nghost;
|
||||
nmax = atom->nmax;
|
||||
nntype = int((n+1)*n/2);
|
||||
|
||||
@ -1242,7 +1240,7 @@ void PairSMTBQ::tabqeq()
|
||||
|
||||
#if VERBOSE
|
||||
printf ("kmax %d, ds %f, nmax %d\n",kmax,ds,nmax);
|
||||
printf ("nlocal = %d, nghost = %d\n",nlocal,nghost);
|
||||
printf ("nlocal = %d, nghost = %d\n",atom->nlocal,atom->nghost);
|
||||
printf ("nntypes %d, kmax %d, rc %f, n %d\n",nntype,kmax,rc,n);
|
||||
#endif
|
||||
|
||||
|
||||
@ -1891,11 +1891,10 @@ void Atom::add_molecule(int narg, char **arg)
|
||||
return -1 if does not exist
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Atom::find_molecule(char *id)
|
||||
int Atom::find_molecule(const char *id)
|
||||
{
|
||||
if (id == nullptr) return -1;
|
||||
int imol;
|
||||
for (imol = 0; imol < nmolecule; imol++)
|
||||
for (int imol = 0; imol < nmolecule; imol++)
|
||||
if (strcmp(id,molecules[imol]->id) == 0) return imol;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -344,7 +344,7 @@ class Atom : protected Pointers {
|
||||
int shape_consistency(int, double &, double &, double &);
|
||||
|
||||
void add_molecule(int, char **);
|
||||
int find_molecule(char *);
|
||||
int find_molecule(const char *);
|
||||
std::vector<Molecule *>get_molecule_by_id(const std::string &);
|
||||
void add_molecule_atom(class Molecule *, int, int, tagint);
|
||||
|
||||
|
||||
18
src/comm.cpp
18
src/comm.cpp
@ -226,14 +226,14 @@ void Comm::init()
|
||||
maxreverse = MAX(maxreverse, fix->comm_reverse);
|
||||
}
|
||||
|
||||
for (int i = 0; i < modify->ncompute; i++) {
|
||||
maxforward = MAX(maxforward,modify->compute[i]->comm_forward);
|
||||
maxreverse = MAX(maxreverse,modify->compute[i]->comm_reverse);
|
||||
for (const auto &compute : modify->get_compute_list()) {
|
||||
maxforward = MAX(maxforward,compute->comm_forward);
|
||||
maxreverse = MAX(maxreverse,compute->comm_reverse);
|
||||
}
|
||||
|
||||
for (int i = 0; i < output->ndump; i++) {
|
||||
maxforward = MAX(maxforward,output->dump[i]->comm_forward);
|
||||
maxreverse = MAX(maxreverse,output->dump[i]->comm_reverse);
|
||||
for (const auto &dump: output->get_dump_list()) {
|
||||
maxforward = MAX(maxforward,dump->comm_forward);
|
||||
maxreverse = MAX(maxreverse,dump->comm_reverse);
|
||||
}
|
||||
|
||||
if (force->newton == 0) maxreverse = 0;
|
||||
@ -247,8 +247,7 @@ void Comm::init()
|
||||
maxexchange_atom = atom->avec->maxexchange;
|
||||
|
||||
maxexchange_fix_dynamic = 0;
|
||||
for (const auto &fix : fix_list)
|
||||
if (fix->maxexchange_dynamic) maxexchange_fix_dynamic = 1;
|
||||
for (const auto &fix : fix_list) if (fix->maxexchange_dynamic) maxexchange_fix_dynamic = 1;
|
||||
|
||||
if ((mode == Comm::MULTI) && (neighbor->style != Neighbor::MULTI))
|
||||
error->all(FLERR,"Cannot use comm mode multi without multi-style neighbor lists");
|
||||
@ -270,8 +269,7 @@ void Comm::init()
|
||||
void Comm::init_exchange()
|
||||
{
|
||||
maxexchange_fix = 0;
|
||||
for (const auto &fix : modify->get_fix_list())
|
||||
maxexchange_fix += fix->maxexchange;
|
||||
for (const auto &fix : modify->get_fix_list()) maxexchange_fix += fix->maxexchange;
|
||||
|
||||
maxexchange = maxexchange_atom + maxexchange_fix;
|
||||
bufextra = maxexchange + BUFEXTRA;
|
||||
|
||||
@ -37,7 +37,7 @@ enum { NOBIAS, BIAS };
|
||||
|
||||
static const char cite_centroid_angle_improper_dihedral[] =
|
||||
"compute centroid/stress/atom for angles, impropers and dihedrals: doi:10.1103/PhysRevE.99.051301\n\n"
|
||||
"@article{PhysRevE.99.051301,\n"
|
||||
"@article{Surblys2019,\n"
|
||||
" title = {Application of Atomic Stress to Compute Heat Flux via Molecular\n"
|
||||
" Dynamics for Systems With Many-Body Interactions},\n"
|
||||
" author = {Surblys, Donatas and Matsubara, Hiroki and Kikugawa, Gota and Ohara, Taku},\n"
|
||||
@ -52,7 +52,7 @@ static const char cite_centroid_angle_improper_dihedral[] =
|
||||
|
||||
static const char cite_centroid_shake_rigid[] =
|
||||
"compute centroid/stress/atom for constrained dynamics: doi:10.1063/5.0070930\n\n"
|
||||
"@article{doi:10.1063/5.0070930,\n"
|
||||
"@article{Surblys2021,\n"
|
||||
" author = {Surblys, Donatas and Matsubara, Hiroki and Kikugawa, Gota and Ohara, Taku},\n"
|
||||
" journal = {Journal of Applied Physics},\n"
|
||||
" title = {Methodology and Meaning of Computing Heat Flux via Atomic Stress in Systems with\n"
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
// clang-format off
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
https://www.lammps.org/, Sandia National Laboratories
|
||||
@ -13,28 +12,29 @@
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#include "compute_pe_atom.h"
|
||||
#include <cstring>
|
||||
#include "atom.h"
|
||||
#include "update.h"
|
||||
#include "comm.h"
|
||||
#include "force.h"
|
||||
#include "pair.h"
|
||||
#include "bond.h"
|
||||
|
||||
#include "angle.h"
|
||||
#include "atom.h"
|
||||
#include "bond.h"
|
||||
#include "comm.h"
|
||||
#include "dihedral.h"
|
||||
#include "error.h"
|
||||
#include "force.h"
|
||||
#include "improper.h"
|
||||
#include "kspace.h"
|
||||
#include "modify.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
#include "modify.h"
|
||||
#include "pair.h"
|
||||
#include "update.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
ComputePEAtom::ComputePEAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
Compute(lmp, narg, arg),
|
||||
energy(nullptr)
|
||||
Compute(lmp, narg, arg), energy(nullptr)
|
||||
{
|
||||
if (narg < 3) error->all(FLERR, "Illegal compute pe/atom command");
|
||||
|
||||
@ -56,14 +56,22 @@ ComputePEAtom::ComputePEAtom(LAMMPS *lmp, int narg, char **arg) :
|
||||
fixflag = 0;
|
||||
int iarg = 3;
|
||||
while (iarg < narg) {
|
||||
if (strcmp(arg[iarg],"pair") == 0) pairflag = 1;
|
||||
else if (strcmp(arg[iarg],"bond") == 0) bondflag = 1;
|
||||
else if (strcmp(arg[iarg],"angle") == 0) angleflag = 1;
|
||||
else if (strcmp(arg[iarg],"dihedral") == 0) dihedralflag = 1;
|
||||
else if (strcmp(arg[iarg],"improper") == 0) improperflag = 1;
|
||||
else if (strcmp(arg[iarg],"kspace") == 0) kspaceflag = 1;
|
||||
else if (strcmp(arg[iarg],"fix") == 0) fixflag = 1;
|
||||
else error->all(FLERR,"Illegal compute pe/atom command");
|
||||
if (strcmp(arg[iarg], "pair") == 0)
|
||||
pairflag = 1;
|
||||
else if (strcmp(arg[iarg], "bond") == 0)
|
||||
bondflag = 1;
|
||||
else if (strcmp(arg[iarg], "angle") == 0)
|
||||
angleflag = 1;
|
||||
else if (strcmp(arg[iarg], "dihedral") == 0)
|
||||
dihedralflag = 1;
|
||||
else if (strcmp(arg[iarg], "improper") == 0)
|
||||
improperflag = 1;
|
||||
else if (strcmp(arg[iarg], "kspace") == 0)
|
||||
kspaceflag = 1;
|
||||
else if (strcmp(arg[iarg], "fix") == 0)
|
||||
fixflag = 1;
|
||||
else
|
||||
error->all(FLERR, "Illegal compute pe/atom command");
|
||||
iarg++;
|
||||
}
|
||||
}
|
||||
@ -153,13 +161,11 @@ void ComputePEAtom::compute_peratom()
|
||||
// add in per-atom contributions from relevant fixes
|
||||
// always only for owned atoms, not ghost
|
||||
|
||||
if (fixflag && modify->n_energy_atom)
|
||||
modify->energy_atom(nlocal,energy);
|
||||
if (fixflag && modify->n_energy_atom) modify->energy_atom(nlocal, energy);
|
||||
|
||||
// communicate ghost energy between neighbor procs
|
||||
|
||||
if (force->newton || (force->kspace && force->kspace->tip4pflag))
|
||||
comm->reverse_comm(this);
|
||||
if (force->newton || (force->kspace && force->kspace->tip4pflag)) comm->reverse_comm(this);
|
||||
|
||||
// zero energy of atoms not in group
|
||||
// only do this after comm since ghost contributions must be included
|
||||
|
||||
@ -262,10 +262,11 @@ void DumpCustom::init_style()
|
||||
|
||||
auto words = utils::split_words(format);
|
||||
if ((int) words.size() < nfield)
|
||||
error->all(FLERR,"Dump_modify format line is too short");
|
||||
error->all(FLERR,"Dump_modify format line is too short: {}", format);
|
||||
|
||||
int i=0;
|
||||
for (const auto &word : words) {
|
||||
if (i >= nfield) break;
|
||||
delete[] vformat[i];
|
||||
|
||||
if (format_column_user[i])
|
||||
|
||||
@ -185,10 +185,11 @@ void DumpLocal::init_style()
|
||||
|
||||
auto words = utils::split_words(format);
|
||||
if ((int) words.size() < size_one)
|
||||
error->all(FLERR,"Dump_modify format line is too short");
|
||||
error->all(FLERR,"Dump_modify format line is too short: {}", format);
|
||||
|
||||
int i=0;
|
||||
for (const auto &word : words) {
|
||||
if (i >= size_one) break;
|
||||
delete[] vformat[i];
|
||||
|
||||
if (format_column_user[i])
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
// clang-format off
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
https://www.lammps.org/, Sandia National Laboratories
|
||||
@ -53,10 +52,9 @@ enum{CONSTANT,EQUAL,ATOM};
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
FixLangevin::FixLangevin(LAMMPS *lmp, int narg, char **arg) :
|
||||
Fix(lmp, narg, arg),
|
||||
gjfflag(0), gfactor1(nullptr), gfactor2(nullptr), ratio(nullptr), tstr(nullptr),
|
||||
flangevin(nullptr), tforce(nullptr), franprev(nullptr),
|
||||
lv(nullptr), id_temp(nullptr), random(nullptr)
|
||||
Fix(lmp, narg, arg), gjfflag(0), gfactor1(nullptr), gfactor2(nullptr), ratio(nullptr),
|
||||
tstr(nullptr), flangevin(nullptr), tforce(nullptr), franprev(nullptr), lv(nullptr),
|
||||
id_temp(nullptr), random(nullptr)
|
||||
{
|
||||
if (narg < 7) error->all(FLERR, "Illegal fix langevin command");
|
||||
|
||||
@ -107,24 +105,24 @@ FixLangevin::FixLangevin(LAMMPS *lmp, int narg, char **arg) :
|
||||
while (iarg < narg) {
|
||||
if (strcmp(arg[iarg], "angmom") == 0) {
|
||||
if (iarg + 2 > narg) error->all(FLERR, "Illegal fix langevin command");
|
||||
if (strcmp(arg[iarg+1],"no") == 0) ascale = 0.0;
|
||||
else ascale = utils::numeric(FLERR,arg[iarg+1],false,lmp);
|
||||
if (strcmp(arg[iarg + 1], "no") == 0)
|
||||
ascale = 0.0;
|
||||
else
|
||||
ascale = utils::numeric(FLERR, arg[iarg + 1], false, lmp);
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg], "gjf") == 0) {
|
||||
if (iarg + 2 > narg) error->all(FLERR, "Illegal fix langevin command");
|
||||
if (strcmp(arg[iarg + 1], "no") == 0) {
|
||||
gjfflag = 0;
|
||||
osflag = 0;
|
||||
}
|
||||
else if (strcmp(arg[iarg+1],"vfull") == 0) {
|
||||
} else if (strcmp(arg[iarg + 1], "vfull") == 0) {
|
||||
gjfflag = 1;
|
||||
osflag = 1;
|
||||
}
|
||||
else if (strcmp(arg[iarg+1],"vhalf") == 0) {
|
||||
} else if (strcmp(arg[iarg + 1], "vhalf") == 0) {
|
||||
gjfflag = 1;
|
||||
osflag = 0;
|
||||
}
|
||||
else error->all(FLERR,"Illegal fix langevin command");
|
||||
} else
|
||||
error->all(FLERR, "Illegal fix langevin command");
|
||||
iarg += 2;
|
||||
} else if (strcmp(arg[iarg], "omega") == 0) {
|
||||
if (iarg + 2 > narg) error->all(FLERR, "Illegal fix langevin command");
|
||||
@ -134,8 +132,7 @@ FixLangevin::FixLangevin(LAMMPS *lmp, int narg, char **arg) :
|
||||
if (iarg + 3 > narg) error->all(FLERR, "Illegal fix langevin command");
|
||||
int itype = utils::inumeric(FLERR, arg[iarg + 1], false, lmp);
|
||||
double scale = utils::numeric(FLERR, arg[iarg + 2], false, lmp);
|
||||
if (itype <= 0 || itype > atom->ntypes)
|
||||
error->all(FLERR,"Illegal fix langevin command");
|
||||
if (itype <= 0 || itype > atom->ntypes) error->all(FLERR, "Illegal fix langevin command");
|
||||
ratio[itype] = scale;
|
||||
iarg += 3;
|
||||
} else if (strcmp(arg[iarg], "tally") == 0) {
|
||||
@ -146,7 +143,8 @@ FixLangevin::FixLangevin(LAMMPS *lmp, int narg, char **arg) :
|
||||
if (iarg + 2 > narg) error->all(FLERR, "Illegal fix langevin command");
|
||||
zeroflag = utils::logical(FLERR, arg[iarg + 1], false, lmp);
|
||||
iarg += 2;
|
||||
} else error->all(FLERR,"Illegal fix langevin command");
|
||||
} else
|
||||
error->all(FLERR, "Illegal fix langevin command");
|
||||
}
|
||||
|
||||
// set temperature = nullptr, user can override via fix_modify if wants bias
|
||||
@ -233,11 +231,13 @@ void FixLangevin::init()
|
||||
int before = 1;
|
||||
int flag = 0;
|
||||
for (int i = 0; i < modify->nfix; i++) {
|
||||
if (strcmp(id,modify->fix[i]->id) == 0) before = 0;
|
||||
else if ((modify->fmask[i] && utils::strmatch(modify->fix[i]->style,"^nve")) && before) flag = 1;
|
||||
auto ifix = modify->get_fix_by_index(i);
|
||||
if (strcmp(id, ifix->id) == 0)
|
||||
before = 0;
|
||||
else if ((modify->fmask[i] && utils::strmatch(ifix->style, "^nve")) && before)
|
||||
flag = 1;
|
||||
}
|
||||
if (flag)
|
||||
error->all(FLERR,"Fix langevin gjf should come before fix nve");
|
||||
if (flag) error->all(FLERR, "Fix langevin gjf should come before fix nve");
|
||||
}
|
||||
|
||||
if (oflag && !atom->sphere_flag)
|
||||
@ -249,11 +249,13 @@ void FixLangevin::init()
|
||||
|
||||
if (tstr) {
|
||||
tvar = input->variable->find(tstr);
|
||||
if (tvar < 0)
|
||||
error->all(FLERR,"Variable name for fix langevin does not exist");
|
||||
if (input->variable->equalstyle(tvar)) tstyle = EQUAL;
|
||||
else if (input->variable->atomstyle(tvar)) tstyle = ATOM;
|
||||
else error->all(FLERR,"Variable for fix langevin is invalid style");
|
||||
if (tvar < 0) error->all(FLERR, "Variable name {} for fix langevin does not exist", tstr);
|
||||
if (input->variable->equalstyle(tvar))
|
||||
tstyle = EQUAL;
|
||||
else if (input->variable->atomstyle(tvar))
|
||||
tstyle = ATOM;
|
||||
else
|
||||
error->all(FLERR, "Variable {} for fix langevin is invalid style", tstr);
|
||||
}
|
||||
|
||||
// if oflag or ascale set, check that all group particles are finite-size
|
||||
@ -265,14 +267,12 @@ void FixLangevin::init()
|
||||
|
||||
for (int i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit)
|
||||
if (radius[i] == 0.0)
|
||||
error->one(FLERR,"Fix langevin omega requires extended particles");
|
||||
if (radius[i] == 0.0) error->one(FLERR, "Fix langevin omega requires extended particles");
|
||||
}
|
||||
|
||||
if (ascale) {
|
||||
avec = dynamic_cast<AtomVecEllipsoid *>(atom->style_match("ellipsoid"));
|
||||
if (!avec)
|
||||
error->all(FLERR,"Fix langevin angmom requires atom style ellipsoid");
|
||||
if (!avec) error->all(FLERR, "Fix langevin angmom requires atom style ellipsoid");
|
||||
|
||||
int *ellipsoid = atom->ellipsoid;
|
||||
int *mask = atom->mask;
|
||||
@ -280,8 +280,7 @@ void FixLangevin::init()
|
||||
|
||||
for (int i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit)
|
||||
if (ellipsoid[i] < 0)
|
||||
error->one(FLERR,"Fix langevin angmom requires extended particles");
|
||||
if (ellipsoid[i] < 0) error->one(FLERR, "Fix langevin angmom requires extended particles");
|
||||
}
|
||||
|
||||
// set force prefactors
|
||||
@ -289,30 +288,30 @@ void FixLangevin::init()
|
||||
if (!atom->rmass) {
|
||||
for (int i = 1; i <= atom->ntypes; i++) {
|
||||
gfactor1[i] = -atom->mass[i] / t_period / force->ftm2v;
|
||||
gfactor2[i] = sqrt(atom->mass[i]) / force->ftm2v;
|
||||
if (gjfflag)
|
||||
gfactor2[i] = sqrt(atom->mass[i]) *
|
||||
sqrt(2.0*force->boltz/t_period/update->dt/force->mvv2e) /
|
||||
force->ftm2v;
|
||||
gfactor2[i] *= sqrt(2.0 * force->boltz / t_period / update->dt / force->mvv2e);
|
||||
else
|
||||
gfactor2[i] = sqrt(atom->mass[i]) *
|
||||
sqrt(24.0*force->boltz/t_period/update->dt/force->mvv2e) /
|
||||
force->ftm2v;
|
||||
gfactor2[i] *= sqrt(24.0 * force->boltz / t_period / update->dt / force->mvv2e);
|
||||
gfactor1[i] *= 1.0 / ratio[i];
|
||||
gfactor2[i] *= 1.0 / sqrt(ratio[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (temperature && temperature->tempbias) tbiasflag = BIAS;
|
||||
else tbiasflag = NOBIAS;
|
||||
if (temperature && temperature->tempbias)
|
||||
tbiasflag = BIAS;
|
||||
else
|
||||
tbiasflag = NOBIAS;
|
||||
|
||||
if (utils::strmatch(update->integrate_style,"^respa"))
|
||||
nlevels_respa = (dynamic_cast<Respa *>( update->integrate))->nlevels;
|
||||
if (utils::strmatch(update->integrate_style, "^respa")) {
|
||||
nlevels_respa = (static_cast<Respa *>(update->integrate))->nlevels;
|
||||
if (gjfflag) error->all(FLERR, "Fix langevin gjf and run style respa are not compatible");
|
||||
}
|
||||
|
||||
if (utils::strmatch(update->integrate_style,"^respa") && gjfflag)
|
||||
error->all(FLERR,"Fix langevin gjf and respa are not compatible");
|
||||
|
||||
if (gjfflag) gjfa = (1.0-update->dt/2.0/t_period)/(1.0+update->dt/2.0/t_period);
|
||||
if (gjfflag) gjfsib = sqrt(1.0+update->dt/2.0/t_period);
|
||||
if (gjfflag) {
|
||||
gjfa = (1.0 - update->dt / 2.0 / t_period) / (1.0 + update->dt / 2.0 / t_period);
|
||||
gjfsib = sqrt(1.0 + update->dt / 2.0 / t_period);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -336,13 +335,11 @@ void FixLangevin::setup(int vflag)
|
||||
v[i][0] -= dtfm * f[i][0];
|
||||
v[i][1] -= dtfm * f[i][1];
|
||||
v[i][2] -= dtfm * f[i][2];
|
||||
if (tbiasflag)
|
||||
temperature->remove_bias(i,v[i]);
|
||||
if (tbiasflag) temperature->remove_bias(i, v[i]);
|
||||
v[i][0] /= gjfa * gjfsib * gjfsib;
|
||||
v[i][1] /= gjfa * gjfsib * gjfsib;
|
||||
v[i][2] /= gjfa * gjfsib * gjfsib;
|
||||
if (tbiasflag)
|
||||
temperature->restore_bias(i,v[i]);
|
||||
if (tbiasflag) temperature->restore_bias(i, v[i]);
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -352,22 +349,21 @@ void FixLangevin::setup(int vflag)
|
||||
v[i][0] -= dtfm * f[i][0];
|
||||
v[i][1] -= dtfm * f[i][1];
|
||||
v[i][2] -= dtfm * f[i][2];
|
||||
if (tbiasflag)
|
||||
temperature->remove_bias(i,v[i]);
|
||||
if (tbiasflag) temperature->remove_bias(i, v[i]);
|
||||
v[i][0] /= gjfa * gjfsib * gjfsib;
|
||||
v[i][1] /= gjfa * gjfsib * gjfsib;
|
||||
v[i][2] /= gjfa * gjfsib * gjfsib;
|
||||
if (tbiasflag)
|
||||
temperature->restore_bias(i,v[i]);
|
||||
if (tbiasflag) temperature->restore_bias(i, v[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (utils::strmatch(update->integrate_style, "^verlet"))
|
||||
post_force(vflag);
|
||||
else {
|
||||
(dynamic_cast<Respa *>( update->integrate))->copy_flevel_f(nlevels_respa-1);
|
||||
auto respa = static_cast<Respa *>(update->integrate);
|
||||
respa->copy_flevel_f(nlevels_respa - 1);
|
||||
post_force_respa(vflag, nlevels_respa - 1, 0);
|
||||
(dynamic_cast<Respa *>( update->integrate))->copy_f_flevel(nlevels_respa-1);
|
||||
respa->copy_f_flevel(nlevels_respa - 1);
|
||||
}
|
||||
if (gjfflag) {
|
||||
double dtfm;
|
||||
@ -427,6 +423,7 @@ void FixLangevin::initial_integrate(int /* vflag */)
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
// clang-format off
|
||||
|
||||
void FixLangevin::post_force(int /*vflag*/)
|
||||
{
|
||||
@ -575,8 +572,7 @@ void FixLangevin::post_force_respa(int vflag, int ilevel, int /*iloop*/)
|
||||
modify forces using one of the many Langevin styles
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
template < int Tp_TSTYLEATOM, int Tp_GJF, int Tp_TALLY,
|
||||
int Tp_BIAS, int Tp_RMASS, int Tp_ZERO >
|
||||
template<int Tp_TSTYLEATOM, int Tp_GJF, int Tp_TALLY, int Tp_BIAS, int Tp_RMASS, int Tp_ZERO>
|
||||
void FixLangevin::post_force_templated()
|
||||
{
|
||||
double gamma1,gamma2;
|
||||
@ -988,6 +984,7 @@ void FixLangevin::end_of_step()
|
||||
energy += energy_onestep*update->dt;
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void FixLangevin::reset_target(double t_new)
|
||||
@ -1001,14 +998,11 @@ void FixLangevin::reset_dt()
|
||||
{
|
||||
if (atom->mass) {
|
||||
for (int i = 1; i <= atom->ntypes; i++) {
|
||||
gfactor2[i] = sqrt(atom->mass[i]) / force->ftm2v;
|
||||
if (gjfflag)
|
||||
gfactor2[i] = sqrt(atom->mass[i]) *
|
||||
sqrt(2.0*force->boltz/t_period/update->dt/force->mvv2e) /
|
||||
force->ftm2v;
|
||||
gfactor2[i] *= sqrt(2.0 * force->boltz / t_period / update->dt / force->mvv2e);
|
||||
else
|
||||
gfactor2[i] = sqrt(atom->mass[i]) *
|
||||
sqrt(24.0*force->boltz/t_period/update->dt/force->mvv2e) /
|
||||
force->ftm2v;
|
||||
gfactor2[i] *= sqrt(24.0 * force->boltz / t_period / update->dt / force->mvv2e);
|
||||
gfactor2[i] *= 1.0 / sqrt(ratio[i]);
|
||||
}
|
||||
}
|
||||
@ -1023,20 +1017,18 @@ void FixLangevin::reset_dt()
|
||||
int FixLangevin::modify_param(int narg, char **arg)
|
||||
{
|
||||
if (strcmp(arg[0], "temp") == 0) {
|
||||
if (narg < 2) error->all(FLERR,"Illegal fix_modify command");
|
||||
if (narg < 2) utils::missing_cmd_args(FLERR, "fix_modify", error);
|
||||
delete[] id_temp;
|
||||
id_temp = utils::strdup(arg[1]);
|
||||
|
||||
int icompute = modify->find_compute(id_temp);
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Could not find fix_modify temperature ID");
|
||||
temperature = modify->compute[icompute];
|
||||
temperature = modify->get_compute_by_id(id_temp);
|
||||
if (!temperature)
|
||||
error->all(FLERR, "Could not find fix_modify temperature compute ID: {}", id_temp);
|
||||
|
||||
if (temperature->tempflag == 0)
|
||||
error->all(FLERR,
|
||||
"Fix_modify temperature ID does not compute temperature");
|
||||
error->all(FLERR, "Fix_modify temperature compute {} does not compute temperature", id_temp);
|
||||
if (temperature->igroup != igroup && comm->me == 0)
|
||||
error->warning(FLERR,"Group for fix_modify temp != fix group");
|
||||
error->warning(FLERR, "Group for fix_modify temp != fix group: {} vs {}",
|
||||
group->names[igroup], group->names[temperature->igroup]);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
@ -1059,18 +1051,16 @@ double FixLangevin::compute_scalar()
|
||||
if (!gjfflag) {
|
||||
for (int i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit)
|
||||
energy_onestep += flangevin[i][0]*v[i][0] + flangevin[i][1]*v[i][1] +
|
||||
flangevin[i][2]*v[i][2];
|
||||
energy_onestep +=
|
||||
flangevin[i][0] * v[i][0] + flangevin[i][1] * v[i][1] + flangevin[i][2] * v[i][2];
|
||||
energy = 0.5 * energy_onestep * update->dt;
|
||||
} else {
|
||||
for (int i = 0; i < nlocal; i++)
|
||||
if (mask[i] & groupbit) {
|
||||
if (tbiasflag)
|
||||
temperature->remove_bias(i, lv[i]);
|
||||
energy_onestep += flangevin[i][0]*lv[i][0] + flangevin[i][1]*lv[i][1] +
|
||||
flangevin[i][2]*lv[i][2];
|
||||
if (tbiasflag)
|
||||
temperature->restore_bias(i, lv[i]);
|
||||
if (tbiasflag) temperature->remove_bias(i, lv[i]);
|
||||
energy_onestep +=
|
||||
flangevin[i][0] * lv[i][0] + flangevin[i][1] * lv[i][1] + flangevin[i][2] * lv[i][2];
|
||||
if (tbiasflag) temperature->restore_bias(i, lv[i]);
|
||||
}
|
||||
energy = -0.5 * energy_onestep * update->dt;
|
||||
}
|
||||
@ -1092,9 +1082,7 @@ double FixLangevin::compute_scalar()
|
||||
void *FixLangevin::extract(const char *str, int &dim)
|
||||
{
|
||||
dim = 0;
|
||||
if (strcmp(str,"t_target") == 0) {
|
||||
return &t_target;
|
||||
}
|
||||
if (strcmp(str, "t_target") == 0) { return &t_target; }
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "error.h"
|
||||
#include "fix_deform.h"
|
||||
#include "force.h"
|
||||
#include "group.h"
|
||||
#include "kspace.h"
|
||||
#include "modify.h"
|
||||
#include "update.h"
|
||||
@ -268,9 +269,9 @@ void FixPressBerendsen::init()
|
||||
|
||||
// insure no conflict with fix deform
|
||||
|
||||
for (int i = 0; i < modify->nfix; i++)
|
||||
if (strcmp(modify->fix[i]->style,"deform") == 0) {
|
||||
int *dimflag = (dynamic_cast<FixDeform *>( modify->fix[i]))->dimflag;
|
||||
for (const auto &ifix : modify->get_fix_list())
|
||||
if (strcmp(ifix->style, "^deform") == 0) {
|
||||
int *dimflag = static_cast<FixDeform *>(ifix)->dimflag;
|
||||
if ((p_flag[0] && dimflag[0]) || (p_flag[1] && dimflag[1]) ||
|
||||
(p_flag[2] && dimflag[2]))
|
||||
error->all(FLERR,"Cannot use fix press/berendsen and "
|
||||
@ -279,18 +280,16 @@ void FixPressBerendsen::init()
|
||||
|
||||
// set temperature and pressure ptrs
|
||||
|
||||
int icompute = modify->find_compute(id_temp);
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Temperature ID for fix press/berendsen does not exist");
|
||||
temperature = modify->compute[icompute];
|
||||
temperature = modify->get_compute_by_id(id_temp);
|
||||
if (!temperature)
|
||||
error->all(FLERR, "Temperature compute ID {} for fix press/berendsen does not exist", id_temp);
|
||||
|
||||
if (temperature->tempbias) which = BIAS;
|
||||
else which = NOBIAS;
|
||||
|
||||
icompute = modify->find_compute(id_press);
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Pressure ID for fix press/berendsen does not exist");
|
||||
pressure = modify->compute[icompute];
|
||||
pressure = modify->get_compute_by_id(id_press);
|
||||
if (!pressure)
|
||||
error->all(FLERR, "Pressure compute ID {} for fix press/berendsen does not exist", id_press);
|
||||
|
||||
// Kspace setting
|
||||
|
||||
@ -306,7 +305,7 @@ void FixPressBerendsen::init()
|
||||
|
||||
for (int i = 0; i < modify->nfix; i++)
|
||||
if (modify->fix[i]->rigid_flag) nrigid++;
|
||||
if (nrigid) {
|
||||
if (nrigid > 0) {
|
||||
rfix = new int[nrigid];
|
||||
nrigid = 0;
|
||||
for (int i = 0; i < modify->nfix; i++)
|
||||
@ -463,21 +462,22 @@ int FixPressBerendsen::modify_param(int narg, char **arg)
|
||||
delete[] id_temp;
|
||||
id_temp = utils::strdup(arg[1]);
|
||||
|
||||
int icompute = modify->find_compute(arg[1]);
|
||||
if (icompute < 0) error->all(FLERR,"Could not find fix_modify temperature ID");
|
||||
temperature = modify->compute[icompute];
|
||||
temperature = modify->get_compute_by_id(arg[1]);
|
||||
if (!temperature)
|
||||
error->all(FLERR,"Could not find fix_modify temperature compute ID: ", arg[1]);
|
||||
|
||||
if (temperature->tempflag == 0)
|
||||
error->all(FLERR,"Fix_modify temperature ID does not compute temperature");
|
||||
error->all(FLERR,"Fix_modify temperature compute {} does not compute temperature", arg[1]);
|
||||
if (temperature->igroup != 0 && comm->me == 0)
|
||||
error->warning(FLERR,"Temperature for NPT is not for group all");
|
||||
error->warning(FLERR,"Temperature compute {} for fix {} is not for group all: {}",
|
||||
arg[1], style, group->names[temperature->igroup]);
|
||||
|
||||
// reset id_temp of pressure to new temperature ID
|
||||
|
||||
icompute = modify->find_compute(id_press);
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Pressure ID for fix press/berendsen does not exist");
|
||||
modify->compute[icompute]->reset_extra_compute_fix(id_temp);
|
||||
auto icompute = modify->get_compute_by_id(id_press);
|
||||
if (!icompute)
|
||||
error->all(FLERR,"Pressure compute ID {} for fix {} does not exist", id_press, style);
|
||||
icompute->reset_extra_compute_fix(id_temp);
|
||||
|
||||
return 2;
|
||||
|
||||
@ -490,12 +490,10 @@ int FixPressBerendsen::modify_param(int narg, char **arg)
|
||||
delete[] id_press;
|
||||
id_press = utils::strdup(arg[1]);
|
||||
|
||||
int icompute = modify->find_compute(arg[1]);
|
||||
if (icompute < 0) error->all(FLERR,"Could not find fix_modify pressure ID");
|
||||
pressure = modify->compute[icompute];
|
||||
|
||||
pressure = modify->get_compute_by_id(arg[1]);
|
||||
if (pressure) error->all(FLERR,"Could not find fix_modify pressure compute ID: {}", arg[1]);
|
||||
if (pressure->pressflag == 0)
|
||||
error->all(FLERR,"Fix_modify pressure ID does not compute pressure");
|
||||
error->all(FLERR,"Fix_modify pressure compute {} does not compute pressure", arg[1]);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@ -19,17 +19,18 @@
|
||||
|
||||
#include "fix_restrain.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include "atom.h"
|
||||
#include "force.h"
|
||||
#include "update.h"
|
||||
#include "domain.h"
|
||||
#include "comm.h"
|
||||
#include "respa.h"
|
||||
#include "domain.h"
|
||||
#include "error.h"
|
||||
#include "force.h"
|
||||
#include "math_const.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
#include "respa.h"
|
||||
#include "update.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
using namespace FixConst;
|
||||
@ -271,14 +272,12 @@ void FixRestrain::restrain_bond(int m)
|
||||
if (newton_bond) {
|
||||
if (i2 == -1 || i2 >= nlocal) return;
|
||||
if (i1 == -1)
|
||||
error->one(FLERR,"Restrain atoms {} {} missing on "
|
||||
"proc {} at step {}", ids[m][0],ids[m][1],
|
||||
error->one(FLERR,"Restrain atoms {} {} missing on proc {} at step {}", ids[m][0],ids[m][1],
|
||||
comm->me,update->ntimestep);
|
||||
} else {
|
||||
if ((i1 == -1 || i1 >= nlocal) && (i2 == -1 || i2 >= nlocal)) return;
|
||||
if (i1 == -1 || i2 == -1)
|
||||
error->one(FLERR,"Restrain atoms {} {} missing on "
|
||||
"proc {} at step {}", ids[m][0],ids[m][1],
|
||||
error->one(FLERR,"Restrain atoms {} {} missing on proc {} at step {}", ids[m][0],ids[m][1],
|
||||
comm->me,update->ntimestep);
|
||||
}
|
||||
|
||||
|
||||
@ -40,7 +40,8 @@ FixTempBerendsen::FixTempBerendsen(LAMMPS *lmp, int narg, char **arg) :
|
||||
Fix(lmp, narg, arg),
|
||||
tstr(nullptr), id_temp(nullptr), tflag(0)
|
||||
{
|
||||
if (narg != 6) error->all(FLERR,"Illegal fix temp/berendsen command");
|
||||
if (narg != 6)
|
||||
error->all(FLERR,"Illegal fix {} command: expected 6 arguments but found {}", style, narg);
|
||||
|
||||
// Berendsen thermostat should be applied every step
|
||||
|
||||
@ -68,7 +69,7 @@ FixTempBerendsen::FixTempBerendsen(LAMMPS *lmp, int narg, char **arg) :
|
||||
// error checks
|
||||
|
||||
if (t_period <= 0.0)
|
||||
error->all(FLERR,"Fix temp/berendsen period must be > 0.0");
|
||||
error->all(FLERR,"Fix temp/berendsen Tdamp period must be > 0.0");
|
||||
|
||||
// create a new compute temp style
|
||||
// id = fix-ID + temp, compute group = fix group
|
||||
@ -110,18 +111,17 @@ void FixTempBerendsen::init()
|
||||
if (tstr) {
|
||||
tvar = input->variable->find(tstr);
|
||||
if (tvar < 0)
|
||||
error->all(FLERR,"Variable name for fix temp/berendsen does not exist");
|
||||
error->all(FLERR,"Variable name {} for fix temp/berendsen does not exist", tstr);
|
||||
if (input->variable->equalstyle(tvar)) tstyle = EQUAL;
|
||||
else error->all(FLERR,"Variable for fix temp/berendsen is invalid style");
|
||||
else error->all(FLERR,"Variable {} for fix temp/berendsen is invalid style", tstr);
|
||||
}
|
||||
|
||||
int icompute = modify->find_compute(id_temp);
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Temperature ID for fix temp/berendsen does not exist");
|
||||
temperature = modify->compute[icompute];
|
||||
temperature = modify->get_compute_by_id(id_temp);
|
||||
if (!temperature)
|
||||
error->all(FLERR,"Temperature compute ID {} for fix {} does not exist", id_temp, style);
|
||||
|
||||
if (modify->check_rigid_group_overlap(groupbit))
|
||||
error->warning(FLERR,"Cannot thermostat atoms in rigid bodies");
|
||||
error->warning(FLERR,"Cannot thermostat atoms in rigid bodies with fix {}", style);
|
||||
|
||||
if (temperature->tempbias) which = BIAS;
|
||||
else which = NOBIAS;
|
||||
@ -139,8 +139,7 @@ void FixTempBerendsen::end_of_step()
|
||||
if (tdof < 1) return;
|
||||
|
||||
if (t_current == 0.0)
|
||||
error->all(FLERR,
|
||||
"Computed temperature for fix temp/berendsen cannot be 0.0");
|
||||
error->all(FLERR, "Computed current temperature for fix temp/berendsen must not be 0.0");
|
||||
|
||||
double delta = update->ntimestep - update->beginstep;
|
||||
if (delta != 0.0) delta /= update->endstep - update->beginstep;
|
||||
@ -154,8 +153,8 @@ void FixTempBerendsen::end_of_step()
|
||||
modify->clearstep_compute();
|
||||
t_target = input->variable->compute_equal(tvar);
|
||||
if (t_target < 0.0)
|
||||
error->one(FLERR,
|
||||
"Fix temp/berendsen variable returned negative temperature");
|
||||
error->one(FLERR, "Fix temp/berendsen variable {} returned negative temperature",
|
||||
input->variable->names[tvar]);
|
||||
modify->addstep_compute(update->ntimestep + nevery);
|
||||
}
|
||||
|
||||
@ -198,7 +197,7 @@ void FixTempBerendsen::end_of_step()
|
||||
int FixTempBerendsen::modify_param(int narg, char **arg)
|
||||
{
|
||||
if (strcmp(arg[0],"temp") == 0) {
|
||||
if (narg < 2) error->all(FLERR,"Illegal fix_modify command");
|
||||
if (narg < 2) utils::missing_cmd_args(FLERR, "fix_modify", error);
|
||||
if (tflag) {
|
||||
modify->delete_compute(id_temp);
|
||||
tflag = 0;
|
||||
@ -206,16 +205,15 @@ int FixTempBerendsen::modify_param(int narg, char **arg)
|
||||
delete[] id_temp;
|
||||
id_temp = utils::strdup(arg[1]);
|
||||
|
||||
int icompute = modify->find_compute(id_temp);
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Could not find fix_modify temperature ID");
|
||||
temperature = modify->compute[icompute];
|
||||
temperature = modify->get_compute_by_id(id_temp);
|
||||
if (!temperature)
|
||||
error->all(FLERR,"Could not find fix_modify temperature compute {}", id_temp);
|
||||
|
||||
if (temperature->tempflag == 0)
|
||||
error->all(FLERR,
|
||||
"Fix_modify temperature ID does not compute temperature");
|
||||
error->all(FLERR, "Fix_modify temperature compute {} does not compute temperature", id_temp);
|
||||
if (temperature->igroup != igroup && comm->me == 0)
|
||||
error->warning(FLERR,"Group for fix_modify temp != fix group");
|
||||
error->warning(FLERR, "Group for fix_modify temp != fix group: {} vs {}",
|
||||
group->names[igroup], group->names[temperature->igroup]);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@ -43,7 +43,7 @@ FixTempRescale::FixTempRescale(LAMMPS *lmp, int narg, char **arg) :
|
||||
if (narg < 8) utils::missing_cmd_args(FLERR, "fix temp/rescale", error);
|
||||
|
||||
nevery = utils::inumeric(FLERR,arg[3],false,lmp);
|
||||
if (nevery <= 0) error->all(FLERR, "Invalid fix temp/rescale argument: {}", nevery);
|
||||
if (nevery <= 0) error->all(FLERR, "Invalid fix temp/rescale every argument: {}", nevery);
|
||||
|
||||
restart_global = 1;
|
||||
scalar_flag = 1;
|
||||
@ -66,6 +66,10 @@ FixTempRescale::FixTempRescale(LAMMPS *lmp, int narg, char **arg) :
|
||||
t_window = utils::numeric(FLERR,arg[6],false,lmp);
|
||||
fraction = utils::numeric(FLERR,arg[7],false,lmp);
|
||||
|
||||
if (t_stop < 0) error->all(FLERR, "Invalid fix temp/rescale Tstop argument: {}", t_stop);
|
||||
if (t_window < 0) error->all(FLERR, "Invalid fix temp/rescale window argument: {}", t_window);
|
||||
if (fraction <= 0) error->all(FLERR, "Invalid fix temp/rescale fraction argument: {}", fraction);
|
||||
|
||||
// create a new compute temp
|
||||
// id = fix-ID + temp, compute group = fix group
|
||||
|
||||
@ -106,15 +110,14 @@ void FixTempRescale::init()
|
||||
if (tstr) {
|
||||
tvar = input->variable->find(tstr);
|
||||
if (tvar < 0)
|
||||
error->all(FLERR,"Variable {} for fix temp/rescale does not exist", tstr);
|
||||
error->all(FLERR,"Variable name {} for fix temp/rescale does not exist", tstr);
|
||||
if (input->variable->equalstyle(tvar)) tstyle = EQUAL;
|
||||
else error->all(FLERR,"Variable {} for fix temp/rescale is invalid style", tstr);
|
||||
}
|
||||
|
||||
int icompute = modify->find_compute(id_temp);
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Temperature ID for fix temp/rescale does not exist");
|
||||
temperature = modify->compute[icompute];
|
||||
temperature = modify->get_compute_by_id(id_temp);
|
||||
if (!temperature)
|
||||
error->all(FLERR,"Temperature ID {} for fix temp/rescale does not exist", id_temp);
|
||||
|
||||
if (temperature->tempbias) which = BIAS;
|
||||
else which = NOBIAS;
|
||||
@ -147,8 +150,7 @@ void FixTempRescale::end_of_step()
|
||||
modify->clearstep_compute();
|
||||
t_target = input->variable->compute_equal(tvar);
|
||||
if (t_target < 0.0)
|
||||
error->one(FLERR,
|
||||
"Fix temp/rescale variable returned negative temperature");
|
||||
error->one(FLERR, "Fix temp/rescale variable returned negative temperature");
|
||||
modify->addstep_compute(update->ntimestep + nevery);
|
||||
}
|
||||
|
||||
@ -203,16 +205,15 @@ int FixTempRescale::modify_param(int narg, char **arg)
|
||||
delete[] id_temp;
|
||||
id_temp = utils::strdup(arg[1]);
|
||||
|
||||
int icompute = modify->find_compute(id_temp);
|
||||
if (icompute < 0)
|
||||
error->all(FLERR,"Could not find fix_modify temperature ID {}", arg[1]);
|
||||
temperature = modify->compute[icompute];
|
||||
temperature = modify->get_compute_by_id(id_temp);
|
||||
if (!temperature)
|
||||
error->all(FLERR,"Could not find fix_modify temperature compute {}", id_temp);
|
||||
|
||||
if (temperature->tempflag == 0)
|
||||
error->all(FLERR,
|
||||
"Fix_modify temperature ID does not compute temperature");
|
||||
error->all(FLERR, "Fix_modify temperature compute {} does not compute temperature", id_temp);
|
||||
if (temperature->igroup != igroup && comm->me == 0)
|
||||
error->warning(FLERR,"Group for fix_modify temp != fix group");
|
||||
error->warning(FLERR, "Group for fix_modify temp != fix group: {} vs {}",
|
||||
group->names[igroup], group->names[temperature->igroup]);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
// clang-format off
|
||||
/* ----------------------------------------------------------------------
|
||||
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||
https://www.lammps.org/, Sandia National Laboratories
|
||||
@ -29,38 +28,31 @@ using namespace FixConst;
|
||||
enum { ONE, RUNNING, WINDOW };
|
||||
enum { SCALAR, VECTOR };
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
FixVector::FixVector(LAMMPS *lmp, int narg, char **arg) :
|
||||
Fix(lmp, narg, arg),
|
||||
nvalues(0), which(nullptr), argindex(nullptr), value2index(nullptr), ids(nullptr), vector(nullptr), array(nullptr)
|
||||
Fix(lmp, narg, arg), vector(nullptr), array(nullptr)
|
||||
{
|
||||
if (narg < 5) error->all(FLERR,"Illegal fix vector command");
|
||||
if (narg < 5) utils::missing_cmd_args(FLERR, "fix vector", error);
|
||||
|
||||
nevery = utils::inumeric(FLERR, arg[3], false, lmp);
|
||||
if (nevery <= 0) error->all(FLERR,"Illegal fix vector command");
|
||||
if (nevery <= 0) error->all(FLERR, "Invalid fix vector every argument: {}", nevery);
|
||||
|
||||
nvalues = narg-4;
|
||||
which = new int[nvalues];
|
||||
argindex = new int[nvalues];
|
||||
value2index = new int[nvalues];
|
||||
ids = new char*[nvalues];
|
||||
|
||||
nvalues = 0;
|
||||
values.clear();
|
||||
for (int iarg = 4; iarg < narg; iarg++) {
|
||||
ArgInfo argi(arg[iarg]);
|
||||
|
||||
which[nvalues] = argi.get_type();
|
||||
argindex[nvalues] = argi.get_index1();
|
||||
ids[nvalues] = argi.copy_name();
|
||||
value_t val;
|
||||
val.which = argi.get_type();
|
||||
val.argindex = argi.get_index1();
|
||||
val.id = argi.get_name();
|
||||
val.val.c = nullptr;
|
||||
|
||||
if ((argi.get_type() == ArgInfo::UNKNOWN)
|
||||
|| (argi.get_type() == ArgInfo::NONE)
|
||||
|| (argi.get_dim() > 1))
|
||||
error->all(FLERR,"Illegal fix vector command");
|
||||
if ((argi.get_type() == ArgInfo::UNKNOWN) || (argi.get_type() == ArgInfo::NONE) ||
|
||||
(argi.get_dim() > 1))
|
||||
error->all(FLERR, "Invalid fix vector argument: {}", arg[iarg]);
|
||||
|
||||
nvalues++;
|
||||
values.push_back(val);
|
||||
}
|
||||
|
||||
// setup and error check
|
||||
@ -69,58 +61,69 @@ FixVector::FixVector(LAMMPS *lmp, int narg, char **arg) :
|
||||
// intensive/extensive flags set by compute,fix,variable that produces value
|
||||
|
||||
int value, finalvalue;
|
||||
for (int i = 0; i < nvalues; i++) {
|
||||
if (which[i] == ArgInfo::COMPUTE) {
|
||||
auto icompute = modify->get_compute_by_id(ids[i]);
|
||||
if (!icompute) error->all(FLERR,"Compute ID {} for fix vector does not exist",ids[i]);
|
||||
if (argindex[i] == 0 && icompute->scalar_flag == 0)
|
||||
error->all(FLERR,"Fix vector compute {} does not calculate a scalar",ids[i]);
|
||||
if (argindex[i] && icompute->vector_flag == 0)
|
||||
error->all(FLERR,"Fix vector compute {} does not calculate a vector",ids[i]);
|
||||
if (argindex[i] && argindex[i] > icompute->size_vector)
|
||||
error->all(FLERR,"Fix vector compute {} vector is accessed out-of-range",ids[i]);
|
||||
bool first = true;
|
||||
for (auto &val : values) {
|
||||
if (val.which == ArgInfo::COMPUTE) {
|
||||
auto icompute = modify->get_compute_by_id(val.id);
|
||||
if (!icompute) error->all(FLERR, "Compute ID {} for fix vector does not exist", val.id);
|
||||
if (val.argindex == 0 && icompute->scalar_flag == 0)
|
||||
error->all(FLERR, "Fix vector compute {} does not calculate a scalar", val.id);
|
||||
if (val.argindex && icompute->vector_flag == 0)
|
||||
error->all(FLERR, "Fix vector compute {} does not calculate a vector", val.id);
|
||||
if (val.argindex && (val.argindex > icompute->size_vector))
|
||||
error->all(FLERR, "Fix vector compute {} vector is accessed out-of-range", val.id);
|
||||
|
||||
if (argindex[i] == 0) value = icompute->extscalar;
|
||||
else if (icompute->extvector >= 0) value = icompute->extvector;
|
||||
else value = icompute->extlist[argindex[i]-1];
|
||||
if (val.argindex == 0)
|
||||
value = icompute->extscalar;
|
||||
else if (icompute->extvector >= 0)
|
||||
value = icompute->extvector;
|
||||
else
|
||||
value = icompute->extlist[val.argindex - 1];
|
||||
val.val.c = icompute;
|
||||
|
||||
} else if (which[i] == ArgInfo::FIX) {
|
||||
auto ifix = modify->get_fix_by_id(ids[i]);
|
||||
if (!ifix) error->all(FLERR,"Fix ID {} for fix vector does not exist",ids[i]);
|
||||
if (argindex[i] == 0 && ifix->scalar_flag == 0)
|
||||
error->all(FLERR,"Fix vector fix {} does not calculate a scalar",ids[i]);
|
||||
if (argindex[i] && ifix->vector_flag == 0)
|
||||
error->all(FLERR,"Fix vector fix {} does not calculate a vector",ids[i]);
|
||||
if (argindex[i] && argindex[i] > ifix->size_vector)
|
||||
error->all(FLERR,"Fix vector fix {} vector is accessed out-of-range",ids[i]);
|
||||
} else if (val.which == ArgInfo::FIX) {
|
||||
auto ifix = modify->get_fix_by_id(val.id);
|
||||
if (!ifix) error->all(FLERR, "Fix ID {} for fix vector does not exist", val.id);
|
||||
if (val.argindex == 0 && ifix->scalar_flag == 0)
|
||||
error->all(FLERR, "Fix vector fix {} does not calculate a scalar", val.id);
|
||||
if (val.argindex && ifix->vector_flag == 0)
|
||||
error->all(FLERR, "Fix vector fix {} does not calculate a vector", val.id);
|
||||
if (val.argindex && val.argindex > ifix->size_vector)
|
||||
error->all(FLERR, "Fix vector fix {} vector is accessed out-of-range", val.id);
|
||||
if (nevery % ifix->global_freq)
|
||||
error->all(FLERR,"Fix for fix {} vector not computed at compatible time",ids[i]);
|
||||
error->all(FLERR, "Fix for fix {} vector not computed at compatible time", val.id);
|
||||
|
||||
if (argindex[i] == 0) value = ifix->extvector;
|
||||
else value = ifix->extarray;
|
||||
if (val.argindex == 0)
|
||||
value = ifix->extvector;
|
||||
else
|
||||
value = ifix->extarray;
|
||||
val.val.f = ifix;
|
||||
|
||||
} else if (which[i] == ArgInfo::VARIABLE) {
|
||||
int ivariable = input->variable->find(ids[i]);
|
||||
} else if (val.which == ArgInfo::VARIABLE) {
|
||||
int ivariable = input->variable->find(val.id.c_str());
|
||||
if (ivariable < 0)
|
||||
error->all(FLERR,"Variable name {} for fix vector does not exist",ids[i]);
|
||||
if (argindex[i] == 0 && input->variable->equalstyle(ivariable) == 0)
|
||||
error->all(FLERR,"Fix vector variable {} is not equal-style variable",ids[i]);
|
||||
if (argindex[i] && input->variable->vectorstyle(ivariable) == 0)
|
||||
error->all(FLERR,"Fix vector variable {} is not vector-style variable",ids[i]);
|
||||
error->all(FLERR, "Variable name {} for fix vector does not exist", val.id);
|
||||
if (val.argindex == 0 && input->variable->equalstyle(ivariable) == 0)
|
||||
error->all(FLERR, "Fix vector variable {} is not equal-style variable", val.id);
|
||||
if (val.argindex && input->variable->vectorstyle(ivariable) == 0)
|
||||
error->all(FLERR, "Fix vector variable {} is not vector-style variable", val.id);
|
||||
value = 0;
|
||||
val.val.v = ivariable;
|
||||
}
|
||||
|
||||
if (i == 0) finalvalue = value;
|
||||
else if (value != finalvalue)
|
||||
if (first) {
|
||||
finalvalue = value;
|
||||
first = false;
|
||||
} else if (value != finalvalue)
|
||||
error->all(FLERR, "Fix vector cannot set output array intensive/extensive from these inputs");
|
||||
}
|
||||
|
||||
if (nvalues == 1) {
|
||||
if (values.size() == 1) {
|
||||
vector_flag = 1;
|
||||
extvector = finalvalue;
|
||||
} else {
|
||||
array_flag = 1;
|
||||
size_array_cols = nvalues;
|
||||
size_array_cols = values.size();
|
||||
extarray = finalvalue;
|
||||
}
|
||||
|
||||
@ -132,8 +135,10 @@ FixVector::FixVector(LAMMPS *lmp, int narg, char **arg) :
|
||||
vector = nullptr;
|
||||
array = nullptr;
|
||||
ncount = ncountmax = 0;
|
||||
if (nvalues == 1) size_vector = 0;
|
||||
else size_array_rows = 0;
|
||||
if (values.size() == 1)
|
||||
size_vector = 0;
|
||||
else
|
||||
size_array_rows = 0;
|
||||
|
||||
// nextstep = next step on which end_of_step does something
|
||||
// add nextstep to all computes that store invocation times
|
||||
@ -153,12 +158,7 @@ FixVector::FixVector(LAMMPS *lmp, int narg, char **arg) :
|
||||
|
||||
FixVector::~FixVector()
|
||||
{
|
||||
delete [] which;
|
||||
delete [] argindex;
|
||||
delete [] value2index;
|
||||
for (int i = 0; i < nvalues; i++) delete [] ids[i];
|
||||
delete [] ids;
|
||||
|
||||
values.clear();
|
||||
memory->destroy(vector);
|
||||
memory->destroy(array);
|
||||
}
|
||||
@ -178,22 +178,19 @@ void FixVector::init()
|
||||
{
|
||||
// set current indices for all computes,fixes,variables
|
||||
|
||||
for (int i = 0; i < nvalues; i++) {
|
||||
if (which[i] == ArgInfo::COMPUTE) {
|
||||
int icompute = modify->find_compute(ids[i]);
|
||||
if (icompute < 0) error->all(FLERR,"Compute ID {} for fix vector does not exist",id[i]);
|
||||
value2index[i] = icompute;
|
||||
for (auto &val : values) {
|
||||
if (val.which == ArgInfo::COMPUTE) {
|
||||
val.val.c = modify->get_compute_by_id(val.id);
|
||||
if (!val.val.c) error->all(FLERR, "Compute ID {} for fix vector does not exist", val.id);
|
||||
|
||||
} else if (which[i] == ArgInfo::FIX) {
|
||||
int ifix = modify->find_fix(ids[i]);
|
||||
if (ifix < 0) error->all(FLERR,"Fix ID {} for fix vector does not exist",id[i]);
|
||||
value2index[i] = ifix;
|
||||
} else if (val.which == ArgInfo::FIX) {
|
||||
val.val.f = modify->get_fix_by_id(val.id);
|
||||
if (!val.val.f) error->all(FLERR, "Fix ID {} for fix vector does not exist", val.id);
|
||||
|
||||
} else if (which[i] == ArgInfo::VARIABLE) {
|
||||
int ivariable = input->variable->find(ids[i]);
|
||||
if (ivariable < 0)
|
||||
error->all(FLERR,"Variable name for fix vector does not exist");
|
||||
value2index[i] = ivariable;
|
||||
} else if (val.which == ArgInfo::VARIABLE) {
|
||||
int ivariable = input->variable->find(val.id.c_str());
|
||||
if (ivariable < 0) error->all(FLERR, "Variable name for fix vector does not exist");
|
||||
val.val.v = ivariable;
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,8 +201,10 @@ void FixVector::init()
|
||||
bigint finalstep = update->endstep / nevery * nevery;
|
||||
if (finalstep > update->endstep) finalstep -= nevery;
|
||||
ncountmax = (finalstep - initialstep) / nevery + 1;
|
||||
if (nvalues == 1) memory->grow(vector,ncountmax,"vector:vector");
|
||||
else memory->grow(array,ncountmax,nvalues,"vector:array");
|
||||
if (values.size() == 1)
|
||||
memory->grow(vector, ncountmax, "vector:vector");
|
||||
else
|
||||
memory->grow(array, ncountmax, values.size(), "vector:array");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -224,61 +223,64 @@ void FixVector::end_of_step()
|
||||
// skip if not step which requires doing something
|
||||
|
||||
if (update->ntimestep != nextstep) return;
|
||||
if (ncount == ncountmax)
|
||||
error->all(FLERR,"Overflow of allocated fix vector storage");
|
||||
if (ncount == ncountmax) error->all(FLERR, "Overflow of allocated fix vector storage");
|
||||
|
||||
// accumulate results of computes,fixes,variables to local copy
|
||||
// compute/fix/variable may invoke computes so wrap with clear/add
|
||||
|
||||
double *result;
|
||||
if (nvalues == 1) result = &vector[ncount];
|
||||
else result = array[ncount];
|
||||
if (values.size() == 1)
|
||||
result = &vector[ncount];
|
||||
else
|
||||
result = array[ncount];
|
||||
|
||||
modify->clearstep_compute();
|
||||
|
||||
for (int i = 0; i < nvalues; i++) {
|
||||
int m = value2index[i];
|
||||
int i = 0;
|
||||
for (auto &val : values) {
|
||||
|
||||
// invoke compute if not previously invoked
|
||||
|
||||
if (which[i] == ArgInfo::COMPUTE) {
|
||||
auto compute = modify->get_compute_by_index(m);
|
||||
if (val.which == ArgInfo::COMPUTE) {
|
||||
|
||||
if (argindex[i] == 0) {
|
||||
if (!(compute->invoked_flag & Compute::INVOKED_SCALAR)) {
|
||||
compute->compute_scalar();
|
||||
compute->invoked_flag |= Compute::INVOKED_SCALAR;
|
||||
if (val.argindex == 0) {
|
||||
if (!(val.val.c->invoked_flag & Compute::INVOKED_SCALAR)) {
|
||||
val.val.c->compute_scalar();
|
||||
val.val.c->invoked_flag |= Compute::INVOKED_SCALAR;
|
||||
}
|
||||
result[i] = compute->scalar;
|
||||
result[i] = val.val.c->scalar;
|
||||
} else {
|
||||
if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) {
|
||||
compute->compute_vector();
|
||||
compute->invoked_flag |= Compute::INVOKED_VECTOR;
|
||||
if (!(val.val.c->invoked_flag & Compute::INVOKED_VECTOR)) {
|
||||
val.val.c->compute_vector();
|
||||
val.val.c->invoked_flag |= Compute::INVOKED_VECTOR;
|
||||
}
|
||||
result[i] = compute->vector[argindex[i]-1];
|
||||
result[i] = val.val.c->vector[val.argindex - 1];
|
||||
}
|
||||
|
||||
// access fix fields, guaranteed to be ready
|
||||
|
||||
} else if (which[i] == ArgInfo::FIX) {
|
||||
if (argindex[i] == 0)
|
||||
result[i] = modify->get_fix_by_index(m)->compute_scalar();
|
||||
} else if (val.which == ArgInfo::FIX) {
|
||||
if (val.argindex == 0)
|
||||
result[i] = val.val.f->compute_scalar();
|
||||
else
|
||||
result[i] = modify->get_fix_by_index(m)->compute_vector(argindex[i]-1);
|
||||
result[i] = val.val.f->compute_vector(val.argindex - 1);
|
||||
|
||||
// evaluate equal-style or vector-style variable
|
||||
|
||||
} else if (which[i] == ArgInfo::VARIABLE) {
|
||||
if (argindex[i] == 0)
|
||||
result[i] = input->variable->compute_equal(m);
|
||||
} else if (val.which == ArgInfo::VARIABLE) {
|
||||
if (val.argindex == 0)
|
||||
result[i] = input->variable->compute_equal(val.val.v);
|
||||
else {
|
||||
double *varvec;
|
||||
int nvec = input->variable->compute_vector(m,&varvec);
|
||||
int index = argindex[i];
|
||||
if (nvec < index) result[i] = 0.0;
|
||||
else result[i] = varvec[index-1];
|
||||
int nvec = input->variable->compute_vector(val.val.v, &varvec);
|
||||
int index = val.argindex;
|
||||
if (nvec < index)
|
||||
result[i] = 0.0;
|
||||
else
|
||||
result[i] = varvec[index - 1];
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
// trigger computes on next needed step
|
||||
@ -289,8 +291,10 @@ void FixVector::end_of_step()
|
||||
// update size of vector or array
|
||||
|
||||
ncount++;
|
||||
if (nvalues == 1) size_vector++;
|
||||
else size_array_rows++;
|
||||
if (values.size() == 1)
|
||||
size_vector++;
|
||||
else
|
||||
size_array_rows++;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
@ -36,9 +36,17 @@ class FixVector : public Fix {
|
||||
double compute_array(int, int) override;
|
||||
|
||||
private:
|
||||
int nvalues;
|
||||
int *which, *argindex, *value2index;
|
||||
char **ids;
|
||||
struct value_t {
|
||||
int which;
|
||||
int argindex;
|
||||
std::string id;
|
||||
union {
|
||||
class Compute *c;
|
||||
class Fix *f;
|
||||
int v;
|
||||
} val;
|
||||
};
|
||||
std::vector<value_t> values;
|
||||
|
||||
bigint nextstep, initialstep;
|
||||
|
||||
@ -47,8 +55,6 @@ class FixVector : public Fix {
|
||||
double *vector;
|
||||
double **array;
|
||||
};
|
||||
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -101,22 +101,21 @@ void Group::assign(int narg, char **arg)
|
||||
// clear mask of each atom assigned to this group
|
||||
|
||||
if (strcmp(arg[1],"delete") == 0) {
|
||||
if (narg != 2) error->all(FLERR,"Illegal group command");
|
||||
if (narg != 2) error->all(FLERR,"Illegal group command: too many arguments");
|
||||
int igroup = find(arg[0]);
|
||||
if (igroup == -1) error->all(FLERR,"Could not find group delete group ID");
|
||||
if (igroup == -1) error->all(FLERR,"Could not find group delete group ID {}",arg[0]);
|
||||
if (igroup == 0) error->all(FLERR,"Cannot delete group all");
|
||||
for (const auto &fix : modify->get_fix_list())
|
||||
if (fix->igroup == igroup)
|
||||
error->all(FLERR,"Cannot delete group currently used by a fix");
|
||||
for (i = 0; i < modify->ncompute; i++)
|
||||
if (modify->compute[i]->igroup == igroup)
|
||||
error->all(FLERR,"Cannot delete group currently used by a compute");
|
||||
for (i = 0; i < output->ndump; i++)
|
||||
if (output->dump[i]->igroup == igroup)
|
||||
error->all(FLERR,"Cannot delete group currently used by a dump");
|
||||
for (const auto &i : modify->get_fix_list())
|
||||
if (i->igroup == igroup)
|
||||
error->all(FLERR,"Cannot delete group {} currently used by fix ID {}",arg[0],i->id);
|
||||
for (const auto &i : modify->get_compute_list())
|
||||
if (i->igroup == igroup)
|
||||
error->all(FLERR,"Cannot delete group {} currently used by compute ID {}",arg[0],i->id);
|
||||
for (const auto &i : output->get_dump_list())
|
||||
if (i->igroup == igroup)
|
||||
error->all(FLERR,"Cannot delete group {} currently used by dump ID {}",arg[0],i->id);
|
||||
if (atom->firstgroupname && strcmp(arg[0],atom->firstgroupname) == 0)
|
||||
error->all(FLERR,
|
||||
"Cannot delete group currently used by atom_modify first");
|
||||
error->all(FLERR,"Cannot delete group {} currently used by atom_modify first",arg[0]);
|
||||
|
||||
int *mask = atom->mask;
|
||||
int nlocal = atom->nlocal;
|
||||
|
||||
37
src/info.cpp
37
src/info.cpp
@ -887,42 +887,17 @@ bool Info::is_defined(const char *category, const char *name)
|
||||
if ((category == nullptr) || (name == nullptr)) return false;
|
||||
|
||||
if (strcmp(category,"compute") == 0) {
|
||||
int ncompute = modify->ncompute;
|
||||
Compute **compute = modify->compute;
|
||||
for (int i=0; i < ncompute; ++i) {
|
||||
if (strcmp(compute[i]->id,name) == 0)
|
||||
return true;
|
||||
}
|
||||
if (modify->get_compute_by_id(name)) return true;
|
||||
} else if (strcmp(category,"dump") == 0) {
|
||||
int ndump = output->ndump;
|
||||
Dump **dump = output->dump;
|
||||
for (int i=0; i < ndump; ++i) {
|
||||
if (strcmp(dump[i]->id,name) == 0)
|
||||
return true;
|
||||
}
|
||||
if (output->get_dump_by_id(name)) return true;
|
||||
} else if (strcmp(category,"fix") == 0) {
|
||||
for (const auto &fix : modify->get_fix_list()) {
|
||||
if (strcmp(fix->id,name) == 0)
|
||||
return true;
|
||||
}
|
||||
if (modify->get_fix_by_id(name)) return true;
|
||||
} else if (strcmp(category,"group") == 0) {
|
||||
int ngroup = group->ngroup;
|
||||
char **names = group->names;
|
||||
for (int i=0; i < ngroup; ++i) {
|
||||
if (strcmp(names[i],name) == 0)
|
||||
return true;
|
||||
}
|
||||
if (group->find(name) >= 0) return true;
|
||||
} else if (strcmp(category,"region") == 0) {
|
||||
for (auto ® : domain->get_region_list())
|
||||
if (strcmp(reg->id,name) == 0) return true;
|
||||
if (domain->get_region_by_id(name)) return true;
|
||||
} else if (strcmp(category,"variable") == 0) {
|
||||
int nvar = input->variable->nvar;
|
||||
char **names = input->variable->names;
|
||||
|
||||
for (int i=0; i < nvar; ++i) {
|
||||
if (strcmp(names[i],name) == 0)
|
||||
return true;
|
||||
}
|
||||
if (input->variable->find(name) >= 0) return true;
|
||||
} else error->all(FLERR,"Unknown category for info is_defined(): {}", category);
|
||||
|
||||
return false;
|
||||
|
||||
@ -4761,43 +4761,19 @@ int lammps_has_id(void *handle, const char *category, const char *name) {
|
||||
auto lmp = (LAMMPS *) handle;
|
||||
|
||||
if (strcmp(category,"compute") == 0) {
|
||||
int ncompute = lmp->modify->ncompute;
|
||||
Compute **compute = lmp->modify->compute;
|
||||
for (int i=0; i < ncompute; ++i) {
|
||||
if (strcmp(name,compute[i]->id) == 0) return 1;
|
||||
}
|
||||
if (lmp->modify->get_compute_by_id(name)) return 1;
|
||||
} else if (strcmp(category,"dump") == 0) {
|
||||
int ndump = lmp->output->ndump;
|
||||
Dump **dump = lmp->output->dump;
|
||||
for (int i=0; i < ndump; ++i) {
|
||||
if (strcmp(name,dump[i]->id) == 0) return 1;
|
||||
}
|
||||
if (lmp->output->get_dump_by_id(name)) return 1;
|
||||
} else if (strcmp(category,"fix") == 0) {
|
||||
for (auto &ifix : lmp->modify->get_fix_list()) {
|
||||
if (strcmp(name,ifix->id) == 0) return 1;
|
||||
}
|
||||
if (lmp->modify->get_fix_by_id(name)) return 1;
|
||||
} else if (strcmp(category,"group") == 0) {
|
||||
int ngroup = lmp->group->ngroup;
|
||||
char **groups = lmp->group->names;
|
||||
for (int i=0; i < ngroup; ++i) {
|
||||
if (strcmp(groups[i],name) == 0) return 1;
|
||||
}
|
||||
if (lmp->group->find(name) >= 0) return 1;
|
||||
} else if (strcmp(category,"molecule") == 0) {
|
||||
int nmolecule = lmp->atom->nmolecule;
|
||||
Molecule **molecule = lmp->atom->molecules;
|
||||
for (int i=0; i < nmolecule; ++i) {
|
||||
if (strcmp(name,molecule[i]->id) == 0) return 1;
|
||||
}
|
||||
if (lmp->atom->find_molecule(name) >= 0) return 1;
|
||||
} else if (strcmp(category,"region") == 0) {
|
||||
for (auto ® : lmp->domain->get_region_list()) {
|
||||
if (strcmp(name,reg->id) == 0) return 1;
|
||||
}
|
||||
if (lmp->domain->get_region_by_id(name)) return 1;
|
||||
} else if (strcmp(category,"variable") == 0) {
|
||||
int nvariable = lmp->input->variable->nvar;
|
||||
char **varnames = lmp->input->variable->names;
|
||||
for (int i=0; i < nvariable; ++i) {
|
||||
if (strcmp(name,varnames[i]) == 0) return 1;
|
||||
}
|
||||
if (lmp->input->variable->find(name) >= 0) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -4823,11 +4799,11 @@ categories.
|
||||
int lammps_id_count(void *handle, const char *category) {
|
||||
auto lmp = (LAMMPS *) handle;
|
||||
if (strcmp(category,"compute") == 0) {
|
||||
return lmp->modify->ncompute;
|
||||
return lmp->modify->get_compute_list().size();
|
||||
} else if (strcmp(category,"dump") == 0) {
|
||||
return lmp->output->ndump;
|
||||
return lmp->output->get_dump_list().size();
|
||||
} else if (strcmp(category,"fix") == 0) {
|
||||
return lmp->modify->nfix;
|
||||
return lmp->modify->get_fix_list().size();
|
||||
} else if (strcmp(category,"group") == 0) {
|
||||
return lmp->group->ngroup;
|
||||
} else if (strcmp(category,"molecule") == 0) {
|
||||
@ -4865,6 +4841,7 @@ set to an empty string, otherwise 1.
|
||||
*/
|
||||
int lammps_id_name(void *handle, const char *category, int idx, char *buffer, int buf_size) {
|
||||
auto lmp = (LAMMPS *) handle;
|
||||
if (idx < 0) return 0;
|
||||
|
||||
if (strcmp(category,"compute") == 0) {
|
||||
auto icompute = lmp->modify->get_compute_by_index(idx);
|
||||
@ -4873,8 +4850,9 @@ int lammps_id_name(void *handle, const char *category, int idx, char *buffer, in
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(category,"dump") == 0) {
|
||||
if ((idx >=0) && (idx < lmp->output->ndump)) {
|
||||
strncpy(buffer, lmp->output->dump[idx]->id, buf_size);
|
||||
auto idump = lmp->output->get_dump_by_index(idx);
|
||||
if (idump) {
|
||||
strncpy(buffer, idump->id, buf_size);
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(category,"fix") == 0) {
|
||||
|
||||
@ -182,15 +182,14 @@ void Min::init()
|
||||
neigh_delay = neighbor->delay;
|
||||
neigh_dist_check = neighbor->dist_check;
|
||||
|
||||
if (neigh_every != 1 || neigh_delay != 0 || neigh_dist_check != 1) {
|
||||
if ((neigh_every != 1) || (neigh_delay != 0)) {
|
||||
if (comm->me == 0)
|
||||
error->warning(FLERR, "Using 'neigh_modify every 1 delay 0 check"
|
||||
" yes' setting during minimization");
|
||||
}
|
||||
|
||||
utils::logmesg(lmp, "Switching to 'neigh_modify every 1 delay 0 check yes' "
|
||||
"setting during minimization\n");
|
||||
neighbor->every = 1;
|
||||
neighbor->delay = 0;
|
||||
neighbor->dist_check = 1;
|
||||
}
|
||||
|
||||
niter = neval = 0;
|
||||
|
||||
|
||||
@ -810,7 +810,7 @@ void Modify::reset_grid()
|
||||
|
||||
Fix *Modify::add_fix(int narg, char **arg, int trysuffix)
|
||||
{
|
||||
if (narg < 3) error->all(FLERR, "Illegal fix command");
|
||||
if (narg < 3) utils::missing_cmd_args(FLERR, "fix", error);
|
||||
|
||||
// cannot define fix before box exists unless style is in exception list
|
||||
// don't like this way of checking for exceptions by adding fixes to list,
|
||||
@ -1001,7 +1001,7 @@ Fix *Modify::replace_fix(const char *replaceID, int narg, char **arg, int trysuf
|
||||
// change ID, igroup, style of fix being replaced to match new fix
|
||||
// requires some error checking on arguments for new fix
|
||||
|
||||
if (narg < 3) error->all(FLERR, "Illegal replace_fix invocation");
|
||||
if (narg < 3) error->all(FLERR, "Not enough arguments for replace_fix invocation");
|
||||
if (get_fix_by_id(arg[0])) error->all(FLERR, "Replace_fix ID {} is already in use", arg[0]);
|
||||
|
||||
delete[] oldfix->id;
|
||||
@ -1039,16 +1039,11 @@ Fix *Modify::replace_fix(const std::string &oldfix, const std::string &fixcmd, i
|
||||
|
||||
void Modify::modify_fix(int narg, char **arg)
|
||||
{
|
||||
if (narg < 2) error->all(FLERR, "Illegal fix_modify command");
|
||||
if (narg < 2) utils::missing_cmd_args(FLERR, "fix_modify", error);
|
||||
|
||||
// lookup Fix ID
|
||||
|
||||
int ifix;
|
||||
for (ifix = 0; ifix < nfix; ifix++)
|
||||
if (strcmp(arg[0], fix[ifix]->id) == 0) break;
|
||||
if (ifix == nfix) error->all(FLERR, "Could not find fix_modify ID {}", arg[0]);
|
||||
|
||||
fix[ifix]->modify_params(narg - 1, &arg[1]);
|
||||
auto ifix = get_fix_by_id(arg[0]);
|
||||
if (!ifix) error->all(FLERR, "Could not find fix_modify ID {}", arg[0]);
|
||||
ifix->modify_params(narg - 1, &arg[1]);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -1239,13 +1234,11 @@ int Modify::check_rigid_list_overlap(int *select)
|
||||
|
||||
Compute *Modify::add_compute(int narg, char **arg, int trysuffix)
|
||||
{
|
||||
if (narg < 3) error->all(FLERR, "Illegal compute command");
|
||||
if (narg < 3) utils::missing_cmd_args(FLERR, "compute", error);
|
||||
|
||||
// error check
|
||||
|
||||
for (int icompute = 0; icompute < ncompute; icompute++)
|
||||
if (strcmp(arg[0], compute[icompute]->id) == 0)
|
||||
error->all(FLERR, "Reuse of compute ID '{}'", arg[0]);
|
||||
if (get_compute_by_id(arg[0])) error->all(FLERR, "Reuse of compute ID '{}'", arg[0]);
|
||||
|
||||
// extend Compute list if necessary
|
||||
|
||||
@ -1312,16 +1305,13 @@ Compute *Modify::add_compute(const std::string &computecmd, int trysuffix)
|
||||
|
||||
void Modify::modify_compute(int narg, char **arg)
|
||||
{
|
||||
if (narg < 2) error->all(FLERR, "Illegal compute_modify command");
|
||||
if (narg < 2) utils::missing_cmd_args(FLERR, "compute_modify",error);
|
||||
|
||||
// lookup Compute ID
|
||||
|
||||
int icompute;
|
||||
for (icompute = 0; icompute < ncompute; icompute++)
|
||||
if (strcmp(arg[0], compute[icompute]->id) == 0) break;
|
||||
if (icompute == ncompute) error->all(FLERR, "Could not find compute_modify ID {}", arg[0]);
|
||||
|
||||
compute[icompute]->modify_params(narg - 1, &arg[1]);
|
||||
auto icompute = get_compute_by_id(arg[0]);
|
||||
if (!icompute) error->all(FLERR, "Could not find compute_modify ID {}", arg[0]);
|
||||
icompute->modify_params(narg - 1, &arg[1]);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
||||
@ -89,11 +89,6 @@ static const char cite_neigh_multi[] =
|
||||
" volume = 179,\n"
|
||||
" pages = {320--329}\n"
|
||||
"}\n\n"
|
||||
"@article{Stratford2018,\n"
|
||||
" author = {Stratford, Kevin and Shire, Tom and Hanley, Kevin},\n"
|
||||
" title = {Implementation of multi-level contact detection in LAMMPS},\n"
|
||||
" year = {2018}\n"
|
||||
"}\n\n"
|
||||
"@article{Shire2020,\n"
|
||||
" author = {Shire, Tom and Hanley, Kevin J. and Stratford, Kevin},\n"
|
||||
" title = {{DEM} Simulations of Polydisperse Media: Efficient Contact\n"
|
||||
@ -1718,7 +1713,7 @@ void Neighbor::print_pairwise_info()
|
||||
}
|
||||
|
||||
std::string out = "Neighbor list info ...\n";
|
||||
out += fmt::format(" update every {} steps, delay {} steps, check {}\n",
|
||||
out += fmt::format(" update: every = {} steps, delay = {} steps, check = {}\n",
|
||||
every,delay,dist_check ? "yes" : "no");
|
||||
out += fmt::format(" max neighbors/atom: {}, page size: {}\n",
|
||||
oneatom, pgsize);
|
||||
|
||||
@ -783,6 +783,7 @@ Dump *Output::add_dump(int narg, char **arg)
|
||||
next_dump[idump] = 0;
|
||||
|
||||
ndump++;
|
||||
dump_list = std::vector<Dump *>(dump, dump + ndump);
|
||||
return dump[idump];
|
||||
}
|
||||
|
||||
@ -792,16 +793,13 @@ Dump *Output::add_dump(int narg, char **arg)
|
||||
|
||||
void Output::modify_dump(int narg, char **arg)
|
||||
{
|
||||
if (narg < 1) utils::missing_cmd_args(FLERR, "dump_modify",error);
|
||||
if (narg < 2) utils::missing_cmd_args(FLERR, "dump_modify",error);
|
||||
|
||||
// find which dump it is
|
||||
|
||||
int idump;
|
||||
for (idump = 0; idump < ndump; idump++)
|
||||
if (strcmp(arg[0],dump[idump]->id) == 0) break;
|
||||
if (idump == ndump) error->all(FLERR,"Could not find dump_modify ID: {}", arg[0]);
|
||||
|
||||
dump[idump]->modify_params(narg-1,&arg[1]);
|
||||
auto idump = get_dump_by_id(arg[0]);
|
||||
if (!idump) error->all(FLERR,"Could not find dump_modify ID: {}", arg[0]);
|
||||
idump->modify_params(narg-1,&arg[1]);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -833,21 +831,7 @@ void Output::delete_dump(const std::string &id)
|
||||
ivar_dump[i-1] = ivar_dump[i];
|
||||
}
|
||||
ndump--;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
find a dump by ID
|
||||
return index of dump or -1 if not found
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Output::find_dump(const char *id)
|
||||
{
|
||||
if (id == nullptr) return -1;
|
||||
int idump;
|
||||
for (idump = 0; idump < ndump; idump++)
|
||||
if (strcmp(id,dump[idump]->id) == 0) break;
|
||||
if (idump == ndump) return -1;
|
||||
return idump;
|
||||
dump_list = std::vector<Dump *>(dump, dump + ndump);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -855,13 +839,23 @@ int Output::find_dump(const char *id)
|
||||
return pointer to dump
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
Dump *Output::get_dump_by_id(const std::string &id)
|
||||
Dump *Output::get_dump_by_id(const std::string &id) const
|
||||
{
|
||||
if (id.empty()) return nullptr;
|
||||
for (int idump = 0; idump < ndump; idump++) if (id == dump[idump]->id) return dump[idump];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
return list of dumps as vector
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
const std::vector<Dump *> &Output::get_dump_list()
|
||||
{
|
||||
dump_list = std::vector<Dump *>(dump, dump + ndump);
|
||||
return dump_list;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
set thermo output frequency from input script
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
10
src/output.h
10
src/output.h
@ -83,8 +83,13 @@ class Output : protected Pointers {
|
||||
Dump *add_dump(int, char **); // add a Dump to Dump list
|
||||
void modify_dump(int, char **); // modify a Dump
|
||||
void delete_dump(const std::string &); // delete a Dump from Dump list
|
||||
int find_dump(const char *); // find a Dump ID
|
||||
Dump *get_dump_by_id(const std::string &); // find a Dump by ID
|
||||
Dump *get_dump_by_id(const std::string &) const; // find a Dump by ID
|
||||
Dump *get_dump_by_index(int idx) const // find a Dump by index in Dump list
|
||||
{
|
||||
return ((idx >= 0) && (idx < ndump)) ? dump[idx] : nullptr;
|
||||
}
|
||||
|
||||
const std::vector<Dump *> &get_dump_list(); // get vector with all dumps
|
||||
int check_time_dumps(bigint); // check if any time dump is output now
|
||||
|
||||
void set_thermo(int, char **); // set thermo output freqquency
|
||||
@ -94,6 +99,7 @@ class Output : protected Pointers {
|
||||
void memory_usage(); // print out memory usage
|
||||
|
||||
private:
|
||||
std::vector<Dump *> dump_list;
|
||||
void calculate_next_dump(int, int, bigint);
|
||||
};
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "angle.h"
|
||||
#include "atom.h"
|
||||
#include "atom_vec.h"
|
||||
#include "atom_vec_body.h"
|
||||
#include "atom_vec_ellipsoid.h"
|
||||
#include "atom_vec_line.h"
|
||||
#include "atom_vec_tri.h"
|
||||
@ -105,7 +106,7 @@ ReadData::ReadData(LAMMPS *lmp) : Command(lmp)
|
||||
ntris = 0;
|
||||
avec_tri = dynamic_cast<AtomVecTri *>(atom->style_match("tri"));
|
||||
nbodies = 0;
|
||||
avec_body = (AtomVecBody *) atom->style_match("body");
|
||||
avec_body = dynamic_cast<AtomVecBody *>(atom->style_match("body"));
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -122,7 +123,7 @@ ReadData::~ReadData()
|
||||
delete[] fix_header[i];
|
||||
delete[] fix_section[i];
|
||||
}
|
||||
memory->destroy(fix_index);
|
||||
memory->sfree(fix_index);
|
||||
memory->sfree(fix_header);
|
||||
memory->sfree(fix_section);
|
||||
}
|
||||
@ -285,16 +286,13 @@ void ReadData::command(int narg, char **arg)
|
||||
} else if (strcmp(arg[iarg],"fix") == 0) {
|
||||
if (iarg+4 > narg)
|
||||
error->all(FLERR,"Illegal read_data command");
|
||||
memory->grow(fix_index,nfix+1,"read_data:fix_index");
|
||||
fix_header = (char **) memory->srealloc(fix_header,(nfix+1)*sizeof(char *),
|
||||
"read_data:fix_header");
|
||||
fix_section = (char **) memory->srealloc(fix_section,(nfix+1)*sizeof(char *),
|
||||
"read_data:fix_section");
|
||||
fix_index = (Fix **)memory->srealloc(fix_index,(nfix+1)*sizeof(Fix *),"read_data:fix_index");
|
||||
fix_header = (char **) memory->srealloc(fix_header,(nfix+1)*sizeof(char *),"read_data:fix_header");
|
||||
fix_section = (char **) memory->srealloc(fix_section,(nfix+1)*sizeof(char *),"read_data:fix_section");
|
||||
if (is_data_section(arg[iarg+3]))
|
||||
error->all(FLERR,"Custom data section name {} for fix {} collides with existing "
|
||||
"data section",arg[iarg+3],arg[iarg+1]);
|
||||
fix_index[nfix] = modify->find_fix(arg[iarg+1]);
|
||||
if (fix_index[nfix] < 0) error->all(FLERR,"Fix ID for read_data does not exist");
|
||||
error->all(FLERR,"Custom data section name {} for fix {} collides with existing data section",arg[iarg+3],arg[iarg+1]);
|
||||
fix_index[nfix] = modify->get_fix_by_id(arg[iarg+1]);
|
||||
if (!fix_index[nfix]) error->all(FLERR,"Fix ID {} for read_data does not exist",arg[iarg+1]);
|
||||
if (strcmp(arg[iarg+2],"NULL") == 0) fix_header[nfix] = nullptr;
|
||||
else fix_header[nfix] = utils::strdup(arg[iarg+2]);
|
||||
if (strcmp(arg[iarg+3],"NULL") == 0) fix_section[nfix] = utils::strdup(arg[iarg+1]);
|
||||
@ -743,8 +741,7 @@ void ReadData::command(int narg, char **arg)
|
||||
for (i = 0; i < nfix; i++)
|
||||
if (strcmp(keyword,fix_section[i]) == 0) {
|
||||
if (firstpass) fix(fix_index[i],keyword);
|
||||
else skip_lines(modify->fix[fix_index[i]]->
|
||||
read_data_skip_lines(keyword));
|
||||
else skip_lines(fix_index[i]->read_data_skip_lines(keyword));
|
||||
break;
|
||||
}
|
||||
if (i == nfix)
|
||||
@ -1011,7 +1008,7 @@ void ReadData::header(int firstpass)
|
||||
for (n = 0; n < nfix; n++) {
|
||||
if (!fix_header[n]) continue;
|
||||
if (strstr(line,fix_header[n])) {
|
||||
modify->fix[fix_index[n]]->read_data_header(line);
|
||||
fix_index[n]->read_data_header(line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1922,18 +1919,18 @@ void ReadData::impropercoeffs(int which)
|
||||
n = index of fix
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void ReadData::fix(int ifix, char *keyword)
|
||||
void ReadData::fix(Fix *ifix, char *keyword)
|
||||
{
|
||||
int nchunk,eof;
|
||||
|
||||
bigint nline = modify->fix[ifix]->read_data_skip_lines(keyword);
|
||||
bigint nline = ifix->read_data_skip_lines(keyword);
|
||||
|
||||
bigint nread = 0;
|
||||
while (nread < nline) {
|
||||
nchunk = MIN(nline-nread,CHUNK);
|
||||
eof = utils::read_lines_from_file(fp,nchunk,MAXLINE,buffer,me,world);
|
||||
if (eof) error->all(FLERR,"Unexpected end of data file");
|
||||
modify->fix[ifix]->read_data_section(keyword,nchunk,buffer,id_offset);
|
||||
if (eof) error->all(FLERR,"Unexpected end of data file while reading section {}",keyword);
|
||||
ifix->read_data_section(keyword,nchunk,buffer,id_offset);
|
||||
nread += nchunk;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ CommandStyle(read_data,ReadData);
|
||||
#include "command.h"
|
||||
|
||||
namespace LAMMPS_NS {
|
||||
|
||||
class Fix;
|
||||
class ReadData : public Command {
|
||||
public:
|
||||
ReadData(class LAMMPS *);
|
||||
@ -73,7 +73,7 @@ class ReadData : public Command {
|
||||
int groupbit;
|
||||
|
||||
int nfix;
|
||||
int *fix_index;
|
||||
Fix **fix_index;
|
||||
char **fix_header;
|
||||
char **fix_section;
|
||||
|
||||
@ -108,7 +108,7 @@ class ReadData : public Command {
|
||||
void dihedralcoeffs(int);
|
||||
void impropercoeffs(int);
|
||||
|
||||
void fix(int, char *);
|
||||
void fix(Fix *, char *);
|
||||
};
|
||||
|
||||
} // namespace LAMMPS_NS
|
||||
|
||||
@ -122,13 +122,13 @@ TEST_F(GroupTest, EmptyDelete)
|
||||
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group new2 delete xxx"););
|
||||
TEST_FAILURE(".*ERROR: Cannot delete group all.*", command("group all delete"););
|
||||
TEST_FAILURE(".*ERROR: Could not find group delete.*", command("group new0 delete"););
|
||||
TEST_FAILURE(".*ERROR: Cannot delete group currently used by a fix.*",
|
||||
TEST_FAILURE(".*ERROR: Cannot delete group new2 currently used by fix.*",
|
||||
command("group new2 delete"););
|
||||
TEST_FAILURE(".*ERROR: Cannot delete group currently used by a compute.*",
|
||||
TEST_FAILURE(".*ERROR: Cannot delete group new3 currently used by compute.*",
|
||||
command("group new3 delete"););
|
||||
TEST_FAILURE(".*ERROR: Cannot delete group currently used by a dump.*",
|
||||
TEST_FAILURE(".*ERROR: Cannot delete group new4 currently used by dump.*",
|
||||
command("group new4 delete"););
|
||||
TEST_FAILURE(".*ERROR: Cannot delete group currently used by atom_modify.*",
|
||||
TEST_FAILURE(".*ERROR: Cannot delete group new5 currently used by atom_modify.*",
|
||||
command("group new5 delete"););
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user