Commit da52d3ae authored by Peter Eastman's avatar Peter Eastman
Browse files

API changes to support variable time step integrators

parent 14f17de5
......@@ -77,6 +77,37 @@ public:
virtual void execute(OpenMMContextImpl& context) = 0;
};
/**
* This kernel is invoked to get or set the current time.
*/
class UpdateTimeKernel : public KernelImpl {
public:
static std::string Name() {
return "UpdateTime";
}
UpdateTimeKernel(std::string name, const Platform& platform) : KernelImpl(name, platform) {
}
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
*/
virtual void initialize(const System& system) = 0;
/**
* Get the current time (in picoseconds).
*
* @param context the context in which to execute this kernel
*/
virtual double getTime(const OpenMMContextImpl& context) const = 0;
/**
* Set the current time (in picoseconds).
*
* @param context the context in which to execute this kernel
* @param time the time
*/
virtual void setTime(OpenMMContextImpl& context, double time) = 0;
};
/**
* This kernel is invoked by HarmonicBondForce to calculate the forces acting on the system and the energy of the system.
*/
......
......@@ -55,13 +55,15 @@ public:
virtual ~Integrator() {
}
/**
* Get the size of each time step, in picoseconds.
* Get the size of each time step, in picoseconds. If this integrator uses variable time steps,
* this is the initial step size that will be attempted for the next step.
*/
double getStepSize() const {
return stepSize;
}
/**
* Set the size of each time step, in picoseconds.
* Set the size of each time step, in picoseconds. If this integrator uses variable time steps,
* this is the initial step size that will be attempted for the next step.
*/
void setStepSize(double size) {
stepSize = size;
......
......@@ -111,10 +111,6 @@ public:
* should be a union of DataType values, e.g. (State::Positions | State::Velocities).
*/
State getState(int types) const;
/**
* Get the current time of the simulation (in picoseconds).
*/
double getTime();
/**
* Set the current time of the simulation (in picoseconds).
*/
......
......@@ -102,15 +102,11 @@ public:
/**
* Get the current time (in picoseconds).
*/
double getTime() const {
return time;
}
double getTime() const;
/**
* Set the current time (in picoseconds).
*/
void setTime(double t) {
time = t;
}
void setTime(double t);
/**
* Get the value of an adjustable parameter. If there is no parameter with the specified name, this
* throws an exception.
......@@ -158,11 +154,10 @@ private:
System& system;
Integrator& integrator;
std::vector<ForceImpl*> forceImpls;
double time;
std::map<std::string, double> parameters;
Platform* platform;
Stream positions, velocities, forces;
Kernel initializeForcesKernel, kineticEnergyKernel;
Kernel initializeForcesKernel, kineticEnergyKernel, updateTimeKernel;
void* platformData;
};
......
......@@ -92,10 +92,6 @@ State OpenMMContext::getState(int types) const {
return state;
}
double OpenMMContext::getTime() {
return impl->getTime();
}
void OpenMMContext::setTime(double time) {
impl->setTime(time);
}
......
......@@ -47,12 +47,12 @@ using std::string;
OpenMMContextImpl::OpenMMContextImpl(OpenMMContext& owner, System& system, Integrator& integrator, Platform* platform) :
owner(owner), system(system),
integrator(integrator), platform(platform),
platformData(NULL),
time(0)
platformData(NULL)
{
vector<string> kernelNames;
kernelNames.push_back(CalcKineticEnergyKernel::Name());
kernelNames.push_back(InitializeForcesKernel::Name());
kernelNames.push_back(UpdateTimeKernel::Name());
for (int i = 0; i < system.getNumForces(); ++i) {
forceImpls.push_back(system.getForce(i).createImpl());
map<string, double> forceParameters = forceImpls[forceImpls.size()-1]->getDefaultParameters();
......@@ -71,6 +71,8 @@ OpenMMContextImpl::OpenMMContextImpl(OpenMMContext& owner, System& system, Integ
dynamic_cast<InitializeForcesKernel&>(initializeForcesKernel.getImpl()).initialize(system);
kineticEnergyKernel = platform->createKernel(CalcKineticEnergyKernel::Name(), *this);
dynamic_cast<CalcKineticEnergyKernel&>(kineticEnergyKernel.getImpl()).initialize(system);
updateTimeKernel = platform->createKernel(UpdateTimeKernel::Name(), *this);
dynamic_cast<UpdateTimeKernel&>(updateTimeKernel.getImpl()).initialize(system);
for (size_t i = 0; i < forceImpls.size(); ++i)
forceImpls[i]->initialize(*this);
integrator.initialize(*this);
......@@ -87,6 +89,14 @@ OpenMMContextImpl::~OpenMMContextImpl() {
platform->contextDestroyed(*this);
}
double OpenMMContextImpl::getTime() const {
return dynamic_cast<const UpdateTimeKernel&>(updateTimeKernel.getImpl()).getTime(*this);
}
void OpenMMContextImpl::setTime(double t) {
dynamic_cast<UpdateTimeKernel&>(updateTimeKernel.getImpl()).setTime(*this, t);
}
double OpenMMContextImpl::getParameter(std::string name) {
if (parameters.find(name) == parameters.end())
throw OpenMMException("Called getParameter() with invalid parameter name");
......
......@@ -26,6 +26,7 @@
#include "BrookKernelFactory.h"
#include "BrookInitializeForcesKernel.h"
#include "BrookUpdateTimeKernel.h"
#include "BrookCalcHarmonicBondForceKernel.h"
#include "BrookCalcHarmonicAngleForceKernel.h"
#include "BrookCalcPeriodicTorsionForceKernel.h"
......@@ -57,6 +58,12 @@ KernelImpl* BrookKernelFactory::createKernelImpl( std::string name, const Platfo
return new BrookInitializeForcesKernel( name, platform, openMMBrookInterface, context.getSystem() );
// update time
} else if( name == UpdateTimeKernel::Name() ){
return new BrookUpdateTimeKernel( name, platform, openMMBrookInterface );
// harmonic bonds
} else if( name == CalcHarmonicBondForceKernel::Name() ){
......
......@@ -281,6 +281,7 @@ void BrookPlatform::_initializeKernelFactory( void ){
BrookKernelFactory* factory = new BrookKernelFactory();
registerKernelFactory( InitializeForcesKernel::Name(), factory );
registerKernelFactory( UpdateTimeKernel::Name(), factory );
registerKernelFactory( CalcHarmonicBondForceKernel::Name(), factory );
registerKernelFactory( CalcHarmonicAngleForceKernel::Name(), factory );
registerKernelFactory( CalcPeriodicTorsionForceKernel::Name(), factory );
......
/* -------------------------------------------------------------------------- *
* 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) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston, Peter Eastman *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/OpenMMException.h"
#include <sstream>
#include "BrookUpdateTimeKernel.h"
using namespace OpenMM;
using namespace std;
/**
* BrookUpdateTimeKernel constructor
*
* @param name kernel name
* @param platform platform
* @param openMMBrookInterface OpenMMBrookInterface reference
*
*/
BrookUpdateTimeKernel::BrookUpdateTimeKernel( std::string name, const Platform& platform, OpenMMBrookInterface& openMMBrookInterface ) :
UpdateTimeKernel( name, platform ), _openMMBrookInterface(openMMBrookInterface){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookUpdateTimeKernel::BrookUpdateTimeKernel";
// ---------------------------------------------------------------------------------------
_log = NULL;
const BrookPlatform& brookPlatform = dynamic_cast<const BrookPlatform&> (platform);
if( brookPlatform.getLog() != NULL ){
setLog( brookPlatform.getLog() );
}
}
/**
* BrookInitializeForcesKernel destructor
*
*/
BrookUpdateTimeKernel::~BrookUpdateTimeKernel( ){
// ---------------------------------------------------------------------------------------
// static const std::string methodName = "BrookUpdateTimeKernel::~BrookUpdateTimeKernel";
// ---------------------------------------------------------------------------------------
}
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* BrookUpdateTimeKernel::getLog( void ) const {
return _log;
}
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int BrookUpdateTimeKernel::setLog( FILE* log ){
_log = log;
return BrookCommon::DefaultReturnValue;
}
/**
* Initialize
*
* @param system System reference
*
* @return DefaultReturnValue
*
*/
void BrookUpdateTimeKernel::initialize( const System& system ){
// ---------------------------------------------------------------------------------------
//static const std::string methodName = "BrookUpdateTimeKernel::initialize";
// ---------------------------------------------------------------------------------------
//FILE* log = getLog();
}
/**
* Get the current time (in picoseconds).
*
* @param context the context in which to execute this kernel
*/
double BrookUpdateTimeKernel::getTime(const OpenMMContextImpl& context) const {
return _openMMBrookInterface.getTime();
}
/**
* Set the current time (in picoseconds).
*
* @param context the context in which to execute this kernel
* @param time the time
*/
void BrookUpdateTimeKernel::setTime(OpenMMContextImpl& context, double time) {
_openMMBrookInterface.setTime(time);
}
#ifndef OPENMM_BROOK_UPDATE_TIME_KERNEL_H_
#define OPENMM_BROOK_UPDATE_TIME_KERNEL_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) 2009 Stanford University and the Authors. *
* Authors: Mark Friedrichs, Mike Houston, Peter Eastman *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "openmm/kernels.h"
#include "OpenMMBrookInterface.h"
namespace OpenMM {
/**
* This kernel initializes the forces
*/
class BrookUpdateTimeKernel : public UpdateTimeKernel {
public:
BrookUpdateTimeKernel( std::string name, const Platform& platform, OpenMMBrookInterface& openMMBrookInterface );
~BrookUpdateTimeKernel();
/**
* Initialize the kernel
*
* @param system the System this kernel will be applied to
*/
void initialize( const System& system );
/**
* Get the current time (in picoseconds).
*
* @param context the context in which to execute this kernel
*/
double getTime(const OpenMMContextImpl& context) const;
/**
* Set the current time (in picoseconds).
*
* @param context the context in which to execute this kernel
* @param time the time
*/
void setTime(OpenMMContextImpl& context, double time);
/**
* Set log file reference
*
* @param log file reference
*
* @return DefaultReturnValue
*
*/
int setLog( FILE* log );
/*
* Get contents of object
*
* @param level of dump
*
* @return string containing contents
*
* */
std::string getContents( int level ) const;
/**
* Get log file reference
*
* @return log file reference
*
*/
FILE* getLog( void ) const;
private:
// log file reference
FILE* _log;
// interface
OpenMMBrookInterface& _openMMBrookInterface;
};
} // namespace OpenMM
#endif /* OPENMM_BROOK_UPDATE_TIME_KERNEL_H_ */
......@@ -64,6 +64,7 @@ OpenMMBrookInterface::OpenMMBrookInterface( int streamWidth, int duplicationFact
_log = NULL;
//_log = stderr;
_time = 0.0;
_particleStreamSize = -1;
......@@ -120,6 +121,31 @@ int OpenMMBrookInterface::setNumberOfParticles( int numberOfParticles ){
return BrookCommon::DefaultReturnValue;
}
/**
* Get the current time
*
* @return the current time
*
*/
double OpenMMBrookInterface::getTime( void ) const {
return _time;
}
/**
* Set the current time
*
* @param time the current time
*
* @return DefaultReturnValue
*
*/
int OpenMMBrookInterface::setTime( double time) {
_time = time;
return BrookCommon::DefaultReturnValue;
}
/**
* Get particle stream width
*
......
......@@ -103,6 +103,26 @@ class OpenMMBrookInterface {
int setNumberOfParticles( int numberOfParticles );
/**
* Get the current time
*
* @return the current time
*
*/
double getTime( void ) const;
/**
* Set the current time
*
* @param time the current time
*
* @return DefaultReturnValue
*
*/
int setTime( double time);
/**
* Get particle stream width
*
......@@ -417,6 +437,7 @@ class OpenMMBrookInterface {
BrookStreamImpl* _positions;
BrookStreamImpl* _velocities;
BrookStreamImpl* _forces;
double _time;
/**
* Set BrookBondParameters
......
......@@ -61,7 +61,7 @@ private:
class CudaPlatform::PlatformData {
public:
PlatformData(_gpuContext* gpu) : gpu(gpu), removeCM(false), nonbondedMethod(0), hasBonds(false), hasAngles(false),
hasPeriodicTorsions(false), hasRB(false), hasNonbonded(false), primaryKernel(NULL), stepCount(0) {
hasPeriodicTorsions(false), hasRB(false), hasNonbonded(false), primaryKernel(NULL), stepCount(0), time(0.0) {
}
_gpuContext* gpu;
KernelImpl* primaryKernel;
......@@ -70,6 +70,7 @@ public:
int nonbondedMethod;
int cmMotionFrequency;
int stepCount;
double time;
};
} // namespace OpenMM
......
......@@ -35,6 +35,8 @@ KernelImpl* CudaKernelFactory::createKernelImpl(std::string name, const Platform
CudaPlatform::PlatformData& data = *static_cast<CudaPlatform::PlatformData*>(context.getPlatformData());
if (name == InitializeForcesKernel::Name())
return new CudaInitializeForcesKernel(name, platform);
if (name == UpdateTimeKernel::Name())
return new CudaUpdateTimeKernel(name, platform, data);
if (name == CalcHarmonicBondForceKernel::Name())
return new CudaCalcHarmonicBondForceKernel(name, platform, data, context.getSystem());
if (name == CalcHarmonicAngleForceKernel::Name())
......@@ -59,6 +61,5 @@ KernelImpl* CudaKernelFactory::createKernelImpl(std::string name, const Platform
return new CudaCalcKineticEnergyKernel(name, platform);
if (name == RemoveCMMotionKernel::Name())
return new CudaRemoveCMMotionKernel(name, platform, data);
else
throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '")+name+"'").c_str());
}
......@@ -87,6 +87,17 @@ void CudaInitializeForcesKernel::initialize(const System& system) {
void CudaInitializeForcesKernel::execute(OpenMMContextImpl& context) {
}
void CudaUpdateTimeKernel::initialize(const System& system) {
}
double CudaUpdateTimeKernel::getTime(const OpenMMContextImpl& context) const {
return data.time;
}
void CudaUpdateTimeKernel::setTime(OpenMMContextImpl& context, double time) {
data.time = time;
}
CudaCalcHarmonicBondForceKernel::~CudaCalcHarmonicBondForceKernel() {
}
......
......@@ -61,6 +61,35 @@ public:
void execute(OpenMMContextImpl& context);
};
/**
* This kernel is invoked to get or set the current time.
*/
class CudaUpdateTimeKernel : public UpdateTimeKernel {
public:
CudaUpdateTimeKernel(std::string name, const Platform& platform, CudaPlatform::PlatformData& data) : UpdateTimeKernel(name, platform), data(data) {
}
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
*/
void initialize(const System& system);
/**
* Get the current time (in picoseconds).
*
* @param context the context in which to execute this kernel
*/
double getTime(const OpenMMContextImpl& context) const;
/**
* Set the current time (in picoseconds).
*
* @param context the context in which to execute this kernel
*/
void setTime(OpenMMContextImpl& context, double time);
private:
CudaPlatform::PlatformData& data;
};
/**
* This kernel is invoked by HarmonicBondForce to calculate the forces acting on the system and the energy of the system.
*/
......
......@@ -42,6 +42,7 @@ extern "C" void initOpenMMPlugin() {
CudaPlatform::CudaPlatform() {
CudaKernelFactory* factory = new CudaKernelFactory();
registerKernelFactory(InitializeForcesKernel::Name(), factory);
registerKernelFactory(UpdateTimeKernel::Name(), factory);
registerKernelFactory(CalcHarmonicBondForceKernel::Name(), factory);
registerKernelFactory(CalcHarmonicAngleForceKernel::Name(), factory);
registerKernelFactory(CalcPeriodicTorsionForceKernel::Name(), factory);
......
......@@ -44,6 +44,7 @@ namespace OpenMM {
class OPENMM_EXPORT ReferencePlatform : public Platform {
public:
class PlatformData;
ReferencePlatform();
std::string getName() const {
return "Reference";
......@@ -53,10 +54,18 @@ public:
}
bool supportsDoublePrecision() const;
const StreamFactory& getDefaultStreamFactory() const;
void contextCreated(OpenMMContextImpl& context) const;
void contextDestroyed(OpenMMContextImpl& context) const;
private:
ReferenceStreamFactory defaultStreamFactory;
};
class ReferencePlatform::PlatformData {
public:
PlatformData() : time(0.0) {
}
double time;
};
} // namespace OpenMM
#endif /*OPENMM_REFERENCEPLATFORM_H_*/
......@@ -31,42 +31,44 @@
#include "ReferenceKernelFactory.h"
#include "ReferenceKernels.h"
#include "openmm/internal/OpenMMContextImpl.h"
#include "openmm/OpenMMException.h"
using namespace OpenMM;
KernelImpl* ReferenceKernelFactory::createKernelImpl(std::string name, const Platform& platform, OpenMMContextImpl& context) const {
ReferencePlatform::PlatformData& data = *static_cast<ReferencePlatform::PlatformData*>(context.getPlatformData());
if (name == InitializeForcesKernel::Name())
return new ReferenceInitializeForcesKernel(name, platform);
else if (name == CalcNonbondedForceKernel::Name())
if (name == UpdateTimeKernel::Name())
return new ReferenceUpdateTimeKernel(name, platform, data);
if (name == CalcNonbondedForceKernel::Name())
return new ReferenceCalcNonbondedForceKernel(name, platform);
else if (name == CalcHarmonicBondForceKernel::Name())
if (name == CalcHarmonicBondForceKernel::Name())
return new ReferenceCalcHarmonicBondForceKernel(name, platform);
else if (name == CalcHarmonicAngleForceKernel::Name())
if (name == CalcHarmonicAngleForceKernel::Name())
return new ReferenceCalcHarmonicAngleForceKernel(name, platform);
else if (name == CalcHarmonicAngleForceKernel::Name())
if (name == CalcHarmonicAngleForceKernel::Name())
return new ReferenceCalcHarmonicAngleForceKernel(name, platform);
else if (name == CalcPeriodicTorsionForceKernel::Name())
if (name == CalcPeriodicTorsionForceKernel::Name())
return new ReferenceCalcPeriodicTorsionForceKernel(name, platform);
else if (name == CalcRBTorsionForceKernel::Name())
if (name == CalcRBTorsionForceKernel::Name())
return new ReferenceCalcRBTorsionForceKernel(name, platform);
else if (name == CalcGBSAOBCForceKernel::Name())
if (name == CalcGBSAOBCForceKernel::Name())
return new ReferenceCalcGBSAOBCForceKernel(name, platform);
else if (name == CalcGBVIForceKernel::Name())
if (name == CalcGBVIForceKernel::Name())
return new ReferenceCalcGBVIForceKernel(name, platform);
else if (name == IntegrateVerletStepKernel::Name())
if (name == IntegrateVerletStepKernel::Name())
return new ReferenceIntegrateVerletStepKernel(name, platform);
else if (name == IntegrateLangevinStepKernel::Name())
if (name == IntegrateLangevinStepKernel::Name())
return new ReferenceIntegrateLangevinStepKernel(name, platform);
else if (name == IntegrateBrownianStepKernel::Name())
if (name == IntegrateBrownianStepKernel::Name())
return new ReferenceIntegrateBrownianStepKernel(name, platform);
else if (name == ApplyAndersenThermostatKernel::Name())
if (name == ApplyAndersenThermostatKernel::Name())
return new ReferenceApplyAndersenThermostatKernel(name, platform);
else if (name == CalcKineticEnergyKernel::Name())
if (name == CalcKineticEnergyKernel::Name())
return new ReferenceCalcKineticEnergyKernel(name, platform);
else if (name == RemoveCMMotionKernel::Name())
if (name == RemoveCMMotionKernel::Name())
return new ReferenceRemoveCMMotionKernel(name, platform);
else {
throw OpenMMException( (std::string("Tried to create kernel with illegal kernel name '") + name + "'").c_str() );
}
}
......@@ -128,6 +128,17 @@ void ReferenceInitializeForcesKernel::execute(OpenMMContextImpl& context) {
context.getForces().fillWithValue(zero);
}
void ReferenceUpdateTimeKernel::initialize(const System& system) {
}
double ReferenceUpdateTimeKernel::getTime(const OpenMMContextImpl& context) const {
return data.time;
}
void ReferenceUpdateTimeKernel::setTime(OpenMMContextImpl& context, double time) {
data.time = time;
}
ReferenceCalcHarmonicBondForceKernel::~ReferenceCalcHarmonicBondForceKernel() {
disposeIntArray(bondIndexArray, numBonds);
disposeRealArray(bondParamArray, numBonds);
......
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