Unify FEP period setting
[alexxy/gromacs.git] / src / gromacs / mdrun / md.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2011-2019,2020,2021, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37 /*! \internal \file
38  *
39  * \brief Implements the integrator for normal molecular dynamics simulations
40  *
41  * \author David van der Spoel <david.vanderspoel@icm.uu.se>
42  * \ingroup module_mdrun
43  */
44 #include "gmxpre.h"
45
46 #include <cinttypes>
47 #include <cmath>
48 #include <cstdio>
49 #include <cstdlib>
50
51 #include <algorithm>
52 #include <memory>
53 #include <numeric>
54
55 #include "gromacs/applied_forces/awh/awh.h"
56 #include "gromacs/applied_forces/awh/read_params.h"
57 #include "gromacs/commandline/filenm.h"
58 #include "gromacs/domdec/collect.h"
59 #include "gromacs/domdec/dlbtiming.h"
60 #include "gromacs/domdec/domdec.h"
61 #include "gromacs/domdec/domdec_network.h"
62 #include "gromacs/domdec/domdec_struct.h"
63 #include "gromacs/domdec/gpuhaloexchange.h"
64 #include "gromacs/domdec/localtopologychecker.h"
65 #include "gromacs/domdec/mdsetup.h"
66 #include "gromacs/domdec/partition.h"
67 #include "gromacs/essentialdynamics/edsam.h"
68 #include "gromacs/ewald/pme_load_balancing.h"
69 #include "gromacs/ewald/pme_pp.h"
70 #include "gromacs/fileio/trxio.h"
71 #include "gromacs/gmxlib/network.h"
72 #include "gromacs/gmxlib/nrnb.h"
73 #include "gromacs/gpu_utils/device_stream_manager.h"
74 #include "gromacs/gpu_utils/gpu_utils.h"
75 #include "gromacs/imd/imd.h"
76 #include "gromacs/listed_forces/listed_forces.h"
77 #include "gromacs/math/functions.h"
78 #include "gromacs/math/invertmatrix.h"
79 #include "gromacs/math/vec.h"
80 #include "gromacs/math/vectypes.h"
81 #include "gromacs/mdlib/checkpointhandler.h"
82 #include "gromacs/mdlib/compute_io.h"
83 #include "gromacs/mdlib/constr.h"
84 #include "gromacs/mdlib/coupling.h"
85 #include "gromacs/mdlib/ebin.h"
86 #include "gromacs/mdlib/enerdata_utils.h"
87 #include "gromacs/mdlib/energyoutput.h"
88 #include "gromacs/mdlib/expanded.h"
89 #include "gromacs/mdlib/force.h"
90 #include "gromacs/mdlib/force_flags.h"
91 #include "gromacs/mdlib/forcerec.h"
92 #include "gromacs/mdlib/freeenergyparameters.h"
93 #include "gromacs/mdlib/md_support.h"
94 #include "gromacs/mdlib/mdatoms.h"
95 #include "gromacs/mdlib/mdoutf.h"
96 #include "gromacs/mdlib/membed.h"
97 #include "gromacs/mdlib/resethandler.h"
98 #include "gromacs/mdlib/sighandler.h"
99 #include "gromacs/mdlib/simulationsignal.h"
100 #include "gromacs/mdlib/stat.h"
101 #include "gromacs/mdlib/stophandler.h"
102 #include "gromacs/mdlib/tgroup.h"
103 #include "gromacs/mdlib/trajectory_writing.h"
104 #include "gromacs/mdlib/update.h"
105 #include "gromacs/mdlib/update_constrain_gpu.h"
106 #include "gromacs/mdlib/update_vv.h"
107 #include "gromacs/mdlib/vcm.h"
108 #include "gromacs/mdlib/vsite.h"
109 #include "gromacs/mdrunutility/freeenergy.h"
110 #include "gromacs/mdrunutility/handlerestart.h"
111 #include "gromacs/mdrunutility/multisim.h"
112 #include "gromacs/mdrunutility/printtime.h"
113 #include "gromacs/mdtypes/awh_history.h"
114 #include "gromacs/mdtypes/awh_params.h"
115 #include "gromacs/mdtypes/commrec.h"
116 #include "gromacs/mdtypes/df_history.h"
117 #include "gromacs/mdtypes/energyhistory.h"
118 #include "gromacs/mdtypes/fcdata.h"
119 #include "gromacs/mdtypes/forcebuffers.h"
120 #include "gromacs/mdtypes/forcerec.h"
121 #include "gromacs/mdtypes/group.h"
122 #include "gromacs/mdtypes/inputrec.h"
123 #include "gromacs/mdtypes/interaction_const.h"
124 #include "gromacs/mdtypes/md_enums.h"
125 #include "gromacs/mdtypes/mdatom.h"
126 #include "gromacs/mdtypes/mdrunoptions.h"
127 #include "gromacs/mdtypes/multipletimestepping.h"
128 #include "gromacs/mdtypes/observableshistory.h"
129 #include "gromacs/mdtypes/pullhistory.h"
130 #include "gromacs/mdtypes/simulation_workload.h"
131 #include "gromacs/mdtypes/state.h"
132 #include "gromacs/mdtypes/state_propagator_data_gpu.h"
133 #include "gromacs/modularsimulator/energydata.h"
134 #include "gromacs/nbnxm/gpu_data_mgmt.h"
135 #include "gromacs/nbnxm/nbnxm.h"
136 #include "gromacs/pbcutil/pbc.h"
137 #include "gromacs/pulling/output.h"
138 #include "gromacs/pulling/pull.h"
139 #include "gromacs/swap/swapcoords.h"
140 #include "gromacs/timing/wallcycle.h"
141 #include "gromacs/timing/walltime_accounting.h"
142 #include "gromacs/topology/atoms.h"
143 #include "gromacs/topology/idef.h"
144 #include "gromacs/topology/mtop_util.h"
145 #include "gromacs/topology/topology.h"
146 #include "gromacs/trajectory/trajectoryframe.h"
147 #include "gromacs/utility/basedefinitions.h"
148 #include "gromacs/utility/cstringutil.h"
149 #include "gromacs/utility/fatalerror.h"
150 #include "gromacs/utility/logger.h"
151 #include "gromacs/utility/real.h"
152 #include "gromacs/utility/smalloc.h"
153
154 #include "legacysimulator.h"
155 #include "replicaexchange.h"
156 #include "shellfc.h"
157
158 using gmx::SimulationSignaller;
159
160 void gmx::LegacySimulator::do_md()
161 {
162     // TODO Historically, the EM and MD "integrators" used different
163     // names for the t_inputrec *parameter, but these must have the
164     // same name, now that it's a member of a struct. We use this ir
165     // alias to avoid a large ripple of nearly useless changes.
166     // t_inputrec is being replaced by IMdpOptionsProvider, so this
167     // will go away eventually.
168     const t_inputrec* ir = inputrec;
169
170     int64_t      step, step_rel;
171     double       t, t0 = ir->init_t;
172     gmx_bool     bGStatEveryStep, bGStat, bCalcVir, bCalcEnerStep, bCalcEner;
173     gmx_bool     bNS = FALSE, bNStList, bStopCM, bFirstStep, bInitStep, bLastStep = FALSE;
174     gmx_bool     bDoDHDL = FALSE, bDoFEP = FALSE, bDoExpanded = FALSE;
175     gmx_bool     do_ene, do_log, do_verbose;
176     gmx_bool     bMasterState;
177     unsigned int force_flags;
178     tensor force_vir = { { 0 } }, shake_vir = { { 0 } }, total_vir = { { 0 } }, pres = { { 0 } };
179     int    i, m;
180     rvec   mu_tot;
181     matrix pressureCouplingMu, M;
182     gmx_repl_ex_t     repl_ex = nullptr;
183     gmx_global_stat_t gstat;
184     gmx_shellfc_t*    shellfc;
185     gmx_bool          bSumEkinhOld, bDoReplEx, bExchanged, bNeedRepartition;
186     gmx_bool          bTrotter;
187     real              dvdl_constr;
188     std::vector<RVec> cbuf;
189     matrix            lastbox;
190     int               lamnew = 0;
191     /* for FEP */
192     double    cycles;
193     real      saved_conserved_quantity = 0;
194     real      last_ekin                = 0;
195     t_extmass MassQ;
196     char      sbuf[STEPSTRSIZE], sbuf2[STEPSTRSIZE];
197
198     /* PME load balancing data for GPU kernels */
199     gmx_bool bPMETune         = FALSE;
200     gmx_bool bPMETunePrinting = FALSE;
201
202     bool bInteractiveMDstep = false;
203
204     SimulationSignals signals;
205     // Most global communnication stages don't propagate mdrun
206     // signals, and will use this object to achieve that.
207     SimulationSignaller nullSignaller(nullptr, nullptr, nullptr, false, false);
208
209     if (!mdrunOptions.writeConfout)
210     {
211         // This is on by default, and the main known use case for
212         // turning it off is for convenience in benchmarking, which is
213         // something that should not show up in the general user
214         // interface.
215         GMX_LOG(mdlog.info)
216                 .asParagraph()
217                 .appendText(
218                         "The -noconfout functionality is deprecated, and may be removed in a "
219                         "future version.");
220     }
221
222     /* md-vv uses averaged full step velocities for T-control
223        md-vv-avek uses averaged half step velocities for T-control (but full step ekin for P control)
224        md uses averaged half step kinetic energies to determine temperature unless defined otherwise by GMX_EKIN_AVE_VEL; */
225     bTrotter = (EI_VV(ir->eI)
226                 && (inputrecNptTrotter(ir) || inputrecNphTrotter(ir) || inputrecNvtTrotter(ir)));
227
228     const bool bRerunMD = false;
229
230     int nstglobalcomm = computeGlobalCommunicationPeriod(mdlog, ir, cr);
231     bGStatEveryStep   = (nstglobalcomm == 1);
232
233     const SimulationGroups* groups = &top_global.groups;
234
235     std::unique_ptr<EssentialDynamics> ed = nullptr;
236     if (opt2bSet("-ei", nfile, fnm))
237     {
238         /* Initialize essential dynamics sampling */
239         ed = init_edsam(mdlog,
240                         opt2fn_null("-ei", nfile, fnm),
241                         opt2fn("-eo", nfile, fnm),
242                         top_global,
243                         *ir,
244                         cr,
245                         constr,
246                         state_global,
247                         observablesHistory,
248                         oenv,
249                         startingBehavior);
250     }
251     else if (observablesHistory->edsamHistory)
252     {
253         gmx_fatal(FARGS,
254                   "The checkpoint is from a run with essential dynamics sampling, "
255                   "but the current run did not specify the -ei option. "
256                   "Either specify the -ei option to mdrun, or do not use this checkpoint file.");
257     }
258
259     int*                fep_state = MASTER(cr) ? &state_global->fep_state : nullptr;
260     gmx::ArrayRef<real> lambda    = MASTER(cr) ? state_global->lambda : gmx::ArrayRef<real>();
261     initialize_lambdas(fplog,
262                        ir->efep,
263                        ir->bSimTemp,
264                        *ir->fepvals,
265                        ir->simtempvals->temperatures,
266                        gmx::arrayRefFromArray(ir->opts.ref_t, ir->opts.ngtc),
267                        MASTER(cr),
268                        fep_state,
269                        lambda);
270     Update upd(*ir, deform);
271     bool   doSimulatedAnnealing = false;
272     {
273         // TODO: Avoid changing inputrec (#3854)
274         // Simulated annealing updates the reference temperature.
275         auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
276         doSimulatedAnnealing   = initSimulatedAnnealing(nonConstInputrec, &upd);
277     }
278     const bool useReplicaExchange = (replExParams.exchangeInterval > 0);
279
280     const t_fcdata& fcdata = *fr->fcdata;
281
282     bool simulationsShareState = false;
283     int  nstSignalComm         = nstglobalcomm;
284     {
285         // TODO This implementation of ensemble orientation restraints is nasty because
286         // a user can't just do multi-sim with single-sim orientation restraints.
287         bool usingEnsembleRestraints = (fcdata.disres->nsystems > 1) || ((ms != nullptr) && fcdata.orires);
288         bool awhUsesMultiSim = (ir->bDoAwh && ir->awhParams->shareBiasMultisim() && (ms != nullptr));
289
290         // Replica exchange, ensemble restraints and AWH need all
291         // simulations to remain synchronized, so they need
292         // checkpoints and stop conditions to act on the same step, so
293         // the propagation of such signals must take place between
294         // simulations, not just within simulations.
295         // TODO: Make algorithm initializers set these flags.
296         simulationsShareState = useReplicaExchange || usingEnsembleRestraints || awhUsesMultiSim;
297
298         if (simulationsShareState)
299         {
300             // Inter-simulation signal communication does not need to happen
301             // often, so we use a minimum of 200 steps to reduce overhead.
302             const int c_minimumInterSimulationSignallingInterval = 200;
303             nstSignalComm = ((c_minimumInterSimulationSignallingInterval + nstglobalcomm - 1) / nstglobalcomm)
304                             * nstglobalcomm;
305         }
306     }
307
308     if (startingBehavior != StartingBehavior::RestartWithAppending)
309     {
310         pleaseCiteCouplingAlgorithms(fplog, *ir);
311     }
312     gmx_mdoutf*       outf = init_mdoutf(fplog,
313                                    nfile,
314                                    fnm,
315                                    mdrunOptions,
316                                    cr,
317                                    outputProvider,
318                                    mdModulesNotifiers,
319                                    ir,
320                                    top_global,
321                                    oenv,
322                                    wcycle,
323                                    startingBehavior,
324                                    simulationsShareState,
325                                    ms);
326     gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf),
327                                    top_global,
328                                    *ir,
329                                    pull_work,
330                                    mdoutf_get_fp_dhdl(outf),
331                                    false,
332                                    startingBehavior,
333                                    simulationsShareState,
334                                    mdModulesNotifiers);
335
336     gstat = global_stat_init(ir);
337
338     const auto& simulationWork     = runScheduleWork->simulationWork;
339     const bool  useGpuForPme       = simulationWork.useGpuPme;
340     const bool  useGpuForNonbonded = simulationWork.useGpuNonbonded;
341     const bool  useGpuForBufferOps = simulationWork.useGpuBufferOps;
342     const bool  useGpuForUpdate    = simulationWork.useGpuUpdate;
343
344     /* Check for polarizable models and flexible constraints */
345     shellfc = init_shell_flexcon(fplog,
346                                  top_global,
347                                  constr ? constr->numFlexibleConstraints() : 0,
348                                  ir->nstcalcenergy,
349                                  DOMAINDECOMP(cr),
350                                  useGpuForPme);
351
352     {
353         double io = compute_io(ir, top_global.natoms, *groups, energyOutput.numEnergyTerms(), 1);
354         if ((io > 2000) && MASTER(cr))
355         {
356             fprintf(stderr, "\nWARNING: This run will generate roughly %.0f Mb of data\n\n", io);
357         }
358     }
359
360     // Local state only becomes valid now.
361     std::unique_ptr<t_state> stateInstance;
362     t_state*                 state;
363
364     gmx_localtop_t top(top_global.ffparams);
365
366     ForceBuffers     f(simulationWork.useMts,
367                    ((useGpuForNonbonded && useGpuForBufferOps) || useGpuForUpdate)
368                                ? PinningPolicy::PinnedIfSupported
369                                : PinningPolicy::CannotBePinned);
370     const t_mdatoms* md = mdAtoms->mdatoms();
371     if (DOMAINDECOMP(cr))
372     {
373         stateInstance = std::make_unique<t_state>();
374         state         = stateInstance.get();
375         dd_init_local_state(*cr->dd, state_global, state);
376
377         /* Distribute the charge groups over the nodes from the master node */
378         dd_partition_system(fplog,
379                             mdlog,
380                             ir->init_step,
381                             cr,
382                             TRUE,
383                             1,
384                             state_global,
385                             top_global,
386                             *ir,
387                             imdSession,
388                             pull_work,
389                             state,
390                             &f,
391                             mdAtoms,
392                             &top,
393                             fr,
394                             vsite,
395                             constr,
396                             nrnb,
397                             nullptr,
398                             FALSE);
399         upd.updateAfterPartition(state->natoms,
400                                  md->cFREEZE ? gmx::arrayRefFromArray(md->cFREEZE, md->nr)
401                                              : gmx::ArrayRef<const unsigned short>(),
402                                  md->cTC ? gmx::arrayRefFromArray(md->cTC, md->nr)
403                                          : gmx::ArrayRef<const unsigned short>());
404     }
405     else
406     {
407         state_change_natoms(state_global, state_global->natoms);
408         /* Copy the pointer to the global state */
409         state = state_global;
410
411         /* Generate and initialize new topology */
412         mdAlgorithmsSetupAtomData(cr, *ir, top_global, &top, fr, &f, mdAtoms, constr, vsite, shellfc);
413
414         upd.updateAfterPartition(state->natoms,
415                                  md->cFREEZE ? gmx::arrayRefFromArray(md->cFREEZE, md->nr)
416                                              : gmx::ArrayRef<const unsigned short>(),
417                                  md->cTC ? gmx::arrayRefFromArray(md->cTC, md->nr)
418                                          : gmx::ArrayRef<const unsigned short>());
419     }
420
421     std::unique_ptr<UpdateConstrainGpu> integrator;
422
423     StatePropagatorDataGpu* stateGpu = fr->stateGpu;
424
425     // TODO: the assertions below should be handled by UpdateConstraintsBuilder.
426     if (useGpuForUpdate)
427     {
428         GMX_RELEASE_ASSERT(!DOMAINDECOMP(cr) || ddUsesUpdateGroups(*cr->dd) || constr == nullptr
429                                    || constr->numConstraintsTotal() == 0,
430                            "Constraints in domain decomposition are only supported with update "
431                            "groups if using GPU update.\n");
432         GMX_RELEASE_ASSERT(ir->eConstrAlg != ConstraintAlgorithm::Shake || constr == nullptr
433                                    || constr->numConstraintsTotal() == 0,
434                            "SHAKE is not supported with GPU update.");
435         GMX_RELEASE_ASSERT(useGpuForPme || (useGpuForNonbonded && simulationWork.useGpuBufferOps),
436                            "Either PME or short-ranged non-bonded interaction tasks must run on "
437                            "the GPU to use GPU update.\n");
438         GMX_RELEASE_ASSERT(ir->eI == IntegrationAlgorithm::MD,
439                            "Only the md integrator is supported with the GPU update.\n");
440         GMX_RELEASE_ASSERT(
441                 ir->etc != TemperatureCoupling::NoseHoover,
442                 "Nose-Hoover temperature coupling is not supported with the GPU update.\n");
443         GMX_RELEASE_ASSERT(
444                 ir->epc == PressureCoupling::No || ir->epc == PressureCoupling::ParrinelloRahman
445                         || ir->epc == PressureCoupling::Berendsen || ir->epc == PressureCoupling::CRescale,
446                 "Only Parrinello-Rahman, Berendsen, and C-rescale pressure coupling are supported "
447                 "with the GPU update.\n");
448         GMX_RELEASE_ASSERT(!md->haveVsites,
449                            "Virtual sites are not supported with the GPU update.\n");
450         GMX_RELEASE_ASSERT(ed == nullptr,
451                            "Essential dynamics is not supported with the GPU update.\n");
452         GMX_RELEASE_ASSERT(!ir->bPull || !pull_have_constraint(*ir->pull),
453                            "Constraints pulling is not supported with the GPU update.\n");
454         GMX_RELEASE_ASSERT(fcdata.orires == nullptr,
455                            "Orientation restraints are not supported with the GPU update.\n");
456         GMX_RELEASE_ASSERT(
457                 ir->efep == FreeEnergyPerturbationType::No
458                         || (!haveFepPerturbedMasses(top_global) && !havePerturbedConstraints(top_global)),
459                 "Free energy perturbation of masses and constraints are not supported with the GPU "
460                 "update.");
461
462         if (constr != nullptr && constr->numConstraintsTotal() > 0)
463         {
464             GMX_LOG(mdlog.info)
465                     .asParagraph()
466                     .appendText("Updating coordinates and applying constraints on the GPU.");
467         }
468         else
469         {
470             GMX_LOG(mdlog.info).asParagraph().appendText("Updating coordinates on the GPU.");
471         }
472         GMX_RELEASE_ASSERT(fr->deviceStreamManager != nullptr,
473                            "Device stream manager should be initialized in order to use GPU "
474                            "update-constraints.");
475         GMX_RELEASE_ASSERT(
476                 fr->deviceStreamManager->streamIsValid(gmx::DeviceStreamType::UpdateAndConstraints),
477                 "Update stream should be initialized in order to use GPU "
478                 "update-constraints.");
479         integrator = std::make_unique<UpdateConstrainGpu>(
480                 *ir,
481                 top_global,
482                 ekind->ngtc,
483                 fr->deviceStreamManager->context(),
484                 fr->deviceStreamManager->stream(gmx::DeviceStreamType::UpdateAndConstraints),
485                 stateGpu->xUpdatedOnDevice(),
486                 wcycle);
487
488         integrator->setPbc(PbcType::Xyz, state->box);
489     }
490
491     if (useGpuForPme || (useGpuForNonbonded && useGpuForBufferOps) || useGpuForUpdate)
492     {
493         changePinningPolicy(&state->x, PinningPolicy::PinnedIfSupported);
494     }
495     if (useGpuForUpdate)
496     {
497         changePinningPolicy(&state->v, PinningPolicy::PinnedIfSupported);
498     }
499
500     // NOTE: The global state is no longer used at this point.
501     // But state_global is still used as temporary storage space for writing
502     // the global state to file and potentially for replica exchange.
503     // (Global topology should persist.)
504
505     update_mdatoms(mdAtoms->mdatoms(), state->lambda[FreeEnergyPerturbationCouplingType::Mass]);
506
507     if (ir->bExpanded)
508     {
509         /* Check nstexpanded here, because the grompp check was broken */
510         if (ir->expandedvals->nstexpanded % ir->nstcalcenergy != 0)
511         {
512             gmx_fatal(FARGS,
513                       "With expanded ensemble, nstexpanded should be a multiple of nstcalcenergy");
514         }
515         init_expanded_ensemble(startingBehavior != StartingBehavior::NewSimulation, ir, state->dfhist);
516     }
517
518     if (MASTER(cr))
519     {
520         EnergyData::initializeEnergyHistory(startingBehavior, observablesHistory, &energyOutput);
521     }
522
523     preparePrevStepPullCom(ir,
524                            pull_work,
525                            gmx::arrayRefFromArray(md->massT, md->nr),
526                            state,
527                            state_global,
528                            cr,
529                            startingBehavior != StartingBehavior::NewSimulation);
530
531     // TODO: Remove this by converting AWH into a ForceProvider
532     auto awh = prepareAwhModule(fplog,
533                                 *ir,
534                                 state_global,
535                                 cr,
536                                 ms,
537                                 startingBehavior != StartingBehavior::NewSimulation,
538                                 shellfc != nullptr,
539                                 opt2fn("-awh", nfile, fnm),
540                                 pull_work);
541
542     if (useReplicaExchange && MASTER(cr))
543     {
544         repl_ex = init_replica_exchange(fplog, ms, top_global.natoms, ir, replExParams);
545     }
546     /* PME tuning is only supported in the Verlet scheme, with PME for
547      * Coulomb. It is not supported with only LJ PME. */
548     bPMETune = (mdrunOptions.tunePme && EEL_PME(fr->ic->eeltype) && !mdrunOptions.reproducible
549                 && ir->cutoff_scheme != CutoffScheme::Group);
550
551     pme_load_balancing_t* pme_loadbal = nullptr;
552     if (bPMETune)
553     {
554         pme_loadbal_init(
555                 &pme_loadbal, cr, mdlog, *ir, state->box, *fr->ic, *fr->nbv, fr->pmedata, fr->nbv->useGpu());
556     }
557
558     if (!ir->bContinuation)
559     {
560         if (state->flags & enumValueToBitMask(StateEntry::V))
561         {
562             auto v = makeArrayRef(state->v);
563             /* Set the velocities of vsites, shells and frozen atoms to zero */
564             for (i = 0; i < md->homenr; i++)
565             {
566                 if (md->ptype[i] == ParticleType::Shell)
567                 {
568                     clear_rvec(v[i]);
569                 }
570                 else if (md->cFREEZE)
571                 {
572                     for (m = 0; m < DIM; m++)
573                     {
574                         if (ir->opts.nFreeze[md->cFREEZE[i]][m])
575                         {
576                             v[i][m] = 0;
577                         }
578                     }
579                 }
580             }
581         }
582
583         if (constr)
584         {
585             /* Constrain the initial coordinates and velocities */
586             do_constrain_first(fplog,
587                                constr,
588                                ir,
589                                md->nr,
590                                md->homenr,
591                                state->x.arrayRefWithPadding(),
592                                state->v.arrayRefWithPadding(),
593                                state->box,
594                                state->lambda[FreeEnergyPerturbationCouplingType::Bonded]);
595         }
596     }
597
598     const int nstfep = computeFepPeriod(*ir, replExParams);
599
600     /* Be REALLY careful about what flags you set here. You CANNOT assume
601      * this is the first step, since we might be restarting from a checkpoint,
602      * and in that case we should not do any modifications to the state.
603      */
604     bStopCM = (ir->comm_mode != ComRemovalAlgorithm::No && !ir->bContinuation);
605
606     // When restarting from a checkpoint, it can be appropriate to
607     // initialize ekind from quantities in the checkpoint. Otherwise,
608     // compute_globals must initialize ekind before the simulation
609     // starts/restarts. However, only the master rank knows what was
610     // found in the checkpoint file, so we have to communicate in
611     // order to coordinate the restart.
612     //
613     // TODO Consider removing this communication if/when checkpoint
614     // reading directly follows .tpr reading, because all ranks can
615     // agree on hasReadEkinState at that time.
616     bool hasReadEkinState = MASTER(cr) ? state_global->ekinstate.hasReadEkinState : false;
617     if (PAR(cr))
618     {
619         gmx_bcast(sizeof(hasReadEkinState), &hasReadEkinState, cr->mpi_comm_mygroup);
620     }
621     if (hasReadEkinState)
622     {
623         restore_ekinstate_from_state(cr, ekind, &state_global->ekinstate);
624     }
625
626     unsigned int cglo_flags =
627             (CGLO_TEMPERATURE | CGLO_GSTAT | (EI_VV(ir->eI) ? CGLO_PRESSURE : 0)
628              | (EI_VV(ir->eI) ? CGLO_CONSTRAINT : 0) | (hasReadEkinState ? CGLO_READEKIN : 0));
629
630     bSumEkinhOld = FALSE;
631
632     t_vcm vcm(top_global.groups, *ir);
633     reportComRemovalInfo(fplog, vcm);
634
635     /* To minimize communication, compute_globals computes the COM velocity
636      * and the kinetic energy for the velocities without COM motion removed.
637      * Thus to get the kinetic energy without the COM contribution, we need
638      * to call compute_globals twice.
639      */
640     for (int cgloIteration = 0; cgloIteration < (bStopCM ? 2 : 1); cgloIteration++)
641     {
642         unsigned int cglo_flags_iteration = cglo_flags;
643         if (bStopCM && cgloIteration == 0)
644         {
645             cglo_flags_iteration |= CGLO_STOPCM;
646             cglo_flags_iteration &= ~CGLO_TEMPERATURE;
647         }
648         if (DOMAINDECOMP(cr) && dd_localTopologyChecker(*cr->dd).shouldCheckNumberOfBondedInteractions()
649             && cgloIteration == 0)
650         {
651             cglo_flags_iteration |= CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS;
652         }
653         compute_globals(gstat,
654                         cr,
655                         ir,
656                         fr,
657                         ekind,
658                         makeConstArrayRef(state->x),
659                         makeConstArrayRef(state->v),
660                         state->box,
661                         md,
662                         nrnb,
663                         &vcm,
664                         nullptr,
665                         enerd,
666                         force_vir,
667                         shake_vir,
668                         total_vir,
669                         pres,
670                         gmx::ArrayRef<real>{},
671                         &nullSignaller,
672                         state->box,
673                         &bSumEkinhOld,
674                         cglo_flags_iteration);
675         if (cglo_flags_iteration & CGLO_STOPCM)
676         {
677             /* At initialization, do not pass x with acceleration-correction mode
678              * to avoid (incorrect) correction of the initial coordinates.
679              */
680             auto x = (vcm.mode == ComRemovalAlgorithm::LinearAccelerationCorrection)
681                              ? ArrayRef<RVec>()
682                              : makeArrayRef(state->x);
683             process_and_stopcm_grp(fplog, &vcm, *md, x, makeArrayRef(state->v));
684             inc_nrnb(nrnb, eNR_STOPCM, md->homenr);
685         }
686     }
687     if (DOMAINDECOMP(cr))
688     {
689         dd_localTopologyChecker(cr->dd)->checkNumberOfBondedInteractions(
690                 &top, makeConstArrayRef(state->x), state->box);
691     }
692     if (ir->eI == IntegrationAlgorithm::VVAK)
693     {
694         /* a second call to get the half step temperature initialized as well */
695         /* we do the same call as above, but turn the pressure off -- internally to
696            compute_globals, this is recognized as a velocity verlet half-step
697            kinetic energy calculation.  This minimized excess variables, but
698            perhaps loses some logic?*/
699
700         compute_globals(gstat,
701                         cr,
702                         ir,
703                         fr,
704                         ekind,
705                         makeConstArrayRef(state->x),
706                         makeConstArrayRef(state->v),
707                         state->box,
708                         md,
709                         nrnb,
710                         &vcm,
711                         nullptr,
712                         enerd,
713                         force_vir,
714                         shake_vir,
715                         total_vir,
716                         pres,
717                         gmx::ArrayRef<real>{},
718                         &nullSignaller,
719                         state->box,
720                         &bSumEkinhOld,
721                         cglo_flags & ~CGLO_PRESSURE);
722     }
723
724     /* Calculate the initial half step temperature, and save the ekinh_old */
725     if (startingBehavior == StartingBehavior::NewSimulation)
726     {
727         for (i = 0; (i < ir->opts.ngtc); i++)
728         {
729             copy_mat(ekind->tcstat[i].ekinh, ekind->tcstat[i].ekinh_old);
730         }
731     }
732
733     /* need to make an initiation call to get the Trotter variables set, as well as other constants
734        for non-trotter temperature control */
735     auto trotter_seq = init_npt_vars(ir, state, &MassQ, bTrotter);
736
737     if (MASTER(cr))
738     {
739         if (!ir->bContinuation)
740         {
741             if (constr && ir->eConstrAlg == ConstraintAlgorithm::Lincs)
742             {
743                 fprintf(fplog,
744                         "RMS relative constraint deviation after constraining: %.2e\n",
745                         constr->rmsd());
746             }
747             if (EI_STATE_VELOCITY(ir->eI))
748             {
749                 real temp = enerd->term[F_TEMP];
750                 if (ir->eI != IntegrationAlgorithm::VV)
751                 {
752                     /* Result of Ekin averaged over velocities of -half
753                      * and +half step, while we only have -half step here.
754                      */
755                     temp *= 2;
756                 }
757                 fprintf(fplog, "Initial temperature: %g K\n", temp);
758             }
759         }
760
761         char tbuf[20];
762         fprintf(stderr, "starting mdrun '%s'\n", *(top_global.name));
763         if (ir->nsteps >= 0)
764         {
765             sprintf(tbuf, "%8.1f", (ir->init_step + ir->nsteps) * ir->delta_t);
766         }
767         else
768         {
769             sprintf(tbuf, "%s", "infinite");
770         }
771         if (ir->init_step > 0)
772         {
773             fprintf(stderr,
774                     "%s steps, %s ps (continuing from step %s, %8.1f ps).\n",
775                     gmx_step_str(ir->init_step + ir->nsteps, sbuf),
776                     tbuf,
777                     gmx_step_str(ir->init_step, sbuf2),
778                     ir->init_step * ir->delta_t);
779         }
780         else
781         {
782             fprintf(stderr, "%s steps, %s ps.\n", gmx_step_str(ir->nsteps, sbuf), tbuf);
783         }
784         fprintf(fplog, "\n");
785     }
786
787     walltime_accounting_start_time(walltime_accounting);
788     wallcycle_start(wcycle, WallCycleCounter::Run);
789     print_start(fplog, cr, walltime_accounting, "mdrun");
790
791     /***********************************************************
792      *
793      *             Loop over MD steps
794      *
795      ************************************************************/
796
797     bFirstStep = TRUE;
798     /* Skip the first Nose-Hoover integration when we get the state from tpx */
799     bInitStep        = startingBehavior == StartingBehavior::NewSimulation || EI_VV(ir->eI);
800     bSumEkinhOld     = FALSE;
801     bExchanged       = FALSE;
802     bNeedRepartition = FALSE;
803
804     step     = ir->init_step;
805     step_rel = 0;
806
807     auto stopHandler = stopHandlerBuilder->getStopHandlerMD(
808             compat::not_null<SimulationSignal*>(&signals[eglsSTOPCOND]),
809             simulationsShareState,
810             MASTER(cr),
811             ir->nstlist,
812             mdrunOptions.reproducible,
813             nstSignalComm,
814             mdrunOptions.maximumHoursToRun,
815             ir->nstlist == 0,
816             fplog,
817             step,
818             bNS,
819             walltime_accounting);
820
821     auto checkpointHandler = std::make_unique<CheckpointHandler>(
822             compat::make_not_null<SimulationSignal*>(&signals[eglsCHKPT]),
823             simulationsShareState,
824             ir->nstlist == 0,
825             MASTER(cr),
826             mdrunOptions.writeConfout,
827             mdrunOptions.checkpointOptions.period);
828
829     const bool resetCountersIsLocal = true;
830     auto       resetHandler         = std::make_unique<ResetHandler>(
831             compat::make_not_null<SimulationSignal*>(&signals[eglsRESETCOUNTERS]),
832             !resetCountersIsLocal,
833             ir->nsteps,
834             MASTER(cr),
835             mdrunOptions.timingOptions.resetHalfway,
836             mdrunOptions.maximumHoursToRun,
837             mdlog,
838             wcycle,
839             walltime_accounting);
840
841     const DDBalanceRegionHandler ddBalanceRegionHandler(cr);
842
843     if (MASTER(cr) && isMultiSim(ms) && !useReplicaExchange)
844     {
845         logInitialMultisimStatus(ms, cr, mdlog, simulationsShareState, ir->nsteps, ir->init_step);
846     }
847
848     /* and stop now if we should */
849     bLastStep = (bLastStep || (ir->nsteps >= 0 && step_rel > ir->nsteps));
850     while (!bLastStep)
851     {
852
853         /* Determine if this is a neighbor search step */
854         bNStList = (ir->nstlist > 0 && step % ir->nstlist == 0);
855
856         if (bPMETune && bNStList)
857         {
858             // This has to be here because PME load balancing is called so early.
859             // TODO: Move to after all booleans are defined.
860             if (useGpuForUpdate && !bFirstStep)
861             {
862                 stateGpu->copyCoordinatesFromGpu(state->x, AtomLocality::Local);
863                 stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
864             }
865             /* PME grid + cut-off optimization with GPUs or PME nodes */
866             pme_loadbal_do(pme_loadbal,
867                            cr,
868                            (mdrunOptions.verbose && MASTER(cr)) ? stderr : nullptr,
869                            fplog,
870                            mdlog,
871                            *ir,
872                            fr,
873                            state->box,
874                            state->x,
875                            wcycle,
876                            step,
877                            step_rel,
878                            &bPMETunePrinting,
879                            simulationWork.useGpuPmePpCommunication);
880         }
881
882         wallcycle_start(wcycle, WallCycleCounter::Step);
883
884         bLastStep = (step_rel == ir->nsteps);
885         t         = t0 + step * ir->delta_t;
886
887         // TODO Refactor this, so that nstfep does not need a default value of zero
888         if (ir->efep != FreeEnergyPerturbationType::No || ir->bSimTemp)
889         {
890             /* find and set the current lambdas */
891             state->lambda = currentLambdas(step, *(ir->fepvals), state->fep_state);
892
893             bDoDHDL = do_per_step(step, ir->fepvals->nstdhdl);
894             bDoFEP  = ((ir->efep != FreeEnergyPerturbationType::No) && do_per_step(step, nstfep));
895             bDoExpanded = (do_per_step(step, ir->expandedvals->nstexpanded) && (ir->bExpanded)
896                            && (!bFirstStep));
897         }
898
899         bDoReplEx = (useReplicaExchange && (step > 0) && !bLastStep
900                      && do_per_step(step, replExParams.exchangeInterval));
901
902         if (doSimulatedAnnealing)
903         {
904             // TODO: Avoid changing inputrec (#3854)
905             // Simulated annealing updates the reference temperature.
906             auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
907             update_annealing_target_temp(nonConstInputrec, t, &upd);
908         }
909
910         /* Stop Center of Mass motion */
911         bStopCM = (ir->comm_mode != ComRemovalAlgorithm::No && do_per_step(step, ir->nstcomm));
912
913         /* Determine whether or not to do Neighbour Searching */
914         bNS = (bFirstStep || bNStList || bExchanged || bNeedRepartition);
915
916         /* Note that the stopHandler will cause termination at nstglobalcomm
917          * steps. Since this concides with nstcalcenergy, nsttcouple and/or
918          * nstpcouple steps, we have computed the half-step kinetic energy
919          * of the previous step and can always output energies at the last step.
920          */
921         bLastStep = bLastStep || stopHandler->stoppingAfterCurrentStep(bNS);
922
923         /* do_log triggers energy and virial calculation. Because this leads
924          * to different code paths, forces can be different. Thus for exact
925          * continuation we should avoid extra log output.
926          * Note that the || bLastStep can result in non-exact continuation
927          * beyond the last step. But we don't consider that to be an issue.
928          */
929         do_log     = (do_per_step(step, ir->nstlog)
930                   || (bFirstStep && startingBehavior == StartingBehavior::NewSimulation) || bLastStep);
931         do_verbose = mdrunOptions.verbose
932                      && (step % mdrunOptions.verboseStepPrintInterval == 0 || bFirstStep || bLastStep);
933
934         if (useGpuForUpdate && !bFirstStep && bNS)
935         {
936             // Copy velocities from the GPU on search steps to keep a copy on host (device buffers are reinitialized).
937             stateGpu->copyVelocitiesFromGpu(state->v, AtomLocality::Local);
938             stateGpu->waitVelocitiesReadyOnHost(AtomLocality::Local);
939             // Copy coordinate from the GPU when needed at the search step.
940             // NOTE: The cases when coordinates needed on CPU for force evaluation are handled in sim_utils.
941             // NOTE: If the coordinates are to be written into output file they are also copied separately before the output.
942             stateGpu->copyCoordinatesFromGpu(state->x, AtomLocality::Local);
943             stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
944         }
945
946         // We only need to calculate virtual velocities if we are writing them in the current step
947         const bool needVirtualVelocitiesThisStep =
948                 (vsite != nullptr)
949                 && (do_per_step(step, ir->nstvout) || checkpointHandler->isCheckpointingStep());
950
951         if (vsite != nullptr)
952         {
953             // Virtual sites need to be updated before domain decomposition and forces are calculated
954             wallcycle_start(wcycle, WallCycleCounter::VsiteConstr);
955             // md-vv calculates virtual velocities once it has full-step real velocities
956             vsite->construct(state->x,
957                              state->v,
958                              state->box,
959                              (!EI_VV(inputrec->eI) && needVirtualVelocitiesThisStep)
960                                      ? VSiteOperation::PositionsAndVelocities
961                                      : VSiteOperation::Positions);
962             wallcycle_stop(wcycle, WallCycleCounter::VsiteConstr);
963         }
964
965         if (bNS && !(bFirstStep && ir->bContinuation))
966         {
967             bMasterState = FALSE;
968             /* Correct the new box if it is too skewed */
969             if (inputrecDynamicBox(ir))
970             {
971                 if (correct_box(fplog, step, state->box))
972                 {
973                     bMasterState = TRUE;
974                     // If update is offloaded, it should be informed about the box size change
975                     if (useGpuForUpdate)
976                     {
977                         integrator->setPbc(PbcType::Xyz, state->box);
978                     }
979                 }
980             }
981             if (DOMAINDECOMP(cr) && bMasterState)
982             {
983                 dd_collect_state(cr->dd, state, state_global);
984             }
985
986             if (DOMAINDECOMP(cr))
987             {
988                 /* Repartition the domain decomposition */
989                 dd_partition_system(fplog,
990                                     mdlog,
991                                     step,
992                                     cr,
993                                     bMasterState,
994                                     nstglobalcomm,
995                                     state_global,
996                                     top_global,
997                                     *ir,
998                                     imdSession,
999                                     pull_work,
1000                                     state,
1001                                     &f,
1002                                     mdAtoms,
1003                                     &top,
1004                                     fr,
1005                                     vsite,
1006                                     constr,
1007                                     nrnb,
1008                                     wcycle,
1009                                     do_verbose && !bPMETunePrinting);
1010                 upd.updateAfterPartition(state->natoms,
1011                                          md->cFREEZE ? gmx::arrayRefFromArray(md->cFREEZE, md->nr)
1012                                                      : gmx::ArrayRef<const unsigned short>(),
1013                                          md->cTC ? gmx::arrayRefFromArray(md->cTC, md->nr)
1014                                                  : gmx::ArrayRef<const unsigned short>());
1015             }
1016         }
1017
1018         // Allocate or re-size GPU halo exchange object, if necessary
1019         if (bNS && havePPDomainDecomposition(cr) && simulationWork.useGpuHaloExchange)
1020         {
1021             GMX_RELEASE_ASSERT(fr->deviceStreamManager != nullptr,
1022                                "GPU device manager has to be initialized to use GPU "
1023                                "version of halo exchange.");
1024             constructGpuHaloExchange(mdlog, *cr, *fr->deviceStreamManager, wcycle);
1025         }
1026
1027         if (MASTER(cr) && do_log)
1028         {
1029             gmx::EnergyOutput::printHeader(
1030                     fplog, step, t); /* can we improve the information printed here? */
1031         }
1032
1033         if (ir->efep != FreeEnergyPerturbationType::No)
1034         {
1035             update_mdatoms(mdAtoms->mdatoms(), state->lambda[FreeEnergyPerturbationCouplingType::Mass]);
1036         }
1037
1038         if (bExchanged)
1039         {
1040             /* We need the kinetic energy at minus the half step for determining
1041              * the full step kinetic energy and possibly for T-coupling.*/
1042             /* This may not be quite working correctly yet . . . . */
1043             int cglo_flags = CGLO_GSTAT | CGLO_TEMPERATURE;
1044             if (DOMAINDECOMP(cr) && dd_localTopologyChecker(*cr->dd).shouldCheckNumberOfBondedInteractions())
1045             {
1046                 cglo_flags |= CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS;
1047             }
1048             compute_globals(gstat,
1049                             cr,
1050                             ir,
1051                             fr,
1052                             ekind,
1053                             makeConstArrayRef(state->x),
1054                             makeConstArrayRef(state->v),
1055                             state->box,
1056                             md,
1057                             nrnb,
1058                             &vcm,
1059                             wcycle,
1060                             enerd,
1061                             nullptr,
1062                             nullptr,
1063                             nullptr,
1064                             nullptr,
1065                             gmx::ArrayRef<real>{},
1066                             &nullSignaller,
1067                             state->box,
1068                             &bSumEkinhOld,
1069                             cglo_flags);
1070             if (DOMAINDECOMP(cr))
1071             {
1072                 dd_localTopologyChecker(cr->dd)->checkNumberOfBondedInteractions(
1073                         &top, makeConstArrayRef(state->x), state->box);
1074             }
1075         }
1076         clear_mat(force_vir);
1077
1078         checkpointHandler->decideIfCheckpointingThisStep(bNS, bFirstStep, bLastStep);
1079
1080         /* Determine the energy and pressure:
1081          * at nstcalcenergy steps and at energy output steps (set below).
1082          */
1083         if (EI_VV(ir->eI) && (!bInitStep))
1084         {
1085             bCalcEnerStep = do_per_step(step, ir->nstcalcenergy);
1086             bCalcVir      = bCalcEnerStep
1087                        || (ir->epc != PressureCoupling::No
1088                            && (do_per_step(step, ir->nstpcouple) || do_per_step(step - 1, ir->nstpcouple)));
1089         }
1090         else
1091         {
1092             bCalcEnerStep = do_per_step(step, ir->nstcalcenergy);
1093             bCalcVir      = bCalcEnerStep
1094                        || (ir->epc != PressureCoupling::No && do_per_step(step, ir->nstpcouple));
1095         }
1096         bCalcEner = bCalcEnerStep;
1097
1098         do_ene = (do_per_step(step, ir->nstenergy) || bLastStep);
1099
1100         if (do_ene || do_log || bDoReplEx)
1101         {
1102             bCalcVir  = TRUE;
1103             bCalcEner = TRUE;
1104         }
1105
1106         /* Do we need global communication ? */
1107         bGStat = (bCalcVir || bCalcEner || bStopCM || do_per_step(step, nstglobalcomm)
1108                   || (EI_VV(ir->eI) && inputrecNvtTrotter(ir) && do_per_step(step - 1, nstglobalcomm)));
1109
1110         force_flags = (GMX_FORCE_STATECHANGED | ((inputrecDynamicBox(ir)) ? GMX_FORCE_DYNAMICBOX : 0)
1111                        | GMX_FORCE_ALLFORCES | (bCalcVir ? GMX_FORCE_VIRIAL : 0)
1112                        | (bCalcEner ? GMX_FORCE_ENERGY : 0) | (bDoFEP ? GMX_FORCE_DHDL : 0));
1113         if (simulationWork.useMts && !do_per_step(step, ir->nstfout))
1114         {
1115             // TODO: merge this with stepWork.useOnlyMtsCombinedForceBuffer
1116             force_flags |= GMX_FORCE_DO_NOT_NEED_NORMAL_FORCE;
1117         }
1118
1119         if (shellfc)
1120         {
1121             /* Now is the time to relax the shells */
1122             relax_shell_flexcon(fplog,
1123                                 cr,
1124                                 ms,
1125                                 mdrunOptions.verbose,
1126                                 enforcedRotation,
1127                                 step,
1128                                 ir,
1129                                 imdSession,
1130                                 pull_work,
1131                                 bNS,
1132                                 force_flags,
1133                                 &top,
1134                                 constr,
1135                                 enerd,
1136                                 state->natoms,
1137                                 state->x.arrayRefWithPadding(),
1138                                 state->v.arrayRefWithPadding(),
1139                                 state->box,
1140                                 state->lambda,
1141                                 &state->hist,
1142                                 &f.view(),
1143                                 force_vir,
1144                                 *md,
1145                                 nrnb,
1146                                 wcycle,
1147                                 shellfc,
1148                                 fr,
1149                                 runScheduleWork,
1150                                 t,
1151                                 mu_tot,
1152                                 vsite,
1153                                 ddBalanceRegionHandler);
1154         }
1155         else
1156         {
1157             /* The AWH history need to be saved _before_ doing force calculations where the AWH bias
1158                is updated (or the AWH update will be performed twice for one step when continuing).
1159                It would be best to call this update function from do_md_trajectory_writing but that
1160                would occur after do_force. One would have to divide the update_awh function into one
1161                function applying the AWH force and one doing the AWH bias update. The update AWH
1162                bias function could then be called after do_md_trajectory_writing (then containing
1163                update_awh_history). The checkpointing will in the future probably moved to the start
1164                of the md loop which will rid of this issue. */
1165             if (awh && checkpointHandler->isCheckpointingStep() && MASTER(cr))
1166             {
1167                 awh->updateHistory(state_global->awhHistory.get());
1168             }
1169
1170             /* The coordinates (x) are shifted (to get whole molecules)
1171              * in do_force.
1172              * This is parallellized as well, and does communication too.
1173              * Check comments in sim_util.c
1174              */
1175             do_force(fplog,
1176                      cr,
1177                      ms,
1178                      *ir,
1179                      awh.get(),
1180                      enforcedRotation,
1181                      imdSession,
1182                      pull_work,
1183                      step,
1184                      nrnb,
1185                      wcycle,
1186                      &top,
1187                      state->box,
1188                      state->x.arrayRefWithPadding(),
1189                      &state->hist,
1190                      &f.view(),
1191                      force_vir,
1192                      md,
1193                      enerd,
1194                      state->lambda,
1195                      fr,
1196                      runScheduleWork,
1197                      vsite,
1198                      mu_tot,
1199                      t,
1200                      ed ? ed->getLegacyED() : nullptr,
1201                      (bNS ? GMX_FORCE_NS : 0) | force_flags,
1202                      ddBalanceRegionHandler);
1203         }
1204
1205         // VV integrators do not need the following velocity half step
1206         // if it is the first step after starting from a checkpoint.
1207         // That is, the half step is needed on all other steps, and
1208         // also the first step when starting from a .tpr file.
1209         if (EI_VV(ir->eI))
1210         {
1211             integrateVVFirstStep(step,
1212                                  bFirstStep,
1213                                  bInitStep,
1214                                  startingBehavior,
1215                                  nstglobalcomm,
1216                                  ir,
1217                                  fr,
1218                                  cr,
1219                                  state,
1220                                  mdAtoms->mdatoms(),
1221                                  fcdata,
1222                                  &MassQ,
1223                                  &vcm,
1224                                  top,
1225                                  enerd,
1226                                  ekind,
1227                                  gstat,
1228                                  &last_ekin,
1229                                  bCalcVir,
1230                                  total_vir,
1231                                  shake_vir,
1232                                  force_vir,
1233                                  pres,
1234                                  M,
1235                                  do_log,
1236                                  do_ene,
1237                                  bCalcEner,
1238                                  bGStat,
1239                                  bStopCM,
1240                                  bTrotter,
1241                                  bExchanged,
1242                                  &bSumEkinhOld,
1243                                  &saved_conserved_quantity,
1244                                  &f,
1245                                  &upd,
1246                                  constr,
1247                                  &nullSignaller,
1248                                  trotter_seq,
1249                                  nrnb,
1250                                  fplog,
1251                                  wcycle);
1252             if (vsite != nullptr && needVirtualVelocitiesThisStep)
1253             {
1254                 // Positions were calculated earlier
1255                 wallcycle_start(wcycle, WallCycleCounter::VsiteConstr);
1256                 vsite->construct(state->x, state->v, state->box, VSiteOperation::Velocities);
1257                 wallcycle_stop(wcycle, WallCycleCounter::VsiteConstr);
1258             }
1259         }
1260
1261         /* ########  END FIRST UPDATE STEP  ############## */
1262         /* ########  If doing VV, we now have v(dt) ###### */
1263         if (bDoExpanded)
1264         {
1265             /* perform extended ensemble sampling in lambda - we don't
1266                actually move to the new state before outputting
1267                statistics, but if performing simulated tempering, we
1268                do update the velocities and the tau_t. */
1269             // TODO: Avoid changing inputrec (#3854)
1270             // Simulated tempering updates the reference temperature.
1271             // Expanded ensemble without simulated tempering does not change the inputrec.
1272             auto* nonConstInputrec = const_cast<t_inputrec*>(inputrec);
1273             lamnew                 = ExpandedEnsembleDynamics(fplog,
1274                                               nonConstInputrec,
1275                                               enerd,
1276                                               state,
1277                                               &MassQ,
1278                                               state->fep_state,
1279                                               state->dfhist,
1280                                               step,
1281                                               state->v.rvec_array(),
1282                                               md->homenr,
1283                                               md->cTC ? gmx::arrayRefFromArray(md->cTC, md->nr)
1284                                                                       : gmx::ArrayRef<const unsigned short>());
1285             /* history is maintained in state->dfhist, but state_global is what is sent to trajectory and log output */
1286             if (MASTER(cr))
1287             {
1288                 copy_df_history(state_global->dfhist, state->dfhist);
1289             }
1290         }
1291
1292         // Copy coordinate from the GPU for the output/checkpointing if the update is offloaded and
1293         // coordinates have not already been copied for i) search or ii) CPU force tasks.
1294         if (useGpuForUpdate && !bNS && !runScheduleWork->domainWork.haveCpuLocalForceWork
1295             && (do_per_step(step, ir->nstxout) || do_per_step(step, ir->nstxout_compressed)
1296                 || checkpointHandler->isCheckpointingStep()))
1297         {
1298             stateGpu->copyCoordinatesFromGpu(state->x, AtomLocality::Local);
1299             stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
1300         }
1301         // Copy velocities if needed for the output/checkpointing.
1302         // NOTE: Copy on the search steps is done at the beginning of the step.
1303         if (useGpuForUpdate && !bNS
1304             && (do_per_step(step, ir->nstvout) || checkpointHandler->isCheckpointingStep()))
1305         {
1306             stateGpu->copyVelocitiesFromGpu(state->v, AtomLocality::Local);
1307             stateGpu->waitVelocitiesReadyOnHost(AtomLocality::Local);
1308         }
1309         // Copy forces for the output if the forces were reduced on the GPU (not the case on virial steps)
1310         // and update is offloaded hence forces are kept on the GPU for update and have not been
1311         // already transferred in do_force().
1312         // TODO: There should be an improved, explicit mechanism that ensures this copy is only executed
1313         //       when the forces are ready on the GPU -- the same synchronizer should be used as the one
1314         //       prior to GPU update.
1315         // TODO: When the output flags will be included in step workload, this copy can be combined with the
1316         //       copy call in do_force(...).
1317         // NOTE: The forces should not be copied here if the vsites are present, since they were modified
1318         //       on host after the D2H copy in do_force(...).
1319         if (runScheduleWork->stepWork.useGpuFBufferOps && (simulationWork.useGpuUpdate && !vsite)
1320             && do_per_step(step, ir->nstfout))
1321         {
1322             stateGpu->copyForcesFromGpu(f.view().force(), AtomLocality::Local);
1323             stateGpu->waitForcesReadyOnHost(AtomLocality::Local);
1324         }
1325         /* Now we have the energies and forces corresponding to the
1326          * coordinates at time t. We must output all of this before
1327          * the update.
1328          */
1329         do_md_trajectory_writing(fplog,
1330                                  cr,
1331                                  nfile,
1332                                  fnm,
1333                                  step,
1334                                  step_rel,
1335                                  t,
1336                                  ir,
1337                                  state,
1338                                  state_global,
1339                                  observablesHistory,
1340                                  top_global,
1341                                  fr,
1342                                  outf,
1343                                  energyOutput,
1344                                  ekind,
1345                                  f.view().force(),
1346                                  checkpointHandler->isCheckpointingStep(),
1347                                  bRerunMD,
1348                                  bLastStep,
1349                                  mdrunOptions.writeConfout,
1350                                  bSumEkinhOld);
1351         /* Check if IMD step and do IMD communication, if bIMD is TRUE. */
1352         bInteractiveMDstep = imdSession->run(step, bNS, state->box, state->x, t);
1353
1354         /* kludge -- virial is lost with restart for MTTK NPT control. Must reload (saved earlier). */
1355         if (startingBehavior != StartingBehavior::NewSimulation && bFirstStep
1356             && (inputrecNptTrotter(ir) || inputrecNphTrotter(ir)))
1357         {
1358             copy_mat(state->svir_prev, shake_vir);
1359             copy_mat(state->fvir_prev, force_vir);
1360         }
1361
1362         stopHandler->setSignal();
1363         resetHandler->setSignal(walltime_accounting);
1364
1365         if (bGStat || !PAR(cr))
1366         {
1367             /* In parallel we only have to check for checkpointing in steps
1368              * where we do global communication,
1369              *  otherwise the other nodes don't know.
1370              */
1371             checkpointHandler->setSignal(walltime_accounting);
1372         }
1373
1374         /* #########   START SECOND UPDATE STEP ################# */
1375
1376         /* at the start of step, randomize or scale the velocities ((if vv. Restriction of Andersen
1377            controlled in preprocessing */
1378
1379         if (ETC_ANDERSEN(ir->etc)) /* keep this outside of update_tcouple because of the extra info required to pass */
1380         {
1381             gmx_bool bIfRandomize;
1382             bIfRandomize = update_randomize_velocities(ir,
1383                                                        step,
1384                                                        cr,
1385                                                        md->homenr,
1386                                                        md->cTC ? gmx::arrayRefFromArray(md->cTC, md->nr)
1387                                                                : gmx::ArrayRef<const unsigned short>(),
1388                                                        gmx::arrayRefFromArray(md->invmass, md->nr),
1389                                                        state->v,
1390                                                        &upd,
1391                                                        constr);
1392             /* if we have constraints, we have to remove the kinetic energy parallel to the bonds */
1393             if (constr && bIfRandomize)
1394             {
1395                 constrain_velocities(constr, do_log, do_ene, step, state, nullptr, false, nullptr);
1396             }
1397         }
1398         /* Box is changed in update() when we do pressure coupling,
1399          * but we should still use the old box for energy corrections and when
1400          * writing it to the energy file, so it matches the trajectory files for
1401          * the same timestep above. Make a copy in a separate array.
1402          */
1403         copy_mat(state->box, lastbox);
1404
1405         dvdl_constr = 0;
1406
1407         if (!useGpuForUpdate)
1408         {
1409             wallcycle_start(wcycle, WallCycleCounter::Update);
1410         }
1411         /* UPDATE PRESSURE VARIABLES IN TROTTER FORMULATION WITH CONSTRAINTS */
1412         if (bTrotter)
1413         {
1414             trotter_update(ir,
1415                            step,
1416                            ekind,
1417                            enerd,
1418                            state,
1419                            total_vir,
1420                            md->homenr,
1421                            md->cTC ? gmx::arrayRefFromArray(md->cTC, md->nr)
1422                                    : gmx::ArrayRef<const unsigned short>(),
1423                            gmx::arrayRefFromArray(md->invmass, md->nr),
1424                            &MassQ,
1425                            trotter_seq,
1426                            TrotterSequence::Three);
1427             /* We can only do Berendsen coupling after we have summed
1428              * the kinetic energy or virial. Since the happens
1429              * in global_state after update, we should only do it at
1430              * step % nstlist = 1 with bGStatEveryStep=FALSE.
1431              */
1432         }
1433         else
1434         {
1435             update_tcouple(step,
1436                            ir,
1437                            state,
1438                            ekind,
1439                            &MassQ,
1440                            md->homenr,
1441                            md->cTC ? gmx::arrayRefFromArray(md->cTC, md->nr)
1442                                    : gmx::ArrayRef<const unsigned short>());
1443             update_pcouple_before_coordinates(fplog, step, ir, state, pressureCouplingMu, M, bInitStep);
1444         }
1445
1446         /* With leap-frog type integrators we compute the kinetic energy
1447          * at a whole time step as the average of the half-time step kinetic
1448          * energies of two subsequent steps. Therefore we need to compute the
1449          * half step kinetic energy also if we need energies at the next step.
1450          */
1451         const bool needHalfStepKineticEnergy =
1452                 (!EI_VV(ir->eI) && (do_per_step(step + 1, nstglobalcomm) || step_rel + 1 == ir->nsteps));
1453
1454         // Parrinello-Rahman requires the pressure to be availible before the update to compute
1455         // the velocity scaling matrix. Hence, it runs one step after the nstpcouple step.
1456         const bool doParrinelloRahman = (ir->epc == PressureCoupling::ParrinelloRahman
1457                                          && do_per_step(step + ir->nstpcouple - 1, ir->nstpcouple));
1458
1459         if (EI_VV(ir->eI))
1460         {
1461             GMX_ASSERT(!useGpuForUpdate, "GPU update is not supported with VVAK integrator.");
1462
1463             integrateVVSecondStep(step,
1464                                   ir,
1465                                   fr,
1466                                   cr,
1467                                   state,
1468                                   mdAtoms->mdatoms(),
1469                                   fcdata,
1470                                   &MassQ,
1471                                   &vcm,
1472                                   pull_work,
1473                                   enerd,
1474                                   ekind,
1475                                   gstat,
1476                                   &dvdl_constr,
1477                                   bCalcVir,
1478                                   total_vir,
1479                                   shake_vir,
1480                                   force_vir,
1481                                   pres,
1482                                   M,
1483                                   lastbox,
1484                                   do_log,
1485                                   do_ene,
1486                                   bGStat,
1487                                   &bSumEkinhOld,
1488                                   &f,
1489                                   &cbuf,
1490                                   &upd,
1491                                   constr,
1492                                   &nullSignaller,
1493                                   trotter_seq,
1494                                   nrnb,
1495                                   wcycle);
1496         }
1497         else
1498         {
1499             if (useGpuForUpdate)
1500             {
1501                 if (bNS && (bFirstStep || DOMAINDECOMP(cr)))
1502                 {
1503                     integrator->set(stateGpu->getCoordinates(),
1504                                     stateGpu->getVelocities(),
1505                                     stateGpu->getForces(),
1506                                     top.idef,
1507                                     *md);
1508
1509                     // Copy data to the GPU after buffers might have being reinitialized
1510                     // coordinates have been copied already if PME or buffer ops has not needed it this step.
1511                     stateGpu->copyVelocitiesToGpu(state->v, AtomLocality::Local);
1512                     const bool useGpuPmeOnThisRank = runScheduleWork->simulationWork.useGpuPme
1513                                                      && thisRankHasDuty(cr, DUTY_PME)
1514                                                      && runScheduleWork->stepWork.computeSlowForces;
1515                     if (!useGpuPmeOnThisRank && !runScheduleWork->stepWork.useGpuXBufferOps)
1516                     {
1517                         stateGpu->copyCoordinatesToGpu(state->x, AtomLocality::Local);
1518                     }
1519                 }
1520
1521                 if (simulationWork.useGpuPme && !runScheduleWork->simulationWork.useGpuPmePpCommunication
1522                     && !thisRankHasDuty(cr, DUTY_PME))
1523                 {
1524                     // The PME forces were recieved to the host, so have to be copied
1525                     stateGpu->copyForcesToGpu(f.view().force(), AtomLocality::All);
1526                 }
1527                 else if (!runScheduleWork->stepWork.useGpuFBufferOps)
1528                 {
1529                     // The buffer ops were not offloaded this step, so the forces are on the
1530                     // host and have to be copied
1531                     stateGpu->copyForcesToGpu(f.view().force(), AtomLocality::Local);
1532                 }
1533
1534                 const bool doTemperatureScaling =
1535                         (ir->etc != TemperatureCoupling::No
1536                          && do_per_step(step + ir->nsttcouple - 1, ir->nsttcouple));
1537
1538                 // This applies Leap-Frog, LINCS and SETTLE in succession
1539                 integrator->integrate(
1540                         stateGpu->getForcesReadyOnDeviceEvent(
1541                                 AtomLocality::Local, runScheduleWork->stepWork.useGpuFBufferOps),
1542                         ir->delta_t,
1543                         true,
1544                         bCalcVir,
1545                         shake_vir,
1546                         doTemperatureScaling,
1547                         ekind->tcstat,
1548                         doParrinelloRahman,
1549                         ir->nstpcouple * ir->delta_t,
1550                         M);
1551
1552                 // Copy velocities D2H after update if:
1553                 // - Globals are computed this step (includes the energy output steps).
1554                 // - Temperature is needed for the next step.
1555                 if (bGStat || needHalfStepKineticEnergy)
1556                 {
1557                     stateGpu->copyVelocitiesFromGpu(state->v, AtomLocality::Local);
1558                     stateGpu->waitVelocitiesReadyOnHost(AtomLocality::Local);
1559                 }
1560             }
1561             else
1562             {
1563                 /* With multiple time stepping we need to do an additional normal
1564                  * update step to obtain the virial, as the actual MTS integration
1565                  * using an acceleration where the slow forces are multiplied by mtsFactor.
1566                  * Using that acceleration would result in a virial with the slow
1567                  * force contribution would be a factor mtsFactor too large.
1568                  */
1569                 if (simulationWork.useMts && bCalcVir && constr != nullptr)
1570                 {
1571                     upd.update_for_constraint_virial(*ir,
1572                                                      md->homenr,
1573                                                      md->havePartiallyFrozenAtoms,
1574                                                      gmx::arrayRefFromArray(md->invmass, md->nr),
1575                                                      gmx::arrayRefFromArray(md->invMassPerDim, md->nr),
1576                                                      *state,
1577                                                      f.view().forceWithPadding(),
1578                                                      *ekind);
1579
1580                     constrain_coordinates(constr,
1581                                           do_log,
1582                                           do_ene,
1583                                           step,
1584                                           state,
1585                                           upd.xp()->arrayRefWithPadding(),
1586                                           &dvdl_constr,
1587                                           bCalcVir,
1588                                           shake_vir);
1589                 }
1590
1591                 ArrayRefWithPadding<const RVec> forceCombined =
1592                         (simulationWork.useMts && step % ir->mtsLevels[1].stepFactor == 0)
1593                                 ? f.view().forceMtsCombinedWithPadding()
1594                                 : f.view().forceWithPadding();
1595                 upd.update_coords(*ir,
1596                                   step,
1597                                   md->homenr,
1598                                   md->havePartiallyFrozenAtoms,
1599                                   gmx::arrayRefFromArray(md->ptype, md->nr),
1600                                   gmx::arrayRefFromArray(md->invmass, md->nr),
1601                                   gmx::arrayRefFromArray(md->invMassPerDim, md->nr),
1602                                   state,
1603                                   forceCombined,
1604                                   fcdata,
1605                                   ekind,
1606                                   M,
1607                                   etrtPOSITION,
1608                                   cr,
1609                                   constr != nullptr);
1610
1611                 wallcycle_stop(wcycle, WallCycleCounter::Update);
1612
1613                 constrain_coordinates(constr,
1614                                       do_log,
1615                                       do_ene,
1616                                       step,
1617                                       state,
1618                                       upd.xp()->arrayRefWithPadding(),
1619                                       &dvdl_constr,
1620                                       bCalcVir && !simulationWork.useMts,
1621                                       shake_vir);
1622
1623                 upd.update_sd_second_half(*ir,
1624                                           step,
1625                                           &dvdl_constr,
1626                                           md->homenr,
1627                                           gmx::arrayRefFromArray(md->ptype, md->nr),
1628                                           gmx::arrayRefFromArray(md->invmass, md->nr),
1629                                           state,
1630                                           cr,
1631                                           nrnb,
1632                                           wcycle,
1633                                           constr,
1634                                           do_log,
1635                                           do_ene);
1636                 upd.finish_update(
1637                         *ir, md->havePartiallyFrozenAtoms, md->homenr, state, wcycle, constr != nullptr);
1638             }
1639
1640             if (ir->bPull && ir->pull->bSetPbcRefToPrevStepCOM)
1641             {
1642                 updatePrevStepPullCom(pull_work, state);
1643             }
1644
1645             enerd->term[F_DVDL_CONSTR] += dvdl_constr;
1646         }
1647
1648         /* ############## IF NOT VV, Calculate globals HERE  ############ */
1649         /* With Leap-Frog we can skip compute_globals at
1650          * non-communication steps, but we need to calculate
1651          * the kinetic energy one step before communication.
1652          */
1653         {
1654             // Organize to do inter-simulation signalling on steps if
1655             // and when algorithms require it.
1656             const bool doInterSimSignal = (simulationsShareState && do_per_step(step, nstSignalComm));
1657
1658             if (bGStat || needHalfStepKineticEnergy || doInterSimSignal)
1659             {
1660                 // Copy coordinates when needed to stop the CM motion.
1661                 if (useGpuForUpdate && (bDoReplEx || (!EI_VV(ir->eI) && bStopCM)))
1662                 {
1663                     stateGpu->copyCoordinatesFromGpu(state->x, AtomLocality::Local);
1664                     stateGpu->waitCoordinatesReadyOnHost(AtomLocality::Local);
1665                 }
1666                 // Since we're already communicating at this step, we
1667                 // can propagate intra-simulation signals. Note that
1668                 // check_nstglobalcomm has the responsibility for
1669                 // choosing the value of nstglobalcomm that is one way
1670                 // bGStat becomes true, so we can't get into a
1671                 // situation where e.g. checkpointing can't be
1672                 // signalled.
1673                 bool                doIntraSimSignal = true;
1674                 SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal);
1675
1676                 compute_globals(
1677                         gstat,
1678                         cr,
1679                         ir,
1680                         fr,
1681                         ekind,
1682                         makeConstArrayRef(state->x),
1683                         makeConstArrayRef(state->v),
1684                         state->box,
1685                         md,
1686                         nrnb,
1687                         &vcm,
1688                         wcycle,
1689                         enerd,
1690                         force_vir,
1691                         shake_vir,
1692                         total_vir,
1693                         pres,
1694                         (!EI_VV(ir->eI) && bCalcEner && constr != nullptr) ? constr->rmsdData()
1695                                                                            : gmx::ArrayRef<real>{},
1696                         &signaller,
1697                         lastbox,
1698                         &bSumEkinhOld,
1699                         (bGStat ? CGLO_GSTAT : 0) | (!EI_VV(ir->eI) && bCalcEner ? CGLO_ENERGY : 0)
1700                                 | (!EI_VV(ir->eI) && bStopCM ? CGLO_STOPCM : 0)
1701                                 | (!EI_VV(ir->eI) ? CGLO_TEMPERATURE : 0)
1702                                 | (!EI_VV(ir->eI) ? CGLO_PRESSURE : 0) | CGLO_CONSTRAINT
1703                                 | (DOMAINDECOMP(cr) && dd_localTopologyChecker(*cr->dd).shouldCheckNumberOfBondedInteractions()
1704                                            ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS
1705                                            : 0));
1706                 if (DOMAINDECOMP(cr))
1707                 {
1708                     dd_localTopologyChecker(cr->dd)->checkNumberOfBondedInteractions(
1709                             &top, makeConstArrayRef(state->x), state->box);
1710                 }
1711                 if (!EI_VV(ir->eI) && bStopCM)
1712                 {
1713                     process_and_stopcm_grp(
1714                             fplog, &vcm, *md, makeArrayRef(state->x), makeArrayRef(state->v));
1715                     inc_nrnb(nrnb, eNR_STOPCM, md->homenr);
1716
1717                     // TODO: The special case of removing CM motion should be dealt more gracefully
1718                     if (useGpuForUpdate)
1719                     {
1720                         stateGpu->copyCoordinatesToGpu(state->x, AtomLocality::Local);
1721                         // Here we block until the H2D copy completes because event sync with the
1722                         // force kernels that use the coordinates on the next steps is not implemented
1723                         // (not because of a race on state->x being modified on the CPU while H2D is in progress).
1724                         stateGpu->waitCoordinatesCopiedToDevice(AtomLocality::Local);
1725                         // If the COM removal changed the velocities on the CPU, this has to be accounted for.
1726                         if (vcm.mode != ComRemovalAlgorithm::No)
1727                         {
1728                             stateGpu->copyVelocitiesToGpu(state->v, AtomLocality::Local);
1729                         }
1730                     }
1731                 }
1732             }
1733         }
1734
1735         /* #############  END CALC EKIN AND PRESSURE ################# */
1736
1737         /* Note: this is OK, but there are some numerical precision issues with using the convergence of
1738            the virial that should probably be addressed eventually. state->veta has better properies,
1739            but what we actually need entering the new cycle is the new shake_vir value. Ideally, we could
1740            generate the new shake_vir, but test the veta value for convergence.  This will take some thought. */
1741
1742         if (ir->efep != FreeEnergyPerturbationType::No && !EI_VV(ir->eI))
1743         {
1744             /* Sum up the foreign energy and dK/dl terms for md and sd.
1745                Currently done every step so that dH/dl is correct in the .edr */
1746             accumulateKineticLambdaComponents(enerd, state->lambda, *ir->fepvals);
1747         }
1748
1749         update_pcouple_after_coordinates(fplog,
1750                                          step,
1751                                          ir,
1752                                          md->homenr,
1753                                          md->cFREEZE ? gmx::arrayRefFromArray(md->cFREEZE, md->nr)
1754                                                      : gmx::ArrayRef<const unsigned short>(),
1755                                          pres,
1756                                          force_vir,
1757                                          shake_vir,
1758                                          pressureCouplingMu,
1759                                          state,
1760                                          nrnb,
1761                                          upd.deform(),
1762                                          !useGpuForUpdate);
1763
1764         const bool doBerendsenPressureCoupling = (inputrec->epc == PressureCoupling::Berendsen
1765                                                   && do_per_step(step, inputrec->nstpcouple));
1766         const bool doCRescalePressureCoupling  = (inputrec->epc == PressureCoupling::CRescale
1767                                                  && do_per_step(step, inputrec->nstpcouple));
1768         if (useGpuForUpdate
1769             && (doBerendsenPressureCoupling || doCRescalePressureCoupling || doParrinelloRahman))
1770         {
1771             integrator->scaleCoordinates(pressureCouplingMu);
1772             if (doCRescalePressureCoupling)
1773             {
1774                 matrix pressureCouplingInvMu;
1775                 gmx::invertBoxMatrix(pressureCouplingMu, pressureCouplingInvMu);
1776                 integrator->scaleVelocities(pressureCouplingInvMu);
1777             }
1778             integrator->setPbc(PbcType::Xyz, state->box);
1779         }
1780
1781         /* ################# END UPDATE STEP 2 ################# */
1782         /* #### We now have r(t+dt) and v(t+dt/2)  ############# */
1783
1784         /* The coordinates (x) were unshifted in update */
1785         if (!bGStat)
1786         {
1787             /* We will not sum ekinh_old,
1788              * so signal that we still have to do it.
1789              */
1790             bSumEkinhOld = TRUE;
1791         }
1792
1793         if (bCalcEner)
1794         {
1795             /* #########  BEGIN PREPARING EDR OUTPUT  ###########  */
1796
1797             /* use the directly determined last velocity, not actually the averaged half steps */
1798             if (bTrotter && ir->eI == IntegrationAlgorithm::VV)
1799             {
1800                 enerd->term[F_EKIN] = last_ekin;
1801             }
1802             enerd->term[F_ETOT] = enerd->term[F_EPOT] + enerd->term[F_EKIN];
1803
1804             if (integratorHasConservedEnergyQuantity(ir))
1805             {
1806                 if (EI_VV(ir->eI))
1807                 {
1808                     enerd->term[F_ECONSERVED] = enerd->term[F_ETOT] + saved_conserved_quantity;
1809                 }
1810                 else
1811                 {
1812                     enerd->term[F_ECONSERVED] = enerd->term[F_ETOT] + NPT_energy(ir, state, &MassQ);
1813                 }
1814             }
1815             /* #########  END PREPARING EDR OUTPUT  ###########  */
1816         }
1817
1818         /* Output stuff */
1819         if (MASTER(cr))
1820         {
1821             if (fplog && do_log && bDoExpanded)
1822             {
1823                 /* only needed if doing expanded ensemble */
1824                 PrintFreeEnergyInfoToFile(fplog,
1825                                           ir->fepvals.get(),
1826                                           ir->expandedvals.get(),
1827                                           ir->bSimTemp ? ir->simtempvals.get() : nullptr,
1828                                           state_global->dfhist,
1829                                           state->fep_state,
1830                                           ir->nstlog,
1831                                           step);
1832             }
1833             if (bCalcEner)
1834             {
1835                 energyOutput.addDataAtEnergyStep(bDoDHDL,
1836                                                  bCalcEnerStep,
1837                                                  t,
1838                                                  md->tmass,
1839                                                  enerd,
1840                                                  ir->fepvals.get(),
1841                                                  ir->expandedvals.get(),
1842                                                  lastbox,
1843                                                  PTCouplingArrays{ state->boxv,
1844                                                                    state->nosehoover_xi,
1845                                                                    state->nosehoover_vxi,
1846                                                                    state->nhpres_xi,
1847                                                                    state->nhpres_vxi },
1848                                                  state->fep_state,
1849                                                  total_vir,
1850                                                  pres,
1851                                                  ekind,
1852                                                  mu_tot,
1853                                                  constr);
1854             }
1855             else
1856             {
1857                 energyOutput.recordNonEnergyStep();
1858             }
1859
1860             gmx_bool do_dr = do_per_step(step, ir->nstdisreout);
1861             gmx_bool do_or = do_per_step(step, ir->nstorireout);
1862
1863             if (doSimulatedAnnealing)
1864             {
1865                 gmx::EnergyOutput::printAnnealingTemperatures(
1866                         do_log ? fplog : nullptr, groups, &(ir->opts));
1867             }
1868             if (do_log || do_ene || do_dr || do_or)
1869             {
1870                 energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf),
1871                                                    do_ene,
1872                                                    do_dr,
1873                                                    do_or,
1874                                                    do_log ? fplog : nullptr,
1875                                                    step,
1876                                                    t,
1877                                                    fr->fcdata.get(),
1878                                                    awh.get());
1879             }
1880             if (do_log && ir->bDoAwh && awh->hasFepLambdaDimension())
1881             {
1882                 const bool isInitialOutput = false;
1883                 printLambdaStateToLog(fplog, state->lambda, isInitialOutput);
1884             }
1885
1886             if (ir->bPull)
1887             {
1888                 pull_print_output(pull_work, step, t);
1889             }
1890
1891             if (do_per_step(step, ir->nstlog))
1892             {
1893                 if (fflush(fplog) != 0)
1894                 {
1895                     gmx_fatal(FARGS, "Cannot flush logfile - maybe you are out of disk space?");
1896                 }
1897             }
1898         }
1899         if (bDoExpanded)
1900         {
1901             /* Have to do this part _after_ outputting the logfile and the edr file */
1902             /* Gets written into the state at the beginning of next loop*/
1903             state->fep_state = lamnew;
1904         }
1905         else if (ir->bDoAwh && awh->needForeignEnergyDifferences(step))
1906         {
1907             state->fep_state = awh->fepLambdaState();
1908         }
1909         /* Print the remaining wall clock time for the run */
1910         if (isMasterSimMasterRank(ms, MASTER(cr)) && (do_verbose || gmx_got_usr_signal()) && !bPMETunePrinting)
1911         {
1912             if (shellfc)
1913             {
1914                 fprintf(stderr, "\n");
1915             }
1916             print_time(stderr, walltime_accounting, step, ir, cr);
1917         }
1918
1919         /* Ion/water position swapping.
1920          * Not done in last step since trajectory writing happens before this call
1921          * in the MD loop and exchanges would be lost anyway. */
1922         bNeedRepartition = FALSE;
1923         if ((ir->eSwapCoords != SwapType::No) && (step > 0) && !bLastStep
1924             && do_per_step(step, ir->swap->nstswap))
1925         {
1926             bNeedRepartition = do_swapcoords(cr,
1927                                              step,
1928                                              t,
1929                                              ir,
1930                                              swap,
1931                                              wcycle,
1932                                              as_rvec_array(state->x.data()),
1933                                              state->box,
1934                                              MASTER(cr) && mdrunOptions.verbose,
1935                                              bRerunMD);
1936
1937             if (bNeedRepartition && DOMAINDECOMP(cr))
1938             {
1939                 dd_collect_state(cr->dd, state, state_global);
1940             }
1941         }
1942
1943         /* Replica exchange */
1944         bExchanged = FALSE;
1945         if (bDoReplEx)
1946         {
1947             bExchanged = replica_exchange(fplog, cr, ms, repl_ex, state_global, enerd, state, step, t);
1948         }
1949
1950         if ((bExchanged || bNeedRepartition) && DOMAINDECOMP(cr))
1951         {
1952             dd_partition_system(fplog,
1953                                 mdlog,
1954                                 step,
1955                                 cr,
1956                                 TRUE,
1957                                 1,
1958                                 state_global,
1959                                 top_global,
1960                                 *ir,
1961                                 imdSession,
1962                                 pull_work,
1963                                 state,
1964                                 &f,
1965                                 mdAtoms,
1966                                 &top,
1967                                 fr,
1968                                 vsite,
1969                                 constr,
1970                                 nrnb,
1971                                 wcycle,
1972                                 FALSE);
1973             upd.updateAfterPartition(state->natoms,
1974                                      md->cFREEZE ? gmx::arrayRefFromArray(md->cFREEZE, md->nr)
1975                                                  : gmx::ArrayRef<const unsigned short>(),
1976                                      md->cTC ? gmx::arrayRefFromArray(md->cTC, md->nr)
1977                                              : gmx::ArrayRef<const unsigned short>());
1978         }
1979
1980         bFirstStep = FALSE;
1981         bInitStep  = FALSE;
1982
1983         /* #######  SET VARIABLES FOR NEXT ITERATION IF THEY STILL NEED IT ###### */
1984         /* With all integrators, except VV, we need to retain the pressure
1985          * at the current step for coupling at the next step.
1986          */
1987         if ((state->flags & enumValueToBitMask(StateEntry::PressurePrevious))
1988             && (bGStatEveryStep || (ir->nstpcouple > 0 && step % ir->nstpcouple == 0)))
1989         {
1990             /* Store the pressure in t_state for pressure coupling
1991              * at the next MD step.
1992              */
1993             copy_mat(pres, state->pres_prev);
1994         }
1995
1996         /* #######  END SET VARIABLES FOR NEXT ITERATION ###### */
1997
1998         if ((membed != nullptr) && (!bLastStep))
1999         {
2000             rescale_membed(step_rel, membed, as_rvec_array(state_global->x.data()));
2001         }
2002
2003         cycles = wallcycle_stop(wcycle, WallCycleCounter::Step);
2004         if (DOMAINDECOMP(cr) && wcycle)
2005         {
2006             dd_cycles_add(cr->dd, cycles, ddCyclStep);
2007         }
2008
2009         /* increase the MD step number */
2010         step++;
2011         step_rel++;
2012
2013 #if GMX_FAHCORE
2014         if (MASTER(cr))
2015         {
2016             fcReportProgress(ir->nsteps + ir->init_step, step);
2017         }
2018 #endif
2019
2020         resetHandler->resetCounters(
2021                 step, step_rel, mdlog, fplog, cr, fr->nbv.get(), nrnb, fr->pmedata, pme_loadbal, wcycle, walltime_accounting);
2022
2023         /* If bIMD is TRUE, the master updates the IMD energy record and sends positions to VMD client */
2024         imdSession->updateEnergyRecordAndSendPositionsAndEnergies(bInteractiveMDstep, step, bCalcEner);
2025     }
2026     /* End of main MD loop */
2027
2028     /* Closing TNG files can include compressing data. Therefore it is good to do that
2029      * before stopping the time measurements. */
2030     mdoutf_tng_close(outf);
2031
2032     /* Stop measuring walltime */
2033     walltime_accounting_end_time(walltime_accounting);
2034
2035     if (!thisRankHasDuty(cr, DUTY_PME))
2036     {
2037         /* Tell the PME only node to finish */
2038         gmx_pme_send_finish(cr);
2039     }
2040
2041     if (MASTER(cr))
2042     {
2043         if (ir->nstcalcenergy > 0)
2044         {
2045             energyOutput.printEnergyConservation(fplog, ir->simulation_part, EI_MD(ir->eI));
2046
2047             gmx::EnergyOutput::printAnnealingTemperatures(fplog, groups, &(ir->opts));
2048             energyOutput.printAverages(fplog, groups);
2049         }
2050     }
2051     done_mdoutf(outf);
2052
2053     if (bPMETune)
2054     {
2055         pme_loadbal_done(pme_loadbal, fplog, mdlog, fr->nbv->useGpu());
2056     }
2057
2058     done_shellfc(fplog, shellfc, step_rel);
2059
2060     if (useReplicaExchange && MASTER(cr))
2061     {
2062         print_replica_exchange_statistics(fplog, repl_ex);
2063     }
2064
2065     walltime_accounting_set_nsteps_done(walltime_accounting, step_rel);
2066
2067     global_stat_destroy(gstat);
2068 }