Merge branch release-2021 into merge-2021-into-master
authorPaul Bauer <paul.bauer.q@gmail.com>
Thu, 6 May 2021 14:22:09 +0000 (16:22 +0200)
committerPaul Bauer <paul.bauer.q@gmail.com>
Fri, 7 May 2021 08:21:46 +0000 (10:21 +0200)
Resolved Conflicts:
cmake/gmxCFlags.cmake
cmake/gmxManageFFTLibraries.cmake
cmake/gmxVersionInfo.cmake
docs/CMakeLists.txt
src/gromacs/applied_forces/awh/bias.cpp
src/gromacs/applied_forces/awh/biasstate.cpp
src/gromacs/applied_forces/awh/biasstate.h
src/gromacs/applied_forces/awh/read_params.cpp
src/gromacs/applied_forces/awh/tests/bias_fep_lambda_state.cpp
src/gromacs/fileio/vmdio.cpp
src/gromacs/gmxpreprocess/readir.cpp
src/gromacs/mdlib/constr.cpp
src/gromacs/mdlib/enerdata_utils.cpp
src/gromacs/mdlib/mdatoms.cpp
src/gromacs/mdrun/mimic.cpp
src/gromacs/mdrun/runner.cpp
src/gromacs/modularsimulator/modularsimulator.cpp
src/gromacs/utility/mdmodulesnotifiers.h

37 files changed:
1  2 
CMakeLists.txt
admin/gitlab-ci/lint.gitlab-ci.yml
api/nblib/CMakeLists.txt
api/nblib/tests/CMakeLists.txt
cmake/FindLibStdCpp.cmake
cmake/gmxCFlags.cmake
cmake/gmxManageFFTLibraries.cmake
cmake/gmxManageSharedLibraries.cmake
cmake/gmxVersionInfo.cmake
docs/CMakeLists.txt
docs/release-notes/index.rst
docs/user-guide/mdp-options.rst
src/gromacs/applied_forces/awh/bias.cpp
src/gromacs/applied_forces/awh/biasparams.cpp
src/gromacs/applied_forces/awh/read_params.cpp
src/gromacs/applied_forces/awh/tests/bias_fep_lambda_state.cpp
src/gromacs/applied_forces/electricfield.cpp
src/gromacs/fileio/matio.cpp
src/gromacs/fileio/vmdio.cpp
src/gromacs/gmxana/gmx_xpm2ps.cpp
src/gromacs/gmxpreprocess/grompp.cpp
src/gromacs/gmxpreprocess/pdb2gmx.cpp
src/gromacs/gmxpreprocess/readir.cpp
src/gromacs/hardware/device_management_ocl.cpp
src/gromacs/mdlib/constr.cpp
src/gromacs/mdlib/enerdata_utils.cpp
src/gromacs/mdlib/mdoutf.cpp
src/gromacs/mdlib/stat.cpp
src/gromacs/mdlib/trajectory_writing.cpp
src/gromacs/mdrun/minimize.cpp
src/gromacs/mdrun/rerun.cpp
src/gromacs/modularsimulator/modularsimulator.cpp
src/gromacs/pbcutil/pbc.cpp
src/gromacs/taskassignment/decidegpuusage.cpp
src/gromacs/topology/mtop_util.cpp
src/gromacs/topology/mtop_util.h
src/gromacs/utility/mdmodulesnotifiers.h

diff --cc CMakeLists.txt
Simple merge
index 799cb538931d34134c10e8fd4d7dbe60dc22d3cd,23eb084a17a8dc16e6daf3d3b4e27d9f149c7be7..51813fee1a848a58e0762a436e1caa6b7c005322
@@@ -118,8 -117,7 +118,7 @@@ copyright-check
      KUBERNETES_CPU_REQUEST: 1
      KUBERNETES_MEMORY_REQUEST: 2Gi
    script:
-     # TODO (issue #3272) `master` is not appropriate for use on release-xxxx branches, how should we handle that?
 -    - REV=$(git fetch -q https://gitlab.com/gromacs/gromacs.git release-2021 && git show -s --pretty=format:"%h" `git merge-base FETCH_HEAD HEAD`)
 +    - REV=$(git fetch -q https://gitlab.com/gromacs/gromacs.git master && git show -s --pretty=format:"%h" `git merge-base FETCH_HEAD HEAD`)
      - HEAD_REV=$(git show -s --pretty=format:"%h" HEAD)
      - if [[ "$REV" == "$HEAD_REV" ]] ; then
          REV="HEAD~1" ;
Simple merge
index f2f2d889c4fd376317964f039a0ca6f35d42bb2c,23b9efc0531d8258fdf6cf3932a5e6b1372d837d..33d34e58c7b65a87539f2bc5f79c607ddd35c4a2
@@@ -1,7 -1,7 +1,7 @@@
  #
  # This file is part of the GROMACS molecular simulation package.
  #
--# Copyright (c) 2020, by the GROMACS development team, led by
++# Copyright (c) 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.
index 7bc75c467bc87b12df0f6ae84b5e0a347bc1d2ea,25c1038a6a330c0ef1af8680f63f45015d0c3a8e..f1f8684c93388729075d057093ab98bd25710750
@@@ -133,8 -137,10 +133,8 @@@ if(NEED_TO_FIND_GPLUSPLUS
      # Set up to use the libstdc++ from that g++. Note that we checked
      # the existing contents of CMAKE_CXX_FLAGS* variables earlier, so
      # we will not override any user settings here.
-     if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+     if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "IntelLLVM")
          set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --gcc-toolchain=${GMX_GPLUSPLUS_PATH}")
 -    else() #Intel
 -        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -gcc-name=${GMX_GPLUSPLUS_PATH}")
      endif()
  endif()
  
Simple merge
index 6f92a5f24cb90fbc921d48054c6aa0052c646b69,bc310470b1523572c0f09057800813d4d0167d5e..e412641fcec82b742f79991a9282151f65bd7083
@@@ -42,7 -40,9 +40,7 @@@ set(PKG_FFT_LIBS ""
  # all their stuff. It's not easy if you only want some of their
  # stuff...
  set(MKL_MANUALLY FALSE)
- if (GMX_FFT_LIBRARY STREQUAL "MKL" AND NOT GMX_ICC_NEXTGEN)
 -if (GMX_FFT_LIBRARY STREQUAL "MKL" AND
 -    NOT ((CMAKE_C_COMPILER_ID MATCHES "Intel" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "11")
 -         OR GMX_INTEL_LLVM))
++if (GMX_FFT_LIBRARY STREQUAL "MKL" AND NOT GMX_INTEL_LLVM)
      # The user will have to provide the set of magic libraries in
      # MKL_LIBRARIES (see below), which we cache (non-advanced), so that they
      # don't have to keep specifying it, and can easily see that
Simple merge
Simple merge
index a4b1b25bc41c0b8a333fe93d4b09898991db2aef,11d7c710ea77354ae638e6347bd7778b85d4d7f8..468c8ed31a43d6c7bcc1a145c76d69f5a9b37591
@@@ -364,16 -364,8 +364,18 @@@ if (SPHINX_FOUND
          how-to/visualize.rst
          install-guide/index.rst
          release-notes/index.rst
 +        release-notes/2022/major/highlights.rst
 +        release-notes/2022/major/features.rst
 +        release-notes/2022/major/performance.rst
 +        release-notes/2022/major/tools.rst
 +        release-notes/2022/major/bugs-fixed.rst
 +        release-notes/2022/major/removed-functionality.rst
 +        release-notes/2022/major/deprecated-functionality.rst
 +        release-notes/2022/major/portability.rst
 +        release-notes/2022/major/miscellaneous.rst
 +        release-notes/2022/major/api.rst
+         release-notes/2021/2021.3.rst
+         release-notes/2021/2021.2.rst
          release-notes/2021/2021.1.rst
          release-notes/2021/major/highlights.rst
          release-notes/2021/major/features.rst
Simple merge
Simple merge
index 926f989286d202292b47343356fb9de7eeb57469,8a4345959ff76b1bdf582b4147c7cb2cb13f97de..9f256ddf91290c92a43e46dfe7cd4092e3e7ecec
   * To help us fund GROMACS development, we humbly ask that you cite
   * the research papers on the package. Check out http://www.gromacs.org.
   */
++
  #include "gmxpre.h"
  
  #include "read_params.h"
  
++#include <algorithm>
++
  #include "gromacs/applied_forces/awh/awh.h"
  #include "gromacs/fileio/readinp.h"
  #include "gromacs/fileio/warninp.h"
@@@ -1283,43 -1156,4 +1286,75 @@@ void setStateDependentAwhParams(AwhPara
      Awh::registerAwhWithPull(*awhParams, pull_work);
  }
  
-     for (int k = 0; k < awhParams.numBias(); k++)
 +void checkAwhParams(const AwhParams& awhParams, const t_inputrec& ir, warninp_t wi)
 +{
 +    std::string opt;
 +    checkMtsConsistency(ir, wi);
 +
 +    opt = "awh-nstout";
 +    if (awhParams.nstout() <= 0)
 +    {
 +        auto message = formatString("Not writing AWH output with AWH (%s = %d) does not make sense",
 +                                    opt.c_str(),
 +                                    awhParams.nstout());
 +        warning_error(wi, message);
 +    }
 +    /* This restriction can be removed by changing a flag of print_ebin() */
 +    if (ir.nstenergy == 0 || awhParams.nstout() % ir.nstenergy != 0)
 +    {
 +        auto message = formatString(
 +                "%s (%d) should be a multiple of nstenergy (%d)", opt.c_str(), awhParams.nstout(), ir.nstenergy);
 +        warning_error(wi, message);
 +    }
 +
 +    opt = "awh-nsamples-update";
 +    if (awhParams.numSamplesUpdateFreeEnergy() <= 0)
 +    {
 +        warning_error(wi, opt + " needs to be an integer > 0");
 +    }
 +
-         checkBiasParams(awhParams.awhBiasParams()[k], prefixawh, ir, wi);
++    bool       haveFepLambdaDim = false;
++    const auto awhBiasParams    = awhParams.awhBiasParams();
++    for (int k = 0; k < awhParams.numBias() && !haveFepLambdaDim; k++)
 +    {
 +        std::string prefixawh = formatString("awh%d", k + 1);
++        checkBiasParams(awhBiasParams[k], prefixawh, ir, wi);
++        /* Check if there is a FEP lambda dimension. */
++        const auto dimParams = awhBiasParams[k].dimParams();
++        haveFepLambdaDim = std::any_of(dimParams.begin(), dimParams.end(), [](const auto& dimParam) {
++            return dimParam.coordinateProvider() == AwhCoordinateProviderType::FreeEnergyLambda;
++        });
++    }
++
++    if (haveFepLambdaDim)
++    {
++        if (awhParams.nstSampleCoord() % ir.nstcalcenergy != 0)
++        {
++            opt          = "awh-nstsample";
++            auto message = formatString(
++                    "%s (%d) should be a multiple of nstcalcenergy (%d) when using AWH for "
++                    "sampling an FEP lambda dimension",
++                    opt.c_str(),
++                    awhParams.nstSampleCoord(),
++                    ir.nstcalcenergy);
++            warning_error(wi, message);
++        }
++        if (awhParams.potential() != AwhPotentialType::Umbrella)
++        {
++            opt          = "awh-potential";
++            auto message = formatString(
++                    "%s (%s) must be set to %s when using AWH for sampling an FEP lambda dimension",
++                    opt.c_str(),
++                    enumValueToString(awhParams.potential()),
++                    enumValueToString(AwhPotentialType::Umbrella));
++            warning_error(wi, message);
++        }
 +    }
 +
 +    if (ir.init_step != 0)
 +    {
 +        warning_error(wi, "With AWH init-step should be 0");
 +    }
 +}
 +
  } // namespace gmx
index 5e1e01618514cc9a3ef8c1bca6c62506753c8690,1d536446bfff1558bb6f71d31bfdadb6e200167a..5eb21950b7473f8d8a19efcd8c0f0e695a49f4bd
@@@ -224,33 -265,16 +221,32 @@@ TEST_P(BiasFepLambdaStateTest, ForcesBi
   */
  INSTANTIATE_TEST_CASE_P(WithParameters,
                          BiasFepLambdaStateTest,
 -                        ::testing::Combine(::testing::Values(eawhgrowthLINEAR, eawhgrowthEXP_LINEAR),
 -                                           ::testing::Values(eawhpotentialUMBRELLA),
 +                        ::testing::Combine(::testing::Values(AwhHistogramGrowthType::Linear,
 +                                                             AwhHistogramGrowthType::ExponentialLinear),
-                                            ::testing::Values(AwhPotentialType::Umbrella,
-                                                              AwhPotentialType::Convolved),
++                                           ::testing::Values(AwhPotentialType::Umbrella),
                                             ::testing::Values(BiasParams::DisableUpdateSkips::yes,
                                                               BiasParams::DisableUpdateSkips::no)));
  
  // Test that we detect coverings and exit the initial stage at the correct step
  TEST(BiasFepLambdaStateTest, DetectsCovering)
  {
 -    const AwhFepLambdaStateTestParameters params =
 -            getAwhFepLambdaTestParameters(eawhgrowthEXP_LINEAR, eawhpotentialUMBRELLA);
 +    constexpr AwhCoordinateProviderType coordinateProvider = AwhCoordinateProviderType::FreeEnergyLambda;
 +    constexpr int                       coordIndex         = 0;
 +    constexpr double                    origin             = 0;
 +    constexpr double                    end                = c_numLambdaStates - 1;
 +    constexpr double                    period             = 0;
 +    constexpr double                    diffusion          = 1e-4 / (0.12927243028700 * 2);
 +    auto                                awhDimBuffer =
 +            awhDimParamSerialized(coordinateProvider, coordIndex, origin, end, period, diffusion);
 +    auto                    awhDimArrayRef = gmx::arrayRefFromArray(&awhDimBuffer, 1);
 +    const AwhTestParameters params(getAwhTestParameters(AwhHistogramGrowthType::ExponentialLinear,
-                                                         AwhPotentialType::Convolved,
++                                                        AwhPotentialType::Umbrella,
 +                                                        awhDimArrayRef,
 +                                                        false,
 +                                                        0.4,
 +                                                        true,
 +                                                        1.0,
 +                                                        c_numLambdaStates));
  
      const double mdTimeStep = 0.1;
  
Simple merge
Simple merge
Simple merge
index 2bbc9523fe852c1a73bda8ef58624f5712e4da66,9c4fc7f255b27b597c5884446540cabf8e4f5251..63f93ae8db332692d91f8316fa314d7d56696a69
  InteractionOfType::InteractionOfType(gmx::ArrayRef<const int>  atoms,
                                       gmx::ArrayRef<const real> params,
                                       const std::string&        name) :
--    atoms_(atoms.begin(), atoms.end()),
--    interactionTypeName_(name)
++    atoms_(atoms.begin(), atoms.end()), interactionTypeName_(name)
  {
      GMX_RELEASE_ASSERT(
              params.size() <= forceParam_.size(),
@@@ -2177,9 -2081,16 +2176,16 @@@ int gmx_grompp(int argc, char* argv[]
      /* check masses */
      check_mol(&sys, wi);
  
+     if (haveFepPerturbedMassesInSettles(sys))
+     {
+         warning_error(wi,
+                       "SETTLE is not implemented for atoms whose mass is perturbed. "
+                       "You might instead use normal constraints.");
+     }
      checkForUnboundAtoms(&sys, bVerbose, wi, logger);
  
 -    if (EI_DYNAMICS(ir->eI) && ir->eI != eiBD)
 +    if (EI_DYNAMICS(ir->eI) && ir->eI != IntegrationAlgorithm::BD)
      {
          check_bonds_timestep(&sys, ir->delta_t, wi);
      }
              copy_mat(ir->compress, compressibility);
          }
          setStateDependentAwhParams(
 -                ir->awhParams, *ir->pull, pull, state.box, ir->pbcType, compressibility, &ir->opts,
 -                ir->efep != efepNO ? ir->fepvals->all_lambda[efptFEP][ir->fepvals->init_fep_state] : 0,
 -                sys, wi);
 +                ir->awhParams.get(),
 +                *ir->pull,
 +                pull,
 +                state.box,
 +                ir->pbcType,
 +                compressibility,
 +                &ir->opts,
-                 ir->efep != FreeEnergyPerturbationType::No
-                         ? ir->fepvals->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Fep)]
-                                                  [ir->fepvals->init_fep_state]
-                         : 0,
++                ir->efep != FreeEnergyPerturbationType::No ? ir->fepvals->all_lambda[static_cast<int>(
++                        FreeEnergyPerturbationCouplingType::Fep)][ir->fepvals->init_fep_state]
++                                                           : 0,
 +                sys,
 +                wi);
      }
  
      if (ir->bPull)
index d562476a1ebe7d20b8493d886bfd8c58e806fea4,ff1fc32edd0c74d785c017f69124cb44b2059ca7..d230a9ef7625d04c1073e507549f9f429b62495e
  struct RtpRename
  {
      RtpRename(const char* newGmx, const char* newMain, const char* newNter, const char* newCter, const char* newBter) :
--        gmx(newGmx),
--        main(newMain),
--        nter(newNter),
--        cter(newCter),
--        bter(newBter)
++        gmx(newGmx), main(newMain), nter(newNter), cter(newCter), bter(newBter)
      {
      }
      std::string gmx;
index 55756cec59aceafdb68a2bf6d3fc13c5ed0dc791,2ca9db05869697bb49dd33d1649bc8b9e1bcb3f2..54008d57b91a7e56c63621fdbc9e502c6c4e874b
@@@ -3268,8 -3246,8 +3270,8 @@@ static bool do_egp_flag(t_inputrec* ir
          j = 0;
          while ((j < nr)
                 && gmx_strcasecmp(
--                          names[2 * i].c_str(),
--                          *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][j]])))
++                       names[2 * i].c_str(),
++                       *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][j]])))
          {
              j++;
          }
          k = 0;
          while ((k < nr)
                 && gmx_strcasecmp(
--                          names[2 * i + 1].c_str(),
--                          *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][k]])))
++                       names[2 * i + 1].c_str(),
++                       *(groups->groupNames[groups->groups[SimulationAtomGroupType::EnergyOutput][k]])))
          {
              k++;
          }
@@@ -4139,36 -4019,45 +4136,45 @@@ static BasicVector<bool> haveAbsoluteRe
          }
      }
  
-     /* Check for position restraints */
-     for (const auto ilist : IListRange(sys))
+     return absRef;
+ }
+ //! Returns whether position restraints are used for dimensions
+ static BasicVector<bool> havePositionRestraints(const gmx_mtop_t& sys)
+ {
+     BasicVector<bool> havePosres = { false, false, false };
 -    gmx_mtop_ilistloop_t iloop = gmx_mtop_ilistloop_init(&sys);
 -    int                  nmol;
 -    while (const InteractionLists* ilist = gmx_mtop_ilistloop_next(iloop, &nmol))
++    for (const auto ilists : IListRange(sys))
      {
-         if (ilist.nmol() > 0 && (AbsRef[XX] == 0 || AbsRef[YY] == 0 || AbsRef[ZZ] == 0))
 -        if (nmol > 0 && (!havePosres[XX] || !havePosres[YY] || !havePosres[ZZ]))
++        const auto& posResList   = ilists.list()[F_POSRES];
++        const auto& fbPosResList = ilists.list()[F_FBPOSRES];
++        if (ilists.nmol() > 0 && (!havePosres[XX] || !havePosres[YY] || !havePosres[ZZ]))
          {
-             for (int i = 0; i < ilist.list()[F_POSRES].size(); i += 2)
 -            for (int i = 0; i < (*ilist)[F_POSRES].size(); i += 2)
++            for (int i = 0; i < posResList.size(); i += 2)
              {
-                 pr = &sys.ffparams.iparams[ilist.list()[F_POSRES].iatoms[i]];
-                 for (d = 0; d < DIM; d++)
 -                const t_iparams& pr = sys.ffparams.iparams[(*ilist)[F_POSRES].iatoms[i]];
++                const t_iparams& pr = sys.ffparams.iparams[posResList.iatoms[i]];
+                 for (int d = 0; d < DIM; d++)
                  {
-                     if (pr->posres.fcA[d] != 0)
+                     if (pr.posres.fcA[d] != 0)
                      {
-                         AbsRef[d] = 1;
+                         havePosres[d] = true;
                      }
                  }
              }
-             for (i = 0; i < ilist.list()[F_FBPOSRES].size(); i += 2)
 -            for (int i = 0; i < (*ilist)[F_FBPOSRES].size(); i += 2)
++            for (int i = 0; i < fbPosResList.size(); i += 2)
              {
                  /* Check for flat-bottom posres */
-                 pr = &sys.ffparams.iparams[ilist.list()[F_FBPOSRES].iatoms[i]];
-                 if (pr->fbposres.k != 0)
 -                const t_iparams& pr = sys.ffparams.iparams[(*ilist)[F_FBPOSRES].iatoms[i]];
++                const t_iparams& pr = sys.ffparams.iparams[fbPosResList.iatoms[i]];
+                 if (pr.fbposres.k != 0)
                  {
-                     switch (pr->fbposres.geom)
+                     switch (pr.fbposres.geom)
                      {
-                         case efbposresSPHERE: AbsRef[XX] = AbsRef[YY] = AbsRef[ZZ] = 1; break;
-                         case efbposresCYLINDERX: AbsRef[YY] = AbsRef[ZZ] = 1; break;
-                         case efbposresCYLINDERY: AbsRef[XX] = AbsRef[ZZ] = 1; break;
+                         case efbposresSPHERE: havePosres = { true, true, true }; break;
+                         case efbposresCYLINDERX: havePosres[YY] = havePosres[ZZ] = true; break;
+                         case efbposresCYLINDERY: havePosres[XX] = havePosres[ZZ] = true; break;
                          case efbposresCYLINDER:
                          /* efbposres is a synonym for efbposresCYLINDERZ for backwards compatibility */
-                         case efbposresCYLINDERZ: AbsRef[XX] = AbsRef[YY] = 1; break;
+                         case efbposresCYLINDERZ: havePosres[XX] = havePosres[YY] = true; break;
                          case efbposresX: /* d=XX */
                          case efbposresY: /* d=YY */
                          case efbposresZ: /* d=ZZ */
                              break;
                          default:
                              gmx_fatal(FARGS,
-                                       " Invalid geometry for flat-bottom position restraint.\n"
+                                       "Invalid geometry for flat-bottom position restraint.\n"
                                        "Expected nr between 1 and %d. Found %d\n",
 -                                      efbposresNR - 1, pr.fbposres.geom);
 +                                      efbposresNR - 1,
-                                       pr->fbposres.geom);
++                                      pr.fbposres.geom);
                      }
                  }
              }
          }
      }
  
-     return (AbsRef[XX] != 0 && AbsRef[YY] != 0 && AbsRef[ZZ] != 0);
+     return havePosres;
  }
  
 -static void check_combination_rule_differences(const gmx_mtop_t* mtop,
 +static void check_combination_rule_differences(const gmx_mtop_t& mtop,
                                                 int               state,
                                                 bool* bC6ParametersWorkWithGeometricRules,
                                                 bool* bC6ParametersWorkWithLBRules,
      ptr = getenv("GMX_LJCOMB_TOL");
      if (ptr != nullptr)
      {
--        double dbl;
++        double            dbl;
          double gmx_unused canary;
  
          if (sscanf(ptr, "%lf%lf", &dbl, &canary) != 1)
@@@ -4327,9 -4219,10 +4337,8 @@@ void triple_check(const char* mdparin, 
  
      char                      err_buf[STRLEN];
      int                       i, m, c, nmol;
 -    bool                      bCharge, bAcc;
 -    real *                    mgrp, mt;
 -    rvec                      acc;
 +    bool                      bCharge;
      gmx_mtop_atomloop_block_t aloopb;
-     ivec                      AbsRef;
      char                      warn_buf[STRLEN];
  
      set_warning_line(wi, mdparin, -1);
          }
      }
  
 -    if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != eiBD && ir->comm_mode == ecmNO
 +    if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != IntegrationAlgorithm::BD
 +        && ir->comm_mode == ComRemovalAlgorithm::No
-         && !(absolute_reference(ir, *sys, FALSE, AbsRef) || ir->nsteps <= 10) && !ETC_ANDERSEN(ir->etc))
+         && !(allTrue(haveAbsoluteReference(*ir)) || allTrue(havePositionRestraints(*sys)) || ir->nsteps <= 10)
+         && !ETC_ANDERSEN(ir->etc))
      {
          warning(wi,
                  "You are not using center of mass motion removal (mdp option comm-mode), numerical "
      }
  
      /* Check for pressure coupling with absolute position restraints */
 -    if (ir->epc != epcNO && ir->refcoord_scaling == erscNO)
 +    if (ir->epc != PressureCoupling::No && ir->refcoord_scaling == RefCoordScaling::No)
      {
-         absolute_reference(ir, *sys, TRUE, AbsRef);
+         const BasicVector<bool> havePosres = havePositionRestraints(*sys);
          {
              for (m = 0; m < DIM; m++)
              {
Simple merge
index 07a26a1e8d83be8cb6899d6040c203842bd50fd0,0ebef33d1e74741c0de981adab7041fe84cc41aa..f76dca56a1e3fafd5398f69f6b992b750f26d014
  #include "gromacs/mdtypes/commrec.h"
  #include "gromacs/mdtypes/enerdata.h"
  #include "gromacs/mdtypes/inputrec.h"
++#include "gromacs/utility/enumerationhelpers.h"
  #include "gromacs/utility/fatalerror.h"
  #include "gromacs/utility/smalloc.h"
  
  ForeignLambdaTerms::ForeignLambdaTerms(int numLambdas) :
--    numLambdas_(numLambdas),
--    energies_(1 + numLambdas),
--    dhdl_(1 + numLambdas)
++    numLambdas_(numLambdas), energies_(1 + numLambdas), dhdl_(1 + numLambdas)
  {
  }
  
@@@ -81,9 -81,9 +80,7 @@@ void ForeignLambdaTerms::zeroAllTerms(
  }
  
  gmx_enerdata_t::gmx_enerdata_t(int numEnergyGroups, int numFepLambdas) :
--    grpp(numEnergyGroups),
--    foreignLambdaTerms(numFepLambdas),
--    foreign_grpp(numEnergyGroups)
++    grpp(numEnergyGroups), foreignLambdaTerms(numFepLambdas), foreign_grpp(numEnergyGroups)
  {
  }
  
@@@ -126,54 -126,38 +123,48 @@@ void sum_epot(const gmx_grppairener_t& 
      }
  }
  
- // Adds computed dV/dlambda contributions to the requested outputs
- static void set_dvdl_output(gmx_enerdata_t* enerd, const t_lambda& fepvals)
+ // Adds computed dH/dlambda contribution i to the requested output
 -static void set_dhdl_output(gmx_enerdata_t* enerd, int i, const t_lambda& fepvals)
++static void set_dhdl_output(gmx_enerdata_t* enerd, FreeEnergyPerturbationCouplingType i, const t_lambda& fepvals)
  {
-     enerd->term[F_DVDL] = 0.0;
-     for (auto i : keysOf(fepvals.separate_dvdl))
+     if (fepvals.separate_dvdl[i])
      {
-         if (fepvals.separate_dvdl[i])
+         /* Translate free-energy term indices to idef term indices.
+          * Could this be done more readably/compactly?
+          */
+         int index;
+         switch (i)
          {
-             /* Translate free-energy term indices to idef term indices.
-              * Could this be done more readably/compactly?
-              */
-             int index;
-             switch (i)
-             {
-                 case (FreeEnergyPerturbationCouplingType::Mass): index = F_DKDL; break;
-                 case (FreeEnergyPerturbationCouplingType::Coul): index = F_DVDL_COUL; break;
-                 case (FreeEnergyPerturbationCouplingType::Vdw): index = F_DVDL_VDW; break;
-                 case (FreeEnergyPerturbationCouplingType::Bonded): index = F_DVDL_BONDED; break;
-                 case (FreeEnergyPerturbationCouplingType::Restraint):
-                     index = F_DVDL_RESTRAINT;
-                     break;
-                 default: index = F_DVDL; break;
-             }
-             enerd->term[index] = enerd->dvdl_lin[i] + enerd->dvdl_nonlin[i];
-             if (debug)
-             {
-                 fprintf(debug,
-                         "dvdl-%s[%2d]: %f: non-linear %f + linear %f\n",
-                         enumValueToString(i),
-                         static_cast<int>(i),
-                         enerd->term[index],
-                         enerd->dvdl_nonlin[i],
-                         enerd->dvdl_lin[i]);
-             }
 -            case (efptMASS): index = F_DKDL; break;
 -            case (efptCOUL): index = F_DVDL_COUL; break;
 -            case (efptVDW): index = F_DVDL_VDW; break;
 -            case (efptBONDED): index = F_DVDL_BONDED; break;
 -            case (efptRESTRAINT): index = F_DVDL_RESTRAINT; break;
++            case (FreeEnergyPerturbationCouplingType::Mass): index = F_DKDL; break;
++            case (FreeEnergyPerturbationCouplingType::Coul): index = F_DVDL_COUL; break;
++            case (FreeEnergyPerturbationCouplingType::Vdw): index = F_DVDL_VDW; break;
++            case (FreeEnergyPerturbationCouplingType::Bonded): index = F_DVDL_BONDED; break;
++            case (FreeEnergyPerturbationCouplingType::Restraint): index = F_DVDL_RESTRAINT; break;
+             default: index = F_DVDL; break;
          }
-         else
+         enerd->term[index] = enerd->dvdl_lin[i] + enerd->dvdl_nonlin[i];
+         if (debug)
          {
-             enerd->term[F_DVDL] += enerd->dvdl_lin[i] + enerd->dvdl_nonlin[i];
-             if (debug)
-             {
-                 fprintf(debug,
-                         "dvd-%sl[%2d]: %f: non-linear %f + linear %f\n",
-                         enumValueToString(FreeEnergyPerturbationCouplingType::Fep),
-                         static_cast<int>(i),
-                         enerd->term[F_DVDL],
-                         enerd->dvdl_nonlin[i],
-                         enerd->dvdl_lin[i]);
-             }
 -            fprintf(debug, "dvdl-%s[%2d]: %f: non-linear %f + linear %f\n", efpt_names[i], i,
 -                    enerd->term[index], enerd->dvdl_nonlin[i], enerd->dvdl_lin[i]);
++            fprintf(debug,
++                    "dvdl-%s[%2d]: %f: non-linear %f + linear %f\n",
++                    enumValueToString(i),
++                    static_cast<int>(i),
++                    enerd->term[index],
++                    enerd->dvdl_nonlin[i],
++                    enerd->dvdl_lin[i]);
+         }
+     }
+     else
+     {
+         enerd->term[F_DVDL] += enerd->dvdl_lin[i] + enerd->dvdl_nonlin[i];
+         if (debug)
+         {
 -            fprintf(debug, "dvd-%sl[%2d]: %f: non-linear %f + linear %f\n", efpt_names[0], i,
 -                    enerd->term[F_DVDL], enerd->dvdl_nonlin[i], enerd->dvdl_lin[i]);
++            fprintf(debug,
++                    "dvd-%sl[%2d]: %f: non-linear %f + linear %f\n",
++                    enumValueToString(FreeEnergyPerturbationCouplingType::Fep),
++                    static_cast<int>(i),
++                    enerd->term[F_DVDL],
++                    enerd->dvdl_nonlin[i],
++                    enerd->dvdl_lin[i]);
          }
      }
  }
@@@ -238,7 -222,15 +229,15 @@@ void accumulatePotentialEnergies(gmx_en
  
      if (fepvals)
      {
-         set_dvdl_output(enerd, *fepvals);
+         enerd->term[F_DVDL] = 0.0;
 -        for (int i = 0; i < efptNR; i++)
++        for (auto i : gmx::EnumerationWrapper<FreeEnergyPerturbationCouplingType>{})
+         {
+             // Skip kinetic terms here, as those are not available here yet
 -            if (i != efptMASS)
++            if (i != FreeEnergyPerturbationCouplingType::Mass)
+             {
+                 set_dhdl_output(enerd, i, *fepvals);
+             }
+         }
  
          enerd->foreignLambdaTerms.finalizePotentialContributions(enerd->dvdl_lin, lambda, *fepvals);
      }
@@@ -302,8 -290,11 +301,11 @@@ void accumulateKineticLambdaComponents(
          enerd->term[F_DVDL] += enerd->term[F_DVDL_CONSTR];
      }
  
 -    set_dhdl_output(enerd, efptMASS, fepvals);
+     // Add computed mass dH/dlambda contribution to the requested output
 -    enerd->foreignLambdaTerms.finalizeKineticContributions(enerd->term, enerd->dvdl_lin[efptMASS],
 -                                                           lambda, fepvals);
++    set_dhdl_output(enerd, FreeEnergyPerturbationCouplingType::Mass, fepvals);
 +    enerd->foreignLambdaTerms.finalizeKineticContributions(
 +            enerd->term, enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Mass], lambda, fepvals);
  
      /* The constrain contribution is now included in other terms, so clear it */
      enerd->term[F_DVDL_CONSTR] = 0;
index f03fb05d824c8883da070ccfa856f217603e39d3,7e06e4fc9ee5fae2fe646c1b404e309fd8436128..71f911b3dd7803ba76b4bd330fbe5601df89c04c
@@@ -570,16 -549,9 +577,15 @@@ void mdoutf_write_to_trajectory_files(F
          f_global = of->f_global;
          if (mdof_flags & MDOF_F)
          {
-             auto globalFRef =
-                     MASTER(cr) ? gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec*>(of->f_global),
-                                                         of->natoms_global)
-                                : gmx::ArrayRef<gmx::RVec>();
 -            dd_collect_vec(
 -                    cr->dd, state_local->ddp_count, state_local->ddp_count_cg_gl, state_local->cg_gl, f_local,
 -                    gmx::arrayRefFromArray(reinterpret_cast<gmx::RVec*>(of->f_global), f_local.size()));
++            auto globalFRef = MASTER(cr) ? gmx::arrayRefFromArray(
++                                      reinterpret_cast<gmx::RVec*>(of->f_global), of->natoms_global)
++                                         : gmx::ArrayRef<gmx::RVec>();
 +            dd_collect_vec(cr->dd,
 +                           state_local->ddp_count,
 +                           state_local->ddp_count_cg_gl,
 +                           state_local->cg_gl,
 +                           f_local,
 +                           globalFRef);
          }
      }
      else
Simple merge
index 79eaaf0a57f833b720f18ffb2e4bf18ef77cf9c9,b6b9376e3aaf9ab81fdc6b86b33cfa94e518b792..a1d42aa6c1f5eddd7e033dd7dc6c6bba03ca0aeb
@@@ -642,9 -586,9 +643,9 @@@ static bool do_em_step(const t_commrec
                         int64_t                                   count)
  
  {
--    t_state *s1, *s2;
--    int      start, end;
--    real     dvdl_constr;
++    t_state *    s1, *s2;
++    int          start, end;
++    real         dvdl_constr;
      int nthreads gmx_unused;
  
      bool validStep = true;
index b5589d8eb998fea902df1d5faa468adc4d849936,36333d3c94273c5ecc147dfce8c94fc1d6824988..78271fae4824e620cf3969fc14ce6097ad9a40e2
@@@ -811,16 -623,14 +812,21 @@@ void gmx::LegacySimulator::do_rerun(
              const bool do_or  = ir->nstorireout != 0;
  
              EnergyOutput::printAnnealingTemperatures(do_log ? fplog : nullptr, groups, &(ir->opts));
 -            energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf), do_ene, do_dr, do_or,
 -                                               do_log ? fplog : nullptr, step, t, fr->fcdata.get(), awh);
 +            energyOutput.printStepToEnergyFile(mdoutf_get_fp_ene(outf),
 +                                               do_ene,
 +                                               do_dr,
 +                                               do_or,
 +                                               do_log ? fplog : nullptr,
 +                                               step,
 +                                               t,
 +                                               fr->fcdata.get(),
 +                                               awh);
  
+             if (ir->bPull)
+             {
+                 pull_print_output(pull_work, step, t);
+             }
              if (do_per_step(step, ir->nstlog))
              {
                  if (fflush(fplog) != 0)
index 503fd87547d9a92dbe99904cf3c27866980f0784,e2c7c8ac6dd96c5ecd7348b2efc9e36426c2df8c..2431e18aa2e759101ada4a27a1c968354bfe00b2
@@@ -224,8 -220,8 +224,8 @@@ bool ModularSimulator::isInputCompatibl
      isInputCompatible =
              isInputCompatible
              && conditionalAssert(
--                       !inputrec->useMts,
--                       "Multiple time stepping is not supported by the modular simulator.");
++                    !inputrec->useMts,
++                    "Multiple time stepping is not supported by the modular simulator.");
      isInputCompatible =
              isInputCompatible
              && conditionalAssert(!doRerun, "Rerun is not supported by the modular simulator.");
      isInputCompatible =
              isInputCompatible
              && conditionalAssert(
-                        inputrec->epc == PressureCoupling::No
-                                || inputrec->epc == PressureCoupling::ParrinelloRahman,
 -                       inputrec->epc == epcNO || inputrec->epc == epcPARRINELLORAHMAN,
--                       "Only Parrinello-Rahman barostat is supported by the modular simulator.");
++                    inputrec->epc == PressureCoupling::No || inputrec->epc == PressureCoupling::ParrinelloRahman,
++                    "Only Parrinello-Rahman barostat is supported by the modular simulator.");
      isInputCompatible =
              isInputCompatible
              && conditionalAssert(
--                       !(inputrecNptTrotter(inputrec) || inputrecNphTrotter(inputrec)
--                         || inputrecNvtTrotter(inputrec)),
--                       "Legacy Trotter decomposition is not supported by the modular simulator.");
 -    isInputCompatible = isInputCompatible
 -                        && conditionalAssert(inputrec->efep == efepNO || inputrec->efep == efepYES
 -                                                     || inputrec->efep == efepSLOWGROWTH,
 -                                             "Expanded ensemble free energy calculation is not "
 -                                             "supported by the modular simulator.");
++                    !(inputrecNptTrotter(inputrec) || inputrecNphTrotter(inputrec)
++                      || inputrecNvtTrotter(inputrec)),
++                    "Legacy Trotter decomposition is not supported by the modular simulator.");
 +    isInputCompatible =
 +            isInputCompatible
 +            && conditionalAssert(inputrec->efep == FreeEnergyPerturbationType::No
 +                                         || inputrec->efep == FreeEnergyPerturbationType::Yes
 +                                         || inputrec->efep == FreeEnergyPerturbationType::SlowGrowth,
 +                                 "Expanded ensemble free energy calculation is not "
 +                                 "supported by the modular simulator.");
      isInputCompatible = isInputCompatible
                          && conditionalAssert(!inputrec->bPull,
                                               "Pulling is not supported by the modular simulator.");
      isInputCompatible =
              isInputCompatible
              && conditionalAssert(
--                       inputrec->deform[XX][XX] == 0.0 && inputrec->deform[XX][YY] == 0.0
--                               && inputrec->deform[XX][ZZ] == 0.0 && inputrec->deform[YY][XX] == 0.0
--                               && inputrec->deform[YY][YY] == 0.0 && inputrec->deform[YY][ZZ] == 0.0
--                               && inputrec->deform[ZZ][XX] == 0.0 && inputrec->deform[ZZ][YY] == 0.0
--                               && inputrec->deform[ZZ][ZZ] == 0.0,
--                       "Deformation is not supported by the modular simulator.");
++                    inputrec->deform[XX][XX] == 0.0 && inputrec->deform[XX][YY] == 0.0
++                            && inputrec->deform[XX][ZZ] == 0.0 && inputrec->deform[YY][XX] == 0.0
++                            && inputrec->deform[YY][YY] == 0.0 && inputrec->deform[YY][ZZ] == 0.0
++                            && inputrec->deform[ZZ][XX] == 0.0 && inputrec->deform[ZZ][YY] == 0.0
++                            && inputrec->deform[ZZ][ZZ] == 0.0,
++                    "Deformation is not supported by the modular simulator.");
      isInputCompatible =
              isInputCompatible
              && conditionalAssert(gmx_mtop_interaction_count(globalTopology, IF_VSITE) == 0,
      isInputCompatible =
              isInputCompatible
              && conditionalAssert(
--                       gmx_mtop_ftype_count(globalTopology, F_ORIRES) == 0,
--                       "Orientation restraints are not supported by the modular simulator.");
++                    gmx_mtop_ftype_count(globalTopology, F_ORIRES) == 0,
++                    "Orientation restraints are not supported by the modular simulator.");
      isInputCompatible =
              isInputCompatible
              && conditionalAssert(ms == nullptr,
      }
      else
      {
--        auto distantRestraintEnsembleEnvVar = getenv("GMX_DISRE_ENSEMBLE_SIZE");
++        auto* distantRestraintEnsembleEnvVar = getenv("GMX_DISRE_ENSEMBLE_SIZE");
          numEnsembleRestraintSystems =
                  (ms != nullptr && distantRestraintEnsembleEnvVar != nullptr)
                          ? static_cast<int>(strtol(distantRestraintEnsembleEnvVar, nullptr, 10))
      isInputCompatible =
              isInputCompatible
              && conditionalAssert(
--                       getenv("GMX_FORCE_UPDATE_DEFAULT_GPU") == nullptr,
--                       "Integration on the GPU is not supported by the modular simulator.");
++                    getenv("GMX_FORCE_UPDATE_DEFAULT_GPU") == nullptr,
++                    "Integration on the GPU is not supported by the modular simulator.");
      // Modular simulator is centered around NS updates
      // TODO: think how to handle nstlist == 0
      isInputCompatible = isInputCompatible
      isInputCompatible = isInputCompatible
                          && conditionalAssert(!GMX_FAHCORE,
                                               "GMX_FAHCORE not supported by the modular simulator.");
-     GMX_RELEASE_ASSERT(
-             isInputCompatible
-                     || !(inputrec->eI == IntegrationAlgorithm::VV
-                          && inputrec->epc == PressureCoupling::ParrinelloRahman),
-             "Requested Parrinello-Rahman barostat with md-vv, but other options are not compatible "
-             "with the modular simulator. The Parrinello-Rahman barostat is not implemented for "
-             "md-vv in the legacy simulator. Use a different pressure control algorithm.");
 -    if (!isInputCompatible && (inputrec->eI == eiVV && inputrec->epc == epcPARRINELLORAHMAN))
++    if (!isInputCompatible
++        && (inputrec->eI == IntegrationAlgorithm::VV && inputrec->epc == PressureCoupling::ParrinelloRahman))
+     {
+         gmx_fatal(FARGS,
+                   "Requested Parrinello-Rahman barostat with md-vv. This combination is only "
+                   "available in the modular simulator. Some other selected options are, however, "
+                   "only available in the legacy simulator. Use a different pressure control "
+                   "algorithm.");
+     }
 -
      return isInputCompatible;
  }
  
Simple merge
index 900dcc7e5845224a7259a9e1e6576765b5fa87b1,269cc533a98318e15ec30d2e1135913573d77416..1e92998ad7025764ec2edc8f2ef62184487d9498
@@@ -239,71 -246,82 +239,70 @@@ gmx_bool gmx_mtop_atomloop_block_next(g
      return TRUE;
  }
  
 -typedef struct gmx_mtop_ilistloop
 +IListIterator::IListIterator(const gmx_mtop_t& mtop, size_t molblock) :
-     mtop_(&mtop),
-     mblock_(molblock)
++    mtop_(&mtop), mblock_(molblock)
  {
 -    const gmx_mtop_t* mtop;
 -    int               mblock;
 -} t_gmx_mtop_ilist;
 +}
  
 -gmx_mtop_ilistloop_t gmx_mtop_ilistloop_init(const gmx_mtop_t* mtop)
 +IListIterator& IListIterator::operator++()
  {
 -    struct gmx_mtop_ilistloop* iloop;
 -
 -    snew(iloop, 1);
 -
 -    iloop->mtop   = mtop;
 -    iloop->mblock = -1;
 -
 -    return iloop;
 +    mblock_++;
 +    return *this;
  }
  
 -gmx_mtop_ilistloop_t gmx_mtop_ilistloop_init(const gmx_mtop_t& mtop)
 +bool IListIterator::operator==(const IListIterator& o) const
  {
 -    return gmx_mtop_ilistloop_init(&mtop);
 +    return mtop_ == o.mtop_ && mblock_ == o.mblock_;
  }
  
 -static void gmx_mtop_ilistloop_destroy(gmx_mtop_ilistloop_t iloop)
 +const InteractionLists& IListProxy::list() const
  {
 -    sfree(iloop);
 +    // one past the end means we want to take the
 +    // intermolecular list instead.
 +    if (it_->mblock_ == it_->mtop_->molblock.size())
 +    {
 +        return *it_->mtop_->intermolecular_ilist;
 +    }
 +    else
 +    {
 +        return it_->mtop_->moltype[it_->mtop_->molblock[it_->mblock_].type].ilist;
 +    }
  }
  
 -const InteractionLists* gmx_mtop_ilistloop_next(gmx_mtop_ilistloop_t iloop, int* nmol)
 +int IListProxy::nmol() const
  {
 -    if (iloop == nullptr)
 +    // one past the end means we want to take the
 +    // intermolecular list instead.
 +    if (it_->mblock_ == it_->mtop_->molblock.size())
      {
 -        gmx_incons("gmx_mtop_ilistloop_next called without calling gmx_mtop_ilistloop_init");
 +        return 1;
      }
 -
 -    iloop->mblock++;
 -    if (iloop->mblock >= gmx::ssize(iloop->mtop->molblock))
 +    else
      {
 -        if (iloop->mblock == gmx::ssize(iloop->mtop->molblock) && iloop->mtop->bIntermolecularInteractions)
 -        {
 -            *nmol = 1;
 -            return iloop->mtop->intermolecular_ilist.get();
 -        }
 -
 -        gmx_mtop_ilistloop_destroy(iloop);
 -        return nullptr;
 +        return it_->mtop_->molblock[it_->mblock_].nmol;
      }
 -
 -    *nmol = iloop->mtop->molblock[iloop->mblock].nmol;
 -
 -    return &iloop->mtop->moltype[iloop->mtop->molblock[iloop->mblock].type].ilist;
  }
 -typedef struct gmx_mtop_ilistloop_all
 -{
 -    const gmx_mtop_t* mtop;
 -    size_t            mblock;
 -    int               mol;
 -    int               a_offset;
 -} t_gmx_mtop_ilist_all;
  
 -int gmx_mtop_ftype_count(const gmx_mtop_t* mtop, int ftype)
 +IListRange::IListRange(const gmx_mtop_t& mtop) : begin_(mtop), end_(mtop, mtop.molblock.size())
  {
 -    gmx_mtop_ilistloop_t iloop;
 -    int                  n, nmol;
 +    if (mtop.bIntermolecularInteractions)
 +    {
 +        end_ = IListIterator(mtop, mtop.molblock.size() + 1);
 +    }
 +}
  
 -    n = 0;
 +int gmx_mtop_ftype_count(const gmx_mtop_t& mtop, int ftype)
 +{
 +    int n = 0;
  
 -    iloop = gmx_mtop_ilistloop_init(mtop);
 -    while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol))
 +    for (const IListProxy il : IListRange(mtop))
      {
 -        n += nmol * (*il)[ftype].size() / (1 + NRAL(ftype));
 +        n += il.nmol() * il.list()[ftype].size() / (1 + NRAL(ftype));
      }
  
 -    if (mtop->bIntermolecularInteractions)
 +    if (mtop.bIntermolecularInteractions)
      {
 -        n += (*mtop->intermolecular_ilist)[ftype].size() / (1 + NRAL(ftype));
 +        n += (*mtop.intermolecular_ilist)[ftype].size() / (1 + NRAL(ftype));
      }
  
      return n;
Simple merge
index 147de9235a3aff188a0cee9248166327087518de,c3eae03170688a665b294e3ba574510f4df4fd6e..012527fa9609bb6574c024239c305fbdaf9a6993
@@@ -220,17 -173,17 +220,17 @@@ struct MDModulesNotifier
       * KeyValueTreeObjectBuilder enables writing of module internal data to
       *                           .tpr files.
       */
-     BuildMDModulesNotifier<EnergyCalculationFrequencyErrors*, IndexGroupsAndNames, KeyValueTreeObjectBuilder>::type preProcessingNotifier_;
 -    registerMdModuleNotification<EnergyCalculationFrequencyErrors*, const IndexGroupsAndNames&, KeyValueTreeObjectBuilder>::type preProcessingNotifications_;
++    BuildMDModulesNotifier<EnergyCalculationFrequencyErrors*, const IndexGroupsAndNames&, KeyValueTreeObjectBuilder>::type preProcessingNotifier_;
  
 -    /*! \brief Checkpointing callback functions.
 +    /*! \brief Handles subscribing and calling checkpointing callback functions.
       *
 -     * MdModulesCheckpointReadingDataOnMaster provides modules with their
 +     * MDModulesCheckpointReadingDataOnMaster provides modules with their
       *                                        checkpointed data on the master
       *                                        node and checkpoint file version
 -     * MdModulesCheckpointReadingBroadcast provides modules with a communicator
 +     * MDModulesCheckpointReadingBroadcast provides modules with a communicator
       *                                     and the checkpoint file version to
       *                                     distribute their data
 -     * MdModulesWriteCheckpointData provides the modules with a key-value-tree
 +     * MDModulesWriteCheckpointData provides the modules with a key-value-tree
       *                              builder to store their checkpoint data and
       *                              the checkpoint file version
       */