Merge pull request #3179 from akohlmey/thermo-refactor-plus-yaml

Refactoring of Thermo class and new thermo style yaml
This commit is contained in:
Axel Kohlmeyer
2022-03-22 20:17:25 -04:00
committed by GitHub
19 changed files with 1096 additions and 1096 deletions

View File

@ -21,7 +21,8 @@ YAML
print """---
timestep: $(step)
pe: $(pe)
ke: $(ke)""" file current_state.yaml screen no
ke: $(ke)
...""" file current_state.yaml screen no
.. code-block:: yaml
:caption: current_state.yaml
@ -51,6 +52,58 @@ JSON
"ke": 2.4962152903997174569
}
YAML format thermo_style output
===============================
.. versionadded:: 24Mar2022
LAMMPS supports the thermo style "yaml" and for "custom" style
thermodynamic output the format can be changed to YAML with
:doc:`thermo_modify line yaml <thermo_modify>`. This will produce a
block of output in a compact YAML format - one "document" per run - of
the following style:
.. code-block:: yaml
---
keywords: [Step, Temp, E_pair, E_mol, TotEng, Press, ]
data:
- [100, 0.757453103239935, -5.7585054860159, 0, -4.62236133677021, 0.207261053624721, ]
- [110, 0.759322359337036, -5.7614668389562, 0, -4.62251889318624, 0.194314975399602, ]
- [120, 0.759372342462676, -5.76149365656489, 0, -4.62247073844943, 0.191600048851267, ]
- [130, 0.756833027516501, -5.75777334823494, 0, -4.62255928350835, 0.208792327853067, ]
...
This data can be extracted and parsed from a log file using python with:
.. code-block:: python
import re, yaml
docs = ""
with open("log.lammps") as f:
for line in f:
m = re.search(r"^(keywords:.*$|data:$|---$|\.\.\.$| - \[.*\]$)", line)
if m: docs += m.group(0) + '\n'
thermo = list(yaml.load_all(docs, Loader=yaml.SafeLoader))
print("Number of runs: ", len(thermo))
print(thermo[1]['keywords'][4], ' = ', thermo[1]['data'][2][4])
After loading the YAML data, `thermo` is a list containing a dictionary
for each "run" where the tag "keywords" maps to the list of thermo
header strings and the tag "data" has a list of lists where the outer
list represents the lines of output and the inner list the values of the
columns matching the header keywords for that step. The second print()
command for example will print the header string for the fifth keyword
of the second run and the corresponding value for the third output line
of that run:
.. parsed-literal::
Number of runs: 2
TotEng = -4.62140097780047
Writing continuous data during a simulation
===========================================

View File

@ -1,27 +1,54 @@
Thermodynamic output options
============================
There is one class that computes and prints thermodynamic information
to the screen and log file; see the file thermo.cpp.
The ``Thermo`` class computes and prints thermodynamic information to
the screen and log file; see the files ``thermo.cpp`` and ``thermo.h``.
There are two styles defined in thermo.cpp: "one" and "multi". There
is also a flexible "custom" style which allows the user to explicitly
list keywords for quantities to print when thermodynamic info is
output. See the :doc:`thermo_style <thermo_style>` command for a list
of defined quantities.
There are four styles defined in ``thermo.cpp``: "one", "multi", "yaml",
and "custom". The "custom" style allows the user to explicitly list
keywords for individual quantities to print when thermodynamic output is
generated. The others have a fixed list of keywords. See the
:doc:`thermo_style <thermo_style>` command for a list of available
quantities. The formatting of the "custom" style defaults to the "one"
style, but can be adapted using :doc:`thermo_modify line <thermo_modify>`.
The thermo styles (one, multi, etc) are simply lists of keywords.
Adding a new style thus only requires defining a new list of keywords.
Search for the word "customize" with references to "thermo style" in
thermo.cpp to see the two locations where code will need to be added.
The thermo styles (one, multi, etc) are defined by lists of keywords
with associated formats for integer and floating point numbers and
identified but an enumerator constant. Adding a new style thus mostly
requires defining a new list of keywords and the associated formats and
then inserting the required output processing where the enumerators are
identified. Search for the word "CUSTOMIZATION" with references to
"thermo style" in the ``thermo.cpp`` file to see the locations where
code will need to be added. The member function ``Thermo::header()``
prints output at the very beginning of a thermodynamic output block and
can be used to print column headers or other front matter. The member
function ``Thermo::footer()`` prints output at the end of a
thermodynamic output block. The formatting of the output is done by
assembling a "line" (which may span multiple lines if the style inserts
newline characters ("\n" as in the "multi" style).
New keywords can also be added to thermo.cpp to compute new quantities
for output. Search for the word "customize" with references to
"keyword" in thermo.cpp to see the several locations where code will
need to be added.
New thermodynamic keywords can also be added to ``thermo.cpp`` to
compute new quantities for output. Search for the word "CUSTOMIZATION"
with references to "keyword" in ``thermo.cpp`` to see the several
locations where code will need to be added. Effectively, you need to
define a member function that computes the property, add an if statement
in ``Thermo::parse_fields()`` where the corresponding header string for
the keyword and the function pointer is registered by calling the
``Thermo::addfield()`` method, and add an if statement in
``Thermo::evaluate_keyword()`` which is called from the ``Variable``
class when a thermo keyword is encountered.
Note that the :doc:`thermo_style custom <thermo_style>` command already allows
for thermo output of quantities calculated by :doc:`fixes <fix>`,
:doc:`computes <compute>`, and :doc:`variables <variable>`. Thus, it may
be simpler to compute what you wish via one of those constructs, than
by adding a new keyword to the thermo command.
.. note::
The third argument to ``Thermo::addfield()`` is a flag indicating
whether the function for the keyword computes a floating point
(FLOAT), regular integer (INT), or big integer (BIGINT) value. This
information is used for formatting the thermodynamic output. Inside
the function the result must then be stored either in the ``dvalue``,
``ivalue`` or ``bivalue`` member variable, respectively.
Since the :doc:`thermo_style custom <thermo_style>` command allows to
use output of quantities calculated by :doc:`fixes <fix>`,
:doc:`computes <compute>`, and :doc:`variables <variable>`, it may often
be simpler to compute what you wish via one of those constructs, rather
than by adding a new keyword to the thermo_style command.

View File

@ -1,8 +1,8 @@
Variable options
================
There is one class that computes and stores :doc:`variable <variable>`
information in LAMMPS; see the file variable.cpp. The value
The ``Variable`` class computes and stores :doc:`variable <variable>`
information in LAMMPS; see the file ``variable.cpp``. The value
associated with a variable can be periodically printed to the screen
via the :doc:`print <print>`, :doc:`fix print <fix_print>`, or
:doc:`thermo_style custom <thermo_style>` commands. Variables of style
@ -19,21 +19,22 @@ of arguments:
compute values = c_mytemp[0], c_thermo_press[3], ...
Adding keywords for the :doc:`thermo_style custom <thermo_style>`
command (which can then be accessed by variables) is discussed on the
:doc:`Modify thermo <Modify_thermo>` doc page.
command (which can then be accessed by variables) is discussed in the
:doc:`Modify thermo <Modify_thermo>` documentation.
Adding a new math function of one or two arguments can be done by
editing one section of the Variable::evaluate() method. Search for
editing one section of the ``Variable::evaluate()`` method. Search for
the word "customize" to find the appropriate location.
Adding a new group function can be done by editing one section of the
Variable::evaluate() method. Search for the word "customize" to find
the appropriate location. You may need to add a new method to the
Group class as well (see the group.cpp file).
``Variable::evaluate()`` method. Search for the word "customize" to
find the appropriate location. You may need to add a new method to the
Group class as well (see the ``group.cpp`` file).
Accessing a new atom-based vector can be done by editing one section
of the Variable::evaluate() method. Search for the word "customize"
to find the appropriate location.
Adding new :doc:`compute styles <compute>` (whose calculated values can
then be accessed by variables) is discussed on the :doc:`Modify compute <Modify_compute>` doc page.
then be accessed by variables) is discussed in the :doc:`Modify compute
<Modify_compute>` documentation.

View File

@ -187,7 +187,7 @@ folder that the dynamic loader searches or inside of the installed
folders are searched by default by Python or the LAMMPS Python
package.
.. versionchanged:: TBD
.. versionchanged:: 24Mar2022
.. note::

View File

@ -63,8 +63,10 @@ Examples
Description
"""""""""""
.. versionchanged:: 24Mar2022
Implement a lattice-Boltzmann fluid on a uniform mesh covering the
LAMMPS simulation domain. Note that this fix was updated in 2021 and is
LAMMPS simulation domain. Note that this fix was updated in 2022 and is
not backward compatible with the previous version. If you need the
previous version, please download an older version of LAMMPS. The MD
particles described by *group-ID* apply a velocity dependent force to

View File

@ -32,18 +32,20 @@ The content and format of what is printed is controlled by the
:doc:`thermo_style <thermo_style>` and
:doc:`thermo_modify <thermo_modify>` commands.
Instead of a numeric value, N can be specified as an :doc:`equal-style variable <variable>`, which should be specified as v_name, where
name is the variable name. In this case, the variable is evaluated at
the beginning of a run to determine the next timestep at which
thermodynamic info will be written out. On that timestep, the
variable will be evaluated again to determine the next timestep, etc.
Thus the variable should return timestep values. See the stagger()
and logfreq() and stride() math functions for :doc:`equal-style variables <variable>`, as examples of useful functions to use in
this context. Other similar math functions could easily be added as
options for :doc:`equal-style variables <variable>`.
Instead of a numeric value, N can be specified as an :doc:`equal-style
variable <variable>`, which should be specified as v_name, where name is
the variable name. In this case, the variable is evaluated at the
beginning of a run to determine the next timestep at which thermodynamic
info will be written out. On that timestep, the variable will be
evaluated again to determine the next timestep, etc. Thus the variable
should return timestep values. See the stagger() and logfreq() and
stride() math functions for :doc:`equal-style variables <variable>`, as
examples of useful functions to use in this context. Other similar math
functions could easily be added as options for :doc:`equal-style
variables <variable>`.
For example, the following commands will output thermodynamic info at
timesteps 0,10,20,30,100,200,300,1000,2000,etc:
timesteps 0, 10, 20, 30, 100, 200, 300, 1000, 2000, *etc*:
.. code-block:: LAMMPS

View File

@ -20,7 +20,7 @@ Syntax
*warn* value = *ignore* or *reset* or *default* or a number
*norm* value = *yes* or *no*
*flush* value = *yes* or *no*
*line* value = *one* or *multi*
*line* value = *one* or *multi* or *yaml*
*format* values = *line* string, *int* string, *float* string, M string, or *none*
string = C-style format string
M = integer from 1 to N, where N = # of quantities being output
@ -36,35 +36,35 @@ Examples
thermo_modify temp myTemp format 3 %15.8g
thermo_modify temp myTemp format line "%ld %g %g %15.8g"
thermo_modify line multi format float %g
themos_modify line yaml format none
Description
"""""""""""
Set options for how thermodynamic information is computed and printed
by LAMMPS.
Set options for how thermodynamic information is computed and printed by
LAMMPS.
.. note::
These options apply to the currently defined thermo style. When
These options apply to the *currently defined* thermo style. When
you specify a :doc:`thermo_style <thermo_style>` command, all
thermodynamic settings are restored to their default values, including
those previously reset by a thermo_modify command. Thus if your input
script specifies a thermo_style command, you should use the
thermo_modify command after it.
thermodynamic settings are restored to their default values,
including those previously reset by a thermo_modify command. Thus if
your input script specifies a thermo_style command, you should use
the thermo_modify command **after** it.
The *lost* keyword determines whether LAMMPS checks for lost atoms
each time it computes thermodynamics and what it does if atoms are
lost. An atom can be "lost" if it moves across a non-periodic
simulation box :doc:`boundary <boundary>` or if it moves more than a box
length outside the simulation domain (or more than a processor
sub-domain length) before reneighboring occurs. The latter case is
typically due to bad dynamics, e.g. too large a timestep or huge
forces and velocities. If the value is *ignore*, LAMMPS does not
check for lost atoms. If the value is *error* or *warn*, LAMMPS
checks and either issues an error or warning. The code will exit with
an error and continue with a warning. A warning will only be issued
once, the first time an atom is lost. This can be a useful debugging
option.
The *lost* keyword determines whether LAMMPS checks for lost atoms each
time it computes thermodynamics and what it does if atoms are lost. An
atom can be "lost" if it moves across a non-periodic simulation box
:doc:`boundary <boundary>` or if it moves more than a box length outside
the simulation domain (or more than a processor sub-domain length)
before reneighboring occurs. The latter case is typically due to bad
dynamics, e.g. too large a timestep or huge forces and velocities. If
the value is *ignore*, LAMMPS does not check for lost atoms. If the
value is *error* or *warn*, LAMMPS checks and either issues an error or
warning. The code will exit with an error and continue with a warning.
A warning will only be issued once, the first time an atom is lost.
This can be a useful debugging option.
The *lost/bond* keyword determines whether LAMMPS throws an error or
not if an atom in a bonded interaction (bond, angle, etc) cannot be
@ -109,55 +109,55 @@ will be reset to zero, and with the value *default*, the counter is
reset and the limit set to 100. An example usage of either *reset* or
*default* would be to re-enable warnings that were disabled or have
reached the limit during equilibration, where the warnings would be
acceptable while the system is still adjusting, but then change
to all warnings for the production run, where they would indicate
problems that would require a closer look at what is causing them.
acceptable while the system is still adjusting, but then change to all
warnings for the production run, where they would indicate problems that
would require a closer look at what is causing them.
The *norm* keyword determines whether various thermodynamic output
values are normalized by the number of atoms or not, depending on
whether it is set to *yes* or *no*\ . Different unit styles have
different defaults for this setting (see below). Even if *norm* is
set to *yes*, a value is only normalized if it is an "extensive"
quantity, meaning that it scales with the number of atoms in the
system. For the thermo keywords described by the page for the
:doc:`thermo_style <thermo_style>` command, all energy-related keywords
are extensive, such as *pe* or *ebond* or *enthalpy*\ . Other keywords
such as *temp* or *press* are "intensive" meaning their value is
independent (in a statistical sense) of the number of atoms in the
system and thus are never normalized. For thermodynamic output values
extracted from fixes and computes in a :doc:`thermo_style custom <thermo_style>` command, the page for the individual
:doc:`fix <fix>` or :doc:`compute <compute>` lists whether the value is
"extensive" or "intensive" and thus whether it is normalized.
Thermodynamic output values calculated by a variable formula are
assumed to be "intensive" and thus are never normalized. You can
always include a divide by the number of atoms in the variable formula
if this is not the case.
different defaults for this setting (see below). Even if *norm* is set
to *yes*, a value is only normalized if it is an "extensive" quantity,
meaning that it scales with the number of atoms in the system. For the
thermo keywords described by the page for the :doc:`thermo_style
<thermo_style>` command, all energy-related keywords are extensive, such
as *pe* or *ebond* or *enthalpy*\ . Other keywords such as *temp* or
*press* are "intensive" meaning their value is independent (in a
statistical sense) of the number of atoms in the system and thus are
never normalized. For thermodynamic output values extracted from fixes
and computes in a :doc:`thermo_style custom <thermo_style>` command, the
page for the individual :doc:`fix <fix>` or :doc:`compute <compute>`
lists whether the value is "extensive" or "intensive" and thus whether
it is normalized. Thermodynamic output values calculated by a variable
formula are assumed to be "intensive" and thus are never normalized.
You can always include a divide by the number of atoms in the variable
formula if this is not the case.
The *flush* keyword invokes a flush operation after thermodynamic info
is written to the screen and log file. This insures the output is
updated and not buffered (by the application) even if LAMMPS halts
before the simulation completes. Please note that this does not
affect buffering by the OS or devices, so you may still lose data
in case the simulation stops due to a hardware failure.
before the simulation completes. Please note that this does not affect
buffering by the OS or devices, so you may still lose data in case the
simulation stops due to a hardware failure.
The *line* keyword determines whether thermodynamics will be output as
a series of numeric values on one line or in a multi-line format with
3 quantities with text strings per line and a dashed-line header
containing the timestep and CPU time. This modify option overrides
the *one* and *multi* thermo_style settings.
The *line* keyword determines whether thermodynamics will be output as a
series of numeric values on one line ("one"), in a multi-line format
with 3 quantities with text strings per line and a dashed-line header
containing the timestep and CPU time ("multi"), or in a YAML format
block ("yaml"). This modify option overrides the *one*, *multi*, or
*yaml* thermo_style settings.
The *format* keyword can be used to change the default numeric format
of any of quantities the :doc:`thermo_style <thermo_style>` command
outputs. All the specified format strings are C-style formats,
e.g. as used by the C/C++ printf() command. The *line* keyword takes
a single argument which is the format string for the entire line of
thermo output, with N fields, which you must enclose in quotes if it
is more than one field. The *int* and *float* keywords take a single
format argument and are applied to all integer or floating-point
quantities output. The setting for *M string* also takes a single
format argument which is used for the Mth value output in each line,
e.g. the fifth column is output in high precision for "format 5
%20.15g".
The *format* keyword can be used to change the default numeric format of
any of quantities the :doc:`thermo_style <thermo_style>` command
outputs. All the specified format strings are C-style formats, e.g. as
used by the C/C++ printf() command. The *line* keyword takes a single
argument which is the format string for the entire line of thermo
output, with N fields, which you must enclose in quotes if it is more
than one field. The *int* and *float* keywords take a single format
argument and are applied to all integer or floating-point quantities
output. The setting for *M string* also takes a single format argument
which is used for the Mth value output in each line, e.g. the fifth
column is output in high precision for "format 5 %20.15g".
The *format* keyword can be used multiple times. The precedence is
that for each value in a line of output, the *M* format (if specified)
@ -168,46 +168,46 @@ settings, reverting all values to their default format.
.. note::
The thermo output values *step* and *atoms* are stored
internally as 8-byte signed integers, rather than the usual 4-byte
signed integers. When specifying the *format int* option you can use
a "%d"-style format identifier in the format string and LAMMPS will
convert this to the corresponding 8-byte form when it is applied to
those keywords. However, when specifying the *line* option or *format
M string* option for *step* and *natoms*, you should specify a format
The thermo output values *step* and *atoms* are stored internally as
8-byte signed integers, rather than the usual 4-byte signed integers.
When specifying the *format int* option you can use a "%d"-style
format identifier in the format string and LAMMPS will convert this
to the corresponding 8-byte form when it is applied to those
keywords. However, when specifying the *line* option or *format M
string* option for *step* and *natoms*, you should specify a format
string appropriate for an 8-byte signed integer, e.g. one with "%ld".
The *temp* keyword is used to determine how thermodynamic temperature
is calculated, which is used by all thermo quantities that require a
The *temp* keyword is used to determine how thermodynamic temperature is
calculated, which is used by all thermo quantities that require a
temperature ("temp", "press", "ke", "etotal", "enthalpy", "pxx", etc).
The specified compute ID must have been previously defined by the user
via the :doc:`compute <compute>` command and it must be a style of
compute that calculates a temperature. As described in the
:doc:`thermo_style <thermo_style>` command, thermo output uses a default
compute for temperature with ID = *thermo_temp*. This option allows
the user to override the default.
compute for temperature with ID = *thermo_temp*. This option allows the
user to override the default.
The *press* keyword is used to determine how thermodynamic pressure is
calculated, which is used by all thermo quantities that require a
pressure ("press", "enthalpy", "pxx", etc). The specified compute ID
must have been previously defined by the user via the
:doc:`compute <compute>` command and it must be a style of compute that
calculates a pressure. As described in the
:doc:`thermo_style <thermo_style>` command, thermo output uses a default
compute for pressure with ID = *thermo_press*. This option allows the
user to override the default.
must have been previously defined by the user via the :doc:`compute
<compute>` command and it must be a style of compute that calculates a
pressure. As described in the :doc:`thermo_style <thermo_style>`
command, thermo output uses a default compute for pressure with ID =
*thermo_press*. This option allows the user to override the default.
.. note::
If both the *temp* and *press* keywords are used in a single
thermo_modify command (or in two separate commands), then the order in
which the keywords are specified is important. Note that a :doc:`pressure compute <compute_pressure>` defines its own temperature compute as
an argument when it is specified. The *temp* keyword will override
this (for the pressure compute being used by thermodynamics), but only
if the *temp* keyword comes after the *press* keyword. If the *temp*
keyword comes before the *press* keyword, then the new pressure
compute specified by the *press* keyword will be unaffected by the
*temp* setting.
thermo_modify command (or in two separate commands), then the order
in which the keywords are specified is important. Note that a
:doc:`pressure compute <compute_pressure>` defines its own
temperature compute as an argument when it is specified. The *temp*
keyword will override this (for the pressure compute being used by
thermodynamics), but only if the *temp* keyword comes after the
*press* keyword. If the *temp* keyword comes before the *press*
keyword, then the new pressure compute specified by the *press*
keyword will be unaffected by the *temp* setting.
Restrictions
""""""""""""
@ -225,7 +225,8 @@ The option defaults are lost = error, warn = 100, norm = yes for unit
style of *lj*, norm = no for unit style of *real* and *metal*,
flush = no, and temp/press = compute IDs defined by thermo_style.
The defaults for the line and format options depend on the thermo
style. For styles "one" and "custom", the line and format defaults
are "one", "%8d", and "%12.8g". For style "multi", the line and
format defaults are "multi", "%8d", and "%14.4f".
The defaults for the line and format options depend on the thermo style.
For styles "one" and "custom", the line and format defaults are "one",
"%10d", and "%12.8g". For style "multi", the line and format defaults
are "multi", "%14d", and "%14.4f". For style "yaml", the line and format
defaults are "%d" and "%.15g".

View File

@ -10,13 +10,14 @@ Syntax
thermo_style style args
* style = *one* or *multi* or *custom*
* style = *one* or *multi* *yaml* or *custom*
* args = list of arguments for a particular style
.. parsed-literal::
*one* args = none
*multi* args = none
*yaml* args = none
*custom* args = list of keywords
possible keywords = step, elapsed, elaplong, dt, time,
cpu, tpcpu, spcpu, cpuremain, part, timeremain,
@ -92,6 +93,8 @@ Examples
.. code-block:: LAMMPS
thermo_style multi
thermo_style yaml
thermo_style one
thermo_style custom step temp pe etotal press vol
thermo_style custom step temp etotal c_myTemp v_abc
thermo_style custom step temp etotal c_myTemp[*] v_abc
@ -99,18 +102,35 @@ Examples
Description
"""""""""""
Set the style and content for printing thermodynamic data to the
screen and log file.
Set the style and content for printing thermodynamic data to the screen
and log files.
Style *one* prints a one-line summary of thermodynamic info that is
the equivalent of "thermo_style custom step temp epair emol etotal
press". The line contains only numeric values.
Style *one* prints a single line of thermodynamic info that is the
equivalent of "thermo_style custom step temp epair emol etotal press".
The line contains only numeric values.
Style *multi* prints a multiple-line listing of thermodynamic info
that is the equivalent of "thermo_style custom etotal ke temp pe ebond
eangle edihed eimp evdwl ecoul elong press". The listing contains
numeric values and a string ID for each quantity.
.. versionadded:: 24Mar2022
Style *yaml* is similar to style *one* but prints the output in `YAML
<https://yaml.org/>`_ format which can be easily read by a variety of
script languages and data handling packages. Since LAMMPS may print
other output before, after, or in between thermodynamic output, the
YAML format content needs to be separated from the rest. All YAML
format thermodynamic output can be matched with a regular expression
and can thus be extracted with commands like ``egrep`` as follows:
.. code-block:: sh
egrep '^(keywords:|data:$|---$|\.\.\.$| - \[)' log.lammps > log.yaml
Information about processing such YAML files is in the :doc:`structured
data output howto <Howto_structured_data>`.
Style *custom* is the most general setting and allows you to specify
which of the keywords listed above you want printed on each
thermodynamic timestep. Note that the keywords c_ID, f_ID, v_name are

View File

@ -46,10 +46,10 @@ void BondFENENM::compute(int eflag, int vflag)
{
int i1, i2, n, type;
double delx, dely, delz, ebond, fbond;
double rsq, r0sq, rlogarg, sr6;
double rsq, r0sq, rlogarg;
double r;
ebond = sr6 = 0.0;
ebond = 0.0;
ev_init(eflag, vflag);
double **x = atom->x;

View File

@ -115,9 +115,8 @@ void PairDPDfdtEnergyKokkos<LMPDeviceSpace>::init_style()
neighflag = lmp->kokkos->neighflag;
auto request = neighbor->find_request(this);
request->set_kokkos_host(std::is_same<DeviceType,LMPHostType>::value &&
!std::is_same<DeviceType,LMPDeviceType>::value);
request->set_kokkos_device(std::is_same<DeviceType,LMPDeviceType>::value);
request->set_kokkos_host(0);
request->set_kokkos_device(1);
if (neighflag == FULL) request->enable_full();
#ifdef DPD_USE_RAN_MARS

View File

@ -335,7 +335,7 @@ void DumpNetCDF::openfile()
if (thermo) {
Thermo *th = output->thermo;
for (int i = 0; i < th->nfield; i++) {
NCERRX( nc_inq_varid(ncid, th->keyword[i], &thermovar[i]), th->keyword[i] );
NCERRX( nc_inq_varid(ncid, th->keyword[i].c_str(), &thermovar[i]), th->keyword[i].c_str() );
}
}
@ -448,18 +448,18 @@ void DumpNetCDF::openfile()
Thermo *th = output->thermo;
for (int i = 0; i < th->nfield; i++) {
if (th->vtype[i] == Thermo::FLOAT) {
NCERRX( nc_def_var(ncid, th->keyword[i], type_nc_real, 1, dims,
&thermovar[i]), th->keyword[i] );
NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), type_nc_real, 1, dims,
&thermovar[i]), th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::INT) {
NCERRX( nc_def_var(ncid, th->keyword[i], NC_INT, 1, dims,
&thermovar[i]), th->keyword[i] );
NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_INT, 1, dims,
&thermovar[i]), th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::BIGINT) {
#if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG)
NCERRX( nc_def_var(ncid, th->keyword[i], NC_INT64, 1, dims,
&thermovar[i]), th->keyword[i] );
NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_INT64, 1, dims,
&thermovar[i]), th->keyword[i].c_str() );
#else
NCERRX( nc_def_var(ncid, th->keyword[i], NC_LONG, 1, dims,
&thermovar[i]), th->keyword[i] );
NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_LONG, 1, dims,
&thermovar[i]), th->keyword[i].c_str() );
#endif
}
}
@ -625,13 +625,13 @@ void DumpNetCDF::write()
if (th->vtype[i] == Thermo::FLOAT) {
NCERRX( nc_put_var1_double(ncid, thermovar[i], start,
&th->dvalue),
th->keyword[i] );
th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::INT) {
NCERRX( nc_put_var1_int(ncid, thermovar[i], start, &th->ivalue),
th->keyword[i] );
th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::BIGINT) {
NCERRX( nc_put_var1_bigint(ncid, thermovar[i], start, &th->bivalue),
th->keyword[i] );
th->keyword[i].c_str() );
}
}
}

View File

@ -332,7 +332,7 @@ void DumpNetCDFMPIIO::openfile()
if (thermo) {
Thermo *th = output->thermo;
for (int i = 0; i < th->nfield; i++) {
NCERRX( ncmpi_inq_varid(ncid, th->keyword[i], &thermovar[i]), th->keyword[i] );
NCERRX( ncmpi_inq_varid(ncid, th->keyword[i].c_str(), &thermovar[i]), th->keyword[i].c_str() );
}
}
@ -436,14 +436,14 @@ void DumpNetCDFMPIIO::openfile()
Thermo *th = output->thermo;
for (int i = 0; i < th->nfield; i++) {
if (th->vtype[i] == Thermo::FLOAT) {
NCERRX( ncmpi_def_var(ncid, th->keyword[i], type_nc_real, 1, dims, &thermovar[i]), th->keyword[i] );
NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::INT) {
NCERRX( ncmpi_def_var(ncid, th->keyword[i], NC_INT, 1, dims, &thermovar[i]), th->keyword[i] );
NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_INT, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::BIGINT) {
#if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG)
NCERRX( ncmpi_def_var(ncid, th->keyword[i], NC_INT64, 1, dims, &thermovar[i]), th->keyword[i] );
NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
#else
NCERRX( ncmpi_def_var(ncid, th->keyword[i], NC_LONG, 1, dims, &thermovar[i]), th->keyword[i] );
NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_LONG, 1, dims, &thermovar[i]), th->keyword[i].c_str() );
#endif
}
}
@ -612,13 +612,13 @@ void DumpNetCDFMPIIO::write()
if (th->vtype[i] == Thermo::FLOAT) {
NCERRX( ncmpi_put_var1_double(ncid, thermovar[i], start,
&th->dvalue),
th->keyword[i] );
th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::INT) {
NCERRX( ncmpi_put_var1_int(ncid, thermovar[i], start, &th->ivalue),
th->keyword[i] );
th->keyword[i].c_str() );
} else if (th->vtype[i] == Thermo::BIGINT) {
NCERRX( ncmpi_put_var1_bigint(ncid, thermovar[i], start, &th->bivalue),
th->keyword[i] );
th->keyword[i].c_str() );
}
}
}

View File

@ -79,6 +79,8 @@ reaxc_multi_body_omp.cpp
reaxc_nonbonded_omp.cpp
reaxc_torsion_angles_omp.cpp
reaxc_valence_angles_omp.cpp
fix_qeq_reax.cpp
fix_qeq_reax.h
fix_reaxc.cpp
fix_reaxc.h
fix_reaxc_bonds.cpp

View File

@ -27,6 +27,8 @@
#include "neigh_list.h"
#include "neigh_request.h"
#include "neighbor.h" // IWYU pragma: keep
#include "output.h"
#include "thermo.h"
#include "timer.h" // IWYU pragma: keep
#include "universe.h"
#include "update.h"
@ -121,10 +123,10 @@ void Finish::end(int flag)
if (time_loop > 0.0) cpu_loop = cpu_loop/time_loop*100.0;
if (me == 0) {
output->thermo->footer();
int ntasks = nprocs * nthreads;
utils::logmesg(lmp,"Loop time of {:.6g} on {} procs for "
"{} steps with {} atoms\n\n",time_loop,
ntasks,update->nsteps,atom->natoms);
utils::logmesg(lmp,"Loop time of {:.6g} on {} procs for {} steps with {} atoms\n\n",
time_loop,ntasks,update->nsteps,atom->natoms);
// Gromacs/NAMD-style performance metric for suitable unit settings
@ -142,8 +144,7 @@ void Finish::end(int flag)
if (strcmp(update->unit_style,"lj") == 0) {
double tau_day = 24.0*3600.0 / t_step * update->dt / one_fs;
utils::logmesg(lmp,"Performance: {:.3f} tau/day, {:.3f} "
"timesteps/s\n",tau_day,step_t);
utils::logmesg(lmp,"Performance: {:.3f} tau/day, {:.3f} timesteps/s\n",tau_day,step_t);
} else if (strcmp(update->unit_style,"electron") == 0) {
double hrs_fs = t_step / update->dt * one_fs / 3600.0;
double fs_day = 24.0*3600.0 / t_step * update->dt / one_fs;
@ -161,15 +162,15 @@ void Finish::end(int flag)
if (timeflag) {
if (lmp->kokkos) {
utils::logmesg(lmp,"{:.1f}% CPU use with {} MPI tasks x {} OpenMP "
"threads\n",cpu_loop,nprocs,lmp->kokkos->nthreads);
utils::logmesg(lmp,"{:.1f}% CPU use with {} MPI tasks x {} OpenMP threads\n",
cpu_loop,nprocs,lmp->kokkos->nthreads);
} else {
#if defined(_OPENMP)
utils::logmesg(lmp,"{:.1f}% CPU use with {} MPI tasks x {} OpenMP "
"threads\n",cpu_loop,nprocs,nthreads);
utils::logmesg(lmp,"{:.1f}% CPU use with {} MPI tasks x {} OpenMP threads\n",
cpu_loop,nprocs,nthreads);
#else
utils::logmesg(lmp,"{:.1f}% CPU use with {} MPI tasks "
"x no OpenMP threads\n",cpu_loop,nprocs);
utils::logmesg(lmp,"{:.1f}% CPU use with {} MPI tasks x no OpenMP threads\n",
cpu_loop,nprocs);
#endif
}
}
@ -192,8 +193,7 @@ void Finish::end(int flag)
if (me == 0) {
std::string mesg = "\nMinimization stats:\n";
mesg += fmt::format(" Stopping criterion = {}\n",
update->minimize->stopstr);
mesg += fmt::format(" Stopping criterion = {}\n",update->minimize->stopstr);
mesg += fmt::format(" Energy initial, next-to-last, final = \n"
" {:18.15g} {:18.15g} {:18.15g}\n",
update->minimize->einitial,
@ -222,33 +222,27 @@ void Finish::end(int flag)
time = timer->get_wall(Timer::DEPHASE);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Dephase time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Dephase time (%) = {} ({})\n",time,time/time_loop*100.0);
time = timer->get_wall(Timer::DYNAMICS);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Dynamics time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Dynamics time (%) = {} ({})\n",time,time/time_loop*100.0);
time = timer->get_wall(Timer::QUENCH);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Quench time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Quench time (%) = {} ({})\n",time,time/time_loop*100.0);
time = timer->get_wall(Timer::REPCOMM);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Comm time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Comm time (%) = {} ({})\n",time,time/time_loop*100.0);
time = timer->get_wall(Timer::REPOUT);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Output time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Output time (%) = {} ({})\n",time,time/time_loop*100.0);
time = time_other;
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Other time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Other time (%) = {} ({})\n",time,time/time_loop*100.0);
}
// TAD stats
@ -259,33 +253,27 @@ void Finish::end(int flag)
time = timer->get_wall(Timer::NEB);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," NEB time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," NEB time (%) = {} ({})\n",time,time/time_loop*100.0);
time = timer->get_wall(Timer::DYNAMICS);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Dynamics time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Dynamics time (%) = {} ({})\n",time,time/time_loop*100.0);
time = timer->get_wall(Timer::QUENCH);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Quench time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Quench time (%) = {} ({})\n",time,time/time_loop*100.0);
time = timer->get_wall(Timer::REPCOMM);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Comm time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Comm time (%) = {} ({})\n",time,time/time_loop*100.0);
time = timer->get_wall(Timer::REPOUT);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Output time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Output time (%) = {} ({})\n",time,time/time_loop*100.0);
time = time_other;
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Other time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Other time (%) = {} ({})\n",time,time/time_loop*100.0);
}
// HYPER stats
@ -296,18 +284,15 @@ void Finish::end(int flag)
time = timer->get_wall(Timer::DYNAMICS);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Dynamics time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Dynamics time (%) = {} ({})\n",time,time/time_loop*100.0);
time = timer->get_wall(Timer::QUENCH);
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Quench time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Quench time (%) = {} ({})\n",time,time/time_loop*100.0);
time = time_other;
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
time = tmp/nprocs;
if (me == 0) utils::logmesg(lmp," Other time (%) = {} ({})\n",
time,time/time_loop*100.0);
if (me == 0) utils::logmesg(lmp," Other time (%) = {} ({})\n",time,time/time_loop*100.0);
}
// further timing breakdowns
@ -326,28 +311,20 @@ void Finish::end(int flag)
"------------------------------------------------------\n");
}
mpi_timings("Pair",timer,Timer::PAIR, world,nprocs,
nthreads,me,time_loop,screen,logfile);
mpi_timings("Pair",timer,Timer::PAIR, world,nprocs,nthreads,me,time_loop,screen,logfile);
if (atom->molecular != Atom::ATOMIC)
mpi_timings("Bond",timer,Timer::BOND,world,nprocs,
nthreads,me,time_loop,screen,logfile);
mpi_timings("Bond",timer,Timer::BOND,world,nprocs,nthreads,me,time_loop,screen,logfile);
if (force->kspace)
mpi_timings("Kspace",timer,Timer::KSPACE,world,nprocs,
nthreads,me,time_loop,screen,logfile);
mpi_timings("Kspace",timer,Timer::KSPACE,world,nprocs,nthreads,me,time_loop,screen,logfile);
mpi_timings("Neigh",timer,Timer::NEIGH,world,nprocs,
nthreads,me,time_loop,screen,logfile);
mpi_timings("Comm",timer,Timer::COMM,world,nprocs,
nthreads,me,time_loop,screen,logfile);
mpi_timings("Output",timer,Timer::OUTPUT,world,nprocs,
nthreads,me,time_loop,screen,logfile);
mpi_timings("Modify",timer,Timer::MODIFY,world,nprocs,
nthreads,me,time_loop,screen,logfile);
mpi_timings("Neigh",timer,Timer::NEIGH,world,nprocs,nthreads,me,time_loop,screen,logfile);
mpi_timings("Comm",timer,Timer::COMM,world,nprocs,nthreads,me,time_loop,screen,logfile);
mpi_timings("Output",timer,Timer::OUTPUT,world,nprocs,nthreads,me,time_loop,screen,logfile);
mpi_timings("Modify",timer,Timer::MODIFY,world,nprocs,nthreads,me,time_loop,screen,logfile);
if (timer->has_sync())
mpi_timings("Sync",timer,Timer::SYNC,world,nprocs,
nthreads,me,time_loop,screen,logfile);
mpi_timings("Sync",timer,Timer::SYNC,world,nprocs,nthreads,me,time_loop,screen,logfile);
time = time_other;
MPI_Allreduce(&time,&tmp,1,MPI_DOUBLE,MPI_SUM,world);
@ -543,8 +520,7 @@ void Finish::end(int flag)
if (atom->natoms > 0)
mesg += fmt::format("Ave neighs/atom = {:.8}\n",nall/atom->natoms);
if ((atom->molecular != Atom::ATOMIC) && (atom->natoms > 0))
mesg += fmt::format("Ave special neighs/atom = {:.8}\n",
nspec_all/atom->natoms);
mesg += fmt::format("Ave special neighs/atom = {:.8}\n",nspec_all/atom->natoms);
mesg += fmt::format("Neighbor list builds = {}\n",neighbor->ncalls);
if (neighbor->dist_check)
mesg += fmt::format("Dangerous builds = {}\n",neighbor->ndanger);

View File

@ -93,8 +93,6 @@ FixNH::FixNH(LAMMPS *lmp, int narg, char **arg) :
tcomputeflag = 0;
pcomputeflag = 0;
id_temp = nullptr;
id_press = nullptr;
// turn on tilt factor scaling, whenever applicable

View File

@ -405,7 +405,7 @@ after calling Py_Finalize().
This function can be called to explicitly clear the Python
environment in case it is safe to do so.
.. versionadded:: TBD
.. versionadded:: 20Sep2021
*See also*
:cpp:func:`lammps_mpi_finalize`, :cpp:func:`lammps_kokkos_finalize`

View File

@ -69,7 +69,7 @@ Output::Output(LAMMPS *lmp) : Pointers(lmp)
char **newarg = new char*[1];
newarg[0] = (char *) "one";
thermo = new Thermo(lmp,1,newarg);
delete [] newarg;
delete[] newarg;
thermo_every = 0;
var_thermo = nullptr;
@ -110,7 +110,7 @@ Output::Output(LAMMPS *lmp) : Pointers(lmp)
Output::~Output()
{
if (thermo) delete thermo;
delete [] var_thermo;
delete[] var_thermo;
memory->destroy(mode_dump);
memory->destroy(every_dump);
@ -118,17 +118,17 @@ Output::~Output()
memory->destroy(next_dump);
memory->destroy(next_time_dump);
memory->destroy(last_dump);
for (int i = 0; i < ndump; i++) delete [] var_dump[i];
for (int i = 0; i < ndump; i++) delete[] var_dump[i];
memory->sfree(var_dump);
memory->destroy(ivar_dump);
for (int i = 0; i < ndump; i++) delete dump[i];
memory->sfree(dump);
delete [] restart1;
delete [] restart2a;
delete [] restart2b;
delete [] var_restart_single;
delete [] var_restart_double;
delete[] restart1;
delete[] restart2a;
delete[] restart2b;
delete[] var_restart_single;
delete[] var_restart_double;
delete restart;
delete dump_map;
@ -545,8 +545,7 @@ void Output::calculate_next_dump(int which, int idump, bigint ntimestep)
}
nextdump = ntimestep +
static_cast<bigint> ((nexttime - tcurrent - EPSDT*update->dt) /
update->dt) + 1;
static_cast<bigint> ((nexttime - tcurrent - EPSDT*update->dt) / update->dt) + 1;
// if delta is too small to reach next timestep, use multiple of delta
@ -557,8 +556,7 @@ void Output::calculate_next_dump(int which, int idump, bigint ntimestep)
((tnext - nexttime) / every_time_dump[idump]);
nexttime = nexttime + (multiple+1)*every_time_dump[idump];
nextdump = ntimestep +
static_cast<bigint> ((nexttime - tcurrent - EPSDT*update->dt) /
update->dt) + 1;
static_cast<bigint> ((nexttime - tcurrent - EPSDT*update->dt) / update->dt) + 1;
}
} else {
@ -575,8 +573,7 @@ void Output::calculate_next_dump(int which, int idump, bigint ntimestep)
error->all(FLERR,"Dump every/time variable returned a bad time");
nextdump = ntimestep +
static_cast<bigint> ((nexttime - tcurrent - EPSDT*update->dt) /
update->dt) + 1;
static_cast<bigint> ((nexttime - tcurrent - EPSDT*update->dt) / update->dt) + 1;
if (nextdump <= ntimestep)
error->all(FLERR,"Dump every/time variable too small for next timestep");
}
@ -825,7 +822,7 @@ void Output::delete_dump(char *id)
if (idump == ndump) error->all(FLERR,"Could not find undump ID");
delete dump[idump];
delete [] var_dump[idump];
delete[] var_dump[idump];
// move other dumps down in list one slot
@ -869,7 +866,7 @@ void Output::set_thermo(int narg, char **arg)
// always reset var_thermo, so it is possible to switch back from
// variable spaced thermo outputs to constant spaced ones.
delete [] var_thermo;
delete[] var_thermo;
var_thermo = nullptr;
if (utils::strmatch(arg[0],"^v_")) {
@ -929,12 +926,12 @@ void Output::create_restart(int narg, char **arg)
delete restart;
restart = nullptr;
delete [] restart1;
delete [] restart2a;
delete [] restart2b;
delete[] restart1;
delete[] restart2a;
delete[] restart2b;
restart1 = restart2a = restart2b = nullptr;
delete [] var_restart_single;
delete [] var_restart_double;
delete[] var_restart_single;
delete[] var_restart_double;
var_restart_single = var_restart_double = nullptr;
return;
@ -950,13 +947,13 @@ void Output::create_restart(int narg, char **arg)
restart_flag = restart_flag_single = 1;
if (varflag) {
delete [] var_restart_single;
delete[] var_restart_single;
var_restart_single = utils::strdup(arg[0]+2);
restart_every_single = 0;
} else restart_every_single = every;
int n = strlen(arg[1]) + 3;
delete [] restart1;
delete[] restart1;
restart1 = new char[n];
strcpy(restart1,arg[1]);
if (strchr(restart1,'*') == nullptr) strcat(restart1,".*");
@ -966,13 +963,13 @@ void Output::create_restart(int narg, char **arg)
restart_flag = restart_flag_double = 1;
if (varflag) {
delete [] var_restart_double;
delete[] var_restart_double;
var_restart_double = utils::strdup(arg[0]+2);
restart_every_double = 0;
} else restart_every_double = every;
delete [] restart2a;
delete [] restart2b;
delete[] restart2a;
delete[] restart2b;
restart_toggle = 0;
restart2a = utils::strdup(arg[1]);
restart2b = utils::strdup(arg[2]);

File diff suppressed because it is too large Load Diff

View File

@ -39,26 +39,16 @@ class Thermo : protected Pointers {
bigint lost_check();
void modify_params(int, char **);
void header();
void footer();
void compute(int);
int evaluate_keyword(const char *, double *);
int evaluate_keyword(const std::string &, double *);
private:
char *line;
char **keyword;
int *vtype;
int nfield, nfield_initial;
int me;
char **format;
char *format_line_user;
char *format_float_user, *format_int_user, *format_bigint_user;
char **format_column_user;
char *format_float_one_def, *format_float_multi_def;
char *format_int_one_def, *format_int_multi_def;
char format_multi[128];
char format_bigint_one_def[8], format_bigint_multi_def[8];
int *vtype;
std::string line;
std::vector<std::string> keyword, format, format_column_user;
std::string format_line_user, format_float_user, format_int_user, format_bigint_user;
int normvalue; // use this for normflag unless natoms = 0
int normuserflag; // 0 if user has not set, 1 if has
@ -88,7 +78,6 @@ class Thermo : protected Pointers {
// id = ID of Compute objects
// Compute * = ptrs to the Compute objects
int index_temp, index_press_scalar, index_press_vector, index_pe;
char *id_temp, *id_press, *id_pe;
class Compute *temperature, *pressure, *pe;
int ncompute; // # of Compute objects called by thermo
@ -109,11 +98,16 @@ class Thermo : protected Pointers {
void allocate();
void deallocate();
void parse_fields(char *);
void parse_fields(const std::string &);
int add_compute(const char *, int);
int add_fix(const char *);
int add_variable(const char *);
void check_temp(const std::string &);
void check_pe(const std::string &);
void check_press_scalar(const std::string &);
void check_press_vector(const std::string &);
typedef void (Thermo::*FnPtr)();
void addfield(const char *, FnPtr, int);
FnPtr *vfunc; // list of ptrs to functions