#include "gromacs/domdec/domdec.h"
#include "gromacs/domdec/domdec_network.h"
#include "gromacs/domdec/domdec_struct.h"
+#include "gromacs/domdec/localtopologychecker.h"
#include "gromacs/domdec/mdsetup.h"
#include "gromacs/domdec/partition.h"
#include "gromacs/essentialdynamics/edsam.h"
#include "gromacs/mdtypes/mdatom.h"
#include "gromacs/mdtypes/mdrunoptions.h"
#include "gromacs/mdtypes/observableshistory.h"
+#include "gromacs/mdtypes/observablesreducer.h"
#include "gromacs/mdtypes/simulation_workload.h"
#include "gromacs/mdtypes/state.h"
#include "gromacs/mimic/utilities.h"
#include "gromacs/pbcutil/pbc.h"
+#include "gromacs/pulling/output.h"
#include "gromacs/pulling/pull.h"
#include "gromacs/swap/swapcoords.h"
#include "gromacs/timing/wallcycle.h"
* \param[in,out] globalState The global state container
* \param[in] constructVsites When true, vsite coordinates are constructed
* \param[in] vsite Vsite setup, can be nullptr when \p constructVsites = false
- * \param[in] timeStep Time step, used for constructing vsites
*/
static void prepareRerunState(const t_trxframe& rerunFrame,
t_state* globalState,
bool constructVsites,
- const VirtualSitesHandler* vsite,
- double timeStep)
+ const VirtualSitesHandler* vsite)
{
auto x = makeArrayRef(globalState->x);
auto rerunX = arrayRefFromArray(reinterpret_cast<gmx::RVec*>(rerunFrame.x), globalState->natoms);
{
GMX_ASSERT(vsite, "Need valid vsite for constructing vsites");
- vsite->construct(globalState->x, timeStep, globalState->v, globalState->box);
+ vsite->construct(globalState->x, globalState->v, globalState->box, gmx::VSiteOperation::PositionsAndVelocities);
}
}
// t_inputrec is being replaced by IMdpOptionsProvider, so this
// will go away eventually.
const t_inputrec* ir = inputrec;
- int64_t step, step_rel;
double t;
bool isLastStep = false;
bool doFreeEnergyPerturbation = false;
t_trxstatus* status = nullptr;
rvec mu_tot;
t_trxframe rerun_fr;
- gmx_localtop_t top(top_global->ffparams);
ForceBuffers f;
gmx_global_stat_t gstat;
gmx_shellfc_t* shellfc;
double cycles;
- /* Domain decomposition could incorrectly miss a bonded
- interaction, but checking for that requires a global
- communication stage, which does not otherwise happen in DD
- code. So we do that alongside the first global energy reduction
- after a new DD is made. These variables handle whether the
- check happens, and the result it returns. */
- bool shouldCheckNumberOfBondedInteractions = false;
- int totalNumberOfBondedInteractions = -1;
-
SimulationSignals signals;
// Most global communnication stages don't propagate mdrun
// signals, and will use this object to achieve that.
"be available in a different form in a future version of GROMACS, "
"e.g. gmx rerun -f.");
- if (ir->efep != efepNO
+ if (ir->efep != FreeEnergyPerturbationType::No
&& (mdAtoms->mdatoms()->nMassPerturbed > 0 || (constr && constr->havePerturbedConstraints())))
{
gmx_fatal(FARGS,
{
gmx_fatal(FARGS, "Multiple simulations not supported by rerun.");
}
- if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc, [](int i) {
- return i != eannNO;
+ if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc, [](SimulatedAnnealing i) {
+ return i != SimulatedAnnealing::No;
}))
{
gmx_fatal(FARGS, "Simulated annealing not supported by rerun.");
int nstglobalcomm = 1;
const bool bNS = true;
- const SimulationGroups* groups = &top_global->groups;
- if (ir->eI == eiMimic)
+ ObservablesReducer observablesReducer = observablesReducerBuilder->build();
+
+ const SimulationGroups* groups = &top_global.groups;
+ if (ir->eI == IntegrationAlgorithm::Mimic)
{
- auto nonConstGlobalTopology = const_cast<gmx_mtop_t*>(top_global);
- nonConstGlobalTopology->intermolecularExclusionGroup = genQmmmIndices(*top_global);
+ auto* nonConstGlobalTopology = const_cast<gmx_mtop_t*>(&top_global);
+ nonConstGlobalTopology->intermolecularExclusionGroup = genQmmmIndices(top_global);
}
int* fep_state = MASTER(cr) ? &state_global->fep_state : nullptr;
gmx::ArrayRef<real> lambda = MASTER(cr) ? state_global->lambda : gmx::ArrayRef<real>();
- initialize_lambdas(fplog, *ir, MASTER(cr), fep_state, lambda);
+ initialize_lambdas(fplog,
+ ir->efep,
+ ir->bSimTemp,
+ *ir->fepvals,
+ ir->simtempvals->temperatures,
+ gmx::arrayRefFromArray(ir->opts.ref_t, ir->opts.ngtc),
+ MASTER(cr),
+ fep_state,
+ lambda);
const bool simulationsShareState = false;
gmx_mdoutf* outf = init_mdoutf(fplog,
nfile,
mdrunOptions,
cr,
outputProvider,
- mdModulesNotifier,
+ mdModulesNotifiers,
ir,
top_global,
oenv,
ms);
gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf),
top_global,
- ir,
+ *ir,
pull_work,
mdoutf_get_fp_dhdl(outf),
true,
StartingBehavior::NewSimulation,
simulationsShareState,
- mdModulesNotifier);
+ mdModulesNotifiers);
gstat = global_stat_init(ir);
top_global,
constr ? constr->numFlexibleConstraints() : 0,
ir->nstcalcenergy,
- DOMAINDECOMP(cr),
+ haveDDAtomOrdering(*cr),
runScheduleWork->simulationWork.useGpuPme);
{
- double io = compute_io(ir, top_global->natoms, *groups, energyOutput.numEnergyTerms(), 1);
+ double io = compute_io(ir, top_global.natoms, *groups, energyOutput.numEnergyTerms(), 1);
if ((io > 2000) && MASTER(cr))
{
fprintf(stderr, "\nWARNING: This run will generate roughly %.0f Mb of data\n\n", io);
}
}
- // Local state only becomes valid now.
- std::unique_ptr<t_state> stateInstance;
- t_state* state;
-
- if (DOMAINDECOMP(cr))
+ if (haveDDAtomOrdering(*cr))
{
- stateInstance = std::make_unique<t_state>();
- state = stateInstance.get();
- dd_init_local_state(cr->dd, state_global, state);
+ // Local state only becomes valid now.
+ dd_init_local_state(*cr->dd, state_global, state);
/* Distribute the charge groups over the nodes from the master node */
dd_partition_system(fplog,
TRUE,
1,
state_global,
- *top_global,
- ir,
+ top_global,
+ *ir,
imdSession,
pull_work,
state,
&f,
mdAtoms,
- &top,
+ top,
fr,
vsite,
constr,
nrnb,
nullptr,
FALSE);
- shouldCheckNumberOfBondedInteractions = true;
}
else
{
/* Copy the pointer to the global state */
state = state_global;
- mdAlgorithmsSetupAtomData(cr, ir, *top_global, &top, fr, &f, mdAtoms, constr, vsite, shellfc);
+ mdAlgorithmsSetupAtomData(cr, *ir, top_global, top, fr, &f, mdAtoms, constr, vsite, shellfc);
}
- auto mdatoms = mdAtoms->mdatoms();
+ auto* mdatoms = mdAtoms->mdatoms();
+ fr->longRangeNonbondeds->updateAfterPartition(*mdatoms);
// NOTE: The global state is no longer used at this point.
// But state_global is still used as temporary storage space for writing
// the global state to file and potentially for replica exchange.
// (Global topology should persist.)
- update_mdatoms(mdatoms, state->lambda[efptMASS]);
+ update_mdatoms(mdatoms, state->lambda[FreeEnergyPerturbationCouplingType::Mass]);
- if (ir->efep != efepNO && ir->fepvals->nstdhdl != 0)
+ if (ir->efep != FreeEnergyPerturbationType::No && ir->fepvals->nstdhdl != 0)
{
doFreeEnergyPerturbation = true;
}
+ int64_t step = ir->init_step;
+ int64_t step_rel = 0;
+
{
- int cglo_flags =
- (CGLO_GSTAT
- | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0));
+ int cglo_flags = CGLO_GSTAT;
bool bSumEkinhOld = false;
t_vcm* vcm = nullptr;
compute_globals(gstat,
shake_vir,
total_vir,
pres,
- gmx::ArrayRef<real>{},
&nullSignaller,
state->box,
- &totalNumberOfBondedInteractions,
&bSumEkinhOld,
- cglo_flags);
+ cglo_flags,
+ step,
+ &observablesReducer);
+ // Clean up after pre-step use of compute_globals()
+ observablesReducer.markAsReadyToReduce();
}
- checkNumberOfBondedInteractions(mdlog,
- cr,
- totalNumberOfBondedInteractions,
- top_global,
- &top,
- makeConstArrayRef(state->x),
- state->box,
- &shouldCheckNumberOfBondedInteractions);
if (MASTER(cr))
{
fprintf(stderr,
"starting md rerun '%s', reading coordinates from"
" input trajectory '%s'\n\n",
- *(top_global->name),
+ *(top_global.name),
opt2fn("-rerun", nfile, fnm));
if (mdrunOptions.verbose)
{
}
walltime_accounting_start_time(walltime_accounting);
- wallcycle_start(wcycle, ewcRUN);
+ wallcycle_start(wcycle, WallCycleCounter::Run);
print_start(fplog, cr, walltime_accounting, "mdrun");
/***********************************************************
if (MASTER(cr))
{
isLastStep = !read_first_frame(oenv, &status, opt2fn("-rerun", nfile, fnm), &rerun_fr, TRX_NEED_X);
- if (rerun_fr.natoms != top_global->natoms)
+ if (rerun_fr.natoms != top_global.natoms)
{
gmx_fatal(FARGS,
"Number of atoms in trajectory (%d) does not match the "
"run input file (%d)\n",
rerun_fr.natoms,
- top_global->natoms);
+ top_global.natoms);
}
if (ir->pbcType != PbcType::No)
calc_shifts(rerun_fr.box, fr->shift_vec);
}
- step = ir->init_step;
- step_rel = 0;
-
auto stopHandler = stopHandlerBuilder->getStopHandlerMD(
compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]),
false,
isLastStep = (isLastStep || (ir->nsteps >= 0 && step_rel > ir->nsteps));
while (!isLastStep)
{
- wallcycle_start(wcycle, ewcSTEP);
+ wallcycle_start(wcycle, WallCycleCounter::Step);
if (rerun_fr.bStep)
{
t = step;
}
- if (ir->efep != efepNO && MASTER(cr))
+ if (ir->efep != FreeEnergyPerturbationType::No && MASTER(cr))
{
if (rerun_fr.bLambda)
{
if (MASTER(cr))
{
const bool constructVsites = ((vsite != nullptr) && mdrunOptions.rerunConstructVsites);
- if (constructVsites && DOMAINDECOMP(cr))
+ if (constructVsites && haveDDAtomOrdering(*cr))
{
gmx_fatal(FARGS,
"Vsite recalculation with -rerun is not implemented with domain "
"decomposition, "
"use a single rank");
}
- prepareRerunState(rerun_fr, state_global, constructVsites, vsite, ir->delta_t);
+ prepareRerunState(rerun_fr, state_global, constructVsites, vsite);
}
isLastStep = isLastStep || stopHandler->stoppingAfterCurrentStep(bNS);
- if (DOMAINDECOMP(cr))
+ if (haveDDAtomOrdering(*cr))
{
/* Repartition the domain decomposition */
const bool bMasterState = true;
bMasterState,
nstglobalcomm,
state_global,
- *top_global,
- ir,
+ top_global,
+ *ir,
imdSession,
pull_work,
state,
&f,
mdAtoms,
- &top,
+ top,
fr,
vsite,
constr,
nrnb,
wcycle,
mdrunOptions.verbose);
- shouldCheckNumberOfBondedInteractions = true;
}
if (MASTER(cr))
EnergyOutput::printHeader(fplog, step, t); /* can we improve the information printed here? */
}
- if (ir->efep != efepNO)
+ if (ir->efep != FreeEnergyPerturbationType::No)
{
- update_mdatoms(mdatoms, state->lambda[efptMASS]);
+ update_mdatoms(mdatoms, state->lambda[FreeEnergyPerturbationCouplingType::Mass]);
}
+ fr->longRangeNonbondeds->updateAfterPartition(*mdatoms);
+
force_flags = (GMX_FORCE_STATECHANGED | GMX_FORCE_DYNAMICBOX | GMX_FORCE_ALLFORCES
| GMX_FORCE_VIRIAL | // TODO: Get rid of this once #2649 and #3400 are solved
GMX_FORCE_ENERGY | (doFreeEnergyPerturbation ? GMX_FORCE_DHDL : 0));
pull_work,
bNS,
force_flags,
- &top,
+ top,
constr,
enerd,
state->natoms,
&state->hist,
&f.view(),
force_vir,
- mdatoms,
+ *mdatoms,
+ fr->longRangeNonbondeds.get(),
nrnb,
wcycle,
shellfc,
do_force(fplog,
cr,
ms,
- ir,
+ *ir,
awh,
enforcedRotation,
imdSession,
step,
nrnb,
wcycle,
- &top,
+ top,
state->box,
state->x.arrayRefWithPadding(),
&state->hist,
mu_tot,
t,
ed,
+ fr->longRangeNonbondeds.get(),
GMX_FORCE_NS | force_flags,
ddBalanceRegionHandler);
}
t_vcm* vcm = nullptr;
SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal);
+ int cglo_flags = CGLO_GSTAT | CGLO_ENERGY;
compute_globals(gstat,
cr,
ir,
shake_vir,
total_vir,
pres,
- constr != nullptr ? constr->rmsdData() : gmx::ArrayRef<real>{},
&signaller,
state->box,
- &totalNumberOfBondedInteractions,
&bSumEkinhOld,
- CGLO_GSTAT | CGLO_ENERGY
- | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS
- : 0));
- checkNumberOfBondedInteractions(mdlog,
- cr,
- totalNumberOfBondedInteractions,
- top_global,
- &top,
- makeConstArrayRef(state->x),
- state->box,
- &shouldCheckNumberOfBondedInteractions);
+ cglo_flags,
+ step,
+ &observablesReducer);
+ // Clean up after pre-step use of compute_globals()
+ observablesReducer.markAsReadyToReduce();
}
/* Note: this is OK, but there are some numerical precision issues with using the convergence of
t,
mdatoms->tmass,
enerd,
- ir->fepvals,
- ir->expandedvals,
+ ir->fepvals.get(),
state->box,
PTCouplingArrays({ state->boxv,
state->nosehoover_xi,
state->nhpres_xi,
state->nhpres_vxi }),
state->fep_state,
- shake_vir,
- force_vir,
total_vir,
pres,
ekind,
fr->fcdata.get(),
awh);
+ if (ir->bPull)
+ {
+ pull_print_output(pull_work, step, t);
+ }
+
if (do_per_step(step, ir->nstlog))
{
if (fflush(fplog) != 0)
/* Ion/water position swapping.
* Not done in last step since trajectory writing happens before this call
* in the MD loop and exchanges would be lost anyway. */
- if ((ir->eSwapCoords != eswapNO) && (step > 0) && !isLastStep && do_per_step(step, ir->swap->nstswap))
+ if ((ir->eSwapCoords != SwapType::No) && (step > 0) && !isLastStep
+ && do_per_step(step, ir->swap->nstswap))
{
const bool doRerun = true;
do_swapcoords(cr,
rerun_parallel_comm(cr, &rerun_fr, &isLastStep);
}
- cycles = wallcycle_stop(wcycle, ewcSTEP);
- if (DOMAINDECOMP(cr) && wcycle)
+ cycles = wallcycle_stop(wcycle, WallCycleCounter::Step);
+ if (haveDDAtomOrdering(*cr) && wcycle)
{
dd_cycles_add(cr->dd, cycles, ddCyclStep);
}
step++;
step_rel++;
}
+ observablesReducer.markAsReadyToReduce();
}
/* End of main MD loop */