Commit 05ad28f2 authored by one's avatar one
Browse files

Merge OpenMM master into dtk26.04

parents 97239ca6 fc21fd19
...@@ -666,12 +666,12 @@ jobs: ...@@ -666,12 +666,12 @@ jobs:
)") )")
for d in api-c++ api-python developerguide userguide; do for d in api-c++ api-python developerguide userguide; do
echo "::group:: Check ${d}" echo "::group:: Check ${d}"
npx linkinator@3.0.0 ./${d}/ --recurse --timeout=20000 --retry-errors --skip "$SKIP_REGEX" --server-root ./build/api-docs --verbosity error npx linkinator@7.6.1 ./${d}/ --recurse --timeout=20000 --retry-errors --skip "$SKIP_REGEX" --server-root ./build/api-docs --verbosity error
((exitcode+=$?)) ((exitcode+=$?))
echo "::endgroup::" echo "::endgroup::"
done done
echo "::group:: Check README" echo "::group:: Check README"
npx linkinator@3.0.0 ./README.md --markdown --retry-errors --skip "$SKIP_REGEX" npx linkinator@7.6.1 ./README.md --markdown --retry-errors --skip "$SKIP_REGEX"
((exitcode+=$?)) ((exitcode+=$?))
echo "::endgroup::" echo "::endgroup::"
exit $exitcode exit $exitcode
...@@ -615,7 +615,7 @@ CHARMM36 ...@@ -615,7 +615,7 @@ CHARMM36
-------- --------
The CHARMM36\ :cite:`Best2012` force field provides parameters for proteins, DNA, The CHARMM36\ :cite:`Best2012` force field provides parameters for proteins, DNA,
RNA, lipids, carbohydrates, water, ions, and various small molecules (see `here <http://mackerell.umaryland.edu/charmm_ff.shtml#refs>`_ RNA, lipids, carbohydrates, water, ions, and various small molecules (see `here <https://mackerell.umaryland.edu/charmm_ff.shtml#refs>`_
for full references). for full references).
.. tabularcolumns:: |l|L| .. tabularcolumns:: |l|L|
...@@ -657,12 +657,12 @@ such as :file:`charmm36_2024/water.xml`, which specifies the default CHARMM wate ...@@ -657,12 +657,12 @@ such as :file:`charmm36_2024/water.xml`, which specifies the default CHARMM wate
how to add hydrogens to these nonstandard residues, and your input topologies how to add hydrogens to these nonstandard residues, and your input topologies
must already contain appropriate hydrogens. This can often cause problems when must already contain appropriate hydrogens. This can often cause problems when
trying to read in PDB files from sources such as `CHARMM-GUI <http://charmm-gui.org/>`_ trying to read in PDB files from sources such as `CHARMM-GUI <http://charmm-gui.org/>`_
that do not generate PDB files that comply with the `PDB standard <http://www.wwpdb.org/documentation/file-format>`_. that do not generate PDB files that comply with the `PDB standard <https://www.wwpdb.org/documentation/file-format>`_.
If you're using files from `CHARMM-GUI <http://charmm-gui.org/>`_, it's easiest to load If you're using files from `CHARMM-GUI <http://charmm-gui.org/>`_, it's easiest to load
the PSF file directly, as discussed in Section :numref:`using-charmm-files`. the PSF file directly, as discussed in Section :numref:`using-charmm-files`.
.. tip:: Trying to read in PDB files from sources such as `CHARMM-GUI <http://charmm-gui.org/>`_ .. tip:: Trying to read in PDB files from sources such as `CHARMM-GUI <http://charmm-gui.org/>`_
that do not generate PDB files that comply with the `PDB standard <http://www.wwpdb.org/documentation/file-format>`_ that do not generate PDB files that comply with the `PDB standard <https://www.wwpdb.org/documentation/file-format>`_
and omit ``CONECT`` records specifying bonds between residues (such as cysteines) and omit ``CONECT`` records specifying bonds between residues (such as cysteines)
or include ``CONECT`` records specifying non-chemical ``H-H`` bonds in waters or include ``CONECT`` records specifying non-chemical ``H-H`` bonds in waters
can cause issues with the detection and parameter assignment for disulfide bonds. can cause issues with the detection and parameter assignment for disulfide bonds.
...@@ -687,7 +687,7 @@ such as :file:`charmm36_2024/water.xml`, which specifies the default CHARMM wate ...@@ -687,7 +687,7 @@ such as :file:`charmm36_2024/water.xml`, which specifies the default CHARMM wate
additional force field XML files that can be loaded as needed. additional force field XML files that can be loaded as needed.
The converted parameter sets come from the The converted parameter sets come from the
`CHARMM36 July 2024 update <http://mackerell.umaryland.edu/charmm_ff.shtml>`_, `CHARMM36 July 2024 update <https://mackerell.umaryland.edu/charmm_ff.shtml>`_,
which includes the CHARMM36m protein parameters. They were converted using the which includes the CHARMM36m protein parameters. They were converted using the
openmmforcefields_ package and `ParmEd <https://github.com/parmed/parmed>`_. openmmforcefields_ package and `ParmEd <https://github.com/parmed/parmed>`_.
...@@ -1494,8 +1494,8 @@ OpenMM can save simulation trajectories to disk in four formats: PDB_, ...@@ -1494,8 +1494,8 @@ OpenMM can save simulation trajectories to disk in four formats: PDB_,
`PDBx/mmCIF`_, DCD_ and XTC_. All of these are widely supported formats, so you `PDBx/mmCIF`_, DCD_ and XTC_. All of these are widely supported formats, so you
should be able to read them into most analysis and visualization programs. should be able to read them into most analysis and visualization programs.
.. _PDB: http://www.wwpdb.org/documentation/format33/v3.3.html .. _PDB: https://www.wwpdb.org/documentation/file-format-content/format33/v3.3.html
.. _PDBx/mmCIF: http://mmcif.wwpdb.org .. _PDBx/mmCIF: https://mmcif.wwpdb.org
.. _DCD: http://www.ks.uiuc.edu/Research/vmd/plugins/molfile/dcdplugin.html .. _DCD: http://www.ks.uiuc.edu/Research/vmd/plugins/molfile/dcdplugin.html
.. _XTC: https://manual.gromacs.org/archive/5.0.4/online/xtc.html .. _XTC: https://manual.gromacs.org/archive/5.0.4/online/xtc.html
...@@ -1617,16 +1617,35 @@ These are known as enhanced sampling methods. OpenMM offers several that you ...@@ -1617,16 +1617,35 @@ These are known as enhanced sampling methods. OpenMM offers several that you
can choose from. They are briefly described here. Consult the API documentation can choose from. They are briefly described here. Consult the API documentation
for more detailed descriptions and example code. for more detailed descriptions and example code.
Simulated Tempering Replica Exchange
------------------- ----------------
Replica exchange involves simulating several copies of the system at once, each in a
different thermodynamic state. It periodically exchanges states between the replicas, allowing
each trajectory to explore multiple states.
In one common version, the thermodynamic states correspond to different temperatures. A
single replica might spend time at a high temperature where barriers are easily crossed, then
transition to the lower temperature you are most interested in to sample the distribution of
conformations at that temperature. This is a powerful method to speed up sampling when you
do not know in advance what motions you want to sample.
In another common version, the thermodynamic states correspond to different potential
functions, for example different values of a global parameter that controls the strength of
a force. A single trajectory might sample the distribution of conformations when the force
has full strength, then reduce the strength of the force so it can cross barriers, and then
turn it back on again.
Expanded Ensemble
-----------------
The expanded ensemble method is closely related to replica exchange, but instead of
simulating many replicas and exchanging thermodynamic states between them, it simulates a
single trajectory that jumps between states. When the states correspond to temperatures,
this method is also known as simulated tempering.
Simulated tempering\ :cite:`Marinari1992` involves making frequent changes to the Expanded ensemble sampling can be more efficient than replica exchange, but also requires a
temperature of a simulation. At high temperatures, it can quickly cross energy barriers bit more care to ensure it samples all thermodynamic states evenly.
and explore a wide range of configurations. At lower temperatures, it more thoroughly
explores each local region of configuration space. This is a powerful method to
speed up sampling when you do not know in advance what motions you want to sample.
Simply specify the range of temperatures to simulate and the algorithm handles
everything for you mostly automatically.
Metadynamics Metadynamics
------------ ------------
......
...@@ -772,7 +772,11 @@ accordingly. ...@@ -772,7 +772,11 @@ accordingly.
Each Monte Carlo step modifies particle positions by scaling the centroid of Each Monte Carlo step modifies particle positions by scaling the centroid of
each molecule, then applying the resulting displacement to each particle in the each molecule, then applying the resulting displacement to each particle in the
molecule. This ensures that each molecule is translated as a unit, so bond molecule. This ensures that each molecule is translated as a unit, so bond
lengths and constrained distances are unaffected. lengths and constrained distances are unaffected. Alternatively, there is an
option to scale the position of each particle independently. This option is
intended for unusual situations, such as when the entire system is a single
molecule. In most other cases it is less efficient than scaling molecules,
and it should never be used with a system that contains constraints.
MonteCarloBarostat assumes the simulation is being run at constant temperature MonteCarloBarostat assumes the simulation is being run at constant temperature
as well as pressure, and the simulation temperature affects the step acceptance as well as pressure, and the simulation temperature affects the step acceptance
......
...@@ -54,6 +54,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ...@@ -54,6 +54,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cmath> #include <cmath>
#include <cstdlib> #include <cstdlib>
#include <stdexcept> #include <stdexcept>
#include <exception>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <complex> #include <complex>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2008-2025 Stanford University and the Authors. * * Portions copyright (c) 2008-2026 Stanford University and the Authors. *
* Authors: Peter Eastman, Evan Pretti * * Authors: Peter Eastman, Evan Pretti *
* Contributors: * * Contributors: *
* * * *
...@@ -116,15 +116,11 @@ public: ...@@ -116,15 +116,11 @@ public:
/** /**
* Get the number of particles for which force field parameters have been defined. * Get the number of particles for which force field parameters have been defined.
*/ */
int getNumParticles() const { int getNumParticles() const;
return particles.size();
}
/** /**
* Get the number of special interactions that should be calculated differently from other interactions. * Get the number of special interactions that should be calculated differently from other interactions.
*/ */
int getNumExceptions() const { int getNumExceptions() const;
return exceptions.size();
}
/** /**
* Get the cutoff distance (in nm) being used for nonbonded interactions. * Get the cutoff distance (in nm) being used for nonbonded interactions.
* *
...@@ -362,9 +358,7 @@ public: ...@@ -362,9 +358,7 @@ public:
/** /**
* Get the number of electrodes that have been added. * Get the number of electrodes that have been added.
*/ */
int getNumElectrodes() const { int getNumElectrodes() const;
return electrodes.size();
}
/** /**
* Add a new electrode from a set of particles. The specified particles * Add a new electrode from a set of particles. The specified particles
* will have their charges solved for such that they are held at the * will have their charges solved for such that they are held at the
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2010-2025 Stanford University and the Authors. * * Portions copyright (c) 2010-2026 Stanford University and the Authors. *
* Authors: Peter Eastman, Lee-Ping Wang * * Authors: Peter Eastman, Lee-Ping Wang *
* Contributors: * * Contributors: *
* * * *
...@@ -96,8 +96,10 @@ public: ...@@ -96,8 +96,10 @@ public:
* @param scaleY whether to allow the Y dimension of the periodic box to change size * @param scaleY whether to allow the Y dimension of the periodic box to change size
* @param scaleZ whether to allow the Z dimension of the periodic box to change size * @param scaleZ whether to allow the Z dimension of the periodic box to change size
* @param frequency the frequency at which Monte Carlo pressure changes should be attempted (in time steps) * @param frequency the frequency at which Monte Carlo pressure changes should be attempted (in time steps)
* @param scaleMoleculesAsRigid if true, coordinate scaling keeps molecules rigid, scaling only the center of mass
* of each one. If false, every atom is scaled independently.
*/ */
MonteCarloAnisotropicBarostat(const Vec3& defaultPressure, double defaultTemperature, bool scaleX = true, bool scaleY = true, bool scaleZ = true, int frequency = 25); MonteCarloAnisotropicBarostat(const Vec3& defaultPressure, double defaultTemperature, bool scaleX = true, bool scaleY = true, bool scaleZ = true, int frequency = 25, bool scaleMoleculesAsRigid = true);
/** /**
* Get the default pressure (in bar). * Get the default pressure (in bar).
* *
...@@ -185,11 +187,28 @@ public: ...@@ -185,11 +187,28 @@ public:
bool usesPeriodicBoundaryConditions() const { bool usesPeriodicBoundaryConditions() const {
return false; return false;
} }
/**
* Get whether scaling is applied to the centroid of each molecule while keeping
* the molecules rigid, or to each atom independently.
*
* @returns true if scaling is applied to molecule centroids, false if it is applied to each atom independently.
*/
bool getScaleMoleculesAsRigid() const {
return scaleMoleculesAsRigid;
}
/**
* Set whether scaling is applied to the centroid of each molecule while keeping
* the molecules rigid, or to each atom independently.
*/
void setScaleMoleculesAsRigid(bool rigid) {
scaleMoleculesAsRigid = rigid;
}
/** /**
* Compute the instantaneous pressure along each axis of a system to which this barostat * Compute the instantaneous pressure along each axis of a system to which this barostat
* is applied. * is applied.
* *
* The pressure is computed from the molecular virial, using a finite difference to * The pressure is computed from the molecular virial if getScaleMoleculesAsRigid()
* is true, or the atomic virial if it is false. It uses a finite difference to
* calculate the derivative of potential energy with respect to volume. For most systems * calculate the derivative of potential energy with respect to volume. For most systems
* in equilibrium, the time average of the instantaneous pressure should equal the * in equilibrium, the time average of the instantaneous pressure should equal the
* pressure applied by the barostat. Fluctuations around the average value can be * pressure applied by the barostat. Fluctuations around the average value can be
...@@ -203,6 +222,7 @@ public: ...@@ -203,6 +222,7 @@ public:
protected: protected:
ForceImpl* createImpl() const; ForceImpl* createImpl() const;
private: private:
bool scaleMoleculesAsRigid;
Vec3 defaultPressure; Vec3 defaultPressure;
double defaultTemperature; double defaultTemperature;
bool scaleX, scaleY, scaleZ; bool scaleX, scaleY, scaleZ;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2010-2025 Stanford University and the Authors. * * Portions copyright (c) 2010-2026 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -71,8 +71,10 @@ public: ...@@ -71,8 +71,10 @@ public:
* @param defaultPressure the default pressure acting on the system (in bar) * @param defaultPressure the default pressure acting on the system (in bar)
* @param defaultTemperature the default temperature at which the system is being maintained (in Kelvin) * @param defaultTemperature the default temperature at which the system is being maintained (in Kelvin)
* @param frequency the frequency at which Monte Carlo pressure changes should be attempted (in time steps) * @param frequency the frequency at which Monte Carlo pressure changes should be attempted (in time steps)
* @param scaleMoleculesAsRigid if true, coordinate scaling keeps molecules rigid, scaling only the center of mass
* of each one. If false, every atom is scaled independently.
*/ */
MonteCarloBarostat(double defaultPressure, double defaultTemperature, int frequency = 25); MonteCarloBarostat(double defaultPressure, double defaultTemperature, int frequency = 25, bool scaleMoleculesAsRigid = true);
/** /**
* Get the default pressure acting on the system (in bar). * Get the default pressure acting on the system (in bar).
* *
...@@ -142,10 +144,27 @@ public: ...@@ -142,10 +144,27 @@ public:
bool usesPeriodicBoundaryConditions() const { bool usesPeriodicBoundaryConditions() const {
return false; return false;
} }
/**
* Get whether scaling is applied to the centroid of each molecule while keeping
* the molecules rigid, or to each atom independently.
*
* @returns true if scaling is applied to molecule centroids, false if it is applied to each atom independently.
*/
bool getScaleMoleculesAsRigid() const {
return scaleMoleculesAsRigid;
}
/**
* Set whether scaling is applied to the centroid of each molecule while keeping
* the molecules rigid, or to each atom independently.
*/
void setScaleMoleculesAsRigid(bool rigid) {
scaleMoleculesAsRigid = rigid;
}
/** /**
* Compute the instantaneous pressure of a system to which this barostat is applied. * Compute the instantaneous pressure of a system to which this barostat is applied.
* *
* The pressure is computed from the molecular virial, using a finite difference to * The pressure is computed from the molecular virial if getScaleMoleculesAsRigid()
* is true, or the atomic virial if it is false. It uses a finite difference to
* calculate the derivative of potential energy with respect to volume. For most systems * calculate the derivative of potential energy with respect to volume. For most systems
* in equilibrium, the time average of the instantaneous pressure should equal the * in equilibrium, the time average of the instantaneous pressure should equal the
* pressure applied by the barostat. Fluctuations around the average value can be * pressure applied by the barostat. Fluctuations around the average value can be
...@@ -159,6 +178,7 @@ public: ...@@ -159,6 +178,7 @@ public:
protected: protected:
ForceImpl* createImpl() const; ForceImpl* createImpl() const;
private: private:
bool scaleMoleculesAsRigid;
double defaultPressure, defaultTemperature; double defaultPressure, defaultTemperature;
int frequency, randomNumberSeed; int frequency, randomNumberSeed;
}; };
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2010-2025 Stanford University and the Authors. * * Portions copyright (c) 2010-2026 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -127,8 +127,11 @@ public: ...@@ -127,8 +127,11 @@ public:
* @param xymode the mode specifying the behavior of the X and Y axes * @param xymode the mode specifying the behavior of the X and Y axes
* @param zmode the mode specifying the behavior of the Z axis * @param zmode the mode specifying the behavior of the Z axis
* @param frequency the frequency at which Monte Carlo volume changes should be attempted (in time steps) * @param frequency the frequency at which Monte Carlo volume changes should be attempted (in time steps)
* @param scaleMoleculesAsRigid if true, coordinate scaling keeps molecules rigid, scaling only the center of mass
* of each one. If false, every atom is scaled independently.
*/ */
MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double defaultTemperature, XYMode xymode, ZMode zmode, int frequency = 25); MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double defaultTemperature, XYMode xymode, ZMode zmode,
int frequency = 25, bool scaleMoleculesAsRigid = true);
/** /**
* Get the default pressure acting on the system (in bar). * Get the default pressure acting on the system (in bar).
* *
...@@ -237,11 +240,28 @@ public: ...@@ -237,11 +240,28 @@ public:
bool usesPeriodicBoundaryConditions() const { bool usesPeriodicBoundaryConditions() const {
return false; return false;
} }
/**
* Get whether scaling is applied to the centroid of each molecule while keeping
* the molecules rigid, or to each atom independently.
*
* @returns true if scaling is applied to molecule centroids, false if it is applied to each atom independently.
*/
bool getScaleMoleculesAsRigid() const {
return scaleMoleculesAsRigid;
}
/**
* Set whether scaling is applied to the centroid of each molecule while keeping
* the molecules rigid, or to each atom independently.
*/
void setScaleMoleculesAsRigid(bool rigid) {
scaleMoleculesAsRigid = rigid;
}
/** /**
* Compute the instantaneous pressure along each axis of a system to which this barostat * Compute the instantaneous pressure along each axis of a system to which this barostat
* is applied. * is applied.
* *
* The pressure is computed from the molecular virial, using a finite difference to * The pressure is computed from the molecular virial if getScaleMoleculesAsRigid()
* is true, or the atomic virial if it is false. It uses a finite difference to
* calculate the derivative of potential energy with respect to volume. For most systems * calculate the derivative of potential energy with respect to volume. For most systems
* in equilibrium, the time average of the instantaneous pressure should equal the * in equilibrium, the time average of the instantaneous pressure should equal the
* pressure applied by the barostat. Fluctuations around the average value can be * pressure applied by the barostat. Fluctuations around the average value can be
...@@ -259,6 +279,7 @@ private: ...@@ -259,6 +279,7 @@ private:
XYMode xymode; XYMode xymode;
ZMode zmode; ZMode zmode;
int frequency, randomNumberSeed; int frequency, randomNumberSeed;
bool scaleMoleculesAsRigid;
}; };
} // namespace OpenMM } // namespace OpenMM
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2008-2025 Stanford University and the Authors. * * Portions copyright (c) 2008-2026 Stanford University and the Authors. *
* Authors: Peter Eastman, Evan Pretti * * Authors: Peter Eastman, Evan Pretti *
* Contributors: * * Contributors: *
* * * *
...@@ -47,6 +47,18 @@ ConstantPotentialForce::ConstantPotentialForce() : constantPotentialMethod(CG), ...@@ -47,6 +47,18 @@ ConstantPotentialForce::ConstantPotentialForce() : constantPotentialMethod(CG),
nx(0), ny(0), nz(0), numContexts(0) { nx(0), ny(0), nz(0), numContexts(0) {
} }
int ConstantPotentialForce::getNumParticles() const {
return particles.size();
}
int ConstantPotentialForce::getNumExceptions() const {
return exceptions.size();
}
int ConstantPotentialForce::getNumElectrodes() const {
return electrodes.size();
}
double ConstantPotentialForce::getCutoffDistance() const { double ConstantPotentialForce::getCutoffDistance() const {
return cutoffDistance; return cutoffDistance;
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2010-2025 Stanford University and the Authors. * * Portions copyright (c) 2010-2026 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
using namespace OpenMM; using namespace OpenMM;
MonteCarloAnisotropicBarostat::MonteCarloAnisotropicBarostat(const Vec3& defaultPressure, double defaultTemperature, bool scaleX, bool scaleY, bool scaleZ, int frequency) : MonteCarloAnisotropicBarostat::MonteCarloAnisotropicBarostat(const Vec3& defaultPressure, double defaultTemperature, bool scaleX, bool scaleY, bool scaleZ, int frequency, bool scaleMoleculesAsRigid) :
scaleX(scaleX), scaleY(scaleY), scaleZ(scaleZ) { scaleX(scaleX), scaleY(scaleY), scaleZ(scaleZ), scaleMoleculesAsRigid(scaleMoleculesAsRigid) {
setDefaultPressure(defaultPressure); setDefaultPressure(defaultPressure);
setDefaultTemperature(defaultTemperature); setDefaultTemperature(defaultTemperature);
setFrequency(frequency); setFrequency(frequency);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2010-2025 Stanford University and the Authors. * * Portions copyright (c) 2010-2026 Stanford University and the Authors. *
* Authors: Peter Eastman, Lee-Ping Wang * * Authors: Peter Eastman, Lee-Ping Wang *
* Contributors: * * Contributors: *
* * * *
...@@ -48,7 +48,7 @@ void MonteCarloAnisotropicBarostatImpl::initialize(ContextImpl& context) { ...@@ -48,7 +48,7 @@ void MonteCarloAnisotropicBarostatImpl::initialize(ContextImpl& context) {
if (!context.getSystem().usesPeriodicBoundaryConditions()) if (!context.getSystem().usesPeriodicBoundaryConditions())
throw OpenMMException("A barostat cannot be used with a non-periodic system"); throw OpenMMException("A barostat cannot be used with a non-periodic system");
kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context); kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context);
kernel.getAs<ApplyMonteCarloBarostatKernel>().initialize(context.getSystem(), owner, 3); kernel.getAs<ApplyMonteCarloBarostatKernel>().initialize(context.getSystem(), owner, 3, owner.getScaleMoleculesAsRigid());
Vec3 box[3]; Vec3 box[3];
context.getPeriodicBoxVectors(box[0], box[1], box[2]); context.getPeriodicBoxVectors(box[0], box[1], box[2]);
double volume = box[0][0]*box[1][1]*box[2][2]; double volume = box[0][0]*box[1][1]*box[2][2];
...@@ -113,9 +113,14 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context, ...@@ -113,9 +113,14 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context,
// Compute the energy of the modified system. // Compute the energy of the modified system.
double numberOfScaledParticles;
if (owner.getScaleMoleculesAsRigid())
numberOfScaledParticles = context.getMolecules().size();
else
numberOfScaledParticles = context.getSystem().getNumParticles();
double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy(); double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy();
double kT = BOLTZ*context.getParameter(MonteCarloAnisotropicBarostat::Temperature()); double kT = BOLTZ*context.getParameter(MonteCarloAnisotropicBarostat::Temperature());
double w = finalEnergy-initialEnergy + pressure*deltaVolume - context.getMolecules().size()*kT*log(newVolume/volume); double w = finalEnergy-initialEnergy + pressure*deltaVolume - numberOfScaledParticles*kT*log(newVolume/volume);
if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > exp(-w/kT)) { if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > exp(-w/kT)) {
// Reject the step. // Reject the step.
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2010-2025 Stanford University and the Authors. * * Portions copyright (c) 2010-2026 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -34,7 +34,8 @@ ...@@ -34,7 +34,8 @@
using namespace OpenMM; using namespace OpenMM;
MonteCarloBarostat::MonteCarloBarostat(double defaultPressure, double defaultTemperature, int frequency) { MonteCarloBarostat::MonteCarloBarostat(double defaultPressure, double defaultTemperature, int frequency, bool scaleMoleculesAsRigid) :
scaleMoleculesAsRigid(scaleMoleculesAsRigid) {
setDefaultPressure(defaultPressure); setDefaultPressure(defaultPressure);
setDefaultTemperature(defaultTemperature); setDefaultTemperature(defaultTemperature);
setFrequency(frequency); setFrequency(frequency);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2010-2025 Stanford University and the Authors. * * Portions copyright (c) 2010-2026 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -48,7 +48,7 @@ void MonteCarloBarostatImpl::initialize(ContextImpl& context) { ...@@ -48,7 +48,7 @@ void MonteCarloBarostatImpl::initialize(ContextImpl& context) {
if (!context.getSystem().usesPeriodicBoundaryConditions()) if (!context.getSystem().usesPeriodicBoundaryConditions())
throw OpenMMException("A barostat cannot be used with a non-periodic system"); throw OpenMMException("A barostat cannot be used with a non-periodic system");
kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context); kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context);
kernel.getAs<ApplyMonteCarloBarostatKernel>().initialize(context.getSystem(), owner, 1); kernel.getAs<ApplyMonteCarloBarostatKernel>().initialize(context.getSystem(), owner, 1, owner.getScaleMoleculesAsRigid());
Vec3 box[3]; Vec3 box[3];
context.getPeriodicBoxVectors(box[0], box[1], box[2]); context.getPeriodicBoxVectors(box[0], box[1], box[2]);
double volume = box[0][0]*box[1][1]*box[2][2]; double volume = box[0][0]*box[1][1]*box[2][2];
...@@ -82,10 +82,15 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context, bool& forc ...@@ -82,10 +82,15 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context, bool& forc
// Compute the energy of the modified system. // Compute the energy of the modified system.
double numberOfScaledParticles;
if (owner.getScaleMoleculesAsRigid())
numberOfScaledParticles = context.getMolecules().size();
else
numberOfScaledParticles = context.getSystem().getNumParticles();
double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy(); double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy();
double pressure = context.getParameter(MonteCarloBarostat::Pressure())*(AVOGADRO*1e-25); double pressure = context.getParameter(MonteCarloBarostat::Pressure())*(AVOGADRO*1e-25);
double kT = BOLTZ*context.getParameter(MonteCarloBarostat::Temperature()); double kT = BOLTZ*context.getParameter(MonteCarloBarostat::Temperature());
double w = finalEnergy-initialEnergy + pressure*deltaVolume - context.getMolecules().size()*kT*log(newVolume/volume); double w = finalEnergy-initialEnergy + pressure*deltaVolume - numberOfScaledParticles*kT*log(newVolume/volume);
if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > exp(-w/kT)) { if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > exp(-w/kT)) {
// Reject the step. // Reject the step.
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2010-2025 Stanford University and the Authors. * * Portions copyright (c) 2010-2026 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
using namespace OpenMM; using namespace OpenMM;
MonteCarloMembraneBarostat::MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double defaultTemperature, XYMode xymode, ZMode zmode, int frequency) : MonteCarloMembraneBarostat::MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double defaultTemperature, XYMode xymode, ZMode zmode,
xymode(xymode), zmode(zmode) { int frequency, bool scaleMoleculesAsRigid) : xymode(xymode), zmode(zmode), scaleMoleculesAsRigid(scaleMoleculesAsRigid) {
setDefaultPressure(defaultPressure); setDefaultPressure(defaultPressure);
setDefaultSurfaceTension(defaultSurfaceTension); setDefaultSurfaceTension(defaultSurfaceTension);
setDefaultTemperature(defaultTemperature); setDefaultTemperature(defaultTemperature);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2010-2025 Stanford University and the Authors. * * Portions copyright (c) 2010-2026 Stanford University and the Authors. *
* Authors: Peter Eastman, Lee-Ping Wang * * Authors: Peter Eastman, Lee-Ping Wang *
* Contributors: * * Contributors: *
* * * *
...@@ -48,7 +48,7 @@ void MonteCarloMembraneBarostatImpl::initialize(ContextImpl& context) { ...@@ -48,7 +48,7 @@ void MonteCarloMembraneBarostatImpl::initialize(ContextImpl& context) {
if (!context.getSystem().usesPeriodicBoundaryConditions()) if (!context.getSystem().usesPeriodicBoundaryConditions())
throw OpenMMException("A barostat cannot be used with a non-periodic system"); throw OpenMMException("A barostat cannot be used with a non-periodic system");
kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context); kernel = context.getPlatform().createKernel(ApplyMonteCarloBarostatKernel::Name(), context);
kernel.getAs<ApplyMonteCarloBarostatKernel>().initialize(context.getSystem(), owner, 3); kernel.getAs<ApplyMonteCarloBarostatKernel>().initialize(context.getSystem(), owner, 3, owner.getScaleMoleculesAsRigid());
Vec3 box[3]; Vec3 box[3];
context.getPeriodicBoxVectors(box[0], box[1], box[2]); context.getPeriodicBoxVectors(box[0], box[1], box[2]);
double volume = box[0][0]*box[1][1]*box[2][2]; double volume = box[0][0]*box[1][1]*box[2][2];
...@@ -114,9 +114,14 @@ void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context, bo ...@@ -114,9 +114,14 @@ void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context, bo
// Compute the energy of the modified system. // Compute the energy of the modified system.
double numberOfScaledParticles;
if (owner.getScaleMoleculesAsRigid())
numberOfScaledParticles = context.getMolecules().size();
else
numberOfScaledParticles = context.getSystem().getNumParticles();
double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy(); double finalEnergy = context.getOwner().getState(State::Energy, false, groups).getPotentialEnergy();
double kT = BOLTZ*context.getParameter(MonteCarloMembraneBarostat::Temperature()); double kT = BOLTZ*context.getParameter(MonteCarloMembraneBarostat::Temperature());
double w = finalEnergy-initialEnergy + pressure*deltaVolume - tension*deltaArea - context.getMolecules().size()*kT*log(newVolume/volume); double w = finalEnergy-initialEnergy + pressure*deltaVolume - tension*deltaArea - numberOfScaledParticles*kT*log(newVolume/volume);
if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > exp(-w/kT)) { if (w > 0 && SimTKOpenMMUtilities::getUniformlyDistributedRandomNumber() > exp(-w/kT)) {
// Reject the step. // Reject the step.
......
...@@ -44,9 +44,7 @@ namespace OpenMM { ...@@ -44,9 +44,7 @@ namespace OpenMM {
class CommonIntegrateCustomStepKernel : public IntegrateCustomStepKernel { class CommonIntegrateCustomStepKernel : public IntegrateCustomStepKernel {
public: public:
enum GlobalTargetType {DT, VARIABLE, PARAMETER}; enum GlobalTargetType {DT, VARIABLE, PARAMETER};
CommonIntegrateCustomStepKernel(std::string name, const Platform& platform, ComputeContext& cc) : IntegrateCustomStepKernel(name, platform), cc(cc), CommonIntegrateCustomStepKernel(std::string name, const Platform& platform, ComputeContext& cc);
hasInitializedKernels(false), deviceGlobalsAreCurrent(false), needsEnergyParamDerivs(false) {
}
/** /**
* Initialize the kernel. * Initialize the kernel.
* *
......
...@@ -49,6 +49,25 @@ private: ...@@ -49,6 +49,25 @@ private:
ComputeContext& context; ComputeContext& context;
}; };
/**
* This class deselects a ComputeContext by calling popAsCurrent() on the
* context when it is created and pushAsCurrent() when it goes out of scope.
* This can be useful to temporarily undo the effect of a ContextSelector and
* must only be used when the context is already selected.
*/
class OPENMM_EXPORT_COMMON ContextDeselector {
public:
ContextDeselector(ComputeContext& context) : context(context) {
context.popAsCurrent();
}
~ContextDeselector() {
context.pushAsCurrent();
}
private:
ComputeContext& context;
};
} // namespace OpenMM } // namespace OpenMM
#endif /*OPENMM_CONTEXTSELECTOR_H_*/ #endif /*OPENMM_CONTEXTSELECTOR_H_*/
...@@ -194,8 +194,6 @@ public: ...@@ -194,8 +194,6 @@ public:
} }
double computeForceAndEnergy(bool includeForces, bool includeEnergy, int groups) { double computeForceAndEnergy(bool includeForces, bool includeEnergy, int groups) {
if ((groups&(1<<forceGroup)) != 0) { if ((groups&(1<<forceGroup)) != 0) {
// Keep the dependency on reciprocal-space work, but avoid stalling the host
// when the default queue can wait for the PME queue asynchronously.
event->queueWait(cc.getCurrentQueue()); event->queueWait(cc.getCurrentQueue());
if (includeEnergy) if (includeEnergy)
addEnergyKernel->execute(pmeEnergyBuffer.getSize()); addEnergyKernel->execute(pmeEnergyBuffer.getSize());
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. * * This is part of the OpenMM molecular simulation toolkit. *
* See https://openmm.org/development. * * See https://openmm.org/development. *
* * * *
* Portions copyright (c) 2008-2025 Stanford University and the Authors. * * Portions copyright (c) 2008-2026 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -113,6 +113,10 @@ private: ...@@ -113,6 +113,10 @@ private:
string param; string param;
}; };
CommonIntegrateCustomStepKernel::CommonIntegrateCustomStepKernel(std::string name, const Platform& platform, ComputeContext& cc) : IntegrateCustomStepKernel(name, platform), cc(cc),
hasInitializedKernels(false), deviceGlobalsAreCurrent(false), needsEnergyParamDerivs(false) {
}
void CommonIntegrateCustomStepKernel::initialize(const System& system, const CustomIntegrator& integrator) { void CommonIntegrateCustomStepKernel::initialize(const System& system, const CustomIntegrator& integrator) {
cc.initializeContexts(); cc.initializeContexts();
ContextSelector selector(cc); ContextSelector selector(cc);
...@@ -683,7 +687,10 @@ void CommonIntegrateCustomStepKernel::execute(ContextImpl& context, CustomIntegr ...@@ -683,7 +687,10 @@ void CommonIntegrateCustomStepKernel::execute(ContextImpl& context, CustomIntegr
} }
else { else {
recordChangedParameters(context); recordChangedParameters(context);
{
ContextDeselector deselector(cc);
energy = context.calcForcesAndEnergy(computeForce, computeEnergy, forceGroups); energy = context.calcForcesAndEnergy(computeForce, computeEnergy, forceGroups);
}
savedEnergy[forceGroups] = energy; savedEnergy[forceGroups] = energy;
if (needsEnergyParamDerivs) { if (needsEnergyParamDerivs) {
context.getEnergyParameterDerivatives(energyParamDerivs); context.getEnergyParameterDerivatives(energyParamDerivs);
......
...@@ -96,17 +96,17 @@ void CommonIntegrateNoseHooverStepKernel::initialize(const System& system, const ...@@ -96,17 +96,17 @@ void CommonIntegrateNoseHooverStepKernel::initialize(const System& system, const
} }
void CommonIntegrateNoseHooverStepKernel::execute(ContextImpl& context, const NoseHooverIntegrator& integrator) { void CommonIntegrateNoseHooverStepKernel::execute(ContextImpl& context, const NoseHooverIntegrator& integrator) {
// If the atom reordering has occured, the forces from the previous step are permuted and thus invalid.
// They need to be either sorted or recomputed; here we choose the latter.
if (cc.getAtomsWereReordered())
context.calcForcesAndEnergy(true, false, integrator.getIntegrationForceGroups());
ContextSelector selector(cc); ContextSelector selector(cc);
IntegrationUtilities& integration = cc.getIntegrationUtilities(); IntegrationUtilities& integration = cc.getIntegrationUtilities();
int paddedNumAtoms = cc.getPaddedNumAtoms(); int paddedNumAtoms = cc.getPaddedNumAtoms();
double dt = integrator.getStepSize(); double dt = integrator.getStepSize();
cc.getIntegrationUtilities().setNextStepSize(dt); cc.getIntegrationUtilities().setNextStepSize(dt);
// If the atom reordering has occured, the forces from the previous step are permuted and thus invalid.
// They need to be either sorted or recomputed; here we choose the latter.
if (cc.getAtomsWereReordered())
context.calcForcesAndEnergy(true, false, integrator.getIntegrationForceGroups());
const auto& atomList = integrator.getAllThermostatedIndividualParticles(); const auto& atomList = integrator.getAllThermostatedIndividualParticles();
const auto& pairList = integrator.getAllThermostatedPairs(); const auto& pairList = integrator.getAllThermostatedPairs();
int numAtoms = atomList.size(); int numAtoms = atomList.size();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment