Commit 74b4d450 authored by peastman's avatar peastman
Browse files

Created API for CustomCVForce

parent 66bc28f5
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "openmm/CustomAngleForce.h" #include "openmm/CustomAngleForce.h"
#include "openmm/CustomBondForce.h" #include "openmm/CustomBondForce.h"
#include "openmm/CustomCentroidBondForce.h" #include "openmm/CustomCentroidBondForce.h"
#include "openmm/CustomCVForce.h"
#include "openmm/CustomCompoundBondForce.h" #include "openmm/CustomCompoundBondForce.h"
#include "openmm/CustomExternalForce.h" #include "openmm/CustomExternalForce.h"
#include "openmm/CustomGBForce.h" #include "openmm/CustomGBForce.h"
...@@ -943,6 +944,42 @@ public: ...@@ -943,6 +944,42 @@ public:
virtual void copyParametersToContext(ContextImpl& context, const GayBerneForce& force) = 0; virtual void copyParametersToContext(ContextImpl& context, const GayBerneForce& force) = 0;
}; };
/**
* This kernel is invoked by CustomCVForce to calculate the forces acting on the system and the energy of the system.
*/
class CalcCustomCVForceKernel : public KernelImpl {
public:
static std::string Name() {
return "CalcCustomCVForce";
}
CalcCustomCVForceKernel(std::string name, const Platform& platform) : KernelImpl(name, platform) {
}
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the CustomCVForce this kernel will be used for
*/
virtual void initialize(const System& system, const CustomCVForce& force) = 0;
/**
* Execute the kernel to calculate the forces and/or energy.
*
* @param context the context in which to execute this kernel
* @param innerContext the context created by the CustomCVForce for computing collective variables
* @param includeForces true if forces should be calculated
* @param includeEnergy true if the energy should be calculated
* @return the potential energy due to the force
*/
virtual double execute(ContextImpl& context, ContextImpl& innerContext, bool includeForces, bool includeEnergy) = 0;
/**
* Copy state information to the inner context.
*
* @param context the context in which to execute this kernel
* @param innerContext the context created by the CustomCVForce for computing collective variables
*/
virtual void copyState(ContextImpl& context, ContextImpl& innerContext) = 0;
};
/** /**
* This kernel is invoked by VerletIntegrator to take one time step. * This kernel is invoked by VerletIntegrator to take one time step.
*/ */
......
...@@ -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) 2009-2016 Stanford University and the Authors. * * Portions copyright (c) 2009-2017 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "openmm/CustomAngleForce.h" #include "openmm/CustomAngleForce.h"
#include "openmm/CustomTorsionForce.h" #include "openmm/CustomTorsionForce.h"
#include "openmm/CustomExternalForce.h" #include "openmm/CustomExternalForce.h"
#include "openmm/CustomCVForce.h"
#include "openmm/CustomGBForce.h" #include "openmm/CustomGBForce.h"
#include "openmm/CustomHbondForce.h" #include "openmm/CustomHbondForce.h"
#include "openmm/CustomIntegrator.h" #include "openmm/CustomIntegrator.h"
......
...@@ -264,6 +264,7 @@ public: ...@@ -264,6 +264,7 @@ public:
const std::vector<std::vector<int> >& getMolecules() const; const std::vector<std::vector<int> >& getMolecules() const;
private: private:
friend class Force; friend class Force;
friend class ForceImpl;
friend class Platform; friend class Platform;
ContextImpl& getImpl(); ContextImpl& getImpl();
const ContextImpl& getImpl() const; const ContextImpl& getImpl() const;
......
#ifndef OPENMM_CUSTOMCVFORCE_H_
#define OPENMM_CUSTOMCVFORCE_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2017 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "TabulatedFunction.h"
#include "Force.h"
#include <vector>
#include "internal/windowsExport.h"
namespace OpenMM {
/**
* This class supports energy functions that depend on collective variables. To use it,
* you define a set of collective variables (scalar valued functions that depend on the
* particle positions), and an algebraic expression for the energy as a function of the
* collective variables. The expression also may involve tabulated functions, and may
* depend on arbitrary global parameters.
*
* Each collective variable is defined by a Force object. The Force's potential energy
* is computed, and that becomes the value of the variable. This provides enormous
* flexibility in defining collective variables, especially by using custom forces.
* Anything that can be computed as a potential function can also be used as a collective
* variable.
*
* To use this class, create a CustomCVForce object, passing an algebraic expression to the
* constructor that defines the potential energy. Then call addCollectiveVariable() to define
* collective variables and addGlobalParameter() to define global parameters. The values
* of global parameters may be modified during a simulation by calling Context::setParameter().
*
* This class also has the ability to compute derivatives of the potential energy with respect to global parameters.
* Call addEnergyParameterDerivative() to request that the derivative with respect to a particular parameter be
* computed. You can then query its value in a Context by calling getState() on it.
*
* Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following
* functions: sqrt, exp, log, sin, cos, sec, csc, tan, cot, asin, acos, atan, sinh, cosh, tanh, erf, erfc, min, max, abs, floor, ceil, step, delta, select. All trigonometric functions
* are defined in radians, and log is the natural logarithm. step(x) = 0 if x is less than 0, 1 otherwise. delta(x) = 1 if x is 0, 0 otherwise.
* select(x,y,z) = z if x = 0, y otherwise.
*
* In addition, you can call addTabulatedFunction() to define a new function based on tabulated values. You specify the function by
* creating a TabulatedFunction object. That function can then appear in the expression.
*/
class OPENMM_EXPORT CustomCVForce : public Force {
public:
/**
* Create a CustomCVForce.
*
* @param energy an algebraic expression giving the energy of the system as a function
* of the collective variables and global parameters
*/
explicit CustomCVForce(const std::string& energy);
~CustomCVForce();
/**
* Get the number of collective variables that the interaction depends on.
*/
int getNumCollectiveVariables() const {
return variables.size();
}
/**
* Get the number of global parameters that the interaction depends on.
*/
int getNumGlobalParameters() const {
return globalParameters.size();
}
/**
* Get the number of global parameters with respect to which the derivative of the energy
* should be computed.
*/
int getNumEnergyParameterDerivatives() const {
return energyParameterDerivatives.size();
}
/**
* Get the number of tabulated functions that have been defined.
*/
int getNumTabulatedFunctions() const {
return functions.size();
}
/**
* Get the algebraic expression that gives the energy of the system
*/
const std::string& getEnergyFunction() const;
/**
* Set the algebraic expression that gives the energy of the system
*/
void setEnergyFunction(const std::string& energy);
/**
* Add a collective variable that the force may depend on. The collective variable
* is represented by a Force object, which should have been created on the heap with the
* "new" operator. The CustomCVForce takes over ownership of it, and deletes the Force when the
* CustomCVForce itself is deleted.
*
* @param name the name of the collective variable, as it will appear in the energy expression
* @param variable the collective variable, represented by a Force object. The value of the
* variable is the energy computed by the Force.
* @return the index within the Force of the variable that was added
*/
int addCollectiveVariable(const std::string& name, Force* variable);
/**
* Get the name of a collective variable.
*
* @param index the index of the collective variable for which to get the name
* @return the variable name
*/
const std::string& getCollectiveVariableName(int index) const;
/**
* Get a writable reference to the Force object that computes a collective variable.
*
* @param index the index of the collective variable to get
* @return the Force object
*/
Force& getCollectiveVariable(int index);
/**
* Get a const reference to the Force object that computes a collective variable.
*
* @param index the index of the collective variable to get
* @return the Force object
*/
const Force& getCollectiveVariable(int index) const;
/**
* Add a new global parameter that the interaction may depend on.
*
* @param name the name of the parameter
* @param defaultValue the default value of the parameter
* @return the index of the parameter that was added
*/
int addGlobalParameter(const std::string& name, double defaultValue);
/**
* 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);
/**
* Get the default value of a global parameter.
*
* @param index the index of the parameter for which to get the default value
* @return the parameter default value
*/
double getGlobalParameterDefaultValue(int index) const;
/**
* Set the default value of a global parameter.
*
* @param index the index of the parameter for which to set the default value
* @param defaultValue the default value of the parameter
*/
void setGlobalParameterDefaultValue(int index, double defaultValue);
/**
* Request that this Force compute the derivative of its energy with respect to a global parameter.
* The parameter must have already been added with addGlobalParameter().
*
* @param name the name of the parameter
*/
void addEnergyParameterDerivative(const std::string& name);
/**
* Get the name of a global parameter with respect to which this Force should compute the
* derivative of the energy.
*
* @param index the index of the parameter derivative, between 0 and getNumEnergyParameterDerivatives()
* @return the parameter name
*/
const std::string& getEnergyParameterDerivativeName(int index) const;
/**
* Add a tabulated function that may appear in the energy expression.
*
* @param name the name of the function as it appears in expressions
* @param function a TabulatedFunction object defining the function. The TabulatedFunction
* should have been created on the heap with the "new" operator. The
* Force takes over ownership of it, and deletes it when the Force itself is deleted.
* @return the index of the function that was added
*/
int addTabulatedFunction(const std::string& name, TabulatedFunction* function);
/**
* Get a const reference to a tabulated function that may appear in the energy expression.
*
* @param index the index of the function to get
* @return the TabulatedFunction object defining the function
*/
const TabulatedFunction& getTabulatedFunction(int index) const;
/**
* Get a reference to a tabulated function that may appear in the energy expression.
*
* @param index the index of the function to get
* @return the TabulatedFunction object defining the function
*/
TabulatedFunction& getTabulatedFunction(int index);
/**
* Get the name of a tabulated function that may appear in the energy expression.
*
* @param index the index of the function to get
* @return the name of the function as it appears in expressions
*/
const std::string& getTabulatedFunctionName(int index) const;
/**
* Get the current values of the collective variables in a Context.
*
* @param context the Context for which to get the values
* @param[out] values the values of the collective variables are computed and
* stored into this
*/
void getCollectiveVariableValues(Context& context, std::vector<double>& values);
/**
* Returns whether or not this force makes use of periodic boundary
* conditions.
*
* @returns true if force uses PBC and false otherwise
*/
bool usesPeriodicBoundaryConditions() const;
protected:
ForceImpl* createImpl() const;
private:
class GlobalParameterInfo;
class VariableInfo;
class FunctionInfo;
std::string energyExpression;
std::vector<GlobalParameterInfo> globalParameters;
std::vector<VariableInfo> variables;
std::vector<FunctionInfo> functions;
std::vector<int> energyParameterDerivatives;
};
/**
* This is an internal class used to record information about a global parameter.
* @private
*/
class CustomCVForce::GlobalParameterInfo {
public:
std::string name;
double defaultValue;
GlobalParameterInfo() {
}
GlobalParameterInfo(const std::string& name, double defaultValue) : name(name), defaultValue(defaultValue) {
}
};
/**
* This is an internal class used to record information about a tabulated function.
* @private
*/
class CustomCVForce::VariableInfo {
public:
std::string name;
Force* variable;
VariableInfo() {
}
VariableInfo(const std::string& name, Force* variable) : name(name), variable(variable) {
}
};
/**
* This is an internal class used to record information about a tabulated function.
* @private
*/
class CustomCVForce::FunctionInfo {
public:
std::string name;
TabulatedFunction* function;
FunctionInfo() {
}
FunctionInfo(const std::string& name, TabulatedFunction* function) : name(name), function(function) {
}
};
} // namespace OpenMM
#endif /*OPENMM_CUSTOMCVFORCE_H_*/
#ifndef OPENMM_CUSTOMCVFORCEIMPL_H_
#define OPENMM_CUSTOMCVFORCEIMPL_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2017 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "ForceImpl.h"
#include "openmm/Context.h"
#include "openmm/CustomCVForce.h"
#include "openmm/Kernel.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include <map>
#include <string>
#include <vector>
namespace OpenMM {
/**
* This is the internal implementation of CustomCVForce.
*/
class OPENMM_EXPORT CustomCVForceImpl : public ForceImpl {
public:
CustomCVForceImpl(const CustomCVForce& owner);
~CustomCVForceImpl();
void initialize(ContextImpl& context);
const CustomCVForce& getOwner() const {
return owner;
}
void updateContextState(ContextImpl& context) {
// This force field doesn't update the state directly.
}
double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups);
std::map<std::string, double> getDefaultParameters();
std::vector<std::string> getKernelNames();
void getCollectiveVariableValues(ContextImpl& context, std::vector<double>& values);
private:
const CustomCVForce& owner;
Kernel kernel;
System innerSystem;
VerletIntegrator innerIntegrator;
Context* innerContext;
};
} // namespace OpenMM
#endif /*OPENMM_CUSTOMCVFORCEIMPL_H_*/
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. * * USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "openmm/Context.h"
#include "openmm/internal/windowsExport.h" #include "openmm/internal/windowsExport.h"
#include <map> #include <map>
#include <string> #include <string>
...@@ -104,6 +105,13 @@ public: ...@@ -104,6 +105,13 @@ public:
virtual std::vector<std::pair<int, int> > getBondedParticles() const { virtual std::vector<std::pair<int, int> > getBondedParticles() const {
return std::vector<std::pair<int, int> >(0); return std::vector<std::pair<int, int> >(0);
} }
protected:
/**
* Get the ContextImpl corresponding to a Context.
*/
ContextImpl& getContextImpl(Context& context) {
return context.getImpl();
}
}; };
} // namespace OpenMM } // namespace OpenMM
......
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2017 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/OpenMMException.h"
#include "openmm/CustomCVForce.h"
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/internal/CustomCVForceImpl.h"
#include <cmath>
#include <map>
#include <set>
#include <utility>
using namespace OpenMM;
using namespace std;
CustomCVForce::CustomCVForce(const string& energy) : energyExpression(energy) {
}
CustomCVForce::~CustomCVForce() {
for (auto variable : variables)
delete variable.variable;
for (auto function : functions)
delete function.function;
}
const string& CustomCVForce::getEnergyFunction() const {
return energyExpression;
}
void CustomCVForce::setEnergyFunction(const std::string& energy) {
energyExpression = energy;
}
int CustomCVForce::addCollectiveVariable(const std::string& name, Force* variable) {
if (variables.size() >= 32)
throw OpenMMException("CustomCVForce cannot have more than 32 collective variables");
variables.push_back(VariableInfo(name, variable));
return variables.size()-1;
}
const string& CustomCVForce::getCollectiveVariableName(int index) const {
ASSERT_VALID_INDEX(index, variables);
return variables[index].name;
}
Force& CustomCVForce::getCollectiveVariable(int index) {
ASSERT_VALID_INDEX(index, variables);
return *variables[index].variable;
}
const Force& CustomCVForce::getCollectiveVariable(int index) const {
ASSERT_VALID_INDEX(index, variables);
return *variables[index].variable;
}
int CustomCVForce::addGlobalParameter(const string& name, double defaultValue) {
globalParameters.push_back(GlobalParameterInfo(name, defaultValue));
return globalParameters.size()-1;
}
const string& CustomCVForce::getGlobalParameterName(int index) const {
ASSERT_VALID_INDEX(index, globalParameters);
return globalParameters[index].name;
}
void CustomCVForce::setGlobalParameterName(int index, const string& name) {
ASSERT_VALID_INDEX(index, globalParameters);
globalParameters[index].name = name;
}
double CustomCVForce::getGlobalParameterDefaultValue(int index) const {
ASSERT_VALID_INDEX(index, globalParameters);
return globalParameters[index].defaultValue;
}
void CustomCVForce::setGlobalParameterDefaultValue(int index, double defaultValue) {
ASSERT_VALID_INDEX(index, globalParameters);
globalParameters[index].defaultValue = defaultValue;
}
void CustomCVForce::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& CustomCVForce::getEnergyParameterDerivativeName(int index) const {
ASSERT_VALID_INDEX(index, energyParameterDerivatives);
return globalParameters[energyParameterDerivatives[index]].name;
}
int CustomCVForce::addTabulatedFunction(const std::string& name, TabulatedFunction* function) {
functions.push_back(FunctionInfo(name, function));
return functions.size()-1;
}
const TabulatedFunction& CustomCVForce::getTabulatedFunction(int index) const {
ASSERT_VALID_INDEX(index, functions);
return *functions[index].function;
}
TabulatedFunction& CustomCVForce::getTabulatedFunction(int index) {
ASSERT_VALID_INDEX(index, functions);
return *functions[index].function;
}
const string& CustomCVForce::getTabulatedFunctionName(int index) const {
ASSERT_VALID_INDEX(index, functions);
return functions[index].name;
}
void CustomCVForce::getCollectiveVariableValues(Context& context, vector<double>& values) {
dynamic_cast<CustomCVForceImpl&>(getImplInContext(context)).getCollectiveVariableValues(getContextImpl(context), values);
}
ForceImpl* CustomCVForce::createImpl() const {
return new CustomCVForceImpl(*this);
}
bool CustomCVForce::usesPeriodicBoundaryConditions() const {
for (auto& variable : variables)
if (variable.variable->usesPeriodicBoundaryConditions())
return true;
return false;
}
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2017 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/NonbondedForce.h"
#include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/CustomCVForceImpl.h"
#include "openmm/kernels.h"
#include "openmm/serialization/XmlSerializer.h"
#include <map>
using namespace OpenMM;
using namespace std;
CustomCVForceImpl::CustomCVForceImpl(const CustomCVForce& owner) : owner(owner), innerIntegrator(1.0),
innerContext(NULL) {
}
CustomCVForceImpl::~CustomCVForceImpl() {
if (innerContext != NULL)
delete innerContext;
}
void CustomCVForceImpl::initialize(ContextImpl& context) {
// Construct the inner system used to evaluate collective variables.
const System& system = context.getSystem();
for (int i = 0; i < system.getNumParticles(); i++)
innerSystem.addParticle(system.getParticleMass(i));
for (int i = 0; i < owner.getNumCollectiveVariables(); i++) {
Force* variable = XmlSerializer::clone<Force>(owner.getCollectiveVariable(i));
variable->setForceGroup(i);
NonbondedForce* nonbonded = dynamic_cast<NonbondedForce*>(variable);
if (nonbonded != NULL)
nonbonded->setReciprocalSpaceForceGroup(-1);
innerSystem.addForce(variable);
}
// Create the inner context.
Platform& platform = context.getPlatform();
map<string, string> properties;
for (auto& name : platform.getPropertyNames())
properties[name] = platform.getPropertyValue(context.getOwner(), name);
innerContext = new Context(innerSystem, innerIntegrator, platform, properties);
// Create the kernel.
kernel = context.getPlatform().createKernel(CalcCustomCVForceKernel::Name(), context);
kernel.getAs<CalcCustomCVForceKernel>().initialize(context.getSystem(), owner);
}
double CustomCVForceImpl::calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) {
if ((groups&(1<<owner.getForceGroup())) != 0)
return kernel.getAs<CalcCustomCVForceKernel>().execute(context, getContextImpl(*innerContext), includeForces, includeEnergy);
return 0.0;
}
vector<string> CustomCVForceImpl::getKernelNames() {
vector<string> names;
names.push_back(CalcCustomCVForceKernel::Name());
return names;
}
map<string, double> CustomCVForceImpl::getDefaultParameters() {
map<string, double> parameters;
for (int i = 0; i < owner.getNumGlobalParameters(); i++)
parameters[owner.getGlobalParameterName(i)] = owner.getGlobalParameterDefaultValue(i);
return parameters;
}
void CustomCVForceImpl::getCollectiveVariableValues(ContextImpl& context, vector<double>& values) {
kernel.getAs<CalcCustomCVForceKernel>().copyState(context, getContextImpl(*innerContext));
values.clear();
for (int i = 0; i < innerSystem.getNumForces(); i++) {
double value = innerContext->getState(State::Energy).getPotentialEnergy();
values.push_back(value);
}
}
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