From 3ba95aac31a47eaf90ad7c5394b4cbe3d9a88a1a Mon Sep 17 00:00:00 2001 From: Paul Bauer Date: Mon, 22 Feb 2021 10:24:36 +0000 Subject: [PATCH] Refactor md_enums 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. --- api/nblib/gmxsetup.cpp | 18 +- src/gromacs/applied_forces/awh/awh.cpp | 4 +- .../applied_forces/awh/read_params.cpp | 57 +- src/gromacs/domdec/collect.cpp | 5 +- src/gromacs/domdec/distribute.cpp | 7 +- src/gromacs/domdec/domdec.cpp | 9 +- src/gromacs/domdec/domdec_setup.cpp | 6 +- src/gromacs/domdec/domdec_topology.cpp | 2 +- src/gromacs/domdec/mdsetup.cpp | 4 +- src/gromacs/domdec/partition.cpp | 6 +- src/gromacs/ewald/ewald.cpp | 2 +- src/gromacs/ewald/long_range_correction.cpp | 12 +- src/gromacs/ewald/pme.cpp | 28 +- src/gromacs/ewald/pme_gpu.cpp | 4 +- src/gromacs/ewald/pme_internal.h | 5 +- src/gromacs/ewald/pme_load_balancing.cpp | 12 +- src/gromacs/ewald/tests/pmebsplinetest.cpp | 7 +- src/gromacs/ewald/tests/pmegathertest.cpp | 4 +- src/gromacs/ewald/tests/pmesolvetest.cpp | 6 +- .../ewald/tests/pmesplinespreadtest.cpp | 4 +- src/gromacs/fileio/checkpoint.cpp | 38 +- src/gromacs/fileio/checkpoint.h | 11 +- src/gromacs/fileio/readinp.cpp | 1 + src/gromacs/fileio/readinp.h | 55 +- src/gromacs/fileio/tpxio.cpp | 282 +++--- src/gromacs/gmxana/gmx_bar.cpp | 6 +- src/gromacs/gmxana/gmx_disre.cpp | 4 +- src/gromacs/gmxana/gmx_energy.cpp | 6 +- src/gromacs/gmxana/gmx_nmr.cpp | 5 +- src/gromacs/gmxana/gmx_wham.cpp | 40 +- .../gmxlib/nonbonded/nb_free_energy.cpp | 51 +- src/gromacs/gmxlib/nonbonded/nb_kernel.h | 11 +- src/gromacs/gmxpreprocess/convparm.cpp | 18 +- src/gromacs/gmxpreprocess/convparm.h | 5 +- src/gromacs/gmxpreprocess/grompp.cpp | 92 +- src/gromacs/gmxpreprocess/readir.cpp | 716 ++++++++-------- src/gromacs/gmxpreprocess/readpull.cpp | 101 +-- src/gromacs/gmxpreprocess/readrot.cpp | 22 +- src/gromacs/gmxpreprocess/topio.cpp | 112 ++- src/gromacs/gmxpreprocess/topio.h | 5 +- src/gromacs/gmxpreprocess/toppush.cpp | 11 +- src/gromacs/gmxpreprocess/toppush.h | 10 +- src/gromacs/imd/imd.cpp | 7 +- src/gromacs/listed_forces/disre.cpp | 17 +- src/gromacs/listed_forces/listed_forces.cpp | 62 +- src/gromacs/listed_forces/listed_forces.h | 30 +- src/gromacs/listed_forces/listed_internal.h | 5 +- src/gromacs/listed_forces/pairs.cpp | 20 +- .../listed_forces/position_restraints.cpp | 52 +- .../listed_forces/position_restraints.h | 7 +- src/gromacs/mdlib/broadcaststructs.cpp | 8 +- src/gromacs/mdlib/calc_verletbuf.cpp | 22 +- src/gromacs/mdlib/compute_io.cpp | 20 +- src/gromacs/mdlib/constr.cpp | 43 +- src/gromacs/mdlib/constr.h | 4 +- src/gromacs/mdlib/constraintrange.cpp | 4 +- src/gromacs/mdlib/coupling.cpp | 58 +- src/gromacs/mdlib/dispersioncorrection.cpp | 69 +- src/gromacs/mdlib/dispersioncorrection.h | 12 +- src/gromacs/mdlib/enerdata_utils.cpp | 46 +- src/gromacs/mdlib/energyoutput.cpp | 112 +-- src/gromacs/mdlib/expanded.cpp | 79 +- src/gromacs/mdlib/expanded_internal.cpp | 7 +- src/gromacs/mdlib/expanded_internal.h | 4 +- src/gromacs/mdlib/force.cpp | 76 +- src/gromacs/mdlib/forcerec.cpp | 107 +-- src/gromacs/mdlib/forcerec_threading.h | 13 +- src/gromacs/mdlib/freeenergyparameters.cpp | 32 +- src/gromacs/mdlib/freeenergyparameters.h | 7 +- src/gromacs/mdlib/lincs.cpp | 8 +- src/gromacs/mdlib/md_support.cpp | 7 +- src/gromacs/mdlib/mdatoms.cpp | 6 +- src/gromacs/mdlib/mdebin_bar.cpp | 43 +- src/gromacs/mdlib/mdebin_bar.h | 17 +- src/gromacs/mdlib/mdoutf.cpp | 45 +- src/gromacs/mdlib/perf_est.cpp | 15 +- src/gromacs/mdlib/rbin.cpp | 10 + src/gromacs/mdlib/rbin.h | 4 +- src/gromacs/mdlib/rf_util.cpp | 4 +- src/gromacs/mdlib/shake.cpp | 6 +- src/gromacs/mdlib/sim_util.cpp | 90 +- src/gromacs/mdlib/stat.cpp | 19 +- src/gromacs/mdlib/tests/constrtestdata.cpp | 10 +- src/gromacs/mdlib/tests/energyoutput.cpp | 58 +- src/gromacs/mdlib/tests/expanded.cpp | 49 +- .../mdlib/tests/freeenergyparameters.cpp | 18 +- src/gromacs/mdlib/tests/leapfrogtestdata.cpp | 2 +- src/gromacs/mdlib/update.cpp | 22 +- src/gromacs/mdlib/update_vv.cpp | 29 +- src/gromacs/mdlib/vcm.cpp | 44 +- src/gromacs/mdlib/vcm.h | 5 +- src/gromacs/mdlib/wall.cpp | 12 +- src/gromacs/mdrun/legacysimulator.cpp | 29 +- src/gromacs/mdrun/md.cpp | 58 +- src/gromacs/mdrun/mimic.cpp | 20 +- src/gromacs/mdrun/minimize.cpp | 32 +- src/gromacs/mdrun/replicaexchange.cpp | 8 +- src/gromacs/mdrun/rerun.cpp | 25 +- src/gromacs/mdrun/runner.cpp | 22 +- src/gromacs/mdrun/shellfc.cpp | 16 +- src/gromacs/mdrun/tpi.cpp | 12 +- src/gromacs/mdtypes/awh_params.h | 4 +- src/gromacs/mdtypes/enerdata.h | 7 +- src/gromacs/mdtypes/fcdata.h | 44 +- src/gromacs/mdtypes/forcerec.h | 24 +- src/gromacs/mdtypes/inputrec.cpp | 253 +++--- src/gromacs/mdtypes/inputrec.h | 71 +- src/gromacs/mdtypes/interaction_const.h | 18 +- src/gromacs/mdtypes/md_enums.cpp | 390 +++++++-- src/gromacs/mdtypes/md_enums.h | 804 +++++++++--------- src/gromacs/mdtypes/multipletimestepping.cpp | 10 +- src/gromacs/mdtypes/nblist.h | 1 + src/gromacs/mdtypes/pull_params.h | 6 +- src/gromacs/mdtypes/state.cpp | 12 +- src/gromacs/mdtypes/state.h | 35 +- src/gromacs/mdtypes/swaphistory.h | 6 +- .../mdtypes/tests/multipletimestepping.cpp | 8 +- .../computeglobalselement.cpp | 7 +- .../modularsimulator/constraintelement.cpp | 23 +- src/gromacs/modularsimulator/energydata.cpp | 8 +- src/gromacs/modularsimulator/forceelement.cpp | 2 +- src/gromacs/modularsimulator/forceelement.h | 5 +- .../freeenergyperturbationdata.cpp | 8 +- .../freeenergyperturbationdata.h | 5 +- .../modularsimulator/modularsimulator.cpp | 28 +- .../parrinellorahmanbarostat.cpp | 4 +- .../modularsimulator/pmeloadbalancehelper.cpp | 4 +- .../modularsimulator/simulatoralgorithm.cpp | 2 +- .../modularsimulator/statepropagatordata.cpp | 7 +- src/gromacs/nbnxm/benchmark/bench_setup.cpp | 9 +- .../nbnxm/cuda/nbnxm_cuda_data_mgmt.cu | 2 +- src/gromacs/nbnxm/kerneldispatch.cpp | 67 +- src/gromacs/nbnxm/nbnxm_gpu_data_mgmt.cpp | 33 +- src/gromacs/nbnxm/nbnxm_setup.cpp | 14 +- .../nbnxm/opencl/nbnxm_ocl_data_mgmt.cpp | 6 +- src/gromacs/nbnxm/pairlist_tuning.cpp | 2 +- .../nbnxm/sycl/nbnxm_sycl_data_mgmt.cpp | 2 +- src/gromacs/pulling/output.cpp | 10 +- src/gromacs/pulling/pull.cpp | 219 ++--- src/gromacs/pulling/pull_rotation.cpp | 152 ++-- src/gromacs/pulling/pullutil.cpp | 10 +- src/gromacs/pulling/tests/pull.cpp | 10 +- src/gromacs/swap/swapcoords.cpp | 150 ++-- src/gromacs/tables/forcetable.cpp | 97 ++- src/gromacs/taskassignment/decidegpuusage.cpp | 10 +- .../taskassignment/resourcedivision.cpp | 7 +- src/gromacs/tools/check.cpp | 8 +- src/gromacs/tools/report_methods.cpp | 4 +- src/gromacs/tools/tune_pme.cpp | 32 +- src/gromacs/utility/enumerationhelpers.h | 12 +- src/gromacs/utility/iserializer.h | 10 + 151 files changed, 3416 insertions(+), 2718 deletions(-) diff --git a/api/nblib/gmxsetup.cpp b/api/nblib/gmxsetup.cpp index b314ad7c0f..b19744755b 100644 --- a/api/nblib/gmxsetup.cpp +++ b/api/nblib/gmxsetup.cpp @@ -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 = diff --git a/src/gromacs/applied_forces/awh/awh.cpp b/src/gromacs/applied_forces/awh/awh.cpp index 4cf4249ca0..a772d31a34 100644 --- a/src/gromacs/applied_forces/awh/awh.cpp +++ b/src/gromacs/applied_forces/awh/awh.cpp @@ -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")); diff --git a/src/gromacs/applied_forces/awh/read_params.cpp b/src/gromacs/applied_forces/awh/read_params.cpp index 013c3ced26..bbdd4f6451 100644 --- a/src/gromacs/applied_forces/awh/read_params.cpp +++ b/src/gromacs/applied_forces/awh/read_params.cpp @@ -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* inp, "distribution: no or yes"); } opt = prefix + "-equilibrate-histogram"; - awhBiasParams->equilibrateHistogram = (get_eeenum(inp, opt, yesno_names, wi) != 0); + awhBiasParams->equilibrateHistogram = (getEnum(inp, opt.c_str(), wi) != Boolean::No); if (bComment) { @@ -547,7 +547,7 @@ void readBiasParams(std::vector* 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(inp, opt.c_str(), wi) != Boolean::No; if (bComment) { @@ -813,7 +813,7 @@ AwhParams* readAwhParams(std::vector* 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(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()); } } diff --git a/src/gromacs/domdec/collect.cpp b/src/gromacs/domdec/collect.cpp index 59c23df45f..63167f8f39 100644 --- a/src/gromacs/domdec/collect.cpp +++ b/src/gromacs/domdec/collect.cpp @@ -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::keys()) { state->lambda[i] = state_local->lambda[i]; } diff --git a/src/gromacs/domdec/distribute.cpp b/src/gromacs/domdec/distribute.cpp index 11609921bd..efa2611c1b 100644 --- a/src/gromacs/domdec/distribute.cpp +++ b/src/gromacs/domdec/distribute.cpp @@ -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::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(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); diff --git a/src/gromacs/domdec/domdec.cpp b/src/gromacs/domdec/domdec.cpp index 2077798da7..1c92f4fa32 100644 --- a/src/gromacs/domdec/domdec.cpp +++ b/src/gromacs/domdec/domdec.cpp @@ -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); diff --git a/src/gromacs/domdec/domdec_setup.cpp b/src/gromacs/domdec/domdec_setup.cpp index 6cf0368a71..6efa4d960c 100644 --- a/src/gromacs/domdec/domdec_setup.cpp +++ b/src/gromacs/domdec/domdec_setup.cpp @@ -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)); } diff --git a/src/gromacs/domdec/domdec_topology.cpp b/src/gromacs/domdec/domdec_topology.cpp index 2ad6f301c4..ebb604c5f2 100644 --- a/src/gromacs/domdec/domdec_topology.cpp +++ b/src/gromacs/domdec/domdec_topology.cpp @@ -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; diff --git a/src/gromacs/domdec/mdsetup.cpp b/src/gromacs/domdec/mdsetup.cpp index ce4458a49c..6c76374521 100644 --- a/src/gromacs/domdec/mdsetup.cpp +++ b/src/gromacs/domdec/mdsetup.cpp @@ -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) diff --git a/src/gromacs/domdec/partition.cpp b/src/gromacs/domdec/partition.cpp index 7bc033884e..0696694f6c 100644 --- a/src/gromacs/domdec/partition.cpp +++ b/src/gromacs/domdec/partition.cpp @@ -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(); } diff --git a/src/gromacs/ewald/ewald.cpp b/src/gromacs/ewald/ewald.cpp index 81e6bb4709..7b155afde0 100644 --- a/src/gromacs/ewald/ewald.cpp +++ b/src/gromacs/ewald/ewald.cpp @@ -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); diff --git a/src/gromacs/ewald/long_range_correction.cpp b/src/gromacs/ewald/long_range_correction.cpp index b75afe50be..a746ae8bc8 100644 --- a/src/gromacs/ewald/long_range_correction.cpp +++ b/src/gromacs/ewald/long_range_correction.cpp @@ -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", diff --git a/src/gromacs/ewald/pme.cpp b/src/gromacs/ewald/pme.cpp index 4fb2b447dc..95cc44791e 100644 --- a/src/gromacs/ewald/pme.cpp +++ b/src/gromacs/ewald/pme.cpp @@ -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) { diff --git a/src/gromacs/ewald/pme_gpu.cpp b/src/gromacs/ewald/pme_gpu.cpp index b90170a045..e0c32e207d 100644 --- a/src/gromacs/ewald/pme_gpu.cpp +++ b/src/gromacs/ewald/pme_gpu.cpp @@ -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_) { diff --git a/src/gromacs/ewald/pme_internal.h b/src/gromacs/ewald/pme_internal.h index a4af8154de..c97f9e2948 100644 --- a/src/gromacs/ewald/pme_internal.h +++ b/src/gromacs/ewald/pme_internal.h @@ -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*/ diff --git a/src/gromacs/ewald/pme_load_balancing.cpp b/src/gromacs/ewald/pme_load_balancing.cpp index 027895d348..16ffbdb14b 100644 --- a/src/gromacs/ewald/pme_load_balancing.cpp +++ b/src/gromacs/ewald/pme_load_balancing.cpp @@ -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); } diff --git a/src/gromacs/ewald/tests/pmebsplinetest.cpp b/src/gromacs/ewald/tests/pmebsplinetest.cpp index aaf475f3c5..7c38a52c91 100644 --- a/src/gromacs/ewald/tests/pmebsplinetest.cpp +++ b/src/gromacs/ewald/tests/pmebsplinetest.cpp @@ -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); diff --git a/src/gromacs/ewald/tests/pmegathertest.cpp b/src/gromacs/ewald/tests/pmegathertest.cpp index dde08758ee..160b319fdb 100644 --- a/src/gromacs/ewald/tests/pmegathertest.cpp +++ b/src/gromacs/ewald/tests/pmegathertest.cpp @@ -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; diff --git a/src/gromacs/ewald/tests/pmesolvetest.cpp b/src/gromacs/ewald/tests/pmesolvetest.cpp index f32517da5d..57ed877302 100644 --- a/src/gromacs/ewald/tests/pmesolvetest.cpp +++ b/src/gromacs/ewald/tests/pmesolvetest.cpp @@ -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")); } diff --git a/src/gromacs/ewald/tests/pmesplinespreadtest.cpp b/src/gromacs/ewald/tests/pmesplinespreadtest.cpp index 032188c247..10a2840ee2 100644 --- a/src/gromacs/ewald/tests/pmesplinespreadtest.cpp +++ b/src/gromacs/ewald/tests/pmesplinespreadtest.cpp @@ -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 optionsToTest = { diff --git a/src/gromacs/fileio/checkpoint.cpp b/src/gromacs/fileio/checkpoint.cpp index 89a2d8da3b..bb08642efb 100644 --- a/src/gromacs/fileio/checkpoint.cpp +++ b/src/gromacs/fileio/checkpoint.cpp @@ -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(contents->eIntegrator); + do_cpt_int_err(xd, "integrator", &integrator, list); + if (bRead) + { + contents->eIntegrator = static_cast(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(contents->eSwapCoords); + do_cpt_int_err(xd, "swap", &swapState, list); + if (bRead) + { + contents->eSwapCoords = static_cast(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(state->lambda.data(), state->lambda.size()), + gmx::arrayRefFromArray( + state->lambda.data(), + gmx::EnumerationArray::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::vectoreSwapCoords != eswapNO && observablesHistory->swapHistory == nullptr) + if (headerContents->eSwapCoords != SwapType::No && observablesHistory->swapHistory == nullptr) { observablesHistory->swapHistory = std::make_unique(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); diff --git a/src/gromacs/fileio/checkpoint.h b/src/gromacs/fileio/checkpoint.h index c3dbc3c107..49cc0fe77b 100644 --- a/src/gromacs/fileio/checkpoint.h +++ b/src/gromacs/fileio/checkpoint.h @@ -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, diff --git a/src/gromacs/fileio/readinp.cpp b/src/gromacs/fileio/readinp.cpp index bf47bcd36a..d9d30ba8b3 100644 --- a/src/gromacs/fileio/readinp.cpp +++ b/src/gromacs/fileio/readinp.cpp @@ -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" diff --git a/src/gromacs/fileio/readinp.h b/src/gromacs/fileio/readinp.h index 5c2e8e5f17..9330e99eb8 100644 --- a/src/gromacs/fileio/readinp.h +++ b/src/gromacs/fileio/readinp.h @@ -44,10 +44,11 @@ #include #include +#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* 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* inp, const char* name); * \return Enum value corresponding to read input */ template -EnumType getEnum(std::vector* inp, const char* name, warninp* wi); +EnumType getEnum(std::vector* 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{}) + { + 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{}) + { + 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* inp, const char* line); diff --git a/src/gromacs/fileio/tpxio.cpp b/src/gromacs/fileio/tpxio.cpp index b963ed295b..b99e3bcf6e 100644 --- a/src/gromacs/fileio/tpxio.cpp +++ b/src/gromacs/fileio/tpxio.cpp @@ -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::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(temp); + } + else + { + int temp = static_cast(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(temp); + } + else + { + int temp = static_cast(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(SwapGroupSplittingType::Split0)].molname = gmx_strdup("split0"); // group 0: split0 + swap->grp[static_cast(SwapGroupSplittingType::Split1)].molname = gmx_strdup("split1"); // group 1: split1 + swap->grp[static_cast(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(SwapGroupSplittingType::Solvent)].nat); + serializer->doInt(&swap->grp[static_cast(SwapGroupSplittingType::Split0)].nat); serializer->doBool(&swap->massw_split[eChannel0]); - serializer->doInt(&swap->grp[eGrpSplit1].nat); + serializer->doInt(&swap->grp[static_cast(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(SwapGroupSplittingType::Solvent), + static_cast(SwapGroupSplittingType::Split0), + static_cast(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(); + } + 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(); + } + 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(); + } + 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; diff --git a/src/gromacs/gmxana/gmx_bar.cpp b/src/gromacs/gmxana/gmx_bar.cpp index 97b0e2c36d..b70ffedf36 100644 --- a/src/gromacs/gmxana/gmx_bar.cpp +++ b/src/gromacs/gmxana/gmx_bar.cpp @@ -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( + fr->block[i].sub[1].ival[1 + j])); if (check) { /* check the components */ diff --git a/src/gromacs/gmxana/gmx_disre.cpp b/src/gromacs/gmxana/gmx_disre.cpp index bd3feef043..b00e05930f 100644 --- a/src/gromacs/gmxana/gmx_disre.cpp +++ b/src/gromacs/gmxana/gmx_disre.cpp @@ -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; diff --git a/src/gromacs/gmxana/gmx_energy.cpp b/src/gromacs/gmxana/gmx_energy.cpp index e3778d7747..47dcde2f60 100644 --- a/src/gromacs/gmxana/gmx_energy.cpp +++ b/src/gromacs/gmxana/gmx_energy.cpp @@ -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( + fr->block[i].sub[1].ival[2 + j])); } } } diff --git a/src/gromacs/gmxana/gmx_nmr.cpp b/src/gromacs/gmxana/gmx_nmr.cpp index 119c5e0a05..7a6ac17faa 100644 --- a/src/gromacs/gmxana/gmx_nmr.cpp +++ b/src/gromacs/gmxana/gmx_nmr.cpp @@ -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(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); diff --git a/src/gromacs/gmxana/gmx_wham.cpp b/src/gromacs/gmxana/gmx_wham.cpp index 1cf91e42d7..282ddd0c38 100644 --- a/src/gromacs/gmxana/gmx_wham.cpp +++ b/src/gromacs/gmxana/gmx_wham.cpp @@ -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]), diff --git a/src/gromacs/gmxlib/nonbonded/nb_free_energy.cpp b/src/gromacs/gmxlib/nonbonded/nb_free_energy.cpp index d036d8510a..290c7345dc 100644 --- a/src/gromacs/gmxlib/nonbonded/nb_free_energy.cpp +++ b/src/gromacs/gmxlib/nonbonded/nb_free_energy.cpp @@ -244,19 +244,21 @@ static void nb_free_energy_kernel(const t_nblist* gmx_restrict nlist, gmx::ArrayRef nbfp = fr->nbfp; gmx::ArrayRef 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(FreeEnergyPerturbationCouplingType::Coul)]; + const real lambda_vdw = + kernel_data->lambda[static_cast(FreeEnergyPerturbationCouplingType::Vdw)]; + gmx::ArrayRef 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(FreeEnergyPerturbationCouplingType::Coul)] += dvdlCoul; #pragma omp atomic - dvdl[efptVDW] += dvdlVdw; + dvdl[static_cast(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(FreeEnergyPerturbationCouplingType::Coul)] + == kernel_data->lambda[static_cast(FreeEnergyPerturbationCouplingType::Vdw)] && scParams.alphaCoulomb == scParams.alphaVdw) { scLambdasOrAlphasDiffer = false; diff --git a/src/gromacs/gmxlib/nonbonded/nb_kernel.h b/src/gromacs/gmxlib/nonbonded/nb_kernel.h index ff75e9159a..c261d2652d 100644 --- a/src/gromacs/gmxlib/nonbonded/nb_kernel.h +++ b/src/gromacs/gmxlib/nonbonded/nb_kernel.h @@ -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 lambda; + gmx::ArrayRef dvdl; /* pointers to tables */ t_forcetable* table_elec; diff --git a/src/gromacs/gmxpreprocess/convparm.cpp b/src/gromacs/gmxpreprocess/convparm.cpp index bafd389bee..f06620e5b4 100644 --- a/src/gromacs/gmxpreprocess/convparm.cpp +++ b/src/gromacs/gmxpreprocess/convparm.cpp @@ -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 old, int comb, double reppow) +static int assign_param(t_functype ftype, + t_iparams* newparam, + gmx::ArrayRef 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 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 nbtypes, gmx::ArrayRef mi, const MoleculeInformation* intermolecular_interactions, - int comb, + CombinationRule comb, double reppow, real fudgeQQ, gmx_mtop_t* mtop) diff --git a/src/gromacs/gmxpreprocess/convparm.h b/src/gromacs/gmxpreprocess/convparm.h index a3d65b8e84..eac7e911ae 100644 --- a/src/gromacs/gmxpreprocess/convparm.h +++ b/src/gromacs/gmxpreprocess/convparm.h @@ -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 nbtypes, gmx::ArrayRef mi, const MoleculeInformation* intermolecular_interactions, - int comb, + CombinationRule comb, double reppow, real fudgeQQ, gmx_mtop_t* mtop); diff --git a/src/gromacs/gmxpreprocess/grompp.cpp b/src/gromacs/gmxpreprocess/grompp.cpp index 2f6f29e3e0..a47fb29950 100644 --- a/src/gromacs/gmxpreprocess/grompp.cpp +++ b/src/gromacs/gmxpreprocess/grompp.cpp @@ -586,7 +586,7 @@ static void new_status(const char* topfile, std::vector* mi, std::unique_ptr* intermolecular_interactions, gmx::ArrayRef 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 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 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 mi; std::unique_ptr 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(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(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(internalParameterBuilder.build()); } - if (ir->comm_mode != ecmNO) + if (ir->comm_mode != ComRemovalAlgorithm::No) { const int nstglobalcomm = computeGlobalCommunicationPeriod(ir); if (ir->nstcomm % nstglobalcomm != 0) diff --git a/src/gromacs/gmxpreprocess/readir.cpp b/src/gromacs/gmxpreprocess/readir.cpp index 6595bff142..2276b84de2 100644 --- a/src/gromacs/gmxpreprocess/readir.cpp +++ b/src/gromacs/gmxpreprocess/readir.cpp @@ -37,6 +37,7 @@ */ #include "gmxpre.h" +#include "gromacs/utility/enumerationhelpers.h" #include "readir.h" #include @@ -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 pullGroupNames; - std::vector rotateGroupNames; + gmx::EnumerationArray fep_lambda; + char lambda_weights[STRLEN]; + std::vector pullGroupNames; + std::vector 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 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((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(FreeEnergyPerturbationCouplingType::Temperature)][i]); + CHECK((fep->all_lambda[static_cast(FreeEnergyPerturbationCouplingType::Temperature)][i] < 0) + || (fep->all_lambda[static_cast(FreeEnergyPerturbationCouplingType::Temperature)][i] + > 1)); + if (fep->all_lambda[static_cast(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(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(FreeEnergyPerturbationCouplingType::Count); j++) { for (i = 0; i < fep->n_lambda; i++) { + auto enumValue = static_cast(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(FreeEnergyPerturbationCouplingType::Vdw)][i], + fep->all_lambda[static_cast(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(FreeEnergyPerturbationCouplingType::Coul)][i] > 0.0) + && (fep->all_lambda[static_cast(FreeEnergyPerturbationCouplingType::Coul)][i] < 1.0)) + && ((fep->all_lambda[static_cast(FreeEnergyPerturbationCouplingType::Vdw)][i] > 0.0) + && (fep->all_lambda[static_cast(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(FreeEnergyPerturbationCouplingType::Count); i++) { + auto enumValue = static_cast(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 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 r; for (int i = 0; i < *n; i++) { try { - (*r)[i] = gmx::fromString(values[i]); + r.emplace_back(gmx::fromString(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 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> count_fep_lambdas; + bool bOneLambda = TRUE; + gmx::EnumerationArray 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(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(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 @@ -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* 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(inp, "lmc-stats", wi); + expand->elmcmove = getEnum(inp, "lmc-move", wi); + expand->elmceq = getEnum(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* 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(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 -EnumType getEnum(std::vector* 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{}) - { - 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{}) - { - 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(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(&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(&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(&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(&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(get_eeenum(&inp, "pbc", pbcTypesNamesChar.data(), wi)); - ir->bPeriodicMols = get_eeenum(&inp, "periodic-molecules", yesno_names, wi) != 0; + ir->bPeriodicMols = getEnum(&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(&inp, "coulombtype", wi); + ir->coulomb_modifier = getEnum(&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(&inp, "vdw-type", wi); + ir->vdw_modifier = getEnum(&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(&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(&inp, "lj-pme-comb-rule", wi); + ir->ewald_geometry = getEnum(&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(&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(&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(&inp, "pcoupl", wi); - ir->epct = get_eeenum(&inp, "pcoupltype", epcoupltype_names, wi); + ir->epct = getEnum(&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(&inp, "refcoord-scaling", wi); /* QMMM */ printStringNewline(&inp, "OPTIONS FOR QMMM calculations"); - ir->bQMMM = (get_eeenum(&inp, "QMMM", yesno_names, wi) != 0); + ir->bQMMM = (getEnum(&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(&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(&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(&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(&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(&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(&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(&inp, "pull", wi) != Boolean::No); if (ir->bPull) { ir->pull = std::make_unique(); @@ -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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&inp, "separate-dhdl-file", wi); + fep->dhdl_derivatives = getEnum(&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(&inp, "simulated-tempering", wi) != Boolean::No); + ir->simtempvals->eSimTempScale = getEnum(&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(&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(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(SwapGroupSplittingType::Split0)].molname, + nullptr); + setStringEntry(&inp, + "split-group1", + ir->swap->grp[static_cast(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(&inp, "massw-split0", wi) != Boolean::No); + ir->swap->massw_split[1] = (getEnum(&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(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(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(SwapGroupSplittingType::Split0)].molname, + swap->grp[static_cast(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(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(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) diff --git a/src/gromacs/gmxpreprocess/readpull.cpp b/src/gromacs/gmxpreprocess/readpull.cpp index 103f9a279f..1af230d135 100644 --- a/src/gromacs/gmxpreprocess/readpull.cpp +++ b/src/gromacs/gmxpreprocess/readpull.cpp @@ -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 read_pullparams(std::vector* 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(inp, "pull-print-com", wi) != Boolean::No); + pull->bPrintRefValue = (getEnum(inp, "pull-print-ref-value", wi) != Boolean::No); + pull->bPrintComp = (getEnum(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(inp, "pull-pbc-ref-prev-step-com", wi) != Boolean::No); + pull->bXOutAverage = (getEnum(inp, "pull-xout-average", wi) != Boolean::No); + pull->bFOutAverage = (getEnum(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 read_pullparams(std::vector* 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(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(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 read_pullparams(std::vector* 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 read_pullparams(std::vector* 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(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 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) { diff --git a/src/gromacs/gmxpreprocess/readrot.cpp b/src/gromacs/gmxpreprocess/readrot.cpp index 7643c5888d..4e72504060 100644 --- a/src/gromacs/gmxpreprocess/readrot.cpp +++ b/src/gromacs/gmxpreprocess/readrot.cpp @@ -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 read_rotparams(std::vector* 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(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(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 read_rotparams(std::vector* 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 read_rotparams(std::vector* 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 read_rotparams(std::vector* 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 read_rotparams(std::vector* 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(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); diff --git a/src/gromacs/gmxpreprocess/topio.cpp b/src/gromacs/gmxpreprocess/topio.cpp index cf702b1f91..54e15169ff 100644 --- a/src/gromacs/gmxpreprocess/topio.cpp +++ b/src/gromacs/gmxpreprocess/topio.cpp @@ -37,6 +37,8 @@ */ #include "gmxpre.h" +#include "gromacs/utility/enumerationhelpers.h" +#include "gromacs/utility/stringutil.h" #include "topio.h" #include @@ -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::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(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(integerValue); + } } - *comb = -1; - for (i = 1; (i < eCOMB_NR); i++) + *comb = CombinationRule::Count; + for (auto i : gmx::EnumerationArray::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(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(integerValue); + } } } @@ -383,7 +397,7 @@ static char** read_topol(const char* infile, std::vector* molinfo, std::unique_ptr* intermolecular_interactions, gmx::ArrayRef 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> 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(ifunc_index( + Directive::d_nonbond_params, static_cast(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(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(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(nb_funct), + &(interactions[static_cast(nb_funct)]), + atypes, + wi); + ncopy = copy_nbparams(nbparam, + static_cast(nb_funct), + &(interactions[static_cast(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(nb_funct)]), &(interactions[F_LJ14]), fudgeLJ, *combination_rule); - ncopy = copy_nbparams(pair, nb_funct, &(interactions[F_LJ14]), ntype); + ncopy = copy_nbparams( + pair, static_cast(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(nb_funct), + &(interactions[static_cast(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 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" diff --git a/src/gromacs/gmxpreprocess/topio.h b/src/gromacs/gmxpreprocess/topio.h index f39c8ec2f0..96ee43e1e3 100644 --- a/src/gromacs/gmxpreprocess/topio.h +++ b/src/gromacs/gmxpreprocess/topio.h @@ -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 plist, - int* combination_rule, + CombinationRule* combination_rule, double* repulsion_power, real* fudgeQQ, PreprocessingAtomTypes* atype, diff --git a/src/gromacs/gmxpreprocess/toppush.cpp b/src/gromacs/gmxpreprocess/toppush.cpp index ba67deb03c..27bc433640 100644 --- a/src/gromacs/gmxpreprocess/toppush.cpp +++ b/src/gromacs/gmxpreprocess/toppush.cpp @@ -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; diff --git a/src/gromacs/gmxpreprocess/toppush.h b/src/gromacs/gmxpreprocess/toppush.h index 66df62b9d3..302af131af 100644 --- a/src/gromacs/gmxpreprocess/toppush.h +++ b/src/gromacs/gmxpreprocess/toppush.h @@ -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 @@ -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, diff --git a/src/gromacs/imd/imd.cpp b/src/gromacs/imd/imd.cpp index 995c4da8df..cf1a9d81da 100644 --- a/src/gromacs/imd/imd.cpp +++ b/src/gromacs/imd/imd.cpp @@ -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 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)) diff --git a/src/gromacs/listed_forces/disre.cpp b/src/gromacs/listed_forces/disre.cpp index 1095ab94df..91f61c4f10 100644 --- a/src/gromacs/listed_forces/disre.cpp +++ b/src/gromacs/listed_forces/disre.cpp @@ -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]); diff --git a/src/gromacs/listed_forces/listed_forces.cpp b/src/gromacs/listed_forces/listed_forces.cpp index 10e54fb419..0364a2d734 100644 --- a/src/gromacs/listed_forces/listed_forces.cpp +++ b/src/gromacs/listed_forces/listed_forces.cpp @@ -44,6 +44,8 @@ */ #include "gmxpre.h" +#include "gromacs/utility/arrayref.h" +#include "gromacs/utility/enumerationhelpers.h" #include "listed_forces.h" #include @@ -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 force, const bonded_threading void reduce_thread_output(gmx::ForceWithShiftForces* forceWithShiftForces, real* ener, gmx_grppairener_t* grpp, - real* dvdl, + gmx::ArrayRef 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(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 lambda, + gmx::ArrayRef 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(efptFTYPE)], + &(dvdl[static_cast(efptFTYPE)]), md, fcd, nullptr, @@ -484,8 +486,8 @@ real calc_one_bond(int thread, f, fshift, pbc, - lambda[efptFTYPE], - &(dvdl[efptFTYPE]), + lambda[static_cast(efptFTYPE)], + &(dvdl[static_cast(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 lambda, + gmx::ArrayRef 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 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 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 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 dvdl, t_nrnb* nrnb, - const real* lambda, + gmx::ArrayRef 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 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 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 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(j)] : fepvals->all_lambda[j][i - 1]); } calc_listed_lambda(idef, threading_.get(), diff --git a/src/gromacs/listed_forces/listed_forces.h b/src/gromacs/listed_forces/listed_forces.h index d82a293b61..0cf099b5ab 100644 --- a/src/gromacs/listed_forces/listed_forces.h +++ b/src/gromacs/listed_forces/listed_forces.h @@ -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 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 lambda, const t_mdatoms* md, int* global_atom_index, const gmx::StepWorkload& stepWork); diff --git a/src/gromacs/listed_forces/listed_internal.h b/src/gromacs/listed_forces/listed_internal.h index 2e130dcb83..5013a6917a 100644 --- a/src/gromacs/listed_forces/listed_internal.h +++ b/src/gromacs/listed_forces/listed_internal.h @@ -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 dvdl; GMX_DISALLOW_COPY_MOVE_AND_ASSIGN(f_thread_t); }; diff --git a/src/gromacs/listed_forces/pairs.cpp b/src/gromacs/listed_forces/pairs.cpp index b742311a43..77c78746fd 100644 --- a/src/gromacs/listed_forces/pairs.cpp +++ b/src/gromacs/listed_forces/pairs.cpp @@ -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(FreeEnergyPerturbationCouplingType::Coul)] += dvdl_coul; + dvdl[static_cast(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(FreeEnergyPerturbationCouplingType::Coul)]; + LFV[0] = 1.0 - lambda[static_cast(FreeEnergyPerturbationCouplingType::Vdw)]; + LFC[1] = lambda[static_cast(FreeEnergyPerturbationCouplingType::Coul)]; + LFV[1] = lambda[static_cast(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. diff --git a/src/gromacs/listed_forces/position_restraints.cpp b/src/gromacs/listed_forces/position_restraints.cpp index ebd3d99ccc..aa881af20d 100644 --- a/src/gromacs/listed_forces/position_restraints.cpp +++ b/src/gromacs/listed_forces/position_restraints.cpp @@ -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 @@ -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 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(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 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(FreeEnergyPerturbationCouplingType::Restraint)] + : fepvals->all_lambda[FreeEnergyPerturbationCouplingType::Restraint][i - 1]); const real v = posres(idef.il[F_POSRES].size(), idef.il[F_POSRES].iatoms.data(), idef.iparams_posres.data(), diff --git a/src/gromacs/listed_forces/position_restraints.h b/src/gromacs/listed_forces/position_restraints.h index 5d3148fb33..3fc8d0020c 100644 --- a/src/gromacs/listed_forces/position_restraints.h +++ b/src/gromacs/listed_forces/position_restraints.h @@ -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 #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 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 lambda, const t_forcerec* fr); /*! \brief Helper function that wraps calls to fbposres for diff --git a/src/gromacs/mdlib/broadcaststructs.cpp b/src/gromacs/mdlib/broadcaststructs.cpp index 4ab660a823..7f2919765d 100644 --- a/src/gromacs/mdlib/broadcaststructs.cpp +++ b/src/gromacs/mdlib/broadcaststructs.cpp @@ -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(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; diff --git a/src/gromacs/mdlib/calc_verletbuf.cpp b/src/gromacs/mdlib/calc_verletbuf.cpp index 3ff12f3342..4cb664fa0b 100644 --- a/src/gromacs/mdlib/calc_verletbuf.cpp +++ b/src/gromacs/mdlib/calc_verletbuf.cpp @@ -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); diff --git a/src/gromacs/mdlib/compute_io.cpp b/src/gromacs/mdlib/compute_io.cpp index 0819f82ef7..1c90a9b23d 100644 --- a/src/gromacs/mdlib/compute_io.cpp +++ b/src/gromacs/mdlib/compute_io.cpp @@ -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; } diff --git a/src/gromacs/mdlib/constr.cpp b/src/gromacs/mdlib/constr.cpp index 106ce657ab..911c55ed6f 100644 --- a/src/gromacs/mdlib/constr.cpp +++ b/src/gromacs/mdlib/constr.cpp @@ -235,17 +235,18 @@ static void clear_constraint_quantity_nonlocal(gmx_domdec_t* dd, ArrayRef } } -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(), computeVirial, @@ -1435,7 +1436,7 @@ void constrain_coordinates(gmx::Constraints* constr, std::move(xp), ArrayRef(), state->box, - state->lambda[efptBONDED], + state->lambda[FreeEnergyPerturbationCouplingType::Bonded], dvdlambda, state->v.arrayRefWithPadding(), computeVirial, diff --git a/src/gromacs/mdlib/constr.h b/src/gromacs/mdlib/constr.h index 0c2dd9096f..3ab516f944 100644 --- a/src/gromacs/mdlib/constr.h +++ b/src/gromacs/mdlib/constr.h @@ -71,7 +71,7 @@ struct t_inputrec; struct t_nrnb; struct t_pbc; class t_state; - +enum class ConstraintAlgorithm : int; namespace gmx { template @@ -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 iparams, int iparamsIndex) diff --git a/src/gromacs/mdlib/constraintrange.cpp b/src/gromacs/mdlib/constraintrange.cpp index a3eacef6f1..308ade02f5 100644 --- a/src/gromacs/mdlib/constraintrange.cpp +++ b/src/gromacs/mdlib/constraintrange.cpp @@ -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); } diff --git a/src/gromacs/mdlib/coupling.cpp b/src/gromacs/mdlib/coupling.cpp index b49e86103e..9c3f8ef0cc 100644 --- a/src/gromacs/mdlib/coupling.cpp +++ b/src/gromacs/mdlib/coupling.cpp @@ -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(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(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(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(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(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(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(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(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(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"); } diff --git a/src/gromacs/mdlib/dispersioncorrection.cpp b/src/gromacs/mdlib/dispersioncorrection.cpp index 3557950ddb..481c8597e7 100644 --- a/src/gromacs/mdlib/dispersioncorrection.cpp +++ b/src/gromacs/mdlib/dispersioncorrection.cpp @@ -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 mk_nbfp_combination_rule(const gmx_ffparams_t& ffparams, const int comb_rule) +static std::vector 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 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(-1.0 / (rc3 * rc3)) - 6.0 * vdwtab[8 * ri0]; iParams->enershifttwelve_ = static_cast(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(-1.0 / (rc3 * rc3)); iParams->enershifttwelve_ = static_cast(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; } diff --git a/src/gromacs/mdlib/dispersioncorrection.h b/src/gromacs/mdlib/dispersioncorrection.h index be656e2130..62e7cbc021 100644 --- a/src/gromacs/mdlib/dispersioncorrection.h +++ b/src/gromacs/mdlib/dispersioncorrection.h @@ -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 @@ -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 diff --git a/src/gromacs/mdlib/enerdata_utils.cpp b/src/gromacs/mdlib/enerdata_utils.cpp index a546dc4125..be5b282c07 100644 --- a/src/gromacs/mdlib/enerdata_utils.cpp +++ b/src/gromacs/mdlib/enerdata_utils.cpp @@ -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(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(i), enerd->term[F_DVDL], enerd->dvdl_nonlin[i], enerd->dvdl_lin[i]); @@ -194,7 +196,7 @@ void ForeignLambdaTerms::finalizePotentialContributions(gmx::ArrayRef(FreeEnergyPerturbationCouplingType::Count); i++) { dvdl_lin += dvdlLinear[i]; } @@ -258,7 +260,7 @@ void ForeignLambdaTerms::finalizeKineticContributions(gmx::ArrayRef // 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 * 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(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(FreeEnergyPerturbationCouplingType::Mass)]; accumulateKinetic(1 + i, dlam * energyTerms[F_DKDL], energyTerms[F_DKDL]); } } @@ -287,7 +293,7 @@ void accumulateKineticLambdaComponents(gmx_enerdata_t* enerd, gmx::ArrayRef 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; diff --git a/src/gromacs/mdlib/energyoutput.cpp b/src/gromacs/mdlib/energyoutput.cpp index b66cb0a933..5fce35b750 100644 --- a/src/gromacs/mdlib/energyoutput.cpp +++ b/src/gromacs/mdlib/energyoutput.cpp @@ -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 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 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(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(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", diff --git a/src/gromacs/mdlib/expanded.cpp b/src/gromacs/mdlib/expanded.cpp index 570229515b..965d92b441 100644 --- a/src/gromacs/mdlib/expanded.cpp +++ b/src/gromacs/mdlib/expanded.cpp @@ -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(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)); } } diff --git a/src/gromacs/mdlib/expanded_internal.cpp b/src/gromacs/mdlib/expanded_internal.cpp index a46f02e1e8..cc63b5e5ad 100644 --- a/src/gromacs/mdlib/expanded_internal.cpp +++ b/src/gromacs/mdlib/expanded_internal.cpp @@ -50,9 +50,10 @@ 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) diff --git a/src/gromacs/mdlib/expanded_internal.h b/src/gromacs/mdlib/expanded_internal.h index be3c7c81f0..f2f70b7145 100644 --- a/src/gromacs/mdlib/expanded_internal.h +++ b/src/gromacs/mdlib/expanded_internal.h @@ -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 diff --git a/src/gromacs/mdlib/force.cpp b/src/gromacs/mdlib/force.cpp index a17b332848..b53ab898c2 100644 --- a/src/gromacs/mdlib/force.cpp +++ b/src/gromacs/mdlib/force.cpp @@ -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(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(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(FreeEnergyPerturbationCouplingType::Coul)], + lambda[static_cast(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(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; diff --git a/src/gromacs/mdlib/forcerec.cpp b/src/gromacs/mdlib/forcerec.cpp index cdc0b418bf..94c505d48a 100644 --- a/src/gromacs/mdlib/forcerec.cpp +++ b/src/gromacs/mdlib/forcerec.cpp @@ -177,7 +177,7 @@ std::vector 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 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(*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( mtop, ir, fr->bBHAM, fr->ntype, fr->nbfp, *fr->ic, tabfn); diff --git a/src/gromacs/mdlib/forcerec_threading.h b/src/gromacs/mdlib/forcerec_threading.h index 15bca48990..8a0e341648 100644 --- a/src/gromacs/mdlib/forcerec_threading.h +++ b/src/gromacs/mdlib/forcerec_threading.h @@ -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. @@ -38,14 +38,15 @@ #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 dvdl; + tensor vir_q; + tensor vir_lj; }; #endif diff --git a/src/gromacs/mdlib/freeenergyparameters.cpp b/src/gromacs/mdlib/freeenergyparameters.cpp index 2ec8bd8acf..1dcbf1a22c 100644 --- a/src/gromacs/mdlib/freeenergyparameters.cpp +++ b/src/gromacs/mdlib/freeenergyparameters.cpp @@ -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. @@ -39,11 +39,14 @@ * \author Christian Blau */ +#include #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 lambdasAtState(const int stateIndex, double** const lambdaArray, const int lambdaArrayExtent) +gmx::EnumerationArray +lambdasAtState(const int stateIndex, gmx::ArrayRef> lambdaArray, const int lambdaArrayExtent) { - std::array lambda; + gmx::EnumerationArray 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(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 interpolatedLambdas(const double currentGlobalLambda, - double** const lambdaArray, - const int lambdaArrayExtent) +gmx::EnumerationArray +interpolatedLambdas(const double currentGlobalLambda, + gmx::ArrayRef> lambdaArray, + const int lambdaArrayExtent) { - std::array lambda; + gmx::EnumerationArray lambda; // when there is no lambda value array, set all lambdas to steps * deltaLambdaPerStep if (lambdaArrayExtent <= 0) { @@ -127,7 +132,7 @@ std::array 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(FreeEnergyPerturbationCouplingType::Count); i++) { lambda[i] = lambdaArray[i][0]; } @@ -135,7 +140,7 @@ std::array interpolatedLambdas(const double currentGlobalLambda, } if (currentGlobalLambda >= 1) { - for (int i = 0; i < efptNR; i++) + for (int i = 0; i < static_cast(FreeEnergyPerturbationCouplingType::Count); i++) { lambda[i] = lambdaArray[i][lambdaArrayExtent - 1]; } @@ -147,7 +152,7 @@ std::array 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(FreeEnergyPerturbationCouplingType::Count); i++) { lambda[i] = lambdaArray[i][fepStateLeft] + fracBetween * (lambdaArray[i][fepStateRight] - lambdaArray[i][fepStateLeft]); @@ -157,7 +162,8 @@ std::array interpolatedLambdas(const double currentGlobalLambda, } // namespace -std::array currentLambdas(const int64_t step, const t_lambda& fepvals, const int currentLambdaState) +gmx::EnumerationArray +currentLambdas(const int64_t step, const t_lambda& fepvals, const int currentLambdaState) { if (fepvals.delta_lambda == 0) { @@ -171,7 +177,7 @@ std::array currentLambdas(const int64_t step, const t_lambda& fepv return lambdasAtState(fepvals.init_fep_state, fepvals.all_lambda, fepvals.n_lambda); } - std::array lambdas; + gmx::EnumerationArray lambdas; std::fill(std::begin(lambdas), std::end(lambdas), fepvals.init_lambda); return lambdas; } diff --git a/src/gromacs/mdlib/freeenergyparameters.h b/src/gromacs/mdlib/freeenergyparameters.h index 0814bc6c88..aaa8307166 100644 --- a/src/gromacs/mdlib/freeenergyparameters.h +++ b/src/gromacs/mdlib/freeenergyparameters.h @@ -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 #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 currentLambdas(int64_t step, const t_lambda& fepvals, int currentLambdaState); +gmx::EnumerationArray currentLambdas(int64_t step, + const t_lambda& fepvals, + int currentLambdaState); } // namespace gmx diff --git a/src/gromacs/mdlib/lincs.cpp b/src/gromacs/mdlib/lincs.cpp index 582676445a..5726cd0fb3 100644 --- a/src/gromacs/mdlib/lincs.cpp +++ b/src/gromacs/mdlib/lincs.cpp @@ -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) { diff --git a/src/gromacs/mdlib/md_support.cpp b/src/gromacs/mdlib/md_support.cpp index 176ef3d751..8104b92d00 100644 --- a/src/gromacs/mdlib/md_support.cpp +++ b/src/gromacs/mdlib/md_support.cpp @@ -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(dvdl_ekin); + enerd->dvdl_lin[FreeEnergyPerturbationCouplingType::Mass] = static_cast(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); diff --git a/src/gromacs/mdlib/mdatoms.cpp b/src/gromacs/mdlib/mdatoms.cpp index 22f3ce96a1..5ca3166ab0 100644 --- a/src/gromacs/mdlib/mdatoms.cpp +++ b/src/gromacs/mdlib/mdatoms.cpp @@ -160,7 +160,7 @@ std::unique_ptr 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 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 diff --git a/src/gromacs/mdlib/mdebin_bar.cpp b/src/gromacs/mdlib/mdebin_bar.cpp index 8c2791b2fd..f51603f836 100644 --- a/src/gromacs/mdlib/mdebin_bar.cpp +++ b/src/gromacs/mdlib/mdebin_bar.cpp @@ -37,6 +37,7 @@ */ #include "gmxpre.h" +#include "gromacs/utility/arrayref.h" #include "mdebin_bar.h" #include @@ -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(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 dhdl, + double* foreign_dU, + double time) { int i; diff --git a/src/gromacs/mdlib/mdebin_bar.h b/src/gromacs/mdlib/mdebin_bar.h index b1dacb29aa..7c852b7d3a 100644 --- a/src/gromacs/mdlib/mdebin_bar.h +++ b/src/gromacs/mdlib/mdebin_bar.h @@ -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 dhdl, + double* foreign_dU, + double time); /* write the data associated with the du blocks collection as a collection of mdebin blocks. diff --git a/src/gromacs/mdlib/mdoutf.cpp b/src/gromacs/mdlib/mdoutf.cpp index 4b73bf6ad8..7efa543cce 100644 --- a/src/gromacs/mdlib/mdoutf.cpp +++ b/src/gromacs/mdlib/mdoutf.cpp @@ -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); } diff --git a/src/gromacs/mdlib/perf_est.cpp b/src/gromacs/mdlib/perf_est.cpp index 765eed2dc7..bd2e21def1 100644 --- a/src/gromacs/mdlib/perf_est.cpp +++ b/src/gromacs/mdlib/perf_est.cpp @@ -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 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; diff --git a/src/gromacs/mdlib/rbin.cpp b/src/gromacs/mdlib/rbin.cpp index d499c94034..0816c06bcd 100644 --- a/src/gromacs/mdlib/rbin.cpp +++ b/src/gromacs/mdlib/rbin.cpp @@ -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 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 r) +{ + extract_bind(b, index, r.size(), r.data()); +} diff --git a/src/gromacs/mdlib/rbin.h b/src/gromacs/mdlib/rbin.h index 20cf110ab7..3d1bb3dff9 100644 --- a/src/gromacs/mdlib/rbin.h +++ b/src/gromacs/mdlib/rbin.h @@ -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 r); int add_bind(t_bin* b, int nr, const double r[]); +int add_bind(t_bin* b, gmx::ArrayRef 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 r); void extract_bind(t_bin* b, int index, int nr, double r[]); +void extract_bind(t_bin* b, int index, gmx::ArrayRef r); /* Extract values from the bin, starting from index (see add_bin) */ #endif diff --git a/src/gromacs/mdlib/rf_util.cpp b/src/gromacs/mdlib/rf_util.cpp index fd02d2d752..4584876236 100644 --- a/src/gromacs/mdlib/rf_util.cpp +++ b/src/gromacs/mdlib/rf_util.cpp @@ -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, diff --git a/src/gromacs/mdlib/shake.cpp b/src/gromacs/mdlib/shake.cpp index e638fc993a..80e2deee7e 100644 --- a/src/gromacs/mdlib/shake.cpp +++ b/src/gromacs/mdlib/shake.cpp @@ -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 iparams = idef.iparams; diff --git a/src/gromacs/mdlib/sim_util.cpp b/src/gromacs/mdlib/sim_util.cpp index b6b21dad6b..a18add2753 100644 --- a/src/gromacs/mdlib/sim_util.cpp +++ b/src/gromacs/mdlib/sim_util.cpp @@ -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(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(FreeEnergyPerturbationCouplingType::Coul)]) + * dipoleData->muStateAB[0][j] + + lambda[static_cast(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(FreeEnergyPerturbationCouplingType::Coul)], + lambda[static_cast(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(FreeEnergyPerturbationCouplingType::Coul)], + lambda[static_cast(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(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(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(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(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(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(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)) { diff --git a/src/gromacs/mdlib/stat.cpp b/src/gromacs/mdlib/stat.cpp index 1ec865802a..fa522f3537 100644 --- a/src/gromacs/mdlib/stat.cpp +++ b/src/gromacs/mdlib/stat.cpp @@ -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]); diff --git a/src/gromacs/mdlib/tests/constrtestdata.cpp b/src/gromacs/mdlib/tests/constrtestdata.cpp index 3de0c11b89..d1819bc7df 100644 --- a/src/gromacs/mdlib/tests/constrtestdata.cpp +++ b/src/gromacs/mdlib/tests/constrtestdata.cpp @@ -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; } diff --git a/src/gromacs/mdlib/tests/energyoutput.cpp b/src/gromacs/mdlib/tests/energyoutput.cpp index 7755ecdfbd..49417a41f5 100644 --- a/src/gromacs/mdlib/tests/energyoutput.cpp +++ b/src/gromacs/mdlib/tests/energyoutput.cpp @@ -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); diff --git a/src/gromacs/mdlib/tests/expanded.cpp b/src/gromacs/mdlib/tests/expanded.cpp index 887a7913f3..9485d8e2a1 100644 --- a/src/gromacs/mdlib/tests/expanded.cpp +++ b/src/gromacs/mdlib/tests/expanded.cpp @@ -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::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; +using RegressionTuple = std::tuple; class CalculateAcceptanceWeightRangeRegression : public ::testing::Test, public ::testing::WithParamInterface @@ -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 diff --git a/src/gromacs/mdlib/tests/freeenergyparameters.cpp b/src/gromacs/mdlib/tests/freeenergyparameters.cpp index a6ea79624d..d6d085bcfb 100644 --- a/src/gromacs/mdlib/tests/freeenergyparameters.cpp +++ b/src/gromacs/mdlib/tests/freeenergyparameters.cpp @@ -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 expectedLambdas = { -1, -1, -1, -1, -1, -1, -1 }; + gmx::EnumerationArray 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> 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 allLambda_; + gmx::EnumerationArray> allLambda_; //! a set of default lambda arrays for different lengths std::vector> defaultLambdaArrayForTest_ = { {}, { 0.8 }, { 0.2, 0.8 }, { 0.2, 0.8, 0.8 } }; }; diff --git a/src/gromacs/mdlib/tests/leapfrogtestdata.cpp b/src/gromacs/mdlib/tests/leapfrogtestdata.cpp index 5a1e2cbf45..8ae0a74051 100644 --- a/src/gromacs/mdlib/tests/leapfrogtestdata.cpp +++ b/src/gromacs/mdlib/tests/leapfrogtestdata.cpp @@ -150,7 +150,7 @@ LeapFrogTestData::LeapFrogTestData(int numAtoms, } } - inputRecord_.eI = eiMD; + inputRecord_.eI = IntegrationAlgorithm::MD; inputRecord_.delta_t = timestep_; state_.flags = 0; diff --git a/src/gromacs/mdlib/update.cpp b/src/gromacs/mdlib/update.cpp index 229a029209..daff232482 100644 --- a/src/gromacs/mdlib/update.cpp +++ b/src/gromacs/mdlib/update.cpp @@ -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(), state->box, - state->lambda[efptBONDED], + state->lambda[static_cast(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& 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 diff --git a/src/gromacs/mdlib/update_vv.cpp b/src/gromacs/mdlib/update_vv.cpp index 9026ae51ae..2b92b3fd97 100644 --- a/src/gromacs/mdlib/update_vv.cpp +++ b/src/gromacs/mdlib/update_vv.cpp @@ -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 */ diff --git a/src/gromacs/mdlib/vcm.cpp b/src/gromacs/mdlib/vcm.cpp index 1f1691f1b8..da4ee32808 100644 --- a/src/gromacs/mdlib/vcm.cpp +++ b/src/gromacs/mdlib/vcm.cpp @@ -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. @@ -58,16 +58,16 @@ 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 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 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 x, gmx::ArrayRef 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); diff --git a/src/gromacs/mdlib/vcm.h b/src/gromacs/mdlib/vcm.h index b0c1424741..eb33b56e42 100644 --- a/src/gromacs/mdlib/vcm.h +++ b/src/gromacs/mdlib/vcm.h @@ -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 #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 diff --git a/src/gromacs/mdlib/wall.cpp b/src/gromacs/mdlib/wall.cpp index d26a50313b..61cb4720ea 100644 --- a/src/gromacs/mdlib/wall.cpp +++ b/src/gromacs/mdlib/wall.cpp @@ -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; diff --git a/src/gromacs/mdrun/legacysimulator.cpp b/src/gromacs/mdrun/legacysimulator.cpp index c6687d7c3a..8859945fcc 100644 --- a/src/gromacs/mdrun/legacysimulator.cpp +++ b/src/gromacs/mdrun/legacysimulator.cpp @@ -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")); } } diff --git a/src/gromacs/mdrun/md.cpp b/src/gromacs/mdrun/md.cpp index f161798d84..254e4d8e61 100644 --- a/src/gromacs/mdrun/md.cpp +++ b/src/gromacs/mdrun/md.cpp @@ -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() - : makeArrayRef(state->x); + auto x = (vcm.mode == ComRemovalAlgorithm::LinearAccelerationCorrection) + ? ArrayRef() + : 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, diff --git a/src/gromacs/mdrun/mimic.cpp b/src/gromacs/mdrun/mimic.cpp index d65d8b7898..e258a8a2c5 100644 --- a/src/gromacs/mdrun/mimic.cpp +++ b/src/gromacs/mdrun/mimic.cpp @@ -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, diff --git a/src/gromacs/mdrun/minimize.cpp b/src/gromacs/mdrun/minimize.cpp index a066a52655..2b0ad5dc61 100644 --- a/src/gromacs/mdrun/minimize.cpp +++ b/src/gromacs/mdrun/minimize.cpp @@ -396,7 +396,7 @@ static void init_em(FILE* fplog, gmx::ArrayRef lambda = MASTER(cr) ? state_global->lambda : gmx::ArrayRef(); 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(), ems->s.box, - ems->s.lambda[efptFEP], + ems->s.lambda[FreeEnergyPerturbationCouplingType::Fep], &dvdl_constr, gmx::ArrayRefWithPadding(), computeVirial, @@ -743,7 +743,7 @@ static bool do_em_step(const t_commrec* cr, s2->x.arrayRefWithPadding(), ArrayRef(), s2->box, - s2->lambda[efptBONDED], + s2->lambda[FreeEnergyPerturbationCouplingType::Bonded], &dvdl_constr, gmx::ArrayRefWithPadding(), 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(), 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); } diff --git a/src/gromacs/mdrun/replicaexchange.cpp b/src/gromacs/mdrun/replicaexchange.cpp index e23bea4250..d813cfdc97 100644 --- a/src/gromacs/mdrun/replicaexchange.cpp +++ b/src/gromacs/mdrun/replicaexchange.cpp @@ -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(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(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(ir->epc), "the pressure coupling", FALSE); - check_multi_int(fplog, ms, ir->efep, "free energy", FALSE); + check_multi_int(fplog, ms, static_cast(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(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]; } diff --git a/src/gromacs/mdrun/rerun.cpp b/src/gromacs/mdrun/rerun.cpp index 91857cb1c0..69bf4d661a 100644 --- a/src/gromacs/mdrun/rerun.cpp +++ b/src/gromacs/mdrun/rerun.cpp @@ -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(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, diff --git a/src/gromacs/mdrun/runner.cpp b/src/gromacs/mdrun/runner.cpp index f3dcf76548..dce96b70ae 100644 --- a/src/gromacs/mdrun/runner.cpp +++ b/src/gromacs/mdrun/runner.cpp @@ -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( diff --git a/src/gromacs/mdrun/shellfc.cpp b/src/gromacs/mdrun/shellfc.cpp index 7521606b7b..92d48683e6 100644 --- a/src/gromacs/mdrun/shellfc.cpp +++ b/src/gromacs/mdrun/shellfc.cpp @@ -907,8 +907,8 @@ static void init_adir(gmx_shellfc_t* shfc, shfc->adir_xnold.arrayRefWithPadding(), {}, box, - lambda[efptBONDED], - &(dvdlambda[efptBONDED]), + lambda[static_cast(FreeEnergyPerturbationCouplingType::Bonded)], + &(dvdlambda[static_cast(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(FreeEnergyPerturbationCouplingType::Bonded)], + &(dvdlambda[static_cast(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(FreeEnergyPerturbationCouplingType::Bonded)], + &(dvdlambda[static_cast(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); diff --git a/src/gromacs/mdrun/tpi.cpp b/src/gromacs/mdrun/tpi.cpp index 2adb328745..2eda488785 100644 --- a/src/gromacs/mdrun/tpi.cpp +++ b/src/gromacs/mdrun/tpi.cpp @@ -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) diff --git a/src/gromacs/mdtypes/awh_params.h b/src/gromacs/mdtypes/awh_params.h index 951a7d2590..c047978b15 100644 --- a/src/gromacs/mdtypes/awh_params.h +++ b/src/gromacs/mdtypes/awh_params.h @@ -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. */ diff --git a/src/gromacs/mdtypes/enerdata.h b/src/gromacs/mdtypes/enerdata.h index 70ce4f66ef..f2d18f7b40 100644 --- a/src/gromacs/mdtypes/enerdata.h +++ b/src/gromacs/mdtypes/enerdata.h @@ -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 dvdl_lin = { 0 }; //! Contributions to dV/dlambda with non-linear dependence on lambda - double dvdl_nonlin[efptNR] = { 0 }; + gmx::EnumerationArray 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 diff --git a/src/gromacs/mdtypes/fcdata.h b/src/gromacs/mdtypes/fcdata.h index 09dce8f273..e8de62a0b6 100644 --- a/src/gromacs/mdtypes/fcdata.h +++ b/src/gromacs/mdtypes/fcdata.h @@ -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. @@ -45,31 +45,33 @@ #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 */ diff --git a/src/gromacs/mdtypes/forcerec.h b/src/gromacs/mdtypes/forcerec.h index 8c1d150015..c324f07400 100644 --- a/src/gromacs/mdtypes/forcerec.h +++ b/src/gromacs/mdtypes/forcerec.h @@ -173,9 +173,9 @@ private: //! Shift force array for computing the virial, size SHIFTS std::vector 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 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; @@ -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; diff --git a/src/gromacs/mdtypes/inputrec.cpp b/src/gromacs/mdtypes/inputrec.cpp index 903e3ef62e..e5abdb4f5e 100644 --- a/src/gromacs/mdtypes/inputrec.cpp +++ b/src/gromacs/mdtypes/inputrec.cpp @@ -37,6 +37,7 @@ */ #include "gmxpre.h" +#include "gromacs/utility/enumerationhelpers.h" #include "inputrec.h" #include @@ -44,6 +45,7 @@ #include #include +#include #include #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(); + expandedvals = std::make_unique(); + simtempvals = std::make_unique(); } 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::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::keys()) { - fprintf(fp, "%18s = ", efpt_names[i]); + fprintf(fp, "%18s = ", enumValueToString(key)); + int i = static_cast(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(SwapGroupSplittingType::Solvent)].molname); + pr_ivec_block(fp, + indent, + str, + swap->grp[static_cast(SwapGroupSplittingType::Solvent)].ind, + swap->grp[static_cast(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(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(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(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(ir1->pbcType), static_cast(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(ir1->bPrintNHChains), static_cast(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(ir1->bSimTemp), static_cast(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(ir1->bDisreMixed), static_cast(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) diff --git a/src/gromacs/mdtypes/inputrec.h b/src/gromacs/mdtypes/inputrec.h index dc2350acd7..4ca33733b7 100644 --- a/src/gromacs/mdtypes/inputrec.h +++ b/src/gromacs/mdtypes/inputrec.h @@ -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> 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 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 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 fepvals; //! Whether to do simulated tempering gmx_bool bSimTemp; //! Variables for simulated tempering - t_simtemp* simtempvals; + std::unique_ptr simtempvals; //! Whether expanded ensembles are used gmx_bool bExpanded; //! Expanded ensemble parameters - t_expanded* expandedvals; + std::unique_ptr 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; diff --git a/src/gromacs/mdtypes/interaction_const.h b/src/gromacs/mdtypes/interaction_const.h index 37812ee2b3..e112758411 100644 --- a/src/gromacs/mdtypes/interaction_const.h +++ b/src/gromacs/mdtypes/interaction_const.h @@ -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; diff --git a/src/gromacs/mdtypes/md_enums.cpp b/src/gromacs/mdtypes/md_enums.cpp index 53a24a3a11..d8999ba87c 100644 --- a/src/gromacs/mdtypes/md_enums.cpp +++ b/src/gromacs/mdtypes/md_enums.cpp @@ -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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 dhdlDerivativeCalculationNames = { + "yes", "no" + }; + return dhdlDerivativeCalculationNames[enumValue]; +} + +const char* enumValueToString(SolventModel enumValue) +{ + static constexpr gmx::EnumerationArray solventModelNames = { + "No", "SPC", "TIP4p" + }; + return solventModelNames[enumValue]; +} + +const char* enumValueToString(DispersionCorrectionType enumValue) +{ + static constexpr gmx::EnumerationArray dispersionCorrectionTypeNames = { + "No", "EnerPres", "Ener", "AllEnerPres", "AllEner" + }; + return dispersionCorrectionTypeNames[enumValue]; +} + +const char* enumValueToString(ComRemovalAlgorithm enumValue) +{ + static constexpr gmx::EnumerationArray 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 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 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 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 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 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 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 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 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 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 nbkernelVdwTypeNames = { + "None", "Lennard-Jones", "Buckingham", "Cubic-Spline-Table", "LJEwald" + }; + return nbkernelVdwTypeNames[enumValue]; +} diff --git a/src/gromacs/mdtypes/md_enums.h b/src/gromacs/mdtypes/md_enums.h index 3728713a30..58a99ab465 100644 --- a/src/gromacs/mdtypes/md_enums.h +++ b/src/gromacs/mdtypes/md_enums.h @@ -60,8 +60,20 @@ */ 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 */ diff --git a/src/gromacs/mdtypes/multipletimestepping.cpp b/src/gromacs/mdtypes/multipletimestepping.cpp index 177dba0e6f..2bd5072a80 100644 --- a/src/gromacs/mdtypes/multipletimestepping.cpp +++ b/src/gromacs/mdtypes/multipletimestepping.cpp @@ -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 checkMtsRequirements(const t_inputrec& ir) ArrayRef 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 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))) { diff --git a/src/gromacs/mdtypes/nblist.h b/src/gromacs/mdtypes/nblist.h index 3b6e5b145f..63fc565ae7 100644 --- a/src/gromacs/mdtypes/nblist.h +++ b/src/gromacs/mdtypes/nblist.h @@ -39,6 +39,7 @@ #include +#include "gromacs/mdtypes/md_enums.h" #include "gromacs/utility/alignedallocator.h" #include "gromacs/utility/real.h" diff --git a/src/gromacs/mdtypes/pull_params.h b/src/gromacs/mdtypes/pull_params.h index c0709ca353..ab81d886ed 100644 --- a/src/gromacs/mdtypes/pull_params.h +++ b/src/gromacs/mdtypes/pull_params.h @@ -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: diff --git a/src/gromacs/mdtypes/state.cpp b/src/gromacs/mdtypes/state.cpp index 1cceba8f80..dfb55ef30d 100644 --- a/src/gromacs/mdtypes/state.cpp +++ b/src/gromacs/mdtypes/state.cpp @@ -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(FreeEnergyPerturbationCouplingType::Count); i++) { double thisLambda; /* overwrite lambda state with init_lambda for now for backwards compatibility */ diff --git a/src/gromacs/mdtypes/state.h b/src/gromacs/mdtypes/state.h index 1d98934318..b4e5d7042b 100644 --- a/src/gromacs/mdtypes/state.h +++ b/src/gromacs/mdtypes/state.h @@ -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 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 nosehoover_xi; //!< Nose-Hoover coordinates (ngtc) - std::vector nosehoover_vxi; //!< Nose-Hoover velocities (ngtc) - std::vector nhpres_xi; //!< Pressure Nose-Hoover coordinates - std::vector nhpres_vxi; //!< Pressure Nose-Hoover velocities - std::vector 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 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 nosehoover_xi; //!< Nose-Hoover coordinates (ngtc) + std::vector nosehoover_vxi; //!< Nose-Hoover velocities (ngtc) + std::vector nhpres_xi; //!< Pressure Nose-Hoover coordinates + std::vector nhpres_vxi; //!< Pressure Nose-Hoover velocities + std::vector 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 x; //!< The coordinates (natoms) PaddedHostVector v; //!< The velocities (natoms) PaddedHostVector cg_p; //!< p vector for conjugate gradient minimization diff --git a/src/gromacs/mdtypes/swaphistory.h b/src/gromacs/mdtypes/swaphistory.h index aeb26465c1..81b8a88ff4 100644 --- a/src/gromacs/mdtypes/swaphistory.h +++ b/src/gromacs/mdtypes/swaphistory.h @@ -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 diff --git a/src/gromacs/mdtypes/tests/multipletimestepping.cpp b/src/gromacs/mdtypes/tests/multipletimestepping.cpp index f69a45a650..e9fdc2e27c 100644 --- a/src/gromacs/mdtypes/tests/multipletimestepping.cpp +++ b/src/gromacs/mdtypes/tests/multipletimestepping.cpp @@ -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); } diff --git a/src/gromacs/modularsimulator/computeglobalselement.cpp b/src/gromacs/modularsimulator/computeglobalselement.cpp index 3bca8ed4a0..1d59ae9063 100644 --- a/src/gromacs/modularsimulator/computeglobalselement.cpp +++ b/src/gromacs/modularsimulator/computeglobalselement.cpp @@ -84,7 +84,7 @@ ComputeGlobalsElement::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::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() - : statePropagatorData_->positionsView(); + auto x = vcm_.mode == ComRemovalAlgorithm::LinearAccelerationCorrection + ? ArrayRefWithPadding() + : statePropagatorData_->positionsView(); process_and_stopcm_grp( fplog_, &vcm_, *mdAtoms_->mdatoms(), x.unpaddedArrayRef(), v.unpaddedArrayRef()); inc_nrnb(nrnb_, eNR_STOPCM, mdAtoms_->mdatoms()->homenr); diff --git a/src/gromacs/modularsimulator/constraintelement.cpp b/src/gromacs/modularsimulator/constraintelement.cpp index bba9ffa92e..06383b3603 100644 --- a/src/gromacs/modularsimulator/constraintelement.cpp +++ b/src/gromacs/modularsimulator/constraintelement.cpp @@ -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 void ConstraintsElement::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( + FreeEnergyPerturbationCouplingType::Bonded)] + : 0; // Constrain the initial coordinates and velocities do_constrain_first(fplog_, constr_, @@ -107,7 +109,7 @@ void ConstraintsElement::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::apply(Step step, bool calculateVirial, bool w ArrayRefWithPadding v; const real lambdaBonded = - freeEnergyPerturbationData_ ? freeEnergyPerturbationData_->constLambdaView()[efptBONDED] : 0; + freeEnergyPerturbationData_ + ? freeEnergyPerturbationData_ + ->constLambdaView()[static_cast(FreeEnergyPerturbationCouplingType::Bonded)] + : 0; real dvdlambda = 0; switch (variable) @@ -179,7 +184,7 @@ void ConstraintsElement::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. diff --git a/src/gromacs/modularsimulator/energydata.cpp b/src/gromacs/modularsimulator/energydata.cpp index 3cda75f3ce..49b53fade8 100644 --- a/src/gromacs/modularsimulator/energydata.cpp +++ b/src/gromacs/modularsimulator/energydata.cpp @@ -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, {}, diff --git a/src/gromacs/modularsimulator/forceelement.cpp b/src/gromacs/modularsimulator/forceelement.cpp index 9b4fb32536..cce364f9fc 100644 --- a/src/gromacs/modularsimulator/forceelement.cpp +++ b/src/gromacs/modularsimulator/forceelement.cpp @@ -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)) { diff --git a/src/gromacs/modularsimulator/forceelement.h b/src/gromacs/modularsimulator/forceelement.h index 0ee81e0430..3e5318a282 100644 --- a/src/gromacs/modularsimulator/forceelement.h +++ b/src/gromacs/modularsimulator/forceelement.h @@ -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 lambda_; + gmx::EnumerationArray lambda_; // Access to ISimulator data //! Handles logging. diff --git a/src/gromacs/modularsimulator/freeenergyperturbationdata.cpp b/src/gromacs/modularsimulator/freeenergyperturbationdata.cpp index 7065c44b17..d780e69216 100644 --- a/src/gromacs/modularsimulator/freeenergyperturbationdata.cpp +++ b/src/gromacs/modularsimulator/freeenergyperturbationdata.cpp @@ -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 diff --git a/src/gromacs/modularsimulator/freeenergyperturbationdata.h b/src/gromacs/modularsimulator/freeenergyperturbationdata.h index 25c2a52916..7ef19d86f1 100644 --- a/src/gromacs/modularsimulator/freeenergyperturbationdata.h +++ b/src/gromacs/modularsimulator/freeenergyperturbationdata.h @@ -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_; //! The lambda vector - std::array lambda_; + gmx::EnumerationArray lambda_; //! The current free energy state int currentFEPState_; diff --git a/src/gromacs/modularsimulator/modularsimulator.cpp b/src/gromacs/modularsimulator/modularsimulator.cpp index d43052c48f..fbb962be3d 100644 --- a/src/gromacs/modularsimulator/modularsimulator.cpp +++ b/src/gromacs/modularsimulator/modularsimulator.cpp @@ -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(); @@ -131,7 +131,7 @@ void ModularSimulator::addIntegrationElements(ModularSimulatorAlgorithmBuilder* builder->add(-1); } } - else if (legacySimulatorData_->inputrec->eI == eiVV) + else if (legacySimulatorData_->inputrec->eI == IntegrationAlgorithm::VV) { // The velocity verlet integration algorithm builder->add(); @@ -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."); diff --git a/src/gromacs/modularsimulator/parrinellorahmanbarostat.cpp b/src/gromacs/modularsimulator/parrinellorahmanbarostat.cpp index 95f0bab2d3..81085d0cda 100644 --- a/src/gromacs/modularsimulator/parrinellorahmanbarostat.cpp +++ b/src/gromacs/modularsimulator/parrinellorahmanbarostat.cpp @@ -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); } diff --git a/src/gromacs/modularsimulator/pmeloadbalancehelper.cpp b/src/gromacs/modularsimulator/pmeloadbalancehelper.cpp index 7c31518acc..e8be0aba8f 100644 --- a/src/gromacs/modularsimulator/pmeloadbalancehelper.cpp +++ b/src/gromacs/modularsimulator/pmeloadbalancehelper.cpp @@ -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, diff --git a/src/gromacs/modularsimulator/simulatoralgorithm.cpp b/src/gromacs/modularsimulator/simulatoralgorithm.cpp index d1e8cb5207..29e24c013f 100644 --- a/src/gromacs/modularsimulator/simulatoralgorithm.cpp +++ b/src/gromacs/modularsimulator/simulatoralgorithm.cpp @@ -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( legacySimulatorData->fplog, legacySimulatorData->inputrec, legacySimulatorData->mdAtoms); diff --git a/src/gromacs/modularsimulator/statepropagatordata.cpp b/src/gromacs/modularsimulator/statepropagatordata.cpp index ce7a3c8618..99406066fe 100644 --- a/src/gromacs/modularsimulator/statepropagatordata.cpp +++ b/src/gromacs/modularsimulator/statepropagatordata.cpp @@ -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::size(); + ++i) { localStateBackup_->lambda[i] = freeEnergyPerturbationData_->constLambdaView()[i]; } diff --git a/src/gromacs/nbnxm/benchmark/bench_setup.cpp b/src/gromacs/nbnxm/benchmark/bench_setup.cpp index 78c333b7b2..32d03cc882 100644 --- a/src/gromacs/nbnxm/benchmark/bench_setup.cpp +++ b/src/gromacs/nbnxm/benchmark/bench_setup.cpp @@ -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 diff --git a/src/gromacs/nbnxm/cuda/nbnxm_cuda_data_mgmt.cu b/src/gromacs/nbnxm/cuda/nbnxm_cuda_data_mgmt.cu index dff7e4d21c..db8654440e 100644 --- a/src/gromacs/nbnxm/cuda/nbnxm_cuda_data_mgmt.cu +++ b/src/gromacs/nbnxm/cuda/nbnxm_cuda_data_mgmt.cu @@ -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); diff --git a/src/gromacs/nbnxm/kerneldispatch.cpp b/src/gromacs/nbnxm/kerneldispatch.cpp index 1952bf3d0c..ae9edafd6a 100644 --- a/src/gromacs/nbnxm/kerneldispatch.cpp +++ b/src/gromacs/nbnxm/kerneldispatch.cpp @@ -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(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(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 lambda, + gmx::ArrayRef 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 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 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(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); diff --git a/src/gromacs/nbnxm/nbnxm_gpu_data_mgmt.cpp b/src/gromacs/nbnxm/nbnxm_gpu_data_mgmt.cpp index 344e69d54e..aad56f4915 100644 --- a/src/gromacs/nbnxm/nbnxm_gpu_data_mgmt.cpp +++ b/src/gromacs/nbnxm/nbnxm_gpu_data_mgmt.cpp @@ -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)))); } } diff --git a/src/gromacs/nbnxm/nbnxm_setup.cpp b/src/gromacs/nbnxm/nbnxm_setup.cpp index 0cfaf9053b..193af53cbe 100644 --- a/src/gromacs/nbnxm/nbnxm_setup.cpp +++ b/src/gromacs/nbnxm/nbnxm_setup.cpp @@ -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 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); diff --git a/src/gromacs/nbnxm/opencl/nbnxm_ocl_data_mgmt.cpp b/src/gromacs/nbnxm/opencl/nbnxm_ocl_data_mgmt.cpp index 706c3a48d5..da998182ca 100644 --- a/src/gromacs/nbnxm/opencl/nbnxm_ocl_data_mgmt.cpp +++ b/src/gromacs/nbnxm/opencl/nbnxm_ocl_data_mgmt.cpp @@ -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 nbfp_comb; initParamLookupTable(&nbfp_comb, nullptr, nbatParams.nbfp_comb.data(), nnbfp_comb, deviceContext); diff --git a/src/gromacs/nbnxm/pairlist_tuning.cpp b/src/gromacs/nbnxm/pairlist_tuning.cpp index b2ffe801d2..f9f61db40f 100644 --- a/src/gromacs/nbnxm/pairlist_tuning.cpp +++ b/src/gromacs/nbnxm/pairlist_tuning.cpp @@ -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; } diff --git a/src/gromacs/nbnxm/sycl/nbnxm_sycl_data_mgmt.cpp b/src/gromacs/nbnxm/sycl/nbnxm_sycl_data_mgmt.cpp index a3d8626fc4..e033a507e8 100644 --- a/src/gromacs/nbnxm/sycl/nbnxm_sycl_data_mgmt.cpp +++ b/src/gromacs/nbnxm/sycl/nbnxm_sycl_data_mgmt.cpp @@ -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); diff --git a/src/gromacs/pulling/output.cpp b/src/gromacs/pulling/output.cpp index 627700a3b2..691a248872 100644 --- a/src/gromacs/pulling/output.cpp +++ b/src/gromacs/pulling/output.cpp @@ -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); diff --git a/src/gromacs/pulling/pull.cpp b/src/gromacs/pulling/pull.cpp index 4140acb066..41b5bbce40 100644 --- a/src/gromacs/pulling/pull.cpp +++ b/src/gromacs/pulling/pull.cpp @@ -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(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& 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(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; } diff --git a/src/gromacs/pulling/pull_rotation.cpp b/src/gromacs/pulling/pull_rotation.cpp index 40e4910c9b..c255c8d190 100644 --- a/src/gromacs/pulling/pull_rotation.cpp +++ b/src/gromacs/pulling/pull_rotation.cpp @@ -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 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); diff --git a/src/gromacs/pulling/pullutil.cpp b/src/gromacs/pulling/pullutil.cpp index cf9b7b45b1..ec15584183 100644 --- a/src/gromacs/pulling/pullutil.cpp +++ b/src/gromacs/pulling/pullutil.cpp @@ -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; } diff --git a/src/gromacs/pulling/tests/pull.cpp b/src/gromacs/pulling/tests/pull.cpp index d42ddc6580..1cf9f3e939 100644 --- a/src/gromacs/pulling/tests/pull.cpp +++ b/src/gromacs/pulling/tests/pull.cpp @@ -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; diff --git a/src/gromacs/swap/swapcoords.cpp b/src/gromacs/swap/swapcoords.cpp index 0bf9ba8ea3..2880c81e33 100644 --- a/src/gromacs/swap/swapcoords.cpp +++ b/src/gromacs/swap/swapcoords.cpp @@ -42,6 +42,7 @@ */ #include "gmxpre.h" +#include "gromacs/utility/enumerationhelpers.h" #include "swapcoords.h" #include @@ -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 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(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(SwapGroupSplittingType::Split0)].center[s->swapdim], + s->group[static_cast(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(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(SwapGroupSplittingType::Split0)].center[s->swapdim]; + pos1 = s->group[static_cast(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(SwapGroupSplittingType::Split0)].center, + sc->cyl0u, + sc->cyl0l, + cyl0_r2, + s->pbc, + sd); + in_cyl1 = is_in_channel(atomPosition, + s->group[static_cast(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(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(SwapGroupSplittingType::Count); ig < s->ngrp; ig++) { g = &s->group[ig]; - gs = &swapstate->ionType[ig - eSwapFixedGrpNR]; + gs = &swapstate->ionType[ig - static_cast(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(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(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(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(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(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(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(SwapGroupSplittingType::Count); ig < s->ngrp; ig++) { g = &s->group[ig]; - gs = &swapstate->ionType[ig - eSwapFixedGrpNR]; + gs = &swapstate->ionType[ig - static_cast(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(SwapGroupSplittingType::Count); ig < s->ngrp; ig++) { g = &s->group[ig]; - gs = &swapstate->ionType[ig - eSwapFixedGrpNR]; + gs = &swapstate->ionType[ig - static_cast(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(SwapGroupSplittingType::Count); ig < s->ngrp; ig++) { g = &s->group[ig]; - gs = &swapstate->ionType[ig - eSwapFixedGrpNR]; + gs = &swapstate->ionType[ig - static_cast(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(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(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(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(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(SwapGroupSplittingType::Split0); + ig <= static_cast(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(SwapGroupSplittingType::Split0)].atomset.numAtomsGlobal(); + swapstate->nat[eChan1] = + s->group[static_cast(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(SwapGroupSplittingType::Split0)].xc_old; + swapstate->xc_old_whole_p[eChan1] = &s->group[static_cast(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(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(SwapGroupSplittingType::Split0)) + || (i == static_cast(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(SwapGroupSplittingType::Split0); + ig <= static_cast(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(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(SwapGroupSplittingType::Split0); + j <= static_cast(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(ig); + g = &(s->group[ig]); fprintf(s->fpout, "# %s group '%s' contains %d atom%s", - ig < eSwapFixedGrpNR ? eSwapFixedGrp_names[ig] : "Ion", + ig < static_cast(SwapGroupSplittingType::Count) ? enumValueToString(enumValue) + : "Ion", g->molname, static_cast(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(SwapGroupSplittingType::Split0); + j <= static_cast(SwapGroupSplittingType::Split1); + j++) { - g = &(s->group[j]); + auto enumValue = static_cast(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(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(SwapGroupSplittingType::Count); ig < s->ngrp; ig++) { g = &s->group[ig]; - gs = &swapstate->ionType[ig - eSwapFixedGrpNR]; + gs = &swapstate->ionType[ig - static_cast(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(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(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(SwapGroupSplittingType::Split0); + ig <= static_cast(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(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(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(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(SwapGroupSplittingType::Solvent)]; + for (ig = static_cast(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(SwapGroupSplittingType::Solvent); ig < s->ngrp; ig++) { g = &s->group[ig]; apply_modified_positions(g, x); diff --git a/src/gromacs/tables/forcetable.cpp b/src/gromacs/tables/forcetable.cpp index 3a8e169483..1006e07f1c 100644 --- a/src/gromacs/tables/forcetable.cpp +++ b/src/gromacs/tables/forcetable.cpp @@ -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 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 fullTable = make_tables(fp, ic, tabfn, rtab, 0); diff --git a/src/gromacs/taskassignment/decidegpuusage.cpp b/src/gromacs/taskassignment/decidegpuusage.cpp index 5d771e5265..fdbf1b32bc 100644 --- a/src/gromacs/taskassignment/decidegpuusage.cpp +++ b/src/gromacs/taskassignment/decidegpuusage.cpp @@ -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"; } diff --git a/src/gromacs/taskassignment/resourcedivision.cpp b/src/gromacs/taskassignment/resourcedivision.cpp index b1fdb52b74..c2a9e61881 100644 --- a/src/gromacs/taskassignment/resourcedivision.cpp +++ b/src/gromacs/taskassignment/resourcedivision.cpp @@ -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 diff --git a/src/gromacs/tools/check.cpp b/src/gromacs/tools/check.cpp index 740a7ffff4..856fcee292 100644 --- a/src/gromacs/tools/check.cpp +++ b/src/gromacs/tools/check.cpp @@ -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(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; diff --git a/src/gromacs/tools/report_methods.cpp b/src/gromacs/tools/report_methods.cpp index 9aba51b78d..809c0f375c 100644 --- a/src/gromacs/tools/report_methods.cpp +++ b/src/gromacs/tools/report_methods.cpp @@ -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 " diff --git a/src/gromacs/tools/tune_pme.cpp b/src/gromacs/tools/tune_pme.cpp index 5da73f7cb3..216fb0cf3e 100644 --- a/src/gromacs/tools/tune_pme.cpp +++ b/src/gromacs/tools/tune_pme.cpp @@ -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 */ diff --git a/src/gromacs/utility/enumerationhelpers.h b/src/gromacs/utility/enumerationhelpers.h index c74866f9a8..59ef2689d3 100644 --- a/src/gromacs/utility/enumerationhelpers.h +++ b/src/gromacs/utility/enumerationhelpers.h @@ -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 -struct EnumerationArray final +template +struct EnumerationArray final // NOLINT(readability-braces-around-statements) { //! Convenience alias using EnumerationWrapperType = EnumerationWrapper; + //! Convenience alias + using value_type = DataType; + /*! \brief Data for names. * * Data is kept public so we can use direct aggregate diff --git a/src/gromacs/utility/iserializer.h b/src/gromacs/utility/iserializer.h index ffa4dd6345..540047566e 100644 --- a/src/gromacs/utility/iserializer.h +++ b/src/gromacs/utility/iserializer.h @@ -190,6 +190,16 @@ public: doInt(&castedValue); *enumValue = static_cast(castedValue); } + + //! Serialize array of enum values with underlying type. + template + void doEnumArrayAsInt(EnumType* values, int elements) + { + for (int i = 0; i < elements; i++) + { + doEnumAsInt(&(values[i])); + } + } }; } // namespace gmx -- 2.22.0