Move implementation to cpp file
authorBerk Hess <hess@kth.se>
Mon, 9 Nov 2020 10:10:29 +0000 (10:10 +0000)
committerPaul Bauer <paul.bauer.q@gmail.com>
Mon, 9 Nov 2020 10:10:29 +0000 (10:10 +0000)
Fixes issue with missing GMX_ASSERT as well.

15 files changed:
docs/release-notes/2021/major/features.rst
src/gromacs/mdlib/energydrifttracker.cpp [new file with mode: 0644]
src/gromacs/mdlib/energydrifttracker.h [new file with mode: 0644]
src/gromacs/mdlib/energyoutput.cpp
src/gromacs/mdlib/energyoutput.h
src/gromacs/mdlib/tests/CMakeLists.txt
src/gromacs/mdlib/tests/energydrifttracker.cpp [new file with mode: 0644]
src/gromacs/mdlib/tests/energyoutput.cpp
src/gromacs/mdrun/md.cpp
src/gromacs/mdrun/mimic.cpp
src/gromacs/mdrun/minimize.cpp
src/gromacs/mdrun/rerun.cpp
src/gromacs/modularsimulator/energydata.cpp
src/gromacs/modularsimulator/energydata.h
src/gromacs/modularsimulator/simulatoralgorithm.cpp

index 39cc8d972e99c119867609c1fe19b8c0d5c54842..fd1de6a7018e0710e7f63778a0f5ca67f18d75ea 100644 (file)
@@ -39,6 +39,12 @@ simulations of systems with SETTLE up to 1000 nm in size (but note that
 constraining with LINCS and SHAKE still introduces significant drift,
 which limits the system size to 100 to 200 nm).
 
+mdrun now reports energy drift
+""""""""""""""""""""""""""""""
+
+With conservative integrators, mdrun now reports the drift of the conserved
+energy quantity in the log file.
+
 FEP using AWH
 """""""""""""
 
diff --git a/src/gromacs/mdlib/energydrifttracker.cpp b/src/gromacs/mdlib/energydrifttracker.cpp
new file mode 100644 (file)
index 0000000..1d5f2b1
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief Implements functions from the EnergyDriftTracker class.
+ *
+ * \author Berk Hess <hess@kth.se>
+ *
+ * \ingroup module_mdlib
+ */
+#include "gmxpre.h"
+
+#include "energydrifttracker.h"
+
+#include <cmath>
+
+#include <string>
+
+#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/real.h"
+#include "gromacs/utility/stringutil.h"
+
+namespace gmx
+{
+
+void EnergyDriftTracker::addPoint(double time, double energy)
+{
+    GMX_ASSERT(std::isfinite(energy), "Non-finite energy encountered!");
+
+    if (!storedFirst_)
+    {
+        firstTime_   = time;
+        firstEnergy_ = energy;
+        storedFirst_ = true;
+    }
+    lastTime_   = time;
+    lastEnergy_ = energy;
+}
+
+double EnergyDriftTracker::energyDrift() const
+{
+    if (timeInterval() > 0)
+    {
+        return (lastEnergy_ - firstEnergy_) / (timeInterval() * numAtoms_);
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+std::string EnergyDriftTracker::energyDriftString(const std::string& partName) const
+{
+    std::string mesg;
+
+    if (timeInterval() > 0)
+    {
+        mesg = formatString("Energy conservation over %s of length %g ns, time %g to %g ns\n",
+                            partName.c_str(), timeInterval(), firstTime_, lastTime_);
+        mesg += formatString("  Conserved energy drift: %.2e kJ/mol/ps per atom\n", energyDrift());
+    }
+    else
+    {
+        mesg = formatString(
+                "Time interval for measuring conserved energy has length 0, time %g to %g\n",
+                firstTime_, lastTime_);
+    }
+
+    return mesg;
+}
+
+} // namespace gmx
diff --git a/src/gromacs/mdlib/energydrifttracker.h b/src/gromacs/mdlib/energydrifttracker.h
new file mode 100644 (file)
index 0000000..f189b66
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief Declares and defines the EnergyDriftTracker class.
+ *
+ * \author Berk Hess <hess@kth.se>
+ *
+ * \ingroup module_mdlib
+ */
+#ifndef GMX_MDLIB_ENERGYDRIFTTRACKER_H
+#define GMX_MDLIB_ENERGYDRIFTTRACKER_H
+
+#include <string>
+
+#include "gromacs/utility/real.h"
+
+namespace gmx
+{
+
+/*! \internal
+ * \brief Class for tracking and printing the drift in the conserved energy quantity
+ */
+class EnergyDriftTracker
+{
+public:
+    /*! \brief Constructor
+     *
+     * \param[in] numAtoms  The total number of atoms in the system
+     */
+    EnergyDriftTracker(int numAtoms) : numAtoms_(numAtoms) {}
+
+    //! Add a point to the conserved energy tracking
+    void addPoint(double time, double energy);
+
+    //! Returns the time of the last point minus the time of the first point
+    double timeInterval() const { return lastTime_ - firstTime_; }
+
+    //! Returns the energy drift over the measured interval
+    double energyDrift() const;
+
+    /*! \brief Returns two-line string with the time interval and drift over the interval
+     *
+     * \param[in] partName  A descriptive name for the period over which the tracking occured
+     */
+    std::string energyDriftString(const std::string& partName) const;
+
+private:
+    //! Whether we stored the first point
+    bool storedFirst_ = false;
+    //! The first time stored
+    double firstTime_ = 0;
+    //! The energy for the first time point
+    double firstEnergy_ = 0;
+    //! The last time stored
+    double lastTime_ = 0;
+    //! The energy for the last time point
+    double lastEnergy_ = 0;
+    //! The number of atoms in the system
+    int numAtoms_;
+};
+
+} // namespace gmx
+
+#endif
index 216a49ecf2c35340482dd1bcc20f9f666299db83..0b72fc4e0cce0e1eaa038941b35cdaf2c71afeb7 100644 (file)
@@ -85,6 +85,8 @@
 #include "gromacs/utility/smalloc.h"
 #include "gromacs/utility/stringutil.h"
 
+#include "energydrifttracker.h"
+
 //! Labels for energy file quantities
 //! \{
 static const char* conrmsd_nm[] = { "Constr. rmsd", "Constr.2 rmsd" };
@@ -127,6 +129,7 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
                            FILE*                    fp_dhdl,
                            bool                     isRerun,
                            const StartingBehavior   startingBehavior,
+                           const bool               simulationsShareState,
                            const MdModulesNotifier& mdModulesNotifier)
 {
     const char*        ener_nm[F_NRE];
@@ -572,6 +575,11 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
     {
         numTemperatures_ = 0;
     }
+
+    if (EI_MD(ir->eI) && !simulationsShareState)
+    {
+        conservedEnergyTracker_ = std::make_unique<EnergyDriftTracker>(mtop->natoms);
+    }
 }
 
 EnergyOutput::~EnergyOutput()
@@ -1142,6 +1150,12 @@ void EnergyOutput::addDataAtEnergyStep(bool                    bDoDHDL,
                                     store_dhdl, dE_ + fep->lambda_start_n, time);
         }
     }
+
+    if (conservedEnergyTracker_)
+    {
+        conservedEnergyTracker_->addPoint(
+                time, bEner_[F_ECONSERVED] ? enerd->term[F_ECONSERVED] : enerd->term[F_ETOT]);
+    }
 }
 
 void EnergyOutput::recordNonEnergyStep()
@@ -1497,4 +1511,24 @@ int EnergyOutput::numEnergyTerms() const
     return ebin_->nener;
 }
 
+void EnergyOutput::printEnergyConservation(FILE* fplog, int simulationPart, bool usingMdIntegrator) const
+{
+    if (fplog == nullptr)
+    {
+        return;
+    }
+
+    if (conservedEnergyTracker_)
+    {
+        std::string partName = formatString("simulation part #%d", simulationPart);
+        fprintf(fplog, "\n%s\n", conservedEnergyTracker_->energyDriftString(partName).c_str());
+    }
+    else if (usingMdIntegrator)
+    {
+        fprintf(fplog,
+                "\nCannot report drift of the conserved energy quantity because simulations share "
+                "state\n\n");
+    }
+}
+
 } // namespace gmx
index 18bfa98de9e12900150a7bb191014403ba5459cc..aa3ee609fcff82103bd1817405f4b0036d9c49ba 100644 (file)
@@ -47,6 +47,8 @@
 
 #include <cstdio>
 
+#include <memory>
+
 #include "gromacs/mdtypes/enerdata.h"
 
 class energyhistory_t;
@@ -97,6 +99,7 @@ enum
 
 namespace gmx
 {
+class EnergyDriftTracker;
 
 /*! \internal
  * \brief Arrays connected to Pressure and Temperature coupling
@@ -136,6 +139,7 @@ public:
      * \param[in] fp_dhdl    FEP file.
      * \param[in] isRerun    Is this is a rerun instead of the simulations.
      * \param[in] startingBehavior  Run starting behavior.
+     * \param[in] simulationsShareState  Tells whether the physical state is shared over simulations
      * \param[in] mdModulesNotifier Notifications to MD modules.
      */
     EnergyOutput(ener_file*               fp_ene,
@@ -145,6 +149,7 @@ public:
                  FILE*                    fp_dhdl,
                  bool                     isRerun,
                  StartingBehavior         startingBehavior,
+                 bool                     simulationsShareState,
                  const MdModulesNotifier& mdModulesNotifier);
 
     ~EnergyOutput();
@@ -277,6 +282,15 @@ public:
     //! Print an output header to the log file.
     static void printHeader(FILE* log, int64_t steps, double time);
 
+    /*! \brief Print conserved energy drift message to \p fplog
+     *
+     * Note that this is only over the current run (times are printed),
+     * this is not from the original start time for runs with continuation.
+     * This has the advantage that one can find if conservation issues are
+     * from the current run with the current settings on the current hardware.
+     */
+    void printEnergyConservation(FILE* fplog, int simulationPart, bool usingMdIntegrator) const;
+
 private:
     //! Timestep
     double delta_t_ = 0;
@@ -411,6 +425,9 @@ private:
     real* temperatures_ = nullptr;
     //! Number of temperatures actually saved
     int numTemperatures_ = 0;
+
+    //! For tracking the conserved or total energy
+    std::unique_ptr<EnergyDriftTracker> conservedEnergyTracker_;
 };
 
 } // namespace gmx
index faab9297da7c13969657a20a519c9f57dc426c61..ef2bb647a211f60611895a3e38da20aef7a09a1d 100644 (file)
@@ -39,6 +39,7 @@ gmx_add_unit_test(MdlibUnitTest mdlib-test HARDWARE_DETECTION
         constrtestdata.cpp
         constrtestrunners.cpp
         ebin.cpp
+       energydrifttracker.cpp
         energyoutput.cpp
         freeenergyparameters.cpp
         leapfrog.cpp
diff --git a/src/gromacs/mdlib/tests/energydrifttracker.cpp b/src/gromacs/mdlib/tests/energydrifttracker.cpp
new file mode 100644 (file)
index 0000000..19652b2
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2020, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief Tests for the EnergyDriftTacker class
+ *
+ * \author berk Hess <hess@kth.se>
+ * \ingroup module_mdlib
+ */
+#include "gmxpre.h"
+
+#include "gromacs/mdlib/energydrifttracker.h"
+
+#include <gtest/gtest.h>
+
+#include "testutils/testasserts.h"
+
+namespace gmx
+{
+
+namespace
+{
+
+TEST(EnergyDriftTracker, emptyWorks)
+{
+    EnergyDriftTracker tracker(1);
+
+    EXPECT_EQ(tracker.timeInterval(), 0);
+    EXPECT_EQ(tracker.energyDrift(), 0);
+}
+
+TEST(EnergyDriftTracker, onePointWorks)
+{
+    EnergyDriftTracker tracker(1);
+
+    tracker.addPoint(1.5, -3.5_real);
+    EXPECT_EQ(tracker.timeInterval(), 0);
+    EXPECT_EQ(tracker.energyDrift(), 0);
+}
+
+TEST(EnergyDriftTracker, manyPointsWorks)
+{
+    EnergyDriftTracker tracker(10);
+
+    tracker.addPoint(1.5, 2.5_real);
+    tracker.addPoint(3.5, 4.0_real);
+    tracker.addPoint(5.5, -5.5_real);
+    EXPECT_FLOAT_EQ(tracker.timeInterval(), 4.0_real);
+    EXPECT_FLOAT_EQ(tracker.energyDrift(), -0.2_real);
+}
+
+} // namespace
+
+} // namespace gmx
index bb4ce4ce00b914871d5dfdc9eabddb5141f793e0..4ebb7eb445c552fcafed1bcfca80fb5db0ace855 100644 (file)
@@ -627,7 +627,7 @@ TEST_P(EnergyOutputTest, CheckOutput)
     MdModulesNotifier             mdModulesNotifier;
     std::unique_ptr<EnergyOutput> energyOutput = std::make_unique<EnergyOutput>(
             energyFile_, &mtop_, &inputrec_, nullptr, nullptr, parameters.isRerun,
-            StartingBehavior::NewSimulation, mdModulesNotifier);
+            StartingBehavior::NewSimulation, false, mdModulesNotifier);
 
     // Add synthetic data for a single step
     double testValue = 10.0;
index f5c0fd393e527b48ecbb59402f34748c0afcf9a7..507e2d0d91d3e9d5f840b3ae37b0df9a869636c6 100644 (file)
@@ -296,7 +296,8 @@ void gmx::LegacySimulator::do_md()
             init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, mdModulesNotifier, ir,
                         top_global, oenv, wcycle, startingBehavior, simulationsShareState, ms);
     gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work,
-                                   mdoutf_get_fp_dhdl(outf), false, startingBehavior, mdModulesNotifier);
+                                   mdoutf_get_fp_dhdl(outf), false, startingBehavior,
+                                   simulationsShareState, mdModulesNotifier);
 
     gstat = global_stat_init(ir);
 
@@ -1700,6 +1701,8 @@ void gmx::LegacySimulator::do_md()
     {
         if (ir->nstcalcenergy > 0)
         {
+            energyOutput.printEnergyConservation(fplog, ir->simulation_part, EI_MD(ir->eI));
+
             gmx::EnergyOutput::printAnnealingTemperatures(fplog, groups, &(ir->opts));
             energyOutput.printAverages(fplog, groups);
         }
index e5ccee65e25322564d4171d6432cd7811df5344c..22a8458f0244f360b65413bb8a1847c2dfa7d371 100644 (file)
@@ -232,7 +232,7 @@ void gmx::LegacySimulator::do_mimic()
                                    StartingBehavior::NewSimulation, simulationsShareState, ms);
     gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work,
                                    mdoutf_get_fp_dhdl(outf), true, StartingBehavior::NewSimulation,
-                                   mdModulesNotifier);
+                                   simulationsShareState, mdModulesNotifier);
 
     gstat = global_stat_init(ir);
 
index 44276f96b1fbbdd9e268c3a0a33596b6522e8b11..f93b04245ce77d333a1788511a802a6ac8530dc8 100644 (file)
@@ -1095,8 +1095,9 @@ void LegacySimulator::do_cg()
     gmx_mdoutf*       outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider,
                                    mdModulesNotifier, inputrec, top_global, nullptr, wcycle,
                                    StartingBehavior::NewSimulation, simulationsShareState, ms);
-    gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work, nullptr,
-                                   false, StartingBehavior::NewSimulation, mdModulesNotifier);
+    gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work,
+                                   nullptr, false, StartingBehavior::NewSimulation,
+                                   simulationsShareState, mdModulesNotifier);
 
     /* Print to log file */
     print_em_start(fplog, cr, walltime_accounting, wcycle, CG);
@@ -1710,8 +1711,9 @@ void LegacySimulator::do_lbfgs()
     gmx_mdoutf*       outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider,
                                    mdModulesNotifier, inputrec, top_global, nullptr, wcycle,
                                    StartingBehavior::NewSimulation, simulationsShareState, ms);
-    gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work, nullptr,
-                                   false, StartingBehavior::NewSimulation, mdModulesNotifier);
+    gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work,
+                                   nullptr, false, StartingBehavior::NewSimulation,
+                                   simulationsShareState, mdModulesNotifier);
 
     start = 0;
     end   = mdatoms->homenr;
@@ -2390,8 +2392,9 @@ void LegacySimulator::do_steep()
     gmx_mdoutf*       outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider,
                                    mdModulesNotifier, inputrec, top_global, nullptr, wcycle,
                                    StartingBehavior::NewSimulation, simulationsShareState, ms);
-    gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work, nullptr,
-                                   false, StartingBehavior::NewSimulation, mdModulesNotifier);
+    gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, inputrec, pull_work,
+                                   nullptr, false, StartingBehavior::NewSimulation,
+                                   simulationsShareState, mdModulesNotifier);
 
     /* Print to log file  */
     print_em_start(fplog, cr, walltime_accounting, wcycle, SD);
index 8b83a92f5a36fb13779d391da6fbd55767d1d967..137e2d75c8b980ac06f0cb5e71434c3f129200ef 100644 (file)
@@ -288,7 +288,7 @@ void gmx::LegacySimulator::do_rerun()
                                    StartingBehavior::NewSimulation, simulationsShareState, ms);
     gmx::EnergyOutput energyOutput(mdoutf_get_fp_ene(outf), top_global, ir, pull_work,
                                    mdoutf_get_fp_dhdl(outf), true, StartingBehavior::NewSimulation,
-                                   mdModulesNotifier);
+                                   simulationsShareState, mdModulesNotifier);
 
     gstat = global_stat_init(ir);
 
index 8bba774e60d1b00caf84bc3603a93509c39e99eb..18174c49178dcd47501c80c78d3eadf083384a2b 100644 (file)
@@ -91,7 +91,8 @@ EnergyData::EnergyData(StatePropagatorData*        statePropagatorData,
                        const MdModulesNotifier&    mdModulesNotifier,
                        bool                        isMasterRank,
                        ObservablesHistory*         observablesHistory,
-                       StartingBehavior            startingBehavior) :
+                       StartingBehavior            startingBehavior,
+                       bool                        simulationsShareState) :
     element_(std::make_unique<Element>(this, isMasterRank)),
     isMasterRank_(isMasterRank),
     forceVirialStep_(-1),
@@ -115,7 +116,8 @@ EnergyData::EnergyData(StatePropagatorData*        statePropagatorData,
     fcd_(fcd),
     mdModulesNotifier_(mdModulesNotifier),
     groups_(&globalTopology->groups),
-    observablesHistory_(observablesHistory)
+    observablesHistory_(observablesHistory),
+    simulationsShareState_(simulationsShareState)
 {
     clear_mat(forceVirial_);
     clear_mat(shakeVirial_);
@@ -164,9 +166,9 @@ void EnergyData::Element::trajectoryWriterSetup(gmx_mdoutf* outf)
 void EnergyData::setup(gmx_mdoutf* outf)
 {
     pull_t* pull_work = nullptr;
-    energyOutput_ = std::make_unique<EnergyOutput>(mdoutf_get_fp_ene(outf), top_global_, inputrec_,
-                                                   pull_work, mdoutf_get_fp_dhdl(outf), false,
-                                                   startingBehavior_, mdModulesNotifier_);
+    energyOutput_     = std::make_unique<EnergyOutput>(
+            mdoutf_get_fp_ene(outf), top_global_, inputrec_, pull_work, mdoutf_get_fp_dhdl(outf),
+            false, startingBehavior_, simulationsShareState_, mdModulesNotifier_);
 
     if (!isMasterRank_)
     {
index 774390a39a95704d2c7074eec22dc82a4eb87029..29e2a0d28f4829f98e86ece3842c54b6deb72905 100644 (file)
@@ -107,7 +107,8 @@ public:
                const MdModulesNotifier&    mdModulesNotifier,
                bool                        isMasterRank,
                ObservablesHistory*         observablesHistory,
-               StartingBehavior            startingBehavior);
+               StartingBehavior            startingBehavior,
+               bool                        simulationsShareState);
 
     /*! \brief Final output
      *
@@ -315,6 +316,8 @@ private:
     const SimulationGroups* groups_;
     //! History of simulation observables.
     ObservablesHistory* observablesHistory_;
+    //! Whether simulations share the state
+    bool simulationsShareState_;
 };
 
 /*! \internal
index aa18bd767d0b24dee23c4659b5e149b06ce03cc0..cf6061054be85155bc76800e3e361bb54b55ef84 100644 (file)
@@ -408,13 +408,16 @@ ModularSimulatorAlgorithmBuilder::ModularSimulatorAlgorithmBuilder(
             opt2fn("-c", legacySimulatorData->nfile, legacySimulatorData->fnm), legacySimulatorData->inputrec,
             legacySimulatorData->mdAtoms->mdatoms(), legacySimulatorData->top_global);
 
+    // Multi sim is turned off
+    const bool simulationsShareState = false;
+
     energyData_ = std::make_unique<EnergyData>(
-            statePropagatorData_.get(), freeEnergyPerturbationData_.get(),
-            legacySimulatorData->top_global, legacySimulatorData->inputrec, legacySimulatorData->mdAtoms,
-            legacySimulatorData->enerd, legacySimulatorData->ekind, legacySimulatorData->constr,
-            legacySimulatorData->fplog, legacySimulatorData->fr->fcdata.get(),
-            legacySimulatorData->mdModulesNotifier, MASTER(legacySimulatorData->cr),
-            legacySimulatorData->observablesHistory, legacySimulatorData->startingBehavior);
+            statePropagatorData_.get(), freeEnergyPerturbationData_.get(), legacySimulatorData->top_global,
+            legacySimulatorData->inputrec, legacySimulatorData->mdAtoms, legacySimulatorData->enerd,
+            legacySimulatorData->ekind, legacySimulatorData->constr, legacySimulatorData->fplog,
+            legacySimulatorData->fr->fcdata.get(), legacySimulatorData->mdModulesNotifier,
+            MASTER(legacySimulatorData->cr), legacySimulatorData->observablesHistory,
+            legacySimulatorData->startingBehavior, simulationsShareState);
 }
 
 ModularSimulatorAlgorithm ModularSimulatorAlgorithmBuilder::build()