Make temperature and pressure coupling enums enum classes
authorPascal Merz <pascal.merz@me.com>
Tue, 9 Feb 2021 10:06:15 +0000 (10:06 +0000)
committerAndrey Alekseenko <al42and@gmail.com>
Tue, 9 Feb 2021 10:06:15 +0000 (10:06 +0000)
This makes the plain enums denoting the temperature and pressure
coupling enums enum classes. Most of this change is simple renaming,
changing etcXXX into TemperatureCoupling::XXX, and epcXXX into
PressureCoupling::XXX.

As these are the first of many enums in md_enums.h being refactored
into enum classes, this also introduces some reusable functionality,
including a templated function mapping enums to a string representing
the functionality, and helper functions used when reading inputrec
from file or comparing inputrec instances.

This keeps explicit static_casts from / to int in two places: When
serializing the inputrec, and when transferring the values over
multiple simulations.

36 files changed:
docs/doxygen/lib/modularsimulator.md
src/gromacs/domdec/domdec_setup.cpp
src/gromacs/domdec/partition.cpp
src/gromacs/fileio/enxio.cpp
src/gromacs/fileio/readinp.cpp
src/gromacs/fileio/readinp.h
src/gromacs/fileio/tpxio.cpp
src/gromacs/gmxpreprocess/grompp.cpp
src/gromacs/gmxpreprocess/readir.cpp
src/gromacs/mdlib/calc_verletbuf.cpp
src/gromacs/mdlib/constr.cpp
src/gromacs/mdlib/coupling.cpp
src/gromacs/mdlib/coupling.h
src/gromacs/mdlib/energyoutput.cpp
src/gromacs/mdlib/energyoutput.h
src/gromacs/mdlib/md_support.cpp
src/gromacs/mdlib/mdebin_bar.cpp
src/gromacs/mdlib/perf_est.cpp
src/gromacs/mdlib/tests/energyoutput.cpp
src/gromacs/mdlib/tests/leapfrogtestdata.cpp
src/gromacs/mdlib/update.cpp
src/gromacs/mdrun/md.cpp
src/gromacs/mdrun/replicaexchange.cpp
src/gromacs/mdrun/runner.cpp
src/gromacs/mdtypes/inputrec.cpp
src/gromacs/mdtypes/inputrec.h
src/gromacs/mdtypes/md_enums.cpp
src/gromacs/mdtypes/md_enums.h
src/gromacs/modularsimulator/modularsimulator.cpp
src/gromacs/modularsimulator/velocityscalingtemperaturecoupling.cpp
src/gromacs/modularsimulator/velocityscalingtemperaturecoupling.h
src/gromacs/nbnxm/pairlist_tuning.cpp
src/gromacs/taskassignment/decidegpuusage.cpp
src/gromacs/tools/report_methods.cpp
src/gromacs/utility/compare.h
src/gromacs/utility/iserializer.h

index c5f73730fa03dc6a74ae37feff3e7456e3cff5cb..108e127feaa904432d897cfc0121b3acabe2c11a 100644 (file)
@@ -200,7 +200,7 @@ the simulator algorithm.
             builder->add<ForceElement>();
              // We have a full state here (positions(t), velocities(t-dt/2), forces(t)
             builder->add<StatePropagatorData::Element>();
-            if (legacySimulatorData_->inputrec->etc == etcVRESCALE)
+            if (legacySimulatorData_->inputrec->etc == TemperatureCoupling::VRescale)
             {
                 builder->add<VRescaleThermostat>(-1, VRescaleThermostatUseFullStepKE::No);
             }
@@ -214,7 +214,7 @@ the simulator algorithm.
             builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::LeapFrog>>();
             // We have the energies at time t here
             builder->add<EnergyData::Element>();
-            if (legacySimulatorData_->inputrec->epc == epcPARRINELLORAHMAN)
+            if (legacySimulatorData_->inputrec->epc == PressureCoupling::ParrinelloRahman)
             {
                 builder->add<ParrinelloRahmanBarostat>(-1);
             }
index 200afa8a5f889f933ea3296558c95ecaa418e8e9..6cf0368a71afb4adb3e87b196a202c67ebcb58b6 100644 (file)
@@ -362,7 +362,8 @@ static float comm_cost_est(real               limit,
     {
         for (int j = i + 1; j < ddbox.npbcdim; j++)
         {
-            if (box[j][i] != 0 || ir.deform[j][i] != 0 || (ir.epc != epcNO && ir.compress[j][i] != 0))
+            if (box[j][i] != 0 || ir.deform[j][i] != 0
+                || (ir.epc != PressureCoupling::No && ir.compress[j][i] != 0))
             {
                 if (nc[j] > 1 && nc[i] == 1)
                 {
@@ -725,7 +726,7 @@ real getDDGridSetupCellSizeLimit(const gmx::MDLogger& mdlog,
                         "Scaling the initial minimum size with 1/%g (option -dds) = %g", dlb_scale, 1 / dlb_scale);
         cellSizeLimit /= dlb_scale;
     }
-    else if (ir.epc != epcNO)
+    else if (ir.epc != PressureCoupling::No)
     {
         GMX_LOG(mdlog.info)
                 .appendTextFormatted(
index 9640d2756bd9eb948444e5321d429f0ebb02370f..06b4937cafcf0a6c98e288a5a8c1664b6c0734de 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,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.
@@ -2761,7 +2761,7 @@ void dd_partition_system(FILE*                     fplog,
     // TODO if the update code becomes accessible here, use
     // upd->deform for this logic.
     bBoxChanged = (bMasterState || inputrecDeform(ir));
-    if (ir->epc != epcNO)
+    if (ir->epc != PressureCoupling::No)
     {
         /* With nstpcouple > 1 pressure coupling happens.
          * one step after calculating the pressure.
@@ -2799,7 +2799,7 @@ void dd_partition_system(FILE*                     fplog,
          * Since it requires (possibly expensive) global communication,
          * we might want to do DLB less frequently.
          */
-        if (bBoxChanged || ir->epc != epcNO)
+        if (bBoxChanged || ir->epc != PressureCoupling::No)
         {
             bDoDLB = bBoxChanged;
         }
index 56d2279c7b80547cca717bd12dbde70c707b1cb1..278306e20840fc0622458c40c6e275ea8d406f83 100644 (file)
@@ -4,7 +4,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 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,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.
@@ -1198,7 +1198,7 @@ void get_enx_state(const char* fn, real t, const SimulationGroups& groups, t_inp
     }
 
     npcoupl = TRICLINIC(ir->compress) ? 6 : 3;
-    if (ir->epc == epcPARRINELLORAHMAN)
+    if (ir->epc == PressureCoupling::ParrinelloRahman)
     {
         clear_mat(state->boxv);
         for (i = 0; i < npcoupl; i++)
@@ -1208,7 +1208,7 @@ void get_enx_state(const char* fn, real t, const SimulationGroups& groups, t_inp
         fprintf(stderr, "\nREAD %d BOX VELOCITIES FROM %s\n\n", npcoupl, fn);
     }
 
-    if (ir->etc == etcNOSEHOOVER)
+    if (ir->etc == TemperatureCoupling::NoseHoover)
     {
         char cns[20];
 
index 1da9fd268afd3f4cf98d5ce676ffdbb536370872..bf47bcd36a8b6d5433339e98e68dccf5bac40279 100644 (file)
@@ -4,7 +4,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 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,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.
@@ -308,7 +308,7 @@ void mark_einp_set(gmx::ArrayRef<t_inpfile> inp, const char* name)
     }
 }
 
-static int get_einp(std::vector<t_inpfile>* inp, const char* name)
+int get_einp(std::vector<t_inpfile>* inp, const char* name)
 {
     std::vector<t_inpfile>& inpRef   = *inp;
     bool                    notfound = false;
index 37034e7c7dc234a5afe3739cf2091c0ec165a8b7..5c2e8e5f176d2c3aa4ea72a8a7b4442fa56be5c3 100644 (file)
@@ -4,7 +4,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 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,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.
@@ -160,6 +160,22 @@ int get_eeenum(std::vector<t_inpfile>* inp, const std::string& name, const char*
 int get_eenum(std::vector<t_inpfile>* inp, const char* name, const char** defs);
 /* defs must be NULL terminated */
 
+//! Get index of option `name`. Exposed here so that `getEnum` can access it.
+int get_einp(std::vector<t_inpfile>* inp, const char* name);
+
+/*! \brief Read option from input and return corresponding enum value
+ *
+ * If the option is not set, return the first value of the enum as default.
+ *
+ * \tparam EnumType  The type of enum to be returned
+ * \param[in]  inp   The input file vector
+ * \param[in]  name  The name of the option to be read
+ * \param[out] wi    Handler for context-sensitive warnings.
+ * \return  Enum value corresponding to read input
+ */
+template<typename EnumType>
+EnumType getEnum(std::vector<t_inpfile>* inp, const char* name, warninp* wi);
+
 //! Replace for macro CCTYPE, prints comment string after newline
 void printStringNewline(std::vector<t_inpfile>* inp, const char* line);
 //! Replace for macro CTYPE, prints comment string
index d50be6feb9237846ed867c7430a23bec01e75c31..b963ed295b94668e9bd3027595a9f51cddc27b67 100644 (file)
@@ -1306,7 +1306,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
         serializer->doInt(&ir->ljpme_combination_rule);
     }
     serializer->doBool(&ir->bContinuation);
-    serializer->doInt(&ir->etc);
+    serializer->doEnumAsInt(&ir->etc);
     /* before version 18, ir->etc was a gmx_bool (ir->btc),
      * but the values 0 and 1 still mean no and
      * berendsen temperature coupling, respectively.
@@ -1323,7 +1323,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     {
         ir->nsttcouple = ir->nstcalcenergy;
     }
-    serializer->doInt(&ir->epc);
+    serializer->doEnumAsInt(&ir->epc);
     serializer->doInt(&ir->epct);
     if (file_version >= 71)
     {
index 441007676f9bac4c79484782bcf9e16ae2aca3c3..2f6f29e3e0e1f92a0f5d8568e8bab10cf98bc2c9 100644 (file)
@@ -907,7 +907,7 @@ static void cont_status(const char*             slog,
     GMX_LOG(logger.info).asParagraph().appendTextFormatted("Using frame at t = %g ps", use_time);
     GMX_LOG(logger.info).asParagraph().appendTextFormatted("Starting time for run is %g ps", ir->init_t);
 
-    if ((ir->epc != epcNO || ir->etc == etcNOSEHOOVER) && ener)
+    if ((ir->epc != PressureCoupling::No || ir->etc == TemperatureCoupling::NoseHoover) && ener)
     {
         get_enx_state(ener, use_time, sys->groups, ir, state);
         preserve_box_shape(ir, state->box_rel, state->boxv);
@@ -2035,7 +2035,7 @@ int gmx_grompp(int argc, char* argv[])
         }
     }
 
-    if (EI_SD(ir->eI) && ir->etc != etcNO)
+    if (EI_SD(ir->eI) && ir->etc != TemperatureCoupling::No)
     {
         warning_note(wi, "Temperature coupling is ignored with SD integrators.");
     }
@@ -2047,14 +2047,14 @@ int gmx_grompp(int argc, char* argv[])
 
     if (nint_ftype(&sys, mi, F_POSRES) > 0 || nint_ftype(&sys, mi, F_FBPOSRES) > 0)
     {
-        if (ir->epc == epcPARRINELLORAHMAN || ir->epc == epcMTTK)
+        if (ir->epc == PressureCoupling::ParrinelloRahman || ir->epc == PressureCoupling::Mttk)
         {
             std::string warningMessage = gmx::formatString(
                     "You are combining position restraints with %s pressure coupling, which can "
                     "lead to instabilities. If you really want to combine position restraints with "
                     "pressure coupling, we suggest to use %s pressure coupling instead.",
-                    EPCOUPLTYPE(ir->epc),
-                    EPCOUPLTYPE(epcBERENDSEN));
+                    enumValueToString(ir->epc),
+                    enumValueToString(PressureCoupling::Berendsen));
             warning_note(wi, warningMessage);
         }
 
@@ -2200,7 +2200,7 @@ int gmx_grompp(int argc, char* argv[])
         {
             real buffer_temp;
 
-            if (EI_MD(ir->eI) && ir->etc == etcNO)
+            if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No)
             {
                 if (bGenVel)
                 {
@@ -2232,7 +2232,7 @@ int gmx_grompp(int argc, char* argv[])
                 buffer_temp = get_max_reference_temp(ir, wi);
             }
 
-            if (EI_MD(ir->eI) && ir->etc == etcNO && buffer_temp == 0)
+            if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No && buffer_temp == 0)
             {
                 /* NVE with initial T=0: we add a fixed ratio to rlist.
                  * Since we don't actually use verletbuf_tol, we set it to -1
@@ -2248,7 +2248,7 @@ int gmx_grompp(int argc, char* argv[])
                  * Note that we can't warn when nsteps=0, since we don't
                  * know how many steps the user intends to run.
                  */
-                if (EI_MD(ir->eI) && ir->etc == etcNO && ir->nstlist > 1 && ir->nsteps > 0)
+                if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No && ir->nstlist > 1 && ir->nsteps > 0)
                 {
                     const real driftTolerance = 0.01;
                     /* We use 2 DOF per atom = 2kT pot+kin energy,
@@ -2393,7 +2393,7 @@ int gmx_grompp(int argc, char* argv[])
     if (ir->bDoAwh)
     {
         tensor compressibility = { { 0 } };
-        if (ir->epc != epcNO)
+        if (ir->epc != PressureCoupling::No)
         {
             copy_mat(ir->compress, compressibility);
         }
index 4ac809a63f6c54f6cc893b97d86225ccb0cf6975..603fae0cdb70794af898c92431a6f6d437502fa8 100644 (file)
@@ -450,7 +450,7 @@ void check_ir(const char*                   mdparin,
     /* GENERAL INTEGRATOR STUFF */
     if (!EI_MD(ir->eI))
     {
-        if (ir->etc != etcNO)
+        if (ir->etc != TemperatureCoupling::No)
         {
             if (EI_RANDOM(ir->eI))
             {
@@ -458,7 +458,7 @@ void check_ir(const char*                   mdparin,
                         "Setting tcoupl from '%s' to 'no'. %s handles temperature coupling "
                         "implicitly. See the documentation for more information on which "
                         "parameters affect temperature for %s.",
-                        etcoupl_names[ir->etc],
+                        enumValueToString(ir->etc),
                         ei_names[ir->eI],
                         ei_names[ir->eI]);
             }
@@ -467,12 +467,12 @@ void check_ir(const char*                   mdparin,
                 sprintf(warn_buf,
                         "Setting tcoupl from '%s' to 'no'. Temperature coupling does not apply to "
                         "%s.",
-                        etcoupl_names[ir->etc],
+                        enumValueToString(ir->etc),
                         ei_names[ir->eI]);
             }
             warning_note(wi, warn_buf);
         }
-        ir->etc = etcNO;
+        ir->etc = TemperatureCoupling::No;
     }
     if (ir->eI == eiVVAK)
     {
@@ -486,15 +486,15 @@ void check_ir(const char*                   mdparin,
     }
     if (!EI_DYNAMICS(ir->eI))
     {
-        if (ir->epc != epcNO)
+        if (ir->epc != PressureCoupling::No)
         {
             sprintf(warn_buf,
                     "Setting pcoupl from '%s' to 'no'. Pressure coupling does not apply to %s.",
-                    epcoupl_names[ir->epc],
+                    enumValueToString(ir->epc),
                     ei_names[ir->eI]);
             warning_note(wi, warn_buf);
         }
-        ir->epc = epcNO;
+        ir->epc = PressureCoupling::No;
     }
     if (EI_DYNAMICS(ir->eI))
     {
@@ -539,7 +539,7 @@ void check_ir(const char*                   mdparin,
             ir->nstcalcenergy = min_nst;
         }
 
-        if (ir->epc != epcNO)
+        if (ir->epc != PressureCoupling::No)
         {
             if (ir->nstpcouple < 0)
             {
@@ -649,12 +649,12 @@ void check_ir(const char*                   mdparin,
 
         /* check compatability of the temperature coupling with simulated tempering */
 
-        if (ir->etc == etcNOSEHOOVER)
+        if (ir->etc == TemperatureCoupling::NoseHoover)
         {
             sprintf(warn_buf,
                     "Nose-Hoover based temperature control such as [%s] my not be "
                     "entirelyconsistent with simulated tempering",
-                    etcoupl_names[ir->etc]);
+                    enumValueToString(ir->etc));
             warning_note(wi, warn_buf);
         }
 
@@ -969,10 +969,10 @@ void check_ir(const char*                   mdparin,
     {
         if (ir->pbcType == PbcType::No)
         {
-            if (ir->epc != epcNO)
+            if (ir->epc != PressureCoupling::No)
             {
                 warning(wi, "Turning off pressure coupling for vacuum system");
-                ir->epc = epcNO;
+                ir->epc = PressureCoupling::No;
             }
         }
         else
@@ -980,7 +980,7 @@ void check_ir(const char*                   mdparin,
             sprintf(err_buf,
                     "Can not have pressure coupling with pbc=%s",
                     c_pbcTypeNames[ir->pbcType].c_str());
-            CHECK(ir->epc != epcNO);
+            CHECK(ir->epc != PressureCoupling::No);
         }
         sprintf(err_buf, "Can not have Ewald with pbc=%s", c_pbcTypeNames[ir->pbcType].c_str());
         CHECK(EEL_FULL(ir->coulombtype));
@@ -1069,15 +1069,15 @@ void check_ir(const char*                   mdparin,
     }
 
     /* TEMPERATURE COUPLING */
-    if (ir->etc == etcYES)
+    if (ir->etc == TemperatureCoupling::Yes)
     {
-        ir->etc = etcBERENDSEN;
+        ir->etc = TemperatureCoupling::Berendsen;
         warning_note(wi,
                      "Old option for temperature coupling given: "
                      "changing \"yes\" to \"Berendsen\"\n");
     }
 
-    if ((ir->etc == etcNOSEHOOVER) || (ir->epc == epcMTTK))
+    if ((ir->etc == TemperatureCoupling::NoseHoover) || (ir->epc == PressureCoupling::Mttk))
     {
         if (ir->opts.nhchainlength < 1)
         {
@@ -1089,7 +1089,7 @@ void check_ir(const char*                   mdparin,
             warning(wi, warn_buf);
         }
 
-        if (ir->etc == etcNOSEHOOVER && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
+        if (ir->etc == TemperatureCoupling::NoseHoover && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
         {
             warning_note(
                     wi,
@@ -1115,17 +1115,17 @@ void check_ir(const char*                   mdparin,
     {
         sprintf(err_buf,
                 "%s temperature control not supported for integrator %s.",
-                etcoupl_names[ir->etc],
+                enumValueToString(ir->etc),
                 ei_names[ir->eI]);
         CHECK(!(EI_VV(ir->eI)));
 
-        if (ir->nstcomm > 0 && (ir->etc == etcANDERSEN))
+        if (ir->nstcomm > 0 && (ir->etc == TemperatureCoupling::Andersen))
         {
             sprintf(warn_buf,
                     "Center of mass removal not necessary for %s.  All velocities of coupled "
                     "groups are rerandomized periodically, so flying ice cube errors will not "
                     "occur.",
-                    etcoupl_names[ir->etc]);
+                    enumValueToString(ir->etc));
             warning_note(wi, warn_buf);
         }
 
@@ -1133,21 +1133,22 @@ void check_ir(const char*                   mdparin,
                 "nstcomm must be 1, not %d for %s, as velocities of atoms in coupled groups are "
                 "randomized every time step",
                 ir->nstcomm,
-                etcoupl_names[ir->etc]);
-        CHECK(ir->nstcomm > 1 && (ir->etc == etcANDERSEN));
+                enumValueToString(ir->etc));
+        CHECK(ir->nstcomm > 1 && (ir->etc == TemperatureCoupling::Andersen));
     }
 
-    if (ir->etc == etcBERENDSEN)
+    if (ir->etc == TemperatureCoupling::Berendsen)
     {
         sprintf(warn_buf,
                 "The %s thermostat does not generate the correct kinetic energy distribution. You "
                 "might want to consider using the %s thermostat.",
-                ETCOUPLTYPE(ir->etc),
-                ETCOUPLTYPE(etcVRESCALE));
+                enumValueToString(ir->etc),
+                enumValueToString(TemperatureCoupling::VRescale));
         warning_note(wi, warn_buf);
     }
 
-    if ((ir->etc == etcNOSEHOOVER || ETC_ANDERSEN(ir->etc)) && ir->epc == epcBERENDSEN)
+    if ((ir->etc == TemperatureCoupling::NoseHoover || ETC_ANDERSEN(ir->etc))
+        && ir->epc == PressureCoupling::Berendsen)
     {
         sprintf(warn_buf,
                 "Using Berendsen pressure coupling invalidates the "
@@ -1156,15 +1157,15 @@ void check_ir(const char*                   mdparin,
     }
 
     /* PRESSURE COUPLING */
-    if (ir->epc == epcISOTROPIC)
+    if (ir->epc == PressureCoupling::Isotropic)
     {
-        ir->epc = epcBERENDSEN;
+        ir->epc = PressureCoupling::Berendsen;
         warning_note(wi,
                      "Old option for pressure coupling given: "
                      "changing \"Isotropic\" to \"Berendsen\"\n");
     }
 
-    if (ir->epc != epcNO)
+    if (ir->epc != PressureCoupling::No)
     {
         dt_pcoupl = ir->nstpcouple * ir->delta_t;
 
@@ -1176,7 +1177,7 @@ void check_ir(const char*                   mdparin,
             sprintf(warn_buf,
                     "For proper integration of the %s barostat, tau-p (%g) should be at least %d "
                     "times larger than nstpcouple*dt (%g)",
-                    EPCOUPLTYPE(ir->epc),
+                    enumValueToString(ir->epc),
                     ir->tau_p,
                     pcouple_min_integration_steps(ir->epc),
                     dt_pcoupl);
@@ -1186,12 +1187,12 @@ void check_ir(const char*                   mdparin,
         sprintf(err_buf,
                 "compressibility must be > 0 when using pressure"
                 " coupling %s\n",
-                EPCOUPLTYPE(ir->epc));
+                enumValueToString(ir->epc));
         CHECK(ir->compress[XX][XX] < 0 || ir->compress[YY][YY] < 0 || ir->compress[ZZ][ZZ] < 0
               || (trace(ir->compress) == 0 && ir->compress[YY][XX] <= 0 && ir->compress[ZZ][XX] <= 0
                   && ir->compress[ZZ][YY] <= 0));
 
-        if (epcPARRINELLORAHMAN == ir->epc && opts->bGenVel)
+        if (PressureCoupling::ParrinelloRahman == ir->epc && opts->bGenVel)
         {
             sprintf(warn_buf,
                     "You are generating velocities so I am assuming you "
@@ -1201,14 +1202,14 @@ void check_ir(const char*                   mdparin,
                     "equilibrating first with Berendsen pressure coupling. If "
                     "you are not equilibrating the system, you can probably "
                     "ignore this warning.",
-                    epcoupl_names[ir->epc]);
+                    enumValueToString(ir->epc));
             warning(wi, warn_buf);
         }
     }
 
     if (!EI_VV(ir->eI))
     {
-        if (ir->epc == epcMTTK)
+        if (ir->epc == PressureCoupling::Mttk)
         {
             warning_error(wi, "MTTK pressure coupling requires a Velocity-verlet integrator");
         }
@@ -1805,6 +1806,53 @@ static void read_expandedparams(std::vector<t_inpfile>* inp, t_expanded* expand,
     expand->bWLoneovert   = (get_eeenum(inp, "wl-oneovert", yesno_names, wi) != 0);
 }
 
+template<typename EnumType>
+EnumType getEnum(std::vector<t_inpfile>* inp, const char* name, warninp_t wi)
+{
+    // If we there's no valid option, we'll use the first enum entry as default.
+    // Note, this assumes the enum is zero based, which is also assumed by
+    // EnumerationWrapper and EnumerationArray.
+    const auto  defaultEnumValue = EnumType::Default;
+    const auto& defaultName      = enumValueToString(defaultEnumValue);
+    // Get index of option in input
+    const auto ii = get_einp(inp, name);
+    if (ii == -1)
+    {
+        // If the option wasn't set, we use the first enum entry as default
+        inp->back().value_.assign(defaultName);
+        return defaultEnumValue;
+    }
+
+    // Check if option string can be mapped to a valid enum value
+    const auto* optionString = (*inp)[ii].value_.c_str();
+    for (auto enumValue : gmx::EnumerationWrapper<EnumType>{})
+    {
+        if (gmx_strcasecmp_min(enumValueToString(enumValue), optionString) == 0)
+        {
+            return enumValue;
+        }
+    }
+
+    // If we get here, the option set is invalid. Print error.
+    std::string errorMessage = gmx::formatString(
+            "Invalid enum '%s' for variable %s, using '%s'\n", optionString, name, defaultName);
+    errorMessage += gmx::formatString("Next time, use one of:");
+    for (auto enumValue : gmx::EnumerationWrapper<EnumType>{})
+    {
+        errorMessage += gmx::formatString(" '%s'", enumValueToString(enumValue));
+    }
+    if (wi != nullptr)
+    {
+        warning_error(wi, errorMessage);
+    }
+    else
+    {
+        fprintf(stderr, "%s\n", errorMessage.c_str());
+    }
+    (*inp)[ii].value_.assign(defaultName);
+    return defaultEnumValue;
+}
+
 /*! \brief Return whether an end state with the given coupling-lambda
  * value describes fully-interacting VDW.
  *
@@ -2075,7 +2123,7 @@ void get_ir(const char*     mdparin,
     /* Coupling stuff */
     printStringNewline(&inp, "OPTIONS FOR WEAK COUPLING ALGORITHMS");
     printStringNoNewline(&inp, "Temperature coupling");
-    ir->etc                = get_eeenum(&inp, "tcoupl", etcoupl_names, wi);
+    ir->etc                = getEnum<TemperatureCoupling>(&inp, "tcoupl", wi);
     ir->nsttcouple         = get_eint(&inp, "nsttcouple", -1, wi);
     ir->opts.nhchainlength = get_eint(&inp, "nh-chain-length", 10, wi);
     ir->bPrintNHChains = (get_eeenum(&inp, "print-nose-hoover-chain-variables", yesno_names, wi) != 0);
@@ -2085,7 +2133,7 @@ void get_ir(const char*     mdparin,
     setStringEntry(&inp, "tau-t", inputrecStrings->tau_t, nullptr);
     setStringEntry(&inp, "ref-t", inputrecStrings->ref_t, nullptr);
     printStringNoNewline(&inp, "pressure coupling");
-    ir->epc        = get_eeenum(&inp, "pcoupl", epcoupl_names, wi);
+    ir->epc        = getEnum<PressureCoupling>(&inp, "pcoupl", wi);
     ir->epct       = get_eeenum(&inp, "pcoupltype", epcoupltype_names, wi);
     ir->nstpcouple = get_eint(&inp, "nstpcouple", -1, wi);
     printStringNoNewline(&inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)");
@@ -2450,7 +2498,7 @@ void get_ir(const char*     mdparin,
         {
             dumdub[m][i] = 0.0;
         }
-        if (ir->epc)
+        if (ir->epc != PressureCoupling::No)
         {
             switch (ir->epct)
             {
@@ -2667,7 +2715,7 @@ void get_ir(const char*     mdparin,
     ir->deform[YY][XX] = dumdub[0][3];
     ir->deform[ZZ][XX] = dumdub[0][4];
     ir->deform[ZZ][YY] = dumdub[0][5];
-    if (ir->epc != epcNO)
+    if (ir->epc != PressureCoupling::No)
     {
         for (i = 0; i < 3; i++)
         {
@@ -3498,7 +3546,7 @@ void do_index(const char*                   mdparin,
                 warning_error(wi, warn_buf);
             }
 
-            if (ir->etc != etcVRESCALE && ir->opts.tau_t[i] == 0)
+            if (ir->etc != TemperatureCoupling::VRescale && ir->opts.tau_t[i] == 0)
             {
                 warning_note(
                         wi,
@@ -3511,23 +3559,23 @@ void do_index(const char*                   mdparin,
                 tau_min = std::min(tau_min, ir->opts.tau_t[i]);
             }
         }
-        if (ir->etc != etcNO && ir->nsttcouple == -1)
+        if (ir->etc != TemperatureCoupling::No && ir->nsttcouple == -1)
         {
             ir->nsttcouple = ir_optimal_nsttcouple(ir);
         }
 
         if (EI_VV(ir->eI))
         {
-            if ((ir->etc == etcNOSEHOOVER) && (ir->epc == epcBERENDSEN))
+            if ((ir->etc == TemperatureCoupling::NoseHoover) && (ir->epc == PressureCoupling::Berendsen))
             {
                 gmx_fatal(FARGS,
                           "Cannot do Nose-Hoover temperature with Berendsen pressure control with "
                           "md-vv; use either vrescale temperature with berendsen pressure or "
                           "Nose-Hoover temperature with MTTK pressure");
             }
-            if (ir->epc == epcMTTK)
+            if (ir->epc == PressureCoupling::Mttk)
             {
-                if (ir->etc != etcNOSEHOOVER)
+                if (ir->etc != TemperatureCoupling::NoseHoover)
                 {
                     gmx_fatal(FARGS,
                               "Cannot do MTTK pressure coupling without Nose-Hoover temperature "
@@ -3572,7 +3620,7 @@ void do_index(const char*                   mdparin,
                 sprintf(warn_buf,
                         "For proper integration of the %s thermostat, tau-t (%g) should be at "
                         "least %d times larger than nsttcouple*dt (%g)",
-                        ETCOUPLTYPE(ir->etc),
+                        enumValueToString(ir->etc),
                         tau_min,
                         nstcmin,
                         ir->nsttcouple * ir->delta_t);
@@ -4282,7 +4330,8 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
     }
 
     if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0 && ir->nstlist > 1
-        && ((EI_MD(ir->eI) || EI_SD(ir->eI)) && (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN)))
+        && ((EI_MD(ir->eI) || EI_SD(ir->eI))
+            && (ir->etc == TemperatureCoupling::VRescale || ir->etc == TemperatureCoupling::Berendsen)))
     {
         /* Check if a too small Verlet buffer might potentially
          * cause more drift than the thermostat can couple off.
@@ -4347,7 +4396,7 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
             CHECK(ir->opts.tau_t[i] < 0);
         }
 
-        if (ir->etc == etcANDERSENMASSIVE && ir->comm_mode != ecmNO)
+        if (ir->etc == TemperatureCoupling::AndersenMassive && ir->comm_mode != ecmNO)
         {
             for (i = 0; i < ir->opts.ngtc; i++)
             {
@@ -4358,7 +4407,7 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
                         "randomized every time step. The input tau_t (%8.3f) leads to %d steps per "
                         "randomization",
                         i,
-                        etcoupl_names[ir->etc],
+                        enumValueToString(ir->etc),
                         ir->nstcomm,
                         ir->opts.tau_t[i],
                         nsteps);
@@ -4375,7 +4424,7 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
                 "rounding errors can lead to build up of kinetic energy of the center of mass");
     }
 
-    if (ir->epc == epcPARRINELLORAHMAN && ir->etc == etcNOSEHOOVER)
+    if (ir->epc == PressureCoupling::ParrinelloRahman && ir->etc == TemperatureCoupling::NoseHoover)
     {
         real tau_t_max = 0;
         for (int g = 0; g < ir->opts.ngtc; g++)
@@ -4387,8 +4436,8 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
             std::string message = gmx::formatString(
                     "With %s T-coupling and %s p-coupling, "
                     "%s (%g) should be at least twice as large as %s (%g) to avoid resonances",
-                    etcoupl_names[ir->etc],
-                    epcoupl_names[ir->epc],
+                    enumValueToString(ir->etc),
+                    enumValueToString(ir->epc),
                     "tau-p",
                     ir->tau_p,
                     "tau-t",
@@ -4398,7 +4447,7 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
     }
 
     /* Check for pressure coupling with absolute position restraints */
-    if (ir->epc != epcNO && ir->refcoord_scaling == erscNO)
+    if (ir->epc != PressureCoupling::No && ir->refcoord_scaling == erscNO)
     {
         absolute_reference(ir, sys, TRUE, AbsRef);
         {
@@ -4501,7 +4550,7 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
         {
             for (m = 0; m <= i; m++)
             {
-                if ((ir->epc != epcNO && ir->compress[i][m] != 0) || ir->deform[i][m] != 0)
+                if ((ir->epc != PressureCoupling::No && ir->compress[i][m] != 0) || ir->deform[i][m] != 0)
                 {
                     for (c = 0; c < ir->pull->ncoord; c++)
                     {
@@ -4545,7 +4594,8 @@ void double_check(t_inputrec* ir, matrix box, bool bHasNormalConstraints, bool b
     if ((ir->eConstrAlg == econtLINCS) && bHasNormalConstraints)
     {
         /* If we have Lincs constraints: */
-        if (ir->eI == eiMD && ir->etc == etcNO && ir->eConstrAlg == econtLINCS && ir->nLincsIter == 1)
+        if (ir->eI == eiMD && ir->etc == TemperatureCoupling::No && ir->eConstrAlg == econtLINCS
+            && ir->nLincsIter == 1)
         {
             sprintf(warn_buf,
                     "For energy conservation with LINCS, lincs_iter should be 2 or larger.\n");
@@ -4559,13 +4609,13 @@ void double_check(t_inputrec* ir, matrix box, bool bHasNormalConstraints, bool b
                     ei_names[ir->eI]);
             warning_note(wi, warn_buf);
         }
-        if (ir->epc == epcMTTK)
+        if (ir->epc == PressureCoupling::Mttk)
         {
             warning_error(wi, "MTTK not compatible with lincs -- use shake instead.");
         }
     }
 
-    if (bHasAnyConstraints && ir->epc == epcMTTK)
+    if (bHasAnyConstraints && ir->epc == PressureCoupling::Mttk)
     {
         warning_error(wi, "Constraints are not implemented with MTTK pressure control.");
     }
index b904b9c409df241fa7ef916da8c64696b4ff837c..cad2c62caac6c75d5801a1ef76e01be2c78fe032 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 2012-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, 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.
@@ -1322,7 +1322,7 @@ real minCellSizeForAtomDisplacement(const gmx_mtop_t&      mtop,
                                     PartitioningPerMoltype updateGrouping,
                                     real                   chanceRequested)
 {
-    if (!EI_DYNAMICS(ir.eI) || (EI_MD(ir.eI) && ir.etc == etcNO))
+    if (!EI_DYNAMICS(ir.eI) || (EI_MD(ir.eI) && ir.etc == TemperatureCoupling::No))
     {
         return minCellSizeFromPairlistBuffer(ir);
     }
index 3c78f53cd34d9d22a90408af773a63b9335a79db..391fe432d67fe190d30d6ac8b17f3acd0399e34f 100644 (file)
@@ -4,7 +4,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 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,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.
@@ -1106,7 +1106,7 @@ Constraints::Impl::Impl(const gmx_mtop_t&     mtop_p,
     nrnb(nrnb_p),
     wcycle(wcycle_p)
 {
-    if (numConstraints + numSettles > 0 && ir.epc == epcMTTK)
+    if (numConstraints + numSettles > 0 && ir.epc == PressureCoupling::Mttk)
     {
         gmx_fatal(FARGS, "Constraints are not implemented with MTTK pressure control.");
     }
index 29af5cb4798acdeef71de80ef690539c5eacc8e5..b49e86103e907051c15e97df5e6a662f24e0e33d 100644 (file)
@@ -114,7 +114,7 @@ void update_tcouple(int64_t           step,
 
     // For VV temperature coupling parameters are updated on the current
     // step, for the others - one step before.
-    if (inputrec->etc == etcNO)
+    if (inputrec->etc == TemperatureCoupling::No)
     {
         doTemperatureCoupling = false;
     }
@@ -136,11 +136,13 @@ void update_tcouple(int64_t           step,
         //      subroutines
         switch (inputrec->etc)
         {
-            case etcNO: break;
-            case etcBERENDSEN:
+            case TemperatureCoupling::No:
+            case TemperatureCoupling::Andersen:
+            case TemperatureCoupling::AndersenMassive: break;
+            case TemperatureCoupling::Berendsen:
                 berendsen_tcoupl(inputrec, ekind, dttc, state->therm_integral);
                 break;
-            case etcNOSEHOOVER:
+            case TemperatureCoupling::NoseHoover:
                 nosehoover_tcoupl(&(inputrec->opts),
                                   ekind,
                                   dttc,
@@ -148,9 +150,10 @@ void update_tcouple(int64_t           step,
                                   state->nosehoover_vxi.data(),
                                   MassQ);
                 break;
-            case etcVRESCALE:
+            case TemperatureCoupling::VRescale:
                 vrescale_tcoupl(inputrec, step, ekind, dttc, state->therm_integral.data());
                 break;
+            default: gmx_fatal(FARGS, "Unknown temperature coupling algorithm");
         }
         /* rescale in place here */
         if (EI_VV(inputrec->eI))
@@ -180,7 +183,7 @@ void update_pcouple_before_coordinates(FILE*             fplog,
     /* Berendsen P-coupling is completely handled after the coordinate update.
      * Trotter P-coupling is handled by separate calls to trotter_update().
      */
-    if (inputrec->epc == epcPARRINELLORAHMAN
+    if (inputrec->epc == PressureCoupling::ParrinelloRahman
         && do_per_step(step + inputrec->nstpcouple - 1, inputrec->nstpcouple))
     {
         real dtpc = inputrec->nstpcouple * inputrec->delta_t;
@@ -213,62 +216,63 @@ void update_pcouple_after_coordinates(FILE*                fplog,
     /* now update boxes */
     switch (inputrec->epc)
     {
-        case (epcNO): break;
-        case (epcBERENDSEN):
+        case (PressureCoupling::No): break;
+        case (PressureCoupling::Berendsen):
             if (do_per_step(step, inputrec->nstpcouple))
             {
                 real dtpc = inputrec->nstpcouple * dt;
-                pressureCouplingCalculateScalingMatrix<epcBERENDSEN>(fplog,
-                                                                     step,
-                                                                     inputrec,
-                                                                     dtpc,
-                                                                     pressure,
-                                                                     state->box,
-                                                                     forceVirial,
-                                                                     constraintVirial,
-                                                                     pressureCouplingMu,
-                                                                     &state->baros_integral);
-                pressureCouplingScaleBoxAndCoordinates<epcBERENDSEN>(inputrec,
-                                                                     pressureCouplingMu,
-                                                                     state->box,
-                                                                     state->box_rel,
-                                                                     start,
-                                                                     homenr,
-                                                                     state->x.rvec_array(),
-                                                                     nullptr,
-                                                                     md->cFREEZE,
-                                                                     nrnb,
-                                                                     scaleCoordinates);
+                pressureCouplingCalculateScalingMatrix<PressureCoupling::Berendsen>(fplog,
+                                                                                    step,
+                                                                                    inputrec,
+                                                                                    dtpc,
+                                                                                    pressure,
+                                                                                    state->box,
+                                                                                    forceVirial,
+                                                                                    constraintVirial,
+                                                                                    pressureCouplingMu,
+                                                                                    &state->baros_integral);
+                pressureCouplingScaleBoxAndCoordinates<PressureCoupling::Berendsen>(inputrec,
+                                                                                    pressureCouplingMu,
+                                                                                    state->box,
+                                                                                    state->box_rel,
+                                                                                    start,
+                                                                                    homenr,
+                                                                                    state->x.rvec_array(),
+                                                                                    nullptr,
+                                                                                    md->cFREEZE,
+                                                                                    nrnb,
+                                                                                    scaleCoordinates);
             }
             break;
-        case (epcCRESCALE):
+        case (PressureCoupling::CRescale):
             if (do_per_step(step, inputrec->nstpcouple))
             {
                 real dtpc = inputrec->nstpcouple * dt;
-                pressureCouplingCalculateScalingMatrix<epcCRESCALE>(fplog,
-                                                                    step,
-                                                                    inputrec,
-                                                                    dtpc,
-                                                                    pressure,
-                                                                    state->box,
-                                                                    forceVirial,
-                                                                    constraintVirial,
-                                                                    pressureCouplingMu,
-                                                                    &state->baros_integral);
-                pressureCouplingScaleBoxAndCoordinates<epcCRESCALE>(inputrec,
-                                                                    pressureCouplingMu,
-                                                                    state->box,
-                                                                    state->box_rel,
-                                                                    start,
-                                                                    homenr,
-                                                                    state->x.rvec_array(),
-                                                                    state->v.rvec_array(),
-                                                                    md->cFREEZE,
-                                                                    nrnb,
-                                                                    scaleCoordinates);
+                pressureCouplingCalculateScalingMatrix<PressureCoupling::CRescale>(fplog,
+                                                                                   step,
+                                                                                   inputrec,
+                                                                                   dtpc,
+                                                                                   pressure,
+                                                                                   state->box,
+                                                                                   forceVirial,
+                                                                                   constraintVirial,
+                                                                                   pressureCouplingMu,
+                                                                                   &state->baros_integral);
+                pressureCouplingScaleBoxAndCoordinates<PressureCoupling::CRescale>(
+                        inputrec,
+                        pressureCouplingMu,
+                        state->box,
+                        state->box_rel,
+                        start,
+                        homenr,
+                        state->x.rvec_array(),
+                        state->v.rvec_array(),
+                        md->cFREEZE,
+                        nrnb,
+                        scaleCoordinates);
             }
             break;
-        case (epcPARRINELLORAHMAN):
+        case (PressureCoupling::ParrinelloRahman):
             if (do_per_step(step + inputrec->nstpcouple - 1, inputrec->nstpcouple))
             {
                 /* The box velocities were updated in do_pr_pcoupl,
@@ -296,7 +300,7 @@ void update_pcouple_after_coordinates(FILE*                fplog,
                 }
             }
             break;
-        case (epcMTTK):
+        case (PressureCoupling::Mttk):
             switch (inputrec->epct)
             {
                 case (epctISOTROPIC):
@@ -341,7 +345,7 @@ extern gmx_bool update_randomize_velocities(const t_inputrec*        ir,
 
     real rate = (ir->delta_t) / ir->opts.tau_t[0];
 
-    if (ir->etc == etcANDERSEN && constr != nullptr)
+    if (ir->etc == TemperatureCoupling::Andersen && constr != nullptr)
     {
         /* Currently, Andersen thermostat does not support constrained
            systems. Functionality exists in the andersen_tcoupl
@@ -356,7 +360,7 @@ extern gmx_bool update_randomize_velocities(const t_inputrec*        ir,
 
     /* proceed with andersen if 1) it's fixed probability per
        particle andersen or 2) it's massive andersen and it's tau_t/dt */
-    if ((ir->etc == etcANDERSEN) || do_per_step(step, gmx::roundToInt(1.0 / rate)))
+    if ((ir->etc == TemperatureCoupling::Andersen) || do_per_step(step, gmx::roundToInt(1.0 / rate)))
     {
         andersen_tcoupl(
                 ir, step, cr, md, v, rate, upd->getAndersenRandomizeGroup(), upd->getBoltzmanFactor());
@@ -847,7 +851,7 @@ static inline real compressibilityFactor(int i, int j, const t_inputrec* ir, rea
 }
 
 //! Details of Berendsen / C-rescale scaling matrix calculation
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
 static void calculateScalingMatrixImplDetail(const t_inputrec* ir,
                                              matrix            mu,
                                              real              dt,
@@ -858,7 +862,7 @@ static void calculateScalingMatrixImplDetail(const t_inputrec* ir,
                                              int64_t           step);
 
 //! Calculate Berendsen / C-rescale scaling matrix
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
 static void calculateScalingMatrixImpl(const t_inputrec* ir,
                                        matrix            mu,
                                        real              dt,
@@ -882,14 +886,14 @@ static void calculateScalingMatrixImpl(const t_inputrec* ir,
 }
 
 template<>
-void calculateScalingMatrixImplDetail<epcBERENDSEN>(const t_inputrec* ir,
-                                                    matrix            mu,
-                                                    real              dt,
-                                                    const matrix      pres,
-                                                    const matrix      box,
-                                                    real              scalar_pressure,
-                                                    real              xy_pressure,
-                                                    int64_t gmx_unused step)
+void calculateScalingMatrixImplDetail<PressureCoupling::Berendsen>(const t_inputrec* ir,
+                                                                   matrix            mu,
+                                                                   real              dt,
+                                                                   const matrix      pres,
+                                                                   const matrix      box,
+                                                                   real    scalar_pressure,
+                                                                   real    xy_pressure,
+                                                                   int64_t gmx_unused step)
 {
     real p_corr_z = 0;
     switch (ir->epct)
@@ -949,14 +953,14 @@ void calculateScalingMatrixImplDetail<epcBERENDSEN>(const t_inputrec* ir,
 }
 
 template<>
-void calculateScalingMatrixImplDetail<epcCRESCALE>(const t_inputrec* ir,
-                                                   matrix            mu,
-                                                   real              dt,
-                                                   const matrix      pres,
-                                                   const matrix      box,
-                                                   real              scalar_pressure,
-                                                   real              xy_pressure,
-                                                   int64_t           step)
+void calculateScalingMatrixImplDetail<PressureCoupling::CRescale>(const t_inputrec* ir,
+                                                                  matrix            mu,
+                                                                  real              dt,
+                                                                  const matrix      pres,
+                                                                  const matrix      box,
+                                                                  real              scalar_pressure,
+                                                                  real              xy_pressure,
+                                                                  int64_t           step)
 {
     gmx::ThreeFry2x64<64>         rng(ir->ld_seed, gmx::RandomDomain::Barostat);
     gmx::NormalDistribution<real> normalDist;
@@ -1025,7 +1029,7 @@ void calculateScalingMatrixImplDetail<epcCRESCALE>(const t_inputrec* ir,
     }
 }
 
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
 void pressureCouplingCalculateScalingMatrix(FILE*             fplog,
                                             int64_t           step,
                                             const t_inputrec* ir,
@@ -1037,7 +1041,8 @@ void pressureCouplingCalculateScalingMatrix(FILE*             fplog,
                                             matrix            mu,
                                             double*           baros_integral)
 {
-    static_assert(pressureCouplingType == epcBERENDSEN || pressureCouplingType == epcCRESCALE,
+    static_assert(pressureCouplingType == PressureCoupling::Berendsen
+                          || pressureCouplingType == PressureCoupling::CRescale,
                   "pressureCouplingCalculateScalingMatrix is only implemented for Berendsen and "
                   "C-rescale pressure coupling");
 
@@ -1098,7 +1103,7 @@ void pressureCouplingCalculateScalingMatrix(FILE*             fplog,
     }
 }
 
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
 void pressureCouplingScaleBoxAndCoordinates(const t_inputrec*    ir,
                                             const matrix         mu,
                                             matrix               box,
@@ -1111,13 +1116,14 @@ void pressureCouplingScaleBoxAndCoordinates(const t_inputrec*    ir,
                                             t_nrnb*              nrnb,
                                             const bool           scaleCoordinates)
 {
-    static_assert(pressureCouplingType == epcBERENDSEN || pressureCouplingType == epcCRESCALE,
+    static_assert(pressureCouplingType == PressureCoupling::Berendsen
+                          || pressureCouplingType == PressureCoupling::CRescale,
                   "pressureCouplingScaleBoxAndCoordinates is only implemented for Berendsen and "
                   "C-rescale pressure coupling");
 
     ivec*  nFreeze = ir->opts.nFreeze;
     matrix inv_mu;
-    if (pressureCouplingType == epcCRESCALE)
+    if (pressureCouplingType == PressureCoupling::CRescale)
     {
         gmx::invertBoxMatrix(mu, inv_mu);
     }
@@ -1139,7 +1145,7 @@ void pressureCouplingScaleBoxAndCoordinates(const t_inputrec*    ir,
             if (!nFreeze[g][XX])
             {
                 x[n][XX] = mu[XX][XX] * x[n][XX] + mu[YY][XX] * x[n][YY] + mu[ZZ][XX] * x[n][ZZ];
-                if (pressureCouplingType == epcCRESCALE)
+                if (pressureCouplingType == PressureCoupling::CRescale)
                 {
                     v[n][XX] = inv_mu[XX][XX] * v[n][XX] + inv_mu[YY][XX] * v[n][YY]
                                + inv_mu[ZZ][XX] * v[n][ZZ];
@@ -1148,7 +1154,7 @@ void pressureCouplingScaleBoxAndCoordinates(const t_inputrec*    ir,
             if (!nFreeze[g][YY])
             {
                 x[n][YY] = mu[YY][YY] * x[n][YY] + mu[ZZ][YY] * x[n][ZZ];
-                if (pressureCouplingType == epcCRESCALE)
+                if (pressureCouplingType == PressureCoupling::CRescale)
                 {
                     v[n][YY] = inv_mu[YY][YY] * v[n][YY] + inv_mu[ZZ][YY] * v[n][ZZ];
                 }
@@ -1156,7 +1162,7 @@ void pressureCouplingScaleBoxAndCoordinates(const t_inputrec*    ir,
             if (!nFreeze[g][ZZ])
             {
                 x[n][ZZ] = mu[ZZ][ZZ] * x[n][ZZ];
-                if (pressureCouplingType == epcCRESCALE)
+                if (pressureCouplingType == PressureCoupling::CRescale)
                 {
                     v[n][ZZ] = inv_mu[ZZ][ZZ] * v[n][ZZ];
                 }
@@ -1250,7 +1256,7 @@ void andersen_tcoupl(const t_inputrec*         ir,
         }
         if (randomize[gc])
         {
-            if (ir->etc == etcANDERSENMASSIVE)
+            if (ir->etc == TemperatureCoupling::AndersenMassive)
             {
                 /* Randomize particle always */
                 bRandomize = TRUE;
@@ -1548,7 +1554,7 @@ init_npt_vars(const t_inputrec* ir, t_state* state, t_extmass* MassQ, gmx_bool b
     nnhpres = state->nnhpres;
     nh      = state->nhchainlength;
 
-    if (EI_VV(ir->eI) && (ir->epc == epcMTTK) && (ir->etc != etcNOSEHOOVER))
+    if (EI_VV(ir->eI) && (ir->epc == PressureCoupling::Mttk) && (ir->etc != TemperatureCoupling::NoseHoover))
     {
         gmx_fatal(FARGS, "Cannot do MTTK pressure coupling without Nose-Hoover temperature control");
     }
@@ -1824,7 +1830,7 @@ real NPT_energy(const t_inputrec* ir, const t_state* state, const t_extmass* Mas
 {
     real energyNPT = 0;
 
-    if (ir->epc != epcNO)
+    if (ir->epc != PressureCoupling::No)
     {
         /* Compute the contribution of the pressure to the conserved quantity*/
 
@@ -1832,7 +1838,7 @@ real NPT_energy(const t_inputrec* ir, const t_state* state, const t_extmass* Mas
 
         switch (ir->epc)
         {
-            case epcPARRINELLORAHMAN:
+            case PressureCoupling::ParrinelloRahman:
             {
                 /* contribution from the pressure momenta */
                 tensor invMass;
@@ -1858,21 +1864,21 @@ real NPT_energy(const t_inputrec* ir, const t_state* state, const t_extmass* Mas
                 energyNPT += vol * trace(ir->ref_p) / (DIM * PRESFAC);
                 break;
             }
-            case epcMTTK:
+            case PressureCoupling::Mttk:
                 /* contribution from the pressure momenta */
                 energyNPT += 0.5 * gmx::square(state->veta) / MassQ->Winv;
 
                 /* contribution from the PV term */
                 energyNPT += vol * trace(ir->ref_p) / (DIM * PRESFAC);
 
-                if (ir->epc == epcMTTK)
+                if (ir->epc == PressureCoupling::Mttk)
                 {
                     /* contribution from the MTTK chain */
                     energyNPT += energyPressureMTTK(ir, state, MassQ);
                 }
                 break;
-            case epcBERENDSEN:
-            case epcCRESCALE: energyNPT += state->baros_integral; break;
+            case PressureCoupling::Berendsen:
+            case PressureCoupling::CRescale: energyNPT += state->baros_integral; break;
             default:
                 GMX_RELEASE_ASSERT(
                         false,
@@ -1884,12 +1890,14 @@ real NPT_energy(const t_inputrec* ir, const t_state* state, const t_extmass* Mas
 
     switch (ir->etc)
     {
-        case etcNO: break;
-        case etcVRESCALE:
-        case etcBERENDSEN: energyNPT += energyVrescale(ir, state); break;
-        case etcNOSEHOOVER: energyNPT += energyNoseHoover(ir, state, MassQ); break;
-        case etcANDERSEN:
-        case etcANDERSENMASSIVE:
+        case TemperatureCoupling::No: break;
+        case TemperatureCoupling::VRescale:
+        case TemperatureCoupling::Berendsen: energyNPT += energyVrescale(ir, state); break;
+        case TemperatureCoupling::NoseHoover:
+            energyNPT += energyNoseHoover(ir, state, MassQ);
+            break;
+        case TemperatureCoupling::Andersen:
+        case TemperatureCoupling::AndersenMassive:
             // Not supported, excluded in integratorHasConservedEnergyQuantity()
             break;
         default:
@@ -2153,15 +2161,15 @@ void pleaseCiteCouplingAlgorithms(FILE* fplog, const t_inputrec& ir)
 {
     if (EI_DYNAMICS(ir.eI))
     {
-        if (ir.etc == etcBERENDSEN)
+        if (ir.etc == TemperatureCoupling::Berendsen)
         {
             please_cite(fplog, "Berendsen84a");
         }
-        if (ir.etc == etcVRESCALE)
+        if (ir.etc == TemperatureCoupling::VRescale)
         {
             please_cite(fplog, "Bussi2007a");
         }
-        if (ir.epc == epcCRESCALE)
+        if (ir.epc == PressureCoupling::CRescale)
         {
             please_cite(fplog, "Bernetti2020");
         }
index 25f959a1e5a627f77f135609dd2acbcffbf17249..7f8d3c5a2617aacbccd7355acb5a9473aa39b72c 100644 (file)
@@ -191,7 +191,7 @@ void parrinellorahman_pcoupl(FILE*             fplog,
  * computes the current value of the scaling matrix. The template
  * parameter determines the pressure coupling algorithm.
  */
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
 void pressureCouplingCalculateScalingMatrix(FILE*             fplog,
                                             int64_t           step,
                                             const t_inputrec* ir,
@@ -210,7 +210,7 @@ void pressureCouplingCalculateScalingMatrix(FILE*             fplog,
  * the scaling matrix mu. The template parameter determines the pressure
  * coupling algorithm.
  */
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
 void pressureCouplingScaleBoxAndCoordinates(const t_inputrec*    ir,
                                             const matrix         mu,
                                             matrix               box,
index f26716a3d2fda1d1225255e5208f69c35a15cb35..b66cb0a933dc37ca77ce0ed38491e8b9a7e56526 100644 (file)
@@ -261,12 +261,12 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
         }
     }
 
-    epc_            = isRerun ? epcNO : ir->epc;
+    epc_            = isRerun ? PressureCoupling::No : ir->epc;
     bDiagPres_      = !TRICLINIC(ir->ref_p) && !isRerun;
     ref_p_          = (ir->ref_p[XX][XX] + ir->ref_p[YY][YY] + ir->ref_p[ZZ][ZZ]) / DIM;
     bTricl_         = TRICLINIC(ir->compress) || TRICLINIC(ir->deform);
     bDynBox_        = inputrecDynamicBox(ir);
-    etc_            = isRerun ? etcNO : ir->etc;
+    etc_            = isRerun ? TemperatureCoupling::No : ir->etc;
     bNHC_trotter_   = inputrecNvtTrotter(ir) && !isRerun;
     bPrintNHChains_ = ir->bPrintNHChains && !isRerun;
     bMTTK_          = (inputrecNptTrotter(ir) || inputrecNphTrotter(ir)) && !isRerun;
@@ -310,7 +310,7 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
         ipres_  = get_ebin_space(ebin_, asize(pres_nm), pres_nm, unit_pres_bar);
         isurft_ = get_ebin_space(ebin_, asize(surft_nm), surft_nm, unit_surft_bar);
     }
-    if (epc_ == epcPARRINELLORAHMAN || epc_ == epcMTTK)
+    if (epc_ == PressureCoupling::ParrinelloRahman || epc_ == PressureCoupling::Mttk)
     {
         ipc_ = get_ebin_space(ebin_, bTricl_ ? boxvel_nm.size() : DIM, boxvel_nm.data(), unit_vel);
     }
@@ -408,7 +408,7 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
     {
         nTCP_ = 0;
     }
-    if (etc_ == etcNOSEHOOVER)
+    if (etc_ == TemperatureCoupling::NoseHoover)
     {
         if (bNHC_trotter_)
         {
@@ -418,7 +418,7 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
         {
             mde_n_ = 2 * nTC_;
         }
-        if (epc_ == epcMTTK)
+        if (epc_ == PressureCoupling::Mttk)
         {
             mdeb_n_ = 2 * nNHC_ * nTCP_;
         }
@@ -447,7 +447,7 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
     }
 
     int allocated = 0;
-    if (etc_ == etcNOSEHOOVER)
+    if (etc_ == TemperatureCoupling::NoseHoover)
     {
         if (bPrintNHChains_)
         {
@@ -500,7 +500,8 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
             }
         }
     }
-    else if (etc_ == etcBERENDSEN || etc_ == etcYES || etc_ == etcVRESCALE)
+    else if (etc_ == TemperatureCoupling::Berendsen || etc_ == TemperatureCoupling::Yes
+             || etc_ == TemperatureCoupling::VRescale)
     {
         for (i = 0; (i < nTC_); i++)
         {
@@ -725,7 +726,7 @@ FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env
     }
 
     nsetsextend = nsets;
-    if ((ir->epc != epcNO) && (fep->n_lambda > 0) && (fep->init_lambda < 0))
+    if ((ir->epc != PressureCoupling::No) && (fep->n_lambda > 0) && (fep->init_lambda < 0))
     {
         nsetsextend += 1; /* for PV term, other terms possible if required for
                              the reduced potential (only needed with foreign
@@ -925,7 +926,7 @@ void EnergyOutput::addDataAtEnergyStep(bool                    bDoDHDL,
         tmp = (pres[ZZ][ZZ] - (pres[XX][XX] + pres[YY][YY]) * 0.5) * box[ZZ][ZZ];
         add_ebin(ebin_, isurft_, 1, &tmp, bSum);
     }
-    if (epc_ == epcPARRINELLORAHMAN || epc_ == epcMTTK)
+    if (epc_ == PressureCoupling::ParrinelloRahman || epc_ == PressureCoupling::Mttk)
     {
         tmp6[0] = ptCouplingArrays.boxv[XX][XX];
         tmp6[1] = ptCouplingArrays.boxv[YY][YY];
@@ -979,7 +980,7 @@ void EnergyOutput::addDataAtEnergyStep(bool                    bDoDHDL,
         }
         add_ebin(ebin_, itemp_, nTC_, tmp_r_, bSum);
 
-        if (etc_ == etcNOSEHOOVER)
+        if (etc_ == TemperatureCoupling::NoseHoover)
         {
             /* whether to print Nose-Hoover chains: */
             if (bPrintNHChains_)
@@ -1022,7 +1023,8 @@ void EnergyOutput::addDataAtEnergyStep(bool                    bDoDHDL,
                 }
             }
         }
-        else if (etc_ == etcBERENDSEN || etc_ == etcYES || etc_ == etcVRESCALE)
+        else if (etc_ == TemperatureCoupling::Berendsen || etc_ == TemperatureCoupling::Yes
+                 || etc_ == TemperatureCoupling::VRescale)
         {
             for (int i = 0; (i < nTC_); i++)
             {
@@ -1094,8 +1096,8 @@ void EnergyOutput::addDataAtEnergyStep(bool                    bDoDHDL,
             {
                 fprintf(fp_dhdl_, " %#.8g", dE_[i]);
             }
-            if (bDynBox_ && bDiagPres_ && (epc_ != epcNO) && foreignTerms.numLambdas() > 0
-                && (fep->init_lambda < 0))
+            if (bDynBox_ && bDiagPres_ && (epc_ != PressureCoupling::No)
+                && foreignTerms.numLambdas() > 0 && (fep->init_lambda < 0))
             {
                 fprintf(fp_dhdl_, " %#.8g", pv); /* PV term only needed when
                                                          there are alternate state
index 91f8112c0082b7804b95166ff6f5b359671ef93e..d78919a559c27d94bd98f3ad4d5ce3bb954cb49d 100644 (file)
@@ -308,7 +308,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 };
@@ -361,7 +361,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;
 
index 1455e0eeb570d36e6583decf6a4f16b4674d7967..176ef3d751af858fb51c57c5e9a126e714bf2ef4 100644 (file)
@@ -452,7 +452,8 @@ int computeGlobalCommunicationPeriod(const t_inputrec* ir)
     int nstglobalcomm = 10;
     {
         // Set up the default behaviour
-        if (!(ir->nstcalcenergy > 0 || ir->nstlist > 0 || ir->etc != etcNO || ir->epc != epcNO))
+        if (!(ir->nstcalcenergy > 0 || ir->nstlist > 0 || ir->etc != TemperatureCoupling::No
+              || ir->epc != PressureCoupling::No))
         {
             /* The user didn't choose the period for anything
                important, so we just make sure we can send signals and
@@ -475,8 +476,8 @@ int computeGlobalCommunicationPeriod(const t_inputrec* ir)
              */
             nstglobalcomm = lcd4(ir->nstcalcenergy,
                                  ir->nstlist,
-                                 ir->etc != etcNO ? ir->nsttcouple : 0,
-                                 ir->epc != epcNO ? ir->nstpcouple : 0);
+                                 ir->etc != TemperatureCoupling::No ? ir->nsttcouple : 0,
+                                 ir->epc != PressureCoupling::No ? ir->nstpcouple : 0);
         }
     }
     return nstglobalcomm;
@@ -540,7 +541,7 @@ void set_state_entries(t_state* state, const t_inputrec* ir, bool useModularSimu
         {
             state->flags |= (1 << estBOX_REL);
         }
-        if ((ir->epc == epcPARRINELLORAHMAN) || (ir->epc == epcMTTK))
+        if ((ir->epc == PressureCoupling::ParrinelloRahman) || (ir->epc == PressureCoupling::Mttk))
         {
             state->flags |= (1 << estBOXV);
             if (!useModularSimulator)
@@ -558,19 +559,19 @@ void set_state_entries(t_state* state, const t_inputrec* ir, bool useModularSimu
             state->flags |= (1 << estVETA);
             state->flags |= (1 << estVOL0);
         }
-        if (ir->epc == epcBERENDSEN || ir->epc == epcCRESCALE)
+        if (ir->epc == PressureCoupling::Berendsen || ir->epc == PressureCoupling::CRescale)
         {
             state->flags |= (1 << estBAROS_INT);
         }
     }
 
-    if (ir->etc == etcNOSEHOOVER)
+    if (ir->etc == TemperatureCoupling::NoseHoover)
     {
         state->flags |= (1 << estNH_XI);
         state->flags |= (1 << estNH_VXI);
     }
 
-    if (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN)
+    if (ir->etc == TemperatureCoupling::VRescale || ir->etc == TemperatureCoupling::Berendsen)
     {
         state->flags |= (1 << estTHERM_INT);
     }
index 994ed39ccc71573114d8c60e341e799469aafbee..8c2791b2fd07fd10aca0f7e0fb787d5704495d30 100644 (file)
@@ -4,7 +4,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 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,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.
@@ -490,7 +490,7 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll* dhc, const t_inputrec* ir)
                 dhc->ndh += 1;
                 bEnergy = TRUE;
             }
-            if (ir->epc > epcNO)
+            if (ir->epc > PressureCoupling::No)
             {
                 dhc->ndh += 1; /* include pressure-volume work */
                 bPV = TRUE;
index 402d10a38fe448ae326b3d8065d98dbd4cc2d7fc..765eed2dc739ff451a36c3a2760b5261fd5fb5bc 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2008, The GROMACS development team.
  * Copyright (c) 2012,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,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.
@@ -181,7 +181,7 @@ void count_bonded_distances(const gmx_mtop_t& mtop, const t_inputrec& ir, double
         {
             nonsimd_step_frac = 0;
         }
-        if (ir.epc != epcNO && 1.0 / ir.nstpcouple > nonsimd_step_frac)
+        if (ir.epc != PressureCoupling::No && 1.0 / ir.nstpcouple > nonsimd_step_frac)
         {
             nonsimd_step_frac = 1.0 / ir.nstpcouple;
         }
index b6937b19c5e8eb39e6988201a4f0aaf707f79006..7755ecdfbd19e1e2a3350f59600e845decee16e7 100644 (file)
@@ -98,9 +98,9 @@ void fcloseWrapper(FILE* fp)
 struct EnergyOutputTestParameters
 {
     //! Thermostat (enum)
-    int temperatureCouplingScheme;
+    TemperatureCoupling temperatureCouplingScheme;
     //! Barostat (enum)
-    int pressureCouplingScheme;
+    PressureCoupling pressureCouplingScheme;
     //! Integrator
     int integrator;
     //! Number of saved energy frames (to test averages output).
@@ -116,17 +116,19 @@ struct EnergyOutputTestParameters
  * Only several combinations of the parameters are used. Using all possible combinations will
  * require ~10 MB of test data and ~2 sec to run the tests.
  */
-const EnergyOutputTestParameters parametersSets[] = { { etcNO, epcNO, eiMD, 1, false, false },
-                                                      { etcNO, epcNO, eiMD, 1, true, false },
-                                                      { etcNO, epcNO, eiMD, 1, false, true },
-                                                      { etcNO, epcNO, eiMD, 0, false, false },
-                                                      { etcNO, epcNO, eiMD, 10, false, false },
-                                                      { etcVRESCALE, epcNO, eiMD, 1, false, false },
-                                                      { etcNOSEHOOVER, epcNO, eiMD, 1, false, false },
-                                                      { etcNO, epcPARRINELLORAHMAN, eiMD, 1, false, false },
-                                                      { etcNO, epcMTTK, eiMD, 1, false, false },
-                                                      { etcNO, epcNO, eiVV, 1, false, false },
-                                                      { etcNO, epcMTTK, eiVV, 1, false, false } };
+const EnergyOutputTestParameters parametersSets[] = {
+    { TemperatureCoupling::No, PressureCoupling::No, eiMD, 1, false, false },
+    { TemperatureCoupling::No, PressureCoupling::No, eiMD, 1, true, false },
+    { TemperatureCoupling::No, PressureCoupling::No, eiMD, 1, false, true },
+    { TemperatureCoupling::No, PressureCoupling::No, eiMD, 0, false, false },
+    { TemperatureCoupling::No, PressureCoupling::No, eiMD, 10, false, false },
+    { TemperatureCoupling::VRescale, PressureCoupling::No, eiMD, 1, false, false },
+    { TemperatureCoupling::NoseHoover, PressureCoupling::No, eiMD, 1, false, false },
+    { TemperatureCoupling::No, PressureCoupling::ParrinelloRahman, eiMD, 1, false, false },
+    { TemperatureCoupling::No, PressureCoupling::Mttk, eiMD, 1, false, false },
+    { TemperatureCoupling::No, PressureCoupling::No, eiVV, 1, false, false },
+    { TemperatureCoupling::No, PressureCoupling::Mttk, eiVV, 1, false, false }
+};
 
 /*! \brief Test fixture to test energy output.
  *
index be38a6b971d156c2e56b710e7336d1f971c9f107..5a1e2cbf45fd82ff0d2fd23d1301b995e3400ebc 100644 (file)
@@ -123,7 +123,7 @@ LeapFrogTestData::LeapFrogTestData(int        numAtoms,
 
     if (numTCoupleGroups_ == 0)
     {
-        inputRecord_.etc = etcNO;
+        inputRecord_.etc = TemperatureCoupling::No;
         for (int i = 0; i < numAtoms_; i++)
         {
             mdAtoms_.cTC[i] = 0;
@@ -135,7 +135,7 @@ LeapFrogTestData::LeapFrogTestData(int        numAtoms,
     }
     else
     {
-        inputRecord_.etc = etcYES;
+        inputRecord_.etc = TemperatureCoupling::Yes;
         for (int i = 0; i < numAtoms_; i++)
         {
             mdAtoms_.cTC[i] = i % numTCoupleGroups_;
@@ -186,7 +186,7 @@ LeapFrogTestData::LeapFrogTestData(int        numAtoms,
 
     if (doPressureCouple_)
     {
-        inputRecord_.epc        = epcPARRINELLORAHMAN;
+        inputRecord_.epc        = PressureCoupling::ParrinelloRahman;
         inputRecord_.nstpcouple = nstpcouple;
         dtPressureCouple_       = inputRecord_.nstpcouple * inputRecord_.delta_t;
 
@@ -204,7 +204,7 @@ LeapFrogTestData::LeapFrogTestData(int        numAtoms,
     }
     else
     {
-        inputRecord_.epc               = epcNO;
+        inputRecord_.epc               = PressureCoupling::No;
         velocityScalingMatrix_[XX][XX] = 1.0;
         velocityScalingMatrix_[XX][YY] = 0.0;
         velocityScalingMatrix_[XX][ZZ] = 0.0;
index 67f2d5bdb47edd690d6f380d17eeb6d982648815..ad61495af8b861af4c869f54ae15192b9ea1d5d2 100644 (file)
@@ -610,14 +610,14 @@ static void do_update_md(int         start,
                          const rvec* gmx_restrict x,
                          rvec* gmx_restrict xprime,
                          rvec* gmx_restrict v,
-                         const rvec* gmx_restrict f,
-                         const int                etc,
-                         const int                epc,
-                         const int                nsttcouple,
-                         const int                nstpcouple,
-                         const t_mdatoms*         md,
-                         const gmx_ekindata_t*    ekind,
-                         const matrix             box,
+                         const rvec* gmx_restrict  f,
+                         const TemperatureCoupling etc,
+                         const PressureCoupling    epc,
+                         const int                 nsttcouple,
+                         const int                 nstpcouple,
+                         const t_mdatoms*          md,
+                         const gmx_ekindata_t*     ekind,
+                         const matrix              box,
                          const double* gmx_restrict nh_vxi,
                          const matrix               M)
 {
@@ -625,10 +625,11 @@ static void do_update_md(int         start,
                "For SIMD optimization certain compilers need to have xprime != x");
 
     /* Note: Berendsen pressure scaling is handled after do_update_md() */
-    bool doTempCouple = (etc != etcNO && do_per_step(step + nsttcouple - 1, nsttcouple));
-    bool doNoseHoover = (etc == etcNOSEHOOVER && doTempCouple);
-    bool doParrinelloRahman =
-            (epc == epcPARRINELLORAHMAN && do_per_step(step + nstpcouple - 1, nstpcouple));
+    bool doTempCouple =
+            (etc != TemperatureCoupling::No && do_per_step(step + nsttcouple - 1, nsttcouple));
+    bool doNoseHoover       = (etc == TemperatureCoupling::NoseHoover && doTempCouple);
+    bool doParrinelloRahman = (epc == PressureCoupling::ParrinelloRahman
+                               && do_per_step(step + nstpcouple - 1, nstpcouple));
     bool doPROffDiagonal = (doParrinelloRahman && (M[YY][XX] != 0 || M[ZZ][XX] != 0 || M[ZZ][YY] != 0));
 
     real dtPressureCouple = (doParrinelloRahman ? nstpcouple * dt : 0);
@@ -1561,8 +1562,9 @@ void Update::Impl::update_coords(const t_inputrec&
                 case (eiVV):
                 case (eiVVAK):
                 {
-                    gmx_bool bExtended = (inputRecord.etc == etcNOSEHOOVER || inputRecord.epc == epcPARRINELLORAHMAN
-                                          || inputRecord.epc == epcMTTK);
+                    gmx_bool bExtended = (inputRecord.etc == TemperatureCoupling::NoseHoover
+                                          || inputRecord.epc == PressureCoupling::ParrinelloRahman
+                                          || inputRecord.epc == PressureCoupling::Mttk);
 
                     /* assuming barostat coupled to group 0 */
                     real alpha = 1.0 + DIM / static_cast<real>(inputRecord.opts.nrdf[0]);
index 04cc254287673b41b8b8e5476aa03d8863336fce..2cc3dad638ce910c6cc6eca40df306098e29e4ab 100644 (file)
@@ -432,11 +432,11 @@ void gmx::LegacySimulator::do_md()
         GMX_RELEASE_ASSERT(ir->eI == eiMD,
                            "Only the md integrator is supported with the GPU update.\n");
         GMX_RELEASE_ASSERT(
-                ir->etc != etcNOSEHOOVER,
+                ir->etc != TemperatureCoupling::NoseHoover,
                 "Nose-Hoover temperature coupling is not supported with the GPU update.\n");
         GMX_RELEASE_ASSERT(
-                ir->epc == epcNO || ir->epc == epcPARRINELLORAHMAN || ir->epc == epcBERENDSEN
-                        || ir->epc == epcCRESCALE,
+                ir->epc == PressureCoupling::No || ir->epc == PressureCoupling::ParrinelloRahman
+                        || ir->epc == PressureCoupling::Berendsen || ir->epc == PressureCoupling::CRescale,
                 "Only Parrinello-Rahman, Berendsen, and C-rescale pressure coupling are supported "
                 "with the GPU update.\n");
         GMX_RELEASE_ASSERT(!mdatoms->haveVsites,
@@ -1072,13 +1072,14 @@ void gmx::LegacySimulator::do_md()
         {
             bCalcEnerStep = do_per_step(step, ir->nstcalcenergy);
             bCalcVir      = bCalcEnerStep
-                       || (ir->epc != epcNO
+                       || (ir->epc != PressureCoupling::No
                            && (do_per_step(step, ir->nstpcouple) || do_per_step(step - 1, ir->nstpcouple)));
         }
         else
         {
             bCalcEnerStep = do_per_step(step, ir->nstcalcenergy);
-            bCalcVir = bCalcEnerStep || (ir->epc != epcNO && do_per_step(step, ir->nstpcouple));
+            bCalcVir      = bCalcEnerStep
+                       || (ir->epc != PressureCoupling::No && do_per_step(step, ir->nstpcouple));
         }
         bCalcEner = bCalcEnerStep;
 
@@ -1405,7 +1406,7 @@ void gmx::LegacySimulator::do_md()
 
         // Parrinello-Rahman requires the pressure to be availible before the update to compute
         // the velocity scaling matrix. Hence, it runs one step after the nstpcouple step.
-        const bool doParrinelloRahman = (ir->epc == epcPARRINELLORAHMAN
+        const bool doParrinelloRahman = (ir->epc == PressureCoupling::ParrinelloRahman
                                          && do_per_step(step + ir->nstpcouple - 1, ir->nstpcouple));
 
         if (EI_VV(ir->eI))
@@ -1481,7 +1482,8 @@ void gmx::LegacySimulator::do_md()
                 }
 
                 const bool doTemperatureScaling =
-                        (ir->etc != etcNO && do_per_step(step + ir->nsttcouple - 1, ir->nsttcouple));
+                        (ir->etc != TemperatureCoupling::No
+                         && do_per_step(step + ir->nsttcouple - 1, ir->nsttcouple));
 
                 // This applies Leap-Frog, LINCS and SETTLE in succession
                 integrator->integrate(
@@ -1676,10 +1678,10 @@ void gmx::LegacySimulator::do_md()
         update_pcouple_after_coordinates(
                 fplog, step, ir, mdatoms, pres, force_vir, shake_vir, pressureCouplingMu, state, nrnb, upd.deform(), !useGpuForUpdate);
 
-        const bool doBerendsenPressureCoupling =
-                (inputrec->epc == epcBERENDSEN && do_per_step(step, inputrec->nstpcouple));
-        const bool doCRescalePressureCoupling =
-                (inputrec->epc == epcCRESCALE && do_per_step(step, inputrec->nstpcouple));
+        const bool doBerendsenPressureCoupling = (inputrec->epc == PressureCoupling::Berendsen
+                                                  && do_per_step(step, inputrec->nstpcouple));
+        const bool doCRescalePressureCoupling  = (inputrec->epc == PressureCoupling::CRescale
+                                                 && do_per_step(step, inputrec->nstpcouple));
         if (useGpuForUpdate
             && (doBerendsenPressureCoupling || doCRescalePressureCoupling || doParrinelloRahman))
         {
index 19172eb0dec9d19f9aa322d4b8b1a7c4ebd988d1..e23bea4250d7d383f976ba132a4f457f12c497b7 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) 2011-2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2011-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.
@@ -253,9 +253,9 @@ gmx_repl_ex_t init_replica_exchange(FILE*                            fplog,
     const int nst = replExParams.exchangeInterval;
     check_multi_int64(
             fplog, ms, (ir->init_step + nst - 1) / nst, "first exchange step: init_step/-replex", FALSE);
-    check_multi_int(fplog, ms, ir->etc, "the temperature coupling", FALSE);
+    check_multi_int(fplog, ms, static_cast<int>(ir->etc), "the temperature coupling", FALSE);
     check_multi_int(fplog, ms, ir->opts.ngtc, "the number of temperature coupling groups", FALSE);
-    check_multi_int(fplog, ms, ir->epc, "the pressure coupling", FALSE);
+    check_multi_int(fplog, ms, static_cast<int>(ir->epc), "the pressure coupling", FALSE);
     check_multi_int(fplog, ms, ir->efep, "free energy", FALSE);
     check_multi_int(fplog, ms, ir->fepvals->n_lambda, "number of lambda states", FALSE);
 
@@ -293,19 +293,19 @@ gmx_repl_ex_t init_replica_exchange(FILE*                            fplog,
     if (bTemp)
     {
         please_cite(fplog, "Sugita1999a");
-        if (ir->epc != epcNO)
+        if (ir->epc != PressureCoupling::No)
         {
             re->bNPT = TRUE;
             fprintf(fplog, "Repl  Using Constant Pressure REMD.\n");
             please_cite(fplog, "Okabe2001a");
         }
-        if (ir->etc == etcBERENDSEN)
+        if (ir->etc == TemperatureCoupling::Berendsen)
         {
             gmx_fatal(FARGS,
                       "REMD with the %s thermostat does not produce correct potential energy "
                       "distributions, consider using the %s thermostat instead",
-                      ETCOUPLTYPE(ir->etc),
-                      ETCOUPLTYPE(etcVRESCALE));
+                      enumValueToString(ir->etc),
+                      enumValueToString(TemperatureCoupling::VRescale));
         }
     }
     if (bLambda)
index d42675f9fa3edb4352056be769ab89f78b6396d7..cb76c778a31747e22a9dc1ff1e043fdb3ebeea48 100644 (file)
@@ -431,7 +431,8 @@ static void prepare_verlet_scheme(FILE*               fplog,
                            "With Verlet lists and no PME rcoulomb and rvdw should be identical");
     }
     /* For NVE simulations, we will retain the initial list buffer */
-    if (EI_DYNAMICS(ir->eI) && ir->verletbuf_tol > 0 && !(EI_MD(ir->eI) && ir->etc == etcNO))
+    if (EI_DYNAMICS(ir->eI) && ir->verletbuf_tol > 0
+        && !(EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No))
     {
         /* Update the Verlet buffer size for the current run setup */
 
index ef67f95d5dfbd1a9c70a02f59e28ce942c6106e1..903e3ef62ebc2a1c3a22c7f2c5d5a2e44259da1e 100644 (file)
@@ -119,22 +119,22 @@ int ir_optimal_nstcalcenergy(const t_inputrec* ir)
     return nst;
 }
 
-int tcouple_min_integration_steps(int etc)
+int tcouple_min_integration_steps(TemperatureCoupling etc)
 {
     int n;
 
     switch (etc)
     {
-        case etcNO: n = 0; break;
-        case etcBERENDSEN:
-        case etcYES: n = nstmin_berendsen_tcouple; break;
-        case etcVRESCALE:
+        case TemperatureCoupling::No: n = 0; break;
+        case TemperatureCoupling::Berendsen:
+        case TemperatureCoupling::Yes: n = nstmin_berendsen_tcouple; break;
+        case TemperatureCoupling::VRescale:
             /* V-rescale supports instantaneous rescaling */
             n = 0;
             break;
-        case etcNOSEHOOVER: n = nstmin_harmonic; break;
-        case etcANDERSEN:
-        case etcANDERSENMASSIVE: n = 1; break;
+        case TemperatureCoupling::NoseHoover: n = nstmin_harmonic; break;
+        case TemperatureCoupling::Andersen:
+        case TemperatureCoupling::AndersenMassive: n = 1; break;
         default: gmx_incons("Unknown etc value");
     }
 
@@ -152,7 +152,7 @@ int ir_optimal_nsttcouple(const t_inputrec* ir)
     nwanted = c_defaultNstTCouple;
 
     tau_min = 1e20;
-    if (ir->etc != etcNO)
+    if (ir->etc != TemperatureCoupling::No)
     {
         for (g = 0; g < ir->opts.ngtc; g++)
         {
@@ -183,18 +183,18 @@ int ir_optimal_nsttcouple(const t_inputrec* ir)
     return n;
 }
 
-int pcouple_min_integration_steps(int epc)
+int pcouple_min_integration_steps(PressureCoupling epc)
 {
     int n;
 
     switch (epc)
     {
-        case epcNO: n = 0; break;
-        case epcBERENDSEN:
-        case epcCRESCALE:
-        case epcISOTROPIC: n = nstmin_berendsen_pcouple; break;
-        case epcPARRINELLORAHMAN:
-        case epcMTTK: n = nstmin_harmonic; break;
+        case PressureCoupling::No: n = 0; break;
+        case PressureCoupling::Berendsen:
+        case PressureCoupling::CRescale:
+        case PressureCoupling::Isotropic: n = nstmin_berendsen_pcouple; break;
+        case PressureCoupling::ParrinelloRahman:
+        case PressureCoupling::Mttk: n = nstmin_harmonic; break;
         default: gmx_incons("Unknown epc value");
     }
 
@@ -906,12 +906,12 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
         PR("epsilon-surface", ir->epsilon_surface);
 
         /* Options for weak coupling algorithms */
-        PS("tcoupl", ETCOUPLTYPE(ir->etc));
+        PS("tcoupl", enumValueToString(ir->etc));
         PI("nsttcouple", ir->nsttcouple);
         PI("nh-chain-length", ir->opts.nhchainlength);
         PS("print-nose-hoover-chain-variables", EBOOL(ir->bPrintNHChains));
 
-        PS("pcoupl", EPCOUPLTYPE(ir->epc));
+        PS("pcoupl", enumValueToString(ir->epc));
         PS("pcoupltype", EPCOUPLTYPETYPE(ir->epct));
         PI("nstpcouple", ir->nstpcouple);
         PR("tau-p", ir->tau_p);
@@ -1382,13 +1382,13 @@ void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real f
             static_cast<int>(ir1->bContinuation),
             static_cast<int>(ir2->bContinuation));
     cmp_int(fp, "inputrec->bShakeSOR", -1, static_cast<int>(ir1->bShakeSOR), static_cast<int>(ir2->bShakeSOR));
-    cmp_int(fp, "inputrec->etc", -1, ir1->etc, ir2->etc);
+    cmpEnum(fp, "inputrec->etc", ir1->etc, ir2->etc);
     cmp_int(fp,
             "inputrec->bPrintNHChains",
             -1,
             static_cast<int>(ir1->bPrintNHChains),
             static_cast<int>(ir2->bPrintNHChains));
-    cmp_int(fp, "inputrec->epc", -1, ir1->epc, ir2->epc);
+    cmpEnum(fp, "inputrec->epc", ir1->epc, ir2->epc);
     cmp_int(fp, "inputrec->epct", -1, ir1->epct, ir2->epct);
     cmp_real(fp, "inputrec->tau_p", -1, ir1->tau_p, ir2->tau_p, ftol, abstol);
     cmp_rvec(fp, "inputrec->ref_p(x)", -1, ir1->ref_p[XX], ir2->ref_p[XX], ftol, abstol);
@@ -1516,12 +1516,12 @@ gmx_bool inputrecDeform(const t_inputrec* ir)
 
 gmx_bool inputrecDynamicBox(const t_inputrec* ir)
 {
-    return (ir->epc != epcNO || ir->eI == eiTPI || inputrecDeform(ir));
+    return (ir->epc != PressureCoupling::No || ir->eI == eiTPI || inputrecDeform(ir));
 }
 
 gmx_bool inputrecPreserveShape(const t_inputrec* ir)
 {
-    return (ir->epc != epcNO && ir->deform[XX][XX] == 0
+    return (ir->epc != PressureCoupling::No && ir->deform[XX][XX] == 0
             && (ir->epct == epctISOTROPIC || ir->epct == epctSEMIISOTROPIC));
 }
 
@@ -1538,17 +1538,20 @@ gmx_bool inputrecExclForces(const t_inputrec* ir)
 
 gmx_bool inputrecNptTrotter(const t_inputrec* ir)
 {
-    return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == epcMTTK) && (ir->etc == etcNOSEHOOVER));
+    return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == PressureCoupling::Mttk)
+            && (ir->etc == TemperatureCoupling::NoseHoover));
 }
 
 gmx_bool inputrecNvtTrotter(const t_inputrec* ir)
 {
-    return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc != epcMTTK) && (ir->etc == etcNOSEHOOVER));
+    return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc != PressureCoupling::Mttk)
+            && (ir->etc == TemperatureCoupling::NoseHoover));
 }
 
 gmx_bool inputrecNphTrotter(const t_inputrec* ir)
 {
-    return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == epcMTTK) && (ir->etc != etcNOSEHOOVER));
+    return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == PressureCoupling::Mttk)
+            && (ir->etc != TemperatureCoupling::NoseHoover));
 }
 
 bool inputrecPbcXY2Walls(const t_inputrec* ir)
@@ -1563,7 +1566,7 @@ bool integratorHasConservedEnergyQuantity(const t_inputrec* ir)
         // Energy minimization or stochastic integrator: no conservation
         return false;
     }
-    else if (ir->etc == etcNO && ir->epc == epcNO)
+    else if (ir->etc == TemperatureCoupling::No && ir->epc == PressureCoupling::No)
     {
         // The total energy is conserved, no additional conserved quanitity
         return false;
@@ -1572,7 +1575,7 @@ bool integratorHasConservedEnergyQuantity(const t_inputrec* ir)
     {
         // Shear stress with Parrinello-Rahman is not supported (tedious)
         bool shearWithPR =
-                ((ir->epc == epcPARRINELLORAHMAN || ir->epc == epcMTTK)
+                ((ir->epc == PressureCoupling::ParrinelloRahman || ir->epc == PressureCoupling::Mttk)
                  && (ir->ref_p[YY][XX] != 0 || ir->ref_p[ZZ][XX] != 0 || ir->ref_p[ZZ][YY] != 0));
 
         return !ETC_ANDERSEN(ir->etc) && !shearWithPR;
@@ -1581,7 +1584,7 @@ bool integratorHasConservedEnergyQuantity(const t_inputrec* ir)
 
 bool integratorHasReferenceTemperature(const t_inputrec* ir)
 {
-    return ((ir->etc != etcNO) || EI_SD(ir->eI) || (ir->eI == eiBD) || EI_TPI(ir->eI));
+    return ((ir->etc != TemperatureCoupling::No) || EI_SD(ir->eI) || (ir->eI == eiBD) || EI_TPI(ir->eI));
 }
 
 int inputrec2nboundeddim(const t_inputrec* ir)
@@ -1619,7 +1622,7 @@ real maxReferenceTemperature(const t_inputrec& ir)
         return 0;
     }
 
-    if (EI_MD(ir.eI) && ir.etc == etcNO)
+    if (EI_MD(ir.eI) && ir.etc == TemperatureCoupling::No)
     {
         return -1;
     }
index 996e6d30cfd5c04e5e446a398060620b8938bf64..dc2350acd746a7478f4ec78dae6d2fadb3d91d0e 100644 (file)
@@ -379,13 +379,13 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
     //! Continuation run: starting state is correct (ie. constrained)
     gmx_bool bContinuation;
     //! Temperature coupling
-    int etc;
+    TemperatureCoupling etc;
     //! Interval in steps for temperature coupling
     int nsttcouple;
     //! Whether to print nose-hoover chains
     gmx_bool bPrintNHChains;
     //! Pressure coupling
-    int epc;
+    PressureCoupling epc;
     //! Pressure coupling type
     int epct;
     //! Interval in steps for pressure coupling
@@ -572,11 +572,11 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
 
 int ir_optimal_nstcalcenergy(const t_inputrec* ir);
 
-int tcouple_min_integration_steps(int etc);
+int tcouple_min_integration_steps(TemperatureCoupling etc);
 
 int ir_optimal_nsttcouple(const t_inputrec* ir);
 
-int pcouple_min_integration_steps(int epc);
+int pcouple_min_integration_steps(PressureCoupling epc);
 
 int ir_optimal_nstpcouple(const t_inputrec* ir);
 
index bd498df33206b5252274ecbd055d3d1f3c1527fd..c3313017cb7a0878a1e181c278500ba444c20829 100644 (file)
@@ -4,7 +4,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 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,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.
@@ -39,6 +39,8 @@
 
 #include "md_enums.h"
 
+#include "gromacs/utility/enumerationhelpers.h"
+
 const char* enum_name(int index, int max_index, const char* const names[])
 {
     if (index < 0 || index >= max_index)
@@ -95,13 +97,21 @@ const char* eintmod_names[eintmodNR + 1] = {
     "Exact-cutoff",           "Force-switch",    nullptr
 };
 
-const char* etcoupl_names[etcNR + 1] = {
-    "No", "Berendsen", "Nose-Hoover", "yes", "Andersen", "Andersen-massive", "V-rescale", nullptr
-}; /* yes is alias for berendsen */
+const char* enumValueToString(TemperatureCoupling enumValue)
+{
+    static constexpr gmx::EnumerationArray<TemperatureCoupling, const char*> temperatureCouplingNames = {
+        "No", "Berendsen", "Nose-Hoover", "yes", "Andersen", "Andersen-massive", "V-rescale"
+    }; /* yes is alias for berendsen */
+    return temperatureCouplingNames[enumValue];
+}
 
-const char* epcoupl_names[epcNR + 1] = { "No",        "Berendsen", "Parrinello-Rahman",
-                                         "Isotropic", "MTTK",      "C-rescale",
-                                         nullptr }; /* isotropic is alias for berendsen */
+const char* enumValueToString(PressureCoupling enumValue)
+{
+    static constexpr gmx::EnumerationArray<PressureCoupling, const char*> pressureCouplingNames = {
+        "No", "Berendsen", "Parrinello-Rahman", "Isotropic", "MTTK", "C-rescale"
+    }; /* isotropic is alias for berendsen */
+    return pressureCouplingNames[enumValue];
+}
 
 const char* epcoupltype_names[epctNR + 1] = { "Isotropic",
                                               "Semiisotropic",
index 763143361219702ba8f278bca6f678038527c7c1..2f358ca418aaab7f5e8f645a0350e3070eb56e61 100644 (file)
@@ -4,7 +4,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 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,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.
@@ -85,43 +85,50 @@ enum eChannel
 /*! \brief Temperature coupling type
  *
  * yes is an alias for berendsen
+ *
+ * Note: Keep `Count` as the second-to-last entry, and `Default` as the last entry -
+ *       this is needed to keep EnumerationWrapper, EnumerationArray and (de)serialization
+ *       working.
  */
-enum
-{
-    etcNO,
-    etcBERENDSEN,
-    etcNOSEHOOVER,
-    etcYES,
-    etcANDERSEN,
-    etcANDERSENMASSIVE,
-    etcVRESCALE,
-    etcNR
-};
-//! Strings corresponding to temperatyre coupling types
-extern const char* etcoupl_names[etcNR + 1];
-//! Macro for selecting t coupling string
-#define ETCOUPLTYPE(e) enum_name(e, etcNR, etcoupl_names)
+enum class TemperatureCoupling : int
+{
+    No,
+    Berendsen,
+    NoseHoover,
+    Yes,
+    Andersen,
+    AndersenMassive,
+    VRescale,
+    Count,
+    Default = No
+};
+//! Return names of temperature coupling schemes
+const char* enumValueToString(TemperatureCoupling enumValue);
 //! Return whether this is andersen coupling
-#define ETC_ANDERSEN(e) (((e) == etcANDERSENMASSIVE) || ((e) == etcANDERSEN))
+#define ETC_ANDERSEN(e) \
+    (((e) == TemperatureCoupling::AndersenMassive) || ((e) == TemperatureCoupling::Andersen))
 
 /*! \brief Pressure coupling types
  *
  * isotropic is an alias for berendsen
+ *
+ * Note: Keep `Count` as the second-to-last entry, and `Default` as the last entry -
+ *       this is needed to keep EnumerationWrapper, EnumerationArray and (de)serialization
+ *       working.
  */
-enum
-{
-    epcNO,
-    epcBERENDSEN,
-    epcPARRINELLORAHMAN,
-    epcISOTROPIC,
-    epcMTTK,
-    epcCRESCALE,
-    epcNR
-};
-//! String corresponding to pressure coupling algorithm
-extern const char* epcoupl_names[epcNR + 1];
-//! Macro to return the correct pcoupling string
-#define EPCOUPLTYPE(e) enum_name(e, epcNR, epcoupl_names)
+enum class PressureCoupling : int
+{
+    No,
+    Berendsen,
+    ParrinelloRahman,
+    Isotropic,
+    Mttk,
+    CRescale,
+    Count,
+    Default = No
+};
+//! Return names of pressure coupling schemes
+const char* enumValueToString(PressureCoupling enumValue);
 
 //! Flat-bottom posres geometries
 enum
index 3109250f9b467cd610b06d9077a3affe2aaf63ce..d43052c48f0f714f5a911984d6530be292c25f20 100644 (file)
@@ -111,8 +111,8 @@ void ModularSimulator::addIntegrationElements(ModularSimulatorAlgorithmBuilder*
         // The leap frog integration algorithm
         builder->add<ForceElement>();
         builder->add<StatePropagatorData::Element>();
-        if (legacySimulatorData_->inputrec->etc == etcVRESCALE
-            || legacySimulatorData_->inputrec->etc == etcBERENDSEN)
+        if (legacySimulatorData_->inputrec->etc == TemperatureCoupling::VRescale
+            || legacySimulatorData_->inputrec->etc == TemperatureCoupling::Berendsen)
         {
             builder->add<VelocityScalingTemperatureCoupling>(
                     -1, UseFullStepKE::No, ReportPreviousStepConservedEnergy::No);
@@ -126,7 +126,7 @@ void ModularSimulator::addIntegrationElements(ModularSimulatorAlgorithmBuilder*
         }
         builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::LeapFrog>>();
         builder->add<EnergyData::Element>();
-        if (legacySimulatorData_->inputrec->epc == epcPARRINELLORAHMAN)
+        if (legacySimulatorData_->inputrec->epc == PressureCoupling::ParrinelloRahman)
         {
             builder->add<ParrinelloRahmanBarostat>(-1);
         }
@@ -145,8 +145,8 @@ void ModularSimulator::addIntegrationElements(ModularSimulatorAlgorithmBuilder*
         }
         builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::VelocityVerlet>>();
         builder->add<StatePropagatorData::Element>();
-        if (legacySimulatorData_->inputrec->etc == etcVRESCALE
-            || legacySimulatorData_->inputrec->etc == etcBERENDSEN)
+        if (legacySimulatorData_->inputrec->etc == TemperatureCoupling::VRescale
+            || legacySimulatorData_->inputrec->etc == TemperatureCoupling::Berendsen)
         {
             builder->add<VelocityScalingTemperatureCoupling>(
                     0, UseFullStepKE::Yes, ReportPreviousStepConservedEnergy::Yes);
@@ -161,7 +161,7 @@ void ModularSimulator::addIntegrationElements(ModularSimulatorAlgorithmBuilder*
         }
         builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::VelocityVerlet>>();
         builder->add<EnergyData::Element>();
-        if (legacySimulatorData_->inputrec->epc == epcPARRINELLORAHMAN)
+        if (legacySimulatorData_->inputrec->epc == PressureCoupling::ParrinelloRahman)
         {
             builder->add<ParrinelloRahmanBarostat>(-1);
         }
@@ -206,7 +206,7 @@ bool ModularSimulator::isInputCompatible(bool                             exitOn
 
     GMX_RELEASE_ASSERT(
             !(modularSimulatorExplicitlyTurnedOff && inputrec->eI == eiVV
-              && inputrec->epc == epcPARRINELLORAHMAN),
+              && inputrec->epc == PressureCoupling::ParrinelloRahman),
             "Cannot use a Parrinello-Rahman barostat with md-vv and "
             "GMX_DISABLE_MODULAR_SIMULATOR=ON, "
             "as the Parrinello-Rahman barostat is not implemented in the legacy simulator. Unset "
@@ -228,14 +228,16 @@ bool ModularSimulator::isInputCompatible(bool                             exitOn
             isInputCompatible
             && conditionalAssert(!doRerun, "Rerun is not supported by the modular simulator.");
     isInputCompatible = isInputCompatible
-                        && conditionalAssert(inputrec->etc == etcNO || inputrec->etc == etcVRESCALE
-                                                     || inputrec->etc == etcBERENDSEN,
+                        && conditionalAssert(inputrec->etc == TemperatureCoupling::No
+                                                     || inputrec->etc == TemperatureCoupling::VRescale
+                                                     || inputrec->etc == TemperatureCoupling::Berendsen,
                                              "Only v-rescale and Berendsen thermostat are "
                                              "supported by the modular simulator.");
     isInputCompatible =
             isInputCompatible
             && conditionalAssert(
-                       inputrec->epc == epcNO || inputrec->epc == epcPARRINELLORAHMAN,
+                       inputrec->epc == PressureCoupling::No
+                               || inputrec->epc == PressureCoupling::ParrinelloRahman,
                        "Only Parrinello-Rahman barostat is supported by the modular simulator.");
     isInputCompatible =
             isInputCompatible
@@ -356,7 +358,8 @@ bool ModularSimulator::isInputCompatible(bool                             exitOn
                         && conditionalAssert(!GMX_FAHCORE,
                                              "GMX_FAHCORE not supported by the modular simulator.");
     GMX_RELEASE_ASSERT(
-            isInputCompatible || !(inputrec->eI == eiVV && inputrec->epc == epcPARRINELLORAHMAN),
+            isInputCompatible
+                    || !(inputrec->eI == eiVV && 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.");
index 89e8b69e055a08baa6cd8c78a861162ca659f51e..95158d50342b871022510b5d8f31b07fa3c7a052 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2019,2020, 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.
@@ -283,7 +283,7 @@ VelocityScalingTemperatureCoupling::VelocityScalingTemperatureCoupling(
         const real*                       couplingTime,
         const real*                       numDegreesOfFreedom,
         EnergyData*                       energyData,
-        TemperatureCouplingType           couplingType) :
+        TemperatureCoupling               couplingType) :
     nstcouple_(nstcouple),
     offset_(offset),
     useFullStepKE_(useFullStepKE),
@@ -301,17 +301,17 @@ VelocityScalingTemperatureCoupling::VelocityScalingTemperatureCoupling(
         temperatureCouplingIntegralPreviousStep_ = temperatureCouplingIntegral_;
     }
     energyData->setVelocityScalingTemperatureCoupling(this);
-    if (couplingType == etcVRESCALE)
+    if (couplingType == TemperatureCoupling::VRescale)
     {
         temperatureCouplingImpl_ = std::make_unique<VRescaleTemperatureCoupling>(seed);
     }
-    else if (couplingType == etcBERENDSEN)
+    else if (couplingType == TemperatureCoupling::Berendsen)
     {
         temperatureCouplingImpl_ = std::make_unique<BerendsenTemperatureCoupling>();
     }
     else
     {
-        throw NotImplementedError("Temperature coupling " + std::string(ETCOUPLTYPE(couplingType))
+        throw NotImplementedError("Temperature coupling " + std::string(enumValueToString(couplingType))
                                   + " is not implemented for modular simulator.");
     }
 }
index 9bd3f740382d0501b4e122f7f5fdca9465a39a20..68daad8497596225b332e73e73e9f388acce9581 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2019,2020, 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.
@@ -75,9 +75,6 @@ enum class ReportPreviousStepConservedEnergy
     Count
 };
 
-//! Typedef to match current use of ints as types.
-using TemperatureCouplingType = int;
-
 /*! \internal
  * \ingroup module_modularsimulator
  * \brief Element implementing the a velocity-scaling thermostat
@@ -104,7 +101,7 @@ public:
                                        const real*                       couplingTime,
                                        const real*                       numDegreesOfFreedom,
                                        EnergyData*                       energyData,
-                                       TemperatureCouplingType           couplingType);
+                                       TemperatureCoupling               couplingType);
 
     /*! \brief Register run function for step / time
      *
index c9c3f3df8db4ab990dc8f8d0144b5273e6c8e764..db31748bbf1e16d4f36d01c849d8bae7278bdd04 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,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.
@@ -80,7 +80,7 @@
 static bool supportsDynamicPairlistGenerationInterval(const t_inputrec& ir)
 {
     return ir.cutoff_scheme == ecutsVERLET && EI_DYNAMICS(ir.eI)
-           && !(EI_MD(ir.eI) && ir.etc == etcNO) && ir.verletbuf_tol > 0;
+           && !(EI_MD(ir.eI) && ir.etc == TemperatureCoupling::No) && ir.verletbuf_tol > 0;
 }
 
 /*! \brief Cost of non-bonded kernels
@@ -190,7 +190,7 @@ void increaseNstlist(FILE*               fp,
         }
     }
 
-    if (EI_MD(ir->eI) && ir->etc == etcNO)
+    if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No)
     {
         if (MASTER(cr))
         {
index 7d96638fde3fe7c3ad8444fac2575a9d7a53b1c4..5d771e526588a4723540b1a09a332cc9133570f1 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 2015,2016,2017,2018,2019 by the GROMACS development team.
- * 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.
@@ -617,12 +617,12 @@ bool decideWhetherToUseGpuForUpdate(const bool                     isDomainDecom
     {
         errorMessage += "Only the md integrator is supported.\n";
     }
-    if (inputrec.etc == etcNOSEHOOVER)
+    if (inputrec.etc == TemperatureCoupling::NoseHoover)
     {
         errorMessage += "Nose-Hoover temperature coupling is not supported.\n";
     }
-    if (!(inputrec.epc == epcNO || inputrec.epc == epcPARRINELLORAHMAN
-          || inputrec.epc == epcBERENDSEN || inputrec.epc == epcCRESCALE))
+    if (!(inputrec.epc == PressureCoupling::No || inputrec.epc == PressureCoupling::ParrinelloRahman
+          || inputrec.epc == PressureCoupling::Berendsen || inputrec.epc == PressureCoupling::CRescale))
     {
         errorMessage +=
                 "Only Parrinello-Rahman, Berendsen, and C-rescale pressure coupling are "
index f7889056b162b0055549e01f5b948fae6bee8653..9aba51b78dc24efe70c3e954fbffc877457a7406 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,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.
@@ -118,15 +118,15 @@ void writeParameterInformation(TextWriter* writer, const t_inputrec& ir, bool wr
     }
     writer->writeLine(formatString(
             "A single cut-off of %g nm was used for Van der Waals interactions.", ir.rlist));
-    if (ir.etc != 0)
+    if (ir.etc != TemperatureCoupling::No)
     {
         writer->writeLine(formatString("Temperature coupling was done with the %s algorithm.",
-                                       etcoupl_names[ir.etc]));
+                                       enumValueToString(ir.etc)));
     }
-    if (ir.epc != 0)
+    if (ir.epc != PressureCoupling::No)
     {
         writer->writeLine(formatString("Pressure coupling was done with the %s algorithm.",
-                                       epcoupl_names[ir.epc]));
+                                       enumValueToString(ir.epc)));
     }
     writer->ensureEmptyLine();
 }
index 6ab41cd3d3e113ee327325041f6ecfbe61abc765..e8e39484cea25645e9a9e81638261a84f5fb02e3 100644 (file)
@@ -4,7 +4,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 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,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.
@@ -47,6 +47,7 @@
 
 #include <cstdio>
 
+#include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/real.h"
 
@@ -84,4 +85,18 @@ void cmp_float(FILE* fp, const char* s, int index, float i1, float i2, float fto
 //! Compares two doubles and prints differences.
 void cmp_double(FILE* fp, const char* s, int index, double i1, double i2, double ftol, double abstol);
 
+//! Compare two enums of generic type and print differences.
+template<typename EnumType>
+void cmpEnum(FILE* fp, const char* s, EnumType value1, EnumType value2)
+{
+    if (value1 != value2)
+    {
+        fprintf(fp, "%s (", s);
+        fprintf(fp, "%s", enumValueToString(value1));
+        fprintf(fp, " - ");
+        fprintf(fp, "%s", enumValueToString(value2));
+        fprintf(fp, ")\n");
+    }
+}
+
 #endif
index aa68dea4f7d637c5a5e69806bf42f23f9048f05f..ffa4dd634500b2764a1053613accba1546d1a5cc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2018,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.
@@ -179,6 +179,17 @@ public:
         }
     }
     ///@}
+
+    //! Serialize enum value with underlying type int
+    template<typename EnumType>
+    void doEnumAsInt(EnumType* enumValue)
+    {
+        static_assert(std::is_same<std::underlying_type_t<EnumType>, int>::value,
+                      "Only enums with underlying type int are supported.");
+        auto castedValue = static_cast<int>(*enumValue);
+        doInt(&castedValue);
+        *enumValue = static_cast<EnumType>(castedValue);
+    }
 };
 
 } // namespace gmx