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

Merge OpenMM master into dtk26.04

parents 97239ca6 fc21fd19
......@@ -666,12 +666,12 @@ jobs:
)")
for d in api-c++ api-python developerguide userguide; do
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+=$?))
echo "::endgroup::"
done
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+=$?))
echo "::endgroup::"
exit $exitcode
......@@ -615,7 +615,7 @@ CHARMM36
--------
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).
.. tabularcolumns:: |l|L|
......@@ -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
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/>`_
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
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/>`_
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)
or include ``CONECT`` records specifying non-chemical ``H-H`` bonds in waters
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
additional force field XML files that can be loaded as needed.
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
openmmforcefields_ package and `ParmEd <https://github.com/parmed/parmed>`_.
......@@ -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
should be able to read them into most analysis and visualization programs.
.. _PDB: http://www.wwpdb.org/documentation/format33/v3.3.html
.. _PDBx/mmCIF: http://mmcif.wwpdb.org
.. _PDB: https://www.wwpdb.org/documentation/file-format-content/format33/v3.3.html
.. _PDBx/mmCIF: https://mmcif.wwpdb.org
.. _DCD: http://www.ks.uiuc.edu/Research/vmd/plugins/molfile/dcdplugin.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
can choose from. They are briefly described here. Consult the API documentation
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
temperature of a simulation. At high temperatures, it can quickly cross energy barriers
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.
Expanded ensemble sampling can be more efficient than replica exchange, but also requires a
bit more care to ensure it samples all thermodynamic states evenly.
Metadynamics
------------
......
......@@ -772,7 +772,11 @@ accordingly.
Each Monte Carlo step modifies particle positions by scaling the centroid of
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
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
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.
#include <cmath>
#include <cstdlib>
#include <stdexcept>
#include <exception>
#include <memory>
#include <vector>
#include <complex>
......
......@@ -7,7 +7,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -116,15 +116,11 @@ public:
/**
* Get the number of particles for which force field parameters have been defined.
*/
int getNumParticles() const {
return particles.size();
}
int getNumParticles() const;
/**
* Get the number of special interactions that should be calculated differently from other interactions.
*/
int getNumExceptions() const {
return exceptions.size();
}
int getNumExceptions() const;
/**
* Get the cutoff distance (in nm) being used for nonbonded interactions.
*
......@@ -362,9 +358,7 @@ public:
/**
* Get the number of electrodes that have been added.
*/
int getNumElectrodes() const {
return electrodes.size();
}
int getNumElectrodes() const;
/**
* 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
......
......@@ -7,7 +7,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -96,8 +96,10 @@ public:
* @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 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).
*
......@@ -185,17 +187,34 @@ public:
bool usesPeriodicBoundaryConditions() const {
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
* 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
* in equilibrium, the time average of the instantaneous pressure should equal the
* pressure applied by the barostat. Fluctuations around the average value can be
* extremely large, however, and it may take a very long simulation to accurately
* compute the average.
*
*
* @param context the Context for which to compute the current pressure
* @returns a vector containing the pressure along each axis
*/
......@@ -203,6 +222,7 @@ public:
protected:
ForceImpl* createImpl() const;
private:
bool scaleMoleculesAsRigid;
Vec3 defaultPressure;
double defaultTemperature;
bool scaleX, scaleY, scaleZ;
......
......@@ -7,7 +7,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -71,8 +71,10 @@ public:
* @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 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).
*
......@@ -142,16 +144,33 @@ public:
bool usesPeriodicBoundaryConditions() const {
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.
*
* 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
* in equilibrium, the time average of the instantaneous pressure should equal the
* pressure applied by the barostat. Fluctuations around the average value can be
* extremely large, however, and it may take a very long simulation to accurately
* compute the average.
*
*
* @param context the Context for which to compute the current pressure
* @returns the instantaneous pressure
*/
......@@ -159,6 +178,7 @@ public:
protected:
ForceImpl* createImpl() const;
private:
bool scaleMoleculesAsRigid;
double defaultPressure, defaultTemperature;
int frequency, randomNumberSeed;
};
......
......@@ -7,7 +7,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -127,8 +127,11 @@ public:
* @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 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).
*
......@@ -237,11 +240,28 @@ public:
bool usesPeriodicBoundaryConditions() const {
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
* 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
* in equilibrium, the time average of the instantaneous pressure should equal the
* pressure applied by the barostat. Fluctuations around the average value can be
......@@ -259,6 +279,7 @@ private:
XYMode xymode;
ZMode zmode;
int frequency, randomNumberSeed;
bool scaleMoleculesAsRigid;
};
} // namespace OpenMM
......
......@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -47,6 +47,18 @@ ConstantPotentialForce::ConstantPotentialForce() : constantPotentialMethod(CG),
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 {
return cutoffDistance;
}
......
......@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -32,8 +32,8 @@
using namespace OpenMM;
MonteCarloAnisotropicBarostat::MonteCarloAnisotropicBarostat(const Vec3& defaultPressure, double defaultTemperature, bool scaleX, bool scaleY, bool scaleZ, int frequency) :
scaleX(scaleX), scaleY(scaleY), scaleZ(scaleZ) {
MonteCarloAnisotropicBarostat::MonteCarloAnisotropicBarostat(const Vec3& defaultPressure, double defaultTemperature, bool scaleX, bool scaleY, bool scaleZ, int frequency, bool scaleMoleculesAsRigid) :
scaleX(scaleX), scaleY(scaleY), scaleZ(scaleZ), scaleMoleculesAsRigid(scaleMoleculesAsRigid) {
setDefaultPressure(defaultPressure);
setDefaultTemperature(defaultTemperature);
setFrequency(frequency);
......
......@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -48,7 +48,7 @@ void MonteCarloAnisotropicBarostatImpl::initialize(ContextImpl& context) {
if (!context.getSystem().usesPeriodicBoundaryConditions())
throw OpenMMException("A barostat cannot be used with a non-periodic system");
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];
context.getPeriodicBoxVectors(box[0], box[1], box[2]);
double volume = box[0][0]*box[1][1]*box[2][2];
......@@ -112,10 +112,15 @@ void MonteCarloAnisotropicBarostatImpl::updateContextState(ContextImpl& context,
kernel.getAs<ApplyMonteCarloBarostatKernel>().scaleCoordinates(context, lengthScale[0], lengthScale[1], lengthScale[2]);
// 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 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)) {
// Reject the step.
......
......@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -34,7 +34,8 @@
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);
setDefaultTemperature(defaultTemperature);
setFrequency(frequency);
......
......@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -48,7 +48,7 @@ void MonteCarloBarostatImpl::initialize(ContextImpl& context) {
if (!context.getSystem().usesPeriodicBoundaryConditions())
throw OpenMMException("A barostat cannot be used with a non-periodic system");
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];
context.getPeriodicBoxVectors(box[0], box[1], box[2]);
double volume = box[0][0]*box[1][1]*box[2][2];
......@@ -81,11 +81,16 @@ void MonteCarloBarostatImpl::updateContextState(ContextImpl& context, bool& forc
kernel.getAs<ApplyMonteCarloBarostatKernel>().scaleCoordinates(context, lengthScale, lengthScale, lengthScale);
// 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 pressure = context.getParameter(MonteCarloBarostat::Pressure())*(AVOGADRO*1e-25);
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)) {
// Reject the step.
......
......@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -32,8 +32,8 @@
using namespace OpenMM;
MonteCarloMembraneBarostat::MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double defaultTemperature, XYMode xymode, ZMode zmode, int frequency) :
xymode(xymode), zmode(zmode) {
MonteCarloMembraneBarostat::MonteCarloMembraneBarostat(double defaultPressure, double defaultSurfaceTension, double defaultTemperature, XYMode xymode, ZMode zmode,
int frequency, bool scaleMoleculesAsRigid) : xymode(xymode), zmode(zmode), scaleMoleculesAsRigid(scaleMoleculesAsRigid) {
setDefaultPressure(defaultPressure);
setDefaultSurfaceTension(defaultSurfaceTension);
setDefaultTemperature(defaultTemperature);
......
......@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -48,7 +48,7 @@ void MonteCarloMembraneBarostatImpl::initialize(ContextImpl& context) {
if (!context.getSystem().usesPeriodicBoundaryConditions())
throw OpenMMException("A barostat cannot be used with a non-periodic system");
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];
context.getPeriodicBoxVectors(box[0], box[1], box[2]);
double volume = box[0][0]*box[1][1]*box[2][2];
......@@ -114,9 +114,14 @@ void MonteCarloMembraneBarostatImpl::updateContextState(ContextImpl& context, bo
// 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 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)) {
// Reject the step.
......
......@@ -44,9 +44,7 @@ namespace OpenMM {
class CommonIntegrateCustomStepKernel : public IntegrateCustomStepKernel {
public:
enum GlobalTargetType {DT, VARIABLE, PARAMETER};
CommonIntegrateCustomStepKernel(std::string name, const Platform& platform, ComputeContext& cc) : IntegrateCustomStepKernel(name, platform), cc(cc),
hasInitializedKernels(false), deviceGlobalsAreCurrent(false), needsEnergyParamDerivs(false) {
}
CommonIntegrateCustomStepKernel(std::string name, const Platform& platform, ComputeContext& cc);
/**
* Initialize the kernel.
*
......
......@@ -49,6 +49,25 @@ private:
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
#endif /*OPENMM_CONTEXTSELECTOR_H_*/
......@@ -194,8 +194,6 @@ public:
}
double computeForceAndEnergy(bool includeForces, bool includeEnergy, int groups) {
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());
if (includeEnergy)
addEnergyKernel->execute(pmeEnergyBuffer.getSize());
......
......@@ -4,7 +4,7 @@
* This is part of the OpenMM molecular simulation toolkit. *
* 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 *
* Contributors: *
* *
......@@ -113,6 +113,10 @@ private:
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) {
cc.initializeContexts();
ContextSelector selector(cc);
......@@ -683,7 +687,10 @@ void CommonIntegrateCustomStepKernel::execute(ContextImpl& context, CustomIntegr
}
else {
recordChangedParameters(context);
energy = context.calcForcesAndEnergy(computeForce, computeEnergy, forceGroups);
{
ContextDeselector deselector(cc);
energy = context.calcForcesAndEnergy(computeForce, computeEnergy, forceGroups);
}
savedEnergy[forceGroups] = energy;
if (needsEnergyParamDerivs) {
context.getEnergyParameterDerivatives(energyParamDerivs);
......
......@@ -96,17 +96,17 @@ void CommonIntegrateNoseHooverStepKernel::initialize(const System& system, const
}
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);
IntegrationUtilities& integration = cc.getIntegrationUtilities();
int paddedNumAtoms = cc.getPaddedNumAtoms();
double dt = integrator.getStepSize();
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& pairList = integrator.getAllThermostatedPairs();
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