Add lambda state to dhdl.xvg with AWH fep
[alexxy/gromacs.git] / src / gromacs / mdlib / energyoutput.h
index 070b7eeb230d79abf3c5e18a0d71f3ab268a2890..54ae8b01b278139a37aa3a74bf52cae7ac09b217 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2019, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, 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 <cstdio>
 
+#include <memory>
+
+#include "gromacs/math/vectypes.h"
+#include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/mdtypes/enerdata.h"
+#include "gromacs/topology/ifunc.h"
+#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/real.h"
 
 class energyhistory_t;
 struct ener_file;
-struct gmx_ekindata_t;
+class gmx_ekindata_t;
 struct gmx_enerdata_t;
 struct SimulationGroups;
 struct gmx_mtop_t;
 struct gmx_output_env_t;
 struct pull_t;
 struct t_ebin;
-struct t_expanded;
 struct t_fcdata;
 struct t_grpopts;
 struct t_inputrec;
@@ -71,12 +77,12 @@ namespace gmx
 {
 class Awh;
 class Constraints;
-struct MdModulesNotifier;
+struct MDModulesNotifiers;
 enum class StartingBehavior;
 } // namespace gmx
 
 //! \brief Printed names for intergroup energies
-extern const char* egrp_nm[egNR + 1];
+const char* enumValueToString(NonBondedEnergyTerms enumValue);
 
 /* \brief delta_h block type enum: the kinds of energies written out. */
 enum
@@ -97,6 +103,24 @@ enum
 
 namespace gmx
 {
+class EnergyDriftTracker;
+
+/*! \internal
+ * \brief Arrays connected to Pressure and Temperature coupling
+ */
+struct PTCouplingArrays
+{
+    //! Box velocities for Parrinello-Rahman P-coupling.
+    const rvec* boxv;
+    //! Nose-Hoover coordinates.
+    ArrayRef<const double> nosehoover_xi;
+    //! Nose-Hoover velocities.
+    ArrayRef<const double> nosehoover_vxi;
+    //! Pressure Nose-Hoover coordinates.
+    ArrayRef<const double> nhpres_xi;
+    //! Pressure Nose-Hoover velocities.
+    ArrayRef<const double> nhpres_vxi;
+};
 
 /* Energy output class
  *
@@ -104,7 +128,6 @@ namespace gmx
  * be written out to the .edr file.
  *
  * \todo Use more std containers.
- * \todo Remove GMX_CONSTRAINTVIR
  * \todo Write free-energy output also to energy file (after adding more tests)
  */
 class EnergyOutput
@@ -114,21 +137,23 @@ public:
      *
      * \param[in] fp_ene     Energy output file.
      * \param[in] mtop       Topology.
-     * \param[in] ir         Input parameters.
+     * \param[in] inputrec   Input parameters.
      * \param[in] pull_work  Pulling simulations data
      * \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] mdModulesNotifier Notifications to MD modules.
+     * \param[in] simulationsShareState  Tells whether the physical state is shared over simulations
+     * \param[in] mdModulesNotifiers Notifications to MD modules.
      */
-    EnergyOutput(ener_file*               fp_ene,
-                 const gmx_mtop_t*        mtop,
-                 const t_inputrec*        ir,
-                 const pull_t*            pull_work,
-                 FILE*                    fp_dhdl,
-                 bool                     isRerun,
-                 StartingBehavior         startingBehavior,
-                 const MdModulesNotifier& mdModulesNotifier);
+    EnergyOutput(ener_file*                fp_ene,
+                 const gmx_mtop_t&         mtop,
+                 const t_inputrec&         inputrec,
+                 const pull_t*             pull_work,
+                 FILE*                     fp_dhdl,
+                 bool                      isRerun,
+                 StartingBehavior          startingBehavior,
+                 bool                      simulationsShareState,
+                 const MDModulesNotifiers& mdModulesNotifiers);
 
     ~EnergyOutput();
 
@@ -136,34 +161,30 @@ public:
      *
      * Called every step on which the thermodynamic values are evaluated.
      *
-     * \param[in] bDoDHDL  Whether the FEP is enabled.
-     * \param[in] bSum     If this stepshould be recorded to compute sums and averaes.
-     * \param[in] time     Current simulation time.
-     * \param[in] tmass    Total mass
-     * \param[in] enerd    Energy data object.
-     * \param[in] state    System state.
-     * \param[in] fep      FEP data.
-     * \param[in] expand   Expanded ensemble (for FEP).
-     * \param[in] lastbox  PBC data.
-     * \param[in] svir     Constraint virial.
-     * \param[in] fvir     Force virial.
-     * \param[in] vir      Total virial.
-     * \param[in] pres     Pressure.
-     * \param[in] ekind    Kinetic energy data.
-     * \param[in] mu_tot   Total dipole.
-     * \param[in] constr   Constraints object to get RMSD from (for LINCS only).
+     * \param[in] bDoDHDL           Whether the FEP is enabled.
+     * \param[in] bSum              If this stepshould be recorded to compute sums and averages.
+     * \param[in] time              Current simulation time.
+     * \param[in] tmass             Total mass
+     * \param[in] enerd             Energy data object.
+     * \param[in] fep               FEP data.
+     * \param[in] lastbox           PBC data.
+     * \param[in] ptCouplingArrays  Arrays connected to pressure and temperature coupling.
+     * \param[in] fep_state         The current alchemical state we are in.
+     * \param[in] vir               Total virial.
+     * \param[in] pres              Pressure.
+     * \param[in] ekind             Kinetic energy data.
+     * \param[in] mu_tot            Total dipole.
+     * \param[in] constr            Constraints object to get RMSD from (for LINCS only).
      */
     void addDataAtEnergyStep(bool                    bDoDHDL,
                              bool                    bSum,
                              double                  time,
                              real                    tmass,
                              const gmx_enerdata_t*   enerd,
-                             const t_state*          state,
                              const t_lambda*         fep,
-                             const t_expanded*       expand,
                              const matrix            lastbox,
-                             const tensor            svir,
-                             const tensor            fvir,
+                             PTCouplingArrays        ptCouplingArrays,
+                             int                     fep_state,
                              const tensor            vir,
                              const tensor            pres,
                              const gmx_ekindata_t*   ekind,
@@ -216,7 +237,7 @@ public:
      * \param[in] opts    Atom temperature coupling groups options
      *                    (annealing is done by groups).
      */
-    void printAnnealingTemperatures(FILE* log, SimulationGroups* groups, t_grpopts* opts);
+    static void printAnnealingTemperatures(FILE* log, const SimulationGroups* groups, const t_grpopts* opts);
 
     /*! \brief Prints average values to log file.
      *
@@ -256,7 +277,16 @@ public:
     void restoreFromEnergyHistory(const energyhistory_t& enerhist);
 
     //! Print an output header to the log file.
-    void printHeader(FILE* log, int64_t steps, double time);
+    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
@@ -275,7 +305,7 @@ private:
     bool bMTTK_ = false;
 
     //! Temperature control scheme
-    int etc_ = 0;
+    TemperatureCoupling etc_ = TemperatureCoupling::No;
 
     //! Which of the main energy terms should be printed
     bool bEner_[F_NRE] = { false };
@@ -309,14 +339,6 @@ private:
     //! Index for entalpy (pV + total energy)
     int ienthalpy_ = 0;
 
-    /*! \brief If the constraints virial should be printed.
-     * Can only be true if "GMX_CONSTRAINTVIR" environmental variable is set */
-    bool bConstrVir_ = false;
-    //! Index for constrains virial
-    int isvir_ = 0;
-    //! Index for force virial
-    int ifvir_ = 0;
-
     //! If we have pressure computed
     bool bPres_ = false;
     //! Index for total virial
@@ -328,7 +350,7 @@ private:
     int isurft_ = 0;
 
     //! Pressure control scheme
-    int epc_ = 0;
+    PressureCoupling epc_ = PressureCoupling::No;
     //! Index for velocity of the box borders
     int ipc_ = 0;
 
@@ -342,8 +364,8 @@ private:
     //! Index for viscocity
     int ivisc_ = 0;
 
-    //! Which energy terms from egNR list should be printed in group-to-group block
-    bool bEInd_[egNR] = { false };
+    //! Which energy terms from NonBondedEnergyTerms list should be printed in group-to-group block
+    gmx::EnumerationArray<NonBondedEnergyTerms, bool> bEInd_;
     //! Number of energy terms to be printed (these, for which bEInd[] == true)
     int nEc_ = 0;
     //! Number of energy output groups
@@ -351,7 +373,7 @@ private:
     //! Number of intergroup energy sets to be printed for each energy term (nE = (nEg*(nEg+1))/2)
     int nE_ = 0;
     //! Indexes for integroup energy sets (each set with nEc energies)
-    int* igrp_ = nullptr;
+    std::vector<int> igrp_;
 
     //! Number of temperature coupling groups
     int nTC_ = 0;
@@ -372,26 +394,22 @@ private:
     //! Index for scalling factor of MTTK
     int itcb_ = 0;
 
-    //! Number of acceleration groups
-    int nU_ = 0;
-    //! Index for group velocities
-    int iu_ = 0;
-
-    //! Array to accumulate values during update
-    real* tmp_r_ = nullptr;
     //! Array to accumulate values during update
-    rvec* tmp_v_ = nullptr;
+    std::vector<real> tmp_r_;
 
     //! The dhdl.xvg output file
     FILE* fp_dhdl_ = nullptr;
+    //! Whether the free-energy lambda moves dynamically between lambda states
+    bool haveFepLambdaMoves_;
     //! Energy components for dhdl.xvg output
-    double* dE_ = nullptr;
+    std::vector<double> dE_;
     //! The delta U components (raw data + histogram)
-    t_mde_delta_h_coll* dhc_ = nullptr;
+    std::unique_ptr<t_mde_delta_h_coll> dhc_;
     //! Temperatures for simulated tempering groups
-    real* temperatures_ = nullptr;
-    //! Number of temperatures actually saved
-    int numTemperatures_ = 0;
+    std::vector<real> temperatures_;
+
+    //! For tracking the conserved or total energy
+    std::unique_ptr<EnergyDriftTracker> conservedEnergyTracker_;
 };
 
 } // namespace gmx