Decouple t_inputrec from MDModules
authorTeemu Murtola <teemu.murtola@gmail.com>
Sun, 26 Feb 2017 13:02:43 +0000 (15:02 +0200)
committerTeemu Murtola <teemu.murtola@gmail.com>
Mon, 27 Feb 2017 13:43:52 +0000 (14:43 +0100)
t_inputrec no longer depends on IInputRecExtension fields being
initialized, so it is not necessary to initialize it in gmx::MDModules.
Now t_inputrec can again be initialized without gmx::MDModules,
clarifying responsibilities.

For now, this again removes the need to use gmx::MDModules for just
reading t_inputrec.  These locations may need further changes as
responsibilities move around more, but in any case, t_inputrec ownership
should be better somewhere else than in MDModules.

Add constructor and destructor to t_inputrec to make it easier to manage
its instances.  Disallow copying (since that is tricky to implement
correctly), and do a manual only-what-is-required copy in PME
reinitialization, which is the only place that relied on copying

Change-Id: I52e0a17b13a0b7dad886fdf1b7d09bcbfcf961aa

23 files changed:
src/gromacs/applied-forces/tests/electricfield.cpp
src/gromacs/ewald/pme.cpp
src/gromacs/ewald/tests/pmebsplinetest.cpp
src/gromacs/ewald/tests/pmegathertest.cpp
src/gromacs/ewald/tests/pmesplinespreadtest.cpp
src/gromacs/gmxana/gmx_disre.cpp
src/gromacs/gmxana/gmx_energy.cpp
src/gromacs/gmxana/gmx_hbond.cpp
src/gromacs/gmxana/gmx_pme_error.cpp
src/gromacs/gmxana/gmx_spol.cpp
src/gromacs/gmxana/gmx_tune_pme.cpp
src/gromacs/gmxana/gmx_wham.cpp
src/gromacs/gmxpreprocess/grompp.cpp
src/gromacs/gmxpreprocess/readir.cpp
src/gromacs/gmxpreprocess/readir.h
src/gromacs/mdrunutility/mdmodules.cpp
src/gromacs/mdrunutility/mdmodules.h
src/gromacs/mdtypes/inputrec.cpp
src/gromacs/mdtypes/inputrec.h
src/gromacs/tools/check.cpp
src/gromacs/tools/convert_tpr.cpp
src/gromacs/tools/dump.cpp
src/programs/mdrun/runner.cpp

index fab8a36dd622d380b957525f6272a3b446092e36..dd0026a6e0546cbac934965cd3daf2010d272f1f 100644 (file)
@@ -99,7 +99,7 @@ class ElectricFieldTest : public ::testing::Test
                 .keyMatchType("/", gmx::StringCompareType::CaseAndDashInsensitive);
             module.initMdpTransform(transform.rules());
             auto result = transform.transform(mdpValues.build(), nullptr);
-            module.assignOptionsToModulesFromMdp(result.object(), nullptr);
+            module.assignOptionsToModules(result.object(), nullptr);
 
             t_mdatoms        md;
             PaddedRVecVector f = { { 0, 0, 0 } };
index b2eef57a6ee5201fbff8ed4fe0d7f272215a689b..0829acd5f7bbd1570dc24491a4368f338bf96dc3 100644 (file)
@@ -866,14 +866,23 @@ int gmx_pme_reinit(struct gmx_pme_t **pmedata,
                    real               ewaldcoeff_q,
                    real               ewaldcoeff_lj)
 {
-    t_inputrec irc;
     int        homenr;
     int        ret;
 
-    irc     = *ir;
-    irc.nkx = grid_size[XX];
-    irc.nky = grid_size[YY];
-    irc.nkz = grid_size[ZZ];
+    // Create a copy of t_inputrec fields that are used in gmx_pme_init().
+    // TODO: This would be better as just copying a sub-structure that contains
+    // all the PME parameters and nothing else.
+    t_inputrec irc;
+    irc.ePBC                   = ir->ePBC;
+    irc.coulombtype            = ir->coulombtype;
+    irc.vdwtype                = ir->vdwtype;
+    irc.efep                   = ir->efep;
+    irc.pme_order              = ir->pme_order;
+    irc.epsilon_r              = ir->epsilon_r;
+    irc.ljpme_combination_rule = ir->ljpme_combination_rule;
+    irc.nkx                    = grid_size[XX];
+    irc.nky                    = grid_size[YY];
+    irc.nkz                    = grid_size[ZZ];
 
     if (pme_src->nnodes == 1)
     {
index 04c0e520d775e783ffcbdc58cb68686de4091694..e75d3c0c0aa14ee34c0c429279b5bfed1c20f18f 100644 (file)
@@ -48,7 +48,6 @@
 
 #include "gromacs/ewald/pme-internal.h"
 #include "gromacs/math/vectypes.h"
-#include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/utility/stringutil.h"
 
@@ -76,10 +75,6 @@ typedef std::tuple<IVec, int, ModuliType> BSplineModuliInputParameters;
 /*! \brief Test fixture for testing PME B-spline moduli creation */
 class PmeBSplineModuliTest : public ::testing::TestWithParam<BSplineModuliInputParameters>
 {
-    private:
-        //! Environment for getting the t_inputrec structure easily
-        MDModules mdModules_;
-
     public:
         //! Default constructor
         PmeBSplineModuliTest() = default;
@@ -100,15 +95,15 @@ class PmeBSplineModuliTest : public ::testing::TestWithParam<BSplineModuliInputP
                                       gridSize[XX], gridSize[YY], gridSize[ZZ]));
 
             /* Storing the input where it's needed */
-            t_inputrec *inputRec = mdModules_.inputrec();
-            inputRec->nkx         = gridSize[XX];
-            inputRec->nky         = gridSize[YY];
-            inputRec->nkz         = gridSize[ZZ];
-            inputRec->coulombtype = (moduliType == ModuliType::P3M) ? eelP3M_AD : eelPME;
-            inputRec->pme_order   = pmeOrder;
+            t_inputrec inputRec;
+            inputRec.nkx         = gridSize[XX];
+            inputRec.nky         = gridSize[YY];
+            inputRec.nkz         = gridSize[ZZ];
+            inputRec.coulombtype = (moduliType == ModuliType::P3M) ? eelP3M_AD : eelPME;
+            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);
+            PmeSafePointer pme = pmeInitEmpty(&inputRec);
 
             /* Setting up the checker */
             TestReferenceData    refData;
index 3e79f4ce3c8c4674639ac9142d3a25ccbcf7b5e0..60c7d5e31c01fe4f6c7ef3cf52fbadf58642fca6 100644 (file)
@@ -46,7 +46,6 @@
 
 #include <gmock/gmock.h>
 
-#include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/utility/stringutil.h"
 
@@ -332,9 +331,6 @@ typedef std::tuple<Matrix3x3, int, IVec, SparseRealGridValuesInput, PmeGatherInp
 class PmeGatherTest : public ::testing::TestWithParam<GatherInputParameters>
 {
     private:
-        //! Environment for getting the t_inputrec structure easily
-        MDModules mdModules_;
-
         //! Storage of all the input atom datasets
         static InputDataByAtomCount s_inputAtomDataSets_;
 
@@ -386,12 +382,12 @@ class PmeGatherTest : public ::testing::TestWithParam<GatherInputParameters>
             auto inputAtomSplineData = inputAtomData.splineDataByPmeOrder[pmeOrder];
 
             /* Storing the input where it's needed, running the test */
-            t_inputrec *inputRec  = mdModules_.inputrec();
-            inputRec->nkx         = gridSize[XX];
-            inputRec->nky         = gridSize[YY];
-            inputRec->nkz         = gridSize[ZZ];
-            inputRec->pme_order   = pmeOrder;
-            inputRec->coulombtype = eelPME;
+            t_inputrec inputRec;
+            inputRec.nkx         = gridSize[XX];
+            inputRec.nky         = gridSize[YY];
+            inputRec.nkz         = gridSize[ZZ];
+            inputRec.pme_order   = pmeOrder;
+            inputRec.coulombtype = eelPME;
 
             TestReferenceData                     refData;
             const std::map<CodePath, std::string> modesToTest = {{CodePath::CPU, "CPU"}};
@@ -407,7 +403,7 @@ class PmeGatherTest : public ::testing::TestWithParam<GatherInputParameters>
                                           (inputForceTreatment == PmeGatherInputHandling::ReduceWith) ? "with reduction" : "without reduction"
                                           ));
 
-                PmeSafePointer pmeSafe = pmeInitWithAtoms(inputRec, inputAtomData.coordinates, inputAtomData.charges, box);
+                PmeSafePointer pmeSafe = pmeInitWithAtoms(&inputRec, inputAtomData.coordinates, inputAtomData.charges, box);
 
                 /* Setting some more inputs */
                 pmeSetRealGrid(pmeSafe.get(), mode.first, nonZeroGridValues);
index 1b9b147d79e602289ce1359088e38dd1d847ca1a..4adbdebca0c8397afc4c9a8164e950f51266b7a6 100644 (file)
@@ -46,7 +46,6 @@
 
 #include <gmock/gmock.h>
 
-#include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/utility/stringutil.h"
 
@@ -81,10 +80,6 @@ typedef std::tuple<Matrix3x3, int, IVec, CoordinatesVector, ChargesVector> Splin
  */
 class PmeSplineAndSpreadTest : public ::testing::TestWithParam<SplineAndSpreadInputParameters>
 {
-    private:
-        //! Environment for getting the t_inputrec structure easily
-        MDModules mdModules_;
-
     public:
         //! Default constructor
         PmeSplineAndSpreadTest() = default;
@@ -102,12 +97,12 @@ class PmeSplineAndSpreadTest : public ::testing::TestWithParam<SplineAndSpreadIn
             const size_t atomCount = coordinates.size();
 
             /* Storing the input where it's needed */
-            t_inputrec *inputRec  = mdModules_.inputrec();
-            inputRec->nkx         = gridSize[XX];
-            inputRec->nky         = gridSize[YY];
-            inputRec->nkz         = gridSize[ZZ];
-            inputRec->pme_order   = pmeOrder;
-            inputRec->coulombtype = eelPME;
+            t_inputrec inputRec;
+            inputRec.nkx         = gridSize[XX];
+            inputRec.nky         = gridSize[YY];
+            inputRec.nkz         = gridSize[ZZ];
+            inputRec.pme_order   = pmeOrder;
+            inputRec.coulombtype = eelPME;
 
             TestReferenceData                                      refData;
 
@@ -130,7 +125,7 @@ class PmeSplineAndSpreadTest : public ::testing::TestWithParam<SplineAndSpreadIn
 
                     /* Running the test */
 
-                    PmeSafePointer pmeSafe = pmeInitWithAtoms(inputRec, coordinates, charges, box);
+                    PmeSafePointer pmeSafe = pmeInitWithAtoms(&inputRec, coordinates, charges, box);
 
                     const bool     computeSplines = (option.first == PmeSplineAndSpreadOptions::SplineOnly) || (option.first == PmeSplineAndSpreadOptions::SplineAndSpreadUnified);
                     const bool     spreadCharges  = (option.first == PmeSplineAndSpreadOptions::SpreadOnly) || (option.first == PmeSplineAndSpreadOptions::SplineAndSpreadUnified);
index 31c04743be8d19fe8bbe6378a445b2ccc61ee68d..d70512f17da9c8aa1447cfd65c0de01f4e1b338e 100644 (file)
@@ -60,7 +60,6 @@
 #include "gromacs/mdlib/force.h"
 #include "gromacs/mdlib/mdatoms.h"
 #include "gromacs/mdlib/mdrun.h"
-#include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/fcdata.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
@@ -748,8 +747,8 @@ int gmx_disre(int argc, char *argv[])
         init5(ntop);
     }
 
-    gmx::MDModules  mdModules;
-    t_inputrec     *ir = mdModules.inputrec();
+    t_inputrec      irInstance;
+    t_inputrec     *ir = &irInstance;
 
     read_tpxheader(ftp2fn(efTPR, NFILE, fnm), &header, FALSE);
     snew(xtop, header.natoms);
index 984b966cc0450dd192c6d11fdd51a46b6e90c5cb..0b69c9dbba852044d807f74ecf1e658660d74934 100644 (file)
@@ -56,7 +56,6 @@
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdlib/mdebin.h"
-#include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/topology/ifunc.h"
@@ -2092,8 +2091,8 @@ int gmx_energy(int argc, char *argv[])
 
     bVisco = opt2bSet("-vis", NFILE, fnm);
 
-    gmx::MDModules  mdModules;
-    t_inputrec     *ir = mdModules.inputrec();
+    t_inputrec  irInstance;
+    t_inputrec *ir = &irInstance;
 
     if ((!bDisRe) && (!bDHDL))
     {
index 941f942a7337980fab8116f19c9c79a8c3b836ca..fa43c15eb8eaef0d97d90a1042785cd94fadd1e1 100644 (file)
@@ -59,7 +59,6 @@
 #include "gromacs/math/functions.h"
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
-#include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/topology/ifunc.h"
@@ -2586,8 +2585,8 @@ int gmx_hbond(int argc, char *argv[])
     hb = mk_hbdata(bHBmap, opt2bSet("-dan", NFILE, fnm), bMerge || bContact);
 
     /* get topology */
-    gmx::MDModules  mdModules;
-    t_inputrec     *ir = mdModules.inputrec();
+    t_inputrec      irInstance;
+    t_inputrec     *ir = &irInstance;
     read_tpx_top(ftp2fn(efTPR, NFILE, fnm), ir, box, &natoms, nullptr, nullptr, &top);
 
     snew(grpnames, grNR);
index d3a0bb019d565571ace959c8e0f5aec2f645cff1..b6d461196b664664a304b546adcf213aa2eae677 100644 (file)
@@ -52,7 +52,6 @@
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdlib/broadcaststructs.h"
-#include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/commrec.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
@@ -1149,11 +1148,9 @@ int gmx_pme_error(int argc, char *argv[])
     create_info(&info);
     info.fourier_sp[0] = fs;
 
-    gmx::MDModules mdModules;
-
     if (MASTER(cr))
     {
-        ir = mdModules.inputrec();
+        ir = new t_inputrec();
         read_tpr_file(opt2fn("-s", NFILE, fnm), &info, &state, &mtop, ir, user_beta, fracself);
         /* Open logfile for reading */
         fp = fopen(opt2fn("-o", NFILE, fnm), "w");
index 8baa73fa7cc00c60135288adba738a7529a559e8..25a78c08ae3c6bdbe99b369f07ba2c470874162f 100644 (file)
@@ -48,7 +48,6 @@
 #include "gromacs/math/functions.h"
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
-#include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/pbcutil/rmpbc.h"
@@ -152,7 +151,6 @@ void spol_atom2molindex(int *n, int *index, const t_block *mols)
 int gmx_spol(int argc, char *argv[])
 {
     t_topology  *top;
-    t_inputrec  *ir;
     t_atom      *atom;
     t_trxstatus *status;
     int          nrefat, natoms, nf, ntot;
@@ -224,8 +222,8 @@ int gmx_spol(int argc, char *argv[])
 
     snew(top, 1);
     // TODO: Only ePBC is used, not the full inputrec.
-    gmx::MDModules mdModules;
-    ir = mdModules.inputrec();
+    t_inputrec  irInstance;
+    t_inputrec *ir = &irInstance;
     read_tpx_top(ftp2fn(efTPR, NFILE, fnm),
                  ir, box, &natoms, nullptr, nullptr, top);
 
index e0d76d6dfafd77d95c5d9883939cac9e7401702e..ed14fbc0c8f978ce2f154d524ecb401cc92a12a0 100644 (file)
@@ -56,7 +56,6 @@
 #include "gromacs/math/utilities.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdlib/perf_est.h"
-#include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/commrec.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
@@ -871,13 +870,12 @@ static void modify_PMEsettings(
         const char     *fn_best_tpr, /* tpr file with the best performance */
         const char     *fn_sim_tpr)  /* name of tpr file to be launched */
 {
-    t_inputrec    *ir;
     t_state        state;
     gmx_mtop_t     mtop;
     char           buf[200];
 
-    gmx::MDModules mdModules;
-    ir = mdModules.inputrec();
+    t_inputrec     irInstance;
+    t_inputrec    *ir = &irInstance;
     read_tpx_state(fn_best_tpr, ir, &state, &mtop);
 
     /* Reset nsteps and init_step to the value of the input .tpr file */
@@ -915,7 +913,6 @@ static void make_benchmark_tprs(
         FILE           *fp)              /* Write the output here                         */
 {
     int           i, j, d;
-    t_inputrec   *ir;
     t_state       state;
     gmx_mtop_t    mtop;
     real          nlist_buffer;     /* Thickness of the buffer regions for PME-switch potentials */
@@ -938,8 +935,8 @@ static void make_benchmark_tprs(
     }
     fprintf(stdout, ".\n");
 
-    gmx::MDModules mdModules;
-    ir = mdModules.inputrec();
+    t_inputrec  irInstance;
+    t_inputrec *ir = &irInstance;
     read_tpx_state(fn_sim_tpr, ir, &state, &mtop);
 
     /* Check if some kind of PME was chosen */
@@ -2048,14 +2045,13 @@ static float inspect_tpr(int nfile, t_filenm fnm[], real *rcoulomb)
     gmx_bool     bFree;     /* Is a free energy simulation requested?         */
     gmx_bool     bNM;       /* Is a normal mode analysis requested?           */
     gmx_bool     bSwap;     /* Is water/ion position swapping requested?      */
-    t_inputrec  *ir;
     t_state      state;
     gmx_mtop_t   mtop;
 
 
     /* Check tpr file for options that trigger extra output files */
-    gmx::MDModules mdModules;
-    ir = mdModules.inputrec();
+    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   );
index 812ab007566d5dd589450ae947d49e53771c6d94..55f60a95b773d8af6b50bf6fe12e8f98a88f17e7 100644 (file)
@@ -61,7 +61,6 @@
 #include "gromacs/math/functions.h"
 #include "gromacs/math/units.h"
 #include "gromacs/math/vec.h"
-#include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/mdtypes/pull-params.h"
@@ -2052,8 +2051,8 @@ void read_pdo_files(char **fn, int nfiles, t_UmbrellaHeader* header,
 //! Read pull groups from a tpr file (including position, force const, geometry, number of groups)
 void read_tpr_header(const char *fn, t_UmbrellaHeader* header, t_UmbrellaOptions *opt, t_coordselection *coordsel)
 {
-    gmx::MDModules  mdModules;
-    t_inputrec     *ir = mdModules.inputrec();
+    t_inputrec      irInstance;
+    t_inputrec     *ir = &irInstance;
     t_state         state;
     static int      first = 1;
 
index 17f3a443095d77a58ff24e7ce471fbbe3b7c5993..8f3b440490e1bf6f11e82b5ccd0e9753aec31f74 100644 (file)
@@ -1842,8 +1842,9 @@ int gmx_grompp(int argc, char *argv[])
     /* PARAMETER file processing */
     mdparin = opt2fn("-f", NFILE, fnm);
     set_warning_line(wi, mdparin, -1);
-    get_ir(mdparin, opt2fn("-po", NFILE, fnm), &mdModules, opts, wi);
-    t_inputrec *ir = mdModules.inputrec();
+    t_inputrec  irInstance;
+    t_inputrec *ir = &irInstance;
+    get_ir(mdparin, opt2fn("-po", NFILE, fnm), &mdModules, ir, opts, wi);
 
     if (bVerbose)
     {
index fc848135b1086f8e5bf057e3158a38af5fbfb536..0c324469e5d409f7253d2f2fdcfde32746df7c0f 100644 (file)
@@ -1808,7 +1808,7 @@ class MdpErrorHandler : public gmx::IKeyValueTreeErrorHandler
 } // namespace
 
 void get_ir(const char *mdparin, const char *mdparout,
-            gmx::MDModules *mdModules, t_gromppopts *opts,
+            gmx::MDModules *mdModules, t_inputrec *ir, t_gromppopts *opts,
             warninp_t wi)
 {
     char       *dumstr[2];
@@ -1817,7 +1817,6 @@ void get_ir(const char *mdparin, const char *mdparout,
     const char *tmp;
     int         i, j, m, ninp;
     char        warn_buf[STRLEN];
-    t_inputrec *ir     = mdModules->inputrec();
     t_lambda   *fep    = ir->fepvals;
     t_expanded *expand = ir->expandedvals;
 
@@ -2249,9 +2248,11 @@ void get_ir(const char *mdparin, const char *mdparout,
         }
         MdpErrorHandler              errorHandler(wi);
         auto                         result
-            = transform.transform(convertedValues, &errorHandler);
+                   = transform.transform(convertedValues, &errorHandler);
+        ir->params = new gmx::KeyValueTreeObject(result.object());
+        mdModules->adjustInputrecBasedOnModules(ir);
         errorHandler.setBackMapping(result.backMapping());
-        mdModules->assignOptionsToModulesFromMdp(result.object(), &errorHandler);
+        mdModules->assignOptionsToModules(*ir->params, &errorHandler);
     }
 
     /* Ion/water position swapping ("computational electrophysiology") */
index 80b2aa4553dbf30be5190edd6ee529cedf2dd7f8..fc1357749ce6d703b0ebb7af61661d3a2c475dea 100644 (file)
@@ -114,7 +114,7 @@ void check_chargegroup_radii(const gmx_mtop_t *mtop, const t_inputrec *ir,
 /* Even more checks, charge group radii vs. cut-off's only. */
 
 void get_ir(const char *mdparin, const char *mdparout,
-            gmx::MDModules *mdModules, t_gromppopts *opts,
+            gmx::MDModules *mdModules, t_inputrec *ir, t_gromppopts *opts,
             warninp_t wi);
 /* Read the input file, and retrieve data for inputrec.
  * More data are read, but the are only evaluated when the next
index af22a974e3d859a63a2f3fe8811895321aad9c0e..902bd8a91818ecd73e594456a1a5f411b1a40be5 100644 (file)
@@ -56,25 +56,13 @@ class MDModules::Impl
 {
     public:
 
-        Impl() : field_(nullptr), ir_(nullptr)
+        Impl()
+            : field_(createElectricFieldModule())
         {
-            snew(ir_, 1);
-            snew(ir_->fepvals, 1);
-            snew(ir_->expandedvals, 1);
-            snew(ir_->simtempvals, 1);
             // TODO Eventually implement a proper IMDModule, to which
             // create*Module() would return a pointer. It might have
             // methods in its interface that return IInputRecExtension
             // (renamed IMdpOptionsProvider) and IForceProvider.
-            field_      = createElectricFieldModule();
-        }
-        ~Impl()
-        {
-            if (ir_ != nullptr)
-            {
-                done_inputrec(ir_);
-                sfree(ir_);
-            }
         }
 
         void makeModuleOptions(Options *options)
@@ -86,7 +74,6 @@ class MDModules::Impl
         }
 
         IInputRecExtensionPtr  field_;
-        t_inputrec            *ir_;
 };
 
 MDModules::MDModules() : impl_(new Impl)
@@ -97,16 +84,6 @@ MDModules::~MDModules()
 {
 }
 
-t_inputrec *MDModules::inputrec()
-{
-    return impl_->ir_;
-}
-
-const t_inputrec *MDModules::inputrec() const
-{
-    return impl_->ir_;
-}
-
 void MDModules::initMdpTransform(IKeyValueTreeTransformRules *rules)
 {
     // TODO The transform rules for applied-forces modules should
@@ -115,43 +92,26 @@ void MDModules::initMdpTransform(IKeyValueTreeTransformRules *rules)
     impl_->field_->initMdpTransform(rules);
 }
 
-void MDModules::assignOptionsToModulesFromMdp(const KeyValueTreeObject  &mdpOptionValues,
-                                              IKeyValueTreeErrorHandler *errorHandler)
+void MDModules::assignOptionsToModules(const KeyValueTreeObject  &params,
+                                       IKeyValueTreeErrorHandler *errorHandler)
 {
     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(&moduleOptions, params, errorHandler);
 }
 
-void MDModules::assignOptionsToModulesFromTpr()
+void MDModules::adjustInputrecBasedOnModules(t_inputrec *ir)
 {
     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);
-}
-
-void MDModules::adjustInputrecBasedOnModules()
-{
-    gmx::Options                        options;
-    impl_->field_->initMdpOptions(&options);
-    std::unique_ptr<KeyValueTreeObject> params(impl_->ir_->params);
-    // Avoid double freeing if the next operation throws.
-    impl_->ir_->params = nullptr;
-    impl_->ir_->params = new KeyValueTreeObject(
-                gmx::adjustKeyValueTreeFromOptions(*params, options));
+    std::unique_ptr<KeyValueTreeObject> params(
+            new KeyValueTreeObject(
+                    gmx::adjustKeyValueTreeFromOptions(*ir->params, moduleOptions)));
+    delete ir->params;
+    ir->params = params.release();
 }
 
 void MDModules::initOutput(FILE *fplog, int nfile, const t_filenm fnm[],
index 4219e5af7e144607ab37022de3f39868cf3a8e79..7383a90292a9ddf0eef2214827f0f846270a2bed 100644 (file)
@@ -81,11 +81,9 @@ class IKeyValueTreeTransformRules;
  * loops over a container of these interfaces, and/or groups of them (e.g.
  * applied forces), instead of the current single pointer.
  *
- * 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.
+ * The assignOptionsToModules() and adjustInputrecBasedOnModules() methods of
+ * this class also take responsibility for wiring up the options (and their
+ * defaults) for each module.
  *
  * \inlibraryapi
  * \ingroup module_mdrunutility
@@ -96,16 +94,6 @@ class MDModules
         MDModules();
         ~MDModules();
 
-        /*! \brief
-         * Returns an initialized t_inputrec structure.
-         *
-         * The inputrec structure is owned by MDModules and will be destroyed
-         * with it.
-         */
-        t_inputrec *inputrec();
-        //! \copydoc t_inputrec *inputrec()
-        const t_inputrec *inputrec() const;
-
         /*! \brief Initializes a transform from mdp values to
          * sectioned options.
          *
@@ -118,23 +106,15 @@ class MDModules
          */
         void initMdpTransform(IKeyValueTreeTransformRules *rules);
 
-        /*! \brief Use \c mdpOptionValues to set the options (e.g.read
-         * from mdp input) for each module.
+        /*! \brief
+         * Sets input parameters from `params` for each module.
          *
-         * \param[in] mdpOptionValues Contains keys and values from user
+         * \param[in]  params  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 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();
+        void assignOptionsToModules(const KeyValueTreeObject  &params,
+                                    IKeyValueTreeErrorHandler *errorHandler);
 
         /*! \brief
          * Normalizes inputrec parameters to match current code version.
@@ -142,7 +122,7 @@ class MDModules
          * This orders the parameters in inputrec to match the current code and
          * adds any missing defaults.
          */
-        void adjustInputrecBasedOnModules();
+        void adjustInputrecBasedOnModules(t_inputrec *ir);
 
         //! Initializes output files.
         void initOutput(FILE *fplog, int nfile, const t_filenm fnm[],
index c4daccd6db33476c188ac960da3c9bc82c7274e9..808fa1977f0735345510a41ca9a01125f869503d 100644 (file)
@@ -39,6 +39,7 @@
 #include "inputrec.h"
 
 #include <cstdio>
+#include <cstdlib>
 #include <cstring>
 
 #include <algorithm>
@@ -68,6 +69,19 @@ const int nstmin_berendsen_tcouple =  5;
 const int nstmin_berendsen_pcouple = 10;
 const int nstmin_harmonic          = 20;
 
+t_inputrec::t_inputrec()
+{
+    std::memset(this, 0, sizeof(*this));
+    snew(fepvals, 1);
+    snew(expandedvals, 1);
+    snew(simtempvals, 1);
+}
+
+t_inputrec::~t_inputrec()
+{
+    done_inputrec(this);
+}
+
 static int nst_wanted(const t_inputrec *ir)
 {
     if (ir->nstlist > 0)
index 1b8f81f10ed75abedb1a2043a028b5e980c70918..121359c040f7d5d8823531a15976a6110f65115d 100644 (file)
@@ -304,6 +304,11 @@ typedef struct t_swapcoords {
 
 struct t_inputrec
 {
+    t_inputrec();
+    explicit t_inputrec(const t_inputrec &) = delete;
+    t_inputrec &operator=(const t_inputrec &) = delete;
+    ~t_inputrec();
+
     int             eI;                      /* Integration method                 */
     gmx_int64_t     nsteps;                  /* number of steps to be taken                    */
     int             simulation_part;         /* Used in checkpointing to separate chunks */
index 381721e040d115efb921febec506f2d0376da140..9751122e10e38e6add252c9ff521d330a520e269 100644 (file)
@@ -91,8 +91,7 @@ static void comp_tpx(const char *fn1, const char *fn2,
                      gmx_bool bRMSD, real ftol, real abstol)
 {
     const char    *ff[2];
-    gmx::MDModules mdModules[2];
-    t_inputrec    *ir[2] = { mdModules[0].inputrec(), mdModules[1].inputrec() };
+    t_inputrec    *ir[2];
     t_state        state[2];
     gmx_mtop_t     mtop[2];
     t_topology     top[2];
@@ -102,8 +101,9 @@ static void comp_tpx(const char *fn1, const char *fn2,
     ff[1] = fn2;
     for (i = 0; i < (fn2 ? 2 : 1); i++)
     {
+        ir[i] = new t_inputrec();
         read_tpx_state(ff[i], ir[i], &state[i], &(mtop[i]));
-        mdModules[i].adjustInputrecBasedOnModules();
+        gmx::MDModules().adjustInputrecBasedOnModules(ir[i]);
     }
     if (fn2)
     {
@@ -247,17 +247,15 @@ static void tpx2params(FILE *fp, const t_inputrec *ir)
 static void tpx2methods(const char *tpx, const char *tex)
 {
     FILE          *fp;
-    t_inputrec    *ir;
     t_state        state;
     gmx_mtop_t     mtop;
 
-    gmx::MDModules mdModules;
-    ir = mdModules.inputrec();
-    read_tpx_state(tpx, ir, &state, &mtop);
+    t_inputrec     ir;
+    read_tpx_state(tpx, &ir, &state, &mtop);
     fp = gmx_fio_fopen(tex, "w");
     fprintf(fp, "\\section{Methods}\n");
     tpx2system(fp, &mtop);
-    tpx2params(fp, ir);
+    tpx2params(fp, &ir);
     gmx_fio_fclose(fp);
 }
 
@@ -390,14 +388,12 @@ void chk_trj(const gmx_output_env_t *oenv, const char *fn, const char *tpr, real
     gmx_mtop_t       mtop;
     gmx_localtop_t  *top = nullptr;
     t_state          state;
-    t_inputrec      *ir;
+    t_inputrec       ir;
 
-    gmx::MDModules   mdModules;
-    ir = mdModules.inputrec();
     if (tpr)
     {
-        read_tpx_state(tpr, ir, &state, &mtop);
-        top = gmx_mtop_generate_local_top(&mtop, ir->efep != efepNO);
+        read_tpx_state(tpr, &ir, &state, &mtop);
+        top = gmx_mtop_generate_local_top(&mtop, ir.efep != efepNO);
     }
     new_natoms = -1;
     natoms     = -1;
@@ -464,7 +460,7 @@ void chk_trj(const gmx_output_env_t *oenv, const char *fn, const char *tpr, real
         natoms = new_natoms;
         if (tpr)
         {
-            chk_bonds(&top->idef, ir->ePBC, fr.x, fr.box, tol);
+            chk_bonds(&top->idef, ir.ePBC, fr.x, fr.box, tol);
         }
         if (fr.bX)
         {
index a2764f506b62f5649b8c7447e7898a0bae9928cc..f63d708d4a5c6abc0dcb283b2ceecbb1ef305bfe 100644 (file)
@@ -44,7 +44,6 @@
 #include "gromacs/fileio/tpxio.h"
 #include "gromacs/fileio/trrio.h"
 #include "gromacs/math/vec.h"
-#include "gromacs/mdrunutility/mdmodules.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/mdtypes/state.h"
@@ -350,7 +349,6 @@ int gmx_convert_tpr(int argc, char *argv[])
     gmx_bool          bNsteps, bExtend, bUntil;
     gmx_mtop_t        mtop;
     t_atoms           atoms;
-    t_inputrec       *ir;
     t_state           state;
     int               gnx;
     char             *grpname;
@@ -395,8 +393,8 @@ int gmx_convert_tpr(int argc, char *argv[])
     top_fn = ftp2fn(efTPR, NFILE, fnm);
     fprintf(stderr, "Reading toplogy and stuff from %s\n", top_fn);
 
-    gmx::MDModules mdModules;
-    ir = mdModules.inputrec();
+    t_inputrec  irInstance;
+    t_inputrec *ir = &irInstance;
     read_tpx_state(top_fn, ir, &state, &mtop);
     run_step = ir->init_step;
     run_t    = ir->init_step*ir->delta_t + ir->init_t;
index e2af9cb1f50a032e195f53bec67fdd51effdc01e..ced610a3eb0beebb77e22b70e5ff38007c242267 100644 (file)
@@ -80,31 +80,27 @@ static void list_tpx(const char *fn,
     FILE         *gp;
     int           indent, i, j, **gcount, atot;
     t_state       state;
-    t_inputrec   *ir = nullptr;
     t_tpxheader   tpx;
     gmx_mtop_t    mtop;
     gmx_groups_t *groups;
     t_topology    top;
 
     read_tpxheader(fn, &tpx, TRUE);
-    gmx::MDModules mdModules;
-    if (tpx.bIr)
-    {
-        ir = mdModules.inputrec();
-    }
+    t_inputrec     ir;
     read_tpx_state(fn,
-                   ir,
+                   tpx.bIr ? &ir : nullptr,
                    &state,
                    tpx.bTop ? &mtop : nullptr);
     if (tpx.bIr && !bOriginalInputrec)
     {
-        mdModules.adjustInputrecBasedOnModules();
+        gmx::MDModules mdModules;
+        mdModules.adjustInputrecBasedOnModules(&ir);
     }
 
     if (mdpfn && tpx.bIr)
     {
         gp = gmx_fio_fopen(mdpfn, "w");
-        pr_inputrec(gp, 0, nullptr, ir, TRUE);
+        pr_inputrec(gp, 0, nullptr, &ir, TRUE);
         gmx_fio_fclose(gp);
     }
 
@@ -119,7 +115,7 @@ static void list_tpx(const char *fn,
         {
             indent = 0;
             pr_title(stdout, indent, fn);
-            pr_inputrec(stdout, 0, "inputrec", ir, FALSE);
+            pr_inputrec(stdout, 0, "inputrec", tpx.bIr ? &ir : nullptr, FALSE);
 
             pr_tpxheader(stdout, indent, "header", &(tpx));
 
index 9628e7283feb25f0002be0239e1e6a7a97511bb8..8f16119320549492a9661bb39a799f711ac6ca45 100644 (file)
@@ -707,7 +707,6 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
              int imdport, unsigned long Flags)
 {
     gmx_bool                  bForceUseGPU, bTryUseGPU, bRerunMD;
-    t_inputrec               *inputrec;
     matrix                    box;
     gmx_ddbox_t               ddbox = {0};
     int                       npme_major, npme_minor;
@@ -736,7 +735,8 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
     /* CAUTION: threads may be started later on in this function, so
        cr doesn't reflect the final parallel state right now */
     gmx::MDModules mdModules;
-    inputrec = mdModules.inputrec();
+    t_inputrec     inputrecInstance;
+    t_inputrec    *inputrec = &inputrecInstance;
     snew(mtop, 1);
 
     if (Flags & MD_APPENDFILES)
@@ -896,7 +896,8 @@ int mdrunner(gmx_hw_opt_t *hw_opt,
          */
         gmx_bcast_sim(sizeof(bUseGPU), &bUseGPU, cr);
     }
-    mdModules.assignOptionsToModulesFromTpr();
+    // TODO: Error handling
+    mdModules.assignOptionsToModules(*inputrec->params, nullptr);
 
     if (fplog != nullptr)
     {