Merge pull request #3440 from lammps/dump-step-post-minimize

Enforce dump snapshots on multiples of N steps in a run after minimize
This commit is contained in:
Axel Kohlmeyer
2022-09-09 16:30:35 -04:00
committed by GitHub
3 changed files with 426 additions and 366 deletions

View File

@ -12,7 +12,7 @@ Syntax
restart N root keyword value ... restart N root keyword value ...
restart N file1 file2 keyword value ... restart N file1 file2 keyword value ...
* N = write a restart file every this many timesteps * N = write a restart file on timesteps which are multipls of N
* N can be a variable (see below) * N can be a variable (see below)
* root = filename to which timestep # is appended * root = filename to which timestep # is appended
* file1,file2 = two full filenames, toggle between them when writing file * file1,file2 = two full filenames, toggle between them when writing file
@ -42,13 +42,14 @@ Description
""""""""""" """""""""""
Write out a binary restart file with the current state of the Write out a binary restart file with the current state of the
simulation every so many timesteps, in either or both of two modes, as simulation on timesteps which are a multiple of N. A value of N = 0
a run proceeds. A value of 0 means do not write out any restart means do not write out any restart files, which is the default.
files. The two modes are as follows. If one filename is specified, a Restart files are written in one (or both) of two modes as a run
series of filenames will be created which include the timestep in the proceeds. If one filename is specified, a series of filenames will be
filename. If two filenames are specified, only 2 restart files will created which include the timestep in the filename. If two filenames
be created, with those names. LAMMPS will toggle between the 2 names are specified, only 2 restart files will be created, with those names.
as it writes successive restart files. LAMMPS will toggle between the 2 names as it writes successive restart
files.
Note that you can specify the restart command twice, once with a Note that you can specify the restart command twice, once with a
single filename and once with two filenames. This would allow you, single filename and once with two filenames. This would allow you,

View File

@ -237,11 +237,9 @@ void Output::setup(int memflag)
last_dump[idump] = ntimestep; last_dump[idump] = ntimestep;
} }
// calculate timestep and/or time for next dump // calculate timestep or time for next dump
// set next_dump and next_time_dump, 0 arg for setup() // set next_dump and next_time_dump
// only do this if dump written or dump has not been written yet
if (writeflag || last_dump[idump] < 0)
calculate_next_dump(SETUP,idump,ntimestep); calculate_next_dump(SETUP,idump,ntimestep);
// if dump not written now, use addstep_compute_all() // if dump not written now, use addstep_compute_all()
@ -268,11 +266,11 @@ void Output::setup(int memflag)
if (restart_flag && update->restrict_output == 0) { if (restart_flag && update->restrict_output == 0) {
if (restart_flag_single) { if (restart_flag_single) {
if (restart_every_single) if (restart_every_single) {
next_restart_single = next_restart_single =
(ntimestep/restart_every_single)*restart_every_single + (ntimestep/restart_every_single)*restart_every_single +
restart_every_single; restart_every_single;
else { } else {
auto nextrestart = static_cast<bigint> auto nextrestart = static_cast<bigint>
(input->variable->compute_equal(ivar_restart_single)); (input->variable->compute_equal(ivar_restart_single));
if (nextrestart <= ntimestep) if (nextrestart <= ntimestep)
@ -365,7 +363,7 @@ void Output::setup(int memflag)
modify->clearstep_compute(); modify->clearstep_compute();
// perform dump // perform dump
// reset next_dump and next_time_dump, 1 arg for write() // set next_dump and next_time_dump
dump[idump]->write(); dump[idump]->write();
last_dump[idump] = ntimestep; last_dump[idump] = ntimestep;
@ -388,7 +386,6 @@ void Output::setup(int memflag)
if (next_restart == ntimestep) { if (next_restart == ntimestep) {
if (next_restart_single == ntimestep) { if (next_restart_single == ntimestep) {
std::string file = restart1; std::string file = restart1;
std::size_t found = file.find('*'); std::size_t found = file.find('*');
if (found != std::string::npos) if (found != std::string::npos)
@ -407,6 +404,7 @@ void Output::setup(int memflag)
modify->addstep_compute(next_restart_single); modify->addstep_compute(next_restart_single);
} }
} }
if (next_restart_double == ntimestep) { if (next_restart_double == ntimestep) {
if (last_restart != ntimestep) { if (last_restart != ntimestep) {
if (restart_toggle == 0) { if (restart_toggle == 0) {
@ -417,6 +415,7 @@ void Output::setup(int memflag)
restart_toggle = 0; restart_toggle = 0;
} }
} }
if (restart_every_double) next_restart_double += restart_every_double; if (restart_every_double) next_restart_double += restart_every_double;
else { else {
modify->clearstep_compute(); modify->clearstep_compute();
@ -489,8 +488,9 @@ void Output::calculate_next_dump(int which, int idump, bigint ntimestep)
if (every_dump[idump]) { if (every_dump[idump]) {
// which = SETUP: nextdump = next multiple of every_dump // which = SETUP: next_dump = next multiple of every_dump
// which = WRITE: increment nextdump by every_dump // which = WRITE: increment next_dump by every_dump
// current step is already multiple of every_dump
if (which == SETUP) if (which == SETUP)
next_dump[idump] = (ntimestep/every_dump[idump])*every_dump[idump] + every_dump[idump]; next_dump[idump] = (ntimestep/every_dump[idump])*every_dump[idump] + every_dump[idump];
@ -728,7 +728,6 @@ void Output::reset_dt()
next = MIN(next,next_thermo); next = MIN(next,next_thermo);
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
add a Dump to list of Dumps add a Dump to list of Dumps
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */

View File

@ -699,6 +699,66 @@ TEST_F(DumpAtomTest, binary_write_dump)
delete_file(dump_file); delete_file(dump_file);
} }
TEST_F(DumpAtomTest, frequency)
{
auto dump_file = dump_filename("frequency");
BEGIN_HIDE_OUTPUT();
command("dump id all atom 5 " + dump_file);
command("run 15 post no");
command("run 12 post no");
END_HIDE_OUTPUT();
// NOTE: must reset to current timestep (27) to avoid unexpected issues with following
TEST_FAILURE(".*ERROR: Cannot reset timestep with active dump - must undump first.*",
command("reset_timestep 27"););
BEGIN_HIDE_OUTPUT();
command("run 3 post no");
command("undump id");
command("reset_timestep 5");
command("dump id all atom 10 " + dump_file);
command("dump_modify id append yes");
command("run 20 post no");
command("undump id");
END_HIDE_OUTPUT();
std::vector<std::string> expected, values;
values = extract_items(dump_file, "TIMESTEP");
expected = {"0", "5", "10", "15", "20", "25", "30", "10", "20"};
ASSERT_EQ(values.size(), expected.size());
for (int i = 0; i < expected.size(); ++i)
ASSERT_THAT(values[i], Eq(expected[i]));
BEGIN_HIDE_OUTPUT();
command("reset_timestep 10");
command("dump id all atom 10 " + dump_file);
command("run 20 post no");
command("undump id");
END_HIDE_OUTPUT();
values = extract_items(dump_file, "TIMESTEP");
expected = {"10", "20", "30"};
ASSERT_EQ(values.size(), expected.size());
for (int i = 0; i < expected.size(); ++i)
ASSERT_THAT(values[i], Eq(expected[i]));
BEGIN_HIDE_OUTPUT();
command("reset_timestep 0");
command("dump id all atom 10 " + dump_file);
command("minimize 0.0 0.0 15 30");
command("run 20 post no");
command("undump id");
END_HIDE_OUTPUT();
values = extract_items(dump_file, "TIMESTEP");
expected = {"0", "10", "15", "20", "30"};
ASSERT_EQ(values.size(), expected.size());
for (int i = 0; i < expected.size(); ++i)
ASSERT_THAT(values[i], Eq(expected[i]));
delete_file(dump_file);
}
//------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------
// dump_modify // dump_modify
//------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------