add logic to rerun command to trigger dumps on expected steps or time

This commit is contained in:
Axel Kohlmeyer
2023-01-05 04:06:11 -05:00
parent 8cfb6680e0
commit e7ab2bc97d
2 changed files with 79 additions and 6 deletions

View File

@ -545,11 +545,9 @@ void Output::calculate_next_dump(int which, int idump, bigint ntimestep)
// if delta is too small to reach next timestep, use multiple of delta
if (nextdump == ntimestep) {
double tnext = update->atime +
(ntimestep+1 - update->atimestep) * update->dt;
int multiple = static_cast<int>
((tnext - nexttime) / every_time_dump[idump]);
nexttime = nexttime + (multiple+1)*every_time_dump[idump];
double tnext = update->atime + (ntimestep + 1 - update->atimestep) * update->dt;
int multiple = static_cast<int>((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;
}

View File

@ -17,17 +17,20 @@
#include "domain.h"
#include "error.h"
#include "finish.h"
#include "input.h"
#include "integrate.h"
#include "modify.h"
#include "output.h"
#include "read_dump.h"
#include "timer.h"
#include "update.h"
#include "variable.h"
#include <cstring>
using namespace LAMMPS_NS;
#define EPSDT 1.0e-6
/* ---------------------------------------------------------------------- */
Rerun::Rerun(LAMMPS *lmp) : Command(lmp) {}
@ -165,6 +168,78 @@ void Rerun::command(int narg, char **arg)
modify->init();
update->integrate->setup_minimal(1);
modify->end_of_step();
// fix up the "next_dump" settings for dumps if the sequence differs from what is read in
for (int idump = 0; idump < output->ndump; ++idump) {
// dumps triggered by timestep
if (output->mode_dump[idump] == 0) {
// rerun has advanced the timestep faster than the dump expected so we need to catch it up
if (output->next_dump[idump] < ntimestep) {
// equidistant dumps
if (output->every_dump[idump]) {
// if current step compatible with dump frequency, adjust next_dump setting for dump
if (ntimestep % output->every_dump[idump] == 0) output->next_dump[idump] = ntimestep;
} else {
// next dump is determined by variable.
// advance next timestep computation from variable until it is equal or larger
// than the current dump timestep; trigger dump only if equal.
bigint savedstep = update->ntimestep;
update->ntimestep = output->next_dump[idump];
bigint nextdump;
do {
nextdump = (bigint) input->variable->compute_equal(output->ivar_dump[idump]);
update->ntimestep = nextdump;
} while (nextdump < ntimestep);
output->next_dump[idump] = nextdump;
update->ntimestep = savedstep;
}
}
} else {
// dumps triggered by time
double tcurrent = update->atime + (ntimestep - update->atimestep) * update->dt;
// rerun time has moved beyond expected time for dump so we need to catch it up
if (output->next_time_dump[idump] < tcurrent) {
// equidistant dumps in time
if (output->every_time_dump[idump] > 0.0) {
// trigger dump if current time is within +/- half a timestep of the every interval
double every = output->every_time_dump[idump];
double rest = fabs(tcurrent/every - round(tcurrent/every)) * every/update->dt;
if (rest < 0.5) {
output->next_dump[idump] = ntimestep;
output->next_time_dump[idump] = tcurrent;
} else {
double nexttime = (floor(tcurrent/every) + 1.0) * every;
output->next_dump[idump] = update->ntimestep
+ (bigint) ((nexttime - (update->atime + (update->ntimestep - update->atimestep) *
update->dt) - EPSDT*update->dt) / update->dt) + 1;
output->next_time_dump[idump] = nexttime;
}
} else {
// next dump time is determined by variable.
// advance next time computation from variable until is is equal or larger
// than the current time/timestep
bigint savedstep = update->ntimestep;
update->ntimestep = output->next_dump[idump];
double nexttime = output->next_time_dump[idump];
bigint nextstep = output->next_dump[idump];
while (nextstep < ntimestep) {
nexttime = input->variable->compute_equal(output->ivar_dump[idump]);
nextstep = update->ntimestep
+ (bigint) ((nexttime - (update->atime + (update->ntimestep - update->atimestep) *
update->dt) - EPSDT*update->dt) / update->dt) + 1;
update->ntimestep = nextstep;
};
if (ntimestep > 0) {
output->next_time_dump[idump] = nexttime;
output->next_dump[idump] = nextstep;
}
update->ntimestep = savedstep;
}
}
}
}
output->next_dump_any = ntimestep;
if (firstflag) output->setup();
else if (output->next) output->write(ntimestep);
@ -172,7 +247,7 @@ void Rerun::command(int narg, char **arg)
firstflag = 0;
ntimestep = rd->next(ntimestep,last,nevery,nskip);
if (stopflag && ntimestep > stop)
error->all(FLERR,"Read rerun dump file timestep > specified stop");
error->all(FLERR,"Read rerun dump file timestep {} > specified stop {}", ntimestep, stop);
if (ntimestep < 0) break;
}