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

CustomNonbondedForce supports named parameters, global parameters, more flexible combining rules

parent e07b8c94
...@@ -89,7 +89,13 @@ public: ...@@ -89,7 +89,13 @@ public:
* Get the number of per-particle parameters that the interaction depends on. * Get the number of per-particle parameters that the interaction depends on.
*/ */
int getNumParameters() const { int getNumParameters() const {
return combiningRules.size(); return parameters.size();
}
/**
* Get the number of global parameters that the interaction depends on.
*/
int getNumGlobalParameters() const {
return globalParameters.size();
} }
/** /**
* Get the algebraic expression that gives the interaction energy between two particles * Get the algebraic expression that gives the interaction energy between two particles
...@@ -144,10 +150,25 @@ public: ...@@ -144,10 +150,25 @@ public:
/** /**
* Add a new per-particle parmeter that the interaction may depend on. * Add a new per-particle parmeter that the interaction may depend on.
* *
* @param name the name of the parameter
* @param combiningRule an algebraic expression giving the combining rule for this parameter * @param combiningRule an algebraic expression giving the combining rule for this parameter
* @return the index of the parameter that was added * @return the index of the parameter that was added
*/ */
int addParameter(const std::string& combiningRule); int addParameter(const std::string& name, const std::string& combiningRule);
/**
* Get the name of a per-particle parameter.
*
* @param index the index of the parameter for which to get the name
* @return the parameter name
*/
const std::string& getParameterName(int index) const;
/**
* Set the name of a per-particle parameter.
*
* @param index the index of the parameter for which to set the name
* @param name the name of the parameter
*/
void setParameterName(int index, const std::string& name);
/** /**
* Get the combining rule for a per-particle parameter. * Get the combining rule for a per-particle parameter.
* *
...@@ -162,6 +183,27 @@ public: ...@@ -162,6 +183,27 @@ public:
* @param combiningRule an algebraic expression giving the combining rule for the parameter * @param combiningRule an algebraic expression giving the combining rule for the parameter
*/ */
void setParameterCombiningRule(int index, const std::string& combiningRule); void setParameterCombiningRule(int index, const std::string& combiningRule);
/**
* Add a new global parmeter that the interaction may depend on.
*
* @param name the name of the parameter
* @return the index of the parameter that was added
*/
int addGlobalParameter(const std::string& name);
/**
* Get the name of a global parameter.
*
* @param index the index of the parameter for which to get the name
* @return the parameter name
*/
const std::string& getGlobalParameterName(int index) const;
/**
* Set the name of a global parameter.
*
* @param index the index of the parameter for which to set the name
* @param name the name of the parameter
*/
void setGlobalParameterName(int index, const std::string& name);
/** /**
* Add the nonbonded force parameters for a particle. This should be called once for each particle * Add the nonbonded force parameters for a particle. This should be called once for each particle
* in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle. * in the System. When it is called for the i'th time, it specifies the parameters for the i'th particle.
...@@ -220,12 +262,14 @@ protected: ...@@ -220,12 +262,14 @@ protected:
ForceImpl* createImpl(); ForceImpl* createImpl();
private: private:
class ParticleInfo; class ParticleInfo;
class ParameterInfo;
class ExceptionInfo; class ExceptionInfo;
NonbondedMethod nonbondedMethod; NonbondedMethod nonbondedMethod;
double cutoffDistance; double cutoffDistance;
Vec3 periodicBoxVectors[3]; Vec3 periodicBoxVectors[3];
std::string energyExpression; std::string energyExpression;
std::vector<std::string> combiningRules; std::vector<ParameterInfo> parameters;
std::vector<std::string> globalParameters;
std::vector<ParticleInfo> particles; std::vector<ParticleInfo> particles;
std::vector<ExceptionInfo> exceptions; std::vector<ExceptionInfo> exceptions;
std::map<std::pair<int, int>, int> exceptionMap; std::map<std::pair<int, int>, int> exceptionMap;
...@@ -240,6 +284,15 @@ public: ...@@ -240,6 +284,15 @@ public:
} }
}; };
class CustomNonbondedForce::ParameterInfo {
public:
std::string name, combiningRule;
ParameterInfo() {
}
ParameterInfo(const std::string& name, const std::string& combiningRule) : name(name), combiningRule(combiningRule) {
}
};
class CustomNonbondedForce::ExceptionInfo { class CustomNonbondedForce::ExceptionInfo {
public: public:
int particle1, particle2; int particle1, particle2;
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "openmm/CustomNonbondedForce.h" #include "openmm/CustomNonbondedForce.h"
#include "openmm/Kernel.h" #include "openmm/Kernel.h"
#include <utility> #include <utility>
#include <map>
#include <string> #include <string>
namespace OpenMM { namespace OpenMM {
...@@ -57,9 +58,7 @@ public: ...@@ -57,9 +58,7 @@ public:
} }
void calcForces(ContextImpl& context, Stream& forces); void calcForces(ContextImpl& context, Stream& forces);
double calcEnergy(ContextImpl& context); double calcEnergy(ContextImpl& context);
std::map<std::string, double> getDefaultParameters() { std::map<std::string, double> getDefaultParameters();
return std::map<std::string, double>(); // This force field doesn't define any parameters.
}
std::vector<std::string> getKernelNames(); std::vector<std::string> getKernelNames();
private: private:
CustomNonbondedForce& owner; CustomNonbondedForce& owner;
......
...@@ -94,17 +94,38 @@ void CustomNonbondedForce::setPeriodicBoxVectors(Vec3 a, Vec3 b, Vec3 c) { ...@@ -94,17 +94,38 @@ void CustomNonbondedForce::setPeriodicBoxVectors(Vec3 a, Vec3 b, Vec3 c) {
periodicBoxVectors[2] = c; periodicBoxVectors[2] = c;
} }
int CustomNonbondedForce::addParameter(const string& combiningRule) { int CustomNonbondedForce::addParameter(const string& name, const string& combiningRule) {
combiningRules.push_back(combiningRule); parameters.push_back(ParameterInfo(name, combiningRule));
return combiningRules.size()-1; return parameters.size()-1;
}
const string& CustomNonbondedForce::getParameterName(int index) const {
return parameters[index].name;
}
void CustomNonbondedForce::setParameterName(int index, const string& name) {
parameters[index].name = name;
} }
const string& CustomNonbondedForce::getParameterCombiningRule(int index) const { const string& CustomNonbondedForce::getParameterCombiningRule(int index) const {
return combiningRules[index]; return parameters[index].combiningRule;
} }
void CustomNonbondedForce::setParameterCombiningRule(int index, const string& combiningRule) { void CustomNonbondedForce::setParameterCombiningRule(int index, const string& combiningRule) {
combiningRules[index] = combiningRule; parameters[index].combiningRule = combiningRule;
}
int CustomNonbondedForce::addGlobalParameter(const string& name) {
globalParameters.push_back(name);
return globalParameters.size()-1;
}
const string& CustomNonbondedForce::getGlobalParameterName(int index) const {
return globalParameters[index];
}
void CustomNonbondedForce::setGlobalParameterName(int index, const string& name) {
globalParameters[index] = name;
} }
int CustomNonbondedForce::addParticle(const vector<double>& parameters) { int CustomNonbondedForce::addParticle(const vector<double>& parameters) {
......
...@@ -36,9 +36,11 @@ ...@@ -36,9 +36,11 @@
#include <sstream> #include <sstream>
using namespace OpenMM; using namespace OpenMM;
using std::map;
using std::pair; using std::pair;
using std::vector; using std::vector;
using std::set; using std::set;
using std::string;
using std::stringstream; using std::stringstream;
CustomNonbondedForceImpl::CustomNonbondedForceImpl(CustomNonbondedForce& owner) : owner(owner) { CustomNonbondedForceImpl::CustomNonbondedForceImpl(CustomNonbondedForce& owner) : owner(owner) {
...@@ -110,9 +112,15 @@ double CustomNonbondedForceImpl::calcEnergy(ContextImpl& context) { ...@@ -110,9 +112,15 @@ double CustomNonbondedForceImpl::calcEnergy(ContextImpl& context) {
return dynamic_cast<CalcCustomNonbondedForceKernel&>(kernel.getImpl()).executeEnergy(context); return dynamic_cast<CalcCustomNonbondedForceKernel&>(kernel.getImpl()).executeEnergy(context);
} }
std::vector<std::string> CustomNonbondedForceImpl::getKernelNames() { vector<string> CustomNonbondedForceImpl::getKernelNames() {
std::vector<std::string> names; vector<string> names;
names.push_back(CalcCustomNonbondedForceKernel::Name()); names.push_back(CalcCustomNonbondedForceKernel::Name());
return names; return names;
} }
map<string, double> CustomNonbondedForceImpl::getDefaultParameters() {
map<string, double> parameters;
for (int i = 0; i < owner.getNumGlobalParameters(); i++)
parameters[owner.getGlobalParameterName(i)] = 0.0;
return parameters;
}
...@@ -545,14 +545,18 @@ void ReferenceCalcCustomNonbondedForceKernel::initialize(const System& system, c ...@@ -545,14 +545,18 @@ void ReferenceCalcCustomNonbondedForceKernel::initialize(const System& system, c
Lepton::ParsedExpression expression = Lepton::Parser::parse(force.getEnergyFunction()).optimize(); Lepton::ParsedExpression expression = Lepton::Parser::parse(force.getEnergyFunction()).optimize();
energyExpression = expression.createProgram(); energyExpression = expression.createProgram();
forceExpression = expression.differentiate("r").optimize().createProgram(); forceExpression = expression.differentiate("r").optimize().createProgram();
for (int i = 0; i < numParameters; i++) for (int i = 0; i < numParameters; i++) {
parameterNames.push_back(force.getParameterName(i));
combiningRules.push_back(Lepton::Parser::parse(force.getParameterCombiningRule(i)).optimize().createProgram()); combiningRules.push_back(Lepton::Parser::parse(force.getParameterCombiningRule(i)).optimize().createProgram());
}
for (int i = 0; i < force.getNumGlobalParameters(); i++)
globalParameterNames.push_back(force.getGlobalParameterName(i));
} }
void ReferenceCalcCustomNonbondedForceKernel::executeForces(ContextImpl& context) { void ReferenceCalcCustomNonbondedForceKernel::executeForces(ContextImpl& context) {
RealOpenMM** posData = const_cast<RealOpenMM**>(((ReferenceFloatStreamImpl&) context.getPositions().getImpl()).getData()); // Reference code needs to be made const correct RealOpenMM** posData = const_cast<RealOpenMM**>(((ReferenceFloatStreamImpl&) context.getPositions().getImpl()).getData()); // Reference code needs to be made const correct
RealOpenMM** forceData = ((ReferenceFloatStreamImpl&) context.getForces().getImpl()).getData(); RealOpenMM** forceData = ((ReferenceFloatStreamImpl&) context.getForces().getImpl()).getData();
ReferenceCustomNonbondedIxn ixn(energyExpression, forceExpression, combiningRules); ReferenceCustomNonbondedIxn ixn(energyExpression, forceExpression, parameterNames, combiningRules);
bool periodic = (nonbondedMethod == CutoffPeriodic); bool periodic = (nonbondedMethod == CutoffPeriodic);
if (nonbondedMethod != NoCutoff) { if (nonbondedMethod != NoCutoff) {
computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, periodic ? periodicBoxSize : NULL, nonbondedCutoff, 0.0); computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, periodic ? periodicBoxSize : NULL, nonbondedCutoff, 0.0);
...@@ -560,15 +564,18 @@ void ReferenceCalcCustomNonbondedForceKernel::executeForces(ContextImpl& context ...@@ -560,15 +564,18 @@ void ReferenceCalcCustomNonbondedForceKernel::executeForces(ContextImpl& context
} }
if (periodic) if (periodic)
ixn.setPeriodic(periodicBoxSize); ixn.setPeriodic(periodicBoxSize);
ixn.calculatePairIxn(numParticles, posData, particleParamArray, exclusionArray, 0, forceData, 0, 0); map<string, double> globalParameters;
ixn.calculateExceptionIxn(num14, bonded14IndexArray, posData, bonded14ParamArray, forceData, 0, 0); for (int i = 0; i < globalParameterNames.size(); i++)
globalParameters[globalParameterNames[i]] = context.getParameter(globalParameterNames[i]);
ixn.calculatePairIxn(numParticles, posData, particleParamArray, exclusionArray, 0, globalParameters, forceData, 0, 0);
ixn.calculateExceptionIxn(num14, bonded14IndexArray, posData, bonded14ParamArray, globalParameters, forceData, 0, 0);
} }
double ReferenceCalcCustomNonbondedForceKernel::executeEnergy(ContextImpl& context) { double ReferenceCalcCustomNonbondedForceKernel::executeEnergy(ContextImpl& context) {
RealOpenMM** posData = const_cast<RealOpenMM**>(((ReferenceFloatStreamImpl&) context.getPositions().getImpl()).getData()); // Reference code needs to be made const correct RealOpenMM** posData = const_cast<RealOpenMM**>(((ReferenceFloatStreamImpl&) context.getPositions().getImpl()).getData()); // Reference code needs to be made const correct
RealOpenMM** forceData = allocateRealArray(numParticles, 3); RealOpenMM** forceData = allocateRealArray(numParticles, 3);
RealOpenMM energy = 0; RealOpenMM energy = 0;
ReferenceCustomNonbondedIxn ixn(energyExpression, forceExpression, combiningRules); ReferenceCustomNonbondedIxn ixn(energyExpression, forceExpression, parameterNames, combiningRules);
bool periodic = (nonbondedMethod == CutoffPeriodic); bool periodic = (nonbondedMethod == CutoffPeriodic);
if (nonbondedMethod != NoCutoff) { if (nonbondedMethod != NoCutoff) {
computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, periodic ? periodicBoxSize : NULL, nonbondedCutoff, 0.0); computeNeighborListVoxelHash(*neighborList, numParticles, posData, exclusions, periodic ? periodicBoxSize : NULL, nonbondedCutoff, 0.0);
...@@ -576,8 +583,11 @@ double ReferenceCalcCustomNonbondedForceKernel::executeEnergy(ContextImpl& conte ...@@ -576,8 +583,11 @@ double ReferenceCalcCustomNonbondedForceKernel::executeEnergy(ContextImpl& conte
} }
if (periodic) if (periodic)
ixn.setPeriodic(periodicBoxSize); ixn.setPeriodic(periodicBoxSize);
ixn.calculatePairIxn(numParticles, posData, particleParamArray, exclusionArray, 0, forceData, 0, &energy); map<string, double> globalParameters;
ixn.calculateExceptionIxn(num14, bonded14IndexArray, posData, bonded14ParamArray, forceData, 0, &energy); for (int i = 0; i < globalParameterNames.size(); i++)
globalParameters[globalParameterNames[i]] = context.getParameter(globalParameterNames[i]);
ixn.calculatePairIxn(numParticles, posData, particleParamArray, exclusionArray, 0, globalParameters, forceData, 0, &energy);
ixn.calculateExceptionIxn(num14, bonded14IndexArray, posData, bonded14ParamArray, globalParameters, forceData, 0, &energy);
disposeRealArray(forceData, numParticles); disposeRealArray(forceData, numParticles);
return energy; return energy;
} }
......
...@@ -310,6 +310,7 @@ private: ...@@ -310,6 +310,7 @@ private:
RealOpenMM nonbondedCutoff, periodicBoxSize[3]; RealOpenMM nonbondedCutoff, periodicBoxSize[3];
std::vector<std::set<int> > exclusions; std::vector<std::set<int> > exclusions;
Lepton::ExpressionProgram energyExpression, forceExpression; Lepton::ExpressionProgram energyExpression, forceExpression;
std::vector<std::string> parameterNames, globalParameterNames;
std::vector<Lepton::ExpressionProgram> combiningRules; std::vector<Lepton::ExpressionProgram> combiningRules;
NonbondedMethod nonbondedMethod; NonbondedMethod nonbondedMethod;
NeighborList* neighborList; NeighborList* neighborList;
......
...@@ -43,9 +43,9 @@ using std::vector; ...@@ -43,9 +43,9 @@ using std::vector;
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceCustomNonbondedIxn::ReferenceCustomNonbondedIxn(const Lepton::ExpressionProgram& energyExpression, ReferenceCustomNonbondedIxn::ReferenceCustomNonbondedIxn(const Lepton::ExpressionProgram& energyExpression,
const Lepton::ExpressionProgram& forceExpression, const std::vector<Lepton::ExpressionProgram>& combiningRules) : const Lepton::ExpressionProgram& forceExpression, const vector<string>& parameterNames, const vector<Lepton::ExpressionProgram>& combiningRules) :
cutoff(false), periodic(false), energyExpression(energyExpression), forceExpression(forceExpression), cutoff(false), periodic(false), energyExpression(energyExpression), forceExpression(forceExpression),
combiningRules(combiningRules) { paramNames(parameterNames), combiningRules(combiningRules) {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
...@@ -53,10 +53,12 @@ ReferenceCustomNonbondedIxn::ReferenceCustomNonbondedIxn(const Lepton::Expressio ...@@ -53,10 +53,12 @@ ReferenceCustomNonbondedIxn::ReferenceCustomNonbondedIxn(const Lepton::Expressio
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
for (int i = 0; i < combiningRules.size(); i++) { for (int i = 0; i < paramNames.size(); i++) {
stringstream name; for (int j = 1; j < 3; j++) {
name << "param" << i; stringstream name;
paramNames.push_back(name.str()); name << paramNames[i] << j;
particleParamNames.push_back(name.str());
}
} }
} }
...@@ -135,6 +137,7 @@ ReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn( ){ ...@@ -135,6 +137,7 @@ ReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn( ){
exclusions[atomIndex][1-no.] = atom indices of atoms to excluded from exclusions[atomIndex][1-no.] = atom indices of atoms to excluded from
interacting w/ atom atomIndex interacting w/ atom atomIndex
@param fixedParameters non atom parameters (not currently used) @param fixedParameters non atom parameters (not currently used)
@param globalParameters the values of global parameters
@param forces force array (forces added) @param forces force array (forces added)
@param energyByAtom atom energy @param energyByAtom atom energy
@param totalEnergy total energy @param totalEnergy total energy
...@@ -145,11 +148,11 @@ ReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn( ){ ...@@ -145,11 +148,11 @@ ReferenceCustomNonbondedIxn::~ReferenceCustomNonbondedIxn( ){
int ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, RealOpenMM** atomCoordinates, int ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, RealOpenMM** atomCoordinates,
RealOpenMM** atomParameters, int** exclusions, RealOpenMM** atomParameters, int** exclusions,
RealOpenMM* fixedParameters, RealOpenMM** forces, RealOpenMM* fixedParameters, map<string, double> globalParameters, RealOpenMM** forces,
RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) const { RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) const {
map<string, double> variablesForParams; map<string, double> variablesForParams = globalParameters;
map<string, double> variablesForForce; map<string, double> variablesForForce = globalParameters;
if (cutoff) { if (cutoff) {
for (int i = 0; i < (int) neighborList->size(); i++) { for (int i = 0; i < (int) neighborList->size(); i++) {
OpenMM::AtomPair pair = (*neighborList)[i]; OpenMM::AtomPair pair = (*neighborList)[i];
...@@ -157,10 +160,11 @@ int ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, RealOpenMM ...@@ -157,10 +160,11 @@ int ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, RealOpenMM
// Apply the combining rules to compute the force field parameters. // Apply the combining rules to compute the force field parameters.
for (int j = 0; j < combiningRules.size(); j++) { for (int j = 0; j < combiningRules.size(); j++) {
variablesForParams["particle1"] = atomParameters[pair.first][j]; variablesForParams[particleParamNames[j*2]] = atomParameters[pair.first][j];
variablesForParams["particle2"] = atomParameters[pair.second][j]; variablesForParams[particleParamNames[j*2+1]] = atomParameters[pair.second][j];
variablesForForce[paramNames[j]] = combiningRules[j].evaluate(variablesForParams);
} }
for (int j = 0; j < combiningRules.size(); j++)
variablesForForce[paramNames[j]] = combiningRules[j].evaluate(variablesForParams);
calculateOneIxn(pair.first, pair.second, atomCoordinates, variablesForForce, forces, energyByAtom, totalEnergy); calculateOneIxn(pair.first, pair.second, atomCoordinates, variablesForForce, forces, energyByAtom, totalEnergy);
} }
} }
...@@ -189,10 +193,11 @@ int ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, RealOpenMM ...@@ -189,10 +193,11 @@ int ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, RealOpenMM
// Apply the combining rules to compute the force field parameters. // Apply the combining rules to compute the force field parameters.
for (int j = 0; j < combiningRules.size(); j++) { for (int j = 0; j < combiningRules.size(); j++) {
variablesForParams["particle1"] = atomParameters[ii][j]; variablesForParams[particleParamNames[j*2]] = atomParameters[ii][j];
variablesForParams["particle2"] = atomParameters[jj][j]; variablesForParams[particleParamNames[j*2+1]] = atomParameters[jj][j];
variablesForForce[paramNames[j]] = combiningRules[j].evaluate(variablesForParams);
} }
for (int j = 0; j < combiningRules.size(); j++)
variablesForForce[paramNames[j]] = combiningRules[j].evaluate(variablesForParams);
calculateOneIxn(ii, jj, atomCoordinates, variablesForForce, forces, energyByAtom, totalEnergy); calculateOneIxn(ii, jj, atomCoordinates, variablesForForce, forces, energyByAtom, totalEnergy);
} }
} }
...@@ -212,16 +217,17 @@ int ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, RealOpenMM ...@@ -212,16 +217,17 @@ int ReferenceCustomNonbondedIxn::calculatePairIxn( int numberOfAtoms, RealOpenMM
@param atomCoordinates atom coordinates: atomCoordinates[atomIndex][3] @param atomCoordinates atom coordinates: atomCoordinates[atomIndex][3]
@param parameters parameters: parameters[exceptionIndex][*]; contents of array @param parameters parameters: parameters[exceptionIndex][*]; contents of array
depend on ixn depend on ixn
@param globalParameters the values of global parameters
@param forces force array (forces added to current values): forces[atomIndex][3] @param forces force array (forces added to current values): forces[atomIndex][3]
@param totalEnergy totalEnergy: sum over { energies[atomIndex] } @param totalEnergy totalEnergy: sum over { energies[atomIndex] }
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void ReferenceCustomNonbondedIxn::calculateExceptionIxn( int numberOfExceptions, int** atomIndices, RealOpenMM** atomCoordinates, void ReferenceCustomNonbondedIxn::calculateExceptionIxn( int numberOfExceptions, int** atomIndices, RealOpenMM** atomCoordinates,
RealOpenMM** parameters, RealOpenMM** forces, RealOpenMM** parameters, map<string, double> globalParameters, RealOpenMM** forces,
RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) const { RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) const {
map<string, double> variables; map<string, double> variables = globalParameters;
for (int i = 0; i < numberOfExceptions; i++) { for (int i = 0; i < numberOfExceptions; i++) {
for (int j = 0; j < combiningRules.size(); j++) for (int j = 0; j < combiningRules.size(); j++)
variables[paramNames[j]] = parameters[i][j]; variables[paramNames[j]] = parameters[i][j];
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
class ReferenceCustomNonbondedIxn : public ReferencePairIxn { class ReferenceCustomNonbondedIxn {
private: private:
...@@ -46,6 +46,7 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn { ...@@ -46,6 +46,7 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn {
Lepton::ExpressionProgram forceExpression; Lepton::ExpressionProgram forceExpression;
std::vector<Lepton::ExpressionProgram> combiningRules; std::vector<Lepton::ExpressionProgram> combiningRules;
std::vector<std::string> paramNames; std::vector<std::string> paramNames;
std::vector<std::string> particleParamNames;
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -75,7 +76,7 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn { ...@@ -75,7 +76,7 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
ReferenceCustomNonbondedIxn(const Lepton::ExpressionProgram& energyExpression, const Lepton::ExpressionProgram& forceExpression, ReferenceCustomNonbondedIxn(const Lepton::ExpressionProgram& energyExpression, const Lepton::ExpressionProgram& forceExpression,
const std::vector<Lepton::ExpressionProgram>& combiningRules); const std::vector<std::string>& parameterNames, const std::vector<Lepton::ExpressionProgram>& combiningRules);
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -124,6 +125,7 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn { ...@@ -124,6 +125,7 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn {
exclusions[atomIndex][1-no.] = atom indices of atoms to excluded from exclusions[atomIndex][1-no.] = atom indices of atoms to excluded from
interacting w/ atom atomIndex interacting w/ atom atomIndex
@param fixedParameters non atom parameters (not currently used) @param fixedParameters non atom parameters (not currently used)
@param globalParameters the values of global parameters
@param forces force array (forces added) @param forces force array (forces added)
@param energyByAtom atom energy @param energyByAtom atom energy
@param totalEnergy total energy @param totalEnergy total energy
...@@ -134,8 +136,8 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn { ...@@ -134,8 +136,8 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn {
int calculatePairIxn( int numberOfAtoms, RealOpenMM** atomCoordinates, int calculatePairIxn( int numberOfAtoms, RealOpenMM** atomCoordinates,
RealOpenMM** atomParameters, int** exclusions, RealOpenMM** atomParameters, int** exclusions,
RealOpenMM* fixedParameters, RealOpenMM** forces, RealOpenMM* fixedParameters, std::map<std::string, double> globalParameters,
RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) const; RealOpenMM** forces, RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) const;
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
...@@ -146,6 +148,7 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn { ...@@ -146,6 +148,7 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn {
@param atomCoordinates atom coordinates: atomCoordinates[atomIndex][3] @param atomCoordinates atom coordinates: atomCoordinates[atomIndex][3]
@param parameters parameters: parameters[excptionIndex][*]; contents of array @param parameters parameters: parameters[excptionIndex][*]; contents of array
depend on ixn depend on ixn
@param globalParameters the values of global parameters
@param forces force array (forces added to current values): forces[atomIndex][3] @param forces force array (forces added to current values): forces[atomIndex][3]
@param energyByAtom atom energy @param energyByAtom atom energy
@param totalEnergy total energy @param totalEnergy total energy
...@@ -153,8 +156,8 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn { ...@@ -153,8 +156,8 @@ class ReferenceCustomNonbondedIxn : public ReferencePairIxn {
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
void calculateExceptionIxn( int numberOfExceptions, int** atomIndices, RealOpenMM** atomCoordinates, void calculateExceptionIxn( int numberOfExceptions, int** atomIndices, RealOpenMM** atomCoordinates,
RealOpenMM** parameters, RealOpenMM** forces, RealOpenMM** parameters, std::map<std::string, double> globalParameters,
RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) const; RealOpenMM** forces, RealOpenMM* energyByAtom, RealOpenMM* totalEnergy ) const;
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
......
...@@ -77,9 +77,11 @@ void testParameters() { ...@@ -77,9 +77,11 @@ void testParameters() {
system.addParticle(1.0); system.addParticle(1.0);
system.addParticle(1.0); system.addParticle(1.0);
VerletIntegrator integrator(0.01); VerletIntegrator integrator(0.01);
CustomNonbondedForce* forceField = new CustomNonbondedForce("param0*(r*param1)^3"); CustomNonbondedForce* forceField = new CustomNonbondedForce("scale*a*(r*b)^3");
forceField->addParameter("particle1*particle2"); forceField->addParameter("a", "a1*a2");
forceField->addParameter("particle1+particle2"); forceField->addParameter("b", "c+b1+b2");
forceField->addGlobalParameter("scale");
forceField->addGlobalParameter("c");
vector<double> params(2); vector<double> params(2);
params[0] = 1.5; params[0] = 1.5;
params[1] = 2.0; params[1] = 2.0;
...@@ -93,20 +95,30 @@ void testParameters() { ...@@ -93,20 +95,30 @@ void testParameters() {
positions[0] = Vec3(0, 0, 0); positions[0] = Vec3(0, 0, 0);
positions[1] = Vec3(2, 0, 0); positions[1] = Vec3(2, 0, 0);
context.setPositions(positions); context.setPositions(positions);
context.setParameter("scale", 1.0);
context.setParameter("c", 0.0);
State state = context.getState(State::Forces | State::Energy); State state = context.getState(State::Forces | State::Energy);
const vector<Vec3>& forces = state.getForces(); vector<Vec3> forces = state.getForces();
double force = -3.0*3*5.0*(10*10); double force = -3.0*3*5.0*(10*10);
ASSERT_EQUAL_VEC(Vec3(-force, 0, 0), forces[0], TOL); ASSERT_EQUAL_VEC(Vec3(-force, 0, 0), forces[0], TOL);
ASSERT_EQUAL_VEC(Vec3(force, 0, 0), forces[1], TOL); ASSERT_EQUAL_VEC(Vec3(force, 0, 0), forces[1], TOL);
ASSERT_EQUAL_TOL(3.0*(10*10*10), state.getPotentialEnergy(), TOL); ASSERT_EQUAL_TOL(3.0*(10*10*10), state.getPotentialEnergy(), TOL);
context.setParameter("scale", 1.5);
context.setParameter("c", 1.0);
state = context.getState(State::Forces | State::Energy);
forces = state.getForces();
force = -1.5*3.0*3*6.0*(12*12);
ASSERT_EQUAL_VEC(Vec3(-force, 0, 0), forces[0], TOL);
ASSERT_EQUAL_VEC(Vec3(force, 0, 0), forces[1], TOL);
ASSERT_EQUAL_TOL(1.5*3.0*(12*12*12), state.getPotentialEnergy(), TOL);
} }
void testExceptions() { void testExceptions() {
ReferencePlatform platform; ReferencePlatform platform;
System system; System system;
VerletIntegrator integrator(0.01); VerletIntegrator integrator(0.01);
CustomNonbondedForce* nonbonded = new CustomNonbondedForce("param0*r"); CustomNonbondedForce* nonbonded = new CustomNonbondedForce("a*r");
nonbonded->addParameter("particle1+particle2"); nonbonded->addParameter("a", "a1+a2");
vector<double> params(1); vector<double> params(1);
vector<Vec3> positions(4); vector<Vec3> positions(4);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
......
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