"platforms/reference/include/ReferenceObc.h" did not exist on "b9d12c46232671c10ade0e36ebd637a4f53bd50a"
Commit a381a3ab authored by peastman's avatar peastman
Browse files

Merge branch 'master' into gayberne

parents 5ecc8e00 1f7866ad
......@@ -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.
......
......@@ -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) 2015 Stanford University and the Authors. *
* Portions copyright (c) 2015-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -34,8 +34,10 @@
#include "openmm/CustomIntegrator.h"
#include "openmm/internal/ContextImpl.h"
#include "lepton/CustomFunction.h"
#include "lepton/ParsedExpression.h"
#include <map>
#include <string>
#include <vector>
namespace OpenMM {
......@@ -48,6 +50,7 @@ class System;
class OPENMM_EXPORT CustomIntegratorUtilities {
public:
class DerivFunction;
enum Comparison {
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:
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,
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
......
......@@ -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-2014 Stanford University and the Authors. *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -63,9 +63,10 @@ public:
void updateParametersInContext(ContextImpl& context);
/**
* 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:
static double integrateInteraction(Lepton::CompiledExpression& expression, const std::vector<double>& params1, const std::vector<double>& params2,
const CustomNonbondedForce& force, const Context& context);
......
......@@ -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 CustomAngleForce::setGlobalParameterDefaultValue(int index, double defaultV
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) {
angles.push_back(AngleInfo(particle1, particle2, particle3, parameters));
return angles.size()-1;
......
......@@ -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;
......
......@@ -104,6 +104,20 @@ void CustomCentroidBondForce::setGlobalParameterDefaultValue(int index, double d
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) {
if (particles.size() != weights.size() && weights.size() > 0)
throw OpenMMException("CustomCentroidBondForce: wrong number of weights specified for a group.");
......
......@@ -105,6 +105,20 @@ void CustomCompoundBondForce::setGlobalParameterDefaultValue(int index, double d
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) {
if (particles.size() != particlesPerBond)
throw OpenMMException("CustomCompoundBondForce: wrong number of particles specified for a bond.");
......
......@@ -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-2014 Stanford University and the Authors. *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -111,6 +111,20 @@ void CustomGBForce::setGlobalParameterDefaultValue(int index, double defaultValu
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) {
particles.push_back(ParticleInfo(parameters));
return particles.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) 2015 Stanford University and the Authors. *
* Portions copyright (c) 2015-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -34,6 +34,7 @@
#include "openmm/internal/ForceImpl.h"
#include "lepton/Operation.h"
#include "lepton/Parser.h"
#include <algorithm>
#include <set>
#include <sstream>
......@@ -81,6 +82,9 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context,
forceGroup.resize(numSteps, -2);
vector<CustomIntegrator::ComputationType> stepType(numSteps);
vector<string> stepVariable(numSteps);
map<string, Lepton::CustomFunction*> customFunctions;
DerivFunction derivFunction;
customFunctions["deriv"] = &derivFunction;
// Parse the expressions.
......@@ -92,11 +96,11 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context,
string lhs, rhs;
parseCondition(expression, lhs, rhs, comparisons[step]);
expressions[step].push_back(Lepton::Parser::parse(lhs).optimize());
expressions[step].push_back(Lepton::Parser::parse(rhs).optimize());
expressions[step].push_back(Lepton::Parser::parse(lhs, customFunctions).optimize());
expressions[step].push_back(Lepton::Parser::parse(rhs, customFunctions).optimize());
}
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.
......@@ -191,6 +195,14 @@ void CustomIntegratorUtilities::analyzeComputations(const ContextImpl& context,
vector<int> jumps(numSteps, -1);
vector<int> stepsInPath;
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,
......@@ -264,4 +276,19 @@ void CustomIntegratorUtilities::analyzeForceComputationsForPath(vector<int>& ste
currentGroup = forceGroup[step];
}
}
}
\ No newline at end of file
}
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 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* 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 *
* Contributors: *
* *
......@@ -61,6 +61,7 @@ CustomNonbondedForce::CustomNonbondedForce(const CustomNonbondedForce& rhs) {
useLongRangeCorrection = rhs.useLongRangeCorrection;
parameters = rhs.parameters;
globalParameters = rhs.globalParameters;
energyParameterDerivatives = rhs.energyParameterDerivatives;
particles = rhs.particles;
exclusions = rhs.exclusions;
interactionGroups = rhs.interactionGroups;
......@@ -161,6 +162,20 @@ void CustomNonbondedForce::setGlobalParameterDefaultValue(int index, double defa
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) {
particles.push_back(ParticleInfo(parameters));
return particles.size()-1;
......@@ -195,6 +210,9 @@ void CustomNonbondedForce::setExclusionParticles(int index, int particle1, int p
void CustomNonbondedForce::createExclusionsFromBonds(const vector<pair<int, int> >& bonds, int bondCutoff) {
if (bondCutoff < 1)
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> > bonded12(exclusions.size());
for (int i = 0; i < (int) bonds.size(); ++i) {
......
......@@ -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-2014 Stanford University and the Authors. *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -157,16 +157,11 @@ void CustomNonbondedForceImpl::updateParametersInContext(ContextImpl& context) {
kernel.getAs<CalcCustomNonbondedForceKernel>().copyParametersToContext(context, owner);
}
double CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForce& force, const Context& context) {
if (force.getNonbondedMethod() == CustomNonbondedForce::NoCutoff || force.getNonbondedMethod() == CustomNonbondedForce::CutoffNonPeriodic)
return 0.0;
// 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();
void CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForce& force, const Context& context, double& coefficient, vector<double>& derivatives) {
if (force.getNonbondedMethod() == CustomNonbondedForce::NoCutoff || force.getNonbondedMethod() == CustomNonbondedForce::CutoffNonPeriodic) {
coefficient = 0.0;
return;
}
// Identify all particle classes (defined by parameters), and record the class of each particle.
......@@ -223,17 +218,35 @@ 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;
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);
double nPart = (double) numParticles;
double numInteractions = (nPart*(nPart+1))/2;
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,
......
......@@ -95,6 +95,20 @@ void CustomTorsionForce::setGlobalParameterDefaultValue(int index, double defaul
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) {
torsions.push_back(TorsionInfo(particle1, particle2, particle3, particle4, parameters));
return torsions.size()-1;
......
......@@ -36,6 +36,7 @@
#include <cmath>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace OpenMM;
using namespace std;
......@@ -108,7 +109,7 @@ void LocalEnergyMinimizer::minimize(Context& context, double tolerance, int maxI
if (x == NULL)
throw OpenMMException("LocalEnergyMinimizer: Failed to allocate memory");
double constraintTol = context.getIntegrator().getConstraintTolerance();
double workingConstraintTol = max(1e-4, constraintTol);
double workingConstraintTol = std::max(1e-4, constraintTol);
double k = tolerance/workingConstraintTol;
// Initialize the minimizer.
......
......@@ -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-2014 Stanford University and the Authors. *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
......@@ -184,6 +184,9 @@ ForceImpl* NonbondedForce::createImpl() const {
}
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.
......
......@@ -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);
}
......
......@@ -47,14 +47,14 @@ private:
const CpuNeighborList* neighborList;
float periodicBoxSize[3];
float cutoffDistance, cutoffDistance2;
int numValues, numParams;
const std::vector<std::set<int> > exclusions;
std::vector<std::string> valueNames;
std::vector<CustomGBForce::ComputationType> valueTypes;
std::vector<std::string> paramNames;
std::vector<CustomGBForce::ComputationType> energyTypes;
ThreadPool& threads;
std::vector<ThreadData*> threadData;
std::vector<double> threadEnergy;
std::vector<std::vector<std::vector<float> > > dValuedParam;
// Workspace vectors
std::vector<std::vector<float> > values, dEdV;
// The following variables are used to make information accessible to the individual threads.
......@@ -189,11 +189,13 @@ public:
const std::vector<Lepton::CompiledExpression>& valueExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueDerivExpressions,
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<CustomGBForce::ComputationType>& valueTypes,
const std::vector<Lepton::CompiledExpression>& energyExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyDerivExpressions,
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<std::string>& parameterNames, ThreadPool& threads);
......@@ -221,16 +223,17 @@ public:
/**
* Calculate custom GB ixn
*
* @param numberOfAtoms number of atoms
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param globalParameters the values of global parameters
* @param forces force array (forces added)
* @param totalEnergy total energy
* @param numberOfAtoms number of atoms
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param globalParameters the values of global parameters
* @param forces force array (forces added)
* @param totalEnergy total energy
* @param energyParamDerivs derivatives of the energy with respect to global parameters
*/
void calculateIxn(int numberOfAtoms, float* posq, RealOpenMM** atomParameters,
std::map<std::string, double>& globalParameters, std::vector<AlignedArray<float> >& threadForce, bool includeForce, bool includeEnergy, double& totalEnergy);
void calculateIxn(int numberOfAtoms, float* posq, RealOpenMM** atomParameters, std::map<std::string, double>& globalParameters,
std::vector<AlignedArray<float> >& threadForce, bool includeForce, bool includeEnergy, double& totalEnergy, double* energyParamDerivs);
};
class CpuCustomGBForce::ThreadData {
......@@ -239,19 +242,23 @@ public:
const std::vector<Lepton::CompiledExpression>& valueExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueDerivExpressions,
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<Lepton::CompiledExpression>& energyExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyDerivExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyGradientExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyParamDerivExpressions,
const std::vector<std::string>& parameterNames);
CompiledExpressionSet expressionSet;
std::vector<Lepton::CompiledExpression> valueExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > valueDerivExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > valueGradientExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > valueParamDerivExpressions;
std::vector<int> valueIndex;
std::vector<Lepton::CompiledExpression> energyExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > energyDerivExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > energyGradientExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > energyParamDerivExpressions;
std::vector<int> paramIndex;
std::vector<int> particleParamIndex;
std::vector<int> particleValueIndex;
......@@ -260,6 +267,8 @@ public:
// Workspace vectors
std::vector<float> value0, dVdR1, dVdR2, dVdX, dVdY, dVdZ;
std::vector<std::vector<float> > dEdV;
std::vector<std::vector<float> > dValue0dParam;
std::vector<float> energyParamDerivs;
};
} // namespace OpenMM
......
/* Portions copyright (c) 2009-2014 Stanford University and Simbios.
/* Portions copyright (c) 2009-2016 Stanford University and Simbios.
* Contributors: Peter Eastman
*
* Permission is hereby granted, free of charge, to any person obtaining
......@@ -27,9 +27,9 @@
#include "AlignedArray.h"
#include "CpuNeighborList.h"
#include "openmm/internal/CompiledExpressionSet.h"
#include "openmm/internal/ThreadPool.h"
#include "openmm/internal/vectorize.h"
#include "lepton/CompiledExpression.h"
#include <map>
#include <set>
#include <utility>
......@@ -47,7 +47,8 @@ class CpuCustomNonbondedForce {
--------------------------------------------------------------------------------------- */
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 {
void calculatePairIxn(int numberOfAtoms, float* posq, std::vector<OpenMM::RealVec>& atomCoordinates, RealOpenMM** atomParameters,
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:
class ComputeForceTask;
class ThreadData;
......@@ -176,13 +177,15 @@ private:
class CpuCustomNonbondedForce::ThreadData {
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 forceExpression;
std::vector<double*> energyParticleParams;
std::vector<double*> forceParticleParams;
double* energyR;
double* forceR;
std::vector<Lepton::CompiledExpression> energyParamDerivExpressions;
CompiledExpressionSet expressionSet;
std::vector<int> particleParamIndex;
int rIndex;
std::vector<RealOpenMM> energyParamDerivs;
};
} // 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