Merge "Merge release-2019 into master"
authorMark Abraham <mark.j.abraham@gmail.com>
Thu, 1 Aug 2019 09:54:26 +0000 (11:54 +0200)
committerMark Abraham <mark.j.abraham@gmail.com>
Thu, 1 Aug 2019 09:54:26 +0000 (11:54 +0200)
16 files changed:
src/gromacs/mdlib/md_support.cpp
src/gromacs/mdlib/md_support.h
src/gromacs/mdlib/tests/CMakeLists.txt
src/gromacs/mdlib/tests/constr.cpp
src/gromacs/mdlib/tests/constrtestdata.cpp [new file with mode: 0644]
src/gromacs/mdlib/tests/constrtestdata.h [moved from src/gromacs/mdlib/tests/constr_impl.h with 90% similarity]
src/gromacs/mdlib/tests/constrtestrunners.cpp [moved from src/gromacs/mdlib/tests/constr_impl.cpp with 99% similarity]
src/gromacs/mdlib/tests/constrtestrunners.cu [moved from src/gromacs/mdlib/tests/constr_impl.cu with 96% similarity]
src/gromacs/mdlib/tests/constrtestrunners.h [new file with mode: 0644]
src/gromacs/mdlib/update.cpp
src/gromacs/mdlib/update.h
src/gromacs/mdlib/vcm.cpp
src/gromacs/mdlib/vcm.h
src/gromacs/mdrun/md.cpp
src/gromacs/mdrun/mimic.cpp
src/gromacs/mdrun/rerun.cpp

index d3d1614c9103117d7c1c79a37002f18ca8c24871..a6cfbaff7338233210f471f965ed8b8e6f1d4eab 100644 (file)
@@ -153,15 +153,16 @@ int multisim_min(const gmx_multisim_t *ms, int nmin, int n)
 
 /* TODO Specialize this routine into init-time and loop-time versions?
    e.g. bReadEkin is only true when restoring from checkpoint */
-void compute_globals(FILE *fplog, gmx_global_stat *gstat, t_commrec *cr, t_inputrec *ir,
+void compute_globals(gmx_global_stat *gstat, t_commrec *cr, const t_inputrec *ir,
                      t_forcerec *fr, gmx_ekindata_t *ekind,
-                     rvec *x, rvec *v, matrix box, real vdwLambda, t_mdatoms *mdatoms,
+                     const rvec *x, const rvec *v, const matrix box,
+                     real vdwLambda, const t_mdatoms *mdatoms,
                      t_nrnb *nrnb, t_vcm *vcm, gmx_wallcycle_t wcycle,
                      gmx_enerdata_t *enerd, tensor force_vir, tensor shake_vir, tensor total_vir,
                      tensor pres, rvec mu_tot, gmx::Constraints *constr,
                      gmx::SimulationSignaller *signalCoordinator,
-                     matrix lastbox, int *totalNumberOfBondedInteractions,
-                     gmx_bool *bSumEkinhOld, int flags)
+                     const matrix lastbox, int *totalNumberOfBondedInteractions,
+                     gmx_bool *bSumEkinhOld, const int flags)
 {
     gmx_bool bEner, bPres, bTemp;
     gmx_bool bStopCM, bGStat,
@@ -211,8 +212,7 @@ void compute_globals(FILE *fplog, gmx_global_stat *gstat, t_commrec *cr, t_input
     /* Calculate center of mass velocity if necessary, also parallellized */
     if (bStopCM)
     {
-        calc_vcm_grp(0, mdatoms->homenr, mdatoms,
-                     x, v, vcm);
+        calc_vcm_grp(*mdatoms, x, v, vcm);
     }
 
     if (bTemp || bStopCM || bPres || bEner || bConstrain || bCheckNumberOfBondedInteractions)
@@ -243,23 +243,6 @@ void compute_globals(FILE *fplog, gmx_global_stat *gstat, t_commrec *cr, t_input
         }
     }
 
-    /* Do center of mass motion removal */
-    if (bStopCM)
-    {
-        check_cm_grp(fplog, vcm, ir, 1);
-        /* At initialization, do not pass x with acceleration-correction mode
-         * to avoid (incorrect) correction of the initial coordinates.
-         */
-        rvec *xPtr = nullptr;
-        if (vcm->mode == ecmANGULAR || (vcm->mode == ecmLINEAR_ACCELERATION_CORRECTION && !(flags & CGLO_INITIALIZATION)))
-        {
-            xPtr = x;
-        }
-        do_stopcm_grp(*mdatoms,
-                      xPtr, v, *vcm);
-        inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr);
-    }
-
     if (bEner)
     {
         /* Calculate the amplitude of the cosine velocity profile */
index 1ed48e542ce8babea35eb70dd5af2c0bf243775b..19acc1afd21a83e651991a9b405cfd079b2fcc5f 100644 (file)
@@ -65,8 +65,6 @@ class SimulationSignaller;
  * passed to compute_globals in md.c and global_stat.
  */
 
-/* we are initializing and not yet in the actual MD loop */
-#define CGLO_INITIALIZATION (1u<<1u)
 /* we are computing the kinetic energy from average velocities */
 #define CGLO_EKINAVEVEL     (1u<<2u)
 /* we are removing the center of mass momenta */
@@ -122,15 +120,22 @@ void setCurrentLambdasLocal(int64_t step, const t_lambda *fepvals,
 int multisim_min(const gmx_multisim_t *ms, int nmin, int n);
 /* Set an appropriate value for n across the whole multi-simulation */
 
-void compute_globals(FILE *fplog, gmx_global_stat *gstat, t_commrec *cr, t_inputrec *ir,
+
+/* Compute global variables during integration
+ *
+ * Coordinates x are needed for kinetic energy calculation with cosine accelation
+ * and for COM removal with rotational and acceleration correction modes.
+ * Velocities v are needed for kinetic energy calculation and for COM removal.
+ */
+void compute_globals(gmx_global_stat *gstat, t_commrec *cr, const t_inputrec *ir,
                      t_forcerec *fr, gmx_ekindata_t *ekind,
-                     rvec *x, rvec *v, matrix box, real vdwLambda, t_mdatoms *mdatoms,
+                     const rvec *x, const rvec *v, const matrix box,
+                     real vdwLambda, const t_mdatoms *mdatoms,
                      t_nrnb *nrnb, t_vcm *vcm, gmx_wallcycle_t wcycle,
                      gmx_enerdata_t *enerd, tensor force_vir, tensor shake_vir, tensor total_vir,
                      tensor pres, rvec mu_tot, gmx::Constraints *constr,
                      gmx::SimulationSignaller *signalCoordinator,
-                     matrix lastbox, int *totalNumberOfBondedInteractions,
+                     const matrix lastbox, int *totalNumberOfBondedInteractions,
                      gmx_bool *bSumEkinhOld, int flags);
-/* Compute global variables during integration */
 
 #endif
index 15ad0b1a1aeca64c5f74a75268c0b55a7413357d..6a1ec6a62f8e872d5ded8ac76518422360c487c4 100644 (file)
 # the research papers on the package. Check out http://www.gromacs.org.
 
 file(GLOB MDLIB_TEST_SOURCES
-     constr_impl.cpp
+     constrtestrunners.cpp
+     constrtestdata.cpp
      )
 
 if (GMX_USE_CUDA)
     file(GLOB MDLIB_TEST_CUDA_SOURCES
-         constr_impl.cu
+         constrtestrunners.cu
          settle_runners.cu
          )
 endif()
index 4d74583aec48c3c9b5369b45d9e960c56fe86504..1d6c85affd032774325ddee296f419fdc6adfc2b 100644 (file)
  * \author Artem Zhmurov <zhmurov@gmail.com>
  * \ingroup module_mdlib
  */
-
 #include "gmxpre.h"
 
-#include "gromacs/mdlib/constr.h"
-
 #include "config.h"
 
 #include <assert.h>
 
-#include <cmath>
-
-#include <algorithm>
 #include <unordered_map>
 #include <vector>
 
 #include <gtest/gtest.h>
 
-#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/gmxlib/nrnb.h"
-#include "gromacs/math/paddedvector.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/math/vectypes.h"
-#include "gromacs/mdlib/lincs.h"
-#include "gromacs/mdlib/shake.h"
-#include "gromacs/mdrunutility/multisim.h"
-#include "gromacs/mdtypes/commrec.h"
-#include "gromacs/mdtypes/inputrec.h"
-#include "gromacs/mdtypes/mdatom.h"
 #include "gromacs/pbcutil/pbc.h"
-#include "gromacs/topology/block.h"
-#include "gromacs/topology/idef.h"
-#include "gromacs/topology/ifunc.h"
-#include "gromacs/topology/topology.h"
-#include "gromacs/utility/smalloc.h"
 #include "gromacs/utility/stringutil.h"
-#include "gromacs/utility/unique_cptr.h"
 
-#include "testutils/refdata.h"
 #include "testutils/testasserts.h"
 
-#include "constr_impl.h"
+#include "constrtestdata.h"
+#include "constrtestrunners.h"
 
 namespace gmx
 {
 namespace test
 {
-
-ConstraintsTestData::ConstraintsTestData(const std::string &title,
-                                         int numAtoms, std::vector<real> masses,
-                                         std::vector<int> constraints, std::vector<real> constraintsR0,
-                                         bool computeVirial, tensor virialScaledRef,
-                                         bool compute_dHdLambda, float dHdLambdaRef,
-                                         real initialTime, real timestep,
-                                         const std::vector<RVec> &x, const std::vector<RVec> &xPrime, const std::vector<RVec> &v,
-                                         real shakeTolerance, gmx_bool shakeUseSOR,
-                                         int lincsNumIterations, int lincsExpansionOrder, real lincsWarnAngle)
-{
-    // This is to trick Gerrit
-    {
-        {
-            title_    = title;    // Human-friendly name of the system
-            numAtoms_ = numAtoms; // Number of atoms
-
-            // Masses of atoms
-            masses_ = masses;
-            invmass_.resize(numAtoms); // Vector of inverse masses
-
-            for (int i = 0; i < numAtoms; i++)
-            {
-                invmass_[i] = 1.0/masses.at(i);
-            }
-
-            // Saving constraints to check if they are satisfied after algorithm was applied
-            constraints_   = constraints;   // Constraints indices (in type-i-j format)
-            constraintsR0_ = constraintsR0; // Equilibrium distances for each type of constraint
-
-            invdt_  = 1.0/timestep;         // Inverse timestep
-
-            // Communication record
-            cr_.nnodes = 1;
-            cr_.dd     = nullptr;
-
-            // Multisim data
-            ms_.sim  = 0;
-            ms_.nsim = 1;
-
-            // Input record - data that usually comes from configuration file (.mdp)
-            ir_.efep           = 0;
-            ir_.init_t         = initialTime;
-            ir_.delta_t        = timestep;
-            ir_.eI             = 0;
-
-            // MD atoms data
-            md_.nMassPerturbed = 0;
-            md_.lambda         = 0.0;
-            md_.invmass        = invmass_.data();
-            md_.nr             = numAtoms;
-            md_.homenr         = numAtoms;
-
-            // Virial evaluation
-            computeVirial_ = computeVirial;
-            if (computeVirial)
-            {
-                for (int i = 0; i < DIM; i++)
-                {
-                    for (int j = 0; j < DIM; j++)
-                    {
-                        virialScaled_[i][j]    = 0;
-                        virialScaledRef_[i][j] = virialScaledRef[i][j];
-                    }
-                }
-            }
-
-
-            // Free energy evaluation
-            compute_dHdLambda_ = compute_dHdLambda;
-            dHdLambda_         = 0;
-            if (compute_dHdLambda_)
-            {
-                ir_.efep                    = efepYES;
-                dHdLambdaRef_               = dHdLambdaRef;
-            }
-            else
-            {
-                ir_.efep                    = efepNO;
-                dHdLambdaRef_               = 0;
-            }
-
-            // Constraints and their parameters (local topology)
-            for (int i = 0; i < F_NRE; i++)
-            {
-                idef_.il[i].nr = 0;
-            }
-            idef_.il[F_CONSTR].nr   = constraints.size();
-
-            snew(idef_.il[F_CONSTR].iatoms, constraints.size());
-            int maxType = 0;
-            for (unsigned i = 0; i < constraints.size(); i++)
-            {
-                if (i % 3 == 0)
-                {
-                    if (maxType < constraints.at(i))
-                    {
-                        maxType = constraints.at(i);
-                    }
-                }
-                idef_.il[F_CONSTR].iatoms[i] = constraints.at(i);
-            }
-            snew(idef_.iparams, maxType + 1);
-            for (unsigned i = 0; i < constraints.size()/3; i++)
-            {
-                idef_.iparams[constraints.at(3*i)].constr.dA = constraintsR0.at(constraints.at(3*i));
-                idef_.iparams[constraints.at(3*i)].constr.dB = constraintsR0.at(constraints.at(3*i));
-            }
-
-            // Constraints and their parameters (global topology)
-            InteractionList interactionList;
-            interactionList.iatoms.resize(constraints.size());
-            for (unsigned i = 0; i < constraints.size(); i++)
-            {
-                interactionList.iatoms.at(i) = constraints.at(i);
-            }
-            InteractionList interactionListEmpty;
-            interactionListEmpty.iatoms.resize(0);
-
-            gmx_moltype_t molType;
-            molType.atoms.nr             = numAtoms;
-            molType.ilist.at(F_CONSTR)   = interactionList;
-            molType.ilist.at(F_CONSTRNC) = interactionListEmpty;
-            mtop_.moltype.push_back(molType);
-
-            gmx_molblock_t molBlock;
-            molBlock.type = 0;
-            molBlock.nmol = 1;
-            mtop_.molblock.push_back(molBlock);
-
-            mtop_.natoms = numAtoms;
-            mtop_.ffparams.iparams.resize(maxType + 1);
-            for (int i = 0; i <= maxType; i++)
-            {
-                mtop_.ffparams.iparams.at(i) = idef_.iparams[i];
-            }
-            mtop_.bIntermolecularInteractions = false;
-
-            // Coordinates and velocities
-            x_.resizeWithPadding(numAtoms);
-            xPrime_.resizeWithPadding(numAtoms);
-            xPrime0_.resizeWithPadding(numAtoms);
-            xPrime2_.resizeWithPadding(numAtoms);
-
-            v_.resizeWithPadding(numAtoms);
-            v0_.resizeWithPadding(numAtoms);
-
-            std::copy(x.begin(), x.end(), x_.begin());
-            std::copy(xPrime.begin(), xPrime.end(), xPrime_.begin());
-            std::copy(xPrime.begin(), xPrime.end(), xPrime0_.begin());
-            std::copy(xPrime.begin(), xPrime.end(), xPrime2_.begin());
-
-            std::copy(v.begin(), v.end(), v_.begin());
-            std::copy(v.begin(), v.end(), v0_.begin());
-
-            // SHAKE-specific parameters
-            ir_.shake_tol            = shakeTolerance;
-            ir_.bShakeSOR            = shakeUseSOR;
-
-            // LINCS-specific parameters
-            ir_.nLincsIter     = lincsNumIterations;
-            ir_.nProjOrder     = lincsExpansionOrder;
-            ir_.LincsWarnAngle = lincsWarnAngle;
-        }
-    }
-}
-
-/*! \brief
- * Reset the data structure so it can be reused.
- *
- * Set the coordinates and velocities back to their values before
- * constraining. The scaled virial tensor and dHdLambda are zeroed.
- *
- */
-void ConstraintsTestData::reset()
-{
-    xPrime_  = xPrime0_;
-    xPrime2_ = xPrime0_;
-    v_       = v0_;
-
-    if (computeVirial_)
-    {
-        for (int i = 0; i < DIM; i++)
-        {
-            for (int j = 0; j < DIM; j++)
-            {
-                virialScaled_[i][j] = 0;
-            }
-        }
-    }
-    dHdLambda_         = 0;
-}
-
-/*! \brief
- * Cleaning up the memory.
- */
-ConstraintsTestData::~ConstraintsTestData()
-{
-    sfree(idef_.il[F_CONSTR].iatoms);
-    sfree(idef_.iparams);
-}
-
 namespace
 {
 
@@ -304,19 +81,19 @@ namespace
  */
 typedef std::tuple<std::string, std::string> ConstraintsTestParameters;
 
-//! Names of all availible algorithms
-std::vector<std::string> algorithmsNames;
+//! Names of all availible runners
+std::vector<std::string> runnersNames;
 
-//! Method that fills and returns algorithmNames to the test macros.
-std::vector<std::string> getAlgorithmsNames()
+//! Method that fills and returns runnersNames to the test macros.
+std::vector<std::string> getRunnersNames()
 {
-    algorithmsNames.emplace_back("SHAKE");
-    algorithmsNames.emplace_back("LINCS");
+    runnersNames.emplace_back("SHAKE");
+    runnersNames.emplace_back("LINCS");
     if (GMX_GPU == GMX_GPU_CUDA && canComputeOnGpu())
     {
-        algorithmsNames.emplace_back("LINCS_CUDA");
+        runnersNames.emplace_back("LINCS_CUDA");
     }
-    return algorithmsNames;
+    return runnersNames;
 }
 
 /*! \brief Test fixture for constraints.
@@ -886,12 +663,12 @@ TEST_P(ConstraintsTest, TriangleOfConstraints){
             lincsNIter, lincslincsExpansionOrder, lincsWarnAngle);
 
     std::string pbcName;
-    std::string algorithmName;
-    std::tie(pbcName, algorithmName) = GetParam();
-    t_pbc                                   pbc       = pbcs_.at(pbcName);
+    std::string runnerName;
+    std::tie(pbcName, runnerName) = GetParam();
+    t_pbc       pbc               = pbcs_.at(pbcName);
 
     // Apply constraints
-    algorithms_.at(algorithmName)(testData.get(), pbc);
+    algorithms_.at(runnerName)(testData.get(), pbc);
 
     checkConstrainsLength(absoluteTolerance(0.0002), *testData, pbc);
     checkConstrainsDirection(*testData, pbc);
@@ -905,7 +682,7 @@ TEST_P(ConstraintsTest, TriangleOfConstraints){
 
 INSTANTIATE_TEST_CASE_P(WithParameters, ConstraintsTest,
                             ::testing::Combine(::testing::Values("PBCNone", "PBCXYZ"),
-                                                   ::testing::ValuesIn(getAlgorithmsNames())));
+                                                   ::testing::ValuesIn(getRunnersNames())));
 
 } // namespace
 } // namespace test
diff --git a/src/gromacs/mdlib/tests/constrtestdata.cpp b/src/gromacs/mdlib/tests/constrtestdata.cpp
new file mode 100644 (file)
index 0000000..46c72d2
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2018,2019, 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 SHAKE and LINCS tests.
+ *
+ * \todo Better tests for virial are needed.
+ * \todo Tests for bigger systems to test threads synchronization,
+ *       reduction, etc. on the GPU.
+ * \todo Tests for algorithms for derivatives.
+ * \todo Free-energy perturbation tests
+ *
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ * \ingroup module_mdlib
+ */
+
+#include "gmxpre.h"
+
+#include "constrtestdata.h"
+
+#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
+
+namespace gmx
+{
+namespace test
+{
+
+ConstraintsTestData::ConstraintsTestData(const std::string &title,
+                                         int numAtoms, std::vector<real> masses,
+                                         std::vector<int> constraints, std::vector<real> constraintsR0,
+                                         bool computeVirial, tensor virialScaledRef,
+                                         bool compute_dHdLambda, float dHdLambdaRef,
+                                         real initialTime, real timestep,
+                                         const std::vector<RVec> &x, const std::vector<RVec> &xPrime, const std::vector<RVec> &v,
+                                         real shakeTolerance, gmx_bool shakeUseSOR,
+                                         int lincsNumIterations, int lincsExpansionOrder, real lincsWarnAngle)
+{
+    title_    = title;    // Human-friendly name of the system
+    numAtoms_ = numAtoms; // Number of atoms
+
+    // Masses of atoms
+    masses_ = masses;
+    invmass_.resize(numAtoms); // Vector of inverse masses
+
+    for (int i = 0; i < numAtoms; i++)
+    {
+        invmass_[i] = 1.0/masses.at(i);
+    }
+
+    // Saving constraints to check if they are satisfied after algorithm was applied
+    constraints_   = constraints;   // Constraints indices (in type-i-j format)
+    constraintsR0_ = constraintsR0; // Equilibrium distances for each type of constraint
+
+    invdt_  = 1.0/timestep;         // Inverse timestep
+
+    // Communication record
+    cr_.nnodes = 1;
+    cr_.dd     = nullptr;
+
+    // Multisim data
+    ms_.sim  = 0;
+    ms_.nsim = 1;
+
+    // Input record - data that usually comes from configuration file (.mdp)
+    ir_.efep           = 0;
+    ir_.init_t         = initialTime;
+    ir_.delta_t        = timestep;
+    ir_.eI             = 0;
+
+    // MD atoms data
+    md_.nMassPerturbed = 0;
+    md_.lambda         = 0.0;
+    md_.invmass        = invmass_.data();
+    md_.nr             = numAtoms;
+    md_.homenr         = numAtoms;
+
+    // Virial evaluation
+    computeVirial_ = computeVirial;
+    if (computeVirial)
+    {
+        for (int i = 0; i < DIM; i++)
+        {
+            for (int j = 0; j < DIM; j++)
+            {
+                virialScaled_[i][j]    = 0;
+                virialScaledRef_[i][j] = virialScaledRef[i][j];
+            }
+        }
+    }
+
+
+    // Free energy evaluation
+    compute_dHdLambda_ = compute_dHdLambda;
+    dHdLambda_         = 0;
+    if (compute_dHdLambda_)
+    {
+        ir_.efep                    = efepYES;
+        dHdLambdaRef_               = dHdLambdaRef;
+    }
+    else
+    {
+        ir_.efep                    = efepNO;
+        dHdLambdaRef_               = 0;
+    }
+
+    // Constraints and their parameters (local topology)
+    for (int i = 0; i < F_NRE; i++)
+    {
+        idef_.il[i].nr = 0;
+    }
+    idef_.il[F_CONSTR].nr   = constraints.size();
+
+    snew(idef_.il[F_CONSTR].iatoms, constraints.size());
+    int maxType = 0;
+    for (unsigned i = 0; i < constraints.size(); i++)
+    {
+        if (i % 3 == 0)
+        {
+            if (maxType < constraints.at(i))
+            {
+                maxType = constraints.at(i);
+            }
+        }
+        idef_.il[F_CONSTR].iatoms[i] = constraints.at(i);
+    }
+    snew(idef_.iparams, maxType + 1);
+    for (unsigned i = 0; i < constraints.size()/3; i++)
+    {
+        idef_.iparams[constraints.at(3*i)].constr.dA = constraintsR0.at(constraints.at(3*i));
+        idef_.iparams[constraints.at(3*i)].constr.dB = constraintsR0.at(constraints.at(3*i));
+    }
+
+    // Constraints and their parameters (global topology)
+    InteractionList interactionList;
+    interactionList.iatoms.resize(constraints.size());
+    for (unsigned i = 0; i < constraints.size(); i++)
+    {
+        interactionList.iatoms.at(i) = constraints.at(i);
+    }
+    InteractionList interactionListEmpty;
+    interactionListEmpty.iatoms.resize(0);
+
+    gmx_moltype_t molType;
+    molType.atoms.nr             = numAtoms;
+    molType.ilist.at(F_CONSTR)   = interactionList;
+    molType.ilist.at(F_CONSTRNC) = interactionListEmpty;
+    mtop_.moltype.push_back(molType);
+
+    gmx_molblock_t molBlock;
+    molBlock.type = 0;
+    molBlock.nmol = 1;
+    mtop_.molblock.push_back(molBlock);
+
+    mtop_.natoms = numAtoms;
+    mtop_.ffparams.iparams.resize(maxType + 1);
+    for (int i = 0; i <= maxType; i++)
+    {
+        mtop_.ffparams.iparams.at(i) = idef_.iparams[i];
+    }
+    mtop_.bIntermolecularInteractions = false;
+
+    // Coordinates and velocities
+    x_.resizeWithPadding(numAtoms);
+    xPrime_.resizeWithPadding(numAtoms);
+    xPrime0_.resizeWithPadding(numAtoms);
+    xPrime2_.resizeWithPadding(numAtoms);
+
+    v_.resizeWithPadding(numAtoms);
+    v0_.resizeWithPadding(numAtoms);
+
+    std::copy(x.begin(), x.end(), x_.begin());
+    std::copy(xPrime.begin(), xPrime.end(), xPrime_.begin());
+    std::copy(xPrime.begin(), xPrime.end(), xPrime0_.begin());
+    std::copy(xPrime.begin(), xPrime.end(), xPrime2_.begin());
+
+    std::copy(v.begin(), v.end(), v_.begin());
+    std::copy(v.begin(), v.end(), v0_.begin());
+
+    // SHAKE-specific parameters
+    ir_.shake_tol            = shakeTolerance;
+    ir_.bShakeSOR            = shakeUseSOR;
+
+    // LINCS-specific parameters
+    ir_.nLincsIter     = lincsNumIterations;
+    ir_.nProjOrder     = lincsExpansionOrder;
+    ir_.LincsWarnAngle = lincsWarnAngle;
+}
+
+/*! \brief
+ * Reset the data structure so it can be reused.
+ *
+ * Set the coordinates and velocities back to their values before
+ * constraining. The scaled virial tensor and dHdLambda are zeroed.
+ *
+ */
+void ConstraintsTestData::reset()
+{
+    xPrime_  = xPrime0_;
+    xPrime2_ = xPrime0_;
+    v_       = v0_;
+
+    if (computeVirial_)
+    {
+        for (int i = 0; i < DIM; i++)
+        {
+            for (int j = 0; j < DIM; j++)
+            {
+                virialScaled_[i][j] = 0;
+            }
+        }
+    }
+    dHdLambda_         = 0;
+}
+
+/*! \brief
+ * Cleaning up the memory.
+ */
+ConstraintsTestData::~ConstraintsTestData()
+{
+    sfree(idef_.il[F_CONSTR].iatoms);
+    sfree(idef_.iparams);
+}
+
+} // namespace test
+} // namespace gmx
similarity index 90%
rename from src/gromacs/mdlib/tests/constr_impl.h
rename to src/gromacs/mdlib/tests/constrtestdata.h
index 875591496895fb12c0978eb4e65b6e88dfdd1a5a..8375d6bbc5b72801256154e32593211d9a272454 100644 (file)
  * \ingroup module_mdlib
  */
 
-#ifndef GMX_MDLIB_TESTS_CONSTR_IMPL_H
-#define GMX_MDLIB_TESTS_CONSTR_IMPL_H
+#ifndef GMX_MDLIB_TESTS_CONSTRTESTDATA_H
+#define GMX_MDLIB_TESTS_CONSTRTESTDATA_H
 
-#include "gmxpre.h"
-
-#include <assert.h>
-
-#include <cmath>
-
-#include <algorithm>
-#include <unordered_map>
 #include <vector>
 
-#include "gromacs/fileio/gmxfio.h"
 #include "gromacs/gmxlib/nrnb.h"
-#include "gromacs/gmxlib/nonbonded/nonbonded.h"
 #include "gromacs/gpu_utils/gpu_testutils.h"
 #include "gromacs/math/paddedvector.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/math/vectypes.h"
-#include "gromacs/mdlib/constr.h"
 #include "gromacs/mdlib/gmx_omp_nthreads.h"
 #include "gromacs/mdlib/lincs.h"
 #include "gromacs/mdlib/shake.h"
 #include "gromacs/mdtypes/inputrec.h"
 #include "gromacs/mdtypes/mdatom.h"
 #include "gromacs/pbcutil/pbc.h"
-#include "gromacs/topology/block.h"
 #include "gromacs/topology/idef.h"
 #include "gromacs/topology/ifunc.h"
 #include "gromacs/topology/topology.h"
-#include "gromacs/utility/smalloc.h"
-#include "gromacs/utility/stringutil.h"
-#include "gromacs/utility/unique_cptr.h"
 
 namespace gmx
 {
@@ -218,20 +203,7 @@ class ConstraintsTestData
         ~ConstraintsTestData();
 };
 
-/*! \brief Apply SHAKE constraints to the test data.
- */
-void applyShake(ConstraintsTestData *testData, t_pbc pbc);
-/*! \brief Apply LINCS constraints to the test data.
- */
-void applyLincs(ConstraintsTestData *testData, t_pbc pbc);
-/*! \brief Apply CUDA version of LINCS constraints to the test data.
- *
- * All the data is copied to the GPU device, then LINCS is applied and
- * the resulting coordinates are copied back.
- */
-void applyLincsCuda(ConstraintsTestData *testData, t_pbc pbc);
-
 }      // namespace test
 }      // namespace gmx
 
-#endif // GMX_MDLIB_TESTS_CONSTR_IMPL_H
+#endif // GMX_MDLIB_TESTS_CONSTRTESTDATA_H
similarity index 99%
rename from src/gromacs/mdlib/tests/constr_impl.cpp
rename to src/gromacs/mdlib/tests/constrtestrunners.cpp
index 452fbd71e17086cab710ff7e3ebd7c69becd989b..dff35e7870f229b683fcf7eb86891d3182b0c95d 100644 (file)
@@ -44,7 +44,7 @@
 
 #include "gmxpre.h"
 
-#include "constr_impl.h"
+#include "constrtestrunners.h"
 
 #include "config.h"
 
@@ -53,7 +53,6 @@
 #include <cmath>
 
 #include <algorithm>
-#include <unordered_map>
 #include <vector>
 
 #include <gtest/gtest.h>
similarity index 96%
rename from src/gromacs/mdlib/tests/constr_impl.cu
rename to src/gromacs/mdlib/tests/constrtestrunners.cu
index 45027bdbb8ebb8f8482d95cc5a7e6b0765087ee3..88143aadfaea165b09c65ba6621cd2e016423a44 100644 (file)
  */
 #include "gmxpre.h"
 
-#include "constr_impl.h"
+#include "constrtestrunners.h"
 
 #include <assert.h>
 
 #include <cmath>
 
 #include <algorithm>
-#include <unordered_map>
 #include <vector>
 
 #include "gromacs/gpu_utils/devicebuffer.cuh"
 #include "gromacs/gpu_utils/gpu_utils.h"
-#include "gromacs/math/vec.h"
-#include "gromacs/math/vectypes.h"
-#include "gromacs/mdlib/constr.h"
 #include "gromacs/mdlib/lincs_cuda.cuh"
 #include "gromacs/pbcutil/pbc.h"
 #include "gromacs/utility/unique_cptr.h"
diff --git a/src/gromacs/mdlib/tests/constrtestrunners.h b/src/gromacs/mdlib/tests/constrtestrunners.h
new file mode 100644 (file)
index 0000000..45a27ab
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2018,2019, 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 SHAKE and LINCS tests header.
+ *
+ * Contains description and constructor for the test data accumulating object,
+ * declares CPU- and GPU-based functions used to apply SHAKE or LINCS on the
+ * test data.
+ *
+ * \author Artem Zhmurov <zhmurov@gmail.com>
+ * \ingroup module_mdlib
+ */
+
+#ifndef GMX_MDLIB_TESTS_CONSTRTESTRUNNERS_H
+#define GMX_MDLIB_TESTS_CONSTRTESTRUNNERS_H
+
+#include "constrtestdata.h"
+
+struct t_pbc;
+
+namespace gmx
+{
+namespace test
+{
+
+/*! \brief Apply SHAKE constraints to the test data.
+ */
+void applyShake(ConstraintsTestData *testData, t_pbc pbc);
+/*! \brief Apply LINCS constraints to the test data.
+ */
+void applyLincs(ConstraintsTestData *testData, t_pbc pbc);
+/*! \brief Apply CUDA version of LINCS constraints to the test data.
+ *
+ * All the data is copied to the GPU device, then LINCS is applied and
+ * the resulting coordinates are copied back.
+ */
+void applyLincsCuda(ConstraintsTestData *testData, t_pbc pbc);
+
+}      // namespace test
+}      // namespace gmx
+
+#endif // GMX_MDLIB_TESTS_CONSTRTESTRUNNERS_H
index 4b121d1bcff273f7aa262cf06d06de94c8c1ad50..35276d7c49cd4baef101ccbc691585ce6ff837d4 100644 (file)
@@ -1219,7 +1219,7 @@ static void calc_ke_part_visc(const matrix box, const rvec x[], const rvec v[],
 }
 
 void calc_ke_part(
-        rvec *x, rvec *v, matrix box,
+        const rvec *x, const rvec *v, const matrix box,
         const t_grpopts *opts, const t_mdatoms *md,
         gmx_ekindata_t *ekind, t_nrnb *nrnb, gmx_bool bEkinAveVel)
 {
index ffc75a45c3c4376bef06b03035cb83e244058199..3fef2cb3c2dd4e734daeab8fab6212dd72fd856e 100644 (file)
@@ -201,7 +201,7 @@ void finish_update(const t_inputrec       *inputrec,
 /* Return TRUE if OK, FALSE in case of Shake Error */
 
 void calc_ke_part(
-        rvec *x, rvec *v, matrix box,
+        const rvec *x, const rvec *v, const matrix box,
         const t_grpopts *opts, const t_mdatoms *md,
         gmx_ekindata_t *ekind, t_nrnb *nrnb, gmx_bool bEkinAveVel);
 /*
index 1388d1ebb457c43d5559ad96ac079de01383904f..34c5d7f9bfbaf4c3a3b1bbe578004c2b71cb5300 100644 (file)
@@ -54,7 +54,8 @@
 #include "gromacs/utility/gmxomp.h"
 #include "gromacs/utility/smalloc.h"
 
-t_vcm::t_vcm(const SimulationGroups &groups, const t_inputrec &ir)
+t_vcm::t_vcm(const SimulationGroups &groups, const t_inputrec &ir) :
+    integratorConservesMomentum(!EI_RANDOM(ir.eI))
 {
     mode     = (ir.nstcomm > 0) ? ir.comm_mode : ecmNO;
     ndim     = ndof_com(&ir);
@@ -151,8 +152,8 @@ static void update_tensor(const rvec x, real m0, tensor I)
 }
 
 /* Center of mass code for groups */
-void calc_vcm_grp(int start, int homenr, t_mdatoms *md,
-                  rvec x[], rvec v[], t_vcm *vcm)
+void calc_vcm_grp(const t_mdatoms &md,
+                  const rvec x[], const rvec v[], t_vcm *vcm)
 {
     int nthreads = gmx_omp_nthreads_get(emntDefault);
     if (vcm->mode != ecmNO)
@@ -176,13 +177,13 @@ void calc_vcm_grp(int start, int homenr, t_mdatoms *md,
             }
 
 #pragma omp for schedule(static)
-            for (int i = start; i < start+homenr; i++)
+            for (int i = 0; i < md.homenr; i++)
             {
                 int  g  = 0;
-                real m0 = md->massT[i];
-                if (md->cVCM)
+                real m0 = md.massT[i];
+                if (md.cVCM)
                 {
-                    g = md->cVCM[i];
+                    g = md.cVCM[i];
                 }
                 t_vcm_thread *vcm_t = &vcm->thread_vcm[t*vcm->stride + g];
                 /* Calculate linear momentum */
@@ -349,8 +350,8 @@ doStopComMotionAccelerationCorrection(int                   homenr,
     }
 }
 
-void do_stopcm_grp(const t_mdatoms &mdatoms,
-                   rvec x[], rvec v[], const t_vcm &vcm)
+static void do_stopcm_grp(const t_mdatoms &mdatoms,
+                          rvec x[], rvec v[], const t_vcm &vcm)
 {
     if (vcm.mode != ecmNO)
     {
@@ -460,7 +461,8 @@ static void get_minv(tensor A, tensor B)
     }
 }
 
-void check_cm_grp(FILE *fp, t_vcm *vcm, t_inputrec *ir, real Temp_Max)
+/* Processes VCM after reduction over ranks and prints warning with high VMC and fp != nullptr */
+static void process_and_check_cm_grp(FILE *fp, t_vcm *vcm, real Temp_Max)
 {
     int    m, g;
     real   ekcm, ekrot, tm, tm_1, Temp_cm;
@@ -546,7 +548,8 @@ void check_cm_grp(FILE *fp, t_vcm *vcm, t_inputrec *ir, real Temp_Max)
             if (vcm->mode == ecmANGULAR)
             {
                 ekrot = 0.5*iprod(vcm->group_j[g], vcm->group_w[g]);
-                if ((ekrot > 1) && fp && !EI_RANDOM(ir->eI))
+                // TODO: Change absolute energy comparison to relative
+                if ((ekrot > 1) && fp && vcm->integratorConservesMomentum)
                 {
                     /* if we have an integrator that may not conserve momenta, skip */
                     tm    = vcm->group_mass[g];
@@ -568,3 +571,17 @@ void check_cm_grp(FILE *fp, t_vcm *vcm, t_inputrec *ir, real Temp_Max)
         }
     }
 }
+
+void process_and_stopcm_grp(FILE *fplog,
+                            t_vcm *vcm,
+                            const t_mdatoms &mdatoms,
+                            rvec x[], rvec v[])
+{
+    if (vcm->mode != ecmNO)
+    {
+        // TODO: Replace fixed temperature of 1 by a system value
+        process_and_check_cm_grp(fplog, vcm, 1);
+
+        do_stopcm_grp(mdatoms, x, v, *vcm);
+    }
+}
index b50d4b0ac59e38afef32c014c3cd32580bedc5bd..555d3e3c17b1b2d542f8845ee093286e2eefbb21 100644 (file)
@@ -78,6 +78,9 @@ struct t_vcm
     ivec                     *nFreeze;    /* Tells whether dimensions are frozen per freeze group */
     std::vector<t_vcm_thread> thread_vcm; /* Temporary data per thread and group */
 
+    // Tell whether the integrator conserves momentum
+    bool integratorConservesMomentum;
+
     t_vcm(const SimulationGroups &groups, const t_inputrec &ir);
     ~t_vcm();
 };
@@ -87,16 +90,18 @@ void reportComRemovalInfo(FILE * fp, const t_vcm &vcm);
 
 
 /* Do a per group center of mass things */
-void calc_vcm_grp(int start, int homenr, t_mdatoms *md,
-                  rvec x[], rvec v[], t_vcm *vcm);
+void calc_vcm_grp(const t_mdatoms &md,
+                  const rvec x[], const rvec v[], t_vcm *vcm);
 
 /* Set the COM velocity to zero and potentially correct the COM position.
  *
- * With linear modes nullptr can be passed for x.
+ * Processes the kinetic energy reduced over MPI before removing COM motion.
+ * With mode linear, nullptr can be passed for x.
+ * With acceleration correction nullptr should be passed for x at initialization
+ * and a pointer to the coordinates at normal MD steps.
+ * When fplog != nullptr, a warning is printed to fplog with high COM velocity.
  */
-void do_stopcm_grp(const t_mdatoms &mdatoms,
-                   rvec x[], rvec v[], const t_vcm &vcm);
-
-void check_cm_grp(FILE *fp, t_vcm *vcm, t_inputrec *ir, real Temp_Max);
+void process_and_stopcm_grp(FILE *fplog, t_vcm *vcm, const t_mdatoms &mdatoms,
+                            rvec x[], rvec v[]);
 
 #endif
index 4a489a141e044e5814a701368f1cee7445870bed..167ad8a2fb44042350c0d0989def268467c99cd8 100644 (file)
@@ -515,7 +515,7 @@ void gmx::LegacySimulator::do_md()
         restore_ekinstate_from_state(cr, ekind, &state_global->ekinstate);
     }
 
-    unsigned int cglo_flags = (CGLO_INITIALIZATION | CGLO_TEMPERATURE | CGLO_GSTAT
+    unsigned int cglo_flags = (CGLO_TEMPERATURE | CGLO_GSTAT
                                | (EI_VV(ir->eI) ? CGLO_PRESSURE : 0)
                                | (EI_VV(ir->eI) ? CGLO_CONSTRAINT : 0)
                                | (hasReadEkinState ? CGLO_READEKIN : 0));
@@ -538,13 +538,26 @@ void gmx::LegacySimulator::do_md()
             cglo_flags_iteration |= CGLO_STOPCM;
             cglo_flags_iteration &= ~CGLO_TEMPERATURE;
         }
-        compute_globals(fplog, gstat, cr, ir, fr, ekind,
+        compute_globals(gstat, cr, ir, fr, ekind,
                         state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW],
                         mdatoms, nrnb, &vcm,
                         nullptr, enerd, force_vir, shake_vir, total_vir, pres, mu_tot,
                         constr, &nullSignaller, state->box,
                         &totalNumberOfBondedInteractions, &bSumEkinhOld, cglo_flags_iteration
                         | (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0));
+        if (cglo_flags_iteration & CGLO_STOPCM)
+        {
+            /* At initialization, do not pass x with acceleration-correction mode
+             * to avoid (incorrect) correction of the initial coordinates.
+             */
+            rvec *xPtr = nullptr;
+            if (vcm.mode != ecmLINEAR_ACCELERATION_CORRECTION)
+            {
+                xPtr = state->x.rvec_array();
+            }
+            process_and_stopcm_grp(fplog, &vcm, *mdatoms, xPtr, state->v.rvec_array());
+            inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr);
+        }
     }
     checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions,
                                     top_global, &top, state->x.rvec_array(), state->box,
@@ -557,7 +570,7 @@ void gmx::LegacySimulator::do_md()
            kinetic energy calculation.  This minimized excess variables, but
            perhaps loses some logic?*/
 
-        compute_globals(fplog, gstat, cr, ir, fr, ekind,
+        compute_globals(gstat, cr, ir, fr, ekind,
                         state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW],
                         mdatoms, nrnb, &vcm,
                         nullptr, enerd, force_vir, shake_vir, total_vir, pres, mu_tot,
@@ -834,7 +847,7 @@ void gmx::LegacySimulator::do_md()
             /* We need the kinetic energy at minus the half step for determining
              * the full step kinetic energy and possibly for T-coupling.*/
             /* This may not be quite working correctly yet . . . . */
-            compute_globals(fplog, gstat, cr, ir, fr, ekind,
+            compute_globals(gstat, cr, ir, fr, ekind,
                             state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW],
                             mdatoms, nrnb, &vcm,
                             wcycle, enerd, nullptr, nullptr, nullptr, nullptr, mu_tot,
@@ -991,7 +1004,7 @@ void gmx::LegacySimulator::do_md()
             if (bGStat || do_per_step(step-1, nstglobalcomm))
             {
                 wallcycle_stop(wcycle, ewcUPDATE);
-                compute_globals(fplog, gstat, cr, ir, fr, ekind,
+                compute_globals(gstat, cr, ir, fr, ekind,
                                 state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW],
                                 mdatoms, nrnb, &vcm,
                                 wcycle, enerd, force_vir, shake_vir, total_vir, pres, mu_tot,
@@ -1016,6 +1029,11 @@ void gmx::LegacySimulator::do_md()
                 checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions,
                                                 top_global, &top, state->x.rvec_array(), state->box,
                                                 &shouldCheckNumberOfBondedInteractions);
+                if (bStopCM)
+                {
+                    process_and_stopcm_grp(fplog, &vcm, *mdatoms, state->x.rvec_array(), state->v.rvec_array());
+                    inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr);
+                }
                 wallcycle_start(wcycle, ewcUPDATE);
             }
             /* temperature scaling and pressure scaling to produce the extended variables at t+dt */
@@ -1048,7 +1066,7 @@ void gmx::LegacySimulator::do_md()
                     /* We need the kinetic energy at minus the half step for determining
                      * the full step kinetic energy and possibly for T-coupling.*/
                     /* This may not be quite working correctly yet . . . . */
-                    compute_globals(fplog, gstat, cr, ir, fr, ekind,
+                    compute_globals(gstat, cr, ir, fr, ekind,
                                     state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW],
                                     mdatoms, nrnb, &vcm,
                                     wcycle, enerd, nullptr, nullptr, nullptr, nullptr, mu_tot,
@@ -1249,7 +1267,7 @@ void gmx::LegacySimulator::do_md()
         {
             /* erase F_EKIN and F_TEMP here? */
             /* just compute the kinetic energy at the half step to perform a trotter step */
-            compute_globals(fplog, gstat, cr, ir, fr, ekind,
+            compute_globals(gstat, cr, ir, fr, ekind,
                             state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW],
                             mdatoms, nrnb, &vcm,
                             wcycle, enerd, force_vir, shake_vir, total_vir, pres, mu_tot,
@@ -1338,7 +1356,7 @@ void gmx::LegacySimulator::do_md()
                 bool                doIntraSimSignal = true;
                 SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal);
 
-                compute_globals(fplog, gstat, cr, ir, fr, ekind,
+                compute_globals(gstat, cr, ir, fr, ekind,
                                 state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW],
                                 mdatoms, nrnb, &vcm,
                                 wcycle, enerd, force_vir, shake_vir, total_vir, pres, mu_tot,
@@ -1356,6 +1374,11 @@ void gmx::LegacySimulator::do_md()
                 checkNumberOfBondedInteractions(mdlog, cr, totalNumberOfBondedInteractions,
                                                 top_global, &top, state->x.rvec_array(), state->box,
                                                 &shouldCheckNumberOfBondedInteractions);
+                if (!EI_VV(ir->eI) && bStopCM)
+                {
+                    process_and_stopcm_grp(fplog, &vcm, *mdatoms, state->x.rvec_array(), state->v.rvec_array());
+                    inc_nrnb(nrnb, eNR_STOPCM, mdatoms->homenr);
+                }
             }
         }
 
index 9d790c21fadb47cfc0b0ddf8a46da4699e203aa5..bfd709a0225e65e22dd3d5d3cc46c625b38cc931 100644 (file)
@@ -305,12 +305,12 @@ void gmx::LegacySimulator::do_mimic()
     }
 
     {
-        int    cglo_flags = (CGLO_INITIALIZATION | CGLO_GSTAT |
+        int    cglo_flags = (CGLO_GSTAT |
                              (shouldCheckNumberOfBondedInteractions ?
                               CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0));
         bool   bSumEkinhOld = false;
         t_vcm *vcm          = nullptr;
-        compute_globals(fplog, gstat, cr, ir, fr, ekind,
+        compute_globals(gstat, cr, ir, fr, ekind,
                         state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW],
                         mdatoms, nrnb, vcm,
                         nullptr, enerd, force_vir, shake_vir, total_vir, pres, mu_tot,
@@ -516,7 +516,7 @@ void gmx::LegacySimulator::do_mimic()
             t_vcm              *vcm              = nullptr;
             SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal);
 
-            compute_globals(fplog, gstat, cr, ir, fr, ekind,
+            compute_globals(gstat, cr, ir, fr, ekind,
                             state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW],
                             mdatoms, nrnb, vcm,
                             wcycle, enerd, nullptr, nullptr, nullptr, nullptr, mu_tot,
index 48c1366148e1b8b152463f4ca90b9eddd7b55275..eb31c8a309b7d30feded2214336c39c4462e6fbb 100644 (file)
@@ -376,11 +376,11 @@ void gmx::LegacySimulator::do_rerun()
     }
 
     {
-        int    cglo_flags = (CGLO_INITIALIZATION | CGLO_GSTAT |
+        int    cglo_flags = (CGLO_GSTAT |
                              (shouldCheckNumberOfBondedInteractions ? CGLO_CHECK_NUMBER_OF_BONDED_INTERACTIONS : 0));
         bool   bSumEkinhOld = false;
         t_vcm *vcm          = nullptr;
-        compute_globals(fplog, gstat, cr, ir, fr, ekind,
+        compute_globals(gstat, cr, ir, fr, ekind,
                         state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW],
                         mdatoms, nrnb, vcm,
                         nullptr, enerd, force_vir, shake_vir, total_vir, pres, mu_tot,
@@ -638,7 +638,7 @@ void gmx::LegacySimulator::do_rerun()
             t_vcm              *vcm              = nullptr;
             SimulationSignaller signaller(&signals, cr, ms, doInterSimSignal, doIntraSimSignal);
 
-            compute_globals(fplog, gstat, cr, ir, fr, ekind,
+            compute_globals(gstat, cr, ir, fr, ekind,
                             state->x.rvec_array(), state->v.rvec_array(), state->box, state->lambda[efptVDW],
                             mdatoms, nrnb, vcm,
                             wcycle, enerd, force_vir, shake_vir, total_vir, pres, mu_tot,