Commit a381a3ab authored by peastman's avatar peastman
Browse files

Merge branch 'master' into gayberne

parents 5ecc8e00 1f7866ad
...@@ -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 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
* This is an enumeration of the types of data which may be stored in a State. When you create * 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. * 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. * Construct an empty State containing no data. This exists so State objects can be used in STL containers.
*/ */
...@@ -108,6 +108,17 @@ public: ...@@ -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. * 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; 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. * Get which data types are stored in this State. The return value is a sum of DataType flags.
*/ */
...@@ -118,6 +129,7 @@ private: ...@@ -118,6 +129,7 @@ private:
void setVelocities(const std::vector<Vec3>& vel); void setVelocities(const std::vector<Vec3>& vel);
void setForces(const std::vector<Vec3>& force); void setForces(const std::vector<Vec3>& force);
void setParameters(const std::map<std::string, double>& params); 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 setEnergy(double ke, double pe);
void setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c); void setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c);
int types; int types;
...@@ -126,7 +138,7 @@ private: ...@@ -126,7 +138,7 @@ private:
std::vector<Vec3> velocities; std::vector<Vec3> velocities;
std::vector<Vec3> forces; std::vector<Vec3> forces;
Vec3 periodicBoxVectors[3]; Vec3 periodicBoxVectors[3];
std::map<std::string, double> parameters; std::map<std::string, double> parameters, energyParameterDerivatives;
}; };
/** /**
...@@ -142,6 +154,7 @@ public: ...@@ -142,6 +154,7 @@ public:
void setVelocities(const std::vector<Vec3>& vel); void setVelocities(const std::vector<Vec3>& vel);
void setForces(const std::vector<Vec3>& force); void setForces(const std::vector<Vec3>& force);
void setParameters(const std::map<std::string, double>& params); 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 setEnergy(double ke, double pe);
void setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c); void setPeriodicBoxVectors(const Vec3& a, const Vec3& b, const Vec3& c);
private: private:
......
...@@ -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-2013 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -138,6 +138,10 @@ public: ...@@ -138,6 +138,10 @@ public:
* @param value the value of the parameter * @param value the value of the parameter
*/ */
void setParameter(std::string name, double value); 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 * Get the vectors defining the axes of the periodic box (measured in nm). They will affect
* any Force that uses periodic boundary conditions. * any Force that uses periodic boundary conditions.
......
...@@ -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) 2015 Stanford University and the Authors. * * Portions copyright (c) 2015-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -34,8 +34,10 @@ ...@@ -34,8 +34,10 @@
#include "openmm/CustomIntegrator.h" #include "openmm/CustomIntegrator.h"
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
#include "lepton/CustomFunction.h"
#include "lepton/ParsedExpression.h" #include "lepton/ParsedExpression.h"
#include <map> #include <map>
#include <string>
#include <vector> #include <vector>
namespace OpenMM { namespace OpenMM {
...@@ -48,6 +50,7 @@ class System; ...@@ -48,6 +50,7 @@ class System;
class OPENMM_EXPORT CustomIntegratorUtilities { class OPENMM_EXPORT CustomIntegratorUtilities {
public: public:
class DerivFunction;
enum Comparison { enum Comparison {
EQUAL = 0, LESS_THAN = 1, GREATER_THAN = 2, NOT_EQUAL = 3, LESS_THAN_OR_EQUAL = 4, GREATER_THAN_OR_EQUAL = 5 EQUAL = 0, LESS_THAN = 1, GREATER_THAN = 2, NOT_EQUAL = 3, LESS_THAN_OR_EQUAL = 4, GREATER_THAN_OR_EQUAL = 5
}; };
...@@ -82,6 +85,28 @@ private: ...@@ -82,6 +85,28 @@ private:
const std::vector<bool>& invalidatesForces, const std::vector<int>& forceGroup, std::vector<bool>& computeBoth); const std::vector<bool>& invalidatesForces, const std::vector<int>& forceGroup, std::vector<bool>& computeBoth);
static void analyzeForceComputationsForPath(std::vector<int>& steps, const std::vector<bool>& needsForces, const std::vector<bool>& needsEnergy, static void analyzeForceComputationsForPath(std::vector<int>& steps, const std::vector<bool>& needsForces, const std::vector<bool>& needsEnergy,
const std::vector<bool>& invalidatesForces, const std::vector<int>& forceGroup, std::vector<bool>& computeBoth); const std::vector<bool>& invalidatesForces, const std::vector<int>& forceGroup, std::vector<bool>& computeBoth);
static void validateDerivatives(const Lepton::ExpressionTreeNode& node, const std::vector<std::string>& derivNames);
};
/**
* This class is used to implement the deriv() function when it appears in expressions.
*/
class CustomIntegratorUtilities::DerivFunction : public Lepton::CustomFunction {
public:
DerivFunction() {
}
int getNumArguments() const {
return 2;
}
double evaluate(const double* arguments) const {
return 0.0;
}
double evaluateDerivative(const double* arguments, const int* derivOrder) const {
return 0.0;
}
CustomFunction* clone() const {
return new DerivFunction();
}
}; };
} // namespace OpenMM } // namespace OpenMM
......
...@@ -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-2014 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -63,9 +63,10 @@ public: ...@@ -63,9 +63,10 @@ public:
void updateParametersInContext(ContextImpl& context); void updateParametersInContext(ContextImpl& context);
/** /**
* Compute the coefficient which, when divided by the periodic box volume, gives the * Compute the coefficient which, when divided by the periodic box volume, gives the
* long range correction to the energy. * long range correction to the energy. If the Force computes parameter derivatives,
* also compute the corresponding derivatives of the correction.
*/ */
static double calcLongRangeCorrection(const CustomNonbondedForce& force, const Context& context); static void calcLongRangeCorrection(const CustomNonbondedForce& force, const Context& context, double& coefficient, std::vector<double>& derivatives);
private: private:
static double integrateInteraction(Lepton::CompiledExpression& expression, const std::vector<double>& params1, const std::vector<double>& params2, static double integrateInteraction(Lepton::CompiledExpression& expression, const std::vector<double>& params1, const std::vector<double>& params2,
const CustomNonbondedForce& force, const Context& context); const CustomNonbondedForce& force, const Context& context);
......
...@@ -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) 2008-2015 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -84,8 +84,9 @@ State Context::getState(int types, bool enforcePeriodicBox, int groups) const { ...@@ -84,8 +84,9 @@ State Context::getState(int types, bool enforcePeriodicBox, int groups) const {
builder.setPeriodicBoxVectors(periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2]); builder.setPeriodicBoxVectors(periodicBoxSize[0], periodicBoxSize[1], periodicBoxSize[2]);
bool includeForces = types&State::Forces; bool includeForces = types&State::Forces;
bool includeEnergy = types&State::Energy; bool includeEnergy = types&State::Energy;
if (includeForces || includeEnergy) { bool includeParameterDerivs = types&State::ParameterDerivatives;
double energy = impl->calcForcesAndEnergy(includeForces || includeEnergy, includeEnergy, groups); if (includeForces || includeEnergy || includeParameterDerivs) {
double energy = impl->calcForcesAndEnergy(includeForces || includeEnergy || includeParameterDerivs, includeEnergy, groups);
if (includeEnergy) if (includeEnergy)
builder.setEnergy(impl->calcKineticEnergy(), energy); builder.setEnergy(impl->calcKineticEnergy(), energy);
if (includeForces) { if (includeForces) {
...@@ -100,6 +101,11 @@ State Context::getState(int types, bool enforcePeriodicBox, int groups) const { ...@@ -100,6 +101,11 @@ State Context::getState(int types, bool enforcePeriodicBox, int groups) const {
params[iter->first] = iter->second; params[iter->first] = iter->second;
builder.setParameters(params); builder.setParameters(params);
} }
if (types&State::ParameterDerivatives) {
map<string, double> derivs;
impl->getEnergyParameterDerivatives(derivs);
builder.setEnergyParameterDerivatives(derivs);
}
if (types&State::Positions) { if (types&State::Positions) {
vector<Vec3> positions; vector<Vec3> positions;
impl->getPositions(positions); impl->getPositions(positions);
......
...@@ -240,6 +240,10 @@ void ContextImpl::setParameter(std::string name, double value) { ...@@ -240,6 +240,10 @@ void ContextImpl::setParameter(std::string name, double value) {
integrator.stateChanged(State::Parameters); 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) { void ContextImpl::getPeriodicBoxVectors(Vec3& a, Vec3& b, Vec3& c) {
updateStateDataKernel.getAs<UpdateStateDataKernel>().getPeriodicBoxVectors(*this, a, b, c); updateStateDataKernel.getAs<UpdateStateDataKernel>().getPeriodicBoxVectors(*this, a, b, c);
} }
......
...@@ -95,6 +95,20 @@ void CustomAngleForce::setGlobalParameterDefaultValue(int index, double defaultV ...@@ -95,6 +95,20 @@ void CustomAngleForce::setGlobalParameterDefaultValue(int index, double defaultV
globalParameters[index].defaultValue = defaultValue; globalParameters[index].defaultValue = defaultValue;
} }
void CustomAngleForce::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& CustomAngleForce::getEnergyParameterDerivativeName(int index) const {
ASSERT_VALID_INDEX(index, energyParameterDerivatives);
return globalParameters[energyParameterDerivatives[index]].name;
}
int CustomAngleForce::addAngle(int particle1, int particle2, int particle3, const vector<double>& parameters) { int CustomAngleForce::addAngle(int particle1, int particle2, int particle3, const vector<double>& parameters) {
angles.push_back(AngleInfo(particle1, particle2, particle3, parameters)); angles.push_back(AngleInfo(particle1, particle2, particle3, parameters));
return angles.size()-1; return angles.size()-1;
......
...@@ -95,6 +95,20 @@ void CustomBondForce::setGlobalParameterDefaultValue(int index, double defaultVa ...@@ -95,6 +95,20 @@ void CustomBondForce::setGlobalParameterDefaultValue(int index, double defaultVa
globalParameters[index].defaultValue = defaultValue; 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) { int CustomBondForce::addBond(int particle1, int particle2, const vector<double>& parameters) {
bonds.push_back(BondInfo(particle1, particle2, parameters)); bonds.push_back(BondInfo(particle1, particle2, parameters));
return bonds.size()-1; return bonds.size()-1;
......
...@@ -104,6 +104,20 @@ void CustomCentroidBondForce::setGlobalParameterDefaultValue(int index, double d ...@@ -104,6 +104,20 @@ void CustomCentroidBondForce::setGlobalParameterDefaultValue(int index, double d
globalParameters[index].defaultValue = defaultValue; globalParameters[index].defaultValue = defaultValue;
} }
void CustomCentroidBondForce::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& CustomCentroidBondForce::getEnergyParameterDerivativeName(int index) const {
ASSERT_VALID_INDEX(index, energyParameterDerivatives);
return globalParameters[energyParameterDerivatives[index]].name;
}
int CustomCentroidBondForce::addGroup(const vector<int>& particles, const vector<double>& weights) { int CustomCentroidBondForce::addGroup(const vector<int>& particles, const vector<double>& weights) {
if (particles.size() != weights.size() && weights.size() > 0) if (particles.size() != weights.size() && weights.size() > 0)
throw OpenMMException("CustomCentroidBondForce: wrong number of weights specified for a group."); throw OpenMMException("CustomCentroidBondForce: wrong number of weights specified for a group.");
......
...@@ -105,6 +105,20 @@ void CustomCompoundBondForce::setGlobalParameterDefaultValue(int index, double d ...@@ -105,6 +105,20 @@ void CustomCompoundBondForce::setGlobalParameterDefaultValue(int index, double d
globalParameters[index].defaultValue = defaultValue; globalParameters[index].defaultValue = defaultValue;
} }
void CustomCompoundBondForce::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& CustomCompoundBondForce::getEnergyParameterDerivativeName(int index) const {
ASSERT_VALID_INDEX(index, energyParameterDerivatives);
return globalParameters[energyParameterDerivatives[index]].name;
}
int CustomCompoundBondForce::addBond(const vector<int>& particles, const vector<double>& parameters) { int CustomCompoundBondForce::addBond(const vector<int>& particles, const vector<double>& parameters) {
if (particles.size() != particlesPerBond) if (particles.size() != particlesPerBond)
throw OpenMMException("CustomCompoundBondForce: wrong number of particles specified for a bond."); throw OpenMMException("CustomCompoundBondForce: wrong number of particles specified for a bond.");
......
...@@ -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) 2008-2014 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -111,6 +111,20 @@ void CustomGBForce::setGlobalParameterDefaultValue(int index, double defaultValu ...@@ -111,6 +111,20 @@ void CustomGBForce::setGlobalParameterDefaultValue(int index, double defaultValu
globalParameters[index].defaultValue = defaultValue; globalParameters[index].defaultValue = defaultValue;
} }
void CustomGBForce::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& CustomGBForce::getEnergyParameterDerivativeName(int index) const {
ASSERT_VALID_INDEX(index, energyParameterDerivatives);
return globalParameters[energyParameterDerivatives[index]].name;
}
int CustomGBForce::addParticle(const vector<double>& parameters) { int CustomGBForce::addParticle(const vector<double>& parameters) {
particles.push_back(ParticleInfo(parameters)); particles.push_back(ParticleInfo(parameters));
return particles.size()-1; return particles.size()-1;
......
...@@ -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) 2015 Stanford University and the Authors. * * Portions copyright (c) 2015-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "openmm/internal/ForceImpl.h" #include "openmm/internal/ForceImpl.h"
#include "lepton/Operation.h" #include "lepton/Operation.h"
#include "lepton/Parser.h" #include "lepton/Parser.h"
#include <algorithm>
#include <set> #include <set>
#include <sstream> #include <sstream>
...@@ -81,6 +82,9 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context, ...@@ -81,6 +82,9 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context,
forceGroup.resize(numSteps, -2); forceGroup.resize(numSteps, -2);
vector<CustomIntegrator::ComputationType> stepType(numSteps); vector<CustomIntegrator::ComputationType> stepType(numSteps);
vector<string> stepVariable(numSteps); vector<string> stepVariable(numSteps);
map<string, Lepton::CustomFunction*> customFunctions;
DerivFunction derivFunction;
customFunctions["deriv"] = &derivFunction;
// Parse the expressions. // Parse the expressions.
...@@ -92,11 +96,11 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context, ...@@ -92,11 +96,11 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context,
string lhs, rhs; string lhs, rhs;
parseCondition(expression, lhs, rhs, comparisons[step]); parseCondition(expression, lhs, rhs, comparisons[step]);
expressions[step].push_back(Lepton::Parser::parse(lhs).optimize()); expressions[step].push_back(Lepton::Parser::parse(lhs, customFunctions).optimize());
expressions[step].push_back(Lepton::Parser::parse(rhs).optimize()); expressions[step].push_back(Lepton::Parser::parse(rhs, customFunctions).optimize());
} }
else if (expression.size() > 0) else if (expression.size() > 0)
expressions[step].push_back(Lepton::Parser::parse(expression).optimize()); expressions[step].push_back(Lepton::Parser::parse(expression, customFunctions).optimize());
} }
// Identify which steps invalidate the forces. // Identify which steps invalidate the forces.
...@@ -191,6 +195,14 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context, ...@@ -191,6 +195,14 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context,
vector<int> jumps(numSteps, -1); vector<int> jumps(numSteps, -1);
vector<int> stepsInPath; vector<int> stepsInPath;
enumeratePaths(0, stepsInPath, jumps, blockEnd, stepType, needsForces, needsEnergy, invalidatesForces, forceGroup, computeBoth); enumeratePaths(0, stepsInPath, jumps, blockEnd, stepType, needsForces, needsEnergy, invalidatesForces, forceGroup, computeBoth);
// Make sure calls to deriv() all valid.
vector<string> derivNames = energyGroupName;
derivNames.push_back("energy");
for (int i = 0; i < expressions.size(); i++)
for (int j = 0; j < expressions[i].size(); j++)
validateDerivatives(expressions[i][j].getRootNode(), derivNames);
} }
void CustomIntegratorUtilities::enumeratePaths(int firstStep, vector<int> steps, vector<int> jumps, const vector<int>& blockEnd, void CustomIntegratorUtilities::enumeratePaths(int firstStep, vector<int> steps, vector<int> jumps, const vector<int>& blockEnd,
...@@ -265,3 +277,18 @@ void CustomIntegratorUtilities::analyzeForceComputationsForPath(vector<int>& ste ...@@ -265,3 +277,18 @@ void CustomIntegratorUtilities::analyzeForceComputationsForPath(vector<int>& ste
} }
} }
} }
void CustomIntegratorUtilities::validateDerivatives(const Lepton::ExpressionTreeNode& node, const vector<string>& derivNames) {
const Lepton::Operation& op = node.getOperation();
if (op.getId() == Lepton::Operation::CUSTOM && op.getName() == "deriv") {
const Lepton::Operation& child = node.getChildren()[0].getOperation();
if (child.getId() != Lepton::Operation::VARIABLE || find(derivNames.begin(), derivNames.end(), child.getName()) == derivNames.end())
throw OpenMMException("The first argument to deriv() must be an energy variable");
if (node.getChildren()[1].getOperation().getId() != Lepton::Operation::VARIABLE)
throw OpenMMException("The second argument to deriv() must be a context parameter");
}
else {
for (int i = 0; i < node.getChildren().size(); i++)
validateDerivatives(node.getChildren()[i], derivNames);
}
}
...@@ -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) 2008-2014 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -61,6 +61,7 @@ CustomNonbondedForce::CustomNonbondedForce(const CustomNonbondedForce& rhs) { ...@@ -61,6 +61,7 @@ CustomNonbondedForce::CustomNonbondedForce(const CustomNonbondedForce& rhs) {
useLongRangeCorrection = rhs.useLongRangeCorrection; useLongRangeCorrection = rhs.useLongRangeCorrection;
parameters = rhs.parameters; parameters = rhs.parameters;
globalParameters = rhs.globalParameters; globalParameters = rhs.globalParameters;
energyParameterDerivatives = rhs.energyParameterDerivatives;
particles = rhs.particles; particles = rhs.particles;
exclusions = rhs.exclusions; exclusions = rhs.exclusions;
interactionGroups = rhs.interactionGroups; interactionGroups = rhs.interactionGroups;
...@@ -161,6 +162,20 @@ void CustomNonbondedForce::setGlobalParameterDefaultValue(int index, double defa ...@@ -161,6 +162,20 @@ void CustomNonbondedForce::setGlobalParameterDefaultValue(int index, double defa
globalParameters[index].defaultValue = defaultValue; globalParameters[index].defaultValue = defaultValue;
} }
void CustomNonbondedForce::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& CustomNonbondedForce::getEnergyParameterDerivativeName(int index) const {
ASSERT_VALID_INDEX(index, energyParameterDerivatives);
return globalParameters[energyParameterDerivatives[index]].name;
}
int CustomNonbondedForce::addParticle(const vector<double>& parameters) { int CustomNonbondedForce::addParticle(const vector<double>& parameters) {
particles.push_back(ParticleInfo(parameters)); particles.push_back(ParticleInfo(parameters));
return particles.size()-1; return particles.size()-1;
...@@ -195,6 +210,9 @@ void CustomNonbondedForce::setExclusionParticles(int index, int particle1, int p ...@@ -195,6 +210,9 @@ void CustomNonbondedForce::setExclusionParticles(int index, int particle1, int p
void CustomNonbondedForce::createExclusionsFromBonds(const vector<pair<int, int> >& bonds, int bondCutoff) { void CustomNonbondedForce::createExclusionsFromBonds(const vector<pair<int, int> >& bonds, int bondCutoff) {
if (bondCutoff < 1) if (bondCutoff < 1)
return; return;
for (int i = 0; i < (int) bonds.size(); ++i)
if (bonds[i].first < 0 || bonds[i].second < 0 || bonds[i].first >= particles.size() || bonds[i].second >= particles.size())
throw OpenMMException("createExclusionsFromBonds: Illegal particle index in list of bonds");
vector<set<int> > exclusions(particles.size()); vector<set<int> > exclusions(particles.size());
vector<set<int> > bonded12(exclusions.size()); vector<set<int> > bonded12(exclusions.size());
for (int i = 0; i < (int) bonds.size(); ++i) { for (int i = 0; i < (int) bonds.size(); ++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) 2008-2014 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -157,16 +157,11 @@ void CustomNonbondedForceImpl::updateParametersInContext(ContextImpl& context) { ...@@ -157,16 +157,11 @@ void CustomNonbondedForceImpl::updateParametersInContext(ContextImpl& context) {
kernel.getAs<CalcCustomNonbondedForceKernel>().copyParametersToContext(context, owner); kernel.getAs<CalcCustomNonbondedForceKernel>().copyParametersToContext(context, owner);
} }
double CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForce& force, const Context& context) { void CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForce& force, const Context& context, double& coefficient, vector<double>& derivatives) {
if (force.getNonbondedMethod() == CustomNonbondedForce::NoCutoff || force.getNonbondedMethod() == CustomNonbondedForce::CutoffNonPeriodic) if (force.getNonbondedMethod() == CustomNonbondedForce::NoCutoff || force.getNonbondedMethod() == CustomNonbondedForce::CutoffNonPeriodic) {
return 0.0; coefficient = 0.0;
return;
// Parse the energy expression. }
map<string, Lepton::CustomFunction*> functions;
for (int i = 0; i < force.getNumFunctions(); i++)
functions[force.getTabulatedFunctionName(i)] = createReferenceTabulatedFunction(force.getTabulatedFunction(i));
Lepton::CompiledExpression expression = Lepton::Parser::parse(force.getEnergyFunction(), functions).createCompiledExpression();
// Identify all particle classes (defined by parameters), and record the class of each particle. // Identify all particle classes (defined by parameters), and record the class of each particle.
...@@ -224,16 +219,34 @@ double CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedFo ...@@ -224,16 +219,34 @@ double CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedFo
} }
} }
// Loop over all pairs of classes to compute the coefficient. // Compute the coefficient.
map<string, Lepton::CustomFunction*> functions;
for (int i = 0; i < force.getNumFunctions(); i++)
functions[force.getTabulatedFunctionName(i)] = createReferenceTabulatedFunction(force.getTabulatedFunction(i));
double nPart = (double) numParticles;
double numInteractions = (nPart*(nPart+1))/2;
Lepton::CompiledExpression expression = Lepton::Parser::parse(force.getEnergyFunction(), functions).createCompiledExpression();
double sum = 0; double sum = 0;
for (int i = 0; i < numClasses; i++) for (int i = 0; i < numClasses; i++)
for (int j = i; j < numClasses; j++) for (int j = i; j < numClasses; j++)
sum += interactionCount[make_pair(i, j)]*integrateInteraction(expression, classes[i], classes[j], force, context); sum += interactionCount[make_pair(i, j)]*integrateInteraction(expression, classes[i], classes[j], force, context);
double nPart = (double) numParticles;
double numInteractions = (nPart*(nPart+1))/2;
sum /= numInteractions; sum /= numInteractions;
return 2*M_PI*nPart*nPart*sum; coefficient = 2*M_PI*nPart*nPart*sum;
// Now do the same for parameter derivatives.
int numDerivs = force.getNumEnergyParameterDerivatives();
derivatives.resize(numDerivs);
for (int k = 0; k < numDerivs; k++) {
expression = Lepton::Parser::parse(force.getEnergyFunction(), functions).differentiate(force.getEnergyParameterDerivativeName(k)).createCompiledExpression();
sum = 0;
for (int i = 0; i < numClasses; i++)
for (int j = i; j < numClasses; j++)
sum += interactionCount[make_pair(i, j)]*integrateInteraction(expression, classes[i], classes[j], force, context);
sum /= numInteractions;
derivatives[k] = 2*M_PI*nPart*nPart*sum;
}
} }
double CustomNonbondedForceImpl::integrateInteraction(Lepton::CompiledExpression& expression, const vector<double>& params1, const vector<double>& params2, double CustomNonbondedForceImpl::integrateInteraction(Lepton::CompiledExpression& expression, const vector<double>& params1, const vector<double>& params2,
......
...@@ -95,6 +95,20 @@ void CustomTorsionForce::setGlobalParameterDefaultValue(int index, double defaul ...@@ -95,6 +95,20 @@ void CustomTorsionForce::setGlobalParameterDefaultValue(int index, double defaul
globalParameters[index].defaultValue = defaultValue; globalParameters[index].defaultValue = defaultValue;
} }
void CustomTorsionForce::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& CustomTorsionForce::getEnergyParameterDerivativeName(int index) const {
ASSERT_VALID_INDEX(index, energyParameterDerivatives);
return globalParameters[energyParameterDerivatives[index]].name;
}
int CustomTorsionForce::addTorsion(int particle1, int particle2, int particle3, int particle4, const vector<double>& parameters) { int CustomTorsionForce::addTorsion(int particle1, int particle2, int particle3, int particle4, const vector<double>& parameters) {
torsions.push_back(TorsionInfo(particle1, particle2, particle3, particle4, parameters)); torsions.push_back(TorsionInfo(particle1, particle2, particle3, particle4, parameters));
return torsions.size()-1; return torsions.size()-1;
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <cmath> #include <cmath>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include <algorithm>
using namespace OpenMM; using namespace OpenMM;
using namespace std; using namespace std;
...@@ -108,7 +109,7 @@ void LocalEnergyMinimizer::minimize(Context& context, double tolerance, int maxI ...@@ -108,7 +109,7 @@ void LocalEnergyMinimizer::minimize(Context& context, double tolerance, int maxI
if (x == NULL) if (x == NULL)
throw OpenMMException("LocalEnergyMinimizer: Failed to allocate memory"); throw OpenMMException("LocalEnergyMinimizer: Failed to allocate memory");
double constraintTol = context.getIntegrator().getConstraintTolerance(); double constraintTol = context.getIntegrator().getConstraintTolerance();
double workingConstraintTol = max(1e-4, constraintTol); double workingConstraintTol = std::max(1e-4, constraintTol);
double k = tolerance/workingConstraintTol; double k = tolerance/workingConstraintTol;
// Initialize the minimizer. // Initialize the minimizer.
......
...@@ -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) 2008-2014 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -184,6 +184,9 @@ ForceImpl* NonbondedForce::createImpl() const { ...@@ -184,6 +184,9 @@ ForceImpl* NonbondedForce::createImpl() const {
} }
void NonbondedForce::createExceptionsFromBonds(const vector<pair<int, int> >& bonds, double coulomb14Scale, double lj14Scale) { void NonbondedForce::createExceptionsFromBonds(const vector<pair<int, int> >& bonds, double coulomb14Scale, double lj14Scale) {
for (int i = 0; i < (int) bonds.size(); ++i)
if (bonds[i].first < 0 || bonds[i].second < 0 || bonds[i].first >= particles.size() || bonds[i].second >= particles.size())
throw OpenMMException("createExceptionsFromBonds: Illegal particle index in list of bonds");
// Find particles separated by 1, 2, or 3 bonds. // Find particles separated by 1, 2, or 3 bonds.
......
...@@ -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) 2008 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -76,6 +76,11 @@ const map<string, double>& State::getParameters() const { ...@@ -76,6 +76,11 @@ const map<string, double>& State::getParameters() const {
throw OpenMMException("Invoked getParameters() on a State which does not contain parameters."); throw OpenMMException("Invoked getParameters() on a State which does not contain parameters.");
return 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 { int State::getDataTypes() const {
return types; return types;
} }
...@@ -103,6 +108,11 @@ void State::setParameters(const std::map<std::string, double>& params) { ...@@ -103,6 +108,11 @@ void State::setParameters(const std::map<std::string, double>& params) {
types |= Parameters; types |= Parameters;
} }
void State::setEnergyParameterDerivatives(const std::map<std::string, double>& derivs) {
energyParameterDerivatives = derivs;
types |= ParameterDerivatives;
}
void State::setEnergy(double kinetic, double potential) { void State::setEnergy(double kinetic, double potential) {
ke = kinetic; ke = kinetic;
pe = potential; pe = potential;
...@@ -138,6 +148,10 @@ void State::StateBuilder::setParameters(const std::map<std::string, double>& par ...@@ -138,6 +148,10 @@ void State::StateBuilder::setParameters(const std::map<std::string, double>& par
state.setParameters(params); 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) { void State::StateBuilder::setEnergy(double ke, double pe) {
state.setEnergy(ke, pe); state.setEnergy(ke, pe);
} }
......
...@@ -47,14 +47,14 @@ private: ...@@ -47,14 +47,14 @@ private:
const CpuNeighborList* neighborList; const CpuNeighborList* neighborList;
float periodicBoxSize[3]; float periodicBoxSize[3];
float cutoffDistance, cutoffDistance2; float cutoffDistance, cutoffDistance2;
int numValues, numParams;
const std::vector<std::set<int> > exclusions; const std::vector<std::set<int> > exclusions;
std::vector<std::string> valueNames;
std::vector<CustomGBForce::ComputationType> valueTypes; std::vector<CustomGBForce::ComputationType> valueTypes;
std::vector<std::string> paramNames;
std::vector<CustomGBForce::ComputationType> energyTypes; std::vector<CustomGBForce::ComputationType> energyTypes;
ThreadPool& threads; ThreadPool& threads;
std::vector<ThreadData*> threadData; std::vector<ThreadData*> threadData;
std::vector<double> threadEnergy; std::vector<double> threadEnergy;
std::vector<std::vector<std::vector<float> > > dValuedParam;
// Workspace vectors // Workspace vectors
std::vector<std::vector<float> > values, dEdV; std::vector<std::vector<float> > values, dEdV;
// The following variables are used to make information accessible to the individual threads. // The following variables are used to make information accessible to the individual threads.
...@@ -189,11 +189,13 @@ public: ...@@ -189,11 +189,13 @@ public:
const std::vector<Lepton::CompiledExpression>& valueExpressions, const std::vector<Lepton::CompiledExpression>& valueExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueDerivExpressions, const std::vector<std::vector<Lepton::CompiledExpression> >& valueDerivExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueGradientExpressions, const std::vector<std::vector<Lepton::CompiledExpression> >& valueGradientExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueParamDerivExpressions,
const std::vector<std::string>& valueNames, const std::vector<std::string>& valueNames,
const std::vector<CustomGBForce::ComputationType>& valueTypes, const std::vector<CustomGBForce::ComputationType>& valueTypes,
const std::vector<Lepton::CompiledExpression>& energyExpressions, const std::vector<Lepton::CompiledExpression>& energyExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyDerivExpressions, const std::vector<std::vector<Lepton::CompiledExpression> >& energyDerivExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyGradientExpressions, const std::vector<std::vector<Lepton::CompiledExpression> >& energyGradientExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyParamDerivExpressions,
const std::vector<CustomGBForce::ComputationType>& energyTypes, const std::vector<CustomGBForce::ComputationType>& energyTypes,
const std::vector<std::string>& parameterNames, ThreadPool& threads); const std::vector<std::string>& parameterNames, ThreadPool& threads);
...@@ -227,10 +229,11 @@ public: ...@@ -227,10 +229,11 @@ public:
* @param globalParameters the values of global parameters * @param globalParameters the values of global parameters
* @param forces force array (forces added) * @param forces force array (forces added)
* @param totalEnergy total energy * @param totalEnergy total energy
* @param energyParamDerivs derivatives of the energy with respect to global parameters
*/ */
void calculateIxn(int numberOfAtoms, float* posq, RealOpenMM** atomParameters, void calculateIxn(int numberOfAtoms, float* posq, RealOpenMM** atomParameters, std::map<std::string, double>& globalParameters,
std::map<std::string, double>& globalParameters, std::vector<AlignedArray<float> >& threadForce, bool includeForce, bool includeEnergy, double& totalEnergy); std::vector<AlignedArray<float> >& threadForce, bool includeForce, bool includeEnergy, double& totalEnergy, double* energyParamDerivs);
}; };
class CpuCustomGBForce::ThreadData { class CpuCustomGBForce::ThreadData {
...@@ -239,19 +242,23 @@ public: ...@@ -239,19 +242,23 @@ public:
const std::vector<Lepton::CompiledExpression>& valueExpressions, const std::vector<Lepton::CompiledExpression>& valueExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueDerivExpressions, const std::vector<std::vector<Lepton::CompiledExpression> >& valueDerivExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueGradientExpressions, const std::vector<std::vector<Lepton::CompiledExpression> >& valueGradientExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueParamDerivExpressions,
const std::vector<std::string>& valueNames, const std::vector<std::string>& valueNames,
const std::vector<Lepton::CompiledExpression>& energyExpressions, const std::vector<Lepton::CompiledExpression>& energyExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyDerivExpressions, const std::vector<std::vector<Lepton::CompiledExpression> >& energyDerivExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyGradientExpressions, const std::vector<std::vector<Lepton::CompiledExpression> >& energyGradientExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyParamDerivExpressions,
const std::vector<std::string>& parameterNames); const std::vector<std::string>& parameterNames);
CompiledExpressionSet expressionSet; CompiledExpressionSet expressionSet;
std::vector<Lepton::CompiledExpression> valueExpressions; std::vector<Lepton::CompiledExpression> valueExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > valueDerivExpressions; std::vector<std::vector<Lepton::CompiledExpression> > valueDerivExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > valueGradientExpressions; std::vector<std::vector<Lepton::CompiledExpression> > valueGradientExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > valueParamDerivExpressions;
std::vector<int> valueIndex; std::vector<int> valueIndex;
std::vector<Lepton::CompiledExpression> energyExpressions; std::vector<Lepton::CompiledExpression> energyExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > energyDerivExpressions; std::vector<std::vector<Lepton::CompiledExpression> > energyDerivExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > energyGradientExpressions; std::vector<std::vector<Lepton::CompiledExpression> > energyGradientExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > energyParamDerivExpressions;
std::vector<int> paramIndex; std::vector<int> paramIndex;
std::vector<int> particleParamIndex; std::vector<int> particleParamIndex;
std::vector<int> particleValueIndex; std::vector<int> particleValueIndex;
...@@ -260,6 +267,8 @@ public: ...@@ -260,6 +267,8 @@ public:
// Workspace vectors // Workspace vectors
std::vector<float> value0, dVdR1, dVdR2, dVdX, dVdY, dVdZ; std::vector<float> value0, dVdR1, dVdR2, dVdX, dVdY, dVdZ;
std::vector<std::vector<float> > dEdV; std::vector<std::vector<float> > dEdV;
std::vector<std::vector<float> > dValue0dParam;
std::vector<float> energyParamDerivs;
}; };
} // namespace OpenMM } // namespace OpenMM
......
/* Portions copyright (c) 2009-2014 Stanford University and Simbios. /* Portions copyright (c) 2009-2016 Stanford University and Simbios.
* Contributors: Peter Eastman * Contributors: Peter Eastman
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
...@@ -27,9 +27,9 @@ ...@@ -27,9 +27,9 @@
#include "AlignedArray.h" #include "AlignedArray.h"
#include "CpuNeighborList.h" #include "CpuNeighborList.h"
#include "openmm/internal/CompiledExpressionSet.h"
#include "openmm/internal/ThreadPool.h" #include "openmm/internal/ThreadPool.h"
#include "openmm/internal/vectorize.h" #include "openmm/internal/vectorize.h"
#include "lepton/CompiledExpression.h"
#include <map> #include <map>
#include <set> #include <set>
#include <utility> #include <utility>
...@@ -47,7 +47,8 @@ class CpuCustomNonbondedForce { ...@@ -47,7 +47,8 @@ class CpuCustomNonbondedForce {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
CpuCustomNonbondedForce(const Lepton::CompiledExpression& energyExpression, const Lepton::CompiledExpression& forceExpression, CpuCustomNonbondedForce(const Lepton::CompiledExpression& energyExpression, const Lepton::CompiledExpression& forceExpression,
const std::vector<std::string>& parameterNames, const std::vector<std::set<int> >& exclusions, ThreadPool& threads); const std::vector<std::string>& parameterNames, const std::vector<std::set<int> >& exclusions,
const std::vector<Lepton::CompiledExpression> energyParamDerivExpressions, ThreadPool& threads);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -119,7 +120,7 @@ class CpuCustomNonbondedForce { ...@@ -119,7 +120,7 @@ class CpuCustomNonbondedForce {
void calculatePairIxn(int numberOfAtoms, float* posq, std::vector<OpenMM::RealVec>& atomCoordinates, RealOpenMM** atomParameters, void calculatePairIxn(int numberOfAtoms, float* posq, std::vector<OpenMM::RealVec>& atomCoordinates, RealOpenMM** atomParameters,
RealOpenMM* fixedParameters, const std::map<std::string, double>& globalParameters, RealOpenMM* fixedParameters, const std::map<std::string, double>& globalParameters,
std::vector<AlignedArray<float> >& threadForce, bool includeForce, bool includeEnergy, double& totalEnergy); std::vector<AlignedArray<float> >& threadForce, bool includeForce, bool includeEnergy, double& totalEnergy, double* energyParamDerivs);
private: private:
class ComputeForceTask; class ComputeForceTask;
class ThreadData; class ThreadData;
...@@ -176,13 +177,15 @@ private: ...@@ -176,13 +177,15 @@ private:
class CpuCustomNonbondedForce::ThreadData { class CpuCustomNonbondedForce::ThreadData {
public: public:
ThreadData(const Lepton::CompiledExpression& energyExpression, const Lepton::CompiledExpression& forceExpression, const std::vector<std::string>& parameterNames); ThreadData(const Lepton::CompiledExpression& energyExpression, const Lepton::CompiledExpression& forceExpression, const std::vector<std::string>& parameterNames,
const std::vector<Lepton::CompiledExpression> energyParamDerivExpressions);
Lepton::CompiledExpression energyExpression; Lepton::CompiledExpression energyExpression;
Lepton::CompiledExpression forceExpression; Lepton::CompiledExpression forceExpression;
std::vector<double*> energyParticleParams; std::vector<Lepton::CompiledExpression> energyParamDerivExpressions;
std::vector<double*> forceParticleParams; CompiledExpressionSet expressionSet;
double* energyR; std::vector<int> particleParamIndex;
double* forceR; int rIndex;
std::vector<RealOpenMM> energyParamDerivs;
}; };
} // namespace OpenMM } // namespace OpenMM
......
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