builder->add<ForceElement>();
// We have a full state here (positions(t), velocities(t-dt/2), forces(t)
builder->add<StatePropagatorData::Element>();
- if (legacySimulatorData_->inputrec->etc == etcVRESCALE)
+ if (legacySimulatorData_->inputrec->etc == TemperatureCoupling::VRescale)
{
builder->add<VRescaleThermostat>(-1, VRescaleThermostatUseFullStepKE::No);
}
builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::LeapFrog>>();
// We have the energies at time t here
builder->add<EnergyData::Element>();
- if (legacySimulatorData_->inputrec->epc == epcPARRINELLORAHMAN)
+ if (legacySimulatorData_->inputrec->epc == PressureCoupling::ParrinelloRahman)
{
builder->add<ParrinelloRahmanBarostat>(-1);
}
{
for (int j = i + 1; j < ddbox.npbcdim; j++)
{
- if (box[j][i] != 0 || ir.deform[j][i] != 0 || (ir.epc != epcNO && ir.compress[j][i] != 0))
+ if (box[j][i] != 0 || ir.deform[j][i] != 0
+ || (ir.epc != PressureCoupling::No && ir.compress[j][i] != 0))
{
if (nc[j] > 1 && nc[i] == 1)
{
"Scaling the initial minimum size with 1/%g (option -dds) = %g", dlb_scale, 1 / dlb_scale);
cellSizeLimit /= dlb_scale;
}
- else if (ir.epc != epcNO)
+ else if (ir.epc != PressureCoupling::No)
{
GMX_LOG(mdlog.info)
.appendTextFormatted(
/*
* 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.
// TODO if the update code becomes accessible here, use
// upd->deform for this logic.
bBoxChanged = (bMasterState || inputrecDeform(ir));
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
/* With nstpcouple > 1 pressure coupling happens.
* one step after calculating the pressure.
* Since it requires (possibly expensive) global communication,
* we might want to do DLB less frequently.
*/
- if (bBoxChanged || ir->epc != epcNO)
+ if (bBoxChanged || ir->epc != PressureCoupling::No)
{
bDoDLB = bBoxChanged;
}
* 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.
}
npcoupl = TRICLINIC(ir->compress) ? 6 : 3;
- if (ir->epc == epcPARRINELLORAHMAN)
+ if (ir->epc == PressureCoupling::ParrinelloRahman)
{
clear_mat(state->boxv);
for (i = 0; i < npcoupl; i++)
fprintf(stderr, "\nREAD %d BOX VELOCITIES FROM %s\n\n", npcoupl, fn);
}
- if (ir->etc == etcNOSEHOOVER)
+ if (ir->etc == TemperatureCoupling::NoseHoover)
{
char cns[20];
* 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.
}
}
-static int get_einp(std::vector<t_inpfile>* inp, const char* name)
+int get_einp(std::vector<t_inpfile>* inp, const char* name)
{
std::vector<t_inpfile>& inpRef = *inp;
bool notfound = false;
* 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.
int get_eenum(std::vector<t_inpfile>* inp, const char* name, const char** defs);
/* defs must be NULL terminated */
+//! Get index of option `name`. Exposed here so that `getEnum` can access it.
+int get_einp(std::vector<t_inpfile>* inp, const char* name);
+
+/*! \brief Read option from input and return corresponding enum value
+ *
+ * If the option is not set, return the first value of the enum as default.
+ *
+ * \tparam EnumType The type of enum to be returned
+ * \param[in] inp The input file vector
+ * \param[in] name The name of the option to be read
+ * \param[out] wi Handler for context-sensitive warnings.
+ * \return Enum value corresponding to read input
+ */
+template<typename EnumType>
+EnumType getEnum(std::vector<t_inpfile>* inp, const char* name, warninp* wi);
+
//! Replace for macro CCTYPE, prints comment string after newline
void printStringNewline(std::vector<t_inpfile>* inp, const char* line);
//! Replace for macro CTYPE, prints comment string
serializer->doInt(&ir->ljpme_combination_rule);
}
serializer->doBool(&ir->bContinuation);
- serializer->doInt(&ir->etc);
+ serializer->doEnumAsInt(&ir->etc);
/* before version 18, ir->etc was a gmx_bool (ir->btc),
* but the values 0 and 1 still mean no and
* berendsen temperature coupling, respectively.
{
ir->nsttcouple = ir->nstcalcenergy;
}
- serializer->doInt(&ir->epc);
+ serializer->doEnumAsInt(&ir->epc);
serializer->doInt(&ir->epct);
if (file_version >= 71)
{
GMX_LOG(logger.info).asParagraph().appendTextFormatted("Using frame at t = %g ps", use_time);
GMX_LOG(logger.info).asParagraph().appendTextFormatted("Starting time for run is %g ps", ir->init_t);
- if ((ir->epc != epcNO || ir->etc == etcNOSEHOOVER) && ener)
+ if ((ir->epc != PressureCoupling::No || ir->etc == TemperatureCoupling::NoseHoover) && ener)
{
get_enx_state(ener, use_time, sys->groups, ir, state);
preserve_box_shape(ir, state->box_rel, state->boxv);
}
}
- if (EI_SD(ir->eI) && ir->etc != etcNO)
+ if (EI_SD(ir->eI) && ir->etc != TemperatureCoupling::No)
{
warning_note(wi, "Temperature coupling is ignored with SD integrators.");
}
if (nint_ftype(&sys, mi, F_POSRES) > 0 || nint_ftype(&sys, mi, F_FBPOSRES) > 0)
{
- if (ir->epc == epcPARRINELLORAHMAN || ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::ParrinelloRahman || ir->epc == PressureCoupling::Mttk)
{
std::string warningMessage = gmx::formatString(
"You are combining position restraints with %s pressure coupling, which can "
"lead to instabilities. If you really want to combine position restraints with "
"pressure coupling, we suggest to use %s pressure coupling instead.",
- EPCOUPLTYPE(ir->epc),
- EPCOUPLTYPE(epcBERENDSEN));
+ enumValueToString(ir->epc),
+ enumValueToString(PressureCoupling::Berendsen));
warning_note(wi, warningMessage);
}
{
real buffer_temp;
- if (EI_MD(ir->eI) && ir->etc == etcNO)
+ if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No)
{
if (bGenVel)
{
buffer_temp = get_max_reference_temp(ir, wi);
}
- if (EI_MD(ir->eI) && ir->etc == etcNO && buffer_temp == 0)
+ if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No && buffer_temp == 0)
{
/* NVE with initial T=0: we add a fixed ratio to rlist.
* Since we don't actually use verletbuf_tol, we set it to -1
* Note that we can't warn when nsteps=0, since we don't
* know how many steps the user intends to run.
*/
- if (EI_MD(ir->eI) && ir->etc == etcNO && ir->nstlist > 1 && ir->nsteps > 0)
+ if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No && ir->nstlist > 1 && ir->nsteps > 0)
{
const real driftTolerance = 0.01;
/* We use 2 DOF per atom = 2kT pot+kin energy,
if (ir->bDoAwh)
{
tensor compressibility = { { 0 } };
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
copy_mat(ir->compress, compressibility);
}
/* GENERAL INTEGRATOR STUFF */
if (!EI_MD(ir->eI))
{
- if (ir->etc != etcNO)
+ if (ir->etc != TemperatureCoupling::No)
{
if (EI_RANDOM(ir->eI))
{
"Setting tcoupl from '%s' to 'no'. %s handles temperature coupling "
"implicitly. See the documentation for more information on which "
"parameters affect temperature for %s.",
- etcoupl_names[ir->etc],
+ enumValueToString(ir->etc),
ei_names[ir->eI],
ei_names[ir->eI]);
}
sprintf(warn_buf,
"Setting tcoupl from '%s' to 'no'. Temperature coupling does not apply to "
"%s.",
- etcoupl_names[ir->etc],
+ enumValueToString(ir->etc),
ei_names[ir->eI]);
}
warning_note(wi, warn_buf);
}
- ir->etc = etcNO;
+ ir->etc = TemperatureCoupling::No;
}
if (ir->eI == eiVVAK)
{
}
if (!EI_DYNAMICS(ir->eI))
{
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
sprintf(warn_buf,
"Setting pcoupl from '%s' to 'no'. Pressure coupling does not apply to %s.",
- epcoupl_names[ir->epc],
+ enumValueToString(ir->epc),
ei_names[ir->eI]);
warning_note(wi, warn_buf);
}
- ir->epc = epcNO;
+ ir->epc = PressureCoupling::No;
}
if (EI_DYNAMICS(ir->eI))
{
ir->nstcalcenergy = min_nst;
}
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
if (ir->nstpcouple < 0)
{
/* check compatability of the temperature coupling with simulated tempering */
- if (ir->etc == etcNOSEHOOVER)
+ if (ir->etc == TemperatureCoupling::NoseHoover)
{
sprintf(warn_buf,
"Nose-Hoover based temperature control such as [%s] my not be "
"entirelyconsistent with simulated tempering",
- etcoupl_names[ir->etc]);
+ enumValueToString(ir->etc));
warning_note(wi, warn_buf);
}
{
if (ir->pbcType == PbcType::No)
{
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
warning(wi, "Turning off pressure coupling for vacuum system");
- ir->epc = epcNO;
+ ir->epc = PressureCoupling::No;
}
}
else
sprintf(err_buf,
"Can not have pressure coupling with pbc=%s",
c_pbcTypeNames[ir->pbcType].c_str());
- CHECK(ir->epc != epcNO);
+ CHECK(ir->epc != PressureCoupling::No);
}
sprintf(err_buf, "Can not have Ewald with pbc=%s", c_pbcTypeNames[ir->pbcType].c_str());
CHECK(EEL_FULL(ir->coulombtype));
}
/* TEMPERATURE COUPLING */
- if (ir->etc == etcYES)
+ if (ir->etc == TemperatureCoupling::Yes)
{
- ir->etc = etcBERENDSEN;
+ ir->etc = TemperatureCoupling::Berendsen;
warning_note(wi,
"Old option for temperature coupling given: "
"changing \"yes\" to \"Berendsen\"\n");
}
- if ((ir->etc == etcNOSEHOOVER) || (ir->epc == epcMTTK))
+ if ((ir->etc == TemperatureCoupling::NoseHoover) || (ir->epc == PressureCoupling::Mttk))
{
if (ir->opts.nhchainlength < 1)
{
warning(wi, warn_buf);
}
- if (ir->etc == etcNOSEHOOVER && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
+ if (ir->etc == TemperatureCoupling::NoseHoover && !EI_VV(ir->eI) && ir->opts.nhchainlength > 1)
{
warning_note(
wi,
{
sprintf(err_buf,
"%s temperature control not supported for integrator %s.",
- etcoupl_names[ir->etc],
+ enumValueToString(ir->etc),
ei_names[ir->eI]);
CHECK(!(EI_VV(ir->eI)));
- if (ir->nstcomm > 0 && (ir->etc == etcANDERSEN))
+ if (ir->nstcomm > 0 && (ir->etc == TemperatureCoupling::Andersen))
{
sprintf(warn_buf,
"Center of mass removal not necessary for %s. All velocities of coupled "
"groups are rerandomized periodically, so flying ice cube errors will not "
"occur.",
- etcoupl_names[ir->etc]);
+ enumValueToString(ir->etc));
warning_note(wi, warn_buf);
}
"nstcomm must be 1, not %d for %s, as velocities of atoms in coupled groups are "
"randomized every time step",
ir->nstcomm,
- etcoupl_names[ir->etc]);
- CHECK(ir->nstcomm > 1 && (ir->etc == etcANDERSEN));
+ enumValueToString(ir->etc));
+ CHECK(ir->nstcomm > 1 && (ir->etc == TemperatureCoupling::Andersen));
}
- if (ir->etc == etcBERENDSEN)
+ if (ir->etc == TemperatureCoupling::Berendsen)
{
sprintf(warn_buf,
"The %s thermostat does not generate the correct kinetic energy distribution. You "
"might want to consider using the %s thermostat.",
- ETCOUPLTYPE(ir->etc),
- ETCOUPLTYPE(etcVRESCALE));
+ enumValueToString(ir->etc),
+ enumValueToString(TemperatureCoupling::VRescale));
warning_note(wi, warn_buf);
}
- if ((ir->etc == etcNOSEHOOVER || ETC_ANDERSEN(ir->etc)) && ir->epc == epcBERENDSEN)
+ if ((ir->etc == TemperatureCoupling::NoseHoover || ETC_ANDERSEN(ir->etc))
+ && ir->epc == PressureCoupling::Berendsen)
{
sprintf(warn_buf,
"Using Berendsen pressure coupling invalidates the "
}
/* PRESSURE COUPLING */
- if (ir->epc == epcISOTROPIC)
+ if (ir->epc == PressureCoupling::Isotropic)
{
- ir->epc = epcBERENDSEN;
+ ir->epc = PressureCoupling::Berendsen;
warning_note(wi,
"Old option for pressure coupling given: "
"changing \"Isotropic\" to \"Berendsen\"\n");
}
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
dt_pcoupl = ir->nstpcouple * ir->delta_t;
sprintf(warn_buf,
"For proper integration of the %s barostat, tau-p (%g) should be at least %d "
"times larger than nstpcouple*dt (%g)",
- EPCOUPLTYPE(ir->epc),
+ enumValueToString(ir->epc),
ir->tau_p,
pcouple_min_integration_steps(ir->epc),
dt_pcoupl);
sprintf(err_buf,
"compressibility must be > 0 when using pressure"
" coupling %s\n",
- EPCOUPLTYPE(ir->epc));
+ enumValueToString(ir->epc));
CHECK(ir->compress[XX][XX] < 0 || ir->compress[YY][YY] < 0 || ir->compress[ZZ][ZZ] < 0
|| (trace(ir->compress) == 0 && ir->compress[YY][XX] <= 0 && ir->compress[ZZ][XX] <= 0
&& ir->compress[ZZ][YY] <= 0));
- if (epcPARRINELLORAHMAN == ir->epc && opts->bGenVel)
+ if (PressureCoupling::ParrinelloRahman == ir->epc && opts->bGenVel)
{
sprintf(warn_buf,
"You are generating velocities so I am assuming you "
"equilibrating first with Berendsen pressure coupling. If "
"you are not equilibrating the system, you can probably "
"ignore this warning.",
- epcoupl_names[ir->epc]);
+ enumValueToString(ir->epc));
warning(wi, warn_buf);
}
}
if (!EI_VV(ir->eI))
{
- if (ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::Mttk)
{
warning_error(wi, "MTTK pressure coupling requires a Velocity-verlet integrator");
}
expand->bWLoneovert = (get_eeenum(inp, "wl-oneovert", yesno_names, wi) != 0);
}
+template<typename EnumType>
+EnumType getEnum(std::vector<t_inpfile>* inp, const char* name, warninp_t wi)
+{
+ // If we there's no valid option, we'll use the first enum entry as default.
+ // Note, this assumes the enum is zero based, which is also assumed by
+ // EnumerationWrapper and EnumerationArray.
+ const auto defaultEnumValue = EnumType::Default;
+ const auto& defaultName = enumValueToString(defaultEnumValue);
+ // Get index of option in input
+ const auto ii = get_einp(inp, name);
+ if (ii == -1)
+ {
+ // If the option wasn't set, we use the first enum entry as default
+ inp->back().value_.assign(defaultName);
+ return defaultEnumValue;
+ }
+
+ // Check if option string can be mapped to a valid enum value
+ const auto* optionString = (*inp)[ii].value_.c_str();
+ for (auto enumValue : gmx::EnumerationWrapper<EnumType>{})
+ {
+ if (gmx_strcasecmp_min(enumValueToString(enumValue), optionString) == 0)
+ {
+ return enumValue;
+ }
+ }
+
+ // If we get here, the option set is invalid. Print error.
+ std::string errorMessage = gmx::formatString(
+ "Invalid enum '%s' for variable %s, using '%s'\n", optionString, name, defaultName);
+ errorMessage += gmx::formatString("Next time, use one of:");
+ for (auto enumValue : gmx::EnumerationWrapper<EnumType>{})
+ {
+ errorMessage += gmx::formatString(" '%s'", enumValueToString(enumValue));
+ }
+ if (wi != nullptr)
+ {
+ warning_error(wi, errorMessage);
+ }
+ else
+ {
+ fprintf(stderr, "%s\n", errorMessage.c_str());
+ }
+ (*inp)[ii].value_.assign(defaultName);
+ return defaultEnumValue;
+}
+
/*! \brief Return whether an end state with the given coupling-lambda
* value describes fully-interacting VDW.
*
/* Coupling stuff */
printStringNewline(&inp, "OPTIONS FOR WEAK COUPLING ALGORITHMS");
printStringNoNewline(&inp, "Temperature coupling");
- ir->etc = get_eeenum(&inp, "tcoupl", etcoupl_names, wi);
+ ir->etc = getEnum<TemperatureCoupling>(&inp, "tcoupl", wi);
ir->nsttcouple = get_eint(&inp, "nsttcouple", -1, wi);
ir->opts.nhchainlength = get_eint(&inp, "nh-chain-length", 10, wi);
ir->bPrintNHChains = (get_eeenum(&inp, "print-nose-hoover-chain-variables", yesno_names, wi) != 0);
setStringEntry(&inp, "tau-t", inputrecStrings->tau_t, nullptr);
setStringEntry(&inp, "ref-t", inputrecStrings->ref_t, nullptr);
printStringNoNewline(&inp, "pressure coupling");
- ir->epc = get_eeenum(&inp, "pcoupl", epcoupl_names, wi);
+ ir->epc = getEnum<PressureCoupling>(&inp, "pcoupl", wi);
ir->epct = get_eeenum(&inp, "pcoupltype", epcoupltype_names, wi);
ir->nstpcouple = get_eint(&inp, "nstpcouple", -1, wi);
printStringNoNewline(&inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)");
{
dumdub[m][i] = 0.0;
}
- if (ir->epc)
+ if (ir->epc != PressureCoupling::No)
{
switch (ir->epct)
{
ir->deform[YY][XX] = dumdub[0][3];
ir->deform[ZZ][XX] = dumdub[0][4];
ir->deform[ZZ][YY] = dumdub[0][5];
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
for (i = 0; i < 3; i++)
{
warning_error(wi, warn_buf);
}
- if (ir->etc != etcVRESCALE && ir->opts.tau_t[i] == 0)
+ if (ir->etc != TemperatureCoupling::VRescale && ir->opts.tau_t[i] == 0)
{
warning_note(
wi,
tau_min = std::min(tau_min, ir->opts.tau_t[i]);
}
}
- if (ir->etc != etcNO && ir->nsttcouple == -1)
+ if (ir->etc != TemperatureCoupling::No && ir->nsttcouple == -1)
{
ir->nsttcouple = ir_optimal_nsttcouple(ir);
}
if (EI_VV(ir->eI))
{
- if ((ir->etc == etcNOSEHOOVER) && (ir->epc == epcBERENDSEN))
+ if ((ir->etc == TemperatureCoupling::NoseHoover) && (ir->epc == PressureCoupling::Berendsen))
{
gmx_fatal(FARGS,
"Cannot do Nose-Hoover temperature with Berendsen pressure control with "
"md-vv; use either vrescale temperature with berendsen pressure or "
"Nose-Hoover temperature with MTTK pressure");
}
- if (ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::Mttk)
{
- if (ir->etc != etcNOSEHOOVER)
+ if (ir->etc != TemperatureCoupling::NoseHoover)
{
gmx_fatal(FARGS,
"Cannot do MTTK pressure coupling without Nose-Hoover temperature "
sprintf(warn_buf,
"For proper integration of the %s thermostat, tau-t (%g) should be at "
"least %d times larger than nsttcouple*dt (%g)",
- ETCOUPLTYPE(ir->etc),
+ enumValueToString(ir->etc),
tau_min,
nstcmin,
ir->nsttcouple * ir->delta_t);
}
if (ir->cutoff_scheme == ecutsVERLET && ir->verletbuf_tol > 0 && ir->nstlist > 1
- && ((EI_MD(ir->eI) || EI_SD(ir->eI)) && (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN)))
+ && ((EI_MD(ir->eI) || EI_SD(ir->eI))
+ && (ir->etc == TemperatureCoupling::VRescale || ir->etc == TemperatureCoupling::Berendsen)))
{
/* Check if a too small Verlet buffer might potentially
* cause more drift than the thermostat can couple off.
CHECK(ir->opts.tau_t[i] < 0);
}
- if (ir->etc == etcANDERSENMASSIVE && ir->comm_mode != ecmNO)
+ if (ir->etc == TemperatureCoupling::AndersenMassive && ir->comm_mode != ecmNO)
{
for (i = 0; i < ir->opts.ngtc; i++)
{
"randomized every time step. The input tau_t (%8.3f) leads to %d steps per "
"randomization",
i,
- etcoupl_names[ir->etc],
+ enumValueToString(ir->etc),
ir->nstcomm,
ir->opts.tau_t[i],
nsteps);
"rounding errors can lead to build up of kinetic energy of the center of mass");
}
- if (ir->epc == epcPARRINELLORAHMAN && ir->etc == etcNOSEHOOVER)
+ if (ir->epc == PressureCoupling::ParrinelloRahman && ir->etc == TemperatureCoupling::NoseHoover)
{
real tau_t_max = 0;
for (int g = 0; g < ir->opts.ngtc; g++)
std::string message = gmx::formatString(
"With %s T-coupling and %s p-coupling, "
"%s (%g) should be at least twice as large as %s (%g) to avoid resonances",
- etcoupl_names[ir->etc],
- epcoupl_names[ir->epc],
+ enumValueToString(ir->etc),
+ enumValueToString(ir->epc),
"tau-p",
ir->tau_p,
"tau-t",
}
/* Check for pressure coupling with absolute position restraints */
- if (ir->epc != epcNO && ir->refcoord_scaling == erscNO)
+ if (ir->epc != PressureCoupling::No && ir->refcoord_scaling == erscNO)
{
absolute_reference(ir, sys, TRUE, AbsRef);
{
{
for (m = 0; m <= i; m++)
{
- if ((ir->epc != epcNO && ir->compress[i][m] != 0) || ir->deform[i][m] != 0)
+ if ((ir->epc != PressureCoupling::No && ir->compress[i][m] != 0) || ir->deform[i][m] != 0)
{
for (c = 0; c < ir->pull->ncoord; c++)
{
if ((ir->eConstrAlg == econtLINCS) && bHasNormalConstraints)
{
/* If we have Lincs constraints: */
- if (ir->eI == eiMD && ir->etc == etcNO && ir->eConstrAlg == econtLINCS && ir->nLincsIter == 1)
+ if (ir->eI == eiMD && ir->etc == TemperatureCoupling::No && ir->eConstrAlg == econtLINCS
+ && ir->nLincsIter == 1)
{
sprintf(warn_buf,
"For energy conservation with LINCS, lincs_iter should be 2 or larger.\n");
ei_names[ir->eI]);
warning_note(wi, warn_buf);
}
- if (ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::Mttk)
{
warning_error(wi, "MTTK not compatible with lincs -- use shake instead.");
}
}
- if (bHasAnyConstraints && ir->epc == epcMTTK)
+ if (bHasAnyConstraints && ir->epc == PressureCoupling::Mttk)
{
warning_error(wi, "Constraints are not implemented with MTTK pressure control.");
}
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2012-2018, The GROMACS development team.
- * Copyright (c) 2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
PartitioningPerMoltype updateGrouping,
real chanceRequested)
{
- if (!EI_DYNAMICS(ir.eI) || (EI_MD(ir.eI) && ir.etc == etcNO))
+ if (!EI_DYNAMICS(ir.eI) || (EI_MD(ir.eI) && ir.etc == TemperatureCoupling::No))
{
return minCellSizeFromPairlistBuffer(ir);
}
* 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.
nrnb(nrnb_p),
wcycle(wcycle_p)
{
- if (numConstraints + numSettles > 0 && ir.epc == epcMTTK)
+ if (numConstraints + numSettles > 0 && ir.epc == PressureCoupling::Mttk)
{
gmx_fatal(FARGS, "Constraints are not implemented with MTTK pressure control.");
}
// For VV temperature coupling parameters are updated on the current
// step, for the others - one step before.
- if (inputrec->etc == etcNO)
+ if (inputrec->etc == TemperatureCoupling::No)
{
doTemperatureCoupling = false;
}
// subroutines
switch (inputrec->etc)
{
- case etcNO: break;
- case etcBERENDSEN:
+ case TemperatureCoupling::No:
+ case TemperatureCoupling::Andersen:
+ case TemperatureCoupling::AndersenMassive: break;
+ case TemperatureCoupling::Berendsen:
berendsen_tcoupl(inputrec, ekind, dttc, state->therm_integral);
break;
- case etcNOSEHOOVER:
+ case TemperatureCoupling::NoseHoover:
nosehoover_tcoupl(&(inputrec->opts),
ekind,
dttc,
state->nosehoover_vxi.data(),
MassQ);
break;
- case etcVRESCALE:
+ case TemperatureCoupling::VRescale:
vrescale_tcoupl(inputrec, step, ekind, dttc, state->therm_integral.data());
break;
+ default: gmx_fatal(FARGS, "Unknown temperature coupling algorithm");
}
/* rescale in place here */
if (EI_VV(inputrec->eI))
/* Berendsen P-coupling is completely handled after the coordinate update.
* Trotter P-coupling is handled by separate calls to trotter_update().
*/
- if (inputrec->epc == epcPARRINELLORAHMAN
+ if (inputrec->epc == PressureCoupling::ParrinelloRahman
&& do_per_step(step + inputrec->nstpcouple - 1, inputrec->nstpcouple))
{
real dtpc = inputrec->nstpcouple * inputrec->delta_t;
/* now update boxes */
switch (inputrec->epc)
{
- case (epcNO): break;
- case (epcBERENDSEN):
+ case (PressureCoupling::No): break;
+ case (PressureCoupling::Berendsen):
if (do_per_step(step, inputrec->nstpcouple))
{
real dtpc = inputrec->nstpcouple * dt;
- pressureCouplingCalculateScalingMatrix<epcBERENDSEN>(fplog,
- step,
- inputrec,
- dtpc,
- pressure,
- state->box,
- forceVirial,
- constraintVirial,
- pressureCouplingMu,
- &state->baros_integral);
- pressureCouplingScaleBoxAndCoordinates<epcBERENDSEN>(inputrec,
- pressureCouplingMu,
- state->box,
- state->box_rel,
- start,
- homenr,
- state->x.rvec_array(),
- nullptr,
- md->cFREEZE,
- nrnb,
- scaleCoordinates);
+ pressureCouplingCalculateScalingMatrix<PressureCoupling::Berendsen>(fplog,
+ step,
+ inputrec,
+ dtpc,
+ pressure,
+ state->box,
+ forceVirial,
+ constraintVirial,
+ pressureCouplingMu,
+ &state->baros_integral);
+ pressureCouplingScaleBoxAndCoordinates<PressureCoupling::Berendsen>(inputrec,
+ pressureCouplingMu,
+ state->box,
+ state->box_rel,
+ start,
+ homenr,
+ state->x.rvec_array(),
+ nullptr,
+ md->cFREEZE,
+ nrnb,
+ scaleCoordinates);
}
break;
- case (epcCRESCALE):
+ case (PressureCoupling::CRescale):
if (do_per_step(step, inputrec->nstpcouple))
{
real dtpc = inputrec->nstpcouple * dt;
- pressureCouplingCalculateScalingMatrix<epcCRESCALE>(fplog,
- step,
- inputrec,
- dtpc,
- pressure,
- state->box,
- forceVirial,
- constraintVirial,
- pressureCouplingMu,
- &state->baros_integral);
- pressureCouplingScaleBoxAndCoordinates<epcCRESCALE>(inputrec,
- pressureCouplingMu,
- state->box,
- state->box_rel,
- start,
- homenr,
- state->x.rvec_array(),
- state->v.rvec_array(),
- md->cFREEZE,
- nrnb,
- scaleCoordinates);
+ pressureCouplingCalculateScalingMatrix<PressureCoupling::CRescale>(fplog,
+ step,
+ inputrec,
+ dtpc,
+ pressure,
+ state->box,
+ forceVirial,
+ constraintVirial,
+ pressureCouplingMu,
+ &state->baros_integral);
+ pressureCouplingScaleBoxAndCoordinates<PressureCoupling::CRescale>(
+ inputrec,
+ pressureCouplingMu,
+ state->box,
+ state->box_rel,
+ start,
+ homenr,
+ state->x.rvec_array(),
+ state->v.rvec_array(),
+ md->cFREEZE,
+ nrnb,
+ scaleCoordinates);
}
break;
- case (epcPARRINELLORAHMAN):
+ case (PressureCoupling::ParrinelloRahman):
if (do_per_step(step + inputrec->nstpcouple - 1, inputrec->nstpcouple))
{
/* The box velocities were updated in do_pr_pcoupl,
}
}
break;
- case (epcMTTK):
+ case (PressureCoupling::Mttk):
switch (inputrec->epct)
{
case (epctISOTROPIC):
real rate = (ir->delta_t) / ir->opts.tau_t[0];
- if (ir->etc == etcANDERSEN && constr != nullptr)
+ if (ir->etc == TemperatureCoupling::Andersen && constr != nullptr)
{
/* Currently, Andersen thermostat does not support constrained
systems. Functionality exists in the andersen_tcoupl
/* proceed with andersen if 1) it's fixed probability per
particle andersen or 2) it's massive andersen and it's tau_t/dt */
- if ((ir->etc == etcANDERSEN) || do_per_step(step, gmx::roundToInt(1.0 / rate)))
+ if ((ir->etc == TemperatureCoupling::Andersen) || do_per_step(step, gmx::roundToInt(1.0 / rate)))
{
andersen_tcoupl(
ir, step, cr, md, v, rate, upd->getAndersenRandomizeGroup(), upd->getBoltzmanFactor());
}
//! Details of Berendsen / C-rescale scaling matrix calculation
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
static void calculateScalingMatrixImplDetail(const t_inputrec* ir,
matrix mu,
real dt,
int64_t step);
//! Calculate Berendsen / C-rescale scaling matrix
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
static void calculateScalingMatrixImpl(const t_inputrec* ir,
matrix mu,
real dt,
}
template<>
-void calculateScalingMatrixImplDetail<epcBERENDSEN>(const t_inputrec* ir,
- matrix mu,
- real dt,
- const matrix pres,
- const matrix box,
- real scalar_pressure,
- real xy_pressure,
- int64_t gmx_unused step)
+void calculateScalingMatrixImplDetail<PressureCoupling::Berendsen>(const t_inputrec* ir,
+ matrix mu,
+ real dt,
+ const matrix pres,
+ const matrix box,
+ real scalar_pressure,
+ real xy_pressure,
+ int64_t gmx_unused step)
{
real p_corr_z = 0;
switch (ir->epct)
}
template<>
-void calculateScalingMatrixImplDetail<epcCRESCALE>(const t_inputrec* ir,
- matrix mu,
- real dt,
- const matrix pres,
- const matrix box,
- real scalar_pressure,
- real xy_pressure,
- int64_t step)
+void calculateScalingMatrixImplDetail<PressureCoupling::CRescale>(const t_inputrec* ir,
+ matrix mu,
+ real dt,
+ const matrix pres,
+ const matrix box,
+ real scalar_pressure,
+ real xy_pressure,
+ int64_t step)
{
gmx::ThreeFry2x64<64> rng(ir->ld_seed, gmx::RandomDomain::Barostat);
gmx::NormalDistribution<real> normalDist;
}
}
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
void pressureCouplingCalculateScalingMatrix(FILE* fplog,
int64_t step,
const t_inputrec* ir,
matrix mu,
double* baros_integral)
{
- static_assert(pressureCouplingType == epcBERENDSEN || pressureCouplingType == epcCRESCALE,
+ static_assert(pressureCouplingType == PressureCoupling::Berendsen
+ || pressureCouplingType == PressureCoupling::CRescale,
"pressureCouplingCalculateScalingMatrix is only implemented for Berendsen and "
"C-rescale pressure coupling");
}
}
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
void pressureCouplingScaleBoxAndCoordinates(const t_inputrec* ir,
const matrix mu,
matrix box,
t_nrnb* nrnb,
const bool scaleCoordinates)
{
- static_assert(pressureCouplingType == epcBERENDSEN || pressureCouplingType == epcCRESCALE,
+ static_assert(pressureCouplingType == PressureCoupling::Berendsen
+ || pressureCouplingType == PressureCoupling::CRescale,
"pressureCouplingScaleBoxAndCoordinates is only implemented for Berendsen and "
"C-rescale pressure coupling");
ivec* nFreeze = ir->opts.nFreeze;
matrix inv_mu;
- if (pressureCouplingType == epcCRESCALE)
+ if (pressureCouplingType == PressureCoupling::CRescale)
{
gmx::invertBoxMatrix(mu, inv_mu);
}
if (!nFreeze[g][XX])
{
x[n][XX] = mu[XX][XX] * x[n][XX] + mu[YY][XX] * x[n][YY] + mu[ZZ][XX] * x[n][ZZ];
- if (pressureCouplingType == epcCRESCALE)
+ if (pressureCouplingType == PressureCoupling::CRescale)
{
v[n][XX] = inv_mu[XX][XX] * v[n][XX] + inv_mu[YY][XX] * v[n][YY]
+ inv_mu[ZZ][XX] * v[n][ZZ];
if (!nFreeze[g][YY])
{
x[n][YY] = mu[YY][YY] * x[n][YY] + mu[ZZ][YY] * x[n][ZZ];
- if (pressureCouplingType == epcCRESCALE)
+ if (pressureCouplingType == PressureCoupling::CRescale)
{
v[n][YY] = inv_mu[YY][YY] * v[n][YY] + inv_mu[ZZ][YY] * v[n][ZZ];
}
if (!nFreeze[g][ZZ])
{
x[n][ZZ] = mu[ZZ][ZZ] * x[n][ZZ];
- if (pressureCouplingType == epcCRESCALE)
+ if (pressureCouplingType == PressureCoupling::CRescale)
{
v[n][ZZ] = inv_mu[ZZ][ZZ] * v[n][ZZ];
}
}
if (randomize[gc])
{
- if (ir->etc == etcANDERSENMASSIVE)
+ if (ir->etc == TemperatureCoupling::AndersenMassive)
{
/* Randomize particle always */
bRandomize = TRUE;
nnhpres = state->nnhpres;
nh = state->nhchainlength;
- if (EI_VV(ir->eI) && (ir->epc == epcMTTK) && (ir->etc != etcNOSEHOOVER))
+ if (EI_VV(ir->eI) && (ir->epc == PressureCoupling::Mttk) && (ir->etc != TemperatureCoupling::NoseHoover))
{
gmx_fatal(FARGS, "Cannot do MTTK pressure coupling without Nose-Hoover temperature control");
}
{
real energyNPT = 0;
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
/* Compute the contribution of the pressure to the conserved quantity*/
switch (ir->epc)
{
- case epcPARRINELLORAHMAN:
+ case PressureCoupling::ParrinelloRahman:
{
/* contribution from the pressure momenta */
tensor invMass;
energyNPT += vol * trace(ir->ref_p) / (DIM * PRESFAC);
break;
}
- case epcMTTK:
+ case PressureCoupling::Mttk:
/* contribution from the pressure momenta */
energyNPT += 0.5 * gmx::square(state->veta) / MassQ->Winv;
/* contribution from the PV term */
energyNPT += vol * trace(ir->ref_p) / (DIM * PRESFAC);
- if (ir->epc == epcMTTK)
+ if (ir->epc == PressureCoupling::Mttk)
{
/* contribution from the MTTK chain */
energyNPT += energyPressureMTTK(ir, state, MassQ);
}
break;
- case epcBERENDSEN:
- case epcCRESCALE: energyNPT += state->baros_integral; break;
+ case PressureCoupling::Berendsen:
+ case PressureCoupling::CRescale: energyNPT += state->baros_integral; break;
default:
GMX_RELEASE_ASSERT(
false,
switch (ir->etc)
{
- case etcNO: break;
- case etcVRESCALE:
- case etcBERENDSEN: energyNPT += energyVrescale(ir, state); break;
- case etcNOSEHOOVER: energyNPT += energyNoseHoover(ir, state, MassQ); break;
- case etcANDERSEN:
- case etcANDERSENMASSIVE:
+ case TemperatureCoupling::No: break;
+ case TemperatureCoupling::VRescale:
+ case TemperatureCoupling::Berendsen: energyNPT += energyVrescale(ir, state); break;
+ case TemperatureCoupling::NoseHoover:
+ energyNPT += energyNoseHoover(ir, state, MassQ);
+ break;
+ case TemperatureCoupling::Andersen:
+ case TemperatureCoupling::AndersenMassive:
// Not supported, excluded in integratorHasConservedEnergyQuantity()
break;
default:
{
if (EI_DYNAMICS(ir.eI))
{
- if (ir.etc == etcBERENDSEN)
+ if (ir.etc == TemperatureCoupling::Berendsen)
{
please_cite(fplog, "Berendsen84a");
}
- if (ir.etc == etcVRESCALE)
+ if (ir.etc == TemperatureCoupling::VRescale)
{
please_cite(fplog, "Bussi2007a");
}
- if (ir.epc == epcCRESCALE)
+ if (ir.epc == PressureCoupling::CRescale)
{
please_cite(fplog, "Bernetti2020");
}
* computes the current value of the scaling matrix. The template
* parameter determines the pressure coupling algorithm.
*/
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
void pressureCouplingCalculateScalingMatrix(FILE* fplog,
int64_t step,
const t_inputrec* ir,
* the scaling matrix mu. The template parameter determines the pressure
* coupling algorithm.
*/
-template<int pressureCouplingType>
+template<PressureCoupling pressureCouplingType>
void pressureCouplingScaleBoxAndCoordinates(const t_inputrec* ir,
const matrix mu,
matrix box,
}
}
- epc_ = isRerun ? epcNO : ir->epc;
+ epc_ = isRerun ? PressureCoupling::No : ir->epc;
bDiagPres_ = !TRICLINIC(ir->ref_p) && !isRerun;
ref_p_ = (ir->ref_p[XX][XX] + ir->ref_p[YY][YY] + ir->ref_p[ZZ][ZZ]) / DIM;
bTricl_ = TRICLINIC(ir->compress) || TRICLINIC(ir->deform);
bDynBox_ = inputrecDynamicBox(ir);
- etc_ = isRerun ? etcNO : ir->etc;
+ etc_ = isRerun ? TemperatureCoupling::No : ir->etc;
bNHC_trotter_ = inputrecNvtTrotter(ir) && !isRerun;
bPrintNHChains_ = ir->bPrintNHChains && !isRerun;
bMTTK_ = (inputrecNptTrotter(ir) || inputrecNphTrotter(ir)) && !isRerun;
ipres_ = get_ebin_space(ebin_, asize(pres_nm), pres_nm, unit_pres_bar);
isurft_ = get_ebin_space(ebin_, asize(surft_nm), surft_nm, unit_surft_bar);
}
- if (epc_ == epcPARRINELLORAHMAN || epc_ == epcMTTK)
+ if (epc_ == PressureCoupling::ParrinelloRahman || epc_ == PressureCoupling::Mttk)
{
ipc_ = get_ebin_space(ebin_, bTricl_ ? boxvel_nm.size() : DIM, boxvel_nm.data(), unit_vel);
}
{
nTCP_ = 0;
}
- if (etc_ == etcNOSEHOOVER)
+ if (etc_ == TemperatureCoupling::NoseHoover)
{
if (bNHC_trotter_)
{
{
mde_n_ = 2 * nTC_;
}
- if (epc_ == epcMTTK)
+ if (epc_ == PressureCoupling::Mttk)
{
mdeb_n_ = 2 * nNHC_ * nTCP_;
}
}
int allocated = 0;
- if (etc_ == etcNOSEHOOVER)
+ if (etc_ == TemperatureCoupling::NoseHoover)
{
if (bPrintNHChains_)
{
}
}
}
- else if (etc_ == etcBERENDSEN || etc_ == etcYES || etc_ == etcVRESCALE)
+ else if (etc_ == TemperatureCoupling::Berendsen || etc_ == TemperatureCoupling::Yes
+ || etc_ == TemperatureCoupling::VRescale)
{
for (i = 0; (i < nTC_); i++)
{
}
nsetsextend = nsets;
- if ((ir->epc != epcNO) && (fep->n_lambda > 0) && (fep->init_lambda < 0))
+ if ((ir->epc != PressureCoupling::No) && (fep->n_lambda > 0) && (fep->init_lambda < 0))
{
nsetsextend += 1; /* for PV term, other terms possible if required for
the reduced potential (only needed with foreign
tmp = (pres[ZZ][ZZ] - (pres[XX][XX] + pres[YY][YY]) * 0.5) * box[ZZ][ZZ];
add_ebin(ebin_, isurft_, 1, &tmp, bSum);
}
- if (epc_ == epcPARRINELLORAHMAN || epc_ == epcMTTK)
+ if (epc_ == PressureCoupling::ParrinelloRahman || epc_ == PressureCoupling::Mttk)
{
tmp6[0] = ptCouplingArrays.boxv[XX][XX];
tmp6[1] = ptCouplingArrays.boxv[YY][YY];
}
add_ebin(ebin_, itemp_, nTC_, tmp_r_, bSum);
- if (etc_ == etcNOSEHOOVER)
+ if (etc_ == TemperatureCoupling::NoseHoover)
{
/* whether to print Nose-Hoover chains: */
if (bPrintNHChains_)
}
}
}
- else if (etc_ == etcBERENDSEN || etc_ == etcYES || etc_ == etcVRESCALE)
+ else if (etc_ == TemperatureCoupling::Berendsen || etc_ == TemperatureCoupling::Yes
+ || etc_ == TemperatureCoupling::VRescale)
{
for (int i = 0; (i < nTC_); i++)
{
{
fprintf(fp_dhdl_, " %#.8g", dE_[i]);
}
- if (bDynBox_ && bDiagPres_ && (epc_ != epcNO) && foreignTerms.numLambdas() > 0
- && (fep->init_lambda < 0))
+ if (bDynBox_ && bDiagPres_ && (epc_ != PressureCoupling::No)
+ && foreignTerms.numLambdas() > 0 && (fep->init_lambda < 0))
{
fprintf(fp_dhdl_, " %#.8g", pv); /* PV term only needed when
there are alternate state
bool bMTTK_ = false;
//! Temperature control scheme
- int etc_ = 0;
+ TemperatureCoupling etc_ = TemperatureCoupling::No;
//! Which of the main energy terms should be printed
bool bEner_[F_NRE] = { false };
int isurft_ = 0;
//! Pressure control scheme
- int epc_ = 0;
+ PressureCoupling epc_ = PressureCoupling::No;
//! Index for velocity of the box borders
int ipc_ = 0;
int nstglobalcomm = 10;
{
// Set up the default behaviour
- if (!(ir->nstcalcenergy > 0 || ir->nstlist > 0 || ir->etc != etcNO || ir->epc != epcNO))
+ if (!(ir->nstcalcenergy > 0 || ir->nstlist > 0 || ir->etc != TemperatureCoupling::No
+ || ir->epc != PressureCoupling::No))
{
/* The user didn't choose the period for anything
important, so we just make sure we can send signals and
*/
nstglobalcomm = lcd4(ir->nstcalcenergy,
ir->nstlist,
- ir->etc != etcNO ? ir->nsttcouple : 0,
- ir->epc != epcNO ? ir->nstpcouple : 0);
+ ir->etc != TemperatureCoupling::No ? ir->nsttcouple : 0,
+ ir->epc != PressureCoupling::No ? ir->nstpcouple : 0);
}
}
return nstglobalcomm;
{
state->flags |= (1 << estBOX_REL);
}
- if ((ir->epc == epcPARRINELLORAHMAN) || (ir->epc == epcMTTK))
+ if ((ir->epc == PressureCoupling::ParrinelloRahman) || (ir->epc == PressureCoupling::Mttk))
{
state->flags |= (1 << estBOXV);
if (!useModularSimulator)
state->flags |= (1 << estVETA);
state->flags |= (1 << estVOL0);
}
- if (ir->epc == epcBERENDSEN || ir->epc == epcCRESCALE)
+ if (ir->epc == PressureCoupling::Berendsen || ir->epc == PressureCoupling::CRescale)
{
state->flags |= (1 << estBAROS_INT);
}
}
- if (ir->etc == etcNOSEHOOVER)
+ if (ir->etc == TemperatureCoupling::NoseHoover)
{
state->flags |= (1 << estNH_XI);
state->flags |= (1 << estNH_VXI);
}
- if (ir->etc == etcVRESCALE || ir->etc == etcBERENDSEN)
+ if (ir->etc == TemperatureCoupling::VRescale || ir->etc == TemperatureCoupling::Berendsen)
{
state->flags |= (1 << estTHERM_INT);
}
* 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.
dhc->ndh += 1;
bEnergy = TRUE;
}
- if (ir->epc > epcNO)
+ if (ir->epc > PressureCoupling::No)
{
dhc->ndh += 1; /* include pressure-volume work */
bPV = TRUE;
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2008, The GROMACS development team.
* Copyright (c) 2012,2014,2015,2016,2017 by the GROMACS development team.
- * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
{
nonsimd_step_frac = 0;
}
- if (ir.epc != epcNO && 1.0 / ir.nstpcouple > nonsimd_step_frac)
+ if (ir.epc != PressureCoupling::No && 1.0 / ir.nstpcouple > nonsimd_step_frac)
{
nonsimd_step_frac = 1.0 / ir.nstpcouple;
}
struct EnergyOutputTestParameters
{
//! Thermostat (enum)
- int temperatureCouplingScheme;
+ TemperatureCoupling temperatureCouplingScheme;
//! Barostat (enum)
- int pressureCouplingScheme;
+ PressureCoupling pressureCouplingScheme;
//! Integrator
int integrator;
//! Number of saved energy frames (to test averages output).
* Only several combinations of the parameters are used. Using all possible combinations will
* require ~10 MB of test data and ~2 sec to run the tests.
*/
-const EnergyOutputTestParameters parametersSets[] = { { etcNO, epcNO, eiMD, 1, false, false },
- { etcNO, epcNO, eiMD, 1, true, false },
- { etcNO, epcNO, eiMD, 1, false, true },
- { etcNO, epcNO, eiMD, 0, false, false },
- { etcNO, epcNO, eiMD, 10, false, false },
- { etcVRESCALE, epcNO, eiMD, 1, false, false },
- { etcNOSEHOOVER, epcNO, eiMD, 1, false, false },
- { etcNO, epcPARRINELLORAHMAN, eiMD, 1, false, false },
- { etcNO, epcMTTK, eiMD, 1, false, false },
- { etcNO, epcNO, eiVV, 1, false, false },
- { etcNO, epcMTTK, eiVV, 1, false, false } };
+const EnergyOutputTestParameters parametersSets[] = {
+ { TemperatureCoupling::No, PressureCoupling::No, eiMD, 1, false, false },
+ { TemperatureCoupling::No, PressureCoupling::No, eiMD, 1, true, false },
+ { TemperatureCoupling::No, PressureCoupling::No, eiMD, 1, false, true },
+ { TemperatureCoupling::No, PressureCoupling::No, eiMD, 0, false, false },
+ { TemperatureCoupling::No, PressureCoupling::No, eiMD, 10, false, false },
+ { TemperatureCoupling::VRescale, PressureCoupling::No, eiMD, 1, false, false },
+ { TemperatureCoupling::NoseHoover, PressureCoupling::No, eiMD, 1, false, false },
+ { TemperatureCoupling::No, PressureCoupling::ParrinelloRahman, eiMD, 1, false, false },
+ { TemperatureCoupling::No, PressureCoupling::Mttk, eiMD, 1, false, false },
+ { TemperatureCoupling::No, PressureCoupling::No, eiVV, 1, false, false },
+ { TemperatureCoupling::No, PressureCoupling::Mttk, eiVV, 1, false, false }
+};
/*! \brief Test fixture to test energy output.
*
if (numTCoupleGroups_ == 0)
{
- inputRecord_.etc = etcNO;
+ inputRecord_.etc = TemperatureCoupling::No;
for (int i = 0; i < numAtoms_; i++)
{
mdAtoms_.cTC[i] = 0;
}
else
{
- inputRecord_.etc = etcYES;
+ inputRecord_.etc = TemperatureCoupling::Yes;
for (int i = 0; i < numAtoms_; i++)
{
mdAtoms_.cTC[i] = i % numTCoupleGroups_;
if (doPressureCouple_)
{
- inputRecord_.epc = epcPARRINELLORAHMAN;
+ inputRecord_.epc = PressureCoupling::ParrinelloRahman;
inputRecord_.nstpcouple = nstpcouple;
dtPressureCouple_ = inputRecord_.nstpcouple * inputRecord_.delta_t;
}
else
{
- inputRecord_.epc = epcNO;
+ inputRecord_.epc = PressureCoupling::No;
velocityScalingMatrix_[XX][XX] = 1.0;
velocityScalingMatrix_[XX][YY] = 0.0;
velocityScalingMatrix_[XX][ZZ] = 0.0;
const rvec* gmx_restrict x,
rvec* gmx_restrict xprime,
rvec* gmx_restrict v,
- const rvec* gmx_restrict f,
- const int etc,
- const int epc,
- const int nsttcouple,
- const int nstpcouple,
- const t_mdatoms* md,
- const gmx_ekindata_t* ekind,
- const matrix box,
+ const rvec* gmx_restrict f,
+ const TemperatureCoupling etc,
+ const PressureCoupling epc,
+ const int nsttcouple,
+ const int nstpcouple,
+ const t_mdatoms* md,
+ const gmx_ekindata_t* ekind,
+ const matrix box,
const double* gmx_restrict nh_vxi,
const matrix M)
{
"For SIMD optimization certain compilers need to have xprime != x");
/* Note: Berendsen pressure scaling is handled after do_update_md() */
- bool doTempCouple = (etc != etcNO && do_per_step(step + nsttcouple - 1, nsttcouple));
- bool doNoseHoover = (etc == etcNOSEHOOVER && doTempCouple);
- bool doParrinelloRahman =
- (epc == epcPARRINELLORAHMAN && do_per_step(step + nstpcouple - 1, nstpcouple));
+ bool doTempCouple =
+ (etc != TemperatureCoupling::No && do_per_step(step + nsttcouple - 1, nsttcouple));
+ bool doNoseHoover = (etc == TemperatureCoupling::NoseHoover && doTempCouple);
+ bool doParrinelloRahman = (epc == PressureCoupling::ParrinelloRahman
+ && do_per_step(step + nstpcouple - 1, nstpcouple));
bool doPROffDiagonal = (doParrinelloRahman && (M[YY][XX] != 0 || M[ZZ][XX] != 0 || M[ZZ][YY] != 0));
real dtPressureCouple = (doParrinelloRahman ? nstpcouple * dt : 0);
case (eiVV):
case (eiVVAK):
{
- gmx_bool bExtended = (inputRecord.etc == etcNOSEHOOVER || inputRecord.epc == epcPARRINELLORAHMAN
- || inputRecord.epc == epcMTTK);
+ gmx_bool bExtended = (inputRecord.etc == TemperatureCoupling::NoseHoover
+ || inputRecord.epc == PressureCoupling::ParrinelloRahman
+ || inputRecord.epc == PressureCoupling::Mttk);
/* assuming barostat coupled to group 0 */
real alpha = 1.0 + DIM / static_cast<real>(inputRecord.opts.nrdf[0]);
GMX_RELEASE_ASSERT(ir->eI == eiMD,
"Only the md integrator is supported with the GPU update.\n");
GMX_RELEASE_ASSERT(
- ir->etc != etcNOSEHOOVER,
+ ir->etc != TemperatureCoupling::NoseHoover,
"Nose-Hoover temperature coupling is not supported with the GPU update.\n");
GMX_RELEASE_ASSERT(
- ir->epc == epcNO || ir->epc == epcPARRINELLORAHMAN || ir->epc == epcBERENDSEN
- || ir->epc == epcCRESCALE,
+ ir->epc == PressureCoupling::No || ir->epc == PressureCoupling::ParrinelloRahman
+ || ir->epc == PressureCoupling::Berendsen || ir->epc == PressureCoupling::CRescale,
"Only Parrinello-Rahman, Berendsen, and C-rescale pressure coupling are supported "
"with the GPU update.\n");
GMX_RELEASE_ASSERT(!mdatoms->haveVsites,
{
bCalcEnerStep = do_per_step(step, ir->nstcalcenergy);
bCalcVir = bCalcEnerStep
- || (ir->epc != epcNO
+ || (ir->epc != PressureCoupling::No
&& (do_per_step(step, ir->nstpcouple) || do_per_step(step - 1, ir->nstpcouple)));
}
else
{
bCalcEnerStep = do_per_step(step, ir->nstcalcenergy);
- bCalcVir = bCalcEnerStep || (ir->epc != epcNO && do_per_step(step, ir->nstpcouple));
+ bCalcVir = bCalcEnerStep
+ || (ir->epc != PressureCoupling::No && do_per_step(step, ir->nstpcouple));
}
bCalcEner = bCalcEnerStep;
// Parrinello-Rahman requires the pressure to be availible before the update to compute
// the velocity scaling matrix. Hence, it runs one step after the nstpcouple step.
- const bool doParrinelloRahman = (ir->epc == epcPARRINELLORAHMAN
+ const bool doParrinelloRahman = (ir->epc == PressureCoupling::ParrinelloRahman
&& do_per_step(step + ir->nstpcouple - 1, ir->nstpcouple));
if (EI_VV(ir->eI))
}
const bool doTemperatureScaling =
- (ir->etc != etcNO && do_per_step(step + ir->nsttcouple - 1, ir->nsttcouple));
+ (ir->etc != TemperatureCoupling::No
+ && do_per_step(step + ir->nsttcouple - 1, ir->nsttcouple));
// This applies Leap-Frog, LINCS and SETTLE in succession
integrator->integrate(
update_pcouple_after_coordinates(
fplog, step, ir, mdatoms, pres, force_vir, shake_vir, pressureCouplingMu, state, nrnb, upd.deform(), !useGpuForUpdate);
- const bool doBerendsenPressureCoupling =
- (inputrec->epc == epcBERENDSEN && do_per_step(step, inputrec->nstpcouple));
- const bool doCRescalePressureCoupling =
- (inputrec->epc == epcCRESCALE && do_per_step(step, inputrec->nstpcouple));
+ const bool doBerendsenPressureCoupling = (inputrec->epc == PressureCoupling::Berendsen
+ && do_per_step(step, inputrec->nstpcouple));
+ const bool doCRescalePressureCoupling = (inputrec->epc == PressureCoupling::CRescale
+ && do_per_step(step, inputrec->nstpcouple));
if (useGpuForUpdate
&& (doBerendsenPressureCoupling || doCRescalePressureCoupling || doParrinelloRahman))
{
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2011-2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2011-2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
const int nst = replExParams.exchangeInterval;
check_multi_int64(
fplog, ms, (ir->init_step + nst - 1) / nst, "first exchange step: init_step/-replex", FALSE);
- check_multi_int(fplog, ms, ir->etc, "the temperature coupling", FALSE);
+ check_multi_int(fplog, ms, static_cast<int>(ir->etc), "the temperature coupling", FALSE);
check_multi_int(fplog, ms, ir->opts.ngtc, "the number of temperature coupling groups", FALSE);
- check_multi_int(fplog, ms, ir->epc, "the pressure coupling", FALSE);
+ check_multi_int(fplog, ms, static_cast<int>(ir->epc), "the pressure coupling", FALSE);
check_multi_int(fplog, ms, ir->efep, "free energy", FALSE);
check_multi_int(fplog, ms, ir->fepvals->n_lambda, "number of lambda states", FALSE);
if (bTemp)
{
please_cite(fplog, "Sugita1999a");
- if (ir->epc != epcNO)
+ if (ir->epc != PressureCoupling::No)
{
re->bNPT = TRUE;
fprintf(fplog, "Repl Using Constant Pressure REMD.\n");
please_cite(fplog, "Okabe2001a");
}
- if (ir->etc == etcBERENDSEN)
+ if (ir->etc == TemperatureCoupling::Berendsen)
{
gmx_fatal(FARGS,
"REMD with the %s thermostat does not produce correct potential energy "
"distributions, consider using the %s thermostat instead",
- ETCOUPLTYPE(ir->etc),
- ETCOUPLTYPE(etcVRESCALE));
+ enumValueToString(ir->etc),
+ enumValueToString(TemperatureCoupling::VRescale));
}
}
if (bLambda)
"With Verlet lists and no PME rcoulomb and rvdw should be identical");
}
/* For NVE simulations, we will retain the initial list buffer */
- if (EI_DYNAMICS(ir->eI) && ir->verletbuf_tol > 0 && !(EI_MD(ir->eI) && ir->etc == etcNO))
+ if (EI_DYNAMICS(ir->eI) && ir->verletbuf_tol > 0
+ && !(EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No))
{
/* Update the Verlet buffer size for the current run setup */
return nst;
}
-int tcouple_min_integration_steps(int etc)
+int tcouple_min_integration_steps(TemperatureCoupling etc)
{
int n;
switch (etc)
{
- case etcNO: n = 0; break;
- case etcBERENDSEN:
- case etcYES: n = nstmin_berendsen_tcouple; break;
- case etcVRESCALE:
+ case TemperatureCoupling::No: n = 0; break;
+ case TemperatureCoupling::Berendsen:
+ case TemperatureCoupling::Yes: n = nstmin_berendsen_tcouple; break;
+ case TemperatureCoupling::VRescale:
/* V-rescale supports instantaneous rescaling */
n = 0;
break;
- case etcNOSEHOOVER: n = nstmin_harmonic; break;
- case etcANDERSEN:
- case etcANDERSENMASSIVE: n = 1; break;
+ case TemperatureCoupling::NoseHoover: n = nstmin_harmonic; break;
+ case TemperatureCoupling::Andersen:
+ case TemperatureCoupling::AndersenMassive: n = 1; break;
default: gmx_incons("Unknown etc value");
}
nwanted = c_defaultNstTCouple;
tau_min = 1e20;
- if (ir->etc != etcNO)
+ if (ir->etc != TemperatureCoupling::No)
{
for (g = 0; g < ir->opts.ngtc; g++)
{
return n;
}
-int pcouple_min_integration_steps(int epc)
+int pcouple_min_integration_steps(PressureCoupling epc)
{
int n;
switch (epc)
{
- case epcNO: n = 0; break;
- case epcBERENDSEN:
- case epcCRESCALE:
- case epcISOTROPIC: n = nstmin_berendsen_pcouple; break;
- case epcPARRINELLORAHMAN:
- case epcMTTK: n = nstmin_harmonic; break;
+ case PressureCoupling::No: n = 0; break;
+ case PressureCoupling::Berendsen:
+ case PressureCoupling::CRescale:
+ case PressureCoupling::Isotropic: n = nstmin_berendsen_pcouple; break;
+ case PressureCoupling::ParrinelloRahman:
+ case PressureCoupling::Mttk: n = nstmin_harmonic; break;
default: gmx_incons("Unknown epc value");
}
PR("epsilon-surface", ir->epsilon_surface);
/* Options for weak coupling algorithms */
- PS("tcoupl", ETCOUPLTYPE(ir->etc));
+ PS("tcoupl", enumValueToString(ir->etc));
PI("nsttcouple", ir->nsttcouple);
PI("nh-chain-length", ir->opts.nhchainlength);
PS("print-nose-hoover-chain-variables", EBOOL(ir->bPrintNHChains));
- PS("pcoupl", EPCOUPLTYPE(ir->epc));
+ PS("pcoupl", enumValueToString(ir->epc));
PS("pcoupltype", EPCOUPLTYPETYPE(ir->epct));
PI("nstpcouple", ir->nstpcouple);
PR("tau-p", ir->tau_p);
static_cast<int>(ir1->bContinuation),
static_cast<int>(ir2->bContinuation));
cmp_int(fp, "inputrec->bShakeSOR", -1, static_cast<int>(ir1->bShakeSOR), static_cast<int>(ir2->bShakeSOR));
- cmp_int(fp, "inputrec->etc", -1, ir1->etc, ir2->etc);
+ cmpEnum(fp, "inputrec->etc", ir1->etc, ir2->etc);
cmp_int(fp,
"inputrec->bPrintNHChains",
-1,
static_cast<int>(ir1->bPrintNHChains),
static_cast<int>(ir2->bPrintNHChains));
- cmp_int(fp, "inputrec->epc", -1, ir1->epc, ir2->epc);
+ cmpEnum(fp, "inputrec->epc", ir1->epc, ir2->epc);
cmp_int(fp, "inputrec->epct", -1, ir1->epct, ir2->epct);
cmp_real(fp, "inputrec->tau_p", -1, ir1->tau_p, ir2->tau_p, ftol, abstol);
cmp_rvec(fp, "inputrec->ref_p(x)", -1, ir1->ref_p[XX], ir2->ref_p[XX], ftol, abstol);
gmx_bool inputrecDynamicBox(const t_inputrec* ir)
{
- return (ir->epc != epcNO || ir->eI == eiTPI || inputrecDeform(ir));
+ return (ir->epc != PressureCoupling::No || ir->eI == eiTPI || inputrecDeform(ir));
}
gmx_bool inputrecPreserveShape(const t_inputrec* ir)
{
- return (ir->epc != epcNO && ir->deform[XX][XX] == 0
+ return (ir->epc != PressureCoupling::No && ir->deform[XX][XX] == 0
&& (ir->epct == epctISOTROPIC || ir->epct == epctSEMIISOTROPIC));
}
gmx_bool inputrecNptTrotter(const t_inputrec* ir)
{
- return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == epcMTTK) && (ir->etc == etcNOSEHOOVER));
+ return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == PressureCoupling::Mttk)
+ && (ir->etc == TemperatureCoupling::NoseHoover));
}
gmx_bool inputrecNvtTrotter(const t_inputrec* ir)
{
- return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc != epcMTTK) && (ir->etc == etcNOSEHOOVER));
+ return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc != PressureCoupling::Mttk)
+ && (ir->etc == TemperatureCoupling::NoseHoover));
}
gmx_bool inputrecNphTrotter(const t_inputrec* ir)
{
- return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == epcMTTK) && (ir->etc != etcNOSEHOOVER));
+ return (((ir->eI == eiVV) || (ir->eI == eiVVAK)) && (ir->epc == PressureCoupling::Mttk)
+ && (ir->etc != TemperatureCoupling::NoseHoover));
}
bool inputrecPbcXY2Walls(const t_inputrec* ir)
// Energy minimization or stochastic integrator: no conservation
return false;
}
- else if (ir->etc == etcNO && ir->epc == epcNO)
+ else if (ir->etc == TemperatureCoupling::No && ir->epc == PressureCoupling::No)
{
// The total energy is conserved, no additional conserved quanitity
return false;
{
// Shear stress with Parrinello-Rahman is not supported (tedious)
bool shearWithPR =
- ((ir->epc == epcPARRINELLORAHMAN || ir->epc == epcMTTK)
+ ((ir->epc == PressureCoupling::ParrinelloRahman || ir->epc == PressureCoupling::Mttk)
&& (ir->ref_p[YY][XX] != 0 || ir->ref_p[ZZ][XX] != 0 || ir->ref_p[ZZ][YY] != 0));
return !ETC_ANDERSEN(ir->etc) && !shearWithPR;
bool integratorHasReferenceTemperature(const t_inputrec* ir)
{
- return ((ir->etc != etcNO) || EI_SD(ir->eI) || (ir->eI == eiBD) || EI_TPI(ir->eI));
+ return ((ir->etc != TemperatureCoupling::No) || EI_SD(ir->eI) || (ir->eI == eiBD) || EI_TPI(ir->eI));
}
int inputrec2nboundeddim(const t_inputrec* ir)
return 0;
}
- if (EI_MD(ir.eI) && ir.etc == etcNO)
+ if (EI_MD(ir.eI) && ir.etc == TemperatureCoupling::No)
{
return -1;
}
//! Continuation run: starting state is correct (ie. constrained)
gmx_bool bContinuation;
//! Temperature coupling
- int etc;
+ TemperatureCoupling etc;
//! Interval in steps for temperature coupling
int nsttcouple;
//! Whether to print nose-hoover chains
gmx_bool bPrintNHChains;
//! Pressure coupling
- int epc;
+ PressureCoupling epc;
//! Pressure coupling type
int epct;
//! Interval in steps for pressure coupling
int ir_optimal_nstcalcenergy(const t_inputrec* ir);
-int tcouple_min_integration_steps(int etc);
+int tcouple_min_integration_steps(TemperatureCoupling etc);
int ir_optimal_nsttcouple(const t_inputrec* ir);
-int pcouple_min_integration_steps(int epc);
+int pcouple_min_integration_steps(PressureCoupling epc);
int ir_optimal_nstpcouple(const t_inputrec* ir);
* 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.
#include "md_enums.h"
+#include "gromacs/utility/enumerationhelpers.h"
+
const char* enum_name(int index, int max_index, const char* const names[])
{
if (index < 0 || index >= max_index)
"Exact-cutoff", "Force-switch", nullptr
};
-const char* etcoupl_names[etcNR + 1] = {
- "No", "Berendsen", "Nose-Hoover", "yes", "Andersen", "Andersen-massive", "V-rescale", nullptr
-}; /* yes is alias for berendsen */
+const char* enumValueToString(TemperatureCoupling enumValue)
+{
+ static constexpr gmx::EnumerationArray<TemperatureCoupling, const char*> temperatureCouplingNames = {
+ "No", "Berendsen", "Nose-Hoover", "yes", "Andersen", "Andersen-massive", "V-rescale"
+ }; /* yes is alias for berendsen */
+ return temperatureCouplingNames[enumValue];
+}
-const char* epcoupl_names[epcNR + 1] = { "No", "Berendsen", "Parrinello-Rahman",
- "Isotropic", "MTTK", "C-rescale",
- nullptr }; /* isotropic is alias for berendsen */
+const char* enumValueToString(PressureCoupling enumValue)
+{
+ static constexpr gmx::EnumerationArray<PressureCoupling, const char*> pressureCouplingNames = {
+ "No", "Berendsen", "Parrinello-Rahman", "Isotropic", "MTTK", "C-rescale"
+ }; /* isotropic is alias for berendsen */
+ return pressureCouplingNames[enumValue];
+}
const char* epcoupltype_names[epctNR + 1] = { "Isotropic",
"Semiisotropic",
* 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.
/*! \brief Temperature coupling type
*
* yes is an alias for berendsen
+ *
+ * Note: Keep `Count` as the second-to-last entry, and `Default` as the last entry -
+ * this is needed to keep EnumerationWrapper, EnumerationArray and (de)serialization
+ * working.
*/
-enum
-{
- etcNO,
- etcBERENDSEN,
- etcNOSEHOOVER,
- etcYES,
- etcANDERSEN,
- etcANDERSENMASSIVE,
- etcVRESCALE,
- etcNR
-};
-//! Strings corresponding to temperatyre coupling types
-extern const char* etcoupl_names[etcNR + 1];
-//! Macro for selecting t coupling string
-#define ETCOUPLTYPE(e) enum_name(e, etcNR, etcoupl_names)
+enum class TemperatureCoupling : int
+{
+ No,
+ Berendsen,
+ NoseHoover,
+ Yes,
+ Andersen,
+ AndersenMassive,
+ VRescale,
+ Count,
+ Default = No
+};
+//! Return names of temperature coupling schemes
+const char* enumValueToString(TemperatureCoupling enumValue);
//! Return whether this is andersen coupling
-#define ETC_ANDERSEN(e) (((e) == etcANDERSENMASSIVE) || ((e) == etcANDERSEN))
+#define ETC_ANDERSEN(e) \
+ (((e) == TemperatureCoupling::AndersenMassive) || ((e) == TemperatureCoupling::Andersen))
/*! \brief Pressure coupling types
*
* isotropic is an alias for berendsen
+ *
+ * Note: Keep `Count` as the second-to-last entry, and `Default` as the last entry -
+ * this is needed to keep EnumerationWrapper, EnumerationArray and (de)serialization
+ * working.
*/
-enum
-{
- epcNO,
- epcBERENDSEN,
- epcPARRINELLORAHMAN,
- epcISOTROPIC,
- epcMTTK,
- epcCRESCALE,
- epcNR
-};
-//! String corresponding to pressure coupling algorithm
-extern const char* epcoupl_names[epcNR + 1];
-//! Macro to return the correct pcoupling string
-#define EPCOUPLTYPE(e) enum_name(e, epcNR, epcoupl_names)
+enum class PressureCoupling : int
+{
+ No,
+ Berendsen,
+ ParrinelloRahman,
+ Isotropic,
+ Mttk,
+ CRescale,
+ Count,
+ Default = No
+};
+//! Return names of pressure coupling schemes
+const char* enumValueToString(PressureCoupling enumValue);
//! Flat-bottom posres geometries
enum
// The leap frog integration algorithm
builder->add<ForceElement>();
builder->add<StatePropagatorData::Element>();
- if (legacySimulatorData_->inputrec->etc == etcVRESCALE
- || legacySimulatorData_->inputrec->etc == etcBERENDSEN)
+ if (legacySimulatorData_->inputrec->etc == TemperatureCoupling::VRescale
+ || legacySimulatorData_->inputrec->etc == TemperatureCoupling::Berendsen)
{
builder->add<VelocityScalingTemperatureCoupling>(
-1, UseFullStepKE::No, ReportPreviousStepConservedEnergy::No);
}
builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::LeapFrog>>();
builder->add<EnergyData::Element>();
- if (legacySimulatorData_->inputrec->epc == epcPARRINELLORAHMAN)
+ if (legacySimulatorData_->inputrec->epc == PressureCoupling::ParrinelloRahman)
{
builder->add<ParrinelloRahmanBarostat>(-1);
}
}
builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::VelocityVerlet>>();
builder->add<StatePropagatorData::Element>();
- if (legacySimulatorData_->inputrec->etc == etcVRESCALE
- || legacySimulatorData_->inputrec->etc == etcBERENDSEN)
+ if (legacySimulatorData_->inputrec->etc == TemperatureCoupling::VRescale
+ || legacySimulatorData_->inputrec->etc == TemperatureCoupling::Berendsen)
{
builder->add<VelocityScalingTemperatureCoupling>(
0, UseFullStepKE::Yes, ReportPreviousStepConservedEnergy::Yes);
}
builder->add<ComputeGlobalsElement<ComputeGlobalsAlgorithm::VelocityVerlet>>();
builder->add<EnergyData::Element>();
- if (legacySimulatorData_->inputrec->epc == epcPARRINELLORAHMAN)
+ if (legacySimulatorData_->inputrec->epc == PressureCoupling::ParrinelloRahman)
{
builder->add<ParrinelloRahmanBarostat>(-1);
}
GMX_RELEASE_ASSERT(
!(modularSimulatorExplicitlyTurnedOff && inputrec->eI == eiVV
- && inputrec->epc == epcPARRINELLORAHMAN),
+ && inputrec->epc == PressureCoupling::ParrinelloRahman),
"Cannot use a Parrinello-Rahman barostat with md-vv and "
"GMX_DISABLE_MODULAR_SIMULATOR=ON, "
"as the Parrinello-Rahman barostat is not implemented in the legacy simulator. Unset "
isInputCompatible
&& conditionalAssert(!doRerun, "Rerun is not supported by the modular simulator.");
isInputCompatible = isInputCompatible
- && conditionalAssert(inputrec->etc == etcNO || inputrec->etc == etcVRESCALE
- || inputrec->etc == etcBERENDSEN,
+ && conditionalAssert(inputrec->etc == TemperatureCoupling::No
+ || inputrec->etc == TemperatureCoupling::VRescale
+ || inputrec->etc == TemperatureCoupling::Berendsen,
"Only v-rescale and Berendsen thermostat are "
"supported by the modular simulator.");
isInputCompatible =
isInputCompatible
&& conditionalAssert(
- inputrec->epc == epcNO || inputrec->epc == epcPARRINELLORAHMAN,
+ inputrec->epc == PressureCoupling::No
+ || inputrec->epc == PressureCoupling::ParrinelloRahman,
"Only Parrinello-Rahman barostat is supported by the modular simulator.");
isInputCompatible =
isInputCompatible
&& conditionalAssert(!GMX_FAHCORE,
"GMX_FAHCORE not supported by the modular simulator.");
GMX_RELEASE_ASSERT(
- isInputCompatible || !(inputrec->eI == eiVV && inputrec->epc == epcPARRINELLORAHMAN),
+ isInputCompatible
+ || !(inputrec->eI == eiVV && inputrec->epc == PressureCoupling::ParrinelloRahman),
"Requested Parrinello-Rahman barostat with md-vv, but other options are not compatible "
"with the modular simulator. The Parrinello-Rahman barostat is not implemented for "
"md-vv in the legacy simulator. Use a different pressure control algorithm.");
/*
* 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.
const real* couplingTime,
const real* numDegreesOfFreedom,
EnergyData* energyData,
- TemperatureCouplingType couplingType) :
+ TemperatureCoupling couplingType) :
nstcouple_(nstcouple),
offset_(offset),
useFullStepKE_(useFullStepKE),
temperatureCouplingIntegralPreviousStep_ = temperatureCouplingIntegral_;
}
energyData->setVelocityScalingTemperatureCoupling(this);
- if (couplingType == etcVRESCALE)
+ if (couplingType == TemperatureCoupling::VRescale)
{
temperatureCouplingImpl_ = std::make_unique<VRescaleTemperatureCoupling>(seed);
}
- else if (couplingType == etcBERENDSEN)
+ else if (couplingType == TemperatureCoupling::Berendsen)
{
temperatureCouplingImpl_ = std::make_unique<BerendsenTemperatureCoupling>();
}
else
{
- throw NotImplementedError("Temperature coupling " + std::string(ETCOUPLTYPE(couplingType))
+ throw NotImplementedError("Temperature coupling " + std::string(enumValueToString(couplingType))
+ " is not implemented for modular simulator.");
}
}
/*
* 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.
Count
};
-//! Typedef to match current use of ints as types.
-using TemperatureCouplingType = int;
-
/*! \internal
* \ingroup module_modularsimulator
* \brief Element implementing the a velocity-scaling thermostat
const real* couplingTime,
const real* numDegreesOfFreedom,
EnergyData* energyData,
- TemperatureCouplingType couplingType);
+ TemperatureCoupling couplingType);
/*! \brief Register run function for step / time
*
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2017,2018,2019,2020, by the GROMACS development team, led by
+ * Copyright (c) 2017,2018,2019,2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
static bool supportsDynamicPairlistGenerationInterval(const t_inputrec& ir)
{
return ir.cutoff_scheme == ecutsVERLET && EI_DYNAMICS(ir.eI)
- && !(EI_MD(ir.eI) && ir.etc == etcNO) && ir.verletbuf_tol > 0;
+ && !(EI_MD(ir.eI) && ir.etc == TemperatureCoupling::No) && ir.verletbuf_tol > 0;
}
/*! \brief Cost of non-bonded kernels
}
}
- if (EI_MD(ir->eI) && ir->etc == etcNO)
+ if (EI_MD(ir->eI) && ir->etc == TemperatureCoupling::No)
{
if (MASTER(cr))
{
* This file is part of the GROMACS molecular simulation package.
*
* Copyright (c) 2015,2016,2017,2018,2019 by the GROMACS development team.
- * Copyright (c) 2020, by the GROMACS development team, led by
+ * Copyright (c) 2020,2021, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
{
errorMessage += "Only the md integrator is supported.\n";
}
- if (inputrec.etc == etcNOSEHOOVER)
+ if (inputrec.etc == TemperatureCoupling::NoseHoover)
{
errorMessage += "Nose-Hoover temperature coupling is not supported.\n";
}
- if (!(inputrec.epc == epcNO || inputrec.epc == epcPARRINELLORAHMAN
- || inputrec.epc == epcBERENDSEN || inputrec.epc == epcCRESCALE))
+ if (!(inputrec.epc == PressureCoupling::No || inputrec.epc == PressureCoupling::ParrinelloRahman
+ || inputrec.epc == PressureCoupling::Berendsen || inputrec.epc == PressureCoupling::CRescale))
{
errorMessage +=
"Only Parrinello-Rahman, Berendsen, and C-rescale pressure coupling are "
/*
* 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.
}
writer->writeLine(formatString(
"A single cut-off of %g nm was used for Van der Waals interactions.", ir.rlist));
- if (ir.etc != 0)
+ if (ir.etc != TemperatureCoupling::No)
{
writer->writeLine(formatString("Temperature coupling was done with the %s algorithm.",
- etcoupl_names[ir.etc]));
+ enumValueToString(ir.etc)));
}
- if (ir.epc != 0)
+ if (ir.epc != PressureCoupling::No)
{
writer->writeLine(formatString("Pressure coupling was done with the %s algorithm.",
- epcoupl_names[ir.epc]));
+ enumValueToString(ir.epc)));
}
writer->ensureEmptyLine();
}
* 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.
#include <cstdio>
+#include "gromacs/mdtypes/md_enums.h"
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/real.h"
//! Compares two doubles and prints differences.
void cmp_double(FILE* fp, const char* s, int index, double i1, double i2, double ftol, double abstol);
+//! Compare two enums of generic type and print differences.
+template<typename EnumType>
+void cmpEnum(FILE* fp, const char* s, EnumType value1, EnumType value2)
+{
+ if (value1 != value2)
+ {
+ fprintf(fp, "%s (", s);
+ fprintf(fp, "%s", enumValueToString(value1));
+ fprintf(fp, " - ");
+ fprintf(fp, "%s", enumValueToString(value2));
+ fprintf(fp, ")\n");
+ }
+}
+
#endif
/*
* 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.
}
}
///@}
+
+ //! Serialize enum value with underlying type int
+ template<typename EnumType>
+ void doEnumAsInt(EnumType* enumValue)
+ {
+ static_assert(std::is_same<std::underlying_type_t<EnumType>, int>::value,
+ "Only enums with underlying type int are supported.");
+ auto castedValue = static_cast<int>(*enumValue);
+ doInt(&castedValue);
+ *enumValue = static_cast<EnumType>(castedValue);
+ }
};
} // namespace gmx