#include "gromacs/commandline/filenm.h"
#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/gmxfio-xdr.h"
-#include "gromacs/fileio/readinp.h"
-#include "gromacs/fileio/warninp.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/gmxlib/network.h"
#include "gromacs/math/units.h"
ElectricField() : fpField_(nullptr) {}
// From IInputRecExtension
- virtual void doTpxIO(t_fileio *fio, bool bRead);
virtual void initMdpTransform(IKeyValueTreeTransformRules *transform);
virtual void initMdpOptions(IOptionsContainerWithSections *options);
virtual void broadCast(const t_commrec *cr);
FILE *fpField_;
};
-void ElectricField::doTpxIO(t_fileio *fio, bool bRead)
-{
- // The content of the tpr file for this feature has
- // been the same since gromacs 4.0 that was used for
- // developing.
- for (int j = 0; (j < DIM); j++)
- {
- int n = 0, nt = 0;
- if (!bRead)
- {
- n = 1;
- if (omega(j) != 0 || sigma(j) != 0 || t0(j) != 0)
- {
- nt = 1;
- }
- }
- gmx_fio_do_int(fio, n);
- gmx_fio_do_int(fio, nt);
- std::vector<real> aa, phi, at, phit;
- if (!bRead)
- {
- aa.push_back(a(j));
- phi.push_back(t0(j));
- at.push_back(omega(j));
- phit.push_back(sigma(j));
- }
- else
- {
- aa.resize(n+1);
- phi.resize(nt+1);
- at.resize(nt+1);
- phit.resize(nt+1);
- }
- gmx_fio_ndo_real(fio, aa.data(), n);
- gmx_fio_ndo_real(fio, phi.data(), n);
- gmx_fio_ndo_real(fio, at.data(), nt);
- gmx_fio_ndo_real(fio, phit.data(), nt);
- if (bRead && n > 0)
- {
- setFieldTerm(j, aa[0], at[0], phi[0], phit[0]);
- if (n > 1 || nt > 1)
- {
- gmx_fatal(FARGS, "Can not handle tpr files with more than one electric field term per direction.");
- }
- }
- }
-}
-
//! Converts static parameters from mdp format to E0.
real convertStaticParameters(const std::string &value)
{
.keyMatchType("/", gmx::StringCompareType::CaseAndDashInsensitive);
module.initMdpTransform(transform.rules());
auto result = transform.transform(mdpValues.build(), nullptr);
- module.assignOptionsToModules(result.object(), nullptr);
+ module.assignOptionsToModulesFromMdp(result.object(), nullptr);
t_mdatoms md;
PaddedRVecVector f = { { 0, 0, 0 } };
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/gmxassert.h"
+#include "gromacs/utility/keyvaluetreebuilder.h"
+#include "gromacs/utility/keyvaluetreeserializer.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/snprintf.h"
#include "gromacs/utility/txtdump.h"
tpxv_RemoveTwinRange, /**< removed support for twin-range interactions */
tpxv_ReplacePullPrintCOM12, /**< Replaced print-com-1, 2 with pull-print-com */
tpxv_PullExternalPotential, /**< Added pull type external potential */
+ tpxv_GenericParamsForElectricField, /**< Introduced KeyValueTree and moved electric field parameters */
tpxv_Count /**< the total number of tpxv versions */
};
}
+static void do_legacy_efield(t_fileio *fio, gmx::KeyValueTreeObjectBuilder *root)
+{
+ const char *const dimName[] = { "x", "y", "z" };
+
+ auto appliedForcesObj = root->addObject("applied-forces");
+ auto efieldObj = appliedForcesObj.addObject("electric-field");
+ // The content of the tpr file for this feature has
+ // been the same since gromacs 4.0 that was used for
+ // developing.
+ for (int j = 0; j < DIM; ++j)
+ {
+ int n, nt;
+ gmx_fio_do_int(fio, n);
+ gmx_fio_do_int(fio, nt);
+ std::vector<real> aa(n+1), phi(nt+1), at(nt+1), phit(nt+1);
+ gmx_fio_ndo_real(fio, aa.data(), n);
+ gmx_fio_ndo_real(fio, phi.data(), n);
+ gmx_fio_ndo_real(fio, at.data(), nt);
+ gmx_fio_ndo_real(fio, phit.data(), nt);
+ if (n > 0)
+ {
+ if (n > 1 || nt > 1)
+ {
+ gmx_fatal(FARGS, "Can not handle tpr files with more than one electric field term per direction.");
+ }
+ auto dimObj = efieldObj.addObject(dimName[j]);
+ dimObj.addValue<real>("E0", aa[0]);
+ dimObj.addValue<real>("omega", at[0]);
+ dimObj.addValue<real>("t0", phi[0]);
+ dimObj.addValue<real>("sigma", phit[0]);
+ }
+ }
+}
+
static void do_inputrec(t_fileio *fio, t_inputrec *ir, gmx_bool bRead,
int file_version, real *fudgeQQ)
return;
}
+ gmx::KeyValueTreeBuilder paramsBuilder;
+ gmx::KeyValueTreeObjectBuilder paramsObj = paramsBuilder.rootObject();
+
/* Basic inputrec stuff */
gmx_fio_do_int(fio, ir->eI);
if (file_version >= 62)
ir->wall_ewald_zfac = 3;
}
/* Cosine stuff for electric fields */
- ir->efield->doTpxIO(fio, bRead);
+ if (file_version < tpxv_GenericParamsForElectricField)
+ {
+ do_legacy_efield(fio, ¶msObj);
+ }
/* Swap ions */
if (file_version >= tpxv_ComputationalElectrophysiology)
}
/* end of QMMM stuff */
}
+
+ if (file_version >= tpxv_GenericParamsForElectricField)
+ {
+ gmx::FileIOXdrSerializer serializer(fio);
+ if (bRead)
+ {
+ paramsObj.mergeObject(
+ gmx::deserializeKeyValueTree(&serializer));
+ }
+ else
+ {
+ GMX_RELEASE_ASSERT(ir->params != nullptr,
+ "Parameters should be present when writing inputrec");
+ gmx::serializeKeyValueTree(*ir->params, &serializer);
+ }
+ }
+ if (bRead)
+ {
+ ir->params = new gmx::KeyValueTreeObject(paramsBuilder.build());
+ }
}
auto result
= transform.transform(convertedValues, &errorHandler);
errorHandler.setBackMapping(result.backMapping());
- mdModules->assignOptionsToModules(result.object(), &errorHandler);
+ mdModules->assignOptionsToModulesFromMdp(result.object(), &errorHandler);
}
/* Ion/water position swapping ("computational electrophysiology") */
gmx::IInputRecExtension *eptr = inputrec->efield;
block_bc(cr, *inputrec);
inputrec->efield = eptr;
+ inputrec->params = nullptr;
bc_grpopts(cr, &(inputrec->opts));
}
}
+ void makeModuleOptions(Options *options)
+ {
+ // Create a section for applied-forces modules
+ auto appliedForcesOptions = options->addSection(OptionSection("applied-forces"));
+ field_->initMdpOptions(&appliedForcesOptions);
+ // In future, other sections would also go here.
+ }
+
IInputRecExtensionPtr field_;
t_inputrec *ir_;
};
impl_->field_->initMdpTransform(rules);
}
-void MDModules::assignOptionsToModules(const KeyValueTreeObject &optionValues,
- IKeyValueTreeErrorHandler *errorHandler)
+void MDModules::assignOptionsToModulesFromMdp(const KeyValueTreeObject &mdpOptionValues,
+ IKeyValueTreeErrorHandler *errorHandler)
{
- Options options;
- // Create a section for applied-forces modules
- auto appliedForcesOptions = options.addSection(OptionSection("applied-forces"));
- impl_->field_->initMdpOptions(&appliedForcesOptions);
- // In future, other sections would also go here.
+ Options moduleOptions;
+ impl_->makeModuleOptions(&moduleOptions);
+
+ KeyValueTreeObject keyValueParameters(mdpOptionValues);
+ impl_->ir_->params = new KeyValueTreeObject(adjustKeyValueTreeFromOptions(keyValueParameters, moduleOptions));
+ // The actual output is in the data fields of the modules that
+ // were set up in the module options.
+ assignOptionsFromKeyValueTree(&moduleOptions, *impl_->ir_->params, errorHandler);
+}
- assignOptionsFromKeyValueTree(&options, optionValues, errorHandler);
+void MDModules::assignOptionsToModulesFromTpr()
+{
+ Options moduleOptions;
+ impl_->makeModuleOptions(&moduleOptions);
+
+ // Note that impl_->ir_->params was set up during tpr reading, so
+ // all we need to do here is integrate that with the module
+ // options, which e.g. might have changed between versions.
+ // The actual output is in the data fields of the modules that
+ // were set up in the module options.
+ //
+ // TODO error handling
+ assignOptionsFromKeyValueTree(&moduleOptions, *impl_->ir_->params, nullptr);
}
} // namespace gmx
* loops over a container of these interfaces, and/or groups of them (e.g.
* applied forces), instead of the current single pointer.
*
- * The assignOptionsToModules() method of this class also takes
- * responsibility for wiring up the options (and their defaults) for
- * each
+ * The assignOptionsToModules() and
+ * assignOptionsToModulesFromInputrec() methods of this class also
+ * take responsibility for wiring up the options (and their defaults)
+ * for each module, respectively for mdp- and tpr-style input of those
+ * options.
*
* \inlibraryapi
* \ingroup module_mdrunutility
*/
void initMdpTransform(IKeyValueTreeTransformRules *rules);
- /*! \brief Use \c optionValues to set the options for each module.
+ /*! \brief Use \c mdpOptionValues to set the options (e.g.read
+ * from mdp input) for each module.
*
- * \param[in] optionValues Contains keys and values from user
+ * \param[in] mdpOptionValues Contains keys and values from user
* input (and defaults) to configure modules that have
* registered options with those keys.
* \param[out] errorHandler Called to report errors. */
- void assignOptionsToModules(const KeyValueTreeObject &optionValues,
- IKeyValueTreeErrorHandler *errorHandler);
+ void assignOptionsToModulesFromMdp(const KeyValueTreeObject &mdpOptionValues,
+ IKeyValueTreeErrorHandler *errorHandler);
+
+ /*! \brief
+ * Initializes modules based on inputrec values read from tpr file.
+ *
+ * This needs to be called after read_tpx_state() if the modules need
+ * to be accessed.
+ */
+ void assignOptionsToModulesFromTpr();
private:
class Impl;
*
* Copyright (c) 1991-2000, University of Groningen, The Netherlands.
* Copyright (c) 2001-2010, The GROMACS development team.
- * Copyright (c) 2012,2014,2015,2016, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014,2015,2016,2017, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "gromacs/utility/compare.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/keyvaluetree.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/snprintf.h"
#include "gromacs/utility/stringutil.h"
done_pull_params(ir->pull);
sfree(ir->pull);
}
+ delete ir->params;
}
static void pr_qm_opts(FILE *fp, int indent, const char *title, const t_grpopts *opts)
class IKeyValueTreeTransformRules;
class IOptionsContainerWithSections;
+class KeyValueTreeObject;
/*! \libinternal \brief
* Inputrec extension interface for a mdrun module.
public:
virtual ~IInputRecExtension() {}
- /*! \brief Read or write tpr file
- *
- * Read or write the necessary data from a tpr file. The routine is responsible
- * for consistency, such that all data belonging to this module is read or written.
- * \param[inout] fio Gromacs file descriptor
- * \param[in] bRead boolean determines whether we are reading or writing
- */
- virtual void doTpxIO(t_fileio *fio, bool bRead) = 0;
-
/*! \brief
* Initializes a transform from mdp values to sectioned options.
*
real scalefactor; /* factor for scaling the MM charges in QM calc.*/
/* Fields for removed features go here (better caching) */
- gmx_bool bAdress; // Whether AdResS is enabled - always false if a valid .tpr was read
- gmx_bool useTwinRange; // Whether twin-range scheme is active - always false if a valid .tpr was read
+ gmx_bool bAdress; // Whether AdResS is enabled - always false if a valid .tpr was read
+ gmx_bool useTwinRange; // Whether twin-range scheme is active - always false if a valid .tpr was read
+
+ gmx::KeyValueTreeObject *params;
};
int ir_optimal_nstcalcenergy(const t_inputrec *ir);
for (i = 0; i < (fn2 ? 2 : 1); i++)
{
read_tpx_state(ff[i], ir[i], &state[i], &(mtop[i]));
+ mdModules[i].assignOptionsToModulesFromTpr();
}
if (fn2)
{
ir,
&state,
tpx.bTop ? &mtop : nullptr);
+ if (tpx.bIr)
+ {
+ mdModules.assignOptionsToModulesFromTpr();
+ }
if (mdpfn && tpx.bIr)
{
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016, by the GROMACS development team, led by
+ * Copyright (c) 2016,2017, 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.
}
void mergeObject(KeyValueTreeValue &&value)
{
- KeyValueTreeObject &obj = value.asObject();
+ mergeObject(std::move(value.asObject()));
+ }
+ void mergeObject(KeyValueTreeObject &&obj)
+ {
for (auto &prop : obj.valueMap_)
{
addRawValue(prop.first, std::move(prop.second));
{
/* Read (nearly) all data required for the simulation */
read_tpx_state(ftp2fn(efTPR, nfile, fnm), inputrec, state, mtop);
+ mdModules.assignOptionsToModulesFromTpr();
if (inputrec->cutoff_scheme == ecutsVERLET)
{