"platforms/cuda/vscode:/vscode.git/clone" did not exist on "bdc8f29eaec9799e386d197153c1031ffc5be201"
Commit cd566c63 authored by peastman's avatar peastman
Browse files

Beginnings of support for derivatives with respect to parameters

parent 77b9b7ba
......@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2015 Stanford University and the Authors. *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -172,6 +172,12 @@ public:
* @param forces on exit, this contains the forces
*/
virtual void getForces(ContextImpl& context, std::vector<Vec3>& forces) = 0;
/**
* Get the current derivatives of the energy with respect to context parameters.
*
* @param derivs on exit, this contains the derivatives
*/
virtual void getEnergyParameterDerivatives(ContextImpl& context, std::map<std::string, double>& derivs) = 0;
/**
* Get the current periodic box vectors.
*
......
......@@ -64,6 +64,10 @@ namespace OpenMM {
* force->addPerBondParameter("r0");
* </pre></tt>
*
* This class also has the ability to compute derivatives of the potential energy with respect to global parameters.
* Call addEnergyParameterDerivative() to request that the derivative with respect to a particular parameter be
* computed. You can then query its value in a Context by calling getState() on it.
*
* Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following
* functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions
* are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise.
......@@ -97,6 +101,13 @@ public:
int getNumGlobalParameters() const {
return globalParameters.size();
}
/**
* Get the number of global parameters with respect to which the derivative of the energy
* should be computed.
*/
int getNumEnergyParameterDerivatives() const {
return energyParameterDerivatives.size();
}
/**
* Get the algebraic expression that gives the interaction energy for each bond
*/
......@@ -162,6 +173,21 @@ public:
* @param defaultValue the default value of the parameter
*/
void setGlobalParameterDefaultValue(int index, double defaultValue);
/**
* Request that this Force compute the derivative of its energy with respect to a global parameter.
* The parameter must have already been added with addGlobalParameter().
*
* @param name the name of the parameter
*/
void addEnergyParameterDerivative(const std::string& name);
/**
* Get the name of a global parameter with respect to which this Force should compute the
* derivative of the energy.
*
* @param index the index of the parameter derivative, between 0 and getNumEnergyParameterDerivatives()
* @return the parameter name
*/
const std::string& getEnergyParameterDerivativeName(int index) const;
/**
* Add a bond term to the force field.
*
......@@ -222,6 +248,7 @@ private:
std::vector<BondParameterInfo> parameters;
std::vector<GlobalParameterInfo> globalParameters;
std::vector<BondInfo> bonds;
std::vector<int> energyParameterDerivatives;
bool usePeriodic;
};
......
......@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008 Stanford University and the Authors. *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -58,7 +58,7 @@ public:
* This is an enumeration of the types of data which may be stored in a State. When you create
* a State, use these values to specify which data types it should contain.
*/
enum DataType {Positions=1, Velocities=2, Forces=4, Energy=8, Parameters=16};
enum DataType {Positions=1, Velocities=2, Forces=4, Energy=8, Parameters=16, ParameterDerivatives=32};
/**
* Construct an empty State containing no data. This exists so State objects can be used in STL containers.
*/
......@@ -108,6 +108,17 @@ public:
* Get a map containing the values of all parameters. If this State does not contain parameters, this will throw an exception.
*/
const std::map<std::string, double>& getParameters() const;
/**
* Get a map containing derivatives of the potential energy with respect to context parameters.
* In most cases derivatives are only calculated if the corresponding Force objects have been
* specifically told to compute them. Otherwise, the values in the map will be zero. Likewise,
* if multiple Forces depend on the same parameter but only some have been told to compute
* derivatives with respect to it, the returned value will include only the contributions from
* the Forces that were told to compute it.
*
* If this State does not contain parameter derivatives, this will throw an exception.
*/
const std::map<std::string, double>& getEnergyParameterDerivatives() const;
/**
* Get which data types are stored in this State. The return value is a sum of DataType flags.
*/
......@@ -118,6 +129,7 @@ private:
void setVelocities(const std::vector<Vec3>& vel);
void setForces(const std::vector<Vec3>& force);
void setParameters(const std::map<std::string, double>& params);
void setEnergyParameterDerivatives(const std::map<std::string, double>& derivs);
void setEnergy(double ke, double pe);
void setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c);
int types;
......@@ -126,7 +138,7 @@ private:
std::vector<Vec3> velocities;
std::vector<Vec3> forces;
Vec3 periodicBoxVectors[3];
std::map<std::string, double> parameters;
std::map<std::string, double> parameters, energyParameterDerivatives;
};
/**
......@@ -142,6 +154,7 @@ public:
void setVelocities(const std::vector<Vec3>& vel);
void setForces(const std::vector<Vec3>& force);
void setParameters(const std::map<std::string, double>& params);
void setEnergyParameterDerivatives(const std::map<std::string, double>& params);
void setEnergy(double ke, double pe);
void setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c);
private:
......
......@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2013 Stanford University and the Authors. *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -138,6 +138,10 @@ public:
* @param value the value of the parameter
*/
void setParameter(std::string name, double value);
/**
* Get the derivatives of the energy with respect to parameters.
*/
void getEnergyParameterDerivatives(std::map<std::string, double>& derivs);
/**
* Get the vectors defining the axes of the periodic box (measured in nm). They will affect
* any Force that uses periodic boundary conditions.
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2015 Stanford University and the Authors. *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -84,8 +84,9 @@ State Context::getState(int types, bool enforcePeriodicBox, int groups) const {
builder.setPeriodicBoxVectors(periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2]);
bool includeForces = types&State::Forces;
bool includeEnergy = types&State::Energy;
if (includeForces || includeEnergy) {
double energy = impl->calcForcesAndEnergy(includeForces || includeEnergy, includeEnergy, groups);
bool includeParameterDerivs = types&State::ParameterDerivatives;
if (includeForces || includeEnergy || includeParameterDerivs) {
double energy = impl->calcForcesAndEnergy(includeForces || includeEnergy || includeParameterDerivs, includeEnergy, groups);
if (includeEnergy)
builder.setEnergy(impl->calcKineticEnergy(), energy);
if (includeForces) {
......@@ -100,6 +101,11 @@ State Context::getState(int types, bool enforcePeriodicBox, int groups) const {
params[iter->first] = iter->second;
builder.setParameters(params);
}
if (types&State::ParameterDerivatives) {
map<string, double> derivs;
impl->getEnergyParameterDerivatives(derivs);
builder.setEnergyParameterDerivatives(derivs);
}
if (types&State::Positions) {
vector<Vec3> positions;
impl->getPositions(positions);
......
......@@ -240,6 +240,10 @@ void ContextImpl::setParameter(std::string name, double value) {
integrator.stateChanged(State::Parameters);
}
void ContextImpl::getEnergyParameterDerivatives(std::map<std::string, double>& derivs) {
updateStateDataKernel.getAs<UpdateStateDataKernel>().getEnergyParameterDerivatives(*this, derivs);
}
void ContextImpl::getPeriodicBoxVectors(Vec3& a, Vec3& b, Vec3& c) {
updateStateDataKernel.getAs<UpdateStateDataKernel>().getPeriodicBoxVectors(*this, a, b, c);
}
......
......@@ -95,6 +95,20 @@ void CustomBondForce::setGlobalParameterDefaultValue(int index, double defaultVa
globalParameters[index].defaultValue = defaultValue;
}
void CustomBondForce::addEnergyParameterDerivative(const string& name) {
for (int i = 0; i < globalParameters.size(); i++)
if (name == globalParameters[i].name) {
energyParameterDerivatives.push_back(i);
return;
}
throw OpenMMException(string("addEnergyParameterDerivative: Unknown global parameter '"+name+"'"));
}
const string& CustomBondForce::getEnergyParameterDerivativeName(int index) const {
ASSERT_VALID_INDEX(index, energyParameterDerivatives);
return globalParameters[energyParameterDerivatives[index]].name;
}
int CustomBondForce::addBond(int particle1, int particle2, const vector<double>& parameters) {
bonds.push_back(BondInfo(particle1, particle2, parameters));
return bonds.size()-1;
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008 Stanford University and the Authors. *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -76,6 +76,11 @@ const map<string, double>& State::getParameters() const {
throw OpenMMException("Invoked getParameters() on a State which does not contain parameters.");
return parameters;
}
const map<string, double>& State::getEnergyParameterDerivatives() const {
if ((types&ParameterDerivatives) == 0)
throw OpenMMException("Invoked getEnergyParameterDerivatives() on a State which does not contain parameter derivatives.");
return energyParameterDerivatives;
}
int State::getDataTypes() const {
return types;
}
......@@ -103,6 +108,11 @@ void State::setParameters(const std::map<std::string, double>& params) {
types |= Parameters;
}
void State::setEnergyParameterDerivatives(const std::map<std::string, double>& derivs) {
energyParameterDerivatives = derivs;
types |= ParameterDerivatives;
}
void State::setEnergy(double kinetic, double potential) {
ke = kinetic;
pe = potential;
......@@ -138,6 +148,10 @@ void State::StateBuilder::setParameters(const std::map<std::string, double>& par
state.setParameters(params);
}
void State::StateBuilder::setEnergyParameterDerivatives(const std::map<std::string, double>& derivs) {
state.setEnergyParameterDerivatives(derivs);
}
void State::StateBuilder::setEnergy(double ke, double pe) {
state.setEnergy(ke, pe);
}
......
......@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2014 Stanford University and the Authors. *
* Portions copyright (c) 2014-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -196,7 +196,7 @@ void CpuBondForce::calculateForce(vector<RealVec>& atomCoordinates, RealOpenMM**
for (int i = 0; i < extraBonds.size(); i++) {
int bond = extraBonds[i];
referenceBondIxn.calculateBondIxn(bondAtoms[bond], atomCoordinates, parameters[bond], forces, totalEnergy);
referenceBondIxn.calculateBondIxn(bondAtoms[bond], atomCoordinates, parameters[bond], forces, totalEnergy, NULL);
}
// Compute the total energy.
......@@ -212,6 +212,6 @@ void CpuBondForce::threadComputeForce(ThreadPool& threads, int threadIndex, vect
int numBonds = bonds.size();
for (int i = 0; i < numBonds; i++) {
int bond = bonds[i];
referenceBondIxn.calculateBondIxn(bondAtoms[bond], atomCoordinates, parameters[bond], forces, totalEnergy);
referenceBondIxn.calculateBondIxn(bondAtoms[bond], atomCoordinates, parameters[bond], forces, totalEnergy, NULL);
}
}
\ No newline at end of file
......@@ -163,6 +163,12 @@ public:
* @param forces on exit, this contains the forces
*/
void getForces(ContextImpl& context, std::vector<Vec3>& forces);
/**
* Get the current derivatives of the energy with respect to context parameters.
*
* @param derivs on exit, this contains the derivatives
*/
void getEnergyParameterDerivatives(ContextImpl& context, std::map<std::string, double>& derivs);
/**
* Get the current periodic box vectors.
*
......
......@@ -339,6 +339,10 @@ void CudaUpdateStateDataKernel::getForces(ContextImpl& context, vector<Vec3>& fo
forces[order[i]] = Vec3(scale*force[i], scale*force[i+paddedNumParticles], scale*force[i+paddedNumParticles*2]);
}
void CudaUpdateStateDataKernel::getEnergyParameterDerivatives(ContextImpl& context, map<string, double>& derivs) {
}
void CudaUpdateStateDataKernel::getPeriodicBoxVectors(ContextImpl& context, Vec3& a, Vec3& b, Vec3& c) const {
cu.getPeriodicBoxVectors(a, b, c);
}
......
......@@ -141,6 +141,12 @@ public:
* @param forces on exit, this contains the forces
*/
void getForces(ContextImpl& context, std::vector<Vec3>& forces);
/**
* Get the current derivatives of the energy with respect to context parameters.
*
* @param derivs on exit, this contains the derivatives
*/
void getEnergyParameterDerivatives(ContextImpl& context, std::map<std::string, double>& derivs);
/**
* Get the current periodic box vectors.
*
......
......@@ -368,6 +368,10 @@ void OpenCLUpdateStateDataKernel::getForces(ContextImpl& context, vector<Vec3>&
}
}
void OpenCLUpdateStateDataKernel::getEnergyParameterDerivatives(ContextImpl& context, map<string, double>& derivs) {
}
void OpenCLUpdateStateDataKernel::getPeriodicBoxVectors(ContextImpl& context, Vec3& a, Vec3& b, Vec3& c) const {
cl.getPeriodicBoxVectors(a, b, c);
}
......
/* Portions copyright (c) 2006 Stanford University and Simbios.
/* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
......@@ -94,7 +94,7 @@ class OPENMM_EXPORT ReferenceAngleBondIxn : public ReferenceBondIxn {
void calculateBondIxn(int* atomIndices, std::vector<OpenMM::RealVec>& atomCoordinates,
RealOpenMM* parameters, std::vector<OpenMM::RealVec>& forces,
RealOpenMM* totalEnergy) const;
RealOpenMM* totalEnergy, double* energyParamDerivs);
};
......
/* Portions copyright (c) 2006 Stanford University and Simbios.
/* Portions copyright (c) 2006-2016 Stanford University and Simbios.
* Contributors: Pande Group
*
* Permission is hereby granted, free of charge, to any person obtaining
......@@ -67,7 +67,7 @@ class OPENMM_EXPORT ReferenceBondIxn {
virtual void calculateBondIxn(int* atomIndices, std::vector<OpenMM::RealVec>& atomCoordinates,
RealOpenMM* parameters, std::vector<OpenMM::RealVec>& forces,
RealOpenMM* totalEnergy) const;
RealOpenMM* totalEnergy, double* energyParamDerivs);
/**---------------------------------------------------------------------------------------
......
/* Portions copyright (c) 2010 Stanford University and Simbios.
/* Portions copyright (c) 2010-2016 Stanford University and Simbios.
* Contributors: Peter Eastman
*
* Permission is hereby granted, free of charge, to any person obtaining
......@@ -97,7 +97,7 @@ public:
void calculateBondIxn(int* atomIndices, std::vector<OpenMM::RealVec>& atomCoordinates,
RealOpenMM* parameters, std::vector<OpenMM::RealVec>& forces,
RealOpenMM* totalEnergy) const;
RealOpenMM* totalEnergy, double* energyParamDerivs);
// ---------------------------------------------------------------------------------------
......
......@@ -85,7 +85,7 @@ class ReferenceCustomAngleIxn : public ReferenceBondIxn {
void calculateBondIxn(int* atomIndices, std::vector<OpenMM::RealVec>& atomCoordinates,
RealOpenMM* parameters, std::vector<OpenMM::RealVec>& forces,
RealOpenMM* totalEnergy) const;
RealOpenMM* totalEnergy, double* energyParamDerivs);
};
......
......@@ -26,6 +26,7 @@
#define __ReferenceCustomBondIxn_H__
#include "ReferenceBondIxn.h"
#include "openmm/internal/CompiledExpressionSet.h"
#include "lepton/CompiledExpression.h"
namespace OpenMM {
......@@ -35,10 +36,10 @@ class ReferenceCustomBondIxn : public ReferenceBondIxn {
private:
Lepton::CompiledExpression energyExpression;
Lepton::CompiledExpression forceExpression;
std::vector<double*> energyParams;
std::vector<double*> forceParams;
double* energyR;
double* forceR;
std::vector<Lepton::CompiledExpression> energyParamDerivExpressions;
CompiledExpressionSet expressionSet;
std::vector<int> bondParamIndex;
int rIndex;
int numParameters;
bool usePeriodic;
RealVec boxVectors[3];
......@@ -52,7 +53,8 @@ class ReferenceCustomBondIxn : public ReferenceBondIxn {
--------------------------------------------------------------------------------------- */
ReferenceCustomBondIxn(const Lepton::CompiledExpression& energyExpression, const Lepton::CompiledExpression& forceExpression,
const std::vector<std::string>& parameterNames, std::map<std::string, double> globalParameters);
const std::vector<std::string>& parameterNames, std::map<std::string, double> globalParameters,
const std::vector<Lepton::CompiledExpression> energyParamDerivExpressions);
/**---------------------------------------------------------------------------------------
......@@ -86,7 +88,7 @@ class ReferenceCustomBondIxn : public ReferenceBondIxn {
void calculateBondIxn(int* atomIndices, std::vector<OpenMM::RealVec>& atomCoordinates,
RealOpenMM* parameters, std::vector<OpenMM::RealVec>& forces,
RealOpenMM* totalEnergy) const;
RealOpenMM* totalEnergy, double* energyParamDerivs);
};
......
......@@ -85,7 +85,7 @@ class ReferenceCustomTorsionIxn : public ReferenceBondIxn {
void calculateBondIxn(int* atomIndices, std::vector<OpenMM::RealVec>& atomCoordinates,
RealOpenMM* parameters, std::vector<OpenMM::RealVec>& forces,
RealOpenMM* totalEnergy) const;
RealOpenMM* totalEnergy, double* energyParamDerivs);
};
......
......@@ -79,7 +79,7 @@ class ReferenceHarmonicBondIxn : public ReferenceBondIxn {
void calculateBondIxn(int* atomIndices, std::vector<OpenMM::RealVec>& atomCoordinates,
RealOpenMM* parameters, std::vector<OpenMM::RealVec>& forces,
RealOpenMM* totalEnergy) const;
RealOpenMM* totalEnergy, double* energyParamDerivs);
};
......
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