Make EnergyOutput wrapper class
authorMark Abraham <mark.j.abraham@gmail.com>
Wed, 6 Feb 2019 09:35:55 +0000 (10:35 +0100)
committerChristian Blau <cblau@gwdg.de>
Wed, 13 Feb 2019 12:17:12 +0000 (13:17 +0100)
Eventually we want a proper class for the energy accumulation and
output behaviours. In the meantime, this hides much about t_mdebin and
t_ebin from integrators, so that we can refactor with minimal
disruption to other work.

Made t_mdebin private to the new EnergyOutput implementation file.
Used bool rather than gmx_bool in the interface of EnergyOutput.
Noted several TODOs for improvements to code structure.

Removed dependency on ebin.h and enxio.h from the new header, so
various other places had to declare their own dependencies.

Change-Id: If09b2c82dd8c139c76cb5fc453d556c26a5eee89

29 files changed:
src/gromacs/gmxana/gmx_bar.cpp
src/gromacs/gmxana/gmx_enemat.cpp
src/gromacs/gmxana/gmx_energy.cpp
src/gromacs/gmxana/gmx_nmr.cpp
src/gromacs/imd/imd.cpp
src/gromacs/mdlib/coupling.cpp
src/gromacs/mdlib/ebin.h
src/gromacs/mdlib/energyoutput.cpp [moved from src/gromacs/mdlib/mdebin.cpp with 91% similarity]
src/gromacs/mdlib/energyoutput.h [new file with mode: 0644]
src/gromacs/mdlib/md_support.cpp
src/gromacs/mdlib/mdebin.h [deleted file]
src/gromacs/mdlib/mdebin_bar.cpp
src/gromacs/mdlib/mdebin_bar.h
src/gromacs/mdlib/shellfc.cpp
src/gromacs/mdlib/sim_util.cpp
src/gromacs/mdlib/sim_util.h
src/gromacs/mdlib/stat.cpp
src/gromacs/mdlib/tests/CMakeLists.txt
src/gromacs/mdlib/tests/energyoutput.cpp [moved from src/gromacs/mdlib/tests/mdebin.cpp with 67% similarity]
src/gromacs/mdlib/tests/refdata/EnergyOutputTest_HandlesEmptyAverages.xml [moved from src/gromacs/mdlib/tests/refdata/MdebinTest_HandlesEmptyAverages.xml with 100% similarity]
src/gromacs/mdlib/tests/refdata/EnergyOutputTest_HandlesSingleStep.xml [moved from src/gromacs/mdlib/tests/refdata/MdebinTest_HandlesSingleStep.xml with 100% similarity]
src/gromacs/mdlib/tests/refdata/EnergyOutputTest_HandlesTwoSteps.xml [moved from src/gromacs/mdlib/tests/refdata/MdebinTest_HandlesTwoSteps.xml with 100% similarity]
src/gromacs/mdlib/trajectory_writing.cpp
src/gromacs/mdlib/trajectory_writing.h
src/gromacs/mdrun/md.cpp
src/gromacs/mdrun/mimic.cpp
src/gromacs/mdrun/minimize.cpp
src/gromacs/mdrun/rerun.cpp
src/gromacs/mdrun/tpi.cpp

index 446d2655225aa68d3cc40052f1036c4b8d07e004..602af7d282a185a117ddd165c4d7194270c63482 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010,2011,2012,2013,2014,2015,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,2017,2018,2019, 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.
@@ -49,8 +49,9 @@
 #include "gromacs/gmxana/gmx_ana.h"
 #include "gromacs/math/units.h"
 #include "gromacs/math/utilities.h"
-#include "gromacs/mdlib/mdebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 #include "gromacs/mdtypes/md_enums.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/dir_separator.h"
index 98083e5fc526d220898854ce757c651e2355ba84..cbf6f9d04d5b16c3e4de3cffa36b5fd0f422476a 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, 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.
@@ -49,7 +49,7 @@
 #include "gromacs/math/functions.h"
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
-#include "gromacs/mdlib/mdebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 #include "gromacs/mdtypes/enerdata.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/trajectory/energyframe.h"
index 03312ef4825b056170bad89798be34ed73696b08..120173df319e88827c8652122f785dd890f102b6 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, 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.
@@ -55,7 +55,7 @@
 #include "gromacs/math/functions.h"
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
-#include "gromacs/mdlib/mdebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/topology/ifunc.h"
index 36035cf6801d0163553eb15ca848c24fb49426a7..929a1d994a36f7ac4b8bfe9450f2b9ca44ca9ee1 100644 (file)
 #include "gromacs/math/functions.h"
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
-#include "gromacs/mdlib/mdebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/topology/ifunc.h"
 #include "gromacs/topology/mtop_lookup.h"
 #include "gromacs/topology/mtop_util.h"
 #include "gromacs/topology/topology.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/trajectoryanalysis/topologyinformation.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/cstringutil.h"
index 22e56153614de1ef2ea49eb6af3b68b8a3e3ee3e..ce4e7bc0cc6d2fa71a50d1f5e6cc69cb677bf6ea 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2016,2017,2018,2019, 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.
@@ -75,6 +75,7 @@
 #include "gromacs/mdlib/mdrun.h"
 #include "gromacs/mdlib/sighandler.h"
 #include "gromacs/mdlib/sim_util.h"
+#include "gromacs/mdtypes/enerdata.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/mdtypes/state.h"
index 1112359096193a8322d62924558a1d7596bf325d..35125482ec9a7f515b472d92d040647c3fab887c 100644 (file)
@@ -53,6 +53,7 @@
 #include "gromacs/mdlib/sim_util.h"
 #include "gromacs/mdlib/update.h"
 #include "gromacs/mdtypes/commrec.h"
+#include "gromacs/mdtypes/enerdata.h"
 #include "gromacs/mdtypes/group.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
index e843438bf945e386349a960b1e7f3e0ff8c47190..f2456e2e308ae1a7c013229d6ab4f05a88972c02 100644 (file)
@@ -45,7 +45,8 @@
 #include "gromacs/utility/basedefinitions.h"
 
 /* This is a running averaging structure ('energy bin') for use during mdrun. */
-typedef struct {
+struct t_ebin
+{
     int             nener;
     gmx_enxnm_t    *enm;
     int64_t         nsteps;
@@ -54,7 +55,7 @@ typedef struct {
     int64_t         nsteps_sim;
     int64_t         nsum_sim;
     t_energy       *e_sim;
-} t_ebin;
+};
 
 enum {
     eprNORMAL, eprAVER, eprRMS, eprNR
similarity index 91%
rename from src/gromacs/mdlib/mdebin.cpp
rename to src/gromacs/mdlib/energyoutput.cpp
index 4070597090d8414e3edfd90adcedf88c4f896baa..b2f55c715855f168ebe02618f92ba24044ebc497 100644 (file)
@@ -36,7 +36,7 @@
  */
 #include "gmxpre.h"
 
-#include "mdebin.h"
+#include "energyoutput.h"
 
 #include <cfloat>
 #include <cstdlib>
@@ -55,6 +55,7 @@
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdlib/constr.h"
+#include "gromacs/mdlib/ebin.h"
 #include "gromacs/mdlib/mdebin_bar.h"
 #include "gromacs/mdlib/mdrun.h"
 #include "gromacs/mdtypes/energyhistory.h"
@@ -102,6 +103,62 @@ const char *egrp_nm[egNR+1] = {
     "Coul-14", "LJ-14", nullptr
 };
 
+/* forward declaration */
+typedef struct t_mde_delta_h_coll t_mde_delta_h_coll;
+
+namespace gmx
+{
+
+namespace detail
+{
+
+/* This is the collection of energy averages collected during mdrun, and to
+   be written out to the .edr file. */
+struct t_mdebin
+{
+    double              delta_t;
+    t_ebin             *ebin;
+    int                 ie, iconrmsd, ib, ivol, idens, ipv, ienthalpy;
+    int                 isvir, ifvir, ipres, ivir, isurft, ipc, itemp, itc, itcb, iu, imu;
+    int                 ivcos, ivisc;
+    int                 nE, nEg, nEc, nTC, nTCP, nU, nNHC;
+    int                *igrp;
+    int                 mde_n, mdeb_n;
+    real               *tmp_r;
+    rvec               *tmp_v;
+    gmx_bool            bConstr;
+    gmx_bool            bConstrVir;
+    gmx_bool            bTricl;
+    gmx_bool            bDynBox;
+    gmx_bool            bNHC_trotter;
+    gmx_bool            bPrintNHChains;
+    gmx_bool            bMTTK;
+    gmx_bool            bMu; /* true if dipole is calculated */
+    gmx_bool            bDiagPres;
+    gmx_bool            bPres;
+    int                 f_nre;
+    int                 epc;
+    real                ref_p;
+    int                 etc;
+    int                 nCrmsd;
+    gmx_bool            bEner[F_NRE];
+    gmx_bool            bEInd[egNR];
+    char              **print_grpnms;
+
+    FILE               *fp_dhdl; /* the dhdl.xvg output file */
+    double             *dE;      /* energy components for dhdl.xvg output */
+    t_mde_delta_h_coll *dhc;     /* the delta U components (raw data + histogram) */
+    real               *temperatures;
+};
+
+}   // namespace detail
+
+using detail::t_mdebin;
+
+namespace
+{
+
+//! Legacy init function
 t_mdebin *init_mdebin(ener_file_t       fp_ene,
                       const gmx_mtop_t *mtop,
                       const t_inputrec *ir,
@@ -612,6 +669,7 @@ t_mdebin *init_mdebin(ener_file_t       fp_ene,
     return md;
 }
 
+//! Legacy cleanup function
 void done_mdebin(t_mdebin *mdebin)
 {
     sfree(mdebin->igrp);
@@ -624,6 +682,9 @@ void done_mdebin(t_mdebin *mdebin)
     sfree(mdebin);
 }
 
+} // namespace
+} // namespace gmx
+
 /* print a lambda vector to a string
    fep = the inputrec's FEP input data
    i = the index of the lambda vector
@@ -683,9 +744,8 @@ static void print_lambda_vector(t_lambda *fep, int i,
     }
 }
 
-
-extern FILE *open_dhdl(const char *filename, const t_inputrec *ir,
-                       const gmx_output_env_t *oenv)
+FILE *open_dhdl(const char *filename, const t_inputrec *ir,
+                const gmx_output_env_t *oenv)
 {
     FILE       *fp;
     const char *dhdl = "dH/d\\lambda", *deltag = "\\DeltaH", *lambda = "\\lambda",
@@ -890,6 +950,12 @@ extern FILE *open_dhdl(const char *filename, const t_inputrec *ir,
     return fp;
 }
 
+namespace gmx
+{
+namespace
+{
+
+//! Legacy update function
 void upd_mdebin(t_mdebin               *md,
                 gmx_bool                bDoDHDL,
                 gmx_bool                bSum,
@@ -1191,13 +1257,18 @@ void upd_mdebin(t_mdebin               *md,
     }
 }
 
+}   // namespace
 
-void upd_mdebin_step(t_mdebin *md)
+void EnergyOutput::recordNonEnergyStep()
 {
-    ebin_increase_count(md->ebin, FALSE);
+    ebin_increase_count(mdebin->ebin, false);
 }
 
-static void npr(FILE *log, int n, char c)
+namespace
+{
+
+//! Legacy output function
+void npr(FILE *log, int n, char c)
 {
     for (; (n > 0); n--)
     {
@@ -1205,7 +1276,8 @@ static void npr(FILE *log, int n, char c)
     }
 }
 
-static void pprint(FILE *log, const char *s, t_mdebin *md)
+//! Legacy output function
+void pprint(FILE *log, const char *s, t_mdebin *md)
 {
     char CHAR = '#';
     int  slen;
@@ -1226,6 +1298,8 @@ static void pprint(FILE *log, const char *s, t_mdebin *md)
     fprintf(log, "\n");
 }
 
+}   // namespace
+
 void print_ebin_header(FILE *log, int64_t steps, double time)
 {
     char buf[22];
@@ -1235,8 +1309,12 @@ void print_ebin_header(FILE *log, int64_t steps, double time)
             "Step", "Time", gmx_step_str(steps, buf), time);
 }
 
+namespace
+{
+
 // TODO It is too many responsibilities for this function to handle
 // both .edr and .log output for both per-time and time-average data.
+//! Legacy ebin output function
 void print_ebin(ener_file_t fp_ene, gmx_bool bEne, gmx_bool bDR, gmx_bool bOR,
                 FILE *log,
                 int64_t step, double time,
@@ -1509,6 +1587,7 @@ void print_ebin(ener_file_t fp_ene, gmx_bool bEne, gmx_bool bDR, gmx_bool bOR,
 
 }
 
+//! Legacy update function
 void update_energyhistory(energyhistory_t * enerhist, const t_mdebin * mdebin)
 {
     const t_ebin * const ebin = mdebin->ebin;
@@ -1547,6 +1626,7 @@ void update_energyhistory(energyhistory_t * enerhist, const t_mdebin * mdebin)
     }
 }
 
+//! Legacy restore function
 void restore_energyhistory_from_state(t_mdebin              * mdebin,
                                       const energyhistory_t * enerhist)
 {
@@ -1580,3 +1660,79 @@ void restore_energyhistory_from_state(t_mdebin              * mdebin,
         mde_delta_h_coll_restore_energyhistory(mdebin->dhc, enerhist->deltaHForeignLambdas.get());
     }
 }
+
+}   // namespace
+
+EnergyOutput::EnergyOutput()
+    : mdebin(nullptr)
+{
+}
+
+void EnergyOutput::prepare(ener_file        *fp_ene,
+                           const gmx_mtop_t *mtop,
+                           const t_inputrec *ir,
+                           FILE             *fp_dhdl,
+                           bool              isRerun)
+{
+    mdebin = init_mdebin(fp_ene, mtop, ir, fp_dhdl, isRerun);
+}
+
+EnergyOutput::~EnergyOutput()
+{
+    done_mdebin(mdebin);
+}
+
+t_ebin *EnergyOutput::getEbin()
+{
+    return mdebin->ebin;
+}
+
+void EnergyOutput::addDataAtEnergyStep(bool                    bDoDHDL,
+                                       bool                    bSum,
+                                       double                  time,
+                                       real                    tmass,
+                                       gmx_enerdata_t         *enerd,
+                                       t_state                *state,
+                                       t_lambda               *fep,
+                                       t_expanded             *expand,
+                                       matrix                  box,
+                                       tensor                  svir,
+                                       tensor                  fvir,
+                                       tensor                  vir,
+                                       tensor                  pres,
+                                       gmx_ekindata_t         *ekind,
+                                       rvec                    mu_tot,
+                                       const gmx::Constraints *constr)
+{
+    upd_mdebin(mdebin, bDoDHDL, bSum, time, tmass, enerd, state, fep,
+               expand, box, svir, fvir, vir, pres, ekind, mu_tot, constr);
+}
+
+void EnergyOutput::printStepToEnergyFile(ener_file *fp_ene, bool bEne, bool bDR, bool bOR,
+                                         FILE *log,
+                                         int64_t step, double time,
+                                         int mode,
+                                         t_fcdata *fcd,
+                                         gmx_groups_t *groups, t_grpopts *opts,
+                                         gmx::Awh *awh)
+{
+    print_ebin(fp_ene, bEne, bDR, bOR, log, step, time, mode,
+               mdebin, fcd, groups, opts, awh);
+}
+
+int EnergyOutput::numEnergyTerms() const
+{
+    return mdebin->ebin->nener;
+}
+
+void EnergyOutput::fillEnergyHistory(energyhistory_t *enerhist) const
+{
+    update_energyhistory(enerhist, mdebin);
+}
+
+void EnergyOutput::restoreFromEnergyHistory(const energyhistory_t &enerhist)
+{
+    restore_energyhistory_from_state(mdebin, &enerhist);
+}
+
+} // namespace gmx
diff --git a/src/gromacs/mdlib/energyoutput.h b/src/gromacs/mdlib/energyoutput.h
new file mode 100644 (file)
index 0000000..7e70501
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, 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.
+ */
+#ifndef GMX_MDLIB_ENERGYOUTPUT_H
+#define GMX_MDLIB_ENERGYOUTPUT_H
+
+#include <cstdio>
+
+#include "gromacs/mdtypes/enerdata.h"
+
+class energyhistory_t;
+struct ener_file;
+struct gmx_ekindata_t;
+struct gmx_enerdata_t;
+struct gmx_groups_t;
+struct gmx_mtop_t;
+struct gmx_output_env_t;
+struct t_ebin;
+struct t_expanded;
+struct t_fcdata;
+struct t_grpopts;
+struct t_inputrec;
+struct t_lambda;
+class t_state;
+
+namespace gmx
+{
+class Awh;
+class Constraints;
+}
+
+extern const char *egrp_nm[egNR+1];
+
+/* delta_h block type enum: the kinds of energies written out. */
+enum
+{
+    dhbtDH   = 0, /* delta H BAR energy difference*/
+    dhbtDHDL = 1, /* dH/dlambda derivative */
+    dhbtEN,       /* System energy */
+    dhbtPV,       /* pV term */
+    dhbtEXPANDED, /* expanded ensemble statistics */
+    dhbtNR
+};
+
+namespace gmx
+{
+
+// TODO remove use of detail namespace when removing t_mdebin in
+// favour of an Impl class.
+namespace detail
+{
+struct t_mdebin;
+}
+
+/* The functions & data structures here determine the content for outputting
+   the .edr file; the file format and actual writing is done with functions
+   defined in enxio.h */
+
+class EnergyOutput
+{
+    public:
+        EnergyOutput();
+        /*! \brief Initiate MD energy bin
+         *
+         * This second phase of construction is needed until we have
+         * modules that understand how to request output from
+         * EnergyOutput.
+         *
+         * \todo Refactor to separate a function to write the energy
+         * file header. Perhaps transform the remainder into a factory
+         * function.
+         */
+        void prepare(ener_file        *fp_ene,
+                     const gmx_mtop_t *mtop,
+                     const t_inputrec *ir,
+                     FILE             *fp_dhdl,
+                     bool              isRerun = false);
+        ~EnergyOutput();
+        /*! \brief Update the averaging structures.
+         *
+         * Called every step on which the energies are evaluated. */
+        void addDataAtEnergyStep(bool                    bDoDHDL,
+                                 bool                    bSum,
+                                 double                  time,
+                                 real                    tmass,
+                                 gmx_enerdata_t         *enerd,
+                                 t_state                *state,
+                                 t_lambda               *fep,
+                                 t_expanded             *expand,
+                                 matrix                  lastbox,
+                                 tensor                  svir,
+                                 tensor                  fvir,
+                                 tensor                  vir,
+                                 tensor                  pres,
+                                 gmx_ekindata_t         *ekind,
+                                 rvec                    mu_tot,
+                                 const gmx::Constraints *constr);
+        /*! \brief Updated the averaging structures
+         *
+         * Called every step on which the energies are not evaluated.
+         *
+         * \todo This schedule is known in advance, and should be made
+         * an intrinsic behaviour of EnergyOutput, rather than being
+         * wastefully called every step. */
+        void recordNonEnergyStep();
+
+        /*! \brief Help write quantites to the energy file
+         *
+         * \todo Perhaps this responsibility should involve some other
+         * object visiting all the contributing objects. */
+        void printStepToEnergyFile(ener_file *fp_ene, bool bEne, bool bDR, bool bOR,
+                                   FILE *log,
+                                   int64_t step, double time,
+                                   int mode,
+                                   t_fcdata *fcd,
+                                   gmx_groups_t *groups, t_grpopts *opts,
+                                   gmx::Awh *awh);
+        /*! \brief Get the number of energy terms recorded.
+         *
+         * \todo Refactor this to return the expected output size,
+         * rather than exposing the implementation details about
+         * energy terms. */
+        int numEnergyTerms() const;
+        /*! \brief Getter used for testing t_ebin
+         *
+         * \todo Find a better approach for this. */
+        t_ebin *getEbin();
+
+        /* Between .edr writes, the averages are history dependent,
+           and that history needs to be retained in checkpoints.
+           These functions set/read the energyhistory_t class
+           that is written to checkpoints in checkpoint.c */
+
+        //! Fill the energyhistory_t data.
+        void fillEnergyHistory(energyhistory_t * enerhist) const;
+        //! Restore from energyhistory_t data.
+        void restoreFromEnergyHistory(const energyhistory_t &enerhist);
+
+    private:
+        // TODO transform this into an impl class.
+        detail::t_mdebin *mdebin = nullptr;
+};
+
+} // namespace gmx
+
+//! Open the dhdl file for output
+FILE *open_dhdl(const char *filename, const t_inputrec *ir,
+                const gmx_output_env_t *oenv);
+
+namespace gmx
+{
+
+//! Print an energy-output header to the log file
+void print_ebin_header(FILE *log, int64_t steps, double time);
+
+} // namespace gmx
+
+#endif
index f87fe607c78bb4a3e948d70e9fd10fdcae56a969..687f9ce0956e25de6cd2b59deed1ef91a2c5e9ac 100644 (file)
@@ -56,6 +56,7 @@
 #include "gromacs/mdlib/vcm.h"
 #include "gromacs/mdtypes/commrec.h"
 #include "gromacs/mdtypes/df_history.h"
+#include "gromacs/mdtypes/enerdata.h"
 #include "gromacs/mdtypes/energyhistory.h"
 #include "gromacs/mdtypes/forcerec.h"
 #include "gromacs/mdtypes/group.h"
diff --git a/src/gromacs/mdlib/mdebin.h b/src/gromacs/mdlib/mdebin.h
deleted file mode 100644 (file)
index f5712bc..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
- */
-#ifndef GMX_MDLIB_MDEBIN_H
-#define GMX_MDLIB_MDEBIN_H
-
-#include <stdio.h>
-
-#include "gromacs/fileio/enxio.h"
-#include "gromacs/mdlib/ebin.h"
-#include "gromacs/mdtypes/enerdata.h"
-
-class energyhistory_t;
-struct gmx_ekindata_t;
-struct gmx_enerdata_t;
-struct gmx_mtop_t;
-struct gmx_output_env_t;
-struct t_expanded;
-struct t_fcdata;
-struct t_grpopts;
-struct t_lambda;
-class t_state;
-
-namespace gmx
-{
-class Awh;
-class Constraints;
-}
-
-extern const char *egrp_nm[egNR+1];
-
-/* The functions & data structures here determine the content for outputting
-   the .edr file; the file format and actual writing is done with functions
-   defined in enxio.h */
-
-/* forward declaration */
-typedef struct t_mde_delta_h_coll t_mde_delta_h_coll;
-
-
-/* This is the collection of energy averages collected during mdrun, and to
-   be written out to the .edr file. */
-typedef struct t_mdebin {
-    double              delta_t;
-    t_ebin             *ebin;
-    int                 ie, iconrmsd, ib, ivol, idens, ipv, ienthalpy;
-    int                 isvir, ifvir, ipres, ivir, isurft, ipc, itemp, itc, itcb, iu, imu;
-    int                 ivcos, ivisc;
-    int                 nE, nEg, nEc, nTC, nTCP, nU, nNHC;
-    int                *igrp;
-    int                 mde_n, mdeb_n;
-    real               *tmp_r;
-    rvec               *tmp_v;
-    gmx_bool            bConstr;
-    gmx_bool            bConstrVir;
-    gmx_bool            bTricl;
-    gmx_bool            bDynBox;
-    gmx_bool            bNHC_trotter;
-    gmx_bool            bPrintNHChains;
-    gmx_bool            bMTTK;
-    gmx_bool            bMu; /* true if dipole is calculated */
-    gmx_bool            bDiagPres;
-    gmx_bool            bPres;
-    int                 f_nre;
-    int                 epc;
-    real                ref_p;
-    int                 etc;
-    int                 nCrmsd;
-    gmx_bool            bEner[F_NRE];
-    gmx_bool            bEInd[egNR];
-    char              **print_grpnms;
-
-    FILE               *fp_dhdl; /* the dhdl.xvg output file */
-    double             *dE;      /* energy components for dhdl.xvg output */
-    t_mde_delta_h_coll *dhc;     /* the delta U components (raw data + histogram) */
-    real               *temperatures;
-} t_mdebin;
-
-
-/* delta_h block type enum: the kinds of energies written out. */
-enum
-{
-    dhbtDH   = 0, /* delta H BAR energy difference*/
-    dhbtDHDL = 1, /* dH/dlambda derivative */
-    dhbtEN,       /* System energy */
-    dhbtPV,       /* pV term */
-    dhbtEXPANDED, /* expanded ensemble statistics */
-    dhbtNR
-};
-
-
-
-t_mdebin *init_mdebin(ener_file_t       fp_ene,
-                      const gmx_mtop_t *mtop,
-                      const t_inputrec *ir,
-                      FILE             *fp_dhdl,
-                      bool              isRerun = false);
-/* Initiate MD energy bin and write header to energy file. */
-
-//! Destroy mdebin
-void done_mdebin(t_mdebin *mdebin);
-
-FILE *open_dhdl(const char *filename, const t_inputrec *ir,
-                const gmx_output_env_t *oenv);
-/* Open the dhdl file for output */
-
-/* update the averaging structures. Called every time
-   the energies are evaluated. */
-void upd_mdebin(t_mdebin                 *md,
-                gmx_bool                  bDoDHDL,
-                gmx_bool                  bSum,
-                double                    time,
-                real                      tmass,
-                gmx_enerdata_t           *enerd,
-                t_state                  *state,
-                t_lambda                 *fep,
-                t_expanded               *expand,
-                matrix                    lastbox,
-                tensor                    svir,
-                tensor                    fvir,
-                tensor                    vir,
-                tensor                    pres,
-                gmx_ekindata_t           *ekind,
-                rvec                      mu_tot,
-                const gmx::Constraints   *constr);
-
-void upd_mdebin_step(t_mdebin *md);
-/* Updates only the step count in md */
-
-void print_ebin_header(FILE *log, int64_t steps, double time);
-
-void print_ebin(ener_file_t fp_ene, gmx_bool bEne, gmx_bool bDR, gmx_bool bOR,
-                FILE *log,
-                int64_t step, double time,
-                int mode,
-                t_mdebin *md, t_fcdata *fcd,
-                gmx_groups_t *groups, t_grpopts *opts,
-                gmx::Awh *awh);
-
-
-
-/* Between .edr writes, the averages are history dependent,
-   and that history needs to be retained in checkpoints.
-   These functions set/read the energyhistory_t class
-   that is written to checkpoints in checkpoint.c */
-
-/* Set the energyhistory_t data from a mdebin structure */
-void update_energyhistory(energyhistory_t * enerhist, const t_mdebin * mdebin);
-
-/* Read the energyhistory_t data to a mdebin structure*/
-void restore_energyhistory_from_state(t_mdebin              * mdebin,
-                                      const energyhistory_t * enerhist);
-
-#endif
index 4b33f86bb6f9a4286ceacaa833d879e88a41469f..f733ae2ab059bd56b3d88bfd8f18b4efa1d7631b 100644 (file)
 #include <memory>
 
 #include "gromacs/fileio/enxio.h"
-#include "gromacs/mdlib/mdebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 #include "gromacs/mdtypes/energyhistory.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
+#include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/smalloc.h"
index db42ac1bd2e79ff1da094e2b48d3c0f19411b597..e7ce32b6f3f104a084e89c0f98d87f1683ecae72 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, 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.
 #ifndef _mdebin_bar_h
 #define _mdebin_bar_h
 
-#include "gromacs/mdlib/mdebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 
 /* The functions & data structures here describe writing
    energy differences (or their histogram )for use with g_bar */
 
 class delta_h_history_t;
+struct t_enxframe;
 
 /* Data for one foreign lambda, or derivative. */
 typedef struct
index 1f81d786fda37d4253eaeba14160a5488281e2e8..2f99a517483135c1ac0e9462b28807d575787b6d 100644 (file)
@@ -62,6 +62,7 @@
 #include "gromacs/mdlib/sim_util.h"
 #include "gromacs/mdlib/vsite.h"
 #include "gromacs/mdtypes/commrec.h"
+#include "gromacs/mdtypes/enerdata.h"
 #include "gromacs/mdtypes/forcerec.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
index 5e3656bd0caf8109a865b48f1f3e0044e15c94e3..4b624481469db67014899518189d8d096edcbee3 100644 (file)
@@ -88,6 +88,7 @@
 #include "gromacs/mdlib/update.h"
 #include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_gpu_ref.h"
 #include "gromacs/mdtypes/commrec.h"
+#include "gromacs/mdtypes/enerdata.h"
 #include "gromacs/mdtypes/forceoutput.h"
 #include "gromacs/mdtypes/iforceprovider.h"
 #include "gromacs/mdtypes/inputrec.h"
index e15ce631b549a1aaa798bfb3b1435bd4245e2a5d..a9804bcdbc5f204ab027adcfdf18c9fb29bde631 100644 (file)
 #define GMX_MDLIB_SIM_UTIL_H
 
 #include "gromacs/fileio/enxio.h"
-#include "gromacs/mdlib/mdebin.h"
 #include "gromacs/mdlib/mdoutf.h"
 #include "gromacs/mdlib/vcm.h"
 #include "gromacs/timing/wallcycle.h"
 #include "gromacs/timing/walltime_accounting.h"
 #include "gromacs/utility/arrayref.h"
 
+struct gmx_ekindata_t;
+struct gmx_enerdata_t;
 struct gmx_output_env_t;
 struct gmx_pme_t;
 struct MdrunOptions;
@@ -57,6 +58,7 @@ namespace gmx
 {
 class BoxDeformation;
 class Constraints;
+class EnergyOutput;
 class IMDOutputProvider;
 class MDLogger;
 class Update;
index a2159835c78994c8f3cee061a18d9cc1ecfd0281..b45431c9f04c78fa1e0f3f741a01ab0f1fdad6cc 100644 (file)
@@ -54,6 +54,7 @@
 #include "gromacs/mdlib/tgroup.h"
 #include "gromacs/mdlib/vcm.h"
 #include "gromacs/mdtypes/commrec.h"
+#include "gromacs/mdtypes/enerdata.h"
 #include "gromacs/mdtypes/group.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
index 82126d980495545fb8a2b158b734f06bf41913ad..a688d0939a3c776f9c37ffc908a79628c673f8a1 100644 (file)
@@ -36,7 +36,7 @@ gmx_add_unit_test(MdlibUnitTest mdlib-test
                   calc_verletbuf.cpp
                   constr.cpp
                   ebin.cpp
-                  mdebin.cpp
+                  energyoutput.cpp
                   settle.cpp
                   shake.cpp
                   simulationsignal.cpp
similarity index 67%
rename from src/gromacs/mdlib/tests/mdebin.cpp
rename to src/gromacs/mdlib/tests/energyoutput.cpp
index 6613ec44d230195bef662e269a6cfe984a7bd1d5..3ccf7ea9eb40e45bc4ee4cef8bbab59790217048 100644 (file)
@@ -34,7 +34,7 @@
  */
 #include "gmxpre.h"
 
-#include "gromacs/mdlib/mdebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 
 #include <cstdio>
 
@@ -65,16 +65,15 @@ void fcloseWrapper(FILE *fp)
     fclose(fp);
 }
 
-class MdebinTest : public ::testing::Test
+class EnergyOutputTest : public ::testing::Test
 {
     public:
         TestFileManager fileManager_;
 
-        // Objects needed to make t_mdebin
+        // Objects needed to make EnergyOutput
         t_inputrec   inputrec_;
         gmx_mtop_t   mtop_;
-        t_mdebin    *mdebin_;
-        unique_cptr<t_mdebin, done_mdebin> mdebinGuard_;
+        EnergyOutput energyOutput_;
 
         // Objects needed for default energy output behavior.
         t_mdatoms                    mdatoms_;
@@ -94,13 +93,12 @@ class MdebinTest : public ::testing::Test
         TestReferenceData                refData_;
         TestReferenceChecker             checker_;
 
-        MdebinTest() :
+        EnergyOutputTest() :
             logFilename_(fileManager_.getTemporaryFilePath(".log")),
             log_(std::fopen(logFilename_.c_str(), "w")), logFileGuard_(log_),
             checker_(refData_.rootChecker())
         {
-            mdebin_ = init_mdebin(nullptr, &mtop_, &inputrec_, nullptr, false);
-            mdebinGuard_.reset(mdebin_);
+            energyOutput_.prepare(nullptr, &mtop_, &inputrec_, nullptr, false);
             constraints_ = makeConstraints(mtop_, inputrec_, false, log_, mdatoms_, nullptr,
                                            nullptr, nullptr, nullptr, false);
         }
@@ -136,27 +134,27 @@ class MdebinTest : public ::testing::Test
 
 };
 
-TEST_F(MdebinTest, HandlesEmptyAverages)
+TEST_F(EnergyOutputTest, HandlesEmptyAverages)
 {
     ASSERT_NE(log_, nullptr);
 
     // Test printing values
-    print_ebin(nullptr, false, false, false, log_,
-               0, 0, eprNORMAL, mdebin_,
-               nullptr, nullptr, nullptr, nullptr);
+    energyOutput_.printStepToEnergyFile(nullptr, false, false, false, log_,
+                                        0, 0, eprNORMAL,
+                                        nullptr, nullptr, nullptr, nullptr);
     // Test printing averages
-    print_ebin(nullptr, false, false, false, log_,
-               0, 0, eprAVER, mdebin_,
-               nullptr, nullptr, nullptr, nullptr);
+    energyOutput_.printStepToEnergyFile(nullptr, false, false, false, log_,
+                                        0, 0, eprAVER,
+                                        nullptr, nullptr, nullptr, nullptr);
 
     // We need to close the file before the contents are available.
     logFileGuard_.reset(nullptr);
 
-    checker_.checkInteger(mdebin_->ebin->nener, "Number of Energy Terms");
+    checker_.checkInteger(energyOutput_.numEnergyTerms(), "Number of Energy Terms");
     checker_.checkString(TextReader::readFileToString(logFilename_), "log");
 }
 
-TEST_F(MdebinTest, HandlesSingleStep)
+TEST_F(EnergyOutputTest, HandlesSingleStep)
 {
     ASSERT_NE(log_, nullptr);
 
@@ -164,29 +162,29 @@ TEST_F(MdebinTest, HandlesSingleStep)
     real time      = 1.0;
     real testValue = 1.0;
     setStepData(testValue);
-    upd_mdebin(mdebin_, false, true, time, 0.0, &enerdata_,
-               nullptr, nullptr, nullptr, box_,
-               nullptr, nullptr, totalVirial_, pressure_,
-               nullptr, nullptr, constraints_.get());
+    energyOutput_.addDataAtEnergyStep(false, true, time, 0.0, &enerdata_,
+                                      nullptr, nullptr, nullptr, box_,
+                                      nullptr, nullptr, totalVirial_, pressure_,
+                                      nullptr, nullptr, constraints_.get());
 
     // Test printing values
-    print_ebin(nullptr, false, false, false, log_,
-               0, 0, eprNORMAL, mdebin_,
-               nullptr, nullptr, nullptr, nullptr);
+    energyOutput_.printStepToEnergyFile(nullptr, false, false, false, log_,
+                                        0, 0, eprNORMAL,
+                                        nullptr, nullptr, nullptr, nullptr);
 
     // Test printing averages
-    print_ebin(nullptr, false, false, false, log_,
-               0, 0, eprAVER, mdebin_,
-               nullptr, nullptr, nullptr, nullptr);
+    energyOutput_.printStepToEnergyFile(nullptr, false, false, false, log_,
+                                        0, 0, eprAVER,
+                                        nullptr, nullptr, nullptr, nullptr);
 
     // We need to close the file before the contents are available.
     logFileGuard_.reset(nullptr);
 
-    checker_.checkInteger(mdebin_->ebin->nener, "Number of Energy Terms");
+    checker_.checkInteger(energyOutput_.numEnergyTerms(), "Number of Energy Terms");
     checker_.checkString(TextReader::readFileToString(logFilename_), "log");
 }
 
-TEST_F(MdebinTest, HandlesTwoSteps)
+TEST_F(EnergyOutputTest, HandlesTwoSteps)
 {
     ASSERT_NE(log_, nullptr);
 
@@ -194,38 +192,38 @@ TEST_F(MdebinTest, HandlesTwoSteps)
     real time      = 1.0;
     real testValue = 1.0;
     setStepData(testValue);
-    upd_mdebin(mdebin_, false, true, time, 0.0, &enerdata_,
-               nullptr, nullptr, nullptr, box_,
-               nullptr, nullptr, totalVirial_, pressure_,
-               nullptr, nullptr, constraints_.get());
+    energyOutput_.addDataAtEnergyStep(false, true, time, 0.0, &enerdata_,
+                                      nullptr, nullptr, nullptr, box_,
+                                      nullptr, nullptr, totalVirial_, pressure_,
+                                      nullptr, nullptr, constraints_.get());
 
     // Test printing values
-    print_ebin(nullptr, false, false, false, log_,
-               0, 0, eprNORMAL, mdebin_,
-               nullptr, nullptr, nullptr, nullptr);
+    energyOutput_.printStepToEnergyFile(nullptr, false, false, false, log_,
+                                        0, 0, eprNORMAL,
+                                        nullptr, nullptr, nullptr, nullptr);
 
     // Add synthetic data for the second step
     time += 0.005;
     setStepData(testValue += 1.0);
-    upd_mdebin(mdebin_, false, true, time, 0.0, &enerdata_,
-               nullptr, nullptr, nullptr, box_,
-               nullptr, nullptr, totalVirial_, pressure_,
-               nullptr, nullptr, constraints_.get());
+    energyOutput_.addDataAtEnergyStep(false, true, time, 0.0, &enerdata_,
+                                      nullptr, nullptr, nullptr, box_,
+                                      nullptr, nullptr, totalVirial_, pressure_,
+                                      nullptr, nullptr, constraints_.get());
 
     // Test printing values
-    print_ebin(nullptr, false, false, false, log_,
-               0, 0, eprNORMAL, mdebin_,
-               nullptr, nullptr, nullptr, nullptr);
+    energyOutput_.printStepToEnergyFile(nullptr, false, false, false, log_,
+                                        0, 0, eprNORMAL,
+                                        nullptr, nullptr, nullptr, nullptr);
 
     // Test printing averages
-    print_ebin(nullptr, false, false, false, log_,
-               0, 0, eprAVER, mdebin_,
-               nullptr, nullptr, nullptr, nullptr);
+    energyOutput_.printStepToEnergyFile(nullptr, false, false, false, log_,
+                                        0, 0, eprAVER,
+                                        nullptr, nullptr, nullptr, nullptr);
 
     // We need to close the file before the contents are available.
     logFileGuard_.reset(nullptr);
 
-    checker_.checkInteger(mdebin_->ebin->nener, "Number of Energy Terms");
+    checker_.checkInteger(energyOutput_.numEnergyTerms(), "Number of Energy Terms");
     checker_.checkString(TextReader::readFileToString(logFilename_), "log");
 }
 
index 4be47bc774dcb748cd210d51817f331c379a66f0..79f5861725437dce3da5018c62a42666f5a546fd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, 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.
 #include "gromacs/utility/smalloc.h"
 
 void
-do_md_trajectory_writing(FILE                    *fplog,
-                         t_commrec               *cr,
-                         int                      nfile,
-                         const t_filenm           fnm[],
-                         int64_t                  step,
-                         int64_t                  step_rel,
-                         double                   t,
-                         t_inputrec              *ir,
-                         t_state                 *state,
-                         t_state                 *state_global,
-                         ObservablesHistory      *observablesHistory,
-                         gmx_mtop_t              *top_global,
-                         t_forcerec              *fr,
-                         gmx_mdoutf_t             outf,
-                         t_mdebin                *mdebin,
-                         gmx_ekindata_t          *ekind,
-                         gmx::ArrayRef<gmx::RVec> f,
-                         gmx_bool                 bCPT,
-                         gmx_bool                 bRerunMD,
-                         gmx_bool                 bLastStep,
-                         gmx_bool                 bDoConfOut,
-                         gmx_bool                 bSumEkinhOld
+do_md_trajectory_writing(FILE                     *fplog,
+                         t_commrec                *cr,
+                         int                       nfile,
+                         const t_filenm            fnm[],
+                         int64_t                   step,
+                         int64_t                   step_rel,
+                         double                    t,
+                         t_inputrec               *ir,
+                         t_state                  *state,
+                         t_state                  *state_global,
+                         ObservablesHistory       *observablesHistory,
+                         gmx_mtop_t               *top_global,
+                         t_forcerec               *fr,
+                         gmx_mdoutf_t              outf,
+                         const gmx::EnergyOutput  &energyOutput,
+                         gmx_ekindata_t           *ekind,
+                         gmx::ArrayRef<gmx::RVec>  f,
+                         gmx_bool                  bCPT,
+                         gmx_bool                  bRerunMD,
+                         gmx_bool                  bLastStep,
+                         gmx_bool                  bDoConfOut,
+                         gmx_bool                  bSumEkinhOld
                          )
 {
     int   mdof_flags;
@@ -158,7 +158,7 @@ do_md_trajectory_writing(FILE                    *fplog,
                     state_global->ekinstate.bUpToDate = TRUE;
                 }
 
-                update_energyhistory(observablesHistory->energyHistory.get(), mdebin);
+                energyOutput.fillEnergyHistory(observablesHistory->energyHistory.get());
             }
         }
         mdoutf_write_to_trajectory_files(fplog, cr, outf, mdof_flags, top_global,
index 20e1c5af16685356ca0f5c3013b96581e16aef6c..95157b53f4f62b7c6c20049b91f3ccdac49a3646 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, 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.
@@ -39,7 +39,7 @@
 
 #include <stdio.h>
 
-#include "gromacs/mdlib/mdebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 #include "gromacs/mdlib/mdoutf.h"
 #include "gromacs/timing/wallcycle.h"
 
@@ -50,6 +50,11 @@ struct t_commrec;
 struct t_filenm;
 struct t_forcerec;
 
+namespace gmx
+{
+class EnergyOutput;
+}
+
 /*! \brief Wrapper routine for writing trajectories during mdrun
  *
  * This routine does communication (e.g. collecting distributed coordinates)
@@ -69,8 +74,8 @@ do_md_trajectory_writing(FILE                     *fplog,
                          struct gmx_mtop_t        *top_global,
                          t_forcerec               *fr,
                          gmx_mdoutf_t              outf,
-                         t_mdebin                 *mdebin,
-                         struct gmx_ekindata_t    *ekind,
+                         const gmx::EnergyOutput  &energyOutput,
+                         gmx_ekindata_t           *ekind,
                          gmx::ArrayRef<gmx::RVec>  f,
                          gmx_bool                  bCPT,
                          gmx_bool                  bRerunMD,
index 8d38a7c068db9838e715cdccea0e0f0f79a923eb..cc93811fcddc40c71234200c582579009a4f7a01 100644 (file)
 #include "gromacs/mdlib/compute_io.h"
 #include "gromacs/mdlib/constr.h"
 #include "gromacs/mdlib/ebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 #include "gromacs/mdlib/expanded.h"
 #include "gromacs/mdlib/force.h"
 #include "gromacs/mdlib/force_flags.h"
 #include "gromacs/mdlib/forcerec.h"
 #include "gromacs/mdlib/md_support.h"
 #include "gromacs/mdlib/mdatoms.h"
-#include "gromacs/mdlib/mdebin.h"
 #include "gromacs/mdlib/mdoutf.h"
 #include "gromacs/mdlib/mdrun.h"
 #include "gromacs/mdlib/mdsetup.h"
@@ -253,10 +253,9 @@ void gmx::Integrator::do_md()
         pleaseCiteCouplingAlgorithms(fplog, *ir);
     }
     init_nrnb(nrnb);
-    gmx_mdoutf *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr,
-                                   outputProvider, ir, top_global, oenv, wcycle);
-    t_mdebin   *mdebin = init_mdebin(mdrunOptions.continuationOptions.appendFiles ? nullptr : mdoutf_get_fp_ene(outf),
-                                     top_global, ir, mdoutf_get_fp_dhdl(outf));
+    gmx_mdoutf       *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, ir, top_global, oenv, wcycle);
+    gmx::EnergyOutput energyOutput;
+    energyOutput.prepare(mdoutf_get_fp_ene(outf), top_global, ir, mdoutf_get_fp_dhdl(outf));
 
     /* Energy terms and groups */
     snew(enerd, 1);
@@ -278,7 +277,7 @@ void gmx::Integrator::do_md()
                                  ir->nstcalcenergy, DOMAINDECOMP(cr));
 
     {
-        double io = compute_io(ir, top_global->natoms, groups, mdebin->ebin->nener, 1);
+        double io = compute_io(ir, top_global->natoms, groups, energyOutput.numEnergyTerms(), 1);
         if ((io > 2000) && MASTER(cr))
         {
             fprintf(stderr,
@@ -353,7 +352,7 @@ void gmx::Integrator::do_md()
     {
         if (startingFromCheckpoint)
         {
-            /* Update mdebin with energy history if appending to output files */
+            /* Restore from energy history if appending to output files */
             if (continuationOptions.appendFiles)
             {
                 /* If no history is available (because a checkpoint is from before
@@ -361,7 +360,7 @@ void gmx::Integrator::do_md()
                  */
                 if (observablesHistory->energyHistory)
                 {
-                    restore_energyhistory_from_state(mdebin, observablesHistory->energyHistory.get());
+                    energyOutput.restoreFromEnergyHistory(*observablesHistory->energyHistory);
                 }
             }
             else if (observablesHistory->energyHistory)
@@ -387,8 +386,8 @@ void gmx::Integrator::do_md()
         {
             observablesHistory->pullHistory = std::make_unique<PullHistory>();
         }
-        /* Set the initial energy history in state by updating once */
-        update_energyhistory(observablesHistory->energyHistory.get(), mdebin);
+        /* Set the initial energy history */
+        energyOutput.fillEnergyHistory(observablesHistory->energyHistory.get());
     }
 
     preparePrevStepPullCom(ir, mdatoms, state, state_global, cr, startingFromCheckpoint);
@@ -1057,7 +1056,7 @@ void gmx::Integrator::do_md()
         do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t,
                                  ir, state, state_global, observablesHistory,
                                  top_global, fr,
-                                 outf, mdebin, ekind, f,
+                                 outf, energyOutput, ekind, f,
                                  checkpointHandler->isCheckpointingStep(),
                                  bRerunMD, bLastStep,
                                  mdrunOptions.writeConfout,
@@ -1351,23 +1350,24 @@ void gmx::Integrator::do_md()
             }
             if (bCalcEner)
             {
-                upd_mdebin(mdebin, bDoDHDL, bCalcEnerStep,
-                           t, mdatoms->tmass, enerd, state,
-                           ir->fepvals, ir->expandedvals, lastbox,
-                           shake_vir, force_vir, total_vir, pres,
-                           ekind, mu_tot, constr);
+                energyOutput.addDataAtEnergyStep(bDoDHDL, bCalcEnerStep,
+                                                 t, mdatoms->tmass, enerd, state,
+                                                 ir->fepvals, ir->expandedvals, lastbox,
+                                                 shake_vir, force_vir, total_vir, pres,
+                                                 ekind, mu_tot, constr);
             }
             else
             {
-                upd_mdebin_step(mdebin);
+                energyOutput.recordNonEnergyStep();
             }
 
             gmx_bool do_dr  = do_per_step(step, ir->nstdisreout);
             gmx_bool do_or  = do_per_step(step, ir->nstorireout);
 
-            print_ebin(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or, do_log ? fplog : nullptr,
-                       step, t,
-                       eprNORMAL, mdebin, fcd, groups, &(ir->opts), awh.get());
+            energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or,
+                                               do_log ? fplog : nullptr,
+                                               step, t,
+                                               eprNORMAL, fcd, groups, &(ir->opts), awh.get());
 
             if (ir->bPull)
             {
@@ -1501,11 +1501,11 @@ void gmx::Integrator::do_md()
     {
         if (ir->nstcalcenergy > 0)
         {
-            print_ebin(mdoutf_get_fp_ene(outf), FALSE, FALSE, FALSE, fplog, step, t,
-                       eprAVER, mdebin, fcd, groups, &(ir->opts), awh.get());
+            energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), FALSE, FALSE, FALSE,
+                                               fplog, step, t,
+                                               eprAVER, fcd, groups, &(ir->opts), awh.get());
         }
     }
-    done_mdebin(mdebin);
     done_mdoutf(outf);
 
     if (bPMETune)
index c77e5637a5899d30b04f6a306277a82ae5328c94..56c3e261da47296885a664ec5e464954204ed4dd 100644 (file)
 #include "gromacs/mdlib/compute_io.h"
 #include "gromacs/mdlib/constr.h"
 #include "gromacs/mdlib/ebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 #include "gromacs/mdlib/expanded.h"
 #include "gromacs/mdlib/force.h"
 #include "gromacs/mdlib/force_flags.h"
 #include "gromacs/mdlib/forcerec.h"
 #include "gromacs/mdlib/md_support.h"
 #include "gromacs/mdlib/mdatoms.h"
-#include "gromacs/mdlib/mdebin.h"
 #include "gromacs/mdlib/mdoutf.h"
 #include "gromacs/mdlib/mdrun.h"
 #include "gromacs/mdlib/mdsetup.h"
 #include "gromacs/mdtypes/awh_params.h"
 #include "gromacs/mdtypes/commrec.h"
 #include "gromacs/mdtypes/df_history.h"
+#include "gromacs/mdtypes/enerdata.h"
 #include "gromacs/mdtypes/energyhistory.h"
 #include "gromacs/mdtypes/fcdata.h"
 #include "gromacs/mdtypes/forcerec.h"
@@ -228,9 +229,9 @@ void gmx::Integrator::do_mimic()
     initialize_lambdas(fplog, *ir, MASTER(cr), &state_global->fep_state, state_global->lambda, lam0);
     init_nrnb(nrnb);
 
-    gmx_mdoutf *outf   = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, ir, top_global, oenv, wcycle);
-    t_mdebin   *mdebin = init_mdebin(mdrunOptions.continuationOptions.appendFiles ? nullptr : mdoutf_get_fp_ene(outf),
-                                     top_global, ir, mdoutf_get_fp_dhdl(outf), true);
+    gmx_mdoutf       *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, ir, top_global, oenv, wcycle);
+    gmx::EnergyOutput energyOutput;
+    energyOutput.prepare(mdoutf_get_fp_ene(outf), top_global, ir, mdoutf_get_fp_dhdl(outf), true);
 
     /* Energy terms and groups */
     snew(enerd, 1);
@@ -252,7 +253,7 @@ void gmx::Integrator::do_mimic()
                                  ir->nstcalcenergy, DOMAINDECOMP(cr));
 
     {
-        double io = compute_io(ir, top_global->natoms, groups, mdebin->ebin->nener, 1);
+        double io = compute_io(ir, top_global->natoms, groups, energyOutput.numEnergyTerms(), 1);
         if ((io > 2000) && MASTER(cr))
         {
             fprintf(stderr,
@@ -480,7 +481,7 @@ void gmx::Integrator::do_mimic()
             do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t,
                                      ir, state, state_global, observablesHistory,
                                      top_global, fr,
-                                     outf, mdebin, ekind, f,
+                                     outf, energyOutput, ekind, f,
                                      isCheckpointingStep, doRerun, isLastStep,
                                      mdrunOptions.writeConfout,
                                      bSumEkinhOld);
@@ -571,11 +572,11 @@ void gmx::Integrator::do_mimic()
         if (MASTER(cr))
         {
             const bool bCalcEnerStep = true;
-            upd_mdebin(mdebin, doFreeEnergyPerturbation, bCalcEnerStep,
-                       t, mdatoms->tmass, enerd, state,
-                       ir->fepvals, ir->expandedvals, state->box,
-                       shake_vir, force_vir, total_vir, pres,
-                       ekind, mu_tot, constr);
+            energyOutput.addDataAtEnergyStep(doFreeEnergyPerturbation, bCalcEnerStep,
+                                             t, mdatoms->tmass, enerd, state,
+                                             ir->fepvals, ir->expandedvals, state->box,
+                                             shake_vir, force_vir, total_vir, pres,
+                                             ekind, mu_tot, constr);
 
             const bool do_ene = true;
             const bool do_log = true;
@@ -583,9 +584,10 @@ void gmx::Integrator::do_mimic()
             const bool do_dr  = ir->nstdisreout != 0;
             const bool do_or  = ir->nstorireout != 0;
 
-            print_ebin(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or, do_log ? fplog : nullptr,
-                       step, t,
-                       eprNORMAL, mdebin, fcd, groups, &(ir->opts), awh);
+            energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or,
+                                               do_log ? fplog : nullptr,
+                                               step, t,
+                                               eprNORMAL, fcd, groups, &(ir->opts), awh);
 
             if (do_per_step(step, ir->nstlog))
             {
@@ -637,7 +639,6 @@ void gmx::Integrator::do_mimic()
         gmx_pme_send_finish(cr);
     }
 
-    done_mdebin(mdebin);
     done_mdoutf(outf);
 
     done_shellfc(fplog, shellfc, step_rel);
index 88a78f329aa41037000e4e11d9c02156aa5089ec..f3ba13faae6aa710d0efb08f9b2265d1125e9dac 100644 (file)
 #include "gromacs/math/functions.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdlib/constr.h"
+#include "gromacs/mdlib/ebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 #include "gromacs/mdlib/force.h"
 #include "gromacs/mdlib/forcerec.h"
 #include "gromacs/mdlib/gmx_omp_nthreads.h"
 #include "gromacs/mdlib/md_support.h"
 #include "gromacs/mdlib/mdatoms.h"
-#include "gromacs/mdlib/mdebin.h"
 #include "gromacs/mdlib/mdrun.h"
 #include "gromacs/mdlib/mdsetup.h"
 #include "gromacs/mdlib/ns.h"
@@ -1113,7 +1114,8 @@ Integrator::do_cg()
     gmx_mdoutf *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, inputrec, top_global, nullptr, wcycle);
     snew(enerd, 1);
     init_enerdata(top_global->groups.grps[egcENER].nr, inputrec->fepvals->n_lambda, enerd);
-    t_mdebin *mdebin = init_mdebin(mdoutf_get_fp_ene(outf), top_global, inputrec, nullptr);
+    gmx::EnergyOutput energyOutput;
+    energyOutput.prepare(mdoutf_get_fp_ene(outf), top_global, inputrec, nullptr);
 
     /* Print to log file */
     print_em_start(fplog, cr, walltime_accounting, wcycle, CG);
@@ -1147,13 +1149,14 @@ Integrator::do_cg()
     {
         /* Copy stuff to the energy bin for easy printing etc. */
         matrix nullBox = {};
-        upd_mdebin(mdebin, FALSE, FALSE, static_cast<double>(step),
-                   mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox,
-                   nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
+        energyOutput.addDataAtEnergyStep(false, false, static_cast<double>(step),
+                                         mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox,
+                                         nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
 
         print_ebin_header(fplog, step, step);
-        print_ebin(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, fplog, step, step, eprNORMAL,
-                   mdebin, fcd, &(top_global->groups), &(inputrec->opts), nullptr);
+        energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE,
+                                           fplog, step, step, eprNORMAL,
+                                           fcd, &(top_global->groups), &(inputrec->opts), nullptr);
     }
 
     /* Estimate/guess the initial stepsize */
@@ -1571,9 +1574,9 @@ Integrator::do_cg()
             }
             /* Store the new (lower) energies */
             matrix nullBox = {};
-            upd_mdebin(mdebin, FALSE, FALSE, static_cast<double>(step),
-                       mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox,
-                       nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
+            energyOutput.addDataAtEnergyStep(false, false, static_cast<double>(step),
+                                             mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox,
+                                             nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
 
             do_log = do_per_step(step, inputrec->nstlog);
             do_ene = do_per_step(step, inputrec->nstenergy);
@@ -1585,9 +1588,9 @@ Integrator::do_cg()
             {
                 print_ebin_header(fplog, step, step);
             }
-            print_ebin(mdoutf_get_fp_ene(outf), do_ene, FALSE, FALSE,
-                       do_log ? fplog : nullptr, step, step, eprNORMAL,
-                       mdebin, fcd, &(top_global->groups), &(inputrec->opts), nullptr);
+            energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, FALSE, FALSE,
+                                               do_log ? fplog : nullptr, step, step, eprNORMAL,
+                                               fcd, &(top_global->groups), &(inputrec->opts), nullptr);
         }
 
         /* Send energies and positions to the IMD client if bIMD is TRUE. */
@@ -1634,9 +1637,9 @@ Integrator::do_cg()
         if (!do_ene || !do_log)
         {
             /* Write final energy file entries */
-            print_ebin(mdoutf_get_fp_ene(outf), !do_ene, FALSE, FALSE,
-                       !do_log ? fplog : nullptr, step, step, eprNORMAL,
-                       mdebin, fcd, &(top_global->groups), &(inputrec->opts), nullptr);
+            energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), !do_ene, FALSE, FALSE,
+                                               !do_log ? fplog : nullptr, step, step, eprNORMAL,
+                                               fcd, &(top_global->groups), &(inputrec->opts), nullptr);
         }
     }
 
@@ -1755,7 +1758,8 @@ Integrator::do_lbfgs()
     gmx_mdoutf *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, inputrec, top_global, nullptr, wcycle);
     snew(enerd, 1);
     init_enerdata(top_global->groups.grps[egcENER].nr, inputrec->fepvals->n_lambda, enerd);
-    t_mdebin *mdebin = init_mdebin(mdoutf_get_fp_ene(outf), top_global, inputrec, nullptr);
+    gmx::EnergyOutput energyOutput;
+    energyOutput.prepare(mdoutf_get_fp_ene(outf), top_global, inputrec, nullptr);
 
     start = 0;
     end   = mdatoms->homenr;
@@ -1826,13 +1830,14 @@ Integrator::do_lbfgs()
     {
         /* Copy stuff to the energy bin for easy printing etc. */
         matrix nullBox = {};
-        upd_mdebin(mdebin, FALSE, FALSE, static_cast<double>(step),
-                   mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox,
-                   nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
+        energyOutput.addDataAtEnergyStep(false, false, static_cast<double>(step),
+                                         mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox,
+                                         nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
 
         print_ebin_header(fplog, step, step);
-        print_ebin(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE, fplog, step, step, eprNORMAL,
-                   mdebin, fcd, &(top_global->groups), &(inputrec->opts), nullptr);
+        energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE, FALSE, FALSE,
+                                           fplog, step, step, eprNORMAL,
+                                           fcd, &(top_global->groups), &(inputrec->opts), nullptr);
     }
 
     /* Set the initial step.
@@ -2313,18 +2318,23 @@ Integrator::do_lbfgs()
             }
             /* Store the new (lower) energies */
             matrix nullBox = {};
-            upd_mdebin(mdebin, FALSE, FALSE, static_cast<double>(step),
-                       mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox,
-                       nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
+            energyOutput.addDataAtEnergyStep(false, false, static_cast<double>(step),
+                                             mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox,
+                                             nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
+
             do_log = do_per_step(step, inputrec->nstlog);
             do_ene = do_per_step(step, inputrec->nstenergy);
+
+            /* Prepare IMD energy record, if bIMD is TRUE. */
+            IMD_fill_energy_record(inputrec->bIMD, inputrec->imd, enerd, step, TRUE);
+
             if (do_log)
             {
                 print_ebin_header(fplog, step, step);
             }
-            print_ebin(mdoutf_get_fp_ene(outf), do_ene, FALSE, FALSE,
-                       do_log ? fplog : nullptr, step, step, eprNORMAL,
-                       mdebin, fcd, &(top_global->groups), &(inputrec->opts), nullptr);
+            energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, FALSE, FALSE,
+                                               do_log ? fplog : nullptr, step, step, eprNORMAL,
+                                               fcd, &(top_global->groups), &(inputrec->opts), nullptr);
         }
 
         /* Send x and E to IMD client, if bIMD is TRUE. */
@@ -2370,9 +2380,9 @@ Integrator::do_lbfgs()
     }
     if (!do_ene || !do_log) /* Write final energy file entries */
     {
-        print_ebin(mdoutf_get_fp_ene(outf), !do_ene, FALSE, FALSE,
-                   !do_log ? fplog : nullptr, step, step, eprNORMAL,
-                   mdebin, fcd, &(top_global->groups), &(inputrec->opts), nullptr);
+        energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), !do_ene, FALSE, FALSE,
+                                           !do_log ? fplog : nullptr, step, step, eprNORMAL,
+                                           fcd, &(top_global->groups), &(inputrec->opts), nullptr);
     }
 
     /* Print some stuff... */
@@ -2449,7 +2459,8 @@ Integrator::do_steep()
     gmx_mdoutf *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, inputrec, top_global, nullptr, wcycle);
     snew(enerd, 1);
     init_enerdata(top_global->groups.grps[egcENER].nr, inputrec->fepvals->n_lambda, enerd);
-    t_mdebin *mdebin = init_mdebin(mdoutf_get_fp_ene(outf), top_global, inputrec, nullptr);
+    gmx::EnergyOutput energyOutput;
+    energyOutput.prepare(mdoutf_get_fp_ene(outf), top_global, inputrec, nullptr);
 
     /* Print to log file  */
     print_em_start(fplog, cr, walltime_accounting, wcycle, SD);
@@ -2538,18 +2549,20 @@ Integrator::do_steep()
             {
                 /* Store the new (lower) energies  */
                 matrix nullBox = {};
-                upd_mdebin(mdebin, FALSE, FALSE, static_cast<double>(count),
-                           mdatoms->tmass, enerd, nullptr, nullptr, nullptr,
-                           nullBox, nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
+                energyOutput.addDataAtEnergyStep(false, false, static_cast<double>(count),
+                                                 mdatoms->tmass, enerd, nullptr, nullptr, nullptr, nullBox,
+                                                 nullptr, nullptr, vir, pres, nullptr, mu_tot, constr);
 
                 /* Prepare IMD energy record, if bIMD is TRUE. */
                 IMD_fill_energy_record(inputrec->bIMD, inputrec->imd, enerd, count, TRUE);
 
-                print_ebin(mdoutf_get_fp_ene(outf), TRUE,
-                           do_per_step(steps_accepted, inputrec->nstdisreout),
-                           do_per_step(steps_accepted, inputrec->nstorireout),
-                           fplog, count, count, eprNORMAL,
-                           mdebin, fcd, &(top_global->groups), &(inputrec->opts), nullptr);
+                const bool do_dr = do_per_step(steps_accepted, inputrec->nstdisreout);
+                const bool do_or = do_per_step(steps_accepted, inputrec->nstorireout);
+                energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), TRUE,
+                                                   do_dr, do_or,
+                                                   fplog, count, count, eprNORMAL,
+                                                   fcd, &(top_global->groups),
+                                                   &(inputrec->opts), nullptr);
                 fflush(fplog);
             }
         }
index 53bcd23b84d7935e36ee3e34482b9286ceed2c36..e964fc080b62157b4848be54d2031e553efeb51a 100644 (file)
 #include "gromacs/mdlib/compute_io.h"
 #include "gromacs/mdlib/constr.h"
 #include "gromacs/mdlib/ebin.h"
+#include "gromacs/mdlib/energyoutput.h"
 #include "gromacs/mdlib/expanded.h"
 #include "gromacs/mdlib/force.h"
 #include "gromacs/mdlib/force_flags.h"
 #include "gromacs/mdlib/forcerec.h"
 #include "gromacs/mdlib/md_support.h"
 #include "gromacs/mdlib/mdatoms.h"
-#include "gromacs/mdlib/mdebin.h"
 #include "gromacs/mdlib/mdoutf.h"
 #include "gromacs/mdlib/mdrun.h"
 #include "gromacs/mdlib/mdsetup.h"
@@ -293,10 +293,9 @@ void gmx::Integrator::do_rerun()
 
     initialize_lambdas(fplog, *ir, MASTER(cr), &state_global->fep_state, state_global->lambda, lam0);
     init_nrnb(nrnb);
-
-    gmx_mdoutf *outf   = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, ir, top_global, oenv, wcycle);
-    t_mdebin   *mdebin = init_mdebin(mdrunOptions.continuationOptions.appendFiles ? nullptr : mdoutf_get_fp_ene(outf),
-                                     top_global, ir, mdoutf_get_fp_dhdl(outf), true);
+    gmx_mdoutf       *outf = init_mdoutf(fplog, nfile, fnm, mdrunOptions, cr, outputProvider, ir, top_global, oenv, wcycle);
+    gmx::EnergyOutput energyOutput;
+    energyOutput.prepare(mdoutf_get_fp_ene(outf), top_global, ir, mdoutf_get_fp_dhdl(outf), true);
 
     /* Energy terms and groups */
     snew(enerd, 1);
@@ -318,7 +317,7 @@ void gmx::Integrator::do_rerun()
                                  ir->nstcalcenergy, DOMAINDECOMP(cr));
 
     {
-        double io = compute_io(ir, top_global->natoms, groups, mdebin->ebin->nener, 1);
+        double io = compute_io(ir, top_global->natoms, groups, energyOutput.numEnergyTerms(), 1);
         if ((io > 2000) && MASTER(cr))
         {
             fprintf(stderr,
@@ -590,7 +589,7 @@ void gmx::Integrator::do_rerun()
             do_md_trajectory_writing(fplog, cr, nfile, fnm, step, step_rel, t,
                                      ir, state, state_global, observablesHistory,
                                      top_global, fr,
-                                     outf, mdebin, ekind, f,
+                                     outf, energyOutput, ekind, f,
                                      isCheckpointingStep, doRerun, isLastStep,
                                      mdrunOptions.writeConfout,
                                      bSumEkinhOld);
@@ -658,11 +657,11 @@ void gmx::Integrator::do_rerun()
         if (MASTER(cr))
         {
             const bool bCalcEnerStep = true;
-            upd_mdebin(mdebin, doFreeEnergyPerturbation, bCalcEnerStep,
-                       t, mdatoms->tmass, enerd, state,
-                       ir->fepvals, ir->expandedvals, rerun_fr.box,
-                       shake_vir, force_vir, total_vir, pres,
-                       ekind, mu_tot, constr);
+            energyOutput.addDataAtEnergyStep(doFreeEnergyPerturbation, bCalcEnerStep,
+                                             t, mdatoms->tmass, enerd, state,
+                                             ir->fepvals, ir->expandedvals, state->box,
+                                             shake_vir, force_vir, total_vir, pres,
+                                             ekind, mu_tot, constr);
 
             const bool do_ene = true;
             const bool do_log = true;
@@ -670,9 +669,10 @@ void gmx::Integrator::do_rerun()
             const bool do_dr  = ir->nstdisreout != 0;
             const bool do_or  = ir->nstorireout != 0;
 
-            print_ebin(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or, do_log ? fplog : nullptr,
-                       step, t,
-                       eprNORMAL, mdebin, fcd, groups, &(ir->opts), awh);
+            energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or,
+                                               do_log ? fplog : nullptr,
+                                               step, t,
+                                               eprNORMAL, fcd, groups, &(ir->opts), awh);
 
             if (do_per_step(step, ir->nstlog))
             {
@@ -752,7 +752,6 @@ void gmx::Integrator::do_rerun()
         gmx_pme_send_finish(cr);
     }
 
-    done_mdebin(mdebin);
     done_mdoutf(outf);
 
     done_shellfc(fplog, shellfc, step_rel);
index cebc50de14f0703d2325e847c0f5426adf539092..da514094d389427cad099348da611fde8f1d12a4 100644 (file)
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdlib/constr.h"
+#include "gromacs/mdlib/energyoutput.h"
 #include "gromacs/mdlib/force.h"
 #include "gromacs/mdlib/force_flags.h"
 #include "gromacs/mdlib/mdatoms.h"
-#include "gromacs/mdlib/mdebin.h"
 #include "gromacs/mdlib/mdrun.h"
 #include "gromacs/mdlib/ns.h"
 #include "gromacs/mdlib/sim_util.h"