Unverified Commit c7441b96 authored by peastman's avatar peastman Committed by GitHub
Browse files

Merge pull request #2436 from peastman/baoab

Create BAOABLangevinIntegrator
parents 8ac16493 6333db3a
...@@ -120,7 +120,7 @@ steps. ...@@ -120,7 +120,7 @@ steps.
forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml') forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME, system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME,
nonbondedCutoff=1*nanometer, constraints=HBonds) nonbondedCutoff=1*nanometer, constraints=HBonds)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
simulation = Simulation(pdb.topology, system, integrator) simulation = Simulation(pdb.topology, system, integrator)
simulation.context.setPositions(pdb.positions) simulation.context.setPositions(pdb.positions)
simulation.minimizeEnergy() simulation.minimizeEnergy()
...@@ -210,10 +210,10 @@ convenient and less error-prone. We could have equivalently specified ...@@ -210,10 +210,10 @@ convenient and less error-prone. We could have equivalently specified
The units system will be described in more detail later, in Section :ref:`units-and-dimensional-analysis`. The units system will be described in more detail later, in Section :ref:`units-and-dimensional-analysis`.
:: ::
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
This line creates the integrator to use for advancing the equations of motion. This line creates the integrator to use for advancing the equations of motion.
It specifies a :class:`LangevinIntegrator`, which performs Langevin dynamics, It specifies a :class:`BAOABLangevinIntegrator`, which performs Langevin dynamics,
and assigns it to a variable called :code:`integrator`\ . It also specifies and assigns it to a variable called :code:`integrator`\ . It also specifies
the values of three parameters that are specific to Langevin dynamics: the the values of three parameters that are specific to Langevin dynamics: the
simulation temperature (300 K), the friction coefficient (1 ps\ :sup:`-1`\ ), and simulation temperature (300 K), the friction coefficient (1 ps\ :sup:`-1`\ ), and
...@@ -295,7 +295,7 @@ found in OpenMM’s :file:`examples` folder with the name :file:`simulateAmber.p ...@@ -295,7 +295,7 @@ found in OpenMM’s :file:`examples` folder with the name :file:`simulateAmber.p
inpcrd = AmberInpcrdFile('input.inpcrd') inpcrd = AmberInpcrdFile('input.inpcrd')
system = prmtop.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer, system = prmtop.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer,
constraints=HBonds) constraints=HBonds)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
simulation = Simulation(prmtop.topology, system, integrator) simulation = Simulation(prmtop.topology, system, integrator)
simulation.context.setPositions(inpcrd.positions) simulation.context.setPositions(inpcrd.positions)
if inpcrd.boxVectors is not None: if inpcrd.boxVectors is not None:
...@@ -389,7 +389,7 @@ with the name :file:`simulateGromacs.py`. ...@@ -389,7 +389,7 @@ with the name :file:`simulateGromacs.py`.
includeDir='/usr/local/gromacs/share/gromacs/top') includeDir='/usr/local/gromacs/share/gromacs/top')
system = top.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer, system = top.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer,
constraints=HBonds) constraints=HBonds)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
simulation = Simulation(top.topology, system, integrator) simulation = Simulation(top.topology, system, integrator)
simulation.context.setPositions(gro.positions) simulation.context.setPositions(gro.positions)
simulation.minimizeEnergy() simulation.minimizeEnergy()
...@@ -453,7 +453,7 @@ on the :class:`CharmmPsfFile`. ...@@ -453,7 +453,7 @@ on the :class:`CharmmPsfFile`.
params = CharmmParameterSet('charmm22.rtf', 'charmm22.prm') params = CharmmParameterSet('charmm22.rtf', 'charmm22.prm')
system = psf.createSystem(params, nonbondedMethod=NoCutoff, system = psf.createSystem(params, nonbondedMethod=NoCutoff,
nonbondedCutoff=1*nanometer, constraints=HBonds) nonbondedCutoff=1*nanometer, constraints=HBonds)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
simulation = Simulation(psf.topology, system, integrator) simulation = Simulation(psf.topology, system, integrator)
simulation.context.setPositions(pdb.positions) simulation.context.setPositions(pdb.positions)
simulation.minimizeEnergy() simulation.minimizeEnergy()
...@@ -1022,13 +1022,13 @@ Integrators ...@@ -1022,13 +1022,13 @@ Integrators
OpenMM offers a choice of several different integration methods. You select OpenMM offers a choice of several different integration methods. You select
which one to use by creating an integrator object of the appropriate type. which one to use by creating an integrator object of the appropriate type.
Langevin Integrator BAOAB Langevin Integrator
------------------- -------------------------
In the examples of the previous sections, we used Langevin integration: In the examples of the previous sections, we used Langevin integration:
:: ::
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
The three parameter values in this line are the simulation temperature (300 K), The three parameter values in this line are the simulation temperature (300 K),
the friction coefficient (1 ps\ :sup:`-1`\ ), and the step size (0.002 ps). You the friction coefficient (1 ps\ :sup:`-1`\ ), and the step size (0.002 ps). You
...@@ -1037,6 +1037,16 @@ on all values. For example, the step size could be written either as ...@@ -1037,6 +1037,16 @@ on all values. For example, the step size could be written either as
:code:`0.002*picoseconds` or :code:`2*femtoseconds`\ . They are exactly :code:`0.002*picoseconds` or :code:`2*femtoseconds`\ . They are exactly
equivalent. equivalent.
Langevin Integrator
-------------------
:code:`LangevinIntegrator` is very similar to :code:`BAOABLangevinIntegrator`,
but it uses a different discretization of the Langevin equation.
:code:`BAOABLangevinIntegrator` tends to produce more accurate configurational
sampling, and therefore is preferred for most applications. Also note that
:code:`LangevinIntegrator` (unlike :code:`BAOABLangevinIntegrator`) is a leapfrog
integrator, so the velocities are offset by half a time step from the positions.
Leapfrog Verlet Integrator Leapfrog Verlet Integrator
-------------------------- --------------------------
...@@ -1145,7 +1155,7 @@ previous section: ...@@ -1145,7 +1155,7 @@ previous section:
system = prmtop.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer, system = prmtop.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer,
constraints=HBonds) constraints=HBonds)
system.addForce(MonteCarloBarostat(1*bar, 300*kelvin)) system.addForce(MonteCarloBarostat(1*bar, 300*kelvin))
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
... ...
The parameters of the Monte Carlo barostat are the pressure (1 bar) and The parameters of the Monte Carlo barostat are the pressure (1 bar) and
...@@ -1705,7 +1715,7 @@ executing 1000 time steps at each temperature: ...@@ -1705,7 +1715,7 @@ executing 1000 time steps at each temperature:
:autonumber:`Example,simulated annealing` :autonumber:`Example,simulated annealing`
This code needs very little explanation. The loop is executed 100 times. Each This code needs very little explanation. The loop is executed 100 times. Each
time through, it adjusts the temperature of the :class:`LangevinIntegrator` and then time through, it adjusts the temperature of the :class:`BAOABLangevinIntegrator` and then
calls :code:`step(1000)` to take 1000 time steps. calls :code:`step(1000)` to take 1000 time steps.
Applying an External Force to Particles: a Spherical Container Applying an External Force to Particles: a Spherical Container
...@@ -1737,7 +1747,7 @@ coordinates. Here is the code to do it: ...@@ -1737,7 +1747,7 @@ coordinates. Here is the code to do it:
system.addForce(force) system.addForce(force)
for i in range(system.getNumParticles()): for i in range(system.getNumParticles()):
force.addParticle(i, []) force.addParticle(i, [])
integrator = LangevinIntegrator(300*kelvin, 91/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 91/picosecond, 0.002*picoseconds)
... ...
.. caption:: .. caption::
......
...@@ -243,14 +243,14 @@ simulation might look like: ...@@ -243,14 +243,14 @@ simulation might look like:
angles->addAngle(angle[i].particle1, angle[i].particle2, angles->addAngle(angle[i].particle1, angle[i].particle2,
angle[i].particle3, angle[i].angle, angle[i].k); angle[i].particle3, angle[i].angle, angle[i].k);
// ...create and initialize other force field terms in the same way // ...create and initialize other force field terms in the same way
LangevinIntegrator integrator(temperature, friction, stepSize); BAOABLangevinIntegrator integrator(temperature, friction, stepSize);
Context context(system, integrator); Context context(system, integrator);
context.setPositions(initialPositions); context.setPositions(initialPositions);
context.setVelocities(initialVelocities); context.setVelocities(initialVelocities);
integrator.step(10000); integrator.step(10000);
We create a System, add various Forces to it, and set parameters on both the We create a System, add various Forces to it, and set parameters on both the
System and the Forces. We then create a LangevinIntegrator, initialize a System and the Forces. We then create a BAOABLangevinIntegrator, initialize a
Context in which to run a simulation, and instruct the Integrator to advance the Context in which to run a simulation, and instruct the Integrator to advance the
simulation for 10,000 time steps. simulation for 10,000 time steps.
......
...@@ -240,6 +240,19 @@ ...@@ -240,6 +240,19 @@
type = {Journal Article} type = {Journal Article}
} }
@article{Leimkuhler2013,
author = {Leimkuhler, Benedict and Matthews, Charles},
title = {Rational Construction of Stochastic Numerical Methods for Molecular Sampling},
journal = {Applied Mathematics Research eXpress},
volume = {2013},
number = {1},
pages = {34-56},
year = {2012},
month = {06},
doi = {10.1093/amrx/abs010},
type = {Journal Article}
}
@article{Li2010 @article{Li2010
author = {Li, D.W. and Br{\"u}schweiler, R.}, author = {Li, D.W. and Br{\"u}schweiler, R.},
title = {{NMR}-based protein potentials}, title = {{NMR}-based protein potentials},
......
...@@ -1338,6 +1338,21 @@ The integration is done using a leap-frog method similar to VerletIntegrator. ...@@ -1338,6 +1338,21 @@ The integration is done using a leap-frog method similar to VerletIntegrator.
:cite:`Izaguirre2010` The same comments about the offset between positions and :cite:`Izaguirre2010` The same comments about the offset between positions and
velocities apply to this integrator as to that one. velocities apply to this integrator as to that one.
BAOABLangevinIntegrator
***********************
This integrator is similar to LangevinIntegerator, but it instead uses the BAOAB
discretization. :cite:`Leimkuhler2013` This tends to produce more accurate
sampling of configurational properties (such as free energies), but less
accurate sampling of kinetic properties (such as mean kinetic energy). Because
configurational properties are much more important than kinetic ones in most
simulations, this integrator is generally preferred over LangevinIntegrator. It
often allows one to use a larger time step while still maintaining similar or
better accuracy.
Unlike LangevinIntegrator, this does not use a leap-frog algorithm. The
positions and velocities all correspond to the same point in time.
BrownianIntegrator BrownianIntegrator
****************** ******************
......
...@@ -6,7 +6,7 @@ from sys import stdout ...@@ -6,7 +6,7 @@ from sys import stdout
prmtop = AmberPrmtopFile('input.prmtop') prmtop = AmberPrmtopFile('input.prmtop')
inpcrd = AmberInpcrdFile('input.inpcrd') inpcrd = AmberInpcrdFile('input.inpcrd')
system = prmtop.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds) system = prmtop.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
simulation = Simulation(prmtop.topology, system, integrator) simulation = Simulation(prmtop.topology, system, integrator)
simulation.context.setPositions(inpcrd.positions) simulation.context.setPositions(inpcrd.positions)
if inpcrd.boxVectors is not None: if inpcrd.boxVectors is not None:
......
...@@ -22,7 +22,7 @@ params = CharmmParameterSet('charmm22.rtf', 'charmm22.par') ...@@ -22,7 +22,7 @@ params = CharmmParameterSet('charmm22.rtf', 'charmm22.par')
# Instantiate the system # Instantiate the system
system = psf.createSystem(params, nonbondedMethod=NoCutoff, system = psf.createSystem(params, nonbondedMethod=NoCutoff,
nonbondedCutoff=None) nonbondedCutoff=None)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
simulation = Simulation(psf.topology, system, integrator) simulation = Simulation(psf.topology, system, integrator)
simulation.context.setPositions(pdb.getPositions()) simulation.context.setPositions(pdb.getPositions())
simulation.minimizeEnergy() simulation.minimizeEnergy()
......
...@@ -6,7 +6,7 @@ from sys import stdout ...@@ -6,7 +6,7 @@ from sys import stdout
gro = GromacsGroFile('input.gro') gro = GromacsGroFile('input.gro')
top = GromacsTopFile('input.top', periodicBoxVectors=gro.getPeriodicBoxVectors()) top = GromacsTopFile('input.top', periodicBoxVectors=gro.getPeriodicBoxVectors())
system = top.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds) system = top.createSystem(nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
simulation = Simulation(top.topology, system, integrator) simulation = Simulation(top.topology, system, integrator)
simulation.context.setPositions(gro.positions) simulation.context.setPositions(gro.positions)
simulation.minimizeEnergy() simulation.minimizeEnergy()
......
...@@ -6,7 +6,7 @@ from sys import stdout ...@@ -6,7 +6,7 @@ from sys import stdout
pdb = PDBFile('input.pdb') pdb = PDBFile('input.pdb')
forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml') forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds) system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME, nonbondedCutoff=1*nanometer, constraints=HBonds)
integrator = LangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds) integrator = BAOABLangevinIntegrator(300*kelvin, 1/picosecond, 0.002*picoseconds)
simulation = Simulation(pdb.topology, system, integrator) simulation = Simulation(pdb.topology, system, integrator)
simulation.context.setPositions(pdb.positions) simulation.context.setPositions(pdb.positions)
simulation.minimizeEnergy() simulation.minimizeEnergy()
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2018 Stanford University and the Authors. * * Portions copyright (c) 2008-2019 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "openmm/AndersenThermostat.h" #include "openmm/AndersenThermostat.h"
#include "openmm/BAOABLangevinIntegrator.h"
#include "openmm/BrownianIntegrator.h" #include "openmm/BrownianIntegrator.h"
#include "openmm/CMAPTorsionForce.h" #include "openmm/CMAPTorsionForce.h"
#include "openmm/CMMotionRemover.h" #include "openmm/CMMotionRemover.h"
...@@ -1090,6 +1091,43 @@ public: ...@@ -1090,6 +1091,43 @@ public:
virtual double computeKineticEnergy(ContextImpl& context, const LangevinIntegrator& integrator) = 0; virtual double computeKineticEnergy(ContextImpl& context, const LangevinIntegrator& integrator) = 0;
}; };
/**
* This kernel is invoked by BAOABLangevinIntegrator to take one time step.
*/
class IntegrateBAOABStepKernel : public KernelImpl {
public:
static std::string Name() {
return "IntegrateBAOABStep";
}
IntegrateBAOABStepKernel(std::string name, const Platform& platform) : KernelImpl(name, platform) {
}
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param integrator the BAOABLangevinIntegrator this kernel will be used for
*/
virtual void initialize(const System& system, const BAOABLangevinIntegrator& integrator) = 0;
/**
* Execute the kernel.
*
* @param context the context in which to execute this kernel
* @param integrator the BAOABLangevinIntegrator this kernel is being used for
* @param forcesAreValid if the context has been modified since the last time step, this will be
* false to show that cached forces are invalid and must be recalculated.
* On exit, this should specify whether the cached forces are valid at the
* end of the step.
*/
virtual void execute(ContextImpl& context, const BAOABLangevinIntegrator& integrator, bool& forcesAreValid) = 0;
/**
* Compute the kinetic energy.
*
* @param context the context in which to execute this kernel
* @param integrator the BAOABLangevinIntegrator this kernel is being used for
*/
virtual double computeKineticEnergy(ContextImpl& context, const BAOABLangevinIntegrator& integrator) = 0;
};
/** /**
* This kernel is invoked by BrownianIntegrator to take one time step. * This kernel is invoked by BrownianIntegrator to take one time step.
*/ */
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "openmm/AndersenThermostat.h" #include "openmm/AndersenThermostat.h"
#include "openmm/BAOABLangevinIntegrator.h"
#include "openmm/BrownianIntegrator.h" #include "openmm/BrownianIntegrator.h"
#include "openmm/CMAPTorsionForce.h" #include "openmm/CMAPTorsionForce.h"
#include "openmm/CMMotionRemover.h" #include "openmm/CMMotionRemover.h"
......
#ifndef OPENMM_BAOABLANGEVININTEGRATOR_H_
#define OPENMM_BAOABLANGEVININTEGRATOR_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2019 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "Integrator.h"
#include "openmm/Kernel.h"
#include "internal/windowsExport.h"
namespace OpenMM {
/**
* This is an Integrator which simulates a System using Langevin dynamics, with
* the BAOAB discretization of Leimkuhler and Matthews (http://dx.doi.org/10.1093/amrx/abs010).
* This method tend to produce more accurate configurational sampling than other
* discretizations, such as the one used in LangevinIntegrator.
*/
class OPENMM_EXPORT BAOABLangevinIntegrator : public Integrator {
public:
/**
* Create a BAOABLangevinIntegrator.
*
* @param temperature the temperature of the heat bath (in Kelvin)
* @param frictionCoeff the friction coefficient which couples the system to the heat bath (in inverse picoseconds)
* @param stepSize the step size with which to integrate the system (in picoseconds)
*/
BAOABLangevinIntegrator(double temperature, double frictionCoeff, double stepSize);
/**
* Get the temperature of the heat bath (in Kelvin).
*
* @return the temperature of the heat bath, measured in Kelvin
*/
double getTemperature() const {
return temperature;
}
/**
* Set the temperature of the heat bath (in Kelvin).
*
* @param temp the temperature of the heat bath, measured in Kelvin
*/
void setTemperature(double temp) {
temperature = temp;
}
/**
* Get the friction coefficient which determines how strongly the system is coupled to
* the heat bath (in inverse ps).
*
* @return the friction coefficient, measured in 1/ps
*/
double getFriction() const {
return friction;
}
/**
* Set the friction coefficient which determines how strongly the system is coupled to
* the heat bath (in inverse ps).
*
* @param coeff the friction coefficient, measured in 1/ps
*/
void setFriction(double coeff) {
friction = coeff;
}
/**
* Get the random number seed. See setRandomNumberSeed() for details.
*/
int getRandomNumberSeed() const {
return randomNumberSeed;
}
/**
* Set the random number seed. The precise meaning of this parameter is undefined, and is left up
* to each Platform to interpret in an appropriate way. It is guaranteed that if two simulations
* are run with different random number seeds, the sequence of random forces will be different. On
* the other hand, no guarantees are made about the behavior of simulations that use the same seed.
* In particular, Platforms are permitted to use non-deterministic algorithms which produce different
* results on successive runs, even if those runs were initialized identically.
*
* If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context
* is created from this Integrator. This is done to ensure that each Context receives unique random seeds
* without you needing to set them explicitly.
*/
void setRandomNumberSeed(int seed) {
randomNumberSeed = seed;
}
/**
* Advance a simulation through time by taking a series of time steps.
*
* @param steps the number of time steps to take
*/
void step(int steps);
protected:
/**
* This will be called by the Context when it is created. It informs the Integrator
* of what context it will be integrating, and gives it a chance to do any necessary initialization.
* It will also get called again if the application calls reinitialize() on the Context.
*/
void initialize(ContextImpl& context);
/**
* This will be called by the Context when it is destroyed to let the Integrator do any necessary
* cleanup. It will also get called again if the application calls reinitialize() on the Context.
*/
void cleanup();
/**
* When the user modifies the state, we need to mark that the forces need to be recalculated.
*/
void stateChanged(State::DataType changed);
/**
* Get the names of all Kernels used by this Integrator.
*/
std::vector<std::string> getKernelNames();
/**
* Compute the kinetic energy of the system at the current time.
*/
double computeKineticEnergy();
private:
double temperature, friction;
int randomNumberSeed;
bool forcesAreValid;
Kernel kernel;
};
} // namespace OpenMM
#endif /*OPENMM_BAOABLANGEVININTEGRATOR_H_*/
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2019 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/BAOABLangevinIntegrator.h"
#include "openmm/Context.h"
#include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/kernels.h"
#include <string>
using namespace OpenMM;
using std::string;
using std::vector;
BAOABLangevinIntegrator::BAOABLangevinIntegrator(double temperature, double frictionCoeff, double stepSize) {
setTemperature(temperature);
setFriction(frictionCoeff);
setStepSize(stepSize);
setConstraintTolerance(1e-5);
setRandomNumberSeed(0);
forcesAreValid = false;
}
void BAOABLangevinIntegrator::initialize(ContextImpl& contextRef) {
if (owner != NULL && &contextRef.getOwner() != owner)
throw OpenMMException("This Integrator is already bound to a context");
context = &contextRef;
owner = &contextRef.getOwner();
kernel = context->getPlatform().createKernel(IntegrateBAOABStepKernel::Name(), contextRef);
kernel.getAs<IntegrateBAOABStepKernel>().initialize(contextRef.getSystem(), *this);
}
void BAOABLangevinIntegrator::cleanup() {
kernel = Kernel();
}
void BAOABLangevinIntegrator::stateChanged(State::DataType changed) {
forcesAreValid = false;
}
vector<string> BAOABLangevinIntegrator::getKernelNames() {
std::vector<std::string> names;
names.push_back(IntegrateBAOABStepKernel::Name());
return names;
}
double BAOABLangevinIntegrator::computeKineticEnergy() {
return kernel.getAs<IntegrateBAOABStepKernel>().computeKineticEnergy(*context, *this);
}
void BAOABLangevinIntegrator::step(int steps) {
if (context == NULL)
throw OpenMMException("This Integrator is not bound to a context!");
for (int i = 0; i < steps; ++i) {
context->updateContextState();
kernel.getAs<IntegrateBAOABStepKernel>().execute(*context, *this, forcesAreValid);
}
}
/* Portions copyright (c) 2013-2019 Stanford University and Simbios.
* Authors: Peter Eastman
* Contributors:
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __CPU_BAOAB_DYNAMICS_H__
#define __CPU_BAOAB_DYNAMICS_H__
#include "ReferenceBAOABDynamics.h"
#include "CpuRandom.h"
#include "openmm/internal/ThreadPool.h"
#include "sfmt/SFMT.h"
namespace OpenMM {
class CpuBAOABDynamics : public ReferenceBAOABDynamics {
public:
/**
* Constructor.
*
* @param numberOfAtoms number of atoms
* @param deltaT delta t for dynamics
* @param friction friction coefficient
* @param temperature temperature
* @param threads thread pool for parallelizing computation
* @param random random number generator
*/
CpuBAOABDynamics(int numberOfAtoms, double deltaT, double friction, double temperature, OpenMM::ThreadPool& threads, OpenMM::CpuRandom& random);
/**
* Destructor.
*/
~CpuBAOABDynamics();
/**
* First update step.
*
* @param numberOfAtoms number of atoms
* @param atomCoordinates atom coordinates
* @param velocities velocities
* @param forces forces
* @param inverseMasses inverse atom masses
* @param xPrime xPrime
*/
void updatePart1(int numberOfAtoms, std::vector<OpenMM::Vec3>& atomCoordinates, std::vector<OpenMM::Vec3>& velocities,
std::vector<OpenMM::Vec3>& forces, std::vector<double>& inverseMasses, std::vector<OpenMM::Vec3>& xPrime);
/**
* Second update step.
*
* @param numberOfAtoms number of atoms
* @param atomCoordinates atom coordinates
* @param velocities velocities
* @param inverseMasses inverse atom masses
* @param xPrime xPrime
*/
void updatePart2(int numberOfAtoms, std::vector<OpenMM::Vec3>& atomCoordinates, std::vector<OpenMM::Vec3>& velocities,
std::vector<double>& inverseMasses, std::vector<OpenMM::Vec3>& xPrime);
/**
* Third update
*
* @param context the context this integrator is updating
* @param numberOfAtoms number of atoms
* @param atomCoordinates atom coordinates
* @param velocities velocities
* @param inverseMasses inverse atom masses
* @param xPrime xPrime
*/
void updatePart3(OpenMM::ContextImpl& context, int numberOfAtoms, std::vector<OpenMM::Vec3>& atomCoordinates, std::vector<OpenMM::Vec3>& velocities,
std::vector<double>& inverseMasses, std::vector<OpenMM::Vec3>& xPrime);
private:
void threadUpdate1(int threadIndex);
void threadUpdate2(int threadIndex);
void threadUpdate3(int threadIndex);
void threadUpdate4(int threadIndex);
OpenMM::ThreadPool& threads;
OpenMM::CpuRandom& random;
std::vector<OpenMM_SFMT::SFMT> threadRandom;
// The following variables are used to make information accessible to the individual threads.
int numberOfAtoms;
OpenMM::Vec3* atomCoordinates;
OpenMM::Vec3* velocities;
OpenMM::Vec3* forces;
double* inverseMasses;
OpenMM::Vec3* xPrime;
};
} // namespace OpenMM
#endif // __CPU_BAOAB_DYNAMICS_H__
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2013-2018 Stanford University and the Authors. * * Portions copyright (c) 2013-2019 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. * * USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "CpuBAOABDynamics.h"
#include "CpuBondForce.h" #include "CpuBondForce.h"
#include "CpuCustomGBForce.h" #include "CpuCustomGBForce.h"
#include "CpuCustomManyParticleForce.h" #include "CpuCustomManyParticleForce.h"
...@@ -536,6 +537,47 @@ private: ...@@ -536,6 +537,47 @@ private:
double prevTemp, prevFriction, prevStepSize; double prevTemp, prevFriction, prevStepSize;
}; };
/**
* This kernel is invoked by BAOABLangevinIntegrator to take one time step.
*/
class CpuIntegrateBAOABStepKernel : public IntegrateBAOABStepKernel {
public:
CpuIntegrateBAOABStepKernel(std::string name, const Platform& platform, CpuPlatform::PlatformData& data) : IntegrateBAOABStepKernel(name, platform),
data(data), dynamics(0) {
}
~CpuIntegrateBAOABStepKernel();
/**
* Initialize the kernel, setting up the particle masses.
*
* @param system the System this kernel will be applied to
* @param integrator the BAOABLangevinIntegrator this kernel will be used for
*/
void initialize(const System& system, const BAOABLangevinIntegrator& integrator);
/**
* Execute the kernel.
*
* @param context the context in which to execute this kernel
* @param integrator the BAOABLangevinIntegrator this kernel is being used for
* @param forcesAreValid if the context has been modified since the last time step, this will be
* false to show that cached forces are invalid and must be recalculated.
* On exit, this should specify whether the cached forces are valid at the
* end of the step.
*/
void execute(ContextImpl& context, const BAOABLangevinIntegrator& integrator, bool& forcesAreValid);
/**
* Compute the kinetic energy.
*
* @param context the context in which to execute this kernel
* @param integrator the BAOABLangevinIntegrator this kernel is being used for
*/
double computeKineticEnergy(ContextImpl& context, const BAOABLangevinIntegrator& integrator);
private:
CpuPlatform::PlatformData& data;
CpuBAOABDynamics* dynamics;
std::vector<double> masses;
double prevTemp, prevFriction, prevStepSize;
};
} // namespace OpenMM } // namespace OpenMM
#endif /*OPENMM_CPUKERNELS_H_*/ #endif /*OPENMM_CPUKERNELS_H_*/
......
/* Portions copyright (c) 2006-2019 Stanford University and Simbios.
* Authors: Peter Eastman
* Contributors:
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "SimTKOpenMMUtilities.h"
#include "CpuBAOABDynamics.h"
using namespace OpenMM;
using namespace std;
CpuBAOABDynamics::CpuBAOABDynamics(int numberOfAtoms, double deltaT, double friction, double temperature, ThreadPool& threads, CpuRandom& random) :
ReferenceBAOABDynamics(numberOfAtoms, deltaT, friction, temperature), threads(threads), random(random) {
}
CpuBAOABDynamics::~CpuBAOABDynamics() {
}
void CpuBAOABDynamics::updatePart1(int numberOfAtoms, vector<Vec3>& atomCoordinates, vector<Vec3>& velocities,
vector<Vec3>& forces, vector<double>& inverseMasses, vector<Vec3>& xPrime) {
// Record the parameters for the threads.
this->numberOfAtoms = numberOfAtoms;
this->atomCoordinates = &atomCoordinates[0];
this->velocities = &velocities[0];
this->forces = &forces[0];
this->inverseMasses = &inverseMasses[0];
this->xPrime = &xPrime[0];
// Signal the threads to start running and wait for them to finish.
threads.execute([&] (ThreadPool& threads, int threadIndex) { threadUpdate1(threadIndex); });
threads.waitForThreads();
}
void CpuBAOABDynamics::updatePart2(int numberOfAtoms, vector<Vec3>& atomCoordinates, vector<Vec3>& velocities,
vector<double>& inverseMasses, vector<Vec3>& xPrime) {
// Record the parameters for the threads.
this->numberOfAtoms = numberOfAtoms;
this->atomCoordinates = &atomCoordinates[0];
this->velocities = &velocities[0];
this->inverseMasses = &inverseMasses[0];
this->xPrime = &xPrime[0];
// Signal the threads to start running and wait for them to finish.
threads.execute([&] (ThreadPool& threads, int threadIndex) { threadUpdate2(threadIndex); });
threads.waitForThreads();
}
void CpuBAOABDynamics::updatePart3(ContextImpl& context, int numberOfAtoms, vector<Vec3>& atomCoordinates, vector<Vec3>& velocities,
vector<double>& inverseMasses, vector<Vec3>& xPrime) {
// Record the parameters for the threads.
this->numberOfAtoms = numberOfAtoms;
this->atomCoordinates = &atomCoordinates[0];
this->velocities = &velocities[0];
this->inverseMasses = &inverseMasses[0];
this->xPrime = &xPrime[0];
// Signal the threads to start running and wait for them to finish.
threads.execute([&] (ThreadPool& threads, int threadIndex) { threadUpdate3(threadIndex); });
threads.waitForThreads();
context.calcForcesAndEnergy(true, false);
threads.execute([&] (ThreadPool& threads, int threadIndex) { threadUpdate4(threadIndex); });
threads.waitForThreads();
}
void CpuBAOABDynamics::threadUpdate1(int threadIndex) {
const double halfdt = 0.5*getDeltaT();
int start = threadIndex*numberOfAtoms/threads.getNumThreads();
int end = (threadIndex+1)*numberOfAtoms/threads.getNumThreads();
for (int i = start; i < end; i++) {
if (inverseMasses[i] != 0.0) {
velocities[i] += (halfdt*inverseMasses[i])*forces[i];
xPrime[i] = atomCoordinates[i] + velocities[i]*halfdt;
oldx[i] = xPrime[i];
}
}
}
void CpuBAOABDynamics::threadUpdate2(int threadIndex) {
const double halfdt = 0.5*getDeltaT();
const double kT = BOLTZ*getTemperature();
const double friction = getFriction();
const double vscale = exp(-getDeltaT()*friction);
const double noisescale = sqrt(1-vscale*vscale);
int start = threadIndex*numberOfAtoms/threads.getNumThreads();
int end = (threadIndex+1)*numberOfAtoms/threads.getNumThreads();
for (int i = start; i < end; i++) {
if (inverseMasses[i] != 0.0) {
velocities[i] += (xPrime[i]-oldx[i])/halfdt;
Vec3 noise(random.getGaussianRandom(threadIndex), random.getGaussianRandom(threadIndex), random.getGaussianRandom(threadIndex));
velocities[i] = vscale*velocities[i] + noisescale*sqrt(kT*inverseMasses[i])*noise;
atomCoordinates[i] = xPrime[i];
xPrime[i] = atomCoordinates[i] + velocities[i]*halfdt;
oldx[i] = xPrime[i];
}
}
}
void CpuBAOABDynamics::threadUpdate3(int threadIndex) {
const double halfdt = 0.5*getDeltaT();
int start = threadIndex*numberOfAtoms/threads.getNumThreads();
int end = (threadIndex+1)*numberOfAtoms/threads.getNumThreads();
for (int i = start; i < end; ++i)
if (inverseMasses[i] != 0.0) {
velocities[i] += (xPrime[i]-oldx[i])/halfdt;
atomCoordinates[i] = xPrime[i];
}
}
void CpuBAOABDynamics::threadUpdate4(int threadIndex) {
const double halfdt = 0.5*getDeltaT();
int start = threadIndex*numberOfAtoms/threads.getNumThreads();
int end = (threadIndex+1)*numberOfAtoms/threads.getNumThreads();
for (int i = start; i < end; ++i)
if (inverseMasses[i] != 0.0)
velocities[i] += (halfdt*inverseMasses[i])*forces[i];
}
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2013-2016 Stanford University and the Authors. * * Portions copyright (c) 2013-2019 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -61,5 +61,7 @@ KernelImpl* CpuKernelFactory::createKernelImpl(std::string name, const Platform& ...@@ -61,5 +61,7 @@ KernelImpl* CpuKernelFactory::createKernelImpl(std::string name, const Platform&
return new CpuCalcGayBerneForceKernel(name, platform, data); return new CpuCalcGayBerneForceKernel(name, platform, data);
if (name == IntegrateLangevinStepKernel::Name()) if (name == IntegrateLangevinStepKernel::Name())
return new CpuIntegrateLangevinStepKernel(name, platform, data); return new CpuIntegrateLangevinStepKernel(name, platform, data);
if (name == IntegrateBAOABStepKernel::Name())
return new CpuIntegrateBAOABStepKernel(name, platform, data);
throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '") + name + "'").c_str()); throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '") + name + "'").c_str());
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2013-2018 Stanford University and the Authors. * * Portions copyright (c) 2013-2019 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -1352,3 +1352,43 @@ void CpuIntegrateLangevinStepKernel::execute(ContextImpl& context, const Langevi ...@@ -1352,3 +1352,43 @@ void CpuIntegrateLangevinStepKernel::execute(ContextImpl& context, const Langevi
double CpuIntegrateLangevinStepKernel::computeKineticEnergy(ContextImpl& context, const LangevinIntegrator& integrator) { double CpuIntegrateLangevinStepKernel::computeKineticEnergy(ContextImpl& context, const LangevinIntegrator& integrator) {
return computeShiftedKineticEnergy(context, masses, 0.5*integrator.getStepSize()); return computeShiftedKineticEnergy(context, masses, 0.5*integrator.getStepSize());
} }
CpuIntegrateBAOABStepKernel::~CpuIntegrateBAOABStepKernel() {
if (dynamics)
delete dynamics;
}
void CpuIntegrateBAOABStepKernel::initialize(const System& system, const BAOABLangevinIntegrator& integrator) {
int numParticles = system.getNumParticles();
masses.resize(numParticles);
for (int i = 0; i < numParticles; ++i)
masses[i] = system.getParticleMass(i);
data.random.initialize(integrator.getRandomNumberSeed(), data.threads.getNumThreads());
}
void CpuIntegrateBAOABStepKernel::execute(ContextImpl& context, const BAOABLangevinIntegrator& integrator, bool& forcesAreValid) {
double temperature = integrator.getTemperature();
double friction = integrator.getFriction();
double stepSize = integrator.getStepSize();
vector<Vec3>& posData = extractPositions(context);
vector<Vec3>& velData = extractVelocities(context);
if (dynamics == 0 || temperature != prevTemp || friction != prevFriction || stepSize != prevStepSize) {
// Recreate the computation objects with the new parameters.
if (dynamics)
delete dynamics;
dynamics = new CpuBAOABDynamics(context.getSystem().getNumParticles(), stepSize, friction, temperature, data.threads, data.random);
dynamics->setReferenceConstraintAlgorithm(&extractConstraints(context));
prevTemp = temperature;
prevFriction = friction;
prevStepSize = stepSize;
}
dynamics->update(context, posData, velData, masses, forcesAreValid, integrator.getConstraintTolerance());
ReferencePlatform::PlatformData* refData = reinterpret_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
refData->time += stepSize;
refData->stepCount++;
}
double CpuIntegrateBAOABStepKernel::computeKineticEnergy(ContextImpl& context, const BAOABLangevinIntegrator& integrator) {
return computeShiftedKineticEnergy(context, masses, 0.0);
}
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2013-2018 Stanford University and the Authors. * * Portions copyright (c) 2013-2019 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -74,6 +74,7 @@ CpuPlatform::CpuPlatform() { ...@@ -74,6 +74,7 @@ CpuPlatform::CpuPlatform() {
registerKernelFactory(CalcCustomGBForceKernel::Name(), factory); registerKernelFactory(CalcCustomGBForceKernel::Name(), factory);
registerKernelFactory(CalcGayBerneForceKernel::Name(), factory); registerKernelFactory(CalcGayBerneForceKernel::Name(), factory);
registerKernelFactory(IntegrateLangevinStepKernel::Name(), factory); registerKernelFactory(IntegrateLangevinStepKernel::Name(), factory);
registerKernelFactory(IntegrateBAOABStepKernel::Name(), factory);
platformProperties.push_back(CpuThreads()); platformProperties.push_back(CpuThreads());
platformProperties.push_back(CpuDeterministicForces()); platformProperties.push_back(CpuDeterministicForces());
int threads = getNumProcessors(); int threads = getNumProcessors();
......
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2019 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "CpuTests.h"
#include "TestBAOABLangevinIntegrator.h"
void runPlatformTests() {
}
...@@ -1401,6 +1401,45 @@ private: ...@@ -1401,6 +1401,45 @@ private:
CUfunction kernel1, kernel2; CUfunction kernel1, kernel2;
}; };
/**
* This kernel is invoked by BAOABLangevinIntegrator to take one time step.
*/
class CudaIntegrateBAOABStepKernel : public IntegrateBAOABStepKernel {
public:
CudaIntegrateBAOABStepKernel(std::string name, const Platform& platform, CudaContext& cu) : IntegrateBAOABStepKernel(name, platform), cu(cu) {
}
/**
* Initialize the kernel, setting up the particle masses.
*
* @param system the System this kernel will be applied to
* @param integrator the BAOABLangevinIntegrator this kernel will be used for
*/
void initialize(const System& system, const BAOABLangevinIntegrator& integrator);
/**
* Execute the kernel.
*
* @param context the context in which to execute this kernel
* @param integrator the BAOABLangevinIntegrator this kernel is being used for
* @param forcesAreValid if the context has been modified since the last time step, this will be
* false to show that cached forces are invalid and must be recalculated.
* On exit, this should specify whether the cached forces are valid at the
* end of the step.
*/
void execute(ContextImpl& context, const BAOABLangevinIntegrator& integrator, bool& forcesAreValid);
/**
* Compute the kinetic energy.
*
* @param context the context in which to execute this kernel
* @param integrator the BAOABLangevinIntegrator this kernel is being used for
*/
double computeKineticEnergy(ContextImpl& context, const BAOABLangevinIntegrator& integrator);
private:
CudaContext& cu;
double prevTemp, prevFriction, prevStepSize;
CudaArray params, oldDelta;
CUfunction kernel1, kernel2, kernel3, kernel4;
};
/** /**
* This kernel is invoked by BrownianIntegrator to take one time step. * This kernel is invoked by BrownianIntegrator to take one time step.
*/ */
......
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