Commit a381a3ab authored by peastman's avatar peastman
Browse files

Merge branch 'master' into gayberne

parents 5ecc8e00 1f7866ad
...@@ -69,8 +69,7 @@ matrix: ...@@ -69,8 +69,7 @@ matrix:
OPENCL=false OPENCL=false
CUDA=false CUDA=false
CMAKE_FLAGS=" CMAKE_FLAGS="
-DOPENMM_BUILD_OPENCL_TESTS=OFF -DOPENMM_BUILD_OPENCL_TESTS=OFF"
-DSWIG_EXECUTABLE=/usr/local/Cellar/swig/3.0.2/bin/swig"
addons: {apt: {packages: []}} addons: {apt: {packages: []}}
- sudo: false - sudo: false
...@@ -106,7 +105,7 @@ before_install: ...@@ -106,7 +105,7 @@ before_install:
- wget https://anaconda.org/omnia/ccache/3.2.4/download/${TRAVIS_OS_NAME}-64/ccache-3.2.4-0.tar.bz2 - wget https://anaconda.org/omnia/ccache/3.2.4/download/${TRAVIS_OS_NAME}-64/ccache-3.2.4-0.tar.bz2
- mkdir -p $HOME/ccache && tar xf ccache-3.2.4-0.tar.bz2 -C $HOME/ccache - mkdir -p $HOME/ccache && tar xf ccache-3.2.4-0.tar.bz2 -C $HOME/ccache
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
brew install doxygen swig fftw; brew install doxygen fftw;
sudo easy_install pytest; sudo easy_install pytest;
fi fi
- if [[ "$OPENCL" == "true" ]]; then - if [[ "$OPENCL" == "true" ]]; then
...@@ -132,6 +131,13 @@ before_install: ...@@ -132,6 +131,13 @@ before_install:
export PATH=$HOME/swig/bin:$PATH; export PATH=$HOME/swig/bin:$PATH;
export SWIG_LIB=$HOME/swig/share/swig/3.0.7; export SWIG_LIB=$HOME/swig/share/swig/3.0.7;
fi fi
- if [[ "$OPENCL" == "false" && "$CUDA" == "false" && "$TRAVIS_OS_NAME" == "osx" ]]; then
wget https://anaconda.org/omnia/swig/3.0.7/download/osx-64/swig-3.0.7-0.tar.bz2;
mkdir $HOME/swig;
tar -xjvf swig-3.0.7-0.tar.bz2 -C $HOME/swig;
export PATH=$HOME/swig/bin:$PATH;
export SWIG_LIB=$HOME/swig/share/swig/3.0.7;
fi
- if [[ "$CUDA" == "true" ]]; then - if [[ "$CUDA" == "true" ]]; then
wget "http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1404/x86_64/cuda-repo-ubuntu1404_${CUDA_VERSION}_amd64.deb"; wget "http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1404/x86_64/cuda-repo-ubuntu1404_${CUDA_VERSION}_amd64.deb";
......
...@@ -29,6 +29,7 @@ install: ...@@ -29,6 +29,7 @@ install:
# Download OpenCL Headers and build the ICD loader # Download OpenCL Headers and build the ICD loader
- ps: $opencl_registry = "https://www.khronos.org/registry/cl" - ps: $opencl_registry = "https://www.khronos.org/registry/cl"
- ps: $opencl_github = "KhronosGroup/OpenCL-Headers"
- ps: mkdir C:/opencl > $null - ps: mkdir C:/opencl > $null
- ps: cd C:/opencl - ps: cd C:/opencl
- ps: wget $opencl_registry/specs/opencl-icd-1.2.11.0.tgz -OutFile opencl-icd-1.2.11.0.tgz - ps: wget $opencl_registry/specs/opencl-icd-1.2.11.0.tgz -OutFile opencl-icd-1.2.11.0.tgz
...@@ -36,7 +37,7 @@ install: ...@@ -36,7 +37,7 @@ install:
- ps: 7z x opencl-icd-1.2.11.0.tar > $null - ps: 7z x opencl-icd-1.2.11.0.tar > $null
- ps: mv .\icd\* . - ps: mv .\icd\* .
- ps: mkdir inc/CL > $null - ps: mkdir inc/CL > $null
- ps: wget $opencl_registry/api/1.2/ | select -ExpandProperty links | where {$_.href -like "*.h*"} | select -ExpandProperty outerText | foreach{ wget $opencl_registry/api/1.2/$_ -OutFile inc/CL/$_ } - ps: wget https://github.com/$opencl_github | select -ExpandProperty links | where {$_.href -like "*.h*"} | select -ExpandProperty outerText | foreach{ wget https://raw.githubusercontent.com/$opencl_github/master/$_ -OutFile inc/CL/$_ }
- ps: mkdir lib > $null - ps: mkdir lib > $null
- ps: cd lib - ps: cd lib
- cmake -G "NMake Makefiles" .. - cmake -G "NMake Makefiles" ..
......
...@@ -21,6 +21,9 @@ Representation and Manipulation ...@@ -21,6 +21,9 @@ Representation and Manipulation
:template: class.rst :template: class.rst
~simtk.openmm.app.topology.Topology ~simtk.openmm.app.topology.Topology
~simtk.openmm.app.topology.Chain
~simtk.openmm.app.topology.Residue
~simtk.openmm.app.topology.Atom
~simtk.openmm.app.modeller.Modeller ~simtk.openmm.app.modeller.Modeller
Simulation Simulation
...@@ -53,3 +56,14 @@ Extras ...@@ -53,3 +56,14 @@ Extras
{% for extra in app_extras %} {% for extra in app_extras %}
~{{ extra }} ~{{ extra }}
{% endfor %} {% endfor %}
Units
~~~~~~
.. autosummary::
:toctree: generated/
:template: class.rst
:nosignatures:
{% for unit in units %}
~{{ unit }}
{% endfor %}
...@@ -32,6 +32,7 @@ def library_template_variables(): ...@@ -32,6 +32,7 @@ def library_template_variables():
'integrators': [], 'integrators': [],
'forces': [], 'forces': [],
'library_extras': [], 'library_extras': [],
'units': [],
} }
mm_klasses = inspect.getmembers(simtk.openmm, predicate=inspect.isclass) mm_klasses = inspect.getmembers(simtk.openmm, predicate=inspect.isclass)
...@@ -65,6 +66,11 @@ def library_template_variables(): ...@@ -65,6 +66,11 @@ def library_template_variables():
if full not in exclude and not klass.__name__[0].islower(): if full not in exclude and not klass.__name__[0].islower():
data['library_extras'].append(full) data['library_extras'].append(full)
# gather units related classes
unit_klasses = inspect.getmembers(simtk.unit, predicate=inspect.isclass)
for name, klass in unit_klasses:
data['units'].append(fullname(klass))
return data return data
...@@ -93,11 +99,14 @@ def app_template_variables(): ...@@ -93,11 +99,14 @@ def app_template_variables():
# gather all classes with "File" in the name # gather all classes with "File" in the name
for name, klass in app_klasses: for name, klass in app_klasses:
if 'File' in name: if 'File' in name or 'CharmmParameterSet' in name:
data['fileclasses'].append(fullname(klass)) data['fileclasses'].append(fullname(klass))
# gather all extra subclasses in simtk.openmm.app # gather all extra subclasses in simtk.openmm.app
exclude = ['simtk.openmm.app.topology.Topology', exclude = ['simtk.openmm.app.topology.Topology',
'simtk.openmm.app.topology.Chain',
'simtk.openmm.app.topology.Residue',
'simtk.openmm.app.topology.Atom',
'simtk.openmm.app.modeller.Modeller', 'simtk.openmm.app.modeller.Modeller',
'simtk.openmm.app.forcefield.ForceField', 'simtk.openmm.app.forcefield.ForceField',
'simtk.openmm.app.simulation.Simulation'] 'simtk.openmm.app.simulation.Simulation']
......
...@@ -2063,6 +2063,107 @@ are :code:`wo1`\ , :code:`wo2`\ , :code:`wo3`\ , :code:`wx1`\ , :code:`wx2`\ , ...@@ -2063,6 +2063,107 @@ are :code:`wo1`\ , :code:`wo2`\ , :code:`wo3`\ , :code:`wx1`\ , :code:`wx2`\ ,
:code:`wx3`\ , :code:`wy1`\ , :code:`wy2`\ , :code:`wy3`\ , :code:`p1`\ , :code:`wx3`\ , :code:`wy1`\ , :code:`wy2`\ , :code:`wy3`\ , :code:`p1`\ ,
:code:`p2`\ , and :code:`p3`\ . :code:`p2`\ , and :code:`p3`\ .
<Patches>
=========
A "patch" is a set of rules for modifying a residue template (or possibly multiple
templates at once). For example a terminal amino acid is slightly different from
one in the middle of a chain. A force field could of course define multiple
templates for each amino acid (standard, N-terminal, C-terminal, and monomer),
but since the modifications are the same for nearly all amino acids, it is simpler
to include only the "standard" templates, along with a set of patches for
modifying terminal residues.
Here is an example of a patch definition:
.. code-block:: xml
<Patch name="NTER">
<RemoveAtom name="H"/>
<RemoveBond atomName1="N" atomName2="H"/>
<AddAtom name="H1" type="H"/>
<AddAtom name="H2" type="H"/>
<AddAtom name="H3" type="H"/>
<AddBond atomName1="N" atomName2="H1"/>
<AddBond atomName1="N" atomName2="H2"/>
<AddBond atomName1="N" atomName2="H3"/>
<RemoveExternalBond atomName="N"/>
<ChangeAtom name="N" type="N3"/>
</Patch>
There is one :code:`<Patch>` tag for each patch definition. That in turn may
contain any of the following tags:
* An :code:`<AddAtom>` tag indicates that an atom should be added to the
template. It specifies the name of the atom and its atom type.
* A :code:`<ChangeAtom>` tag indicates that the type of an atom already present
in the template should be altered. It specifies the name of the atom and its
new atom type.
* A :code:`<RemoveAtom>` tag indicates that an atom should be removed from the
template. It specifies the name of the atom to remove.
* An :code:`<AddBond>` tag indicates that a bond should be added to the
template. It specifies the names of the two bonded atoms.
* A :code:`<RemoveBond>` tag indicates that a bond already present in the
template should be removed. It specifies the names of the two bonded atoms.
* An :code:`<AddExternalBond>` tag indicates that a new external bond should be
added to the template. It specifies the name of the bonded atom.
* A :code:`<RemoveExternalBond>` tag indicates that an external bond aleady
present in the template should be removed. It specifies the name of the
bonded atom.
In addition to defining the patches, you also must identify which residue
templates each patch can be applied to. This can be done in two ways. The more
common one is to have each template identify the patches that can be applied to
it. This is done with an :code:`<AllowPatch>` tag:
.. code-block:: xml
<Residue name="ALA">
<AllowPatch name="CTER"/>
<AllowPatch name="NTER"/>
...
</Residue>
Alternatively, the patch can indicate which residues it may be applied to. This
is done with an :code:`<ApplyToResidue>` tag:
.. code-block:: xml
<Patch name="NTER">
<ApplyToResidue name="ALA"/>
<ApplyToResidue name="ARG"/>
...
</Patch>
A patch can alter multiple templates at once. This is useful for creating bonds
between molecules, and allows the atom types in one residue to depend on the
identity of the other residue it is bonded to. To create a multi-residue patch,
added a :code:`residues` attribute to the :code:`<Patch>` tag specifying how many
residues that patch covers. Then whenever you refer to an atom, prefix its name
with the index of the residue it belongs to:
.. code-block:: xml
<Patch name="Disulfide" residues="2">
<RemoveAtom name="1:HG"/>
<RemoveAtom name="2:HG"/>
<AddBond atomName1="1:SG" atomName2="2:SG"/>
<ApplyToResidue name="1:CYS"/>
<ApplyToResidue name="2:CYS"/>
</Patch>
In this example, the patch modifies two residues of the same type, but that need
not always be true. Each :code:`<ApplyToResidue>` tag therefore indicates which
one of the residue templates it modifies may be of the specified type. Similarly,
if a residue template includes an :code:`<AcceptPatch>` tag for a multi-residue
patch, it must specify the name of the patch, followed by the index of the residue
within that patch:
.. code-block:: xml
<AllowPatch name="Disulfide:1"/>
Missing residue templates Missing residue templates
========================= =========================
......
...@@ -26,7 +26,7 @@ sys.path.append(os.path.abspath('../sphinx')) ...@@ -26,7 +26,7 @@ sys.path.append(os.path.abspath('../sphinx'))
# Add any Sphinx extension module names here, as strings. They can be extensions # Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.pngmath', 'sphinx.ext.mathjax', 'sphinxcontrib.bibtex', 'autonumber', 'samepage', 'caption', 'numsec'] extensions = ['sphinx.ext.mathjax', 'sphinxcontrib.bibtex', 'autonumber', 'samepage', 'caption', 'numsec']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']
......
...@@ -1086,6 +1086,24 @@ is exactly equivalent to ...@@ -1086,6 +1086,24 @@ is exactly equivalent to
The definition of an intermediate value may itself involve other intermediate The definition of an intermediate value may itself involve other intermediate
values. All uses of a value must appear *before* that value’s definition. values. All uses of a value must appear *before* that value’s definition.
Parameter Derivatives
*********************
Many custom forces have the ability to compute derivatives of the potential energy
with respect to global parameters. To use this feature, first define a global
parameter that the energy depends on. Then instruct the custom force to compute
the derivative with respect to that parameter by calling :meth:`addEnergyParameterDerivative()`
on it. Whenever forces and energies are computed, the specified derivative will
then also be computed at the same time. You can query it by calling :meth:`getState()`
on a :class:`Context`, just as you would query forces or energies.
An important application of this feature is to use it in combination with a
:class:`CustomIntegrator` (described in section :ref:`custom-integrator`\ ). The
derivative can appear directly in expressions that define the integration
algorithm. This can be used to implement algorithms such as lambda-dynamics,
where a global parameter is integrated as a dynamic variable.
Integrators Integrators
########### ###########
...@@ -1235,6 +1253,8 @@ Furthermore, because Langevin dynamics involves a random force, it can never be ...@@ -1235,6 +1253,8 @@ Furthermore, because Langevin dynamics involves a random force, it can never be
symplectic and therefore the fixed step size Verlet integrator’s advantages do symplectic and therefore the fixed step size Verlet integrator’s advantages do
not apply to the Langevin integrator. not apply to the Langevin integrator.
.. _custom-integrator:
CustomIntegrator CustomIntegrator
**************** ****************
......
...@@ -48,7 +48,7 @@ public: ...@@ -48,7 +48,7 @@ public:
virtual ~CustomFunction() { virtual ~CustomFunction() {
} }
/** /**
* Get the number of arguments this function exprects. * Get the number of arguments this function expects.
*/ */
virtual int getNumArguments() const = 0; virtual int getNumArguments() const = 0;
/** /**
......
...@@ -109,7 +109,7 @@ ExpressionTreeNode ParsedExpression::precalculateConstantSubexpressions(const Ex ...@@ -109,7 +109,7 @@ ExpressionTreeNode ParsedExpression::precalculateConstantSubexpressions(const Ex
for (int i = 0; i < (int) children.size(); i++) for (int i = 0; i < (int) children.size(); i++)
children[i] = precalculateConstantSubexpressions(node.getChildren()[i]); children[i] = precalculateConstantSubexpressions(node.getChildren()[i]);
ExpressionTreeNode result = ExpressionTreeNode(node.getOperation().clone(), children); ExpressionTreeNode result = ExpressionTreeNode(node.getOperation().clone(), children);
if (node.getOperation().getId() == Operation::VARIABLE) if (node.getOperation().getId() == Operation::VARIABLE || node.getOperation().getId() == Operation::CUSTOM)
return result; return result;
for (int i = 0; i < (int) children.size(); i++) for (int i = 0; i < (int) children.size(); i++)
if (children[i].getOperation().getId() != Operation::CONSTANT) if (children[i].getOperation().getId() != Operation::CONSTANT)
......
...@@ -124,14 +124,12 @@ public: ...@@ -124,14 +124,12 @@ public:
}; };
void SFMT::createCheckpoint(std::ostream& stream) { void SFMT::createCheckpoint(std::ostream& stream) {
stream.write((char*) &data->baseData, sizeof(data->baseData)); stream.write((char*) data->sfmt, N*sizeof(w128_t));
stream.write((char*) &data->sfmt, sizeof(data->sfmt));
stream.write((char*) &data->idx, sizeof(data->idx)); stream.write((char*) &data->idx, sizeof(data->idx));
} }
void SFMT::loadCheckpoint(std::istream& stream) { void SFMT::loadCheckpoint(std::istream& stream) {
stream.read((char*) &data->baseData, sizeof(data->baseData)); stream.read((char*) data->sfmt, N*sizeof(w128_t));
stream.read((char*) &data->sfmt, sizeof(data->sfmt));
stream.read((char*) &data->idx, sizeof(data->idx)); stream.read((char*) &data->idx, sizeof(data->idx));
} }
......
...@@ -173,6 +173,12 @@ public: ...@@ -173,6 +173,12 @@ public:
* @param forces on exit, this contains the forces * @param forces on exit, this contains the forces
*/ */
virtual void getForces(ContextImpl& context, std::vector<Vec3>& forces) = 0; virtual void getForces(ContextImpl& context, std::vector<Vec3>& forces) = 0;
/**
* Get the current derivatives of the energy with respect to context parameters.
*
* @param derivs on exit, this contains the derivatives
*/
virtual void getEnergyParameterDerivatives(ContextImpl& context, std::map<std::string, double>& derivs) = 0;
/** /**
* Get the current periodic box vectors. * Get the current periodic box vectors.
* *
......
...@@ -320,7 +320,11 @@ const string& Platform::getDefaultPluginsDirectory() { ...@@ -320,7 +320,11 @@ const string& Platform::getDefaultPluginsDirectory() {
#define STRING(x) STRING1(x) #define STRING(x) STRING1(x)
const string& Platform::getOpenMMVersion() { const string& Platform::getOpenMMVersion() {
#if OPENMM_BUILD_VERSION == 0
static const string version = STRING(OPENMM_MAJOR_VERSION) "." STRING(OPENMM_MINOR_VERSION); static const string version = STRING(OPENMM_MAJOR_VERSION) "." STRING(OPENMM_MINOR_VERSION);
#else
static const string version = STRING(OPENMM_MAJOR_VERSION) "." STRING(OPENMM_MINOR_VERSION) "." STRING(OPENMM_BUILD_VERSION);
#endif
return version; return version;
} }
......
...@@ -64,6 +64,10 @@ namespace OpenMM { ...@@ -64,6 +64,10 @@ namespace OpenMM {
* force->addPerAngleParameter("theta0"); * force->addPerAngleParameter("theta0");
* </pre></tt> * </pre></tt>
* *
* 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 * 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.
...@@ -97,6 +101,13 @@ public: ...@@ -97,6 +101,13 @@ public:
int getNumGlobalParameters() const { int getNumGlobalParameters() const {
return globalParameters.size(); 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 algebraic expression that gives the interaction energy for each angle * Get the algebraic expression that gives the interaction energy for each angle
*/ */
...@@ -162,6 +173,21 @@ public: ...@@ -162,6 +173,21 @@ public:
* @param defaultValue the default value of the parameter * @param defaultValue the default value of the parameter
*/ */
void setGlobalParameterDefaultValue(int index, double defaultValue); 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 an angle term to the force field. * Add an angle term to the force field.
* *
...@@ -225,6 +251,7 @@ private: ...@@ -225,6 +251,7 @@ private:
std::vector<AngleParameterInfo> parameters; std::vector<AngleParameterInfo> parameters;
std::vector<GlobalParameterInfo> globalParameters; std::vector<GlobalParameterInfo> globalParameters;
std::vector<AngleInfo> angles; std::vector<AngleInfo> angles;
std::vector<int> energyParameterDerivatives;
bool usePeriodic; bool usePeriodic;
}; };
......
...@@ -64,6 +64,10 @@ namespace OpenMM { ...@@ -64,6 +64,10 @@ namespace OpenMM {
* force->addPerBondParameter("r0"); * force->addPerBondParameter("r0");
* </pre></tt> * </pre></tt>
* *
* 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 * 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.
...@@ -97,6 +101,13 @@ public: ...@@ -97,6 +101,13 @@ public:
int getNumGlobalParameters() const { int getNumGlobalParameters() const {
return globalParameters.size(); 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 algebraic expression that gives the interaction energy for each bond * Get the algebraic expression that gives the interaction energy for each bond
*/ */
...@@ -162,6 +173,21 @@ public: ...@@ -162,6 +173,21 @@ public:
* @param defaultValue the default value of the parameter * @param defaultValue the default value of the parameter
*/ */
void setGlobalParameterDefaultValue(int index, double defaultValue); 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 bond term to the force field. * Add a bond term to the force field.
* *
...@@ -222,6 +248,7 @@ private: ...@@ -222,6 +248,7 @@ private:
std::vector<BondParameterInfo> parameters; std::vector<BondParameterInfo> parameters;
std::vector<GlobalParameterInfo> globalParameters; std::vector<GlobalParameterInfo> globalParameters;
std::vector<BondInfo> bonds; std::vector<BondInfo> bonds;
std::vector<int> energyParameterDerivatives;
bool usePeriodic; bool usePeriodic;
}; };
......
...@@ -99,6 +99,10 @@ namespace OpenMM { ...@@ -99,6 +99,10 @@ namespace OpenMM {
* force->addBond(bondGroups, bondParameters); * force->addBond(bondGroups, bondParameters);
* </pre></tt> * </pre></tt>
* *
* 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 * 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.
...@@ -150,6 +154,13 @@ public: ...@@ -150,6 +154,13 @@ public:
int getNumGlobalParameters() const { int getNumGlobalParameters() const {
return globalParameters.size(); 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. * Get the number of tabulated functions that have been defined.
*/ */
...@@ -229,6 +240,21 @@ public: ...@@ -229,6 +240,21 @@ public:
* @param defaultValue the default value of the parameter * @param defaultValue the default value of the parameter
*/ */
void setGlobalParameterDefaultValue(int index, double defaultValue); 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 particle group. * Add a particle group.
* *
...@@ -351,6 +377,7 @@ private: ...@@ -351,6 +377,7 @@ private:
std::vector<GroupInfo> groups; std::vector<GroupInfo> groups;
std::vector<BondInfo> bonds; std::vector<BondInfo> bonds;
std::vector<FunctionInfo> functions; std::vector<FunctionInfo> functions;
std::vector<int> energyParameterDerivatives;
bool usePeriodic; bool usePeriodic;
}; };
......
...@@ -88,6 +88,10 @@ namespace OpenMM { ...@@ -88,6 +88,10 @@ namespace OpenMM {
* force->addPerBondParameter("r0"); * force->addPerBondParameter("r0");
* </pre></tt> * </pre></tt>
* *
* 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 * 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.
...@@ -133,6 +137,13 @@ public: ...@@ -133,6 +137,13 @@ public:
int getNumGlobalParameters() const { int getNumGlobalParameters() const {
return globalParameters.size(); 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. * Get the number of tabulated functions that have been defined.
*/ */
...@@ -212,6 +223,21 @@ public: ...@@ -212,6 +223,21 @@ public:
* @param defaultValue the default value of the parameter * @param defaultValue the default value of the parameter
*/ */
void setGlobalParameterDefaultValue(int index, double defaultValue); 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 bond to the force * Add a bond to the force
* *
...@@ -323,6 +349,7 @@ private: ...@@ -323,6 +349,7 @@ private:
std::vector<GlobalParameterInfo> globalParameters; std::vector<GlobalParameterInfo> globalParameters;
std::vector<BondInfo> bonds; std::vector<BondInfo> bonds;
std::vector<FunctionInfo> functions; std::vector<FunctionInfo> functions;
std::vector<int> energyParameterDerivatives;
bool usePeriodic; bool usePeriodic;
}; };
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2014 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -128,6 +128,10 @@ namespace OpenMM { ...@@ -128,6 +128,10 @@ namespace OpenMM {
* however, you can use the computation type ParticlePairNoExclusions to indicate that exclusions should not be applied to a * however, you can use the computation type ParticlePairNoExclusions to indicate that exclusions should not be applied to a
* particular piece of the computation. * particular piece of the computation.
* *
* 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 * 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.
...@@ -207,6 +211,13 @@ public: ...@@ -207,6 +211,13 @@ public:
int getNumGlobalParameters() const { int getNumGlobalParameters() const {
return globalParameters.size(); 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. * Get the number of tabulated functions that have been defined.
*/ */
...@@ -312,6 +323,21 @@ public: ...@@ -312,6 +323,21 @@ public:
* @param defaultValue the default value of the parameter * @param defaultValue the default value of the parameter
*/ */
void setGlobalParameterDefaultValue(int index, double defaultValue); 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 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.
...@@ -550,6 +576,7 @@ private: ...@@ -550,6 +576,7 @@ private:
std::vector<FunctionInfo> functions; std::vector<FunctionInfo> functions;
std::vector<ComputationInfo> computedValues; std::vector<ComputationInfo> computedValues;
std::vector<ComputationInfo> energyTerms; std::vector<ComputationInfo> energyTerms;
std::vector<int> energyParameterDerivatives;
}; };
/** /**
......
...@@ -202,6 +202,16 @@ namespace OpenMM { ...@@ -202,6 +202,16 @@ namespace OpenMM {
* following comparison operators: =, <. >, !=, <=, >=. Blocks may be nested * following comparison operators: =, <. >, !=, <=, >=. Blocks may be nested
* inside each other. * inside each other.
* *
* Another feature of CustomIntegrator is that it can use derivatives of the
* potential energy with respect to context parameters. These derivatives are
* typically computed by custom forces, and are only computed if a Force object
* has been specifically told to compute them by calling addEnergyParameterDerivative()
* on it. CustomIntegrator provides a deriv() function for accessing these
* derivatives in global or per-DOF expressions. For example, "deriv(energy, lambda)"
* is the derivative of the total potentially energy with respect to the parameter
* lambda. You can also restrict it to a single force group by specifying a different
* variable for the first argument, such as "deriv(energy1, lambda)".
*
* An Integrator has one other job in addition to evolving the equations of motion: * An Integrator has one other job in addition to evolving the equations of motion:
* it defines how to compute the kinetic energy of the system. Depending on the * it defines how to compute the kinetic energy of the system. Depending on the
* integration method used, simply summing mv<sup>2</sup>/2 over all degrees of * integration method used, simply summing mv<sup>2</sup>/2 over all degrees of
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2014 Stanford University and the Authors. * * Portions copyright (c) 2008-2016 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -119,6 +119,10 @@ namespace OpenMM { ...@@ -119,6 +119,10 @@ namespace OpenMM {
* (or when you modify per-particle parameters by calling updateParametersInContext()). This means that if parameters change * (or when you modify per-particle parameters by calling updateParametersInContext()). This means that if parameters change
* frequently, the long range correction can be very slow. For this reason, it is disabled by default. * frequently, the long range correction can be very slow. For this reason, it is disabled by default.
* *
* 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 * 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.
...@@ -204,6 +208,13 @@ public: ...@@ -204,6 +208,13 @@ public:
int getNumInteractionGroups() const { int getNumInteractionGroups() const {
return interactionGroups.size(); return interactionGroups.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 algebraic expression that gives the interaction energy between two particles * Get the algebraic expression that gives the interaction energy between two particles
*/ */
...@@ -321,6 +332,21 @@ public: ...@@ -321,6 +332,21 @@ public:
* @param defaultValue the default value of the parameter * @param defaultValue the default value of the parameter
*/ */
void setGlobalParameterDefaultValue(int index, double defaultValue); 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 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.
...@@ -494,6 +520,7 @@ private: ...@@ -494,6 +520,7 @@ private:
std::vector<ExclusionInfo> exclusions; std::vector<ExclusionInfo> exclusions;
std::vector<FunctionInfo> functions; std::vector<FunctionInfo> functions;
std::vector<InteractionGroupInfo> interactionGroups; std::vector<InteractionGroupInfo> interactionGroups;
std::vector<int> energyParameterDerivatives;
}; };
/** /**
......
...@@ -64,6 +64,10 @@ namespace OpenMM { ...@@ -64,6 +64,10 @@ namespace OpenMM {
* force->addPerTorsionParameter("theta0"); * force->addPerTorsionParameter("theta0");
* </pre></tt> * </pre></tt>
* *
* 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 * 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.
...@@ -97,6 +101,13 @@ public: ...@@ -97,6 +101,13 @@ public:
int getNumGlobalParameters() const { int getNumGlobalParameters() const {
return globalParameters.size(); 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 algebraic expression that gives the interaction energy for each torsion * Get the algebraic expression that gives the interaction energy for each torsion
*/ */
...@@ -162,6 +173,21 @@ public: ...@@ -162,6 +173,21 @@ public:
* @param defaultValue the default value of the parameter * @param defaultValue the default value of the parameter
*/ */
void setGlobalParameterDefaultValue(int index, double defaultValue); 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 torsion term to the force field. * Add a torsion term to the force field.
* *
...@@ -228,6 +254,7 @@ private: ...@@ -228,6 +254,7 @@ private:
std::vector<TorsionParameterInfo> parameters; std::vector<TorsionParameterInfo> parameters;
std::vector<GlobalParameterInfo> globalParameters; std::vector<GlobalParameterInfo> globalParameters;
std::vector<TorsionInfo> torsions; std::vector<TorsionInfo> torsions;
std::vector<int> energyParameterDerivatives;
bool usePeriodic; bool usePeriodic;
}; };
......
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