Add end-to-end tests of energy minimization
authorMark Abraham <mark.j.abraham@gmail.com>
Tue, 4 Sep 2018 19:08:11 +0000 (21:08 +0200)
committerMark Abraham <mark.j.abraham@gmail.com>
Wed, 3 Oct 2018 16:36:26 +0000 (18:36 +0200)
Reformed CMakeLists.txt so that we have fewer issues running into
timeouts for each test run from ctest. This means the energy
minimization tests are reasonble to run in OpenCL configurations.

Added some convenience overloads of test infrastructure.

Change-Id: I3b21afb30a3367963d9921950f0dac17a66f15d1

28 files changed:
src/gromacs/mdrun/minimize.cpp
src/programs/mdrun/tests/CMakeLists.txt
src/programs/mdrun/tests/energycomparison.cpp
src/programs/mdrun/tests/energycomparison.h
src/programs/mdrun/tests/glycine_no_constraints_vacuo.gro [new file with mode: 0644]
src/programs/mdrun/tests/glycine_no_constraints_vacuo.ndx [new file with mode: 0644]
src/programs/mdrun/tests/glycine_no_constraints_vacuo.top [new file with mode: 0644]
src/programs/mdrun/tests/glycine_vacuo.gro [new file with mode: 0644]
src/programs/mdrun/tests/glycine_vacuo.itp [new file with mode: 0644]
src/programs/mdrun/tests/glycine_vacuo.ndx [new file with mode: 0644]
src/programs/mdrun/tests/glycine_vacuo.top [new file with mode: 0644]
src/programs/mdrun/tests/minimize.cpp [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_0.xml [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_1.xml [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_2.xml [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_3.xml [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_4.xml [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_5.xml [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_0.xml [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_1.xml [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_2.xml [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_3.xml [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_4.xml [new file with mode: 0644]
src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_5.xml [new file with mode: 0644]
src/programs/mdrun/tests/simulationdatabase.cpp
src/programs/mdrun/tests/simulationdatabase.h
src/testutils/refdata.cpp
src/testutils/refdata.h

index 04f394601b371351fe3c023e1e33e279bdbe487a..3adc5d219eb1532d62c5a7c7de1cbad9a8c0b0f5 100644 (file)
@@ -1726,7 +1726,7 @@ Integrator::do_lbfgs()
 
     if (PAR(cr))
     {
-        gmx_fatal(FARGS, "Cannot do parallel L-BFGS Minimization - yet.\n");
+        gmx_fatal(FARGS, "L-BFGS minimization only supports a single rank");
     }
 
     if (nullptr != constr)
index 24ae43628bfa47eda58d15a95c963b7e2ff2fe65..7d3d12f110689e47532f04e76628a126526c0ef2 100644 (file)
 # To help us fund GROMACS development, we humbly ask that you cite
 # the research papers on the package. Check out http://www.gromacs.org.
 
-# make an "object library" for code that we re-use for both kinds of tests
+# Make an "object library" for test infrastructure code that we re-use
+# in multiple test executables.
 add_library(mdrun_test_objlib OBJECT
     energyreader.cpp
+    energycomparison.cpp
     moduletest.cpp
     simulationdatabase.cpp
     terminationhelper.cpp
-    # PME tests
-    pmetest.cpp
+    trajectorycomparison.cpp
+    trajectoryreader.cpp
     )
 
 set(testname "MdrunTests")
@@ -49,17 +51,14 @@ gmx_add_gtest_executable(
     ${exename}
     # files with code for tests
     compressed_x_output.cpp
-    energycomparison.cpp
     grompp.cpp
     initialconstraints.cpp
     interactiveMD.cpp
-    rerun.cpp
+    pmetest.cpp
     swapcoords.cpp
     tabulated_bonded_interactions.cpp
     termination.cpp
     trajectory_writing.cpp
-    trajectorycomparison.cpp
-    trajectoryreader.cpp
     # pseudo-library for code for testing mdrun
     $<TARGET_OBJECTS:mdrun_test_objlib>
     # pseudo-library for code for mdrun
@@ -71,11 +70,33 @@ else()
     gmx_register_gtest_test(${testname} ${exename} OPENMP_THREADS 2 INTEGRATION_TEST)
 endif()
 
+# To avoid running into test timeouts, some end-to-end tests of mdrun
+# functionality are split off. This can be rearranged in future as we
+# see fit.
+set(testname "MdrunNonIntegratorTests")
+set(exename "mdrun-non-integrator-test")
+
+gmx_add_gtest_executable(
+    ${exename}
+    # files with code for tests
+    minimize.cpp
+    rerun.cpp
+    # pseudo-library for code for testing mdrun
+    $<TARGET_OBJECTS:mdrun_test_objlib>
+    # pseudo-library for code for mdrun
+    $<TARGET_OBJECTS:mdrun_objlib>
+    )
+gmx_register_gtest_test(${testname} ${exename} OPENMP_THREADS 2 INTEGRATION_TEST)
+
+# To permit other end-to-end tests to run with multiple OpenMP
+# threads, test cases that still use the group scheme are separated.
 set(testname "LegacyGroupSchemeMdrunTests")
 set(exename "legacy-mdrun-test")
 
 gmx_add_gtest_executable(
     ${exename}
+    # When TPI supports the Verlet scheme, move this into
+    # MdrunNonIntegratorTest
     tpitest.cpp
     # pseudo-library for code for testing mdrun
     $<TARGET_OBJECTS:mdrun_test_objlib>
@@ -84,6 +105,8 @@ gmx_add_gtest_executable(
     )
 gmx_register_gtest_test(${testname} ${exename} INTEGRATION_TEST)
 
+# Tests that only make sense to run with multiple ranks and/or real
+# MPI are implemented here.
 set(testname "MdrunMpiTests")
 set(exename "mdrun-mpi-test")
 
@@ -91,12 +114,18 @@ gmx_add_gtest_executable(
     ${exename} MPI
     # files with code for tests
     domain_decomposition.cpp
+    minimize.cpp
     multisim.cpp
     multisimtest.cpp
+    pmetest.cpp
     replicaexchange.cpp
     # pseudo-library for code for testing mdrun
     $<TARGET_OBJECTS:mdrun_test_objlib>
     # pseudo-library for code for mdrun
     $<TARGET_OBJECTS:mdrun_objlib>
     )
-gmx_register_gtest_test(${testname} ${exename} MPI_RANKS 2 INTEGRATION_TEST)
+if (GMX_GPU AND GMX_USE_OPENCL)
+    gmx_register_gtest_test(${testname} ${exename} OPENMP_THREADS 2 OCL_INTEGRATION_TEST)
+else()
+    gmx_register_gtest_test(${testname} ${exename} OPENMP_THREADS 2 INTEGRATION_TEST)
+endif()
index babe81bf9315f441589094b1e8fb0b76747bdafd..93e4fa47adef769b547ee0919e7730794040c020 100644 (file)
 
 #include "energycomparison.h"
 
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.h>
+
 #include "gromacs/trajectory/energyframe.h"
+#include "gromacs/utility/basenetwork.h"
+#include "gromacs/utility/strconvert.h"
+#include "gromacs/utility/stringutil.h"
 
+#include "testutils/refdata.h"
 #include "testutils/testasserts.h"
 
+#include "energyreader.h"
+#include "moduletest.h"
+
 namespace gmx
 {
 namespace test
@@ -75,5 +85,55 @@ void compareEnergyFrames(const EnergyFrame      &reference,
     }
 }
 
+void
+checkEnergiesAgainstReferenceData(const std::string      &energyFilename,
+                                  const EnergyTolerances &energiesToMatch,
+                                  TestReferenceChecker   *checker)
+{
+    const bool thisRankChecks = (gmx_node_rank() == 0);
+
+    if (thisRankChecks)
+    {
+        auto namesOfEnergiesToMatch = getKeys(energiesToMatch);
+        auto energyReader           = openEnergyFileToReadFields(energyFilename,
+                                                                 namesOfEnergiesToMatch);
+
+        std::unordered_map<std::string, TestReferenceChecker> checkers;
+        for (const auto &energyToMatch : energiesToMatch)
+        {
+            const auto &energyName = energyToMatch.first;
+            checkers[energyName] = checker->checkCompound("Energy", energyName.c_str());
+            const auto &energyTolerance = energyToMatch.second;
+            checkers[energyName].setDefaultTolerance(energyTolerance);
+        }
+
+        // We can't assume that frame names based purely on frame
+        // contents are unique. For example, CG can write multiple
+        // frames with the same step number. But we need a unique
+        // identifier so we match the intended reference data, so we
+        // keep track of the number of the frame read from the file.
+        int frameNumber = 0;
+        while (energyReader->readNextFrame())
+        {
+            const EnergyFrame &frame     = energyReader->frame();
+            const std::string  frameName = frame.frameName() + " in frame " + toString(frameNumber);
+
+            for (const auto &energyToMatch : energiesToMatch)
+            {
+                const std::string &energyName  = energyToMatch.first;
+                const real         energyValue = frame.at(energyName);
+
+                SCOPED_TRACE("Comparing " +  energyName + " in " + frameName);
+                checkers[energyName].checkReal(energyValue, frameName.c_str());
+            }
+            ++frameNumber;
+        }
+    }
+    else
+    {
+        EXPECT_NONFATAL_FAILURE(checker->checkUnusedEntries(), ""); // skip checks on other ranks
+    }
+}
+
 }  // namespace test
 }  // namespace gmx
index 51a26deb860a9e83ac668adea59f8e666a7f838e..10b6729ef238f9039fee821c8e8c1ff13f448a6a 100644 (file)
@@ -55,6 +55,8 @@ class EnergyFrame;
 namespace test
 {
 
+class TestReferenceChecker;
+
 //! Convenience type
 using EnergyTolerances = std::unordered_map<std::string, FloatingPointTolerance>;
 
@@ -68,6 +70,24 @@ void compareEnergyFrames(const EnergyFrame      &reference,
                          const EnergyFrame      &test,
                          const EnergyTolerances &tolerances);
 
+/*! \brief Check a subset of the energies found in an energy file
+ * against reference data.
+ *
+ * Opens the energy file, loops over all frames, matching the
+ * indicated energies against refdata at the given tolerance.
+ *
+ * \param[in]  energyFilename   The name of an energy file.
+ * \param[in]  energiesToMatch  Set of energies to match at given tolerances.
+ * \param[in]  checker          Root checker for reference data.
+ *
+ * \todo This is quite similar to the functionality used in PmeTest,
+ * and we should consider reducing the duplication.
+ */
+void
+checkEnergiesAgainstReferenceData(const std::string      &energyFilename,
+                                  const EnergyTolerances &energiesToMatch,
+                                  TestReferenceChecker   *checker);
+
 }  // namespace test
 }  // namespace gmx
 
diff --git a/src/programs/mdrun/tests/glycine_no_constraints_vacuo.gro b/src/programs/mdrun/tests/glycine_no_constraints_vacuo.gro
new file mode 100644 (file)
index 0000000..dd8ca9c
--- /dev/null
@@ -0,0 +1,13 @@
+Glycine
+   10
+    7GLY      N    1   4.063   1.415   0.028
+    7GLY     H1    2   4.152   1.370   0.036
+    7GLY     H2    3   3.990   1.348   0.041
+    7GLY     H3    4   4.055   1.456  -0.063
+    7GLY     CA    5   4.052   1.522   0.132
+    7GLY    HA1    6   4.075   1.480   0.229
+    7GLY    HA2    7   4.124   1.599   0.111
+    7GLY      C    8   3.921   1.596   0.127
+    7GLY    OT1    9   3.921   1.716   0.153
+    7GLY    OT2   10   3.903   1.695   0.218
+   8.05623   5.63712   7.44504
diff --git a/src/programs/mdrun/tests/glycine_no_constraints_vacuo.ndx b/src/programs/mdrun/tests/glycine_no_constraints_vacuo.ndx
new file mode 100644 (file)
index 0000000..0020d24
--- /dev/null
@@ -0,0 +1,2 @@
+[ System ]
+   1    2    3    4    5    6    7    8    9   10
diff --git a/src/programs/mdrun/tests/glycine_no_constraints_vacuo.top b/src/programs/mdrun/tests/glycine_no_constraints_vacuo.top
new file mode 100644 (file)
index 0000000..b6af4e4
--- /dev/null
@@ -0,0 +1,12 @@
+; Include forcefield parameters
+#include "charmm27.ff/forcefield.itp"
+
+#include "glycine_vacuo.itp"
+
+[ system ]
+; Name
+Glycine
+
+[ molecules ]
+; Compound        #mols
+Glycine           1
diff --git a/src/programs/mdrun/tests/glycine_vacuo.gro b/src/programs/mdrun/tests/glycine_vacuo.gro
new file mode 100644 (file)
index 0000000..dd8ca9c
--- /dev/null
@@ -0,0 +1,13 @@
+Glycine
+   10
+    7GLY      N    1   4.063   1.415   0.028
+    7GLY     H1    2   4.152   1.370   0.036
+    7GLY     H2    3   3.990   1.348   0.041
+    7GLY     H3    4   4.055   1.456  -0.063
+    7GLY     CA    5   4.052   1.522   0.132
+    7GLY    HA1    6   4.075   1.480   0.229
+    7GLY    HA2    7   4.124   1.599   0.111
+    7GLY      C    8   3.921   1.596   0.127
+    7GLY    OT1    9   3.921   1.716   0.153
+    7GLY    OT2   10   3.903   1.695   0.218
+   8.05623   5.63712   7.44504
diff --git a/src/programs/mdrun/tests/glycine_vacuo.itp b/src/programs/mdrun/tests/glycine_vacuo.itp
new file mode 100644 (file)
index 0000000..eecd4c5
--- /dev/null
@@ -0,0 +1,87 @@
+[ moleculetype ]
+; Name            nrexcl
+Glycine             3
+
+[ atoms ]
+;   nr       type  resnr residue  atom   cgnr     charge       mass  typeB    chargeB      massB
+; residue   7 GLY rtp GLY  q  0.0
+     1        NH3      7    GLY      N      1       -0.3     14.007   ; qtot -0.3
+     2         HC      7    GLY     H1      2       0.33      1.008   ; qtot 0.03
+     3         HC      7    GLY     H2      3       0.33      1.008   ; qtot 0.36
+     4         HC      7    GLY     H3      4       0.33      1.008   ; qtot 0.69
+     5        CT2      7    GLY     CA      5       0.13     12.011   ; qtot 0.82
+     6         HB      7    GLY    HA1      6       0.09      1.008   ; qtot 0.91
+     7         HB      7    GLY    HA2      7       0.09      1.008   ; qtot 1
+     8         CC      7    GLY      C      8       0.34     12.011   ; qtot 1.34
+     9         OC      7    GLY    OT1      9      -0.67    15.9994   ; qtot 0.67
+    10         OC      7    GLY    OT2     10      -0.67    15.9994   ; qtot 0
+
+[ bonds ]
+;  ai    aj funct            c0            c1            c2            c3
+    1     2     1
+    1     3     1
+    1     4     1
+    1     5     1
+    5     6     1
+    5     7     1
+    5     8     1
+    8     9     1
+    8    10     1
+
+[ pairs ]
+;  ai    aj funct            c0            c1            c2            c3
+    1     9     1
+    1    10     1
+    2     6     1
+    2     7     1
+    2     8     1
+    3     6     1
+    3     7     1
+    3     8     1
+    4     6     1
+    4     7     1
+    4     8     1
+    6     9     1
+    6    10     1
+    7     9     1
+    7    10     1
+
+[ angles ]
+;  ai    aj    ak funct            c0            c1            c2            c3
+    2     1     3     5
+    2     1     4     5
+    2     1     5     5
+    3     1     4     5
+    3     1     5     5
+    4     1     5     5
+    1     5     6     5
+    1     5     7     5
+    1     5     8     5
+    6     5     7     5
+    6     5     8     5
+    7     5     8     5
+    5     8     9     5
+    5     8    10     5
+    9     8    10     5
+
+[ dihedrals ]
+;  ai    aj    ak    al funct            c0            c1            c2            c3            c4            c5
+    2     1     5     6     9
+    2     1     5     7     9
+    2     1     5     8     9
+    3     1     5     6     9
+    3     1     5     7     9
+    3     1     5     8     9
+    4     1     5     6     9
+    4     1     5     7     9
+    4     1     5     8     9
+    1     5     8     9     9
+    1     5     8    10     9
+    6     5     8     9     9
+    6     5     8    10     9
+    7     5     8     9     9
+    7     5     8    10     9
+
+[ dihedrals ]
+;  ai    aj    ak    al funct            c0            c1            c2            c3
+    8     5    10     9     2
diff --git a/src/programs/mdrun/tests/glycine_vacuo.ndx b/src/programs/mdrun/tests/glycine_vacuo.ndx
new file mode 100644 (file)
index 0000000..0020d24
--- /dev/null
@@ -0,0 +1,2 @@
+[ System ]
+   1    2    3    4    5    6    7    8    9   10
diff --git a/src/programs/mdrun/tests/glycine_vacuo.top b/src/programs/mdrun/tests/glycine_vacuo.top
new file mode 100644 (file)
index 0000000..b6af4e4
--- /dev/null
@@ -0,0 +1,12 @@
+; Include forcefield parameters
+#include "charmm27.ff/forcefield.itp"
+
+#include "glycine_vacuo.itp"
+
+[ system ]
+; Name
+Glycine
+
+[ molecules ]
+; Compound        #mols
+Glycine           1
diff --git a/src/programs/mdrun/tests/minimize.cpp b/src/programs/mdrun/tests/minimize.cpp
new file mode 100644 (file)
index 0000000..1117939
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2018, 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.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+
+/*! \internal \file
+ * \brief
+ * Tests for the energy minimization functionality.
+ *
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \ingroup module_mdrun_integration_tests
+ */
+#include "gmxpre.h"
+
+#include <map>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include "gromacs/compat/make_unique.h"
+#include "gromacs/options/filenameoption.h"
+#include "gromacs/topology/idef.h"
+#include "gromacs/topology/ifunc.h"
+#include "gromacs/trajectory/energyframe.h"
+#include "gromacs/trajectory/trajectoryframe.h"
+#include "gromacs/utility/basenetwork.h"
+#include "gromacs/utility/stringutil.h"
+
+#include "testutils/mpitest.h"
+#include "testutils/refdata.h"
+#include "testutils/testasserts.h"
+
+#include "energycomparison.h"
+#include "energyreader.h"
+#include "moduletest.h"
+#include "simulationdatabase.h"
+
+namespace gmx
+{
+namespace test
+{
+namespace
+{
+
+/*! \brief Test fixture base for energy minimizaiton
+ *
+ * This test ensures mdrun can run an energy minimization, reaching
+ * a reproducible final energy.
+ *
+ * The choices for tolerance are arbitrary but sufficient. */
+class EnergyMinimizationTest : public MdrunTestFixture,
+                               public ::testing::WithParamInterface <
+                               std::tuple < std::string, std::string>>
+{
+};
+
+/*! \brief Database of empirical tolerances for EM integrators on the various systems. */
+std::unordered_map<std::string, FloatingPointTolerance> potentialEnergyToleranceForSystem_g =
+{{
+     {
+         "argon12",
+         relativeToleranceAsPrecisionDependentUlp(-1, 10, 200)
+     },
+     {
+         "spc5",
+         relativeToleranceAsPrecisionDependentUlp(-50, 150, 3500)
+     },
+     {
+         "glycine_vacuo",
+         relativeToleranceAsPrecisionDependentUlp(1000, 100, 100)
+     },
+     {
+         "alanine_vsite_vacuo",
+         relativeToleranceAsPrecisionDependentUlp(-160, 100, 400)
+     },
+     {
+         "glycine_no_constraints_vacuo",
+         relativeToleranceAsPrecisionDependentUlp(2000, 100, 100)
+     }
+ }};
+
+TEST_P(EnergyMinimizationTest, WithinTolerances)
+{
+    auto params         = GetParam();
+    auto simulationName = std::get<0>(params);
+    auto minimizer      = std::get<1>(params);
+    SCOPED_TRACE(formatString("Comparing '%s' energy minimization for simulation '%s'",
+                              minimizer.c_str(), simulationName.c_str()));
+
+    auto mdpFieldValues = prepareMdpFieldValues(simulationName.c_str(),
+                                                minimizer.c_str(),
+                                                "no", "no");
+    mdpFieldValues["nsteps"] = "4";
+
+    int maxWarningsTolerated = (minimizer == "l-bfgs") ? 1 : 0;
+    // prepare the .tpr file
+    {
+        // TODO evolve grompp to report the number of warnings issued, so
+        // tests always expect the right number.
+        CommandLine caller;
+        caller.append("grompp");
+        caller.addOption("-maxwarn", maxWarningsTolerated);
+        runner_.useTopGroAndNdxFromDatabase(simulationName);
+        runner_.useStringAsMdpFile(prepareMdpFileContents(mdpFieldValues));
+        EXPECT_EQ(0, runner_.callGrompp(caller));
+    }
+
+    // do mdrun, preparing to check the energies later
+    runner_.edrFileName_ = fileManager_.getTemporaryFilePath("minimize.edr");
+    {
+        CommandLine mdrunCaller;
+        mdrunCaller.append("mdrun");
+        if (minimizer == "l-bfgs" && getNumberOfTestMpiRanks() > 1)
+        {
+            // Ideally we would use this death test, but it is not
+            // stable enough in Jenkins, so we just skip it.
+            //EXPECT_DEATH_IF_SUPPORTED(runner_.callMdrun(mdrunCaller),
+            //                          "L-BFGS minimization only supports a single rank");
+            return;
+        }
+        else
+        {
+            ASSERT_EQ(0, runner_.callMdrun(mdrunCaller));
+        }
+    }
+
+    EnergyTolerances energiesToMatch
+    {{
+         {
+             interaction_function[F_EPOT].longname, potentialEnergyToleranceForSystem_g.at(simulationName)
+         },
+     }};
+
+    TestReferenceData refData;
+    auto              checker = refData.rootChecker()
+            .checkCompound("Simulation", simulationName)
+            .checkCompound("Minimizer", minimizer);
+    checkEnergiesAgainstReferenceData(runner_.edrFileName_,
+                                      energiesToMatch,
+                                      &checker);
+}
+
+//! Containers of systems and integrators to test.
+//! \{
+std::vector<std::string> unconstrainedSystemsToTest_g = { "argon12", "glycine_no_constraints_vacuo" };
+std::vector<std::string> minimizersToTest_g           = { "steep", "cg", "l-bfgs" };
+
+std::vector<std::string> constrainedSystemsToTest_g        = { "spc5", "glycine_vacuo", "alanine_vsite_vacuo" };
+std::vector<std::string> minimizersToTestWithConstraints_g = { "steep", "cg" };
+//! \}
+
+// The time for OpenCL kernel compilation means these tests might time
+// out. If that proves to be a problem, these can be disabled for
+// OpenCL builds. However, once that compilation is cached for the
+// lifetime of the whole test binary process, these tests should run in
+// such configurations.
+INSTANTIATE_TEST_CASE_P(MinimizersWorkWithConstraints, EnergyMinimizationTest,
+                            ::testing::Combine(::testing::ValuesIn(constrainedSystemsToTest_g),
+                                                   ::testing::ValuesIn(minimizersToTestWithConstraints_g)));
+INSTANTIATE_TEST_CASE_P(MinimizersWork, EnergyMinimizationTest,
+                            ::testing::Combine(::testing::ValuesIn(unconstrainedSystemsToTest_g),
+                                                   ::testing::ValuesIn(minimizersToTest_g)));
+
+} // namespace
+} // namespace test
+} // namespace gmx
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_0.xml b/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_0.xml
new file mode 100644 (file)
index 0000000..6899c4f
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="spc5">
+    <Minimizer Name="steep">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">-9.6231425679441998</Real>
+        <Real Name="Time 1.000000 Step 1 in frame 1">-16.824484254501229</Real>
+        <Real Name="Time 2.000000 Step 2 in frame 2">-27.187878502925926</Real>
+        <Real Name="Time 3.000000 Step 3 in frame 3">-37.906539302378249</Real>
+        <Real Name="Time 4.000000 Step 4 in frame 4">-47.991046443359224</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_1.xml b/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_1.xml
new file mode 100644 (file)
index 0000000..8e75a6a
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="spc5">
+    <Minimizer Name="cg">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">-9.6231425679441998</Real>
+        <Real Name="Time 0.000000 Step 0 in frame 1">-14.332060088206859</Real>
+        <Real Name="Time 4.000000 Step 4 in frame 2">-55.862253955236056</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_2.xml b/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_2.xml
new file mode 100644 (file)
index 0000000..b632228
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="glycine_vacuo">
+    <Minimizer Name="steep">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">2188.6237281397243</Real>
+        <Real Name="Time 1.000000 Step 1 in frame 1">1675.0453966455655</Real>
+        <Real Name="Time 2.000000 Step 2 in frame 2">1195.8320906920646</Real>
+        <Real Name="Time 3.000000 Step 3 in frame 3">739.9882576159057</Real>
+        <Real Name="Time 4.000000 Step 4 in frame 4">319.37689948961605</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_3.xml b/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_3.xml
new file mode 100644 (file)
index 0000000..10da56f
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="glycine_vacuo">
+    <Minimizer Name="cg">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">2188.6237281397243</Real>
+        <Real Name="Time 0.000000 Step 0 in frame 1">1842.8583301483945</Real>
+        <Real Name="Time 4.000000 Step 4 in frame 2">151.7430178757935</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_4.xml b/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_4.xml
new file mode 100644 (file)
index 0000000..a545eb2
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="alanine_vsite_vacuo">
+    <Minimizer Name="steep">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">-133.03444555671706</Real>
+        <Real Name="Time 1.000000 Step 1 in frame 1">-144.65547897475835</Real>
+        <Real Name="Time 3.000000 Step 3 in frame 2">-156.9841940951402</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_5.xml b/src/programs/mdrun/tests/refdata/MinimizersWorkWithConstraints_EnergyMinimizationTest_WithinTolerances_5.xml
new file mode 100644 (file)
index 0000000..2b96703
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="alanine_vsite_vacuo">
+    <Minimizer Name="cg">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">-133.03444555671706</Real>
+        <Real Name="Time 0.000000 Step 0 in frame 1">-147.76071249343909</Real>
+        <Real Name="Time 4.000000 Step 4 in frame 2">-169.41077894123521</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_0.xml b/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_0.xml
new file mode 100644 (file)
index 0000000..7d6aa02
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="argon12">
+    <Minimizer Name="steep">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">-0.97425707583544685</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_1.xml b/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_1.xml
new file mode 100644 (file)
index 0000000..cc80de5
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="argon12">
+    <Minimizer Name="cg">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">-0.97425707583544685</Real>
+        <Real Name="Time 0.000000 Step 0 in frame 1">-0.99064231389395707</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_2.xml b/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_2.xml
new file mode 100644 (file)
index 0000000..6562949
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="argon12">
+    <Minimizer Name="l-bfgs">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">-0.97425707583544685</Real>
+        <Real Name="Time 0.000000 Step 0 in frame 1">-0.99064231389395707</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_3.xml b/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_3.xml
new file mode 100644 (file)
index 0000000..f79a04c
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="glycine_no_constraints_vacuo">
+    <Minimizer Name="steep">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">2195.7786482024485</Real>
+        <Real Name="Time 1.000000 Step 1 in frame 1">1676.9767708823963</Real>
+        <Real Name="Time 2.000000 Step 2 in frame 2">1197.7060676659407</Real>
+        <Real Name="Time 3.000000 Step 3 in frame 3">741.59906676238325</Real>
+        <Real Name="Time 4.000000 Step 4 in frame 4">319.39548462989205</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_4.xml b/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_4.xml
new file mode 100644 (file)
index 0000000..8bf99c7
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="glycine_no_constraints_vacuo">
+    <Minimizer Name="cg">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">2195.7786482024485</Real>
+        <Real Name="Time 0.000000 Step 0 in frame 1">1848.1873657020258</Real>
+        <Real Name="Time 4.000000 Step 4 in frame 2">156.25879363422524</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
diff --git a/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_5.xml b/src/programs/mdrun/tests/refdata/MinimizersWork_EnergyMinimizationTest_WithinTolerances_5.xml
new file mode 100644 (file)
index 0000000..e63e232
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+  <Simulation Name="glycine_no_constraints_vacuo">
+    <Minimizer Name="l-bfgs">
+      <Energy Name="Potential">
+        <Real Name="Time 0.000000 Step 0 in frame 0">2195.7786482024485</Real>
+        <Real Name="Time 0.000000 Step 0 in frame 1">1848.1873657020258</Real>
+        <Real Name="Time 4.000000 Step 4 in frame 2">1847.227343785434</Real>
+      </Energy>
+    </Minimizer>
+  </Simulation>
+</ReferenceData>
index 72ff4bb6a2d1f13a602a20605431a3be1b9cb1d0..5f3e0b7fe7ce75d79bf5d2892f2bcfda2adebcf0 100644 (file)
@@ -111,8 +111,26 @@ MdpFileValues mdpFileValueDatabase_g
     {
         "alanine_vsite_solvated", { {
                                         "constraints", "all-bonds"
+                                    },
+                                    {
+                                        "compressibility", "5e-10"
+                                    },
+                                    {
+                                        "tau-p", "1000"
                                     } }
     },
+    // Zwitterionic glycine in vacuo
+    {
+        "glycine_vacuo", { {
+                               "constraints", "h-bonds"
+                           } }
+    },
+    // Zwitterionic glycine in vacuo, without constraints
+    {
+        "glycine_no_constraints_vacuo", { {
+                                              "constraints", "none"
+                                          } }
+    },
     // Nonanol molecule in vacuo, topology suitable for testing FEP
     // on KE, angles, dihedral restraints, coulomb and vdw
     {
index cafeb048131e01d22d94fffc5d8397266a98b069..8e99f393e06fb189a9862000b9539472e25627be 100644 (file)
@@ -63,7 +63,9 @@ using MdpFieldValues = std::map<std::string, std::string>;
  *     - spc216
  *     - alanine_vsite_vacuo
  *     - alanine_vsite_solvated
- *     - nonanol
+ *     - glycine_vacuo
+ *     - glycine_no_constraints_vacuo
+ *     - nonanol_vacuo
  *
  * Some of these systems are pretty minimal, because having
  * few atoms means few interactions, highly reproducible
index f703c2e2a6374269c23cd54bf18ace8d4e1d2bd1..af51f8a0280b788e618b0a4dfd18e91aa9858720 100644 (file)
@@ -830,6 +830,10 @@ TestReferenceChecker TestReferenceChecker::checkCompound(const char *type, const
                      impl_->defaultTolerance_));
 }
 
+TestReferenceChecker TestReferenceChecker::checkCompound(const char *type, const std::string &id)
+{
+    return checkCompound(type, id.c_str());
+}
 
 /*! \brief Throw a TestException if the caller tries to write particular refdata that can't work.
  *
index f6a12445f3c3f6e83667ce0a747a1a9c9d8659fa..c1040949d737bc54c3b04bcad96b24f78b19fe5e 100644 (file)
@@ -332,6 +332,8 @@ class TestReferenceChecker
          * Compound structures can be nested.
          */
         TestReferenceChecker checkCompound(const char *type, const char *id);
+        //! \copydoc checkCompound(const char *, const char *)
+        TestReferenceChecker checkCompound(const char *type, const std::string &id);
 
         //! Check a single boolean value.
         void checkBoolean(bool value, const char *id);