bug fixes to make a series of test inputs run correctly
This commit is contained in:
@ -169,11 +169,12 @@ or multiple smaller files).
|
||||
|
||||
.. note::
|
||||
|
||||
Because periodic boundary conditions are enforced only on
|
||||
timesteps when neighbor lists are rebuilt, the coordinates of an atom
|
||||
written to a dump file may be slightly outside the simulation box.
|
||||
Re-neighbor timesteps will not typically coincide with the timesteps
|
||||
dump snapshots are written. See the :doc:`dump_modify pbc <dump_modify>` command if you with to force coordinates to be
|
||||
Because periodic boundary conditions are enforced only on timesteps
|
||||
when neighbor lists are rebuilt, the coordinates of an atom written
|
||||
to a dump file may be slightly outside the simulation box.
|
||||
Re-neighbor timesteps will not typically coincide with the
|
||||
timesteps dump snapshots are written. See the :doc:`dump_modify
|
||||
pbc <dump_modify>` command if you with to force coordinates to be
|
||||
strictly inside the simulation box.
|
||||
|
||||
.. note::
|
||||
@ -189,20 +190,21 @@ or multiple smaller files).
|
||||
multiple processors, each of which owns a subset of the atoms.
|
||||
|
||||
For the *atom*, *custom*, *cfg*, and *local* styles, sorting is off by
|
||||
default. For the *dcd*, *xtc*, *xyz*, and *molfile* styles, sorting by
|
||||
atom ID is on by default. See the :doc:`dump_modify <dump_modify>` doc
|
||||
page for details.
|
||||
default. For the *dcd*, *xtc*, *xyz*, and *molfile* styles, sorting
|
||||
by atom ID is on by default. See the :doc:`dump_modify <dump_modify>`
|
||||
doc page for details.
|
||||
|
||||
The *atom/gz*, *cfg/gz*, *custom/gz*, *local/gz*, and *xyz/gz* styles are identical
|
||||
in command syntax to the corresponding styles without "gz", however,
|
||||
they generate compressed files using the zlib library. Thus the filename
|
||||
suffix ".gz" is mandatory. This is an alternative approach to writing
|
||||
compressed files via a pipe, as done by the regular dump styles, which
|
||||
may be required on clusters where the interface to the high-speed network
|
||||
disallows using the fork() library call (which is needed for a pipe).
|
||||
For the remainder of this doc page, you should thus consider the *atom*
|
||||
and *atom/gz* styles (etc) to be inter-changeable, with the exception
|
||||
of the required filename suffix.
|
||||
The *atom/gz*, *cfg/gz*, *custom/gz*, *local/gz*, and *xyz/gz* styles
|
||||
are identical in command syntax to the corresponding styles without
|
||||
"gz", however, they generate compressed files using the zlib
|
||||
library. Thus the filename suffix ".gz" is mandatory. This is an
|
||||
alternative approach to writing compressed files via a pipe, as done
|
||||
by the regular dump styles, which may be required on clusters where
|
||||
the interface to the high-speed network disallows using the fork()
|
||||
library call (which is needed for a pipe). For the remainder of this
|
||||
doc page, you should thus consider the *atom* and *atom/gz* styles
|
||||
(etc) to be inter-changeable, with the exception of the required
|
||||
filename suffix.
|
||||
|
||||
Similarly, the *atom/zstd*, *cfg/zstd*, *custom/zstd*, *local/zstd*,
|
||||
and *xyz/zstd* styles are identical to the gz styles, but use the Zstd
|
||||
@ -275,10 +277,11 @@ This bounding box is convenient for many visualization programs. The
|
||||
meaning of the 6 character flags for "xx yy zz" is the same as above.
|
||||
|
||||
Note that the first two numbers on each line are now xlo_bound instead
|
||||
of xlo, etc, since they represent a bounding box. See the :doc:`Howto triclinic <Howto_triclinic>` page for a geometric description
|
||||
of triclinic boxes, as defined by LAMMPS, simple formulas for how the
|
||||
6 bounding box extents (xlo_bound,xhi_bound,etc) are calculated from
|
||||
the triclinic parameters, and how to transform those parameters to and
|
||||
of xlo, etc, since they represent a bounding box. See the :doc:`Howto
|
||||
triclinic <Howto_triclinic>` page for a geometric description of
|
||||
triclinic boxes, as defined by LAMMPS, simple formulas for how the 6
|
||||
bounding box extents (xlo_bound,xhi_bound,etc) are calculated from the
|
||||
triclinic parameters, and how to transform those parameters to and
|
||||
from other commonly used triclinic representations.
|
||||
|
||||
The "ITEM: ATOMS" line in each snapshot lists column descriptors for
|
||||
@ -310,23 +313,24 @@ written to the dump file. This local data is typically calculated by
|
||||
each processor based on the atoms it owns, but there may be zero or
|
||||
more entities per atom, e.g. a list of bond distances. An explanation
|
||||
of the possible dump local attributes is given below. Note that by
|
||||
using input from the :doc:`compute property/local <compute_property_local>` command with dump local,
|
||||
it is possible to generate information on bonds, angles, etc that can
|
||||
be cut and pasted directly into a data file read by the
|
||||
:doc:`read_data <read_data>` command.
|
||||
using input from the :doc:`compute property/local
|
||||
<compute_property_local>` command with dump local, it is possible to
|
||||
generate information on bonds, angles, etc that can be cut and pasted
|
||||
directly into a data file read by the :doc:`read_data <read_data>`
|
||||
command.
|
||||
|
||||
Style *cfg* has the same command syntax as style *custom* and writes
|
||||
extended CFG format files, as used by the
|
||||
`AtomEye <http://li.mit.edu/Archive/Graphics/A/>`_ visualization
|
||||
package. Since the extended CFG format uses a single snapshot of the
|
||||
system per file, a wildcard "\*" must be included in the filename, as
|
||||
discussed below. The list of atom attributes for style *cfg* must
|
||||
begin with either "mass type xs ys zs" or "mass type xsu ysu zsu"
|
||||
since these quantities are needed to write the CFG files in the
|
||||
appropriate format (though the "mass" and "type" fields do not appear
|
||||
explicitly in the file). Any remaining attributes will be stored as
|
||||
"auxiliary properties" in the CFG files. Note that you will typically
|
||||
want to use the :doc:`dump_modify element <dump_modify>` command with
|
||||
extended CFG format files, as used by the `AtomEye
|
||||
<http://li.mit.edu/Archive/Graphics/A/>`_ visualization package.
|
||||
Since the extended CFG format uses a single snapshot of the system per
|
||||
file, a wildcard "\*" must be included in the filename, as discussed
|
||||
below. The list of atom attributes for style *cfg* must begin with
|
||||
either "mass type xs ys zs" or "mass type xsu ysu zsu" since these
|
||||
quantities are needed to write the CFG files in the appropriate format
|
||||
(though the "mass" and "type" fields do not appear explicitly in the
|
||||
file). Any remaining attributes will be stored as "auxiliary
|
||||
properties" in the CFG files. Note that you will typically want to
|
||||
use the :doc:`dump_modify element <dump_modify>` command with
|
||||
CFG-formatted files, to associate element names with atom types, so
|
||||
that AtomEye can render atoms appropriately. When unwrapped
|
||||
coordinates *xsu*, *ysu*, and *zsu* are requested, the nominal AtomEye
|
||||
|
||||
@ -17,7 +17,7 @@ Syntax
|
||||
* one or more keyword/value pairs may be appended
|
||||
|
||||
* these keywords apply to various dump styles
|
||||
* keyword = *append* or *at* or *buffer* or *delay* or *element* or *every* or *fileper* or *first* or *flush* or *format* or *header* or *image* or *label* or *maxfiles* or *nfile* or *pad* or *pbc* or *precision* or *region* or *refresh* or *scale* or *sfactor* or *sort* or *tfactor* or *thermo* or *thresh* or *time* or *units* or *unwrap*
|
||||
* keyword = *append* or *at* or *buffer* or *delay* or *element* or *every* or *every/time* or *fileper* or *first* or *flush* or *format* or *header* or *image* or *label* or *maxfiles* or *nfile* or *pad* or *pbc* or *precision* or *region* or *refresh* or *scale* or *sfactor* or *sort* or *tfactor* or *thermo* or *thresh* or *time* or *units* or *unwrap*
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
@ -32,6 +32,9 @@ Syntax
|
||||
*every* arg = N
|
||||
N = dump every this many timesteps
|
||||
N can be a variable (see below)
|
||||
*every/time* arg = Delta
|
||||
Delta = dump every this interval in simulation time (time units)
|
||||
Delta can be a variable (see below)
|
||||
*fileper* arg = Np
|
||||
Np = write one file for every this many processors
|
||||
*first* arg = *yes* or *no*
|
||||
@ -197,11 +200,18 @@ will be accepted.
|
||||
|
||||
----------
|
||||
|
||||
The *every* keyword changes the dump frequency originally specified by
|
||||
the :doc:`dump <dump>` command to a new value. The every keyword can be
|
||||
specified in one of two ways. It can be a numeric value in which case
|
||||
it must be > 0. Or it can be an :doc:`equal-style variable <variable>`,
|
||||
which should be specified as v_name, where name is the variable name.
|
||||
The *every* keyword does two things. It specifies that the interval
|
||||
between dump snapshots will be specified in timesteps, which is the
|
||||
default if the *every* or *every/time* keywords are not used. See the
|
||||
*every/time* keyword for how to specify the interval in simulation
|
||||
time, i.e. in time units of the :doc:`units <units>` command. This
|
||||
command also sets the interval value, which overrides the dump
|
||||
frequency originally specified by the :doc:`dump <dump>` command.
|
||||
|
||||
The every keyword can be specified in one of two ways. It can be a
|
||||
numeric value in which case it must be > 0. Or it can be 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 a dump snapshot will be written
|
||||
@ -210,11 +220,12 @@ 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>`. Also see the next() function, which allows
|
||||
use of a file-style variable which reads successive values from a
|
||||
file, each time the variable is evaluated. Used with the *every*
|
||||
keyword, if the file contains a list of ascending timesteps, you can
|
||||
output snapshots whenever you wish.
|
||||
could easily be added as options for :doc:`equal-style variables
|
||||
<variable>`. Also see the next() function, which allows use of a
|
||||
file-style variable which reads successive values from a file, each
|
||||
time the variable is evaluated. Used with the *every* keyword, if the
|
||||
file contains a list of ascending timesteps, you can output snapshots
|
||||
whenever you wish.
|
||||
|
||||
Note that when using the variable option with the *every* keyword, you
|
||||
need to use the *first* option if you want an initial snapshot written
|
||||
@ -255,14 +266,95 @@ in file tmp.times:
|
||||
|
||||
----------
|
||||
|
||||
The *every/time* keyword does two things. It specifies that the
|
||||
interval between dump snapshots will be specified in simulation time,
|
||||
i.e. in time units of the :doc:`units <units>` command. This can be
|
||||
useful when the timestep size varies during a simulation run, e.g. by
|
||||
use of the :doc:`fix dt/reset <fix_dt_reset>` command. The default is
|
||||
to specify the interval in timesteps; see the *every* keyword. This
|
||||
command also sets the interval value.
|
||||
|
||||
Note that since snapshots are output on simulation steps, each
|
||||
snapshot will be written on the first timestep whose associated
|
||||
simulation time is >= the exact snapshot time value.
|
||||
|
||||
As with the *every* option, the *Delta* value can be specified in one
|
||||
of two ways. It can be a numeric value in which case it must be >
|
||||
0.0. Or it can be 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 simulation time at which a dump snapshot will be
|
||||
written out. On that timestep the variable will be evaluated again to
|
||||
determine the next simulation time, etc. Thus the variable should
|
||||
return values in time units. Note the current timestep or simulation
|
||||
time can be used in an :doc:`equal-style variables <variable>` since
|
||||
they are both thermodynamic keywords. Also see the next() function,
|
||||
which allows use of a file-style variable which reads successive
|
||||
values from a file, each time the variable is evaluated. Used with
|
||||
the *every/time* keyword, if the file contains a list of ascending
|
||||
simulation times, you can output snapshots whenever you wish.
|
||||
|
||||
Note that when using the variable option with the *every/time*
|
||||
keyword, you need to use the *first* option if you want an initial
|
||||
snapshot written to the dump file. The *every/time* keyword cannot be
|
||||
used with the dump *dcd* style.
|
||||
|
||||
For example, the following commands will write snapshots at successive
|
||||
simulation times which grow by a factor of 1.5 with each interval.
|
||||
The dt value used in the variable is to avoid a zero result when the
|
||||
initial simulation time is 0.0.
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
variable increase equal 1.5*(time+dt)
|
||||
dump 1 all atom 100 tmp.dump
|
||||
dump_modify 1 every/time v_increase first yes
|
||||
|
||||
The following commands would write snapshots at the times listed in
|
||||
file tmp.times:
|
||||
|
||||
.. code-block:: LAMMPS
|
||||
|
||||
variable f file tmp.times
|
||||
variable s equal next(f)
|
||||
dump 1 all atom 100 tmp.dump
|
||||
dump_modify 1 every/time v_s
|
||||
|
||||
.. note::
|
||||
|
||||
When using a file-style variable with the *every* keyword, the file
|
||||
of timesteps must list a first times that is beyond the time
|
||||
associated with the current timestep (e.g. it cannot be 0.0). And
|
||||
it must list one or more times beyond the length of the run you
|
||||
perform. This is because the dump command will generate an error
|
||||
if the next time it reads from the file is not a value greater than
|
||||
the current time. Thus if you wanted output at times 0,15,100 of a
|
||||
run of length 100 in simulation time, the file should contain the
|
||||
values 15,100,101 and you should also use the dump_modify first
|
||||
command. Any final value > 100 could be used in place of 101.
|
||||
|
||||
----------
|
||||
|
||||
The *first* keyword determines whether a dump snapshot is written on
|
||||
the very first timestep after the dump command is invoked. This will
|
||||
always occur if the current timestep is a multiple of N, the frequency
|
||||
specified in the :doc:`dump <dump>` command, including timestep 0. But
|
||||
if this is not the case, a dump snapshot will only be written if the
|
||||
setting of this keyword is *yes*\ . If it is *no*, which is the
|
||||
always occur if the current timestep is a multiple of $N$, the
|
||||
frequency specified in the :doc:`dump <dump>` command or
|
||||
:doc:`dump_modify every <dump_modify>` command, including timestep 0.
|
||||
It will also always occur if the current simulation time is a multiple
|
||||
of *Delta*, the time interval specified in the doc:`dump_modify every/time
|
||||
<dump_modify>` command.
|
||||
|
||||
But if this is not the case, a dump snapshot will only be written if
|
||||
the setting of this keyword is *yes*\ . If it is *no*, which is the
|
||||
default, then it will not be written.
|
||||
|
||||
Note that if the argument to the :doc:`dump_modify every
|
||||
<dump_modify>` doc:`dump_modify every/time <dump_modify>` commands is
|
||||
a variable and not a numeric value, then specifying *first yes* is the
|
||||
only way to write a dump snapshot on the first timestep after the dump
|
||||
command is invoked.
|
||||
|
||||
----------
|
||||
|
||||
The *flush* keyword determines whether a flush operation is invoked
|
||||
@ -342,10 +434,10 @@ The *fileper* keyword is documented below with the *nfile* keyword.
|
||||
|
||||
----------
|
||||
|
||||
The *header* keyword toggles whether the dump file will include a header.
|
||||
Excluding a header will reduce the size of the dump file for fixes such as
|
||||
:doc:`fix pair/tracker <fix_pair_tracker>` which do not require the information
|
||||
typically written to the header.
|
||||
The *header* keyword toggles whether the dump file will include a
|
||||
header. Excluding a header will reduce the size of the dump file for
|
||||
fixes such as :doc:`fix pair/tracker <fix_pair_tracker>` which do not
|
||||
require the information typically written to the header.
|
||||
|
||||
----------
|
||||
|
||||
|
||||
@ -78,13 +78,20 @@ outer loop (largest) timestep, which is the same timestep that the
|
||||
|
||||
Note that the cumulative simulation time (in time units), which
|
||||
accounts for changes in the timestep size as a simulation proceeds,
|
||||
can be accessed by the :doc:`thermo_style time <thermo_style>` keyword.
|
||||
can be accessed by the :doc:`thermo_style time <thermo_style>`
|
||||
keyword.
|
||||
|
||||
Also note that the :doc:`dump_modify every/time <dump_modify>` option
|
||||
allows dump files to be written at intervals specified by simulation
|
||||
time, rather than by timesteps. Simulation time is in time units;
|
||||
see the :doc:`units <units>` doc page for details.
|
||||
|
||||
Restart, fix_modify, output, run start/stop, minimize info
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
No information about this fix is written to :doc:`binary restart files <restart>`. None of the :doc:`fix_modify <fix_modify>` options
|
||||
are relevant to this fix.
|
||||
No information about this fix is written to :doc:`binary restart files
|
||||
<restart>`. None of the :doc:`fix_modify <fix_modify>` options are
|
||||
relevant to this fix.
|
||||
|
||||
This fix computes a global scalar which can be accessed by various
|
||||
:doc:`output commands <Howto_output>`. The scalar stores the last
|
||||
@ -93,7 +100,8 @@ timestep on which the timestep was reset to a new value.
|
||||
The scalar value calculated by this fix is "intensive".
|
||||
|
||||
No parameter of this fix can be used with the *start/stop* keywords of
|
||||
the :doc:`run <run>` command. This fix is not invoked during :doc:`energy minimization <minimize>`.
|
||||
the :doc:`run <run>` command. This fix is not invoked during
|
||||
:doc:`energy minimization <minimize>`.
|
||||
|
||||
Restrictions
|
||||
""""""""""""
|
||||
@ -102,7 +110,7 @@ Restrictions
|
||||
Related commands
|
||||
""""""""""""""""
|
||||
|
||||
:doc:`timestep <timestep>`
|
||||
:doc:`timestep <timestep>`, :doc:`dump_modify every/time <dump_modify>`
|
||||
|
||||
Default
|
||||
"""""""
|
||||
|
||||
36
src/dump.cpp
36
src/dump.cpp
@ -918,24 +918,6 @@ void Dump::modify_params(int narg, char **arg)
|
||||
else delay_flag = 0;
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"delta") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command");
|
||||
int idump;
|
||||
for (idump = 0; idump < output->ndump; idump++)
|
||||
if (strcmp(id,output->dump[idump]->id) == 0) break;
|
||||
double delta;
|
||||
if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) {
|
||||
delete [] output->var_dump[idump];
|
||||
output->var_dump[idump] = utils::strdup(&arg[iarg+1][2]);
|
||||
delta = 0.0;
|
||||
} else {
|
||||
delta = utils::numeric(FLERR,arg[iarg+1],false,lmp);
|
||||
if (delta <= 0.0) error->all(FLERR,"Illegal dump_modify command");
|
||||
}
|
||||
output->mode_dump[idump] = 1;
|
||||
output->delta_dump[idump] = delta;
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"every") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command");
|
||||
int idump;
|
||||
@ -954,6 +936,24 @@ void Dump::modify_params(int narg, char **arg)
|
||||
output->every_dump[idump] = n;
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"every/time") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command");
|
||||
int idump;
|
||||
for (idump = 0; idump < output->ndump; idump++)
|
||||
if (strcmp(id,output->dump[idump]->id) == 0) break;
|
||||
double delta;
|
||||
if (strstr(arg[iarg+1],"v_") == arg[iarg+1]) {
|
||||
delete [] output->var_dump[idump];
|
||||
output->var_dump[idump] = utils::strdup(&arg[iarg+1][2]);
|
||||
delta = 0.0;
|
||||
} else {
|
||||
delta = utils::numeric(FLERR,arg[iarg+1],false,lmp);
|
||||
if (delta <= 0.0) error->all(FLERR,"Illegal dump_modify command");
|
||||
}
|
||||
output->mode_dump[idump] = 1;
|
||||
output->every_time_dump[idump] = delta;
|
||||
iarg += 2;
|
||||
|
||||
} else if (strcmp(arg[iarg],"fileper") == 0) {
|
||||
if (iarg+2 > narg) error->all(FLERR,"Illegal dump_modify command");
|
||||
if (!multiproc)
|
||||
|
||||
@ -197,12 +197,15 @@ void FixDtReset::end_of_step()
|
||||
|
||||
laststep = update->ntimestep;
|
||||
|
||||
// calls to other classes that need to know timestep size changed
|
||||
|
||||
update->update_time();
|
||||
update->dt = dt;
|
||||
update->dt_default = 0;
|
||||
if (respaflag) update->integrate->reset_dt();
|
||||
if (force->pair) force->pair->reset_dt();
|
||||
for (int i = 0; i < modify->nfix; i++) modify->fix[i]->reset_dt();
|
||||
output->reset_dt();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
204
src/output.cpp
204
src/output.cpp
@ -29,6 +29,7 @@
|
||||
#include "variable.h"
|
||||
#include "write_restart.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
using namespace LAMMPS_NS;
|
||||
@ -62,7 +63,7 @@ Output::Output(LAMMPS *lmp) : Pointers(lmp)
|
||||
max_dump = 0;
|
||||
mode_dump = nullptr;
|
||||
every_dump = nullptr;
|
||||
delta_dump = nullptr;
|
||||
every_time_dump = nullptr;
|
||||
next_dump = nullptr;
|
||||
next_time_dump = nullptr;
|
||||
last_dump = nullptr;
|
||||
@ -98,7 +99,7 @@ Output::~Output()
|
||||
|
||||
memory->destroy(mode_dump);
|
||||
memory->destroy(every_dump);
|
||||
memory->destroy(delta_dump);
|
||||
memory->destroy(every_time_dump);
|
||||
memory->destroy(next_dump);
|
||||
memory->destroy(next_time_dump);
|
||||
memory->destroy(last_dump);
|
||||
@ -134,7 +135,7 @@ void Output::init()
|
||||
for (int i = 0; i < ndump; i++) dump[i]->init();
|
||||
for (int i = 0; i < ndump; i++)
|
||||
if ((mode_dump[i] == 0 && every_dump[i] == 0) ||
|
||||
(mode_dump[i] == 1 && delta_dump[i] == 0.0)) {
|
||||
(mode_dump[i] == 1 && every_time_dump[i] == 0.0)) {
|
||||
ivar_dump[i] = input->variable->find(var_dump[i]);
|
||||
if (ivar_dump[i] < 0)
|
||||
error->all(FLERR,"Variable name for dump every or delta does not exist");
|
||||
@ -169,42 +170,61 @@ void Output::setup(int memflag)
|
||||
{
|
||||
bigint ntimestep = update->ntimestep;
|
||||
|
||||
// perform dump at start of run only if:
|
||||
// current timestep is multiple of every and last dump not >= this step
|
||||
// this is first run after dump created and firstflag is set
|
||||
// note that variable freq will not write unless triggered by firstflag
|
||||
// set next_dump, and also next_time_dump for mode_dump = 1
|
||||
// set next_dump_any to smallest next_dump
|
||||
// wrap dumps that invoke computes or do variable eval with clear/add
|
||||
// if dump not written now, use addstep_compute_all() since don't know
|
||||
// what computes the dump write would invoke
|
||||
// if no dumps, set next_dump_any to last+1 so will not influence next
|
||||
|
||||
int writeflag;
|
||||
// consider all dumps
|
||||
// decide whether to write snapshot and/or calculate next step for dump
|
||||
|
||||
if (ndump && update->restrict_output == 0) {
|
||||
for (int idump = 0; idump < ndump; idump++) {
|
||||
|
||||
// wrap dumps that invoke computes or do variable eval with clear/add
|
||||
|
||||
if (dump[idump]->clearstep || var_dump[idump])
|
||||
modify->clearstep_compute();
|
||||
|
||||
writeflag = 0;
|
||||
if (mode_dump[idump] == 0) {
|
||||
if (every_dump[idump] && (ntimestep % every_dump[idump] == 0) &&
|
||||
last_dump[idump] != ntimestep) writeflag = 1;
|
||||
} else {
|
||||
if (delta_dump[idump] >= 0.0 && last_dump[idump] != ntimestep)
|
||||
writeflag = 1;
|
||||
}
|
||||
// write a snapshot at setup only if any of these 3 conditions hold
|
||||
// (1) this is first run since dump was created and its first_flag = 0
|
||||
// (2) mode_dump = 0 and timestep is multiple of every_dump
|
||||
// (3) mode_dump = 1 and time is multiple of every_time_dump (within EPSDT)
|
||||
// (2) and (3) only apply for non-variable dump intervals
|
||||
// finally, do not write if same snapshot written previously,
|
||||
// i.e. on last timestep of previous run
|
||||
|
||||
int writeflag = 0;
|
||||
|
||||
if (last_dump[idump] < 0 && dump[idump]->first_flag == 1) writeflag = 1;
|
||||
|
||||
if (mode_dump[idump] == 0) {
|
||||
if (every_dump[idump] && (ntimestep % every_dump[idump] == 0))
|
||||
writeflag = 1;
|
||||
} else {
|
||||
if (every_time_dump[idump] > 0.0) {
|
||||
double tcurrent = update->atime +
|
||||
(ntimestep - update->atimestep) * update->dt;
|
||||
double remainder = fmod(tcurrent,every_time_dump[idump]);
|
||||
if ((remainder < EPSDT*update->dt) ||
|
||||
(every_time_dump[idump] - remainder < EPSDT*update->dt))
|
||||
writeflag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (last_dump[idump] == ntimestep) writeflag = 0;
|
||||
|
||||
// perform dump
|
||||
|
||||
if (writeflag) {
|
||||
dump[idump]->write();
|
||||
last_dump[idump] = ntimestep;
|
||||
}
|
||||
|
||||
// calculate timestep and/or time for next dump
|
||||
// set next_dump and next_time_dump, 0 arg for setup()
|
||||
// only do this if dump written or dump has not been written yet
|
||||
|
||||
calculate_next_dump(0,idump,ntimestep);
|
||||
if (writeflag || last_dump[idump] < 0)
|
||||
calculate_next_dump(0,idump,ntimestep);
|
||||
|
||||
// if dump not written now, use addstep_compute_all()
|
||||
// since don't know what computes the dump will invoke
|
||||
|
||||
if (dump[idump]->clearstep || var_dump[idump]) {
|
||||
if (writeflag) modify->addstep_compute(next_dump[idump]);
|
||||
@ -214,6 +234,9 @@ void Output::setup(int memflag)
|
||||
if (idump) next_dump_any = MIN(next_dump_any,next_dump[idump]);
|
||||
else next_dump_any = next_dump[0];
|
||||
}
|
||||
|
||||
// if no dumps, set next_dump_any to last+1 so will not influence next
|
||||
|
||||
} else next_dump_any = update->laststep + 1;
|
||||
|
||||
// do not write restart files at start of run
|
||||
@ -296,33 +319,26 @@ void Output::write(bigint ntimestep)
|
||||
// set next_dump and also next_time_dump for mode_dump = 1
|
||||
// set next_dump_any to smallest next_dump
|
||||
// wrap dumps that invoke computes or do variable eval with clear/add
|
||||
// if dump not written now, use addstep_compute_all() since don't know
|
||||
// what computes the dump write would invoke
|
||||
|
||||
|
||||
int writeflag;
|
||||
|
||||
if (next_dump_any == ntimestep) {
|
||||
for (int idump = 0; idump < ndump; idump++) {
|
||||
if (next_dump[idump] == ntimestep) {
|
||||
if (last_dump[idump] == ntimestep) continue;
|
||||
|
||||
if (dump[idump]->clearstep || var_dump[idump])
|
||||
modify->clearstep_compute();
|
||||
|
||||
writeflag = 0;
|
||||
if (last_dump[idump] != ntimestep) writeflag = 1;
|
||||
// perform dump
|
||||
// reset next_dump and next_time_dump, 1 arg for write()
|
||||
|
||||
if (writeflag) {
|
||||
dump[idump]->write();
|
||||
last_dump[idump] = ntimestep;
|
||||
}
|
||||
|
||||
// set next_dump and next_time_dump, 1 arg for write()
|
||||
|
||||
dump[idump]->write();
|
||||
last_dump[idump] = ntimestep;
|
||||
calculate_next_dump(1,idump,ntimestep);
|
||||
|
||||
if (dump[idump]->clearstep || var_dump[idump]) {
|
||||
if (writeflag) modify->addstep_compute(next_dump[idump]);
|
||||
else modify->addstep_compute_all(next_dump[idump]);
|
||||
}
|
||||
if (dump[idump]->clearstep || var_dump[idump])
|
||||
modify->addstep_compute(next_dump[idump]);
|
||||
}
|
||||
|
||||
if (idump) next_dump_any = MIN(next_dump_any,next_dump[idump]);
|
||||
@ -422,6 +438,10 @@ void Output::write_dump(bigint ntimestep)
|
||||
operates in one of two modes, based on mode_dump flag
|
||||
for timestep mode, set next_dump
|
||||
for simulation time mode, set next_time_dump and next_dump
|
||||
which flag depends on caller
|
||||
0 = from setup() at start of run
|
||||
1 = from write() during run each time a dump file is written
|
||||
2 = from reset_dt() called from fix dt/reset when it changes timestep size
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Output::calculate_next_dump(int which, int idump, bigint ntimestep)
|
||||
@ -431,13 +451,17 @@ void Output::write_dump(bigint ntimestep)
|
||||
|
||||
if (mode_dump[idump] == 0) {
|
||||
|
||||
// for setup, make next_dump a multiple of every_dump
|
||||
|
||||
if (every_dump[idump]) {
|
||||
if (which == 1) next_dump[idump] += every_dump[idump];
|
||||
else
|
||||
|
||||
// which = 0: nextdump = next multiple of every_dump
|
||||
// which = 1: increment nextdump by every_dump
|
||||
|
||||
if (which == 0)
|
||||
next_dump[idump] =
|
||||
(ntimestep/every_dump[idump])*every_dump[idump] + every_dump[idump];
|
||||
else if (which == 1)
|
||||
next_dump[idump] += every_dump[idump];
|
||||
|
||||
} else {
|
||||
next_dump[idump] = static_cast<bigint>
|
||||
(input->variable->compute_equal(ivar_dump[idump]));
|
||||
@ -449,22 +473,29 @@ void Output::write_dump(bigint ntimestep)
|
||||
// set next_time_dump and next_dump
|
||||
|
||||
} else {
|
||||
|
||||
bigint nextdump;
|
||||
double nexttime;
|
||||
double tcurrent = update->atime +
|
||||
(ntimestep - update->atimestep) * update->dt;
|
||||
|
||||
// for setup, make nexttime a multiple of delta_dump
|
||||
if (every_time_dump[idump] > 0.0) {
|
||||
|
||||
if (delta_dump[idump] > 0.0) {
|
||||
if (which == 1) nexttime = next_time_dump[idump] + delta_dump[idump];
|
||||
else
|
||||
nexttime = static_cast<bigint> (tcurrent/delta_dump[idump]) *
|
||||
delta_dump[idump] + delta_dump[idump];
|
||||
// which = 0: nexttime = next multiple of every_time_dump
|
||||
// which = 1: increment nexttime by every_time_dump
|
||||
// which = 2: no change to previous nexttime (only timestep has changed)
|
||||
|
||||
if (which == 0)
|
||||
nexttime = static_cast<bigint> (tcurrent/every_time_dump[idump]) *
|
||||
every_time_dump[idump] + every_time_dump[idump];
|
||||
else if (which == 1)
|
||||
nexttime = next_time_dump[idump] + every_time_dump[idump];
|
||||
else if (which == 2)
|
||||
nexttime = next_time_dump[idump];
|
||||
|
||||
nextdump = ntimestep +
|
||||
static_cast<bigint> ((nexttime - tcurrent + EPSDT*update->dt) /
|
||||
update->dt);
|
||||
static_cast<bigint> ((nexttime - tcurrent - EPSDT*update->dt) /
|
||||
update->dt) + 1;
|
||||
|
||||
// if delta is too small to reach next timestep, use multiple of delta
|
||||
|
||||
@ -472,30 +503,35 @@ void Output::write_dump(bigint ntimestep)
|
||||
double tnext = update->atime +
|
||||
(ntimestep+1 - update->atimestep) * update->dt;
|
||||
int multiple = static_cast<int>
|
||||
((tnext - nexttime) / delta_dump[idump]);
|
||||
nexttime = nexttime + (multiple+1)*delta_dump[idump];
|
||||
((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);
|
||||
static_cast<bigint> ((nexttime - tcurrent - EPSDT*update->dt) /
|
||||
update->dt) + 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
nexttime = input->variable->compute_equal(ivar_dump[idump]);
|
||||
|
||||
// do not re-evaulate variable for which = 2, leave nexttime as-is
|
||||
// unless next_time_dump < 0.0, which means variable never yet evaluated
|
||||
|
||||
if (which < 2 || next_time_dump[idump] < 0.0)
|
||||
nexttime = input->variable->compute_equal(ivar_dump[idump]);
|
||||
else
|
||||
nexttime = next_time_dump[idump];
|
||||
|
||||
if (nexttime <= tcurrent)
|
||||
error->all(FLERR,"Dump delta variable returned a bad time");
|
||||
error->all(FLERR,"Dump every/time variable returned a bad time");
|
||||
|
||||
nextdump = ntimestep +
|
||||
static_cast<bigint> ((nexttime - tcurrent + EPSDT*update->dt) /
|
||||
update->dt);
|
||||
static_cast<bigint> ((nexttime - tcurrent - EPSDT*update->dt) /
|
||||
update->dt) + 1;
|
||||
if (nextdump <= ntimestep)
|
||||
error->all(FLERR,"Dump delta variable too small for next timestep");
|
||||
error->all(FLERR,"Dump every/time variable too small for next timestep");
|
||||
}
|
||||
|
||||
next_time_dump[idump] = nexttime;
|
||||
next_dump[idump] = nextdump;
|
||||
|
||||
//printf("END time %20.16g step %ld ratio %g\n",
|
||||
// next_time_dump[idump],next_dump[idump],
|
||||
// next_time_dump[idump]/update->dt/(next_dump[idump]+1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,7 +565,7 @@ void Output::write_restart(bigint ntimestep)
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
timestep is being changed, called by update->reset_timestep()
|
||||
reset next timestep values for dumps, restart, thermo output
|
||||
reset next output values for dumps, restart, thermo output
|
||||
reset to smallest value >= new timestep
|
||||
if next timestep set by variable evaluation,
|
||||
eval for ntimestep-1, so current ntimestep can be returned if needed
|
||||
@ -626,6 +662,35 @@ void Output::reset_timestep(bigint ntimestep)
|
||||
next = MIN(next,next_thermo);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
timestep size is being changed, called by fix dt/reset (at end of step)
|
||||
reset next output values for dumps which have mode_dump=1
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Output::reset_dt()
|
||||
{
|
||||
next_dump_any = MAXBIGINT;
|
||||
|
||||
for (int idump = 0; idump < ndump; idump++) {
|
||||
if (mode_dump[idump] == 1) {
|
||||
|
||||
// reset next_dump for unchanged next_time_dump, 2 arg for reset_dt()
|
||||
|
||||
calculate_next_dump(2,idump,update->ntimestep);
|
||||
|
||||
// use compute_all() b/c don't know what computes will be needed
|
||||
|
||||
if (dump[idump]->clearstep || var_dump[idump])
|
||||
modify->addstep_compute_all(next_dump[idump]);
|
||||
}
|
||||
|
||||
next_dump_any = MIN(next_dump_any,next_dump[idump]);
|
||||
}
|
||||
|
||||
next = MIN(next_dump_any,next_restart);
|
||||
next = MIN(next,next_thermo);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
add a Dump to list of Dumps
|
||||
------------------------------------------------------------------------- */
|
||||
@ -652,7 +717,7 @@ void Output::add_dump(int narg, char **arg)
|
||||
memory->srealloc(dump,max_dump*sizeof(Dump *),"output:dump");
|
||||
memory->grow(mode_dump,max_dump,"output:mode_dump");
|
||||
memory->grow(every_dump,max_dump,"output:every_dump");
|
||||
memory->grow(delta_dump,max_dump,"output:delta_dump");
|
||||
memory->grow(every_time_dump,max_dump,"output:every_time_dump");
|
||||
memory->grow(next_dump,max_dump,"output:next_dump");
|
||||
memory->grow(next_time_dump,max_dump,"output:next_time_dump");
|
||||
memory->grow(last_dump,max_dump,"output:last_dump");
|
||||
@ -673,7 +738,8 @@ void Output::add_dump(int narg, char **arg)
|
||||
mode_dump[ndump] = 0;
|
||||
every_dump[ndump] = utils::inumeric(FLERR,arg[3],false,lmp);
|
||||
if (every_dump[ndump] <= 0) error->all(FLERR,"Illegal dump command");
|
||||
delta_dump[ndump] = 0.0;
|
||||
every_time_dump[ndump] = 0.0;
|
||||
next_time_dump[ndump] = -1.0;
|
||||
last_dump[ndump] = -1;
|
||||
var_dump[ndump] = nullptr;
|
||||
ivar_dump[ndump] = -1;
|
||||
@ -731,7 +797,7 @@ void Output::delete_dump(char *id)
|
||||
dump[i-1] = dump[i];
|
||||
mode_dump[i-1] = mode_dump[i];
|
||||
every_dump[i-1] = every_dump[i];
|
||||
delta_dump[i-1] = delta_dump[i];
|
||||
every_time_dump[i-1] = every_time_dump[i];
|
||||
next_dump[i-1] = next_dump[i];
|
||||
next_time_dump[i-1] = next_time_dump[i];
|
||||
last_dump[i-1] = last_dump[i];
|
||||
|
||||
@ -37,8 +37,8 @@ class Output : protected Pointers {
|
||||
int max_dump; // max size of Dump list
|
||||
bigint next_dump_any; // next timestep for any Dump
|
||||
int *mode_dump; // 0/1 if write every N timesteps or Delta in sim time
|
||||
int *every_dump; // dump every this many timesteps, 0 if variable
|
||||
double *delta_dump; // dump every this delta sim time, 0.0 if variable
|
||||
int *every_dump; // dump every N timesteps, 0 if variable
|
||||
double *every_time_dump; // dump every Delta of sim time, 0.0 if variable
|
||||
bigint *next_dump; // next timestep to perform dump
|
||||
double *next_time_dump; // next simulation time to perform dump (mode = 1)
|
||||
bigint *last_dump; // last timestep each snapshot was output
|
||||
@ -75,7 +75,8 @@ class Output : protected Pointers {
|
||||
void write(bigint); // output for current timestep
|
||||
void write_dump(bigint); // force output of dump snapshots
|
||||
void write_restart(bigint); // force output of a restart file
|
||||
void reset_timestep(bigint); // reset next timestep for all output
|
||||
void reset_timestep(bigint); // reset output which depeneds on timestep
|
||||
void reset_dt(); // reset output which depends on dt
|
||||
|
||||
void add_dump(int, char **); // add a Dump to Dump list
|
||||
void modify_dump(int, char **); // modify a Dump
|
||||
|
||||
@ -458,7 +458,7 @@ Min *Update::minimize_creator(LAMMPS *lmp)
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
reset timestep as called from input script
|
||||
reset timestep called from input script
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Update::reset_timestep(int narg, char **arg)
|
||||
@ -470,24 +470,32 @@ void Update::reset_timestep(int narg, char **arg)
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
reset timestep
|
||||
called from rerun command and input script (indirectly)
|
||||
called from input script (indirectly) or rerun command
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
void Update::reset_timestep(bigint newstep)
|
||||
{
|
||||
if (newstep < 0) error->all(FLERR,"Timestep must be >= 0");
|
||||
|
||||
bigint oldstep = ntimestep;
|
||||
ntimestep = newstep;
|
||||
if (ntimestep < 0) error->all(FLERR,"Timestep must be >= 0");
|
||||
|
||||
// set atimestep to new timestep
|
||||
// so future update_time() calls will be correct
|
||||
// if newstep >= oldstep, update simulation time accordingly
|
||||
// if newstep < oldstep, zero simulation time
|
||||
|
||||
atimestep = ntimestep;
|
||||
if (newstep >= oldstep) update_time();
|
||||
|
||||
// trigger reset of timestep for output
|
||||
// do not allow any timestep-dependent fixes to be already defined
|
||||
if (newstep < oldstep) {
|
||||
atime = 0.0;
|
||||
atimestep = newstep;
|
||||
}
|
||||
|
||||
// changes to output that depend on timestep
|
||||
|
||||
output->reset_timestep(ntimestep);
|
||||
|
||||
// do not allow timestep-dependent fixes to be defined
|
||||
|
||||
for (const auto &ifix : modify->get_fix_list())
|
||||
if (ifix->time_depend)
|
||||
error->all(FLERR, "Cannot reset timestep with time-dependent fix {} defined",ifix->style);
|
||||
@ -508,7 +516,7 @@ void Update::reset_timestep(bigint newstep)
|
||||
if (icompute->timeflag) icompute->clearstep();
|
||||
}
|
||||
|
||||
// Neighbor Bin/Stencil/Pair classes store timestamps that need to be cleared
|
||||
// neighbor Bin/Stencil/Pair classes store timestamps that need to be cleared
|
||||
|
||||
neighbor->reset_timestep(ntimestep);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user