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

Merge branch 'master' into nucleic

parents 0a751b5b 6a985cfd
#if defined(__ANDROID__)
#include "neon_mathfun.h"
#else
#if !defined(__PNACL__)
#define USE_SSE2
#include "sse_mathfun.h"
#endif
#endif
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "openmm/CMMotionRemover.h" #include "openmm/CMMotionRemover.h"
#include "openmm/CustomAngleForce.h" #include "openmm/CustomAngleForce.h"
#include "openmm/CustomBondForce.h" #include "openmm/CustomBondForce.h"
#include "openmm/CustomCentroidBondForce.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"
...@@ -580,6 +581,15 @@ public: ...@@ -580,6 +581,15 @@ public:
* @param force the NonbondedForce to copy the parameters from * @param force the NonbondedForce to copy the parameters from
*/ */
virtual void copyParametersToContext(ContextImpl& context, const NonbondedForce& force) = 0; virtual void copyParametersToContext(ContextImpl& context, const NonbondedForce& force) = 0;
/**
* Get the parameters being used for PME.
*
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
*/
virtual void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const = 0;
}; };
/** /**
...@@ -801,6 +811,41 @@ public: ...@@ -801,6 +811,41 @@ public:
virtual void copyParametersToContext(ContextImpl& context, const CustomHbondForce& force) = 0; virtual void copyParametersToContext(ContextImpl& context, const CustomHbondForce& force) = 0;
}; };
/**
* This kernel is invoked by CustomCentroidBondForce to calculate the forces acting on the system and the energy of the system.
*/
class CalcCustomCentroidBondForceKernel : public KernelImpl {
public:
static std::string Name() {
return "CalcCustomCentroidBondForce";
}
CalcCustomCentroidBondForceKernel(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 CustomCentroidBondForce this kernel will be used for
*/
virtual void initialize(const System& system, const CustomCentroidBondForce& force) = 0;
/**
* Execute the kernel to calculate the forces and/or energy.
*
* @param context the context in which to execute this kernel
* @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, bool includeForces, bool includeEnergy) = 0;
/**
* Copy changed parameters over to a context.
*
* @param context the context to copy parameters to
* @param force the CustomCentroidBondForce to copy the parameters from
*/
virtual void copyParametersToContext(ContextImpl& context, const CustomCentroidBondForce& force) = 0;
};
/** /**
* This kernel is invoked by CustomCompoundBondForce to calculate the forces acting on the system and the energy of the system. * This kernel is invoked by CustomCompoundBondForce to calculate the forces acting on the system and the energy of the system.
*/ */
...@@ -1245,6 +1290,15 @@ public: ...@@ -1245,6 +1290,15 @@ public:
* @return the potential energy due to the PME reciprocal space interactions * @return the potential energy due to the PME reciprocal space interactions
*/ */
virtual double finishComputation(IO& io) = 0; virtual double finishComputation(IO& io) = 0;
/**
* Get the parameters being used for PME.
*
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
*/
virtual void getPMEParameters(double& alpha, int& nx, int& ny, int& nz) const = 0;
}; };
/** /**
......
...@@ -38,6 +38,8 @@ Kernel::Kernel() : impl(0) { ...@@ -38,6 +38,8 @@ Kernel::Kernel() : impl(0) {
} }
Kernel::Kernel(KernelImpl* impl) : impl(impl) { Kernel::Kernel(KernelImpl* impl) : impl(impl) {
if (impl)
impl->referenceCount++;
} }
Kernel::Kernel(const Kernel& copy) : impl(copy.impl) { Kernel::Kernel(const Kernel& copy) : impl(copy.impl) {
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
using namespace OpenMM; using namespace OpenMM;
using namespace std; using namespace std;
KernelImpl::KernelImpl(string name, const Platform& platform) : name(name), platform(&platform), referenceCount(1) { KernelImpl::KernelImpl(string name, const Platform& platform) : name(name), platform(&platform), referenceCount(0) {
} }
std::string KernelImpl::getName() const { std::string KernelImpl::getName() const {
......
...@@ -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 Stanford University and the Authors. * * Portions copyright (c) 2009-2015 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "openmm/CMAPTorsionForce.h" #include "openmm/CMAPTorsionForce.h"
#include "openmm/CMMotionRemover.h" #include "openmm/CMMotionRemover.h"
#include "openmm/CustomBondForce.h" #include "openmm/CustomBondForce.h"
#include "openmm/CustomCentroidBondForce.h"
#include "openmm/CustomCompoundBondForce.h" #include "openmm/CustomCompoundBondForce.h"
#include "openmm/CustomAngleForce.h" #include "openmm/CustomAngleForce.h"
#include "openmm/CustomTorsionForce.h" #include "openmm/CustomTorsionForce.h"
......
...@@ -261,6 +261,7 @@ private: ...@@ -261,6 +261,7 @@ private:
friend class Force; friend class Force;
friend class Platform; friend class Platform;
ContextImpl& getImpl(); ContextImpl& getImpl();
const ContextImpl& getImpl() const;
ContextImpl* impl; ContextImpl* impl;
std::map<std::string, std::string> properties; std::map<std::string, std::string> properties;
}; };
......
...@@ -171,7 +171,7 @@ public: ...@@ -171,7 +171,7 @@ public:
* @param parameters the list of parameters for the new angle * @param parameters the list of parameters for the new angle
* @return the index of the angle that was added * @return the index of the angle that was added
*/ */
int addAngle(int particle1, int particle2, int particle3, const std::vector<double>& parameters); int addAngle(int particle1, int particle2, int particle3, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Get the force field parameters for an angle term. * Get the force field parameters for an angle term.
* *
...@@ -191,7 +191,7 @@ public: ...@@ -191,7 +191,7 @@ public:
* @param particle3 the index of the third particle connected by the angle * @param particle3 the index of the third particle connected by the angle
* @param parameters the list of parameters for the angle * @param parameters the list of parameters for the angle
*/ */
void setAngleParameters(int index, int particle1, int particle2, int particle3, const std::vector<double>& parameters); void setAngleParameters(int index, int particle1, int particle2, int particle3, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Update the per-angle parameters in a Context to match those stored in this Force object. This method provides * Update the per-angle parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it. * an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
......
...@@ -170,7 +170,7 @@ public: ...@@ -170,7 +170,7 @@ public:
* @param parameters the list of parameters for the new bond * @param parameters the list of parameters for the new bond
* @return the index of the bond that was added * @return the index of the bond that was added
*/ */
int addBond(int particle1, int particle2, const std::vector<double>& parameters); int addBond(int particle1, int particle2, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Get the force field parameters for a bond term. * Get the force field parameters for a bond term.
* *
...@@ -188,7 +188,7 @@ public: ...@@ -188,7 +188,7 @@ public:
* @param particle2 the index of the second particle connected by the bond * @param particle2 the index of the second particle connected by the bond
* @param parameters the list of parameters for the bond * @param parameters the list of parameters for the bond
*/ */
void setBondParameters(int index, int particle1, int particle2, const std::vector<double>& parameters); void setBondParameters(int index, int particle1, int particle2, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Update the per-bond parameters in a Context to match those stored in this Force object. This method provides * Update the per-bond parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it. * an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
......
#ifndef OPENMM_CUSTOMCENTROIDBONDFORCE_H_
#define OPENMM_CUSTOMCENTROIDBONDFORCE_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-2015 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 "Vec3.h"
#include <vector>
#include "internal/windowsExport.h"
namespace OpenMM {
/**
* This class is similar to CustomCompoundBondForce, but instead of applying forces between individual particles,
* it applies them between the centers of groups of particles. This is useful for a variety of purposes, such as
* restraints to keep two molecules from moving too far apart.
*
* When using this class, you define groups of particles, and the center of each group is calculated as a weighted
* average of the particle positions. By default, the particle masses are used as weights, so the center position
* is the center of mass. You can optionally specify different weights to use. You then add bonds just as with
* CustomCompoundBondForce, but instead of specifying the particles that make up a bond, you specify the groups.
*
* When creating a CustomCentroidBondForce, you specify the number of groups involved in a bond, and an expression
* for the energy of each bond. It may depend on the center positions of individual groups, the distances between
* the centers of pairs of groups, the angles formed by sets of three groups, and the dihedral angles formed by
* sets of four groups.
*
* We refer to the groups in a bond as g1, g2, g3, etc. For each bond, CustomCentroidBondForce evaluates a
* user supplied algebraic expression to determine the interaction energy. The expression may depend on the
* following variables and functions:
*
* <ul>
* <li>x1, y1, z1, x2, y2, z2, etc.: The x, y, and z coordinates of the centers of the groups. For example, x1
* is the x coordinate of the center of group g1, and y3 is the y coordinate of the center of group g3.</li>
* <li>distance(g1, g2): the distance between the centers of groups g1 and g2 (where "g1" and "g2" may be replaced
* by the names of whichever groups you want to calculate the distance between).</li>
* <li>angle(g1, g2, g3): the angle formed by the centers of the three specified groups.</li>
* <li>dihedral(g1, g2, g3, g4): the dihedral angle formed by the centers of the four specified groups.</li>
* </ul>
*
* The expression also may involve tabulated functions, and may depend on arbitrary global and per-bond parameters.
*
* To use this class, create a CustomCentroidBondForce object, passing an algebraic expression to the constructor
* that defines the interaction energy of each bond. Then call addPerBondParameter() to define per-bond
* parameters and addGlobalParameter() to define global parameters. The values of per-bond parameters are specified
* as part of the system definition, while values of global parameters may be modified during a simulation by calling
* Context::setParameter().
*
* Next call addGroup() to define the particle groups. Each group is specified by the particles it contains, and
* the weights to use when computing the center position.
*
* Then call addBond() to define bonds and specify their parameter values. After a bond has been added, you can
* modify its parameters by calling setBondParameters(). This will have no effect on Contexts that already exist unless
* you call updateParametersInContext().
*
* As an example, the following code creates a CustomCentroidBondForce that implements a harmonic force between the
* centers of mass of two groups of particles.
*
* <tt><pre>
* CustomCentroidBondForce* force = new CustomCentroidBondForce(2, "0.5*k*distance(g1,g2)^2");
* force->addPerBondParameter("k");
* force->addGroup(particles1);
* force->addGroup(particles2);
* vector<int> bondGroups;
* bondGroups.push_back(0);
* bondGroups.push_back(1);
* vector<double> bondParameters;
* bondParameters.push_back(k);
* force->addBond(bondGroups, bondParameters);
* </pre></tt>
*
* 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 CustomCentroidBondForce : public Force {
public:
/**
* Create a CustomCentroidBondForce.
*
* @param numGroups the number of groups used to define each bond
* @param energy an algebraic expression giving the interaction energy of each bond as a function
* of particle positions, inter-particle distances, angles, and dihedrals, and any global
* and per-bond parameters
*/
explicit CustomCentroidBondForce(int numGroups, const std::string& energy);
~CustomCentroidBondForce();
/**
* Get the number of groups used to define each bond.
*/
int getNumGroupsPerBond() const {
return groupsPerBond;
}
/**
* Get the number of particle groups that have been defined.
*/
int getNumGroups() const {
return groups.size();
}
/**
* Get the number of bonds for which force field parameters have been defined.
*/
int getNumBonds() const {
return bonds.size();
}
/**
* Get the number of per-bond parameters that the interaction depends on.
*/
int getNumPerBondParameters() const {
return bondParameters.size();
}
/**
* Get the number of global parameters that the interaction depends on.
*/
int getNumGlobalParameters() const {
return globalParameters.size();
}
/**
* Get the number of tabulated functions that have been defined.
*/
int getNumTabulatedFunctions() const {
return functions.size();
}
/**
* Get the number of tabulated functions that have been defined.
*
* @deprecated This method exists only for backward compatibility. Use getNumTabulatedFunctions() instead.
*/
int getNumFunctions() const {
return functions.size();
}
/**
* Get the algebraic expression that gives the interaction energy of each bond
*/
const std::string& getEnergyFunction() const;
/**
* Set the algebraic expression that gives the interaction energy of each bond
*/
void setEnergyFunction(const std::string& energy);
/**
* Add a new per-bond parameter that the interaction may depend on.
*
* @param name the name of the parameter
* @return the index of the parameter that was added
*/
int addPerBondParameter(const std::string& name);
/**
* Get the name of a per-bond parameter.
*
* @param index the index of the parameter for which to get the name
* @return the parameter name
*/
const std::string& getPerBondParameterName(int index) const;
/**
* Set the name of a per-bond parameter.
*
* @param index the index of the parameter for which to set the name
* @param name the name of the parameter
*/
void setPerBondParameterName(int index, const std::string& name);
/**
* 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 name the default value of the parameter
*/
void setGlobalParameterDefaultValue(int index, double defaultValue);
/**
* Add a particle group.
*
* @param particles the indices of the particles to include in the group
* @param weights the weight to use for each particle when computing the center position.
* If this is omitted, then particle masses will be used as weights.
* @return the index of the group that was added
*/
int addGroup(const std::vector<int>& particles, const std::vector<double>& weights=std::vector<double>());
/**
* Get the properties of a group.
*
* @param index the index of the group to get
* @param particles the indices of the particles in the group
* @param weights the weight used for each particle when computing the center position.
* If no weights were specified, this vector will be empty indicating that particle
* masses should be used as weights.
*/
void getGroupParameters(int index, std::vector<int>& particles, std::vector<double>& weights) const;
/**
* Set the properties of a group.
*
* @param index the index of the group to set
* @param particles the indices of the particles in the group
* @param weights the weight to use for each particle when computing the center position.
* If this is omitted, then particle masses will be used as weights.
*/
void setGroupParameters(int index, const std::vector<int>& particles, const std::vector<double>& weights=std::vector<double>());
/**
* Add a bond to the force
*
* @param groups the indices of the groups the bond depends on
* @param parameters the list of per-bond parameter values for the new bond
* @return the index of the bond that was added
*/
int addBond(const std::vector<int>& groups, const std::vector<double>& parameters=std::vector<double>());
/**
* Get the properties of a bond.
*
* @param index the index of the bond to get
* @param groups the indices of the groups in the bond
* @param parameters the list of per-bond parameter values for the bond
*/
void getBondParameters(int index, std::vector<int>& groups, std::vector<double>& parameters) const;
/**
* Set the properties of a bond.
*
* @param index the index of the bond to set
* @param groups the indices of the groups in the bond
* @param parameters the list of per-bond parameter values for the bond
*/
void setBondParameters(int index, const std::vector<int>& groups, const std::vector<double>& parameters=std::vector<double>());
/**
* 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;
/**
* Update the per-bond parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
* Simply call setBondParameters() to modify this object's parameters, then call updateParametersInContext()
* to copy them over to the Context.
*
* This method has several limitations. The only information it updates is the values of per-bond parameters.
* All other aspects of the Force (such as the energy function) are unaffected and can only be changed by reinitializing
* the Context. Neither the definitions of groups nor the set of groups involved in a bond can be changed, nor can new
* bonds be added.
*/
void updateParametersInContext(Context& context);
/**
* Returns whether or not this force makes use of periodic boundary
* conditions.
*
* @returns false
*/
bool usesPeriodicBoundaryConditions() const {
return false;
}
protected:
ForceImpl* createImpl() const;
private:
class GroupInfo;
class BondInfo;
class BondParameterInfo;
class GlobalParameterInfo;
class FunctionInfo;
int groupsPerBond;
std::string energyExpression;
std::vector<BondParameterInfo> bondParameters;
std::vector<GlobalParameterInfo> globalParameters;
std::vector<GroupInfo> groups;
std::vector<BondInfo> bonds;
std::vector<FunctionInfo> functions;
};
/**
* This is an internal class used to record information about a group.
* @private
*/
class CustomCentroidBondForce::GroupInfo {
public:
std::vector<int> particles;
std::vector<double> weights;
GroupInfo() {
}
GroupInfo(const std::vector<int>& particles, const std::vector<double>& weights) :
particles(particles), weights(weights) {
}
};
/**
* This is an internal class used to record information about a bond.
* @private
*/
class CustomCentroidBondForce::BondInfo {
public:
std::vector<int> groups;
std::vector<double> parameters;
BondInfo() {
}
BondInfo(const std::vector<int>& groups, const std::vector<double>& parameters) :
groups(groups), parameters(parameters) {
}
};
/**
* This is an internal class used to record information about a per-bond parameter.
* @private
*/
class CustomCentroidBondForce::BondParameterInfo {
public:
std::string name;
BondParameterInfo() {
}
BondParameterInfo(const std::string& name) : name(name) {
}
};
/**
* This is an internal class used to record information about a global parameter.
* @private
*/
class CustomCentroidBondForce::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 CustomCentroidBondForce::FunctionInfo {
public:
std::string name;
TabulatedFunction* function;
FunctionInfo() {
}
FunctionInfo(const std::string& name, TabulatedFunction* function) : name(name), function(function) {
}
};
} // namespace OpenMM
#endif /*OPENMM_CUSTOMCENTROIDBONDFORCE_H_*/
...@@ -219,7 +219,7 @@ public: ...@@ -219,7 +219,7 @@ public:
* @param parameters the list of per-bond parameter values for the new bond * @param parameters the list of per-bond parameter values for the new bond
* @return the index of the bond that was added * @return the index of the bond that was added
*/ */
int addBond(const std::vector<int>& particles, const std::vector<double>& parameters); int addBond(const std::vector<int>& particles, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Get the properties of a bond. * Get the properties of a bond.
* *
...@@ -231,11 +231,11 @@ public: ...@@ -231,11 +231,11 @@ public:
/** /**
* Set the properties of a bond. * Set the properties of a bond.
* *
* @param index the index of the bond group to set * @param index the index of the bond to set
* @param particles the indices of the particles in the bond * @param particles the indices of the particles in the bond
* @param parameters the list of per-bond parameter values for the bond * @param parameters the list of per-bond parameter values for the bond
*/ */
void setBondParameters(int index, const std::vector<int>& particles, const std::vector<double>& parameters); void setBondParameters(int index, const std::vector<int>& particles, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Add a tabulated function that may appear in the energy expression. * Add a tabulated function that may appear in the energy expression.
* *
...@@ -323,7 +323,7 @@ private: ...@@ -323,7 +323,7 @@ private:
}; };
/** /**
* This is an internal class used to record information about a bond or acceptor. * This is an internal class used to record information about a bond.
* @private * @private
*/ */
class CustomCompoundBondForce::BondInfo { class CustomCompoundBondForce::BondInfo {
...@@ -338,7 +338,7 @@ public: ...@@ -338,7 +338,7 @@ public:
}; };
/** /**
* This is an internal class used to record information about a per-bond or per-acceptor parameter. * This is an internal class used to record information about a per-bond parameter.
* @private * @private
*/ */
class CustomCompoundBondForce::BondParameterInfo { class CustomCompoundBondForce::BondParameterInfo {
......
...@@ -67,6 +67,14 @@ namespace OpenMM { ...@@ -67,6 +67,14 @@ namespace OpenMM {
* force->addPerParticleParameter("z0"); * force->addPerParticleParameter("z0");
* </pre></tt> * </pre></tt>
* *
* Special care is needed in systems that use periodic boundary conditions. In that case, each particle really represents
* an infinite set of particles repeating through space. The variables x, y, and z contain the coordinates of one of those
* periodic copies, but there is no guarantee about which. It might even change from one time step to the next. You can handle
* this situation by using the function periodicdistance(x1, y1, z1, x2, y2, z2), which returns the minimum distance between
* periodic copies of the points (x1, y1, z1) and (x2, y2, z2). For example, the force given above would be rewritten as
*
* <tt>CustomExternalForce* force = new CustomExternalForce("k*periodicdistance(x, y, z, x0, y0, z0)^2");</tt>
*
* Expressions may involve the operators + (add), - (subtract), * (multiply), / (divide), and ^ (power), and the following * 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 * 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. * 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.
...@@ -172,7 +180,7 @@ public: ...@@ -172,7 +180,7 @@ public:
* @param parameters the list of parameters for the new force term * @param parameters the list of parameters for the new force term
* @return the index of the particle term that was added * @return the index of the particle term that was added
*/ */
int addParticle(int particle, const std::vector<double>& parameters); int addParticle(int particle, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Get the force field parameters for a force field term. * Get the force field parameters for a force field term.
* *
...@@ -188,7 +196,7 @@ public: ...@@ -188,7 +196,7 @@ public:
* @param particle the index of the particle this term is applied to * @param particle the index of the particle this term is applied to
* @param parameters the list of parameters for the force field term * @param parameters the list of parameters for the force field term
*/ */
void setParticleParameters(int index, int particle, const std::vector<double>& parameters); void setParticleParameters(int index, int particle, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Update the per-particle parameters in a Context to match those stored in this Force object. This method provides * Update the per-particle parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it. * an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
...@@ -206,9 +214,7 @@ public: ...@@ -206,9 +214,7 @@ public:
* *
* @returns false * @returns false
*/ */
bool usesPeriodicBoundaryConditions() const { bool usesPeriodicBoundaryConditions() const;
return false;
}
protected: protected:
ForceImpl* createImpl() const; ForceImpl* createImpl() const;
private: private:
......
...@@ -319,7 +319,7 @@ public: ...@@ -319,7 +319,7 @@ public:
* @param parameters the list of parameters for the new particle * @param parameters the list of parameters for the new particle
* @return the index of the particle that was added * @return the index of the particle that was added
*/ */
int addParticle(const std::vector<double>& parameters); int addParticle(const std::vector<double>& parameters=std::vector<double>());
/** /**
* Get the nonbonded force parameters for a particle. * Get the nonbonded force parameters for a particle.
* *
......
...@@ -296,7 +296,7 @@ public: ...@@ -296,7 +296,7 @@ public:
* @param parameters the list of per-donor parameter values for the new donor * @param parameters the list of per-donor parameter values for the new donor
* @return the index of the donor that was added * @return the index of the donor that was added
*/ */
int addDonor(int d1, int d2, int d3, const std::vector<double>& parameters); int addDonor(int d1, int d2, int d3, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Get the properties of a donor group. * Get the properties of a donor group.
* *
...@@ -320,7 +320,7 @@ public: ...@@ -320,7 +320,7 @@ public:
* less than three particles, this must be -1. * less than three particles, this must be -1.
* @param parameters the list of per-donor parameter values for the donor * @param parameters the list of per-donor parameter values for the donor
*/ */
void setDonorParameters(int index, int d1, int d2, int d3, const std::vector<double>& parameters); void setDonorParameters(int index, int d1, int d2, int d3, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Add an acceptor group to the force * Add an acceptor group to the force
* *
...@@ -332,7 +332,7 @@ public: ...@@ -332,7 +332,7 @@ public:
* @param parameters the list of per-acceptor parameter values for the new acceptor * @param parameters the list of per-acceptor parameter values for the new acceptor
* @return the index of the acceptor that was added * @return the index of the acceptor that was added
*/ */
int addAcceptor(int a1, int a2, int a3, const std::vector<double>& parameters); int addAcceptor(int a1, int a2, int a3, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Get the properties of an acceptor group. * Get the properties of an acceptor group.
* *
...@@ -356,7 +356,7 @@ public: ...@@ -356,7 +356,7 @@ public:
* less than three particles, this must be -1. * less than three particles, this must be -1.
* @param parameters the list of per-acceptor parameter values for the acceptor * @param parameters the list of per-acceptor parameter values for the acceptor
*/ */
void setAcceptorParameters(int index, int a1, int a2, int a3, const std::vector<double>& parameters); void setAcceptorParameters(int index, int a1, int a2, int a3, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Add a donor-acceptor pair to the list of interactions that should be excluded. * Add a donor-acceptor pair to the list of interactions that should be excluded.
* *
......
...@@ -348,7 +348,7 @@ public: ...@@ -348,7 +348,7 @@ public:
* @param type the type of the new particle * @param type the type of the new particle
* @return the index of the particle that was added * @return the index of the particle that was added
*/ */
int addParticle(const std::vector<double>& parameters, int type=0); int addParticle(const std::vector<double>& parameters=std::vector<double>(), int type=0);
/** /**
* Get the nonbonded force parameters for a particle. * Get the nonbonded force parameters for a particle.
* *
......
...@@ -328,7 +328,7 @@ public: ...@@ -328,7 +328,7 @@ public:
* @param parameters the list of parameters for the new particle * @param parameters the list of parameters for the new particle
* @return the index of the particle that was added * @return the index of the particle that was added
*/ */
int addParticle(const std::vector<double>& parameters); int addParticle(const std::vector<double>& parameters=std::vector<double>());
/** /**
* Get the nonbonded force parameters for a particle. * Get the nonbonded force parameters for a particle.
* *
......
...@@ -172,7 +172,7 @@ public: ...@@ -172,7 +172,7 @@ public:
* @param parameters the list of parameters for the new torsion * @param parameters the list of parameters for the new torsion
* @return the index of the torsion that was added * @return the index of the torsion that was added
*/ */
int addTorsion(int particle1, int particle2, int particle3, int particle4, const std::vector<double>& parameters); int addTorsion(int particle1, int particle2, int particle3, int particle4, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Get the force field parameters for a torsion term. * Get the force field parameters for a torsion term.
* *
...@@ -194,7 +194,7 @@ public: ...@@ -194,7 +194,7 @@ public:
* @param particle4 the index of the fourth particle connected by the torsion * @param particle4 the index of the fourth particle connected by the torsion
* @param parameters the list of parameters for the torsion * @param parameters the list of parameters for the torsion
*/ */
void setTorsionParameters(int index, int particle1, int particle2, int particle3, int particle4, const std::vector<double>& parameters); void setTorsionParameters(int index, int particle1, int particle2, int particle3, int particle4, const std::vector<double>& parameters=std::vector<double>());
/** /**
* Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides * Update the per-torsion parameters in a Context to match those stored in this Force object. This method provides
* an efficient method to update certain parameters in an existing Context without needing to reinitialize it. * an efficient method to update certain parameters in an existing Context without needing to reinitialize it.
......
...@@ -98,6 +98,10 @@ protected: ...@@ -98,6 +98,10 @@ protected:
* Get the ForceImpl corresponding to this Force in a Context. * Get the ForceImpl corresponding to this Force in a Context.
*/ */
ForceImpl& getImplInContext(Context& context); ForceImpl& getImplInContext(Context& context);
/**
* Get a const reference to the ForceImpl corresponding to this Force in a Context.
*/
const ForceImpl& getImplInContext(const Context& context) const;
/** /**
* Get the ContextImpl corresponding to a Context. * Get the ContextImpl corresponding to a Context.
*/ */
......
...@@ -217,6 +217,19 @@ public: ...@@ -217,6 +217,19 @@ public:
* @param nz the number of grid points along the Z axis * @param nz the number of grid points along the Z axis
*/ */
void setPMEParameters(double alpha, int nx, int ny, int nz); void setPMEParameters(double alpha, int nx, int ny, int nz);
/**
* Get the parameters being used for PME in a particular Context. Because some platforms have restrictions
* on the allowed grid sizes, the values that are actually used may be slightly different from those
* specified with setPMEParameters(), or the standard values calculated based on the Ewald error tolerance.
* See the manual for details.
*
* @param context the Context for which to get the parameters
* @param alpha the separation parameter
* @param nx the number of grid points along the X axis
* @param ny the number of grid points along the Y axis
* @param nz the number of grid points along the Z axis
*/
void getPMEParametersInContext(const Context& context, double& alpha, int& nx, int& ny, int& nz) const;
/** /**
* 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.
......
#ifndef OPENMM_CUSTOMCENTROIDBONDFORCEIMPL_H_
#define OPENMM_CUSTOMCENTROIDBONDFORCEIMPL_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-2015 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/CustomCentroidBondForce.h"
#include "openmm/Kernel.h"
#include "openmm/System.h"
#include "lepton/CustomFunction.h"
#include "lepton/ExpressionTreeNode.h"
#include "lepton/ParsedExpression.h"
#include <utility>
#include <map>
#include <set>
#include <string>
namespace OpenMM {
/**
* This is the internal implementation of CustomCentroidBondForce.
*/
class OPENMM_EXPORT CustomCentroidBondForceImpl : public ForceImpl {
public:
CustomCentroidBondForceImpl(const CustomCentroidBondForce& owner);
~CustomCentroidBondForceImpl();
void initialize(ContextImpl& context);
const CustomCentroidBondForce& 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();
std::vector<std::pair<int, int> > getBondedParticles() const;
void updateParametersInContext(ContextImpl& context);
/**
* This is a utility routine that parses the energy expression, identifies the angles and dihedrals
* in it, and replaces them with variables.
*
* @param force the CustomCentroidBondForce to process
* @param functions definitions of custom function that may appear in the expression
* @param distances on exit, this will contain an entry for each distance used in the expression. The key is the name
* of the corresponding variable, and the value is the list of particle indices.
* @param angles on exit, this will contain an entry for each angle used in the expression. The key is the name
* of the corresponding variable, and the value is the list of particle indices.
* @param dihedrals on exit, this will contain an entry for each dihedral used in the expression. The key is the name
* of the corresponding variable, and the value is the list of particle indices.
* @return a Parsed expression for the energy
*/
static Lepton::ParsedExpression prepareExpression(const CustomCentroidBondForce& force, const std::map<std::string, Lepton::CustomFunction*>& functions, std::map<std::string, std::vector<int> >& distances,
std::map<std::string, std::vector<int> >& angles, std::map<std::string, std::vector<int> >& dihedrals);
/**
* Compute the normalized weights to use for each particle in each group.
*
* @param force the CustomCentroidBondForce to process
* @param system the System it is part of
* @param weights on exit, weights[i][j] contains the normalized weight for particle j in group i.
*/
static void computeNormalizedWeights(const CustomCentroidBondForce& force, const System& system, std::vector<std::vector<double> >& weights);
private:
class FunctionPlaceholder;
static Lepton::ExpressionTreeNode replaceFunctions(const Lepton::ExpressionTreeNode& node, std::map<std::string, int> atoms,
std::map<std::string, std::vector<int> >& distances, std::map<std::string, std::vector<int> >& angles,
std::map<std::string, std::vector<int> >& dihedrals, std::set<std::string>& variables);
void addBondsBetweenGroups(int group1, int group2, std::vector<std::pair<int, int> >& bonds) const;
const CustomCentroidBondForce& owner;
Kernel kernel;
};
} // namespace OpenMM
#endif /*OPENMM_CUSTOMCENTROIDBONDFORCEIMPL_H_*/
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "lepton/ParsedExpression.h" #include "lepton/ParsedExpression.h"
#include <utility> #include <utility>
#include <map> #include <map>
#include <set>
#include <string> #include <string>
namespace OpenMM { namespace OpenMM {
...@@ -83,7 +84,7 @@ private: ...@@ -83,7 +84,7 @@ private:
class FunctionPlaceholder; class FunctionPlaceholder;
static Lepton::ExpressionTreeNode replaceFunctions(const Lepton::ExpressionTreeNode& node, std::map<std::string, int> atoms, static Lepton::ExpressionTreeNode replaceFunctions(const Lepton::ExpressionTreeNode& node, std::map<std::string, int> atoms,
std::map<std::string, std::vector<int> >& distances, std::map<std::string, std::vector<int> >& angles, std::map<std::string, std::vector<int> >& distances, std::map<std::string, std::vector<int> >& angles,
std::map<std::string, std::vector<int> >& dihedrals); std::map<std::string, std::vector<int> >& dihedrals, std::set<std::string>& variables);
const CustomCompoundBondForce& owner; const CustomCompoundBondForce& owner;
Kernel kernel; Kernel kernel;
}; };
......
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