Refactor md_enums
authorPaul Bauer <paul.bauer.q@gmail.com>
Mon, 22 Feb 2021 10:24:36 +0000 (10:24 +0000)
committerAndrey Alekseenko <al42and@gmail.com>
Mon, 22 Feb 2021 10:24:36 +0000 (10:24 +0000)
The old enum handling caused clang-tidy to complain about the globally
defined symbols for the enum strings, and also violated type safety by
using the enums both as enumerations and integers.

Changed all exposed enum strings and their corresponding char arrays
to classes and enumeration arrays.

Used enumeration array in a few places where it made sense to me.

Was not able to get rid of some instances where the enum to integer
conversion was abused.

Moved enum reading template to header to have it available for reading
all enums.

151 files changed:
api/nblib/gmxsetup.cpp
src/gromacs/applied_forces/awh/awh.cpp
src/gromacs/applied_forces/awh/read_params.cpp
src/gromacs/domdec/collect.cpp
src/gromacs/domdec/distribute.cpp
src/gromacs/domdec/domdec.cpp
src/gromacs/domdec/domdec_setup.cpp
src/gromacs/domdec/domdec_topology.cpp
src/gromacs/domdec/mdsetup.cpp
src/gromacs/domdec/partition.cpp
src/gromacs/ewald/ewald.cpp
src/gromacs/ewald/long_range_correction.cpp
src/gromacs/ewald/pme.cpp
src/gromacs/ewald/pme_gpu.cpp
src/gromacs/ewald/pme_internal.h
src/gromacs/ewald/pme_load_balancing.cpp
src/gromacs/ewald/tests/pmebsplinetest.cpp
src/gromacs/ewald/tests/pmegathertest.cpp
src/gromacs/ewald/tests/pmesolvetest.cpp
src/gromacs/ewald/tests/pmesplinespreadtest.cpp
src/gromacs/fileio/checkpoint.cpp
src/gromacs/fileio/checkpoint.h
src/gromacs/fileio/readinp.cpp
src/gromacs/fileio/readinp.h
src/gromacs/fileio/tpxio.cpp
src/gromacs/gmxana/gmx_bar.cpp
src/gromacs/gmxana/gmx_disre.cpp
src/gromacs/gmxana/gmx_energy.cpp
src/gromacs/gmxana/gmx_nmr.cpp
src/gromacs/gmxana/gmx_wham.cpp
src/gromacs/gmxlib/nonbonded/nb_free_energy.cpp
src/gromacs/gmxlib/nonbonded/nb_kernel.h
src/gromacs/gmxpreprocess/convparm.cpp
src/gromacs/gmxpreprocess/convparm.h
src/gromacs/gmxpreprocess/grompp.cpp
src/gromacs/gmxpreprocess/readir.cpp
src/gromacs/gmxpreprocess/readpull.cpp
src/gromacs/gmxpreprocess/readrot.cpp
src/gromacs/gmxpreprocess/topio.cpp
src/gromacs/gmxpreprocess/topio.h
src/gromacs/gmxpreprocess/toppush.cpp
src/gromacs/gmxpreprocess/toppush.h
src/gromacs/imd/imd.cpp
src/gromacs/listed_forces/disre.cpp
src/gromacs/listed_forces/listed_forces.cpp
src/gromacs/listed_forces/listed_forces.h
src/gromacs/listed_forces/listed_internal.h
src/gromacs/listed_forces/pairs.cpp
src/gromacs/listed_forces/position_restraints.cpp
src/gromacs/listed_forces/position_restraints.h
src/gromacs/mdlib/broadcaststructs.cpp
src/gromacs/mdlib/calc_verletbuf.cpp
src/gromacs/mdlib/compute_io.cpp
src/gromacs/mdlib/constr.cpp
src/gromacs/mdlib/constr.h
src/gromacs/mdlib/constraintrange.cpp
src/gromacs/mdlib/coupling.cpp
src/gromacs/mdlib/dispersioncorrection.cpp
src/gromacs/mdlib/dispersioncorrection.h
src/gromacs/mdlib/enerdata_utils.cpp
src/gromacs/mdlib/energyoutput.cpp
src/gromacs/mdlib/expanded.cpp
src/gromacs/mdlib/expanded_internal.cpp
src/gromacs/mdlib/expanded_internal.h
src/gromacs/mdlib/force.cpp
src/gromacs/mdlib/forcerec.cpp
src/gromacs/mdlib/forcerec_threading.h
src/gromacs/mdlib/freeenergyparameters.cpp
src/gromacs/mdlib/freeenergyparameters.h
src/gromacs/mdlib/lincs.cpp
src/gromacs/mdlib/md_support.cpp
src/gromacs/mdlib/mdatoms.cpp
src/gromacs/mdlib/mdebin_bar.cpp
src/gromacs/mdlib/mdebin_bar.h
src/gromacs/mdlib/mdoutf.cpp
src/gromacs/mdlib/perf_est.cpp
src/gromacs/mdlib/rbin.cpp
src/gromacs/mdlib/rbin.h
src/gromacs/mdlib/rf_util.cpp
src/gromacs/mdlib/shake.cpp
src/gromacs/mdlib/sim_util.cpp
src/gromacs/mdlib/stat.cpp
src/gromacs/mdlib/tests/constrtestdata.cpp
src/gromacs/mdlib/tests/energyoutput.cpp
src/gromacs/mdlib/tests/expanded.cpp
src/gromacs/mdlib/tests/freeenergyparameters.cpp
src/gromacs/mdlib/tests/leapfrogtestdata.cpp
src/gromacs/mdlib/update.cpp
src/gromacs/mdlib/update_vv.cpp
src/gromacs/mdlib/vcm.cpp
src/gromacs/mdlib/vcm.h
src/gromacs/mdlib/wall.cpp
src/gromacs/mdrun/legacysimulator.cpp
src/gromacs/mdrun/md.cpp
src/gromacs/mdrun/mimic.cpp
src/gromacs/mdrun/minimize.cpp
src/gromacs/mdrun/replicaexchange.cpp
src/gromacs/mdrun/rerun.cpp
src/gromacs/mdrun/runner.cpp
src/gromacs/mdrun/shellfc.cpp
src/gromacs/mdrun/tpi.cpp
src/gromacs/mdtypes/awh_params.h
src/gromacs/mdtypes/enerdata.h
src/gromacs/mdtypes/fcdata.h
src/gromacs/mdtypes/forcerec.h
src/gromacs/mdtypes/inputrec.cpp
src/gromacs/mdtypes/inputrec.h
src/gromacs/mdtypes/interaction_const.h
src/gromacs/mdtypes/md_enums.cpp
src/gromacs/mdtypes/md_enums.h
src/gromacs/mdtypes/multipletimestepping.cpp
src/gromacs/mdtypes/nblist.h
src/gromacs/mdtypes/pull_params.h
src/gromacs/mdtypes/state.cpp
src/gromacs/mdtypes/state.h
src/gromacs/mdtypes/swaphistory.h
src/gromacs/mdtypes/tests/multipletimestepping.cpp
src/gromacs/modularsimulator/computeglobalselement.cpp
src/gromacs/modularsimulator/constraintelement.cpp
src/gromacs/modularsimulator/energydata.cpp
src/gromacs/modularsimulator/forceelement.cpp
src/gromacs/modularsimulator/forceelement.h
src/gromacs/modularsimulator/freeenergyperturbationdata.cpp
src/gromacs/modularsimulator/freeenergyperturbationdata.h
src/gromacs/modularsimulator/modularsimulator.cpp
src/gromacs/modularsimulator/parrinellorahmanbarostat.cpp
src/gromacs/modularsimulator/pmeloadbalancehelper.cpp
src/gromacs/modularsimulator/simulatoralgorithm.cpp
src/gromacs/modularsimulator/statepropagatordata.cpp
src/gromacs/nbnxm/benchmark/bench_setup.cpp
src/gromacs/nbnxm/cuda/nbnxm_cuda_data_mgmt.cu
src/gromacs/nbnxm/kerneldispatch.cpp
src/gromacs/nbnxm/nbnxm_gpu_data_mgmt.cpp
src/gromacs/nbnxm/nbnxm_setup.cpp
src/gromacs/nbnxm/opencl/nbnxm_ocl_data_mgmt.cpp
src/gromacs/nbnxm/pairlist_tuning.cpp
src/gromacs/nbnxm/sycl/nbnxm_sycl_data_mgmt.cpp
src/gromacs/pulling/output.cpp
src/gromacs/pulling/pull.cpp
src/gromacs/pulling/pull_rotation.cpp
src/gromacs/pulling/pullutil.cpp
src/gromacs/pulling/tests/pull.cpp
src/gromacs/swap/swapcoords.cpp
src/gromacs/tables/forcetable.cpp
src/gromacs/taskassignment/decidegpuusage.cpp
src/gromacs/taskassignment/resourcedivision.cpp
src/gromacs/tools/check.cpp
src/gromacs/tools/report_methods.cpp
src/gromacs/tools/tune_pme.cpp
src/gromacs/utility/enumerationhelpers.h
src/gromacs/utility/iserializer.h

index b314ad7c0fad76e86f620a05b198ae1faeade9f0..b19744755b501a126f8c656b08f023b783ce7d8c 100644 (file)
@@ -231,22 +231,26 @@ void NbvSetupUtil::setupStepWorkload(const NBKernelOptions& options)
 
 void NbvSetupUtil::setupInteractionConst(const NBKernelOptions& options)
 {
-    gmxForceCalculator_->interactionConst_->vdwtype      = evdwCUT;
-    gmxForceCalculator_->interactionConst_->vdw_modifier = eintmodPOTSHIFT;
+    gmxForceCalculator_->interactionConst_->vdwtype      = VanDerWaalsType::Cut;
+    gmxForceCalculator_->interactionConst_->vdw_modifier = InteractionModifiers::PotShift;
     gmxForceCalculator_->interactionConst_->rvdw         = options.pairlistCutoff;
 
     switch (options.coulombType)
     {
-        case CoulombType::Pme: gmxForceCalculator_->interactionConst_->eeltype = eelPME; break;
-        case CoulombType::Cutoff: gmxForceCalculator_->interactionConst_->eeltype = eelCUT; break;
+        case CoulombType::Pme:
+            gmxForceCalculator_->interactionConst_->eeltype = CoulombInteractionType::Pme;
+            break;
+        case CoulombType::Cutoff:
+            gmxForceCalculator_->interactionConst_->eeltype = CoulombInteractionType::Cut;
+            break;
         case CoulombType::ReactionField:
-            gmxForceCalculator_->interactionConst_->eeltype = eelRF;
+            gmxForceCalculator_->interactionConst_->eeltype = CoulombInteractionType::RF;
             break;
         case CoulombType::Count: throw InputException("Unsupported electrostatic interaction");
     }
-    gmxForceCalculator_->interactionConst_->coulomb_modifier = eintmodPOTSHIFT;
+    gmxForceCalculator_->interactionConst_->coulomb_modifier = InteractionModifiers::PotShift;
     gmxForceCalculator_->interactionConst_->rcoulomb         = options.pairlistCutoff;
-    // Note: values correspond to ic->coulomb_modifier = eintmodPOTSHIFT
+    // Note: values correspond to ic->coulomb_modifier = InteractionModifiers::PotShift
     gmxForceCalculator_->interactionConst_->dispersion_shift.cpot =
             -1.0 / gmx::power6(gmxForceCalculator_->interactionConst_->rvdw);
     gmxForceCalculator_->interactionConst_->repulsion_shift.cpot =
index 4cf4249ca09d8db047d9326e3f53c9328abaac97..a772d31a34345daf5d6129a893d13d4548f0f7ec 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,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.
@@ -235,7 +235,7 @@ Awh::Awh(FILE*                 fplog,
             if (awhDimParams.eCoordProvider == eawhcoordproviderPULL)
             {
                 const t_pull_coord& pullCoord = inputRecord.pull->coord[awhDimParams.coordIndex];
-                if (pullCoord.eGeom == epullgDIRPBC)
+                if (pullCoord.eGeom == PullGroupGeometry::DirectionPBC)
                 {
                     GMX_THROW(InvalidInputError(
                             "Pull geometry 'direction-periodic' is not supported by AWH"));
index 013c3ced268a155a6b46367dead0ea18025d3029..bbdd4f6451388f615536460ba960f36b5dc7e6bf 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.
@@ -186,10 +186,10 @@ void checkPullDimParams(const std::string&   prefix,
     }
 
     /* Grid params for each axis */
-    int eGeom = pull_params.coord[dimParams->coordIndex].eGeom;
+    PullGroupGeometry eGeom = pull_params.coord[dimParams->coordIndex].eGeom;
 
     /* Check that the requested interval is in allowed range */
-    if (eGeom == epullgDIST)
+    if (eGeom == PullGroupGeometry::Distance)
     {
         if (dimParams->origin < 0 || dimParams->end < 0)
         {
@@ -201,10 +201,10 @@ void checkPullDimParams(const std::string&   prefix,
                       dimParams->origin,
                       prefix.c_str(),
                       dimParams->end,
-                      EPULLGEOM(epullgDIR));
+                      enumValueToString(PullGroupGeometry::Direction));
         }
     }
-    else if (eGeom == epullgANGLE || eGeom == epullgANGLEAXIS)
+    else if (eGeom == PullGroupGeometry::Angle || eGeom == PullGroupGeometry::AngleAxis)
     {
         if (dimParams->origin < 0 || dimParams->end > 180)
         {
@@ -215,11 +215,11 @@ void checkPullDimParams(const std::string&   prefix,
                       dimParams->origin,
                       prefix.c_str(),
                       dimParams->end,
-                      EPULLGEOM(epullgANGLE),
-                      EPULLGEOM(epullgANGLEAXIS));
+                      enumValueToString(PullGroupGeometry::Angle),
+                      enumValueToString(PullGroupGeometry::AngleAxis));
         }
     }
-    else if (eGeom == epullgDIHEDRAL)
+    else if (eGeom == PullGroupGeometry::Dihedral)
     {
         if (dimParams->origin < -180 || dimParams->end > 180)
         {
@@ -230,7 +230,7 @@ void checkPullDimParams(const std::string&   prefix,
                       dimParams->origin,
                       prefix.c_str(),
                       dimParams->end,
-                      EPULLGEOM(epullgDIHEDRAL));
+                      enumValueToString(PullGroupGeometry::Dihedral));
         }
     }
 }
@@ -244,11 +244,11 @@ void checkPullDimParams(const std::string&   prefix,
  * \param[in] efep           This is the type of FEP calculation (efep enumerator).
  * \param[in,out] wi         Struct for bookeeping warnings.
  */
-void checkFepLambdaDimParams(const std::string&  prefix,
-                             const AwhDimParams* dimParams,
-                             const t_lambda*     lambdaParams,
-                             const int           efep,
-                             warninp_t           wi)
+void checkFepLambdaDimParams(const std::string&               prefix,
+                             const AwhDimParams*              dimParams,
+                             const t_lambda*                  lambdaParams,
+                             const FreeEnergyPerturbationType efep,
+                             warninp_t                        wi)
 {
     std::string opt;
 
@@ -269,14 +269,14 @@ void checkFepLambdaDimParams(const std::string&  prefix,
                   -1);
     }
 
-    if (efep == efepSLOWGROWTH || lambdaParams->delta_lambda != 0)
+    if (efep == FreeEnergyPerturbationType::SlowGrowth || lambdaParams->delta_lambda != 0)
     {
         gmx_fatal(FARGS,
                   "AWH coupled to the free energy lambda state is not compatible with slow-growth "
                   "and delta-lambda must be 0.");
     }
 
-    if (efep == efepEXPANDED)
+    if (efep == FreeEnergyPerturbationType::Expanded)
     {
         gmx_fatal(FARGS,
                   "AWH is not treated like other expanded ensemble methods. Do not use expanded.");
@@ -441,13 +441,13 @@ void checkDimParams(const std::string& prefix, AwhDimParams* dimParams, const t_
     }
     else if (dimParams->eCoordProvider == eawhcoordproviderFREE_ENERGY_LAMBDA)
     {
-        if (ir->efep == efepNO)
+        if (ir->efep == FreeEnergyPerturbationType::No)
         {
             gmx_fatal(FARGS,
                       "AWH biasing along a free energy lambda state dimension is only compatible "
                       "with free energy turned on");
         }
-        checkFepLambdaDimParams(prefix, dimParams, ir->fepvals, ir->efep, wi);
+        checkFepLambdaDimParams(prefix, dimParams, ir->fepvals.get(), ir->efep, wi);
     }
     else
     {
@@ -516,7 +516,7 @@ void readBiasParams(std::vector<t_inpfile>* inp,
                              "distribution: no or yes");
     }
     opt                                 = prefix + "-equilibrate-histogram";
-    awhBiasParams->equilibrateHistogram = (get_eeenum(inp, opt, yesno_names, wi) != 0);
+    awhBiasParams->equilibrateHistogram = (getEnum<Boolean>(inp, opt.c_str(), wi) != Boolean::No);
 
     if (bComment)
     {
@@ -547,7 +547,7 @@ void readBiasParams(std::vector<t_inpfile>* inp,
         printStringNoNewline(inp, "Initialize PMF and target with user data: no or yes");
     }
     opt                      = prefix + "-user-data";
-    awhBiasParams->bUserData = get_eeenum(inp, opt, yesno_names, wi);
+    awhBiasParams->bUserData = getEnum<Boolean>(inp, opt.c_str(), wi) != Boolean::No;
 
     if (bComment)
     {
@@ -813,7 +813,7 @@ AwhParams* readAwhParams(std::vector<t_inpfile>* inp, warninp_t wi)
     printStringNoNewline(
             inp, "When true, biases with share-group>0 are shared between multiple simulations");
     opt                          = "awh-share-multisim";
-    awhParams->shareBiasMultisim = (get_eeenum(inp, opt, yesno_names, wi) != 0);
+    awhParams->shareBiasMultisim = (getEnum<Boolean>(inp, opt.c_str(), wi) != Boolean::No);
 
     printStringNoNewline(inp, "The number of independent AWH biases");
     opt                = "awh-nbias";
@@ -892,7 +892,7 @@ static double get_pull_coord_period(const t_pull_coord& pullCoordParams, const t
 {
     double period = 0;
 
-    if (pullCoordParams.eGeom == epullgDIR)
+    if (pullCoordParams.eGeom == PullGroupGeometry::Direction)
     {
         const real margin = 0.001;
         // Make dims periodic when the interval covers > 95%
@@ -921,7 +921,7 @@ static double get_pull_coord_period(const t_pull_coord& pullCoordParams, const t
             }
         }
     }
-    else if (pullCoordParams.eGeom == epullgDIHEDRAL)
+    else if (pullCoordParams.eGeom == PullGroupGeometry::Dihedral)
     {
         /* The dihedral angle is periodic in -180 to 180 deg */
         period = 360;
@@ -1086,21 +1086,22 @@ static void setStateDependentAwhPullDimParams(AwhDimParams*        dimParams,
 {
     const t_pull_coord& pullCoordParams = pull_params->coord[dimParams->coordIndex];
 
-    if (pullCoordParams.eGeom == epullgDIRPBC)
+    if (pullCoordParams.eGeom == PullGroupGeometry::DirectionPBC)
     {
         gmx_fatal(FARGS,
                   "AWH does not support pull geometry '%s'. "
                   "If the maximum distance between the groups is always "
                   "less than half the box size, "
                   "you can use geometry '%s' instead.",
-                  EPULLGEOM(epullgDIRPBC),
-                  EPULLGEOM(epullgDIR));
+                  enumValueToString(PullGroupGeometry::DirectionPBC),
+                  enumValueToString(PullGroupGeometry::Direction));
     }
 
     dimParams->period = get_pull_coord_period(pullCoordParams, pbc, dimParams->end - dimParams->origin);
     // We would like to check for scaling, but we don't have the full inputrec available here
     if (dimParams->period > 0
-        && !(pullCoordParams.eGeom == epullgANGLE || pullCoordParams.eGeom == epullgDIHEDRAL))
+        && !(pullCoordParams.eGeom == PullGroupGeometry::Angle
+             || pullCoordParams.eGeom == PullGroupGeometry::Dihedral))
     {
         bool coordIsScaled = false;
         for (int d2 = 0; d2 < DIM; d2++)
@@ -1118,7 +1119,7 @@ static void setStateDependentAwhPullDimParams(AwhDimParams*        dimParams,
                     "corresponding box vector, this is not supported.",
                     dimIndex + 1,
                     biasIndex + 1,
-                    EPULLGEOM(pullCoordParams.eGeom));
+                    enumValueToString(pullCoordParams.eGeom));
             warning(wi, mesg.c_str());
         }
     }
index 59c23df45fdd5f0a82220fac8a005bd789533216..63167f8f395d435d6496b504787df2de0916ab65 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.
@@ -49,6 +49,7 @@
 #include "gromacs/domdec/domdec_network.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdtypes/state.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/fatalerror.h"
 
 #include "atomdistribution.h"
@@ -272,7 +273,7 @@ void dd_collect_state(gmx_domdec_t* dd, const t_state* state_local, t_state* sta
         GMX_RELEASE_ASSERT(state->nhchainlength == nh,
                            "The global and local Nose-Hoover chain lengths should match");
 
-        for (int i = 0; i < efptNR; i++)
+        for (auto i : gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real>::keys())
         {
             state->lambda[i] = state_local->lambda[i];
         }
index 11609921bd5b09fbf5ddbee0aad4ddea479f164c..efa2611c1b6742c1f408560682bc466805f8437b 100644 (file)
@@ -54,6 +54,7 @@
 #include "gromacs/mdtypes/df_history.h"
 #include "gromacs/mdtypes/state.h"
 #include "gromacs/topology/topology.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/logger.h"
 
@@ -204,7 +205,7 @@ static void dd_distribute_state(gmx_domdec_t* dd, const t_state* state, t_state*
         GMX_RELEASE_ASSERT(state->nhchainlength == nh,
                            "The global and local Nose-Hoover chain lengths should match");
 
-        for (int i = 0; i < efptNR; i++)
+        for (auto i : gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real>::keys())
         {
             state_local->lambda[i] = state->lambda[i];
         }
@@ -239,7 +240,9 @@ static void dd_distribute_state(gmx_domdec_t* dd, const t_state* state, t_state*
         }
         state_local->baros_integral = state->baros_integral;
     }
-    dd_bcast(dd, ((efptNR) * sizeof(real)), state_local->lambda.data());
+    dd_bcast(dd,
+             (static_cast<int>(FreeEnergyPerturbationCouplingType::Count) * sizeof(real)),
+             state_local->lambda.data());
     dd_bcast(dd, sizeof(int), &state_local->fep_state);
     dd_bcast(dd, sizeof(real), &state_local->veta);
     dd_bcast(dd, sizeof(real), &state_local->vol0);
index 2077798da78a7a7e9b6a1843cc1dd8a876d92f2c..1c92f4fa327929b8102cd885c4d0d535d96fe24d 100644 (file)
@@ -1756,7 +1756,7 @@ static void check_dd_restrictions(const gmx_domdec_t* dd, const t_inputrec* ir,
         gmx_fatal(FARGS, "Domain decomposition does not work with nstlist=0");
     }
 
-    if (ir->comm_mode == ecmANGULAR && ir->pbcType != PbcType::No)
+    if (ir->comm_mode == ComRemovalAlgorithm::Angular && ir->pbcType != PbcType::No)
     {
         GMX_LOG(mdlog.warning)
                 .appendText(
@@ -1840,8 +1840,9 @@ static DlbState determineInitialDlbState(const gmx::MDLogger&     mdlog,
     /* Unsupported integrators */
     if (!EI_DYNAMICS(ir->eI))
     {
-        auto reasonStr = gmx::formatString(
-                "it is only supported with dynamics, not with integrator '%s'.", EI(ir->eI));
+        auto reasonStr =
+                gmx::formatString("it is only supported with dynamics, not with integrator '%s'.",
+                                  enumValueToString(ir->eI));
         return forceDlbOffOrBail(dlbState, reasonStr, mdlog);
     }
 
@@ -2039,7 +2040,7 @@ static DDSystemInfo getSystemInfo(const gmx::MDLogger&           mdlog,
 
     /* We need to decide on update groups early, as this affects communication distances */
     systemInfo.useUpdateGroups = false;
-    if (ir.cutoff_scheme == ecutsVERLET)
+    if (ir.cutoff_scheme == CutoffScheme::Verlet)
     {
         real cutoffMargin = std::sqrt(max_cutoff2(ir.pbcType, box)) - ir.rlist;
         setupUpdateGroups(mdlog, mtop, ir, cutoffMargin, &systemInfo);
index 6cf0368a71afb4adb3e87b196a202c67ebcb58b6..6efa4d960c2661c4ca3f3c80775ea76a0200ef84 100644 (file)
@@ -299,8 +299,8 @@ real comm_box_frac(const gmx::IVec& dd_nc, real cutoff, const gmx_ddbox_t& ddbox
 /*! \brief Return whether the DD inhomogeneous in the z direction */
 static gmx_bool inhomogeneous_z(const t_inputrec& ir)
 {
-    return ((EEL_PME(ir.coulombtype) || ir.coulombtype == eelEWALD) && ir.pbcType == PbcType::Xyz
-            && ir.ewald_geometry == eewg3DC);
+    return ((EEL_PME(ir.coulombtype) || ir.coulombtype == CoulombInteractionType::Ewald)
+            && ir.pbcType == PbcType::Xyz && ir.ewald_geometry == EwaldGeometry::ThreeDC);
 }
 
 /*! \brief Estimate cost of PME FFT communication
@@ -633,7 +633,7 @@ static gmx::IVec optimizeDDCells(const gmx::MDLogger& mdlog,
                 .appendTextFormatted(
                         "Ewald_geometry=%s: assuming inhomogeneous particle distribution in z, "
                         "will not decompose in z.",
-                        eewg_names[ir.ewald_geometry]);
+                        enumValueToString(ir.ewald_geometry));
     }
 
 
index 2ad6f301c4339f879a9bdbb844beb16b3c8db0ba..ebb604c5f293bd7d094672081b50d8bb0abc2024 100644 (file)
@@ -751,7 +751,7 @@ void dd_make_reverse_top(FILE*                           fplog,
                                       !dd->comm->systemInfo.haveSplitConstraints,
                                       !dd->comm->systemInfo.haveSplitSettles);
 
-    dd->reverse_top = new gmx_reverse_top_t(*mtop, ir->efep != efepNO, rtOptions);
+    dd->reverse_top = new gmx_reverse_top_t(*mtop, ir->efep != FreeEnergyPerturbationType::No, rtOptions);
 
     dd->nbonded_global = dd->reverse_top->numInteractionsToCheck;
 
index ce4458a49cbd5ff43ce72bdc87908c8b7de35329..6c76374521295cd75026894b3a1ed93f55a02163 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.
@@ -112,7 +112,7 @@ void mdAlgorithmsSetupAtomData(const t_commrec*     cr,
     }
     else
     {
-        gmx_mtop_generate_local_top(top_global, top, ir->efep != efepNO);
+        gmx_mtop_generate_local_top(top_global, top, ir->efep != FreeEnergyPerturbationType::No);
     }
 
     if (vsite)
index 7bc033884e7914163806f288e7778698f76837cb..0696694f6c9438db07dce2874b06c30be6bc8378 100644 (file)
@@ -2700,7 +2700,9 @@ void print_dd_statistics(const t_commrec* cr, const t_inputrec* ir, FILE* fplog)
                 {
                     fprintf(fplog,
                             " av. #atoms communicated per step for vsites: %d x %.1f\n",
-                            (EEL_PME(ir->coulombtype) || ir->coulombtype == eelEWALD) ? 3 : 2,
+                            (EEL_PME(ir->coulombtype) || ir->coulombtype == CoulombInteractionType::Ewald)
+                                    ? 3
+                                    : 2,
                             av);
                 }
                 break;
@@ -3141,7 +3143,7 @@ void dd_partition_system(FILE*                     fplog,
         /* With the group scheme the sorting array is part of the DD state,
          * but it just got out of sync, so mark as invalid by emptying it.
          */
-        if (ir->cutoff_scheme == ecutsGROUP)
+        if (ir->cutoff_scheme == CutoffScheme::Group)
         {
             comm->sort->sorted.clear();
         }
index 81e6bb4709ca51ff9429dc04085691d276032e90..7b155afde00f20d1a4e0a8e0877f42c6e8ac28e3 100644 (file)
@@ -192,7 +192,7 @@ real do_ewald(const t_inputrec& ir,
         snew(et->tab_qxyz, natoms);
     }
 
-    bFreeEnergy = (ir.efep != efepNO);
+    bFreeEnergy = (ir.efep != FreeEnergyPerturbationType::No);
 
     clear_mat(lrvir);
 
index b75afe50beb28abfb0104e8f0bfbdd7d6f18fbd3..a746ae8bc865e7dd2f27dc0f0e47302a667f528c 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.
@@ -119,7 +119,7 @@ void ewald_LRcorrection(const int         numAtomsLocal,
     real boxVolume = scaledBox[XX][XX] * scaledBox[YY][YY] * scaledBox[ZZ][ZZ];
     switch (ir.ewald_geometry)
     {
-        case eewg3D:
+        case EwaldGeometry::ThreeD:
             if (ir.epsilon_surface != 0)
             {
                 dipole_coeff = 2 * M_PI * ONE_4PI_EPS0
@@ -131,7 +131,7 @@ void ewald_LRcorrection(const int         numAtomsLocal,
                 }
             }
             break;
-        case eewg3DC:
+        case EwaldGeometry::ThreeDC:
             dipole_coeff = 2 * M_PI * one_4pi_eps / boxVolume;
             dipcorrA[ZZ] = 2 * dipole_coeff * mutot[0][ZZ];
             dipcorrB[ZZ] = 2 * dipole_coeff * mutot[1][ZZ];
@@ -195,11 +195,11 @@ void ewald_LRcorrection(const int         numAtomsLocal,
              */
             if (dipole_coeff != 0)
             {
-                if (ir.ewald_geometry == eewg3D)
+                if (ir.ewald_geometry == EwaldGeometry::ThreeD)
                 {
                     Vdipole[q] = dipole_coeff * iprod(mutot[q], mutot[q]);
                 }
-                else if (ir.ewald_geometry == eewg3DC)
+                else if (ir.ewald_geometry == EwaldGeometry::ThreeDC)
                 {
                     Vdipole[q] = dipole_coeff * mutot[q][ZZ] * mutot[q][ZZ];
 
@@ -244,7 +244,7 @@ void ewald_LRcorrection(const int         numAtomsLocal,
         fprintf(debug, "Electrostatic Long Range correction: Vexcl=%g\n", Vexcl_q);
         if (MASTER(cr) && thread == 0)
         {
-            if (ir.epsilon_surface > 0 || ir.ewald_geometry == eewg3DC)
+            if (ir.epsilon_surface > 0 || ir.ewald_geometry == EwaldGeometry::ThreeDC)
             {
                 fprintf(debug,
                         "Total dipole correction: Vdipole=%g\n",
index 4fb2b447dc0f75cd8911c120bf9b9013d9ef7e22..95cc44791ef1e5816f58d642e675998da26e0321 100644 (file)
@@ -710,15 +710,15 @@ gmx_pme_t* gmx_pme_init(const t_commrec*     cr,
      * not calculating free-energy for Coulomb and/or LJ while gmx_pme_init()
      * configures with free-energy, but that has never been tested.
      */
-    pme->doCoulomb     = EEL_PME(ir->coulombtype);
-    pme->doLJ          = EVDW_PME(ir->vdwtype);
-    pme->bFEP_q        = ((ir->efep != efepNO) && bFreeEnergy_q);
-    pme->bFEP_lj       = ((ir->efep != efepNO) && bFreeEnergy_lj);
-    pme->bFEP          = (pme->bFEP_q || pme->bFEP_lj);
-    pme->nkx           = ir->nkx;
-    pme->nky           = ir->nky;
-    pme->nkz           = ir->nkz;
-    pme->bP3M          = (ir->coulombtype == eelP3M_AD || getenv("GMX_PME_P3M") != nullptr);
+    pme->doCoulomb = EEL_PME(ir->coulombtype);
+    pme->doLJ      = EVDW_PME(ir->vdwtype);
+    pme->bFEP_q    = ((ir->efep != FreeEnergyPerturbationType::No) && bFreeEnergy_q);
+    pme->bFEP_lj   = ((ir->efep != FreeEnergyPerturbationType::No) && bFreeEnergy_lj);
+    pme->bFEP      = (pme->bFEP_q || pme->bFEP_lj);
+    pme->nkx       = ir->nkx;
+    pme->nky       = ir->nky;
+    pme->nkz       = ir->nkz;
+    pme->bP3M = (ir->coulombtype == CoulombInteractionType::P3mAD || getenv("GMX_PME_P3M") != nullptr);
     pme->pme_order     = ir->pme_order;
     pme->ewaldcoeff_q  = ewaldcoeff_q;
     pme->ewaldcoeff_lj = ewaldcoeff_lj;
@@ -849,7 +849,7 @@ gmx_pme_t* gmx_pme_init(const t_commrec*     cr,
      */
     if (pme->doLJ)
     {
-        pme->ngrids = ((ir->ljpme_combination_rule == eljpmeLB) ? DO_Q_AND_LJ_LB : DO_Q_AND_LJ);
+        pme->ngrids = ((ir->ljpme_combination_rule == LongRangeVdW::LB) ? DO_Q_AND_LJ_LB : DO_Q_AND_LJ);
     }
     else
     {
@@ -863,7 +863,7 @@ gmx_pme_t* gmx_pme_init(const t_commrec*     cr,
     {
         if ((i < DO_Q && pme->doCoulomb && (i == 0 || bFreeEnergy_q))
             || (i >= DO_Q && pme->doLJ
-                && (i == 2 || bFreeEnergy_lj || ir->ljpme_combination_rule == eljpmeLB)))
+                && (i == 2 || bFreeEnergy_lj || ir->ljpme_combination_rule == LongRangeVdW::LB)))
         {
             pmegrids_init(&pme->pmegrid[i],
                           pme->pmegrid_nx,
@@ -1155,7 +1155,7 @@ int gmx_pme_do(struct gmx_pme_t*              pme,
      */
 
     /* If we are doing LJ-PME with LB, we only do Q here */
-    max_grid_index = (pme->ljpme_combination_rule == eljpmeLB) ? DO_Q : DO_Q_AND_LJ;
+    max_grid_index = (pme->ljpme_combination_rule == LongRangeVdW::LB) ? DO_Q : DO_Q_AND_LJ;
 
     for (grid_index = 0; grid_index < max_grid_index; ++grid_index)
     {
@@ -1387,7 +1387,7 @@ int gmx_pme_do(struct gmx_pme_t*              pme,
     /* For Lorentz-Berthelot combination rules in LJ-PME, we need to calculate
      * seven terms. */
 
-    if (pme->doLJ && pme->ljpme_combination_rule == eljpmeLB)
+    if (pme->doLJ && pme->ljpme_combination_rule == LongRangeVdW::LB)
     {
         /* Loop over A- and B-state if we are doing FEP */
         for (fep_state = 0; fep_state < fep_states_lj; ++fep_state)
@@ -1619,7 +1619,7 @@ int gmx_pme_do(struct gmx_pme_t*              pme,
                 bFirst = FALSE;
             } /* for (grid_index = 8; grid_index >= 2; --grid_index) */
         }     /* for (fep_state = 0; fep_state < fep_states_lj; ++fep_state) */
-    }         /* if (pme->doLJ && pme->ljpme_combination_rule == eljpmeLB) */
+    }         /* if (pme->doLJ && pme->ljpme_combination_rule == LongRangeVdW::LB) */
 
     if (stepWork.computeForces && pme->nnodes > 1)
     {
index b90170a045f3b722fa112191e94dac7be1602667..e0c32e207d1b46edcf1365c6750581f980c013d3 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.
@@ -317,7 +317,7 @@ static void pme_gpu_reduce_outputs(const bool            computeEnergyAndVirial,
         GMX_ASSERT(enerd, "Invalid energy output manager");
         forceWithVirial->addVirialContribution(output.coulombVirial_);
         enerd->term[F_COUL_RECIP] += output.coulombEnergy_;
-        enerd->dvdl_lin[efptCOUL] += output.coulombDvdl_;
+        enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Coul] += output.coulombDvdl_;
     }
     if (output.haveForceOutput_)
     {
index a4af8154de90709f18f06827d9135ec8c5eb1495..c97f9e2948460c11c51c1ac2d70349ffa53112a1 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.
@@ -76,6 +76,7 @@ struct t_inputrec;
 struct PmeGpu;
 
 enum class PmeRunMode;
+enum class LongRangeVdW : int;
 
 //@{
 //! Grid indices for A state for charge and Lennard-Jones C6
@@ -357,7 +358,7 @@ struct gmx_pme_t
     class EwaldBoxZScaler* boxScaler; /**< The scaling data Ewald uses with walls (set at pme_init constant for the entire run) */
 
 
-    int ljpme_combination_rule; /* Type of combination rule in LJ-PME */
+    LongRangeVdW ljpme_combination_rule; /* Type of combination rule in LJ-PME */
 
     int ngrids; /* number of grids we maintain for pmegrid, (c)fftgrid and pfft_setups*/
 
index 027895d348ae6ee82d9aba2f0c087cbf2c9f798b..16ffbdb14bde0483dec0b82a3fc84436cfe5ac7e 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 2012,2013,2014,2015,2016 by the GROMACS development team.
- * 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.
@@ -184,7 +184,7 @@ struct pme_load_balancing_t
     int                      start;    /**< start of setup index range to consider in stage>0 */
     int                      end;      /**< end   of setup index range to consider in stage>0 */
     int                      elimited; /**< was the balancing limited, uses enum above */
-    int                      cutoff_scheme; /**< Verlet or group cut-offs */
+    CutoffScheme             cutoff_scheme; /**< Verlet or group cut-offs */
 
     int stage; /**< the current stage */
 
@@ -406,7 +406,7 @@ static gmx_bool pme_loadbal_increase_cutoff(pme_load_balancing_t* pme_lb, int pm
         set.rcut_coulomb = pme_lb->rcut_coulomb_start;
     }
 
-    if (pme_lb->cutoff_scheme == ecutsVERLET)
+    if (pme_lb->cutoff_scheme == CutoffScheme::Verlet)
     {
         /* Never decrease the Coulomb and VdW list buffers */
         set.rlistOuter = std::max(set.rcut_coulomb + pme_lb->rbufOuter_coulomb,
@@ -831,7 +831,7 @@ static void pme_load_balance(pme_load_balancing_t*          pme_lb,
     nbv->changePairlistRadii(set->rlistOuter, set->rlistInner);
     ic->ewaldcoeff_q = set->ewaldcoeff_q;
     /* TODO: centralize the code that sets the potentials shifts */
-    if (ic->coulomb_modifier == eintmodPOTSHIFT)
+    if (ic->coulomb_modifier == InteractionModifiers::PotShift)
     {
         GMX_RELEASE_ASSERT(ic->rcoulomb != 0, "Cutoff radius cannot be zero");
         ic->sh_ewald = std::erfc(ic->ewaldcoeff_q * ic->rcoulomb) / ic->rcoulomb;
@@ -841,7 +841,7 @@ static void pme_load_balance(pme_load_balancing_t*          pme_lb,
         /* We have PME for both Coulomb and VdW, set rvdw equal to rcoulomb */
         ic->rvdw          = set->rcut_coulomb;
         ic->ewaldcoeff_lj = set->ewaldcoeff_lj;
-        if (ic->vdw_modifier == eintmodPOTSHIFT)
+        if (ic->vdw_modifier == InteractionModifiers::PotShift)
         {
             real crc2;
 
@@ -1075,7 +1075,7 @@ void pme_loadbal_do(pme_load_balancing_t*          pme_lb,
         /* Update deprecated rlist in forcerec to stay in sync with fr->nbv */
         fr->rlist = fr->nbv->pairlistOuterRadius();
 
-        if (ir.eDispCorr != edispcNO)
+        if (ir.eDispCorr != DispersionCorrectionType::No)
         {
             fr->dispersionCorrection->setParameters(*fr->ic);
         }
index aaf475f3c5f02f7be54aa754091431303add2932..7c38a52c91599c1e60d7fc7899e476fa7296b248 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.
@@ -101,8 +101,9 @@ public:
         inputRec.nkx         = gridSize[XX];
         inputRec.nky         = gridSize[YY];
         inputRec.nkz         = gridSize[ZZ];
-        inputRec.coulombtype = (moduliType == ModuliType::P3M) ? eelP3M_AD : eelPME;
-        inputRec.pme_order   = pmeOrder;
+        inputRec.coulombtype = (moduliType == ModuliType::P3M) ? CoulombInteractionType::P3mAD
+                                                               : CoulombInteractionType::Pme;
+        inputRec.pme_order = pmeOrder;
 
         /* PME initialization call which checks the inputs and computes the B-spline moduli according to the grid sizes. */
         PmeSafePointer pme = pmeInitEmpty(&inputRec);
index dde08758eea1ca1e8144c42273b3d5b3362bb7de..160b319fdb09b87a95dd5436b82d8ee637276471 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.
@@ -276,7 +276,7 @@ public:
         inputRec.nky         = gridSize[YY];
         inputRec.nkz         = gridSize[ZZ];
         inputRec.pme_order   = pmeOrder;
-        inputRec.coulombtype = eelPME;
+        inputRec.coulombtype = CoulombInteractionType::Pme;
         inputRec.epsilon_r   = 1.0;
 
         TestReferenceData refData;
index f32517da5da4e56e46c0d97672f3ef53997f4720..57ed877302062762c7db49e7f14c98917db21b59 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.
@@ -98,13 +98,13 @@ public:
         inputRec.nky         = gridSize[YY];
         inputRec.nkz         = gridSize[ZZ];
         inputRec.pme_order   = 4;
-        inputRec.coulombtype = eelPME;
+        inputRec.coulombtype = CoulombInteractionType::Pme;
         inputRec.epsilon_r   = epsilon_r;
         switch (method)
         {
             case PmeSolveAlgorithm::Coulomb: break;
 
-            case PmeSolveAlgorithm::LennardJones: inputRec.vdwtype = evdwPME; break;
+            case PmeSolveAlgorithm::LennardJones: inputRec.vdwtype = VanDerWaalsType::Pme; break;
 
             default: GMX_THROW(InternalError("Unknown PME solver"));
         }
index 032188c2479a2098b5507435d735b62957e708c3..10a2840ee2f643e40a958e04f2b0043a3870390d 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.
@@ -106,7 +106,7 @@ public:
         inputRec.nky         = gridSize[YY];
         inputRec.nkz         = gridSize[ZZ];
         inputRec.pme_order   = pmeOrder;
-        inputRec.coulombtype = eelPME;
+        inputRec.coulombtype = CoulombInteractionType::Pme;
         inputRec.epsilon_r   = 1.0;
 
         const std::map<PmeSplineAndSpreadOptions, std::string> optionsToTest = {
index 89a2d8da3b0b404e5ad9272180808895f377e015..bb08642efb755317ed9e754ebeefdd12d6d5d9ab 100644 (file)
@@ -1152,7 +1152,14 @@ static void do_cpt_header(XDR* xd, gmx_bool bRead, FILE* list, CheckpointHeaderC
     {
         contents->nlambda = 0;
     }
-    do_cpt_int_err(xd, "integrator", &contents->eIntegrator, list);
+    {
+        int integrator = static_cast<int>(contents->eIntegrator);
+        do_cpt_int_err(xd, "integrator", &integrator, list);
+        if (bRead)
+        {
+            contents->eIntegrator = static_cast<IntegrationAlgorithm>(integrator);
+        }
+    }
     if (contents->file_version >= 3)
     {
         do_cpt_int_err(xd, "simulation part #", &contents->simulation_part, list);
@@ -1211,11 +1218,16 @@ static void do_cpt_header(XDR* xd, gmx_bool bRead, FILE* list, CheckpointHeaderC
 
     if (contents->file_version >= 16)
     {
-        do_cpt_int_err(xd, "swap", &contents->eSwapCoords, list);
+        int swapState = static_cast<int>(contents->eSwapCoords);
+        do_cpt_int_err(xd, "swap", &swapState, list);
+        if (bRead)
+        {
+            contents->eSwapCoords = static_cast<SwapType>(swapState);
+        }
     }
     else
     {
-        contents->eSwapCoords = eswapNO;
+        contents->eSwapCoords = SwapType::No;
     }
 
     if (contents->file_version >= 17)
@@ -1290,7 +1302,9 @@ static int do_cpt_state(XDR* xd, int fflags, t_state* state, FILE* list)
                             part,
                             i,
                             sflags,
-                            gmx::arrayRefFromArray<real>(state->lambda.data(), state->lambda.size()),
+                            gmx::arrayRefFromArray<real>(
+                                    state->lambda.data(),
+                                    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real>::size()),
                             list);
                     break;
                 case estFEPSTATE:
@@ -1428,11 +1442,11 @@ static int do_cpt_ekinstate(XDR* xd, int fflags, ekinstate_t* ekins, FILE* list)
 }
 
 
-static int do_cpt_swapstate(XDR* xd, gmx_bool bRead, int eSwapCoords, swaphistory_t* swapstate, FILE* list)
+static int do_cpt_swapstate(XDR* xd, gmx_bool bRead, SwapType eSwapCoords, swaphistory_t* swapstate, FILE* list)
 {
     int swap_cpt_version = 2;
 
-    if (eSwapCoords == eswapNO)
+    if (eSwapCoords == SwapType::No)
     {
         return 0;
     }
@@ -2245,7 +2259,7 @@ static int do_cpt_files(XDR* xd, gmx_bool bRead, std::vector<gmx_file_position_t
 void write_checkpoint_data(t_fileio*                         fp,
                            CheckpointHeaderContents          headerContents,
                            gmx_bool                          bExpanded,
-                           int                               elamstats,
+                           LambdaWeightCalculation           elamstats,
                            t_state*                          state,
                            ObservablesHistory*               observablesHistory,
                            const gmx::MdModulesNotifier&     mdModulesNotifier,
@@ -2302,8 +2316,8 @@ void write_checkpoint_data(t_fileio*                         fp,
         {
             headerContents.flags_dfh |= ((1 << edfhWLDELTA) | (1 << edfhWLHISTO));
         }
-        if ((elamstats == elamstatsMINVAR) || (elamstats == elamstatsBARKER)
-            || (elamstats == elamstatsMETROPOLIS))
+        if ((elamstats == LambdaWeightCalculation::Minvar) || (elamstats == LambdaWeightCalculation::Barker)
+            || (elamstats == LambdaWeightCalculation::Metropolis))
         {
             headerContents.flags_dfh |= ((1 << edfhACCUMP) | (1 << edfhACCUMM) | (1 << edfhACCUMP2)
                                          | (1 << edfhACCUMM2) | (1 << edfhSUMMINVAR) | (1 << edfhSUMVAR));
@@ -2520,7 +2534,7 @@ static void read_checkpoint(const char*                    fn,
                             t_fileio*                      logfio,
                             const t_commrec*               cr,
                             const ivec                     dd_nc,
-                            int                            eIntegrator,
+                            IntegrationAlgorithm           eIntegrator,
                             int*                           init_fep_state,
                             CheckpointHeaderContents*      headerContents,
                             t_state*                       state,
@@ -2721,7 +2735,7 @@ static void read_checkpoint(const char*                    fn,
         cp_error();
     }
 
-    if (headerContents->eSwapCoords != eswapNO && observablesHistory->swapHistory == nullptr)
+    if (headerContents->eSwapCoords != SwapType::No && observablesHistory->swapHistory == nullptr)
     {
         observablesHistory->swapHistory = std::make_unique<swaphistory_t>(swaphistory_t{});
     }
@@ -2949,7 +2963,7 @@ void read_checkpoint_trxframe(t_fileio* fp, t_trxframe* fr)
     fr->bTime     = TRUE;
     fr->time      = headerContents.t;
     fr->bLambda   = TRUE;
-    fr->lambda    = state.lambda[efptFEP];
+    fr->lambda    = state.lambda[FreeEnergyPerturbationCouplingType::Fep];
     fr->fep_state = state.fep_state;
     fr->bAtoms    = FALSE;
     fr->bX        = ((state.flags & (1 << estX)) != 0);
index c3dbc3c1077ee06c3eb055250e74c70823d6e0b3..49cc0fe77bd37e3c04f58b6fa4180ef17a295e3c 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.
@@ -57,6 +57,9 @@ struct t_fileio;
 struct t_inputrec;
 class t_state;
 struct t_trxframe;
+enum class IntegrationAlgorithm : int;
+enum class SwapType : int;
+enum class LambdaWeightCalculation : int;
 
 namespace gmx
 {
@@ -199,7 +202,7 @@ struct CheckpointHeaderContents
     //! Time string.
     char ftime[CPTSTRLEN];
     //! Which integrator is in use.
-    int eIntegrator;
+    IntegrationAlgorithm eIntegrator;
     //! Which part of the simulation this is.
     int simulation_part;
     //! Which step the checkpoint is at.
@@ -237,7 +240,7 @@ struct CheckpointHeaderContents
     //! Essential dynamics states.
     int nED;
     //! Enum for coordinate swapping.
-    int eSwapCoords;
+    SwapType eSwapCoords;
     //! Whether the checkpoint was written by modular simulator.
     bool isModularSimulatorCheckpoint = false;
 };
@@ -246,7 +249,7 @@ struct CheckpointHeaderContents
 void write_checkpoint_data(t_fileio*                         fp,
                            CheckpointHeaderContents          headerContents,
                            gmx_bool                          bExpanded,
-                           int                               elamstats,
+                           LambdaWeightCalculation           elamstats,
                            t_state*                          state,
                            ObservablesHistory*               observablesHistory,
                            const gmx::MdModulesNotifier&     notifier,
index bf47bcd36a8b6d5433339e98e68dccf5bac40279..d9d30ba8b394ac2bcb011f7ed9a4a01b22a6c631 100644 (file)
@@ -48,6 +48,7 @@
 #include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/binaryinformation.h"
 #include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/keyvaluetreebuilder.h"
index 5c2e8e5f176d2c3aa4ea72a8a7b4442fa56be5c3..9330e99eb848860f7711140b0862637c82a68a85 100644 (file)
 #include <utility>
 #include <vector>
 
+#include "gromacs/fileio/warninp.h"
 #include "gromacs/utility/basedefinitions.h"
-
-struct warninp;
-typedef warninp* warninp_t;
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/enumerationhelpers.h"
+#include "gromacs/utility/stringutil.h"
 
 namespace gmx
 {
@@ -166,6 +167,7 @@ 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.
+ * Defined here so we don't need to instantiate the templates in the source file.
  *
  * \tparam EnumType  The type of enum to be returned
  * \param[in]  inp   The input file vector
@@ -174,7 +176,52 @@ int get_einp(std::vector<t_inpfile>* inp, const char* name);
  * \return  Enum value corresponding to read input
  */
 template<typename EnumType>
-EnumType getEnum(std::vector<t_inpfile>* inp, const char* name, warninp* wi);
+EnumType getEnum(std::vector<t_inpfile>* inp, const char* name, warninp* wi)
+{
+    // If there's no valid option, we'll use the EnumType::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 return EnumType::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;
+}
+
 
 //! Replace for macro CCTYPE, prints comment string after newline
 void printStringNewline(std::vector<t_inpfile>* inp, const char* line);
index b963ed295b94668e9bd3027595a9f51cddc27b67..b99e3bcf6e8ec014475e0f9d2ff53d3685f3a26f 100644 (file)
@@ -291,16 +291,16 @@ static void do_pull_group(gmx::ISerializer* serializer, t_pull_group* pgrp)
 static void do_pull_coord(gmx::ISerializer* serializer,
                           t_pull_coord*     pcrd,
                           int               file_version,
-                          int               ePullOld,
-                          int               eGeomOld,
+                          PullingAlgorithm  ePullOld,
+                          PullGroupGeometry eGeomOld,
                           ivec              dimOld)
 {
     if (file_version >= tpxv_PullCoordNGroup)
     {
-        serializer->doInt(&pcrd->eType);
+        serializer->doEnumAsInt(&pcrd->eType);
         if (file_version >= tpxv_PullExternalPotential)
         {
-            if (pcrd->eType == epullEXTERNAL)
+            if (pcrd->eType == PullingAlgorithm::External)
             {
                 std::string buf;
                 if (serializer->reading())
@@ -330,7 +330,7 @@ static void do_pull_coord(gmx::ISerializer* serializer,
          * changing the tpx version. This requires checks when printing the
          * geometry string and a check and fatal_error in init_pull.
          */
-        serializer->doInt(&pcrd->eGeom);
+        serializer->doEnumAsInt(&pcrd->eGeom);
         serializer->doInt(&pcrd->ngroup);
         if (pcrd->ngroup <= c_pullCoordNgroupMax)
         {
@@ -359,9 +359,9 @@ static void do_pull_coord(gmx::ISerializer* serializer,
         serializer->doInt(&pcrd->group[1]);
         if (file_version >= tpxv_PullCoordTypeGeom)
         {
-            pcrd->ngroup = (pcrd->eGeom == epullgDIRRELATIVE ? 4 : 2);
-            serializer->doInt(&pcrd->eType);
-            serializer->doInt(&pcrd->eGeom);
+            pcrd->ngroup = (pcrd->eGeom == PullGroupGeometry::DirectionRelative ? 4 : 2);
+            serializer->doEnumAsInt(&pcrd->eType);
+            serializer->doEnumAsInt(&pcrd->eGeom);
             if (pcrd->ngroup == 4)
             {
                 serializer->doInt(&pcrd->group[2]);
@@ -404,17 +404,14 @@ static void do_expandedvals(gmx::ISerializer* serializer, t_expanded* expand, t_
     {
         if (n_lambda > 0)
         {
-            if (serializer->reading())
-            {
-                snew(expand->init_lambda_weights, n_lambda);
-            }
-            serializer->doRealArray(expand->init_lambda_weights, n_lambda);
+            expand->init_lambda_weights.resize(n_lambda);
+            serializer->doRealArray(expand->init_lambda_weights.data(), n_lambda);
             serializer->doBool(&expand->bInit_weights);
         }
 
         serializer->doInt(&expand->nstexpanded);
-        serializer->doInt(&expand->elmcmove);
-        serializer->doInt(&expand->elamstats);
+        serializer->doEnumAsInt(&expand->elmcmove);
+        serializer->doEnumAsInt(&expand->elamstats);
         serializer->doInt(&expand->lmc_repeats);
         serializer->doInt(&expand->gibbsdeltalam);
         serializer->doInt(&expand->lmc_forced_nstart);
@@ -428,7 +425,7 @@ static void do_expandedvals(gmx::ISerializer* serializer, t_expanded* expand, t_
         serializer->doReal(&expand->wl_ratio);
         serializer->doReal(&expand->init_wl_delta);
         serializer->doBool(&expand->bWLoneovert);
-        serializer->doInt(&expand->elmceq);
+        serializer->doEnumAsInt(&expand->elmceq);
         serializer->doInt(&expand->equil_steps);
         serializer->doInt(&expand->equil_samples);
         serializer->doInt(&expand->equil_n_at_lam);
@@ -441,7 +438,7 @@ static void do_simtempvals(gmx::ISerializer* serializer, t_simtemp* simtemp, int
 {
     if (file_version >= 79)
     {
-        serializer->doInt(&simtemp->eSimTempScale);
+        serializer->doEnumAsInt(&simtemp->eSimTempScale);
         serializer->doReal(&simtemp->simtemp_high);
         serializer->doReal(&simtemp->simtemp_low);
         if (n_lambda > 0)
@@ -468,7 +465,6 @@ static void do_imd(gmx::ISerializer* serializer, t_IMD* imd)
 static void do_fepvals(gmx::ISerializer* serializer, t_lambda* fepvals, int file_version)
 {
     /* i is defined in the ndo_double macro; use g to iterate. */
-    int  g;
     real rdum;
 
     /* free energy values */
@@ -494,24 +490,19 @@ static void do_fepvals(gmx::ISerializer* serializer, t_lambda* fepvals, int file
     if (file_version >= 79)
     {
         serializer->doInt(&fepvals->n_lambda);
-        if (serializer->reading())
-        {
-            snew(fepvals->all_lambda, efptNR);
-        }
-        for (g = 0; g < efptNR; g++)
+        for (auto g : keysOf(fepvals->all_lambda))
         {
             if (fepvals->n_lambda > 0)
             {
-                if (serializer->reading())
-                {
-                    snew(fepvals->all_lambda[g], fepvals->n_lambda);
-                }
-                serializer->doDoubleArray(fepvals->all_lambda[g], fepvals->n_lambda);
-                serializer->doBoolArray(fepvals->separate_dvdl, efptNR);
+                fepvals->all_lambda[g].resize(fepvals->n_lambda);
+                serializer->doDoubleArray(fepvals->all_lambda[g].data(), fepvals->n_lambda);
+                serializer->doBoolArray(
+                        fepvals->separate_dvdl.begin(),
+                        gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real>::size());
             }
             else if (fepvals->init_lambda >= 0)
             {
-                fepvals->separate_dvdl[efptFEP] = TRUE;
+                fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Fep] = TRUE;
             }
         }
     }
@@ -520,36 +511,33 @@ static void do_fepvals(gmx::ISerializer* serializer, t_lambda* fepvals, int file
         serializer->doInt(&fepvals->n_lambda);
         if (serializer->reading())
         {
-            int g;
-
-            snew(fepvals->all_lambda, efptNR);
             /* still allocate the all_lambda array's contents. */
-            for (g = 0; g < efptNR; g++)
+            for (auto g : keysOf(fepvals->all_lambda))
             {
                 if (fepvals->n_lambda > 0)
                 {
-                    snew(fepvals->all_lambda[g], fepvals->n_lambda);
+                    fepvals->all_lambda[g].resize(fepvals->n_lambda);
                 }
             }
         }
-        serializer->doDoubleArray(fepvals->all_lambda[efptFEP], fepvals->n_lambda);
+        serializer->doDoubleArray(fepvals->all_lambda[FreeEnergyPerturbationCouplingType::Fep].data(),
+                                  fepvals->n_lambda);
         if (fepvals->init_lambda >= 0)
         {
-            int g, h;
-
-            fepvals->separate_dvdl[efptFEP] = TRUE;
+            fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Fep] = TRUE;
 
             if (serializer->reading())
             {
                 /* copy the contents of the efptFEP lambda component to all
                    the other components */
-                for (g = 0; g < efptNR; g++)
+                for (auto g : keysOf(fepvals->all_lambda))
                 {
-                    for (h = 0; h < fepvals->n_lambda; h++)
+                    for (int h = 0; h < fepvals->n_lambda; h++)
                     {
-                        if (g != efptFEP)
+                        if (g != FreeEnergyPerturbationCouplingType::Fep)
                         {
-                            fepvals->all_lambda[g][h] = fepvals->all_lambda[efptFEP][h];
+                            fepvals->all_lambda[g][h] =
+                                    fepvals->all_lambda[FreeEnergyPerturbationCouplingType::Fep][h];
                         }
                     }
                 }
@@ -558,11 +546,10 @@ static void do_fepvals(gmx::ISerializer* serializer, t_lambda* fepvals, int file
     }
     else
     {
-        fepvals->n_lambda   = 0;
-        fepvals->all_lambda = nullptr;
+        fepvals->n_lambda = 0;
         if (fepvals->init_lambda >= 0)
         {
-            fepvals->separate_dvdl[efptFEP] = TRUE;
+            fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Fep] = TRUE;
         }
     }
     serializer->doReal(&fepvals->sc_alpha);
@@ -610,13 +597,13 @@ static void do_fepvals(gmx::ISerializer* serializer, t_lambda* fepvals, int file
 
     if (file_version >= 73)
     {
-        serializer->doInt(&fepvals->separate_dhdl_file);
-        serializer->doInt(&fepvals->dhdl_derivatives);
+        serializer->doEnumAsInt(&fepvals->separate_dhdl_file);
+        serializer->doEnumAsInt(&fepvals->dhdl_derivatives);
     }
     else
     {
-        fepvals->separate_dhdl_file = esepdhdlfileYES;
-        fepvals->dhdl_derivatives   = edhdlderivativesYES;
+        fepvals->separate_dhdl_file = SeparateDhdlFile::Yes;
+        fepvals->dhdl_derivatives   = DhDlDerivativeCalculation::Yes;
     }
     if (file_version >= 71)
     {
@@ -630,11 +617,11 @@ static void do_fepvals(gmx::ISerializer* serializer, t_lambda* fepvals, int file
     }
     if (file_version >= 79)
     {
-        serializer->doInt(&fepvals->edHdLPrintEnergy);
+        serializer->doEnumAsInt(&fepvals->edHdLPrintEnergy);
     }
     else
     {
-        fepvals->edHdLPrintEnergy = edHdLPrintEnergyNO;
+        fepvals->edHdLPrintEnergy = FreeEnergyPrintEnergy::No;
     }
 
     /* handle lambda_neighbors */
@@ -674,7 +661,17 @@ static void do_awhBias(gmx::ISerializer* serializer, gmx::AwhBiasParams* awhBias
     serializer->doDouble(&awhBiasParams->targetBetaScaling);
     serializer->doDouble(&awhBiasParams->targetCutoff);
     serializer->doInt(&awhBiasParams->eGrowth);
-    serializer->doInt(&awhBiasParams->bUserData);
+    if (serializer->reading())
+    {
+        int temp = 0;
+        serializer->doInt(&temp);
+        awhBiasParams->bUserData = static_cast<bool>(temp);
+    }
+    else
+    {
+        int temp = static_cast<int>(awhBiasParams->bUserData);
+        serializer->doInt(&temp);
+    }
     serializer->doDouble(&awhBiasParams->errorInitial);
     serializer->doInt(&awhBiasParams->ndim);
     serializer->doInt(&awhBiasParams->shareGroup);
@@ -725,11 +722,11 @@ static void do_awh(gmx::ISerializer* serializer, gmx::AwhParams* awhParams, int
     }
 }
 
-static void do_pull(gmx::ISerializer* serializer, pull_params_t* pull, int file_version, int ePullOld)
+static void do_pull(gmx::ISerializer* serializer, pull_params_t* pull, int file_version, PullingAlgorithm ePullOld)
 {
-    int  eGeomOld = -1;
-    ivec dimOld;
-    int  g;
+    PullGroupGeometry eGeomOld = PullGroupGeometry::Count;
+    ivec              dimOld;
+    int               g;
 
     if (file_version >= 95)
     {
@@ -744,7 +741,7 @@ static void do_pull(gmx::ISerializer* serializer, pull_params_t* pull, int file_
     {
         real dum;
 
-        serializer->doInt(&eGeomOld);
+        serializer->doEnumAsInt(&eGeomOld);
         serializer->doIvec(&dimOld);
         /* The inner cylinder radius, now removed */
         serializer->doReal(&dum);
@@ -788,13 +785,25 @@ static void do_pull(gmx::ISerializer* serializer, pull_params_t* pull, int file_
     if (file_version < 95)
     {
         /* epullgPOS for position pulling, before epullgDIRPBC was removed */
-        if (eGeomOld == epullgDIRPBC)
+        if (eGeomOld == PullGroupGeometry::DirectionPBC)
         {
             gmx_fatal(FARGS, "pull-geometry=position is no longer supported");
         }
-        if (eGeomOld > epullgDIRPBC)
+        if (eGeomOld > PullGroupGeometry::DirectionPBC)
         {
-            eGeomOld -= 1;
+            switch (eGeomOld)
+            {
+                case (PullGroupGeometry::DirectionRelative):
+                    eGeomOld = PullGroupGeometry::DirectionPBC;
+                    break;
+                case (PullGroupGeometry::Angle):
+                    eGeomOld = PullGroupGeometry::DirectionRelative;
+                    break;
+                case (PullGroupGeometry::Dihedral): eGeomOld = PullGroupGeometry::Angle; break;
+                case (PullGroupGeometry::AngleAxis): eGeomOld = PullGroupGeometry::Dihedral; break;
+                case (PullGroupGeometry::Count): eGeomOld = PullGroupGeometry::AngleAxis; break;
+                default: GMX_RELEASE_ASSERT(false, "Unhandled old pull type");
+            }
         }
 
         for (g = 0; g < pull->ngroup; g++)
@@ -837,8 +846,18 @@ static void do_pull(gmx::ISerializer* serializer, pull_params_t* pull, int file_
 
 static void do_rotgrp(gmx::ISerializer* serializer, t_rotgrp* rotg)
 {
-    serializer->doInt(&rotg->eType);
-    serializer->doInt(&rotg->bMassW);
+    serializer->doEnumAsInt(&rotg->eType);
+    if (serializer->reading())
+    {
+        int temp = 0;
+        serializer->doInt(&temp);
+        rotg->bMassW = static_cast<bool>(temp);
+    }
+    else
+    {
+        int temp = static_cast<int>(rotg->bMassW);
+        serializer->doInt(&temp);
+    }
     serializer->doInt(&rotg->nat);
     if (serializer->reading())
     {
@@ -857,7 +876,7 @@ static void do_rotgrp(gmx::ISerializer* serializer, t_rotgrp* rotg)
     serializer->doReal(&rotg->slab_dist);
     serializer->doReal(&rotg->min_gaussian);
     serializer->doReal(&rotg->eps);
-    serializer->doInt(&rotg->eFittype);
+    serializer->doEnumAsInt(&rotg->eFittype);
     serializer->doInt(&rotg->PotAngle_nstep);
     serializer->doReal(&rotg->PotAngle_step);
 }
@@ -959,17 +978,18 @@ static void do_swapcoords_tpx(gmx::ISerializer* serializer, t_swapcoords* swap,
         swap->ngrp = 5;
         snew(swap->grp, swap->ngrp);
 
-        swap->grp[eGrpSplit0].molname  = gmx_strdup("split0");  // group 0: split0
-        swap->grp[eGrpSplit1].molname  = gmx_strdup("split1");  // group 1: split1
-        swap->grp[eGrpSolvent].molname = gmx_strdup("solvent"); // group 2: solvent
-        swap->grp[3].molname           = gmx_strdup("anions");  // group 3: anions
-        swap->grp[4].molname           = gmx_strdup("cations"); // group 4: cations
+        swap->grp[static_cast<int>(SwapGroupSplittingType::Split0)].molname = gmx_strdup("split0"); // group 0: split0
+        swap->grp[static_cast<int>(SwapGroupSplittingType::Split1)].molname = gmx_strdup("split1"); // group 1: split1
+        swap->grp[static_cast<int>(SwapGroupSplittingType::Solvent)].molname =
+                gmx_strdup("solvent");                // group 2: solvent
+        swap->grp[3].molname = gmx_strdup("anions");  // group 3: anions
+        swap->grp[4].molname = gmx_strdup("cations"); // group 4: cations
 
         serializer->doInt(&swap->grp[3].nat);
-        serializer->doInt(&swap->grp[eGrpSolvent].nat);
-        serializer->doInt(&swap->grp[eGrpSplit0].nat);
+        serializer->doInt(&swap->grp[static_cast<int>(SwapGroupSplittingType::Solvent)].nat);
+        serializer->doInt(&swap->grp[static_cast<int>(SwapGroupSplittingType::Split0)].nat);
         serializer->doBool(&swap->massw_split[eChannel0]);
-        serializer->doInt(&swap->grp[eGrpSplit1].nat);
+        serializer->doInt(&swap->grp[static_cast<int>(SwapGroupSplittingType::Split1)].nat);
         serializer->doBool(&swap->massw_split[eChannel1]);
         serializer->doInt(&swap->nstswap);
         serializer->doInt(&swap->nAverage);
@@ -984,7 +1004,10 @@ static void do_swapcoords_tpx(gmx::ISerializer* serializer, t_swapcoords* swap,
         // The order[] array keeps compatibility with older .tpr files
         // by reading in the groups in the classic order
         {
-            const int order[4] = { 3, eGrpSolvent, eGrpSplit0, eGrpSplit1 };
+            const int order[4] = { 3,
+                                   static_cast<int>(SwapGroupSplittingType::Solvent),
+                                   static_cast<int>(SwapGroupSplittingType::Split0),
+                                   static_cast<int>(SwapGroupSplittingType::Split1) };
 
             for (int ig = 0; ig < 4; ig++)
             {
@@ -1066,7 +1089,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     gmx::KeyValueTreeObjectBuilder paramsObj = paramsBuilder.rootObject();
 
     /* Basic inputrec stuff */
-    serializer->doInt(&ir->eI);
+    serializer->doEnumAsInt(&ir->eI);
     if (file_version >= 62)
     {
         serializer->doInt64(&ir->nsteps);
@@ -1122,15 +1145,21 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     }
     if (file_version >= 81)
     {
-        serializer->doInt(&ir->cutoff_scheme);
+        serializer->doEnumAsInt(&ir->cutoff_scheme);
         if (file_version < 94)
         {
-            ir->cutoff_scheme = 1 - ir->cutoff_scheme;
+            // Need to invert the scheme order
+            switch (ir->cutoff_scheme)
+            {
+                case (CutoffScheme::Group): ir->cutoff_scheme = CutoffScheme::Verlet; break;
+                case (CutoffScheme::Verlet): ir->cutoff_scheme = CutoffScheme::Group; break;
+                default: GMX_RELEASE_ASSERT(false, "Unhandled cutoff scheme type");
+            }
         }
     }
     else
     {
-        ir->cutoff_scheme = ecutsGROUP;
+        ir->cutoff_scheme = CutoffScheme::Group;
     }
     serializer->doInt(&idum); /* used to be ns_type; not used anymore */
     serializer->doInt(&ir->nstlist);
@@ -1139,7 +1168,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     serializer->doReal(&ir->rtpi);
 
     serializer->doInt(&ir->nstcomm);
-    serializer->doInt(&ir->comm_mode);
+    serializer->doEnumAsInt(&ir->comm_mode);
 
     /* ignore nstcheckpoint */
     if (file_version < tpxv_RemoveObsoleteParameters1)
@@ -1211,29 +1240,31 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
         int dummy_nstcalclr = -1;
         serializer->doInt(&dummy_nstcalclr);
     }
-    serializer->doInt(&ir->coulombtype);
+    serializer->doEnumAsInt(&ir->coulombtype);
     if (file_version >= 81)
     {
-        serializer->doInt(&ir->coulomb_modifier);
+        serializer->doEnumAsInt(&ir->coulomb_modifier);
     }
     else
     {
-        ir->coulomb_modifier = (ir->cutoff_scheme == ecutsVERLET ? eintmodPOTSHIFT : eintmodNONE);
+        ir->coulomb_modifier = (ir->cutoff_scheme == CutoffScheme::Verlet ? InteractionModifiers::PotShift
+                                                                          : InteractionModifiers::None);
     }
     serializer->doReal(&ir->rcoulomb_switch);
     serializer->doReal(&ir->rcoulomb);
-    serializer->doInt(&ir->vdwtype);
+    serializer->doEnumAsInt(&ir->vdwtype);
     if (file_version >= 81)
     {
-        serializer->doInt(&ir->vdw_modifier);
+        serializer->doEnumAsInt(&ir->vdw_modifier);
     }
     else
     {
-        ir->vdw_modifier = (ir->cutoff_scheme == ecutsVERLET ? eintmodPOTSHIFT : eintmodNONE);
+        ir->vdw_modifier = (ir->cutoff_scheme == CutoffScheme::Verlet ? InteractionModifiers::PotShift
+                                                                      : InteractionModifiers::None);
     }
     serializer->doReal(&ir->rvdw_switch);
     serializer->doReal(&ir->rvdw);
-    serializer->doInt(&ir->eDispCorr);
+    serializer->doEnumAsInt(&ir->eDispCorr);
     serializer->doReal(&ir->epsilon_r);
     serializer->doReal(&ir->epsilon_rf);
     serializer->doReal(&ir->tabext);
@@ -1292,7 +1323,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     {
         ir->ewald_rtol_lj = ir->ewald_rtol;
     }
-    serializer->doInt(&ir->ewald_geometry);
+    serializer->doEnumAsInt(&ir->ewald_geometry);
     serializer->doReal(&ir->epsilon_surface);
 
     /* ignore bOptFFT */
@@ -1303,7 +1334,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
 
     if (file_version >= 93)
     {
-        serializer->doInt(&ir->ljpme_combination_rule);
+        serializer->doEnumAsInt(&ir->ljpme_combination_rule);
     }
     serializer->doBool(&ir->bContinuation);
     serializer->doEnumAsInt(&ir->etc);
@@ -1324,7 +1355,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
         ir->nsttcouple = ir->nstcalcenergy;
     }
     serializer->doEnumAsInt(&ir->epc);
-    serializer->doInt(&ir->epct);
+    serializer->doEnumAsInt(&ir->epct);
     if (file_version >= 71)
     {
         serializer->doInt(&ir->nstpcouple);
@@ -1340,7 +1371,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     serializer->doRvec(&ir->compress[XX]);
     serializer->doRvec(&ir->compress[YY]);
     serializer->doRvec(&ir->compress[ZZ]);
-    serializer->doInt(&ir->refcoord_scaling);
+    serializer->doEnumAsInt(&ir->refcoord_scaling);
     serializer->doRvec(&ir->posres_com);
     serializer->doRvec(&ir->posres_comB);
 
@@ -1355,8 +1386,12 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
 
     serializer->doReal(&ir->shake_tol);
 
-    serializer->doInt(&ir->efep);
-    do_fepvals(serializer, ir->fepvals, file_version);
+    serializer->doEnumAsInt(&ir->efep);
+    if (serializer->reading())
+    {
+        ir->fepvals = std::make_unique<t_lambda>();
+    }
+    do_fepvals(serializer, ir->fepvals.get(), file_version);
 
     if (file_version >= 79)
     {
@@ -1372,7 +1407,11 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     }
     if (ir->bSimTemp)
     {
-        do_simtempvals(serializer, ir->simtempvals, ir->fepvals->n_lambda, file_version);
+        if (serializer->reading())
+        {
+            ir->simtempvals = std::make_unique<t_simtemp>();
+        }
+        do_simtempvals(serializer, ir->simtempvals.get(), ir->fepvals->n_lambda, file_version);
     }
 
     if (file_version >= 79)
@@ -1381,11 +1420,15 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     }
     if (ir->bExpanded)
     {
-        do_expandedvals(serializer, ir->expandedvals, ir->fepvals, file_version);
+        if (serializer->reading())
+        {
+            ir->expandedvals = std::make_unique<t_expanded>();
+        }
+        do_expandedvals(serializer, ir->expandedvals.get(), ir->fepvals.get(), file_version);
     }
 
-    serializer->doInt(&ir->eDisre);
-    serializer->doInt(&ir->eDisreWeighting);
+    serializer->doEnumAsInt(&ir->eDisre);
+    serializer->doEnumAsInt(&ir->eDisreWeighting);
     serializer->doBool(&ir->bDisreMixed);
     serializer->doReal(&ir->dr_fc);
     serializer->doReal(&ir->dr_tau);
@@ -1405,7 +1448,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     serializer->doBool(&ir->bShakeSOR);
     serializer->doInt(&ir->niter);
     serializer->doReal(&ir->fc_stepsize);
-    serializer->doInt(&ir->eConstrAlg);
+    serializer->doEnumAsInt(&ir->eConstrAlg);
     serializer->doInt(&ir->nProjOrder);
     serializer->doReal(&ir->LincsWarnAngle);
     serializer->doInt(&ir->nLincsIter);
@@ -1476,7 +1519,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
 
     /* pull stuff */
     {
-        int ePullOld = 0;
+        PullingAlgorithm ePullOld = PullingAlgorithm::Umbrella;
 
         if (file_version >= tpxv_PullCoordTypeGeom)
         {
@@ -1484,10 +1527,28 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
         }
         else
         {
-            serializer->doInt(&ePullOld);
-            ir->bPull = (ePullOld > 0);
+            serializer->doEnumAsInt(&ePullOld);
+            ir->bPull = (ePullOld != PullingAlgorithm::Umbrella);
             /* We removed the first ePull=ePullNo for the enum */
-            ePullOld -= 1;
+            switch (ePullOld)
+            {
+                case (PullingAlgorithm::Umbrella): break; // this is equal to not using pulling
+                case (PullingAlgorithm::Constraint): ePullOld = PullingAlgorithm::Umbrella; break;
+                case (PullingAlgorithm::ConstantForce):
+                    ePullOld = PullingAlgorithm::Constraint;
+                    break;
+                case (PullingAlgorithm::FlatBottom):
+                    ePullOld = PullingAlgorithm::ConstantForce;
+                    break;
+                case (PullingAlgorithm::FlatBottomHigh):
+                    ePullOld = PullingAlgorithm::FlatBottom;
+                    break;
+                case (PullingAlgorithm::External):
+                    ePullOld = PullingAlgorithm::FlatBottomHigh;
+                    break;
+                case (PullingAlgorithm::Count): ePullOld = PullingAlgorithm::External; break;
+                default: GMX_RELEASE_ASSERT(false, "Unhandled old pull algorithm");
+            }
         }
         if (ir->bPull)
         {
@@ -1610,7 +1671,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     serializer->doIntArray(ir->opts.egp_flags, ir->opts.ngener * ir->opts.ngener);
 
     /* First read the lists with annealing and npoints for each group */
-    serializer->doIntArray(ir->opts.annealing, ir->opts.ngtc);
+    serializer->doEnumArrayAsInt(ir->opts.annealing, ir->opts.ngtc);
     serializer->doIntArray(ir->opts.anneal_npoints, ir->opts.ngtc);
     for (j = 0; j < (ir->opts.ngtc); j++)
     {
@@ -1626,7 +1687,7 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     /* Walls */
     {
         serializer->doInt(&ir->nwall);
-        serializer->doInt(&ir->wall_type);
+        serializer->doEnumAsInt(&ir->wall_type);
         serializer->doReal(&ir->wall_r_linpot);
         serializer->doInt(&ir->wall_atomtype[0]);
         serializer->doInt(&ir->wall_atomtype[1]);
@@ -1644,8 +1705,8 @@ static void do_inputrec(gmx::ISerializer* serializer, t_inputrec* ir, int file_v
     /* Swap ions */
     if (file_version >= tpxv_ComputationalElectrophysiology)
     {
-        serializer->doInt(&ir->eSwapCoords);
-        if (ir->eSwapCoords != eswapNO)
+        serializer->doEnumAsInt(&ir->eSwapCoords);
+        if (ir->eSwapCoords != SwapType::No)
         {
             if (serializer->reading())
             {
@@ -3085,14 +3146,9 @@ static void do_tpx_finalize(TpxFileHeader* tpx, t_inputrec* ir, t_state* state,
         {
             if (tpx->fileVersion < 57)
             {
-                if (!mtop->moltype[0].ilist[F_DISRES].empty())
-                {
-                    ir->eDisre = edrSimple;
-                }
-                else
-                {
-                    ir->eDisre = edrNone;
-                }
+                ir->eDisre = !mtop->moltype[0].ilist[F_DISRES].empty()
+                                     ? DistanceRestraintRefinement::Simple
+                                     : DistanceRestraintRefinement::None;
             }
         }
     }
@@ -3183,7 +3239,7 @@ static TpxFileHeader populateTpxHeader(const t_state& state, const t_inputrec* i
     header.natoms         = state.natoms;
     header.ngtc           = state.ngtc;
     header.fep_state      = state.fep_state;
-    header.lambda         = state.lambda[efptFEP];
+    header.lambda         = state.lambda[FreeEnergyPerturbationCouplingType::Fep];
     header.bIr            = ir != nullptr;
     header.bTop           = mtop != nullptr;
     header.bX             = (state.flags & (1 << estX)) != 0;
index 97b0e2c36d6d30cf4d88bbaf8637fb2e43221592..b70ffedf36c5851d9c214921c664e1ca7361c664 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 2010-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.
@@ -3142,7 +3142,9 @@ static void read_barsim_edr(const char* fn, real* temp, sim_data_t* sd)
                     n_lambda_vec = fr->block[i].sub[1].ival[1];
                     for (j = 0; j < n_lambda_vec; j++)
                     {
-                        const char* name = efpt_singular_names[fr->block[i].sub[1].ival[1 + j]];
+                        const char* name =
+                                enumValueToStringSingular(static_cast<FreeEnergyPerturbationCouplingType>(
+                                        fr->block[i].sub[1].ival[1 + j]));
                         if (check)
                         {
                             /* check the components */
index bd3feef0437da3b4e6bc022e0a2d719e3de37e83..b00e05930fdb4b34ac960331a0b9b14a9b6534de 100644 (file)
@@ -357,7 +357,7 @@ static void dump_viol(FILE* log, int ndr, t_dr_stats* drs, gmx_bool bLinear)
         fprintf(log,
                 "%6d%5s%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f%8.3f\n",
                 drs[i].label,
-                yesno_names[drs[i].bCore],
+                booleanValueToString(drs[i].bCore),
                 drs[i].up1,
                 drs[i].r,
                 drs[i].rT3,
@@ -806,7 +806,7 @@ int gmx_disre(int argc, char* argv[])
     }
 
     gmx_localtop_t top(topInfo.mtop()->ffparams);
-    gmx_mtop_generate_local_top(*topInfo.mtop(), &top, ir->efep != efepNO);
+    gmx_mtop_generate_local_top(*topInfo.mtop(), &top, ir->efep != FreeEnergyPerturbationType::No);
     const InteractionDefinitions& idef = top.idef;
 
     pbc_null = nullptr;
index e3778d7747249348bd6a8d1ff0ed99c391c122ce..47dcde2f60d9e1b927c85c50287a90db7d6c219d 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.
@@ -1465,7 +1465,9 @@ static void do_dhdl(t_enxframe*             fr,
                 for (j = 0; j < n_lambda_vec; j++)
                 {
                     native_lambda_vec[j] = fr->block[i].sub[0].dval[5 + j];
-                    lambda_components[j] = efpt_singular_names[fr->block[i].sub[1].ival[2 + j]];
+                    lambda_components[j] =
+                            enumValueToStringSingular(static_cast<FreeEnergyPerturbationCouplingType>(
+                                    fr->block[i].sub[1].ival[2 + j]));
                 }
             }
         }
index 119c5e0a05a62bda81916d1736996965e09f791c..7a6ac17faa8a0b1dd770332dd7215fce827b9d71 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.
@@ -618,7 +618,8 @@ int gmx_nmr(int argc, char* argv[])
         {
             topInfo.fillFromInputFile(ftp2fn(efTPR, NFILE, fnm));
             top = std::make_unique<gmx_localtop_t>(topInfo.mtop()->ffparams);
-            gmx_mtop_generate_local_top(*topInfo.mtop(), top.get(), ir->efep != efepNO);
+            gmx_mtop_generate_local_top(
+                    *topInfo.mtop(), top.get(), ir->efep != FreeEnergyPerturbationType::No);
         }
         nbounds = get_bounds(&bounds, &index, &pair, &npairs, top->idef);
         snew(violaver, npairs);
index 1cf91e42d76bd7d0b16fe2e7c0c7a259b44834b1..282ddd0c38466450dd7cc04a2427f7a09d468ca6 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.
@@ -138,14 +138,14 @@ enum
 //! Parameters of one pull coodinate
 typedef struct
 {
-    int  pull_type;       //!< such as constraint, umbrella, ...
-    int  geometry;        //!< such as distance, direction, cylinder
-    int  ngroup;          //!< the number of pull groups involved
-    ivec dim;             //!< pull dimension with geometry distance
-    int  ndim;            //!< nr of pull_dim != 0
-    real k;               //!< force constants in tpr file
-    real init_dist;       //!< reference displacement
-    char coord_unit[256]; //!< unit of the displacement
+    PullingAlgorithm  pull_type;       //!< such as constraint, umbrella, ...
+    PullGroupGeometry geometry;        //!< such as distance, direction, cylinder
+    int               ngroup;          //!< the number of pull groups involved
+    ivec              dim;             //!< pull dimension with geometry distance
+    int               ndim;            //!< nr of pull_dim != 0
+    real              k;               //!< force constants in tpr file
+    real              init_dist;       //!< reference displacement
+    char              coord_unit[256]; //!< unit of the displacement
 } t_pullcoord;
 
 //! Parameters of the umbrella potentials
@@ -2108,7 +2108,7 @@ static void read_tpr_header(const char* fn, t_UmbrellaHeader* header, t_Umbrella
 
         std::strcpy(header->pcrd[i].coord_unit, pull_coordinate_units(&ir->pull->coord[i]));
 
-        if (ir->efep != efepNO && ir->pull->coord[i].k != ir->pull->coord[i].kB)
+        if (ir->efep != FreeEnergyPerturbationType::No && ir->pull->coord[i].k != ir->pull->coord[i].kB)
         {
             gmx_fatal(FARGS,
                       "Seems like you did free-energy perturbation, and you perturbed the force "
@@ -2127,14 +2127,14 @@ static void read_tpr_header(const char* fn, t_UmbrellaHeader* header, t_Umbrella
     }
 
     /* Check pull coords for consistency */
-    int  geom          = -1;
-    ivec thedim        = { 0, 0, 0 };
-    bool geometryIsSet = false;
+    PullGroupGeometry geom          = PullGroupGeometry::Count;
+    ivec              thedim        = { 0, 0, 0 };
+    bool              geometryIsSet = false;
     for (int i = 0; i < ir->pull->ncoord; i++)
     {
         if (coordsel == nullptr || coordsel->bUse[i])
         {
-            if (header->pcrd[i].pull_type != epullUMBRELLA)
+            if (header->pcrd[i].pull_type != PullingAlgorithm::Umbrella)
             {
                 gmx_fatal(FARGS,
                           "%s: Pull coordinate %d is of type \"%s\", expected \"umbrella\". Only "
@@ -2143,7 +2143,7 @@ static void read_tpr_header(const char* fn, t_UmbrellaHeader* header, t_Umbrella
                           "umbrella coordinates with gmx wham -is\n",
                           fn,
                           i + 1,
-                          epull_names[header->pcrd[i].pull_type]);
+                          enumValueToString(header->pcrd[i].pull_type));
             }
             if (!geometryIsSet)
             {
@@ -2159,9 +2159,9 @@ static void read_tpr_header(const char* fn, t_UmbrellaHeader* header, t_Umbrella
                           "If you want to use only some pull coordinates in WHAM, please select "
                           "them with option gmx wham -is\n",
                           fn,
-                          epullg_names[geom],
+                          enumValueToString(geom),
                           i + 1,
-                          epullg_names[header->pcrd[i].geometry]);
+                          enumValueToString(header->pcrd[i].geometry));
             }
             if (thedim[XX] != header->pcrd[i].dim[XX] || thedim[YY] != header->pcrd[i].dim[YY]
                 || thedim[ZZ] != header->pcrd[i].dim[ZZ])
@@ -2180,7 +2180,7 @@ static void read_tpr_header(const char* fn, t_UmbrellaHeader* header, t_Umbrella
                           int2YN(header->pcrd[i].dim[YY]),
                           int2YN(header->pcrd[i].dim[ZZ]));
             }
-            if (header->pcrd[i].geometry == epullgCYL)
+            if (header->pcrd[i].geometry == PullGroupGeometry::Cylinder)
             {
                 if (header->pcrd[i].dim[XX] || header->pcrd[i].dim[YY] || (!header->pcrd[i].dim[ZZ]))
                 {
@@ -2211,7 +2211,7 @@ static void read_tpr_header(const char* fn, t_UmbrellaHeader* header, t_Umbrella
         int maxlen = 0;
         for (int i = 0; i < ir->pull->ncoord; i++)
         {
-            int lentmp = strlen(epullg_names[header->pcrd[i].geometry]);
+            int lentmp = strlen(enumValueToString(header->pcrd[i].geometry));
             maxlen     = (lentmp > maxlen) ? lentmp : maxlen;
         }
         char fmt[STRLEN];
@@ -2223,7 +2223,7 @@ static void read_tpr_header(const char* fn, t_UmbrellaHeader* header, t_Umbrella
         {
             bool use = (coordsel == nullptr || coordsel->bUse[i]);
             printf(fmt,
-                   epullg_names[header->pcrd[i].geometry],
+                   enumValueToString(header->pcrd[i].geometry),
                    header->pcrd[i].k,
                    header->pcrd[i].init_dist,
                    int2YN(header->pcrd[i].dim[XX]),
index d036d8510a4317526382c44330da3defee190d9f..290c7345dc17dc0818945215b840c12a3d30fae8 100644 (file)
@@ -244,19 +244,21 @@ static void nb_free_energy_kernel(const t_nblist* gmx_restrict nlist,
     gmx::ArrayRef<const real> nbfp      = fr->nbfp;
     gmx::ArrayRef<const real> nbfp_grid = fr->ljpme_c6grid;
 
-    real*       Vv            = kernel_data->energygrp_vdw;
-    const real  lambda_coul   = kernel_data->lambda[efptCOUL];
-    const real  lambda_vdw    = kernel_data->lambda[efptVDW];
-    real*       dvdl          = kernel_data->dvdl;
-    const auto& scParams      = *ic->softCoreParameters;
-    const real  alpha_coul    = scParams.alphaCoulomb;
-    const real  alpha_vdw     = scParams.alphaVdw;
-    const real  lam_power     = scParams.lambdaPower;
-    const real  sigma6_def    = scParams.sigma6WithInvalidSigma;
-    const real  sigma6_min    = scParams.sigma6Minimum;
-    const bool  doForces      = ((kernel_data->flags & GMX_NONBONDED_DO_FORCE) != 0);
-    const bool  doShiftForces = ((kernel_data->flags & GMX_NONBONDED_DO_SHIFTFORCE) != 0);
-    const bool  doPotential   = ((kernel_data->flags & GMX_NONBONDED_DO_POTENTIAL) != 0);
+    real*      Vv = kernel_data->energygrp_vdw;
+    const real lambda_coul =
+            kernel_data->lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)];
+    const real lambda_vdw =
+            kernel_data->lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)];
+    gmx::ArrayRef<real> dvdl          = kernel_data->dvdl;
+    const auto&         scParams      = *ic->softCoreParameters;
+    const real          alpha_coul    = scParams.alphaCoulomb;
+    const real          alpha_vdw     = scParams.alphaVdw;
+    const real          lam_power     = scParams.lambdaPower;
+    const real          sigma6_def    = scParams.sigma6WithInvalidSigma;
+    const real          sigma6_min    = scParams.sigma6Minimum;
+    const bool          doForces      = ((kernel_data->flags & GMX_NONBONDED_DO_FORCE) != 0);
+    const bool          doShiftForces = ((kernel_data->flags & GMX_NONBONDED_DO_SHIFTFORCE) != 0);
+    const bool          doPotential   = ((kernel_data->flags & GMX_NONBONDED_DO_POTENTIAL) != 0);
 
     // Extract data from interaction_const_t
     const real facel           = ic->epsfac;
@@ -269,7 +271,7 @@ static void nb_free_energy_kernel(const t_nblist* gmx_restrict nlist,
     const real repulsionShift  = ic->repulsion_shift.cpot;
 
     // Note that the nbnxm kernels do not support Coulomb potential switching at all
-    GMX_ASSERT(ic->coulomb_modifier != eintmodPOTSWITCH,
+    GMX_ASSERT(ic->coulomb_modifier != InteractionModifiers::PotSwitch,
                "Potential switching is not supported for Coulomb with FEP");
 
     real vdw_swV3, vdw_swV4, vdw_swV5, vdw_swF2, vdw_swF3, vdw_swF4;
@@ -289,14 +291,14 @@ static void nb_free_energy_kernel(const t_nblist* gmx_restrict nlist,
         vdw_swV3 = vdw_swV4 = vdw_swV5 = vdw_swF2 = vdw_swF3 = vdw_swF4 = 0.0;
     }
 
-    int icoul;
-    if (ic->eeltype == eelCUT || EEL_RF(ic->eeltype))
+    NbkernelElecType icoul;
+    if (ic->eeltype == CoulombInteractionType::Cut || EEL_RF(ic->eeltype))
     {
-        icoul = GMX_NBKERNEL_ELEC_REACTIONFIELD;
+        icoul = NbkernelElecType::ReactionField;
     }
     else
     {
-        icoul = GMX_NBKERNEL_ELEC_NONE;
+        icoul = NbkernelElecType::None;
     }
 
     real rcutoff_max2 = std::max(ic->rcoulomb, ic->rvdw);
@@ -669,7 +671,7 @@ static void nb_free_energy_kernel(const t_nblist* gmx_restrict nlist,
                     }
                 }
             } // end if (bPairIncluded)
-            else if (icoul == GMX_NBKERNEL_ELEC_REACTIONFIELD)
+            else if (icoul == NbkernelElecType::ReactionField)
             {
                 /* For excluded pairs, which are only in this pair list when
                  * using the Verlet scheme, we don't use soft-core.
@@ -840,9 +842,9 @@ static void nb_free_energy_kernel(const t_nblist* gmx_restrict nlist,
     } // end for (int n = 0; n < nri; n++)
 
 #pragma omp atomic
-    dvdl[efptCOUL] += dvdlCoul;
+    dvdl[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)] += dvdlCoul;
 #pragma omp atomic
-    dvdl[efptVDW] += dvdlVdw;
+    dvdl[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)] += dvdlVdw;
 
     /* Estimate flops, average for free energy stuff:
      * 12  flops per outer iteration
@@ -996,14 +998,14 @@ void gmx_nb_free_energy_kernel(const t_nblist*            nlist,
                                t_nrnb*                    nrnb)
 {
     const interaction_const_t& ic = *fr->ic;
-    GMX_ASSERT(EEL_PME_EWALD(ic.eeltype) || ic.eeltype == eelCUT || EEL_RF(ic.eeltype),
+    GMX_ASSERT(EEL_PME_EWALD(ic.eeltype) || ic.eeltype == CoulombInteractionType::Cut || EEL_RF(ic.eeltype),
                "Unsupported eeltype with free energy");
     GMX_ASSERT(ic.softCoreParameters, "We need soft-core parameters");
 
     const auto& scParams                   = *ic.softCoreParameters;
     const bool  vdwInteractionTypeIsEwald  = (EVDW_PME(ic.vdwtype));
     const bool  elecInteractionTypeIsEwald = (EEL_PME_EWALD(ic.eeltype));
-    const bool  vdwModifierIsPotSwitch     = (ic.vdw_modifier == eintmodPOTSWITCH);
+    const bool  vdwModifierIsPotSwitch     = (ic.vdw_modifier == InteractionModifiers::PotSwitch);
     bool        scLambdasOrAlphasDiffer    = true;
     const bool  useSimd                    = fr->use_simd_kernels;
 
@@ -1013,7 +1015,8 @@ void gmx_nb_free_energy_kernel(const t_nblist*            nlist,
     }
     else
     {
-        if (kernel_data->lambda[efptCOUL] == kernel_data->lambda[efptVDW]
+        if (kernel_data->lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)]
+                    == kernel_data->lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)]
             && scParams.alphaCoulomb == scParams.alphaVdw)
         {
             scLambdasOrAlphasDiffer = false;
index ff75e9159a77affa82c9ec88f3e04ab6a52c4c2d..c261d2652d20d805c3450b07143ea84942fc1713 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 2012,2014,2015,2017,2018 by 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.
@@ -41,6 +41,7 @@
 #include "gromacs/gmxlib/nrnb.h"
 #include "gromacs/math/vectypes.h"
 #include "gromacs/mdtypes/nblist.h"
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/real.h"
 
 struct t_blocka;
@@ -51,10 +52,10 @@ struct t_mdatoms;
  */
 typedef struct
 {
-    int                    flags;
-    const struct t_blocka* exclusions;
-    const real*            lambda;
-    real*                  dvdl;
+    int                       flags;
+    const struct t_blocka*    exclusions;
+    gmx::ArrayRef<const real> lambda;
+    gmx::ArrayRef<real>       dvdl;
 
     /* pointers to tables */
     t_forcetable* table_elec;
index bafd389beef3e8f175c292fffb3efab499b72c20..f06620e5b422af31a417471baf5f36ca5d433343 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.
@@ -86,9 +86,9 @@ static int round_check(real r, int limit, int ftype, const char* name)
     return i;
 }
 
-static void set_ljparams(int comb, double reppow, double v, double w, real* c6, real* c12)
+static void set_ljparams(CombinationRule comb, double reppow, double v, double w, real* c6, real* c12)
 {
-    if (comb == eCOMB_ARITHMETIC || comb == eCOMB_GEOM_SIG_EPS)
+    if (comb == CombinationRule::Arithmetic || comb == CombinationRule::GeomSigEps)
     {
         if (v >= 0)
         {
@@ -112,7 +112,11 @@ static void set_ljparams(int comb, double reppow, double v, double w, real* c6,
 /* A return value of 0 means parameters were assigned successfully,
  * returning -1 means this is an all-zero interaction that should not be added.
  */
-static int assign_param(t_functype ftype, t_iparams* newparam, gmx::ArrayRef<const real> old, int comb, double reppow)
+static int assign_param(t_functype                ftype,
+                        t_iparams*                newparam,
+                        gmx::ArrayRef<const real> old,
+                        CombinationRule           comb,
+                        double                    reppow)
 {
     bool all_param_zero = true;
 
@@ -453,7 +457,7 @@ static int assign_param(t_functype ftype, t_iparams* newparam, gmx::ArrayRef<con
 static int enter_params(gmx_ffparams_t*           ffparams,
                         t_functype                ftype,
                         gmx::ArrayRef<const real> forceparams,
-                        int                       comb,
+                        CombinationRule           comb,
                         real                      reppow,
                         int                       start,
                         bool                      bAppend)
@@ -516,7 +520,7 @@ static void append_interaction(InteractionList* ilist, int type, gmx::ArrayRef<c
 
 static void enter_function(const InteractionsOfType* p,
                            t_functype                ftype,
-                           int                       comb,
+                           CombinationRule           comb,
                            real                      reppow,
                            gmx_ffparams_t*           ffparams,
                            InteractionList*          il,
@@ -543,7 +547,7 @@ void convertInteractionsOfType(int                                      atnr,
                                gmx::ArrayRef<const InteractionsOfType>  nbtypes,
                                gmx::ArrayRef<const MoleculeInformation> mi,
                                const MoleculeInformation*               intermolecular_interactions,
-                               int                                      comb,
+                               CombinationRule                          comb,
                                double                                   reppow,
                                real                                     fudgeQQ,
                                gmx_mtop_t*                              mtop)
index a3d65b8e846219e96e7daf97bb782a0a25581823..eac7e911aeb9f0d78fe473dca6ef04af884b6f2b 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,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.
@@ -43,6 +43,7 @@
 struct gmx_mtop_t;
 struct MoleculeInformation;
 struct InteractionsOfType;
+enum class CombinationRule : int;
 
 namespace gmx
 {
@@ -54,7 +55,7 @@ void convertInteractionsOfType(int                                      atnr,
                                gmx::ArrayRef<const InteractionsOfType>  nbtypes,
                                gmx::ArrayRef<const MoleculeInformation> mi,
                                const MoleculeInformation*               intermolecular_interactions,
-                               int                                      comb,
+                               CombinationRule                          comb,
                                double                                   reppow,
                                real                                     fudgeQQ,
                                gmx_mtop_t*                              mtop);
index 2f6f29e3e0e1f92a0f5d8568e8bab10cf98bc2c9..a47fb29950cb09e5c7a8baebd751e370b0b48e8d 100644 (file)
@@ -586,7 +586,7 @@ static void new_status(const char*                           topfile,
                        std::vector<MoleculeInformation>*     mi,
                        std::unique_ptr<MoleculeInformation>* intermolecular_interactions,
                        gmx::ArrayRef<InteractionsOfType>     interactions,
-                       int*                                  comb,
+                       CombinationRule*                      comb,
                        double*                               reppow,
                        real*                                 fudgeQQ,
                        gmx_bool                              bMorse,
@@ -646,7 +646,7 @@ static void new_status(const char*                           topfile,
         convert_harmonics(*mi, atypes);
     }
 
-    if (ir->eDisre == edrNone)
+    if (ir->eDisre == DistanceRestraintRefinement::None)
     {
         i = rm_interactions(F_DISRES, *mi);
         if (i > 0)
@@ -918,7 +918,7 @@ static void read_posres(gmx_mtop_t*                              mtop,
                         gmx::ArrayRef<const MoleculeInformation> molinfo,
                         gmx_bool                                 bTopB,
                         const char*                              fn,
-                        int                                      rc_scaling,
+                        RefCoordScaling                          rc_scaling,
                         PbcType                                  pbcType,
                         rvec                                     com,
                         warninp*                                 wi,
@@ -955,7 +955,7 @@ static void read_posres(gmx_mtop_t*                              mtop,
     npbcdim = numPbcDimensions(pbcType);
     GMX_RELEASE_ASSERT(npbcdim <= DIM, "Invalid npbcdim");
     clear_rvec(com);
-    if (rc_scaling != erscNO)
+    if (rc_scaling != RefCoordScaling::No)
     {
         copy_mat(box, invbox);
         for (int j = npbcdim; j < DIM; j++)
@@ -993,7 +993,7 @@ static void read_posres(gmx_mtop_t*                              mtop,
                               natoms);
                 }
                 hadAtom[ai] = TRUE;
-                if (rc_scaling == erscCOM)
+                if (rc_scaling == RefCoordScaling::Com)
                 {
                     /* Determine the center of mass of the posres reference coordinates */
                     for (int j = 0; j < npbcdim; j++)
@@ -1017,7 +1017,7 @@ static void read_posres(gmx_mtop_t*                              mtop,
                               fn,
                               natoms);
                 }
-                if (rc_scaling == erscCOM && !hadAtom[ai])
+                if (rc_scaling == RefCoordScaling::Com && !hadAtom[ai])
                 {
                     /* Determine the center of mass of the posres reference coordinates */
                     for (int j = 0; j < npbcdim; j++)
@@ -1046,7 +1046,7 @@ static void read_posres(gmx_mtop_t*                              mtop,
         }
         a += nat_molb;
     }
-    if (rc_scaling == erscCOM)
+    if (rc_scaling == RefCoordScaling::Com)
     {
         if (totmass == 0)
         {
@@ -1065,7 +1065,7 @@ static void read_posres(gmx_mtop_t*                              mtop,
                         com[ZZ]);
     }
 
-    if (rc_scaling != erscNO)
+    if (rc_scaling != RefCoordScaling::No)
     {
         GMX_ASSERT(npbcdim <= DIM, "Only DIM dimensions can have PBC");
 
@@ -1079,7 +1079,7 @@ static void read_posres(gmx_mtop_t*                              mtop,
                 {
                     for (int j = 0; j < npbcdim; j++)
                     {
-                        if (rc_scaling == erscALL)
+                        if (rc_scaling == RefCoordScaling::All)
                         {
                             /* Convert from Cartesian to crystal coordinates */
                             xp[i][j] *= invbox[j][j];
@@ -1088,7 +1088,7 @@ static void read_posres(gmx_mtop_t*                              mtop,
                                 xp[i][j] += invbox[k][j] * xp[i][k];
                             }
                         }
-                        else if (rc_scaling == erscCOM)
+                        else if (rc_scaling == RefCoordScaling::Com)
                         {
                             /* Subtract the center of mass */
                             xp[i][j] -= com[j];
@@ -1098,7 +1098,7 @@ static void read_posres(gmx_mtop_t*                              mtop,
             }
         }
 
-        if (rc_scaling == erscCOM)
+        if (rc_scaling == RefCoordScaling::Com)
         {
             /* Convert the COM from Cartesian to crystal coordinates */
             for (int j = 0; j < npbcdim; j++)
@@ -1121,7 +1121,7 @@ static void gen_posres(gmx_mtop_t*                              mtop,
                        gmx::ArrayRef<const MoleculeInformation> mi,
                        const char*                              fnA,
                        const char*                              fnB,
-                       int                                      rc_scaling,
+                       RefCoordScaling                          rc_scaling,
                        PbcType                                  pbcType,
                        rvec                                     com,
                        rvec                                     comB,
@@ -1605,11 +1605,12 @@ static void checkDecoupledModeAccuracy(const gmx_mtop_t* mtop, const t_inputrec*
     const int  lincsOrderThreshold      = 4;
     const real shakeToleranceThreshold  = 0.005 * ir->delta_t;
 
-    bool lincsWithSufficientTolerance = (ir->eConstrAlg == econtLINCS && ir->nLincsIter >= lincsIterationThreshold
-                                         && ir->nProjOrder >= lincsOrderThreshold);
-    bool shakeWithSufficientTolerance =
-            (ir->eConstrAlg == econtSHAKE && ir->shake_tol <= 1.1 * shakeToleranceThreshold);
-    if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol <= 1.1 * bufferToleranceThreshold
+    bool lincsWithSufficientTolerance =
+            (ir->eConstrAlg == ConstraintAlgorithm::Lincs
+             && ir->nLincsIter >= lincsIterationThreshold && ir->nProjOrder >= lincsOrderThreshold);
+    bool shakeWithSufficientTolerance = (ir->eConstrAlg == ConstraintAlgorithm::Shake
+                                         && ir->shake_tol <= 1.1 * shakeToleranceThreshold);
+    if (ir->cutoff_scheme == CutoffScheme::Verlet && ir->verletbuf_tol <= 1.1 * bufferToleranceThreshold
         && (lincsWithSufficientTolerance || shakeWithSufficientTolerance))
     {
         return;
@@ -1631,7 +1632,7 @@ static void checkDecoupledModeAccuracy(const gmx_mtop_t* mtop, const t_inputrec*
                 "and with masses that differ by more than a factor of %g. This means "
                 "that there are likely dynamic modes that are only very weakly coupled.",
                 massFactorThreshold);
-        if (ir->cutoff_scheme == ecutsVERLET)
+        if (ir->cutoff_scheme == CutoffScheme::Verlet)
         {
             message += gmx::formatString(
                     " To ensure good equipartitioning, you need to either not use "
@@ -1639,7 +1640,7 @@ static void checkDecoupledModeAccuracy(const gmx_mtop_t* mtop, const t_inputrec*
                     "hydrogens) or use integrator = %s or decrease one or more tolerances: "
                     "verlet-buffer-tolerance <= %g, LINCS iterations >= %d, LINCS order "
                     ">= %d or SHAKE tolerance <= %g",
-                    ei_names[eiSD1],
+                    enumValueToString(IntegrationAlgorithm::SD1),
                     bufferToleranceThreshold,
                     lincsIterationThreshold,
                     lincsOrderThreshold,
@@ -1651,7 +1652,7 @@ static void checkDecoupledModeAccuracy(const gmx_mtop_t* mtop, const t_inputrec*
                     " To ensure good equipartitioning, we suggest to switch to the %s "
                     "cutoff-scheme, since that allows for better control over the Verlet "
                     "buffer size and thus over the energy drift.",
-                    ecutscheme_names[ecutsVERLET]);
+                    enumValueToString(CutoffScheme::Verlet));
         }
         warning(wi, message);
     }
@@ -1828,7 +1829,8 @@ int gmx_grompp(int argc, char* argv[])
     };
     std::vector<MoleculeInformation>     mi;
     std::unique_ptr<MoleculeInformation> intermolecular_interactions;
-    int                                  nvsite, comb;
+    int                                  nvsite;
+    CombinationRule                      comb;
     real                                 fudgeQQ;
     double                               reppow;
     const char*                          mdparin;
@@ -2015,22 +2017,23 @@ int gmx_grompp(int argc, char* argv[])
         }
     }
 
-    if ((count_constraints(&sys, mi, wi) != 0) && (ir->eConstrAlg == econtSHAKE))
+    if ((count_constraints(&sys, mi, wi) != 0) && (ir->eConstrAlg == ConstraintAlgorithm::Shake))
     {
-        if (ir->eI == eiCG || ir->eI == eiLBFGS)
+        if (ir->eI == IntegrationAlgorithm::CG || ir->eI == IntegrationAlgorithm::LBFGS)
         {
-            std::string warningMessage = gmx::formatString("Can not do %s with %s, use %s",
-                                                           EI(ir->eI),
-                                                           econstr_names[econtSHAKE],
-                                                           econstr_names[econtLINCS]);
+            std::string warningMessage =
+                    gmx::formatString("Can not do %s with %s, use %s",
+                                      enumValueToString(ir->eI),
+                                      enumValueToString(ConstraintAlgorithm::Shake),
+                                      enumValueToString(ConstraintAlgorithm::Lincs));
             warning_error(wi, warningMessage);
         }
         if (ir->bPeriodicMols)
         {
             std::string warningMessage =
                     gmx::formatString("Can not do periodic molecules with %s, use %s",
-                                      econstr_names[econtSHAKE],
-                                      econstr_names[econtLINCS]);
+                                      enumValueToString(ConstraintAlgorithm::Shake),
+                                      enumValueToString(ConstraintAlgorithm::Lincs));
             warning_error(wi, warningMessage);
         }
     }
@@ -2169,7 +2172,7 @@ int gmx_grompp(int argc, char* argv[])
 
     checkForUnboundAtoms(&sys, bVerbose, wi, logger);
 
-    if (EI_DYNAMICS(ir->eI) && ir->eI != eiBD)
+    if (EI_DYNAMICS(ir->eI) && ir->eI != IntegrationAlgorithm::BD)
     {
         check_bonds_timestep(&sys, ir->delta_t, wi);
     }
@@ -2194,7 +2197,7 @@ int gmx_grompp(int argc, char* argv[])
     }
     do_index(mdparin, ftp2fn_null(efNDX, NFILE, fnm), &sys, bVerbose, mdModules.notifier(), ir, wi);
 
-    if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0)
+    if (ir->cutoff_scheme == CutoffScheme::Verlet && ir->verletbuf_tol > 0)
     {
         if (EI_DYNAMICS(ir->eI) && inputrec2nboundeddim(ir) == 3)
         {
@@ -2293,7 +2296,7 @@ int gmx_grompp(int argc, char* argv[])
         pr_symtab(debug, 0, "After close", &sys.symtab);
     }
 
-    if (ir->eI == eiMimic)
+    if (ir->eI == IntegrationAlgorithm::Mimic)
     {
         generate_qmexcl(&sys, ir, logger);
     }
@@ -2354,10 +2357,10 @@ int gmx_grompp(int argc, char* argv[])
     /* MRS: eventually figure out better logic for initializing the fep
        values that makes declaring the lambda and declaring the state not
        potentially conflict if not handled correctly. */
-    if (ir->efep != efepNO)
+    if (ir->efep != FreeEnergyPerturbationType::No)
     {
         state.fep_state = ir->fepvals->init_fep_state;
-        for (i = 0; i < efptNR; i++)
+        for (i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
         {
             /* init_lambda trumps state definitions*/
             if (ir->fepvals->init_lambda >= 0)
@@ -2366,7 +2369,7 @@ int gmx_grompp(int argc, char* argv[])
             }
             else
             {
-                if (ir->fepvals->all_lambda[i] == nullptr)
+                if (ir->fepvals->all_lambda[i].empty())
                 {
                     gmx_fatal(FARGS, "Values of lambda not set for a free energy calculation!");
                 }
@@ -2382,7 +2385,12 @@ int gmx_grompp(int argc, char* argv[])
 
     if (ir->bPull)
     {
-        pull = set_pull_init(ir, &sys, state.x.rvec_array(), state.box, state.lambda[efptMASS], wi);
+        pull = set_pull_init(ir,
+                             &sys,
+                             state.x.rvec_array(),
+                             state.box,
+                             state.lambda[FreeEnergyPerturbationCouplingType::Mass],
+                             wi);
     }
 
     /* Modules that supply external potential for pull coordinates
@@ -2405,7 +2413,10 @@ int gmx_grompp(int argc, char* argv[])
                 ir->pbcType,
                 compressibility,
                 &ir->opts,
-                ir->efep != efepNO ? ir->fepvals->all_lambda[efptFEP][ir->fepvals->init_fep_state] : 0,
+                ir->efep != FreeEnergyPerturbationType::No
+                        ? ir->fepvals->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Fep)]
+                                                 [ir->fepvals->init_fep_state]
+                        : 0,
                 sys,
                 wi);
     }
@@ -2438,14 +2449,15 @@ int gmx_grompp(int argc, char* argv[])
          * charges. This will double the cost, but the optimal performance will
          * then probably be at a slightly larger cut-off and grid spacing.
          */
-        if ((ir->efep == efepNO && ratio > 1.0 / 2.0) || (ir->efep != efepNO && ratio > 2.0 / 3.0))
+        if ((ir->efep == FreeEnergyPerturbationType::No && ratio > 1.0 / 2.0)
+            || (ir->efep != FreeEnergyPerturbationType::No && ratio > 2.0 / 3.0))
         {
             warning_note(
                     wi,
                     "The optimal PME mesh load for parallel simulations is below 0.5\n"
                     "and for highly parallel simulations between 0.25 and 0.33,\n"
                     "for higher performance, increase the cut-off and the PME grid spacing.\n");
-            if (ir->efep != efepNO)
+            if (ir->efep != FreeEnergyPerturbationType::No)
             {
                 warning_note(wi,
                              "For free energy simulations, the optimal load limit increases from "
@@ -2479,7 +2491,7 @@ int gmx_grompp(int argc, char* argv[])
                 std::make_unique<gmx::KeyValueTreeObject>(internalParameterBuilder.build());
     }
 
-    if (ir->comm_mode != ecmNO)
+    if (ir->comm_mode != ComRemovalAlgorithm::No)
     {
         const int nstglobalcomm = computeGlobalCommunicationPeriod(ir);
         if (ir->nstcomm % nstglobalcomm != 0)
index 6595bff142eefec8798a74cefad4c2d81c450c9b..2276b84de2ece6a26ab28878eefa816d00017318 100644 (file)
@@ -37,6 +37,7 @@
  */
 #include "gmxpre.h"
 
+#include "gromacs/utility/enumerationhelpers.h"
 #include "readir.h"
 
 #include <cctype>
@@ -107,10 +108,10 @@ struct gmx_inputrec_strings
             energy[STRLEN], user1[STRLEN], user2[STRLEN], vcm[STRLEN], x_compressed_groups[STRLEN],
             couple_moltype[STRLEN], orirefitgrp[STRLEN], egptable[STRLEN], egpexcl[STRLEN],
             wall_atomtype[STRLEN], wall_density[STRLEN], deform[STRLEN], QMMM[STRLEN], imd_grp[STRLEN];
-    char                     fep_lambda[efptNR][STRLEN];
-    char                     lambda_weights[STRLEN];
-    std::vector<std::string> pullGroupNames;
-    std::vector<std::string> rotateGroupNames;
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, std::string> fep_lambda;
+    char                                                                   lambda_weights[STRLEN];
+    std::vector<std::string>                                               pullGroupNames;
+    std::vector<std::string>                                               rotateGroupNames;
     char anneal[STRLEN], anneal_npoints[STRLEN], anneal_time[STRLEN], anneal_temp[STRLEN];
 };
 
@@ -150,7 +151,7 @@ static const char* constraints[eshNR + 1] = { "none",     "h-bonds",    "all-bon
 
 static const char* couple_lam[ecouplamNR + 1] = { "vdw-q", "vdw", "q", "none", nullptr };
 
-static void GetSimTemps(int ntemps, t_simtemp* simtemp, double* temperature_lambdas)
+static void getSimTemps(int ntemps, t_simtemp* simtemp, gmx::ArrayRef<double> temperature_lambdas)
 {
 
     int i;
@@ -158,20 +159,20 @@ static void GetSimTemps(int ntemps, t_simtemp* simtemp, double* temperature_lamb
     for (i = 0; i < ntemps; i++)
     {
         /* simple linear scaling -- allows more control */
-        if (simtemp->eSimTempScale == esimtempLINEAR)
+        if (simtemp->eSimTempScale == SimulatedTempering::Linear)
         {
             simtemp->temperatures[i] =
                     simtemp->simtemp_low
                     + (simtemp->simtemp_high - simtemp->simtemp_low) * temperature_lambdas[i];
         }
         else if (simtemp->eSimTempScale
-                 == esimtempGEOMETRIC) /* should give roughly equal acceptance for constant heat capacity . . . */
+                 == SimulatedTempering::Geometric) /* should give roughly equal acceptance for constant heat capacity . . . */
         {
             simtemp->temperatures[i] = simtemp->simtemp_low
                                        * std::pow(simtemp->simtemp_high / simtemp->simtemp_low,
                                                   static_cast<real>((1.0 * i) / (ntemps - 1)));
         }
-        else if (simtemp->eSimTempScale == esimtempEXPONENTIAL)
+        else if (simtemp->eSimTempScale == SimulatedTempering::Exponential)
         {
             simtemp->temperatures[i] = simtemp->simtemp_low
                                        + (simtemp->simtemp_high - simtemp->simtemp_low)
@@ -180,7 +181,7 @@ static void GetSimTemps(int ntemps, t_simtemp* simtemp, double* temperature_lamb
         else
         {
             char errorstr[128];
-            sprintf(errorstr, "eSimTempScale=%d not defined", simtemp->eSimTempScale);
+            sprintf(errorstr, "eSimTempScale=%s not defined", enumValueToString(simtemp->eSimTempScale));
             gmx_fatal(FARGS, "%s", errorstr);
         }
     }
@@ -209,11 +210,11 @@ static void check_nst(const char* desc_nst, int nst, const char* desc_p, int* p,
 }
 
 //! Convert legacy mdp entries to modern ones.
-static void process_interaction_modifier(int* eintmod)
+static void process_interaction_modifier(InteractionModifiers* eintmod)
 {
-    if (*eintmod == eintmodPOTSHIFT_VERLET_UNSUPPORTED)
+    if (*eintmod == InteractionModifiers::PotShiftVerletUnsupported)
     {
-        *eintmod = eintmodPOTSHIFT;
+        *eintmod = InteractionModifiers::PotShift;
     }
 }
 
@@ -235,8 +236,8 @@ void check_ir(const char*                   mdparin,
     char        err_buf[256], warn_buf[STRLEN];
     int         i, j;
     real        dt_pcoupl;
-    t_lambda*   fep    = ir->fepvals;
-    t_expanded* expand = ir->expandedvals;
+    t_lambda*   fep    = ir->fepvals.get();
+    t_expanded* expand = ir->expandedvals.get();
 
     set_warning_line(wi, mdparin, -1);
 
@@ -253,10 +254,12 @@ void check_ir(const char*                   mdparin,
         }
     }
 
-    if (ir->coulombtype == eelRF_NEC_UNSUPPORTED)
+    if (ir->coulombtype == CoulombInteractionType::RFNecUnsupported)
     {
-        sprintf(warn_buf, "%s electrostatics is no longer supported", eel_names[eelRF_NEC_UNSUPPORTED]);
-        warning_error(wi, warn_buf);
+        std::string message =
+                gmx::formatString("%s electrostatics is no longer supported",
+                                  enumValueToString(CoulombInteractionType::RFNecUnsupported));
+        warning_error(wi, message);
     }
 
     /* BASIC CUT-OFF STUFF */
@@ -268,7 +271,7 @@ void check_ir(const char*                   mdparin,
     {
         warning_error(wi, "rvdw should be >= 0");
     }
-    if (ir->rlist < 0 && !(ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0))
+    if (ir->rlist < 0 && !(ir->cutoff_scheme == CutoffScheme::Verlet && ir->verletbuf_tol > 0))
     {
         warning_error(wi, "rlist should be >= 0");
     }
@@ -281,13 +284,13 @@ void check_ir(const char*                   mdparin,
     process_interaction_modifier(&ir->coulomb_modifier);
     process_interaction_modifier(&ir->vdw_modifier);
 
-    if (ir->cutoff_scheme == ecutsGROUP)
+    if (ir->cutoff_scheme == CutoffScheme::Group)
     {
         gmx_fatal(FARGS,
                   "The group cutoff scheme has been removed since GROMACS 2020. "
                   "Please use the Verlet cutoff scheme.");
     }
-    if (ir->cutoff_scheme == ecutsVERLET)
+    if (ir->cutoff_scheme == CutoffScheme::Verlet)
     {
         real rc_max;
 
@@ -302,8 +305,9 @@ void check_ir(const char*                   mdparin,
         {
             // Since we have PME coulomb + LJ cut-off kernels with rcoulomb>rvdw
             // for PME load balancing, we can support this exception.
-            bool bUsesPmeTwinRangeKernel = (EEL_PME_EWALD(ir->coulombtype) && ir->vdwtype == evdwCUT
-                                            && ir->rcoulomb > ir->rvdw);
+            bool bUsesPmeTwinRangeKernel =
+                    (EEL_PME_EWALD(ir->coulombtype) && ir->vdwtype == VanDerWaalsType::Cut
+                     && ir->rcoulomb > ir->rvdw);
             if (!bUsesPmeTwinRangeKernel)
             {
                 warning_error(wi,
@@ -312,47 +316,51 @@ void check_ir(const char*                   mdparin,
             }
         }
 
-        if (ir->vdwtype == evdwSHIFT || ir->vdwtype == evdwSWITCH)
+        if (ir->vdwtype == VanDerWaalsType::Shift || ir->vdwtype == VanDerWaalsType::Switch)
         {
-            if (ir->vdw_modifier == eintmodNONE || ir->vdw_modifier == eintmodPOTSHIFT)
+            if (ir->vdw_modifier == InteractionModifiers::None
+                || ir->vdw_modifier == InteractionModifiers::PotShift)
             {
-                ir->vdw_modifier = (ir->vdwtype == evdwSHIFT ? eintmodFORCESWITCH : eintmodPOTSWITCH);
+                ir->vdw_modifier =
+                        (ir->vdwtype == VanDerWaalsType::Shift ? InteractionModifiers::ForceSwitch
+                                                               : InteractionModifiers::PotSwitch);
 
                 sprintf(warn_buf,
                         "Replacing vdwtype=%s by the equivalent combination of vdwtype=%s and "
                         "vdw_modifier=%s",
-                        evdw_names[ir->vdwtype],
-                        evdw_names[evdwCUT],
-                        eintmod_names[ir->vdw_modifier]);
+                        enumValueToString(ir->vdwtype),
+                        enumValueToString(VanDerWaalsType::Cut),
+                        enumValueToString(ir->vdw_modifier));
                 warning_note(wi, warn_buf);
 
-                ir->vdwtype = evdwCUT;
+                ir->vdwtype = VanDerWaalsType::Cut;
             }
             else
             {
                 sprintf(warn_buf,
                         "Unsupported combination of vdwtype=%s and vdw_modifier=%s",
-                        evdw_names[ir->vdwtype],
-                        eintmod_names[ir->vdw_modifier]);
+                        enumValueToString(ir->vdwtype),
+                        enumValueToString(ir->vdw_modifier));
                 warning_error(wi, warn_buf);
             }
         }
 
-        if (!(ir->vdwtype == evdwCUT || ir->vdwtype == evdwPME))
+        if (!(ir->vdwtype == VanDerWaalsType::Cut || ir->vdwtype == VanDerWaalsType::Pme))
         {
             warning_error(wi,
                           "With Verlet lists only cut-off and PME LJ interactions are supported");
         }
-        if (!(ir->coulombtype == eelCUT || EEL_RF(ir->coulombtype) || EEL_PME(ir->coulombtype)
-              || ir->coulombtype == eelEWALD))
+        if (!(ir->coulombtype == CoulombInteractionType::Cut || EEL_RF(ir->coulombtype)
+              || EEL_PME(ir->coulombtype) || ir->coulombtype == CoulombInteractionType::Ewald))
         {
             warning_error(wi,
                           "With Verlet lists only cut-off, reaction-field, PME and Ewald "
                           "electrostatics are supported");
         }
-        if (!(ir->coulomb_modifier == eintmodNONE || ir->coulomb_modifier == eintmodPOTSHIFT))
+        if (!(ir->coulomb_modifier == InteractionModifiers::None
+              || ir->coulomb_modifier == InteractionModifiers::PotShift))
         {
-            sprintf(warn_buf, "coulomb_modifier=%s is not supported", eintmod_names[ir->coulomb_modifier]);
+            sprintf(warn_buf, "coulomb_modifier=%s is not supported", enumValueToString(ir->coulomb_modifier));
             warning_error(wi, warn_buf);
         }
 
@@ -360,7 +368,7 @@ void check_ir(const char*                   mdparin,
         {
             sprintf(warn_buf,
                     "Coulomb type %s is not supported with the verlet scheme",
-                    eel_names[ir->coulombtype]);
+                    enumValueToString(ir->coulombtype));
             warning_error(wi, warn_buf);
         }
 
@@ -459,8 +467,8 @@ void check_ir(const char*                   mdparin,
                         "implicitly. See the documentation for more information on which "
                         "parameters affect temperature for %s.",
                         enumValueToString(ir->etc),
-                        ei_names[ir->eI],
-                        ei_names[ir->eI]);
+                        enumValueToString(ir->eI),
+                        enumValueToString(ir->eI));
             }
             else
             {
@@ -468,20 +476,20 @@ void check_ir(const char*                   mdparin,
                         "Setting tcoupl from '%s' to 'no'. Temperature coupling does not apply to "
                         "%s.",
                         enumValueToString(ir->etc),
-                        ei_names[ir->eI]);
+                        enumValueToString(ir->eI));
             }
             warning_note(wi, warn_buf);
         }
         ir->etc = TemperatureCoupling::No;
     }
-    if (ir->eI == eiVVAK)
+    if (ir->eI == IntegrationAlgorithm::VVAK)
     {
         sprintf(warn_buf,
                 "Integrator method %s is implemented primarily for validation purposes; for "
                 "molecular dynamics, you should probably be using %s or %s",
-                ei_names[eiVVAK],
-                ei_names[eiMD],
-                ei_names[eiVV]);
+                enumValueToString(IntegrationAlgorithm::VVAK),
+                enumValueToString(IntegrationAlgorithm::MD),
+                enumValueToString(IntegrationAlgorithm::VV));
         warning_note(wi, warn_buf);
     }
     if (!EI_DYNAMICS(ir->eI))
@@ -491,7 +499,7 @@ void check_ir(const char*                   mdparin,
             sprintf(warn_buf,
                     "Setting pcoupl from '%s' to 'no'. Pressure coupling does not apply to %s.",
                     enumValueToString(ir->epc),
-                    ei_names[ir->eI]);
+                    enumValueToString(ir->eI));
             warning_note(wi, warn_buf);
         }
         ir->epc = PressureCoupling::No;
@@ -517,7 +525,7 @@ void check_ir(const char*                   mdparin,
             }
         }
         else if ((ir->nstenergy > 0 && ir->nstcalcenergy > ir->nstenergy)
-                 || (ir->efep != efepNO && ir->fepvals->nstdhdl > 0
+                 || (ir->efep != FreeEnergyPerturbationType::No && ir->fepvals->nstdhdl > 0
                      && (ir->nstcalcenergy > ir->fepvals->nstdhdl)))
 
         {
@@ -527,7 +535,7 @@ void check_ir(const char*                   mdparin,
             int         min_nst  = ir->nstenergy;
 
             /* find the smallest of ( nstenergy, nstdhdl ) */
-            if (ir->efep != efepNO && ir->fepvals->nstdhdl > 0
+            if (ir->efep != FreeEnergyPerturbationType::No && ir->fepvals->nstdhdl > 0
                 && (ir->nstenergy == 0 || ir->fepvals->nstdhdl < ir->nstenergy))
             {
                 min_nst  = ir->fepvals->nstdhdl;
@@ -555,7 +563,7 @@ void check_ir(const char*                   mdparin,
 
         if (ir->nstcalcenergy > 0)
         {
-            if (ir->efep != efepNO)
+            if (ir->efep != FreeEnergyPerturbationType::No)
             {
                 /* nstdhdl should be a multiple of nstcalcenergy */
                 check_nst("nstcalcenergy", ir->nstcalcenergy, "nstdhdl", &ir->fepvals->nstdhdl, wi);
@@ -592,7 +600,7 @@ void check_ir(const char*                   mdparin,
     }
 
     /* LD STUFF */
-    if ((EI_SD(ir->eI) || ir->eI == eiBD) && ir->bContinuation && ir->ld_seed != -1)
+    if ((EI_SD(ir->eI) || ir->eI == IntegrationAlgorithm::BD) && ir->bContinuation && ir->ld_seed != -1)
     {
         warning_note(wi,
                      "You are doing a continuation with SD or BD, make sure that ld_seed is "
@@ -617,7 +625,7 @@ void check_ir(const char*                   mdparin,
         warning(wi, warn_buf);
     }
 
-    if ((EI_SD(ir->eI) || ir->eI == eiBD) && ir->bContinuation && ir->ld_seed != -1)
+    if ((EI_SD(ir->eI) || ir->eI == IntegrationAlgorithm::BD) && ir->bContinuation && ir->ld_seed != -1)
     {
         warning_note(wi,
                      "You are doing a continuation with SD or BD, make sure that ld_seed is "
@@ -633,10 +641,12 @@ void check_ir(const char*                   mdparin,
             sprintf(err_buf,
                     "Entry %d for %s must be between 0 and 1, instead is %g",
                     i,
-                    efpt_names[efptTEMPERATURE],
-                    fep->all_lambda[efptTEMPERATURE][i]);
-            CHECK((fep->all_lambda[efptTEMPERATURE][i] < 0) || (fep->all_lambda[efptTEMPERATURE][i] > 1));
-            if (fep->all_lambda[efptTEMPERATURE][i] > 0)
+                    enumValueToString(FreeEnergyPerturbationCouplingType::Temperature),
+                    fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Temperature)][i]);
+            CHECK((fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Temperature)][i] < 0)
+                  || (fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Temperature)][i]
+                      > 1));
+            if (fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Temperature)][i] > 0)
             {
                 bAllTempZero = FALSE;
             }
@@ -645,7 +655,7 @@ void check_ir(const char*                   mdparin,
         CHECK(bAllTempZero == TRUE);
 
         sprintf(err_buf, "Simulated tempering is currently only compatible with md-vv");
-        CHECK(ir->eI != eiVV);
+        CHECK(ir->eI != IntegrationAlgorithm::VV);
 
         /* check compatability of the temperature coupling with simulated tempering */
 
@@ -680,9 +690,9 @@ void check_ir(const char*                   mdparin,
 
     /* verify free energy options */
 
-    if (ir->efep != efepNO)
+    if (ir->efep != FreeEnergyPerturbationType::No)
     {
-        fep = ir->fepvals;
+        fep = ir->fepvals.get();
         sprintf(err_buf, "The soft-core power is %d and can only be 1 or 2", fep->sc_power);
         CHECK(fep->sc_alpha != 0 && fep->sc_power != 1 && fep->sc_power != 2);
 
@@ -701,13 +711,13 @@ void check_ir(const char*                   mdparin,
         sprintf(err_buf,
                 "Can't use positive delta-lambda (%g) with expanded ensemble simulations",
                 fep->delta_lambda);
-        CHECK(fep->delta_lambda > 0 && (ir->efep == efepEXPANDED));
+        CHECK(fep->delta_lambda > 0 && (ir->efep == FreeEnergyPerturbationType::Expanded));
 
         sprintf(err_buf, "Can only use expanded ensemble with md-vv (for now)");
-        CHECK(!(EI_VV(ir->eI)) && (ir->efep == efepEXPANDED));
+        CHECK(!(EI_VV(ir->eI)) && (ir->efep == FreeEnergyPerturbationType::Expanded));
 
         sprintf(err_buf, "Free-energy not implemented for Ewald");
-        CHECK(ir->coulombtype == eelEWALD);
+        CHECK(ir->coulombtype == CoulombInteractionType::Ewald);
 
         /* check validty of lambda inputs */
         if (fep->n_lambda == 0)
@@ -741,7 +751,7 @@ void check_ir(const char*                   mdparin,
         {
             int n_lambda_terms;
             n_lambda_terms = 0;
-            for (i = 0; i < efptNR; i++)
+            for (i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
             {
                 if (fep->separate_dvdl[i])
                 {
@@ -765,14 +775,15 @@ void check_ir(const char*                   mdparin,
             }
         }
 
-        for (j = 0; j < efptNR; j++)
+        for (j = 0; j < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); j++)
         {
             for (i = 0; i < fep->n_lambda; i++)
             {
+                auto enumValue = static_cast<FreeEnergyPerturbationCouplingType>(j);
                 sprintf(err_buf,
                         "Entry %d for %s must be between 0 and 1, instead is %g",
                         i,
-                        efpt_names[j],
+                        enumValueToString(enumValue),
                         fep->all_lambda[j][i]);
                 CHECK((fep->all_lambda[j][i] < 0) || (fep->all_lambda[j][i] > 1));
             }
@@ -787,11 +798,14 @@ void check_ir(const char*                   mdparin,
                         "coul-lambdas (%f) is nonzero without coulomb softcore: this will lead to "
                         "crashes, and is not supported.",
                         i,
-                        fep->all_lambda[efptVDW][i],
-                        fep->all_lambda[efptCOUL][i]);
+                        fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)][i],
+                        fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)][i]);
                 CHECK((fep->sc_alpha > 0)
-                      && (((fep->all_lambda[efptCOUL][i] > 0.0) && (fep->all_lambda[efptCOUL][i] < 1.0))
-                          && ((fep->all_lambda[efptVDW][i] > 0.0) && (fep->all_lambda[efptVDW][i] < 1.0))));
+                      && (((fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)][i] > 0.0)
+                           && (fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)][i] < 1.0))
+                          && ((fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)][i] > 0.0)
+                              && (fep->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)][i]
+                                  < 1.0))));
             }
         }
 
@@ -821,19 +835,20 @@ void check_ir(const char*                   mdparin,
         /*  Free Energy Checks -- In an ideal world, slow growth and FEP would
             be treated differently, but that's the next step */
 
-        for (i = 0; i < efptNR; i++)
+        for (i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
         {
+            auto enumValue = static_cast<FreeEnergyPerturbationCouplingType>(i);
             for (j = 0; j < fep->n_lambda; j++)
             {
-                sprintf(err_buf, "%s[%d] must be between 0 and 1", efpt_names[i], j);
+                sprintf(err_buf, "%s[%d] must be between 0 and 1", enumValueToString(enumValue), j);
                 CHECK((fep->all_lambda[i][j] < 0) || (fep->all_lambda[i][j] > 1));
             }
         }
     }
 
-    if ((ir->bSimTemp) || (ir->efep == efepEXPANDED))
+    if ((ir->bSimTemp) || (ir->efep == FreeEnergyPerturbationType::Expanded))
     {
-        fep = ir->fepvals;
+        fep = ir->fepvals.get();
 
         /* checking equilibration of weights inputs for validity */
 
@@ -841,72 +856,75 @@ void check_ir(const char*                   mdparin,
                 "weight-equil-number-all-lambda (%d) is ignored if lmc-weights-equil is not equal "
                 "to %s",
                 expand->equil_n_at_lam,
-                elmceq_names[elmceqNUMATLAM]);
-        CHECK((expand->equil_n_at_lam > 0) && (expand->elmceq != elmceqNUMATLAM));
+                enumValueToString(LambdaWeightWillReachEquilibrium::NumAtLambda));
+        CHECK((expand->equil_n_at_lam > 0)
+              && (expand->elmceq != LambdaWeightWillReachEquilibrium::NumAtLambda));
 
         sprintf(err_buf,
                 "weight-equil-number-samples (%d) is ignored if lmc-weights-equil is not equal to "
                 "%s",
                 expand->equil_samples,
-                elmceq_names[elmceqSAMPLES]);
-        CHECK((expand->equil_samples > 0) && (expand->elmceq != elmceqSAMPLES));
+                enumValueToString(LambdaWeightWillReachEquilibrium::Samples));
+        CHECK((expand->equil_samples > 0) && (expand->elmceq != LambdaWeightWillReachEquilibrium::Samples));
 
         sprintf(err_buf,
                 "weight-equil-number-steps (%d) is ignored if lmc-weights-equil is not equal to %s",
                 expand->equil_steps,
-                elmceq_names[elmceqSTEPS]);
-        CHECK((expand->equil_steps > 0) && (expand->elmceq != elmceqSTEPS));
+                enumValueToString(LambdaWeightWillReachEquilibrium::Steps));
+        CHECK((expand->equil_steps > 0) && (expand->elmceq != LambdaWeightWillReachEquilibrium::Steps));
 
         sprintf(err_buf,
                 "weight-equil-wl-delta (%d) is ignored if lmc-weights-equil is not equal to %s",
                 expand->equil_samples,
-                elmceq_names[elmceqWLDELTA]);
-        CHECK((expand->equil_wl_delta > 0) && (expand->elmceq != elmceqWLDELTA));
+                enumValueToString(LambdaWeightWillReachEquilibrium::WLDelta));
+        CHECK((expand->equil_wl_delta > 0) && (expand->elmceq != LambdaWeightWillReachEquilibrium::WLDelta));
 
         sprintf(err_buf,
                 "weight-equil-count-ratio (%f) is ignored if lmc-weights-equil is not equal to %s",
                 expand->equil_ratio,
-                elmceq_names[elmceqRATIO]);
-        CHECK((expand->equil_ratio > 0) && (expand->elmceq != elmceqRATIO));
+                enumValueToString(LambdaWeightWillReachEquilibrium::Ratio));
+        CHECK((expand->equil_ratio > 0) && (expand->elmceq != LambdaWeightWillReachEquilibrium::Ratio));
 
         sprintf(err_buf,
                 "weight-equil-number-all-lambda (%d) must be a positive integer if "
                 "lmc-weights-equil=%s",
                 expand->equil_n_at_lam,
-                elmceq_names[elmceqNUMATLAM]);
-        CHECK((expand->equil_n_at_lam <= 0) && (expand->elmceq == elmceqNUMATLAM));
+                enumValueToString(LambdaWeightWillReachEquilibrium::NumAtLambda));
+        CHECK((expand->equil_n_at_lam <= 0)
+              && (expand->elmceq == LambdaWeightWillReachEquilibrium::NumAtLambda));
 
         sprintf(err_buf,
                 "weight-equil-number-samples (%d) must be a positive integer if "
                 "lmc-weights-equil=%s",
                 expand->equil_samples,
-                elmceq_names[elmceqSAMPLES]);
-        CHECK((expand->equil_samples <= 0) && (expand->elmceq == elmceqSAMPLES));
+                enumValueToString(LambdaWeightWillReachEquilibrium::Samples));
+        CHECK((expand->equil_samples <= 0) && (expand->elmceq == LambdaWeightWillReachEquilibrium::Samples));
 
         sprintf(err_buf,
                 "weight-equil-number-steps (%d) must be a positive integer if lmc-weights-equil=%s",
                 expand->equil_steps,
-                elmceq_names[elmceqSTEPS]);
-        CHECK((expand->equil_steps <= 0) && (expand->elmceq == elmceqSTEPS));
+                enumValueToString(LambdaWeightWillReachEquilibrium::Steps));
+        CHECK((expand->equil_steps <= 0) && (expand->elmceq == LambdaWeightWillReachEquilibrium::Steps));
 
         sprintf(err_buf,
                 "weight-equil-wl-delta (%f) must be > 0 if lmc-weights-equil=%s",
                 expand->equil_wl_delta,
-                elmceq_names[elmceqWLDELTA]);
-        CHECK((expand->equil_wl_delta <= 0) && (expand->elmceq == elmceqWLDELTA));
+                enumValueToString(LambdaWeightWillReachEquilibrium::WLDelta));
+        CHECK((expand->equil_wl_delta <= 0)
+              && (expand->elmceq == LambdaWeightWillReachEquilibrium::WLDelta));
 
         sprintf(err_buf,
                 "weight-equil-count-ratio (%f) must be > 0 if lmc-weights-equil=%s",
                 expand->equil_ratio,
-                elmceq_names[elmceqRATIO]);
-        CHECK((expand->equil_ratio <= 0) && (expand->elmceq == elmceqRATIO));
+                enumValueToString(LambdaWeightWillReachEquilibrium::Ratio));
+        CHECK((expand->equil_ratio <= 0) && (expand->elmceq == LambdaWeightWillReachEquilibrium::Ratio));
 
         sprintf(err_buf,
                 "lmc-weights-equil=%s only possible when lmc-stats = %s or lmc-stats %s",
-                elmceq_names[elmceqWLDELTA],
-                elamstats_names[elamstatsWL],
-                elamstats_names[elamstatsWWL]);
-        CHECK((expand->elmceq == elmceqWLDELTA) && (!EWL(expand->elamstats)));
+                enumValueToString(LambdaWeightWillReachEquilibrium::WLDelta),
+                enumValueToString(LambdaWeightCalculation::WL),
+                enumValueToString(LambdaWeightCalculation::WWL));
+        CHECK((expand->elmceq == LambdaWeightWillReachEquilibrium::WLDelta) && (!EWL(expand->elamstats)));
 
         sprintf(err_buf, "lmc-repeats (%d) must be greater than 0", expand->lmc_repeats);
         CHECK((expand->lmc_repeats <= 0));
@@ -920,7 +938,7 @@ void check_ir(const char*                   mdparin,
                 fep->init_fep_state,
                 expand->lmc_forced_nstart);
         CHECK((fep->init_fep_state != 0) && (expand->lmc_forced_nstart > 0)
-              && (expand->elmcmove != elmcmoveNO));
+              && (expand->elmcmove != LambdaMoveCalculation::No));
         sprintf(err_buf, "lmc-forced-nstart (%d) must not be negative", expand->lmc_forced_nstart);
         CHECK((expand->lmc_forced_nstart < 0));
         sprintf(err_buf,
@@ -936,8 +954,8 @@ void check_ir(const char*                   mdparin,
         CHECK((expand->wl_scale <= 0) || (expand->wl_scale >= 1));
 
         /* if there is no temperature control, we need to specify an MC temperature */
-        if (!integratorHasReferenceTemperature(ir) && (expand->elmcmove != elmcmoveNO)
-            && (expand->mc_temp <= 0.0))
+        if (!integratorHasReferenceTemperature(ir)
+            && (expand->elmcmove != LambdaMoveCalculation::No) && (expand->mc_temp <= 0.0))
         {
             sprintf(err_buf,
                     "If there is no temperature control, and lmc-mcmove!='no', mc_temp must be set "
@@ -988,7 +1006,7 @@ void check_ir(const char*                   mdparin,
         sprintf(err_buf,
                 "Can not have dispersion correction with pbc=%s",
                 c_pbcTypeNames[ir->pbcType].c_str());
-        CHECK(ir->eDispCorr != edispcNO);
+        CHECK(ir->eDispCorr != DispersionCorrectionType::No);
     }
 
     if (ir->rlist == 0.0)
@@ -998,10 +1016,11 @@ void check_ir(const char*                   mdparin,
                 "with coulombtype = %s or coulombtype = %s\n"
                 "without periodic boundary conditions (pbc = %s) and\n"
                 "rcoulomb and rvdw set to zero",
-                eel_names[eelCUT],
-                eel_names[eelUSER],
+                enumValueToString(CoulombInteractionType::Cut),
+                enumValueToString(CoulombInteractionType::User),
                 c_pbcTypeNames[PbcType::No].c_str());
-        CHECK(((ir->coulombtype != eelCUT) && (ir->coulombtype != eelUSER))
+        CHECK(((ir->coulombtype != CoulombInteractionType::Cut)
+               && (ir->coulombtype != CoulombInteractionType::User))
               || (ir->pbcType != PbcType::No) || (ir->rcoulomb != 0.0) || (ir->rvdw != 0.0));
 
         if (ir->nstlist > 0)
@@ -1017,9 +1036,9 @@ void check_ir(const char*                   mdparin,
     {
         // TODO Change this behaviour. There should be exactly one way
         // to turn off an algorithm.
-        ir->comm_mode = ecmNO;
+        ir->comm_mode = ComRemovalAlgorithm::No;
     }
-    if (ir->comm_mode != ecmNO)
+    if (ir->comm_mode != ComRemovalAlgorithm::No)
     {
         if (ir->nstcomm < 0)
         {
@@ -1042,7 +1061,7 @@ void check_ir(const char*                   mdparin,
             ir->nstcomm = ir->nstcalcenergy;
         }
 
-        if (ir->comm_mode == ecmANGULAR)
+        if (ir->comm_mode == ComRemovalAlgorithm::Angular)
         {
             sprintf(err_buf,
                     "Can not remove the rotation around the center of mass with periodic "
@@ -1058,13 +1077,14 @@ void check_ir(const char*                   mdparin,
         }
     }
 
-    if (EI_STATE_VELOCITY(ir->eI) && !EI_SD(ir->eI) && ir->pbcType == PbcType::No && ir->comm_mode != ecmANGULAR)
+    if (EI_STATE_VELOCITY(ir->eI) && !EI_SD(ir->eI) && ir->pbcType == PbcType::No
+        && ir->comm_mode != ComRemovalAlgorithm::Angular)
     {
         sprintf(warn_buf,
                 "Tumbling and flying ice-cubes: We are not removing rotation around center of mass "
                 "in a non-periodic system. You should probably set comm_mode = ANGULAR or use "
                 "integrator = %s.",
-                ei_names[eiSD1]);
+                enumValueToString(IntegrationAlgorithm::SD1));
         warning_note(wi, warn_buf);
     }
 
@@ -1102,12 +1122,12 @@ void check_ir(const char*                   mdparin,
         ir->opts.nhchainlength = 0;
     }
 
-    if (ir->eI == eiVVAK)
+    if (ir->eI == IntegrationAlgorithm::VVAK)
     {
         sprintf(err_buf,
                 "%s implemented primarily for validation, and requires nsttcouple = 1 and "
                 "nstpcouple = 1.",
-                ei_names[eiVVAK]);
+                enumValueToString(IntegrationAlgorithm::VVAK));
         CHECK((ir->nsttcouple != 1) || (ir->nstpcouple != 1));
     }
 
@@ -1116,7 +1136,7 @@ void check_ir(const char*                   mdparin,
         sprintf(err_buf,
                 "%s temperature control not supported for integrator %s.",
                 enumValueToString(ir->etc),
-                ei_names[ir->eI]);
+                enumValueToString(ir->eI));
         CHECK(!(EI_VV(ir->eI)));
 
         if (ir->nstcomm > 0 && (ir->etc == TemperatureCoupling::Andersen))
@@ -1218,13 +1238,13 @@ void check_ir(const char*                   mdparin,
     /* ELECTROSTATICS */
     /* More checks are in triple check (grompp.c) */
 
-    if (ir->coulombtype == eelSWITCH)
+    if (ir->coulombtype == CoulombInteractionType::Switch)
     {
         sprintf(warn_buf,
                 "coulombtype = %s is only for testing purposes and can lead to serious "
                 "artifacts, advice: use coulombtype = %s",
-                eel_names[ir->coulombtype],
-                eel_names[eelRF_ZERO]);
+                enumValueToString(ir->coulombtype),
+                enumValueToString(CoulombInteractionType::RFZero));
         warning(wi, warn_buf);
     }
 
@@ -1259,11 +1279,11 @@ void check_ir(const char*                   mdparin,
     {
         /* reaction field (at the cut-off) */
 
-        if (ir->coulombtype == eelRF_ZERO && ir->epsilon_rf != 0)
+        if (ir->coulombtype == CoulombInteractionType::RFZero && ir->epsilon_rf != 0)
         {
             sprintf(warn_buf,
                     "With coulombtype = %s, epsilon-rf must be 0, assuming you meant epsilon_rf=0",
-                    eel_names[ir->coulombtype]);
+                    enumValueToString(ir->coulombtype));
             warning(wi, warn_buf);
             ir->epsilon_rf = 0.0;
         }
@@ -1274,7 +1294,7 @@ void check_ir(const char*                   mdparin,
         {
             sprintf(warn_buf,
                     "Using epsilon-rf = epsilon-r with %s does not make sense",
-                    eel_names[ir->coulombtype]);
+                    enumValueToString(ir->coulombtype));
             warning(wi, warn_buf);
         }
     }
@@ -1289,28 +1309,28 @@ void check_ir(const char*                   mdparin,
             sprintf(err_buf,
                     "With coulombtype = %s rcoulomb_switch must be < rcoulomb. Or, better: Use the "
                     "potential modifier options!",
-                    eel_names[ir->coulombtype]);
+                    enumValueToString(ir->coulombtype));
             CHECK(ir->rcoulomb_switch >= ir->rcoulomb);
         }
     }
 
-    if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT)
+    if (ir->coulombtype == CoulombInteractionType::Switch || ir->coulombtype == CoulombInteractionType::Shift)
     {
         sprintf(err_buf,
                 "Explicit switch/shift coulomb interactions cannot be used in combination with a "
                 "secondary coulomb-modifier.");
-        CHECK(ir->coulomb_modifier != eintmodNONE);
+        CHECK(ir->coulomb_modifier != InteractionModifiers::None);
     }
-    if (ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT)
+    if (ir->vdwtype == VanDerWaalsType::Switch || ir->vdwtype == VanDerWaalsType::Shift)
     {
         sprintf(err_buf,
                 "Explicit switch/shift vdw interactions cannot be used in combination with a "
                 "secondary vdw-modifier.");
-        CHECK(ir->vdw_modifier != eintmodNONE);
+        CHECK(ir->vdw_modifier != InteractionModifiers::None);
     }
 
-    if (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT || ir->vdwtype == evdwSWITCH
-        || ir->vdwtype == evdwSHIFT)
+    if (ir->coulombtype == CoulombInteractionType::Switch || ir->coulombtype == CoulombInteractionType::Shift
+        || ir->vdwtype == VanDerWaalsType::Switch || ir->vdwtype == VanDerWaalsType::Shift)
     {
         sprintf(warn_buf,
                 "The switch/shift interaction settings are just for compatibility; you will get "
@@ -1319,7 +1339,8 @@ void check_ir(const char*                   mdparin,
         warning_note(wi, warn_buf);
     }
 
-    if (ir->coulombtype == eelPMESWITCH || ir->coulomb_modifier == eintmodPOTSWITCH)
+    if (ir->coulombtype == CoulombInteractionType::PmeSwitch
+        || ir->coulomb_modifier == InteractionModifiers::PotSwitch)
     {
         if (ir->rcoulomb_switch / ir->rcoulomb < 0.9499)
         {
@@ -1336,7 +1357,7 @@ void check_ir(const char*                   mdparin,
         }
     }
 
-    if (ir->vdwtype == evdwSWITCH || ir->vdw_modifier == eintmodPOTSWITCH)
+    if (ir->vdwtype == VanDerWaalsType::Switch || ir->vdw_modifier == InteractionModifiers::PotSwitch)
     {
         if (ir->rvdw_switch == 0)
         {
@@ -1351,10 +1372,13 @@ void check_ir(const char*                   mdparin,
 
     if (EEL_FULL(ir->coulombtype))
     {
-        if (ir->coulombtype == eelPMESWITCH || ir->coulombtype == eelPMEUSER
-            || ir->coulombtype == eelPMEUSERSWITCH)
+        if (ir->coulombtype == CoulombInteractionType::PmeSwitch
+            || ir->coulombtype == CoulombInteractionType::PmeUser
+            || ir->coulombtype == CoulombInteractionType::PmeUserSwitch)
         {
-            sprintf(err_buf, "With coulombtype = %s, rcoulomb must be <= rlist", eel_names[ir->coulombtype]);
+            sprintf(err_buf,
+                    "With coulombtype = %s, rcoulomb must be <= rlist",
+                    enumValueToString(ir->coulombtype));
             CHECK(ir->rcoulomb > ir->rlist);
         }
     }
@@ -1363,13 +1387,13 @@ void check_ir(const char*                   mdparin,
     {
         // TODO: Move these checks into the ewald module with the options class
         int orderMin = 3;
-        int orderMax = (ir->coulombtype == eelP3M_AD ? 8 : 12);
+        int orderMax = (ir->coulombtype == CoulombInteractionType::P3mAD ? 8 : 12);
 
         if (ir->pme_order < orderMin || ir->pme_order > orderMax)
         {
             sprintf(warn_buf,
                     "With coulombtype = %s, you should have %d <= pme-order <= %d",
-                    eel_names[ir->coulombtype],
+                    enumValueToString(ir->coulombtype),
                     orderMin,
                     orderMax);
             warning_error(wi, warn_buf);
@@ -1378,24 +1402,25 @@ void check_ir(const char*                   mdparin,
 
     if (ir->nwall == 2 && EEL_FULL(ir->coulombtype))
     {
-        if (ir->ewald_geometry == eewg3D)
+        if (ir->ewald_geometry == EwaldGeometry::ThreeD)
         {
             sprintf(warn_buf,
                     "With pbc=%s you should use ewald-geometry=%s",
                     c_pbcTypeNames[ir->pbcType].c_str(),
-                    eewg_names[eewg3DC]);
+                    enumValueToString(EwaldGeometry::ThreeDC));
             warning(wi, warn_buf);
         }
         /* This check avoids extra pbc coding for exclusion corrections */
         sprintf(err_buf, "wall-ewald-zfac should be >= 2");
         CHECK(ir->wall_ewald_zfac < 2);
     }
-    if ((ir->ewald_geometry == eewg3DC) && (ir->pbcType != PbcType::XY) && EEL_FULL(ir->coulombtype))
+    if ((ir->ewald_geometry == EwaldGeometry::ThreeDC) && (ir->pbcType != PbcType::XY)
+        && EEL_FULL(ir->coulombtype))
     {
         sprintf(warn_buf,
                 "With %s and ewald_geometry = %s you should use pbc = %s",
-                eel_names[ir->coulombtype],
-                eewg_names[eewg3DC],
+                enumValueToString(ir->coulombtype),
+                enumValueToString(EwaldGeometry::ThreeDC),
                 c_pbcTypeNames[PbcType::XY].c_str());
         warning(wi, warn_buf);
     }
@@ -1429,20 +1454,21 @@ void check_ir(const char*                   mdparin,
         }
     }
 
-    if (ir->vdwtype == evdwPME)
+    if (ir->vdwtype == VanDerWaalsType::Pme)
     {
-        if (!(ir->vdw_modifier == eintmodNONE || ir->vdw_modifier == eintmodPOTSHIFT))
+        if (!(ir->vdw_modifier == InteractionModifiers::None
+              || ir->vdw_modifier == InteractionModifiers::PotShift))
         {
             sprintf(err_buf,
                     "With vdwtype = %s, the only supported modifiers are %s and %s",
-                    evdw_names[ir->vdwtype],
-                    eintmod_names[eintmodPOTSHIFT],
-                    eintmod_names[eintmodNONE]);
+                    enumValueToString(ir->vdwtype),
+                    enumValueToString(InteractionModifiers::PotShift),
+                    enumValueToString(InteractionModifiers::None));
             warning_error(wi, err_buf);
         }
     }
 
-    if (ir->vdwtype == evdwUSER && ir->eDispCorr != edispcNO)
+    if (ir->vdwtype == VanDerWaalsType::User && ir->eDispCorr != DispersionCorrectionType::No)
     {
         warning_note(wi,
                      "You have selected user tables with dispersion correction, the dispersion "
@@ -1451,20 +1477,22 @@ void check_ir(const char*                   mdparin,
                      "really want dispersion correction to -C6/r^6.");
     }
 
-    if (ir->eI == eiLBFGS && (ir->coulombtype == eelCUT || ir->vdwtype == evdwCUT) && ir->rvdw != 0)
+    if (ir->eI == IntegrationAlgorithm::LBFGS
+        && (ir->coulombtype == CoulombInteractionType::Cut || ir->vdwtype == VanDerWaalsType::Cut)
+        && ir->rvdw != 0)
     {
         warning(wi, "For efficient BFGS minimization, use switch/shift/pme instead of cut-off.");
     }
 
-    if (ir->eI == eiLBFGS && ir->nbfgscorr <= 0)
+    if (ir->eI == IntegrationAlgorithm::LBFGS && ir->nbfgscorr <= 0)
     {
         warning(wi, "Using L-BFGS with nbfgscorr<=0 just gets you steepest descent.");
     }
 
     /* IMPLICIT SOLVENT */
-    if (ir->coulombtype == eelGB_NOTUSED)
+    if (ir->coulombtype == CoulombInteractionType::GBNotused)
     {
-        sprintf(warn_buf, "Invalid option %s for coulombtype", eel_names[ir->coulombtype]);
+        sprintf(warn_buf, "Invalid option %s for coulombtype", enumValueToString(ir->coulombtype));
         warning_error(wi, warn_buf);
     }
 
@@ -1479,7 +1507,7 @@ void check_ir(const char*                   mdparin,
     }
 
     // cosine acceleration is only supported in leap-frog
-    if (ir->cos_accel != 0.0 && ir->eI != eiMD)
+    if (ir->cos_accel != 0.0 && ir->eI != IntegrationAlgorithm::MD)
     {
         warning_error(wi, "cos-acceleration is only supported by integrator = md");
     }
@@ -1490,17 +1518,17 @@ void check_ir(const char*                   mdparin,
    str = the input string
    n = the (pre-allocated) number of doubles read
    r = the output array of doubles. */
-static void parse_n_real(char* str, int* n, real** r, warninp_t wi)
+static std::vector<real> parse_n_real(const std::string& str, int* n, warninp_t wi)
 {
     auto values = gmx::splitString(str);
     *n          = values.size();
 
-    snew(*r, *n);
+    std::vector<real> r;
     for (int i = 0; i < *n; i++)
     {
         try
         {
-            (*r)[i] = gmx::fromString<real>(values[i]);
+            r.emplace_back(gmx::fromString<real>(values[i]));
         }
         catch (gmx::GromacsException&)
         {
@@ -1509,33 +1537,33 @@ static void parse_n_real(char* str, int* n, real** r, warninp_t wi)
                                   + " in string in mdp file. Expected a real number.");
         }
     }
+    return r;
 }
 
 
-static void do_fep_params(t_inputrec* ir, char fep_lambda[][STRLEN], char weights[STRLEN], warninp_t wi)
+static void do_fep_params(t_inputrec* ir, gmx::ArrayRef<std::string> fep_lambda, char weights[STRLEN], warninp_t wi)
 {
 
-    int         i, j, max_n_lambda, nweights, nfep[efptNR];
-    t_lambda*   fep    = ir->fepvals;
-    t_expanded* expand = ir->expandedvals;
-    real**      count_fep_lambdas;
-    bool        bOneLambda = TRUE;
-
-    snew(count_fep_lambdas, efptNR);
+    int         i, j, max_n_lambda, nweights;
+    t_lambda*   fep    = ir->fepvals.get();
+    t_expanded* expand = ir->expandedvals.get();
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, std::vector<real>> count_fep_lambdas;
+    bool                                                                         bOneLambda = TRUE;
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, int>               nfep;
 
     /* FEP input processing */
     /* first, identify the number of lambda values for each type.
        All that are nonzero must have the same number */
 
-    for (i = 0; i < efptNR; i++)
+    for (auto i : keysOf(nfep))
     {
-        parse_n_real(fep_lambda[i], &(nfep[i]), &(count_fep_lambdas[i]), wi);
+        count_fep_lambdas[i] = parse_n_real(fep_lambda[static_cast<int>(i)], &(nfep[i]), wi);
     }
 
     /* now, determine the number of components.  All must be either zero, or equal. */
 
     max_n_lambda = 0;
-    for (i = 0; i < efptNR; i++)
+    for (auto i : keysOf(nfep))
     {
         if (nfep[i] > max_n_lambda)
         {
@@ -1545,7 +1573,7 @@ static void do_fep_params(t_inputrec* ir, char fep_lambda[][STRLEN], char weight
         }
     }
 
-    for (i = 0; i < efptNR; i++)
+    for (auto i : keysOf(nfep))
     {
         if (nfep[i] == 0)
         {
@@ -1553,7 +1581,7 @@ static void do_fep_params(t_inputrec* ir, char fep_lambda[][STRLEN], char weight
         }
         else if (nfep[i] == max_n_lambda)
         {
-            if (i != efptTEMPERATURE) /* we treat this differently -- not really a reason to compute
+            if (i != FreeEnergyPerturbationCouplingType::Temperature) /* we treat this differently -- not really a reason to compute
                                          the derivative with respect to the temperature currently */
             {
                 ir->fepvals->separate_dvdl[i] = TRUE;
@@ -1565,28 +1593,26 @@ static void do_fep_params(t_inputrec* ir, char fep_lambda[][STRLEN], char weight
                       "Number of lambdas (%d) for FEP type %s not equal to number of other types "
                       "(%d)",
                       nfep[i],
-                      efpt_names[i],
+                      enumValueToString(i),
                       max_n_lambda);
         }
     }
     /* we don't print out dhdl if the temperature is changing, since we can't correctly define dhdl in this case */
-    ir->fepvals->separate_dvdl[efptTEMPERATURE] = FALSE;
+    ir->fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Temperature] = FALSE;
 
     /* the number of lambdas is the number we've read in, which is either zero
        or the same for all */
     fep->n_lambda = max_n_lambda;
 
-    /* allocate space for the array of lambda values */
-    snew(fep->all_lambda, efptNR);
     /* if init_lambda is defined, we need to set lambda */
     if ((fep->init_lambda > 0) && (fep->n_lambda == 0))
     {
-        ir->fepvals->separate_dvdl[efptFEP] = TRUE;
+        ir->fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Fep] = TRUE;
     }
     /* otherwise allocate the space for all of the lambdas, and transfer the data */
-    for (i = 0; i < efptNR; i++)
+    for (auto i : keysOf(nfep))
     {
-        snew(fep->all_lambda[i], fep->n_lambda);
+        fep->all_lambda[i].resize(fep->n_lambda);
         if (nfep[i] > 0) /* if it's zero, then the count_fep_lambda arrays
                             are zero */
         {
@@ -1594,19 +1620,17 @@ static void do_fep_params(t_inputrec* ir, char fep_lambda[][STRLEN], char weight
             {
                 fep->all_lambda[i][j] = static_cast<double>(count_fep_lambdas[i][j]);
             }
-            sfree(count_fep_lambdas[i]);
         }
     }
-    sfree(count_fep_lambdas);
 
     /* "fep-vals" is either zero or the full number. If zero, we'll need to define fep-lambdas for
        internal bookkeeping -- for now, init_lambda */
 
-    if ((nfep[efptFEP] == 0) && (fep->init_lambda >= 0))
+    if ((nfep[FreeEnergyPerturbationCouplingType::Fep] == 0) && (fep->init_lambda >= 0))
     {
         for (i = 0; i < fep->n_lambda; i++)
         {
-            fep->all_lambda[efptFEP][i] = fep->init_lambda;
+            fep->all_lambda[FreeEnergyPerturbationCouplingType::Fep][i] = fep->init_lambda;
         }
     }
 
@@ -1619,9 +1643,9 @@ static void do_fep_params(t_inputrec* ir, char fep_lambda[][STRLEN], char weight
     }
     else
     {
-        for (i = 0; i < efptNR; i++)
+        for (auto i : keysOf(nfep))
         {
-            if ((nfep[i] != 0) && (i != efptFEP))
+            if ((nfep[i] != 0) && (i != FreeEnergyPerturbationCouplingType::Fep))
             {
                 bOneLambda = FALSE;
             }
@@ -1636,23 +1660,23 @@ static void do_fep_params(t_inputrec* ir, char fep_lambda[][STRLEN], char weight
        specified (i.e. nfep[i] == 0).  This means if fep is not defined,
        they are all zero. */
 
-    for (i = 0; i < efptNR; i++)
+    for (auto i : keysOf(nfep))
     {
-        if ((nfep[i] == 0) && (i != efptFEP))
+        if ((nfep[i] == 0) && (i != FreeEnergyPerturbationCouplingType::Fep))
         {
             for (j = 0; j < fep->n_lambda; j++)
             {
-                fep->all_lambda[i][j] = fep->all_lambda[efptFEP][j];
+                fep->all_lambda[i][j] = fep->all_lambda[FreeEnergyPerturbationCouplingType::Fep][j];
             }
         }
     }
 
 
     /* now read in the weights */
-    parse_n_real(weights, &nweights, &(expand->init_lambda_weights), wi);
+    expand->init_lambda_weights = parse_n_real(weights, &nweights, wi);
     if (nweights == 0)
     {
-        snew(expand->init_lambda_weights, fep->n_lambda); /* initialize to zero */
+        expand->init_lambda_weights.resize(fep->n_lambda); /* initialize to zero */
     }
     else if (nweights != fep->n_lambda)
     {
@@ -1661,7 +1685,7 @@ static void do_fep_params(t_inputrec* ir, char fep_lambda[][STRLEN], char weight
                   nweights,
                   fep->n_lambda);
     }
-    if ((expand->nstexpanded < 0) && (ir->efep != efepNO))
+    if ((expand->nstexpanded < 0) && (ir->efep != FreeEnergyPerturbationType::No))
     {
         expand->nstexpanded = fep->nstdhdl;
         /* if you don't specify nstexpanded when doing expanded ensemble free energy calcs, it is set to nstdhdl */
@@ -1673,7 +1697,9 @@ static void do_simtemp_params(t_inputrec* ir)
 {
 
     snew(ir->simtempvals->temperatures, ir->fepvals->n_lambda);
-    GetSimTemps(ir->fepvals->n_lambda, ir->simtempvals, ir->fepvals->all_lambda[efptTEMPERATURE]);
+    getSimTemps(ir->fepvals->n_lambda,
+                ir->simtempvals.get(),
+                ir->fepvals->all_lambda[FreeEnergyPerturbationCouplingType::Temperature]);
 }
 
 template<typename T>
@@ -1747,7 +1773,7 @@ static void do_wall_params(t_inputrec* ir, char* wall_atomtype, char* wall_densi
             opts->wall_atomtype[i] = gmx_strdup(wallAtomTypes[i].c_str());
         }
 
-        if (ir->wall_type == ewt93 || ir->wall_type == ewt104)
+        if (ir->wall_type == WallType::NineThree || ir->wall_type == WallType::TenFour)
         {
             auto wallDensity = gmx::splitString(wall_density);
             if (wallDensity.size() != size_t(ir->nwall))
@@ -1786,10 +1812,10 @@ static void read_expandedparams(std::vector<t_inpfile>* inp, t_expanded* expand,
 {
     /* read expanded ensemble parameters */
     printStringNewline(inp, "expanded ensemble variables");
-    expand->nstexpanded    = get_eint(inp, "nstexpanded", -1, wi);
-    expand->elamstats      = get_eeenum(inp, "lmc-stats", elamstats_names, wi);
-    expand->elmcmove       = get_eeenum(inp, "lmc-move", elmcmove_names, wi);
-    expand->elmceq         = get_eeenum(inp, "lmc-weights-equil", elmceq_names, wi);
+    expand->nstexpanded = get_eint(inp, "nstexpanded", -1, wi);
+    expand->elamstats   = getEnum<LambdaWeightCalculation>(inp, "lmc-stats", wi);
+    expand->elmcmove    = getEnum<LambdaMoveCalculation>(inp, "lmc-move", wi);
+    expand->elmceq      = getEnum<LambdaWeightWillReachEquilibrium>(inp, "lmc-weights-equil", wi);
     expand->equil_n_at_lam = get_eint(inp, "weight-equil-number-all-lambda", -1, wi);
     expand->equil_samples  = get_eint(inp, "weight-equil-number-samples", -1, wi);
     expand->equil_steps    = get_eint(inp, "weight-equil-number-steps", -1, wi);
@@ -1802,61 +1828,14 @@ static void read_expandedparams(std::vector<t_inpfile>* inp, t_expanded* expand,
     expand->gibbsdeltalam     = get_eint(inp, "lmc-gibbsdelta", -1, wi);
     expand->lmc_forced_nstart = get_eint(inp, "lmc-forced-nstart", 0, wi);
     expand->bSymmetrizedTMatrix =
-            (get_eeenum(inp, "symmetrized-transition-matrix", yesno_names, wi) != 0);
+            (getEnum<Boolean>(inp, "symmetrized-transition-matrix", wi) != Boolean::No);
     expand->nstTij        = get_eint(inp, "nst-transition-matrix", -1, wi);
     expand->minvarmin     = get_eint(inp, "mininum-var-min", 100, wi); /*default is reasonable */
     expand->c_range       = get_eint(inp, "weight-c-range", 0, wi);    /* default is just C=0 */
     expand->wl_scale      = get_ereal(inp, "wl-scale", 0.8, wi);
     expand->wl_ratio      = get_ereal(inp, "wl-ratio", 0.8, wi);
     expand->init_wl_delta = get_ereal(inp, "init-wl-delta", 1.0, wi);
-    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;
+    expand->bWLoneovert   = (getEnum<Boolean>(inp, "wl-oneovert", wi) != Boolean::No);
 }
 
 /*! \brief Return whether an end state with the given coupling-lambda
@@ -1920,8 +1899,8 @@ void get_ir(const char*     mdparin,
     double      dumdub[2][6];
     int         i, j, m;
     char        warn_buf[STRLEN];
-    t_lambda*   fep    = ir->fepvals;
-    t_expanded* expand = ir->expandedvals;
+    t_lambda*   fep    = ir->fepvals.get();
+    t_expanded* expand = ir->expandedvals.get();
 
     const char* no_names[] = { "no", nullptr };
 
@@ -1988,7 +1967,7 @@ void get_ir(const char*     mdparin,
     setStringEntry(&inp, "define", opts->define, nullptr);
 
     printStringNewline(&inp, "RUN CONTROL PARAMETERS");
-    ir->eI = get_eeenum(&inp, "integrator", ei_names, wi);
+    ir->eI = getEnum<IntegrationAlgorithm>(&inp, "integrator", wi);
     printStringNoNewline(&inp, "Start time and timestep in ps");
     ir->init_t  = get_ereal(&inp, "tinit", 0.0, wi);
     ir->delta_t = get_ereal(&inp, "dt", 0.001, wi);
@@ -1999,7 +1978,7 @@ void get_ir(const char*     mdparin,
             &inp, "Part index is updated automatically on checkpointing (keeps files separate)");
     ir->simulation_part = get_eint(&inp, "simulation-part", 1, wi);
     printStringNoNewline(&inp, "Multiple time-stepping");
-    ir->useMts = (get_eeenum(&inp, "mts", yesno_names, wi) != 0);
+    ir->useMts = (getEnum<Boolean>(&inp, "mts", wi) != Boolean::No);
     if (ir->useMts)
     {
         gmx::GromppMtsOpts& mtsOpts = opts->mtsOpts;
@@ -2014,7 +1993,7 @@ void get_ir(const char*     mdparin,
         }
     }
     printStringNoNewline(&inp, "mode for center of mass motion removal");
-    ir->comm_mode = get_eeenum(&inp, "comm-mode", ecm_names, wi);
+    ir->comm_mode = getEnum<ComRemovalAlgorithm>(&inp, "comm-mode", wi);
     printStringNoNewline(&inp, "number of steps for center of mass motion removal");
     ir->nstcomm = get_eint(&inp, "nstcomm", 100, wi);
     printStringNoNewline(&inp, "group(s) for center of mass motion removal");
@@ -2064,7 +2043,7 @@ void get_ir(const char*     mdparin,
     /* Neighbor searching */
     printStringNewline(&inp, "NEIGHBORSEARCHING PARAMETERS");
     printStringNoNewline(&inp, "cut-off scheme (Verlet: particle based cut-offs)");
-    ir->cutoff_scheme = get_eeenum(&inp, "cutoff-scheme", ecutscheme_names, wi);
+    ir->cutoff_scheme = getEnum<CutoffScheme>(&inp, "cutoff-scheme", wi);
     printStringNoNewline(&inp, "nblist update frequency");
     ir->nstlist = get_eint(&inp, "nstlist", 10, wi);
     printStringNoNewline(&inp, "Periodic boundary conditions: xyz, no, xy");
@@ -2075,7 +2054,7 @@ void get_ir(const char*     mdparin,
         pbcTypesNamesChar.push_back(pbcTypeName.c_str());
     }
     ir->pbcType       = static_cast<PbcType>(get_eeenum(&inp, "pbc", pbcTypesNamesChar.data(), wi));
-    ir->bPeriodicMols = get_eeenum(&inp, "periodic-molecules", yesno_names, wi) != 0;
+    ir->bPeriodicMols = getEnum<Boolean>(&inp, "periodic-molecules", wi) != Boolean::No;
     printStringNoNewline(&inp,
                          "Allowed energy error due to the Verlet buffer in kJ/mol/ps per atom,");
     printStringNoNewline(&inp, "a value of -1 means: use rlist");
@@ -2087,8 +2066,8 @@ void get_ir(const char*     mdparin,
     /* Electrostatics */
     printStringNewline(&inp, "OPTIONS FOR ELECTROSTATICS AND VDW");
     printStringNoNewline(&inp, "Method for doing electrostatics");
-    ir->coulombtype      = get_eeenum(&inp, "coulombtype", eel_names, wi);
-    ir->coulomb_modifier = get_eeenum(&inp, "coulomb-modifier", eintmod_names, wi);
+    ir->coulombtype      = getEnum<CoulombInteractionType>(&inp, "coulombtype", wi);
+    ir->coulomb_modifier = getEnum<InteractionModifiers>(&inp, "coulomb-modifier", wi);
     printStringNoNewline(&inp, "cut-off lengths");
     ir->rcoulomb_switch = get_ereal(&inp, "rcoulomb-switch", 0.0, wi);
     ir->rcoulomb        = get_ereal(&inp, "rcoulomb", 1.0, wi);
@@ -2096,13 +2075,13 @@ void get_ir(const char*     mdparin,
     ir->epsilon_r  = get_ereal(&inp, "epsilon-r", 1.0, wi);
     ir->epsilon_rf = get_ereal(&inp, "epsilon-rf", 0.0, wi);
     printStringNoNewline(&inp, "Method for doing Van der Waals");
-    ir->vdwtype      = get_eeenum(&inp, "vdw-type", evdw_names, wi);
-    ir->vdw_modifier = get_eeenum(&inp, "vdw-modifier", eintmod_names, wi);
+    ir->vdwtype      = getEnum<VanDerWaalsType>(&inp, "vdw-type", wi);
+    ir->vdw_modifier = getEnum<InteractionModifiers>(&inp, "vdw-modifier", wi);
     printStringNoNewline(&inp, "cut-off lengths");
     ir->rvdw_switch = get_ereal(&inp, "rvdw-switch", 0.0, wi);
     ir->rvdw        = get_ereal(&inp, "rvdw", 1.0, wi);
     printStringNoNewline(&inp, "Apply long range dispersion corrections for Energy and Pressure");
-    ir->eDispCorr = get_eeenum(&inp, "DispCorr", edispc_names, wi);
+    ir->eDispCorr = getEnum<DispersionCorrectionType>(&inp, "DispCorr", wi);
     printStringNoNewline(&inp, "Extension of the potential lookup tables beyond the cut-off");
     ir->tabext = get_ereal(&inp, "table-extension", 1.0, wi);
     printStringNoNewline(&inp, "Separate tables between energy group pairs");
@@ -2117,8 +2096,8 @@ void get_ir(const char*     mdparin,
     ir->pme_order              = get_eint(&inp, "pme-order", 4, wi);
     ir->ewald_rtol             = get_ereal(&inp, "ewald-rtol", 0.00001, wi);
     ir->ewald_rtol_lj          = get_ereal(&inp, "ewald-rtol-lj", 0.001, wi);
-    ir->ljpme_combination_rule = get_eeenum(&inp, "lj-pme-comb-rule", eljpme_names, wi);
-    ir->ewald_geometry         = get_eeenum(&inp, "ewald-geometry", eewg_names, wi);
+    ir->ljpme_combination_rule = getEnum<LongRangeVdW>(&inp, "lj-pme-comb-rule", wi);
+    ir->ewald_geometry         = getEnum<EwaldGeometry>(&inp, "ewald-geometry", wi);
     ir->epsilon_surface        = get_ereal(&inp, "epsilon-surface", 0.0, wi);
 
     /* Implicit solvation is no longer supported, but we need grompp
@@ -2132,7 +2111,7 @@ void get_ir(const char*     mdparin,
     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);
+    ir->bPrintNHChains = (getEnum<Boolean>(&inp, "print-nose-hoover-chain-variables", wi) != Boolean::No);
     printStringNoNewline(&inp, "Groups to couple separately");
     setStringEntry(&inp, "tc-grps", inputrecStrings->tcgrps, nullptr);
     printStringNoNewline(&inp, "Time constant (ps) and reference temperature (K)");
@@ -2140,18 +2119,18 @@ void get_ir(const char*     mdparin,
     setStringEntry(&inp, "ref-t", inputrecStrings->ref_t, nullptr);
     printStringNoNewline(&inp, "pressure coupling");
     ir->epc        = getEnum<PressureCoupling>(&inp, "pcoupl", wi);
-    ir->epct       = get_eeenum(&inp, "pcoupltype", epcoupltype_names, wi);
+    ir->epct       = getEnum<PressureCouplingType>(&inp, "pcoupltype", wi);
     ir->nstpcouple = get_eint(&inp, "nstpcouple", -1, wi);
     printStringNoNewline(&inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)");
     ir->tau_p = get_ereal(&inp, "tau-p", 1.0, wi);
     setStringEntry(&inp, "compressibility", dumstr[0], nullptr);
     setStringEntry(&inp, "ref-p", dumstr[1], nullptr);
     printStringNoNewline(&inp, "Scaling of reference coordinates, No, All or COM");
-    ir->refcoord_scaling = get_eeenum(&inp, "refcoord-scaling", erefscaling_names, wi);
+    ir->refcoord_scaling = getEnum<RefCoordScaling>(&inp, "refcoord-scaling", wi);
 
     /* QMMM */
     printStringNewline(&inp, "OPTIONS FOR QMMM calculations");
-    ir->bQMMM = (get_eeenum(&inp, "QMMM", yesno_names, wi) != 0);
+    ir->bQMMM = (getEnum<Boolean>(&inp, "QMMM", wi) != Boolean::No);
     printStringNoNewline(&inp, "Groups treated with MiMiC");
     setStringEntry(&inp, "QMMM-grps", inputrecStrings->QMMM, nullptr);
 
@@ -2169,7 +2148,7 @@ void get_ir(const char*     mdparin,
 
     /* Startup run */
     printStringNewline(&inp, "GENERATE VELOCITIES FOR STARTUP RUN");
-    opts->bGenVel = (get_eeenum(&inp, "gen-vel", yesno_names, wi) != 0);
+    opts->bGenVel = (getEnum<Boolean>(&inp, "gen-vel", wi) != Boolean::No);
     opts->tempi   = get_ereal(&inp, "gen-temp", 300.0, wi);
     opts->seed    = get_eint(&inp, "gen-seed", -1, wi);
 
@@ -2177,12 +2156,12 @@ void get_ir(const char*     mdparin,
     printStringNewline(&inp, "OPTIONS FOR BONDS");
     opts->nshake = get_eeenum(&inp, "constraints", constraints, wi);
     printStringNoNewline(&inp, "Type of constraint algorithm");
-    ir->eConstrAlg = get_eeenum(&inp, "constraint-algorithm", econstr_names, wi);
+    ir->eConstrAlg = getEnum<ConstraintAlgorithm>(&inp, "constraint-algorithm", wi);
     printStringNoNewline(&inp, "Do not constrain the start configuration");
-    ir->bContinuation = (get_eeenum(&inp, "continuation", yesno_names, wi) != 0);
+    ir->bContinuation = (getEnum<Boolean>(&inp, "continuation", wi) != Boolean::No);
     printStringNoNewline(&inp,
                          "Use successive overrelaxation to reduce the number of shake iterations");
-    ir->bShakeSOR = (get_eeenum(&inp, "Shake-SOR", yesno_names, wi) != 0);
+    ir->bShakeSOR = (getEnum<Boolean>(&inp, "Shake-SOR", wi) != Boolean::No);
     printStringNoNewline(&inp, "Relative tolerance of shake");
     ir->shake_tol = get_ereal(&inp, "shake-tol", 0.0001, wi);
     printStringNoNewline(&inp, "Highest order in the expansion of the constraint coupling matrix");
@@ -2195,7 +2174,7 @@ void get_ir(const char*     mdparin,
     printStringNoNewline(&inp, "rotates over more degrees than");
     ir->LincsWarnAngle = get_ereal(&inp, "lincs-warnangle", 30.0, wi);
     printStringNoNewline(&inp, "Convert harmonic bonds to morse potentials");
-    opts->bMorse = (get_eeenum(&inp, "morse", yesno_names, wi) != 0);
+    opts->bMorse = (getEnum<Boolean>(&inp, "morse", wi) != Boolean::No);
 
     /* Energy group exclusions */
     printStringNewline(&inp, "ENERGY GROUP EXCLUSIONS");
@@ -2208,7 +2187,7 @@ void get_ir(const char*     mdparin,
     printStringNoNewline(
             &inp, "Number of walls, type, atom types, densities and box-z scale factor for Ewald");
     ir->nwall         = get_eint(&inp, "nwall", 0, wi);
-    ir->wall_type     = get_eeenum(&inp, "wall-type", ewt_names, wi);
+    ir->wall_type     = getEnum<WallType>(&inp, "wall-type", wi);
     ir->wall_r_linpot = get_ereal(&inp, "wall-r-linpot", -1, wi);
     setStringEntry(&inp, "wall-atomtype", inputrecStrings->wall_atomtype, nullptr);
     setStringEntry(&inp, "wall-density", inputrecStrings->wall_density, nullptr);
@@ -2216,7 +2195,7 @@ void get_ir(const char*     mdparin,
 
     /* COM pulling */
     printStringNewline(&inp, "COM PULLING");
-    ir->bPull = (get_eeenum(&inp, "pull", yesno_names, wi) != 0);
+    ir->bPull = (getEnum<Boolean>(&inp, "pull", wi) != Boolean::No);
     if (ir->bPull)
     {
         ir->pull                        = std::make_unique<pull_params_t>();
@@ -2226,7 +2205,7 @@ void get_ir(const char*     mdparin,
         {
             for (int c = 0; c < ir->pull->ncoord; c++)
             {
-                if (ir->pull->coord[c].eType == epullCONSTRAINT)
+                if (ir->pull->coord[c].eType == PullingAlgorithm::Constraint)
                 {
                     warning_error(wi,
                                   "Constraint COM pulling is not supported in combination with "
@@ -2240,7 +2219,7 @@ void get_ir(const char*     mdparin,
     /* AWH biasing
        NOTE: needs COM pulling or free energy input */
     printStringNewline(&inp, "AWH biasing");
-    ir->bDoAwh = (get_eeenum(&inp, "awh", yesno_names, wi) != 0);
+    ir->bDoAwh = (getEnum<Boolean>(&inp, "awh", wi) != Boolean::No);
     if (ir->bDoAwh)
     {
         ir->awhParams = gmx::readAwhParams(&inp, wi);
@@ -2249,7 +2228,7 @@ void get_ir(const char*     mdparin,
     /* Enforced rotation */
     printStringNewline(&inp, "ENFORCED ROTATION");
     printStringNoNewline(&inp, "Enforced rotation: No or Yes");
-    ir->bRot = (get_eeenum(&inp, "rotation", yesno_names, wi) != 0);
+    ir->bRot = (getEnum<Boolean>(&inp, "rotation", wi) != Boolean::No);
     if (ir->bRot)
     {
         snew(ir->rot, 1);
@@ -2269,18 +2248,18 @@ void get_ir(const char*     mdparin,
     /* Refinement */
     printStringNewline(&inp, "NMR refinement stuff");
     printStringNoNewline(&inp, "Distance restraints type: No, Simple or Ensemble");
-    ir->eDisre = get_eeenum(&inp, "disre", edisre_names, wi);
+    ir->eDisre = getEnum<DistanceRestraintRefinement>(&inp, "disre", wi);
     printStringNoNewline(
             &inp, "Force weighting of pairs in one distance restraint: Conservative or Equal");
-    ir->eDisreWeighting = get_eeenum(&inp, "disre-weighting", edisreweighting_names, wi);
+    ir->eDisreWeighting = getEnum<DistanceRestraintWeighting>(&inp, "disre-weighting", wi);
     printStringNoNewline(&inp, "Use sqrt of the time averaged times the instantaneous violation");
-    ir->bDisreMixed = (get_eeenum(&inp, "disre-mixed", yesno_names, wi) != 0);
+    ir->bDisreMixed = (getEnum<Boolean>(&inp, "disre-mixed", wi) != Boolean::No);
     ir->dr_fc       = get_ereal(&inp, "disre-fc", 1000.0, wi);
     ir->dr_tau      = get_ereal(&inp, "disre-tau", 0.0, wi);
     printStringNoNewline(&inp, "Output frequency for pair distances to energy file");
     ir->nstdisreout = get_eint(&inp, "nstdisreout", 100, wi);
     printStringNoNewline(&inp, "Orientation restraints: No or Yes");
-    opts->bOrire = (get_eeenum(&inp, "orire", yesno_names, wi) != 0);
+    opts->bOrire = (getEnum<Boolean>(&inp, "orire", wi) != Boolean::No);
     printStringNoNewline(&inp, "Orientation restraints force constant and tau for time averaging");
     ir->orires_fc  = get_ereal(&inp, "orire-fc", 0.0, wi);
     ir->orires_tau = get_ereal(&inp, "orire-tau", 0.0, wi);
@@ -2290,11 +2269,11 @@ void get_ir(const char*     mdparin,
 
     /* free energy variables */
     printStringNewline(&inp, "Free energy variables");
-    ir->efep = get_eeenum(&inp, "free-energy", efep_names, wi);
+    ir->efep = getEnum<FreeEnergyPerturbationType>(&inp, "free-energy", wi);
     setStringEntry(&inp, "couple-moltype", inputrecStrings->couple_moltype, nullptr);
     opts->couple_lam0  = get_eeenum(&inp, "couple-lambda0", couple_lam, wi);
     opts->couple_lam1  = get_eeenum(&inp, "couple-lambda1", couple_lam, wi);
-    opts->bCoupleIntra = (get_eeenum(&inp, "couple-intramol", yesno_names, wi) != 0);
+    opts->bCoupleIntra = (getEnum<Boolean>(&inp, "couple-intramol", wi) != Boolean::No);
 
     fep->init_lambda = get_ereal(&inp, "init-lambda", -1, wi); /* start with -1 so
                                                                          we can recognize if
@@ -2302,25 +2281,32 @@ void get_ir(const char*     mdparin,
     fep->init_fep_state = get_eint(&inp, "init-lambda-state", -1, wi);
     fep->delta_lambda   = get_ereal(&inp, "delta-lambda", 0.0, wi);
     fep->nstdhdl        = get_eint(&inp, "nstdhdl", 50, wi);
-    setStringEntry(&inp, "fep-lambdas", inputrecStrings->fep_lambda[efptFEP], nullptr);
-    setStringEntry(&inp, "mass-lambdas", inputrecStrings->fep_lambda[efptMASS], nullptr);
-    setStringEntry(&inp, "coul-lambdas", inputrecStrings->fep_lambda[efptCOUL], nullptr);
-    setStringEntry(&inp, "vdw-lambdas", inputrecStrings->fep_lambda[efptVDW], nullptr);
-    setStringEntry(&inp, "bonded-lambdas", inputrecStrings->fep_lambda[efptBONDED], nullptr);
-    setStringEntry(&inp, "restraint-lambdas", inputrecStrings->fep_lambda[efptRESTRAINT], nullptr);
-    setStringEntry(&inp, "temperature-lambdas", inputrecStrings->fep_lambda[efptTEMPERATURE], nullptr);
+    inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Fep] =
+            setStringEntry(&inp, "fep-lambdas", "");
+    inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Mass] =
+            setStringEntry(&inp, "mass-lambdas", "");
+    inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Coul] =
+            setStringEntry(&inp, "coul-lambdas", "");
+    inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Vdw] =
+            setStringEntry(&inp, "vdw-lambdas", "");
+    inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Bonded] =
+            setStringEntry(&inp, "bonded-lambdas", "");
+    inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Restraint] =
+            setStringEntry(&inp, "restraint-lambdas", "");
+    inputrecStrings->fep_lambda[FreeEnergyPerturbationCouplingType::Temperature] =
+            setStringEntry(&inp, "temperature-lambdas", "");
     fep->lambda_neighbors = get_eint(&inp, "calc-lambda-neighbors", 1, wi);
     setStringEntry(&inp, "init-lambda-weights", inputrecStrings->lambda_weights, nullptr);
-    fep->edHdLPrintEnergy   = get_eeenum(&inp, "dhdl-print-energy", edHdLPrintEnergy_names, wi);
+    fep->edHdLPrintEnergy   = getEnum<FreeEnergyPrintEnergy>(&inp, "dhdl-print-energy", wi);
     fep->sc_alpha           = get_ereal(&inp, "sc-alpha", 0.0, wi);
     fep->sc_power           = get_eint(&inp, "sc-power", 1, wi);
     fep->sc_r_power         = get_ereal(&inp, "sc-r-power", 6.0, wi);
     fep->sc_sigma           = get_ereal(&inp, "sc-sigma", 0.3, wi);
-    fep->bScCoul            = (get_eeenum(&inp, "sc-coul", yesno_names, wi) != 0);
+    fep->bScCoul            = (getEnum<Boolean>(&inp, "sc-coul", wi) != Boolean::No);
     fep->dh_hist_size       = get_eint(&inp, "dh_hist_size", 0, wi);
     fep->dh_hist_spacing    = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
-    fep->separate_dhdl_file = get_eeenum(&inp, "separate-dhdl-file", separate_dhdl_file_names, wi);
-    fep->dhdl_derivatives   = get_eeenum(&inp, "dhdl-derivatives", dhdl_derivatives_names, wi);
+    fep->separate_dhdl_file = getEnum<SeparateDhdlFile>(&inp, "separate-dhdl-file", wi);
+    fep->dhdl_derivatives   = getEnum<DhDlDerivativeCalculation>(&inp, "dhdl-derivatives", wi);
     fep->dh_hist_size       = get_eint(&inp, "dh_hist_size", 0, wi);
     fep->dh_hist_spacing    = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
 
@@ -2333,13 +2319,13 @@ void get_ir(const char*     mdparin,
 
     /* simulated tempering variables */
     printStringNewline(&inp, "simulated tempering variables");
-    ir->bSimTemp = (get_eeenum(&inp, "simulated-tempering", yesno_names, wi) != 0);
-    ir->simtempvals->eSimTempScale = get_eeenum(&inp, "simulated-tempering-scaling", esimtemp_names, wi);
+    ir->bSimTemp = (getEnum<Boolean>(&inp, "simulated-tempering", wi) != Boolean::No);
+    ir->simtempvals->eSimTempScale = getEnum<SimulatedTempering>(&inp, "simulated-tempering-scaling", wi);
     ir->simtempvals->simtemp_low  = get_ereal(&inp, "sim-temp-low", 300.0, wi);
     ir->simtempvals->simtemp_high = get_ereal(&inp, "sim-temp-high", 300.0, wi);
 
     /* expanded ensemble variables */
-    if (ir->efep == efepEXPANDED || ir->bSimTemp)
+    if (ir->efep == FreeEnergyPerturbationType::Expanded || ir->bSimTemp)
     {
         read_expandedparams(&inp, expand, wi);
     }
@@ -2367,8 +2353,8 @@ void get_ir(const char*     mdparin,
     printStringNewline(&inp,
                        "Ion/water position swapping for computational electrophysiology setups");
     printStringNoNewline(&inp, "Swap positions along direction: no, X, Y, Z");
-    ir->eSwapCoords = get_eeenum(&inp, "swapcoords", eSwapTypes_names, wi);
-    if (ir->eSwapCoords != eswapNO)
+    ir->eSwapCoords = getEnum<SwapType>(&inp, "swapcoords", wi);
+    if (ir->eSwapCoords != SwapType::No)
     {
         char buf[STRLEN];
         int  nIonTypes;
@@ -2383,7 +2369,7 @@ void get_ir(const char*     mdparin,
         {
             warning_error(wi, "You need to provide at least one ion type for position exchanges.");
         }
-        ir->swap->ngrp = nIonTypes + eSwapFixedGrpNR;
+        ir->swap->ngrp = nIonTypes + static_cast<int>(SwapGroupSplittingType::Count);
         snew(ir->swap->grp, ir->swap->ngrp);
         for (i = 0; i < ir->swap->ngrp; i++)
         {
@@ -2391,16 +2377,25 @@ void get_ir(const char*     mdparin,
         }
         printStringNoNewline(&inp,
                              "Two index groups that contain the compartment-partitioning atoms");
-        setStringEntry(&inp, "split-group0", ir->swap->grp[eGrpSplit0].molname, nullptr);
-        setStringEntry(&inp, "split-group1", ir->swap->grp[eGrpSplit1].molname, nullptr);
+        setStringEntry(&inp,
+                       "split-group0",
+                       ir->swap->grp[static_cast<int>(SwapGroupSplittingType::Split0)].molname,
+                       nullptr);
+        setStringEntry(&inp,
+                       "split-group1",
+                       ir->swap->grp[static_cast<int>(SwapGroupSplittingType::Split1)].molname,
+                       nullptr);
         printStringNoNewline(&inp,
                              "Use center of mass of split groups (yes/no), otherwise center of "
                              "geometry is used");
-        ir->swap->massw_split[0] = (get_eeenum(&inp, "massw-split0", yesno_names, wi) != 0);
-        ir->swap->massw_split[1] = (get_eeenum(&inp, "massw-split1", yesno_names, wi) != 0);
+        ir->swap->massw_split[0] = (getEnum<Boolean>(&inp, "massw-split0", wi) != Boolean::No);
+        ir->swap->massw_split[1] = (getEnum<Boolean>(&inp, "massw-split1", wi) != Boolean::No);
 
         printStringNoNewline(&inp, "Name of solvent molecules");
-        setStringEntry(&inp, "solvent-group", ir->swap->grp[eGrpSolvent].molname, nullptr);
+        setStringEntry(&inp,
+                       "solvent-group",
+                       ir->swap->grp[static_cast<int>(SwapGroupSplittingType::Solvent)].molname,
+                       nullptr);
 
         printStringNoNewline(&inp,
                              "Split cylinder: radius, upper and lower extension (nm) (this will "
@@ -2430,7 +2425,7 @@ void get_ir(const char*     mdparin,
         printStringNoNewline(&inp, "-1 means fix the numbers as found in step 0");
         for (i = 0; i < nIonTypes; i++)
         {
-            int ig = eSwapFixedGrpNR + i;
+            int ig = static_cast<int>(SwapGroupSplittingType::Count) + i;
 
             sprintf(buf, "iontype%d-name", i);
             setStringEntry(&inp, buf, ir->swap->grp[ig].molname, nullptr);
@@ -2508,7 +2503,7 @@ void get_ir(const char*     mdparin,
         {
             switch (ir->epct)
             {
-                case epctISOTROPIC:
+                case PressureCouplingType::Isotropic:
                     if (sscanf(dumstr[m], "%lf", &(dumdub[m][XX])) != 1)
                     {
                         warning_error(
@@ -2517,8 +2512,8 @@ void get_ir(const char*     mdparin,
                     }
                     dumdub[m][YY] = dumdub[m][ZZ] = dumdub[m][XX];
                     break;
-                case epctSEMIISOTROPIC:
-                case epctSURFACETENSION:
+                case PressureCouplingType::SemiIsotropic:
+                case PressureCouplingType::SurfaceTension:
                     if (sscanf(dumstr[m], "%lf%lf", &(dumdub[m][XX]), &(dumdub[m][ZZ])) != 2)
                     {
                         warning_error(
@@ -2527,7 +2522,7 @@ void get_ir(const char*     mdparin,
                     }
                     dumdub[m][YY] = dumdub[m][XX];
                     break;
-                case epctANISOTROPIC:
+                case PressureCouplingType::Anisotropic:
                     if (sscanf(dumstr[m],
                                "%lf%lf%lf%lf%lf%lf",
                                &(dumdub[m][XX]),
@@ -2546,7 +2541,7 @@ void get_ir(const char*     mdparin,
                 default:
                     gmx_fatal(FARGS,
                               "Pressure coupling type %s not implemented yet",
-                              epcoupltype_names[ir->epct]);
+                              enumValueToString(ir->epct));
             }
         }
     }
@@ -2557,7 +2552,7 @@ void get_ir(const char*     mdparin,
         ir->ref_p[i][i]    = dumdub[1][i];
         ir->compress[i][i] = dumdub[0][i];
     }
-    if (ir->epct == epctANISOTROPIC)
+    if (ir->epct == PressureCouplingType::Anisotropic)
     {
         ir->ref_p[XX][YY] = dumdub[1][3];
         ir->ref_p[XX][ZZ] = dumdub[1][4];
@@ -2581,7 +2576,7 @@ void get_ir(const char*     mdparin,
         }
     }
 
-    if (ir->comm_mode == ecmNO)
+    if (ir->comm_mode == ComRemovalAlgorithm::No)
     {
         ir->nstcomm = 0;
     }
@@ -2589,14 +2584,15 @@ void get_ir(const char*     mdparin,
     opts->couple_moltype = nullptr;
     if (strlen(inputrecStrings->couple_moltype) > 0)
     {
-        if (ir->efep != efepNO)
+        if (ir->efep != FreeEnergyPerturbationType::No)
         {
             opts->couple_moltype = gmx_strdup(inputrecStrings->couple_moltype);
             if (opts->couple_lam0 == opts->couple_lam1)
             {
                 warning(wi, "The lambda=0 and lambda=1 states for coupling are identical");
             }
-            if (ir->eI == eiMD && (opts->couple_lam0 == ecouplamNONE || opts->couple_lam1 == ecouplamNONE))
+            if (ir->eI == IntegrationAlgorithm::MD
+                && (opts->couple_lam0 == ecouplamNONE || opts->couple_lam1 == ecouplamNONE))
             {
                 warning_note(
                         wi,
@@ -2612,23 +2608,23 @@ void get_ir(const char*     mdparin,
         }
     }
     /* FREE ENERGY AND EXPANDED ENSEMBLE OPTIONS */
-    if (ir->efep != efepNO)
+    if (ir->efep != FreeEnergyPerturbationType::No)
     {
         if (fep->delta_lambda != 0)
         {
-            ir->efep = efepSLOWGROWTH;
+            ir->efep = FreeEnergyPerturbationType::SlowGrowth;
         }
     }
 
-    if (fep->edHdLPrintEnergy == edHdLPrintEnergyYES)
+    if (fep->edHdLPrintEnergy == FreeEnergyPrintEnergy::Yes)
     {
-        fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
+        fep->edHdLPrintEnergy = FreeEnergyPrintEnergy::Total;
         warning_note(wi,
                      "Old option for dhdl-print-energy given: "
                      "changing \"yes\" to \"total\"\n");
     }
 
-    if (ir->bSimTemp && (fep->edHdLPrintEnergy == edHdLPrintEnergyNO))
+    if (ir->bSimTemp && (fep->edHdLPrintEnergy == FreeEnergyPrintEnergy::No))
     {
         /* always print out the energy to dhdl if we are doing
            expanded ensemble, since we need the total energy for
@@ -2637,13 +2633,13 @@ void get_ir(const char*     mdparin,
            we will allow that if the appropriate mdp setting has
            been enabled. Otherwise, total it is:
          */
-        fep->edHdLPrintEnergy = edHdLPrintEnergyTOTAL;
+        fep->edHdLPrintEnergy = FreeEnergyPrintEnergy::Total;
     }
 
-    if ((ir->efep != efepNO) || ir->bSimTemp)
+    if ((ir->efep != FreeEnergyPerturbationType::No) || ir->bSimTemp)
     {
         ir->bExpanded = FALSE;
-        if ((ir->efep == efepEXPANDED) || ir->bSimTemp)
+        if ((ir->efep == FreeEnergyPerturbationType::Expanded) || ir->bSimTemp)
         {
             ir->bExpanded = TRUE;
         }
@@ -2661,7 +2657,8 @@ void get_ir(const char*     mdparin,
          * If the (advanced) user does FEP through manual topology changes,
          * this check will not be triggered.
          */
-        if (ir->efep != efepNO && ir->fepvals->n_lambda == 0 && ir->fepvals->sc_alpha != 0
+        if (ir->efep != FreeEnergyPerturbationType::No && ir->fepvals->n_lambda == 0
+            && ir->fepvals->sc_alpha != 0
             && (couple_lambda_has_vdw_on(opts->couple_lam0) && couple_lambda_has_vdw_on(opts->couple_lam1)))
         {
             warning(wi,
@@ -2756,7 +2753,7 @@ void get_ir(const char*     mdparin,
     }
 
     /* Ion/water position swapping checks */
-    if (ir->eSwapCoords != eswapNO)
+    if (ir->eSwapCoords != SwapType::No)
     {
         if (ir->swap->nstswap < 1)
         {
@@ -3111,7 +3108,7 @@ static void calc_nrdf(const gmx_mtop_t* mtop, t_inputrec* ir, char** gnames)
 
         for (int i = 0; i < pull->ncoord; i++)
         {
-            if (pull->coord[i].eType != epullCONSTRAINT)
+            if (pull->coord[i].eType != PullingAlgorithm::Constraint)
             {
                 continue;
             }
@@ -3169,8 +3166,8 @@ static void calc_nrdf(const gmx_mtop_t* mtop, t_inputrec* ir, char** gnames)
         {
             switch (ir->comm_mode)
             {
-                case ecmLINEAR:
-                case ecmLINEAR_ACCELERATION_CORRECTION:
+                case ComRemovalAlgorithm::Linear:
+                case ComRemovalAlgorithm::LinearAccelerationCorrection:
                     nrdf_vcm_sub[j] = 0;
                     for (int d = 0; d < ndim_rm_vcm; d++)
                     {
@@ -3180,7 +3177,7 @@ static void calc_nrdf(const gmx_mtop_t* mtop, t_inputrec* ir, char** gnames)
                         }
                     }
                     break;
-                case ecmANGULAR: nrdf_vcm_sub[j] = 6; break;
+                case ComRemovalAlgorithm::Angular: nrdf_vcm_sub[j] = 6; break;
                 default: gmx_incons("Checking comm_mode");
             }
         }
@@ -3306,9 +3303,13 @@ static void make_swap_groups(t_swapcoords* swap, t_blocka* grps, char** gnames)
 
 
     /* Just a quick check here, more thorough checks are in mdrun */
-    if (strcmp(swap->grp[eGrpSplit0].molname, swap->grp[eGrpSplit1].molname) == 0)
+    if (strcmp(swap->grp[static_cast<int>(SwapGroupSplittingType::Split0)].molname,
+               swap->grp[static_cast<int>(SwapGroupSplittingType::Split1)].molname)
+        == 0)
     {
-        gmx_fatal(FARGS, "The split groups can not both be '%s'.", swap->grp[eGrpSplit0].molname);
+        gmx_fatal(FARGS,
+                  "The split groups can not both be '%s'.",
+                  swap->grp[static_cast<int>(SwapGroupSplittingType::Split0)].molname);
     }
 
     /* Get the index atoms of the split0, split1, solvent, and swap groups */
@@ -3322,7 +3323,7 @@ static void make_swap_groups(t_swapcoords* swap, t_blocka* grps, char** gnames)
         {
             fprintf(stderr,
                     "%s group '%s' contains %d atoms.\n",
-                    ig < 3 ? eSwapFixedGrp_names[ig] : "Swap",
+                    ig < 3 ? enumValueToString(static_cast<SwapGroupSplittingType>(ig)) : "Swap",
                     swap->grp[ig].molname,
                     swapg->nat);
             snew(swapg->ind, swapg->nat);
@@ -3530,7 +3531,7 @@ void do_index(const char*                   mdparin,
     snew(ir->opts.nrdf, nr);
     snew(ir->opts.tau_t, nr);
     snew(ir->opts.ref_t, nr);
-    if (ir->eI == eiBD && ir->bd_fric == 0)
+    if (ir->eI == IntegrationAlgorithm::BD && ir->bd_fric == 0)
     {
         fprintf(stderr, "bd-fric=0, so tau-t will be used as the inverse friction constant(s)\n");
     }
@@ -3546,9 +3547,11 @@ void do_index(const char*                   mdparin,
         convertReals(wi, temperatureCouplingTauValues, "tau-t", ir->opts.tau_t);
         for (i = 0; (i < nr); i++)
         {
-            if ((ir->eI == eiBD) && ir->opts.tau_t[i] <= 0)
+            if ((ir->eI == IntegrationAlgorithm::BD) && ir->opts.tau_t[i] <= 0)
             {
-                sprintf(warn_buf, "With integrator %s tau-t should be larger than 0", ei_names[ir->eI]);
+                sprintf(warn_buf,
+                        "With integrator %s tau-t should be larger than 0",
+                        enumValueToString(ir->eI));
                 warning_error(wi, warn_buf);
             }
 
@@ -3671,7 +3674,7 @@ void do_index(const char*                   mdparin,
         snew(ir->opts.anneal_temp, nr);
         for (i = 0; i < nr; i++)
         {
-            ir->opts.annealing[i]      = eannNO;
+            ir->opts.annealing[i]      = SimulatedAnnealing::No;
             ir->opts.anneal_npoints[i] = 0;
             ir->opts.anneal_time[i]    = nullptr;
             ir->opts.anneal_temp[i]    = nullptr;
@@ -3683,16 +3686,16 @@ void do_index(const char*                   mdparin,
             {
                 if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "N", 1))
                 {
-                    ir->opts.annealing[i] = eannNO;
+                    ir->opts.annealing[i] = SimulatedAnnealing::No;
                 }
                 else if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "S", 1))
                 {
-                    ir->opts.annealing[i] = eannSINGLE;
+                    ir->opts.annealing[i] = SimulatedAnnealing::Single;
                     bAnneal               = TRUE;
                 }
                 else if (gmx::equalCaseInsensitive(simulatedAnnealingGroupNames[i], "P", 1))
                 {
-                    ir->opts.annealing[i] = eannPERIODIC;
+                    ir->opts.annealing[i] = SimulatedAnnealing::Periodic;
                     bAnneal               = TRUE;
                 }
             }
@@ -3784,13 +3787,13 @@ void do_index(const char*                   mdparin,
                 /* Print out some summary information, to make sure we got it right */
                 for (i = 0; i < nr; i++)
                 {
-                    if (ir->opts.annealing[i] != eannNO)
+                    if (ir->opts.annealing[i] != SimulatedAnnealing::No)
                     {
                         j = groups->groups[SimulationAtomGroupType::TemperatureCoupling][i];
                         fprintf(stderr,
                                 "Simulated annealing for group %s: %s, %d timepoints\n",
                                 *(groups->groupNames[j]),
-                                eann_names[ir->opts.annealing[i]],
+                                enumValueToString(ir->opts.annealing[i]),
                                 ir->opts.anneal_npoints[i]);
                         fprintf(stderr, "Time (ps)   Temperature (K)\n");
                         /* All terms except the last one */
@@ -3804,7 +3807,7 @@ void do_index(const char*                   mdparin,
 
                         /* Finally the last one */
                         j = ir->opts.anneal_npoints[i] - 1;
-                        if (ir->opts.annealing[i] == eannSINGLE)
+                        if (ir->opts.annealing[i] == SimulatedAnnealing::Single)
                         {
                             fprintf(stderr,
                                     "%9.1f-     %5.1f\n",
@@ -3850,7 +3853,7 @@ void do_index(const char*                   mdparin,
         make_rotation_groups(ir->rot, inputrecStrings->rotateGroupNames, defaultIndexGroups, gnames);
     }
 
-    if (ir->eSwapCoords != eswapNO)
+    if (ir->eSwapCoords != SwapType::No)
     {
         make_swap_groups(ir->swap, defaultIndexGroups, gnames);
     }
@@ -3938,7 +3941,7 @@ void do_index(const char*                   mdparin,
                  bVerbose,
                  wi);
 
-    if (ir->comm_mode != ecmNO)
+    if (ir->comm_mode != ComRemovalAlgorithm::No)
     {
         checkAndUpdateVcmFreezeGroupConsistency(groups, natoms, ir->opts, wi);
     }
@@ -4029,7 +4032,7 @@ void do_index(const char*                   mdparin,
     snew(ir->opts.egp_flags, nr * nr);
 
     bExcl = do_egp_flag(ir, groups, "energygrp-excl", inputrecStrings->egpexcl, EGP_EXCL);
-    if (bExcl && ir->cutoff_scheme == ecutsVERLET)
+    if (bExcl && ir->cutoff_scheme == CutoffScheme::Verlet)
     {
         warning_error(wi, "Energy group exclusions are currently not supported");
     }
@@ -4039,8 +4042,10 @@ void do_index(const char*                   mdparin,
     }
 
     bTable = do_egp_flag(ir, groups, "energygrp-table", inputrecStrings->egptable, EGP_TABLE);
-    if (bTable && !(ir->vdwtype == evdwUSER) && !(ir->coulombtype == eelUSER)
-        && !(ir->coulombtype == eelPMEUSER) && !(ir->coulombtype == eelPMEUSERSWITCH))
+    if (bTable && !(ir->vdwtype == VanDerWaalsType::User)
+        && !(ir->coulombtype == CoulombInteractionType::User)
+        && !(ir->coulombtype == CoulombInteractionType::PmeUser)
+        && !(ir->coulombtype == CoulombInteractionType::PmeUserSwitch))
     {
         gmx_fatal(FARGS,
                   "Can only have energy group pair tables in combination with user tables for VdW "
@@ -4273,7 +4278,7 @@ static void check_combination_rules(const t_inputrec* ir, const gmx_mtop_t* mtop
 
     check_combination_rule_differences(
             mtop, 0, &bC6ParametersWorkWithGeometricRules, &bC6ParametersWorkWithLBRules, &bLBRulesPossible);
-    if (ir->ljpme_combination_rule == eljpmeLB)
+    if (ir->ljpme_combination_rule == LongRangeVdW::LB)
     {
         if (!bC6ParametersWorkWithLBRules || !bLBRulesPossible)
         {
@@ -4287,7 +4292,7 @@ static void check_combination_rules(const t_inputrec* ir, const gmx_mtop_t* mtop
     {
         if (!bC6ParametersWorkWithGeometricRules)
         {
-            if (ir->eDispCorr != edispcNO)
+            if (ir->eDispCorr != DispersionCorrectionType::No)
             {
                 warning_note(wi,
                              "You are using geometric combination rules in "
@@ -4335,7 +4340,7 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
                      "macro-molecule, the artifacts are usually negligible.");
     }
 
-    if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0 && ir->nstlist > 1
+    if (ir->cutoff_scheme == CutoffScheme::Verlet && ir->verletbuf_tol > 0 && ir->nstlist > 1
         && ((EI_MD(ir->eI) || EI_SD(ir->eI))
             && (ir->etc == TemperatureCoupling::VRescale || ir->etc == TemperatureCoupling::Berendsen)))
     {
@@ -4402,7 +4407,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 == TemperatureCoupling::AndersenMassive && ir->comm_mode != ecmNO)
+        if (ir->etc == TemperatureCoupling::AndersenMassive && ir->comm_mode != ComRemovalAlgorithm::No)
         {
             for (i = 0; i < ir->opts.ngtc; i++)
             {
@@ -4422,7 +4427,8 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
         }
     }
 
-    if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != eiBD && ir->comm_mode == ecmNO
+    if (EI_DYNAMICS(ir->eI) && !EI_SD(ir->eI) && ir->eI != IntegrationAlgorithm::BD
+        && ir->comm_mode == ComRemovalAlgorithm::No
         && !(absolute_reference(ir, sys, FALSE, AbsRef) || ir->nsteps <= 10) && !ETC_ANDERSEN(ir->etc))
     {
         warning(wi,
@@ -4453,7 +4459,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 != PressureCoupling::No && ir->refcoord_scaling == erscNO)
+    if (ir->epc != PressureCoupling::No && ir->refcoord_scaling == RefCoordScaling::No)
     {
         absolute_reference(ir, sys, TRUE, AbsRef);
         {
@@ -4489,19 +4495,19 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
                     "You are using full electrostatics treatment %s for a system without charges.\n"
                     "This costs a lot of performance for just processing zeros, consider using %s "
                     "instead.\n",
-                    EELTYPE(ir->coulombtype),
-                    EELTYPE(eelCUT));
+                    enumValueToString(ir->coulombtype),
+                    enumValueToString(CoulombInteractionType::Cut));
             warning(wi, err_buf);
         }
     }
     else
     {
-        if (ir->coulombtype == eelCUT && ir->rcoulomb > 0)
+        if (ir->coulombtype == CoulombInteractionType::Cut && ir->rcoulomb > 0)
         {
             sprintf(err_buf,
                     "You are using a plain Coulomb cut-off, which might produce artifacts.\n"
                     "You might want to consider using %s electrostatics.\n",
-                    EELTYPE(eelPME));
+                    enumValueToString(CoulombInteractionType::Pme));
             warning_note(wi, err_buf);
         }
     }
@@ -4513,7 +4519,7 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
     }
 
     /* Generalized reaction field */
-    if (ir->coulombtype == eelGRF_NOTUSED)
+    if (ir->coulombtype == CoulombInteractionType::GRFNotused)
     {
         warning_error(wi,
                       "Generalized reaction-field electrostatics is no longer supported. "
@@ -4521,7 +4527,7 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
                       "constant by hand.");
     }
 
-    if (ir->efep != efepNO && ir->fepvals->sc_alpha != 0
+    if (ir->efep != FreeEnergyPerturbationType::No && ir->fepvals->sc_alpha != 0
         && !gmx_within_tol(sys->ffparams.reppow, 12.0, 10 * GMX_DOUBLE_EPS))
     {
         gmx_fatal(FARGS, "Soft-core interactions are only supported with VdW repulsion power 12");
@@ -4560,12 +4566,13 @@ void triple_check(const char* mdparin, t_inputrec* ir, gmx_mtop_t* sys, warninp_
                 {
                     for (c = 0; c < ir->pull->ncoord; c++)
                     {
-                        if (ir->pull->coord[c].eGeom == epullgDIRPBC && ir->pull->coord[c].vec[m] != 0)
+                        if (ir->pull->coord[c].eGeom == PullGroupGeometry::DirectionPBC
+                            && ir->pull->coord[c].vec[m] != 0)
                         {
                             gmx_fatal(FARGS,
                                       "Can not have dynamic box while using pull geometry '%s' "
                                       "(dim %c)",
-                                      EPULLGEOM(ir->pull->coord[c].eGeom),
+                                      enumValueToString(ir->pull->coord[c].eGeom),
                                       'x' + m);
                         }
                     }
@@ -4588,7 +4595,7 @@ void double_check(t_inputrec* ir, matrix box, bool bHasNormalConstraints, bool b
         warning_error(wi, ptr);
     }
 
-    if (bHasNormalConstraints && ir->eConstrAlg == econtSHAKE)
+    if (bHasNormalConstraints && ir->eConstrAlg == ConstraintAlgorithm::Shake)
     {
         if (ir->shake_tol <= 0.0)
         {
@@ -4597,22 +4604,23 @@ void double_check(t_inputrec* ir, matrix box, bool bHasNormalConstraints, bool b
         }
     }
 
-    if ((ir->eConstrAlg == econtLINCS) && bHasNormalConstraints)
+    if ((ir->eConstrAlg == ConstraintAlgorithm::Lincs) && bHasNormalConstraints)
     {
         /* If we have Lincs constraints: */
-        if (ir->eI == eiMD && ir->etc == TemperatureCoupling::No && ir->eConstrAlg == econtLINCS
-            && ir->nLincsIter == 1)
+        if (ir->eI == IntegrationAlgorithm::MD && ir->etc == TemperatureCoupling::No
+            && ir->eConstrAlg == ConstraintAlgorithm::Lincs && ir->nLincsIter == 1)
         {
             sprintf(warn_buf,
                     "For energy conservation with LINCS, lincs_iter should be 2 or larger.\n");
             warning_note(wi, warn_buf);
         }
 
-        if ((ir->eI == eiCG || ir->eI == eiLBFGS) && (ir->nProjOrder < 8))
+        if ((ir->eI == IntegrationAlgorithm::CG || ir->eI == IntegrationAlgorithm::LBFGS)
+            && (ir->nProjOrder < 8))
         {
             sprintf(warn_buf,
                     "For accurate %s with LINCS constraints, lincs-order should be 8 or more.",
-                    ei_names[ir->eI]);
+                    enumValueToString(ir->eI));
             warning_note(wi, warn_buf);
         }
         if (ir->epc == PressureCoupling::Mttk)
index 103f9a279f387f2dc0189b74106b4036fc532b3e..1af230d1351e4aca7117dcb7b3773b86e651bb35 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.
@@ -119,15 +119,16 @@ static void process_pull_dim(char* dim_buf, ivec dim, const t_pull_coord* pcrd)
     {
         gmx_fatal(FARGS, "All entries in pull dim are N");
     }
-    if ((pcrd->eGeom == epullgDIHEDRAL) && (ndim < 3))
+    if ((pcrd->eGeom == PullGroupGeometry::Dihedral) && (ndim < 3))
     {
         gmx_fatal(FARGS, "Pull geometry dihedral is only useful with pull-dim = Y Y Y");
     }
-    if ((pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS) && (ndim < 2))
+    if ((pcrd->eGeom == PullGroupGeometry::Angle || pcrd->eGeom == PullGroupGeometry::AngleAxis)
+        && (ndim < 2))
     {
         gmx_fatal(FARGS,
                   "Pull geometry %s is only useful with pull-dim = Y for at least 2 dimensions",
-                  EPULLGEOM(pcrd->eGeom));
+                  enumValueToString(pcrd->eGeom));
     }
 }
 
@@ -142,26 +143,27 @@ static void init_pull_coord(t_pull_coord* pcrd,
     dvec origin, vec;
     char buf[STRLEN];
 
-    if (pcrd->eType == epullCONSTRAINT
-        && (pcrd->eGeom == epullgCYL || pcrd->eGeom == epullgDIRRELATIVE || pcrd->eGeom == epullgANGLE
-            || pcrd->eGeom == epullgANGLEAXIS || pcrd->eGeom == epullgDIHEDRAL))
+    if (pcrd->eType == PullingAlgorithm::Constraint
+        && (pcrd->eGeom == PullGroupGeometry::Cylinder || pcrd->eGeom == PullGroupGeometry::DirectionRelative
+            || pcrd->eGeom == PullGroupGeometry::Angle || pcrd->eGeom == PullGroupGeometry::AngleAxis
+            || pcrd->eGeom == PullGroupGeometry::Dihedral))
     {
         gmx_fatal(FARGS,
                   "Pulling of type %s can not be combined with geometry %s. Consider using pull "
                   "type %s.",
-                  epull_names[pcrd->eType],
-                  epullg_names[pcrd->eGeom],
-                  epull_names[epullUMBRELLA]);
+                  enumValueToString(pcrd->eType),
+                  enumValueToString(pcrd->eGeom),
+                  enumValueToString(PullingAlgorithm::Umbrella));
     }
 
-    if (pcrd->eType == epullEXTERNAL)
+    if (pcrd->eType == PullingAlgorithm::External)
     {
         if (pcrd->externalPotentialProvider[0] == '\0')
         {
             sprintf(buf,
                     "The use of pull type '%s' for pull coordinate %d requires that the name of "
                     "the module providing the potential external is set with the option %s%d%s",
-                    epull_names[pcrd->eType],
+                    enumValueToString(pcrd->eType),
                     coord_index_for_output,
                     "pull-coord",
                     coord_index_for_output,
@@ -174,12 +176,12 @@ static void init_pull_coord(t_pull_coord* pcrd,
             sprintf(buf,
                     "The use of pull type '%s' for pull coordinate %d requires that the pull rate "
                     "is zero",
-                    epull_names[pcrd->eType],
+                    enumValueToString(pcrd->eType),
                     coord_index_for_output);
             warning_error(wi, buf);
         }
 
-        if (pcrd->eGeom == epullgCYL)
+        if (pcrd->eGeom == PullGroupGeometry::Cylinder)
         {
             /* Warn the user of a PBC restriction, caused by the fact that
              * there is no reference value with an external pull potential.
@@ -188,8 +190,8 @@ static void init_pull_coord(t_pull_coord* pcrd,
                     "With pull type '%s' and geometry '%s', the distance component along the "
                     "cylinder axis between atoms in the cylinder group and the COM of the pull "
                     "group should be smaller than half the box length",
-                    epull_names[pcrd->eType],
-                    epullg_names[pcrd->eGeom]);
+                    enumValueToString(pcrd->eType),
+                    enumValueToString(pcrd->eGeom));
             warning_note(wi, buf);
         }
     }
@@ -203,7 +205,7 @@ static void init_pull_coord(t_pull_coord* pcrd,
     }
 
     /* Check the given initial reference value and warn for dangerous values */
-    if (pcrd->eGeom == epullgDIST)
+    if (pcrd->eGeom == PullGroupGeometry::Distance)
     {
         if (pcrd->bStart && pcrd->init < 0)
         {
@@ -214,12 +216,12 @@ static void init_pull_coord(t_pull_coord* pcrd,
                     "this value, but only for certain starting distances. "
                     "If this is a mistake you may want to use geometry %s instead.",
                     pcrd->init,
-                    EPULLGEOM(pcrd->eGeom),
-                    EPULLGEOM(epullgDIR));
+                    enumValueToString(pcrd->eGeom),
+                    enumValueToString(PullGroupGeometry::Direction));
             warning(wi, buf);
         }
     }
-    else if (pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS)
+    else if (pcrd->eGeom == PullGroupGeometry::Angle || pcrd->eGeom == PullGroupGeometry::AngleAxis)
     {
         if (pcrd->bStart && (pcrd->init < 0 || pcrd->init > 180))
         {
@@ -230,11 +232,11 @@ static void init_pull_coord(t_pull_coord* pcrd,
                     "This may work, since you have set pull-coord-start to 'yes' which modifies "
                     "this value, but only for certain starting angles.",
                     pcrd->init,
-                    EPULLGEOM(pcrd->eGeom));
+                    enumValueToString(pcrd->eGeom));
             warning(wi, buf);
         }
     }
-    else if (pcrd->eGeom == epullgDIHEDRAL)
+    else if (pcrd->eGeom == PullGroupGeometry::Dihedral)
     {
         if (pcrd->bStart && (pcrd->init < -180 || pcrd->init > 180))
         {
@@ -244,7 +246,7 @@ static void init_pull_coord(t_pull_coord* pcrd,
                     "This may work, since you have set pull-coord-start to 'yes' which modifies "
                     "this value, but only for certain starting angles.",
                     pcrd->init,
-                    EPULLGEOM(pcrd->eGeom));
+                    enumValueToString(pcrd->eGeom));
             warning(wi, buf);
         }
     }
@@ -253,14 +255,14 @@ static void init_pull_coord(t_pull_coord* pcrd,
     clear_dvec(vec);
     string2dvec(vec_buf, vec);
 
-    if (pcrd->eGeom == epullgDIR || pcrd->eGeom == epullgCYL || pcrd->eGeom == epullgDIRPBC
-        || pcrd->eGeom == epullgANGLEAXIS)
+    if (pcrd->eGeom == PullGroupGeometry::Direction || pcrd->eGeom == PullGroupGeometry::Cylinder
+        || pcrd->eGeom == PullGroupGeometry::DirectionPBC || pcrd->eGeom == PullGroupGeometry::AngleAxis)
     {
         if (dnorm2(vec) == 0)
         {
             gmx_fatal(FARGS,
                       "With pull geometry %s the pull vector can not be 0,0,0",
-                      epullg_names[pcrd->eGeom]);
+                      enumValueToString(pcrd->eGeom));
         }
         for (int d = 0; d < DIM; d++)
         {
@@ -288,8 +290,10 @@ static void init_pull_coord(t_pull_coord* pcrd,
                     vec[0],
                     vec[1],
                     vec[2],
-                    EPULLGEOM(pcrd->eGeom),
-                    pcrd->eGeom == epullgANGLE ? EPULLGEOM(epullgANGLEAXIS) : EPULLGEOM(epullgDIR));
+                    enumValueToString(pcrd->eGeom),
+                    pcrd->eGeom == PullGroupGeometry::Angle
+                            ? enumValueToString(PullGroupGeometry::AngleAxis)
+                            : enumValueToString(PullGroupGeometry::Direction));
             warning(wi, buf);
         }
     }
@@ -311,14 +315,15 @@ std::vector<std::string> read_pullparams(std::vector<t_inpfile>* inp, pull_param
     printStringNoNewline(inp, "Cylinder radius for dynamic reaction force groups (nm)");
     pull->cylinder_r     = get_ereal(inp, "pull-cylinder-r", 1.5, wi);
     pull->constr_tol     = get_ereal(inp, "pull-constr-tol", 1E-6, wi);
-    pull->bPrintCOM      = (get_eeenum(inp, "pull-print-com", yesno_names, wi) != 0);
-    pull->bPrintRefValue = (get_eeenum(inp, "pull-print-ref-value", yesno_names, wi) != 0);
-    pull->bPrintComp     = (get_eeenum(inp, "pull-print-components", yesno_names, wi) != 0);
+    pull->bPrintCOM      = (getEnum<Boolean>(inp, "pull-print-com", wi) != Boolean::No);
+    pull->bPrintRefValue = (getEnum<Boolean>(inp, "pull-print-ref-value", wi) != Boolean::No);
+    pull->bPrintComp     = (getEnum<Boolean>(inp, "pull-print-components", wi) != Boolean::No);
     pull->nstxout        = get_eint(inp, "pull-nstxout", 50, wi);
     pull->nstfout        = get_eint(inp, "pull-nstfout", 50, wi);
-    pull->bSetPbcRefToPrevStepCOM = (get_eeenum(inp, "pull-pbc-ref-prev-step-com", yesno_names, wi) != 0);
-    pull->bXOutAverage            = (get_eeenum(inp, "pull-xout-average", yesno_names, wi) != 0);
-    pull->bFOutAverage            = (get_eeenum(inp, "pull-fout-average", yesno_names, wi) != 0);
+    pull->bSetPbcRefToPrevStepCOM =
+            (getEnum<Boolean>(inp, "pull-pbc-ref-prev-step-com", wi) != Boolean::No);
+    pull->bXOutAverage = (getEnum<Boolean>(inp, "pull-xout-average", wi) != Boolean::No);
+    pull->bFOutAverage = (getEnum<Boolean>(inp, "pull-fout-average", wi) != Boolean::No);
     printStringNoNewline(inp, "Number of pull groups");
     pull->ngroup = get_eint(inp, "pull-ngroups", 1, wi);
     printStringNoNewline(inp, "Number of pull coordinates");
@@ -365,20 +370,20 @@ std::vector<std::string> read_pullparams(std::vector<t_inpfile>* inp, pull_param
     {
         t_pull_coord pullCoord; // = &pull->coord[coordNum - 1];
         sprintf(buf, "pull-coord%d-type", coordNum);
-        pullCoord.eType = get_eeenum(inp, buf, epull_names, wi);
+        pullCoord.eType = getEnum<PullingAlgorithm>(inp, buf, wi);
         sprintf(buf, "pull-coord%d-potential-provider", coordNum);
         setStringEntry(inp, buf, provider, "");
         pullCoord.externalPotentialProvider = gmx_strdup(provider);
         sprintf(buf, "pull-coord%d-geometry", coordNum);
-        pullCoord.eGeom = get_eeenum(inp, buf, epullg_names, wi);
+        pullCoord.eGeom = getEnum<PullGroupGeometry>(inp, buf, wi);
         sprintf(buf, "pull-coord%d-groups", coordNum);
         setStringEntry(inp, buf, groups, "");
 
         switch (pullCoord.eGeom)
         {
-            case epullgDIHEDRAL: pullCoord.ngroup = 6; break;
-            case epullgDIRRELATIVE:
-            case epullgANGLE: pullCoord.ngroup = 4; break;
+            case PullGroupGeometry::Dihedral: pullCoord.ngroup = 6; break;
+            case PullGroupGeometry::DirectionRelative:
+            case PullGroupGeometry::Angle: pullCoord.ngroup = 4; break;
             default: pullCoord.ngroup = 2; break;
         }
 
@@ -397,7 +402,7 @@ std::vector<std::string> read_pullparams(std::vector<t_inpfile>* inp, pull_param
                     gmx::formatString("%s should contain %d pull group indices with geometry %s",
                                       buf,
                                       pullCoord.ngroup,
-                                      epullg_names[pullCoord.eGeom]);
+                                      enumValueToString(pullCoord.eGeom));
             set_warning_line(wi, nullptr, -1);
             warning_error(wi, message);
         }
@@ -422,7 +427,7 @@ std::vector<std::string> read_pullparams(std::vector<t_inpfile>* inp, pull_param
         sprintf(buf, "pull-coord%d-vec", coordNum);
         setStringEntry(inp, buf, vec_buf, "0.0 0.0 0.0");
         sprintf(buf, "pull-coord%d-start", coordNum);
-        pullCoord.bStart = (get_eeenum(inp, buf, yesno_names, wi) != 0);
+        pullCoord.bStart = (getEnum<Boolean>(inp, buf, wi) != Boolean::No);
         sprintf(buf, "pull-coord%d-init", coordNum);
         pullCoord.init = get_ereal(inp, buf, 0.0, wi);
         sprintf(buf, "pull-coord%d-rate", coordNum);
@@ -532,7 +537,7 @@ void checkPullCoords(gmx::ArrayRef<const t_pull_group> pullGroups, gmx::ArrayRef
             gmx_fatal(FARGS, "Identical pull group indices in pull-coord%d-groups", c + 1);
         }
 
-        if (pcrd.eGeom == epullgCYL)
+        if (pcrd.eGeom == PullGroupGeometry::Cylinder)
         {
             if (!pullGroups[pcrd.group[0]].weight.empty())
             {
@@ -557,7 +562,7 @@ pull_t* set_pull_init(t_inputrec* ir, const gmx_mtop_t* mtop, rvec* x, matrix bo
     auto mdAtoms = gmx::makeMDAtoms(nullptr, *mtop, *ir, false);
     auto md      = mdAtoms->mdatoms();
     atoms2md(mtop, ir, -1, {}, mtop->natoms, mdAtoms.get());
-    if (ir->efep)
+    if (ir->efep != FreeEnergyPerturbationType::No)
     {
         update_mdatoms(md, lambda);
     }
@@ -665,7 +670,7 @@ pull_t* set_pull_init(t_inputrec* ir, const gmx_mtop_t* mtop, rvec* x, matrix bo
             pcrd->init = value + init;
         }
 
-        if (pcrd->eGeom == epullgDIST)
+        if (pcrd->eGeom == PullGroupGeometry::Distance)
         {
             if (pcrd->init < 0)
             {
@@ -673,8 +678,8 @@ pull_t* set_pull_init(t_inputrec* ir, const gmx_mtop_t* mtop, rvec* x, matrix bo
                           "The initial pull distance (%g) needs to be non-negative with geometry "
                           "%s. If you want a signed distance, use geometry %s instead.",
                           pcrd->init,
-                          EPULLGEOM(pcrd->eGeom),
-                          EPULLGEOM(epullgDIR));
+                          enumValueToString(pcrd->eGeom),
+                          enumValueToString(PullGroupGeometry::Direction));
             }
 
             /* TODO: With a positive init but a negative rate things could still
@@ -685,7 +690,7 @@ pull_t* set_pull_init(t_inputrec* ir, const gmx_mtop_t* mtop, rvec* x, matrix bo
              * generalization of the pull code makes pull dim available here.
              */
         }
-        else if (pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgANGLEAXIS)
+        else if (pcrd->eGeom == PullGroupGeometry::Angle || pcrd->eGeom == PullGroupGeometry::AngleAxis)
         {
             if (pcrd->init < 0 || pcrd->init > 180)
             {
@@ -695,7 +700,7 @@ pull_t* set_pull_init(t_inputrec* ir, const gmx_mtop_t* mtop, rvec* x, matrix bo
                           pcrd->init);
             }
         }
-        else if (pcrd->eGeom == epullgDIHEDRAL)
+        else if (pcrd->eGeom == PullGroupGeometry::Dihedral)
         {
             if (pcrd->init < -180 || pcrd->init > 180)
             {
index 7643c5888d5c8fdce18c86847a4bf178d3ea9a06..4e725040602a64956316856a5cf6884e09c0088a 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.
@@ -111,11 +111,11 @@ extern std::vector<std::string> read_rotparams(std::vector<t_inpfile>* inp, t_ro
                              "Rotation potential. Can be iso, iso-pf, pm, pm-pf, rm, rm-pf, rm2, "
                              "rm2-pf, flex, flex-t, flex2, flex2-t");
         sprintf(buf, "rot-type%d", g);
-        rotg->eType = get_eenum(inp, buf, erotg_names);
+        rotg->eType = getEnum<EnforcedRotationGroupType>(inp, buf, wi);
 
         printStringNoNewline(inp, "Use mass-weighting of the rotation group positions");
         sprintf(buf, "rot-massw%d", g);
-        rotg->bMassW = get_eenum(inp, buf, yesno_names);
+        rotg->bMassW = getEnum<Boolean>(inp, buf, wi) != Boolean::No;
 
         printStringNoNewline(inp, "Rotation vector, will get normalized");
         sprintf(buf, "rot-vec%d", g);
@@ -135,7 +135,7 @@ extern std::vector<std::string> read_rotparams(std::vector<t_inpfile>* inp, t_ro
                 "%s Group %d (%s) normalized rot. vector: %f %f %f\n",
                 RotStr,
                 g,
-                erotg_names[rotg->eType],
+                enumValueToString(rotg->eType),
                 vec[0],
                 vec[1],
                 vec[2]);
@@ -148,8 +148,10 @@ extern std::vector<std::string> read_rotparams(std::vector<t_inpfile>* inp, t_ro
         sprintf(buf, "rot-pivot%d", g);
         setStringEntry(inp, buf, s_vec, "0.0 0.0 0.0");
         clear_dvec(vec);
-        if ((rotg->eType == erotgISO) || (rotg->eType == erotgPM) || (rotg->eType == erotgRM)
-            || (rotg->eType == erotgRM2))
+        if ((rotg->eType == EnforcedRotationGroupType::Iso)
+            || (rotg->eType == EnforcedRotationGroupType::Pm)
+            || (rotg->eType == EnforcedRotationGroupType::Rm)
+            || (rotg->eType == EnforcedRotationGroupType::Rm2))
         {
             string2dvec(s_vec, vec);
         }
@@ -194,7 +196,9 @@ extern std::vector<std::string> read_rotparams(std::vector<t_inpfile>* inp, t_ro
                 inp, "Value of additive constant epsilon' (nm^2) for rm2* and flex2* potentials");
         sprintf(buf, "rot-eps%d", g);
         rotg->eps = get_ereal(inp, buf, 1e-4, wi);
-        if ((rotg->eps <= 0.0) && (rotg->eType == erotgRM2 || rotg->eType == erotgFLEX2))
+        if ((rotg->eps <= 0.0)
+            && (rotg->eType == EnforcedRotationGroupType::Rm2
+                || rotg->eType == EnforcedRotationGroupType::Flex2))
         {
             sprintf(warn_buf, "rot-eps%d <= 0", g);
             warning_error(wi, warn_buf);
@@ -204,13 +208,13 @@ extern std::vector<std::string> read_rotparams(std::vector<t_inpfile>* inp, t_ro
                 inp,
                 "Fitting method to determine angle of rotation group (rmsd, norm, or potential)");
         sprintf(buf, "rot-fit-method%d", g);
-        rotg->eFittype = get_eenum(inp, buf, erotg_fitnames);
+        rotg->eFittype = getEnum<RotationGroupFitting>(inp, buf, wi);
         printStringNoNewline(inp,
                              "For fit type 'potential', nr. of angles around the reference for "
                              "which the pot. is evaluated");
         sprintf(buf, "rot-potfit-nsteps%d", g);
         rotg->PotAngle_nstep = get_eint(inp, buf, 21, wi);
-        if ((rotg->eFittype == erotgFitPOT) && (rotg->PotAngle_nstep < 1))
+        if ((rotg->eFittype == RotationGroupFitting::Pot) && (rotg->PotAngle_nstep < 1))
         {
             sprintf(warn_buf, "rot-potfit-nsteps%d < 1", g);
             warning_error(wi, warn_buf);
index cf702b1f9178adb9c315e3127253769e6a70c7c1..54e15169ff25a1b52eba5f40c74a039dc0ccaca6 100644 (file)
@@ -37,6 +37,8 @@
  */
 #include "gmxpre.h"
 
+#include "gromacs/utility/enumerationhelpers.h"
+#include "gromacs/utility/stringutil.h"
 #include "topio.h"
 
 #include <cassert>
@@ -87,7 +89,7 @@
 #define OPENDIR '['  /* starting sign for directive */
 #define CLOSEDIR ']' /* ending sign for directive   */
 
-static void gen_pairs(const InteractionsOfType& nbs, InteractionsOfType* pairs, real fudge, int comb)
+static void gen_pairs(const InteractionsOfType& nbs, InteractionsOfType* pairs, real fudge, CombinationRule comb)
 {
     real scaling;
     int  ntp = nbs.size();
@@ -122,7 +124,8 @@ static void gen_pairs(const InteractionsOfType& nbs, InteractionsOfType* pairs,
              * should be scaled, but not sigma.
              * The sigma values have even indices 0,2, etc.
              */
-            if ((comb == eCOMB_ARITHMETIC || comb == eCOMB_GEOM_SIG_EPS) && (j % 2 == 0))
+            if ((comb == CombinationRule::Arithmetic || comb == CombinationRule::GeomSigEps)
+                && (j % 2 == 0))
             {
                 scaling = 1.0;
             }
@@ -247,46 +250,57 @@ static void sum_q(const t_atoms* atoms, int numMols, double* qTotA, double* qTot
     *qTotB += numMols * roundedMoleculeCharge(qmolB, sumAbsQB);
 }
 
-static void get_nbparm(char* nb_str, char* comb_str, int* nb, int* comb, warninp* wi)
+static void get_nbparm(char* nb_str, char* comb_str, VanDerWaalsPotential* nb, CombinationRule* comb, warninp* wi)
 {
-    int  i;
-    char warn_buf[STRLEN];
-
-    *nb = -1;
-    for (i = 1; (i < eNBF_NR); i++)
+    *nb = VanDerWaalsPotential::Count;
+    for (auto i : gmx::EnumerationArray<VanDerWaalsPotential, bool>::keys())
     {
-        if (gmx_strcasecmp(nb_str, enbf_names[i]) == 0)
+        if (gmx_strcasecmp(nb_str, enumValueToString(i)) == 0)
         {
             *nb = i;
         }
     }
-    if (*nb == -1)
-    {
-        *nb = strtol(nb_str, nullptr, 10);
-    }
-    if ((*nb < 1) || (*nb >= eNBF_NR))
+    if (*nb == VanDerWaalsPotential::Count)
     {
-        sprintf(warn_buf, "Invalid nonbond function selector '%s' using %s", nb_str, enbf_names[1]);
-        warning_error(wi, warn_buf);
-        *nb = 1;
+        int integerValue = strtol(nb_str, nullptr, 10);
+        if ((integerValue < 1) || (integerValue >= static_cast<int>(VanDerWaalsPotential::Count)))
+        {
+            std::string message =
+                    gmx::formatString("Invalid nonbond function selector '%s' using %s",
+                                      nb_str,
+                                      enumValueToString(VanDerWaalsPotential::LJ));
+            warning_error(wi, message);
+            *nb = VanDerWaalsPotential::LJ;
+        }
+        else
+        {
+            *nb = static_cast<VanDerWaalsPotential>(integerValue);
+        }
     }
-    *comb = -1;
-    for (i = 1; (i < eCOMB_NR); i++)
+    *comb = CombinationRule::Count;
+    for (auto i : gmx::EnumerationArray<CombinationRule, bool>::keys())
     {
-        if (gmx_strcasecmp(comb_str, ecomb_names[i]) == 0)
+        if (gmx_strcasecmp(comb_str, enumValueToString(i)) == 0)
         {
             *comb = i;
         }
     }
-    if (*comb == -1)
+    if (*comb == CombinationRule::Count)
     {
-        *comb = strtol(comb_str, nullptr, 10);
-    }
-    if ((*comb < 1) || (*comb >= eCOMB_NR))
-    {
-        sprintf(warn_buf, "Invalid combination rule selector '%s' using %s", comb_str, ecomb_names[1]);
-        warning_error(wi, warn_buf);
-        *comb = 1;
+        int integerValue = strtol(comb_str, nullptr, 10);
+        if ((integerValue < 1) || (integerValue >= static_cast<int>(CombinationRule::Count)))
+        {
+            std::string message =
+                    gmx::formatString("Invalid combination rule selector '%s' using %s",
+                                      comb_str,
+                                      enumValueToString(CombinationRule::Geometric));
+            warning_error(wi, message);
+            *comb = CombinationRule::Geometric;
+        }
+        else
+        {
+            *comb = static_cast<CombinationRule>(integerValue);
+        }
     }
 }
 
@@ -383,7 +397,7 @@ static char** read_topol(const char*                           infile,
                          std::vector<MoleculeInformation>*     molinfo,
                          std::unique_ptr<MoleculeInformation>* intermolecular_interactions,
                          gmx::ArrayRef<InteractionsOfType>     interactions,
-                         int*                                  combination_rule,
+                         CombinationRule*                      combination_rule,
                          double*                               reppow,
                          t_gromppopts*                         opts,
                          real*                                 fudgeQQ,
@@ -396,7 +410,7 @@ static char** read_topol(const char*                           infile,
                          const gmx::MDLogger&                  logger)
 {
     FILE*                out;
-    int                  sl, nb_funct;
+    int                  sl;
     char *               pline = nullptr, **title = nullptr;
     char                 line[STRLEN], errbuf[256], comb_str[256], nb_str[256];
     char                 genpairs[32];
@@ -447,7 +461,7 @@ static char** read_topol(const char*                           infile,
     nbparam = nullptr;              /* The temporary non-bonded matrix */
     pair    = nullptr;              /* The temporary pair interaction matrix */
     std::vector<std::vector<gmx::ExclusionBlock>> exclusionBlocks;
-    nb_funct = F_LJ;
+    VanDerWaalsPotential                          nb_funct = VanDerWaalsPotential::LJ;
 
     *reppow = 12.0; /* Default value for repulsion power     */
 
@@ -618,7 +632,7 @@ static char** read_topol(const char*                           infile,
                                 if (nscan >= 3)
                                 {
                                     bGenPairs = (gmx::equalCaseInsensitive(genpairs, "Y", 1));
-                                    if (nb_funct != eNBF_LJ && bGenPairs)
+                                    if (nb_funct != VanDerWaalsPotential::LJ && bGenPairs)
                                     {
                                         gmx_fatal(FARGS,
                                                   "Generating pair parameters is only supported "
@@ -638,7 +652,8 @@ static char** read_topol(const char*                           infile,
                                     *reppow = fPOW;
                                 }
                             }
-                            nb_funct = ifunc_index(Directive::d_nonbond_params, nb_funct);
+                            nb_funct = static_cast<VanDerWaalsPotential>(ifunc_index(
+                                    Directive::d_nonbond_params, static_cast<int>(nb_funct)));
 
                             break;
                         case Directive::d_atomtypes:
@@ -646,7 +661,7 @@ static char** read_topol(const char*                           infile,
                                     atypes,
                                     &bondAtomType,
                                     pline,
-                                    nb_funct,
+                                    static_cast<int>(nb_funct),
                                     &nbparam,
                                     bGenPairs ? &pair : nullptr,
                                     wi);
@@ -675,7 +690,7 @@ static char** read_topol(const char*                           infile,
                             break;
 
                         case Directive::d_nonbond_params:
-                            push_nbt(d, nbparam, atypes, pline, nb_funct, wi);
+                            push_nbt(d, nbparam, atypes, pline, static_cast<int>(nb_funct), wi);
                             break;
 
                         case Directive::d_implicit_genborn_params: // NOLINT bugprone-branch-clone
@@ -709,9 +724,15 @@ static char** read_topol(const char*                           infile,
                                 }
                                 ntype  = atypes->size();
                                 ncombs = (ntype * (ntype + 1)) / 2;
-                                generate_nbparams(
-                                        *combination_rule, nb_funct, &(interactions[nb_funct]), atypes, wi);
-                                ncopy = copy_nbparams(nbparam, nb_funct, &(interactions[nb_funct]), ntype);
+                                generate_nbparams(*combination_rule,
+                                                  static_cast<int>(nb_funct),
+                                                  &(interactions[static_cast<int>(nb_funct)]),
+                                                  atypes,
+                                                  wi);
+                                ncopy = copy_nbparams(nbparam,
+                                                      static_cast<int>(nb_funct),
+                                                      &(interactions[static_cast<int>(nb_funct)]),
+                                                      ntype);
                                 GMX_LOG(logger.info)
                                         .asParagraph()
                                         .appendTextFormatted(
@@ -722,11 +743,12 @@ static char** read_topol(const char*                           infile,
                                 free_nbparam(nbparam, ntype);
                                 if (bGenPairs)
                                 {
-                                    gen_pairs((interactions[nb_funct]),
+                                    gen_pairs((interactions[static_cast<int>(nb_funct)]),
                                               &(interactions[F_LJ14]),
                                               fudgeLJ,
                                               *combination_rule);
-                                    ncopy = copy_nbparams(pair, nb_funct, &(interactions[F_LJ14]), ntype);
+                                    ncopy = copy_nbparams(
+                                            pair, static_cast<int>(nb_funct), &(interactions[F_LJ14]), ntype);
                                     GMX_LOG(logger.info)
                                             .asParagraph()
                                             .appendTextFormatted(
@@ -898,8 +920,8 @@ static char** read_topol(const char*                           infile,
                                                            opts->couple_lam0,
                                                            opts->couple_lam1,
                                                            opts->bCoupleIntra,
-                                                           nb_funct,
-                                                           &(interactions[nb_funct]),
+                                                           static_cast<int>(nb_funct),
+                                                           &(interactions[static_cast<int>(nb_funct)]),
                                                            wi);
                                 }
                                 stupid_fill_block(&mi0->mols, mi0->atoms.nr, TRUE);
@@ -1025,7 +1047,7 @@ char** do_top(bool                                  bVerbose,
               bool                                  bZero,
               t_symtab*                             symtab,
               gmx::ArrayRef<InteractionsOfType>     interactions,
-              int*                                  combination_rule,
+              CombinationRule*                      combination_rule,
               double*                               repulsion_power,
               real*                                 fudgeQQ,
               PreprocessingAtomTypes*               atypes,
@@ -1069,13 +1091,13 @@ char** do_top(bool                                  bVerbose,
                        fudgeQQ,
                        molblock,
                        ffParametrizedWithHBondConstraints,
-                       ir->efep != efepNO,
+                       ir->efep != FreeEnergyPerturbationType::No,
                        bZero,
                        EEL_FULL(ir->coulombtype),
                        wi,
                        logger);
 
-    if ((*combination_rule != eCOMB_GEOMETRIC) && (ir->vdwtype == evdwUSER))
+    if ((*combination_rule != CombinationRule::Geometric) && (ir->vdwtype == VanDerWaalsType::User))
     {
         warning(wi,
                 "Using sigma/epsilon based combination rules with"
index f39c8ec2f0fe17a100ac8deef983120655ca5dd6..96ee43e1e3c9c6dcfa9e3dc6ffdf1d7fa4bcb836 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) 2012,2014,2015,2016,2018 by 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.
@@ -54,6 +54,7 @@ struct InteractionsOfType;
 struct t_symtab;
 struct warninp;
 typedef warninp* warninp_t;
+enum class CombinationRule : int;
 
 namespace gmx
 {
@@ -72,7 +73,7 @@ char** do_top(bool                                  bVerbose,
               bool                                  bZero,
               t_symtab*                             symtab,
               gmx::ArrayRef<InteractionsOfType>     plist,
-              int*                                  combination_rule,
+              CombinationRule*                      combination_rule,
               double*                               repulsion_power,
               real*                                 fudgeQQ,
               PreprocessingAtomTypes*               atype,
index ba67deb03cfee6ee0693a2bf800f3cb168d6d558..27bc433640cca62ea2ceb69da7a8e1ce3af5bdd9 100644 (file)
@@ -67,7 +67,7 @@
 #include "gromacs/utility/smalloc.h"
 #include "gromacs/utility/stringutil.h"
 
-void generate_nbparams(int                     comb,
+void generate_nbparams(CombinationRule         comb,
                        int                     ftype,
                        InteractionsOfType*     interactions,
                        PreprocessingAtomTypes* atypes,
@@ -88,7 +88,7 @@ void generate_nbparams(int                     comb,
         case F_LJ:
             switch (comb)
             {
-                case eCOMB_GEOMETRIC:
+                case CombinationRule::Geometric:
                     /* Gromos rules */
                     for (int i = 0; (i < nr); i++)
                     {
@@ -106,7 +106,7 @@ void generate_nbparams(int                     comb,
                     }
                     break;
 
-                case eCOMB_ARITHMETIC:
+                case CombinationRule::Arithmetic:
                     /* c0 and c1 are sigma and epsilon */
                     for (int i = 0; (i < nr); i++)
                     {
@@ -130,7 +130,7 @@ void generate_nbparams(int                     comb,
                     }
 
                     break;
-                case eCOMB_GEOM_SIG_EPS:
+                case CombinationRule::GeomSigEps:
                     /* c0 and c1 are sigma and epsilon */
                     for (int i = 0; (i < nr); i++)
                     {
@@ -155,7 +155,8 @@ void generate_nbparams(int                     comb,
 
                     break;
                 default:
-                    auto message = gmx::formatString("No such combination rule %d", comb);
+                    auto message =
+                            gmx::formatString("No such combination rule %s", enumValueToString(comb));
                     warning_error_and_exit(wi, message, FARGS);
             }
             break;
index 66df62b9d303446f36f023f708b54d2063a07cb3..302af131afab39db3b965a760e684da94c8d85d1 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,2018 by 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.
@@ -54,7 +54,7 @@ class InteractionOfType;
 struct InteractionsOfType;
 struct PreprocessResidue;
 struct warninp;
-
+enum class CombinationRule : int;
 namespace gmx
 {
 template<typename>
@@ -62,7 +62,11 @@ class ArrayRef;
 struct ExclusionBlock;
 } // namespace gmx
 
-void generate_nbparams(int comb, int funct, InteractionsOfType* plist, PreprocessingAtomTypes* atype, warninp* wi);
+void generate_nbparams(CombinationRule         comb,
+                       int                     funct,
+                       InteractionsOfType*     plist,
+                       PreprocessingAtomTypes* atype,
+                       warninp*                wi);
 
 void push_at(struct t_symtab*           symtab,
              PreprocessingAtomTypes*    at,
index 995c4da8dfd8ca99362429b3533bc764d085a3c7..cf1a9d81da7f24375995d2721728e4e8b64cac6c 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 2014,2015,2016,2017,2018 by 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.
@@ -1286,7 +1286,8 @@ static void imd_check_integrator_parallel(const t_inputrec* ir, const t_commrec*
 {
     if (PAR(cr))
     {
-        if (((ir->eI) == eiSteep) || ((ir->eI) == eiCG) || ((ir->eI) == eiLBFGS) || ((ir->eI) == eiNM))
+        if (((ir->eI) == IntegrationAlgorithm::Steep) || ((ir->eI) == IntegrationAlgorithm::CG)
+            || ((ir->eI) == IntegrationAlgorithm::LBFGS) || ((ir->eI) == IntegrationAlgorithm::NM))
         {
             gmx_fatal(FARGS,
                       "%s Energy minimization via steep, CG, lbfgs and nm in parallel is currently "
@@ -1343,7 +1344,7 @@ std::unique_ptr<ImdSession> makeImdSession(const t_inputrec*           ir,
                         "%s Integrator '%s' is not supported for Interactive Molecular Dynamics, "
                         "running normally instead",
                         IMDstr,
-                        ei_names[ir->eI]);
+                        enumValueToString(ir->eI));
         return session;
     }
     if (isMultiSim(ms))
index 1095ab94df32935603332f5d10889c3de1daa114..91f61c4f10468c58853aab94f305d59354b96ad8 100644 (file)
@@ -138,7 +138,7 @@ void init_disres(FILE*                 fplog,
     iloop     = gmx_mtop_ilistloop_init(mtop);
     while (const InteractionLists* il = gmx_mtop_ilistloop_next(iloop, &nmol))
     {
-        if (nmol > 1 && !(*il)[F_DISRES].empty() && ir->eDisre != edrEnsemble)
+        if (nmol > 1 && !(*il)[F_DISRES].empty() && ir->eDisre != DistanceRestraintRefinement::Ensemble)
         {
             gmx_fatal(FARGS,
                       "NMR distance restraints with multiple copies of the same molecule are "
@@ -158,7 +158,7 @@ void init_disres(FILE*                 fplog,
             npair = mtop->ffparams.iparams[type].disres.npair;
             if (np == npair)
             {
-                dd->nres += (ir->eDisre == edrEnsemble ? 1 : nmol);
+                dd->nres += (ir->eDisre == DistanceRestraintRefinement::Ensemble ? 1 : nmol);
                 dd->npair += nmol * npair;
                 np = 0;
 
@@ -440,14 +440,13 @@ real ta_disres(int              nfa,
     real     tav_viol_Rtav7, instant_viol_Rtav7;
     real     up1, up2, low;
     gmx_bool bConservative, bMixed, bViolation;
-    int      dr_weighting;
     gmx_bool dr_bMixed;
 
-    dr_weighting = disresdata->dr_weighting;
-    dr_bMixed    = disresdata->dr_bMixed;
-    Rtl_6        = disresdata->Rtl_6;
-    Rt_6         = disresdata->Rt_6;
-    Rtav_6       = disresdata->Rtav_6;
+    DistanceRestraintWeighting dr_weighting = disresdata->dr_weighting;
+    dr_bMixed                               = disresdata->dr_bMixed;
+    Rtl_6                                   = disresdata->Rtl_6;
+    Rt_6                                    = disresdata->Rt_6;
+    Rtav_6                                  = disresdata->Rtav_6;
 
     tav_viol = instant_viol = mixed_viol = tav_viol_Rtav7 = instant_viol_Rtav7 = 0;
 
@@ -479,7 +478,7 @@ real ta_disres(int              nfa,
         /* save some flops when there is only one pair */
         if (ip[type].disres.type != 2)
         {
-            bConservative = (dr_weighting == edrwConservative) && (npair > 1);
+            bConservative = (dr_weighting == DistanceRestraintWeighting::Conservative) && (npair > 1);
             bMixed        = dr_bMixed;
             Rt            = gmx::invsixthroot(Rt_6[res]);
             Rtav          = gmx::invsixthroot(Rtav_6[res]);
index 10e54fb419a2e07a43fd4aa8d8d40de8da1cf976..0364a2d7349a86b6a0f60b60aa32b2b558e85e49 100644 (file)
@@ -44,6 +44,8 @@
  */
 #include "gmxpre.h"
 
+#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "listed_forces.h"
 
 #include <cassert>
@@ -226,7 +228,7 @@ void zero_thread_output(f_thread_t* f_t)
             f_t->grpp.ener[i][j] = 0;
         }
     }
-    for (int i = 0; i < efptNR; i++)
+    for (auto i : keysOf(f_t->dvdl))
     {
         f_t->dvdl[i] = 0;
     }
@@ -298,7 +300,7 @@ void reduce_thread_forces(gmx::ArrayRef<gmx::RVec> force, const bonded_threading
 void reduce_thread_output(gmx::ForceWithShiftForces* forceWithShiftForces,
                           real*                      ener,
                           gmx_grppairener_t*         grpp,
-                          real*                      dvdl,
+                          gmx::ArrayRef<real>        dvdl,
                           const bonded_threading_t*  bt,
                           const gmx::StepWorkload&   stepWork)
 {
@@ -349,12 +351,12 @@ void reduce_thread_output(gmx::ForceWithShiftForces* forceWithShiftForces,
         }
         if (stepWork.computeDhdl)
         {
-            for (int i = 0; i < efptNR; i++)
+            for (auto i : keysOf(f_t[1]->dvdl))
             {
 
                 for (int t = 1; t < bt->nthreads; t++)
                 {
-                    dvdl[i] += f_t[t]->dvdl[i];
+                    dvdl[static_cast<int>(i)] += f_t[t]->dvdl[i];
                 }
             }
         }
@@ -414,8 +416,8 @@ real calc_one_bond(int                           thread,
                    const t_pbc*                  pbc,
                    gmx_grppairener_t*            grpp,
                    t_nrnb*                       nrnb,
-                   const real*                   lambda,
-                   real*                         dvdl,
+                   gmx::ArrayRef<const real>     lambda,
+                   gmx::ArrayRef<real>           dvdl,
                    const t_mdatoms*              md,
                    t_fcdata*                     fcd,
                    const gmx::StepWorkload&      stepWork,
@@ -428,14 +430,14 @@ real calc_one_bond(int                           thread,
             (idef.ilsort == ilsortFE_SORTED && numNonperturbedInteractions < iatoms.ssize());
     BondedKernelFlavor flavor =
             selectBondedKernelFlavor(stepWork, fr->use_simd_kernels, havePerturbedInteractions);
-    int efptFTYPE;
+    FreeEnergyPerturbationCouplingType efptFTYPE;
     if (IS_RESTRAINT_TYPE(ftype))
     {
-        efptFTYPE = efptRESTRAINT;
+        efptFTYPE = FreeEnergyPerturbationCouplingType::Restraint;
     }
     else
     {
-        efptFTYPE = efptBONDED;
+        efptFTYPE = FreeEnergyPerturbationCouplingType::Bonded;
     }
 
     const int nat1   = interaction_function[ftype].nratoms + 1;
@@ -466,8 +468,8 @@ real calc_one_bond(int                           thread,
                           f,
                           fshift,
                           pbc,
-                          lambda[efptFTYPE],
-                          &(dvdl[efptFTYPE]),
+                          lambda[static_cast<int>(efptFTYPE)],
+                          &(dvdl[static_cast<int>(efptFTYPE)]),
                           md,
                           fcd,
                           nullptr,
@@ -484,8 +486,8 @@ real calc_one_bond(int                           thread,
                                     f,
                                     fshift,
                                     pbc,
-                                    lambda[efptFTYPE],
-                                    &(dvdl[efptFTYPE]),
+                                    lambda[static_cast<int>(efptFTYPE)],
+                                    &(dvdl[static_cast<int>(efptFTYPE)]),
                                     md,
                                     fcd,
                                     fcd->disres,
@@ -507,8 +509,8 @@ real calc_one_bond(int                           thread,
                  f,
                  fshift,
                  pbc,
-                 lambda,
-                 dvdl,
+                 lambda.data(),
+                 dvdl.data(),
                  md,
                  fr,
                  havePerturbedInteractions,
@@ -537,8 +539,8 @@ static void calcBondedForces(const InteractionDefinitions& idef,
                              rvec*                         fshiftMasterBuffer,
                              gmx_enerdata_t*               enerd,
                              t_nrnb*                       nrnb,
-                             const real*                   lambda,
-                             real*                         dvdl,
+                             gmx::ArrayRef<const real>     lambda,
+                             gmx::ArrayRef<real>           dvdl,
                              const t_mdatoms*              md,
                              t_fcdata*                     fcd,
                              const gmx::StepWorkload&      stepWork,
@@ -553,9 +555,9 @@ static void calcBondedForces(const InteractionDefinitions& idef,
             int         ftype;
             real *      epot, v;
             /* thread stuff */
-            rvec*              fshift;
-            real*              dvdlt;
-            gmx_grppairener_t* grpp;
+            rvec*               fshift;
+            gmx::ArrayRef<real> dvdlt;
+            gmx_grppairener_t*  grpp;
 
             zero_thread_output(&threadBuffers);
 
@@ -643,7 +645,7 @@ void calc_listed(struct gmx_wallcycle*         wcycle,
                  const t_pbc*                  pbc,
                  gmx_enerdata_t*               enerd,
                  t_nrnb*                       nrnb,
-                 const real*                   lambda,
+                 gmx::ArrayRef<const real>     lambda,
                  const t_mdatoms*              md,
                  t_fcdata*                     fcd,
                  int*                          global_atom_index,
@@ -656,7 +658,7 @@ void calc_listed(struct gmx_wallcycle*         wcycle,
         wallcycle_sub_start(wcycle, ewcsLISTED);
         /* The dummy array is to have a place to store the dhdl at other values
            of lambda, which will be thrown away in the end */
-        real dvdl[efptNR] = { 0 };
+        gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> dvdl = { 0 };
         calcBondedForces(idef,
                          bt,
                          x,
@@ -678,7 +680,7 @@ void calc_listed(struct gmx_wallcycle*         wcycle,
 
         if (stepWork.computeDhdl)
         {
-            for (int i = 0; i < efptNR; i++)
+            for (auto i : keysOf(enerd->dvdl_lin))
             {
                 enerd->dvdl_nonlin[i] += dvdl[i];
             }
@@ -709,7 +711,7 @@ void calc_listed_lambda(const InteractionDefinitions& idef,
                         real*                         epot,
                         gmx::ArrayRef<real>           dvdl,
                         t_nrnb*                       nrnb,
-                        const real*                   lambda,
+                        gmx::ArrayRef<const real>     lambda,
                         const t_mdatoms*              md,
                         t_fcdata*                     fcd,
                         int*                          global_atom_index)
@@ -766,7 +768,7 @@ void calc_listed_lambda(const InteractionDefinitions& idef,
                                        grpp,
                                        nrnb,
                                        lambda,
-                                       dvdl.data(),
+                                       dvdl,
                                        md,
                                        fcd,
                                        tempFlags,
@@ -793,7 +795,7 @@ void ListedForces::calculate(struct gmx_wallcycle*                     wcycle,
                              const struct t_pbc*                       pbc,
                              gmx_enerdata_t*                           enerd,
                              t_nrnb*                                   nrnb,
-                             const real*                               lambda,
+                             gmx::ArrayRef<const real>                 lambda,
                              const t_mdatoms*                          md,
                              int*                                      global_atom_index,
                              const gmx::StepWorkload&                  stepWork)
@@ -874,7 +876,7 @@ void ListedForces::calculate(struct gmx_wallcycle*                     wcycle,
      */
     if (fepvals->n_lambda > 0 && stepWork.computeDhdl)
     {
-        real dvdl[efptNR] = { 0 };
+        gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> dvdl = { 0 };
         if (!idef.il[F_POSRES].empty())
         {
             posres_wrapper_lambda(wcycle, fepvals, idef, &pbc_full, x, enerd, lambda, fr);
@@ -888,12 +890,12 @@ void ListedForces::calculate(struct gmx_wallcycle*                     wcycle,
             }
             for (int i = 0; i < 1 + enerd->foreignLambdaTerms.numLambdas(); i++)
             {
-                real lam_i[efptNR];
+                gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> lam_i;
 
                 reset_foreign_enerdata(enerd);
-                for (int j = 0; j < efptNR; j++)
+                for (auto j : keysOf(lam_i))
                 {
-                    lam_i[j] = (i == 0 ? lambda[j] : fepvals->all_lambda[j][i - 1]);
+                    lam_i[j] = (i == 0 ? lambda[static_cast<int>(j)] : fepvals->all_lambda[j][i - 1]);
                 }
                 calc_listed_lambda(idef,
                                    threading_.get(),
index d82a293b61ce5c84ae523b116be81fff440cdc05..0cf099b5ab802517d7fb78b920e713c0c98a3009 100644 (file)
@@ -108,20 +108,20 @@ class ArrayRefWithPadding;
 } // namespace gmx
 
 //! Type of CPU function to compute a bonded interaction.
-using BondedFunction = real (*)(int              nbonds,
-                                const t_iatom    iatoms[],
-                                const t_iparams  iparams[],
-                                const rvec       x[],
-                                rvec4            f[],
-                                rvec             fshift[],
-                                const t_pbc*     pbc,
-                                real             lambda,
-                                real*            dvdlambda,
-                                const t_mdatoms* md,
-                                t_fcdata*        fcd,
-                                t_disresdata*    disresdata,
-                                t_oriresdata*    oriresdata,
-                                int*             ddgatindex);
+using BondedFunction = real (*)(int                 nbonds,
+                                const t_iatom       iatoms[],
+                                const t_iparams     iparams[],
+                                const rvec          x[],
+                                rvec4               f[],
+                                rvec                fshift[],
+                                const t_pbc*        pbc,
+                                real                lambda,
+                                gmx::ArrayRef<real> dvdlambda,
+                                const t_mdatoms*    md,
+                                t_fcdata*           fcd,
+                                t_disresdata*       disresdata,
+                                t_oriresdata*       oriresdata,
+                                int*                ddgatindex);
 
 //! Getter for finding a callable CPU function to compute an \c ftype interaction.
 BondedFunction bondedFunction(int ftype);
@@ -203,7 +203,7 @@ public:
                    const struct t_pbc*                       pbc,
                    gmx_enerdata_t*                           enerd,
                    t_nrnb*                                   nrnb,
-                   const real*                               lambda,
+                   gmx::ArrayRef<const real>                 lambda,
                    const t_mdatoms*                          md,
                    int*                                      global_atom_index,
                    const gmx::StepWorkload&                  stepWork);
index 2e130dcb835930729d9623cb47413bd9a98721eb..5013a6917a2b1cb31ce2ea57fbcdf2c22b6fbe67 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 2014,2015,2016,2017,2018 by 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.
@@ -54,6 +54,7 @@
 #include "gromacs/utility/alignedallocator.h"
 #include "gromacs/utility/bitmask.h"
 #include "gromacs/utility/classhelpers.h"
+#include "gromacs/utility/enumerationhelpers.h"
 
 /* We reduce the force array in blocks of 32 atoms. This is large enough
  * to not cause overhead and 32*sizeof(rvec) is a multiple of the cache-line
@@ -117,7 +118,7 @@ struct f_thread_t
     //! Group pair energy data for pairs
     gmx_grppairener_t grpp;
     //! Free-energy dV/dl output
-    real dvdl[efptNR];
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> dvdl;
 
     GMX_DISALLOW_COPY_MOVE_AND_ASSIGN(f_thread_t);
 };
index b742311a43ab41868fda2236a818d2888d447b41..77c78746fddb9ad54a2b70c84672fc82df963d59 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 2014,2015,2016,2017,2018 by 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.
@@ -331,8 +331,8 @@ static real free_energy_evaluate_single(real
                     + LFV[i] * alpha_vdw_eff * dlfac_vdw[i] * fscal_vdw[i] * sigma_pow[i];
     }
 
-    dvdl[efptCOUL] += dvdl_coul;
-    dvdl[efptVDW] += dvdl_vdw;
+    dvdl[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)] += dvdl_coul;
+    dvdl[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)] += dvdl_vdw;
 
     *velectot = velecsum;
     *vvdwtot  = vvdwsum;
@@ -389,13 +389,13 @@ static real do_pairs_general(int                 ftype,
             gmx_fatal(FARGS, "Unknown function type %d in do_nonbonded14", ftype);
     }
 
-    if (fr->efep != efepNO)
+    if (fr->efep != FreeEnergyPerturbationType::No)
     {
         /* Lambda factor for state A=1-lambda and B=lambda */
-        LFC[0] = 1.0 - lambda[efptCOUL];
-        LFV[0] = 1.0 - lambda[efptVDW];
-        LFC[1] = lambda[efptCOUL];
-        LFV[1] = lambda[efptVDW];
+        LFC[0] = 1.0 - lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)];
+        LFV[0] = 1.0 - lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)];
+        LFC[1] = lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)];
+        LFV[1] = lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)];
 
         /*derivative of the lambda factor for state A and B */
         DLF[0] = -1;
@@ -439,7 +439,7 @@ static real do_pairs_general(int                 ftype,
         switch (ftype)
         {
             case F_LJ14:
-                bFreeEnergy = (fr->efep != efepNO
+                bFreeEnergy = (fr->efep != FreeEnergyPerturbationType::No
                                && (((md->nPerturbed != 0) && (md->bPerturbed[ai] || md->bPerturbed[aj]))
                                    || iparams[itype].lj14.c6A != iparams[itype].lj14.c6B
                                    || iparams[itype].lj14.c12A != iparams[itype].lj14.c12B));
@@ -684,7 +684,7 @@ void do_pairs(int                      ftype,
               gmx_grppairener_t*       grppener,
               int*                     global_atom_index)
 {
-    if (ftype == F_LJ14 && fr->ic->vdwtype != evdwUSER && !EEL_USER(fr->ic->eeltype)
+    if (ftype == F_LJ14 && fr->ic->vdwtype != VanDerWaalsType::User && !EEL_USER(fr->ic->eeltype)
         && !havePerturbedInteractions && (!stepWork.computeVirial && !stepWork.computeEnergy))
     {
         /* We use a fast code-path for plain LJ 1-4 without FEP.
index ebd3d99cccbc308556f23774b703c2873ccc909b..aa881af20d6c3e0ec7b556797bb533666b959863 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 2014,2015,2016,2017,2018 by 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.
@@ -45,6 +45,7 @@
 
 #include "gmxpre.h"
 
+#include "gromacs/utility/arrayref.h"
 #include "position_restraints.h"
 
 #include <cassert>
@@ -71,18 +72,18 @@ namespace
 
 /*! \brief returns dx, rdist, and dpdl for functions posres() and fbposres()
  */
-void posres_dx(const rvec   x,
-               const rvec   pos0A,
-               const rvec   pos0B,
-               const rvec   comA_sc,
-               const rvec   comB_sc,
-               real         lambda,
-               const t_pbc* pbc,
-               int          refcoord_scaling,
-               int          npbcdim,
-               rvec         dx,
-               rvec         rdist,
-               rvec         dpdl)
+void posres_dx(const rvec      x,
+               const rvec      pos0A,
+               const rvec      pos0B,
+               const rvec      comA_sc,
+               const rvec      comB_sc,
+               real            lambda,
+               const t_pbc*    pbc,
+               RefCoordScaling refcoord_scaling,
+               int             npbcdim,
+               rvec            dx,
+               rvec            rdist,
+               rvec            dpdl)
 {
     int  m, d;
     real posA, posB, L1, ref = 0.;
@@ -98,12 +99,12 @@ void posres_dx(const rvec   x,
         {
             switch (refcoord_scaling)
             {
-                case erscNO:
+                case RefCoordScaling::No:
                     ref      = 0;
                     rdist[m] = L1 * posA + lambda * posB;
                     dpdl[m]  = posB - posA;
                     break;
-                case erscALL:
+                case RefCoordScaling::All:
                     /* Box relative coordinates are stored for dimensions with pbc */
                     posA *= pbc->box[m][m];
                     posB *= pbc->box[m][m];
@@ -117,7 +118,7 @@ void posres_dx(const rvec   x,
                     rdist[m] = 0;
                     dpdl[m]  = posB - posA;
                     break;
-                case erscCOM:
+                case RefCoordScaling::Com:
                     ref      = L1 * comA_sc[m] + lambda * comB_sc[m];
                     rdist[m] = L1 * posA + lambda * posB;
                     dpdl[m]  = comB_sc[m] - comA_sc[m] + posB - posA;
@@ -194,7 +195,7 @@ real fbposres(int                   nbonds,
               const rvec            x[],
               gmx::ForceWithVirial* forceWithVirial,
               const t_pbc*          pbc,
-              int                   refcoord_scaling,
+              RefCoordScaling       refcoord_scaling,
               PbcType               pbcType,
               const rvec            com)
 /* compute flat-bottomed positions restraints */
@@ -208,7 +209,7 @@ real fbposres(int                   nbonds,
 
     npbcdim = numPbcDimensions(pbcType);
     GMX_ASSERT((pbcType == PbcType::No) == (npbcdim == 0), "");
-    if (refcoord_scaling == erscCOM)
+    if (refcoord_scaling == RefCoordScaling::Com)
     {
         clear_rvec(com_sc);
         for (m = 0; m < npbcdim; m++)
@@ -337,7 +338,7 @@ real posres(int                   nbonds,
             const struct t_pbc*   pbc,
             real                  lambda,
             real*                 dvdlambda,
-            int                   refcoord_scaling,
+            RefCoordScaling       refcoord_scaling,
             PbcType               pbcType,
             const rvec            comA,
             const rvec            comB)
@@ -349,7 +350,7 @@ real posres(int                   nbonds,
 
     npbcdim = numPbcDimensions(pbcType);
     GMX_ASSERT((pbcType == PbcType::No) == (npbcdim == 0), "");
-    if (refcoord_scaling == erscCOM)
+    if (refcoord_scaling == RefCoordScaling::Com)
     {
         clear_rvec(comA_sc);
         clear_rvec(comB_sc);
@@ -426,7 +427,7 @@ void posres_wrapper(t_nrnb*                       nrnb,
                     const struct t_pbc*           pbc,
                     const rvec*                   x,
                     gmx_enerdata_t*               enerd,
-                    const real*                   lambda,
+                    gmx::ArrayRef<const real>     lambda,
                     const t_forcerec*             fr,
                     gmx::ForceWithVirial*         forceWithVirial)
 {
@@ -439,7 +440,7 @@ void posres_wrapper(t_nrnb*                       nrnb,
                      x,
                      forceWithVirial,
                      fr->pbcType == PbcType::No ? nullptr : pbc,
-                     lambda[efptRESTRAINT],
+                     lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Restraint)],
                      &dvdl,
                      fr->rc_scaling,
                      fr->pbcType,
@@ -449,7 +450,7 @@ void posres_wrapper(t_nrnb*                       nrnb,
     /* If just the force constant changes, the FEP term is linear,
      * but if k changes, it is not.
      */
-    enerd->dvdl_nonlin[efptRESTRAINT] += dvdl;
+    enerd->dvdl_nonlin[FreeEnergyPerturbationCouplingType::Restraint] += dvdl;
     inc_nrnb(nrnb, eNR_POSRES, gmx::exactDiv(idef.il[F_POSRES].size(), 2));
 }
 
@@ -459,7 +460,7 @@ void posres_wrapper_lambda(struct gmx_wallcycle*         wcycle,
                            const struct t_pbc*           pbc,
                            const rvec                    x[],
                            gmx_enerdata_t*               enerd,
-                           const real*                   lambda,
+                           gmx::ArrayRef<const real>     lambda,
                            const t_forcerec*             fr)
 {
     wallcycle_sub_start_nocount(wcycle, ewcsRESTRAINTS);
@@ -470,7 +471,8 @@ void posres_wrapper_lambda(struct gmx_wallcycle*         wcycle,
         real dvdl = 0;
 
         const real lambda_dum =
-                (i == 0 ? lambda[efptRESTRAINT] : fepvals->all_lambda[efptRESTRAINT][i - 1]);
+                (i == 0 ? lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Restraint)]
+                        : fepvals->all_lambda[FreeEnergyPerturbationCouplingType::Restraint][i - 1]);
         const real v = posres<false>(idef.il[F_POSRES].size(),
                                      idef.il[F_POSRES].iatoms.data(),
                                      idef.iparams_posres.data(),
index 5d3148fb33aac3e5c986661c9dd188745c629f72..3fc8d0020c76421e0c09f8696f26c207376800b6 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,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.
@@ -51,6 +51,7 @@
 #include <stdio.h>
 
 #include "gromacs/math/vectypes.h"
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/real.h"
 
 struct gmx_enerdata_t;
@@ -72,7 +73,7 @@ void posres_wrapper(t_nrnb*                       nrnb,
                     const struct t_pbc*           pbc,
                     const rvec*                   x,
                     gmx_enerdata_t*               enerd,
-                    const real*                   lambda,
+                    gmx::ArrayRef<const real>     lambda,
                     const t_forcerec*             fr,
                     gmx::ForceWithVirial*         forceWithVirial);
 
@@ -84,7 +85,7 @@ void posres_wrapper_lambda(struct gmx_wallcycle*         wcycle,
                            const struct t_pbc*           pbc,
                            const rvec                    x[],
                            gmx_enerdata_t*               enerd,
-                           const real*                   lambda,
+                           gmx::ArrayRef<const real>     lambda,
                            const t_forcerec*             fr);
 
 /*! \brief Helper function that wraps calls to fbposres for
index 4ab660a823ae573eabdb965cd87143a319bad844..7f2919765d9ce50fd2d50af3ea6b87d01ed1aee3 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.
@@ -78,7 +78,11 @@ void broadcastStateWithoutDynamics(MPI_Comm communicator,
         {
             switch (i)
             {
-                case estLAMBDA: nblock_bc(communicator, efptNR, state->lambda.data()); break;
+                case estLAMBDA:
+                    nblock_bc(communicator,
+                              static_cast<int>(FreeEnergyPerturbationCouplingType::Count),
+                              state->lambda.data());
+                    break;
                 case estFEPSTATE: block_bc(communicator, state->fep_state); break;
                 case estBOX: block_bc(communicator, state->box); break;
                 case estX: bcastPaddedRVecVector(communicator, &state->x, state->natoms); break;
index 3ff12f3342104ba246a099bce52b597f171c90c0..4cb664fa0ba8e362b1c4a28d660980924f3307f9 100644 (file)
@@ -785,7 +785,7 @@ static real displacementVariance(const t_inputrec& ir, real temperature, real ti
 {
     real kT_fac;
 
-    if (ir.eI == eiBD)
+    if (ir.eI == IntegrationAlgorithm::BD)
     {
         /* Get the displacement distribution from the random component only.
          * With accurate integration the systematic (force) displacement
@@ -914,7 +914,7 @@ real calcVerletBufferSize(const gmx_mtop_t&         mtop,
     /* TODO: Obtain masses through (future) integrator functionality
      *       to avoid scattering the code with (or forgetting) checks.
      */
-    const bool setMassesToOne = (ir.eI == eiBD && ir.bd_fric > 0);
+    const bool setMassesToOne = (ir.eI == IntegrationAlgorithm::BD && ir.bd_fric > 0);
     const auto att            = getVerletBufferAtomtypes(mtop, setMassesToOne);
     GMX_ASSERT(!att.empty(), "We expect at least one type");
 
@@ -928,25 +928,25 @@ real calcVerletBufferSize(const gmx_mtop_t&         mtop,
     pot_derivatives_t ljRep  = { 0, 0, 0 };
     real              repPow = mtop.ffparams.reppow;
 
-    if (ir.vdwtype == evdwCUT)
+    if (ir.vdwtype == VanDerWaalsType::Cut)
     {
         real sw_range, md3_pswf;
 
         switch (ir.vdw_modifier)
         {
-            case eintmodNONE:
-            case eintmodPOTSHIFT:
+            case InteractionModifiers::None:
+            case InteractionModifiers::PotShift:
                 /* -dV/dr of -r^-6 and r^-reppow */
                 ljDisp.md1 = -6 * std::pow(ir.rvdw, -7.0);
                 ljRep.md1  = repPow * std::pow(ir.rvdw, -(repPow + 1));
                 /* The contribution of the higher derivatives is negligible */
                 break;
-            case eintmodFORCESWITCH:
+            case InteractionModifiers::ForceSwitch:
                 /* At the cut-off: V=V'=V''=0, so we use only V''' */
                 ljDisp.md3 = -md3_force_switch(6.0, ir.rvdw_switch, ir.rvdw);
                 ljRep.md3  = md3_force_switch(repPow, ir.rvdw_switch, ir.rvdw);
                 break;
-            case eintmodPOTSWITCH:
+            case InteractionModifiers::PotSwitch:
                 /* At the cut-off: V=V'=V''=0.
                  * V''' is given by the original potential times
                  * the third derivative of the switch function.
@@ -986,11 +986,11 @@ real calcVerletBufferSize(const gmx_mtop_t&         mtop,
     // Determine the 1st and 2nd derivative for the electostatics
     pot_derivatives_t elec = { 0, 0, 0 };
 
-    if (ir.coulombtype == eelCUT || EEL_RF(ir.coulombtype))
+    if (ir.coulombtype == CoulombInteractionType::Cut || EEL_RF(ir.coulombtype))
     {
         real eps_rf, k_rf;
 
-        if (ir.coulombtype == eelCUT)
+        if (ir.coulombtype == CoulombInteractionType::Cut)
         {
             eps_rf = 1;
             k_rf   = 0;
@@ -1015,7 +1015,7 @@ real calcVerletBufferSize(const gmx_mtop_t&         mtop,
         }
         elec.d2 = elfac * (2.0 / gmx::power3(ir.rcoulomb) + 2 * k_rf);
     }
-    else if (EEL_PME(ir.coulombtype) || ir.coulombtype == eelEWALD)
+    else if (EEL_PME(ir.coulombtype) || ir.coulombtype == CoulombInteractionType::Ewald)
     {
         real b, rc, br;
 
@@ -1333,7 +1333,7 @@ real minCellSizeForAtomDisplacement(const gmx_mtop_t&      mtop,
      */
     const real temperature = maxReferenceTemperature(ir);
 
-    const bool setMassesToOne = (ir.eI == eiBD && ir.bd_fric > 0);
+    const bool setMassesToOne = (ir.eI == IntegrationAlgorithm::BD && ir.bd_fric > 0);
 
     const auto atomtypes = getVerletBufferAtomtypes(mtop, setMassesToOne);
 
index 0819f82ef7918b9bab13159848d815509974381d..1c90a9b23dcdf969a1efc5f39b9484f275a396d1 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) 2012,2014,2015,2017,2018 by 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.
@@ -62,8 +62,8 @@ static int div_nsteps(int nsteps, int nst)
 double compute_io(const t_inputrec* ir, int natoms, const SimulationGroups& groups, int nrener, int nrepl)
 {
 
-    int    nsteps = ir->nsteps;
-    int    i, nxtcatoms = 0;
+    int    nsteps    = ir->nsteps;
+    int    nxtcatoms = 0;
     int    nstx, nstv, nstf, nste, nstlog, nstxtc;
     double cio;
 
@@ -93,13 +93,13 @@ double compute_io(const t_inputrec* ir, int natoms, const SimulationGroups& grou
     /* t_energy contains doubles, but real is written to edr */
     cio += (1.0 * nste) * nrener * 3 * sizeof(real);
 
-    if ((ir->efep != efepNO || ir->bSimTemp) && (ir->fepvals->nstdhdl > 0))
+    if ((ir->efep != FreeEnergyPerturbationType::No || ir->bSimTemp) && (ir->fepvals->nstdhdl > 0))
     {
         int ndh    = ir->fepvals->n_lambda;
         int ndhdl  = 0;
         int nchars = 0;
 
-        for (i = 0; i < efptNR; i++)
+        for (auto i : keysOf(ir->fepvals->separate_dvdl))
         {
             if (ir->fepvals->separate_dvdl[i])
             {
@@ -107,15 +107,15 @@ double compute_io(const t_inputrec* ir, int natoms, const SimulationGroups& grou
             }
         }
 
-        if (ir->fepvals->separate_dhdl_file == esepdhdlfileYES)
+        if (ir->fepvals->separate_dhdl_file == SeparateDhdlFile::Yes)
         {
             nchars = 8 + ndhdl * 8 + ndh * 10; /* time data ~8 chars/entry, dH data ~10 chars/entry */
-            if (ir->expandedvals->elmcmove > elmcmoveNO)
+            if (ir->expandedvals->elmcmove > LambdaMoveCalculation::No)
             {
                 nchars += 5; /* alchemical state */
             }
 
-            if (ir->fepvals->edHdLPrintEnergy != edHdLPrintEnergyNO)
+            if (ir->fepvals->edHdLPrintEnergy != FreeEnergyPrintEnergy::No)
             {
                 nchars += 12; /* energy for dhdl */
             }
@@ -127,11 +127,11 @@ double compute_io(const t_inputrec* ir, int natoms, const SimulationGroups& grou
             if (ir->fepvals->dh_hist_size <= 0)
             {
                 int ndh_tot = ndh + ndhdl;
-                if (ir->expandedvals->elmcmove > elmcmoveNO)
+                if (ir->expandedvals->elmcmove > LambdaMoveCalculation::No)
                 {
                     ndh_tot += 1;
                 }
-                if (ir->fepvals->edHdLPrintEnergy != edHdLPrintEnergyNO)
+                if (ir->fepvals->edHdLPrintEnergy != FreeEnergyPrintEnergy::No)
                 {
                     ndh_tot += 1;
                 }
index 106ce657ab4bb01f24b8092ff1007009ca6692db..911c55ed6fb6d53bf7a28313e135f6589fea124d 100644 (file)
@@ -235,17 +235,18 @@ static void clear_constraint_quantity_nonlocal(gmx_domdec_t* dd, ArrayRef<RVec>
     }
 }
 
-void too_many_constraint_warnings(int eConstrAlg, int warncount)
+void too_many_constraint_warnings(ConstraintAlgorithm eConstrAlg, int warncount)
 {
-    gmx_fatal(
-            FARGS,
-            "Too many %s warnings (%d)\n"
-            "If you know what you are doing you can %s"
-            "set the environment variable GMX_MAXCONSTRWARN to -1,\n"
-            "but normally it is better to fix the problem",
-            (eConstrAlg == econtLINCS) ? "LINCS" : "SETTLE",
-            warncount,
-            (eConstrAlg == econtLINCS) ? "adjust the lincs warning threshold in your mdp file\nor " : "\n");
+    gmx_fatal(FARGS,
+              "Too many %s warnings (%d)\n"
+              "If you know what you are doing you can %s"
+              "set the environment variable GMX_MAXCONSTRWARN to -1,\n"
+              "but normally it is better to fix the problem",
+              (eConstrAlg == ConstraintAlgorithm::Lincs) ? "LINCS" : "SETTLE",
+              warncount,
+              (eConstrAlg == ConstraintAlgorithm::Lincs)
+                      ? "adjust the lincs warning threshold in your mdp file\nor "
+                      : "\n");
 }
 
 //! Writes out coordinates.
@@ -439,7 +440,7 @@ bool Constraints::Impl::apply(bool                      bLog,
         invdt = 1.0 / scaled_delta_t;
     }
 
-    if (ir.efep != efepNO && EI_DYNAMICS(ir.eI))
+    if (ir.efep != FreeEnergyPerturbationType::No && EI_DYNAMICS(ir.eI))
     {
         /* Set the constraint lengths for the step at which this configuration
          * is meant to be. The invmasses should not be changed.
@@ -534,7 +535,7 @@ bool Constraints::Impl::apply(bool                      bLog,
             {
                 fprintf(log,
                         "Constraint error in algorithm %s at step %s\n",
-                        econstr_names[econtLINCS],
+                        enumValueToString(ConstraintAlgorithm::Lincs),
                         gmx_step_str(step, buf));
             }
             bDump = TRUE;
@@ -568,7 +569,7 @@ bool Constraints::Impl::apply(bool                      bLog,
             {
                 fprintf(log,
                         "Constraint error in algorithm %s at step %s\n",
-                        econstr_names[econtSHAKE],
+                        enumValueToString(ConstraintAlgorithm::Shake),
                         gmx_step_str(step, buf));
             }
             bDump = TRUE;
@@ -702,7 +703,7 @@ bool Constraints::Impl::apply(bool                      bLog,
                 warncount_settle++;
                 if (warncount_settle > maxwarn)
                 {
-                    too_many_constraint_warnings(-1, warncount_settle);
+                    too_many_constraint_warnings(ConstraintAlgorithm::Count, warncount_settle);
                 }
                 bDump = TRUE;
 
@@ -1016,11 +1017,11 @@ void Constraints::Impl::setConstraints(gmx_localtop_t* top,
         /* With DD we might also need to call LINCS on a domain no constraints for
          * communicating coordinates to other nodes that do have constraints.
          */
-        if (ir.eConstrAlg == econtLINCS)
+        if (ir.eConstrAlg == ConstraintAlgorithm::Lincs)
         {
             set_lincs(*idef, numAtoms_, inverseMasses_, lambda_, EI_DYNAMICS(ir.eI), cr, lincsd);
         }
-        if (ir.eConstrAlg == econtSHAKE)
+        if (ir.eConstrAlg == ConstraintAlgorithm::Shake)
         {
             if (cr->dd)
             {
@@ -1154,7 +1155,7 @@ Constraints::Impl::Impl(const gmx_mtop_t&     mtop_p,
             }
         }
 
-        if (ir.eConstrAlg == econtLINCS)
+        if (ir.eConstrAlg == ConstraintAlgorithm::Lincs)
         {
             lincsd = init_lincs(log,
                                 mtop,
@@ -1165,7 +1166,7 @@ Constraints::Impl::Impl(const gmx_mtop_t&     mtop_p,
                                 ir.nProjOrder);
         }
 
-        if (ir.eConstrAlg == econtSHAKE)
+        if (ir.eConstrAlg == ConstraintAlgorithm::Shake)
         {
             if (DOMAINDECOMP(cr) && ddHaveSplitConstraints(*cr->dd))
             {
@@ -1335,7 +1336,7 @@ void do_constrain_first(FILE*                     fplog,
                       gmx::ConstraintVariable::Velocities);
     }
     /* constrain the inital velocities at t-dt/2 */
-    if (EI_STATE_VELOCITY(ir->eI) && ir->eI != eiVV)
+    if (EI_STATE_VELOCITY(ir->eI) && ir->eI != IntegrationAlgorithm::VV)
     {
         auto subX = x.paddedArrayRef().subArray(start, end);
         auto subV = v.paddedArrayRef().subArray(start, end);
@@ -1405,7 +1406,7 @@ void constrain_velocities(gmx::Constraints* constr,
                       state->v.arrayRefWithPadding(),
                       state->v.arrayRefWithPadding().unpaddedArrayRef(),
                       state->box,
-                      state->lambda[efptBONDED],
+                      state->lambda[FreeEnergyPerturbationCouplingType::Bonded],
                       dvdlambda,
                       ArrayRefWithPadding<RVec>(),
                       computeVirial,
@@ -1435,7 +1436,7 @@ void constrain_coordinates(gmx::Constraints*         constr,
                       std::move(xp),
                       ArrayRef<RVec>(),
                       state->box,
-                      state->lambda[efptBONDED],
+                      state->lambda[FreeEnergyPerturbationCouplingType::Bonded],
                       dvdlambda,
                       state->v.arrayRefWithPadding(),
                       computeVirial,
index 0c2dd9096f85be04c521b295606d41337a2db433..3ab516f9448858823f4a2355c1f144073152e8ac 100644 (file)
@@ -71,7 +71,7 @@ struct t_inputrec;
 struct t_nrnb;
 struct t_pbc;
 class t_state;
-
+enum class ConstraintAlgorithm : int;
 namespace gmx
 {
 template<typename T>
@@ -219,7 +219,7 @@ private:
 };
 
 /*! \brief Generate a fatal error because of too many LINCS/SETTLE warnings. */
-[[noreturn]] void too_many_constraint_warnings(int eConstrAlg, int warncount);
+[[noreturn]] void too_many_constraint_warnings(ConstraintAlgorithm eConstrAlg, int warncount);
 
 /*! \brief Returns whether constraint with parameter \p iparamsIndex is a flexible constraint */
 static inline bool isConstraintFlexible(ArrayRef<const t_iparams> iparams, int iparamsIndex)
index a3eacef6f1721d03846eff64297ccfdf0dd10307..308ade02f59bc0f68df0caaf5dad51777f96376b 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.
@@ -192,7 +192,7 @@ static real constr_r_max_moltype(const gmx_moltype_t*           molt,
         constr_recur(
                 at2con, molt->ilist, iparams, FALSE, at, 0, 1 + ir->nProjOrder, path, r0, r1, &r2maxA, &count);
     }
-    if (ir->efep == efepNO)
+    if (ir->efep == FreeEnergyPerturbationType::No)
     {
         rmax = sqrt(r2maxA);
     }
index b49e86103e907051c15e97df5e6a662f24e0e33d..9c3f8ef0cc4807125133c71e2809554b374902a2 100644 (file)
@@ -303,7 +303,7 @@ void update_pcouple_after_coordinates(FILE*                fplog,
         case (PressureCoupling::Mttk):
             switch (inputrec->epct)
             {
-                case (epctISOTROPIC):
+                case (PressureCouplingType::Isotropic):
                     /* DIM * eta = ln V.  so DIM*eta_new = DIM*eta_old + DIM*dt*veta =>
                        ln V_new = ln V_old + 3*dt*veta => V_new = V_old*exp(3*dt*veta) =>
                        Side length scales as exp(veta*dt) */
@@ -542,7 +542,7 @@ static void boxv_trotter(const t_inputrec*     ir,
        2006 Tuckerman et al paper., the order is iL_{T_baro} iL {T_part}
      */
 
-    if (ir->epct == epctSEMIISOTROPIC)
+    if (ir->epct == PressureCouplingType::SemiIsotropic)
     {
         nwall = 2;
     }
@@ -705,7 +705,7 @@ void parrinellorahman_pcoupl(FILE*             fplog,
 
         m_sub(pres, ir->ref_p, pdiff);
 
-        if (ir->epct == epctSURFACETENSION)
+        if (ir->epct == PressureCouplingType::SurfaceTension)
         {
             /* Unlike Berendsen coupling it might not be trivial to include a z
              * pressure correction here? On the other hand we don't scale the
@@ -733,7 +733,7 @@ void parrinellorahman_pcoupl(FILE*             fplog,
 
         switch (ir->epct)
         {
-            case epctANISOTROPIC:
+            case PressureCouplingType::Anisotropic:
                 for (int d = 0; d < DIM; d++)
                 {
                     for (int n = 0; n <= d; n++)
@@ -742,7 +742,7 @@ void parrinellorahman_pcoupl(FILE*             fplog,
                     }
                 }
                 break;
-            case epctISOTROPIC:
+            case PressureCouplingType::Isotropic:
                 /* calculate total volume acceleration */
                 atot = box[XX][XX] * box[YY][YY] * t1[ZZ][ZZ] + box[XX][XX] * t1[YY][YY] * box[ZZ][ZZ]
                        + t1[XX][XX] * box[YY][YY] * box[ZZ][ZZ];
@@ -757,8 +757,8 @@ void parrinellorahman_pcoupl(FILE*             fplog,
                     }
                 }
                 break;
-            case epctSEMIISOTROPIC:
-            case epctSURFACETENSION:
+            case PressureCouplingType::SemiIsotropic:
+            case PressureCouplingType::SurfaceTension:
                 /* Note the correction to pdiff above for surftens. coupling  */
 
                 /* calculate total XY volume acceleration */
@@ -782,7 +782,7 @@ void parrinellorahman_pcoupl(FILE*             fplog,
                 gmx_fatal(FARGS,
                           "Parrinello-Rahman pressure coupling type %s "
                           "not supported yet\n",
-                          EPCOUPLTYPETYPE(ir->epct));
+                          enumValueToString(ir->epct));
         }
 
         real maxchange = 0;
@@ -898,13 +898,13 @@ void calculateScalingMatrixImplDetail<PressureCoupling::Berendsen>(const t_input
     real p_corr_z = 0;
     switch (ir->epct)
     {
-        case epctISOTROPIC:
+        case PressureCouplingType::Isotropic:
             for (int d = 0; d < DIM; d++)
             {
                 mu[d][d] = 1.0 - compressibilityFactor(d, d, ir, dt) * (ir->ref_p[d][d] - scalar_pressure) / DIM;
             }
             break;
-        case epctSEMIISOTROPIC:
+        case PressureCouplingType::SemiIsotropic:
             for (int d = 0; d < ZZ; d++)
             {
                 mu[d][d] = 1.0 - compressibilityFactor(d, d, ir, dt) * (ir->ref_p[d][d] - xy_pressure) / DIM;
@@ -912,7 +912,7 @@ void calculateScalingMatrixImplDetail<PressureCoupling::Berendsen>(const t_input
             mu[ZZ][ZZ] =
                     1.0 - compressibilityFactor(ZZ, ZZ, ir, dt) * (ir->ref_p[ZZ][ZZ] - pres[ZZ][ZZ]) / DIM;
             break;
-        case epctANISOTROPIC:
+        case PressureCouplingType::Anisotropic:
             for (int d = 0; d < DIM; d++)
             {
                 for (int n = 0; n < DIM; n++)
@@ -922,7 +922,7 @@ void calculateScalingMatrixImplDetail<PressureCoupling::Berendsen>(const t_input
                 }
             }
             break;
-        case epctSURFACETENSION:
+        case PressureCouplingType::SurfaceTension:
             /* ir->ref_p[0/1] is the reference surface-tension times *
              * the number of surfaces                                */
             if (ir->compress[ZZ][ZZ] != 0.0F)
@@ -948,7 +948,7 @@ void calculateScalingMatrixImplDetail<PressureCoupling::Berendsen>(const t_input
         default:
             gmx_fatal(FARGS,
                       "Berendsen pressure coupling type %s not supported yet\n",
-                      EPCOUPLTYPETYPE(ir->epct));
+                      enumValueToString(ir->epct));
     }
 }
 
@@ -980,7 +980,7 @@ void calculateScalingMatrixImplDetail<PressureCoupling::CRescale>(const t_inputr
 
     switch (ir->epct)
     {
-        case epctISOTROPIC:
+        case PressureCouplingType::Isotropic:
             gauss = normalDist(rng);
             for (int d = 0; d < DIM; d++)
             {
@@ -989,7 +989,7 @@ void calculateScalingMatrixImplDetail<PressureCoupling::CRescale>(const t_inputr
                                     + std::sqrt(2.0 * kt * factor * PRESFAC / vol) * gauss / DIM);
             }
             break;
-        case epctSEMIISOTROPIC:
+        case PressureCouplingType::SemiIsotropic:
             gauss  = normalDist(rng);
             gauss2 = normalDist(rng);
             for (int d = 0; d < ZZ; d++)
@@ -1005,7 +1005,7 @@ void calculateScalingMatrixImplDetail<PressureCoupling::CRescale>(const t_inputr
                                       + std::sqrt(2.0 * kt * factor * PRESFAC / vol / DIM) * gauss2);
             }
             break;
-        case epctSURFACETENSION:
+        case PressureCouplingType::SurfaceTension:
             gauss  = normalDist(rng);
             gauss2 = normalDist(rng);
             for (int d = 0; d < ZZ; d++)
@@ -1025,7 +1025,7 @@ void calculateScalingMatrixImplDetail<PressureCoupling::CRescale>(const t_inputr
         default:
             gmx_fatal(FARGS,
                       "C-rescale pressure coupling type %s not supported yet\n",
-                      EPCOUPLTYPETYPE(ir->epct));
+                      enumValueToString(ir->epct));
     }
 }
 
@@ -1193,7 +1193,7 @@ void berendsen_tcoupl(const t_inputrec* ir, gmx_ekindata_t* ekind, real dt, std:
     {
         real Ek, T;
 
-        if (ir->eI == eiVV)
+        if (ir->eI == IntegrationAlgorithm::VV)
         {
             Ek = trace(ekind->tcstat[i].ekinf);
             T  = ekind->tcstat[i].T;
@@ -1402,7 +1402,7 @@ void trotter_update(const t_inputrec*               ir,
                             scalefac,
                             nullptr,
                             MassQ,
-                            (ir->eI == eiVV));
+                            (ir->eI == IntegrationAlgorithm::VV));
                 /* need to rescale the kinetic energies and velocities here.  Could
                    scale the velocities later, but we need them scaled in order to
                    produce the correct outputs, so we'll scale them here. */
@@ -1456,7 +1456,7 @@ extern void init_npt_masses(const t_inputrec* ir, t_state* state, t_extmass* Mas
     ngtc = ir->opts.ngtc;
     nh   = state->nhchainlength;
 
-    if (ir->eI == eiMD)
+    if (ir->eI == IntegrationAlgorithm::MD)
     {
         if (bInit)
         {
@@ -1581,7 +1581,7 @@ init_npt_vars(const t_inputrec* ir, t_state* state, t_extmass* MassQ, gmx_bool b
     /* compute the kinetic energy by using the half step velocities or
      * the kinetic energies, depending on the order of the trotter calls */
 
-    if (ir->eI == eiVV)
+    if (ir->eI == IntegrationAlgorithm::VV)
     {
         if (inputrecNptTrotter(ir))
         {
@@ -1631,7 +1631,7 @@ init_npt_vars(const t_inputrec* ir, t_state* state, t_extmass* MassQ, gmx_bool b
             /* trotter_seq[4] is etrtNHC for second 1/2 step velocities - leave zero */
         }
     }
-    else if (ir->eI == eiVVAK)
+    else if (ir->eI == IntegrationAlgorithm::VVAK)
     {
         if (inputrecNptTrotter(ir))
         {
@@ -1685,7 +1685,7 @@ init_npt_vars(const t_inputrec* ir, t_state* state, t_extmass* MassQ, gmx_bool b
 
     switch (ir->epct)
     {
-        case epctISOTROPIC:
+        case PressureCouplingType::Isotropic:
         default: bmass = DIM * DIM; /* recommended mass parameters for isotropic barostat */
     }
 
@@ -1999,7 +1999,7 @@ void vrescale_tcoupl(const t_inputrec* ir, int64_t step, gmx_ekindata_t* ekind,
 
     for (i = 0; (i < opts->ngtc); i++)
     {
-        if (ir->eI == eiVV)
+        if (ir->eI == IntegrationAlgorithm::VV)
         {
             Ek = trace(ekind->tcstat[i].ekinf);
         }
@@ -2071,7 +2071,7 @@ bool doSimulatedAnnealing(const t_inputrec* ir)
     for (int i = 0; i < ir->opts.ngtc; i++)
     {
         /* set bSimAnn if any group is being annealed */
-        if (ir->opts.annealing[i] != eannNO)
+        if (ir->opts.annealing[i] != SimulatedAnnealing::No)
         {
             return true;
         }
@@ -2102,8 +2102,8 @@ void update_annealing_target_temp(t_inputrec* ir, real t, gmx::Update* upd)
         npoints = ir->opts.anneal_npoints[i];
         switch (ir->opts.annealing[i])
         {
-            case eannNO: continue;
-            case eannPERIODIC:
+            case SimulatedAnnealing::No: continue;
+            case SimulatedAnnealing::Periodic:
                 /* calculate time modulo the period */
                 pert  = ir->opts.anneal_time[i][npoints - 1];
                 n     = static_cast<int>(t / pert);
@@ -2114,7 +2114,7 @@ void update_annealing_target_temp(t_inputrec* ir, real t, gmx::Update* upd)
                     thist = 0;
                 }
                 break;
-            case eannSINGLE: thist = t; break;
+            case SimulatedAnnealing::Single: thist = t; break;
             default:
                 gmx_fatal(FARGS,
                           "Death horror in update_annealing_target_temp (i=%d/%d npoints=%d)",
@@ -2174,7 +2174,7 @@ void pleaseCiteCouplingAlgorithms(FILE* fplog, const t_inputrec& ir)
             please_cite(fplog, "Bernetti2020");
         }
         // TODO this is actually an integrator, not a coupling algorithm
-        if (ir.eI == eiSD1)
+        if (ir.eI == IntegrationAlgorithm::SD1)
         {
             please_cite(fplog, "Goga2012");
         }
index 3557950ddba1ba8bca9ce148450ba43b2fc2bd88..481c8597e79e9c96ff843df4f6a11838a216d356 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.
@@ -57,7 +57,8 @@
 DispersionCorrection::InteractionParams::~InteractionParams() = default;
 
 /* Returns a matrix, as flat list, of combination rule combined LJ parameters */
-static std::vector<real> mk_nbfp_combination_rule(const gmx_ffparams_t& ffparams, const int comb_rule)
+static std::vector<real> mk_nbfp_combination_rule(const gmx_ffparams_t& ffparams,
+                                                  const CombinationRule comb_rule)
 {
     const int atnr = ffparams.atnr;
 
@@ -73,7 +74,7 @@ static std::vector<real> mk_nbfp_combination_rule(const gmx_ffparams_t& ffparams
             const real c12j = ffparams.iparams[j * (atnr + 1)].lj.c12;
             real       c6   = std::sqrt(c6i * c6j);
             real       c12  = std::sqrt(c12i * c12j);
-            if (comb_rule == eCOMB_ARITHMETIC && !gmx_numzero(c6) && !gmx_numzero(c12))
+            if (comb_rule == CombinationRule::Arithmetic && !gmx_numzero(c6) && !gmx_numzero(c12))
             {
                 const real sigmai = gmx::sixthroot(c12i / c6i);
                 const real sigmaj = gmx::sixthroot(c12j / c6j);
@@ -121,9 +122,10 @@ DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t&         m
      * combination rules. */
     if (EVDW_PME(inputrec.vdwtype))
     {
-        nbfp_comb = mk_nbfp_combination_rule(
-                mtop.ffparams,
-                (inputrec.ljpme_combination_rule == eljpmeLB) ? eCOMB_ARITHMETIC : eCOMB_GEOMETRIC);
+        nbfp_comb = mk_nbfp_combination_rule(mtop.ffparams,
+                                             (inputrec.ljpme_combination_rule == LongRangeVdW::LB)
+                                                     ? CombinationRule::Arithmetic
+                                                     : CombinationRule::Geometric);
         for (int tpi = 0; tpi < ntp; ++tpi)
         {
             for (int tpj = 0; tpj < ntp; ++tpj)
@@ -135,7 +137,7 @@ DispersionCorrection::TopologyParams::TopologyParams(const gmx_mtop_t&         m
         nbfp = nbfp_comb;
     }
 
-    for (int q = 0; q < (inputrec.efep == efepNO ? 1 : 2); q++)
+    for (int q = 0; q < (inputrec.efep == FreeEnergyPerturbationType::No ? 1 : 2); q++)
     {
         double  csix    = 0;
         double  ctwelve = 0;
@@ -384,18 +386,20 @@ void DispersionCorrection::setInteractionParameters(InteractionParams*         i
     InteractionCorrection energy;
     InteractionCorrection virial;
 
-    if ((ic.vdw_modifier == eintmodPOTSHIFT) || (ic.vdw_modifier == eintmodPOTSWITCH)
-        || (ic.vdw_modifier == eintmodFORCESWITCH) || (ic.vdwtype == evdwSHIFT)
-        || (ic.vdwtype == evdwSWITCH))
+    if ((ic.vdw_modifier == InteractionModifiers::PotShift)
+        || (ic.vdw_modifier == InteractionModifiers::PotSwitch)
+        || (ic.vdw_modifier == InteractionModifiers::ForceSwitch)
+        || (ic.vdwtype == VanDerWaalsType::Shift) || (ic.vdwtype == VanDerWaalsType::Switch))
     {
-        if (((ic.vdw_modifier == eintmodPOTSWITCH) || (ic.vdw_modifier == eintmodFORCESWITCH)
-             || (ic.vdwtype == evdwSWITCH))
+        if (((ic.vdw_modifier == InteractionModifiers::PotSwitch)
+             || (ic.vdw_modifier == InteractionModifiers::ForceSwitch)
+             || (ic.vdwtype == VanDerWaalsType::Switch))
             && ic.rvdw_switch == 0)
         {
             gmx_fatal(FARGS,
                       "With dispersion correction rvdw-switch can not be zero "
                       "for vdw-type = %s",
-                      evdw_names[ic.vdwtype]);
+                      enumValueToString(ic.vdwtype));
         }
 
         GMX_ASSERT(iParams->dispersionCorrectionTable_, "We need an initialized table");
@@ -429,13 +433,13 @@ void DispersionCorrection::setInteractionParameters(InteractionParams*         i
          * we need to calculate the constant shift up to the point where we
          * start modifying the potential.
          */
-        ri0 = (ic.vdw_modifier == eintmodPOTSHIFT) ? ri1 : ri0;
+        ri0 = (ic.vdw_modifier == InteractionModifiers::PotShift) ? ri1 : ri0;
 
         const double r0  = ri0 / scale;
         const double rc3 = r0 * r0 * r0;
         const double rc9 = rc3 * rc3 * rc3;
 
-        if ((ic.vdw_modifier == eintmodFORCESWITCH) || (ic.vdwtype == evdwSHIFT))
+        if ((ic.vdw_modifier == InteractionModifiers::ForceSwitch) || (ic.vdwtype == VanDerWaalsType::Shift))
         {
             /* Determine the constant energy shift below rvdw_switch.
              * Table has a scale factor since we have scaled it down to compensate
@@ -444,7 +448,7 @@ void DispersionCorrection::setInteractionParameters(InteractionParams*         i
             iParams->enershiftsix_ = static_cast<real>(-1.0 / (rc3 * rc3)) - 6.0 * vdwtab[8 * ri0];
             iParams->enershifttwelve_ = static_cast<real>(1.0 / (rc9 * rc3)) - 12.0 * vdwtab[8 * ri0 + 4];
         }
-        else if (ic.vdw_modifier == eintmodPOTSHIFT)
+        else if (ic.vdw_modifier == InteractionModifiers::PotShift)
         {
             iParams->enershiftsix_    = static_cast<real>(-1.0 / (rc3 * rc3));
             iParams->enershifttwelve_ = static_cast<real>(1.0 / (rc9 * rc3));
@@ -482,7 +486,8 @@ void DispersionCorrection::setInteractionParameters(InteractionParams*         i
          */
         addCorrectionBeyondCutoff(&energy, &virial, r0);
     }
-    else if (ic.vdwtype == evdwCUT || EVDW_PME(ic.vdwtype) || ic.vdwtype == evdwUSER)
+    else if (ic.vdwtype == VanDerWaalsType::Cut || EVDW_PME(ic.vdwtype)
+             || ic.vdwtype == VanDerWaalsType::User)
     {
         /* Note that with LJ-PME, the dispersion correction is multiplied
          * by the difference between the actual C6 and the value of C6
@@ -493,7 +498,7 @@ void DispersionCorrection::setInteractionParameters(InteractionParams*         i
 
         const double rc3 = ic.rvdw * ic.rvdw * ic.rvdw;
         const double rc9 = rc3 * rc3 * rc3;
-        if (ic.vdw_modifier == eintmodPOTSHIFT)
+        if (ic.vdw_modifier == InteractionModifiers::PotShift)
         {
             /* Contribution within the cut-off */
             energy.dispersion += -4.0 * M_PI / (3.0 * rc3);
@@ -504,7 +509,9 @@ void DispersionCorrection::setInteractionParameters(InteractionParams*         i
     }
     else
     {
-        gmx_fatal(FARGS, "Dispersion correction is not implemented for vdw-type = %s", evdw_names[ic.vdwtype]);
+        gmx_fatal(FARGS,
+                  "Dispersion correction is not implemented for vdw-type = %s",
+                  enumValueToString(ic.vdwtype));
     }
 
     iParams->enerdiffsix_    = energy.dispersion;
@@ -526,7 +533,7 @@ DispersionCorrection::DispersionCorrection(const gmx_mtop_t&          mtop,
     eFep_(inputrec.efep),
     topParams_(mtop, inputrec, useBuckingham, numAtomTypes, nonbondedForceParameters)
 {
-    if (eDispCorr_ != edispcNO)
+    if (eDispCorr_ != DispersionCorrectionType::No)
     {
         GMX_RELEASE_ASSERT(tableFileName, "Need a table file name");
 
@@ -536,7 +543,8 @@ DispersionCorrection::DispersionCorrection(const gmx_mtop_t&          mtop,
 
 bool DispersionCorrection::correctFullInteraction() const
 {
-    return (eDispCorr_ == edispcAllEner || eDispCorr_ == edispcAllEnerPres);
+    return (eDispCorr_ == DispersionCorrectionType::AllEner
+            || eDispCorr_ == DispersionCorrectionType::AllEnerPres);
 }
 
 void DispersionCorrection::print(const gmx::MDLogger& mdlog) const
@@ -547,7 +555,7 @@ void DispersionCorrection::print(const gmx::MDLogger& mdlog) const
                 .asParagraph()
                 .appendText("WARNING: There are no atom pairs for dispersion correction");
     }
-    else if (vdwType_ == evdwUSER)
+    else if (vdwType_ == VanDerWaalsType::User)
     {
         GMX_LOG(mdlog.warning)
                 .asParagraph()
@@ -564,7 +572,7 @@ void DispersionCorrection::print(const gmx::MDLogger& mdlog) const
 
 void DispersionCorrection::setParameters(const interaction_const_t& ic)
 {
-    if (eDispCorr_ != edispcNO)
+    if (eDispCorr_ != DispersionCorrectionType::No)
     {
         setInteractionParameters(&iParams_, ic, nullptr);
     }
@@ -575,13 +583,14 @@ DispersionCorrection::Correction DispersionCorrection::calculate(const matrix bo
 {
     Correction corr;
 
-    if (eDispCorr_ == edispcNO)
+    if (eDispCorr_ == DispersionCorrectionType::No)
     {
         return corr;
     }
 
     const bool bCorrAll  = correctFullInteraction();
-    const bool bCorrPres = (eDispCorr_ == edispcEnerPres || eDispCorr_ == edispcAllEnerPres);
+    const bool bCorrPres = (eDispCorr_ == DispersionCorrectionType::EnerPres
+                            || eDispCorr_ == DispersionCorrectionType::AllEnerPres);
 
     const real invvol  = 1 / det(box);
     const real density = topParams_.numAtomsForDensity_ * invvol;
@@ -589,7 +598,7 @@ DispersionCorrection::Correction DispersionCorrection::calculate(const matrix bo
 
     real avcsix;
     real avctwelve;
-    if (eFep_ == efepNO)
+    if (eFep_ == FreeEnergyPerturbationType::No)
     {
         avcsix    = topParams_.avcsix_[0];
         avctwelve = topParams_.avctwelve_[0];
@@ -603,7 +612,7 @@ DispersionCorrection::Correction DispersionCorrection::calculate(const matrix bo
     const real enerdiff = numCorr * (density * iParams_.enerdiffsix_ - iParams_.enershiftsix_);
     corr.energy += avcsix * enerdiff;
     real dvdlambda = 0;
-    if (eFep_ != efepNO)
+    if (eFep_ != FreeEnergyPerturbationType::No)
     {
         dvdlambda += (topParams_.avcsix_[1] - topParams_.avcsix_[0]) * enerdiff;
     }
@@ -611,7 +620,7 @@ DispersionCorrection::Correction DispersionCorrection::calculate(const matrix bo
     {
         const real enerdiff = numCorr * (density * iParams_.enerdifftwelve_ - iParams_.enershifttwelve_);
         corr.energy += avctwelve * enerdiff;
-        if (eFep_ != efepNO)
+        if (eFep_ != FreeEnergyPerturbationType::No)
         {
             dvdlambda += (topParams_.avctwelve_[1] - topParams_.avctwelve_[0]) * enerdiff;
         }
@@ -620,7 +629,7 @@ DispersionCorrection::Correction DispersionCorrection::calculate(const matrix bo
     if (bCorrPres)
     {
         corr.virial = numCorr * density * avcsix * iParams_.virdiffsix_ / 3.0;
-        if (eDispCorr_ == edispcAllEnerPres)
+        if (eDispCorr_ == DispersionCorrectionType::AllEnerPres)
         {
             corr.virial += numCorr * density * avctwelve * iParams_.virdifftwelve_ / 3.0;
         }
@@ -628,7 +637,7 @@ DispersionCorrection::Correction DispersionCorrection::calculate(const matrix bo
         corr.pressure = -2.0 * invvol * corr.virial * PRESFAC;
     }
 
-    if (eFep_ != efepNO)
+    if (eFep_ != FreeEnergyPerturbationType::No)
     {
         corr.dvdl += dvdlambda;
     }
index be656e2130c4769ff0963a28d5a3127acf8ce959..62e7cbc021d7b8873f7ed3b1c5049a907ac41b32 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.
@@ -47,7 +47,9 @@ struct interaction_const_t;
 struct t_forcerec;
 struct t_forcetable;
 struct t_inputrec;
-
+enum class DispersionCorrectionType : int;
+enum class VanDerWaalsType : int;
+enum class FreeEnergyPerturbationType : int;
 namespace gmx
 {
 template<typename>
@@ -177,11 +179,11 @@ private:
     bool correctFullInteraction() const;
 
     //! Type of dispersion correction
-    int eDispCorr_;
+    DispersionCorrectionType eDispCorr_;
     //! Type of Van der Waals interaction
-    int vdwType_;
+    VanDerWaalsType vdwType_;
     //! Free-energy perturbation
-    int eFep_;
+    FreeEnergyPerturbationType eFep_;
     //! Topology parameters
     TopologyParams topParams_;
     //! Interaction parameters
index a546dc4125231d436e48ef2320258c0bb1ed19f7..be5b282c072466a509f7693365896c6ea60090fa 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.
@@ -130,7 +130,7 @@ void sum_epot(const gmx_grppairener_t& grpp, real* epot)
 static void set_dvdl_output(gmx_enerdata_t* enerd, const t_lambda& fepvals)
 {
     enerd->term[F_DVDL] = 0.0;
-    for (int i = 0; i < efptNR; i++)
+    for (auto i : keysOf(fepvals.separate_dvdl))
     {
         if (fepvals.separate_dvdl[i])
         {
@@ -140,11 +140,13 @@ static void set_dvdl_output(gmx_enerdata_t* enerd, const t_lambda& fepvals)
             int index;
             switch (i)
             {
-                case (efptMASS): index = F_DKDL; break;
-                case (efptCOUL): index = F_DVDL_COUL; break;
-                case (efptVDW): index = F_DVDL_VDW; break;
-                case (efptBONDED): index = F_DVDL_BONDED; break;
-                case (efptRESTRAINT): index = F_DVDL_RESTRAINT; break;
+                case (FreeEnergyPerturbationCouplingType::Mass): index = F_DKDL; break;
+                case (FreeEnergyPerturbationCouplingType::Coul): index = F_DVDL_COUL; break;
+                case (FreeEnergyPerturbationCouplingType::Vdw): index = F_DVDL_VDW; break;
+                case (FreeEnergyPerturbationCouplingType::Bonded): index = F_DVDL_BONDED; break;
+                case (FreeEnergyPerturbationCouplingType::Restraint):
+                    index = F_DVDL_RESTRAINT;
+                    break;
                 default: index = F_DVDL; break;
             }
             enerd->term[index] = enerd->dvdl_lin[i] + enerd->dvdl_nonlin[i];
@@ -152,8 +154,8 @@ static void set_dvdl_output(gmx_enerdata_t* enerd, const t_lambda& fepvals)
             {
                 fprintf(debug,
                         "dvdl-%s[%2d]: %f: non-linear %f + linear %f\n",
-                        efpt_names[i],
-                        i,
+                        enumValueToString(i),
+                        static_cast<int>(i),
                         enerd->term[index],
                         enerd->dvdl_nonlin[i],
                         enerd->dvdl_lin[i]);
@@ -166,8 +168,8 @@ static void set_dvdl_output(gmx_enerdata_t* enerd, const t_lambda& fepvals)
             {
                 fprintf(debug,
                         "dvd-%sl[%2d]: %f: non-linear %f + linear %f\n",
-                        efpt_names[0],
-                        i,
+                        enumValueToString(FreeEnergyPerturbationCouplingType::Fep),
+                        static_cast<int>(i),
                         enerd->term[F_DVDL],
                         enerd->dvdl_nonlin[i],
                         enerd->dvdl_lin[i]);
@@ -194,7 +196,7 @@ void ForeignLambdaTerms::finalizePotentialContributions(gmx::ArrayRef<const doub
     }
 
     double dvdl_lin = 0;
-    for (int i = 0; i < efptNR; i++)
+    for (int i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
     {
         dvdl_lin += dvdlLinear[i];
     }
@@ -258,7 +260,7 @@ void ForeignLambdaTerms::finalizeKineticContributions(gmx::ArrayRef<const real>
 
     // Treat current lambda, the deltaH contribution is 0 as delta-lambda=0 for the current lambda
     accumulateKinetic(0, 0.0, energyTerms[F_DVDL_CONSTR]);
-    if (!fepvals.separate_dvdl[efptMASS])
+    if (!fepvals.separate_dvdl[FreeEnergyPerturbationCouplingType::Mass])
     {
         accumulateKinetic(0, 0.0, energyTerms[F_DKDL]);
     }
@@ -271,13 +273,17 @@ void ForeignLambdaTerms::finalizeKineticContributions(gmx::ArrayRef<const real>
          * a linear extrapolation. This is an approximation, but usually
          * quite accurate since constraints change little between lambdas.
          */
-        const int    lambdaIndex = (fepvals.separate_dvdl[efptBONDED] ? efptBONDED : efptFEP);
-        const double dlam        = fepvals.all_lambda[lambdaIndex][i] - lambda[lambdaIndex];
+        const FreeEnergyPerturbationCouplingType lambdaIndex =
+                (fepvals.separate_dvdl[FreeEnergyPerturbationCouplingType::Bonded]
+                         ? FreeEnergyPerturbationCouplingType::Bonded
+                         : FreeEnergyPerturbationCouplingType::Fep);
+        const double dlam = fepvals.all_lambda[lambdaIndex][i] - lambda[static_cast<int>(lambdaIndex)];
         accumulateKinetic(1 + i, dlam * energyTerms[F_DVDL_CONSTR], energyTerms[F_DVDL_CONSTR]);
 
-        if (!fepvals.separate_dvdl[efptMASS])
+        if (!fepvals.separate_dvdl[FreeEnergyPerturbationCouplingType::Mass])
         {
-            const double dlam = fepvals.all_lambda[efptMASS][i] - lambda[efptMASS];
+            const double dlam = fepvals.all_lambda[FreeEnergyPerturbationCouplingType::Mass][i]
+                                - lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Mass)];
             accumulateKinetic(1 + i, dlam * energyTerms[F_DKDL], energyTerms[F_DKDL]);
         }
     }
@@ -287,7 +293,7 @@ void accumulateKineticLambdaComponents(gmx_enerdata_t*           enerd,
                                        gmx::ArrayRef<const real> lambda,
                                        const t_lambda&           fepvals)
 {
-    if (fepvals.separate_dvdl[efptBONDED])
+    if (fepvals.separate_dvdl[FreeEnergyPerturbationCouplingType::Bonded])
     {
         enerd->term[F_DVDL_BONDED] += enerd->term[F_DVDL_CONSTR];
     }
@@ -297,7 +303,7 @@ void accumulateKineticLambdaComponents(gmx_enerdata_t*           enerd,
     }
 
     enerd->foreignLambdaTerms.finalizeKineticContributions(
-            enerd->term, enerd->dvdl_lin[efptMASS], lambda, fepvals);
+            enerd->term, enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Mass], lambda, fepvals);
 
     /* The constrain contribution is now included in other terms, so clear it */
     enerd->term[F_DVDL_CONSTR] = 0;
@@ -326,7 +332,7 @@ void reset_foreign_enerdata(gmx_enerdata_t* enerd)
 
 void reset_dvdl_enerdata(gmx_enerdata_t* enerd)
 {
-    for (int i = 0; i < efptNR; i++)
+    for (auto i : keysOf(enerd->dvdl_lin))
     {
         enerd->dvdl_lin[i]    = 0.0;
         enerd->dvdl_nonlin[i] = 0.0;
index b66cb0a933dc37ca77ce0ed38491e8b9a7e56526..5fce35b75093f893f2077c9ab12e6fa179699ff5 100644 (file)
@@ -80,6 +80,7 @@
 #include "gromacs/topology/mtop_util.h"
 #include "gromacs/trajectory/energyframe.h"
 #include "gromacs/utility/arraysize.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/mdmodulenotification.h"
 #include "gromacs/utility/smalloc.h"
@@ -177,7 +178,7 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
     nCrmsd_      = 0;
     if (bConstr)
     {
-        if (ncon > 0 && ir->eConstrAlg == econtLINCS)
+        if (ncon > 0 && ir->eConstrAlg == ConstraintAlgorithm::Lincs)
         {
             nCrmsd_ = 1;
         }
@@ -209,14 +210,14 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
         bEner_[F_TEMP] = EI_DYNAMICS(ir->eI);
 
         bEner_[F_ECONSERVED] = integratorHasConservedEnergyQuantity(ir);
-        bEner_[F_PDISPCORR]  = (ir->eDispCorr != edispcNO);
+        bEner_[F_PDISPCORR]  = (ir->eDispCorr != DispersionCorrectionType::No);
         bEner_[F_PRES]       = true;
     }
 
     bEner_[F_LJ]           = !bBHAM;
     bEner_[F_BHAM]         = bBHAM;
     bEner_[F_EQM]          = ir->bQMMM;
-    bEner_[F_RF_EXCL]      = (EEL_RF(ir->coulombtype) && ir->cutoff_scheme == ecutsGROUP);
+    bEner_[F_RF_EXCL]      = (EEL_RF(ir->coulombtype) && ir->cutoff_scheme == CutoffScheme::Group);
     bEner_[F_COUL_RECIP]   = EEL_FULL(ir->coulombtype);
     bEner_[F_LJ_RECIP]     = EVDW_PME(ir->vdwtype);
     bEner_[F_LJ14]         = b14;
@@ -225,12 +226,19 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
     bEner_[F_LJC_PAIRS_NB] = false;
 
 
-    bEner_[F_DVDL_COUL]      = (ir->efep != efepNO) && ir->fepvals->separate_dvdl[efptCOUL];
-    bEner_[F_DVDL_VDW]       = (ir->efep != efepNO) && ir->fepvals->separate_dvdl[efptVDW];
-    bEner_[F_DVDL_BONDED]    = (ir->efep != efepNO) && ir->fepvals->separate_dvdl[efptBONDED];
-    bEner_[F_DVDL_RESTRAINT] = (ir->efep != efepNO) && ir->fepvals->separate_dvdl[efptRESTRAINT];
-    bEner_[F_DKDL]           = (ir->efep != efepNO) && ir->fepvals->separate_dvdl[efptMASS];
-    bEner_[F_DVDL]           = (ir->efep != efepNO) && ir->fepvals->separate_dvdl[efptFEP];
+    bEner_[F_DVDL_COUL] = (ir->efep != FreeEnergyPerturbationType::No)
+                          && ir->fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Coul];
+    bEner_[F_DVDL_VDW] = (ir->efep != FreeEnergyPerturbationType::No)
+                         && ir->fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Vdw];
+    bEner_[F_DVDL_BONDED] = (ir->efep != FreeEnergyPerturbationType::No)
+                            && ir->fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Bonded];
+    bEner_[F_DVDL_RESTRAINT] =
+            (ir->efep != FreeEnergyPerturbationType::No)
+            && ir->fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Restraint];
+    bEner_[F_DKDL] = (ir->efep != FreeEnergyPerturbationType::No)
+                     && ir->fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Mass];
+    bEner_[F_DVDL] = (ir->efep != FreeEnergyPerturbationType::No)
+                     && ir->fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Fep];
 
     bEner_[F_CONSTR]   = false;
     bEner_[F_CONSTRNC] = false;
@@ -239,7 +247,7 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
     bEner_[F_COUL_SR] = true;
     bEner_[F_EPOT]    = true;
 
-    bEner_[F_DISPCORR]   = (ir->eDispCorr != edispcNO);
+    bEner_[F_DISPCORR]   = (ir->eDispCorr != DispersionCorrectionType::No);
     bEner_[F_DISRESVIOL] = (gmx_mtop_ftype_count(mtop, F_DISRES) > 0);
     bEner_[F_ORIRESDEV]  = (gmx_mtop_ftype_count(mtop, F_ORIRES) > 0);
     bEner_[F_COM_PULL]   = ((ir->bPull && pull_have_potential(*pull_work)) || ir->bRot);
@@ -527,7 +535,7 @@ EnergyOutput::EnergyOutput(ener_file*               fp_ene,
 
     /* check whether we're going to write dh histograms */
     dhc_ = nullptr;
-    if (ir->fepvals->separate_dhdl_file == esepdhdlfileNO)
+    if (ir->fepvals->separate_dhdl_file == SeparateDhdlFile::No)
     {
         /* Currently dh histograms are only written with dynamics */
         if (EI_DYNAMICS(ir->eI))
@@ -591,10 +599,10 @@ EnergyOutput::~EnergyOutput()
  */
 static void print_lambda_vector(t_lambda* fep, int i, bool get_native_lambda, bool get_names, char* str)
 {
-    int j, k = 0;
+    int k    = 0;
     int Nsep = 0;
 
-    for (j = 0; j < efptNR; j++)
+    for (auto j : keysOf(fep->separate_dvdl))
     {
         if (fep->separate_dvdl[j])
         {
@@ -606,7 +614,7 @@ static void print_lambda_vector(t_lambda* fep, int i, bool get_native_lambda, bo
     {
         str += sprintf(str, "("); /* set the opening parenthesis*/
     }
-    for (j = 0; j < efptNR; j++)
+    for (auto j : keysOf(fep->separate_dvdl))
     {
         if (fep->separate_dvdl[j])
         {
@@ -623,7 +631,7 @@ static void print_lambda_vector(t_lambda* fep, int i, bool get_native_lambda, bo
             }
             else
             {
-                str += sprintf(str, "%s", efpt_singular_names[j]);
+                str += sprintf(str, "%s", enumValueToStringSingular(j));
             }
             /* print comma for the next item */
             if (k < Nsep - 1)
@@ -647,8 +655,8 @@ FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env
                *lambdastate = "\\lambda state";
     int         i, nsets, nsets_de, nsetsbegin;
     int         n_lambda_terms = 0;
-    t_lambda*   fep            = ir->fepvals; /* for simplicity */
-    t_expanded* expand         = ir->expandedvals;
+    t_lambda*   fep            = ir->fepvals.get(); /* for simplicity */
+    t_expanded* expand         = ir->expandedvals.get();
     char        lambda_vec_str[STRLEN], lambda_name_str[STRLEN];
 
     int  nsets_dhdl = 0;
@@ -657,7 +665,7 @@ FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env
     bool write_pV = false;
 
     /* count the number of different lambda terms */
-    for (i = 0; i < efptNR; i++)
+    for (auto i : keysOf(fep->separate_dvdl))
     {
         if (fep->separate_dvdl[i])
         {
@@ -687,7 +695,8 @@ FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env
     {
         buf = gmx::formatString("T = %g (K) ", ir->opts.ref_t[0]);
     }
-    if ((ir->efep != efepSLOWGROWTH) && (ir->efep != efepEXPANDED))
+    if ((ir->efep != FreeEnergyPerturbationType::SlowGrowth)
+        && (ir->efep != FreeEnergyPerturbationType::Expanded))
     {
         if ((fep->init_lambda >= 0) && (n_lambda_terms == 1))
         {
@@ -706,7 +715,7 @@ FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env
 
 
     nsets_dhdl = 0;
-    if (fep->dhdl_derivatives == edhdlderivativesYES)
+    if (fep->dhdl_derivatives == DhDlDerivativeCalculation::Yes)
     {
         nsets_dhdl = n_lambda_terms;
     }
@@ -715,12 +724,12 @@ FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env
 
     nsets = nsets_dhdl + nsets_de; /* dhdl + fep differences */
 
-    if (fep->n_lambda > 0 && (expand->elmcmove > elmcmoveNO))
+    if (fep->n_lambda > 0 && (expand->elmcmove > LambdaMoveCalculation::No))
     {
         nsets += 1; /*add fep state for expanded ensemble */
     }
 
-    if (fep->edHdLPrintEnergy != edHdLPrintEnergyNO)
+    if (fep->edHdLPrintEnergy != FreeEnergyPrintEnergy::No)
     {
         nsets += 1; /* add energy to the dhdl as well */
     }
@@ -737,30 +746,30 @@ FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env
     }
     std::vector<std::string> setname(nsetsextend);
 
-    if (expand->elmcmove > elmcmoveNO)
+    if (expand->elmcmove > LambdaMoveCalculation::No)
     {
         /* state for the fep_vals, if we have alchemical sampling */
         setname[s++] = "Thermodynamic state";
     }
 
-    if (fep->edHdLPrintEnergy != edHdLPrintEnergyNO)
+    if (fep->edHdLPrintEnergy != FreeEnergyPrintEnergy::No)
     {
         std::string energy;
         switch (fep->edHdLPrintEnergy)
         {
-            case edHdLPrintEnergyPOTENTIAL:
+            case FreeEnergyPrintEnergy::Potential:
                 energy = gmx::formatString("%s (%s)", "Potential Energy", unit_energy);
                 break;
-            case edHdLPrintEnergyTOTAL:
-            case edHdLPrintEnergyYES:
+            case FreeEnergyPrintEnergy::Total:
+            case FreeEnergyPrintEnergy::Yes:
             default: energy = gmx::formatString("%s (%s)", "Total Energy", unit_energy);
         }
         setname[s++] = energy;
     }
 
-    if (fep->dhdl_derivatives == edhdlderivativesYES)
+    if (fep->dhdl_derivatives == DhDlDerivativeCalculation::Yes)
     {
-        for (i = 0; i < efptNR; i++)
+        for (auto i : keysOf(fep->separate_dvdl))
         {
             if (fep->separate_dvdl[i])
             {
@@ -777,7 +786,7 @@ FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env
                     {
                         lam = fep->all_lambda[i][fep->init_fep_state];
                     }
-                    derivative = gmx::formatString("%s %s = %.4f", dhdl, efpt_singular_names[i], lam);
+                    derivative = gmx::formatString("%s %s = %.4f", dhdl, enumValueToStringSingular(i), lam);
                 }
                 setname[s++] = derivative;
             }
@@ -790,7 +799,7 @@ FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env
          * from this xvg legend.
          */
 
-        if (expand->elmcmove > elmcmoveNO)
+        if (expand->elmcmove > LambdaMoveCalculation::No)
         {
             nsetsbegin = 1; /* for including the expanded ensemble */
         }
@@ -799,7 +808,7 @@ FILE* open_dhdl(const char* filename, const t_inputrec* ir, const gmx_output_env
             nsetsbegin = 0;
         }
 
-        if (fep->edHdLPrintEnergy != edHdLPrintEnergyNO)
+        if (fep->edHdLPrintEnergy != FreeEnergyPrintEnergy::No)
         {
             nsetsbegin += 1;
         }
@@ -859,13 +868,14 @@ void EnergyOutput::addDataAtEnergyStep(bool                    bDoDHDL,
                                        const rvec              mu_tot,
                                        const gmx::Constraints* constr)
 {
-    int    j, k, kk, n, gid;
-    real   crmsd[2], tmp6[6];
-    real   bs[tricl_boxs_nm.size()], vol, dens, pv, enthalpy;
-    real   eee[egNR];
-    double store_dhdl[efptNR];
-    real   store_energy = 0;
-    real   tmp;
+    int  j, k, kk, n, gid;
+    real crmsd[2], tmp6[6];
+    real bs[tricl_boxs_nm.size()], vol, dens, enthalpy;
+    real eee[egNR];
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, double> store_dhdl;
+    real                                                              store_energy = 0;
+    real                                                              tmp;
+    real pv = 0.0; // static analyzer warns about uninitialized variable warnings here.
 
     /* Do NOT use the box in the state variable, but the separate box provided
      * as an argument. This is because we sometimes need to write the box from
@@ -1063,32 +1073,34 @@ void EnergyOutput::addDataAtEnergyStep(bool                    bDoDHDL,
             /* the current free energy state */
 
             /* print the current state if we are doing expanded ensemble */
-            if (expand->elmcmove > elmcmoveNO)
+            if (expand->elmcmove > LambdaMoveCalculation::No)
             {
                 fprintf(fp_dhdl_, " %4d", fep_state);
             }
             /* total energy (for if the temperature changes */
 
-            if (fep->edHdLPrintEnergy != edHdLPrintEnergyNO)
+            if (fep->edHdLPrintEnergy != FreeEnergyPrintEnergy::No)
             {
                 switch (fep->edHdLPrintEnergy)
                 {
-                    case edHdLPrintEnergyPOTENTIAL: store_energy = enerd->term[F_EPOT]; break;
-                    case edHdLPrintEnergyTOTAL:
-                    case edHdLPrintEnergyYES:
+                    case FreeEnergyPrintEnergy::Potential:
+                        store_energy = enerd->term[F_EPOT];
+                        break;
+                    case FreeEnergyPrintEnergy::Total:
+                    case FreeEnergyPrintEnergy::Yes:
                     default: store_energy = enerd->term[F_ETOT];
                 }
                 fprintf(fp_dhdl_, " %#.8g", store_energy);
             }
 
-            if (fep->dhdl_derivatives == edhdlderivativesYES)
+            if (fep->dhdl_derivatives == DhDlDerivativeCalculation::Yes)
             {
-                for (int i = 0; i < efptNR; i++)
+                for (auto i : keysOf(fep->separate_dvdl))
                 {
                     if (fep->separate_dvdl[i])
                     {
                         /* assumes F_DVDL is first */
-                        fprintf(fp_dhdl_, " %#.8g", enerd->term[F_DVDL + i]);
+                        fprintf(fp_dhdl_, " %#.8g", enerd->term[F_DVDL + static_cast<int>(i)]);
                     }
                 }
             }
@@ -1110,12 +1122,12 @@ void EnergyOutput::addDataAtEnergyStep(bool                    bDoDHDL,
         if (dhc_ && bDoDHDL)
         {
             int idhdl = 0;
-            for (int i = 0; i < efptNR; i++)
+            for (auto i : keysOf(fep->separate_dvdl))
             {
                 if (fep->separate_dvdl[i])
                 {
                     /* assumes F_DVDL is first */
-                    store_dhdl[idhdl] = enerd->term[F_DVDL + i];
+                    store_dhdl[idhdl] = enerd->term[F_DVDL + static_cast<int>(i)];
                     idhdl += 1;
                 }
             }
@@ -1298,7 +1310,7 @@ void EnergyOutput::printAnnealingTemperatures(FILE* log, const SimulationGroups*
         {
             for (int i = 0; i < opts->ngtc; i++)
             {
-                if (opts->annealing[i] != eannNO)
+                if (opts->annealing[i] != SimulatedAnnealing::No)
                 {
                     fprintf(log,
                             "Current ref_t for group %s: %8.1f\n",
index 570229515be08ac9bf33ca21c770dc8d3d4133fc..965d92b4418d793aa568abf6ecd8563183413428 100644 (file)
@@ -66,6 +66,7 @@
 #include "gromacs/random/threefry.h"
 #include "gromacs/random/uniformrealdistribution.h"
 #include "gromacs/timing/wallcycle.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/gmxmpi.h"
 #include "gromacs/utility/smalloc.h"
@@ -89,7 +90,7 @@ void init_expanded_ensemble(gmx_bool bStateFromCP, const t_inputrec* ir, df_hist
 {
     if (!bStateFromCP)
     {
-        init_df_history_weights(dfhist, ir->expandedvals, ir->fepvals->n_lambda);
+        init_df_history_weights(dfhist, ir->expandedvals.get(), ir->fepvals->n_lambda);
     }
 }
 
@@ -258,22 +259,22 @@ static gmx_bool CheckIfDoneEquilibrating(int nlim, const t_expanded* expand, con
         /* calculate the total number of samples */
         switch (expand->elmceq)
         {
-            case elmceqNO:
+            case LambdaWeightWillReachEquilibrium::No:
                 /* We have not equilibrated, and won't, ever. */
                 bDoneEquilibrating = FALSE;
                 break;
-            case elmceqYES:
+            case LambdaWeightWillReachEquilibrium::Yes:
                 /* we have equilibrated -- we're done */
                 bDoneEquilibrating = TRUE;
                 break;
-            case elmceqSTEPS:
+            case LambdaWeightWillReachEquilibrium::Steps:
                 /* first, check if we are equilibrating by steps, if we're still under */
                 if (step < expand->equil_steps)
                 {
                     bDoneEquilibrating = FALSE;
                 }
                 break;
-            case elmceqSAMPLES:
+            case LambdaWeightWillReachEquilibrium::Samples:
                 totalsamples = 0;
                 for (i = 0; i < nlim; i++)
                 {
@@ -284,7 +285,7 @@ static gmx_bool CheckIfDoneEquilibrating(int nlim, const t_expanded* expand, con
                     bDoneEquilibrating = FALSE;
                 }
                 break;
-            case elmceqNUMATLAM:
+            case LambdaWeightWillReachEquilibrium::NumAtLambda:
                 for (i = 0; i < nlim; i++)
                 {
                     if (dfhist->n_at_lam[i]
@@ -296,7 +297,7 @@ static gmx_bool CheckIfDoneEquilibrating(int nlim, const t_expanded* expand, con
                     }
                 }
                 break;
-            case elmceqWLDELTA:
+            case LambdaWeightWillReachEquilibrium::WLDelta:
                 if (EWL(expand->elamstats)) /* This check is in readir as well, but
                                                just to be sure */
                 {
@@ -306,13 +307,13 @@ static gmx_bool CheckIfDoneEquilibrating(int nlim, const t_expanded* expand, con
                     }
                 }
                 break;
-            case elmceqRATIO:
+            case LambdaWeightWillReachEquilibrium::Ratio:
                 /* we can use the flatness as a judge of good weights, as long as
                    we're not doing minvar, or Wang-Landau.
                    But turn off for now until we figure out exactly how we do this.
                  */
 
-                if (!(EWL(expand->elamstats) || expand->elamstats == elamstatsMINVAR))
+                if (!(EWL(expand->elamstats) || expand->elamstats == LambdaWeightCalculation::Minvar))
                 {
                     /* we want to use flatness -avoiding- the forced-through samples.  Plus, we need
                        to convert to floats for this histogram function. */
@@ -387,12 +388,13 @@ static gmx_bool UpdateWeights(int           nlim,
 
     if (EWL(expand->elamstats))
     {
-        if (expand->elamstats == elamstatsWL) /* Using standard Wang-Landau for weight updates */
+        if (expand->elamstats
+            == LambdaWeightCalculation::WL) /* Using standard Wang-Landau for weight updates */
         {
             dfhist->sum_weights[fep_state] -= dfhist->wl_delta;
             dfhist->wl_histo[fep_state] += 1.0;
         }
-        else if (expand->elamstats == elamstatsWWL)
+        else if (expand->elamstats == LambdaWeightCalculation::WWL)
         /* Using weighted Wang-Landau for weight updates.
          * Very closly equivalent to accelerated weight histogram approach
          * applied to expanded ensemble. */
@@ -434,8 +436,9 @@ static gmx_bool UpdateWeights(int           nlim,
         }
     }
 
-    if (expand->elamstats == elamstatsBARKER || expand->elamstats == elamstatsMETROPOLIS
-        || expand->elamstats == elamstatsMINVAR)
+    if (expand->elamstats == LambdaWeightCalculation::Barker
+        || expand->elamstats == LambdaWeightCalculation::Metropolis
+        || expand->elamstats == LambdaWeightCalculation::Minvar)
     {
         maxc = 2 * expand->c_range + 1;
 
@@ -786,7 +789,7 @@ static gmx_bool UpdateWeights(int           nlim,
             lam_variance[fep_state] = clam_varp;
         }
 
-        if (expand->elamstats == elamstatsMINVAR)
+        if (expand->elamstats == LambdaWeightCalculation::Minvar)
         {
             bSufficientSamples = TRUE;
             /* make sure the number of samples in each state are all
@@ -910,7 +913,8 @@ static int ChooseNewLambda(int               nlim,
             accept[ifep]  = 0;
         }
 
-        if ((expand->elmcmove == elmcmoveGIBBS) || (expand->elmcmove == elmcmoveMETGIBBS))
+        if ((expand->elmcmove == LambdaMoveCalculation::Gibbs)
+            || (expand->elmcmove == LambdaMoveCalculation::MetropolisGibbs))
         {
             /* use the Gibbs sampler, with restricted range */
             if (expand->gibbsdeltalam < 0)
@@ -934,7 +938,7 @@ static int ChooseNewLambda(int               nlim,
 
             GenerateGibbsProbabilities(weighted_lamee, p_k, &pks, minfep, maxfep);
 
-            if (expand->elmcmove == elmcmoveGIBBS)
+            if (expand->elmcmove == LambdaMoveCalculation::Gibbs)
             {
                 for (ifep = minfep; ifep <= maxfep; ifep++)
                 {
@@ -952,7 +956,7 @@ static int ChooseNewLambda(int               nlim,
                     r1 -= p_k[lamnew];
                 }
             }
-            else if (expand->elmcmove == elmcmoveMETGIBBS)
+            else if (expand->elmcmove == LambdaMoveCalculation::MetropolisGibbs)
             {
 
                 /* Metropolized Gibbs sampling */
@@ -1074,7 +1078,8 @@ static int ChooseNewLambda(int               nlim,
                 }
             }
         }
-        else if ((expand->elmcmove == elmcmoveMETROPOLIS) || (expand->elmcmove == elmcmoveBARKER))
+        else if ((expand->elmcmove == LambdaMoveCalculation::Metropolis)
+                 || (expand->elmcmove == LambdaMoveCalculation::Barker))
         {
             /* use the metropolis sampler with trial +/- 1 */
             r1 = dist(rng);
@@ -1102,7 +1107,7 @@ static int ChooseNewLambda(int               nlim,
             }
 
             de = weighted_lamee[lamtrial] - weighted_lamee[fep_state];
-            if (expand->elmcmove == elmcmoveMETROPOLIS)
+            if (expand->elmcmove == LambdaMoveCalculation::Metropolis)
             {
                 tprob = 1.0;
                 if (de < 0)
@@ -1115,7 +1120,7 @@ static int ChooseNewLambda(int               nlim,
                         1.0; /* doesn't actually matter, never proposed unless fep_state = ntrial, in which case it's 1.0 anyway */
                 accept[lamtrial] = tprob;
             }
-            else if (expand->elmcmove == elmcmoveBARKER)
+            else if (expand->elmcmove == LambdaMoveCalculation::Barker)
             {
                 if (de > 0) /* Numerically stable version */
                 {
@@ -1170,11 +1175,9 @@ void PrintFreeEnergyInfoToFile(FILE*               outfile,
                                int                 frequency,
                                int64_t             step)
 {
-    int         nlim, i, ifep, jfep;
-    real        dw, dg, dv, Tprint;
-    const char* print_names[efptNR] = { " FEPL", "MassL", "CoulL",   " VdwL",
-                                        "BondL", "RestT", "Temp.(K)" };
-    gmx_bool    bSimTemp            = FALSE;
+    int      nlim, ifep, jfep;
+    real     dw, dg, dv, Tprint;
+    gmx_bool bSimTemp = FALSE;
 
     nlim = fep->n_lambda;
     if (simtemp != nullptr)
@@ -1190,19 +1193,19 @@ void PrintFreeEnergyInfoToFile(FILE*               outfile,
             fprintf(outfile, "  Wang-Landau incrementor is: %11.5g\n", dfhist->wl_delta);
         }
         fprintf(outfile, "  N");
-        for (i = 0; i < efptNR; i++)
+        for (auto i : keysOf(fep->separate_dvdl))
         {
             if (fep->separate_dvdl[i])
             {
-                fprintf(outfile, "%7s", print_names[i]);
+                fprintf(outfile, "%7s", enumValueToString(i));
             }
-            else if ((i == efptTEMPERATURE) && bSimTemp)
+            else if ((i == FreeEnergyPerturbationCouplingType::Temperature) && bSimTemp)
             {
-                fprintf(outfile, "%10s", print_names[i]); /* more space for temperature formats */
+                fprintf(outfile, "%10s", enumValueToString(i)); /* more space for temperature formats */
             }
         }
         fprintf(outfile, "    Count   ");
-        if (expand->elamstats == elamstatsMINVAR)
+        if (expand->elamstats == LambdaWeightCalculation::Minvar)
         {
             fprintf(outfile, "W(in kT)   G(in kT)  dG(in kT)  dV(in kT)\n");
         }
@@ -1226,13 +1229,13 @@ void PrintFreeEnergyInfoToFile(FILE*               outfile,
                                - gmx::square(dfhist->sum_variance[ifep]));
             }
             fprintf(outfile, "%3d", (ifep + 1));
-            for (i = 0; i < efptNR; i++)
+            for (auto i : keysOf(fep->separate_dvdl))
             {
                 if (fep->separate_dvdl[i])
                 {
                     fprintf(outfile, "%7.3f", fep->all_lambda[i][ifep]);
                 }
-                else if (i == efptTEMPERATURE && bSimTemp)
+                else if (i == FreeEnergyPerturbationCouplingType::Temperature && bSimTemp)
                 {
                     fprintf(outfile, "%9.3f", simtemp->temperatures[ifep]);
                 }
@@ -1240,7 +1243,7 @@ void PrintFreeEnergyInfoToFile(FILE*               outfile,
             if (EWL(expand->elamstats)
                 && (!(dfhist->bEquil))) /* if performing WL and still haven't equilibrated */
             {
-                if (expand->elamstats == elamstatsWL)
+                if (expand->elamstats == LambdaWeightCalculation::WL)
                 {
                     fprintf(outfile, " %8d", static_cast<int>(dfhist->wl_histo[ifep]));
                 }
@@ -1253,7 +1256,7 @@ void PrintFreeEnergyInfoToFile(FILE*               outfile,
             {
                 fprintf(outfile, " %8d", dfhist->n_at_lam[ifep]);
             }
-            if (expand->elamstats == elamstatsMINVAR)
+            if (expand->elamstats == LambdaWeightCalculation::Minvar)
             {
                 fprintf(outfile,
                         " %10.5f %10.5f %10.5f %10.5f",
@@ -1365,8 +1368,8 @@ int ExpandedEnsembleDynamics(FILE*                 log,
     t_simtemp*  simtemp;
     gmx_bool    bIfReset, bSwitchtoOneOverT, bDoneEquilibrating = FALSE;
 
-    expand  = ir->expandedvals;
-    simtemp = ir->simtempvals;
+    expand  = ir->expandedvals.get();
+    simtemp = ir->simtempvals.get();
     nlim    = ir->fepvals->n_lambda;
 
     snew(scaled_lamee, nlim);
@@ -1392,7 +1395,7 @@ int ExpandedEnsembleDynamics(FILE*                 log,
     /* we don't need to include the pressure term, since the volume is the same between the two.
        is there some term we are neglecting, however? */
 
-    if (ir->efep != efepNO)
+    if (ir->efep != FreeEnergyPerturbationType::No)
     {
         for (i = 0; i < nlim; i++)
         {
@@ -1469,7 +1472,7 @@ int ExpandedEnsembleDynamics(FILE*                 log,
             fprintf(log,
                     "\nStep %" PRId64 ": Weights have equilibrated, using criteria: %s\n",
                     step,
-                    elmceq_names[expand->elmceq]);
+                    enumValueToString(expand->elmceq));
         }
     }
 
index a46f02e1e8f9f073024cfecd170ca9cd7d45f265..cc63b5e5ad366a9d82e069c5061f398b57092c95 100644 (file)
 
 namespace gmx
 {
-real calculateAcceptanceWeight(int calculationMode, real lambdaEnergyDifference)
+real calculateAcceptanceWeight(LambdaWeightCalculation calculationMode, real lambdaEnergyDifference)
 {
-    if (calculationMode == elamstatsBARKER || calculationMode == elamstatsMINVAR)
+    if (calculationMode == LambdaWeightCalculation::Barker
+        || calculationMode == LambdaWeightCalculation::Minvar)
     {
         /* Barker acceptance rule forumula is used for accumulation of probability for
          * both the Barker variant of the weight accumulation algorithm and the
@@ -77,7 +78,7 @@ real calculateAcceptanceWeight(int calculationMode, real lambdaEnergyDifference)
             return std::exp(-lambdaEnergyDifference) / (1.0 + std::exp(-lambdaEnergyDifference));
         }
     }
-    else if (calculationMode == elamstatsMETROPOLIS)
+    else if (calculationMode == LambdaWeightCalculation::Metropolis)
     {
         /* Metropolis acceptance rule for a jump from state i -> j is defined as
          *     1            (if dE_ij < 0)
index be3c7c81f0ecb63896d41e089e992dbf482932e9..f2f70b7145ea39f8010452cf090bebf68266e4fa 100644 (file)
@@ -46,6 +46,8 @@
 
 #include "gromacs/utility/real.h"
 
+enum class LambdaWeightCalculation : int;
+
 namespace gmx
 {
 /*! \brief Calculates the acceptance weight for a lambda state transition
@@ -54,7 +56,7 @@ namespace gmx
  * \param[in] lambdaEnergyDifference  The difference in energy between the two states
  * \return  The acceptance weight
  */
-real calculateAcceptanceWeight(int calculationMode, real lambdaEnergyDifference);
+real calculateAcceptanceWeight(LambdaWeightCalculation calculationMode, real lambdaEnergyDifference);
 } // namespace gmx
 
 #endif // GMX_MDLIB_EXPANDEDINTERNAL_H
index a17b332848d4411e3f41b24884b2bd38d672a778..b53ab898c23c567eeaf7a25c6b2172ff45f1f0f1 100644 (file)
@@ -75,10 +75,10 @@ using gmx::RVec;
 
 static void clearEwaldThreadOutput(ewald_corr_thread_t* ewc_t)
 {
-    ewc_t->Vcorr_q        = 0;
-    ewc_t->Vcorr_lj       = 0;
-    ewc_t->dvdl[efptCOUL] = 0;
-    ewc_t->dvdl[efptVDW]  = 0;
+    ewc_t->Vcorr_q                                        = 0;
+    ewc_t->Vcorr_lj                                       = 0;
+    ewc_t->dvdl[FreeEnergyPerturbationCouplingType::Coul] = 0;
+    ewc_t->dvdl[FreeEnergyPerturbationCouplingType::Vdw]  = 0;
     clear_mat(ewc_t->vir_q);
     clear_mat(ewc_t->vir_lj);
 }
@@ -91,8 +91,10 @@ static void reduceEwaldThreadOuput(int nthreads, ewald_corr_thread_t* ewc_t)
     {
         dest.Vcorr_q += ewc_t[t].Vcorr_q;
         dest.Vcorr_lj += ewc_t[t].Vcorr_lj;
-        dest.dvdl[efptCOUL] += ewc_t[t].dvdl[efptCOUL];
-        dest.dvdl[efptVDW] += ewc_t[t].dvdl[efptVDW];
+        dest.dvdl[FreeEnergyPerturbationCouplingType::Coul] +=
+                ewc_t[t].dvdl[FreeEnergyPerturbationCouplingType::Coul];
+        dest.dvdl[FreeEnergyPerturbationCouplingType::Vdw] +=
+                ewc_t[t].dvdl[FreeEnergyPerturbationCouplingType::Vdw];
         m_add(dest.vir_q, ewc_t[t].vir_q, dest.vir_q);
         m_add(dest.vir_lj, ewc_t[t].vir_lj, dest.vir_lj);
     }
@@ -122,7 +124,7 @@ void calculateLongRangeNonbondeds(t_forcerec*                   fr,
     /* Do long-range electrostatics and/or LJ-PME
      * and compute PME surface terms when necessary.
      */
-    if ((computePmeOnCpu || fr->ic->eeltype == eelEWALD || haveEwaldSurfaceTerm)
+    if ((computePmeOnCpu || fr->ic->eeltype == CoulombInteractionType::Ewald || haveEwaldSurfaceTerm)
         && stepWork.computeNonbondedForces)
     {
         int  status = 0;
@@ -159,22 +161,23 @@ void calculateLongRangeNonbondeds(t_forcerec*                   fr,
                          * the forces in the normal, single forceWithVirial->force_ array.
                          */
                         const rvec* x = as_rvec_array(coordinates.data());
-                        ewald_LRcorrection(md->homenr,
-                                           cr,
-                                           nthreads,
-                                           t,
-                                           *fr,
-                                           ir,
-                                           md->chargeA,
-                                           md->chargeB,
-                                           (md->nChargePerturbed != 0),
-                                           x,
-                                           box,
-                                           mu_tot,
-                                           as_rvec_array(forceWithVirial->force_.data()),
-                                           &ewc_t.Vcorr_q,
-                                           lambda[efptCOUL],
-                                           &ewc_t.dvdl[efptCOUL]);
+                        ewald_LRcorrection(
+                                md->homenr,
+                                cr,
+                                nthreads,
+                                t,
+                                *fr,
+                                ir,
+                                md->chargeA,
+                                md->chargeB,
+                                (md->nChargePerturbed != 0),
+                                x,
+                                box,
+                                mu_tot,
+                                as_rvec_array(forceWithVirial->force_.data()),
+                                &ewc_t.Vcorr_q,
+                                lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)],
+                                &ewc_t.dvdl[FreeEnergyPerturbationCouplingType::Coul]);
                     }
                     GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
                 }
@@ -190,7 +193,12 @@ void calculateLongRangeNonbondeds(t_forcerec*                   fr,
                 /* This is not in a subcounter because it takes a
                    negligible and constant-sized amount of time */
                 ewaldOutput.Vcorr_q += ewald_charge_correction(
-                        cr, fr, lambda[efptCOUL], box, &ewaldOutput.dvdl[efptCOUL], ewaldOutput.vir_q);
+                        cr,
+                        fr,
+                        lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)],
+                        box,
+                        &ewaldOutput.dvdl[FreeEnergyPerturbationCouplingType::Coul],
+                        ewaldOutput.vir_q);
             }
 
             if (computePmeOnCpu)
@@ -226,10 +234,10 @@ void calculateLongRangeNonbondeds(t_forcerec*                   fr,
                             ewaldOutput.vir_lj,
                             &Vlr_q,
                             &Vlr_lj,
-                            lambda[efptCOUL],
-                            lambda[efptVDW],
-                            &ewaldOutput.dvdl[efptCOUL],
-                            &ewaldOutput.dvdl[efptVDW],
+                            lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)],
+                            lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)],
+                            &ewaldOutput.dvdl[FreeEnergyPerturbationCouplingType::Coul],
+                            &ewaldOutput.dvdl[FreeEnergyPerturbationCouplingType::Vdw],
                             stepWork);
                     wallcycle_stop(wcycle, ewcPMEMESH);
                     if (status != 0)
@@ -259,7 +267,7 @@ void calculateLongRangeNonbondeds(t_forcerec*                   fr,
             }
         }
 
-        if (fr->ic->eeltype == eelEWALD)
+        if (fr->ic->eeltype == CoulombInteractionType::Ewald)
         {
             const rvec* x = as_rvec_array(coordinates.data());
             Vlr_q         = do_ewald(ir,
@@ -272,8 +280,8 @@ void calculateLongRangeNonbondeds(t_forcerec*                   fr,
                              md->homenr,
                              ewaldOutput.vir_q,
                              fr->ic->ewaldcoeff_q,
-                             lambda[efptCOUL],
-                             &ewaldOutput.dvdl[efptCOUL],
+                             lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)],
+                             &ewaldOutput.dvdl[FreeEnergyPerturbationCouplingType::Coul],
                              fr->ewald_table);
         }
 
@@ -282,8 +290,10 @@ void calculateLongRangeNonbondeds(t_forcerec*                   fr,
         // long-range virial contribution.
         forceWithVirial->addVirialContribution(ewaldOutput.vir_q);
         forceWithVirial->addVirialContribution(ewaldOutput.vir_lj);
-        enerd->dvdl_lin[efptCOUL] += ewaldOutput.dvdl[efptCOUL];
-        enerd->dvdl_lin[efptVDW] += ewaldOutput.dvdl[efptVDW];
+        enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Coul] +=
+                ewaldOutput.dvdl[FreeEnergyPerturbationCouplingType::Coul];
+        enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Vdw] +=
+                ewaldOutput.dvdl[FreeEnergyPerturbationCouplingType::Vdw];
         enerd->term[F_COUL_RECIP] = Vlr_q + ewaldOutput.Vcorr_q;
         enerd->term[F_LJ_RECIP]   = Vlr_lj + ewaldOutput.Vcorr_lj;
 
index cdc0b418bfb6269afc9cc399767b2396b4bc91ce..94c505d48aa52a79b206243e2384737ac3eafde4 100644 (file)
@@ -177,7 +177,7 @@ std::vector<real> makeLJPmeC6GridCorrectionParameters(const gmx_ffparams_t& forc
             c6j  = forceFieldParams.iparams[j * (atnr + 1)].lj.c6;
             c12j = forceFieldParams.iparams[j * (atnr + 1)].lj.c12;
             c6   = std::sqrt(c6i * c6j);
-            if (forceRec.ljpme_combination_rule == eljpmeLB && !gmx_numzero(c6)
+            if (forceRec.ljpme_combination_rule == LongRangeVdW::LB && !gmx_numzero(c6)
                 && !gmx_numzero(c12i) && !gmx_numzero(c12j))
             {
                 sigmai = gmx::sixthroot(c12i / c6i);
@@ -325,7 +325,7 @@ static std::vector<cginfo_mb_t> init_cginfo_mb(const gmx_mtop_t& mtop, const t_f
                 {
                     SET_CGINFO_HAS_Q(atomInfo);
                 }
-                if (fr->efep != efepNO && PERTURBED(atom))
+                if (fr->efep != FreeEnergyPerturbationType::No && PERTURBED(atom))
                 {
                     SET_CGINFO_FEP(atomInfo);
                 }
@@ -390,7 +390,7 @@ static bool set_chargesum(FILE* log, t_forcerec* fr, const gmx_mtop_t& mtop)
     fr->q2sum[0] = q2sum;
     fr->c6sum[0] = c6sum;
 
-    if (fr->efep != efepNO)
+    if (fr->efep != FreeEnergyPerturbationType::No)
     {
         qsum  = 0;
         q2sum = 0;
@@ -420,7 +420,7 @@ static bool set_chargesum(FILE* log, t_forcerec* fr, const gmx_mtop_t& mtop)
     }
     if (log)
     {
-        if (fr->efep == efepNO)
+        if (fr->efep == FreeEnergyPerturbationType::No)
         {
             fprintf(log, "System total charge: %.3f\n", fr->qsum[0]);
         }
@@ -649,7 +649,7 @@ static void initCoulombEwaldParameters(FILE*                fp,
     {
         fprintf(fp, "Will do PME sum in reciprocal space for electrostatic interactions.\n");
 
-        if (ir.coulombtype == eelP3M_AD)
+        if (ir.coulombtype == CoulombInteractionType::P3mAD)
         {
             please_cite(fp, "Hockney1988");
             please_cite(fp, "Ballenegger2012");
@@ -659,7 +659,7 @@ static void initCoulombEwaldParameters(FILE*                fp,
             please_cite(fp, "Essmann95a");
         }
 
-        if (ir.ewald_geometry == eewg3DC)
+        if (ir.ewald_geometry == EwaldGeometry::ThreeDC)
         {
             if (fp)
             {
@@ -681,7 +681,7 @@ static void initCoulombEwaldParameters(FILE*                fp,
         fprintf(fp, "Using a Gaussian width (1/beta) of %g nm for Ewald\n", 1 / ic->ewaldcoeff_q);
     }
 
-    if (ic->coulomb_modifier == eintmodPOTSHIFT)
+    if (ic->coulomb_modifier == InteractionModifiers::PotShift)
     {
         GMX_RELEASE_ASSERT(ic->rcoulomb != 0, "Cutoff radius cannot be zero");
         ic->sh_ewald = std::erfc(ic->ewaldcoeff_q * ic->rcoulomb) / ic->rcoulomb;
@@ -711,7 +711,7 @@ static void initVdwEwaldParameters(FILE* fp, const t_inputrec& ir, interaction_c
         fprintf(fp, "Using a Gaussian width (1/beta) of %g nm for LJ Ewald\n", 1 / ic->ewaldcoeff_lj);
     }
 
-    if (ic->vdw_modifier == eintmodPOTSHIFT)
+    if (ic->vdw_modifier == InteractionModifiers::PotShift)
     {
         real crc2       = gmx::square(ic->ewaldcoeff_lj * ic->rvdw);
         ic->sh_lj_ewald = (std::exp(-crc2) * (1 + crc2 + 0.5 * crc2 * crc2) - 1) / gmx::power6(ic->rvdw);
@@ -860,22 +860,22 @@ static void init_interaction_const(FILE*                 fp,
 
     switch (ic->vdw_modifier)
     {
-        case eintmodPOTSHIFT:
+        case InteractionModifiers::PotShift:
             /* Only shift the potential, don't touch the force */
             ic->dispersion_shift.cpot = -1.0 / gmx::power6(ic->rvdw);
             ic->repulsion_shift.cpot  = -1.0 / gmx::power12(ic->rvdw);
             break;
-        case eintmodFORCESWITCH:
+        case InteractionModifiers::ForceSwitch:
             /* Switch the force, switch and shift the potential */
             force_switch_constants(6.0, ic->rvdw_switch, ic->rvdw, &ic->dispersion_shift);
             force_switch_constants(12.0, ic->rvdw_switch, ic->rvdw, &ic->repulsion_shift);
             break;
-        case eintmodPOTSWITCH:
+        case InteractionModifiers::PotSwitch:
             /* Switch the potential and force */
             potential_switch_constants(ic->rvdw_switch, ic->rvdw, &ic->vdw_switch);
             break;
-        case eintmodNONE:
-        case eintmodEXACTCUTOFF:
+        case InteractionModifiers::None:
+        case InteractionModifiers::ExactCutoff:
             /* Nothing to do here */
             break;
         default: gmx_incons("unimplemented potential modifier");
@@ -902,7 +902,8 @@ static void init_interaction_const(FILE*                 fp,
     /* Reaction-field */
     if (EEL_RF(ic->eeltype))
     {
-        GMX_RELEASE_ASSERT(ic->eeltype != eelGRF_NOTUSED, "GRF is no longer supported");
+        GMX_RELEASE_ASSERT(ic->eeltype != CoulombInteractionType::GRFNotused,
+                           "GRF is no longer supported");
         ic->reactionFieldPermitivity = ir.epsilon_rf;
 
         calc_rffac(fp,
@@ -917,7 +918,7 @@ static void init_interaction_const(FILE*                 fp,
         /* For plain cut-off we might use the reaction-field kernels */
         ic->reactionFieldPermitivity = ic->epsilon_r;
         ic->reactionFieldCoefficient = 0;
-        if (ir.coulomb_modifier == eintmodPOTSHIFT)
+        if (ir.coulomb_modifier == InteractionModifiers::PotShift)
         {
             ic->reactionFieldShift = 1 / ic->rcoulomb;
         }
@@ -940,7 +941,7 @@ static void init_interaction_const(FILE*                 fp,
         }
         fprintf(fp, "Potential shift: LJ r^-12: %.3e r^-6: %.3e", ic->repulsion_shift.cpot, dispersion_shift);
 
-        if (ic->eeltype == eelCUT)
+        if (ic->eeltype == CoulombInteractionType::Cut)
         {
             fprintf(fp, ", Coulomb %.e", -ic->reactionFieldShift);
         }
@@ -951,7 +952,7 @@ static void init_interaction_const(FILE*                 fp,
         fprintf(fp, "\n");
     }
 
-    if (ir.efep != efepNO)
+    if (ir.efep != FreeEnergyPerturbationType::No)
     {
         GMX_RELEASE_ASSERT(ir.fepvals, "ir.fepvals should be set wth free-energy");
         ic->softCoreParameters = std::make_unique<interaction_const_t::SoftCoreParameters>(*ir.fepvals);
@@ -992,9 +993,10 @@ void init_forcerec(FILE*                            fp,
         fr->n_tpi = 0;
     }
 
-    if (ir.coulombtype == eelRF_NEC_UNSUPPORTED || ir.coulombtype == eelGRF_NOTUSED)
+    if (ir.coulombtype == CoulombInteractionType::RFNecUnsupported
+        || ir.coulombtype == CoulombInteractionType::GRFNotused)
     {
-        gmx_fatal(FARGS, "%s electrostatics is no longer supported", eel_names[ir.coulombtype]);
+        gmx_fatal(FARGS, "%s electrostatics is no longer supported", enumValueToString(ir.coulombtype));
     }
 
     if (ir.bAdress)
@@ -1098,7 +1100,7 @@ void init_forcerec(FILE*                            fp,
     const interaction_const_t* ic = fr->ic;
 
     /* TODO: Replace this Ewald table or move it into interaction_const_t */
-    if (ir.coulombtype == eelEWALD)
+    if (ir.coulombtype == CoulombInteractionType::Ewald)
     {
         init_ewald_tab(&(fr->ewald_table), ir, fp);
     }
@@ -1106,49 +1108,58 @@ void init_forcerec(FILE*                            fp,
     /* Electrostatics: Translate from interaction-setting-in-mdp-file to kernel interaction format */
     switch (ic->eeltype)
     {
-        case eelCUT: fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_COULOMB; break;
+        case CoulombInteractionType::Cut:
+            fr->nbkernel_elec_interaction = NbkernelElecType::Coulomb;
+            break;
 
-        case eelRF:
-        case eelRF_ZERO: fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_REACTIONFIELD; break;
+        case CoulombInteractionType::RF:
+        case CoulombInteractionType::RFZero:
+            fr->nbkernel_elec_interaction = NbkernelElecType::ReactionField;
+            break;
 
-        case eelSWITCH:
-        case eelSHIFT:
-        case eelUSER:
-        case eelPMESWITCH:
-        case eelPMEUSER:
-        case eelPMEUSERSWITCH:
-            fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_CUBICSPLINETABLE;
+        case CoulombInteractionType::Switch:
+        case CoulombInteractionType::Shift:
+        case CoulombInteractionType::User:
+        case CoulombInteractionType::PmeSwitch:
+        case CoulombInteractionType::PmeUser:
+        case CoulombInteractionType::PmeUserSwitch:
+            fr->nbkernel_elec_interaction = NbkernelElecType::CubicSplineTable;
             break;
 
-        case eelPME:
-        case eelP3M_AD:
-        case eelEWALD: fr->nbkernel_elec_interaction = GMX_NBKERNEL_ELEC_EWALD; break;
+        case CoulombInteractionType::Pme:
+        case CoulombInteractionType::P3mAD:
+        case CoulombInteractionType::Ewald:
+            fr->nbkernel_elec_interaction = NbkernelElecType::Ewald;
+            break;
 
         default:
-            gmx_fatal(FARGS, "Unsupported electrostatic interaction: %s", eel_names[ic->eeltype]);
+            gmx_fatal(FARGS, "Unsupported electrostatic interaction: %s", enumValueToString(ic->eeltype));
     }
     fr->nbkernel_elec_modifier = ic->coulomb_modifier;
 
     /* Vdw: Translate from mdp settings to kernel format */
     switch (ic->vdwtype)
     {
-        case evdwCUT:
+        case VanDerWaalsType::Cut:
             if (fr->bBHAM)
             {
-                fr->nbkernel_vdw_interaction = GMX_NBKERNEL_VDW_BUCKINGHAM;
+                fr->nbkernel_vdw_interaction = NbkernelVdwType::Buckingham;
             }
             else
             {
-                fr->nbkernel_vdw_interaction = GMX_NBKERNEL_VDW_LENNARDJONES;
+                fr->nbkernel_vdw_interaction = NbkernelVdwType::LennardJones;
             }
             break;
-        case evdwPME: fr->nbkernel_vdw_interaction = GMX_NBKERNEL_VDW_LJEWALD; break;
+        case VanDerWaalsType::Pme: fr->nbkernel_vdw_interaction = NbkernelVdwType::LJEwald; break;
 
-        case evdwSWITCH:
-        case evdwSHIFT:
-        case evdwUSER: fr->nbkernel_vdw_interaction = GMX_NBKERNEL_VDW_CUBICSPLINETABLE; break;
+        case VanDerWaalsType::Switch:
+        case VanDerWaalsType::Shift:
+        case VanDerWaalsType::User:
+            fr->nbkernel_vdw_interaction = NbkernelVdwType::CubicSplineTable;
+            break;
 
-        default: gmx_fatal(FARGS, "Unsupported vdw interaction: %s", evdw_names[ic->vdwtype]);
+        default:
+            gmx_fatal(FARGS, "Unsupported vdw interaction: %s", enumValueToString(ic->vdwtype));
     }
     fr->nbkernel_vdw_modifier = ic->vdw_modifier;
 
@@ -1161,7 +1172,7 @@ void init_forcerec(FILE*                            fp,
      */
     if (EEL_USER(fr->ic->eeltype))
     {
-        gmx_fatal(FARGS, "Electrostatics type %s is currently not supported", eel_names[ir.coulombtype]);
+        gmx_fatal(FARGS, "Electrostatics type %s is currently not supported", enumValueToString(ir.coulombtype));
     }
 
     fr->bvdwtab  = FALSE;
@@ -1210,7 +1221,7 @@ void init_forcerec(FILE*                            fp,
     fr->egp_flags = ir.opts.egp_flags;
 
     /* Van der Waals stuff */
-    if ((ic->vdwtype != evdwCUT) && (ic->vdwtype != evdwUSER) && !fr->bBHAM)
+    if ((ic->vdwtype != VanDerWaalsType::Cut) && (ic->vdwtype != VanDerWaalsType::User) && !fr->bBHAM)
     {
         if (ic->rvdw_switch >= ic->rvdw)
         {
@@ -1220,7 +1231,7 @@ void init_forcerec(FILE*                            fp,
         {
             fprintf(fp,
                     "Using %s Lennard-Jones, switch between %g and %g nm\n",
-                    (ic->eeltype == eelSWITCH) ? "switched" : "shifted",
+                    (ic->eeltype == CoulombInteractionType::Switch) ? "switched" : "shifted",
                     ic->rvdw_switch,
                     ic->rvdw);
         }
@@ -1231,7 +1242,7 @@ void init_forcerec(FILE*                            fp,
         gmx_fatal(FARGS, "LJ PME not supported with Buckingham");
     }
 
-    if (fr->bBHAM && (ic->vdwtype == evdwSHIFT || ic->vdwtype == evdwSWITCH))
+    if (fr->bBHAM && (ic->vdwtype == VanDerWaalsType::Shift || ic->vdwtype == VanDerWaalsType::Switch))
     {
         gmx_fatal(FARGS, "Switch/shift interaction not supported with Buckingham");
     }
@@ -1264,7 +1275,7 @@ void init_forcerec(FILE*                            fp,
 
     /* Wall stuff */
     fr->nwall = ir.nwall;
-    if (ir.nwall && ir.wall_type == ewtTABLE)
+    if (ir.nwall && ir.wall_type == WallType::Table)
     {
         make_wall_tables(fp, ir, tabfn, &mtop.groups, fr);
     }
@@ -1361,7 +1372,7 @@ void init_forcerec(FILE*                            fp,
     fr->nthread_ewc = gmx_omp_nthreads_get(emntBonded);
     snew(fr->ewc_t, fr->nthread_ewc);
 
-    if (ir.eDispCorr != edispcNO)
+    if (ir.eDispCorr != DispersionCorrectionType::No)
     {
         fr->dispersionCorrection = std::make_unique<DispersionCorrection>(
                 mtop, ir, fr->bBHAM, fr->ntype, fr->nbfp, *fr->ic, tabfn);
index 15bca48990a80bdf36319cc6c9cd6e035d9e323f..8a0e3416484d6ff4b8f879d8fcab8a61f8586506 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015,2018,2019,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
 
 #include "gromacs/math/vectypes.h"
 #include "gromacs/mdtypes/md_enums.h"
+#include "gromacs/utility/enumerationhelpers.h"
 
 struct ewald_corr_thread_t
 {
-    real   Vcorr_q;
-    real   Vcorr_lj;
-    real   dvdl[efptNR];
-    tensor vir_q;
-    tensor vir_lj;
+    real                                                            Vcorr_q;
+    real                                                            Vcorr_lj;
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> dvdl;
+    tensor                                                          vir_q;
+    tensor                                                          vir_lj;
 };
 
 #endif
index 2ec8bd8acfaab679a67218780485c0db97bfd00d..1dcbf1a22cd591e1a4ac25f903adc50e1cd6dad0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
  * \author Christian Blau <blau@kth.se>
  */
 
+#include <vector>
 #include "gmxpre.h"
 
 #include "freeenergyparameters.h"
 
 #include "gromacs/mdtypes/inputrec.h"
+#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/enumerationhelpers.h"
 
 namespace gmx
 {
@@ -51,13 +54,14 @@ namespace gmx
 namespace
 {
 
-std::array<real, efptNR> lambdasAtState(const int stateIndex, double** const lambdaArray, const int lambdaArrayExtent)
+gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real>
+lambdasAtState(const int stateIndex, gmx::ArrayRef<const std::vector<double>> lambdaArray, const int lambdaArrayExtent)
 {
-    std::array<real, efptNR> lambda;
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> lambda;
     // set lambda from an fep state index from stateIndex, if stateIndex was defined (> -1)
     if (stateIndex >= 0 && stateIndex < lambdaArrayExtent)
     {
-        for (int i = 0; i < efptNR; i++)
+        for (int i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
         {
             lambda[i] = lambdaArray[i][stateIndex];
         }
@@ -112,11 +116,12 @@ double currentGlobalLambda(const int64_t step,
  * \param[in] lambdaArray array of lambda values
  * \param[in] lambdaArrayExtent number of lambda values
  */
-std::array<real, efptNR> interpolatedLambdas(const double   currentGlobalLambda,
-                                             double** const lambdaArray,
-                                             const int      lambdaArrayExtent)
+gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real>
+interpolatedLambdas(const double                             currentGlobalLambda,
+                    gmx::ArrayRef<const std::vector<double>> lambdaArray,
+                    const int                                lambdaArrayExtent)
 {
-    std::array<real, efptNR> lambda;
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> lambda;
     // when there is no lambda value array, set all lambdas to steps * deltaLambdaPerStep
     if (lambdaArrayExtent <= 0)
     {
@@ -127,7 +132,7 @@ std::array<real, efptNR> interpolatedLambdas(const double   currentGlobalLambda,
     // if we run over the boundary of the lambda array, return the boundary array values
     if (currentGlobalLambda <= 0)
     {
-        for (int i = 0; i < efptNR; i++)
+        for (int i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
         {
             lambda[i] = lambdaArray[i][0];
         }
@@ -135,7 +140,7 @@ std::array<real, efptNR> interpolatedLambdas(const double   currentGlobalLambda,
     }
     if (currentGlobalLambda >= 1)
     {
-        for (int i = 0; i < efptNR; i++)
+        for (int i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
         {
             lambda[i] = lambdaArray[i][lambdaArrayExtent - 1];
         }
@@ -147,7 +152,7 @@ std::array<real, efptNR> interpolatedLambdas(const double   currentGlobalLambda,
     const int fepStateRight = fepStateLeft + 1;
     // interpolate between this state and the next
     const double fracBetween = currentGlobalLambda * (lambdaArrayExtent - 1) - fepStateLeft;
-    for (int i = 0; i < efptNR; i++)
+    for (int i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
     {
         lambda[i] = lambdaArray[i][fepStateLeft]
                     + fracBetween * (lambdaArray[i][fepStateRight] - lambdaArray[i][fepStateLeft]);
@@ -157,7 +162,8 @@ std::array<real, efptNR> interpolatedLambdas(const double   currentGlobalLambda,
 
 } // namespace
 
-std::array<real, efptNR> currentLambdas(const int64_t step, const t_lambda& fepvals, const int currentLambdaState)
+gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real>
+currentLambdas(const int64_t step, const t_lambda& fepvals, const int currentLambdaState)
 {
     if (fepvals.delta_lambda == 0)
     {
@@ -171,7 +177,7 @@ std::array<real, efptNR> currentLambdas(const int64_t step, const t_lambda& fepv
             return lambdasAtState(fepvals.init_fep_state, fepvals.all_lambda, fepvals.n_lambda);
         }
 
-        std::array<real, efptNR> lambdas;
+        gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> lambdas;
         std::fill(std::begin(lambdas), std::end(lambdas), fepvals.init_lambda);
         return lambdas;
     }
index 0814bc6c8855c90d9facc981935260e6a53430de..aaa8307166c895f08e44a47ccf64d0bcf9a44482 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -46,6 +46,7 @@
 #include <array>
 
 #include "gromacs/mdtypes/md_enums.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/real.h"
 
 struct t_lambda;
@@ -60,7 +61,9 @@ namespace gmx
  * \param[in] currentLambdaState the lambda state to use to set the lambdas, -1 if not set
  * \returns the current lambda-value array
  */
-std::array<real, efptNR> currentLambdas(int64_t step, const t_lambda& fepvals, int currentLambdaState);
+gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> currentLambdas(int64_t         step,
+                                                                               const t_lambda& fepvals,
+                                                                               int currentLambdaState);
 
 } // namespace gmx
 
index 582676445a21595757bbefa30e13b77fcd9d9984..5726cd0fb347ed3b5c3921ceefab0b22ab42f145 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.
@@ -2197,7 +2197,7 @@ static void lincs_warning(gmx_domdec_t*                 dd,
     }
     if (*warncount > maxwarn)
     {
-        too_many_constraint_warnings(econtLINCS, *warncount);
+        too_many_constraint_warnings(ConstraintAlgorithm::Lincs, *warncount);
     }
 }
 
@@ -2294,7 +2294,7 @@ bool constrain_lincs(bool                            computeRmsd,
      * We can also easily check if any constraint length is changed,
      * if not dH/dlambda=0 and we can also set the boolean to FALSE.
      */
-    bool bCalcDHDL = (ir.efep != efepNO && dvdlambda != nullptr);
+    bool bCalcDHDL = (ir.efep != FreeEnergyPerturbationType::No && dvdlambda != nullptr);
 
     if (lincsd->nc == 0 && cr->dd == nullptr)
     {
@@ -2314,7 +2314,7 @@ bool constrain_lincs(bool                            computeRmsd,
         /* We can't use bCalcDHDL here, since NULL can be passed for dvdlambda
          * also with efep!=fepNO.
          */
-        if (ir.efep != efepNO)
+        if (ir.efep != FreeEnergyPerturbationType::No)
         {
             if (hasMassPerturbed && lincsd->matlam != lambda)
             {
index 176ef3d751af858fb51c57c5e9a126e714bf2ef4..8104b92d00c7265dfa842e696e12659c6b152c17 100644 (file)
@@ -323,7 +323,8 @@ void compute_globals(gmx_global_stat*               gstat,
     /* we calculate a full state kinetic energy either with full-step velocity verlet
        or half step where we need the pressure */
 
-    bEkinAveVel = (ir->eI == eiVV || (ir->eI == eiVVAK && bPres) || bReadEkin);
+    bEkinAveVel = (ir->eI == IntegrationAlgorithm::VV
+                   || (ir->eI == IntegrationAlgorithm::VVAK && bPres) || bReadEkin);
 
     /* in initalization, it sums the shake virial in vv, and to
        sums ekinh_old in leapfrog (or if we are calculating ekinh_old) for other reasons */
@@ -396,7 +397,7 @@ void compute_globals(gmx_global_stat*               gstat,
            If FALSE, we average ekinh_old and ekinh*ekinscale_nhc to get an averaged half step kinetic energy.
          */
         enerd->term[F_TEMP] = sum_ekin(&(ir->opts), ekind, &dvdl_ekin, bEkinAveVel, bScaleEkin);
-        enerd->dvdl_lin[efptMASS] = static_cast<double>(dvdl_ekin);
+        enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Mass] = static_cast<double>(dvdl_ekin);
 
         enerd->term[F_EKIN] = trace(ekind->ekin);
     }
@@ -520,7 +521,7 @@ void set_state_entries(t_state* state, const t_inputrec* ir, bool useModularSimu
      * with what is needed, so we correct this here.
      */
     state->flags = 0;
-    if (ir->efep != efepNO || ir->bExpanded)
+    if (ir->efep != FreeEnergyPerturbationType::No || ir->bExpanded)
     {
         state->flags |= (1 << estLAMBDA);
         state->flags |= (1 << estFEPSTATE);
index 22f3ce96a1813f838b9b662b7332ff022a4165f0..5ca3166ab0e4a3e6aacce8ddefb56f4d64c18813 100644 (file)
@@ -160,7 +160,7 @@ std::unique_ptr<MDAtoms> makeMDAtoms(FILE* fp, const gmx_mtop_t& mtop, const t_i
             md->haveVsites = TRUE;
         }
 
-        if (ir.efep != efepNO && PERTURBED(*atom))
+        if (ir.efep != FreeEnergyPerturbationType::No && PERTURBED(*atom))
         {
             md->nPerturbed++;
             if (atom->mB != atom->m)
@@ -181,7 +181,7 @@ std::unique_ptr<MDAtoms> makeMDAtoms(FILE* fp, const gmx_mtop_t& mtop, const t_i
     md->tmassA = totalMassA;
     md->tmassB = totalMassB;
 
-    if (ir.efep != efepNO && fp)
+    if (ir.efep != FreeEnergyPerturbationType::No && fp)
     {
         fprintf(fp,
                 "There are %d atoms and %d charges for free energy perturbation\n",
@@ -353,7 +353,7 @@ void atoms2md(const gmx_mtop_t*  mtop,
                 mA = 1.0;
                 mB = 1.0;
             }
-            else if (ir->eI == eiBD)
+            else if (ir->eI == IntegrationAlgorithm::BD)
             {
                 /* With BD the physical masses are irrelevant.
                  * To keep the code simple we use most of the normal MD code path
index 8c2791b2fd07fd10aca0f7e0fb787d5704495d30..f51603f8369cb697003aacd622d82a07c56341cc 100644 (file)
@@ -37,6 +37,7 @@
  */
 #include "gmxpre.h"
 
+#include "gromacs/utility/arrayref.h"
 #include "mdebin_bar.h"
 
 #include <cassert>
@@ -384,7 +385,7 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll* dhc, const t_inputrec* ir)
     int       i, j, n;
     double*   lambda_vec;
     int       ndhmax = ir->nstenergy / ir->nstcalcenergy;
-    t_lambda* fep    = ir->fepvals;
+    t_lambda* fep    = ir->fepvals.get();
 
     dhc->temperature    = ir->opts.ref_t[0]; /* only store system temperature */
     dhc->start_time     = 0.;
@@ -402,7 +403,7 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll* dhc, const t_inputrec* ir)
         /* create the native lambda vectors */
         dhc->lambda_index = fep->init_fep_state;
         dhc->n_lambda_vec = 0;
-        for (i = 0; i < efptNR; i++)
+        for (auto i : keysOf(fep->separate_dvdl))
         {
             if (fep->separate_dvdl[i])
             {
@@ -412,11 +413,11 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll* dhc, const t_inputrec* ir)
         snew(dhc->native_lambda_vec, dhc->n_lambda_vec);
         snew(dhc->native_lambda_components, dhc->n_lambda_vec);
         j = 0;
-        for (i = 0; i < efptNR; i++)
+        for (auto i : keysOf(fep->separate_dvdl))
         {
             if (fep->separate_dvdl[i])
             {
-                dhc->native_lambda_components[j] = i;
+                dhc->native_lambda_components[j] = static_cast<int>(i);
                 if (fep->init_fep_state >= 0 && fep->init_fep_state < fep->n_lambda)
                 {
                     dhc->native_lambda_vec[j] = fep->all_lambda[i][fep->init_fep_state];
@@ -460,9 +461,9 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll* dhc, const t_inputrec* ir)
         /* first count the number of states */
 
         /* add the dhdl's */
-        if (fep->dhdl_derivatives == edhdlderivativesYES)
+        if (fep->dhdl_derivatives == DhDlDerivativeCalculation::Yes)
         {
-            for (i = 0; i < efptNR; i++)
+            for (auto i : keysOf(fep->separate_dvdl))
             {
                 if (ir->fepvals->separate_dvdl[i])
                 {
@@ -479,13 +480,13 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll* dhc, const t_inputrec* ir)
         {
             /* include one more for the specification of the state, by lambda or
                fep_state*/
-            if (ir->expandedvals->elmcmove > elmcmoveNO)
+            if (ir->expandedvals->elmcmove > LambdaMoveCalculation::No)
             {
                 dhc->ndh += 1;
                 bExpanded = TRUE;
             }
             /* whether to print energies */
-            if (ir->fepvals->edHdLPrintEnergy != edHdLPrintEnergyNO)
+            if (ir->fepvals->edHdLPrintEnergy != FreeEnergyPrintEnergy::No)
             {
                 dhc->ndh += 1;
                 bEnergy = TRUE;
@@ -525,10 +526,10 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll* dhc, const t_inputrec* ir)
         }
         /* add the dhdl's */
         n_lambda_components = 0;
-        if (fep->dhdl_derivatives == edhdlderivativesYES)
+        if (fep->dhdl_derivatives == DhDlDerivativeCalculation::Yes)
         {
             dhc->dh_dhdl = dhc->dh + n;
-            for (i = 0; i < efptNR; i++)
+            for (auto i : keysOf(fep->separate_dvdl))
             {
                 if (ir->fepvals->separate_dvdl[i])
                 {
@@ -548,9 +549,9 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll* dhc, const t_inputrec* ir)
         }
         else
         {
-            for (i = 0; i < efptNR; i++)
+            for (auto i : keysOf(fep->separate_dvdl))
             {
-                if (ir->fepvals->separate_dvdl[i])
+                if (fep->separate_dvdl[i])
                 {
                     n_lambda_components++; /* count the components */
                 }
@@ -563,9 +564,9 @@ void mde_delta_h_coll_init(t_mde_delta_h_coll* dhc, const t_inputrec* ir)
         {
             int k = 0;
 
-            for (j = 0; j < efptNR; j++)
+            for (auto j : keysOf(fep->separate_dvdl))
             {
-                if (ir->fepvals->separate_dvdl[j])
+                if (fep->separate_dvdl[j])
                 {
                     lambda_vec[k++] = fep->all_lambda[j][i];
                 }
@@ -611,13 +612,13 @@ void done_mde_delta_h_coll(t_mde_delta_h_coll* dhc)
 }
 
 /* add a bunch of samples - note fep_state is double to allow for better data storage */
-void mde_delta_h_coll_add_dh(t_mde_delta_h_coll* dhc,
-                             double              fep_state,
-                             double              energy,
-                             double              pV,
-                             double*             dhdl,
-                             double*             foreign_dU,
-                             double              time)
+void mde_delta_h_coll_add_dh(t_mde_delta_h_coll*   dhc,
+                             double                fep_state,
+                             double                energy,
+                             double                pV,
+                             gmx::ArrayRef<double> dhdl,
+                             double*               foreign_dU,
+                             double                time)
 {
     int i;
 
index b1dacb29aaa5e321f46809bf974f3492782c2867..7c852b7d3a945e30ddced140111bc5b2abd5e5df 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.
@@ -40,6 +40,7 @@
 #define _mdebin_bar_h
 
 #include "gromacs/mdlib/energyoutput.h"
+#include "gromacs/utility/arrayref.h"
 
 /* The functions & data structures here describe writing
    energy differences (or their histogram )for use with g_bar */
@@ -146,13 +147,13 @@ void done_mde_delta_h_coll(t_mde_delta_h_coll* dhc);
  */
 
 /* add a bunch of samples - note fep_state is double to allow for better data storage */
-void mde_delta_h_coll_add_dh(t_mde_delta_h_coll* dhc,
-                             double              fep_state,
-                             double              energy,
-                             double              pV,
-                             double*             dhdl,
-                             double*             foreign_dU,
-                             double              time);
+void mde_delta_h_coll_add_dh(t_mde_delta_h_coll*   dhc,
+                             double                fep_state,
+                             double                energy,
+                             double                pV,
+                             gmx::ArrayRef<double> dhdl,
+                             double*               foreign_dU,
+                             double                time);
 
 /* write the data associated with the du blocks collection as a collection
     of mdebin blocks.
index 4b73bf6ad89af92f263f8532c5f53b58a721c277..7efa543cce2f240cb827b5fb276fccf25a0101d0 100644 (file)
@@ -83,9 +83,9 @@ struct gmx_mdoutf
     ener_file_t                   fp_ene;
     const char*                   fn_cpt;
     gmx_bool                      bKeepAndNumCPT;
-    int                           eIntegrator;
+    IntegrationAlgorithm          eIntegrator;
     gmx_bool                      bExpanded;
-    int                           elamstats;
+    LambdaWeightCalculation       elamstats;
     int                           simulation_part;
     FILE*                         fp_dhdl;
     int                           natoms_global;
@@ -206,8 +206,8 @@ gmx_mdoutf_t init_mdoutf(FILE*                         fplog,
         }
         of->fn_cpt = opt2fn("-cpo", nfile, fnm);
 
-        if ((ir->efep != efepNO || ir->bSimTemp) && ir->fepvals->nstdhdl > 0
-            && (ir->fepvals->separate_dhdl_file == esepdhdlfileYES) && EI_DYNAMICS(ir->eI))
+        if ((ir->efep != FreeEnergyPerturbationType::No || ir->bSimTemp) && ir->fepvals->nstdhdl > 0
+            && (ir->fepvals->separate_dhdl_file == SeparateDhdlFile::Yes) && EI_DYNAMICS(ir->eI))
         {
             if (restartWithAppending)
             {
@@ -289,10 +289,10 @@ static void write_checkpoint(const char*                     fn,
                              const t_commrec*                cr,
                              ivec                            domdecCells,
                              int                             nppnodes,
-                             int                             eIntegrator,
+                             IntegrationAlgorithm            eIntegrator,
                              int                             simulation_part,
                              gmx_bool                        bExpanded,
-                             int                             elamstats,
+                             LambdaWeightCalculation         elamstats,
                              int64_t                         step,
                              double                          t,
                              t_state*                        state,
@@ -355,7 +355,7 @@ static void write_checkpoint(const char*                     fn,
     int             nED       = (edsamhist ? edsamhist->nED : 0);
 
     swaphistory_t* swaphist    = observablesHistory->swapHistory.get();
-    int            eSwapCoords = (swaphist ? swaphist->eSwapCoords : eswapNO);
+    SwapType       eSwapCoords = (swaphist ? swaphist->eSwapCoords : SwapType::No);
 
     CheckpointHeaderContents headerContents = { 0,
                                                 { 0 },
@@ -605,8 +605,15 @@ void mdoutf_write_to_trajectory_files(FILE*                           fplog,
 
             if (of->fp_trn)
             {
-                gmx_trr_write_frame(
-                        of->fp_trn, step, t, state_local->lambda[efptFEP], state_local->box, natoms, x, v, f);
+                gmx_trr_write_frame(of->fp_trn,
+                                    step,
+                                    t,
+                                    state_local->lambda[FreeEnergyPerturbationCouplingType::Fep],
+                                    state_local->box,
+                                    natoms,
+                                    x,
+                                    v,
+                                    f);
                 if (gmx_fio_flush(of->fp_trn) != 0)
                 {
                     gmx_file("Cannot write trajectory; maybe you are out of disk space?");
@@ -617,8 +624,16 @@ void mdoutf_write_to_trajectory_files(FILE*                           fplog,
                velocities and forces to it. */
             else if (of->tng)
             {
-                gmx_fwrite_tng(
-                        of->tng, FALSE, step, t, state_local->lambda[efptFEP], state_local->box, natoms, x, v, f);
+                gmx_fwrite_tng(of->tng,
+                               FALSE,
+                               step,
+                               t,
+                               state_local->lambda[FreeEnergyPerturbationCouplingType::Fep],
+                               state_local->box,
+                               natoms,
+                               x,
+                               v,
+                               f);
             }
             /* If only a TNG file is open for compressed coordinate output (no uncompressed
                coordinate output) also write forces and velocities to it. */
@@ -628,7 +643,7 @@ void mdoutf_write_to_trajectory_files(FILE*                           fplog,
                                FALSE,
                                step,
                                t,
-                               state_local->lambda[efptFEP],
+                               state_local->lambda[FreeEnergyPerturbationCouplingType::Fep],
                                state_local->box,
                                natoms,
                                x,
@@ -675,7 +690,7 @@ void mdoutf_write_to_trajectory_files(FILE*                           fplog,
                            TRUE,
                            step,
                            t,
-                           state_local->lambda[efptFEP],
+                           state_local->lambda[FreeEnergyPerturbationCouplingType::Fep],
                            state_local->box,
                            of->natoms_x_compressed,
                            xxtc,
@@ -698,7 +713,7 @@ void mdoutf_write_to_trajectory_files(FILE*                           fplog,
                 }
                 if (mdof_flags & MDOF_LAMBDA)
                 {
-                    lambda = state_local->lambda[efptFEP];
+                    lambda = state_local->lambda[FreeEnergyPerturbationCouplingType::Fep];
                 }
                 gmx_fwrite_tng(of->tng, FALSE, step, t, lambda, box, natoms, nullptr, nullptr, nullptr);
             }
@@ -716,7 +731,7 @@ void mdoutf_write_to_trajectory_files(FILE*                           fplog,
                 }
                 if (mdof_flags & MDOF_LAMBDA_COMPRESSED)
                 {
-                    lambda = state_local->lambda[efptFEP];
+                    lambda = state_local->lambda[FreeEnergyPerturbationCouplingType::Fep];
                 }
                 gmx_fwrite_tng(of->tng_low_prec, FALSE, step, t, lambda, box, natoms, nullptr, nullptr, nullptr);
             }
index 765eed2dc739ff451a36c3a2760b5261fd5fb5bc..bd2e21def19b6c8ae51a93e23285517da969fc83 100644 (file)
@@ -166,7 +166,8 @@ void count_bonded_distances(const gmx_mtop_t& mtop, const t_inputrec& ir, double
     gmx_bool   bSimdBondeds        = FALSE;
 #endif
 
-    bExcl = (ir.cutoff_scheme == ecutsGROUP && inputrecExclForces(&ir) && !EEL_FULL(ir.coulombtype));
+    bExcl = (ir.cutoff_scheme == CutoffScheme::Group && inputrecExclForces(&ir)
+             && !EEL_FULL(ir.coulombtype));
 
     if (bSimdBondeds)
     {
@@ -277,7 +278,7 @@ static void pp_verlet_load(const gmx_mtop_t& mtop,
     const real nbnxn_refkernel_fac = 8.0;
 #endif
 
-    bQRF = (EEL_RF(ir.coulombtype) || ir.coulombtype == eelCUT);
+    bQRF = (EEL_RF(ir.coulombtype) || ir.coulombtype == CoulombInteractionType::Cut);
 
     gmx::ArrayRef<const t_iparams> iparams = mtop.ffparams.iparams;
     atnr                                   = mtop.ffparams.atnr;
@@ -350,12 +351,12 @@ static void pp_verlet_load(const gmx_mtop_t& mtop,
     c_qlj = (bQRF ? c_nbnxn_qrf_lj : c_nbnxn_qexp_lj);
     c_q   = (bQRF ? c_nbnxn_qrf : c_nbnxn_qexp);
     c_lj  = c_nbnxn_lj;
-    if (ir.vdw_modifier == eintmodPOTSWITCH || EVDW_PME(ir.vdwtype))
+    if (ir.vdw_modifier == InteractionModifiers::PotSwitch || EVDW_PME(ir.vdwtype))
     {
         c_qlj += c_nbnxn_ljexp_add;
         c_lj += c_nbnxn_ljexp_add;
     }
-    if (EVDW_PME(ir.vdwtype) && ir.ljpme_combination_rule == eljpmeLB)
+    if (EVDW_PME(ir.vdwtype) && ir.ljpme_combination_rule == LongRangeVdW::LB)
     {
         /* We don't have LJ-PME LB comb. rule kernels, we use slow kernels */
         c_qlj *= nbnxn_refkernel_fac;
@@ -406,7 +407,7 @@ float pme_load_estimate(const gmx_mtop_t& mtop, const t_inputrec& ir, const matr
     {
         double grid = ir.nkx * ir.nky * gridNkzFactor;
 
-        int f = ((ir.efep != efepNO && bChargePerturbed) ? 2 : 1);
+        int f = ((ir.efep != FreeEnergyPerturbationType::No && bChargePerturbed) ? 2 : 1);
         cost_redist += c_pme_redist * nq_tot;
         cost_spread += f * c_pme_spread * nq_tot * gmx::power3(ir.pme_order);
         cost_fft += f * c_pme_fft * grid * std::log(grid) / std::log(2.0);
@@ -417,8 +418,8 @@ float pme_load_estimate(const gmx_mtop_t& mtop, const t_inputrec& ir, const matr
     {
         double grid = ir.nkx * ir.nky * gridNkzFactor;
 
-        int f = ((ir.efep != efepNO && bTypePerturbed) ? 2 : 1);
-        if (ir.ljpme_combination_rule == eljpmeLB)
+        int f = ((ir.efep != FreeEnergyPerturbationType::No && bTypePerturbed) ? 2 : 1);
+        if (ir.ljpme_combination_rule == LongRangeVdW::LB)
         {
             /* LB combination rule: we have 7 mesh terms */
             f *= 7;
index d499c9403471a589ad144768d5070758999605b8..0816c06bcd5fa8c47851bbd37f45047bb9858343 100644 (file)
@@ -131,6 +131,11 @@ int add_bind(t_bin* b, int nr, const double r[])
     return index;
 }
 
+int add_bind(t_bin* b, gmx::ArrayRef<const double> r)
+{
+    return add_bind(b, r.size(), r.data());
+}
+
 void sum_bin(t_bin* b, const t_commrec* cr)
 {
     int i;
@@ -170,3 +175,8 @@ void extract_bind(t_bin* b, int index, int nr, double r[])
         r[i] = rbuf[i];
     }
 }
+
+void extract_bind(t_bin* b, int index, gmx::ArrayRef<double> r)
+{
+    extract_bind(b, index, r.size(), r.data());
+}
index 20cf110ab751ec75205a0b9981410b7bfaf0d46e..3d1bb3dff95b650920f09700c76773cd30c9eedb 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) 2010,2014,2015,2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2010,2014,2015,2018,2019,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.
@@ -61,6 +61,7 @@ void reset_bin(t_bin* b);
 int add_binr(t_bin* b, int nr, const real r[]);
 int add_binr(t_bin* b, gmx::ArrayRef<const real> r);
 int add_bind(t_bin* b, int nr, const double r[]);
+int add_bind(t_bin* b, gmx::ArrayRef<const double> r);
 /* Add reals to the bin. Returns index */
 
 void sum_bin(t_bin* b, const t_commrec* cr);
@@ -69,6 +70,7 @@ void sum_bin(t_bin* b, const t_commrec* cr);
 void extract_binr(t_bin* b, int index, int nr, real r[]);
 void extract_binr(t_bin* b, int index, gmx::ArrayRef<real> r);
 void extract_bind(t_bin* b, int index, int nr, double r[]);
+void extract_bind(t_bin* b, int index, gmx::ArrayRef<double> r);
 /* Extract values from the bin, starting from index (see add_bin) */
 
 #endif
index fd02d2d75266eff133804c52396838034439bdfc..4584876236e0802897f58858caa0d3499ffd8349 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,2017,2018 by 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.
@@ -69,7 +69,7 @@ void calc_rffac(FILE* fplog, real eps_r, real eps_rf, real Rc, real* krf, real*
         fprintf(fplog,
                 "%s:\n"
                 "epsRF = %g, rc = %g, krf = %g, crf = %g, epsfac = %g\n",
-                eel_names[eelRF],
+                enumValueToString(CoulombInteractionType::RF),
                 eps_rf,
                 Rc,
                 *krf,
index e638fc993af2bd9940f4cfe9ca9028306472fe09..80e2deee7eb95e48c6c968e901efa39dc29367ac 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,2017,2018 by 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.
@@ -746,7 +746,7 @@ static bool bshakef(FILE*                         log,
                         prime,
                         pbc,
                         shaked->omega,
-                        ir.efep != efepNO,
+                        ir.efep != FreeEnergyPerturbationType::No,
                         lambda,
                         lam,
                         invdt,
@@ -774,7 +774,7 @@ static bool bshakef(FILE*                         log,
     /* only for position part? */
     if (econq == ConstraintVariable::Positions)
     {
-        if (ir.efep != efepNO)
+        if (ir.efep != FreeEnergyPerturbationType::No)
         {
             ArrayRef<const t_iparams> iparams = idef.iparams;
 
index b6b21dad6b138ae46f8bb98520da2ecb9aa08592..a18add27538ca959c091944fd5dba7ea4b036cce 100644 (file)
@@ -203,9 +203,17 @@ static void pull_potential_wrapper(const t_commrec*               cr,
     wallcycle_start(wcycle, ewcPULLPOT);
     set_pbc(&pbc, ir.pbcType, box);
     dvdl = 0;
-    enerd->term[F_COM_PULL] += pull_potential(
-            pull_work, mdatoms->massT, &pbc, cr, t, lambda[efptRESTRAINT], as_rvec_array(x.data()), force, &dvdl);
-    enerd->dvdl_lin[efptRESTRAINT] += dvdl;
+    enerd->term[F_COM_PULL] +=
+            pull_potential(pull_work,
+                           mdatoms->massT,
+                           &pbc,
+                           cr,
+                           t,
+                           lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Restraint)],
+                           as_rvec_array(x.data()),
+                           force,
+                           &dvdl);
+    enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Restraint] += dvdl;
     wallcycle_stop(wcycle, ewcPULLPOT);
 }
 
@@ -241,8 +249,8 @@ static void pme_receive_force_ener(t_forcerec*           fr,
                       &cycles_seppme);
     enerd->term[F_COUL_RECIP] += e_q;
     enerd->term[F_LJ_RECIP] += e_lj;
-    enerd->dvdl_lin[efptCOUL] += dvdl_q;
-    enerd->dvdl_lin[efptVDW] += dvdl_lj;
+    enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Coul] += dvdl_q;
+    enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Vdw] += dvdl_lj;
 
     if (wcycle)
     {
@@ -896,7 +904,8 @@ static DomainLifetimeWorkload setupDomainLifetimeWorkload(const t_inputrec&
     }
     domainWork.haveGpuBondedWork = ((fr.gpuBonded != nullptr) && fr.gpuBonded->haveInteractions());
     // Note that haveFreeEnergyWork is constant over the whole run
-    domainWork.haveFreeEnergyWork = (fr.efep != efepNO && mdatoms.nPerturbed != 0);
+    domainWork.haveFreeEnergyWork =
+            (fr.efep != FreeEnergyPerturbationType::No && mdatoms.nPerturbed != 0);
     // We assume we have local force work if there are CPU
     // force tasks including PME or nonbondeds.
     domainWork.haveCpuLocalForceWork =
@@ -1044,8 +1053,10 @@ static void reduceAndUpdateMuTot(DipoleData*                   dipoleData,
     {
         for (int j = 0; j < DIM; j++)
         {
-            muTotal[j] = (1.0 - lambda[efptCOUL]) * dipoleData->muStateAB[0][j]
-                         + lambda[efptCOUL] * dipoleData->muStateAB[1][j];
+            muTotal[j] = (1.0 - lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)])
+                                 * dipoleData->muStateAB[0][j]
+                         + lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)]
+                                   * dipoleData->muStateAB[1][j];
         }
     }
 }
@@ -1285,8 +1296,8 @@ void do_force(FILE*                               fplog,
                                  cr,
                                  box,
                                  as_rvec_array(x.unpaddedArrayRef().data()),
-                                 lambda[efptCOUL],
-                                 lambda[efptVDW],
+                                 lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)],
+                                 lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)],
                                  (stepWork.computeVirial || stepWork.computeEnergy),
                                  step,
                                  simulationWork.useGpuPmePpCommunication,
@@ -1332,8 +1343,8 @@ void do_force(FILE*                               fplog,
                                  cr,
                                  box,
                                  as_rvec_array(x.unpaddedArrayRef().data()),
-                                 lambda[efptCOUL],
-                                 lambda[efptVDW],
+                                 lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)],
+                                 lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)],
                                  (stepWork.computeVirial || stepWork.computeEnergy),
                                  step,
                                  simulationWork.useGpuPmePpCommunication,
@@ -1345,7 +1356,12 @@ void do_force(FILE*                               fplog,
 
     if (useGpuPmeOnThisRank)
     {
-        launchPmeGpuSpread(fr->pmedata, box, stepWork, localXReadyOnDevice, lambda[efptCOUL], wcycle);
+        launchPmeGpuSpread(fr->pmedata,
+                           box,
+                           stepWork,
+                           localXReadyOnDevice,
+                           lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)],
+                           wcycle);
     }
 
     const gmx::DomainLifetimeWorkload& domainWork = runScheduleWork->domainWork;
@@ -1501,7 +1517,10 @@ void do_force(FILE*                               fplog,
         // X copy/transform to allow overlap as well as after the GPU NB
         // launch to avoid FFT launch overhead hijacking the CPU and delaying
         // the nonbonded kernel.
-        launchPmeGpuFftAndGather(fr->pmedata, lambda[efptCOUL], wcycle, stepWork);
+        launchPmeGpuFftAndGather(fr->pmedata,
+                                 lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)],
+                                 wcycle,
+                                 stepWork);
     }
 
     /* Communicate coordinates and sum dipole if necessary +
@@ -1643,7 +1662,8 @@ void do_force(FILE*                               fplog,
                 dipoleData.muStaging[0],
                 dipoleData.muStaging[1]);
 
-        reduceAndUpdateMuTot(&dipoleData, cr, (fr->efep != efepNO), lambda, muTotal, ddBalanceRegionHandler);
+        reduceAndUpdateMuTot(
+                &dipoleData, cr, (fr->efep != FreeEnergyPerturbationType::No), lambda, muTotal, ddBalanceRegionHandler);
     }
 
     /* Reset energies */
@@ -1721,7 +1741,7 @@ void do_force(FILE*                               fplog,
         do_nb_verlet(fr, ic, enerd, stepWork, InteractionLocality::Local, enbvClearFYes, step, nrnb, wcycle);
     }
 
-    if (fr->efep != efepNO && stepWork.computeNonbondedForces)
+    if (fr->efep != FreeEnergyPerturbationType::No && stepWork.computeNonbondedForces)
     {
         /* Calculate the local and non-local free energy interactions here.
          * Happens here on the CPU both with and without GPU.
@@ -1731,7 +1751,7 @@ void do_force(FILE*                               fplog,
                                       as_rvec_array(x.unpaddedArrayRef().data()),
                                       &forceOutNonbonded->forceWithShiftForces(),
                                       *mdatoms,
-                                      inputrec.fepvals,
+                                      inputrec.fepvals.get(),
                                       lambda,
                                       enerd,
                                       stepWork,
@@ -1744,7 +1764,7 @@ void do_force(FILE*                               fplog,
                                           as_rvec_array(x.unpaddedArrayRef().data()),
                                           &forceOutNonbonded->forceWithShiftForces(),
                                           *mdatoms,
-                                          inputrec.fepvals,
+                                          inputrec.fepvals.get(),
                                           lambda,
                                           enerd,
                                           stepWork,
@@ -1801,10 +1821,10 @@ void do_force(FILE*                               fplog,
                                    *mdatoms,
                                    x.unpaddedConstArrayRef(),
                                    &forceOutMtsLevel0.forceWithVirial(),
-                                   lambda[efptVDW],
+                                   lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)],
                                    enerd->grpp.ener[egLJSR].data(),
                                    nrnb);
-        enerd->dvdl_lin[efptVDW] += dvdl_walls;
+        enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Vdw] += dvdl_walls;
     }
 
     if (stepWork.computeListedForces)
@@ -1835,7 +1855,7 @@ void do_force(FILE*                               fplog,
             ForceOutputs& forceOut     = (mtsIndex == 0 ? forceOutMtsLevel0 : *forceOutMtsLevel1);
             listedForces.calculate(wcycle,
                                    box,
-                                   inputrec.fepvals,
+                                   inputrec.fepvals.get(),
                                    cr,
                                    ms,
                                    x,
@@ -1847,7 +1867,7 @@ void do_force(FILE*                               fplog,
                                    &pbc,
                                    enerd,
                                    nrnb,
-                                   lambda.data(),
+                                   lambda,
                                    mdatoms,
                                    DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr,
                                    stepWork);
@@ -1878,14 +1898,14 @@ void do_force(FILE*                               fplog,
     if ((stepWork.computeEnergy || stepWork.computeVirial) && fr->dispersionCorrection && MASTER(cr))
     {
         // Calculate long range corrections to pressure and energy
-        const DispersionCorrection::Correction correction =
-                fr->dispersionCorrection->calculate(box, lambda[efptVDW]);
+        const DispersionCorrection::Correction correction = fr->dispersionCorrection->calculate(
+                box, lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Vdw)]);
 
         if (stepWork.computeEnergy)
         {
             enerd->term[F_DISPCORR] = correction.energy;
             enerd->term[F_DVDL_VDW] += correction.dvdl;
-            enerd->dvdl_lin[efptVDW] += correction.dvdl;
+            enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Vdw] += correction.dvdl;
         }
         if (stepWork.computeVirial)
         {
@@ -2050,14 +2070,24 @@ void do_force(FILE*                               fplog,
                              && !DOMAINDECOMP(cr) && !stepWork.useGpuFBufferOps);
     if (alternateGpuWait)
     {
-        alternatePmeNbGpuWaitReduce(
-                fr->nbv.get(), fr->pmedata, forceOutNonbonded, forceOutMtsLevel1, enerd, lambda[efptCOUL], stepWork, wcycle);
+        alternatePmeNbGpuWaitReduce(fr->nbv.get(),
+                                    fr->pmedata,
+                                    forceOutNonbonded,
+                                    forceOutMtsLevel1,
+                                    enerd,
+                                    lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)],
+                                    stepWork,
+                                    wcycle);
     }
 
     if (!alternateGpuWait && useGpuPmeOnThisRank)
     {
-        pme_gpu_wait_and_reduce(
-                fr->pmedata, stepWork, wcycle, &forceOutMtsLevel1->forceWithVirial(), enerd, lambda[efptCOUL]);
+        pme_gpu_wait_and_reduce(fr->pmedata,
+                                stepWork,
+                                wcycle,
+                                &forceOutMtsLevel1->forceWithVirial(),
+                                enerd,
+                                lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Coul)]);
     }
 
     /* Wait for local GPU NB outputs on the non-alternating wait path */
@@ -2254,7 +2284,7 @@ void do_force(FILE*                               fplog,
     if (stepWork.computeEnergy)
     {
         /* Compute the final potential energy terms */
-        accumulatePotentialEnergies(enerd, lambda, inputrec.fepvals);
+        accumulatePotentialEnergies(enerd, lambda, inputrec.fepvals.get());
 
         if (!EI_TPI(inputrec.eI))
         {
index 1ec865802af6150730932d9b064a09044acfe48e..fa522f3537f461d01dddf430dbaccd98fca72de7 100644 (file)
@@ -169,7 +169,8 @@ void global_stat(const gmx_global_stat* gs,
     bEner       = ((flags & CGLO_ENERGY) != 0);
     bPres       = ((flags & CGLO_PRESSURE) != 0);
     bConstrVir  = ((flags & CGLO_CONSTRAINT) != 0);
-    bEkinAveVel = (inputrec->eI == eiVV || (inputrec->eI == eiVVAK && bPres));
+    bEkinAveVel = (inputrec->eI == IntegrationAlgorithm::VV
+                   || (inputrec->eI == IntegrationAlgorithm::VVAK && bPres));
     bReadEkin   = ((flags & CGLO_READEKIN) != 0);
 
     rb   = gs->rb;
@@ -246,10 +247,10 @@ void global_stat(const gmx_global_stat* gs,
         {
             inn[j] = add_binr(rb, enerd->grpp.nener, enerd->grpp.ener[j].data());
         }
-        if (inputrec->efep != efepNO)
+        if (inputrec->efep != FreeEnergyPerturbationType::No)
         {
-            idvdll  = add_bind(rb, efptNR, enerd->dvdl_lin);
-            idvdlnl = add_bind(rb, efptNR, enerd->dvdl_nonlin);
+            idvdll  = add_bind(rb, enerd->dvdl_lin);
+            idvdlnl = add_bind(rb, enerd->dvdl_nonlin);
             if (enerd->foreignLambdaTerms.numLambdas() > 0)
             {
                 iepl = add_bind(rb,
@@ -263,7 +264,7 @@ void global_stat(const gmx_global_stat* gs,
     {
         icm   = add_binr(rb, DIM * vcm->nr, vcm->group_p[0]);
         imass = add_binr(rb, vcm->nr, vcm->group_mass.data());
-        if (vcm->mode == ecmANGULAR)
+        if (vcm->mode == ComRemovalAlgorithm::Angular)
         {
             icj = add_binr(rb, DIM * vcm->nr, vcm->group_j[0]);
             icx = add_binr(rb, DIM * vcm->nr, vcm->group_x[0]);
@@ -343,10 +344,10 @@ void global_stat(const gmx_global_stat* gs,
         {
             extract_binr(rb, inn[j], enerd->grpp.nener, enerd->grpp.ener[j].data());
         }
-        if (inputrec->efep != efepNO)
+        if (inputrec->efep != FreeEnergyPerturbationType::No)
         {
-            extract_bind(rb, idvdll, efptNR, enerd->dvdl_lin);
-            extract_bind(rb, idvdlnl, efptNR, enerd->dvdl_nonlin);
+            extract_bind(rb, idvdll, enerd->dvdl_lin);
+            extract_bind(rb, idvdlnl, enerd->dvdl_nonlin);
             if (enerd->foreignLambdaTerms.numLambdas() > 0)
             {
                 extract_bind(rb,
@@ -363,7 +364,7 @@ void global_stat(const gmx_global_stat* gs,
     {
         extract_binr(rb, icm, DIM * vcm->nr, vcm->group_p[0]);
         extract_binr(rb, imass, vcm->nr, vcm->group_mass.data());
-        if (vcm->mode == ecmANGULAR)
+        if (vcm->mode == ComRemovalAlgorithm::Angular)
         {
             extract_binr(rb, icj, DIM * vcm->nr, vcm->group_j[0]);
             extract_binr(rb, icx, DIM * vcm->nr, vcm->group_x[0]);
index 3de0c11b896b37adb798905aded2347f098e6e56..d1819bc7df138ad2b290c1067810863cb56326f4 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.
@@ -96,10 +96,10 @@ ConstraintsTestData::ConstraintsTestData(const std::string&       title,
     invdt_ = 1.0 / timestep; // Inverse timestep
 
     // Input record - data that usually comes from configuration file (.mdp)
-    ir_.efep    = 0;
+    ir_.efep    = FreeEnergyPerturbationType::No;
     ir_.init_t  = initialTime;
     ir_.delta_t = timestep;
-    ir_.eI      = 0;
+    ir_.eI      = IntegrationAlgorithm::MD;
 
     // Virial evaluation
     computeVirial_ = computeVirial;
@@ -122,12 +122,12 @@ ConstraintsTestData::ConstraintsTestData(const std::string&       title,
     dHdLambda_         = 0;
     if (compute_dHdLambda_)
     {
-        ir_.efep      = efepYES;
+        ir_.efep      = FreeEnergyPerturbationType::Yes;
         dHdLambdaRef_ = dHdLambdaRef;
     }
     else
     {
-        ir_.efep      = efepNO;
+        ir_.efep      = FreeEnergyPerturbationType::No;
         dHdLambdaRef_ = 0;
     }
 
index 7755ecdfbd19e1e2a3350f59600e845decee16e7..49417a41f5d695c8c65cdd113deefff529cbe30f 100644 (file)
@@ -102,7 +102,7 @@ struct EnergyOutputTestParameters
     //! Barostat (enum)
     PressureCoupling pressureCouplingScheme;
     //! Integrator
-    int integrator;
+    IntegrationAlgorithm integrator;
     //! Number of saved energy frames (to test averages output).
     int numFrames;
     //! If output should be initialized as a rerun.
@@ -117,17 +117,17 @@ struct EnergyOutputTestParameters
  * require ~10 MB of test data and ~2 sec to run the tests.
  */
 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 }
+    { TemperatureCoupling::No, PressureCoupling::No, IntegrationAlgorithm::MD, 1, false, false },
+    { TemperatureCoupling::No, PressureCoupling::No, IntegrationAlgorithm::MD, 1, true, false },
+    { TemperatureCoupling::No, PressureCoupling::No, IntegrationAlgorithm::MD, 1, false, true },
+    { TemperatureCoupling::No, PressureCoupling::No, IntegrationAlgorithm::MD, 0, false, false },
+    { TemperatureCoupling::No, PressureCoupling::No, IntegrationAlgorithm::MD, 10, false, false },
+    { TemperatureCoupling::VRescale, PressureCoupling::No, IntegrationAlgorithm::MD, 1, false, false },
+    { TemperatureCoupling::NoseHoover, PressureCoupling::No, IntegrationAlgorithm::MD, 1, false, false },
+    { TemperatureCoupling::No, PressureCoupling::ParrinelloRahman, IntegrationAlgorithm::MD, 1, false, false },
+    { TemperatureCoupling::No, PressureCoupling::Mttk, IntegrationAlgorithm::MD, 1, false, false },
+    { TemperatureCoupling::No, PressureCoupling::No, IntegrationAlgorithm::VV, 1, false, false },
+    { TemperatureCoupling::No, PressureCoupling::Mttk, IntegrationAlgorithm::VV, 1, false, false }
 };
 
 /*! \brief Test fixture to test energy output.
@@ -205,24 +205,24 @@ public:
         // F_EQM
         inputrec_.bQMMM = true;
         // F_RF_EXCL will not be tested - group scheme is not supported any more
-        inputrec_.cutoff_scheme = ecutsVERLET;
+        inputrec_.cutoff_scheme = CutoffScheme::Verlet;
         // F_COUL_RECIP
-        inputrec_.coulombtype = eelPME;
+        inputrec_.coulombtype = CoulombInteractionType::Pme;
         // F_LJ_RECIP
-        inputrec_.vdwtype = evdwPME;
+        inputrec_.vdwtype = VanDerWaalsType::Pme;
 
         // F_DVDL_COUL, F_DVDL_VDW, F_DVDL_BONDED, F_DVDL_RESTRAINT, F_DKDL and F_DVDL
-        inputrec_.efep                                  = efepYES;
-        inputrec_.fepvals->separate_dvdl[efptCOUL]      = true;
-        inputrec_.fepvals->separate_dvdl[efptVDW]       = true;
-        inputrec_.fepvals->separate_dvdl[efptBONDED]    = true;
-        inputrec_.fepvals->separate_dvdl[efptRESTRAINT] = true;
-        inputrec_.fepvals->separate_dvdl[efptMASS]      = true;
-        inputrec_.fepvals->separate_dvdl[efptCOUL]      = true;
-        inputrec_.fepvals->separate_dvdl[efptFEP]       = true;
+        inputrec_.efep = FreeEnergyPerturbationType::Yes;
+        inputrec_.fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Coul]      = true;
+        inputrec_.fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Vdw]       = true;
+        inputrec_.fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Bonded]    = true;
+        inputrec_.fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Restraint] = true;
+        inputrec_.fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Mass]      = true;
+        inputrec_.fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Coul]      = true;
+        inputrec_.fepvals->separate_dvdl[FreeEnergyPerturbationCouplingType::Fep]       = true;
 
         // F_DISPCORR and F_PDISPCORR
-        inputrec_.eDispCorr = edispcEner;
+        inputrec_.eDispCorr = DispersionCorrectionType::Ener;
         inputrec_.bRot      = true;
 
         // F_ECONSERVED
@@ -231,13 +231,13 @@ public:
         inputrec_.ref_p[ZZ][YY] = 0.0;
 
         // Dipole (mu)
-        inputrec_.ewald_geometry = eewg3DC;
+        inputrec_.ewald_geometry = EwaldGeometry::ThreeDC;
 
         // GMX_CONSTRAINTVIR environment variable should also be
         // set to print constraints and force virials separately.
         gmxSetenv("GMX_CONSTRAINTVIR", "true", 1);
         // To print constrain RMSD, constraints algorithm should be set to LINCS.
-        inputrec_.eConstrAlg = econtLINCS;
+        inputrec_.eConstrAlg = ConstraintAlgorithm::Lincs;
 
         mtop_.bIntermolecularInteractions = false;
 
@@ -355,9 +355,9 @@ public:
         inputrec_.opts.ngtc = 3;
         snew(inputrec_.opts.ref_t, inputrec_.opts.ngtc);
         snew(inputrec_.opts.annealing, inputrec_.opts.ngtc);
-        inputrec_.opts.annealing[0] = eannNO;
-        inputrec_.opts.annealing[1] = eannSINGLE;
-        inputrec_.opts.annealing[2] = eannPERIODIC;
+        inputrec_.opts.annealing[0] = SimulatedAnnealing::No;
+        inputrec_.opts.annealing[1] = SimulatedAnnealing::Single;
+        inputrec_.opts.annealing[2] = SimulatedAnnealing::Periodic;
 
         // This is to keep done_inputrec happy (otherwise sfree() segfaults)
         snew(inputrec_.opts.anneal_time, inputrec_.opts.ngtc);
index 887a7913f35fe9eddf7ea98267370b06ffb180a1..9485d8e2a159ab39352212eeaccab5c8e6bba404 100644 (file)
@@ -54,6 +54,7 @@
 #include "gromacs/mdlib/expanded_internal.h"
 #include "gromacs/mdtypes/md_enums.h"
 
+#include "gromacs/utility/enumerationhelpers.h"
 #include "testutils/testasserts.h"
 
 namespace gmx
@@ -70,10 +71,11 @@ class CalculateAcceptanceWeightSimple : public ::testing::Test, public ::testing
 // Check that unimplemented calculation modes throw
 TEST_P(CalculateAcceptanceWeightSimple, UnknownCalculationModeThrows)
 {
-    for (auto calculationMode = 0; calculationMode < elamstatsNR; ++calculationMode)
+    for (auto calculationMode : gmx::EnumerationArray<LambdaWeightCalculation, bool>::keys())
     {
-        if (calculationMode != elamstatsBARKER && calculationMode != elamstatsMINVAR
-            && calculationMode != elamstatsMETROPOLIS)
+        if (calculationMode != LambdaWeightCalculation::Barker
+            && calculationMode != LambdaWeightCalculation::Minvar
+            && calculationMode != LambdaWeightCalculation::Metropolis)
         {
             EXPECT_THROW_GMX(calculateAcceptanceWeight(calculationMode, GetParam()), NotImplementedError);
         }
@@ -82,21 +84,21 @@ TEST_P(CalculateAcceptanceWeightSimple, UnknownCalculationModeThrows)
 // Check that implemented calculation modes don't throw
 TEST_P(CalculateAcceptanceWeightSimple, KnownCalculationModeDoesNotThrow)
 {
-    EXPECT_NO_THROW(calculateAcceptanceWeight(elamstatsMETROPOLIS, GetParam()));
-    EXPECT_NO_THROW(calculateAcceptanceWeight(elamstatsBARKER, GetParam()));
-    EXPECT_NO_THROW(calculateAcceptanceWeight(elamstatsMINVAR, GetParam()));
+    EXPECT_NO_THROW(calculateAcceptanceWeight(LambdaWeightCalculation::Metropolis, GetParam()));
+    EXPECT_NO_THROW(calculateAcceptanceWeight(LambdaWeightCalculation::Barker, GetParam()));
+    EXPECT_NO_THROW(calculateAcceptanceWeight(LambdaWeightCalculation::Minvar, GetParam()));
 }
 // Barker and MinVar are expected to be equal
 TEST_P(CalculateAcceptanceWeightSimple, BarkerAndMinVarAreIdentical)
 {
-    EXPECT_EQ(calculateAcceptanceWeight(elamstatsBARKER, GetParam()),
-              calculateAcceptanceWeight(elamstatsMINVAR, GetParam()));
+    EXPECT_EQ(calculateAcceptanceWeight(LambdaWeightCalculation::Barker, GetParam()),
+              calculateAcceptanceWeight(LambdaWeightCalculation::Minvar, GetParam()));
 }
 
 /*! \brief Test fixture accepting a calculation mode and an input value for
  *         calculateAcceptanceWeight as well as the expected output value
  */
-using RegressionTuple = std::tuple<int, real, real>;
+using RegressionTuple = std::tuple<LambdaWeightCalculation, real, real>;
 class CalculateAcceptanceWeightRangeRegression :
     public ::testing::Test,
     public ::testing::WithParamInterface<RegressionTuple>
@@ -119,20 +121,21 @@ INSTANTIATE_TEST_CASE_P(
 INSTANTIATE_TEST_CASE_P(
         RegressionTests,
         CalculateAcceptanceWeightRangeRegression,
-        ::testing::Values(RegressionTuple{ elamstatsMETROPOLIS, 0.0, 1.0 },
-                          RegressionTuple{ elamstatsMETROPOLIS, GMX_REAL_NEGZERO, 1.0 },
-                          RegressionTuple{ elamstatsMETROPOLIS, GMX_REAL_EPS, 1.0 },
-                          RegressionTuple{ elamstatsMETROPOLIS, -1.0, 1.0 },
-                          RegressionTuple{ elamstatsMETROPOLIS, -GMX_REAL_MAX, 1.0 },
-                          RegressionTuple{ elamstatsMETROPOLIS, 1.0, std::exp(-1.0) },
-                          RegressionTuple{ elamstatsMETROPOLIS, GMX_REAL_MAX, 0.0 },
-                          RegressionTuple{ elamstatsBARKER, 0.0, 0.5 },
-                          RegressionTuple{ elamstatsBARKER, GMX_REAL_NEGZERO, 0.5 },
-                          RegressionTuple{ elamstatsBARKER, GMX_REAL_EPS, 0.5 },
-                          RegressionTuple{ elamstatsBARKER, -1.0, 1.0 / (1.0 + std::exp(-1.0)) },
-                          RegressionTuple{ elamstatsBARKER, -GMX_REAL_MAX, 1.0 },
-                          RegressionTuple{ elamstatsBARKER, 1.0, 1.0 / (1.0 + std::exp(1.0)) },
-                          RegressionTuple{ elamstatsBARKER, GMX_REAL_MAX, 0.0 }));
+        ::testing::Values(
+                RegressionTuple{ LambdaWeightCalculation::Metropolis, 0.0, 1.0 },
+                RegressionTuple{ LambdaWeightCalculation::Metropolis, GMX_REAL_NEGZERO, 1.0 },
+                RegressionTuple{ LambdaWeightCalculation::Metropolis, GMX_REAL_EPS, 1.0 },
+                RegressionTuple{ LambdaWeightCalculation::Metropolis, -1.0, 1.0 },
+                RegressionTuple{ LambdaWeightCalculation::Metropolis, -GMX_REAL_MAX, 1.0 },
+                RegressionTuple{ LambdaWeightCalculation::Metropolis, 1.0, std::exp(-1.0) },
+                RegressionTuple{ LambdaWeightCalculation::Metropolis, GMX_REAL_MAX, 0.0 },
+                RegressionTuple{ LambdaWeightCalculation::Barker, 0.0, 0.5 },
+                RegressionTuple{ LambdaWeightCalculation::Barker, GMX_REAL_NEGZERO, 0.5 },
+                RegressionTuple{ LambdaWeightCalculation::Barker, GMX_REAL_EPS, 0.5 },
+                RegressionTuple{ LambdaWeightCalculation::Barker, -1.0, 1.0 / (1.0 + std::exp(-1.0)) },
+                RegressionTuple{ LambdaWeightCalculation::Barker, -GMX_REAL_MAX, 1.0 },
+                RegressionTuple{ LambdaWeightCalculation::Barker, 1.0, 1.0 / (1.0 + std::exp(1.0)) },
+                RegressionTuple{ LambdaWeightCalculation::Barker, GMX_REAL_MAX, 0.0 }));
 
 } // namespace
 } // namespace test
index a6ea79624dd7ebdc240935f1a250d29214c2ad1b..d6d085bcfb12a718115f85f65ecd28f4269a0e8e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -47,6 +47,8 @@
 
 #include "gromacs/mdtypes/inputrec.h"
 
+#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "testutils/testasserts.h"
 #include "testutils/testmatchers.h"
 
@@ -76,7 +78,9 @@ struct FreeEnergyParameterTestParameters
     //! the current simulation step
     int64_t step = 0;
     //! the expected lambda at the current simulation step
-    std::array<real, efptNR> expectedLambdas = { -1, -1, -1, -1, -1, -1, -1 };
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> expectedLambdas = { -1, -1, -1,
+                                                                                        -1, -1, -1,
+                                                                                        -1 };
 };
 
 
@@ -143,18 +147,18 @@ public:
      * \param[in] nLambda
      * \returns nLambda * eftpNR matrix with pre-defined values
      */
-    double** getLambdaMatrix(int nLambda)
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, std::vector<double>> getLambdaMatrix(int nLambda)
     {
-        for (int i = 0; i < efptNR; ++i)
+        for (auto i : keysOf(allLambda_))
         {
-            allLambda_[i] = defaultLambdaArrayForTest_[nLambda].data();
+            allLambda_[i] = defaultLambdaArrayForTest_[nLambda];
         }
-        return allLambda_.data();
+        return allLambda_;
     }
 
 private:
     //! Construction aide for double ** matrix without snew
-    std::array<double*, efptNR> allLambda_;
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, std::vector<double>> allLambda_;
     //! a set of default lambda arrays for different lengths
     std::vector<std::vector<double>> defaultLambdaArrayForTest_ = { {}, { 0.8 }, { 0.2, 0.8 }, { 0.2, 0.8, 0.8 } };
 };
index 5a1e2cbf45fd82ff0d2fd23d1301b995e3400ebc..8ae0a74051978cfad7bb8a18b3bcb572f2a1cbf9 100644 (file)
@@ -150,7 +150,7 @@ LeapFrogTestData::LeapFrogTestData(int        numAtoms,
         }
     }
 
-    inputRecord_.eI      = eiMD;
+    inputRecord_.eI      = IntegrationAlgorithm::MD;
     inputRecord_.delta_t = timestep_;
 
     state_.flags = 0;
index 229a0292099b7b4d62ade1f521a8bba805033ee3..daff232482f260d1a21035120d73cb628556c152 100644 (file)
@@ -854,7 +854,7 @@ gmx_stochd_t::gmx_stochd_t(const t_inputrec& inputRecord)
     const t_grpopts* opts = &inputRecord.opts;
     const int        ngtc = opts->ngtc;
 
-    if (inputRecord.eI == eiBD)
+    if (inputRecord.eI == IntegrationAlgorithm::BD)
     {
         bd_rf.resize(ngtc);
     }
@@ -903,7 +903,7 @@ gmx_stochd_t::gmx_stochd_t(const t_inputrec& inputRecord)
 
 void Update::Impl::update_temperature_constants(const t_inputrec& inputRecord)
 {
-    if (inputRecord.eI == eiBD)
+    if (inputRecord.eI == IntegrationAlgorithm::BD)
     {
         if (inputRecord.bd_fric != 0)
         {
@@ -921,7 +921,7 @@ void Update::Impl::update_temperature_constants(const t_inputrec& inputRecord)
             }
         }
     }
-    if (inputRecord.eI == eiSD1)
+    if (inputRecord.eI == IntegrationAlgorithm::SD1)
     {
         for (int gt = 0; gt < inputRecord.opts.ngtc; gt++)
         {
@@ -1304,7 +1304,7 @@ void Update::Impl::update_sd_second_half(const t_inputrec& inputRecord,
     {
         return;
     }
-    if (inputRecord.eI == eiSD1)
+    if (inputRecord.eI == IntegrationAlgorithm::SD1)
     {
         int homenr = md->homenr;
 
@@ -1363,7 +1363,7 @@ void Update::Impl::update_sd_second_half(const t_inputrec& inputRecord,
                       xp_.arrayRefWithPadding(),
                       ArrayRef<RVec>(),
                       state->box,
-                      state->lambda[efptBONDED],
+                      state->lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Bonded)],
                       dvdlambda,
                       state->v.arrayRefWithPadding(),
                       computeVirial,
@@ -1477,7 +1477,7 @@ void Update::Impl::update_coords(const t_inputrec&
 
             switch (inputRecord.eI)
             {
-                case (eiMD):
+                case (IntegrationAlgorithm::MD):
                     do_update_md(start_th,
                                  end_th,
                                  dt,
@@ -1496,7 +1496,7 @@ void Update::Impl::update_coords(const t_inputrec&
                                  state->nosehoover_vxi.data(),
                                  M);
                     break;
-                case (eiSD1):
+                case (IntegrationAlgorithm::SD1):
                     do_update_sd(start_th,
                                  end_th,
                                  dt,
@@ -1515,7 +1515,7 @@ void Update::Impl::update_coords(const t_inputrec&
                                  sd_,
                                  haveConstraints);
                     break;
-                case (eiBD):
+                case (IntegrationAlgorithm::BD):
                     do_update_bd(start_th,
                                  end_th,
                                  dt,
@@ -1534,8 +1534,8 @@ void Update::Impl::update_coords(const t_inputrec&
                                  inputRecord.ld_seed,
                                  DOMAINDECOMP(cr) ? cr->dd->globalAtomIndices.data() : nullptr);
                     break;
-                case (eiVV):
-                case (eiVVAK):
+                case (IntegrationAlgorithm::VV):
+                case (IntegrationAlgorithm::VVAK):
                 {
                     gmx_bool bExtended = (inputRecord.etc == TemperatureCoupling::NoseHoover
                                           || inputRecord.epc == PressureCoupling::ParrinelloRahman
@@ -1589,7 +1589,7 @@ void Update::Impl::update_for_constraint_virial(const t_inputrec& inputRecord,
                                                 const gmx::ArrayRefWithPadding<const gmx::RVec>& f,
                                                 const gmx_ekindata_t& ekind)
 {
-    GMX_ASSERT(inputRecord.eI == eiMD || inputRecord.eI == eiSD1,
+    GMX_ASSERT(inputRecord.eI == IntegrationAlgorithm::MD || inputRecord.eI == IntegrationAlgorithm::SD1,
                "Only leap-frog is supported here");
 
     // Cast to real for faster code, no loss in precision
index 9026ae51aeb08316761aace3093449f9900efdb9..2b92b3fd970ccfe1ea7d4e2fc004d4509bf0e697 100644 (file)
@@ -121,7 +121,7 @@ void integrateVVFirstStep(int64_t                   step,
         rvec* vbuf = nullptr;
 
         wallcycle_start(wcycle, ewcUPDATE);
-        if (ir->eI == eiVV && bInitStep)
+        if (ir->eI == IntegrationAlgorithm::VV && bInitStep)
         {
             /* if using velocity verlet with full time step Ekin,
              * take the first half step only to compute the
@@ -151,11 +151,12 @@ void integrateVVFirstStep(int64_t                   step,
          * Think about ways around this in the future?
          * For now, keep this choice in comments.
          */
-        /*bPres = (ir->eI==eiVV || inputrecNptTrotter(ir)); */
-        /*bTemp = ((ir->eI==eiVV &&(!bInitStep)) || (ir->eI==eiVVAK && inputrecNptTrotter(ir)));*/
+        /*bPres = (ir->eI==IntegrationAlgorithm::VV || inputrecNptTrotter(ir)); */
+        /*bTemp = ((ir->eI==IntegrationAlgorithm::VV &&(!bInitStep)) || (ir->eI==IntegrationAlgorithm::VVAK && inputrecNptTrotter(ir)));*/
         bool bPres = TRUE;
-        bool bTemp = ((ir->eI == eiVV && (!bInitStep)) || (ir->eI == eiVVAK));
-        if (bCalcEner && ir->eI == eiVVAK)
+        bool bTemp = ((ir->eI == IntegrationAlgorithm::VV && (!bInitStep))
+                      || (ir->eI == IntegrationAlgorithm::VVAK));
+        if (bCalcEner && ir->eI == IntegrationAlgorithm::VVAK)
         {
             *bSumEkinhOld = TRUE;
         }
@@ -233,10 +234,11 @@ void integrateVVFirstStep(int64_t                   step,
                     copy_mat(shake_vir, state->svir_prev);
                     copy_mat(force_vir, state->fvir_prev);
                 }
-                if ((inputrecNptTrotter(ir) || inputrecNvtTrotter(ir)) && ir->eI == eiVV)
+                if ((inputrecNptTrotter(ir) || inputrecNvtTrotter(ir)) && ir->eI == IntegrationAlgorithm::VV)
                 {
                     /* update temperature and kinetic energy now that step is over - this is the v(t+dt) point */
-                    enerd->term[F_TEMP] = sum_ekin(&(ir->opts), ekind, nullptr, (ir->eI == eiVV), FALSE);
+                    enerd->term[F_TEMP] = sum_ekin(
+                            &(ir->opts), ekind, nullptr, (ir->eI == IntegrationAlgorithm::VV), FALSE);
                     enerd->term[F_EKIN] = trace(ekind->ekin);
                 }
             }
@@ -273,7 +275,7 @@ void integrateVVFirstStep(int64_t                   step,
             }
         }
         /* if it's the initial step, we performed this first step just to get the constraint virial */
-        if (ir->eI == eiVV && bInitStep)
+        if (ir->eI == IntegrationAlgorithm::VV && bInitStep)
         {
             copy_rvecn(vbuf, state->v.rvec_array(), 0, state->natoms);
             sfree(vbuf);
@@ -283,16 +285,17 @@ void integrateVVFirstStep(int64_t                   step,
 
     /* compute the conserved quantity */
     *saved_conserved_quantity = NPT_energy(ir, state, MassQ);
-    if (ir->eI == eiVV)
+    if (ir->eI == IntegrationAlgorithm::VV)
     {
         *last_ekin = enerd->term[F_EKIN];
     }
-    if ((ir->eDispCorr != edispcEnerPres) && (ir->eDispCorr != edispcAllEnerPres))
+    if ((ir->eDispCorr != DispersionCorrectionType::EnerPres)
+        && (ir->eDispCorr != DispersionCorrectionType::AllEnerPres))
     {
         *saved_conserved_quantity -= enerd->term[F_DISPCORR];
     }
     /* sum up the foreign kinetic energy and dK/dl terms for vv.  currently done every step so that dhdl is correct in the .edr */
-    if (ir->efep != efepNO)
+    if (ir->efep != FreeEnergyPerturbationType::No)
     {
         accumulateKineticLambdaComponents(enerd, state->lambda, *ir->fepvals);
     }
@@ -342,7 +345,7 @@ void integrateVVSecondStep(int64_t                                  step,
      * and entire integrator for MD.
      */
 
-    if (ir->eI == eiVVAK)
+    if (ir->eI == IntegrationAlgorithm::VVAK)
     {
         cbuf->resize(state->x.size());
         std::copy(state->x.begin(), state->x.end(), cbuf->begin());
@@ -365,7 +368,7 @@ void integrateVVSecondStep(int64_t                                  step,
             *ir, step, dvdl_constr, mdatoms, state, cr, nrnb, wcycle, constr, do_log, do_ene);
     upd->finish_update(*ir, mdatoms, state, wcycle, constr != nullptr);
 
-    if (ir->eI == eiVVAK)
+    if (ir->eI == IntegrationAlgorithm::VVAK)
     {
         /* erase F_EKIN and F_TEMP here? */
         /* just compute the kinetic energy at the half step to perform a trotter step */
index 1f1691f1b84509b41b2c0769a311e83f52bb1896..da4ee32808f5239af56b0f9800a539111cc5006a 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.
 t_vcm::t_vcm(const SimulationGroups& groups, const t_inputrec& ir) :
     integratorConservesMomentum(!EI_RANDOM(ir.eI))
 {
-    mode     = (ir.nstcomm > 0) ? ir.comm_mode : ecmNO;
+    mode     = (ir.nstcomm > 0) ? ir.comm_mode : ComRemovalAlgorithm::No;
     ndim     = ndof_com(&ir);
     timeStep = ir.nstcomm * ir.delta_t;
 
-    if (mode == ecmANGULAR && ndim < 3)
+    if (mode == ComRemovalAlgorithm::Angular && ndim < 3)
     {
         gmx_fatal(FARGS, "Can not have angular comm removal with pbc=%s", c_pbcTypeNames[ir.pbcType].c_str());
     }
 
-    if (mode != ecmNO)
+    if (mode != ComRemovalAlgorithm::No)
     {
         nr = groups.groups[SimulationAtomGroupType::MassCenterVelocityRemoval].size();
         /* Allocate one extra for a possible rest group */
@@ -76,7 +76,7 @@ t_vcm::t_vcm(const SimulationGroups& groups, const t_inputrec& ir) :
          * invalidation we add 2 elements to get a 152 byte separation.
          */
         stride = nr + 3;
-        if (mode == ecmANGULAR)
+        if (mode == ComRemovalAlgorithm::Angular)
         {
             snew(group_i, size);
 
@@ -105,7 +105,7 @@ t_vcm::t_vcm(const SimulationGroups& groups, const t_inputrec& ir) :
 
 t_vcm::~t_vcm()
 {
-    if (mode == ecmANGULAR)
+    if (mode == ComRemovalAlgorithm::Angular)
     {
         sfree(group_i);
     }
@@ -115,9 +115,9 @@ void reportComRemovalInfo(FILE* fp, const t_vcm& vcm)
 {
 
     /* Copy pointer to group names and print it. */
-    if (fp && vcm.mode != ecmNO)
+    if (fp && vcm.mode != ComRemovalAlgorithm::No)
     {
-        fprintf(fp, "Center of mass motion removal mode is %s\n", ECOM(vcm.mode));
+        fprintf(fp, "Center of mass motion removal mode is %s\n", enumValueToString(vcm.mode));
         fprintf(fp,
                 "We have the following groups for center of"
                 " mass motion removal:\n");
@@ -156,7 +156,7 @@ void calc_vcm_grp(const t_mdatoms&               md,
                   gmx::ArrayRef<const gmx::RVec> v,
                   t_vcm*                         vcm)
 {
-    if (vcm->mode == ecmNO)
+    if (vcm->mode == ComRemovalAlgorithm::No)
     {
         return;
     }
@@ -172,7 +172,7 @@ void calc_vcm_grp(const t_mdatoms&               md,
                 t_vcm_thread* vcm_t = &vcm->thread_vcm[t * vcm->stride + g];
                 vcm_t->mass         = 0;
                 clear_rvec(vcm_t->p);
-                if (vcm->mode == ecmANGULAR)
+                if (vcm->mode == ComRemovalAlgorithm::Angular)
                 {
                     /* Reset angular momentum */
                     clear_rvec(vcm_t->j);
@@ -199,7 +199,7 @@ void calc_vcm_grp(const t_mdatoms&               md,
                     vcm_t->p[m] += m0 * v[i][m];
                 }
 
-                if (vcm->mode == ecmANGULAR)
+                if (vcm->mode == ComRemovalAlgorithm::Angular)
                 {
                     /* Calculate angular momentum */
                     rvec j0;
@@ -220,7 +220,7 @@ void calc_vcm_grp(const t_mdatoms&               md,
             /* Reset linear momentum */
             vcm->group_mass[g] = 0;
             clear_rvec(vcm->group_p[g]);
-            if (vcm->mode == ecmANGULAR)
+            if (vcm->mode == ComRemovalAlgorithm::Angular)
             {
                 /* Reset angular momentum */
                 clear_rvec(vcm->group_j[g]);
@@ -234,7 +234,7 @@ void calc_vcm_grp(const t_mdatoms&               md,
                 t_vcm_thread* vcm_t = &vcm->thread_vcm[t * vcm->stride + g];
                 vcm->group_mass[g] += vcm_t->mass;
                 rvec_inc(vcm->group_p[g], vcm_t->p);
-                if (vcm->mode == ecmANGULAR)
+                if (vcm->mode == ComRemovalAlgorithm::Angular)
                 {
                     rvec_inc(vcm->group_j[g], vcm_t->j);
                     rvec_inc(vcm->group_x[g], vcm_t->x);
@@ -356,7 +356,7 @@ static void do_stopcm_grp(const t_mdatoms&         mdatoms,
                           gmx::ArrayRef<gmx::RVec> v,
                           const t_vcm&             vcm)
 {
-    if (vcm.mode == ecmNO)
+    if (vcm.mode == ComRemovalAlgorithm::No)
     {
         return;
     }
@@ -370,8 +370,8 @@ static void do_stopcm_grp(const t_mdatoms&         mdatoms,
 #pragma omp parallel num_threads(nth) default(none) shared(x, v, vcm, group_id, mdatoms) \
         firstprivate(homenr)
         {
-            if (vcm.mode == ecmLINEAR || vcm.mode == ecmANGULAR
-                || (vcm.mode == ecmLINEAR_ACCELERATION_CORRECTION && x.empty()))
+            if (vcm.mode == ComRemovalAlgorithm::Linear || vcm.mode == ComRemovalAlgorithm::Angular
+                || (vcm.mode == ComRemovalAlgorithm::LinearAccelerationCorrection && x.empty()))
             {
                 /* Subtract linear momentum for v */
                 switch (vcm.ndim)
@@ -383,7 +383,7 @@ static void do_stopcm_grp(const t_mdatoms&         mdatoms,
             }
             else
             {
-                GMX_ASSERT(vcm.mode == ecmLINEAR_ACCELERATION_CORRECTION,
+                GMX_ASSERT(vcm.mode == ComRemovalAlgorithm::LinearAccelerationCorrection,
                            "When the mode is not linear or angular, it should be acceleration "
                            "correction");
                 /* Subtract linear momentum for v and x*/
@@ -400,7 +400,7 @@ static void do_stopcm_grp(const t_mdatoms&         mdatoms,
                         break;
                 }
             }
-            if (vcm.mode == ecmANGULAR)
+            if (vcm.mode == ComRemovalAlgorithm::Angular)
             {
                 /* Subtract angular momentum */
                 GMX_ASSERT(!x.empty(), "Need x to compute angular momentum correction");
@@ -473,7 +473,7 @@ static void process_and_check_cm_grp(FILE* fp, t_vcm* vcm, real Temp_Max)
     tensor Icm;
 
     /* First analyse the total results */
-    if (vcm->mode != ecmNO)
+    if (vcm->mode != ComRemovalAlgorithm::No)
     {
         for (g = 0; (g < vcm->nr); g++)
         {
@@ -485,7 +485,7 @@ static void process_and_check_cm_grp(FILE* fp, t_vcm* vcm, real Temp_Max)
             }
             /* Else it's zero anyway! */
         }
-        if (vcm->mode == ecmANGULAR)
+        if (vcm->mode == ComRemovalAlgorithm::Angular)
         {
             for (g = 0; (g < vcm->nr); g++)
             {
@@ -552,7 +552,7 @@ static void process_and_check_cm_grp(FILE* fp, t_vcm* vcm, real Temp_Max)
                         Temp_cm);
             }
 
-            if (vcm->mode == ecmANGULAR)
+            if (vcm->mode == ComRemovalAlgorithm::Angular)
             {
                 ekrot = 0.5 * iprod(vcm->group_j[g], vcm->group_w[g]);
                 // TODO: Change absolute energy comparison to relative
@@ -604,7 +604,7 @@ void process_and_stopcm_grp(FILE*                    fplog,
                             gmx::ArrayRef<gmx::RVec> x,
                             gmx::ArrayRef<gmx::RVec> v)
 {
-    if (vcm->mode != ecmNO)
+    if (vcm->mode != ComRemovalAlgorithm::No)
     {
         // TODO: Replace fixed temperature of 1 by a system value
         process_and_check_cm_grp(fplog, vcm, 1);
index b0c142474101f740f8fda554d70e1b6ee6382118..eb33b56e4253c673dd523354a5f8a6987a4f0309 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.
@@ -43,6 +43,7 @@
 #include <vector>
 
 #include "gromacs/math/vectypes.h"
+#include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/real.h"
 
@@ -79,7 +80,7 @@ struct t_vcm
     //! Stride for thread data
     int stride = 0;
     //! One of the enums above
-    int mode = 0;
+    ComRemovalAlgorithm mode = ComRemovalAlgorithm::Linear;
     //! The number of dimensions for corr.
     int ndim = 0;
     //! The time step for COMM removal
index d26a50313b8becd76cecbdf8f02683315232294e..61cb4720ea91d14ef72566423eee9e8d82531039 100644 (file)
@@ -192,11 +192,11 @@ real do_walls(const t_inputrec&              ir,
         ntw[w] = 2 * ntype * ir.wall_atomtype[w];
         switch (ir.wall_type)
         {
-            case ewt93:
+            case WallType::NineThree:
                 fac_d[w] = ir.wall_density[w] * M_PI / 6;
                 fac_r[w] = ir.wall_density[w] * M_PI / 45;
                 break;
-            case ewt104:
+            case WallType::TenFour:
                 fac_d[w] = ir.wall_density[w] * M_PI / 2;
                 fac_r[w] = ir.wall_density[w] * M_PI / 5;
                 break;
@@ -272,11 +272,11 @@ real do_walls(const t_inputrec&              ir,
                     real r1, r2, r4, Vd, Vr;
                     switch (ir.wall_type)
                     {
-                        case ewtTABLE:
+                        case WallType::Table:
                             tableForce(r, *fr.wall_tab[w][gid[i]], Cd, Cr, &V, &F);
                             F *= lamfac;
                             break;
-                        case ewt93:
+                        case WallType::NineThree:
                             r1 = 1 / r;
                             r2 = r1 * r1;
                             r4 = r2 * r2;
@@ -285,7 +285,7 @@ real do_walls(const t_inputrec&              ir,
                             V  = Vr - Vd;
                             F  = lamfac * (9 * Vr - 3 * Vd) * r1;
                             break;
-                        case ewt104:
+                        case WallType::TenFour:
                             r1 = 1 / r;
                             r2 = r1 * r1;
                             r4 = r2 * r2;
@@ -294,7 +294,7 @@ real do_walls(const t_inputrec&              ir,
                             V  = Vr - Vd;
                             F  = lamfac * (10 * Vr - 4 * Vd) * r1;
                             break;
-                        case ewt126:
+                        case WallType::TwelveSix:
                             r1 = 1 / r;
                             r2 = r1 * r1;
                             r4 = r2 * r2;
index c6687d7c3adf1c186cfaf1c0035444fe6ac87c47..8859945fcc394cbdc9096181758f671ffe3e0e74 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,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.
@@ -54,11 +54,11 @@ void LegacySimulator::run()
 {
     switch (inputrec->eI)
     {
-        case eiMD:
-        case eiBD:
-        case eiSD1:
-        case eiVV:
-        case eiVVAK:
+        case IntegrationAlgorithm::MD:
+        case IntegrationAlgorithm::BD:
+        case IntegrationAlgorithm::SD1:
+        case IntegrationAlgorithm::VV:
+        case IntegrationAlgorithm::VVAK:
             if (!EI_DYNAMICS(inputrec->eI))
             {
                 GMX_THROW(APIError(
@@ -73,7 +73,7 @@ void LegacySimulator::run()
                 do_md();
             }
             break;
-        case eiMimic:
+        case IntegrationAlgorithm::Mimic:
             if (doRerun)
             {
                 do_rerun();
@@ -83,19 +83,20 @@ void LegacySimulator::run()
                 do_mimic();
             }
             break;
-        case eiSteep: do_steep(); break;
-        case eiCG: do_cg(); break;
-        case eiNM: do_nm(); break;
-        case eiLBFGS: do_lbfgs(); break;
-        case eiTPI:
-        case eiTPIC:
+        case IntegrationAlgorithm::Steep: do_steep(); break;
+        case IntegrationAlgorithm::CG: do_cg(); break;
+        case IntegrationAlgorithm::NM: do_nm(); break;
+        case IntegrationAlgorithm::LBFGS: do_lbfgs(); break;
+        case IntegrationAlgorithm::TPI:
+        case IntegrationAlgorithm::TPIC:
             if (!EI_TPI(inputrec->eI))
             {
                 GMX_THROW(APIError("do_tpi integrator would be called for a non-TPI integrator"));
             }
             do_tpi();
             break;
-        case eiSD2_REMOVED: GMX_THROW(NotImplementedError("SD2 integrator has been removed"));
+        case IntegrationAlgorithm::SD2Removed:
+            GMX_THROW(NotImplementedError("SD2 integrator has been removed"));
         default: GMX_THROW(APIError("Non existing integrator selected"));
     }
 }
index f161798d84833df7651824d0cc4492218b4c141e..254e4d8e6139e85402490197f60c595b92a699f8 100644 (file)
@@ -423,13 +423,13 @@ void gmx::LegacySimulator::do_md()
                                    || constr->numConstraintsTotal() == 0,
                            "Constraints in domain decomposition are only supported with update "
                            "groups if using GPU update.\n");
-        GMX_RELEASE_ASSERT(ir->eConstrAlg != econtSHAKE || constr == nullptr
+        GMX_RELEASE_ASSERT(ir->eConstrAlg != ConstraintAlgorithm::Shake || constr == nullptr
                                    || constr->numConstraintsTotal() == 0,
                            "SHAKE is not supported with GPU update.");
         GMX_RELEASE_ASSERT(useGpuForPme || (useGpuForNonbonded && simulationWork.useGpuBufferOps),
                            "Either PME or short-ranged non-bonded interaction tasks must run on "
                            "the GPU to use GPU update.\n");
-        GMX_RELEASE_ASSERT(ir->eI == eiMD,
+        GMX_RELEASE_ASSERT(ir->eI == IntegrationAlgorithm::MD,
                            "Only the md integrator is supported with the GPU update.\n");
         GMX_RELEASE_ASSERT(
                 ir->etc != TemperatureCoupling::NoseHoover,
@@ -448,7 +448,7 @@ void gmx::LegacySimulator::do_md()
         GMX_RELEASE_ASSERT(fcdata.orires->nr == 0,
                            "Orientation restraints are not supported with the GPU update.\n");
         GMX_RELEASE_ASSERT(
-                ir->efep == efepNO
+                ir->efep == FreeEnergyPerturbationType::No
                         || (!haveFepPerturbedMasses(*top_global) && !havePerturbedConstraints(*top_global)),
                 "Free energy perturbation of masses and constraints are not supported with the GPU "
                 "update.");
@@ -496,7 +496,7 @@ void gmx::LegacySimulator::do_md()
     // the global state to file and potentially for replica exchange.
     // (Global topology should persist.)
 
-    update_mdatoms(mdatoms, state->lambda[efptMASS]);
+    update_mdatoms(mdatoms, state->lambda[FreeEnergyPerturbationCouplingType::Mass]);
 
     if (ir->bExpanded)
     {
@@ -535,7 +535,7 @@ void gmx::LegacySimulator::do_md()
     /* PME tuning is only supported in the Verlet scheme, with PME for
      * Coulomb. It is not supported with only LJ PME. */
     bPMETune = (mdrunOptions.tunePme && EEL_PME(fr->ic->eeltype) && !mdrunOptions.reproducible
-                && ir->cutoff_scheme != ecutsGROUP);
+                && ir->cutoff_scheme != CutoffScheme::Group);
 
     pme_load_balancing_t* pme_loadbal = nullptr;
     if (bPMETune)
@@ -580,11 +580,11 @@ void gmx::LegacySimulator::do_md()
                                state->x.arrayRefWithPadding(),
                                state->v.arrayRefWithPadding(),
                                state->box,
-                               state->lambda[efptBONDED]);
+                               state->lambda[FreeEnergyPerturbationCouplingType::Bonded]);
         }
     }
 
-    if (ir->efep != efepNO)
+    if (ir->efep != FreeEnergyPerturbationType::No)
     {
         /* Set free energy calculation frequency as the greatest common
          * denominator of nstdhdl and repl_ex_nst. */
@@ -607,7 +607,7 @@ void gmx::LegacySimulator::do_md()
      * this is the first step, since we might be restarting from a checkpoint,
      * and in that case we should not do any modifications to the state.
      */
-    bStopCM = (ir->comm_mode != ecmNO && !ir->bContinuation);
+    bStopCM = (ir->comm_mode != ComRemovalAlgorithm::No && !ir->bContinuation);
 
     // When restarting from a checkpoint, it can be appropriate to
     // initialize ekind from quantities in the checkpoint. Otherwise,
@@ -681,8 +681,9 @@ void gmx::LegacySimulator::do_md()
             /* At initialization, do not pass x with acceleration-correction mode
              * to avoid (incorrect) correction of the initial coordinates.
              */
-            auto x = (vcm.mode == ecmLINEAR_ACCELERATION_CORRECTION) ? ArrayRef<RVec>()
-                                                                     : makeArrayRef(state->x);
+            auto x = (vcm.mode == ComRemovalAlgorithm::LinearAccelerationCorrection)
+                             ? ArrayRef<RVec>()
+                             : makeArrayRef(state->x);
             process_and_stopcm_grp(fplog, &vcm, *mdatoms, x, makeArrayRef(state->v));
             inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr);
         }
@@ -695,7 +696,7 @@ void gmx::LegacySimulator::do_md()
                                     makeConstArrayRef(state->x),
                                     state->box,
                                     &shouldCheckNumberOfBondedInteractions);
-    if (ir->eI == eiVVAK)
+    if (ir->eI == IntegrationAlgorithm::VVAK)
     {
         /* a second call to get the half step temperature initialized as well */
         /* we do the same call as above, but turn the pressure off -- internally to
@@ -745,7 +746,7 @@ void gmx::LegacySimulator::do_md()
     {
         if (!ir->bContinuation)
         {
-            if (constr && ir->eConstrAlg == econtLINCS)
+            if (constr && ir->eConstrAlg == ConstraintAlgorithm::Lincs)
             {
                 fprintf(fplog,
                         "RMS relative constraint deviation after constraining: %.2e\n",
@@ -754,7 +755,7 @@ void gmx::LegacySimulator::do_md()
             if (EI_STATE_VELOCITY(ir->eI))
             {
                 real temp = enerd->term[F_TEMP];
-                if (ir->eI != eiVV)
+                if (ir->eI != IntegrationAlgorithm::VV)
                 {
                     /* Result of Ekin averaged over velocities of -half
                      * and +half step, while we only have -half step here.
@@ -892,13 +893,13 @@ void gmx::LegacySimulator::do_md()
         t         = t0 + step * ir->delta_t;
 
         // TODO Refactor this, so that nstfep does not need a default value of zero
-        if (ir->efep != efepNO || ir->bSimTemp)
+        if (ir->efep != FreeEnergyPerturbationType::No || ir->bSimTemp)
         {
             /* find and set the current lambdas */
             state->lambda = currentLambdas(step, *(ir->fepvals), state->fep_state);
 
-            bDoDHDL     = do_per_step(step, ir->fepvals->nstdhdl);
-            bDoFEP      = ((ir->efep != efepNO) && do_per_step(step, nstfep));
+            bDoDHDL = do_per_step(step, ir->fepvals->nstdhdl);
+            bDoFEP  = ((ir->efep != FreeEnergyPerturbationType::No) && do_per_step(step, nstfep));
             bDoExpanded = (do_per_step(step, ir->expandedvals->nstexpanded) && (ir->bExpanded)
                            && (!bFirstStep));
         }
@@ -915,7 +916,7 @@ void gmx::LegacySimulator::do_md()
         }
 
         /* Stop Center of Mass motion */
-        bStopCM = (ir->comm_mode != ecmNO && do_per_step(step, ir->nstcomm));
+        bStopCM = (ir->comm_mode != ComRemovalAlgorithm::No && do_per_step(step, ir->nstcomm));
 
         /* Determine whether or not to do Neighbour Searching */
         bNS = (bFirstStep || bNStList || bExchanged || bNeedRepartition);
@@ -1034,9 +1035,9 @@ void gmx::LegacySimulator::do_md()
                     fplog, step, t); /* can we improve the information printed here? */
         }
 
-        if (ir->efep != efepNO)
+        if (ir->efep != FreeEnergyPerturbationType::No)
         {
-            update_mdatoms(mdatoms, state->lambda[efptMASS]);
+            update_mdatoms(mdatoms, state->lambda[FreeEnergyPerturbationCouplingType::Mass]);
         }
 
         if (bExchanged)
@@ -1666,7 +1667,7 @@ void gmx::LegacySimulator::do_md()
                         // (not because of a race on state->x being modified on the CPU while H2D is in progress).
                         stateGpu->waitCoordinatesCopiedToDevice(AtomLocality::Local);
                         // If the COM removal changed the velocities on the CPU, this has to be accounted for.
-                        if (vcm.mode != ecmNO)
+                        if (vcm.mode != ComRemovalAlgorithm::No)
                         {
                             stateGpu->copyVelocitiesToGpu(state->v, AtomLocality::Local);
                         }
@@ -1682,7 +1683,7 @@ void gmx::LegacySimulator::do_md()
            but what we actually need entering the new cycle is the new shake_vir value. Ideally, we could
            generate the new shake_vir, but test the veta value for convergence.  This will take some thought. */
 
-        if (ir->efep != efepNO && !EI_VV(ir->eI))
+        if (ir->efep != FreeEnergyPerturbationType::No && !EI_VV(ir->eI))
         {
             /* Sum up the foreign energy and dK/dl terms for md and sd.
                Currently done every step so that dH/dl is correct in the .edr */
@@ -1726,7 +1727,7 @@ void gmx::LegacySimulator::do_md()
             /* #########  BEGIN PREPARING EDR OUTPUT  ###########  */
 
             /* use the directly determined last velocity, not actually the averaged half steps */
-            if (bTrotter && ir->eI == eiVV)
+            if (bTrotter && ir->eI == IntegrationAlgorithm::VV)
             {
                 enerd->term[F_EKIN] = last_ekin;
             }
@@ -1753,9 +1754,9 @@ void gmx::LegacySimulator::do_md()
             {
                 /* only needed if doing expanded ensemble */
                 PrintFreeEnergyInfoToFile(fplog,
-                                          ir->fepvals,
-                                          ir->expandedvals,
-                                          ir->bSimTemp ? ir->simtempvals : nullptr,
+                                          ir->fepvals.get(),
+                                          ir->expandedvals.get(),
+                                          ir->bSimTemp ? ir->simtempvals.get() : nullptr,
                                           state_global->dfhist,
                                           state->fep_state,
                                           ir->nstlog,
@@ -1768,8 +1769,8 @@ void gmx::LegacySimulator::do_md()
                                                  t,
                                                  mdatoms->tmass,
                                                  enerd,
-                                                 ir->fepvals,
-                                                 ir->expandedvals,
+                                                 ir->fepvals.get(),
+                                                 ir->expandedvals.get(),
                                                  lastbox,
                                                  PTCouplingArrays{ state->boxv,
                                                                    state->nosehoover_xi,
@@ -1853,7 +1854,8 @@ void gmx::LegacySimulator::do_md()
          * Not done in last step since trajectory writing happens before this call
          * in the MD loop and exchanges would be lost anyway. */
         bNeedRepartition = FALSE;
-        if ((ir->eSwapCoords != eswapNO) && (step > 0) && !bLastStep && do_per_step(step, ir->swap->nstswap))
+        if ((ir->eSwapCoords != SwapType::No) && (step > 0) && !bLastStep
+            && do_per_step(step, ir->swap->nstswap))
         {
             bNeedRepartition = do_swapcoords(cr,
                                              step,
index d65d8b7898064a76030bd31dabe3736de839b608..e258a8a2c5d6f76deff0eec9d2d85be416b3e41f 100644 (file)
@@ -197,8 +197,8 @@ void gmx::LegacySimulator::do_mimic()
     {
         gmx_fatal(FARGS, "Multiple simulations not supported by MiMiC.");
     }
-    if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc, [](int i) {
-            return i != eannNO;
+    if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc, [](SimulatedAnnealing i) {
+            return i != SimulatedAnnealing::No;
         }))
     {
         gmx_fatal(FARGS, "Simulated annealing not supported by MiMiC.");
@@ -334,9 +334,9 @@ void gmx::LegacySimulator::do_mimic()
     // the global state to file and potentially for replica exchange.
     // (Global topology should persist.)
 
-    update_mdatoms(mdatoms, state->lambda[efptMASS]);
+    update_mdatoms(mdatoms, state->lambda[FreeEnergyPerturbationCouplingType::Mass]);
 
-    if (ir->efep != efepNO && ir->fepvals->nstdhdl != 0)
+    if (ir->efep != FreeEnergyPerturbationType::No && ir->fepvals->nstdhdl != 0)
     {
         doFreeEnergyPerturbation = true;
     }
@@ -454,7 +454,7 @@ void gmx::LegacySimulator::do_mimic()
             MimicCommunicator::getCoords(&state_global->x, state_global->natoms);
         }
 
-        if (ir->efep != efepNO)
+        if (ir->efep != FreeEnergyPerturbationType::No)
         {
             state->lambda = currentLambdas(step, *(ir->fepvals), state_global->fep_state);
         }
@@ -510,9 +510,9 @@ void gmx::LegacySimulator::do_mimic()
             EnergyOutput::printHeader(fplog, step, t); /* can we improve the information printed here? */
         }
 
-        if (ir->efep != efepNO)
+        if (ir->efep != FreeEnergyPerturbationType::No)
         {
-            update_mdatoms(mdatoms, state->lambda[efptMASS]);
+            update_mdatoms(mdatoms, state->lambda[FreeEnergyPerturbationCouplingType::Mass]);
         }
 
         force_flags = (GMX_FORCE_STATECHANGED | GMX_FORCE_DYNAMICBOX | GMX_FORCE_ALLFORCES
@@ -696,7 +696,7 @@ void gmx::LegacySimulator::do_mimic()
            but what we actually need entering the new cycle is the new shake_vir value. Ideally, we could
            generate the new shake_vir, but test the veta value for convergence.  This will take some thought. */
 
-        if (ir->efep != efepNO)
+        if (ir->efep != FreeEnergyPerturbationType::No)
         {
             /* Sum up the foreign energy and dhdl terms for md and sd.
                Currently done every step so that dhdl is correct in the .edr */
@@ -712,8 +712,8 @@ void gmx::LegacySimulator::do_mimic()
                                              t,
                                              mdatoms->tmass,
                                              enerd,
-                                             ir->fepvals,
-                                             ir->expandedvals,
+                                             ir->fepvals.get(),
+                                             ir->expandedvals.get(),
                                              state->box,
                                              PTCouplingArrays({ state->boxv,
                                                                 state->nosehoover_xi,
index a066a5265536130d2274702d427b796b7f4dc268..2b0ad5dc6141f7c097f386b4e4087be626d3bcde 100644 (file)
@@ -396,7 +396,7 @@ static void init_em(FILE*                fplog,
     gmx::ArrayRef<real> lambda    = MASTER(cr) ? state_global->lambda : gmx::ArrayRef<real>();
     initialize_lambdas(fplog, *ir, MASTER(cr), fep_state, lambda);
 
-    if (ir->eI == eiNM)
+    if (ir->eI == IntegrationAlgorithm::NM)
     {
         GMX_ASSERT(shellfc != nullptr, "With NM we always support shells");
 
@@ -461,17 +461,17 @@ static void init_em(FILE*                fplog,
                 cr, ir, *top_global, top, fr, &ems->f, mdAtoms, constr, vsite, shellfc ? *shellfc : nullptr);
     }
 
-    update_mdatoms(mdAtoms->mdatoms(), ems->s.lambda[efptMASS]);
+    update_mdatoms(mdAtoms->mdatoms(), ems->s.lambda[FreeEnergyPerturbationCouplingType::Mass]);
 
     if (constr)
     {
         // TODO how should this cross-module support dependency be managed?
-        if (ir->eConstrAlg == econtSHAKE && gmx_mtop_ftype_count(top_global, F_CONSTR) > 0)
+        if (ir->eConstrAlg == ConstraintAlgorithm::Shake && gmx_mtop_ftype_count(top_global, F_CONSTR) > 0)
         {
             gmx_fatal(FARGS,
                       "Can not do energy minimization with %s, use %s\n",
-                      econstr_names[econtSHAKE],
-                      econstr_names[econtLINCS]);
+                      enumValueToString(ConstraintAlgorithm::Shake),
+                      enumValueToString(ConstraintAlgorithm::Lincs));
         }
 
         if (!ir->bContinuation)
@@ -490,7 +490,7 @@ static void init_em(FILE*                fplog,
                           ems->s.x.arrayRefWithPadding(),
                           ArrayRef<RVec>(),
                           ems->s.box,
-                          ems->s.lambda[efptFEP],
+                          ems->s.lambda[FreeEnergyPerturbationCouplingType::Fep],
                           &dvdl_constr,
                           gmx::ArrayRefWithPadding<RVec>(),
                           computeVirial,
@@ -743,7 +743,7 @@ static bool do_em_step(const t_commrec*                          cr,
                                   s2->x.arrayRefWithPadding(),
                                   ArrayRef<RVec>(),
                                   s2->box,
-                                  s2->lambda[efptBONDED],
+                                  s2->lambda[FreeEnergyPerturbationCouplingType::Bonded],
                                   &dvdl_constr,
                                   gmx::ArrayRefWithPadding<RVec>(),
                                   false,
@@ -762,14 +762,14 @@ static bool do_em_step(const t_commrec*                          cr,
         }
 
         // We should move this check to the different minimizers
-        if (!validStep && ir->eI != eiSteep)
+        if (!validStep && ir->eI != IntegrationAlgorithm::Steep)
         {
             gmx_fatal(FARGS,
                       "The coordinates could not be constrained. Minimizer '%s' can not handle "
                       "constraint failures, use minimizer '%s' before using '%s'.",
-                      EI(ir->eI),
-                      EI(eiSteep),
-                      EI(ir->eI));
+                      enumValueToString(ir->eI),
+                      enumValueToString(IntegrationAlgorithm::Steep),
+                      enumValueToString(ir->eI));
         }
     }
 
@@ -960,7 +960,7 @@ void EnergyEvaluator::run(em_state_t* ems, rvec mu_tot, tensor vir, tensor pres,
     clear_mat(pres);
 
     /* Communicate stuff when parallel */
-    if (PAR(cr) && inputrec->eI != eiNM)
+    if (PAR(cr) && inputrec->eI != IntegrationAlgorithm::NM)
     {
         wallcycle_start(wcycle, ewcMoveE);
 
@@ -985,8 +985,8 @@ void EnergyEvaluator::run(em_state_t* ems, rvec mu_tot, tensor vir, tensor pres,
     if (fr->dispersionCorrection)
     {
         /* Calculate long range corrections to pressure and energy */
-        const DispersionCorrection::Correction correction =
-                fr->dispersionCorrection->calculate(ems->s.box, ems->s.lambda[efptVDW]);
+        const DispersionCorrection::Correction correction = fr->dispersionCorrection->calculate(
+                ems->s.box, ems->s.lambda[FreeEnergyPerturbationCouplingType::Vdw]);
 
         enerd->term[F_DISPCORR] = correction.energy;
         enerd->term[F_EPOT] += correction.energy;
@@ -1017,7 +1017,7 @@ void EnergyEvaluator::run(em_state_t* ems, rvec mu_tot, tensor vir, tensor pres,
                       f,
                       f.unpaddedArrayRef(),
                       ems->s.box,
-                      ems->s.lambda[efptBONDED],
+                      ems->s.lambda[FreeEnergyPerturbationCouplingType::Bonded],
                       &dvdl_constr,
                       gmx::ArrayRefWithPadding<RVec>(),
                       computeVirial,
@@ -1034,7 +1034,7 @@ void EnergyEvaluator::run(em_state_t* ems, rvec mu_tot, tensor vir, tensor pres,
     clear_mat(ekin);
     enerd->term[F_PRES] = calc_pres(fr->pbcType, inputrec->nwall, ems->s.box, ekin, vir, pres);
 
-    if (inputrec->efep != efepNO)
+    if (inputrec->efep != FreeEnergyPerturbationType::No)
     {
         accumulateKineticLambdaComponents(enerd, ems->s.lambda, *inputrec->fepvals);
     }
index e23bea4250d7d383f976ba132a4f457f12c497b7..d813cfdc97b87319c29266d346fa51f1fd495f10 100644 (file)
@@ -248,7 +248,7 @@ gmx_repl_ex_t init_replica_exchange(FILE*                            fplog,
      * but it does guarantee that we can perform replica exchange.
      */
     check_multi_int(fplog, ms, numAtomsInSystem, "the number of atoms", FALSE);
-    check_multi_int(fplog, ms, ir->eI, "the integrator", FALSE);
+    check_multi_int(fplog, ms, static_cast<int>(ir->eI), "the integrator", FALSE);
     check_multi_int64(fplog, ms, ir->init_step + ir->nsteps, "init_step+nsteps", FALSE);
     const int nst = replExParams.exchangeInterval;
     check_multi_int64(
@@ -256,7 +256,7 @@ gmx_repl_ex_t init_replica_exchange(FILE*                            fplog,
     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, static_cast<int>(ir->epc), "the pressure coupling", FALSE);
-    check_multi_int(fplog, ms, ir->efep, "free energy", FALSE);
+    check_multi_int(fplog, ms, static_cast<int>(ir->efep), "free energy", FALSE);
     check_multi_int(fplog, ms, ir->fepvals->n_lambda, "number of lambda states", FALSE);
 
     re->temp = ir->opts.ref_t[0];
@@ -275,7 +275,7 @@ gmx_repl_ex_t init_replica_exchange(FILE*                            fplog,
 
     re->type = -1;
     bTemp    = repl_quantity(ms, re, ereTEMP, re->temp);
-    if (ir->efep != efepNO)
+    if (ir->efep != FreeEnergyPerturbationType::No)
     {
         bLambda = repl_quantity(ms, re, ereLAMBDA, static_cast<real>(ir->fepvals->init_fep_state));
     }
@@ -318,7 +318,7 @@ gmx_repl_ex_t init_replica_exchange(FILE*                            fplog,
     if (re->bNPT)
     {
         snew(re->pres, re->nrepl);
-        if (ir->epct == epctSURFACETENSION)
+        if (ir->epct == PressureCouplingType::SurfaceTension)
         {
             pres = ir->ref_p[ZZ][ZZ];
         }
index 91857cb1c0bf6a581c27d965c44dbb323ea7c9dd..69bf4d661af0a539569be3eb1cd85d0c3c50e67e 100644 (file)
@@ -209,7 +209,7 @@ void gmx::LegacySimulator::do_rerun()
                     "be available in a different form in a future version of GROMACS, "
                     "e.g. gmx rerun -f.");
 
-    if (ir->efep != efepNO
+    if (ir->efep != FreeEnergyPerturbationType::No
         && (mdAtoms->mdatoms()->nMassPerturbed > 0 || (constr && constr->havePerturbedConstraints())))
     {
         gmx_fatal(FARGS,
@@ -245,8 +245,8 @@ void gmx::LegacySimulator::do_rerun()
     {
         gmx_fatal(FARGS, "Multiple simulations not supported by rerun.");
     }
-    if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc, [](int i) {
-            return i != eannNO;
+    if (std::any_of(ir->opts.annealing, ir->opts.annealing + ir->opts.ngtc, [](SimulatedAnnealing i) {
+            return i != SimulatedAnnealing::No;
         }))
     {
         gmx_fatal(FARGS, "Simulated annealing not supported by rerun.");
@@ -277,7 +277,7 @@ void gmx::LegacySimulator::do_rerun()
     const bool bNS           = true;
 
     const SimulationGroups* groups = &top_global->groups;
-    if (ir->eI == eiMimic)
+    if (ir->eI == IntegrationAlgorithm::Mimic)
     {
         auto nonConstGlobalTopology                          = const_cast<gmx_mtop_t*>(top_global);
         nonConstGlobalTopology->intermolecularExclusionGroup = genQmmmIndices(*top_global);
@@ -378,9 +378,9 @@ void gmx::LegacySimulator::do_rerun()
     // the global state to file and potentially for replica exchange.
     // (Global topology should persist.)
 
-    update_mdatoms(mdatoms, state->lambda[efptMASS]);
+    update_mdatoms(mdatoms, state->lambda[FreeEnergyPerturbationCouplingType::Mass]);
 
-    if (ir->efep != efepNO && ir->fepvals->nstdhdl != 0)
+    if (ir->efep != FreeEnergyPerturbationType::No && ir->fepvals->nstdhdl != 0)
     {
         doFreeEnergyPerturbation = true;
     }
@@ -555,7 +555,7 @@ void gmx::LegacySimulator::do_rerun()
             t = step;
         }
 
-        if (ir->efep != efepNO && MASTER(cr))
+        if (ir->efep != FreeEnergyPerturbationType::No && MASTER(cr))
         {
             if (rerun_fr.bLambda)
             {
@@ -620,9 +620,9 @@ void gmx::LegacySimulator::do_rerun()
             EnergyOutput::printHeader(fplog, step, t); /* can we improve the information printed here? */
         }
 
-        if (ir->efep != efepNO)
+        if (ir->efep != FreeEnergyPerturbationType::No)
         {
-            update_mdatoms(mdatoms, state->lambda[efptMASS]);
+            update_mdatoms(mdatoms, state->lambda[FreeEnergyPerturbationCouplingType::Mass]);
         }
 
         force_flags = (GMX_FORCE_STATECHANGED | GMX_FORCE_DYNAMICBOX | GMX_FORCE_ALLFORCES
@@ -793,8 +793,8 @@ void gmx::LegacySimulator::do_rerun()
                                              t,
                                              mdatoms->tmass,
                                              enerd,
-                                             ir->fepvals,
-                                             ir->expandedvals,
+                                             ir->fepvals.get(),
+                                             ir->expandedvals.get(),
                                              state->box,
                                              PTCouplingArrays({ state->boxv,
                                                                 state->nosehoover_xi,
@@ -849,7 +849,8 @@ void gmx::LegacySimulator::do_rerun()
         /* Ion/water position swapping.
          * Not done in last step since trajectory writing happens before this call
          * in the MD loop and exchanges would be lost anyway. */
-        if ((ir->eSwapCoords != eswapNO) && (step > 0) && !isLastStep && do_per_step(step, ir->swap->nstswap))
+        if ((ir->eSwapCoords != SwapType::No) && (step > 0) && !isLastStep
+            && do_per_step(step, ir->swap->nstswap))
         {
             const bool doRerun = true;
             do_swapcoords(cr,
index f3dcf765489113fb721d56bc7e11e5af0f8e4008..dce96b70ae4d9860563d31bcf77709793c79bae5 100644 (file)
@@ -420,7 +420,7 @@ static void prepare_verlet_scheme(FILE*               fplog,
 {
     // We checked the cut-offs in grompp, but double-check here.
     // We have PME+LJcutoff kernels for rcoulomb>rvdw.
-    if (EEL_PME_EWALD(ir->coulombtype) && ir->vdwtype == eelCUT)
+    if (EEL_PME_EWALD(ir->coulombtype) && ir->vdwtype == VanDerWaalsType::Cut)
     {
         GMX_RELEASE_ASSERT(ir->rcoulomb >= ir->rvdw,
                            "With Verlet lists and PME we should have rcoulomb>=rvdw");
@@ -916,7 +916,8 @@ int Mdrunner::mdrunner()
     // the inputrec read by the master rank. The ranks can now all run
     // the task-deciding functions and will agree on the result
     // without needing to communicate.
-    const bool useDomainDecomposition = (PAR(cr) && !(EI_TPI(inputrec->eI) || inputrec->eI == eiNM));
+    const bool useDomainDecomposition =
+            (PAR(cr) && !(EI_TPI(inputrec->eI) || inputrec->eI == IntegrationAlgorithm::NM));
 
     // Note that these variables describe only their own node.
     //
@@ -1026,7 +1027,7 @@ int Mdrunner::mdrunner()
     /* NM and TPI parallelize over force/energy calculations, not atoms,
      * so we need to initialize and broadcast the global state.
      */
-    if (inputrec->eI == eiNM || inputrec->eI == eiTPI)
+    if (inputrec->eI == IntegrationAlgorithm::NM || inputrec->eI == IntegrationAlgorithm::TPI)
     {
         if (!MASTER(cr))
         {
@@ -1056,7 +1057,7 @@ int Mdrunner::mdrunner()
 #endif
     }
 
-    if (doRerun && (EI_ENERGY_MINIMIZATION(inputrec->eI) || eiNM == inputrec->eI))
+    if (doRerun && (EI_ENERGY_MINIMIZATION(inputrec->eI) || IntegrationAlgorithm::NM == inputrec->eI))
     {
         gmx_fatal(FARGS,
                   "The .mdp file specified an energy mininization or normal mode algorithm, and "
@@ -1246,7 +1247,7 @@ int Mdrunner::mdrunner()
         gmx_bcast(sizeof(box), box, cr->mpiDefaultCommunicator);
     }
 
-    if (inputrec->cutoff_scheme != ecutsVERLET)
+    if (inputrec->cutoff_scheme != CutoffScheme::Verlet)
     {
         gmx_fatal(FARGS,
                   "This group-scheme .tpr file can no longer be run by mdrun. Please update to the "
@@ -1834,7 +1835,7 @@ int Mdrunner::mdrunner()
         }
 
         t_swap* swap = nullptr;
-        if (inputrec->eSwapCoords != eswapNO)
+        if (inputrec->eSwapCoords != SwapType::No)
         {
             /* Initialize ion swapping code */
             swap = init_swapcoords(fplog,
@@ -1860,7 +1861,7 @@ int Mdrunner::mdrunner()
 
         // cos acceleration is only supported by md, but older tpr
         // files might still combine it with other integrators
-        GMX_RELEASE_ASSERT(inputrec->cos_accel == 0.0 || inputrec->eI == eiMD,
+        GMX_RELEASE_ASSERT(inputrec->cos_accel == 0.0 || inputrec->eI == IntegrationAlgorithm::MD,
                            "cos_acceleration is only supported by integrator=md");
 
         /* Kinetic energy data */
@@ -1915,9 +1916,10 @@ int Mdrunner::mdrunner()
             && ((runScheduleWork.simulationWork.useGpuPme && thisRankHasDuty(cr, DUTY_PME))
                 || runScheduleWork.simulationWork.useGpuBufferOps))
         {
-            GpuApiCallBehavior transferKind = (inputrec->eI == eiMD && !doRerun && !useModularSimulator)
-                                                      ? GpuApiCallBehavior::Async
-                                                      : GpuApiCallBehavior::Sync;
+            GpuApiCallBehavior transferKind =
+                    (inputrec->eI == IntegrationAlgorithm::MD && !doRerun && !useModularSimulator)
+                            ? GpuApiCallBehavior::Async
+                            : GpuApiCallBehavior::Sync;
             GMX_RELEASE_ASSERT(deviceStreamManager != nullptr,
                                "GPU device stream manager should be initialized to use GPU.");
             stateGpu = std::make_unique<gmx::StatePropagatorDataGpu>(
index 7521606b7be6a446f5bf454ed286d6dacf12dd73..92d48683e619eb71b7441109a8da19bd7deaf2fc 100644 (file)
@@ -907,8 +907,8 @@ static void init_adir(gmx_shellfc_t*            shfc,
                   shfc->adir_xnold.arrayRefWithPadding(),
                   {},
                   box,
-                  lambda[efptBONDED],
-                  &(dvdlambda[efptBONDED]),
+                  lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Bonded)],
+                  &(dvdlambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Bonded)]),
                   {},
                   computeVirial,
                   nullptr,
@@ -922,8 +922,8 @@ static void init_adir(gmx_shellfc_t*            shfc,
                   shfc->adir_xnew.arrayRefWithPadding(),
                   {},
                   box,
-                  lambda[efptBONDED],
-                  &(dvdlambda[efptBONDED]),
+                  lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Bonded)],
+                  &(dvdlambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Bonded)]),
                   {},
                   computeVirial,
                   nullptr,
@@ -949,8 +949,8 @@ static void init_adir(gmx_shellfc_t*            shfc,
                   shfc->adir_xnew.arrayRefWithPadding(),
                   acc_dir,
                   box,
-                  lambda[efptBONDED],
-                  &(dvdlambda[efptBONDED]),
+                  lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Bonded)],
+                  &(dvdlambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Bonded)]),
                   {},
                   computeVirial,
                   nullptr,
@@ -1135,7 +1135,7 @@ void relax_shell_flexcon(FILE*                         fplog,
             sf_dir += md->massT[i] * norm2(shfc->acc_dir[i]);
         }
     }
-    accumulatePotentialEnergies(enerd, lambda, inputrec->fepvals);
+    accumulatePotentialEnergies(enerd, lambda, inputrec->fepvals.get());
     Epot[Min] = enerd->term[F_EPOT];
 
     df[Min] = rms_force(cr, forceWithPadding[Min].paddedArrayRef(), shells, nflexcon, &sf_dir, &Epot[Min]);
@@ -1249,7 +1249,7 @@ void relax_shell_flexcon(FILE*                         fplog,
                  nullptr,
                  shellfc_flags,
                  ddBalanceRegionHandler);
-        accumulatePotentialEnergies(enerd, lambda, inputrec->fepvals);
+        accumulatePotentialEnergies(enerd, lambda, inputrec->fepvals.get());
         if (gmx_debug_at)
         {
             pr_rvecs(debug, 0, "RELAX: force[Min]", as_rvec_array(force[Min].data()), homenr);
index 2adb328745531b784b89204690e0408d3f9b4e64..2eda48878568839abae065cc5b7b95c190837871 100644 (file)
@@ -221,11 +221,11 @@ void LegacySimulator::do_tpi()
 
     nnodes = cr->nnodes;
 
-    gmx_mtop_generate_local_top(*top_global, &top, inputrec->efep != efepNO);
+    gmx_mtop_generate_local_top(*top_global, &top, inputrec->efep != FreeEnergyPerturbationType::No);
 
     const SimulationGroups* groups = &top_global->groups;
 
-    bCavity = (inputrec->eI == eiTPIC);
+    bCavity = (inputrec->eI == IntegrationAlgorithm::TPIC);
     if (bCavity)
     {
         ptr = getenv("GMX_TPIC_MASSES");
@@ -340,7 +340,7 @@ void LegacySimulator::do_tpi()
 
     snew(x_mol, a_tp1 - a_tp0);
 
-    bDispCorr = (inputrec->eDispCorr != edispcNO);
+    bDispCorr = (inputrec->eDispCorr != DispersionCorrectionType::No);
     bCharge   = FALSE;
     for (i = a_tp0; i < a_tp1; i++)
     {
@@ -569,9 +569,9 @@ void LegacySimulator::do_tpi()
 
     switch (inputrec->eI)
     {
-        case eiTPI: stepblocksize = inputrec->nstlist; break;
-        case eiTPIC: stepblocksize = 1; break;
-        default: gmx_fatal(FARGS, "Unknown integrator %s", ei_names[inputrec->eI]);
+        case IntegrationAlgorithm::TPI: stepblocksize = inputrec->nstlist; break;
+        case IntegrationAlgorithm::TPIC: stepblocksize = 1; break;
+        default: gmx_fatal(FARGS, "Unknown integrator %s", enumValueToString(inputrec->eI));
     }
 
     while (bNotLastFrame)
index 951a7d25907ebf55a8728690d0f147b6057a467f..c047978b15bd913e1a65dd249c197d2674270ac6 100644 (file)
@@ -2,7 +2,7 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * 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.
@@ -133,7 +133,7 @@ struct AwhBiasParams
     double   targetBetaScaling; /**< Beta scaling value for Boltzmann type target distributions. */
     double   targetCutoff; /**< Free energy cutoff value for cutoff type target distribution in kJ/mol.*/
     int      eGrowth;      /**< How the biasing histogram grows. */
-    int      bUserData;    /**< Is there a user-defined initial PMF estimate and target estimate? */
+    bool     bUserData;    /**< Is there a user-defined initial PMF estimate and target estimate? */
     double   errorInitial; /**< Estimated initial free energy error in kJ/mol. */
     int      shareGroup; /**< When >0, the bias is shared with biases of the same group and across multiple simulations when shareBiasMultisim=true */
     gmx_bool equilibrateHistogram; /**< True if the simulation starts out by equilibrating the histogram. */
index 70ce4f66efedff1345494de40590ae08256aedae..f2d18f7b408bcbf963a54306d06033184f109a1a 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.
@@ -42,6 +42,7 @@
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/topology/idef.h"
 #include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/real.h"
 
@@ -199,9 +200,9 @@ struct gmx_enerdata_t
     //! Energy group pair non-bonded energies
     struct gmx_grppairener_t grpp;
     //! Contributions to dV/dlambda with linear dependence on lambda
-    double dvdl_lin[efptNR] = { 0 };
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, double> dvdl_lin = { 0 };
     //! Contributions to dV/dlambda with non-linear dependence on lambda
-    double dvdl_nonlin[efptNR] = { 0 };
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, double> dvdl_nonlin = { 0 };
     /* The idea is that dvdl terms with linear lambda dependence will be added
      * automatically to enerpart_lambda. Terms with non-linear lambda dependence
      * should explicitly determine the energies at foreign lambda points
index 09dce8f273f319b959feda55db855f28a71ad220..e8de62a0b68737eae3625c9d5ed951315ef45c9d 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) 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.
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/real.h"
 
+enum class DistanceRestraintWeighting : int;
+
 typedef real rvec5[5];
 
 /* Distance restraining stuff */
 typedef struct t_disresdata
 {
-    int      dr_weighting; /* Weighting of pairs in one restraint              */
-    gmx_bool dr_bMixed;    /* Use sqrt of the instantaneous times              *
-                            * the time averaged violation                      */
-    real dr_fc;            /* Force constant for disres,                       *
-                            * which is multiplied by a (possibly)              *
-                            * different factor for each restraint              */
-    real  dr_tau;          /* Time constant for disres                   */
-    real  ETerm;           /* multiplication factor for time averaging         */
-    real  ETerm1;          /* 1 - ETerm1                                       */
-    real  exp_min_t_tau;   /* Factor for slowly switching on the force         */
-    int   nres;            /* The number of distance restraints                */
-    int   npair;           /* The number of distance restraint pairs           */
-    int   type_min;        /* The minimum iparam type index for restraints     */
-    real  sumviol;         /* The sum of violations                            */
-    real* rt;              /* The instantaneous distance (npair)               */
-    real* rm3tav;          /* The time averaged distance (npair)               */
-    real* Rtl_6;           /* The instantaneous r^-6 (nres)                    */
-    real* Rt_6;            /* The instantaneous ensemble averaged r^-6 (nres)  */
-    real* Rtav_6;          /* The time and ensemble averaged r^-6 (nres)       */
-    int   nsystems;        /* The number of systems for ensemble averaging     */
+    DistanceRestraintWeighting dr_weighting; /* Weighting of pairs in one restraint              */
+    gmx_bool                   dr_bMixed;    /* Use sqrt of the instantaneous times              *
+                                              * the time averaged violation                      */
+    real dr_fc;                              /* Force constant for disres,                       *
+                                              * which is multiplied by a (possibly)              *
+                                              * different factor for each restraint              */
+    real  dr_tau;                            /* Time constant for disres                         */
+    real  ETerm;                             /* multiplication factor for time averaging         */
+    real  ETerm1;                            /* 1 - ETerm1                                       */
+    real  exp_min_t_tau;                     /* Factor for slowly switching on the force         */
+    int   nres;                              /* The number of distance restraints                */
+    int   npair;                             /* The number of distance restraint pairs           */
+    int   type_min;                          /* The minimum iparam type index for restraints     */
+    real  sumviol;                           /* The sum of violations                            */
+    real* rt;                                /* The instantaneous distance (npair)               */
+    real* rm3tav;                            /* The time averaged distance (npair)               */
+    real* Rtl_6;                             /* The instantaneous r^-6 (nres)                    */
+    real* Rt_6;                              /* The instantaneous ensemble averaged r^-6 (nres)  */
+    real* Rtav_6;                            /* The time and ensemble averaged r^-6 (nres)       */
+    int   nsystems;                          /* The number of systems for ensemble averaging     */
 
     /* TODO: Implement a proper solution for parallel disre indexing */
     const t_iatom* forceatomsStart; /* Pointer to the start of the disre forceatoms */
index 8c1d1500155f0d38b0d4a33289381d8c4799c151..c324f07400971ed5c9e07304395b6483a393c0bc 100644 (file)
@@ -173,9 +173,9 @@ private:
     //! Shift force array for computing the virial, size SHIFTS
     std::vector<gmx::RVec> shiftForces_;
 };
-
+// NOLINTNEXTLINE (clang-analyzer-optin.performance.Padding)
 struct t_forcerec
-{ // NOLINT (clang-analyzer-optin.performance.Padding)
+{
     // Declare an explicit constructor and destructor, so they can be
     // implemented in a single source file, so that not every source
     // file that includes this one needs to understand how to find the
@@ -190,10 +190,10 @@ struct t_forcerec
     //! Tells whether atoms inside a molecule can be in different periodic images,
     //  i.e. whether we need to take into account PBC when computing distances inside molecules.
     //  This determines whether PBC must be considered for e.g. bonded interactions.
-    gmx_bool bMolPBC     = FALSE;
-    int      rc_scaling  = 0;
-    rvec     posres_com  = { 0 };
-    rvec     posres_comB = { 0 };
+    gmx_bool        bMolPBC     = FALSE;
+    RefCoordScaling rc_scaling  = RefCoordScaling::No;
+    rvec            posres_com  = { 0 };
+    rvec            posres_comB = { 0 };
 
     gmx_bool use_simd_kernels = FALSE;
 
@@ -206,10 +206,10 @@ struct t_forcerec
      * tabulated we already included the inputrec modification there, so the kernel
      * modification setting will say 'none' in that case.
      */
-    int nbkernel_elec_interaction = 0;
-    int nbkernel_vdw_interaction  = 0;
-    int nbkernel_elec_modifier    = 0;
-    int nbkernel_vdw_modifier     = 0;
+    NbkernelElecType     nbkernel_elec_interaction = NbkernelElecType::None;
+    NbkernelVdwType      nbkernel_vdw_interaction  = NbkernelVdwType::None;
+    InteractionModifiers nbkernel_elec_modifier    = InteractionModifiers::None;
+    InteractionModifiers nbkernel_vdw_modifier     = InteractionModifiers::None;
 
     /* Cut-Off stuff.
      * Infinite cut-off's will be GMX_CUTOFF_INF (unlike in t_inputrec: 0).
@@ -234,7 +234,7 @@ struct t_forcerec
     std::unique_ptr<t_forcetable> pairsTable; /* for 1-4 interactions, [pairs] and [pairs_nb] */
 
     /* Free energy */
-    int efep = 0;
+    FreeEnergyPerturbationType efep = FreeEnergyPerturbationType::No;
 
     /* Information about atom properties for the molecule blocks in the system */
     std::vector<cginfo_mb_t> cginfo_mb;
@@ -262,7 +262,7 @@ struct t_forcerec
 
     /* Data for PPPM/PME/Ewald */
     struct gmx_pme_t* pmedata                = nullptr;
-    int               ljpme_combination_rule = 0;
+    LongRangeVdW      ljpme_combination_rule = LongRangeVdW::Geom;
 
     /* PME/Ewald stuff */
     struct gmx_ewald_tab_t* ewald_table = nullptr;
index 903e3ef62ebc2a1c3a22c7f2c5d5a2e44259da1e..e5abdb4f5e2ebd010b94e6b7c9e19aaf79b48946 100644 (file)
@@ -37,6 +37,7 @@
  */
 #include "gmxpre.h"
 
+#include "gromacs/utility/enumerationhelpers.h"
 #include "inputrec.h"
 
 #include <cstdio>
@@ -44,6 +45,7 @@
 #include <cstring>
 
 #include <algorithm>
+#include <memory>
 #include <numeric>
 
 #include "gromacs/math/veccompare.h"
@@ -88,9 +90,9 @@ t_inputrec::t_inputrec()
     // TODO When this memset is removed, remove the suppression of
     // gcc -Wno-class-memaccess in a CMakeLists.txt file.
     std::memset(this, 0, sizeof(*this)); // NOLINT(bugprone-undefined-memory-manipulation)
-    snew(fepvals, 1);
-    snew(expandedvals, 1);
-    snew(simtempvals, 1);
+    fepvals      = std::make_unique<t_lambda>();
+    expandedvals = std::make_unique<t_expanded>();
+    simtempvals  = std::make_unique<t_simtemp>();
 }
 
 t_inputrec::~t_inputrec()
@@ -243,48 +245,43 @@ int ir_optimal_nstpcouple(const t_inputrec* ir)
 
 gmx_bool ir_coulomb_switched(const t_inputrec* ir)
 {
-    return (ir->coulombtype == eelSWITCH || ir->coulombtype == eelSHIFT
-            || ir->coulombtype == eelPMESWITCH || ir->coulombtype == eelPMEUSERSWITCH
-            || ir->coulomb_modifier == eintmodPOTSWITCH || ir->coulomb_modifier == eintmodFORCESWITCH);
+    return (ir->coulombtype == CoulombInteractionType::Switch
+            || ir->coulombtype == CoulombInteractionType::Shift
+            || ir->coulombtype == CoulombInteractionType::PmeSwitch
+            || ir->coulombtype == CoulombInteractionType::PmeUserSwitch
+            || ir->coulomb_modifier == InteractionModifiers::PotSwitch
+            || ir->coulomb_modifier == InteractionModifiers::ForceSwitch);
 }
 
 gmx_bool ir_coulomb_is_zero_at_cutoff(const t_inputrec* ir)
 {
-    return (ir->cutoff_scheme == ecutsVERLET || ir_coulomb_switched(ir)
-            || ir->coulomb_modifier != eintmodNONE || ir->coulombtype == eelRF_ZERO);
+    return (ir->cutoff_scheme == CutoffScheme::Verlet || ir_coulomb_switched(ir)
+            || ir->coulomb_modifier != InteractionModifiers::None
+            || ir->coulombtype == CoulombInteractionType::RFZero);
 }
 
 gmx_bool ir_coulomb_might_be_zero_at_cutoff(const t_inputrec* ir)
 {
-    return (ir_coulomb_is_zero_at_cutoff(ir) || ir->coulombtype == eelUSER || ir->coulombtype == eelPMEUSER);
+    return (ir_coulomb_is_zero_at_cutoff(ir) || ir->coulombtype == CoulombInteractionType::User
+            || ir->coulombtype == CoulombInteractionType::PmeUser);
 }
 
 gmx_bool ir_vdw_switched(const t_inputrec* ir)
 {
-    return (ir->vdwtype == evdwSWITCH || ir->vdwtype == evdwSHIFT
-            || ir->vdw_modifier == eintmodPOTSWITCH || ir->vdw_modifier == eintmodFORCESWITCH);
+    return (ir->vdwtype == VanDerWaalsType::Switch || ir->vdwtype == VanDerWaalsType::Shift
+            || ir->vdw_modifier == InteractionModifiers::PotSwitch
+            || ir->vdw_modifier == InteractionModifiers::ForceSwitch);
 }
 
 gmx_bool ir_vdw_is_zero_at_cutoff(const t_inputrec* ir)
 {
-    return (ir->cutoff_scheme == ecutsVERLET || ir_vdw_switched(ir) || ir->vdw_modifier != eintmodNONE);
+    return (ir->cutoff_scheme == CutoffScheme::Verlet || ir_vdw_switched(ir)
+            || ir->vdw_modifier != InteractionModifiers::None);
 }
 
 gmx_bool ir_vdw_might_be_zero_at_cutoff(const t_inputrec* ir)
 {
-    return (ir_vdw_is_zero_at_cutoff(ir) || ir->vdwtype == evdwUSER);
-}
-
-static void done_lambdas(t_lambda* fep)
-{
-    if (fep->n_lambda > 0)
-    {
-        for (int i = 0; i < efptNR; i++)
-        {
-            sfree(fep->all_lambda[i]);
-        }
-    }
-    sfree(fep->all_lambda);
+    return (ir_vdw_is_zero_at_cutoff(ir) || ir->vdwtype == VanDerWaalsType::User);
 }
 
 static void done_t_rot(t_rot* rot)
@@ -321,10 +318,6 @@ void done_inputrec(t_inputrec* ir)
     sfree(ir->opts.tau_t);
     sfree(ir->opts.nFreeze);
     sfree(ir->opts.egp_flags);
-    done_lambdas(ir->fepvals);
-    sfree(ir->fepvals);
-    sfree(ir->expandedvals);
-    sfree(ir->simtempvals);
 
     done_t_rot(ir->rot);
     delete ir->params;
@@ -367,7 +360,7 @@ static void pr_grp_opts(FILE* out, int indent, const char* title, const t_grpopt
     fprintf(out, "annealing%s", bMDPformat ? " = " : ":");
     for (i = 0; (i < opts->ngtc); i++)
     {
-        fprintf(out, "  %10s", EANNEAL(opts->annealing[i]));
+        fprintf(out, "  %10s", enumValueToString(opts->annealing[i]));
     }
     fprintf(out, "\n");
 
@@ -465,12 +458,12 @@ static void pr_pull_coord(FILE* fp, int indent, int c, const t_pull_coord* pcrd)
 
     pr_indent(fp, indent);
     fprintf(fp, "pull-coord %d:\n", c);
-    PS("type", EPULLTYPE(pcrd->eType));
-    if (pcrd->eType == epullEXTERNAL)
+    PS("type", enumValueToString(pcrd->eType));
+    if (pcrd->eType == PullingAlgorithm::External)
     {
         PS("potential-provider", pcrd->externalPotentialProvider.c_str());
     }
-    PS("geometry", EPULLGEOM(pcrd->eGeom));
+    PS("geometry", enumValueToString(pcrd->eGeom));
     for (g = 0; g < pcrd->ngroup; g++)
     {
         char buf[STRLEN];
@@ -490,7 +483,7 @@ static void pr_pull_coord(FILE* fp, int indent, int c, const t_pull_coord* pcrd)
 
 static void pr_simtempvals(FILE* fp, int indent, const t_simtemp* simtemp, int n_lambda)
 {
-    PS("simulated-tempering-scaling", ESIMTEMP(simtemp->eSimTempScale));
+    PS("simulated-tempering-scaling", enumValueToString(simtemp->eSimTempScale));
     PR("sim-temp-low", simtemp->simtemp_low);
     PR("sim-temp-high", simtemp->simtemp_high);
     pr_rvec(fp, indent, "simulated tempering temperatures", simtemp->temperatures, n_lambda, TRUE);
@@ -500,26 +493,26 @@ static void pr_expandedvals(FILE* fp, int indent, const t_expanded* expand, int
 {
 
     PI("nstexpanded", expand->nstexpanded);
-    PS("lmc-stats", elamstats_names[expand->elamstats]);
-    PS("lmc-move", elmcmove_names[expand->elmcmove]);
-    PS("lmc-weights-equil", elmceq_names[expand->elmceq]);
-    if (expand->elmceq == elmceqNUMATLAM)
+    PS("lmc-stats", enumValueToString(expand->elamstats));
+    PS("lmc-move", enumValueToString(expand->elmcmove));
+    PS("lmc-weights-equil", enumValueToString(expand->elmceq));
+    if (expand->elmceq == LambdaWeightWillReachEquilibrium::NumAtLambda)
     {
         PI("weight-equil-number-all-lambda", expand->equil_n_at_lam);
     }
-    if (expand->elmceq == elmceqSAMPLES)
+    if (expand->elmceq == LambdaWeightWillReachEquilibrium::Samples)
     {
         PI("weight-equil-number-samples", expand->equil_samples);
     }
-    if (expand->elmceq == elmceqSTEPS)
+    if (expand->elmceq == LambdaWeightWillReachEquilibrium::Steps)
     {
         PI("weight-equil-number-steps", expand->equil_steps);
     }
-    if (expand->elmceq == elmceqWLDELTA)
+    if (expand->elmceq == LambdaWeightWillReachEquilibrium::WLDelta)
     {
         PR("weight-equil-wl-delta", expand->equil_wl_delta);
     }
-    if (expand->elmceq == elmceqRATIO)
+    if (expand->elmceq == LambdaWeightWillReachEquilibrium::Ratio)
     {
         PR("weight-equil-count-ratio", expand->equil_ratio);
     }
@@ -538,13 +531,13 @@ static void pr_expandedvals(FILE* fp, int indent, const t_expanded* expand, int
     PS("wl-oneovert", EBOOL(expand->bWLoneovert));
 
     pr_indent(fp, indent);
-    pr_rvec(fp, indent, "init-lambda-weights", expand->init_lambda_weights, n_lambda, TRUE);
+    pr_rvec(fp, indent, "init-lambda-weights", expand->init_lambda_weights.data(), n_lambda, TRUE);
     PS("init-weights", EBOOL(expand->bInit_weights));
 }
 
 static void pr_fepvals(FILE* fp, int indent, const t_lambda* fep, gmx_bool bMDPformat)
 {
-    int i, j;
+    int j;
 
     PR("init-lambda", fep->init_lambda);
     PI("init-lambda-state", fep->init_fep_state);
@@ -559,9 +552,9 @@ static void pr_fepvals(FILE* fp, int indent, const t_lambda* fep, gmx_bool bMDPf
     {
         pr_indent(fp, indent);
         fprintf(fp, "separate-dvdl%s\n", bMDPformat ? " = " : ":");
-        for (i = 0; i < efptNR; i++)
+        for (auto i : gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, bool>::keys())
         {
-            fprintf(fp, "%18s = ", efpt_names[i]);
+            fprintf(fp, "%18s = ", enumValueToString(i));
             if (fep->separate_dvdl[i])
             {
                 fprintf(fp, "  TRUE");
@@ -573,9 +566,10 @@ static void pr_fepvals(FILE* fp, int indent, const t_lambda* fep, gmx_bool bMDPf
             fprintf(fp, "\n");
         }
         fprintf(fp, "all-lambdas%s\n", bMDPformat ? " = " : ":");
-        for (i = 0; i < efptNR; i++)
+        for (auto key : gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, bool>::keys())
         {
-            fprintf(fp, "%18s = ", efpt_names[i]);
+            fprintf(fp, "%18s = ", enumValueToString(key));
+            int i = static_cast<int>(key);
             for (j = 0; j < fep->n_lambda; j++)
             {
                 fprintf(fp, "  %10g", fep->all_lambda[i][j]);
@@ -584,7 +578,7 @@ static void pr_fepvals(FILE* fp, int indent, const t_lambda* fep, gmx_bool bMDPf
         }
     }
     PI("calc-lambda-neighbors", fep->lambda_neighbors);
-    PS("dhdl-print-energy", edHdLPrintEnergy_names[fep->edHdLPrintEnergy]);
+    PS("dhdl-print-energy", enumValueToString(fep->edHdLPrintEnergy));
     PR("sc-alpha", fep->sc_alpha);
     PI("sc-power", fep->sc_power);
     PR("sc-r-power", fep->sc_r_power);
@@ -593,8 +587,8 @@ static void pr_fepvals(FILE* fp, int indent, const t_lambda* fep, gmx_bool bMDPf
     PS("sc-coul", EBOOL(fep->bScCoul));
     PI("dh-hist-size", fep->dh_hist_size);
     PD("dh-hist-spacing", fep->dh_hist_spacing);
-    PS("separate-dhdl-file", SEPDHDLFILETYPE(fep->separate_dhdl_file));
-    PS("dhdl-derivatives", DHDLDERIVATIVESTYPE(fep->dhdl_derivatives));
+    PS("separate-dhdl-file", enumValueToString(fep->separate_dhdl_file));
+    PS("dhdl-derivatives", enumValueToString(fep->dhdl_derivatives));
 };
 
 static void pr_pull(FILE* fp, int indent, const pull_params_t& pull)
@@ -691,7 +685,7 @@ static void pr_rotgrp(FILE* fp, int indent, int g, const t_rotgrp* rotg)
     pr_indent(fp, indent);
     fprintf(fp, "rot-group %d:\n", g);
     indent += 2;
-    PS("rot-type", EROTGEOM(rotg->eType));
+    PS("rot-type", enumValueToString(rotg->eType));
     PS("rot-massw", EBOOL(rotg->bMassW));
     pr_ivec_block(fp, indent, "atom", rotg->ind, rotg->nat, TRUE);
     pr_rvecs(fp, indent, "x-ref", rotg->x_ref, rotg->nat);
@@ -702,7 +696,7 @@ static void pr_rotgrp(FILE* fp, int indent, int g, const t_rotgrp* rotg)
     PR("rot-slab-dist", rotg->slab_dist);
     PR("rot-min-gauss", rotg->min_gaussian);
     PR("rot-eps", rotg->eps);
-    PS("rot-fit-method", EROTFIT(rotg->eFittype));
+    PS("rot-fit-method", enumValueToString(rotg->eFittype));
     PI("rot-potfit-nstep", rotg->PotAngle_nstep);
     PR("rot-potfit-step", rotg->PotAngle_step);
 }
@@ -745,11 +739,19 @@ static void pr_swap(FILE* fp, int indent, const t_swapcoords* swap)
     }
 
     /* The solvent group */
-    snprintf(str, STRLEN, "solvent group %s", swap->grp[eGrpSolvent].molname);
-    pr_ivec_block(fp, indent, str, swap->grp[eGrpSolvent].ind, swap->grp[eGrpSolvent].nat, TRUE);
+    snprintf(str,
+             STRLEN,
+             "solvent group %s",
+             swap->grp[static_cast<int>(SwapGroupSplittingType::Solvent)].molname);
+    pr_ivec_block(fp,
+                  indent,
+                  str,
+                  swap->grp[static_cast<int>(SwapGroupSplittingType::Solvent)].ind,
+                  swap->grp[static_cast<int>(SwapGroupSplittingType::Solvent)].nat,
+                  TRUE);
 
     /* Now print the indices for all the ion groups: */
-    for (int ig = eSwapFixedGrpNR; ig < swap->ngrp; ig++)
+    for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < swap->ngrp; ig++)
     {
         snprintf(str, STRLEN, "ion group %s", swap->grp[ig].molname);
         pr_ivec_block(fp, indent, str, swap->grp[ig].ind, swap->grp[ig].nat, TRUE);
@@ -766,7 +768,7 @@ static void pr_swap(FILE* fp, int indent, const t_swapcoords* swap)
     /* Print the requested ion counts for both compartments */
     for (int ic = eCompA; ic <= eCompB; ic++)
     {
-        for (int ig = eSwapFixedGrpNR; ig < swap->ngrp; ig++)
+        for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < swap->ngrp; ig++)
         {
             snprintf(str, STRLEN, "%s-in-%c", swap->grp[ig].molname, 'A' + ic);
             PI(str, swap->grp[ig].nmolReq[ic]);
@@ -800,7 +802,7 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
          * options are written in the default mdout.mdp, and with
          * the same user-exposed names to facilitate debugging.
          */
-        PS("integrator", EI(ir->eI));
+        PS("integrator", enumValueToString(ir->eI));
         PR("tinit", ir->init_t);
         PR("dt", ir->delta_t);
         PSTEP("nsteps", ir->nsteps);
@@ -830,7 +832,7 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
                 PI(factorKey.c_str(), mtsLevel.stepFactor);
             }
         }
-        PS("comm-mode", ECOM(ir->comm_mode));
+        PS("comm-mode", enumValueToString(ir->comm_mode));
         PI("nstcomm", ir->nstcomm);
 
         /* Langevin dynamics */
@@ -859,7 +861,7 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
         PR("compressed-x-precision", ir->x_compression_precision);
 
         /* Neighborsearching parameters */
-        PS("cutoff-scheme", ECUTSCHEME(ir->cutoff_scheme));
+        PS("cutoff-scheme", enumValueToString(ir->cutoff_scheme));
         PI("nstlist", ir->nstlist);
         PS("pbc", c_pbcTypeNames[ir->pbcType].c_str());
         PS("periodic-molecules", EBOOL(ir->bPeriodicMols));
@@ -867,8 +869,8 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
         PR("rlist", ir->rlist);
 
         /* Options for electrostatics and VdW */
-        PS("coulombtype", EELTYPE(ir->coulombtype));
-        PS("coulomb-modifier", INTMODIFIER(ir->coulomb_modifier));
+        PS("coulombtype", enumValueToString(ir->coulombtype));
+        PS("coulomb-modifier", enumValueToString(ir->coulomb_modifier));
         PR("rcoulomb-switch", ir->rcoulomb_switch);
         PR("rcoulomb", ir->rcoulomb);
         if (ir->epsilon_r != 0)
@@ -887,11 +889,11 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
         {
             PS("epsilon-rf", infbuf);
         }
-        PS("vdw-type", EVDWTYPE(ir->vdwtype));
-        PS("vdw-modifier", INTMODIFIER(ir->vdw_modifier));
+        PS("vdw-type", enumValueToString(ir->vdwtype));
+        PS("vdw-modifier", enumValueToString(ir->vdw_modifier));
         PR("rvdw-switch", ir->rvdw_switch);
         PR("rvdw", ir->rvdw);
-        PS("DispCorr", EDISPCORR(ir->eDispCorr));
+        PS("DispCorr", enumValueToString(ir->eDispCorr));
         PR("table-extension", ir->tabext);
 
         PR("fourierspacing", ir->fourier_spacing);
@@ -901,8 +903,8 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
         PI("pme-order", ir->pme_order);
         PR("ewald-rtol", ir->ewald_rtol);
         PR("ewald-rtol-lj", ir->ewald_rtol_lj);
-        PS("lj-pme-comb-rule", ELJPMECOMBNAMES(ir->ljpme_combination_rule));
-        PR("ewald-geometry", ir->ewald_geometry);
+        PS("lj-pme-comb-rule", enumValueToString(ir->ljpme_combination_rule));
+        PS("ewald-geometry", enumValueToString(ir->ewald_geometry));
         PR("epsilon-surface", ir->epsilon_surface);
 
         /* Options for weak coupling algorithms */
@@ -912,12 +914,12 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
         PS("print-nose-hoover-chain-variables", EBOOL(ir->bPrintNHChains));
 
         PS("pcoupl", enumValueToString(ir->epc));
-        PS("pcoupltype", EPCOUPLTYPETYPE(ir->epct));
+        PS("pcoupltype", enumValueToString(ir->epct));
         PI("nstpcouple", ir->nstpcouple);
         PR("tau-p", ir->tau_p);
         pr_matrix(fp, indent, "compressibility", ir->compress, bMDPformat);
         pr_matrix(fp, indent, "ref-p", ir->ref_p, bMDPformat);
-        PS("refcoord-scaling", EREFSCALINGTYPE(ir->refcoord_scaling));
+        PS("refcoord-scaling", enumValueToString(ir->refcoord_scaling));
 
         if (bMDPformat)
         {
@@ -936,7 +938,7 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
         pr_int(fp, indent, "ngQM", ir->opts.ngQM);
 
         /* CONSTRAINT OPTIONS */
-        PS("constraint-algorithm", ECONSTRTYPE(ir->eConstrAlg));
+        PS("constraint-algorithm", enumValueToString(ir->eConstrAlg));
         PS("continuation", EBOOL(ir->bContinuation));
 
         PS("Shake-SOR", EBOOL(ir->bShakeSOR));
@@ -947,7 +949,7 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
 
         /* Walls */
         PI("nwall", ir->nwall);
-        PS("wall-type", EWALLTYPE(ir->wall_type));
+        PS("wall-type", enumValueToString(ir->wall_type));
         PR("wall-r-linpot", ir->wall_r_linpot);
         /* wall-atomtype */
         PI("wall-atomtype[0]", ir->wall_atomtype[0]);
@@ -986,8 +988,8 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
         }
 
         /* NMR refinement stuff */
-        PS("disre", EDISRETYPE(ir->eDisre));
-        PS("disre-weighting", EDISREWEIGHTING(ir->eDisreWeighting));
+        PS("disre", enumValueToString(ir->eDisre));
+        PS("disre-weighting", enumValueToString(ir->eDisreWeighting));
         PS("disre-mixed", EBOOL(ir->bDisreMixed));
         PR("dr-fc", ir->dr_fc);
         PR("dr-tau", ir->dr_tau);
@@ -998,14 +1000,14 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
         PR("nstorireout", ir->nstorireout);
 
         /* FREE ENERGY VARIABLES */
-        PS("free-energy", EFEPTYPE(ir->efep));
-        if (ir->efep != efepNO || ir->bSimTemp)
+        PS("free-energy", enumValueToString(ir->efep));
+        if (ir->efep != FreeEnergyPerturbationType::No || ir->bSimTemp)
         {
-            pr_fepvals(fp, indent, ir->fepvals, bMDPformat);
+            pr_fepvals(fp, indent, ir->fepvals.get(), bMDPformat);
         }
         if (ir->bExpanded)
         {
-            pr_expandedvals(fp, indent, ir->expandedvals, ir->fepvals->n_lambda);
+            pr_expandedvals(fp, indent, ir->expandedvals.get(), ir->fepvals->n_lambda);
         }
 
         /* NON-equilibrium MD stuff */
@@ -1016,12 +1018,12 @@ void pr_inputrec(FILE* fp, int indent, const char* title, const t_inputrec* ir,
         PS("simulated-tempering", EBOOL(ir->bSimTemp));
         if (ir->bSimTemp)
         {
-            pr_simtempvals(fp, indent, ir->simtempvals, ir->fepvals->n_lambda);
+            pr_simtempvals(fp, indent, ir->simtempvals.get(), ir->fepvals->n_lambda);
         }
 
         /* ION/WATER SWAPPING FOR COMPUTATIONAL ELECTROPHYSIOLOGY */
-        PS("swapcoords", ESWAPTYPE(ir->eSwapCoords));
-        if (ir->eSwapCoords != eswapNO)
+        PS("swapcoords", enumValueToString(ir->eSwapCoords));
+        if (ir->eSwapCoords != SwapType::No)
         {
             pr_swap(fp, indent, ir->swap);
         }
@@ -1063,7 +1065,7 @@ static void cmp_grpopts(FILE* fp, const t_grpopts* opt1, const t_grpopts* opt2,
         cmp_real(fp, "inputrec->grpopts.nrdf", i, opt1->nrdf[i], opt2->nrdf[i], ftol, abstol);
         cmp_real(fp, "inputrec->grpopts.ref_t", i, opt1->ref_t[i], opt2->ref_t[i], ftol, abstol);
         cmp_real(fp, "inputrec->grpopts.tau_t", i, opt1->tau_t[i], opt2->tau_t[i], ftol, abstol);
-        cmp_int(fp, "inputrec->grpopts.annealing", i, opt1->annealing[i], opt2->annealing[i]);
+        cmpEnum(fp, "inputrec->grpopts.annealing", opt1->annealing[i], opt2->annealing[i]);
         cmp_int(fp, "inputrec->grpopts.anneal_npoints", i, opt1->anneal_npoints[i], opt2->anneal_npoints[i]);
         if (opt1->anneal_npoints[i] == opt2->anneal_npoints[i])
         {
@@ -1155,7 +1157,7 @@ static void cmp_awhBiasParams(FILE*                     fp,
                ftol,
                abstol);
     cmp_int(fp, "inputrec->awhParams->biaseGrowth", biasIndex, bias1->eGrowth, bias2->eGrowth);
-    cmp_bool(fp, "inputrec->awhParams->biasbUserData", biasIndex, bias1->bUserData != 0, bias2->bUserData != 0);
+    cmp_bool(fp, "inputrec->awhParams->biasbUserData", biasIndex, bias1->bUserData, bias2->bUserData);
     cmp_double(fp,
                "inputrec->awhParams->biaserror_initial",
                biasIndex,
@@ -1202,7 +1204,7 @@ static void cmp_simtempvals(FILE*            fp,
                             real             abstol)
 {
     int i;
-    cmp_int(fp, "inputrec->simtempvals->eSimTempScale", -1, simtemp1->eSimTempScale, simtemp2->eSimTempScale);
+    cmpEnum(fp, "inputrec->simtempvals->eSimTempScale", simtemp1->eSimTempScale, simtemp2->eSimTempScale);
     cmp_real(fp, "inputrec->simtempvals->simtemp_high", -1, simtemp1->simtemp_high, simtemp2->simtemp_high, ftol, abstol);
     cmp_real(fp, "inputrec->simtempvals->simtemp_low", -1, simtemp1->simtemp_low, simtemp2->simtemp_low, ftol, abstol);
     for (i = 0; i < n_lambda; i++)
@@ -1240,12 +1242,12 @@ static void cmp_expandedvals(FILE*             fp,
                  abstol);
     }
 
-    cmp_int(fp, "inputrec->expandedvals->lambda-stats", -1, expand1->elamstats, expand2->elamstats);
-    cmp_int(fp, "inputrec->expandedvals->lambda-mc-move", -1, expand1->elmcmove, expand2->elmcmove);
+    cmpEnum(fp, "inputrec->expandedvals->lambda-stats", expand1->elamstats, expand2->elamstats);
+    cmpEnum(fp, "inputrec->expandedvals->lambda-mc-move", expand1->elmcmove, expand2->elmcmove);
     cmp_int(fp, "inputrec->expandedvals->lmc-repeats", -1, expand1->lmc_repeats, expand2->lmc_repeats);
     cmp_int(fp, "inputrec->expandedvals->lmc-gibbsdelta", -1, expand1->gibbsdeltalam, expand2->gibbsdeltalam);
     cmp_int(fp, "inputrec->expandedvals->lmc-forced-nstart", -1, expand1->lmc_forced_nstart, expand2->lmc_forced_nstart);
-    cmp_int(fp, "inputrec->expandedvals->lambda-weights-equil", -1, expand1->elmceq, expand2->elmceq);
+    cmpEnum(fp, "inputrec->expandedvals->lambda-weights-equil", expand1->elmceq, expand2->elmceq);
     cmp_int(fp,
             "inputrec->expandedvals->,weight-equil-number-all-lambda",
             -1,
@@ -1290,7 +1292,7 @@ static void cmp_fepvals(FILE* fp, const t_lambda* fep1, const t_lambda* fep2, re
     cmp_double(fp, "inputrec->fepvals->init_fep_state", -1, fep1->init_fep_state, fep2->init_fep_state, ftol, abstol);
     cmp_double(fp, "inputrec->fepvals->delta_lambda", -1, fep1->delta_lambda, fep2->delta_lambda, ftol, abstol);
     cmp_int(fp, "inputrec->fepvals->n_lambda", -1, fep1->n_lambda, fep2->n_lambda);
-    for (i = 0; i < efptNR; i++)
+    for (i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
     {
         for (j = 0; j < std::min(fep1->n_lambda, fep2->n_lambda); j++)
         {
@@ -1308,10 +1310,10 @@ static void cmp_fepvals(FILE* fp, const t_lambda* fep1, const t_lambda* fep2, re
     cmp_int(fp, "inputrec->fepvals->sc_power", -1, fep1->sc_power, fep2->sc_power);
     cmp_real(fp, "inputrec->fepvals->sc_r_power", -1, fep1->sc_r_power, fep2->sc_r_power, ftol, abstol);
     cmp_real(fp, "inputrec->fepvals->sc_sigma", -1, fep1->sc_sigma, fep2->sc_sigma, ftol, abstol);
-    cmp_int(fp, "inputrec->fepvals->edHdLPrintEnergy", -1, fep1->edHdLPrintEnergy, fep1->edHdLPrintEnergy);
+    cmpEnum(fp, "inputrec->fepvals->edHdLPrintEnergy", fep1->edHdLPrintEnergy, fep1->edHdLPrintEnergy);
     cmp_bool(fp, "inputrec->fepvals->bScCoul", -1, fep1->bScCoul, fep1->bScCoul);
-    cmp_int(fp, "inputrec->separate_dhdl_file", -1, fep1->separate_dhdl_file, fep2->separate_dhdl_file);
-    cmp_int(fp, "inputrec->dhdl_derivatives", -1, fep1->dhdl_derivatives, fep2->dhdl_derivatives);
+    cmpEnum(fp, "inputrec->separate_dhdl_file", fep1->separate_dhdl_file, fep2->separate_dhdl_file);
+    cmpEnum(fp, "inputrec->dhdl_derivatives", fep1->dhdl_derivatives, fep2->dhdl_derivatives);
     cmp_int(fp, "inputrec->dh_hist_size", -1, fep1->dh_hist_size, fep2->dh_hist_size);
     cmp_double(fp, "inputrec->dh_hist_spacing", -1, fep1->dh_hist_spacing, fep2->dh_hist_spacing, ftol, abstol);
 }
@@ -1327,7 +1329,7 @@ void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real f
      * #define CII(s) cmp_int(fp,"inputrec->"#s,0,ir1->##s,ir2->##s)
      * #define CIR(s) cmp_real(fp,"inputrec->"#s,0,ir1->##s,ir2->##s,ftol)
      */
-    cmp_int(fp, "inputrec->eI", -1, ir1->eI, ir2->eI);
+    cmpEnum(fp, "inputrec->eI", ir1->eI, ir2->eI);
     cmp_int64(fp, "inputrec->nsteps", ir1->nsteps, ir2->nsteps);
     cmp_int64(fp, "inputrec->init_step", ir1->init_step, ir2->init_step);
     cmp_int(fp, "inputrec->simulation_part", -1, ir1->simulation_part, ir2->simulation_part);
@@ -1348,10 +1350,10 @@ void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real f
     }
     cmp_int(fp, "inputrec->pbcType", -1, static_cast<int>(ir1->pbcType), static_cast<int>(ir2->pbcType));
     cmp_bool(fp, "inputrec->bPeriodicMols", -1, ir1->bPeriodicMols, ir2->bPeriodicMols);
-    cmp_int(fp, "inputrec->cutoff_scheme", -1, ir1->cutoff_scheme, ir2->cutoff_scheme);
+    cmpEnum(fp, "inputrec->cutoff_scheme", ir1->cutoff_scheme, ir2->cutoff_scheme);
     cmp_int(fp, "inputrec->nstlist", -1, ir1->nstlist, ir2->nstlist);
     cmp_int(fp, "inputrec->nstcomm", -1, ir1->nstcomm, ir2->nstcomm);
-    cmp_int(fp, "inputrec->comm_mode", -1, ir1->comm_mode, ir2->comm_mode);
+    cmpEnum(fp, "inputrec->comm_mode", ir1->comm_mode, ir2->comm_mode);
     cmp_int(fp, "inputrec->nstlog", -1, ir1->nstlog, ir2->nstlog);
     cmp_int(fp, "inputrec->nstxout", -1, ir1->nstxout, ir2->nstxout);
     cmp_int(fp, "inputrec->nstvout", -1, ir1->nstvout, ir2->nstvout);
@@ -1374,7 +1376,7 @@ void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real f
     cmp_int(fp, "inputrec->nkz", -1, ir1->nkz, ir2->nkz);
     cmp_int(fp, "inputrec->pme_order", -1, ir1->pme_order, ir2->pme_order);
     cmp_real(fp, "inputrec->ewald_rtol", -1, ir1->ewald_rtol, ir2->ewald_rtol, ftol, abstol);
-    cmp_int(fp, "inputrec->ewald_geometry", -1, ir1->ewald_geometry, ir2->ewald_geometry);
+    cmpEnum(fp, "inputrec->ewald_geometry", ir1->ewald_geometry, ir2->ewald_geometry);
     cmp_real(fp, "inputrec->epsilon_surface", -1, ir1->epsilon_surface, ir2->epsilon_surface, ftol, abstol);
     cmp_int(fp,
             "inputrec->bContinuation",
@@ -1389,7 +1391,7 @@ void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real f
             static_cast<int>(ir1->bPrintNHChains),
             static_cast<int>(ir2->bPrintNHChains));
     cmpEnum(fp, "inputrec->epc", ir1->epc, ir2->epc);
-    cmp_int(fp, "inputrec->epct", -1, ir1->epct, ir2->epct);
+    cmpEnum(fp, "inputrec->epct", 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);
     cmp_rvec(fp, "inputrec->ref_p(y)", -1, ir1->ref_p[YY], ir2->ref_p[YY], ftol, abstol);
@@ -1397,34 +1399,34 @@ void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real f
     cmp_rvec(fp, "inputrec->compress(x)", -1, ir1->compress[XX], ir2->compress[XX], ftol, abstol);
     cmp_rvec(fp, "inputrec->compress(y)", -1, ir1->compress[YY], ir2->compress[YY], ftol, abstol);
     cmp_rvec(fp, "inputrec->compress(z)", -1, ir1->compress[ZZ], ir2->compress[ZZ], ftol, abstol);
-    cmp_int(fp, "refcoord_scaling", -1, ir1->refcoord_scaling, ir2->refcoord_scaling);
+    cmpEnum(fp, "refcoord_scaling", ir1->refcoord_scaling, ir2->refcoord_scaling);
     cmp_rvec(fp, "inputrec->posres_com", -1, ir1->posres_com, ir2->posres_com, ftol, abstol);
     cmp_rvec(fp, "inputrec->posres_comB", -1, ir1->posres_comB, ir2->posres_comB, ftol, abstol);
     cmp_real(fp, "inputrec->verletbuf_tol", -1, ir1->verletbuf_tol, ir2->verletbuf_tol, ftol, abstol);
     cmp_real(fp, "inputrec->rlist", -1, ir1->rlist, ir2->rlist, ftol, abstol);
     cmp_real(fp, "inputrec->rtpi", -1, ir1->rtpi, ir2->rtpi, ftol, abstol);
-    cmp_int(fp, "inputrec->coulombtype", -1, ir1->coulombtype, ir2->coulombtype);
-    cmp_int(fp, "inputrec->coulomb_modifier", -1, ir1->coulomb_modifier, ir2->coulomb_modifier);
+    cmpEnum(fp, "inputrec->coulombtype", ir1->coulombtype, ir2->coulombtype);
+    cmpEnum(fp, "inputrec->coulomb_modifier", ir1->coulomb_modifier, ir2->coulomb_modifier);
     cmp_real(fp, "inputrec->rcoulomb_switch", -1, ir1->rcoulomb_switch, ir2->rcoulomb_switch, ftol, abstol);
     cmp_real(fp, "inputrec->rcoulomb", -1, ir1->rcoulomb, ir2->rcoulomb, ftol, abstol);
-    cmp_int(fp, "inputrec->vdwtype", -1, ir1->vdwtype, ir2->vdwtype);
-    cmp_int(fp, "inputrec->vdw_modifier", -1, ir1->vdw_modifier, ir2->vdw_modifier);
+    cmpEnum(fp, "inputrec->vdwtype", ir1->vdwtype, ir2->vdwtype);
+    cmpEnum(fp, "inputrec->vdw_modifier", ir1->vdw_modifier, ir2->vdw_modifier);
     cmp_real(fp, "inputrec->rvdw_switch", -1, ir1->rvdw_switch, ir2->rvdw_switch, ftol, abstol);
     cmp_real(fp, "inputrec->rvdw", -1, ir1->rvdw, ir2->rvdw, ftol, abstol);
     cmp_real(fp, "inputrec->epsilon_r", -1, ir1->epsilon_r, ir2->epsilon_r, ftol, abstol);
     cmp_real(fp, "inputrec->epsilon_rf", -1, ir1->epsilon_rf, ir2->epsilon_rf, ftol, abstol);
     cmp_real(fp, "inputrec->tabext", -1, ir1->tabext, ir2->tabext, ftol, abstol);
 
-    cmp_int(fp, "inputrec->eDispCorr", -1, ir1->eDispCorr, ir2->eDispCorr);
+    cmpEnum(fp, "inputrec->eDispCorr", ir1->eDispCorr, ir2->eDispCorr);
     cmp_real(fp, "inputrec->shake_tol", -1, ir1->shake_tol, ir2->shake_tol, ftol, abstol);
-    cmp_int(fp, "inputrec->efep", -1, ir1->efep, ir2->efep);
-    cmp_fepvals(fp, ir1->fepvals, ir2->fepvals, ftol, abstol);
+    cmpEnum(fp, "inputrec->efep", ir1->efep, ir2->efep);
+    cmp_fepvals(fp, ir1->fepvals.get(), ir2->fepvals.get(), ftol, abstol);
     cmp_int(fp, "inputrec->bSimTemp", -1, static_cast<int>(ir1->bSimTemp), static_cast<int>(ir2->bSimTemp));
     if ((ir1->bSimTemp == ir2->bSimTemp) && (ir1->bSimTemp))
     {
         cmp_simtempvals(fp,
-                        ir1->simtempvals,
-                        ir2->simtempvals,
+                        ir1->simtempvals.get(),
+                        ir2->simtempvals.get(),
                         std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda),
                         ftol,
                         abstol);
@@ -1433,14 +1435,14 @@ void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real f
     if ((ir1->bExpanded == ir2->bExpanded) && (ir1->bExpanded))
     {
         cmp_expandedvals(fp,
-                         ir1->expandedvals,
-                         ir2->expandedvals,
+                         ir1->expandedvals.get(),
+                         ir2->expandedvals.get(),
                          std::min(ir1->fepvals->n_lambda, ir2->fepvals->n_lambda),
                          ftol,
                          abstol);
     }
     cmp_int(fp, "inputrec->nwall", -1, ir1->nwall, ir2->nwall);
-    cmp_int(fp, "inputrec->wall_type", -1, ir1->wall_type, ir2->wall_type);
+    cmpEnum(fp, "inputrec->wall_type", ir1->wall_type, ir2->wall_type);
     cmp_int(fp, "inputrec->wall_atomtype[0]", -1, ir1->wall_atomtype[0], ir2->wall_atomtype[0]);
     cmp_int(fp, "inputrec->wall_atomtype[1]", -1, ir1->wall_atomtype[1], ir2->wall_atomtype[1]);
     cmp_real(fp, "inputrec->wall_density[0]", -1, ir1->wall_density[0], ir2->wall_density[0], ftol, abstol);
@@ -1459,9 +1461,9 @@ void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real f
         cmp_awhParams(fp, ir1->awhParams, ir2->awhParams, ftol, abstol);
     }
 
-    cmp_int(fp, "inputrec->eDisre", -1, ir1->eDisre, ir2->eDisre);
+    cmpEnum(fp, "inputrec->eDisre", ir1->eDisre, ir2->eDisre);
     cmp_real(fp, "inputrec->dr_fc", -1, ir1->dr_fc, ir2->dr_fc, ftol, abstol);
-    cmp_int(fp, "inputrec->eDisreWeighting", -1, ir1->eDisreWeighting, ir2->eDisreWeighting);
+    cmpEnum(fp, "inputrec->eDisreWeighting", ir1->eDisreWeighting, ir2->eDisreWeighting);
     cmp_int(fp, "inputrec->bDisreMixed", -1, static_cast<int>(ir1->bDisreMixed), static_cast<int>(ir2->bDisreMixed));
     cmp_int(fp, "inputrec->nstdisreout", -1, ir1->nstdisreout, ir2->nstdisreout);
     cmp_real(fp, "inputrec->dr_tau", -1, ir1->dr_tau, ir2->dr_tau, ftol, abstol);
@@ -1474,7 +1476,7 @@ void cmp_inputrec(FILE* fp, const t_inputrec* ir1, const t_inputrec* ir2, real f
     cmp_real(fp, "inputrec->fc_stepsize", -1, ir1->fc_stepsize, ir2->fc_stepsize, ftol, abstol);
     cmp_int(fp, "inputrec->nstcgsteep", -1, ir1->nstcgsteep, ir2->nstcgsteep);
     cmp_int(fp, "inputrec->nbfgscorr", 0, ir1->nbfgscorr, ir2->nbfgscorr);
-    cmp_int(fp, "inputrec->eConstrAlg", -1, ir1->eConstrAlg, ir2->eConstrAlg);
+    cmpEnum(fp, "inputrec->eConstrAlg", ir1->eConstrAlg, ir2->eConstrAlg);
     cmp_int(fp, "inputrec->nProjOrder", -1, ir1->nProjOrder, ir2->nProjOrder);
     cmp_real(fp, "inputrec->LincsWarnAngle", -1, ir1->LincsWarnAngle, ir2->LincsWarnAngle, ftol, abstol);
     cmp_int(fp, "inputrec->nLincsIter", -1, ir1->nLincsIter, ir2->nLincsIter);
@@ -1516,19 +1518,20 @@ gmx_bool inputrecDeform(const t_inputrec* ir)
 
 gmx_bool inputrecDynamicBox(const t_inputrec* ir)
 {
-    return (ir->epc != PressureCoupling::No || ir->eI == eiTPI || inputrecDeform(ir));
+    return (ir->epc != PressureCoupling::No || ir->eI == IntegrationAlgorithm::TPI || inputrecDeform(ir));
 }
 
 gmx_bool inputrecPreserveShape(const t_inputrec* ir)
 {
     return (ir->epc != PressureCoupling::No && ir->deform[XX][XX] == 0
-            && (ir->epct == epctISOTROPIC || ir->epct == epctSEMIISOTROPIC));
+            && (ir->epct == PressureCouplingType::Isotropic
+                || ir->epct == PressureCouplingType::SemiIsotropic));
 }
 
 gmx_bool inputrecNeedMutot(const t_inputrec* ir)
 {
-    return ((ir->coulombtype == eelEWALD || EEL_PME(ir->coulombtype))
-            && (ir->ewald_geometry == eewg3DC || ir->epsilon_surface != 0));
+    return ((ir->coulombtype == CoulombInteractionType::Ewald || EEL_PME(ir->coulombtype))
+            && (ir->ewald_geometry == EwaldGeometry::ThreeDC || ir->epsilon_surface != 0));
 }
 
 gmx_bool inputrecExclForces(const t_inputrec* ir)
@@ -1538,20 +1541,20 @@ gmx_bool inputrecExclForces(const t_inputrec* ir)
 
 gmx_bool inputrecNptTrotter(const t_inputrec* ir)
 {
-    return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == PressureCoupling::Mttk)
-            && (ir->etc == TemperatureCoupling::NoseHoover));
+    return (((ir->eI == IntegrationAlgorithm::VV) || (ir->eI == IntegrationAlgorithm::VVAK))
+            && (ir->epc == PressureCoupling::Mttk) && (ir->etc == TemperatureCoupling::NoseHoover));
 }
 
 gmx_bool inputrecNvtTrotter(const t_inputrec* ir)
 {
-    return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc != PressureCoupling::Mttk)
-            && (ir->etc == TemperatureCoupling::NoseHoover));
+    return (((ir->eI == IntegrationAlgorithm::VV) || (ir->eI == IntegrationAlgorithm::VVAK))
+            && (ir->epc != PressureCoupling::Mttk) && (ir->etc == TemperatureCoupling::NoseHoover));
 }
 
 gmx_bool inputrecNphTrotter(const t_inputrec* ir)
 {
-    return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == PressureCoupling::Mttk)
-            && (ir->etc != TemperatureCoupling::NoseHoover));
+    return (((ir->eI == IntegrationAlgorithm::VV) || (ir->eI == IntegrationAlgorithm::VVAK))
+            && (ir->epc == PressureCoupling::Mttk) && (ir->etc != TemperatureCoupling::NoseHoover));
 }
 
 bool inputrecPbcXY2Walls(const t_inputrec* ir)
@@ -1584,7 +1587,8 @@ bool integratorHasConservedEnergyQuantity(const t_inputrec* ir)
 
 bool integratorHasReferenceTemperature(const t_inputrec* ir)
 {
-    return ((ir->etc != TemperatureCoupling::No) || EI_SD(ir->eI) || (ir->eI == eiBD) || EI_TPI(ir->eI));
+    return ((ir->etc != TemperatureCoupling::No) || EI_SD(ir->eI)
+            || (ir->eI == IntegrationAlgorithm::BD) || EI_TPI(ir->eI));
 }
 
 int inputrec2nboundeddim(const t_inputrec* ir)
@@ -1617,7 +1621,7 @@ int ndof_com(const t_inputrec* ir)
 
 real maxReferenceTemperature(const t_inputrec& ir)
 {
-    if (EI_ENERGY_MINIMIZATION(ir.eI) || ir.eI == eiNM)
+    if (EI_ENERGY_MINIMIZATION(ir.eI) || ir.eI == IntegrationAlgorithm::NM)
     {
         return 0;
     }
@@ -1645,7 +1649,8 @@ real maxReferenceTemperature(const t_inputrec& ir)
 
 bool haveEwaldSurfaceContribution(const t_inputrec& ir)
 {
-    return EEL_PME_EWALD(ir.coulombtype) && (ir.ewald_geometry == eewg3DC || ir.epsilon_surface != 0);
+    return EEL_PME_EWALD(ir.coulombtype)
+           && (ir.ewald_geometry == EwaldGeometry::ThreeDC || ir.epsilon_surface != 0);
 }
 
 bool haveFreeEnergyType(const t_inputrec& ir, const int fepType)
index dc2350acd746a7478f4ec78dae6d2fadb3d91d0e..4ca33733b7ce5cd136ac01e663a264c5e91d8661 100644 (file)
@@ -46,6 +46,7 @@
 #include "gromacs/math/vectypes.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/utility/basedefinitions.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/real.h"
 
 #define EGP_EXCL (1 << 0)
@@ -80,7 +81,7 @@ struct t_grpopts
     //! Coupling temperature   per group
     real* ref_t;
     //! No/simple/periodic simulated annealing for each group
-    int* annealing;
+    SimulatedAnnealing* annealing;
     //! Number of annealing time points per group
     int* anneal_npoints;
     //! For each group: Time points
@@ -102,7 +103,7 @@ struct t_grpopts
 struct t_simtemp
 {
     //! Simulated temperature scaling; linear or exponential
-    int eSimTempScale;
+    SimulatedTempering eSimTempScale;
     //! The low temperature for simulated tempering
     real simtemp_low;
     //! The high temperature for simulated tempering
@@ -122,11 +123,11 @@ struct t_lambda
     //! Change of lambda per time step (fraction of (0.1)
     double delta_lambda;
     //! Print no, total or potential energies in dhdl
-    int edHdLPrintEnergy;
+    FreeEnergyPrintEnergy edHdLPrintEnergy;
     //! The number of foreign lambda points
     int n_lambda;
     //! The array of all lambda values
-    double** all_lambda;
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, std::vector<double>> all_lambda;
     //! The number of neighboring lambda states to calculate the energy for in up and down directions (-1 for all)
     int lambda_neighbors;
     //! The first lambda to calculate energies for
@@ -146,11 +147,11 @@ struct t_lambda
     //! Use softcore for the coulomb portion as well (default FALSE)
     gmx_bool bScCoul;
     //! Whether to print the dvdl term associated with this term; if it is not specified as separate, it is lumped with the FEP term
-    gmx_bool separate_dvdl[efptNR];
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, bool> separate_dvdl;
     //! Whether to write a separate dhdl.xvg file note: NOT a gmx_bool, but an enum
-    int separate_dhdl_file;
+    SeparateDhdlFile separate_dhdl_file;
     //! Whether to calculate+write dhdl derivatives note: NOT a gmx_bool, but an enum
-    int dhdl_derivatives;
+    DhDlDerivativeCalculation dhdl_derivatives;
     //! The maximum table size for the dH histogram
     int dh_hist_size;
     //! The spacing for the dH histogram
@@ -162,11 +163,11 @@ struct t_expanded
     //! The frequency of expanded ensemble state changes
     int nstexpanded;
     //! Which type of move updating do we use for lambda monte carlo (or no for none)
-    int elamstats;
+    LambdaWeightCalculation elamstats;
     //! What move set will be we using for state space moves
-    int elmcmove;
+    LambdaMoveCalculation elmcmove;
     //! The method we use to decide of we have equilibrated the weights
-    int elmceq;
+    LambdaWeightWillReachEquilibrium elmceq;
     //! The minumum number of samples at each lambda for deciding whether we have reached a minimum
     int equil_n_at_lam;
     //! Wang-Landau delta at which we stop equilibrating weights
@@ -210,15 +211,15 @@ struct t_expanded
     //! To override the main temperature, or define it if it's not defined
     real mc_temp;
     //! User-specified initial weights to start with
-    real* init_lambda_weights;
+    std::vector<real> init_lambda_weights;
 };
 
 struct t_rotgrp
 {
     //! Rotation type for this group
-    int eType;
+    EnforcedRotationGroupType eType;
     //! Use mass-weighed positions?
-    int bMassW;
+    bool bMassW;
     //! Number of atoms in the group
     int nat;
     //! The global atoms numbers
@@ -234,7 +235,7 @@ struct t_rotgrp
     //! Pivot point of rotation axis (nm)
     rvec pivot;
     //! Type of fit to determine actual group angle
-    int eFittype;
+    RotationGroupFitting eFittype;
     //! Number of angles around the reference angle for which the rotation potential is also evaluated (for fit type 'potential' only)
     int PotAngle_nstep;
     //! Distance between two angles in degrees (for fit type 'potential' only)
@@ -313,7 +314,7 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
     ~t_inputrec();
 
     //! Integration method
-    int eI;
+    IntegrationAlgorithm eI;
     //! Number of steps to be taken
     int64_t nsteps;
     //! Used in checkpointing to separate chunks
@@ -323,13 +324,13 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
     //! Frequency of energy calc. and T/P coupl. upd.
     int nstcalcenergy;
     //! Group or verlet cutoffs
-    int cutoff_scheme;
+    CutoffScheme cutoff_scheme;
     //! Number of steps before pairlist is generated
     int nstlist;
     //! Number of steps after which center of mass motion is removed
     int nstcomm;
     //! Center of mass motion removal algorithm
-    int comm_mode;
+    ComRemovalAlgorithm comm_mode;
     //! Number of steps after which print to logfile
     int nstlog;
     //! Number of steps after which X is output
@@ -367,11 +368,11 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
     //! Real space tolerance for LJ-Ewald
     real ewald_rtol_lj;
     //! Normal/3D ewald, or pseudo-2D LR corrections
-    int ewald_geometry;
+    EwaldGeometry ewald_geometry;
     //! Epsilon for PME dipole correction
     real epsilon_surface;
     //! Type of combination rule in LJ-PME
-    int ljpme_combination_rule;
+    LongRangeVdW ljpme_combination_rule;
     //! Type of periodic boundary conditions
     PbcType pbcType;
     //! Periodic molecules
@@ -387,7 +388,7 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
     //! Pressure coupling
     PressureCoupling epc;
     //! Pressure coupling type
-    int epct;
+    PressureCouplingType epct;
     //! Interval in steps for pressure coupling
     int nstpcouple;
     //! Pressure coupling time (ps)
@@ -397,7 +398,7 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
     //! Compressibility ((mol nm^3)/kJ)
     tensor compress;
     //! How to scale absolute reference coordinates
-    int refcoord_scaling;
+    RefCoordScaling refcoord_scaling;
     //! The COM of the posres atoms
     rvec posres_com;
     //! The B-state COM of the posres atoms
@@ -411,9 +412,9 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
     //! Radius for test particle insertion
     real rtpi;
     //! Type of electrostatics treatment
-    int coulombtype;
+    CoulombInteractionType coulombtype;
     //! Modify the Coulomb interaction
-    int coulomb_modifier;
+    InteractionModifiers coulomb_modifier;
     //! Coulomb switch range start (nm)
     real rcoulomb_switch;
     //! Coulomb cutoff (nm)
@@ -425,37 +426,37 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
     //! Always false (no longer supported)
     bool implicit_solvent;
     //! Type of Van der Waals treatment
-    int vdwtype;
+    VanDerWaalsType vdwtype;
     //! Modify the Van der Waals interaction
-    int vdw_modifier;
+    InteractionModifiers vdw_modifier;
     //! Van der Waals switch range start (nm)
     real rvdw_switch;
     //! Van der Waals cutoff (nm)
     real rvdw;
     //! Perform Long range dispersion corrections
-    int eDispCorr;
+    DispersionCorrectionType eDispCorr;
     //! Extension of the table beyond the cut-off, as well as the table length for 1-4 interac.
     real tabext;
     //! Tolerance for shake
     real shake_tol;
     //! Free energy calculations
-    int efep;
+    FreeEnergyPerturbationType efep;
     //! Data for the FEP state
-    t_lambda* fepvals;
+    std::unique_ptr<t_lambda> fepvals;
     //! Whether to do simulated tempering
     gmx_bool bSimTemp;
     //! Variables for simulated tempering
-    t_simtemp* simtempvals;
+    std::unique_ptr<t_simtemp> simtempvals;
     //! Whether expanded ensembles are used
     gmx_bool bExpanded;
     //! Expanded ensemble parameters
-    t_expanded* expandedvals;
+    std::unique_ptr<t_expanded> expandedvals;
     //! Type of distance restraining
-    int eDisre;
+    DistanceRestraintRefinement eDisre;
     //! Force constant for time averaged distance restraints
     real dr_fc;
     //! Type of weighting of pairs in one restraints
-    int eDisreWeighting;
+    DistanceRestraintWeighting eDisreWeighting;
     //! Use combination of time averaged and instantaneous violations
     gmx_bool bDisreMixed;
     //! Frequency of writing pair distances to enx
@@ -481,7 +482,7 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
     //! Number of corrections to the Hessian to keep
     int nbfgscorr;
     //! Type of constraint algorithm
-    int eConstrAlg;
+    ConstraintAlgorithm eConstrAlg;
     //! Order of the LINCS Projection Algorithm
     int nProjOrder;
     //! Warn if any bond rotates more than this many degrees
@@ -497,7 +498,7 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
     //! The number of walls
     int nwall;
     //! The type of walls
-    int wall_type;
+    WallType wall_type;
     //! The potentail is linear for r<=wall_r_linpot
     real wall_r_linpot;
     //! The atom type for walls
@@ -526,7 +527,7 @@ struct t_inputrec // NOLINT (clang-analyzer-optin.performance.Padding)
     t_rot* rot;
 
     //! Whether to do ion/water position exchanges (CompEL)
-    int eSwapCoords;
+    SwapType eSwapCoords;
     //! Swap data structure.
     t_swapcoords* swap;
 
index 37812ee2b3a7e3064e42a83402eedda69fab142e..e112758411cdf54097d44d247cd49a15cd7c5d15 100644 (file)
@@ -127,8 +127,8 @@ struct interaction_const_t
     };
 
     /* VdW */
-    int                    vdwtype          = evdwCUT;
-    int                    vdw_modifier     = eintmodNONE;
+    VanDerWaalsType        vdwtype          = VanDerWaalsType::Cut;
+    InteractionModifiers   vdw_modifier     = InteractionModifiers::None;
     double                 reppow           = 12;
     real                   rvdw             = 1;
     real                   rvdw_switch      = 0;
@@ -139,19 +139,19 @@ struct interaction_const_t
     real                   buckinghamBMax   = 0;
 
     /* type of electrostatics */
-    int eeltype          = eelCUT;
-    int coulomb_modifier = eintmodNONE;
+    CoulombInteractionType eeltype          = CoulombInteractionType::Cut;
+    InteractionModifiers   coulomb_modifier = InteractionModifiers::None;
 
     /* Coulomb */
     real rcoulomb        = 1;
     real rcoulomb_switch = 0;
 
     /* PME/Ewald */
-    real ewaldcoeff_q    = 0;
-    real ewaldcoeff_lj   = 0;
-    int  ljpme_comb_rule = eljpmeGEOM; /* LJ combination rule for the LJ PME mesh part */
-    real sh_ewald        = 0;          /* -sh_ewald is added to the direct space potential */
-    real sh_lj_ewald     = 0;          /* sh_lj_ewald is added to the correction potential */
+    real ewaldcoeff_q  = 0;
+    real ewaldcoeff_lj = 0;
+    LongRangeVdW ljpme_comb_rule = LongRangeVdW::Geom; /* LJ combination rule for the LJ PME mesh part */
+    real sh_ewald                = 0; /* -sh_ewald is added to the direct space potential */
+    real sh_lj_ewald = 0;             /* sh_lj_ewald is added to the correction potential */
 
     /* Dielectric constant resp. multiplication factor for charges */
     real epsilon_r = 1;
index 53a24a3a11afd1c311a02bf98b3c0e7b8f9048f9..d8999ba87cad94740a32d479cd0c5b252c0ed41f 100644 (file)
@@ -54,48 +54,79 @@ const char* enum_name(int index, int max_index, const char* const names[])
     }
 }
 
-const char* yesno_names[BOOL_NR + 1] = { "no", "yes", nullptr };
-
-const char* ei_names[eiNR + 1] = { "md",    "steep",      "cg",    "bd",   "sd2 - removed",
-                                   "nm",    "l-bfgs",     "tpi",   "tpic", "sd",
-                                   "md-vv", "md-vv-avek", "mimic", nullptr };
-
-const char* ecutscheme_names[ecutsNR + 1] = { "Verlet", "Group", nullptr };
-
-const char* erefscaling_names[erscNR + 1] = { "No", "All", "COM", nullptr };
+const char* enumValueToString(IntegrationAlgorithm enumValue)
+{
+    static constexpr gmx::EnumerationArray<IntegrationAlgorithm, const char*> interationAlgorithmNames = {
+        "md",  "steep", "cg", "bd",    "sd2 - removed", "nm",   "l-bfgs",
+        "tpi", "tpic",  "sd", "md-vv", "md-vv-avek",    "mimic"
+    };
+    return interationAlgorithmNames[enumValue];
+}
 
-const char* eel_names[eelNR + 1] = { "Cut-off",
-                                     "Reaction-Field",
-                                     "Generalized-Reaction-Field (unused)",
-                                     "PME",
-                                     "Ewald",
-                                     "P3M-AD",
-                                     "Poisson",
-                                     "Switch",
-                                     "Shift",
-                                     "User",
-                                     "Generalized-Born (unused)",
-                                     "Reaction-Field-nec (unsupported)",
-                                     "Encad-shift (unused)",
-                                     "PME-User",
-                                     "PME-Switch",
-                                     "PME-User-Switch",
-                                     "Reaction-Field-zero",
-                                     nullptr };
+const char* enumValueToString(CoulombInteractionType enumValue)
+{
+    static constexpr gmx::EnumerationArray<CoulombInteractionType, const char*> coloumbTreatmentNames = {
+        "Cut-off",
+        "Reaction-Field",
+        "Generalized-Reaction-Field (unused)",
+        "PME",
+        "Ewald",
+        "P3M-AD",
+        "Poisson",
+        "Switch",
+        "Shift",
+        "User",
+        "Generalized-Born (unused)",
+        "Reaction-Field-nec (unsupported)",
+        "Encad-shift (unused)",
+        "PME-User",
+        "PME-Switch",
+        "PME-User-Switch",
+        "Reaction-Field-zero"
+    };
+    return coloumbTreatmentNames[enumValue];
+}
 
-const char* eewg_names[eewgNR + 1] = { "3d", "3dc", nullptr };
+const char* enumValueToString(EwaldGeometry enumValue)
+{
+    static constexpr gmx::EnumerationArray<EwaldGeometry, const char*> ewaldGeometryNames = {
+        "3d", "3dc"
+    };
+    return ewaldGeometryNames[enumValue];
+}
 
-const char* eljpme_names[eljpmeNR + 1] = { "Geometric", "Lorentz-Berthelot", nullptr };
+const char* enumValueToString(LongRangeVdW enumValue)
+{
+    static constexpr gmx::EnumerationArray<LongRangeVdW, const char*> longRangeVdWNames = {
+        "Geometric", "Lorentz-Berthelot"
+    };
+    return longRangeVdWNames[enumValue];
+}
 
-const char* evdw_names[evdwNR + 1] = { "Cut-off", "Switch", "Shift", "User", "Encad-shift (unused)",
-                                       "PME",     nullptr };
+const char* enumValueToString(VanDerWaalsType enumValue)
+{
+    static constexpr gmx::EnumerationArray<VanDerWaalsType, const char*> vanDerWaalsTypeNames = {
+        "Cut-off", "Switch", "Shift", "User", "Encad-shift (unused)", "PME"
+    };
+    return vanDerWaalsTypeNames[enumValue];
+}
 
-const char* econstr_names[econtNR + 1] = { "Lincs", "Shake", nullptr };
+const char* enumValueToString(ConstraintAlgorithm enumValue)
+{
+    static constexpr gmx::EnumerationArray<ConstraintAlgorithm, const char*> constraintAlgorithmNames = {
+        "Lincs", "Shake"
+    };
+    return constraintAlgorithmNames[enumValue];
+}
 
-const char* eintmod_names[eintmodNR + 1] = {
-    "Potential-shift-Verlet", "Potential-shift", "None", "Potential-switch",
-    "Exact-cutoff",           "Force-switch",    nullptr
-};
+const char* enumValueToString(InteractionModifiers enumValue)
+{
+    static constexpr gmx::EnumerationArray<InteractionModifiers, const char*> interactionModifierNames = {
+        "Potential-shift-Verlet", "Potential-shift", "None",
+        "Potential-switch",       "Exact-cutoff",    "Force-switch"
+    };
+    return interactionModifierNames[enumValue];
+}
 
 const char* enumValueToString(TemperatureCoupling enumValue)
 {
@@ -113,86 +144,261 @@ const char* enumValueToString(PressureCoupling enumValue)
     return pressureCouplingNames[enumValue];
 }
 
-const char* epcoupltype_names[epctNR + 1] = { "Isotropic",
-                                              "Semiisotropic",
-                                              "Anisotropic",
-                                              "Surface-Tension",
-                                              nullptr };
+const char* enumValueToString(Boolean enumValue)
+{
+    static constexpr gmx::EnumerationArray<Boolean, const char*> booleanNames = { "no", "yes" };
+    return booleanNames[enumValue];
+}
 
-const char* edisre_names[edrNR + 1] = { "No", "Simple", "Ensemble", nullptr };
+const char* booleanValueToString(bool value)
+{
+    Boolean enumValue = value ? Boolean::Yes : Boolean::No;
+    return enumValueToString(enumValue);
+}
 
-const char* edisreweighting_names[edrwNR + 1] = { "Conservative", "Equal", nullptr };
+const char* enumValueToString(RefCoordScaling enumValue)
+{
+    static constexpr gmx::EnumerationArray<RefCoordScaling, const char*> refCoordScalingNames = {
+        "No", "All", "COM"
+    };
+    return refCoordScalingNames[enumValue];
+}
 
-const char* enbf_names[eNBF_NR + 1] = { "", "LJ", "Buckingham", nullptr };
+const char* enumValueToString(CutoffScheme enumValue)
+{
+    static constexpr gmx::EnumerationArray<CutoffScheme, const char*> cutoffSchemeNames = {
+        "Verlet", "Group"
+    };
+    return cutoffSchemeNames[enumValue];
+}
 
-const char* ecomb_names[eCOMB_NR + 1] = { "", "Geometric", "Arithmetic", "GeomSigEps", nullptr };
+const char* enumValueToString(PressureCouplingType enumValue)
+{
+    static constexpr gmx::EnumerationArray<PressureCouplingType, const char*> pressureCouplingTypeNames = {
+        "Isotropic", "Semiisotropic", "Anisotropic", "Surface-Tension"
+    };
+    return pressureCouplingTypeNames[enumValue];
+}
 
-const char* esimtemp_names[esimtempNR + 1] = { "geometric", "exponential", "linear", nullptr };
+const char* enumValueToString(DistanceRestraintRefinement enumValue)
+{
+    static constexpr gmx::EnumerationArray<DistanceRestraintRefinement, const char*> distanceRestraintRefinementNames = {
+        "No", "Simple", "Ensemble"
+    };
+    return distanceRestraintRefinementNames[enumValue];
+}
 
-const char* efep_names[efepNR + 1] = { "no", "yes", "static", "slow-growth", "expanded", nullptr };
+const char* enumValueToString(DistanceRestraintWeighting enumValue)
+{
+    static constexpr gmx::EnumerationArray<DistanceRestraintWeighting, const char*> distanceRestraintWeightingNames = {
+        "Conservative", "Equal"
+    };
+    return distanceRestraintWeightingNames[enumValue];
+}
 
-const char* efpt_names[efptNR + 1] = { "fep-lambdas",         "mass-lambdas",   "coul-lambdas",
-                                       "vdw-lambdas",         "bonded-lambdas", "restraint-lambdas",
-                                       "temperature-lambdas", nullptr };
+const char* enumValueToString(VanDerWaalsPotential enumValue)
+{
+    static constexpr gmx::EnumerationArray<VanDerWaalsPotential, const char*> vanDerWaalsPotentialNames = {
+        "None", "LJ", "Buckingham"
+    };
+    return vanDerWaalsPotentialNames[enumValue];
+}
 
-const char* efpt_singular_names[efptNR + 1] = { "fep-lambda",         "mass-lambda",
-                                                "coul-lambda",        "vdw-lambda",
-                                                "bonded-lambda",      "restraint-lambda",
-                                                "temperature-lambda", nullptr };
+const char* enumValueToString(CombinationRule enumValue)
+{
+    static constexpr gmx::EnumerationArray<CombinationRule, const char*> combinationRuleNames = {
+        "None", "Geometric", "Arithmetic", "GeomSigEps"
+    };
+    return combinationRuleNames[enumValue];
+}
 
-const char* edHdLPrintEnergy_names[edHdLPrintEnergyNR + 1] = { "no", "total", "potential", "yes", nullptr };
+const char* enumValueToString(SimulatedTempering enumValue)
+{
+    static constexpr gmx::EnumerationArray<SimulatedTempering, const char*> simulatedTemperingNames = {
+        "geometric", "exponential", "linear"
+    };
+    return simulatedTemperingNames[enumValue];
+}
 
-const char* elamstats_names[elamstatsNR + 1] = {
-    "no",     "metropolis-transition", "barker-transition",
-    "minvar", "wang-landau",           "weighted-wang-landau",
-    nullptr
-};
+const char* enumValueToString(FreeEnergyPerturbationType enumValue)
+{
+    static constexpr gmx::EnumerationArray<FreeEnergyPerturbationType, const char*> freeEnergyPerturbationTypeNames = {
+        "no", "yes", "static", "slow-growth", "expanded"
+    };
+    return freeEnergyPerturbationTypeNames[enumValue];
+}
 
-const char* elmcmove_names[elmcmoveNR + 1] = { "no",    "metropolis",         "barker",
-                                               "gibbs", "metropolized-gibbs", nullptr };
+const char* enumValueToString(FreeEnergyPerturbationCouplingType enumValue)
+{
+    static constexpr gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, const char*> freeEnergyPerturbationCouplingTypeNames = {
+        "fep-lambdas",    "mass-lambdas",      "coul-lambdas",       "vdw-lambdas",
+        "bonded-lambdas", "restraint-lambdas", "temperature-lambdas"
+    };
+    return freeEnergyPerturbationCouplingTypeNames[enumValue];
+}
 
-const char* elmceq_names[elmceqNR + 1] = { "no",           "yes",
-                                           "wl-delta",     "number-all-lambda",
-                                           "number-steps", "number-samples",
-                                           "count-ratio",  nullptr };
+const char* enumValueToStringSingular(FreeEnergyPerturbationCouplingType enumValue)
+{
+    static constexpr gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, const char*> freeEnergyPerturbationCouplingTypeNames = {
+        "fep-lambda",    "mass-lambda",      "coul-lambda",       "vdw-lambda",
+        "bonded-lambda", "restraint-lambda", "temperature-lambda"
+    };
+    return freeEnergyPerturbationCouplingTypeNames[enumValue];
+}
 
-const char* separate_dhdl_file_names[esepdhdlfileNR + 1] = { "yes", "no", nullptr };
+const char* enumValueToString(FreeEnergyPrintEnergy enumValue)
+{
+    static constexpr gmx::EnumerationArray<FreeEnergyPrintEnergy, const char*> freeEnergyPrintNames = {
+        "no", "total", "potential", "yes"
+    };
+    return freeEnergyPrintNames[enumValue];
+}
 
-const char* dhdl_derivatives_names[edhdlderivativesNR + 1] = { "yes", "no", nullptr };
+const char* enumValueToString(LambdaWeightCalculation enumValue)
+{
+    static constexpr gmx::EnumerationArray<LambdaWeightCalculation, const char*> lambdaWeightCalculationNames = {
+        "no",     "metropolis-transition", "barker-transition",
+        "minvar", "wang-landau",           "weighted-wang-landau"
+    };
+    return lambdaWeightCalculationNames[enumValue];
+}
 
-const char* esol_names[esolNR + 1] = { "No", "SPC", "TIP4p", nullptr };
+const char* enumValueToString(LambdaMoveCalculation enumValue)
+{
+    static constexpr gmx::EnumerationArray<LambdaMoveCalculation, const char*> lambdaMoveCalculationNames = {
+        "no", "metropolis", "barker", "gibbs", "metropolized-gibbs"
+    };
+    return lambdaMoveCalculationNames[enumValue];
+}
 
-const char* edispc_names[edispcNR + 1] = { "No",          "EnerPres", "Ener",
-                                           "AllEnerPres", "AllEner",  nullptr };
+const char* enumValueToString(LambdaWeightWillReachEquilibrium enumValue)
+{
+    static constexpr gmx::EnumerationArray<LambdaWeightWillReachEquilibrium, const char*> lambdaWeightEquilibriumNames = {
+        "no",         "yes", "wl-delta", "number-all-lambda", "number-steps", "number-samples",
+        "count-ratio"
+    };
+    return lambdaWeightEquilibriumNames[enumValue];
+}
+
+const char* enumValueToString(SeparateDhdlFile enumValue)
+{
+    static constexpr gmx::EnumerationArray<SeparateDhdlFile, const char*> separateDhdlFileNames = {
+        "yes", "no"
+    };
+    return separateDhdlFileNames[enumValue];
+}
 
-const char* ecm_names[ecmNR + 1] = { "Linear", "Angular", "None", "Linear-acceleration-correction", nullptr };
+const char* enumValueToString(DhDlDerivativeCalculation enumValue)
+{
+    static constexpr gmx::EnumerationArray<DhDlDerivativeCalculation, const char*> dhdlDerivativeCalculationNames = {
+        "yes", "no"
+    };
+    return dhdlDerivativeCalculationNames[enumValue];
+}
+
+const char* enumValueToString(SolventModel enumValue)
+{
+    static constexpr gmx::EnumerationArray<SolventModel, const char*> solventModelNames = {
+        "No", "SPC", "TIP4p"
+    };
+    return solventModelNames[enumValue];
+}
+
+const char* enumValueToString(DispersionCorrectionType enumValue)
+{
+    static constexpr gmx::EnumerationArray<DispersionCorrectionType, const char*> dispersionCorrectionTypeNames = {
+        "No", "EnerPres", "Ener", "AllEnerPres", "AllEner"
+    };
+    return dispersionCorrectionTypeNames[enumValue];
+}
+
+const char* enumValueToString(ComRemovalAlgorithm enumValue)
+{
+    static constexpr gmx::EnumerationArray<ComRemovalAlgorithm, const char*> comRemovalAlgorithmNames = {
+        "Linear", "Angular", "None", "Linear-acceleration-correction"
+    };
+    return comRemovalAlgorithmNames[enumValue];
+}
 
-const char* eann_names[eannNR + 1] = { "No", "Single", "Periodic", nullptr };
+const char* enumValueToString(SimulatedAnnealing enumValue)
+{
+    static constexpr gmx::EnumerationArray<SimulatedAnnealing, const char*> simulatedAnnealingNames = {
+        "No", "Single", "Periodic"
+    };
+    return simulatedAnnealingNames[enumValue];
+}
 
-const char* ewt_names[ewtNR + 1] = { "9-3", "10-4", "table", "12-6", nullptr };
+const char* enumValueToString(WallType enumValue)
+{
+    static constexpr gmx::EnumerationArray<WallType, const char*> wallTypeNames = {
+        "9-3", "10-4", "table", "12-6"
+    };
+    return wallTypeNames[enumValue];
+}
 
-const char* epull_names[epullNR + 1] = { "umbrella",    "constraint",       "constant-force",
-                                         "flat-bottom", "flat-bottom-high", "external-potential",
-                                         nullptr };
+const char* enumValueToString(PullingAlgorithm enumValue)
+{
+    static constexpr gmx::EnumerationArray<PullingAlgorithm, const char*> pullAlgorithmNames = {
+        "umbrella",    "constraint",       "constant-force",
+        "flat-bottom", "flat-bottom-high", "external-potential"
+    };
+    return pullAlgorithmNames[enumValue];
+}
 
-const char* epullg_names[epullgNR + 1] = { "distance",           "direction",          "cylinder",
-                                           "direction-periodic", "direction-relative", "angle",
-                                           "dihedral",           "angle-axis",         nullptr };
+const char* enumValueToString(PullGroupGeometry enumValue)
+{
+    static constexpr gmx::EnumerationArray<PullGroupGeometry, const char*> pullGroupControlNames = {
+        "distance",           "direction", "cylinder", "direction-periodic",
+        "direction-relative", "angle",     "dihedral", "angle-axis"
+    };
+    return pullGroupControlNames[enumValue];
+}
 
-const char* erotg_names[erotgNR + 1] = { "iso",   "iso-pf",  "pm",     "pm-pf", "rm",
-                                         "rm-pf", "rm2",     "rm2-pf", "flex",  "flex-t",
-                                         "flex2", "flex2-t", nullptr };
+const char* enumValueToString(EnforcedRotationGroupType enumValue)
+{
+    static constexpr gmx::EnumerationArray<EnforcedRotationGroupType, const char*> enforcedRotationGroupNames = {
+        "iso", "iso-pf", "pm",   "pm-pf",  "rm",    "rm-pf",
+        "rm2", "rm2-pf", "flex", "flex-t", "flex2", "flex2-t"
+    };
+    return enforcedRotationGroupNames[enumValue];
+}
 
-const char* erotg_fitnames[erotgFitNR + 1] = { "rmsd", "norm", "potential", nullptr };
+const char* enumValueToString(RotationGroupFitting enumValue)
+{
+    static constexpr gmx::EnumerationArray<RotationGroupFitting, const char*> rotationGroupFittingNames = {
+        "rmsd", "norm", "potential"
+    };
+    return rotationGroupFittingNames[enumValue];
+}
 
-const char* eSwapTypes_names[eSwapTypesNR + 1] = { "no", "X", "Y", "Z", nullptr };
+const char* enumValueToString(SwapType enumValue)
+{
+    static constexpr gmx::EnumerationArray<SwapType, const char*> swapTypeNames = {
+        "no", "X", "Y", "Z"
+    };
+    return swapTypeNames[enumValue];
+}
 
-const char* eSwapFixedGrp_names[eSwapFixedGrpNR + 1] = { "Split0", "Split1", "Solvent", nullptr };
+const char* enumValueToString(SwapGroupSplittingType enumValue)
+{
+    static constexpr gmx::EnumerationArray<SwapGroupSplittingType, const char*> swapGroupSplittingTypeNames = {
+        "Split0", "Split1", "Solvent"
+    };
+    return swapGroupSplittingTypeNames[enumValue];
+}
 
-const char* gmx_nbkernel_elec_names[GMX_NBKERNEL_ELEC_NR + 1] = {
-    "None", "Coulomb", "Reaction-Field", "Cubic-Spline-Table", "Ewald", nullptr
-};
+const char* enumValueToString(NbkernelElecType enumValue)
+{
+    static constexpr gmx::EnumerationArray<NbkernelElecType, const char*> nbkernelElecTypeNames = {
+        "None", "Coulomb", "Reaction-Field", "Cubic-Spline-Table", "Ewald"
+    };
+    return nbkernelElecTypeNames[enumValue];
+}
 
-const char* gmx_nbkernel_vdw_names[GMX_NBKERNEL_VDW_NR + 1] = { "None",       "Lennard-Jones",
-                                                                "Buckingham", "Cubic-Spline-Table",
-                                                                "LJEwald",    nullptr };
+const char* enumValueToString(NbkernelVdwType enumValue)
+{
+    static constexpr gmx::EnumerationArray<NbkernelVdwType, const char*> nbkernelVdwTypeNames = {
+        "None", "Lennard-Jones", "Buckingham", "Cubic-Spline-Table", "LJEwald"
+    };
+    return nbkernelVdwTypeNames[enumValue];
+}
index 3728713a308f5c40ff0a520b3285401909f1a453..58a99ab4659c9cd1b1b321d1046cbfc0c0c7c41b 100644 (file)
  */
 const char* enum_name(int index, int max_index, const char* const names[]);
 
-//! Boolean strings no or yes
-extern const char* yesno_names[BOOL_NR + 1];
+/*! \brief Enum for setting answer to yes or no
+ */
+enum class Boolean : int
+{
+    No,
+    Yes,
+    Count,
+    Default = No
+};
+
+//! Return name of boolean selection.
+const char* enumValueToString(Boolean enumValue);
+//! Return name of boolean selection for actual bool.
+const char* booleanValueToString(bool value);
 
 //! \brief The two compartments for CompEL setups.
 enum eCompartment
@@ -146,17 +158,17 @@ enum
 };
 
 //! Relative coordinate scaling type for position restraints.
-enum
+enum class RefCoordScaling : int
 {
-    erscNO,
-    erscALL,
-    erscCOM,
-    erscNR
+    No,
+    All,
+    Com,
+    Count,
+    Default = No
 };
-//! String corresponding to relativ coordinate scaling.
-extern const char* erefscaling_names[erscNR + 1];
-//! Macro to select correct coordinate scaling string.
-#define EREFSCALINGTYPE(e) enum_name(e, erscNR, erefscaling_names)
+
+//! String corresponding to relative coordinate scaling.
+const char* enumValueToString(RefCoordScaling enumValue);
 
 //! Trotter decomposition extended variable parts.
 enum
@@ -187,132 +199,132 @@ enum
 };
 
 //! Pressure coupling type
-enum
+enum class PressureCouplingType : int
 {
-    epctISOTROPIC,
-    epctSEMIISOTROPIC,
-    epctANISOTROPIC,
-    epctSURFACETENSION,
-    epctNR
+    Isotropic,
+    SemiIsotropic,
+    Anisotropic,
+    SurfaceTension,
+    Count,
+    Default = Isotropic
 };
 //! String corresponding to pressure coupling type
-extern const char* epcoupltype_names[epctNR + 1];
-//! Macro to select the right string for pcoupl type
-#define EPCOUPLTYPETYPE(e) enum_name(e, epctNR, epcoupltype_names)
+const char* enumValueToString(PressureCouplingType enumValue);
 
 //! \\brief Cutoff scheme
-enum
+enum class CutoffScheme : int
 {
-    ecutsVERLET,
-    ecutsGROUP,
-    ecutsNR
+    Verlet,
+    Group,
+    Count,
+    Default = Verlet
 };
 //! String corresponding to cutoff scheme
-extern const char* ecutscheme_names[ecutsNR + 1];
-//! Macro to select the right string for cutoff scheme
-#define ECUTSCHEME(e) enum_name(e, ecutsNR, ecutscheme_names)
+const char* enumValueToString(CutoffScheme enumValue);
 
 /*! \brief Coulomb / VdW interaction modifiers.
  *
  * grompp replaces eintmodPOTSHIFT_VERLET_UNSUPPORTED by eintmodPOTSHIFT.
  * Exactcutoff is only used by Reaction-field-zero, and is not user-selectable.
  */
-enum eintmod
-{
-    eintmodPOTSHIFT_VERLET_UNSUPPORTED,
-    eintmodPOTSHIFT,
-    eintmodNONE,
-    eintmodPOTSWITCH,
-    eintmodEXACTCUTOFF,
-    eintmodFORCESWITCH,
-    eintmodNR
+enum class InteractionModifiers : int
+{
+    PotShiftVerletUnsupported,
+    PotShift,
+    None,
+    PotSwitch,
+    ExactCutoff,
+    ForceSwitch,
+    Count,
+    Default = PotShiftVerletUnsupported
 };
 //! String corresponding to interaction modifiers
-extern const char* eintmod_names[eintmodNR + 1];
-//! Macro to select the correct string for modifiers
-#define INTMODIFIER(e) enum_name(e, eintmodNR, eintmod_names)
+const char* enumValueToString(InteractionModifiers enumValue);
 
 /*! \brief Cut-off treatment for Coulomb */
-enum
-{
-    eelCUT,
-    eelRF,
-    eelGRF_NOTUSED,
-    eelPME,
-    eelEWALD,
-    eelP3M_AD,
-    eelPOISSON,
-    eelSWITCH,
-    eelSHIFT,
-    eelUSER,
-    eelGB_NOTUSED,
-    eelRF_NEC_UNSUPPORTED,
-    eelENCADSHIFT_NOTUSED,
-    eelPMEUSER,
-    eelPMESWITCH,
-    eelPMEUSERSWITCH,
-    eelRF_ZERO,
-    eelNR
+enum class CoulombInteractionType : int
+{
+    Cut,
+    RF,
+    GRFNotused,
+    Pme,
+    Ewald,
+    P3mAD,
+    Poisson,
+    Switch,
+    Shift,
+    User,
+    GBNotused,
+    RFNecUnsupported,
+    EncadShiftNotused,
+    PmeUser,
+    PmeSwitch,
+    PmeUserSwitch,
+    RFZero,
+    Count,
+    Default = Cut
 };
 //! String corresponding to Coulomb treatment
-extern const char* eel_names[eelNR + 1];
-//! Macro for correct string for Coulomb treatment
-#define EELTYPE(e) enum_name(e, eelNR, eel_names)
+const char* enumValueToString(CoulombInteractionType enumValue);
 
 //! Ewald geometry.
-enum
+enum class EwaldGeometry : int
 {
-    eewg3D,
-    eewg3DC,
-    eewgNR
+    ThreeD,
+    ThreeDC,
+    Count,
+    Default = ThreeD
 };
 //! String corresponding to Ewald geometry
-extern const char* eewg_names[eewgNR + 1];
+const char* enumValueToString(EwaldGeometry enumValue);
 
 //! Macro telling us whether we use reaction field
-#define EEL_RF(e) \
-    ((e) == eelRF || (e) == eelGRF_NOTUSED || (e) == eelRF_NEC_UNSUPPORTED || (e) == eelRF_ZERO)
+#define EEL_RF(e)                                                                   \
+    ((e) == CoulombInteractionType::RF || (e) == CoulombInteractionType::GRFNotused \
+     || (e) == CoulombInteractionType::RFNecUnsupported || (e) == CoulombInteractionType::RFZero)
 
 //! Macro telling us whether we use PME
-#define EEL_PME(e) \
-    ((e) == eelPME || (e) == eelPMESWITCH || (e) == eelPMEUSER || (e) == eelPMEUSERSWITCH || (e) == eelP3M_AD)
+#define EEL_PME(e)                                                                             \
+    ((e) == CoulombInteractionType::Pme || (e) == CoulombInteractionType::PmeSwitch            \
+     || (e) == CoulombInteractionType::PmeUser || (e) == CoulombInteractionType::PmeUserSwitch \
+     || (e) == CoulombInteractionType::P3mAD)
 //! Macro telling us whether we use PME or full Ewald
-#define EEL_PME_EWALD(e) (EEL_PME(e) || (e) == eelEWALD)
+#define EEL_PME_EWALD(e) (EEL_PME(e) || (e) == CoulombInteractionType::Ewald)
 //! Macro telling us whether we use full electrostatics of any sort
-#define EEL_FULL(e) (EEL_PME_EWALD(e) || (e) == eelPOISSON)
+#define EEL_FULL(e) (EEL_PME_EWALD(e) || (e) == CoulombInteractionType::Poisson)
 //! Macro telling us whether we use user defined electrostatics
-#define EEL_USER(e) ((e) == eelUSER || (e) == eelPMEUSER || (e) == (eelPMEUSERSWITCH))
+#define EEL_USER(e)                                                                \
+    ((e) == CoulombInteractionType::User || (e) == CoulombInteractionType::PmeUser \
+     || (e) == (CoulombInteractionType::PmeUserSwitch))
 
 //! Van der Waals interaction treatment
-enum
-{
-    evdwCUT,
-    evdwSWITCH,
-    evdwSHIFT,
-    evdwUSER,
-    evdwENCADSHIFT_UNUSED,
-    evdwPME,
-    evdwNR
+enum class VanDerWaalsType : int
+{
+    Cut,
+    Switch,
+    Shift,
+    User,
+    EncadShiftUnused,
+    Pme,
+    Count,
+    Default = Cut
 };
 //! String corresponding to Van der Waals treatment
-extern const char* evdw_names[evdwNR + 1];
-//! Macro for selecting correct string for VdW treatment
-#define EVDWTYPE(e) enum_name(e, evdwNR, evdw_names)
+const char* enumValueToString(VanDerWaalsType enumValue);
 
 //! Type of long-range VdW treatment of combination rules
-enum
+enum class LongRangeVdW : int
 {
-    eljpmeGEOM,
-    eljpmeLB,
-    eljpmeNR
+    Geom,
+    LB,
+    Count,
+    Default = Geom
 };
 //! String for LJPME combination rule treatment
-extern const char* eljpme_names[eljpmeNR + 1];
-//! Macro for correct LJPME comb rule name
-#define ELJPMECOMBNAMES(e) enum_name(e, eljpmeNR, eljpme_names)
+const char* enumValueToString(LongRangeVdW enumValue);
 
 //! Macro to tell us whether we use LJPME
-#define EVDW_PME(e) ((e) == evdwPME)
+#define EVDW_PME(e) ((e) == VanDerWaalsType::Pme)
 
 /*! \brief Integrator algorithm
  *
@@ -322,462 +334,444 @@ extern const char* eljpme_names[eljpmeNR + 1];
  * eiVVAK uses 1/2*(KE(t-dt/2)+KE(t+dt/2)) as the kinetic energy,
  * and the half step kinetic energy for temperature control
  */
-enum
-{
-    eiMD,
-    eiSteep,
-    eiCG,
-    eiBD,
-    eiSD2_REMOVED,
-    eiNM,
-    eiLBFGS,
-    eiTPI,
-    eiTPIC,
-    eiSD1,
-    eiVV,
-    eiVVAK,
-    eiMimic,
-    eiNR
+enum class IntegrationAlgorithm : int
+{
+    MD,
+    Steep,
+    CG,
+    BD,
+    SD2Removed,
+    NM,
+    LBFGS,
+    TPI,
+    TPIC,
+    SD1,
+    VV,
+    VVAK,
+    Mimic,
+    Count,
+    Default = MD
 };
 //! Name of the integrator algorithm
-extern const char* ei_names[eiNR + 1];
-//! Macro returning integrator string
-#define EI(e) enum_name(e, eiNR, ei_names)
+const char* enumValueToString(IntegrationAlgorithm enumValue);
 //! Do we use MiMiC QM/MM?
-#define EI_MIMIC(e) ((e) == eiMimic)
+#define EI_MIMIC(e) ((e) == IntegrationAlgorithm::Mimic)
 //! Do we use velocity Verlet
-#define EI_VV(e) ((e) == eiVV || (e) == eiVVAK)
+#define EI_VV(e) ((e) == IntegrationAlgorithm::VV || (e) == IntegrationAlgorithm::VVAK)
 //! Do we use molecular dynamics
-#define EI_MD(e) ((e) == eiMD || EI_VV(e) || EI_MIMIC(e))
+#define EI_MD(e) ((e) == IntegrationAlgorithm::MD || EI_VV(e) || EI_MIMIC(e))
 //! Do we use stochastic dynamics
-#define EI_SD(e) ((e) == eiSD1)
+#define EI_SD(e) ((e) == IntegrationAlgorithm::SD1)
 //! Do we use any stochastic integrator
-#define EI_RANDOM(e) (EI_SD(e) || (e) == eiBD)
+#define EI_RANDOM(e) (EI_SD(e) || (e) == IntegrationAlgorithm::BD)
 /*above integrators may not conserve momenta*/
 //! Do we use any type of dynamics
 #define EI_DYNAMICS(e) (EI_MD(e) || EI_RANDOM(e))
 //! Or do we use minimization
-#define EI_ENERGY_MINIMIZATION(e) ((e) == eiSteep || (e) == eiCG || (e) == eiLBFGS)
+#define EI_ENERGY_MINIMIZATION(e)                                          \
+    ((e) == IntegrationAlgorithm::Steep || (e) == IntegrationAlgorithm::CG \
+     || (e) == IntegrationAlgorithm::LBFGS)
 //! Do we apply test particle insertion
-#define EI_TPI(e) ((e) == eiTPI || (e) == eiTPIC)
+#define EI_TPI(e) ((e) == IntegrationAlgorithm::TPI || (e) == IntegrationAlgorithm::TPIC)
 //! Do we deal with particle velocities
 #define EI_STATE_VELOCITY(e) (EI_MD(e) || EI_SD(e))
 
 //! Constraint algorithm
-enum
+enum class ConstraintAlgorithm : int
 {
-    econtLINCS,
-    econtSHAKE,
-    econtNR
+    Lincs,
+    Shake,
+    Count,
+    Default = Lincs
 };
 //! String corresponding to constraint algorithm
-extern const char* econstr_names[econtNR + 1];
-//! Macro to select the correct string
-#define ECONSTRTYPE(e) enum_name(e, econtNR, econstr_names)
+const char* enumValueToString(ConstraintAlgorithm enumValue);
 
 //! Distance restraint refinement algorithm
-enum
+enum class DistanceRestraintRefinement : int
 {
-    edrNone,
-    edrSimple,
-    edrEnsemble,
-    edrNR
+    None,
+    Simple,
+    Ensemble,
+    Count,
+    Default = None
 };
 //! String corresponding to distance restraint algorithm
-extern const char* edisre_names[edrNR + 1];
-//! Macro to select the right disre algorithm string
-#define EDISRETYPE(e) enum_name(e, edrNR, edisre_names)
+const char* enumValueToString(DistanceRestraintRefinement enumValue);
 
 //! Distance restraints weighting type
-enum
+enum class DistanceRestraintWeighting : int
 {
-    edrwConservative,
-    edrwEqual,
-    edrwNR
+    Conservative,
+    Equal,
+    Count,
+    Default = Conservative
 };
 //! String corresponding to distance restraint weighting
-extern const char* edisreweighting_names[edrwNR + 1];
-//! Macro corresponding to dr weighting
-#define EDISREWEIGHTING(e) enum_name(e, edrwNR, edisreweighting_names)
+const char* enumValueToString(DistanceRestraintWeighting enumValue);
 
 //! Combination rule algorithm.
-enum
+enum class CombinationRule : int
 {
-    eCOMB_NONE,
-    eCOMB_GEOMETRIC,
-    eCOMB_ARITHMETIC,
-    eCOMB_GEOM_SIG_EPS,
-    eCOMB_NR
+    None,
+    Geometric,
+    Arithmetic,
+    GeomSigEps,
+    Count,
+    Default = Geometric
 };
 //! String for combination rule algorithm
-extern const char* ecomb_names[eCOMB_NR + 1];
-//! Macro to select the comb rule string
-#define ECOMBNAME(e) enum_name(e, eCOMB_NR, ecomb_names)
+const char* enumValueToString(CombinationRule enumValue);
 
 //! Van der Waals potential.
-enum
+enum class VanDerWaalsPotential : int
 {
-    eNBF_NONE,
-    eNBF_LJ,
-    eNBF_BHAM,
-    eNBF_NR
+    None,
+    LJ,
+    Buckingham,
+    Count,
+    Default = LJ
 };
 //! String corresponding to Van der Waals potential
-extern const char* enbf_names[eNBF_NR + 1];
-//! Macro for correct VdW potential string
-#define ENBFNAME(e) enum_name(e, eNBF_NR, enbf_names)
+const char* enumValueToString(VanDerWaalsPotential enumValue);
 
 //! Simulated tempering methods.
-enum
+enum class SimulatedTempering : int
 {
-    esimtempGEOMETRIC,
-    esimtempEXPONENTIAL,
-    esimtempLINEAR,
-    esimtempNR
+    Geometric,
+    Exponential,
+    Linear,
+    Count,
+    Default = Geometric
 };
 //! String corresponding to simulated tempering
-extern const char* esimtemp_names[esimtempNR + 1];
-//! Macro for correct tempering string
-#define ESIMTEMP(e) enum_name(e, esimtempNR, esimtemp_names)
+const char* enumValueToString(SimulatedTempering enumValue);
 
 /*! \brief Free energy perturbation type
- *
- * efepNO, there are no evaluations at other states.
- * efepYES, treated equivalently to efepSTATIC.
- * efepSTATIC, then lambdas do not change during the simulation.
- * efepSLOWGROWTH, then the states change monotonically
- * throughout the simulation.
- * efepEXPANDED, then expanded ensemble simulations are occuring.
  */
-enum
+enum class FreeEnergyPerturbationType : int
 {
-    efepNO,
-    efepYES,
-    efepSTATIC,
-    efepSLOWGROWTH,
-    efepEXPANDED,
-    efepNR
+    //! there are no evaluations at other states
+    No,
+    //! treated equivalently to Static
+    Yes,
+    //! then lambdas do not change during the simulation
+    Static,
+    //! then the states change monotonically throughout the simulation
+    SlowGrowth,
+    //! then expanded ensemble simulations are occuring
+    Expanded,
+    Count,
+    Default = No
 };
 //! String corresponding to FEP type.
-extern const char* efep_names[efepNR + 1];
-//! Macro corresponding to FEP string.
-#define EFEPTYPE(e) enum_name(e, efepNR, efep_names)
+const char* enumValueToString(FreeEnergyPerturbationType enumValue);
 
 //! Free energy pertubation coupling types.
-enum
-{
-    efptFEP,
-    efptMASS,
-    efptCOUL,
-    efptVDW,
-    efptBONDED,
-    efptRESTRAINT,
-    efptTEMPERATURE,
-    efptNR
+enum class FreeEnergyPerturbationCouplingType : int
+{
+    Fep,
+    Mass,
+    Coul,
+    Vdw,
+    Bonded,
+    Restraint,
+    Temperature,
+    Count,
+    Default = Fep
 };
 //! String for FEP coupling type
-extern const char* efpt_names[efptNR + 1];
-//! Long names for FEP coupling type
-extern const char* efpt_singular_names[efptNR + 1];
+const char* enumValueToString(FreeEnergyPerturbationCouplingType enumValue);
+//! String for FEP coupling type, singular mention.
+const char* enumValueToStringSingular(FreeEnergyPerturbationCouplingType enumValue);
 
 /*! \brief What to print for free energy calculations
  *
  * Printing the energy to the free energy dhdl file.
- * YES is an alias to TOTAL, and
+ * Yes is an alias to Total, and
  * will be converted in readir, so we never have to account for it in code.
  */
-enum
+enum class FreeEnergyPrintEnergy : int
 {
-    edHdLPrintEnergyNO,
-    edHdLPrintEnergyTOTAL,
-    edHdLPrintEnergyPOTENTIAL,
-    edHdLPrintEnergyYES,
-    edHdLPrintEnergyNR
+    No,
+    Total,
+    Potential,
+    Yes,
+    Count,
+    Default = No
 };
 //! String corresponding to printing of free energy
-extern const char* edHdLPrintEnergy_names[edHdLPrintEnergyNR + 1];
+const char* enumValueToString(FreeEnergyPrintEnergy enumValue);
 
 /*! \brief How the lambda weights are calculated
- *
- * elamstatsMETROPOLIS - using the metropolis criteria
- * elamstatsBARKER     - using the Barker critera for transition weights,
- *                       also called unoptimized Bennett
- * elamstatsMINVAR     - using Barker + minimum variance for weights
- * elamstatsWL         - Wang-Landu (using visitation counts)
- * elamstatsWWL        - Weighted Wang-Landau (using optimized Gibbs
- *                       weighted visitation counts)
  */
-enum
+enum class LambdaWeightCalculation : int
 {
-    elamstatsNO,
-    elamstatsMETROPOLIS,
-    elamstatsBARKER,
-    elamstatsMINVAR,
-    elamstatsWL,
-    elamstatsWWL,
-    elamstatsNR
+    //! don't calculate
+    No,
+    //! using the metropolis criteria
+    Metropolis,
+    //! using the Barker critera for transition weights, also called unoptimized Bennett
+    Barker,
+    //! using Barker + minimum variance for weights
+    Minvar,
+    //! Wang-Landu (using visitation counts)
+    WL,
+    //! Weighted Wang-Landau (using optimized Gibbs weighted visitation counts)
+    WWL,
+    Count,
+    Default = No
 };
 //! String corresponding to lambda weights
-extern const char* elamstats_names[elamstatsNR + 1];
+const char* enumValueToString(LambdaWeightCalculation enumValue);
 //! Macro telling us whether we use expanded ensemble
-#define ELAMSTATS_EXPANDED(e) ((e) > elamstatsNO)
+#define ELAMSTATS_EXPANDED(e) ((e) > LambdaWeightCalculation::No)
 //! Macro telling us whether we use some kind of Wang-Landau
-#define EWL(e) ((e) == elamstatsWL || (e) == elamstatsWWL)
+#define EWL(e) ((e) == LambdaWeightCalculation::WL || (e) == LambdaWeightCalculation::WWL)
 
 /*! \brief How moves in lambda are calculated
- *
- * elmovemcMETROPOLIS - using the Metropolis criteria, and 50% up and down
- * elmovemcBARKER     - using the Barker criteria, and 50% up and down
- * elmovemcGIBBS      - computing the transition using the marginalized
- *                      probabilities of the lambdas
- * elmovemcMETGIBBS   - computing the transition using the metropolized
- *                      version of Gibbs (Monte Carlo Strategies in
- *                      Scientific computing, Liu, p. 134)
  */
-enum
+enum class LambdaMoveCalculation : int
 {
-    elmcmoveNO,
-    elmcmoveMETROPOLIS,
-    elmcmoveBARKER,
-    elmcmoveGIBBS,
-    elmcmoveMETGIBBS,
-    elmcmoveNR
+    //! don't calculate move
+    No,
+    //! using the Metropolis criteria, and 50% up and down
+    Metropolis,
+    //! using the Barker criteria, and 50% up and down
+    Barker,
+    //! computing the transition using the marginalized probabilities of the lambdas
+    Gibbs,
+    /*! \brief
+     * using the metropolized version of Gibbs
+     *
+     * Monte Carlo Strategies in Scientific computing, Liu, p. 134
+     */
+    MetropolisGibbs,
+    Count,
+    Default = No
 };
 //! String corresponding to lambda moves
-extern const char* elmcmove_names[elmcmoveNR + 1];
+const char* enumValueToString(LambdaMoveCalculation enumValue);
 
 /*! \brief How we decide whether weights have reached equilibrium
- *
- * elmceqNO       - never stop, weights keep going
- * elmceqYES      - fix the weights from the beginning; no movement
- * elmceqWLDELTA  - stop when the WL-delta falls below a certain level
- * elmceqNUMATLAM - stop when we have a certain number of samples at
- *                  every step
- * elmceqSTEPS    - stop when we've run a certain total number of steps
- * elmceqSAMPLES  - stop when we've run a certain total number of samples
- * elmceqRATIO    - stop when the ratio of samples (lowest to highest)
- *                  is sufficiently large
  */
-enum
+enum class LambdaWeightWillReachEquilibrium : int
 {
-    elmceqNO,
-    elmceqYES,
-    elmceqWLDELTA,
-    elmceqNUMATLAM,
-    elmceqSTEPS,
-    elmceqSAMPLES,
-    elmceqRATIO,
-    elmceqNR
+    //! never stop, weights keep going
+    No,
+    //! fix the weights from the beginning; no movement
+    Yes,
+    //! stop when the WL-delta falls below a certain level
+    WLDelta,
+    //! stop when we have a certain number of samples at every step
+    NumAtLambda,
+    //! stop when we've run a certain total number of steps
+    Steps,
+    //! stop when we've run a certain total number of samples
+    Samples,
+    //! stop when the ratio of samples (lowest to highest) is sufficiently large
+    Ratio,
+    Count,
+    Default = No
 };
 //! String corresponding to equilibrium algorithm
-extern const char* elmceq_names[elmceqNR + 1];
+const char* enumValueToString(LambdaWeightWillReachEquilibrium enumValue);
 
 /*! \brief separate_dhdl_file selection
  *
  * NOTE: YES is the first one. Do NOT interpret this one as a gmx_bool
+ * Why was this done this way, just .........
  */
-enum
+enum class SeparateDhdlFile : int
 {
-    esepdhdlfileYES,
-    esepdhdlfileNO,
-    esepdhdlfileNR
+    Yes,
+    No,
+    Count,
+    Default = Yes
 };
 //! String corresponding to separate DHDL file selection
-extern const char* separate_dhdl_file_names[esepdhdlfileNR + 1];
-//! Monster macro for DHDL file selection
-#define SEPDHDLFILETYPE(e) enum_name(e, esepdhdlfileNR, separate_dhdl_file_names)
+const char* enumValueToString(SeparateDhdlFile enumValue);
 
 /*! \brief dhdl_derivatives selection \
  *
  * NOTE: YES is the first one. Do NOT interpret this one as a gmx_bool
+ * Why was this done this way, just .........
  */
-enum
+enum class DhDlDerivativeCalculation : int
 {
-    edhdlderivativesYES,
-    edhdlderivativesNO,
-    edhdlderivativesNR
+    Yes,
+    No,
+    Count,
+    Default = Yes
 };
 //! String for DHDL derivatives
-extern const char* dhdl_derivatives_names[edhdlderivativesNR + 1];
-//! YAMM (Yet another monster macro)
-#define DHDLDERIVATIVESTYPE(e) enum_name(e, edhdlderivativesNR, dhdl_derivatives_names)
+const char* enumValueToString(DhDlDerivativeCalculation enumValue);
 
 /*! \brief Solvent model
  *
  * Distinguishes classical water types with 3 or 4 particles
  */
-enum
+enum class SolventModel : int
 {
-    esolNO,
-    esolSPC,
-    esolTIP4P,
-    esolNR
+    No,
+    Spc,
+    Tip4p,
+    Count,
+    Default = Spc
 };
 //! String corresponding to solvent type
-extern const char* esol_names[esolNR + 1];
-//! Macro lest we print the wrong solvent model string
-#define ESOLTYPE(e) enum_name(e, esolNR, esol_names)
+const char* enumValueToString(SolventModel enumValue);
 
 //! Dispersion correction.
-enum
+enum class DispersionCorrectionType : int
 {
-    edispcNO,
-    edispcEnerPres,
-    edispcEner,
-    edispcAllEnerPres,
-    edispcAllEner,
-    edispcNR
+    No,
+    EnerPres,
+    Ener,
+    AllEnerPres,
+    AllEner,
+    Count,
+    Default = No
 };
 //! String corresponding to dispersion corrections
-extern const char* edispc_names[edispcNR + 1];
-//! Macro for dispcorr string
-#define EDISPCORR(e) enum_name(e, edispcNR, edispc_names)
+const char* enumValueToString(DispersionCorrectionType enumValue);
 
 //! Center of mass motion removal algorithm.
-enum
+enum class ComRemovalAlgorithm : int
 {
-    ecmLINEAR,
-    ecmANGULAR,
-    ecmNO,
-    ecmLINEAR_ACCELERATION_CORRECTION,
-    ecmNR
+    Linear,
+    Angular,
+    No,
+    LinearAccelerationCorrection,
+    Count,
+    Default = Linear
 };
 //! String corresponding to COM removal
-extern const char* ecm_names[ecmNR + 1];
-//! Macro for COM removal string
-#define ECOM(e) enum_name(e, ecmNR, ecm_names)
+const char* enumValueToString(ComRemovalAlgorithm enumValue);
 
 //! Algorithm for simulated annealing.
-enum
+enum class SimulatedAnnealing : int
 {
-    eannNO,
-    eannSINGLE,
-    eannPERIODIC,
-    eannNR
+    No,
+    Single,
+    Periodic,
+    Count,
+    Default = No
 };
 //! String for simulated annealing
-extern const char* eann_names[eannNR + 1];
-//! And macro for simulated annealing string
-#define EANNEAL(e) enum_name(e, eannNR, eann_names)
+const char* enumValueToString(SimulatedAnnealing enumValue);
 
 //! Wall types.
-enum
+enum class WallType : int
 {
-    ewt93,
-    ewt104,
-    ewtTABLE,
-    ewt126,
-    ewtNR
+    NineThree,
+    TenFour,
+    Table,
+    TwelveSix,
+    Count,
+    Default = NineThree
 };
 //! String corresponding to wall type
-extern const char* ewt_names[ewtNR + 1];
-//! Macro for wall type string
-#define EWALLTYPE(e) enum_name(e, ewtNR, ewt_names)
+const char* enumValueToString(WallType enumValue);
 
 //! Pulling algorithm.
-enum
-{
-    epullUMBRELLA,
-    epullCONSTRAINT,
-    epullCONST_F,
-    epullFLATBOTTOM,
-    epullFLATBOTTOMHIGH,
-    epullEXTERNAL,
-    epullNR
+enum class PullingAlgorithm : int
+{
+    Umbrella,
+    Constraint,
+    ConstantForce,
+    FlatBottom,
+    FlatBottomHigh,
+    External,
+    Count,
+    Default = Umbrella
 };
 //! String for pulling algorithm
-extern const char* epull_names[epullNR + 1];
-//! Macro for pulling string
-#define EPULLTYPE(e) enum_name(e, epullNR, epull_names)
+const char* enumValueToString(PullingAlgorithm enumValue);
 
 //! Control of pull groups
-enum
-{
-    epullgDIST,
-    epullgDIR,
-    epullgCYL,
-    epullgDIRPBC,
-    epullgDIRRELATIVE,
-    epullgANGLE,
-    epullgDIHEDRAL,
-    epullgANGLEAXIS,
-    epullgNR
+enum class PullGroupGeometry : int
+{
+    Distance,
+    Direction,
+    Cylinder,
+    DirectionPBC,
+    DirectionRelative,
+    Angle,
+    Dihedral,
+    AngleAxis,
+    Count,
+    Default = Distance
 };
 //! String for pull groups
-extern const char* epullg_names[epullgNR + 1];
-//! Macro for pull group string
-#define EPULLGEOM(e) enum_name(e, epullgNR, epullg_names)
+const char* enumValueToString(PullGroupGeometry enumValue);
 
 //! Enforced rotation groups.
-enum
-{
-    erotgISO,
-    erotgISOPF,
-    erotgPM,
-    erotgPMPF,
-    erotgRM,
-    erotgRMPF,
-    erotgRM2,
-    erotgRM2PF,
-    erotgFLEX,
-    erotgFLEXT,
-    erotgFLEX2,
-    erotgFLEX2T,
-    erotgNR
+enum class EnforcedRotationGroupType : int
+{
+    Iso,
+    Isopf,
+    Pm,
+    Pmpf,
+    Rm,
+    Rmpf,
+    Rm2,
+    Rm2pf,
+    Flex,
+    Flext,
+    Flex2,
+    Flex2t,
+    Count,
+    Default = Iso
 };
 //! Rotation group names
-extern const char* erotg_names[erotgNR + 1];
-//! Macro for rot group names
-#define EROTGEOM(e) enum_name(e, erotgNR, erotg_names)
+const char* enumValueToString(EnforcedRotationGroupType enumValue);
 //! String for rotation group origin names
-extern const char* erotg_originnames[erotgNR + 1];
-//! Macro for rot group origin names
-#define EROTORIGIN(e) enum_name(e, erotgOriginNR, erotg_originnames)
+const char* enumValueToLongString(EnforcedRotationGroupType enumValue);
 
 //! Rotation group fitting type
-enum
+enum class RotationGroupFitting : int
 {
-    erotgFitRMSD,
-    erotgFitNORM,
-    erotgFitPOT,
-    erotgFitNR
+    Rmsd,
+    Norm,
+    Pot,
+    Count,
+    Default = Rmsd
 };
 //! String corresponding to rotation group fitting
-extern const char* erotg_fitnames[erotgFitNR + 1];
-//! Macro for rot group fit names
-#define EROTFIT(e) enum_name(e, erotgFitNR, erotg_fitnames)
+const char* enumValueToString(RotationGroupFitting enumValue);
 
 /*! \brief Direction along which ion/water swaps happen
  *
  * Part of "Computational Electrophysiology" (CompEL) setups
  */
-enum eSwaptype
+enum class SwapType : int
 {
-    eswapNO,
-    eswapX,
-    eswapY,
-    eswapZ,
-    eSwapTypesNR
+    No,
+    X,
+    Y,
+    Z,
+    Count,
+    Default = No
 };
 //! Names for swapping
-extern const char* eSwapTypes_names[eSwapTypesNR + 1];
-//! Macro for swapping string
-#define ESWAPTYPE(e) enum_name(e, eSwapTypesNR, eSwapTypes_names)
+const char* enumValueToString(SwapType enumValue);
 
 /*! \brief Swap group splitting type
  *
  * These are just the fixed groups we need for any setup. In t_swap's grp
  * entry after that follows the variable number of swap groups.
  */
-enum
+enum class SwapGroupSplittingType : int
 {
-    eGrpSplit0,
-    eGrpSplit1,
-    eGrpSolvent,
-    eSwapFixedGrpNR
+    Split0,
+    Split1,
+    Solvent,
+    Count,
+    Default = Solvent
 };
 //! String for swap group splitting
-extern const char* eSwapFixedGrp_names[eSwapFixedGrpNR + 1];
+const char* enumValueToString(SwapGroupSplittingType enumValue);
 
 /*! \brief Types of electrostatics calculations
  *
@@ -785,17 +779,18 @@ extern const char* eSwapFixedGrp_names[eSwapFixedGrpNR + 1];
  * Note that these do NOT necessarily correspond to the user selections
  * in the MDP file; many interactions for instance map to tabulated kernels.
  */
-enum gmx_nbkernel_elec
+enum class NbkernelElecType : int
 {
-    GMX_NBKERNEL_ELEC_NONE,
-    GMX_NBKERNEL_ELEC_COULOMB,
-    GMX_NBKERNEL_ELEC_REACTIONFIELD,
-    GMX_NBKERNEL_ELEC_CUBICSPLINETABLE,
-    GMX_NBKERNEL_ELEC_EWALD,
-    GMX_NBKERNEL_ELEC_NR
+    None,
+    Coulomb,
+    ReactionField,
+    CubicSplineTable,
+    Ewald,
+    Count,
+    Default = None
 };
 //! String corresponding to electrostatics kernels
-extern const char* gmx_nbkernel_elec_names[GMX_NBKERNEL_ELEC_NR + 1];
+const char* enumValueToString(NbkernelElecType enumValue);
 
 /*! \brief Types of vdw calculations available
  *
@@ -803,16 +798,17 @@ extern const char* gmx_nbkernel_elec_names[GMX_NBKERNEL_ELEC_NR + 1];
  * Note that these do NOT necessarily correspond to the user selections
  * in the MDP file; many interactions for instance map to tabulated kernels.
  */
-enum gmx_nbkernel_vdw
+enum class NbkernelVdwType : int
 {
-    GMX_NBKERNEL_VDW_NONE,
-    GMX_NBKERNEL_VDW_LENNARDJONES,
-    GMX_NBKERNEL_VDW_BUCKINGHAM,
-    GMX_NBKERNEL_VDW_CUBICSPLINETABLE,
-    GMX_NBKERNEL_VDW_LJEWALD,
-    GMX_NBKERNEL_VDW_NR
+    None,
+    LennardJones,
+    Buckingham,
+    CubicSplineTable,
+    LJEwald,
+    Count,
+    Default = None
 };
 //! String corresponding to VdW kernels
-extern const char* gmx_nbkernel_vdw_names[GMX_NBKERNEL_VDW_NR + 1];
+const char* enumValueToString(NbkernelVdwType enumValue);
 
 #endif /* GMX_MDTYPES_MD_ENUMS_H */
index 177dba0e6f58e6c16a2626929de2c526af1723ad..2bd5072a806623770f0a4e5ba61e1f5326f5d3c7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -153,12 +153,12 @@ std::vector<std::string> checkMtsRequirements(const t_inputrec& ir)
 
     ArrayRef<const MtsLevel> mtsLevels = ir.mtsLevels;
 
-    if (!(ir.eI == eiMD || ir.eI == eiSD1))
+    if (!(ir.eI == IntegrationAlgorithm::MD || ir.eI == IntegrationAlgorithm::SD1))
     {
         errorMessages.push_back(gmx::formatString(
                 "Multiple time stepping is only supported with integrators %s and %s",
-                ei_names[eiMD],
-                ei_names[eiSD1]));
+                enumValueToString(IntegrationAlgorithm::MD),
+                enumValueToString(IntegrationAlgorithm::SD1)));
     }
 
     if ((EEL_FULL(ir.coulombtype) || EVDW_PME(ir.vdwtype))
@@ -189,7 +189,7 @@ std::vector<std::string> checkMtsRequirements(const t_inputrec& ir)
     {
         errorMessages.push_back(mesg.value());
     }
-    if (ir.efep != efepNO)
+    if (ir.efep != FreeEnergyPerturbationType::No)
     {
         if ((mesg = checkMtsInterval(mtsLevels, "nstdhdl", ir.fepvals->nstdhdl)))
         {
index 3b6e5b145f7a585e60932cd000345d090ffa8d33..63fc565ae745ae08c4c994008f91831c87f48dbf 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <vector>
 
+#include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/utility/alignedallocator.h"
 #include "gromacs/utility/real.h"
 
index c0709ca353edb9ac738bcf1681d44e57c2fe039d..ab81d886edd9b2e6451914f85122a9c3ce0e4e4d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2015,2016,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2015,2016,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.
@@ -75,11 +75,11 @@ static const int c_pullCoordNgroupMax = 6;
 struct t_pull_coord
 {
     //! The pull type: umbrella, constraint, ...
-    int eType = 0;
+    PullingAlgorithm eType = PullingAlgorithm::Umbrella;
     //! Name of the module providing   the external potential, only used with eType==epullEXTERNAL
     std::string externalPotentialProvider;
     //! The pull geometry
-    int eGeom = 0;
+    PullGroupGeometry eGeom = PullGroupGeometry::Distance;
     //! The number of groups, depends on eGeom
     int ngroup = 0;
     /*! \brief The pull groups:
index 1cceba8f80639cb428366be05eecb67262ff8cfb..dfb55ef30dbff4a098917247d5011872c8b0e683 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.
@@ -323,7 +323,7 @@ void set_box_rel(const t_inputrec* ir, t_state* state)
 
     if (inputrecPreserveShape(ir))
     {
-        const int ndim = ir->epct == epctSEMIISOTROPIC ? 2 : 3;
+        const int ndim = ir->epct == PressureCouplingType::SemiIsotropic ? 2 : 3;
         do_box_rel(ndim, ir->deform, state->box_rel, state->box, true);
     }
 }
@@ -332,7 +332,7 @@ void preserve_box_shape(const t_inputrec* ir, matrix box_rel, matrix box)
 {
     if (inputrecPreserveShape(ir))
     {
-        const int ndim = ir->epct == epctSEMIISOTROPIC ? 2 : 3;
+        const int ndim = ir->epct == PressureCouplingType::SemiIsotropic ? 2 : 3;
         do_box_rel(ndim, ir->deform, box_rel, box, false);
     }
 }
@@ -356,12 +356,12 @@ void initialize_lambdas(FILE* fplog, const t_inputrec& ir, bool isMaster, int* f
        t_state.  This function works, but could probably use a logic
        rewrite to keep all the different types of efep straight. */
 
-    if ((ir.efep == efepNO) && (!ir.bSimTemp))
+    if ((ir.efep == FreeEnergyPerturbationType::No) && (!ir.bSimTemp))
     {
         return;
     }
 
-    const t_lambda* fep = ir.fepvals;
+    const t_lambda* fep = ir.fepvals.get();
     if (isMaster)
     {
         *fep_state = fep->init_fep_state; /* this might overwrite the checkpoint
@@ -369,7 +369,7 @@ void initialize_lambdas(FILE* fplog, const t_inputrec& ir, bool isMaster, int* f
                                              to prevent this.*/
     }
 
-    for (int i = 0; i < efptNR; i++)
+    for (int i = 0; i < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); i++)
     {
         double thisLambda;
         /* overwrite lambda state with init_lambda for now for backwards compatibility */
index 1d98934318928c61005cb957b4c75a198ba0cea7..b4e5d7042b77528d0af1b1827d804f1a466c5931 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.
@@ -65,6 +65,7 @@
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/basedefinitions.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/real.h"
 
 struct t_inputrec;
@@ -237,22 +238,22 @@ public:
     int nnhpres;       //!< The number of NH-chains for the MTTK barostat (always 1 or 0)
     int nhchainlength; //!< The NH-chain length for temperature coupling and MTTK barostat
     int flags; //!< Set of bit-flags telling which entries are present, see enum at the top of the file
-    int                      fep_state;      //!< indicates which of the alchemical states we are in
-    std::array<real, efptNR> lambda;         //!< Free-energy lambda vector
-    matrix                   box;            //!< Matrix of box vectors
-    matrix                   box_rel;        //!< Relative box vectors to preserve box shape
-    matrix                   boxv;           //!< Box velocities for Parrinello-Rahman P-coupling
-    matrix                   pres_prev;      //!< Pressure of the previous step for pcoupl
-    matrix                   svir_prev;      //!< Shake virial for previous step for pcoupl
-    matrix                   fvir_prev;      //!< Force virial of the previous step for pcoupl
-    std::vector<double>      nosehoover_xi;  //!< Nose-Hoover coordinates (ngtc)
-    std::vector<double>      nosehoover_vxi; //!< Nose-Hoover velocities (ngtc)
-    std::vector<double>      nhpres_xi;      //!< Pressure Nose-Hoover coordinates
-    std::vector<double>      nhpres_vxi;     //!< Pressure Nose-Hoover velocities
-    std::vector<double>      therm_integral; //!< Work exterted N-H/V-rescale T-coupling (ngtc)
-    double                   baros_integral; //!< For Berendsen P-coupling conserved quantity
-    real                     veta;           //!< Trotter based isotropic P-coupling
-    real vol0; //!< Initial volume,required for computing MTTK conserved quantity
+    int fep_state; //!< indicates which of the alchemical states we are in
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> lambda; //!< Free-energy lambda vector
+    matrix                                                          box; //!< Matrix of box vectors
+    matrix              box_rel;        //!< Relative box vectors to preserve box shape
+    matrix              boxv;           //!< Box velocities for Parrinello-Rahman P-coupling
+    matrix              pres_prev;      //!< Pressure of the previous step for pcoupl
+    matrix              svir_prev;      //!< Shake virial for previous step for pcoupl
+    matrix              fvir_prev;      //!< Force virial of the previous step for pcoupl
+    std::vector<double> nosehoover_xi;  //!< Nose-Hoover coordinates (ngtc)
+    std::vector<double> nosehoover_vxi; //!< Nose-Hoover velocities (ngtc)
+    std::vector<double> nhpres_xi;      //!< Pressure Nose-Hoover coordinates
+    std::vector<double> nhpres_vxi;     //!< Pressure Nose-Hoover velocities
+    std::vector<double> therm_integral; //!< Work exterted N-H/V-rescale T-coupling (ngtc)
+    double              baros_integral; //!< For Berendsen P-coupling conserved quantity
+    real                veta;           //!< Trotter based isotropic P-coupling
+    real                vol0; //!< Initial volume,required for computing MTTK conserved quantity
     PaddedHostVector<gmx::RVec> x;    //!< The coordinates (natoms)
     PaddedHostVector<gmx::RVec> v;    //!< The velocities (natoms)
     PaddedHostVector<gmx::RVec> cg_p; //!< p vector for conjugate gradient minimization
index aeb26465c1f2204e3924281d1834023d07dfb28c..81b8a88ff485133d3b86a06af4b744ba9a05bf68 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016,2017,2019, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017,2019,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.
@@ -74,8 +74,8 @@ typedef struct swapstateIons_t
  */
 typedef struct swaphistory_t
 {
-    int  eSwapCoords; // Swapping along x, y, or z-direction?
-    int  nIonTypes;   // Number of ion types, this is the size of the following arrays
+    SwapType eSwapCoords; // Swapping along x, y, or z-direction?
+    int      nIonTypes;   // Number of ion types, this is the size of the following arrays
     int  nAverage; // Use average over this many swap attempt steps when determining the ion counts
     int  fluxleak; // Ions not going through any channel (bad!)
     int* fluxleak_p;               // Pointer to this data
index f69a45a650d741c3430a50b8383b3f737cfda3f5..e9fdc2e27ce3ab0ea1cd1a7a9f99477146eccf01 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -154,7 +154,7 @@ TEST(MultipleTimeStepping, ChecksPmeIsAtLastLevel)
     const GromppMtsOpts mtsOpts = simpleMtsOpts();
 
     t_inputrec ir;
-    ir.coulombtype = eelPME;
+    ir.coulombtype = CoulombInteractionType::Pme;
 
     setAndCheckMtsLevels(mtsOpts, &ir, 1);
 }
@@ -189,7 +189,7 @@ public:
         }
         else if (parameterName == "nstdhdl")
         {
-            ir_.efep             = efepYES;
+            ir_.efep             = FreeEnergyPerturbationType::Yes;
             ir_.fepvals->nstdhdl = interval;
         }
         else
@@ -223,7 +223,7 @@ TEST(MultipleTimeStepping, ChecksIntegrator)
     const GromppMtsOpts mtsOpts = simpleMtsOpts();
 
     t_inputrec ir;
-    ir.eI = eiBD;
+    ir.eI = IntegrationAlgorithm::BD;
 
     setAndCheckMtsLevels(mtsOpts, &ir, 1);
 }
index 3bca8ed4a0bb6c226716e26ce5a94befef7da737..1d59ae9063065f5f03e88b3a02709e4e9044296c 100644 (file)
@@ -84,7 +84,7 @@ ComputeGlobalsElement<algorithm>::ComputeGlobalsElement(StatePropagatorData* sta
     energyReductionStep_(-1),
     virialReductionStep_(-1),
     vvSchedulingStep_(-1),
-    doStopCM_(inputrec->comm_mode != ecmNO),
+    doStopCM_(inputrec->comm_mode != ComRemovalAlgorithm::No),
     nstcomm_(inputrec->nstcomm),
     nstglobalcomm_(nstglobalcomm),
     lastStep_(inputrec->nsteps + inputrec->init_step),
@@ -136,8 +136,9 @@ void ComputeGlobalsElement<algorithm>::elementSetup()
         auto v = statePropagatorData_->velocitiesView();
         // At initialization, do not pass x with acceleration-correction mode
         // to avoid (incorrect) correction of the initial coordinates.
-        auto x = vcm_.mode == ecmLINEAR_ACCELERATION_CORRECTION ? ArrayRefWithPadding<RVec>()
-                                                                : statePropagatorData_->positionsView();
+        auto x = vcm_.mode == ComRemovalAlgorithm::LinearAccelerationCorrection
+                         ? ArrayRefWithPadding<RVec>()
+                         : statePropagatorData_->positionsView();
         process_and_stopcm_grp(
                 fplog_, &vcm_, *mdAtoms_->mdatoms(), x.unpaddedArrayRef(), v.unpaddedArrayRef());
         inc_nrnb(nrnb_, eNR_STOPCM, mdAtoms_->mdatoms()->homenr);
index bba9ffa92ea734566647af98fbdd1b5ed9c04f0c..06383b360345531c481df1e3e6d4e25081e5bc94 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.
@@ -88,12 +88,14 @@ template<ConstraintVariable variable>
 void ConstraintsElement<variable>::elementSetup()
 {
     if (!inputrec_->bContinuation
-        && ((variable == ConstraintVariable::Positions && inputrec_->eI == eiMD)
-            || (variable == ConstraintVariable::Velocities && inputrec_->eI == eiVV)))
+        && ((variable == ConstraintVariable::Positions && inputrec_->eI == IntegrationAlgorithm::MD)
+            || (variable == ConstraintVariable::Velocities && inputrec_->eI == IntegrationAlgorithm::VV)))
     {
-        const real lambdaBonded = freeEnergyPerturbationData_
-                                          ? freeEnergyPerturbationData_->constLambdaView()[efptBONDED]
-                                          : 0;
+        const real lambdaBonded =
+                freeEnergyPerturbationData_
+                        ? freeEnergyPerturbationData_->constLambdaView()[static_cast<int>(
+                                  FreeEnergyPerturbationCouplingType::Bonded)]
+                        : 0;
         // Constrain the initial coordinates and velocities
         do_constrain_first(fplog_,
                            constr_,
@@ -107,7 +109,7 @@ void ConstraintsElement<variable>::elementSetup()
 
         if (isMasterRank_)
         {
-            if (inputrec_->eConstrAlg == econtLINCS)
+            if (inputrec_->eConstrAlg == ConstraintAlgorithm::Lincs)
             {
                 fprintf(fplog_,
                         "RMS relative constraint deviation after constraining: %.2e\n",
@@ -143,7 +145,10 @@ void ConstraintsElement<variable>::apply(Step step, bool calculateVirial, bool w
     ArrayRefWithPadding<RVec> v;
 
     const real lambdaBonded =
-            freeEnergyPerturbationData_ ? freeEnergyPerturbationData_->constLambdaView()[efptBONDED] : 0;
+            freeEnergyPerturbationData_
+                    ? freeEnergyPerturbationData_
+                              ->constLambdaView()[static_cast<int>(FreeEnergyPerturbationCouplingType::Bonded)]
+                    : 0;
     real dvdlambda = 0;
 
     switch (variable)
@@ -179,7 +184,7 @@ void ConstraintsElement<variable>::apply(Step step, bool calculateVirial, bool w
 
     if (calculateVirial)
     {
-        if (inputrec_->eI == eiVV)
+        if (inputrec_->eI == IntegrationAlgorithm::VV)
         {
             // For some reason, the shake virial in VV is reset twice a step.
             // Energy element will only do this once per step.
index 3cda75f3cea59a49e5a6d861b9d8558285072894..49b53fade819076afb909790843580c5633d66b9 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.
@@ -195,7 +195,7 @@ void EnergyData::setup(gmx_mdoutf* outf)
     if (!inputrec_->bContinuation)
     {
         real temp = enerd_->term[F_TEMP];
-        if (inputrec_->eI != eiVV)
+        if (inputrec_->eI != IntegrationAlgorithm::VV)
         {
             /* Result of Ekin averaged over velocities of -half
              * and +half step, while we only have -half step here.
@@ -263,8 +263,8 @@ void EnergyData::doStep(Time time, bool isEnergyCalculationStep, bool isFreeEner
             time,
             mdAtoms_->mdatoms()->tmass,
             enerd_,
-            inputrec_->fepvals,
-            inputrec_->expandedvals,
+            inputrec_->fepvals.get(),
+            inputrec_->expandedvals.get(),
             statePropagatorData_->constPreviousBox(),
             PTCouplingArrays({ parrinelloRahmanBarostat_ ? parrinelloRahmanBarostat_->boxVelocities() : nullMatrix,
                                {},
index 9b4fb32536c74f2ba60f5b18fb54bd8eae186f4a..cce364f9fce21b65ab50d89633cf3802397b9109 100644 (file)
@@ -124,7 +124,7 @@ ForceElement::ForceElement(StatePropagatorData*        statePropagatorData,
     constr_(constr),
     enforcedRotation_(enforcedRotation)
 {
-    lambda_.fill(0);
+    std::fill(lambda_.begin(), lambda_.end(), 0);
 
     if (doShellFC_ && !DOMAINDECOMP(cr))
     {
index 0ee81e0430a0fa505d2a3896e1f9d96644ded86f..3e5318a28257ff4a8f8a17ef8440442f7e9262e0 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.
@@ -51,6 +51,7 @@
 
 #include "gromacs/domdec/dlbtiming.h"
 #include "gromacs/mdtypes/md_enums.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/real.h"
 
 #include "modularsimulatorinterfaces.h"
@@ -193,7 +194,7 @@ private:
      * Used if FEP is off, since do_force
      * requires lambda to be allocated anyway
      */
-    std::array<real, efptNR> lambda_;
+    gmx::EnumerationArray<FreeEnergyPerturbationType, real> lambda_;
 
     // Access to ISimulator data
     //! Handles logging.
index 7065c44b175ffb2e9f1c5eaf76fd730f9be112f2..d780e69216eb38303ddadc503d75b77a04bfa11c 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.
@@ -68,7 +68,7 @@ FreeEnergyPerturbationData::FreeEnergyPerturbationData(FILE* fplog, const t_inpu
     inputrec_(inputrec),
     mdAtoms_(mdAtoms)
 {
-    lambda_.fill(0);
+    std::fill(lambda_.begin(), lambda_.end(), 0);
     // The legacy implementation only filled the lambda vector in state_global, which is only
     // available on master. We have the lambda vector available everywhere, so we pass a `true`
     // for isMaster on all ranks. See #3647.
@@ -109,7 +109,7 @@ int FreeEnergyPerturbationData::currentFEPState()
 
 void FreeEnergyPerturbationData::updateMDAtoms()
 {
-    update_mdatoms(mdAtoms_->mdatoms(), lambda_[efptMASS]);
+    update_mdatoms(mdAtoms_->mdatoms(), lambda_[FreeEnergyPerturbationCouplingType::Mass]);
 }
 
 namespace
@@ -204,7 +204,7 @@ void FreeEnergyPerturbationData::readCheckpointToTrxFrame(t_trxframe* trxFrame,
     {
         FreeEnergyPerturbationData freeEnergyPerturbationData;
         freeEnergyPerturbationData.doCheckpointData(&readCheckpointData.value());
-        trxFrame->lambda    = freeEnergyPerturbationData.lambda_[efptFEP];
+        trxFrame->lambda = freeEnergyPerturbationData.lambda_[FreeEnergyPerturbationCouplingType::Fep];
         trxFrame->fep_state = freeEnergyPerturbationData.currentFEPState_;
     }
     else
index 25c2a52916e6bfaa2b6430ccfa5205fdd10d1515..7ef19d86f1e26fc21a8b4203dbb0081903356d97 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.
@@ -46,6 +46,7 @@
 
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/real.h"
 
 #include "modularsimulatorinterfaces.h"
@@ -111,7 +112,7 @@ private:
     std::unique_ptr<Element> element_;
 
     //! The lambda vector
-    std::array<real, efptNR> lambda_;
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> lambda_;
     //! The current free energy state
     int currentFEPState_;
 
index d43052c48f0f714f5a911984d6530be292c25f20..fbb962be3dd49771f9fee1e43147ca0ce0b7c126 100644 (file)
@@ -106,7 +106,7 @@ void ModularSimulator::run()
 
 void ModularSimulator::addIntegrationElements(ModularSimulatorAlgorithmBuilder* builder)
 {
-    if (legacySimulatorData_->inputrec->eI == eiMD)
+    if (legacySimulatorData_->inputrec->eI == IntegrationAlgorithm::MD)
     {
         // The leap frog integration algorithm
         builder->add<ForceElement>();
@@ -131,7 +131,7 @@ void ModularSimulator::addIntegrationElements(ModularSimulatorAlgorithmBuilder*
             builder->add<ParrinelloRahmanBarostat>(-1);
         }
     }
-    else if (legacySimulatorData_->inputrec->eI == eiVV)
+    else if (legacySimulatorData_->inputrec->eI == IntegrationAlgorithm::VV)
     {
         // The velocity verlet integration algorithm
         builder->add<ForceElement>();
@@ -205,7 +205,7 @@ bool ModularSimulator::isInputCompatible(bool                             exitOn
             "or unset both to recover default behavior.");
 
     GMX_RELEASE_ASSERT(
-            !(modularSimulatorExplicitlyTurnedOff && inputrec->eI == eiVV
+            !(modularSimulatorExplicitlyTurnedOff && inputrec->eI == IntegrationAlgorithm::VV
               && inputrec->epc == PressureCoupling::ParrinelloRahman),
             "Cannot use a Parrinello-Rahman barostat with md-vv and "
             "GMX_DISABLE_MODULAR_SIMULATOR=ON, "
@@ -213,10 +213,11 @@ bool ModularSimulator::isInputCompatible(bool                             exitOn
             "GMX_DISABLE_MODULAR_SIMULATOR or use a different pressure control algorithm.");
 
     bool isInputCompatible = conditionalAssert(
-            inputrec->eI == eiMD || inputrec->eI == eiVV,
+            inputrec->eI == IntegrationAlgorithm::MD || inputrec->eI == IntegrationAlgorithm::VV,
             "Only integrators md and md-vv are supported by the modular simulator.");
     isInputCompatible = isInputCompatible
-                        && conditionalAssert(inputrec->eI != eiMD || modularSimulatorExplicitlyTurnedOn,
+                        && conditionalAssert(inputrec->eI != IntegrationAlgorithm::MD
+                                                     || modularSimulatorExplicitlyTurnedOn,
                                              "Set GMX_USE_MODULAR_SIMULATOR=ON to use the modular "
                                              "simulator with integrator md.");
     isInputCompatible =
@@ -245,11 +246,13 @@ bool ModularSimulator::isInputCompatible(bool                             exitOn
                        !(inputrecNptTrotter(inputrec) || inputrecNphTrotter(inputrec)
                          || inputrecNvtTrotter(inputrec)),
                        "Legacy Trotter decomposition is not supported by the modular simulator.");
-    isInputCompatible = isInputCompatible
-                        && conditionalAssert(inputrec->efep == efepNO || inputrec->efep == efepYES
-                                                     || inputrec->efep == efepSLOWGROWTH,
-                                             "Expanded ensemble free energy calculation is not "
-                                             "supported by the modular simulator.");
+    isInputCompatible =
+            isInputCompatible
+            && conditionalAssert(inputrec->efep == FreeEnergyPerturbationType::No
+                                         || inputrec->efep == FreeEnergyPerturbationType::Yes
+                                         || inputrec->efep == FreeEnergyPerturbationType::SlowGrowth,
+                                 "Expanded ensemble free energy calculation is not "
+                                 "supported by the modular simulator.");
     isInputCompatible = isInputCompatible
                         && conditionalAssert(!inputrec->bPull,
                                              "Pulling is not supported by the modular simulator.");
@@ -331,7 +334,7 @@ bool ModularSimulator::isInputCompatible(bool                             exitOn
             && conditionalAssert(!doEssentialDynamics,
                                  "Essential dynamics is not supported by the modular simulator.");
     isInputCompatible = isInputCompatible
-                        && conditionalAssert(inputrec->eSwapCoords == eswapNO,
+                        && conditionalAssert(inputrec->eSwapCoords == SwapType::No,
                                              "Ion / water position swapping is not supported by "
                                              "the modular simulator.");
     isInputCompatible =
@@ -359,7 +362,8 @@ bool ModularSimulator::isInputCompatible(bool                             exitOn
                                              "GMX_FAHCORE not supported by the modular simulator.");
     GMX_RELEASE_ASSERT(
             isInputCompatible
-                    || !(inputrec->eI == eiVV && inputrec->epc == PressureCoupling::ParrinelloRahman),
+                    || !(inputrec->eI == IntegrationAlgorithm::VV
+                         && inputrec->epc == PressureCoupling::ParrinelloRahman),
             "Requested Parrinello-Rahman barostat with md-vv, but other options are not compatible "
             "with the modular simulator. The Parrinello-Rahman barostat is not implemented for "
             "md-vv in the legacy simulator. Use a different pressure control algorithm.");
index 95f0bab2d3a127300dd0b6677e5bfcd93a4cf52a..81085d0cda1797465e6f61fc4eaea0355da9eb33 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.
@@ -168,7 +168,7 @@ void ParrinelloRahmanBarostat::elementSetup()
     if (inputrecPreserveShape(inputrec_))
     {
         auto      box  = statePropagatorData_->box();
-        const int ndim = inputrec_->epct == epctSEMIISOTROPIC ? 2 : 3;
+        const int ndim = inputrec_->epct == PressureCouplingType::SemiIsotropic ? 2 : 3;
         do_box_rel(ndim, inputrec_->deform, boxRel_, box, true);
     }
 
index 7c31518acc3884b66daa72697253a0a414301ef8..e8be0aba8f930c472eafb6b3bfdd98ffc37af86a 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.
@@ -61,7 +61,7 @@ bool PmeLoadBalanceHelper::doPmeLoadBalancing(const MdrunOptions& mdrunOptions,
                                               const t_forcerec*   fr)
 {
     return (mdrunOptions.tunePme && EEL_PME(fr->ic->eeltype) && !mdrunOptions.reproducible
-            && inputrec->cutoff_scheme != ecutsGROUP);
+            && inputrec->cutoff_scheme != CutoffScheme::Group);
 }
 
 PmeLoadBalanceHelper::PmeLoadBalanceHelper(bool                 isVerbose,
index d1e8cb5207cec9ab795767fc4c0be87d81ac81ee..29e24c013f03c41647e583967faebb1f3cb072b4 100644 (file)
@@ -404,7 +404,7 @@ ModularSimulatorAlgorithmBuilder::ModularSimulatorAlgorithmBuilder(
                              legacySimulatorData->startingBehavior,
                              legacySimulatorData->cr)
 {
-    if (legacySimulatorData->inputrec->efep != efepNO)
+    if (legacySimulatorData->inputrec->efep != FreeEnergyPerturbationType::No)
     {
         freeEnergyPerturbationData_ = std::make_unique<FreeEnergyPerturbationData>(
                 legacySimulatorData->fplog, legacySimulatorData->inputrec, legacySimulatorData->mdAtoms);
index ce7a3c861888814a76ed3c4b693973272c199fad..99406066fe0a9fe81af3586e0a4c18680d3811b4 100644 (file)
@@ -41,6 +41,7 @@
 
 #include "gmxpre.h"
 
+#include "gromacs/utility/enumerationhelpers.h"
 #include "statepropagatordata.h"
 
 #include "gromacs/commandline/filenm.h"
@@ -164,7 +165,7 @@ StatePropagatorData::StatePropagatorData(int                numAtoms,
                 }
             }
         }
-        if (inputrec->eI == eiVV)
+        if (inputrec->eI == IntegrationAlgorithm::VV)
         {
             vvResetVelocities_ = true;
         }
@@ -358,7 +359,9 @@ void StatePropagatorData::Element::saveState()
     if (freeEnergyPerturbationData_)
     {
         localStateBackup_->fep_state = freeEnergyPerturbationData_->currentFEPState();
-        for (unsigned long i = 0; i < localStateBackup_->lambda.size(); ++i)
+        for (unsigned long i = 0;
+             i < gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, double>::size();
+             ++i)
         {
             localStateBackup_->lambda[i] = freeEnergyPerturbationData_->constLambdaView()[i];
         }
index 78c333b7b27ab5cf8a7159078d0c9e47420848bd..32d03cc88260669bb4feb076a9dad7d6adc2f76e 100644 (file)
@@ -146,12 +146,13 @@ static interaction_const_t setupInteractionConst(const KernelBenchOptions& optio
 {
     interaction_const_t ic;
 
-    ic.vdwtype      = evdwCUT;
-    ic.vdw_modifier = eintmodPOTSHIFT;
+    ic.vdwtype      = VanDerWaalsType::Cut;
+    ic.vdw_modifier = InteractionModifiers::PotShift;
     ic.rvdw         = options.pairlistCutoff;
 
-    ic.eeltype          = (options.coulombType == BenchMarkCoulomb::Pme ? eelPME : eelRF);
-    ic.coulomb_modifier = eintmodPOTSHIFT;
+    ic.eeltype = (options.coulombType == BenchMarkCoulomb::Pme ? CoulombInteractionType::Pme
+                                                               : CoulombInteractionType::RF);
+    ic.coulomb_modifier = InteractionModifiers::PotShift;
     ic.rcoulomb         = options.pairlistCutoff;
 
     // Reaction-field with reactionFieldPermitivity=inf
index dff7e4d21cf8e68f98c1a6e7852b7b9a67fe4ef0..db8654440e14116102bca32b6e555ed2ea72e48d 100644 (file)
@@ -156,7 +156,7 @@ static void init_nbparam(NBParamGpu*                     nbp,
     }
 
     /* set up LJ-PME parameter lookup table */
-    if (ic->vdwtype == evdwPME)
+    if (ic->vdwtype == VanDerWaalsType::Pme)
     {
         initParamLookupTable(
                 &nbp->nbfp_comb, &nbp->nbfp_comb_texobj, nbatParams.nbfp_comb.data(), 2 * ntypes, deviceContext);
index 1952bf3d0c249a4cb1468d9eb426d0512d99ba2d..ae9edafd6a2110d81bf5dca0774db68ae966b1cb 100644 (file)
@@ -56,6 +56,7 @@
 #include "gromacs/nbnxm/nbnxm.h"
 #include "gromacs/simd/simd.h"
 #include "gromacs/timing/wallcycle.h"
+#include "gromacs/utility/enumerationhelpers.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/real.h"
@@ -138,7 +139,7 @@ static void reduceGroupEnergySimdBuffers(int numGroups, int numGroups_2log, nbnx
 static int getCoulombKernelType(const Nbnxm::KernelSetup& kernelSetup, const interaction_const_t& ic)
 {
 
-    if (EEL_RF(ic.eeltype) || ic.eeltype == eelCUT)
+    if (EEL_RF(ic.eeltype) || ic.eeltype == CoulombInteractionType::Cut)
     {
         return coulktRF;
     }
@@ -173,12 +174,12 @@ static int getVdwKernelType(const Nbnxm::KernelSetup&       kernelSetup,
                             const nbnxn_atomdata_t::Params& nbatParams,
                             const interaction_const_t&      ic)
 {
-    if (ic.vdwtype == evdwCUT)
+    if (ic.vdwtype == VanDerWaalsType::Cut)
     {
         switch (ic.vdw_modifier)
         {
-            case eintmodNONE:
-            case eintmodPOTSHIFT:
+            case InteractionModifiers::None:
+            case InteractionModifiers::PotShift:
                 switch (nbatParams.ljCombinationRule)
                 {
                     case LJCombinationRule::Geometric: return vdwktLJCUT_COMBGEOM;
@@ -186,19 +187,19 @@ static int getVdwKernelType(const Nbnxm::KernelSetup&       kernelSetup,
                     case LJCombinationRule::None: return vdwktLJCUT_COMBNONE;
                     default: gmx_incons("Unknown combination rule");
                 }
-            case eintmodFORCESWITCH: return vdwktLJFORCESWITCH;
-            case eintmodPOTSWITCH: return vdwktLJPOTSWITCH;
+            case InteractionModifiers::ForceSwitch: return vdwktLJFORCESWITCH;
+            case InteractionModifiers::PotSwitch: return vdwktLJPOTSWITCH;
             default:
                 std::string errorMsg =
                         gmx::formatString("Unsupported VdW interaction modifier %s (%d)",
-                                          INTMODIFIER(ic.vdw_modifier),
-                                          ic.vdw_modifier);
+                                          enumValueToString(ic.vdw_modifier),
+                                          static_cast<int>(ic.vdw_modifier));
                 gmx_incons(errorMsg);
         }
     }
-    else if (ic.vdwtype == evdwPME)
+    else if (ic.vdwtype == VanDerWaalsType::Pme)
     {
-        if (ic.ljpme_comb_rule == eljpmeGEOM)
+        if (ic.ljpme_comb_rule == LongRangeVdW::Geom)
         {
             return vdwktLJEWALDCOMBGEOM;
         }
@@ -213,8 +214,9 @@ static int getVdwKernelType(const Nbnxm::KernelSetup&       kernelSetup,
     }
     else
     {
-        std::string errorMsg = gmx::formatString(
-                "Unsupported VdW interaction type %s (%d)", EVDWTYPE(ic.vdwtype), ic.vdwtype);
+        std::string errorMsg = gmx::formatString("Unsupported VdW interaction type %s (%d)",
+                                                 enumValueToString(ic.vdwtype),
+                                                 static_cast<int>(ic.vdwtype));
         gmx_incons(errorMsg);
     }
 }
@@ -388,7 +390,7 @@ static void accountFlops(t_nrnb*                    nrnb,
     const bool usingGpuKernels = nbv.useGpu();
 
     int enr_nbnxn_kernel_ljc = eNRNB;
-    if (EEL_RF(ic.eeltype) || ic.eeltype == eelCUT)
+    if (EEL_RF(ic.eeltype) || ic.eeltype == CoulombInteractionType::Cut)
     {
         enr_nbnxn_kernel_ljc = eNR_NBNXN_LJ_RF;
     }
@@ -414,21 +416,21 @@ static void accountFlops(t_nrnb*                    nrnb,
     /* The Coulomb-only kernels are offset -eNR_NBNXN_LJ_RF+eNR_NBNXN_RF */
     inc_nrnb(nrnb, enr_nbnxn_kernel_ljc - eNR_NBNXN_LJ_RF + eNR_NBNXN_RF, pairlistSet.natpair_q_);
 
-    if (ic.vdw_modifier == eintmodFORCESWITCH)
+    if (ic.vdw_modifier == InteractionModifiers::ForceSwitch)
     {
         /* We add up the switch cost separately */
         inc_nrnb(nrnb,
                  eNR_NBNXN_ADD_LJ_FSW + (stepWork.computeEnergy ? 1 : 0),
                  pairlistSet.natpair_ljq_ + pairlistSet.natpair_lj_);
     }
-    if (ic.vdw_modifier == eintmodPOTSWITCH)
+    if (ic.vdw_modifier == InteractionModifiers::PotSwitch)
     {
         /* We add up the switch cost separately */
         inc_nrnb(nrnb,
                  eNR_NBNXN_ADD_LJ_PSW + (stepWork.computeEnergy ? 1 : 0),
                  pairlistSet.natpair_ljq_ + pairlistSet.natpair_lj_);
     }
-    if (ic.vdwtype == evdwPME)
+    if (ic.vdwtype == VanDerWaalsType::Pme)
     {
         /* We add up the LJ Ewald cost separately */
         inc_nrnb(nrnb,
@@ -494,7 +496,7 @@ void nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality   iLo
                                                   gmx::ForceWithShiftForces* forceWithShiftForces,
                                                   const t_mdatoms&           mdatoms,
                                                   t_lambda*                  fepvals,
-                                                  gmx::ArrayRef<real const>  lambda,
+                                                  gmx::ArrayRef<const real>  lambda,
                                                   gmx_enerdata_t*            enerd,
                                                   const gmx::StepWorkload&   stepWork,
                                                   t_nrnb*                    nrnb)
@@ -524,11 +526,11 @@ void nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality   iLo
         donb_flags |= GMX_NONBONDED_DO_POTENTIAL;
     }
 
-    nb_kernel_data_t kernel_data;
-    real             dvdl_nb[efptNR] = { 0 };
-    kernel_data.flags                = donb_flags;
-    kernel_data.lambda               = lambda.data();
-    kernel_data.dvdl                 = dvdl_nb;
+    nb_kernel_data_t                                                kernel_data;
+    gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> dvdl_nb = { 0 };
+    kernel_data.flags                                                       = donb_flags;
+    kernel_data.lambda                                                      = lambda;
+    kernel_data.dvdl                                                        = dvdl_nb;
 
     kernel_data.energygrp_elec = enerd->grpp.ener[egCOULSR].data();
     kernel_data.energygrp_vdw  = enerd->grpp.ener[egLJSR].data();
@@ -550,13 +552,17 @@ void nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality   iLo
 
     if (fepvals->sc_alpha != 0)
     {
-        enerd->dvdl_nonlin[efptVDW] += dvdl_nb[efptVDW];
-        enerd->dvdl_nonlin[efptCOUL] += dvdl_nb[efptCOUL];
+        enerd->dvdl_nonlin[FreeEnergyPerturbationCouplingType::Vdw] +=
+                dvdl_nb[FreeEnergyPerturbationCouplingType::Vdw];
+        enerd->dvdl_nonlin[FreeEnergyPerturbationCouplingType::Coul] +=
+                dvdl_nb[FreeEnergyPerturbationCouplingType::Coul];
     }
     else
     {
-        enerd->dvdl_lin[efptVDW] += dvdl_nb[efptVDW];
-        enerd->dvdl_lin[efptCOUL] += dvdl_nb[efptCOUL];
+        enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Vdw] +=
+                dvdl_nb[FreeEnergyPerturbationCouplingType::Vdw];
+        enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Coul] +=
+                dvdl_nb[FreeEnergyPerturbationCouplingType::Coul];
     }
 
     /* If we do foreign lambda and we have soft-core interactions
@@ -564,7 +570,7 @@ void nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality   iLo
      */
     if (fepvals->n_lambda > 0 && stepWork.computeDhdl && fepvals->sc_alpha != 0)
     {
-        real lam_i[efptNR];
+        gmx::EnumerationArray<FreeEnergyPerturbationCouplingType, real> lam_i;
         kernel_data.flags = (donb_flags & ~(GMX_NONBONDED_DO_FORCE | GMX_NONBONDED_DO_SHIFTFORCE))
                             | GMX_NONBONDED_DO_FOREIGNLAMBDA;
         kernel_data.lambda         = lam_i;
@@ -575,7 +581,7 @@ void nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality   iLo
         for (gmx::index i = 0; i < 1 + enerd->foreignLambdaTerms.numLambdas(); i++)
         {
             std::fill(std::begin(dvdl_nb), std::end(dvdl_nb), 0);
-            for (int j = 0; j < efptNR; j++)
+            for (int j = 0; j < static_cast<int>(FreeEnergyPerturbationCouplingType::Count); j++)
             {
                 lam_i[j] = (i == 0 ? lambda[j] : fepvals->all_lambda[j][i - 1]);
             }
@@ -593,7 +599,10 @@ void nonbonded_verlet_t::dispatchFreeEnergyKernel(gmx::InteractionLocality   iLo
 
             sum_epot(enerd->foreign_grpp, enerd->foreign_term);
             enerd->foreignLambdaTerms.accumulate(
-                    i, enerd->foreign_term[F_EPOT], dvdl_nb[efptVDW] + dvdl_nb[efptCOUL]);
+                    i,
+                    enerd->foreign_term[F_EPOT],
+                    dvdl_nb[FreeEnergyPerturbationCouplingType::Vdw]
+                            + dvdl_nb[FreeEnergyPerturbationCouplingType::Coul]);
         }
     }
     wallcycle_sub_stop(wcycle_, ewcsNONBONDED_FEP);
index 344e69d54ed887a8813f44c00b0c555e7684147e..aad56f49155f63facabd475f6fad7a6ae94c4e3a 100644 (file)
@@ -338,7 +338,7 @@ bool gpu_is_kernel_ewald_analytical(const NbnxmGpu* nb)
 enum ElecType nbnxmGpuPickElectrostaticsKernelType(const interaction_const_t* ic,
                                                    const DeviceInformation&   deviceInfo)
 {
-    if (ic->eeltype == eelCUT)
+    if (ic->eeltype == CoulombInteractionType::Cut)
     {
         return ElecType::Cut;
     }
@@ -346,7 +346,7 @@ enum ElecType nbnxmGpuPickElectrostaticsKernelType(const interaction_const_t* ic
     {
         return ElecType::RF;
     }
-    else if ((EEL_PME(ic->eeltype) || ic->eeltype == eelEWALD))
+    else if ((EEL_PME(ic->eeltype) || ic->eeltype == CoulombInteractionType::Ewald))
     {
         return nbnxn_gpu_pick_ewald_kernel_type(*ic, deviceInfo);
     }
@@ -354,22 +354,21 @@ enum ElecType nbnxmGpuPickElectrostaticsKernelType(const interaction_const_t* ic
     {
         /* Shouldn't happen, as this is checked when choosing Verlet-scheme */
         GMX_THROW(gmx::InconsistentInputError(
-                gmx::formatString("The requested electrostatics type %s (%d) is not implemented in "
+                gmx::formatString("The requested electrostatics type %s is not implemented in "
                                   "the GPU accelerated kernels!",
-                                  EELTYPE(ic->eeltype),
-                                  ic->eeltype)));
+                                  enumValueToString(ic->eeltype))));
     }
 }
 
 
 enum VdwType nbnxmGpuPickVdwKernelType(const interaction_const_t* ic, LJCombinationRule ljCombinationRule)
 {
-    if (ic->vdwtype == evdwCUT)
+    if (ic->vdwtype == VanDerWaalsType::Cut)
     {
         switch (ic->vdw_modifier)
         {
-            case eintmodNONE:
-            case eintmodPOTSHIFT:
+            case InteractionModifiers::None:
+            case InteractionModifiers::PotShift:
                 switch (ljCombinationRule)
                 {
                     case LJCombinationRule::None: return VdwType::Cut;
@@ -381,19 +380,18 @@ enum VdwType nbnxmGpuPickVdwKernelType(const interaction_const_t* ic, LJCombinat
                                 "the GPU accelerated kernels!",
                                 enumValueToString(ljCombinationRule))));
                 }
-            case eintmodFORCESWITCH: return VdwType::FSwitch;
-            case eintmodPOTSWITCH: return VdwType::PSwitch;
+            case InteractionModifiers::ForceSwitch: return VdwType::FSwitch;
+            case InteractionModifiers::PotSwitch: return VdwType::PSwitch;
             default:
                 GMX_THROW(gmx::InconsistentInputError(
-                        gmx::formatString("The requested VdW interaction modifier %s (%d) is not "
+                        gmx::formatString("The requested VdW interaction modifier %s is not "
                                           "implemented in the GPU accelerated kernels!",
-                                          INTMODIFIER(ic->vdw_modifier),
-                                          ic->vdw_modifier)));
+                                          enumValueToString(ic->vdw_modifier))));
         }
     }
-    else if (ic->vdwtype == evdwPME)
+    else if (ic->vdwtype == VanDerWaalsType::Pme)
     {
-        if (ic->ljpme_comb_rule == eljpmeGEOM)
+        if (ic->ljpme_comb_rule == LongRangeVdW::Geom)
         {
             assert(ljCombinationRule == LJCombinationRule::Geometric);
             return VdwType::EwaldGeom;
@@ -407,9 +405,8 @@ enum VdwType nbnxmGpuPickVdwKernelType(const interaction_const_t* ic, LJCombinat
     else
     {
         GMX_THROW(gmx::InconsistentInputError(gmx::formatString(
-                "The requested VdW type %s (%d) is not implemented in the GPU accelerated kernels!",
-                EVDWTYPE(ic->vdwtype),
-                ic->vdwtype)));
+                "The requested VdW type %s is not implemented in the GPU accelerated kernels!",
+                enumValueToString(ic->vdwtype))));
     }
 }
 
index 0cfaf9053bcb7dbf15997a745060850bf1960fec..193af53cbe4609e8e4531eb102bce464ea98c45d 100644 (file)
@@ -85,7 +85,7 @@ enum class NonbondedResource : int
  */
 static bool nbnxn_simd_supported(const gmx::MDLogger& mdlog, const t_inputrec& inputrec)
 {
-    if (inputrec.vdwtype == evdwPME && inputrec.ljpme_combination_rule == eljpmeLB)
+    if (inputrec.vdwtype == VanDerWaalsType::Pme && inputrec.ljpme_combination_rule == LongRangeVdW::LB)
     {
         /* LJ PME with LB combination rule does 7 mesh operations.
          * This so slow that we don't compile SIMD non-bonded kernels
@@ -344,17 +344,18 @@ static int getMinimumIlistCountForGpuBalancing(NbnxmGpu* nbnxmGpu)
 
 static int getENbnxnInitCombRule(const t_forcerec& forcerec)
 {
-    if (forcerec.ic->vdwtype == evdwCUT
-        && (forcerec.ic->vdw_modifier == eintmodNONE || forcerec.ic->vdw_modifier == eintmodPOTSHIFT)
+    if (forcerec.ic->vdwtype == VanDerWaalsType::Cut
+        && (forcerec.ic->vdw_modifier == InteractionModifiers::None
+            || forcerec.ic->vdw_modifier == InteractionModifiers::PotShift)
         && getenv("GMX_NO_LJ_COMB_RULE") == nullptr)
     {
         /* Plain LJ cut-off: we can optimize with combination rules */
         return enbnxninitcombruleDETECT;
     }
-    else if (forcerec.ic->vdwtype == evdwPME)
+    else if (forcerec.ic->vdwtype == VanDerWaalsType::Pme)
     {
         /* LJ-PME: we need to use a combination rule for the grid */
-        if (forcerec.ljpme_combination_rule == eljpmeGEOM)
+        if (forcerec.ljpme_combination_rule == LongRangeVdW::Geom)
         {
             return enbnxninitcombruleGEOM;
         }
@@ -405,7 +406,8 @@ std::unique_ptr<nonbonded_verlet_t> init_nb_verlet(const gmx::MDLogger& mdlog,
 
     const bool haveMultipleDomains = havePPDomainDecomposition(commrec);
 
-    bool bFEP_NonBonded = (forcerec.efep != efepNO) && haveFepPerturbedNBInteractions(mtop);
+    bool bFEP_NonBonded = (forcerec.efep != FreeEnergyPerturbationType::No)
+                          && haveFepPerturbedNBInteractions(mtop);
     PairlistParams pairlistParams(
             kernelSetup.kernelType, bFEP_NonBonded, inputrec.rlist, haveMultipleDomains);
 
index 706c3a48d5441ab520522501c0e19d8436dbfe9e..da998182cab678c5ae77f15393bca429baf34bec 100644 (file)
@@ -138,9 +138,9 @@ static void init_nbparam(NBParamGpu*                     nbp,
     nbp->vdwType  = nbnxmGpuPickVdwKernelType(ic, nbatParams.ljCombinationRule);
     nbp->elecType = nbnxmGpuPickElectrostaticsKernelType(ic, deviceContext.deviceInfo());
 
-    if (ic->vdwtype == evdwPME)
+    if (ic->vdwtype == VanDerWaalsType::Pme)
     {
-        if (ic->ljpme_comb_rule == eljpmeGEOM)
+        if (ic->ljpme_comb_rule == LongRangeVdW::Geom)
         {
             GMX_ASSERT(nbatParams.ljCombinationRule == LJCombinationRule::Geometric,
                        "Combination rule mismatch!");
@@ -172,7 +172,7 @@ static void init_nbparam(NBParamGpu*                     nbp,
         initParamLookupTable(&nbfp, nullptr, nbatParams.nbfp.data(), nnbfp, deviceContext);
         nbp->nbfp = nbfp;
 
-        if (ic->vdwtype == evdwPME)
+        if (ic->vdwtype == VanDerWaalsType::Pme)
         {
             DeviceBuffer<float> nbfp_comb;
             initParamLookupTable(&nbfp_comb, nullptr, nbatParams.nbfp_comb.data(), nnbfp_comb, deviceContext);
index b2ffe801d25fde6e9991261d9b483dc788d5dbad..f9f61db40f6278efca9525be89628076eec66ec6 100644 (file)
@@ -79,7 +79,7 @@
  */
 static bool supportsDynamicPairlistGenerationInterval(const t_inputrec& ir)
 {
-    return ir.cutoff_scheme == ecutsVERLET && EI_DYNAMICS(ir.eI)
+    return ir.cutoff_scheme == CutoffScheme::Verlet && EI_DYNAMICS(ir.eI)
            && !(EI_MD(ir.eI) && ir.etc == TemperatureCoupling::No) && ir.verletbuf_tol > 0;
 }
 
index a3d8626fc431da1b64d3dd4deebe1cbbc64a63e2..e033a507e8f44698bf3dc26dac55f8e5f9a8f255 100644 (file)
@@ -129,7 +129,7 @@ static void initNbparam(NBParamGpu*                     nbp,
     }
 
     /* set up LJ-PME parameter lookup table */
-    if (ic.vdwtype == evdwPME)
+    if (ic.vdwtype == VanDerWaalsType::Pme)
     {
         initParamLookupTable(
                 &nbp->nbfp_comb, &nbp->nbfp_comb_texobj, nbatParams.nbfp_comb.data(), 2 * numTypes, deviceContext);
index 627700a3b22cfff3045be2847d80243d7a31fb52..691a2488722b129d0ddf500caef90c89dc0f1d4d 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.
@@ -91,7 +91,7 @@ static void addToPullxHistory(pull_t* pull)
             pcrdHistory.dr23[m] += pcrd.spatialData.dr23[m];
             pcrdHistory.dr45[m] += pcrd.spatialData.dr45[m];
         }
-        if (pcrd.params.eGeom == epullgCYL)
+        if (pcrd.params.eGeom == PullGroupGeometry::Cylinder)
         {
             for (int m = 0; m < DIM; m++)
             {
@@ -178,7 +178,7 @@ static void pull_print_coord_dr(FILE*                out,
 
     fprintf(out, "\t%g", pcrdData.value * unit_factor / numValuesInSum);
 
-    if (pullParams.bPrintRefValue && coordParams.eType != epullEXTERNAL)
+    if (pullParams.bPrintRefValue && coordParams.eType != PullingAlgorithm::External)
     {
         fprintf(out, "\t%g", referenceValue * unit_factor / numValuesInSum);
     }
@@ -223,7 +223,7 @@ static void pull_print_x(FILE* out, pull_t* pull, double t)
 
         if (pull->params.bPrintCOM)
         {
-            if (pcrd.params.eGeom == epullgCYL)
+            if (pcrd.params.eGeom == PullGroupGeometry::Cylinder)
             {
                 for (int m = 0; m < DIM; m++)
                 {
@@ -457,7 +457,7 @@ static FILE* open_pull_out(const char*             fn,
                 sprintf(buf, "%zu", c + 1);
                 setname[nsets] = gmx_strdup(buf);
                 nsets++;
-                if (pull->params.bPrintRefValue && pull->coord[c].params.eType != epullEXTERNAL)
+                if (pull->params.bPrintRefValue && pull->coord[c].params.eType != PullingAlgorithm::External)
                 {
                     sprintf(buf, "%zu ref", c + 1);
                     setname[nsets] = gmx_strdup(buf);
index 4140acb066e62c6a13b31f14f3be0d8bfa408326..41b5bbce40310cc2d5b3273eb6d788eaab8797ee 100644 (file)
@@ -37,6 +37,7 @@
  */
 #include "gmxpre.h"
 
+#include "gromacs/utility/stringutil.h"
 #include "pull.h"
 
 #include "config.h"
@@ -132,13 +133,15 @@ pull_group_work_t::pull_group_work_t(const t_pull_group& params,
 
 bool pull_coordinate_is_angletype(const t_pull_coord* pcrd)
 {
-    return (pcrd->eGeom == epullgANGLE || pcrd->eGeom == epullgDIHEDRAL || pcrd->eGeom == epullgANGLEAXIS);
+    return (pcrd->eGeom == PullGroupGeometry::Angle || pcrd->eGeom == PullGroupGeometry::Dihedral
+            || pcrd->eGeom == PullGroupGeometry::AngleAxis);
 }
 
 static bool pull_coordinate_is_directional(const t_pull_coord* pcrd)
 {
-    return (pcrd->eGeom == epullgDIR || pcrd->eGeom == epullgDIRPBC
-            || pcrd->eGeom == epullgDIRRELATIVE || pcrd->eGeom == epullgCYL);
+    return (pcrd->eGeom == PullGroupGeometry::Direction || pcrd->eGeom == PullGroupGeometry::DirectionPBC
+            || pcrd->eGeom == PullGroupGeometry::DirectionRelative
+            || pcrd->eGeom == PullGroupGeometry::Cylinder);
 }
 
 const char* pull_coordinate_units(const t_pull_coord* pcrd)
@@ -333,7 +336,7 @@ static void apply_forces_coord(struct pull_t*               pull,
 
     const pull_coord_work_t& pcrd = pull->coord[coord];
 
-    if (pcrd.params.eGeom == epullgCYL)
+    if (pcrd.params.eGeom == PullGroupGeometry::Cylinder)
     {
         apply_forces_cyl_grp(&pull->dyna[coord],
                              pcrd.spatialData.cyl_dev,
@@ -354,7 +357,7 @@ static void apply_forces_coord(struct pull_t*               pull,
     }
     else
     {
-        if (pcrd.params.eGeom == epullgDIRRELATIVE)
+        if (pcrd.params.eGeom == PullGroupGeometry::DirectionRelative)
         {
             /* We need to apply the torque forces to the pull groups
              * that define the pull vector.
@@ -485,7 +488,7 @@ static void low_get_pull_coord_dr(const struct pull_t*     pull,
     copy_dvec(xref, xrefr);
 
     dvec dref = { 0, 0, 0 };
-    if (pcrd->params.eGeom == epullgDIRPBC)
+    if (pcrd->params.eGeom == PullGroupGeometry::DirectionPBC)
     {
         for (int m = 0; m < DIM; m++)
         {
@@ -522,13 +525,13 @@ static void low_get_pull_coord_dr(const struct pull_t*     pull,
                   pcrd->params.group[groupIndex1],
                   sqrt(dr2),
                   sqrt(0.98 * 0.98 * max_dist2),
-                  pcrd->params.eGeom == epullgDIR
+                  pcrd->params.eGeom == PullGroupGeometry::Direction
                           ? "You might want to consider using \"pull-geometry = "
                             "direction-periodic\" instead.\n"
                           : "");
     }
 
-    if (pcrd->params.eGeom == epullgDIRPBC)
+    if (pcrd->params.eGeom == PullGroupGeometry::DirectionPBC)
     {
         dvec_inc(dr, dref);
     }
@@ -546,8 +549,9 @@ static void get_pull_coord_dr(struct pull_t* pull, int coord_ind, const t_pbc* p
     /* With AWH pulling we allow for periodic pulling with geometry=direction.
      * TODO: Store a periodicity flag instead of checking for external pull provider.
      */
-    if (pcrd->params.eGeom == epullgDIRPBC
-        || (pcrd->params.eGeom == epullgDIR && pcrd->params.eType == epullEXTERNAL))
+    if (pcrd->params.eGeom == PullGroupGeometry::DirectionPBC
+        || (pcrd->params.eGeom == PullGroupGeometry::Direction
+            && pcrd->params.eType == PullingAlgorithm::External))
     {
         md2 = -1;
     }
@@ -556,7 +560,7 @@ static void get_pull_coord_dr(struct pull_t* pull, int coord_ind, const t_pbc* p
         md2 = static_cast<double>(max_pull_distance2(pcrd, pbc));
     }
 
-    if (pcrd->params.eGeom == epullgDIRRELATIVE)
+    if (pcrd->params.eGeom == PullGroupGeometry::DirectionRelative)
     {
         /* We need to determine the pull vector */
         dvec vec;
@@ -593,15 +597,16 @@ static void get_pull_coord_dr(struct pull_t* pull, int coord_ind, const t_pbc* p
     pull_group_work_t* pgrp0 = &pull->group[pcrd->params.group[0]];
     pull_group_work_t* pgrp1 = &pull->group[pcrd->params.group[1]];
 
-    low_get_pull_coord_dr(pull,
-                          pcrd,
-                          pbc,
-                          pgrp1->x,
-                          pcrd->params.eGeom == epullgCYL ? pull->dyna[coord_ind].x : pgrp0->x,
-                          0,
-                          1,
-                          md2,
-                          spatialData.dr01);
+    low_get_pull_coord_dr(
+            pull,
+            pcrd,
+            pbc,
+            pgrp1->x,
+            pcrd->params.eGeom == PullGroupGeometry::Cylinder ? pull->dyna[coord_ind].x : pgrp0->x,
+            0,
+            1,
+            md2,
+            spatialData.dr01);
 
     if (pcrd->params.ngroup >= 4)
     {
@@ -640,10 +645,10 @@ static void make_periodic_2pi(double* x)
 /* This function should always be used to modify pcrd->value_ref */
 static void low_set_pull_coord_reference_value(pull_coord_work_t* pcrd, int coord_ind, double value_ref)
 {
-    GMX_ASSERT(pcrd->params.eType != epullEXTERNAL,
+    GMX_ASSERT(pcrd->params.eType != PullingAlgorithm::External,
                "The pull coord reference value should not be used with type external-potential");
 
-    if (pcrd->params.eGeom == epullgDIST)
+    if (pcrd->params.eGeom == PullGroupGeometry::Distance)
     {
         if (value_ref < 0)
         {
@@ -653,7 +658,8 @@ static void low_set_pull_coord_reference_value(pull_coord_work_t* pcrd, int coor
                       value_ref);
         }
     }
-    else if (pcrd->params.eGeom == epullgANGLE || pcrd->params.eGeom == epullgANGLEAXIS)
+    else if (pcrd->params.eGeom == PullGroupGeometry::Angle
+             || pcrd->params.eGeom == PullGroupGeometry::AngleAxis)
     {
         if (value_ref < 0 || value_ref > M_PI)
         {
@@ -664,7 +670,7 @@ static void low_set_pull_coord_reference_value(pull_coord_work_t* pcrd, int coor
                       value_ref * pull_conversion_factor_internal2userinput(&pcrd->params));
         }
     }
-    else if (pcrd->params.eGeom == epullgDIHEDRAL)
+    else if (pcrd->params.eGeom == PullGroupGeometry::Dihedral)
     {
         /* Allow pulling to be periodic for dihedral angles by remapping the reference value to the interval [-pi, pi). */
         make_periodic_2pi(&value_ref);
@@ -721,14 +727,14 @@ static void get_pull_coord_distance(struct pull_t* pull, int coord_ind, const t_
 
     switch (pcrd->params.eGeom)
     {
-        case epullgDIST:
+        case PullGroupGeometry::Distance:
             /* Pull along the vector between the com's */
             spatialData.value = dnorm(spatialData.dr01);
             break;
-        case epullgDIR:
-        case epullgDIRPBC:
-        case epullgDIRRELATIVE:
-        case epullgCYL:
+        case PullGroupGeometry::Direction:
+        case PullGroupGeometry::DirectionPBC:
+        case PullGroupGeometry::DirectionRelative:
+        case PullGroupGeometry::Cylinder:
             /* Pull along vec */
             spatialData.value = 0;
             for (m = 0; m < DIM; m++)
@@ -736,11 +742,13 @@ static void get_pull_coord_distance(struct pull_t* pull, int coord_ind, const t_
                 spatialData.value += spatialData.vec[m] * spatialData.dr01[m];
             }
             break;
-        case epullgANGLE:
+        case PullGroupGeometry::Angle:
             spatialData.value = gmx_angle_between_dvecs(spatialData.dr01, spatialData.dr23);
             break;
-        case epullgDIHEDRAL: spatialData.value = get_dihedral_angle_coord(&spatialData); break;
-        case epullgANGLEAXIS:
+        case PullGroupGeometry::Dihedral:
+            spatialData.value = get_dihedral_angle_coord(&spatialData);
+            break;
+        case PullGroupGeometry::AngleAxis:
             spatialData.value = gmx_angle_between_dvecs(spatialData.dr01, spatialData.vec);
             break;
         default: gmx_incons("Unsupported pull type in get_pull_coord_distance");
@@ -770,14 +778,14 @@ static double get_pull_coord_deviation(struct pull_t* pull, int coord_ind, const
     dev = pcrd->spatialData.value - pcrd->value_ref;
 
     /* Check that values are allowed */
-    if (pcrd->params.eGeom == epullgDIST && pcrd->spatialData.value == 0)
+    if (pcrd->params.eGeom == PullGroupGeometry::Distance && pcrd->spatialData.value == 0)
     {
         /* With no vector we can not determine the direction for the force,
          * so we set the force to zero.
          */
         dev = 0;
     }
-    else if (pcrd->params.eGeom == epullgDIHEDRAL)
+    else if (pcrd->params.eGeom == PullGroupGeometry::Dihedral)
     {
         /* The reference value is in [-pi, pi). The coordinate value is in (-pi, pi].
            Thus, the unwrapped deviation is here in (-2pi, 2pi].
@@ -844,7 +852,7 @@ do_constraint(struct pull_t* pull, t_pbc* pbc, rvec* x, rvec* v, gmx_bool bMaste
 
         pcrd = &pull->coord[c];
 
-        if (pcrd->params.eType != epullCONSTRAINT)
+        if (pcrd->params.eType != PullingAlgorithm::Constraint)
         {
             continue;
         }
@@ -866,7 +874,8 @@ do_constraint(struct pull_t* pull, t_pbc* pbc, rvec* x, rvec* v, gmx_bool bMaste
                     spatialData.dr01[ZZ]);
         }
 
-        if (pcrd->params.eGeom == epullgDIR || pcrd->params.eGeom == epullgDIRPBC)
+        if (pcrd->params.eGeom == PullGroupGeometry::Direction
+            || pcrd->params.eGeom == PullGroupGeometry::DirectionPBC)
         {
             /* Select the component along vec */
             a = 0;
@@ -907,7 +916,7 @@ do_constraint(struct pull_t* pull, t_pbc* pbc, rvec* x, rvec* v, gmx_bool bMaste
 
             pcrd = &pull->coord[c];
 
-            if (pcrd->params.eType != epullCONSTRAINT)
+            if (pcrd->params.eType != PullingAlgorithm::Constraint)
             {
                 continue;
             }
@@ -930,7 +939,7 @@ do_constraint(struct pull_t* pull, t_pbc* pbc, rvec* x, rvec* v, gmx_bool bMaste
 
             switch (pcrd->params.eGeom)
             {
-                case epullgDIST:
+                case PullGroupGeometry::Distance:
                     if (pcrd->value_ref <= 0)
                     {
                         gmx_fatal(
@@ -969,9 +978,9 @@ do_constraint(struct pull_t* pull, t_pbc* pbc, rvec* x, rvec* v, gmx_bool bMaste
                     dsvmul(lambda * rm * pgrp0->invtm, r_ij[c], dr0);
                     dr_tot[c] += -lambda * dnorm(r_ij[c]);
                     break;
-                case epullgDIR:
-                case epullgDIRPBC:
-                case epullgCYL:
+                case PullGroupGeometry::Direction:
+                case PullGroupGeometry::DirectionPBC:
+                case PullGroupGeometry::Cylinder:
                     /* A 1-dimensional constraint along a vector */
                     a = 0;
                     for (m = 0; m < DIM; m++)
@@ -1041,7 +1050,7 @@ do_constraint(struct pull_t* pull, t_pbc* pbc, rvec* x, rvec* v, gmx_bool bMaste
         /* Check if all constraints are fullfilled now */
         for (pull_coord_work_t& coord : pull->coord)
         {
-            if (coord.params.eType != epullCONSTRAINT)
+            if (coord.params.eType != PullingAlgorithm::Constraint)
             {
                 continue;
             }
@@ -1051,12 +1060,12 @@ do_constraint(struct pull_t* pull, t_pbc* pbc, rvec* x, rvec* v, gmx_bool bMaste
 
             switch (coord.params.eGeom)
             {
-                case epullgDIST:
+                case PullGroupGeometry::Distance:
                     bConverged = fabs(dnorm(unc_ij) - coord.value_ref) < pull->params.constr_tol;
                     break;
-                case epullgDIR:
-                case epullgDIRPBC:
-                case epullgCYL:
+                case PullGroupGeometry::Direction:
+                case PullGroupGeometry::DirectionPBC:
+                case PullGroupGeometry::Cylinder:
                     for (m = 0; m < DIM; m++)
                     {
                         vec[m] = coord.spatialData.vec[m];
@@ -1065,6 +1074,11 @@ do_constraint(struct pull_t* pull, t_pbc* pbc, rvec* x, rvec* v, gmx_bool bMaste
                     dsvmul(inpr, vec, unc_ij);
                     bConverged = fabs(diprod(unc_ij, vec) - coord.value_ref) < pull->params.constr_tol;
                     break;
+                default:
+                    GMX_ASSERT(false,
+                               gmx::formatString("Geometry %s not handled here",
+                                                 enumValueToString(coord.params.eGeom))
+                                       .c_str());
             }
 
             if (!bConverged)
@@ -1149,7 +1163,7 @@ do_constraint(struct pull_t* pull, t_pbc* pbc, rvec* x, rvec* v, gmx_bool bMaste
 
         pcrd = &pull->coord[c];
 
-        if (pcrd->params.eType != epullCONSTRAINT)
+        if (pcrd->params.eType != PullingAlgorithm::Constraint)
         {
             continue;
         }
@@ -1161,7 +1175,7 @@ do_constraint(struct pull_t* pull, t_pbc* pbc, rvec* x, rvec* v, gmx_bool bMaste
                    * dt * dt);
         pcrd->scalarForce += force;
 
-        if (vir != nullptr && pcrd->params.eGeom != epullgDIRPBC && bMaster)
+        if (vir != nullptr && pcrd->params.eGeom != PullGroupGeometry::DirectionPBC && bMaster)
         {
             double f_invr;
 
@@ -1199,7 +1213,7 @@ static void add_virial_coord_dr(tensor vir, const dvec dr, const dvec f)
 /* Adds the pull contribution to the virial */
 static void add_virial_coord(tensor vir, const pull_coord_work_t& pcrd, const PullCoordVectorForces& forces)
 {
-    if (vir != nullptr && pcrd.params.eGeom != epullgDIRPBC)
+    if (vir != nullptr && pcrd.params.eGeom != PullGroupGeometry::DirectionPBC)
     {
         /* Add the pull contribution for each distance vector to the virial. */
         add_virial_coord_dr(vir, pcrd.spatialData.dr01, forces.force01);
@@ -1227,15 +1241,15 @@ static void calc_pull_coord_scalar_force_and_potential(pull_coord_work_t* pcrd,
 
     switch (pcrd->params.eType)
     {
-        case epullUMBRELLA:
-        case epullFLATBOTTOM:
-        case epullFLATBOTTOMHIGH:
+        case PullingAlgorithm::Umbrella:
+        case PullingAlgorithm::FlatBottom:
+        case PullingAlgorithm::FlatBottomHigh:
             /* The only difference between an umbrella and a flat-bottom
              * potential is that a flat-bottom is zero above or below
                the reference value.
              */
-            if ((pcrd->params.eType == epullFLATBOTTOM && dev < 0)
-                || (pcrd->params.eType == epullFLATBOTTOMHIGH && dev > 0))
+            if ((pcrd->params.eType == PullingAlgorithm::FlatBottom && dev < 0)
+                || (pcrd->params.eType == PullingAlgorithm::FlatBottomHigh && dev > 0))
             {
                 dev = 0;
             }
@@ -1244,12 +1258,12 @@ static void calc_pull_coord_scalar_force_and_potential(pull_coord_work_t* pcrd,
             *V += 0.5 * k * gmx::square(dev);
             *dVdl += 0.5 * dkdl * gmx::square(dev);
             break;
-        case epullCONST_F:
+        case PullingAlgorithm::ConstantForce:
             pcrd->scalarForce = -k;
             *V += k * pcrd->spatialData.value;
             *dVdl += dkdl * pcrd->spatialData.value;
             break;
-        case epullEXTERNAL:
+        case PullingAlgorithm::External:
             gmx_incons(
                     "the scalar pull force should not be calculated internally for pull type "
                     "external");
@@ -1265,7 +1279,7 @@ static PullCoordVectorForces calculateVectorForces(const pull_coord_work_t& pcrd
     /* The geometry of the coordinate determines how the scalar force relates to the force on each group */
     PullCoordVectorForces forces;
 
-    if (params.eGeom == epullgDIST)
+    if (params.eGeom == PullGroupGeometry::Distance)
     {
         double invdr01 = spatialData.value > 0 ? 1. / spatialData.value : 0.;
         for (int m = 0; m < DIM; m++)
@@ -1273,7 +1287,7 @@ static PullCoordVectorForces calculateVectorForces(const pull_coord_work_t& pcrd
             forces.force01[m] = pcrd.scalarForce * spatialData.dr01[m] * invdr01;
         }
     }
-    else if (params.eGeom == epullgANGLE)
+    else if (params.eGeom == PullGroupGeometry::Angle)
     {
 
         double cos_theta, cos_theta2;
@@ -1317,7 +1331,7 @@ static PullCoordVectorForces calculateVectorForces(const pull_coord_work_t& pcrd
             clear_dvec(forces.force23);
         }
     }
-    else if (params.eGeom == epullgANGLEAXIS)
+    else if (params.eGeom == PullGroupGeometry::AngleAxis)
     {
         double cos_theta, cos_theta2;
 
@@ -1348,7 +1362,7 @@ static PullCoordVectorForces calculateVectorForces(const pull_coord_work_t& pcrd
             clear_dvec(forces.force01);
         }
     }
-    else if (params.eGeom == epullgDIHEDRAL)
+    else if (params.eGeom == PullGroupGeometry::Dihedral)
     {
         double m2, n2, tol, sqrdist_32;
         dvec   dr32;
@@ -1436,7 +1450,7 @@ void register_external_pull_potential(struct pull_t* pull, int coord_index, cons
 
     pull_coord_work_t* pcrd = &pull->coord[coord_index];
 
-    if (pcrd->params.eType != epullEXTERNAL)
+    if (pcrd->params.eType != PullingAlgorithm::External)
     {
         gmx_fatal(
                 FARGS,
@@ -1444,8 +1458,8 @@ void register_external_pull_potential(struct pull_t* pull, int coord_index, cons
                 "which of type '%s', whereas external potentials are only supported with type '%s'",
                 provider,
                 coord_index + 1,
-                epull_names[pcrd->params.eType],
-                epull_names[epullEXTERNAL]);
+                enumValueToString(pcrd->params.eType),
+                enumValueToString(PullingAlgorithm::External));
     }
 
     GMX_RELEASE_ASSERT(!pcrd->params.externalPotentialProvider.empty(),
@@ -1491,7 +1505,7 @@ static void check_external_potential_registration(const struct pull_t* pull)
         size_t c;
         for (c = 0; c < pull->coord.size(); c++)
         {
-            if (pull->coord[c].params.eType == epullEXTERNAL
+            if (pull->coord[c].params.eType == PullingAlgorithm::External
                 && !pull->coord[c].bExternalPotentialProviderHasBeenRegistered)
             {
                 break;
@@ -1533,7 +1547,7 @@ void apply_external_pull_coord_force(struct pull_t*        pull,
         pcrd = &pull->coord[coord_index];
 
         GMX_RELEASE_ASSERT(
-                pcrd->params.eType == epullEXTERNAL,
+                pcrd->params.eType == PullingAlgorithm::External,
                 "The pull force can only be set externally on pull coordinates of external type");
 
         GMX_ASSERT(pcrd->bExternalPotentialProviderHasBeenRegistered,
@@ -1574,7 +1588,7 @@ static PullCoordVectorForces do_pull_pot_coord(struct pull_t* pull,
 {
     pull_coord_work_t& pcrd = pull->coord[coord_ind];
 
-    assert(pcrd.params.eType != epullCONSTRAINT);
+    assert(pcrd.params.eType != PullingAlgorithm::Constraint);
 
     double dev = get_pull_coord_deviation(pull, coord_ind, pbc, t);
 
@@ -1623,7 +1637,8 @@ real pull_potential(struct pull_t*        pull,
 
             /* For external potential the force is assumed to be given by an external module by a
                call to apply_pull_coord_external_force */
-            if (pcrd->params.eType == epullCONSTRAINT || pcrd->params.eType == epullEXTERNAL)
+            if (pcrd->params.eType == PullingAlgorithm::Constraint
+                || pcrd->params.eType == PullingAlgorithm::External)
             {
                 continue;
             }
@@ -1821,8 +1836,8 @@ static void init_pull_group_index(FILE*              fplog,
      * But we still want to have the correct mass-weighted COMs.
      * So we store the real masses in the weights.
      */
-    const bool setWeights =
-            (!pg->params.weight.empty() || EI_ENERGY_MINIMIZATION(ir->eI) || ir->eI == eiBD);
+    const bool setWeights = (!pg->params.weight.empty() || EI_ENERGY_MINIMIZATION(ir->eI)
+                             || ir->eI == IntegrationAlgorithm::BD);
 
     /* In parallel, store we need to extract localWeights from weights at DD time */
     std::vector<real>& weights = ((cr && PAR(cr)) ? pg->globalWeights : pg->localWeights);
@@ -1851,7 +1866,7 @@ static void init_pull_group_index(FILE*              fplog,
         }
         const t_atom& atom = mtopGetAtomParameters(mtop, ii, &molb);
         real          m;
-        if (ir->efep == efepNO)
+        if (ir->efep == FreeEnergyPerturbationType::No)
         {
             m = atom.m;
         }
@@ -1874,7 +1889,7 @@ static void init_pull_group_index(FILE*              fplog,
             w *= m;
             m = 1;
         }
-        else if (ir->eI == eiBD)
+        else if (ir->eI == IntegrationAlgorithm::BD)
         {
             real mbd;
             if (ir->bd_fric != 0.0F)
@@ -1926,7 +1941,8 @@ static void init_pull_group_index(FILE*              fplog,
     if (fplog)
     {
         fprintf(fplog, "Pull group %d: %5zu atoms, mass %9.3f", g, pg->params.ind.size(), tmass);
-        if (!pg->params.weight.empty() || EI_ENERGY_MINIMIZATION(ir->eI) || ir->eI == eiBD)
+        if (!pg->params.weight.empty() || EI_ENERGY_MINIMIZATION(ir->eI)
+            || ir->eI == IntegrationAlgorithm::BD)
         {
             fprintf(fplog, ", weighted mass %9.3f", wmass * wmass / wwmass);
         }
@@ -2020,14 +2036,14 @@ struct pull_t* init_pull(FILE*                     fplog,
 
         switch (pcrd->params.eGeom)
         {
-            case epullgDIST:
-            case epullgDIRRELATIVE: /* Direction vector is determined at each step */
-            case epullgANGLE:
-            case epullgDIHEDRAL: break;
-            case epullgDIR:
-            case epullgDIRPBC:
-            case epullgCYL:
-            case epullgANGLEAXIS:
+            case PullGroupGeometry::Distance:
+            case PullGroupGeometry::DirectionRelative: /* Direction vector is determined at each step */
+            case PullGroupGeometry::Angle:
+            case PullGroupGeometry::Dihedral: break;
+            case PullGroupGeometry::Direction:
+            case PullGroupGeometry::DirectionPBC:
+            case PullGroupGeometry::Cylinder:
+            case PullGroupGeometry::AngleAxis:
                 copy_rvec_to_dvec(pull_params->coord[c].vec, pcrd->spatialData.vec);
                 break;
             default:
@@ -2042,27 +2058,29 @@ struct pull_t* init_pull(FILE*                     fplog,
                  */
                 gmx_fatal(FARGS,
                           "Pull geometry not supported for pull coordinate %d. The geometry enum "
-                          "%d in the input is larger than that supported by the code (up to %d). "
+                          "%s in the input is larger than that supported by the code (up to %d). "
                           "You are probably reading a tpr file generated with a newer version of "
-                          "Gromacs with an binary from an older version of Gromacs.",
+                          "GROMACS with an binary from an older version of Gromacs.",
                           c + 1,
-                          pcrd->params.eGeom,
-                          epullgNR - 1);
+                          enumValueToString(pcrd->params.eGeom),
+                          static_cast<int>(PullGroupGeometry::Count) - 1);
         }
 
-        if (pcrd->params.eType == epullCONSTRAINT)
+        if (pcrd->params.eType == PullingAlgorithm::Constraint)
         {
             /* Check restrictions of the constraint pull code */
-            if (pcrd->params.eGeom == epullgCYL || pcrd->params.eGeom == epullgDIRRELATIVE
-                || pcrd->params.eGeom == epullgANGLE || pcrd->params.eGeom == epullgDIHEDRAL
-                || pcrd->params.eGeom == epullgANGLEAXIS)
+            if (pcrd->params.eGeom == PullGroupGeometry::Cylinder
+                || pcrd->params.eGeom == PullGroupGeometry::DirectionRelative
+                || pcrd->params.eGeom == PullGroupGeometry::Angle
+                || pcrd->params.eGeom == PullGroupGeometry::Dihedral
+                || pcrd->params.eGeom == PullGroupGeometry::AngleAxis)
             {
                 gmx_fatal(FARGS,
                           "Pulling of type %s can not be combined with geometry %s. Consider using "
                           "pull type %s.",
-                          epull_names[pcrd->params.eType],
-                          epullg_names[pcrd->params.eGeom],
-                          epull_names[epullUMBRELLA]);
+                          enumValueToString(pcrd->params.eType),
+                          enumValueToString(pcrd->params.eGeom),
+                          enumValueToString(PullingAlgorithm::Umbrella));
             }
 
             GMX_RELEASE_ASSERT(
@@ -2076,12 +2094,13 @@ struct pull_t* init_pull(FILE*                     fplog,
             pull->bPotential = TRUE;
         }
 
-        if (pcrd->params.eGeom == epullgCYL)
+        if (pcrd->params.eGeom == PullGroupGeometry::Cylinder)
         {
             pull->bCylinder = TRUE;
         }
-        else if (pcrd->params.eGeom == epullgANGLE || pcrd->params.eGeom == epullgDIHEDRAL
-                 || pcrd->params.eGeom == epullgANGLEAXIS)
+        else if (pcrd->params.eGeom == PullGroupGeometry::Angle
+                 || pcrd->params.eGeom == PullGroupGeometry::Dihedral
+                 || pcrd->params.eGeom == PullGroupGeometry::AngleAxis)
         {
             pull->bAngle = TRUE;
         }
@@ -2093,7 +2112,7 @@ struct pull_t* init_pull(FILE*                     fplog,
         for (int i = 0; i < pcrd->params.ngroup; i++)
         {
             int groupIndex = pcrd->params.group[i];
-            if (groupIndex > 0 && !(pcrd->params.eGeom == epullgCYL && i == 0))
+            if (groupIndex > 0 && !(pcrd->params.eGeom == PullGroupGeometry::Cylinder && i == 0))
             {
                 pull->group[groupIndex].needToCalcCom = true;
             }
@@ -2103,7 +2122,7 @@ struct pull_t* init_pull(FILE*                     fplog,
         if (pcrd->params.rate == 0)
         {
             /* Initialize the constant reference value */
-            if (pcrd->params.eType != epullEXTERNAL)
+            if (pcrd->params.eType != PullingAlgorithm::External)
             {
                 low_set_pull_coord_reference_value(
                         pcrd, c, pcrd->params.init * pull_conversion_factor_userinput2internal(&pcrd->params));
@@ -2122,7 +2141,7 @@ struct pull_t* init_pull(FILE*                     fplog,
             }
         }
 
-        if (pcrd->params.eType == epullEXTERNAL)
+        if (pcrd->params.eType == PullingAlgorithm::External)
         {
             GMX_RELEASE_ASSERT(
                     pcrd->params.rate == 0,
@@ -2245,7 +2264,7 @@ struct pull_t* init_pull(FILE*                     fplog,
                         {
                             pulldim[m] = 1;
 
-                            if (coord.params.eType == epullCONSTRAINT)
+                            if (coord.params.eType == PullingAlgorithm::Constraint)
                             {
                                 bConstraint    = TRUE;
                                 pulldim_con[m] = 1;
@@ -2303,7 +2322,7 @@ struct pull_t* init_pull(FILE*                     fplog,
     {
         for (const pull_coord_work_t& coord : pull->coord)
         {
-            if (coord.params.eGeom == epullgCYL)
+            if (coord.params.eGeom == PullGroupGeometry::Cylinder)
             {
                 if (pull->group[coord.params.group[0]].params.ind.empty())
                 {
@@ -2447,7 +2466,7 @@ bool pull_have_constraint(const pull_params_t& pullParameters)
 {
     for (int c = 0; c < pullParameters.ncoord; c++)
     {
-        if (pullParameters.coord[c].eType == epullCONSTRAINT)
+        if (pullParameters.coord[c].eType == PullingAlgorithm::Constraint)
         {
             return true;
         }
index 40e4910c9b454715b3b6e3eb228e87bf64c8b83b..c255c8d1904cac24aa141ce8c59f08f81faebcd1 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) 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.
@@ -345,12 +345,16 @@ gmx_enfrot* EnforcedRotation::getLegacyEnfrot()
 #endif
 
 /* Shortcuts for often used queries */
-#define ISFLEX(rg)                                                                            \
-    (((rg)->eType == erotgFLEX) || ((rg)->eType == erotgFLEXT) || ((rg)->eType == erotgFLEX2) \
-     || ((rg)->eType == erotgFLEX2T))
-#define ISCOLL(rg)                                                                            \
-    (((rg)->eType == erotgFLEX) || ((rg)->eType == erotgFLEXT) || ((rg)->eType == erotgFLEX2) \
-     || ((rg)->eType == erotgFLEX2T) || ((rg)->eType == erotgRMPF) || ((rg)->eType == erotgRM2PF))
+#define ISFLEX(rg)                                                                                         \
+    (((rg)->eType == EnforcedRotationGroupType::Flex) || ((rg)->eType == EnforcedRotationGroupType::Flext) \
+     || ((rg)->eType == EnforcedRotationGroupType::Flex2)                                                  \
+     || ((rg)->eType == EnforcedRotationGroupType::Flex2t))
+#define ISCOLL(rg)                                                                                         \
+    (((rg)->eType == EnforcedRotationGroupType::Flex) || ((rg)->eType == EnforcedRotationGroupType::Flext) \
+     || ((rg)->eType == EnforcedRotationGroupType::Flex2)                                                  \
+     || ((rg)->eType == EnforcedRotationGroupType::Flex2t)                                                 \
+     || ((rg)->eType == EnforcedRotationGroupType::Rmpf)                                                   \
+     || ((rg)->eType == EnforcedRotationGroupType::Rm2pf))
 
 
 /* Does any of the rotation groups use slab decomposition? */
@@ -374,7 +378,7 @@ static gmx_bool HavePotFitGroups(const t_rot* rot)
 {
     for (int g = 0; g < rot->ngrp; g++)
     {
-        if (erotgFitPOT == rot->grp[g].eFittype)
+        if (RotationGroupFitting::Pot == rot->grp[g].eFittype)
         {
             return TRUE;
         }
@@ -440,7 +444,7 @@ static real get_fitangle(const gmx_enfrotgrp* erg)
 /* Reduce potential angle fit data for this group at this time step? */
 static inline gmx_bool bPotAngle(const gmx_enfrot* er, const t_rotgrp* rotg, int64_t step)
 {
-    return ((erotgFitPOT == rotg->eFittype)
+    return ((RotationGroupFitting::Pot == rotg->eFittype)
             && (do_per_step(step, er->nstsout) || do_per_step(step, er->nstrout)));
 }
 
@@ -543,7 +547,7 @@ static void reduce_output(const t_commrec* cr, gmx_enfrot* er, real t, int64_t s
             /* Output to main rotation output file: */
             if (do_per_step(step, er->nstrout))
             {
-                if (erotgFitPOT == rotg->eFittype)
+                if (RotationGroupFitting::Pot == rotg->eFittype)
                 {
                     fitangle = get_fitangle(erg);
                 }
@@ -582,7 +586,7 @@ static void reduce_output(const t_commrec* cr, gmx_enfrot* er, real t, int64_t s
                 }
 
                 /* Output to angles log file: */
-                if (erotgFitPOT == rotg->eFittype)
+                if (RotationGroupFitting::Pot == rotg->eFittype)
                 {
                     fprintf(er->out_angles, "%12.3e%6d%12.4f", t, erg->groupIndex, erg->degangle);
                     /* Output energies at a set of angles around the reference angle */
@@ -901,7 +905,7 @@ static FILE* open_slab_out(const char* fn, gmx_enfrot* er)
                 fprintf(fp,
                         "# Rotation group %d (%s), slab distance %f nm, %s.\n",
                         erg->groupIndex,
-                        erotg_names[erg->rotg->eType],
+                        enumValueToString(erg->rotg->eType),
                         erg->rotg->slab_dist,
                         erg->rotg->bMassW ? "centers of mass" : "geometrical centers");
             }
@@ -993,8 +997,8 @@ static FILE* open_rot_out(const char* fn, const gmx_output_env_t* oenv, gmx_enfr
             bFlex                     = ISFLEX(rotg);
 
             fprintf(fp, "#\n");
-            fprintf(fp, "# ROTATION GROUP %d, potential type '%s':\n", g, erotg_names[rotg->eType]);
-            fprintf(fp, "# rot-massw%d          %s\n", g, yesno_names[rotg->bMassW]);
+            fprintf(fp, "# ROTATION GROUP %d, potential type '%s':\n", g, enumValueToString(rotg->eType));
+            fprintf(fp, "# rot-massw%d          %s\n", g, booleanValueToString(rotg->bMassW));
             fprintf(fp,
                     "# rot-vec%d            %12.5e %12.5e %12.5e\n",
                     g,
@@ -1003,8 +1007,9 @@ static FILE* open_rot_out(const char* fn, const gmx_output_env_t* oenv, gmx_enfr
                     erg->vec[ZZ]);
             fprintf(fp, "# rot-rate%d           %12.5e degrees/ps\n", g, rotg->rate);
             fprintf(fp, "# rot-k%d              %12.5e kJ/(mol*nm^2)\n", g, rotg->k);
-            if (rotg->eType == erotgISO || rotg->eType == erotgPM || rotg->eType == erotgRM
-                || rotg->eType == erotgRM2)
+            if (rotg->eType == EnforcedRotationGroupType::Iso || rotg->eType == EnforcedRotationGroupType::Pm
+                || rotg->eType == EnforcedRotationGroupType::Rm
+                || rotg->eType == EnforcedRotationGroupType::Rm2)
             {
                 fprintf(fp,
                         "# rot-pivot%d          %12.5e %12.5e %12.5e  nm\n",
@@ -1021,8 +1026,12 @@ static FILE* open_rot_out(const char* fn, const gmx_output_env_t* oenv, gmx_enfr
             }
 
             /* Output the centers of the rotation groups for the pivot-free potentials */
-            if ((rotg->eType == erotgISOPF) || (rotg->eType == erotgPMPF) || (rotg->eType == erotgRMPF)
-                || (rotg->eType == erotgRM2PF || (rotg->eType == erotgFLEXT) || (rotg->eType == erotgFLEX2T)))
+            if ((rotg->eType == EnforcedRotationGroupType::Isopf)
+                || (rotg->eType == EnforcedRotationGroupType::Pmpf)
+                || (rotg->eType == EnforcedRotationGroupType::Rmpf)
+                || (rotg->eType == EnforcedRotationGroupType::Rm2pf
+                    || (rotg->eType == EnforcedRotationGroupType::Flext)
+                    || (rotg->eType == EnforcedRotationGroupType::Flex2t)))
             {
                 fprintf(fp,
                         "# ref. grp. %d center  %12.5e %12.5e %12.5e\n",
@@ -1039,11 +1048,13 @@ static FILE* open_rot_out(const char* fn, const gmx_output_env_t* oenv, gmx_enfr
                         erg->xc_center[ZZ]);
             }
 
-            if ((rotg->eType == erotgRM2) || (rotg->eType == erotgFLEX2) || (rotg->eType == erotgFLEX2T))
+            if ((rotg->eType == EnforcedRotationGroupType::Rm2)
+                || (rotg->eType == EnforcedRotationGroupType::Flex2)
+                || (rotg->eType == EnforcedRotationGroupType::Flex2t))
             {
                 fprintf(fp, "# rot-eps%d            %12.5e nm^2\n", g, rotg->eps);
             }
-            if (erotgFitPOT == rotg->eFittype)
+            if (RotationGroupFitting::Pot == rotg->eFittype)
             {
                 fprintf(fp, "#\n");
                 fprintf(fp,
@@ -1090,7 +1101,7 @@ static FILE* open_rot_out(const char* fn, const gmx_output_env_t* oenv, gmx_enfr
 
             /* For flexible axis rotation we use RMSD fitting to determine the
              * actual angle of the rotation group */
-            if (bFlex || erotgFitPOT == rotg->eFittype)
+            if (bFlex || RotationGroupFitting::Pot == rotg->eFittype)
             {
                 sprintf(buf, "theta_fit%d", g);
             }
@@ -1157,7 +1168,7 @@ static FILE* open_angles_out(const char* fn, gmx_enfrot* er)
 
             /* Output for this group happens only if potential type is flexible or
              * if fit type is potential! */
-            if (ISFLEX(rotg) || (erotgFitPOT == rotg->eFittype))
+            if (ISFLEX(rotg) || (RotationGroupFitting::Pot == rotg->eFittype))
             {
                 if (ISFLEX(rotg))
                 {
@@ -1171,13 +1182,13 @@ static FILE* open_angles_out(const char* fn, gmx_enfrot* er)
                 fprintf(fp,
                         "#\n# ROTATION GROUP %d '%s',%s fit type '%s'.\n",
                         g,
-                        erotg_names[rotg->eType],
+                        enumValueToString(rotg->eType),
                         buf,
-                        erotg_fitnames[rotg->eFittype]);
+                        enumValueToString(rotg->eFittype));
 
                 /* Special type of fitting using the potential minimum. This is
                  * done for the whole group only, not for the individual slabs. */
-                if (erotgFitPOT == rotg->eFittype)
+                if (RotationGroupFitting::Pot == rotg->eFittype)
                 {
                     fprintf(fp,
                             "#    To obtain theta_fit%d, the potential is evaluated for %d angles "
@@ -1197,7 +1208,7 @@ static FILE* open_angles_out(const char* fn, gmx_enfrot* er)
                 print_aligned_short(fp, "grp");
                 print_aligned(fp, "theta_ref");
 
-                if (erotgFitPOT == rotg->eFittype)
+                if (RotationGroupFitting::Pot == rotg->eFittype)
                 {
                     /* Output the set of angles around the reference angle */
                     for (int i = 0; i < rotg->PotAngle_nstep; i++)
@@ -1251,7 +1262,7 @@ static FILE* open_torque_out(const char* fn, gmx_enfrot* er)
                 fprintf(fp,
                         "# Rotation group %d (%s), slab distance %f nm.\n",
                         g,
-                        erotg_names[rotg->eType],
+                        enumValueToString(rotg->eType),
                         rotg->slab_dist);
                 fprintf(fp,
                         "# The scalar tau is the torque (kJ/mol) in the direction of the rotation "
@@ -1616,7 +1627,7 @@ static real flex_fit_angle(gmx_enfrotgrp* erg)
     get_center(erg->xc, erg->mc_sorted, erg->rotg->nat, center);
 
     /* === Determine the optimal fit angle for the rotation group === */
-    if (erg->rotg->eFittype == erotgFitNORM)
+    if (erg->rotg->eFittype == RotationGroupFitting::Norm)
     {
         /* Normalize every position to it's reference length */
         for (int i = 0; i < erg->rotg->nat; i++)
@@ -1721,7 +1732,7 @@ static void flex_fit_angle_perslab(gmx_enfrotgrp* erg, double t, real degangle,
             /* Get the center of the slabs reference and current positions */
             get_center(sd->ref, sd->weight, sd->nat, ref_center);
             get_center(sd->x, sd->weight, sd->nat, act_center);
-            if (erg->rotg->eFittype == erotgFitNORM)
+            if (erg->rotg->eFittype == RotationGroupFitting::Norm)
             {
                 /* Normalize every position to it's reference length
                  * prior to performing the fit */
@@ -2039,7 +2050,7 @@ static real do_flex2_lowlevel(gmx_enfrotgrp* erg,
      * them again for every atom */
     flex2_precalc_inner_sum(erg);
 
-    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (erotgFitPOT == erg->rotg->eFittype);
+    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (RotationGroupFitting::Pot == erg->rotg->eFittype);
 
     /********************************************************/
     /* Main loop over all local atoms of the rotation group */
@@ -2298,7 +2309,7 @@ static real do_flex_lowlevel(gmx_enfrotgrp* erg,
      * them again for every atom */
     flex_precalc_inner_sum(erg);
 
-    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (erotgFitPOT == erg->rotg->eFittype);
+    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (RotationGroupFitting::Pot == erg->rotg->eFittype);
 
     /********************************************************/
     /* Main loop over all local atoms of the rotation group */
@@ -2631,11 +2642,13 @@ static void do_flexible(gmx_bool       bMaster,
     }
 
     /* Call the rotational forces kernel */
-    if (erg->rotg->eType == erotgFLEX || erg->rotg->eType == erotgFLEXT)
+    if (erg->rotg->eType == EnforcedRotationGroupType::Flex
+        || erg->rotg->eType == EnforcedRotationGroupType::Flext)
     {
         erg->V = do_flex_lowlevel(erg, sigma, x, bOutstepRot, bOutstepSlab, box);
     }
-    else if (erg->rotg->eType == erotgFLEX2 || erg->rotg->eType == erotgFLEX2T)
+    else if (erg->rotg->eType == EnforcedRotationGroupType::Flex2
+             || erg->rotg->eType == EnforcedRotationGroupType::Flex2t)
     {
         erg->V = do_flex2_lowlevel(erg, sigma, x, bOutstepRot, bOutstepSlab, box);
     }
@@ -2646,7 +2659,7 @@ static void do_flexible(gmx_bool       bMaster,
 
     /* Determine angle by RMSD fit to the reference - Let's hope this */
     /* only happens once in a while, since this is not parallelized! */
-    if (bMaster && (erotgFitPOT != erg->rotg->eFittype))
+    if (bMaster && (RotationGroupFitting::Pot != erg->rotg->eFittype))
     {
         if (bOutstepRot)
         {
@@ -2743,8 +2756,9 @@ static void do_fixed(gmx_enfrotgrp* erg,
 
     gmx_bool bProject;
 
-    bProject    = (erg->rotg->eType == erotgPM) || (erg->rotg->eType == erotgPMPF);
-    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (erotgFitPOT == erg->rotg->eFittype);
+    bProject = (erg->rotg->eType == EnforcedRotationGroupType::Pm)
+               || (erg->rotg->eType == EnforcedRotationGroupType::Pmpf);
+    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (RotationGroupFitting::Pot == erg->rotg->eFittype);
 
     N_M                                      = erg->rotg->nat * erg->invmass;
     const auto& collectiveRotationGroupIndex = erg->atomSet->collectiveIndex();
@@ -2846,7 +2860,7 @@ static void do_radial_motion(gmx_enfrotgrp* erg,
     real wj;  /* Mass-weighting of the positions */
     real N_M; /* N/M */
 
-    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (erotgFitPOT == erg->rotg->eFittype);
+    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (RotationGroupFitting::Pot == erg->rotg->eFittype);
 
     N_M                                      = erg->rotg->nat * erg->invmass;
     const auto& collectiveRotationGroupIndex = erg->atomSet->collectiveIndex();
@@ -2944,7 +2958,7 @@ static void do_radial_motion_pf(gmx_enfrotgrp* erg,
     real mj, wi, wj; /* Mass-weighting of the positions */
     real N_M;        /* N/M */
 
-    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (erotgFitPOT == erg->rotg->eFittype);
+    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (RotationGroupFitting::Pot == erg->rotg->eFittype);
 
     N_M = erg->rotg->nat * erg->invmass;
 
@@ -3146,8 +3160,8 @@ static void do_radial_motion2(gmx_enfrotgrp* erg,
     rvec     innersumvec;
     gmx_bool bCalcPotFit;
 
-    bPF         = erg->rotg->eType == erotgRM2PF;
-    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (erotgFitPOT == erg->rotg->eFittype);
+    bPF         = erg->rotg->eType == EnforcedRotationGroupType::Rm2pf;
+    bCalcPotFit = (bOutstepRot || bOutstepSlab) && (RotationGroupFitting::Pot == erg->rotg->eFittype);
 
     clear_rvec(yj0_yc0); /* Make the compiler happy */
 
@@ -3455,7 +3469,7 @@ static void init_rot_group(FILE*            fplog,
         snew(erg->xc_eshifts, erg->rotg->nat);
         snew(erg->xc_old, erg->rotg->nat);
 
-        if (erg->rotg->eFittype == erotgFitNORM)
+        if (erg->rotg->eFittype == RotationGroupFitting::Norm)
         {
             snew(erg->xc_ref_length, erg->rotg->nat); /* in case fit type NORM is chosen */
             snew(erg->xc_norm, erg->rotg->nat);
@@ -3472,7 +3486,7 @@ static void init_rot_group(FILE*            fplog,
 
     /* Make space for the calculation of the potential at other angles (used
      * for fitting only) */
-    if (erotgFitPOT == erg->rotg->eFittype)
+    if (RotationGroupFitting::Pot == erg->rotg->eFittype)
     {
         snew(erg->PotAngleFit, 1);
         snew(erg->PotAngleFit->degangle, erg->rotg->PotAngle_nstep);
@@ -3520,8 +3534,10 @@ static void init_rot_group(FILE*            fplog,
     erg->invmass = 1.0 / totalmass;
 
     /* Set xc_ref_center for any rotation potential */
-    if ((erg->rotg->eType == erotgISO) || (erg->rotg->eType == erotgPM)
-        || (erg->rotg->eType == erotgRM) || (erg->rotg->eType == erotgRM2))
+    if ((erg->rotg->eType == EnforcedRotationGroupType::Iso)
+        || (erg->rotg->eType == EnforcedRotationGroupType::Pm)
+        || (erg->rotg->eType == EnforcedRotationGroupType::Rm)
+        || (erg->rotg->eType == EnforcedRotationGroupType::Rm2))
     {
         /* Set the pivot point for the fixed, stationary-axis potentials. This
          * won't change during the simulation */
@@ -3588,7 +3604,8 @@ static void init_rot_group(FILE*            fplog,
 #endif
     }
 
-    if ((erg->rotg->eType != erotgFLEX) && (erg->rotg->eType != erotgFLEX2))
+    if ((erg->rotg->eType != EnforcedRotationGroupType::Flex)
+        && (erg->rotg->eType != EnforcedRotationGroupType::Flex2))
     {
         /* Put the reference positions into origin: */
         for (int i = 0; i < erg->rotg->nat; i++)
@@ -3619,7 +3636,7 @@ static void init_rot_group(FILE*            fplog,
         get_slab_centers(erg, erg->rotg->x_ref, erg->mc, -1, out_slabs, bOutputCenters, TRUE);
 
         /* Length of each x_rotref vector from center (needed if fit routine NORM is chosen): */
-        if (erg->rotg->eFittype == erotgFitNORM)
+        if (erg->rotg->eFittype == RotationGroupFitting::Norm)
         {
             for (int i = 0; i < erg->rotg->nat; i++)
             {
@@ -3650,7 +3667,7 @@ static int calc_mpi_bufsize(const gmx_enfrot* er)
         }
 
         /* Add space for the potentials at different angles: */
-        if (erotgFitPOT == erg->rotg->eFittype)
+        if (RotationGroupFitting::Pot == erg->rotg->eFittype)
         {
             count_group += erg->rotg->PotAngle_nstep;
         }
@@ -3745,7 +3762,11 @@ std::unique_ptr<gmx::EnforcedRotation> init_rot(FILE*                       fplo
 
         if (nullptr != fplog)
         {
-            fprintf(fplog, "%s group %d type '%s'\n", RotStr, groupIndex, erotg_names[erg->rotg->eType]);
+            fprintf(fplog,
+                    "%s group %d type '%s'\n",
+                    RotStr,
+                    groupIndex,
+                    enumValueToString(erg->rotg->eType));
         }
 
         if (erg->rotg->nat > 0)
@@ -3934,7 +3955,8 @@ void do_rotation(const t_commrec* cr, gmx_enfrot* er, const matrix box, rvec x[]
             choose_pbc_image(x, erg, box, 3);
 
             /* Get the center of the rotation group */
-            if ((rotg->eType == erotgISOPF) || (rotg->eType == erotgPMPF))
+            if ((rotg->eType == EnforcedRotationGroupType::Isopf)
+                || (rotg->eType == EnforcedRotationGroupType::Pmpf))
             {
                 get_center_comm(
                         cr, erg->x_loc_pbc, erg->m_loc, erg->atomSet->numAtomsLocal(), rotg->nat, erg->xc_center);
@@ -3965,7 +3987,7 @@ void do_rotation(const t_commrec* cr, gmx_enfrot* er, const matrix box, rvec x[]
         }
 
         /* Calculate angles and rotation matrices for potential fitting: */
-        if ((outstep_rot || outstep_slab) && (erotgFitPOT == rotg->eFittype))
+        if ((outstep_rot || outstep_slab) && (RotationGroupFitting::Pot == rotg->eFittype))
         {
             fit = erg->PotAngleFit;
             for (int i = 0; i < rotg->PotAngle_nstep; i++)
@@ -3985,16 +4007,22 @@ void do_rotation(const t_commrec* cr, gmx_enfrot* er, const matrix box, rvec x[]
 
         switch (rotg->eType)
         {
-            case erotgISO:
-            case erotgISOPF:
-            case erotgPM:
-            case erotgPMPF: do_fixed(erg, outstep_rot, outstep_slab); break;
-            case erotgRM: do_radial_motion(erg, outstep_rot, outstep_slab); break;
-            case erotgRMPF: do_radial_motion_pf(erg, x, box, outstep_rot, outstep_slab); break;
-            case erotgRM2:
-            case erotgRM2PF: do_radial_motion2(erg, x, box, outstep_rot, outstep_slab); break;
-            case erotgFLEXT:
-            case erotgFLEX2T:
+            case EnforcedRotationGroupType::Iso:
+            case EnforcedRotationGroupType::Isopf:
+            case EnforcedRotationGroupType::Pm:
+            case EnforcedRotationGroupType::Pmpf: do_fixed(erg, outstep_rot, outstep_slab); break;
+            case EnforcedRotationGroupType::Rm:
+                do_radial_motion(erg, outstep_rot, outstep_slab);
+                break;
+            case EnforcedRotationGroupType::Rmpf:
+                do_radial_motion_pf(erg, x, box, outstep_rot, outstep_slab);
+                break;
+            case EnforcedRotationGroupType::Rm2:
+            case EnforcedRotationGroupType::Rm2pf:
+                do_radial_motion2(erg, x, box, outstep_rot, outstep_slab);
+                break;
+            case EnforcedRotationGroupType::Flext:
+            case EnforcedRotationGroupType::Flex2t:
                 /* Subtract the center of the rotation group from the collective positions array
                  * Also store the center in erg->xc_center since it needs to be subtracted
                  * in the low level routines from the local coordinates as well */
@@ -4003,8 +4031,8 @@ void do_rotation(const t_commrec* cr, gmx_enfrot* er, const matrix box, rvec x[]
                 translate_x(erg->xc, rotg->nat, transvec);
                 do_flexible(MASTER(cr), er, erg, x, box, t, outstep_rot, outstep_slab);
                 break;
-            case erotgFLEX:
-            case erotgFLEX2:
+            case EnforcedRotationGroupType::Flex:
+            case EnforcedRotationGroupType::Flex2:
                 /* Do NOT subtract the center of mass in the low level routines! */
                 clear_rvec(erg->xc_center);
                 do_flexible(MASTER(cr), er, erg, x, box, t, outstep_rot, outstep_slab);
index cf9b7b45b1df9a018dfe6f405846fcdb80efe7b4..ec15584183734e56c41747955a56d39e97b921ba 100644 (file)
@@ -191,7 +191,7 @@ make_cyl_refgrps(const t_commrec* cr, pull_t* pull, const real* masses, t_pbc* p
         clear_dvec(radf_fac0);
         clear_dvec(radf_fac1);
 
-        if (pcrd->params.eGeom == epullgCYL)
+        if (pcrd->params.eGeom == PullGroupGeometry::Cylinder)
         {
             /* pref will be the same group for all pull coordinates */
             const pull_group_work_t& pref  = pull->group[pcrd->params.group[0]];
@@ -309,7 +309,7 @@ make_cyl_refgrps(const t_commrec* cr, pull_t* pull, const real* masses, t_pbc* p
 
         pcrd = &pull->coord[c];
 
-        if (pcrd->params.eGeom == epullgCYL)
+        if (pcrd->params.eGeom == PullGroupGeometry::Cylinder)
         {
             pull_group_work_t*    pdyna       = &pull->dyna[c];
             pull_group_work_t*    pgrp        = &pull->group[pcrd->params.group[1]];
@@ -911,7 +911,8 @@ int pullCheckPbcWithinGroups(const pull_t& pull, const rvec* x, const t_pbc& pbc
         {
             for (int d = 0; d < DIM; d++)
             {
-                if (coordParams.dim[d] && !(coordParams.eGeom == epullgCYL && groupIndex == 0))
+                if (coordParams.dim[d]
+                    && !(coordParams.eGeom == PullGroupGeometry::Cylinder && groupIndex == 0))
                 {
                     dimUsed[coordParams.group[groupIndex]][d] = true;
                 }
@@ -963,7 +964,8 @@ bool pullCheckPbcWithinGroup(const pull_t&                  pull,
             {
                 for (int d = 0; d < DIM; d++)
                 {
-                    if (coordParams.dim[d] && !(coordParams.eGeom == epullgCYL && groupIndex == 0))
+                    if (coordParams.dim[d]
+                        && !(coordParams.eGeom == PullGroupGeometry::Cylinder && groupIndex == 0))
                     {
                         dimUsed[d] = true;
                     }
index d42ddc6580bd821696d47e43845c889b1136a97a..1cf9f3e93912a85d164ae5e1935031ea9fa953ce 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2016,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.
@@ -93,7 +93,7 @@ protected:
         {
             // Distance pulling in all 3 dimensions
             t_pull_coord params;
-            params.eGeom   = epullgDIST;
+            params.eGeom   = PullGroupGeometry::Distance;
             params.dim[XX] = 1;
             params.dim[YY] = 1;
             params.dim[ZZ] = 1;
@@ -112,7 +112,7 @@ protected:
         {
             // Distance pulling along Z
             t_pull_coord params;
-            params.eGeom   = epullgDIST;
+            params.eGeom   = PullGroupGeometry::Distance;
             params.dim[XX] = 0;
             params.dim[YY] = 0;
             params.dim[ZZ] = 1;
@@ -125,7 +125,7 @@ protected:
         {
             // Directional pulling along Z
             t_pull_coord params;
-            params.eGeom   = epullgDIR;
+            params.eGeom   = PullGroupGeometry::Direction;
             params.dim[XX] = 1;
             params.dim[YY] = 1;
             params.dim[ZZ] = 1;
@@ -139,7 +139,7 @@ protected:
         {
             // Directional pulling along X
             t_pull_coord params;
-            params.eGeom   = epullgDIR;
+            params.eGeom   = PullGroupGeometry::Direction;
             params.dim[XX] = 1;
             params.dim[YY] = 1;
             params.dim[ZZ] = 1;
index 0bf9ba8ea3f30bd4a22b1bb3a328dce60b49b55b..2880c81e338cfbbe662842599f9fef6b9817373b 100644 (file)
@@ -42,6 +42,7 @@
  */
 #include "gmxpre.h"
 
+#include "gromacs/utility/enumerationhelpers.h"
 #include "swapcoords.h"
 
 #include <cstdio>
@@ -83,7 +84,7 @@
 static const char* SwS      = { "SWAP:" }; /**< For output that comes from the swap module */
 static const char* SwSEmpty = { "     " }; /**< Placeholder for multi-line output */
 static const char* CompStr[eCompNR] = { "A", "B" }; /**< Compartment name */
-static const char* SwapStr[eSwapTypesNR + 1] = { "", "X-", "Y-", "Z-", nullptr }; /**< Name for the swap types. */
+static constexpr gmx::EnumerationArray<SwapType, const char*> SwapStr = { "", "X-", "Y-", "Z-" }; /**< Name for the swap types. */
 static const char* DimStr[DIM + 1] = { "X", "Y", "Z", nullptr }; /**< Name for the swap dimension. */
 
 /** Keep track of through which channel the ions have passed */
@@ -294,7 +295,7 @@ static void print_ionlist(t_swap* s, double time, const char comment[])
     // compartment and ion type
     for (int iComp = 0; iComp < eCompNR; iComp++)
     {
-        for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+        for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
         {
             t_compartment* comp = &s->group[ig].comp[iComp];
 
@@ -305,13 +306,13 @@ static void print_ionlist(t_swap* s, double time, const char comment[])
     // Output center of split groups
     fprintf(s->fpout,
             "%10g%10g",
-            s->group[eGrpSplit0].center[s->swapdim],
-            s->group[eGrpSplit1].center[s->swapdim]);
+            s->group[static_cast<int>(SwapGroupSplittingType::Split0)].center[s->swapdim],
+            s->group[static_cast<int>(SwapGroupSplittingType::Split1)].center[s->swapdim]);
 
     // Output ion flux for each channel and ion type
     for (int iChan = 0; iChan < eChanNR; iChan++)
     {
-        for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+        for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
         {
             t_swapgrp* g = &s->group[ig];
             fprintf(s->fpout, "%10d", g->fluxfromAtoB[iChan]);
@@ -496,8 +497,8 @@ static void get_compartment_boundaries(int c, t_swap* s, const matrix box, real*
         gmx_fatal(FARGS, "No compartment %c.", c + 'A');
     }
 
-    pos0 = s->group[eGrpSplit0].center[s->swapdim];
-    pos1 = s->group[eGrpSplit1].center[s->swapdim];
+    pos0 = s->group[static_cast<int>(SwapGroupSplittingType::Split0)].center[s->swapdim];
+    pos1 = s->group[static_cast<int>(SwapGroupSplittingType::Split1)].center[s->swapdim];
 
     if (pos0 < pos1)
     {
@@ -569,10 +570,20 @@ static void detect_flux_per_channel(t_swapgrp*          g,
     sd = s->swapdim;
 
     /* Check whether ion is inside any of the channels */
-    in_cyl0 = is_in_channel(
-            atomPosition, s->group[eGrpSplit0].center, sc->cyl0u, sc->cyl0l, cyl0_r2, s->pbc, sd);
-    in_cyl1 = is_in_channel(
-            atomPosition, s->group[eGrpSplit1].center, sc->cyl1u, sc->cyl1l, cyl1_r2, s->pbc, sd);
+    in_cyl0 = is_in_channel(atomPosition,
+                            s->group[static_cast<int>(SwapGroupSplittingType::Split0)].center,
+                            sc->cyl0u,
+                            sc->cyl0l,
+                            cyl0_r2,
+                            s->pbc,
+                            sd);
+    in_cyl1 = is_in_channel(atomPosition,
+                            s->group[static_cast<int>(SwapGroupSplittingType::Split1)].center,
+                            sc->cyl1u,
+                            sc->cyl1l,
+                            cyl1_r2,
+                            s->pbc,
+                            sd);
 
     if (in_cyl0 && in_cyl1)
     {
@@ -835,7 +846,7 @@ static void get_initial_ioncounts(const t_inputrec* ir,
     sc = ir->swap;
 
     /* Loop over the user-defined (ion) groups */
-    for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+    for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
     {
         g = &s->group[ig];
 
@@ -920,10 +931,10 @@ static void get_initial_ioncounts_from_cpt(const t_inputrec* ir,
             fprintf(stderr, "%s Copying values from checkpoint\n", SwS);
         }
 
-        for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+        for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
         {
             g  = &s->group[ig];
-            gs = &swapstate->ionType[ig - eSwapFixedGrpNR];
+            gs = &swapstate->ionType[ig - static_cast<int>(SwapGroupSplittingType::Count)];
 
             for (int ic = 0; ic < eCompNR; ic++)
             {
@@ -964,7 +975,7 @@ static void bc_initial_concentrations(t_commrec* cr, t_swapcoords* swap, t_swap*
     t_swapgrp* g;
 
 
-    for (ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+    for (ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
     {
         g = &s->group[ig];
 
@@ -1083,14 +1094,14 @@ static void print_ionlist_legend(const t_inputrec* ir, t_swap* s, const gmx_outp
     int          count = 0;
     char         buf[STRLEN];
 
-    int nIonTypes = ir->swap->ngrp - eSwapFixedGrpNR;
+    int nIonTypes = ir->swap->ngrp - static_cast<int>(SwapGroupSplittingType::Count);
     snew(legend, eCompNR * nIonTypes * 3 + 2 + eChanNR * nIonTypes + 1);
 
     // Number of molecules and difference to reference counts for each
     // compartment and ion type
     for (int ic = count = 0; ic < eCompNR; ic++)
     {
-        for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+        for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
         {
             t_swapGroup* g = &ir->swap->grp[ig];
             real         q = s->group[ig].q;
@@ -1116,19 +1127,19 @@ static void print_ionlist_legend(const t_inputrec* ir, t_swap* s, const gmx_outp
              STRLEN,
              "%scenter of %s of split group 0",
              SwapStr[ir->eSwapCoords],
-             (nullptr != s->group[eGrpSplit0].m) ? "mass" : "geometry");
+             (nullptr != s->group[static_cast<int>(SwapGroupSplittingType::Split0)].m) ? "mass" : "geometry");
     legend[count++] = gmx_strdup(buf);
     snprintf(buf,
              STRLEN,
              "%scenter of %s of split group 1",
              SwapStr[ir->eSwapCoords],
-             (nullptr != s->group[eGrpSplit1].m) ? "mass" : "geometry");
+             (nullptr != s->group[static_cast<int>(SwapGroupSplittingType::Split1)].m) ? "mass" : "geometry");
     legend[count++] = gmx_strdup(buf);
 
     // Ion flux for each channel and ion type
     for (int ic = 0; ic < eChanNR; ic++)
     {
-        for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+        for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
         {
             t_swapGroup* g = &ir->swap->grp[ig];
             snprintf(buf, STRLEN, "A->ch%d->B %s permeations", ic, g->molname);
@@ -1173,10 +1184,10 @@ static void detect_flux_per_channel_init(t_swap* s, swaphistory_t* swapstate, co
         return;
     }
 
-    for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+    for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
     {
         g  = &s->group[ig];
-        gs = &swapstate->ionType[ig - eSwapFixedGrpNR];
+        gs = &swapstate->ionType[ig - static_cast<int>(SwapGroupSplittingType::Count)];
 
         /******************************************************/
         /* Channel and domain history for the individual ions */
@@ -1221,10 +1232,10 @@ static void detect_flux_per_channel_init(t_swap* s, swaphistory_t* swapstate, co
 
 
     // Loop over ion types (and both channels)
-    for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+    for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
     {
         g  = &s->group[ig];
-        gs = &swapstate->ionType[ig - eSwapFixedGrpNR];
+        gs = &swapstate->ionType[ig - static_cast<int>(SwapGroupSplittingType::Count)];
 
         for (int ic = 0; ic < eChanNR; ic++)
         {
@@ -1245,10 +1256,10 @@ static void detect_flux_per_channel_init(t_swap* s, swaphistory_t* swapstate, co
 
     /* Set pointers for checkpoint writing */
     swapstate->fluxleak_p = &s->fluxleak;
-    for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+    for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
     {
         g  = &s->group[ig];
-        gs = &swapstate->ionType[ig - eSwapFixedGrpNR];
+        gs = &swapstate->ionType[ig - static_cast<int>(SwapGroupSplittingType::Count)];
 
         for (int ic = 0; ic < eChanNR; ic++)
         {
@@ -1312,12 +1323,12 @@ static void init_swapstate(swaphistory_t*    swapstate,
     if (swapstate->bFromCpt)
     {
         /* Copy the last whole positions of each channel from .cpt */
-        g = &(s->group[eGrpSplit0]);
+        g = &(s->group[static_cast<int>(SwapGroupSplittingType::Split0)]);
         for (size_t i = 0; i < g->atomset.numAtomsGlobal(); i++)
         {
             copy_rvec(swapstate->xc_old_whole[eChan0][i], g->xc_old[i]);
         }
-        g = &(s->group[eGrpSplit1]);
+        g = &(s->group[static_cast<int>(SwapGroupSplittingType::Split1)]);
         for (size_t i = 0; i < g->atomset.numAtomsGlobal(); i++)
         {
             copy_rvec(swapstate->xc_old_whole[eChan1][i], g->xc_old[i]);
@@ -1328,7 +1339,7 @@ static void init_swapstate(swaphistory_t*    swapstate,
         swapstate->eSwapCoords = ir->eSwapCoords;
 
         /* Set the number of ion types and allocate memory for checkpointing */
-        swapstate->nIonTypes = s->ngrp - eSwapFixedGrpNR;
+        swapstate->nIonTypes = s->ngrp - static_cast<int>(SwapGroupSplittingType::Count);
         snew(swapstate->ionType, swapstate->nIonTypes);
 
         /* Store the total number of ions of each type in the swapstateIons
@@ -1336,7 +1347,7 @@ static void init_swapstate(swaphistory_t*    swapstate,
         for (int ii = 0; ii < swapstate->nIonTypes; ii++)
         {
             swapstateIons_t* gs = &swapstate->ionType[ii];
-            gs->nMol            = sc->grp[ii + eSwapFixedGrpNR].nat;
+            gs->nMol            = sc->grp[ii + static_cast<int>(SwapGroupSplittingType::Count)].nat;
         }
 
         /* Extract the initial split group positions. */
@@ -1353,7 +1364,9 @@ static void init_swapstate(swaphistory_t*    swapstate,
 
         /* If this is the first run (i.e. no checkpoint present) we assume
          * that the starting positions give us the correct PBC representation */
-        for (int ig = eGrpSplit0; ig <= eGrpSplit1; ig++)
+        for (int ig = static_cast<int>(SwapGroupSplittingType::Split0);
+             ig <= static_cast<int>(SwapGroupSplittingType::Split1);
+             ig++)
         {
             g = &(s->group[ig]);
             for (size_t i = 0; i < g->atomset.numAtomsGlobal(); i++)
@@ -1364,14 +1377,16 @@ static void init_swapstate(swaphistory_t*    swapstate,
         sfree(x_pbc);
 
         /* Prepare swapstate arrays for later checkpoint writing */
-        swapstate->nat[eChan0] = s->group[eGrpSplit0].atomset.numAtomsGlobal();
-        swapstate->nat[eChan1] = s->group[eGrpSplit1].atomset.numAtomsGlobal();
+        swapstate->nat[eChan0] =
+                s->group[static_cast<int>(SwapGroupSplittingType::Split0)].atomset.numAtomsGlobal();
+        swapstate->nat[eChan1] =
+                s->group[static_cast<int>(SwapGroupSplittingType::Split1)].atomset.numAtomsGlobal();
     }
 
     /* For subsequent checkpoint writing, set the swapstate pointers to the xc_old
      * arrays that get updated at every swapping step */
-    swapstate->xc_old_whole_p[eChan0] = &s->group[eGrpSplit0].xc_old;
-    swapstate->xc_old_whole_p[eChan1] = &s->group[eGrpSplit1].xc_old;
+    swapstate->xc_old_whole_p[eChan0] = &s->group[static_cast<int>(SwapGroupSplittingType::Split0)].xc_old;
+    swapstate->xc_old_whole_p[eChan1] = &s->group[static_cast<int>(SwapGroupSplittingType::Split1)].xc_old;
 }
 
 /*! \brief Determine the total charge imbalance resulting from the swap groups */
@@ -1386,7 +1401,7 @@ static real getRequestedChargeImbalance(t_swap* s)
     //        s->deltaQ =  ( (-1) * s->comp[eCompA][eIonNEG].nat_req + s->comp[eCompA][eIonPOS].nat_req )
     //                   - ( (-1) * s->comp[eCompB][eIonNEG].nat_req + s->comp[eCompB][eIonPOS].nat_req );
 
-    for (ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+    for (ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
     {
         g = &s->group[ig];
 
@@ -1565,9 +1580,9 @@ t_swap* init_swapcoords(FILE*                       fplog,
 
     switch (ir->eSwapCoords)
     {
-        case eswapX: s->swapdim = XX; break;
-        case eswapY: s->swapdim = YY; break;
-        case eswapZ: s->swapdim = ZZ; break;
+        case SwapType::X: s->swapdim = XX; break;
+        case SwapType::Y: s->swapdim = YY; break;
+        case SwapType::Z: s->swapdim = ZZ; break;
         default: s->swapdim = -1; break;
     }
 
@@ -1602,7 +1617,8 @@ t_swap* init_swapcoords(FILE*                       fplog,
         /* For the split groups (the channels) we need some extra memory to
          * be able to make the molecules whole even if they span more than
          * half of the box size. */
-        if ((i == eGrpSplit0) || (i == eGrpSplit1))
+        if ((i == static_cast<int>(SwapGroupSplittingType::Split0))
+            || (i == static_cast<int>(SwapGroupSplittingType::Split1)))
         {
             snew(g->xc_shifts, g->atomset.numAtomsGlobal());
             snew(g->xc_eshifts, g->atomset.numAtomsGlobal());
@@ -1625,7 +1641,9 @@ t_swap* init_swapcoords(FILE*                       fplog,
      * channels. Now transfer that to all nodes */
     if (PAR(cr))
     {
-        for (int ig = eGrpSplit0; ig <= eGrpSplit1; ig++)
+        for (int ig = static_cast<int>(SwapGroupSplittingType::Split0);
+             ig <= static_cast<int>(SwapGroupSplittingType::Split1);
+             ig++)
         {
             g = &(s->group[ig]);
             gmx_bcast((g->atomset.numAtomsGlobal()) * sizeof((g->xc_old)[0]), g->xc_old, cr->mpi_comm_mygroup);
@@ -1634,7 +1652,7 @@ t_swap* init_swapcoords(FILE*                       fplog,
 
     /* Make sure that all molecules in the solvent and ion groups contain the
      * same number of atoms each */
-    for (int ig = eGrpSolvent; ig < s->ngrp; ig++)
+    for (int ig = static_cast<int>(SwapGroupSplittingType::Solvent); ig < s->ngrp; ig++)
     {
         real charge;
 
@@ -1658,7 +1676,9 @@ t_swap* init_swapcoords(FILE*                       fplog,
 
 
     /* Need mass-weighted center of split group? */
-    for (int j = eGrpSplit0; j <= eGrpSplit1; j++)
+    for (int j = static_cast<int>(SwapGroupSplittingType::Split0);
+         j <= static_cast<int>(SwapGroupSplittingType::Split1);
+         j++)
     {
         g = &(s->group[j]);
         if (sc->massw_split[j])
@@ -1693,14 +1713,17 @@ t_swap* init_swapcoords(FILE*                       fplog,
 
             for (int ig = 0; ig < s->ngrp; ig++)
             {
-                g = &(s->group[ig]);
+                auto enumValue = static_cast<SwapGroupSplittingType>(ig);
+                g              = &(s->group[ig]);
                 fprintf(s->fpout,
                         "# %s group '%s' contains %d atom%s",
-                        ig < eSwapFixedGrpNR ? eSwapFixedGrp_names[ig] : "Ion",
+                        ig < static_cast<int>(SwapGroupSplittingType::Count) ? enumValueToString(enumValue)
+                                                                             : "Ion",
                         g->molname,
                         static_cast<int>(g->atomset.numAtomsGlobal()),
                         (g->atomset.numAtomsGlobal() > 1) ? "s" : "");
-                if (!(eGrpSplit0 == ig || eGrpSplit1 == ig))
+                if (!(SwapGroupSplittingType::Split0 == enumValue
+                      || SwapGroupSplittingType::Split1 == enumValue))
                 {
                     fprintf(s->fpout,
                             " with %d atom%s in each molecule of charge %g",
@@ -1714,9 +1737,12 @@ t_swap* init_swapcoords(FILE*                       fplog,
             fprintf(s->fpout, "#\n# Initial positions of split groups:\n");
         }
 
-        for (int j = eGrpSplit0; j <= eGrpSplit1; j++)
+        for (int j = static_cast<int>(SwapGroupSplittingType::Split0);
+             j <= static_cast<int>(SwapGroupSplittingType::Split1);
+             j++)
         {
-            g = &(s->group[j]);
+            auto enumValue = static_cast<SwapGroupSplittingType>(j);
+            g              = &(s->group[j]);
             for (size_t i = 0; i < g->atomset.numAtomsGlobal(); i++)
             {
                 copy_rvec(globalState->x[sc->grp[j].ind[i]], g->xc[i]);
@@ -1728,7 +1754,7 @@ t_swap* init_swapcoords(FILE*                       fplog,
             {
                 fprintf(s->fpout,
                         "# %s group %s-center %5f nm\n",
-                        eSwapFixedGrp_names[j],
+                        enumValueToString(enumValue),
                         DimStr[s->swapdim],
                         g->center[s->swapdim]);
             }
@@ -1785,7 +1811,7 @@ t_swap* init_swapcoords(FILE*                       fplog,
     }
 
     /* Allocate memory to remember the past particle counts for time averaging */
-    for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+    for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
     {
         g = &(s->group[ig]);
         for (int ic = 0; ic < eCompNR; ic++)
@@ -1828,10 +1854,10 @@ t_swap* init_swapcoords(FILE*                       fplog,
         fprintf(stderr, "%s Setting pointers for checkpoint writing\n", SwS);
         for (int ic = 0; ic < eCompNR; ic++)
         {
-            for (int ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+            for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
             {
                 g  = &s->group[ig];
-                gs = &swapstate->ionType[ig - eSwapFixedGrpNR];
+                gs = &swapstate->ionType[ig - static_cast<int>(SwapGroupSplittingType::Count)];
 
                 gs->nMolReq_p[ic]    = &(g->comp[ic].nMolReq);
                 gs->nMolPast_p[ic]   = &(g->comp[ic].nMolPast[0]);
@@ -1858,7 +1884,7 @@ t_swap* init_swapcoords(FILE*                       fplog,
     }
 
     /* Update the time-averaged number of molecules for all groups and compartments */
-    for (int ig = eSwapFixedGrpNR; ig < sc->ngrp; ig++)
+    for (int ig = static_cast<int>(SwapGroupSplittingType::Count); ig < sc->ngrp; ig++)
     {
         g = &s->group[ig];
         for (int ic = 0; ic < eCompNR; ic++)
@@ -1902,7 +1928,7 @@ static gmx_bool need_swap(const t_swapcoords* sc, t_swap* s)
     int        ic, ig;
     t_swapgrp* g;
 
-    for (ig = eSwapFixedGrpNR; ig < sc->ngrp; ig++)
+    for (ig = static_cast<int>(SwapGroupSplittingType::Count); ig < sc->ngrp; ig++)
     {
         g = &s->group[ig];
 
@@ -2035,7 +2061,9 @@ gmx_bool do_swapcoords(t_commrec*        cr,
      * Here we also pass a shifts array to communicate_group_positions(), so that it can make
      * the molecules whole even in cases where they span more than half of the box in
      * any dimension */
-    for (ig = eGrpSplit0; ig <= eGrpSplit1; ig++)
+    for (ig = static_cast<int>(SwapGroupSplittingType::Split0);
+         ig <= static_cast<int>(SwapGroupSplittingType::Split1);
+         ig++)
     {
         g = &(s->group[ig]);
         communicate_group_positions(cr,
@@ -2057,7 +2085,7 @@ gmx_bool do_swapcoords(t_commrec*        cr,
     /* Assemble the positions of the ions (ig = 3, 4, ...). These molecules should
      * be small and we can always make them whole with a simple distance check.
      * Therefore we pass NULL as third argument. */
-    for (ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+    for (ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
     {
         g = &(s->group[ig]);
         communicate_group_positions(cr,
@@ -2096,7 +2124,7 @@ gmx_bool do_swapcoords(t_commrec*        cr,
     {
         /* Since we here know that we have to perform ion/water position exchanges,
          * we now assemble the solvent positions */
-        g = &(s->group[eGrpSolvent]);
+        g = &(s->group[static_cast<int>(SwapGroupSplittingType::Solvent)]);
         communicate_group_positions(cr,
                                     g->xc,
                                     nullptr,
@@ -2117,7 +2145,7 @@ gmx_bool do_swapcoords(t_commrec*        cr,
         g->comp[eCompA].nMolBefore = g->comp[eCompA].nMol;
         g->comp[eCompB].nMolBefore = g->comp[eCompB].nMol;
 
-        for (ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+        for (ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
         {
             g = &(s->group[ig]);
 
@@ -2132,8 +2160,8 @@ gmx_bool do_swapcoords(t_commrec*        cr,
         }
 
         /* Now actually perform the particle exchanges, one swap group after another */
-        gsol = &s->group[eGrpSolvent];
-        for (ig = eSwapFixedGrpNR; ig < s->ngrp; ig++)
+        gsol = &s->group[static_cast<int>(SwapGroupSplittingType::Solvent)];
+        for (ig = static_cast<int>(SwapGroupSplittingType::Count); ig < s->ngrp; ig++)
         {
             nswaps = 0;
             g      = &s->group[ig];
@@ -2206,7 +2234,7 @@ gmx_bool do_swapcoords(t_commrec*        cr,
 
         /* For the solvent and user-defined swap groups, each rank writes back its
          * (possibly modified) local positions to the official position array. */
-        for (ig = eGrpSolvent; ig < s->ngrp; ig++)
+        for (ig = static_cast<int>(SwapGroupSplittingType::Solvent); ig < s->ngrp; ig++)
         {
             g = &s->group[ig];
             apply_modified_positions(g, x);
index 3a8e1694833f7e391aa60c625ad4320910c3f0f4..1006e07f1c544054fb525eb3f84cbd9755394dce 100644 (file)
@@ -814,15 +814,18 @@ static void fill_table(t_tabledata* td, int tp, const interaction_const_t* ic, g
     }
     else
     {
-        bPotentialSwitch = ((tp == etabLJ6Switch) || (tp == etabLJ12Switch) || (tp == etabCOULSwitch)
-                            || (tp == etabEwaldSwitch) || (tp == etabEwaldUserSwitch)
-                            || (tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodPOTSWITCH))
-                            || (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodPOTSWITCH)));
-        bForceSwitch     = ((tp == etabLJ6Shift) || (tp == etabLJ12Shift) || (tp == etabShift)
-                        || (tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodFORCESWITCH))
-                        || (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodFORCESWITCH)));
-        bPotentialShift  = ((tprops[tp].bCoulomb && (ic->coulomb_modifier == eintmodPOTSHIFT))
-                           || (!tprops[tp].bCoulomb && (ic->vdw_modifier == eintmodPOTSHIFT)));
+        bPotentialSwitch =
+                ((tp == etabLJ6Switch) || (tp == etabLJ12Switch) || (tp == etabCOULSwitch)
+                 || (tp == etabEwaldSwitch) || (tp == etabEwaldUserSwitch)
+                 || (tprops[tp].bCoulomb && (ic->coulomb_modifier == InteractionModifiers::PotSwitch))
+                 || (!tprops[tp].bCoulomb && (ic->vdw_modifier == InteractionModifiers::PotSwitch)));
+        bForceSwitch =
+                ((tp == etabLJ6Shift) || (tp == etabLJ12Shift) || (tp == etabShift)
+                 || (tprops[tp].bCoulomb && (ic->coulomb_modifier == InteractionModifiers::ForceSwitch))
+                 || (!tprops[tp].bCoulomb && (ic->vdw_modifier == InteractionModifiers::ForceSwitch)));
+        bPotentialShift =
+                ((tprops[tp].bCoulomb && (ic->coulomb_modifier == InteractionModifiers::PotShift))
+                 || (!tprops[tp].bCoulomb && (ic->vdw_modifier == InteractionModifiers::PotShift)));
     }
 
     reppow = ic->reppow;
@@ -1131,21 +1134,23 @@ static void fill_table(t_tabledata* td, int tp, const interaction_const_t* ic, g
 
 static void set_table_type(int tabsel[], const interaction_const_t* ic, gmx_bool b14only)
 {
-    int eltype, vdwtype;
-
     /* Set the different table indices.
      * Coulomb first.
      */
 
+    CoulombInteractionType eltype;
+    VanDerWaalsType        vdwtype;
 
     if (b14only)
     {
         switch (ic->eeltype)
         {
-            case eelUSER:
-            case eelPMEUSER:
-            case eelPMEUSERSWITCH: eltype = eelUSER; break;
-            default: eltype = eelCUT;
+            case CoulombInteractionType::User:
+            case CoulombInteractionType::PmeUser:
+            case CoulombInteractionType::PmeUserSwitch:
+                eltype = CoulombInteractionType::User;
+                break;
+            default: eltype = CoulombInteractionType::Cut;
         }
     }
     else
@@ -1155,9 +1160,9 @@ static void set_table_type(int tabsel[], const interaction_const_t* ic, gmx_bool
 
     switch (eltype)
     {
-        case eelCUT: tabsel[etiCOUL] = etabCOUL; break;
-        case eelPOISSON: tabsel[etiCOUL] = etabShift; break;
-        case eelSHIFT:
+        case CoulombInteractionType::Cut: tabsel[etiCOUL] = etabCOUL; break;
+        case CoulombInteractionType::Poisson: tabsel[etiCOUL] = etabShift; break;
+        case CoulombInteractionType::Shift:
             if (ic->rcoulomb > ic->rcoulomb_switch)
             {
                 tabsel[etiCOUL] = etabShift;
@@ -1167,17 +1172,17 @@ static void set_table_type(int tabsel[], const interaction_const_t* ic, gmx_bool
                 tabsel[etiCOUL] = etabCOUL;
             }
             break;
-        case eelEWALD:
-        case eelPME:
-        case eelP3M_AD: tabsel[etiCOUL] = etabEwald; break;
-        case eelPMESWITCH: tabsel[etiCOUL] = etabEwaldSwitch; break;
-        case eelPMEUSER: tabsel[etiCOUL] = etabEwaldUser; break;
-        case eelPMEUSERSWITCH: tabsel[etiCOUL] = etabEwaldUserSwitch; break;
-        case eelRF:
-        case eelRF_ZERO: tabsel[etiCOUL] = etabRF_ZERO; break;
-        case eelSWITCH: tabsel[etiCOUL] = etabCOULSwitch; break;
-        case eelUSER: tabsel[etiCOUL] = etabUSER; break;
-        default: gmx_fatal(FARGS, "Invalid eeltype %d", eltype);
+        case CoulombInteractionType::Ewald:
+        case CoulombInteractionType::Pme:
+        case CoulombInteractionType::P3mAD: tabsel[etiCOUL] = etabEwald; break;
+        case CoulombInteractionType::PmeSwitch: tabsel[etiCOUL] = etabEwaldSwitch; break;
+        case CoulombInteractionType::PmeUser: tabsel[etiCOUL] = etabEwaldUser; break;
+        case CoulombInteractionType::PmeUserSwitch: tabsel[etiCOUL] = etabEwaldUserSwitch; break;
+        case CoulombInteractionType::RF:
+        case CoulombInteractionType::RFZero: tabsel[etiCOUL] = etabRF_ZERO; break;
+        case CoulombInteractionType::Switch: tabsel[etiCOUL] = etabCOULSwitch; break;
+        case CoulombInteractionType::User: tabsel[etiCOUL] = etabUSER; break;
+        default: gmx_fatal(FARGS, "Invalid eeltype %s", enumValueToString(eltype));
     }
 
     /* Van der Waals time */
@@ -1188,9 +1193,9 @@ static void set_table_type(int tabsel[], const interaction_const_t* ic, gmx_bool
     }
     else
     {
-        if (b14only && ic->vdwtype != evdwUSER)
+        if (b14only && ic->vdwtype != VanDerWaalsType::User)
         {
-            vdwtype = evdwCUT;
+            vdwtype = VanDerWaalsType::Cut;
         }
         else
         {
@@ -1199,33 +1204,33 @@ static void set_table_type(int tabsel[], const interaction_const_t* ic, gmx_bool
 
         switch (vdwtype)
         {
-            case evdwSWITCH:
+            case VanDerWaalsType::Switch:
                 tabsel[etiLJ6]  = etabLJ6Switch;
                 tabsel[etiLJ12] = etabLJ12Switch;
                 break;
-            case evdwSHIFT:
+            case VanDerWaalsType::Shift:
                 tabsel[etiLJ6]  = etabLJ6Shift;
                 tabsel[etiLJ12] = etabLJ12Shift;
                 break;
-            case evdwUSER:
+            case VanDerWaalsType::User:
                 tabsel[etiLJ6]  = etabUSER;
                 tabsel[etiLJ12] = etabUSER;
                 break;
-            case evdwCUT:
+            case VanDerWaalsType::Cut:
                 tabsel[etiLJ6]  = etabLJ6;
                 tabsel[etiLJ12] = etabLJ12;
                 break;
-            case evdwPME:
+            case VanDerWaalsType::Pme:
                 tabsel[etiLJ6]  = etabLJ6Ewald;
                 tabsel[etiLJ12] = etabLJ12;
                 break;
             default:
-                gmx_fatal(FARGS, "Invalid vdwtype %d in %s line %d", vdwtype, __FILE__, __LINE__);
+                gmx_fatal(FARGS, "Invalid vdwtype %s in %s line %d", enumValueToString(vdwtype), __FILE__, __LINE__);
         }
 
-        if (!b14only && ic->vdw_modifier != eintmodNONE)
+        if (!b14only && ic->vdw_modifier != InteractionModifiers::None)
         {
-            if (ic->vdw_modifier != eintmodPOTSHIFT && ic->vdwtype != evdwCUT)
+            if (ic->vdw_modifier != InteractionModifiers::PotShift && ic->vdwtype != VanDerWaalsType::Cut)
             {
                 gmx_incons(
                         "Potential modifiers other than potential-shift are only implemented for "
@@ -1235,20 +1240,20 @@ static void set_table_type(int tabsel[], const interaction_const_t* ic, gmx_bool
             /* LJ-PME and other (shift-only) modifiers are handled by applying the modifiers
              * to the original interaction forms when we fill the table, so we only check cutoffs here.
              */
-            if (ic->vdwtype == evdwCUT)
+            if (ic->vdwtype == VanDerWaalsType::Cut)
             {
                 switch (ic->vdw_modifier)
                 {
-                    case eintmodNONE:
-                    case eintmodPOTSHIFT:
-                    case eintmodEXACTCUTOFF:
+                    case InteractionModifiers::None:
+                    case InteractionModifiers::PotShift:
+                    case InteractionModifiers::ExactCutoff:
                         /* No modification */
                         break;
-                    case eintmodPOTSWITCH:
+                    case InteractionModifiers::PotSwitch:
                         tabsel[etiLJ6]  = etabLJ6Switch;
                         tabsel[etiLJ12] = etabLJ12Switch;
                         break;
-                    case eintmodFORCESWITCH:
+                    case InteractionModifiers::ForceSwitch:
                         tabsel[etiLJ6]  = etabLJ6Shift;
                         tabsel[etiLJ12] = etabLJ12Shift;
                         break;
@@ -1432,7 +1437,7 @@ bondedtable_t make_bonded_table(FILE* fplog, const char* fn, int angle)
 std::unique_ptr<t_forcetable>
 makeDispersionCorrectionTable(FILE* fp, const interaction_const_t* ic, real rtab, const char* tabfn)
 {
-    GMX_RELEASE_ASSERT(ic->vdwtype != evdwUSER || tabfn,
+    GMX_RELEASE_ASSERT(ic->vdwtype != VanDerWaalsType::User || tabfn,
                        "With VdW user tables we need a table file name");
 
     std::unique_ptr<t_forcetable> fullTable = make_tables(fp, ic, tabfn, rtab, 0);
index 5d771e526588a4723540b1a09a332cc9133570f1..fdbf1b32bccdeb65b4bed880a23c19d2e74c73f1 100644 (file)
@@ -592,7 +592,8 @@ bool decideWhetherToUseGpuForUpdate(const bool                     isDomainDecom
         errorMessage += "Multiple time stepping is not supported.\n";
     }
 
-    if (inputrec.eConstrAlg == econtSHAKE && hasAnyConstraints && gmx_mtop_ftype_count(mtop, F_CONSTR) > 0)
+    if (inputrec.eConstrAlg == ConstraintAlgorithm::Shake && hasAnyConstraints
+        && gmx_mtop_ftype_count(mtop, F_CONSTR) > 0)
     {
         errorMessage += "SHAKE constraints are not supported.\n";
     }
@@ -613,7 +614,7 @@ bool decideWhetherToUseGpuForUpdate(const bool                     isDomainDecom
     {
         errorMessage += "Only a CUDA build is supported.\n";
     }
-    if (inputrec.eI != eiMD)
+    if (inputrec.eI != IntegrationAlgorithm::MD)
     {
         errorMessage += "Only the md integrator is supported.\n";
     }
@@ -650,7 +651,8 @@ bool decideWhetherToUseGpuForUpdate(const bool                     isDomainDecom
         // The graph is needed, but not supported
         errorMessage += "Orientation restraints are not supported.\n";
     }
-    if (inputrec.efep != efepNO && (haveFepPerturbedMasses(mtop) || havePerturbedConstraints(mtop)))
+    if (inputrec.efep != FreeEnergyPerturbationType::No
+        && (haveFepPerturbedMasses(mtop) || havePerturbedConstraints(mtop)))
     {
         errorMessage += "Free energy perturbation for mass and constraints are not supported.\n";
     }
@@ -663,7 +665,7 @@ bool decideWhetherToUseGpuForUpdate(const bool                     isDomainDecom
     {
         errorMessage += "Replica exchange simulations are not supported.\n";
     }
-    if (inputrec.eSwapCoords != eswapNO)
+    if (inputrec.eSwapCoords != SwapType::No)
     {
         errorMessage += "Swapping the coordinates is not supported.\n";
     }
index b1fdb52b743fa1b2e380eb418850ae3af2b7f96b..c2a9e618812d8ada49cc13acda09aa4aa16495f3 100644 (file)
@@ -378,8 +378,9 @@ int get_nthreads_mpi(const gmx_hw_info_t* hwinfo,
         // had to define a function that returns such requirements,
         // and a description string.
         SingleRankChecker checker;
-        checker.applyConstraint(inputrec->eI == eiLBFGS, "L-BFGS minimization");
-        checker.applyConstraint(inputrec->coulombtype == eelEWALD, "Plain Ewald electrostatics");
+        checker.applyConstraint(inputrec->eI == IntegrationAlgorithm::LBFGS, "L-BFGS minimization");
+        checker.applyConstraint(inputrec->coulombtype == CoulombInteractionType::Ewald,
+                                "Plain Ewald electrostatics");
         checker.applyConstraint(doMembed, "Membrane embedding");
         bool useOrientationRestraints = (gmx_mtop_ftype_count(mtop, F_ORIRES) > 0);
         checker.applyConstraint(useOrientationRestraints, "Orientation restraints");
@@ -437,7 +438,7 @@ int get_nthreads_mpi(const gmx_hw_info_t* hwinfo,
 
     nrank = get_tmpi_omp_thread_division(hwinfo, *hw_opt, nthreads_tot_max, ngpu);
 
-    if (inputrec->eI == eiNM || EI_TPI(inputrec->eI))
+    if (inputrec->eI == IntegrationAlgorithm::NM || EI_TPI(inputrec->eI))
     {
         /* Dims/steps are divided over the nodes iso splitting the atoms.
          * With NM we can't have more ranks than #atoms*#dim. With TPI it's
index 740a7ffff4e7998b711e84f90b7d9d208b505a92..856fcee29204b0cd1b51ec2735af20c8f40f8869 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2013, 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.
@@ -117,9 +117,9 @@ static void comp_tpx(const char* fn1, const char* fn2, gmx_bool bRMSD, real ftol
     }
     else
     {
-        if (ir[0]->efep == efepNO)
+        if (ir[0]->efep == FreeEnergyPerturbationType::No)
         {
-            fprintf(stdout, "inputrec->efep = %s\n", efep_names[ir[0]->efep]);
+            fprintf(stdout, "inputrec->efep = %s\n", enumValueToString(ir[0]->efep));
         }
         else
         {
@@ -302,7 +302,7 @@ static void chk_trj(const gmx_output_env_t* oenv, const char* fn, const char* tp
     {
         read_tpx_state(tpr, &ir, &state, &mtop);
         top = std::make_unique<gmx_localtop_t>(mtop.ffparams);
-        gmx_mtop_generate_local_top(mtop, top.get(), ir.efep != efepNO);
+        gmx_mtop_generate_local_top(mtop, top.get(), ir.efep != FreeEnergyPerturbationType::No);
     }
     new_natoms = -1;
     natoms     = -1;
index 9aba51b78dc24efe70c3e954fbffc877457a7406..809c0f375c982fc88e5ab73cbc134ead6b2d6e12 100644 (file)
@@ -104,9 +104,9 @@ void writeParameterInformation(TextWriter* writer, const t_inputrec& ir, bool wr
                                    1000 * ir.delta_t));
     writer->writeLine(formatString("Neighbor searching was performed every %d steps.", ir.nstlist));
     writer->writeLine(formatString("The %s algorithm was used for electrostatic interactions.",
-                                   EELTYPE(ir.coulombtype)));
+                                   enumValueToString(ir.coulombtype)));
     writer->writeLine(formatString("with a cut-off of %g nm.", ir.rcoulomb));
-    if (ir.coulombtype == eelPME)
+    if (ir.coulombtype == CoulombInteractionType::Pme)
     {
         writer->writeLine(
                 formatString("A reciprocal grid of %d x %d x %d cells was used with %dth order "
index 5da73f7cb3fe2621ca375c1f3b9df77250e73f31..216fb0cf3e990fd43c8212af0c1a87f1f77cbae2 100644 (file)
@@ -890,12 +890,13 @@ static void modify_PMEsettings(int64_t     simsteps,    /* Set this value as num
     write_tpx_state(fn_sim_tpr, ir, &state, &mtop);
 }
 
-static gmx_bool can_scale_rvdw(int vdwtype)
+static gmx_bool can_scale_rvdw(VanDerWaalsType vdwtype)
 {
-    return (evdwCUT == vdwtype || evdwPME == vdwtype);
+    return (VanDerWaalsType::Cut == vdwtype || VanDerWaalsType::Pme == vdwtype);
 }
 
-#define EPME_SWITCHED(e) ((e) == eelPMESWITCH || (e) == eelPMEUSERSWITCH)
+#define EPME_SWITCHED(e) \
+    ((e) == CoulombInteractionType::PmeSwitch || (e) == CoulombInteractionType::PmeUserSwitch)
 
 /* Make additional TPR files with more computational load for the
  * direct space processors: */
@@ -944,15 +945,18 @@ static void make_benchmark_tprs(const char* fn_sim_tpr,  /* READ : User-provided
     /* Check if some kind of PME was chosen */
     if (EEL_PME(ir->coulombtype) == FALSE)
     {
-        gmx_fatal(FARGS, "Can only do optimizations for simulations with %s electrostatics.", EELTYPE(eelPME));
+        gmx_fatal(FARGS,
+                  "Can only do optimizations for simulations with %s electrostatics.",
+                  enumValueToString(CoulombInteractionType::Pme));
     }
 
     /* Check if rcoulomb == rlist, which is necessary for plain PME. */
-    if ((ir->cutoff_scheme != ecutsVERLET) && (eelPME == ir->coulombtype) && !(ir->rcoulomb == ir->rlist))
+    if ((ir->cutoff_scheme != CutoffScheme::Verlet)
+        && (CoulombInteractionType::Pme == ir->coulombtype) && !(ir->rcoulomb == ir->rlist))
     {
         gmx_fatal(FARGS,
                   "%s requires rcoulomb (%f) to be equal to rlist (%f).",
-                  EELTYPE(eelPME),
+                  enumValueToString(CoulombInteractionType::Pme),
                   ir->rcoulomb,
                   ir->rlist);
     }
@@ -961,7 +965,7 @@ static void make_benchmark_tprs(const char* fn_sim_tpr,  /* READ : User-provided
     {
         gmx_fatal(FARGS,
                   "%s requires rcoulomb (%f) to be equal to or smaller than rlist (%f)",
-                  EELTYPE(ir->coulombtype),
+                  enumValueToString(ir->coulombtype),
                   ir->rcoulomb,
                   ir->rlist);
     }
@@ -1026,13 +1030,13 @@ static void make_benchmark_tprs(const char* fn_sim_tpr,  /* READ : User-provided
     fprintf(fp, "   Number of particles  : %d\n", mtop.natoms);
 
     /* Print information about settings of which some are potentially modified: */
-    fprintf(fp, "   Coulomb type         : %s\n", EELTYPE(ir->coulombtype));
+    fprintf(fp, "   Coulomb type         : %s\n", enumValueToString(ir->coulombtype));
     fprintf(fp,
             "   Grid spacing x y z   : %f %f %f\n",
             box_size[XX] / ir->nkx,
             box_size[YY] / ir->nky,
             box_size[ZZ] / ir->nkz);
-    fprintf(fp, "   Van der Waals type   : %s\n", EVDWTYPE(ir->vdwtype));
+    fprintf(fp, "   Van der Waals type   : %s\n", enumValueToString(ir->vdwtype));
     if (ir_vdw_switched(ir))
     {
         fprintf(fp, "   rvdw_switch          : %f nm\n", ir->rvdw_switch);
@@ -1095,7 +1099,7 @@ static void make_benchmark_tprs(const char* fn_sim_tpr,  /* READ : User-provided
                         &ir->nkz);
 
             /* Adjust other radii since various conditions need to be fulfilled */
-            if (eelPME == ir->coulombtype)
+            if (CoulombInteractionType::Pme == ir->coulombtype)
             {
                 /* plain PME, rcoulomb must be equal to rlist TODO only in the group scheme? */
                 ir->rlist = ir->rcoulomb;
@@ -1108,7 +1112,7 @@ static void make_benchmark_tprs(const char* fn_sim_tpr,  /* READ : User-provided
 
             if (bScaleRvdw && can_scale_rvdw(ir->vdwtype))
             {
-                if (ecutsVERLET == ir->cutoff_scheme || evdwPME == ir->vdwtype)
+                if (CutoffScheme::Verlet == ir->cutoff_scheme || VanDerWaalsType::Pme == ir->vdwtype)
                 {
                     /* With either the Verlet cutoff-scheme or LJ-PME,
                        the van der Waals radius must always equal the
@@ -2074,9 +2078,9 @@ static float inspect_tpr(int nfile, t_filenm fnm[], real* rcoulomb)
     t_inputrec  irInstance;
     t_inputrec* ir = &irInstance;
     read_tpx_state(opt2fn("-s", nfile, fnm), ir, &state, &mtop);
-    bFree = (efepNO != ir->efep);
-    bNM   = (eiNM == ir->eI);
-    bSwap = (eswapNO != ir->eSwapCoords);
+    bFree = (FreeEnergyPerturbationType::No != ir->efep);
+    bNM   = (IntegrationAlgorithm::NM == ir->eI);
+    bSwap = (SwapType::No != ir->eSwapCoords);
     bTpi  = EI_TPI(ir->eI);
 
     /* Set these output files on the tuning command-line */
index c74866f9a8ad78f0fc35d8d7177594d8c31a7e54..59ef2689d3cda84a5ec5e237d7c1df636e9af82b 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.
@@ -194,15 +194,15 @@ public:
  * \tparam  DataType   Type of the data stored in the array.
  * \tparam  ArraySize  Size in entries of the array.
  */
-template<typename EnumType,                   // The enum (class) type.
-         typename DataType,                   // Type of the data stored in the array.
-         EnumType ArraySize = EnumType::Count // Size in entries of the array.
-         >
-struct EnumerationArray final
+template<typename EnumType, typename DataType, EnumType ArraySize = EnumType::Count>
+struct EnumerationArray final // NOLINT(readability-braces-around-statements)
 {
     //! Convenience alias
     using EnumerationWrapperType = EnumerationWrapper<EnumType, ArraySize>;
 
+    //! Convenience alias
+    using value_type = DataType;
+
     /*! \brief Data for names.
      *
      * Data is kept public so we can use direct aggregate
index ffa4dd634500b2764a1053613accba1546d1a5cc..540047566e5fdc4fb65ddb2c517e489200a8581c 100644 (file)
@@ -190,6 +190,16 @@ public:
         doInt(&castedValue);
         *enumValue = static_cast<EnumType>(castedValue);
     }
+
+    //! Serialize array of enum values with underlying type.
+    template<typename EnumType>
+    void doEnumArrayAsInt(EnumType* values, int elements)
+    {
+        for (int i = 0; i < elements; i++)
+        {
+            doEnumAsInt<EnumType>(&(values[i]));
+        }
+    }
 };
 
 } // namespace gmx