Merge pull request #3771 from lammps/variable-current
Change how variables check if computes are current
This commit is contained in:
@ -1420,132 +1420,75 @@ will occur when the formula for "vratio" is evaluated later.
|
|||||||
Variable Accuracy
|
Variable Accuracy
|
||||||
"""""""""""""""""
|
"""""""""""""""""
|
||||||
|
|
||||||
Obviously, LAMMPS attempts to evaluate variables containing formulas
|
Obviously, LAMMPS attempts to evaluate variables which contain
|
||||||
(\ *equal* and *atom* style variables) accurately whenever the
|
formulas (\ *equal* and *vector* and *atom* style variables)
|
||||||
evaluation is performed. Depending on what is included in the
|
accurately whenever the evaluation is performed. Depending on what is
|
||||||
formula, this may require invoking a :doc:`compute <compute>`, either
|
included in the formula, this may require invoking a :doc:`compute
|
||||||
directly or indirectly via a thermo keyword, or accessing a value
|
<compute>`, either directly or indirectly via a thermo keyword, or
|
||||||
previously calculated by a compute, or accessing a value calculated
|
accessing a value previously calculated by a compute, or accessing a
|
||||||
and stored by a :doc:`fix <fix>`. If the compute is one that calculates
|
value calculated and stored by a :doc:`fix <fix>`. If the compute is
|
||||||
the pressure or energy of the system, then these quantities need to be
|
one that calculates the energy or pressure of the system, then the
|
||||||
tallied during the evaluation of the interatomic potentials (pair,
|
corresponding energy or virial quantities need to be tallied during
|
||||||
bond, etc) on timesteps that the variable will need the values.
|
the evaluation of the interatomic potentials (pair, bond, etc) on any
|
||||||
|
timestep that the variable needs the tallies. An input script can
|
||||||
|
also request variables be evaluated before or after or in between
|
||||||
|
runs, e.g. by including them in a :doc:`print <print>` command.
|
||||||
|
|
||||||
LAMMPS keeps track of all of this during a :doc:`run <run>` or :doc:`energy minimization <minimize>`. An error will be generated if you
|
LAMMPS keeps track of all of this as it performs a doc:`run <run>` or
|
||||||
attempt to evaluate a variable on timesteps when it cannot produce
|
:doc:`minimize <minimize>` simulation, as well as in between
|
||||||
accurate values. For example, if a :doc:`thermo_style custom <thermo_style>` command prints a variable which accesses
|
simulations. An error will be generated if you attempt to evaluate a
|
||||||
values stored by a :doc:`fix ave/time <fix_ave_time>` command and the
|
variable when LAMMPS knows it cannot produce accurate values. For
|
||||||
timesteps on which thermo output is generated are not multiples of the
|
example, if a :doc:`thermo_style custom <thermo_style>` command prints
|
||||||
averaging frequency used in the fix command, then an error will occur.
|
a variable which accesses values stored by a :doc:`fix ave/time
|
||||||
|
<fix_ave_time>` command and the timesteps on which thermo output is
|
||||||
|
generated are not multiples of the averaging frequency used in the fix
|
||||||
|
command, then an error will occur.
|
||||||
|
|
||||||
An input script can also request variables be evaluated before or
|
However, there are two special cases to be aware when a variable
|
||||||
after or in between runs, e.g. by including them in a
|
requires invocation of a compute (directly or indirectly). The first
|
||||||
:doc:`print <print>` command. In this case, if a compute is needed to
|
is if the variable is evaluated before the first doc:`run <run>` or
|
||||||
evaluate a variable (either directly or indirectly), LAMMPS will not
|
:doc:`minimize <minimize>` command in the input script. In this case,
|
||||||
invoke the compute, but it will use a value previously calculated by
|
LAMMPS will generate an error. This is because many computes require
|
||||||
the compute, and can do this only if it was invoked on the current
|
initializations which have not yet taken place. One example is the
|
||||||
timestep. Fixes will always provide a quantity needed by a variable,
|
calculation of degrees of freedom for temperature computes. Another
|
||||||
but the quantity may or may not be current. This leads to one of
|
example are the computes mentioned above which require tallying of
|
||||||
three kinds of behavior:
|
energy or virial quantities; these values are not tallied until the
|
||||||
|
first simulation begins.
|
||||||
|
|
||||||
(1) The variable may be evaluated accurately. If it contains
|
The second special case is when a variable that depends on a compute
|
||||||
references to a compute or fix, and these values were calculated on
|
is evaluated in between doc:`run <run>` or :doc:`minimize <minimize>`
|
||||||
the last timestep of a preceding run, then they will be accessed and
|
commands. It is possible for other input script commands issued
|
||||||
used by the variable and the result will be accurate.
|
following the previous run, but before the variable is evaluated, to
|
||||||
|
change the system. For example, the doc:`delete_atoms <delete_atoms>`
|
||||||
|
command could be used to remove atoms. Since the compute will not
|
||||||
|
re-initialize itself until the next simulation or it may depend on
|
||||||
|
energy/virial computations performed before the system was changed, it
|
||||||
|
will potentially generate an incorrect answer when evaluated. Note
|
||||||
|
that LAMMPS will not generate an error in this case; the evaluated
|
||||||
|
variable may simply be incorrect.
|
||||||
|
|
||||||
(2) LAMMPS may not be able to evaluate the variable and will generate
|
The way to get around both of these special cases is to perform a
|
||||||
an error message stating so. For example, if the variable requires a
|
0-timestep run before evaluating the variable. For example, these
|
||||||
quantity from a :doc:`compute <compute>` that has not been invoked on
|
commands
|
||||||
the current timestep, LAMMPS will generate an error. This means, for
|
|
||||||
example, that such a variable cannot be evaluated before the first run
|
|
||||||
has occurred. Likewise, in between runs, a variable containing a
|
|
||||||
compute cannot be evaluated unless the compute was invoked on the last
|
|
||||||
timestep of the preceding run, e.g. by thermodynamic output.
|
|
||||||
|
|
||||||
One way to get around this problem is to perform a 0-timestep run
|
|
||||||
before using the variable. For example, these commands
|
|
||||||
|
|
||||||
.. code-block:: LAMMPS
|
.. code-block:: LAMMPS
|
||||||
|
|
||||||
variable t equal temp
|
# delete_atoms random fraction 0.5 yes all NULL 49839
|
||||||
print "Initial temperature = $t"
|
# run 0
|
||||||
|
variable t equal temp # this thermo keyword invokes a temperature compute
|
||||||
|
print "Temperature of system = $t"
|
||||||
run 1000
|
run 1000
|
||||||
|
|
||||||
will generate an error if the run is the first run specified in the
|
will generate an error if the "run 1000" command is the first
|
||||||
input script, because generating a value for the "t" variable requires
|
simulation in the input script. If there were a previous run, these
|
||||||
a compute for calculating the temperature to be invoked.
|
commands will print the correct temperature of the system. But if the
|
||||||
|
:doc:`delete_atoms <delete_atoms>` command is uncommented, the printed
|
||||||
|
temperature will be incorrect, because information stored by
|
||||||
|
temperature compute is no longer valid.
|
||||||
|
|
||||||
However, this sequence of commands would be fine:
|
Both these issues are resolved, if the "run 0" command is uncommented.
|
||||||
|
This is because the "run 0" simulation will initialize (or
|
||||||
.. code-block:: LAMMPS
|
re-initialize) the temperature compute correctly.
|
||||||
|
|
||||||
run 0
|
|
||||||
variable t equal temp
|
|
||||||
print "Initial temperature = $t"
|
|
||||||
run 1000
|
|
||||||
|
|
||||||
The 0-timestep run initializes and invokes various computes, including
|
|
||||||
the one for temperature, so that the value it stores is current and
|
|
||||||
can be accessed by the variable "t" after the run has completed. Note
|
|
||||||
that a 0-timestep run does not alter the state of the system, so it
|
|
||||||
does not change the input state for the 1000-timestep run that
|
|
||||||
follows. Also note that the 0-timestep run must actually use and
|
|
||||||
invoke the compute in question (e.g. via :doc:`thermo <thermo_style>` or
|
|
||||||
:doc:`dump <dump>` output) in order for it to enable the compute to be
|
|
||||||
used in a variable after the run. Thus if you are trying to print a
|
|
||||||
variable that uses a compute you have defined, you can ensure it is
|
|
||||||
invoked on the last timestep of the preceding run by including it in
|
|
||||||
thermodynamic output.
|
|
||||||
|
|
||||||
Unlike computes, :doc:`fixes <fix>` will never generate an error if
|
|
||||||
their values are accessed by a variable in between runs. They always
|
|
||||||
return some value to the variable. However, the value may not be what
|
|
||||||
you expect if the fix has not yet calculated the quantity of interest
|
|
||||||
or it is not current. For example, the :doc:`fix indent <fix_indent>`
|
|
||||||
command stores the force on the indenter. But this is not computed
|
|
||||||
until a run is performed. Thus if a variable attempts to print this
|
|
||||||
value before the first run, zeroes will be output. Again, performing
|
|
||||||
a 0-timestep run before printing the variable has the desired effect.
|
|
||||||
|
|
||||||
(3) The variable may be evaluated incorrectly and LAMMPS may have no
|
|
||||||
way to detect this has occurred. Consider the following sequence of
|
|
||||||
commands:
|
|
||||||
|
|
||||||
.. code-block:: LAMMPS
|
|
||||||
|
|
||||||
pair_coeff 1 1 1.0 1.0
|
|
||||||
run 1000
|
|
||||||
pair_coeff 1 1 1.5 1.0
|
|
||||||
variable e equal pe
|
|
||||||
print "Final potential energy = $e"
|
|
||||||
|
|
||||||
The first run is performed using one setting for the pairwise
|
|
||||||
potential defined by the :doc:`pair_style <pair_style>` and
|
|
||||||
:doc:`pair_coeff <pair_coeff>` commands. The potential energy is
|
|
||||||
evaluated on the final timestep and stored by the :doc:`compute pe
|
|
||||||
<compute_pe>` compute (this is done by the :doc:`thermo_style
|
|
||||||
<thermo_style>` command). Then a pair coefficient is changed,
|
|
||||||
altering the potential energy of the system. When the potential
|
|
||||||
energy is printed via the "e" variable, LAMMPS will use the potential
|
|
||||||
energy value stored by the :doc:`compute pe <compute_pe>` compute,
|
|
||||||
thinking it is current. There are many other commands which could
|
|
||||||
alter the state of the system between runs, causing a variable to
|
|
||||||
evaluate incorrectly.
|
|
||||||
|
|
||||||
The solution to this issue is the same as for case (2) above, namely
|
|
||||||
perform a 0-timestep run before the variable is evaluated to ensure
|
|
||||||
the system is up-to-date. For example, this sequence of commands
|
|
||||||
would print a potential energy that reflected the changed pairwise
|
|
||||||
coefficient:
|
|
||||||
|
|
||||||
.. code-block:: LAMMPS
|
|
||||||
|
|
||||||
pair_coeff 1 1 1.0 1.0
|
|
||||||
run 1000
|
|
||||||
pair_coeff 1 1 1.5 1.0
|
|
||||||
run 0
|
|
||||||
variable e equal pe
|
|
||||||
print "Final potential energy = $e"
|
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -1555,11 +1498,12 @@ Restrictions
|
|||||||
Indexing any formula element by global atom ID, such as an atom value,
|
Indexing any formula element by global atom ID, such as an atom value,
|
||||||
requires the :doc:`atom style <atom_style>` to use a global mapping in
|
requires the :doc:`atom style <atom_style>` to use a global mapping in
|
||||||
order to look up the vector indices. By default, only atom styles
|
order to look up the vector indices. By default, only atom styles
|
||||||
with molecular information create global maps. The :doc:`atom_modify map <atom_modify>` command can override the default, e.g. for
|
with molecular information create global maps. The :doc:`atom_modify
|
||||||
|
map <atom_modify>` command can override the default, e.g. for
|
||||||
atomic-style atom styles.
|
atomic-style atom styles.
|
||||||
|
|
||||||
All *universe*\ - and *uloop*\ -style variables defined in an input script
|
All *universe*\ - and *uloop*\ -style variables defined in an input
|
||||||
must have the same number of values.
|
script must have the same number of values.
|
||||||
|
|
||||||
Related commands
|
Related commands
|
||||||
""""""""""""""""
|
""""""""""""""""
|
||||||
|
|||||||
@ -294,21 +294,15 @@ int DumpVTK::count()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// invoke Computes for per-atom quantities
|
// invoke Computes for per-atom quantities
|
||||||
// only if within a run or minimize
|
// cannot invoke before first run, otherwise invoke if necessary
|
||||||
// else require that computes are current
|
|
||||||
// this prevents a compute from being invoked by the WriteDump class
|
|
||||||
|
|
||||||
if (ncompute) {
|
if (ncompute) {
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
for (i = 0; i < ncompute; i++)
|
error->all(FLERR,"Dump compute cannot be invoked before first run");
|
||||||
if (compute[i]->invoked_peratom != update->ntimestep)
|
for (i = 0; i < ncompute; i++) {
|
||||||
error->all(FLERR,"Compute used in dump between runs is not current");
|
if (!(compute[i]->invoked_flag & Compute::INVOKED_PERATOM)) {
|
||||||
} else {
|
compute[i]->compute_peratom();
|
||||||
for (i = 0; i < ncompute; i++) {
|
compute[i]->invoked_flag |= Compute::INVOKED_PERATOM;
|
||||||
if (!(compute[i]->invoked_flag & Compute::INVOKED_PERATOM)) {
|
|
||||||
compute[i]->compute_peratom();
|
|
||||||
compute[i]->invoked_flag |= Compute::INVOKED_PERATOM;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -556,21 +556,15 @@ int DumpCustom::count()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// invoke Computes for per-atom quantities
|
// invoke Computes for per-atom quantities
|
||||||
// only if within a run or minimize
|
// cannot invoke before first run, otherwise invoke if necessary
|
||||||
// else require that computes are current
|
|
||||||
// this prevents a compute from being invoked by the WriteDump class
|
|
||||||
|
|
||||||
if (ncompute) {
|
if (ncompute) {
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
for (i = 0; i < ncompute; i++)
|
error->all(FLERR,"Dump compute cannot be invoked before first run");
|
||||||
if (compute[i]->invoked_peratom != update->ntimestep)
|
for (i = 0; i < ncompute; i++) {
|
||||||
error->all(FLERR,"Compute used in dump between runs is not current");
|
if (!(compute[i]->invoked_flag & Compute::INVOKED_PERATOM)) {
|
||||||
} else {
|
compute[i]->compute_peratom();
|
||||||
for (i = 0; i < ncompute; i++) {
|
compute[i]->invoked_flag |= Compute::INVOKED_PERATOM;
|
||||||
if (!(compute[i]->invoked_flag & Compute::INVOKED_PERATOM)) {
|
|
||||||
compute[i]->compute_peratom();
|
|
||||||
compute[i]->invoked_flag |= Compute::INVOKED_PERATOM;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -522,21 +522,15 @@ int DumpGrid::count()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// invoke Computes for per-grid quantities
|
// invoke Computes for per-grid quantities
|
||||||
// only if within a run or minimize
|
// cannot invoke before first run, otherwise invoke if necessary
|
||||||
// else require that computes are current
|
|
||||||
// this prevents a compute from being invoked by the WriteDump class
|
|
||||||
|
|
||||||
if (ncompute) {
|
if (ncompute) {
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
for (i = 0; i < ncompute; i++)
|
error->all(FLERR,"Dump compute cannot be invoked before first run");
|
||||||
if (compute[i]->invoked_pergrid != update->ntimestep)
|
for (i = 0; i < ncompute; i++) {
|
||||||
error->all(FLERR,"Compute {} used in dump between runs is not current", compute[i]->id);
|
if (!(compute[i]->invoked_flag & Compute::INVOKED_PERGRID)) {
|
||||||
} else {
|
compute[i]->compute_pergrid();
|
||||||
for (i = 0; i < ncompute; i++) {
|
compute[i]->invoked_flag |= Compute::INVOKED_PERGRID;
|
||||||
if (!(compute[i]->invoked_flag & Compute::INVOKED_PERGRID)) {
|
|
||||||
compute[i]->compute_pergrid();
|
|
||||||
compute[i]->invoked_flag |= Compute::INVOKED_PERGRID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -664,20 +664,14 @@ void DumpImage::write()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// invoke Compute for per-grid quantities
|
// invoke Compute for per-grid quantities
|
||||||
// only if within a run or minimize
|
// cannot invoke before first run, otherwise invoke if necessary
|
||||||
// else require the compute is current
|
|
||||||
// this prevents the compute from being invoked by the WriteDump class
|
|
||||||
|
|
||||||
if (grid_compute) {
|
if (grid_compute) {
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (grid_compute->invoked_pergrid != update->ntimestep)
|
error->all(FLERR,"Grid compute used in dump image cannot be invoked before first run");
|
||||||
error->all(FLERR,"Grid compute {} used in dump image between runs is not current",
|
if (!(grid_compute->invoked_flag & Compute::INVOKED_PERGRID)) {
|
||||||
grid_compute->id);
|
grid_compute->compute_pergrid();
|
||||||
} else {
|
grid_compute->invoked_flag |= Compute::INVOKED_PERGRID;
|
||||||
if (!(grid_compute->invoked_flag & Compute::INVOKED_PERGRID)) {
|
|
||||||
grid_compute->compute_pergrid();
|
|
||||||
grid_compute->invoked_flag |= Compute::INVOKED_PERGRID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -325,21 +325,15 @@ int DumpLocal::count()
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
// invoke Computes for local quantities
|
// invoke Computes for local quantities
|
||||||
// only if within a run or minimize
|
// cannot invoke before first run, otherwise invoke if necessary
|
||||||
// else require that computes are current
|
|
||||||
// this prevents a compute from being invoked by the WriteDump class
|
|
||||||
|
|
||||||
if (ncompute) {
|
if (ncompute) {
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
for (i = 0; i < ncompute; i++)
|
error->all(FLERR,"Dump compute cannot be invoked before first run");
|
||||||
if (compute[i]->invoked_local != update->ntimestep)
|
for (i = 0; i < ncompute; i++) {
|
||||||
error->all(FLERR,"Compute used in dump between runs is not current");
|
if (!(compute[i]->invoked_flag & Compute::INVOKED_LOCAL)) {
|
||||||
} else {
|
compute[i]->compute_local();
|
||||||
for (i = 0; i < ncompute; i++) {
|
compute[i]->invoked_flag |= Compute::INVOKED_LOCAL;
|
||||||
if (!(compute[i]->invoked_flag & Compute::INVOKED_LOCAL)) {
|
|
||||||
compute[i]->compute_local();
|
|
||||||
compute[i]->invoked_flag |= Compute::INVOKED_LOCAL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "modify.h"
|
#include "modify.h"
|
||||||
|
#include "update.h"
|
||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -92,6 +93,14 @@ void ResetAtomsImage::command(int narg, char **arg)
|
|||||||
"c_ifmax_r_i_f[*] c_ifmin_r_i_f[*]");
|
"c_ifmax_r_i_f[*] c_ifmin_r_i_f[*]");
|
||||||
|
|
||||||
// trigger computes
|
// trigger computes
|
||||||
|
// need to ensure update->first_update = 1
|
||||||
|
// to allow this input script command prior to first run/minimize
|
||||||
|
// this is b/c internal variables are evaulated which invoke computes
|
||||||
|
// that will trigger an error unless first_update = 1
|
||||||
|
// reset update->first_update when done
|
||||||
|
|
||||||
|
int first_update_saved = update->first_update;
|
||||||
|
update->first_update = 1;
|
||||||
|
|
||||||
frags->compute_peratom();
|
frags->compute_peratom();
|
||||||
chunk->compute_peratom();
|
chunk->compute_peratom();
|
||||||
@ -100,6 +109,8 @@ void ResetAtomsImage::command(int narg, char **arg)
|
|||||||
ifmax->compute_array();
|
ifmax->compute_array();
|
||||||
cdist->compute_peratom();
|
cdist->compute_peratom();
|
||||||
|
|
||||||
|
update->first_update = first_update_saved;
|
||||||
|
|
||||||
// reset image flags for atoms in group
|
// reset image flags for atoms in group
|
||||||
|
|
||||||
const int *const mask = atom->mask;
|
const int *const mask = atom->mask;
|
||||||
|
|||||||
@ -1118,7 +1118,7 @@ int Thermo::add_variable(const char *id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
check whether temperature compute is defined, available, and current
|
check whether temperature compute is defined, active, and needs invoking
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Thermo::check_temp(const std::string &keyword)
|
void Thermo::check_temp(const std::string &keyword)
|
||||||
@ -1126,18 +1126,16 @@ void Thermo::check_temp(const std::string &keyword)
|
|||||||
if (!temperature)
|
if (!temperature)
|
||||||
error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init temperature",
|
error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init temperature",
|
||||||
keyword);
|
keyword);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (temperature->invoked_scalar != update->ntimestep)
|
error->all(FLERR,"Thermo keyword {} cannot be invoked before first run",keyword);
|
||||||
error->all(FLERR, "Compute {} {} used in variable thermo keyword between runs is not current",
|
if (!(temperature->invoked_flag & Compute::INVOKED_SCALAR)) {
|
||||||
temperature->style, temperature->id);
|
|
||||||
} else if (!(temperature->invoked_flag & Compute::INVOKED_SCALAR)) {
|
|
||||||
temperature->compute_scalar();
|
temperature->compute_scalar();
|
||||||
temperature->invoked_flag |= Compute::INVOKED_SCALAR;
|
temperature->invoked_flag |= Compute::INVOKED_SCALAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
check whether potential energy compute is defined, available, and current
|
check whether potential energy compute is defined, active, and needs invoking
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Thermo::check_pe(const std::string &keyword)
|
void Thermo::check_pe(const std::string &keyword)
|
||||||
@ -1147,47 +1145,41 @@ void Thermo::check_pe(const std::string &keyword)
|
|||||||
if (!pe)
|
if (!pe)
|
||||||
error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init potential energy",
|
error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init potential energy",
|
||||||
keyword);
|
keyword);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (pe->invoked_scalar != update->ntimestep)
|
error->all(FLERR,"Thermo keyword {} cannot be invoked before first run",keyword);
|
||||||
error->all(FLERR, "Compute {} {} used in variable thermo keyword between runs is not current",
|
if (!(pe->invoked_flag & Compute::INVOKED_SCALAR)) {
|
||||||
pe->style, pe->id);
|
|
||||||
} else {
|
|
||||||
pe->compute_scalar();
|
pe->compute_scalar();
|
||||||
pe->invoked_flag |= Compute::INVOKED_SCALAR;
|
pe->invoked_flag |= Compute::INVOKED_SCALAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
check whether scalar pressure compute is defined, available, and current
|
check whether scalar pressure compute is defined, active, and needs invoking
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Thermo::check_press_scalar(const std::string &keyword)
|
void Thermo::check_press_scalar(const std::string &keyword)
|
||||||
{
|
{
|
||||||
if (!pressure)
|
if (!pressure)
|
||||||
error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init press", keyword);
|
error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init press", keyword);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (pressure->invoked_scalar != update->ntimestep)
|
error->all(FLERR,"Thermo keyword {} cannot be invoked before first run",keyword);
|
||||||
error->all(FLERR, "Compute {} {} used in variable thermo keyword between runs is not current",
|
if (!(pressure->invoked_flag & Compute::INVOKED_SCALAR)) {
|
||||||
pressure->style, pressure->id);
|
|
||||||
} else if (!(pressure->invoked_flag & Compute::INVOKED_SCALAR)) {
|
|
||||||
pressure->compute_scalar();
|
pressure->compute_scalar();
|
||||||
pressure->invoked_flag |= Compute::INVOKED_SCALAR;
|
pressure->invoked_flag |= Compute::INVOKED_SCALAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
check whether pressure tensor compute is defined, available, and current
|
check whether tensor pressure compute is defined, active, and needs invoking
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Thermo::check_press_vector(const std::string &keyword)
|
void Thermo::check_press_vector(const std::string &keyword)
|
||||||
{
|
{
|
||||||
if (!pressure)
|
if (!pressure)
|
||||||
error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init press", keyword);
|
error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init press", keyword);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (pressure->invoked_vector != update->ntimestep)
|
error->all(FLERR,"Thermo keyword {} cannot be invoked before first run",keyword);
|
||||||
error->all(FLERR, "Compute {} {} used in variable thermo keyword between runs is not current",
|
if (!(pressure->invoked_flag & Compute::INVOKED_VECTOR)) {
|
||||||
pressure->style, pressure->id);
|
|
||||||
} else if (!(pressure->invoked_flag & Compute::INVOKED_VECTOR)) {
|
|
||||||
pressure->compute_vector();
|
pressure->compute_vector();
|
||||||
pressure->invoked_flag |= Compute::INVOKED_VECTOR;
|
pressure->invoked_flag |= Compute::INVOKED_VECTOR;
|
||||||
}
|
}
|
||||||
@ -1214,8 +1206,6 @@ int Thermo::evaluate_keyword(const std::string &word, double *answer)
|
|||||||
|
|
||||||
// invoke a lo-level thermo routine to compute the variable value
|
// invoke a lo-level thermo routine to compute the variable value
|
||||||
// if keyword requires a compute, error if thermo doesn't use the compute
|
// if keyword requires a compute, error if thermo doesn't use the compute
|
||||||
// if inbetween runs and needed compute is not current, error
|
|
||||||
// if in middle of run and needed compute is not current, invoke it
|
|
||||||
// for keywords that use energy (evdwl, ebond, etc):
|
// for keywords that use energy (evdwl, ebond, etc):
|
||||||
// check if energy was tallied on this timestep and set pe->invoked_flag
|
// check if energy was tallied on this timestep and set pe->invoked_flag
|
||||||
// this will trigger next timestep for energy tallying via addstep()
|
// this will trigger next timestep for energy tallying via addstep()
|
||||||
|
|||||||
@ -1505,10 +1505,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
|||||||
|
|
||||||
if (nbracket == 0 && compute->scalar_flag && lowercase) {
|
if (nbracket == 0 && compute->scalar_flag && lowercase) {
|
||||||
|
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (compute->invoked_scalar != update->ntimestep)
|
print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar);
|
||||||
print_var_error(FLERR,"Compute used in variable between runs is not current",ivar);
|
if (!(compute->invoked_flag & Compute::INVOKED_SCALAR)) {
|
||||||
} else if (!(compute->invoked_flag & Compute::INVOKED_SCALAR)) {
|
|
||||||
compute->compute_scalar();
|
compute->compute_scalar();
|
||||||
compute->invoked_flag |= Compute::INVOKED_SCALAR;
|
compute->invoked_flag |= Compute::INVOKED_SCALAR;
|
||||||
}
|
}
|
||||||
@ -1528,10 +1527,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
|||||||
if (index1 > compute->size_vector &&
|
if (index1 > compute->size_vector &&
|
||||||
compute->size_vector_variable == 0)
|
compute->size_vector_variable == 0)
|
||||||
print_var_error(FLERR,"Variable formula compute vector is accessed out-of-range",ivar,0);
|
print_var_error(FLERR,"Variable formula compute vector is accessed out-of-range",ivar,0);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (compute->invoked_vector != update->ntimestep)
|
print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar);
|
||||||
print_var_error(FLERR,"Compute used in variable between runs is not current",ivar);
|
if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) {
|
||||||
} else if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) {
|
|
||||||
compute->compute_vector();
|
compute->compute_vector();
|
||||||
compute->invoked_flag |= Compute::INVOKED_VECTOR;
|
compute->invoked_flag |= Compute::INVOKED_VECTOR;
|
||||||
}
|
}
|
||||||
@ -1555,10 +1553,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
|||||||
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
|
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
|
||||||
if (index2 > compute->size_array_cols)
|
if (index2 > compute->size_array_cols)
|
||||||
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
|
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (compute->invoked_array != update->ntimestep)
|
print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar);
|
||||||
print_var_error(FLERR,"Compute used in variable between runs is not current",ivar);
|
if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) {
|
||||||
} else if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) {
|
|
||||||
compute->compute_array();
|
compute->compute_array();
|
||||||
compute->invoked_flag |= Compute::INVOKED_ARRAY;
|
compute->invoked_flag |= Compute::INVOKED_ARRAY;
|
||||||
}
|
}
|
||||||
@ -1583,10 +1580,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
|||||||
print_var_error(FLERR,"Compute global vector in atom-style variable formula",ivar);
|
print_var_error(FLERR,"Compute global vector in atom-style variable formula",ivar);
|
||||||
if (compute->size_vector == 0)
|
if (compute->size_vector == 0)
|
||||||
print_var_error(FLERR,"Variable formula compute vector is zero length",ivar);
|
print_var_error(FLERR,"Variable formula compute vector is zero length",ivar);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (compute->invoked_vector != update->ntimestep)
|
print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar);
|
||||||
print_var_error(FLERR,"Compute used in variable between runs is not current",ivar);
|
if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) {
|
||||||
} else if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) {
|
|
||||||
compute->compute_vector();
|
compute->compute_vector();
|
||||||
compute->invoked_flag |= Compute::INVOKED_VECTOR;
|
compute->invoked_flag |= Compute::INVOKED_VECTOR;
|
||||||
}
|
}
|
||||||
@ -1608,10 +1604,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
|||||||
print_var_error(FLERR,"Compute global vector in atom-style variable formula",ivar);
|
print_var_error(FLERR,"Compute global vector in atom-style variable formula",ivar);
|
||||||
if (compute->size_array_rows == 0)
|
if (compute->size_array_rows == 0)
|
||||||
print_var_error(FLERR,"Variable formula compute array is zero length",ivar);
|
print_var_error(FLERR,"Variable formula compute array is zero length",ivar);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (compute->invoked_array != update->ntimestep)
|
print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar);
|
||||||
print_var_error(FLERR,"Compute used in variable between runs is not current",ivar);
|
if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) {
|
||||||
} else if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) {
|
|
||||||
compute->compute_array();
|
compute->compute_array();
|
||||||
compute->invoked_flag |= Compute::INVOKED_ARRAY;
|
compute->invoked_flag |= Compute::INVOKED_ARRAY;
|
||||||
}
|
}
|
||||||
@ -1628,10 +1623,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
|||||||
} else if (nbracket == 1 && compute->peratom_flag &&
|
} else if (nbracket == 1 && compute->peratom_flag &&
|
||||||
compute->size_peratom_cols == 0) {
|
compute->size_peratom_cols == 0) {
|
||||||
|
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (compute->invoked_peratom != update->ntimestep)
|
print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar);
|
||||||
print_var_error(FLERR,"Compute used in variable between runs is not current",ivar);
|
if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
||||||
} else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
|
||||||
compute->compute_peratom();
|
compute->compute_peratom();
|
||||||
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
||||||
}
|
}
|
||||||
@ -1646,10 +1640,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
|||||||
|
|
||||||
if (index2 > compute->size_peratom_cols)
|
if (index2 > compute->size_peratom_cols)
|
||||||
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
|
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (compute->invoked_peratom != update->ntimestep)
|
print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar);
|
||||||
print_var_error(FLERR,"Compute used in variable between runs is not current",ivar);
|
if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
||||||
} else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
|
||||||
compute->compute_peratom();
|
compute->compute_peratom();
|
||||||
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
||||||
}
|
}
|
||||||
@ -1670,10 +1663,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
|||||||
print_var_error(FLERR,"Per-atom compute in equal-style variable formula",ivar);
|
print_var_error(FLERR,"Per-atom compute in equal-style variable formula",ivar);
|
||||||
if (treetype == VECTOR)
|
if (treetype == VECTOR)
|
||||||
print_var_error(FLERR,"Per-atom compute in vector-style variable formula",ivar);
|
print_var_error(FLERR,"Per-atom compute in vector-style variable formula",ivar);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (compute->invoked_peratom != update->ntimestep)
|
print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar);
|
||||||
print_var_error(FLERR,"Compute used in variable between runs is not current",ivar);
|
if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
||||||
} else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
|
||||||
compute->compute_peratom();
|
compute->compute_peratom();
|
||||||
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
||||||
}
|
}
|
||||||
@ -1695,10 +1687,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
|||||||
print_var_error(FLERR,"Per-atom compute in vector-style variable formula",ivar);
|
print_var_error(FLERR,"Per-atom compute in vector-style variable formula",ivar);
|
||||||
if (index1 > compute->size_peratom_cols)
|
if (index1 > compute->size_peratom_cols)
|
||||||
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
|
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (compute->invoked_peratom != update->ntimestep)
|
print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar);
|
||||||
print_var_error(FLERR,"Compute used in variable between runs is not current",ivar);
|
if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
||||||
} else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) {
|
|
||||||
compute->compute_peratom();
|
compute->compute_peratom();
|
||||||
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
compute->invoked_flag |= Compute::INVOKED_PERATOM;
|
||||||
}
|
}
|
||||||
@ -4163,10 +4154,9 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t
|
|||||||
print_var_error(FLERR,mesg,ivar);
|
print_var_error(FLERR,mesg,ivar);
|
||||||
}
|
}
|
||||||
if (index == 0 && compute->vector_flag) {
|
if (index == 0 && compute->vector_flag) {
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (compute->invoked_vector != update->ntimestep)
|
print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar);
|
||||||
print_var_error(FLERR,"Compute used in variable between runs is not current",ivar);
|
if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) {
|
||||||
} else if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) {
|
|
||||||
compute->compute_vector();
|
compute->compute_vector();
|
||||||
compute->invoked_flag |= Compute::INVOKED_VECTOR;
|
compute->invoked_flag |= Compute::INVOKED_VECTOR;
|
||||||
}
|
}
|
||||||
@ -4175,10 +4165,9 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t
|
|||||||
} else if (index && compute->array_flag) {
|
} else if (index && compute->array_flag) {
|
||||||
if (index > compute->size_array_cols)
|
if (index > compute->size_array_cols)
|
||||||
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
|
print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0);
|
||||||
if (update->whichflag == 0) {
|
if (update->first_update == 0)
|
||||||
if (compute->invoked_array != update->ntimestep)
|
print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar);
|
||||||
print_var_error(FLERR,"Compute used in variable between runs is not current",ivar);
|
if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) {
|
||||||
} else if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) {
|
|
||||||
compute->compute_array();
|
compute->compute_array();
|
||||||
compute->invoked_flag |= Compute::INVOKED_ARRAY;
|
compute->invoked_flag |= Compute::INVOKED_ARRAY;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,9 @@
|
|||||||
%pointer_cast(void *, double *, void_p_to_double_p);
|
%pointer_cast(void *, double *, void_p_to_double_p);
|
||||||
%pointer_cast(void *, double **, void_p_to_double_2d_p);
|
%pointer_cast(void *, double **, void_p_to_double_2d_p);
|
||||||
|
|
||||||
|
#if !defined(SWIGLUA)
|
||||||
%cstring_output_maxsize(char *buffer, int buf_size);
|
%cstring_output_maxsize(char *buffer, int buf_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user