Commit 18295108 authored by peastman's avatar peastman
Browse files

Merge changes from main branch

parents e6101f68 8d7234e5
...@@ -128,6 +128,7 @@ before_install: ...@@ -128,6 +128,7 @@ before_install:
export LD_LIBRARY_PATH=${AMDAPPSDK}/lib/x86_64:${LD_LIBRARY_PATH}; export LD_LIBRARY_PATH=${AMDAPPSDK}/lib/x86_64:${LD_LIBRARY_PATH};
chmod +x ${AMDAPPSDK}/bin/x86_64/clinfo; chmod +x ${AMDAPPSDK}/bin/x86_64/clinfo;
${AMDAPPSDK}/bin/x86_64/clinfo; ${AMDAPPSDK}/bin/x86_64/clinfo;
sudo apt-get install -y libgl1-mesa-dev;
fi fi
# Install swig for Python wrappers. However, testing CUDA and OpenCL, we # Install swig for Python wrappers. However, testing CUDA and OpenCL, we
# skip the Python wrapper for speed. We're not using anaconda python, # skip the Python wrapper for speed. We're not using anaconda python,
...@@ -159,6 +160,7 @@ before_install: ...@@ -159,6 +160,7 @@ before_install:
export CUDA_HOME=/usr/local/cuda-${CUDA_VERSION%%-*}; export CUDA_HOME=/usr/local/cuda-${CUDA_VERSION%%-*};
export LD_LIBRARY_PATH=${CUDA_HOME}/lib64:${LD_LIBRARY_PATH}; export LD_LIBRARY_PATH=${CUDA_HOME}/lib64:${LD_LIBRARY_PATH};
export PATH=${CUDA_HOME}/bin:${PATH}; export PATH=${CUDA_HOME}/bin:${PATH};
sudo apt-get install -y libgl1-mesa-dev;
fi fi
script: script:
...@@ -179,7 +181,7 @@ script: ...@@ -179,7 +181,7 @@ script:
- python devtools/run-ctest.py --start-time $START_TIME - python devtools/run-ctest.py --start-time $START_TIME
- if [[ ! -z "${DOCS_DEPLOY}" && "${DOCS_DEPLOY}" = "true" ]]; then - if [[ ! -z "${DOCS_DEPLOY}" && "${DOCS_DEPLOY}" = "true" ]]; then
pip install sphinx sphinxcontrib-bibtex sphinxcontrib-lunrsearch sphinxcontrib-autodoc_doxygen; pip install sphinx==1.5.6 sphinxcontrib-bibtex sphinxcontrib-lunrsearch sphinxcontrib-autodoc_doxygen;
make sphinxhtml; make sphinxhtml;
make C++ApiDocs PythonApiDocs; make C++ApiDocs PythonApiDocs;
mkdir -p api-docs; mkdir -p api-docs;
......
...@@ -141,7 +141,7 @@ ENDIF (NOT CMAKE_CXX_FLAGS_RELEASE) ...@@ -141,7 +141,7 @@ ENDIF (NOT CMAKE_CXX_FLAGS_RELEASE)
SET(OPENMM_LIBRARY_NAME OpenMM) SET(OPENMM_LIBRARY_NAME OpenMM)
SET(OPENMM_MAJOR_VERSION 7) SET(OPENMM_MAJOR_VERSION 7)
SET(OPENMM_MINOR_VERSION 1) SET(OPENMM_MINOR_VERSION 2)
SET(OPENMM_BUILD_VERSION 0) SET(OPENMM_BUILD_VERSION 0)
ADD_DEFINITIONS(-DOPENMM_LIBRARY_NAME=${OPENMM_LIBRARY_NAME} ADD_DEFINITIONS(-DOPENMM_LIBRARY_NAME=${OPENMM_LIBRARY_NAME}
......
...@@ -39,7 +39,7 @@ install: ...@@ -39,7 +39,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 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: wget https://github.com/$opencl_github/tree/master/opencl20/CL | select -ExpandProperty links | where {$_.href -like "*.h*"} | select -ExpandProperty outerText | foreach{ wget https://raw.githubusercontent.com/$opencl_github/master/opencl20/CL/$_ -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" ..
......
# Packaging OpenMM into ZIP installers # Packaging OpenMM into ZIP installers
Set your environment variable `TAG` to the git tag for the release:
```bash
# OpenMM 7.1.1
export TAG="c1a64aa"
```
## Source ## Source
Start the docker container: Start the docker container:
```bash ```bash
docker run -i -t --rm -v `pwd`:/io jchodera/omnia-build-box:cuda80-amd30-clang38 bash docker run -i -t --rm -e TAG -v `pwd`:/io jchodera/omnia-build-box:cuda80-amd30-clang38 bash
```
Patch the docker container for missing LaTeX files:
``` ```
Inside the docker container: tlmgr install fncychap tabulary capt-of eqparbox environ trimspaces
```
Build the installer inside the docker container:
```bash ```bash
# Clone the OpenMM beta or release candidate tag $TAG # Clone the OpenMM beta or release candidate tag $TAG
git clone https://github.com/pandegroup/openmm.git git clone https://github.com/pandegroup/openmm.git
...@@ -23,9 +33,13 @@ cp packaging/compressed/* /io ...@@ -23,9 +33,13 @@ cp packaging/compressed/* /io
Start the docker container: Start the docker container:
```bash ```bash
docker run -i -t --rm -v `pwd`:/io jchodera/omnia-build-box:cuda80-amd30-clang38 bash docker run -i -t --rm -e TAG -v `pwd`:/io jchodera/omnia-build-box:cuda80-amd30-clang38 bash
```
Patch the docker container for missing LaTeX files:
``` ```
Inside the docker container: tlmgr install fncychap tabulary capt-of eqparbox environ trimspaces
```
Build the installer inside the docker container:
```bash ```bash
# Clone the OpenMM beta or release candidate tag $TAG # Clone the OpenMM beta or release candidate tag $TAG
git clone https://github.com/pandegroup/openmm.git git clone https://github.com/pandegroup/openmm.git
...@@ -50,4 +64,3 @@ source openmm/devtools/packaging/scripts/osx/prepare.sh ...@@ -50,4 +64,3 @@ source openmm/devtools/packaging/scripts/osx/prepare.sh
source openmm/devtools/packaging/scripts/osx/build.sh source openmm/devtools/packaging/scripts/osx/build.sh
source openmm/devtools/packaging/scripts/osx/package.sh source openmm/devtools/packaging/scripts/osx/package.sh
``` ```
...@@ -26,5 +26,5 @@ export PATH=$WORKSPACE/miniconda/bin:$PATH ...@@ -26,5 +26,5 @@ export PATH=$WORKSPACE/miniconda/bin:$PATH
# Ensure configuration is up to date. # Ensure configuration is up to date.
conda config --add channels http://conda.binstar.org/omnia conda config --add channels http://conda.binstar.org/omnia
conda install --yes --quiet swig fftw3f pip conda install --yes --quiet swig fftw3f pip doxygen sphinx sphinxcontrib-bibtex sphinxcontrib-lunrsearch sphinxcontrib-autodoc_doxygen lxml cmake
pip install sphinxcontrib-bibtex sphinxcontrib-lunrsearch sphinxcontrib-autodoc_doxygen pip install sphinxcontrib-bibtex sphinxcontrib-lunrsearch sphinxcontrib-autodoc_doxygen
...@@ -14,8 +14,11 @@ def process_docstring(app, what, name, obj, options, lines): ...@@ -14,8 +14,11 @@ def process_docstring(app, what, name, obj, options, lines):
s = m.group(1) s = m.group(1)
if not s.startswith(linesep): if not s.startswith(linesep):
s = linesep + s s = linesep + s
newline = '|LINEBREAK|.. admonition:: Deprecated' + linesep newline = '|LINEBREAK|.. admonition::|LINEBREAK| Deprecated' + linesep
return newline + ' ' + s.replace(linesep, linesep + ' ') return newline + ' ' + s.replace(linesep, linesep + ' ')
def repl3(m):
s = m.group(1)
return '*' + s + '*'
linesep = '|LINEBREAK|' linesep = '|LINEBREAK|'
joined = linesep.join(lines) joined = linesep.join(lines)
...@@ -23,6 +26,7 @@ def process_docstring(app, what, name, obj, options, lines): ...@@ -23,6 +26,7 @@ def process_docstring(app, what, name, obj, options, lines):
joined = re.sub(r'<tt><pre>((|LINEBREAK|)?.*?)</pre></tt>', repl, joined) joined = re.sub(r'<tt><pre>((|LINEBREAK|)?.*?)</pre></tt>', repl, joined)
joined = re.sub(r'<tt>(.*?)</tt>', repl, joined) joined = re.sub(r'<tt>(.*?)</tt>', repl, joined)
joined = re.sub(r'@deprecated(.*?\|LINEBREAK\|)', repl2, joined, flags=re.IGNORECASE) joined = re.sub(r'@deprecated(.*?\|LINEBREAK\|)', repl2, joined, flags=re.IGNORECASE)
joined = re.sub(r'<i>(.*?)</i>', repl3, joined)
lines[:] = [(l if not l.isspace() else '') for l in joined.split(linesep)] lines[:] = [(l if not l.isspace() else '') for l in joined.split(linesep)]
......
...@@ -2051,10 +2051,9 @@ be represented with a virtual site. The :code:`type` attribute may equal ...@@ -2051,10 +2051,9 @@ be represented with a virtual site. The :code:`type` attribute may equal
:code:`"localCoords"`\ , which correspond to the TwoParticleAverageSite, ThreeParticleAverageSite, :code:`"localCoords"`\ , which correspond to the TwoParticleAverageSite, ThreeParticleAverageSite,
OutOfPlaneSite, and LocalCoordinatesSite classes respectively. The :code:`siteName` OutOfPlaneSite, and LocalCoordinatesSite classes respectively. The :code:`siteName`
attribute gives the name of the atom to represent with a virtual site. The atoms attribute gives the name of the atom to represent with a virtual site. The atoms
it is calculated based on are specified by :code:`atomName1`\ , :code:`atomName2`\ , it is calculated based on are specified by :code:`atomName1`\ , :code:`atomName2`\ , etc.
and (for virtual site classes that involve three atoms) :code:`atomName3`\ .
(Some old force fields use the deprecated tags :code:`index`, :code:`atom1`, (Some old force fields use the deprecated tags :code:`index`, :code:`atom1`,
:code:`atom2`, and :code:`atom3` to refer to them by index instead of name.) :code:`atom2`, etc. to refer to them by index instead of name.)
The remaining attributes are specific to the virtual site class, and specify the The remaining attributes are specific to the virtual site class, and specify the
parameters for calculating the site position. For a TwoParticleAverageSite, parameters for calculating the site position. For a TwoParticleAverageSite,
...@@ -2062,9 +2061,10 @@ they are :code:`weight1` and :code:`weight2`\ . For a ...@@ -2062,9 +2061,10 @@ they are :code:`weight1` and :code:`weight2`\ . For a
ThreeParticleAverageSite, they are :code:`weight1`\ , :code:`weight2`\ , and ThreeParticleAverageSite, they are :code:`weight1`\ , :code:`weight2`\ , and
\ :code:`weight3`\ . For an OutOfPlaneSite, they are :code:`weight12`\ , \ :code:`weight3`\ . For an OutOfPlaneSite, they are :code:`weight12`\ ,
:code:`weight13`\ , and :code:`weightCross`\ . For a LocalCoordinatesSite, they :code:`weight13`\ , and :code:`weightCross`\ . For a LocalCoordinatesSite, they
are :code:`wo1`\ , :code:`wo2`\ , :code:`wo3`\ , :code:`wx1`\ , :code:`wx2`\ , are :code:`p1`\ , :code:`p2`\ , and :code:`p3` (giving the x, y, and z coordinates
:code:`wx3`\ , :code:`wy1`\ , :code:`wy2`\ , :code:`wy3`\ , :code:`p1`\ , of the site position in the local coordinate system), and :code:`wo1`\ ,
:code:`p2`\ , and :code:`p3`\ . :code:`wx1`\ , :code:`wy1`\ , :code:`wo2`\ , :code:`wx2`\ , :code:`wy2`\ , ...
(giving the weights for computing the origin, x axis, and y axis).
<Patches> <Patches>
========= =========
...@@ -2937,6 +2937,32 @@ need to be specified once for each class. The atom charges, which are different ...@@ -2937,6 +2937,32 @@ need to be specified once for each class. The atom charges, which are different
for each type, are taken from the residue template instead. for each type, are taken from the residue template instead.
Including Other Files
=====================
Sometimes it is useful to split a force field definition into multiple files,
but still be able to use the force field by specifying only a single file. You
can accomplish this with the :code:`<Include>` tag. For example:
.. code-block:: xml
<ForceField>
<Include file="definitions.xml"/>
...
</ForceField>
The :code:`file` attribute gives the path of the file to include. It may be
relative either to the directory containing the parent XML file (the one with
the :code:`<Include>` tag) or the OpenMM data directory (the one containing
built in force fields).
The included file is fully processed before any other tags in the parent file
are processed, and its definitions are added to the force field. This means the
parent file can refer to atom types defined in the included file, but not the
other way around. If there are multiple :code:`<Include>` tags, they are processed
in the order they appear in the file.
Using Multiple Files Using Multiple Files
******************** ********************
......
...@@ -522,9 +522,9 @@ ...@@ -522,9 +522,9 @@
author = {Wang, Lee-Ping and McKiernan, Keri A. and Gomes, Joseph and Beauchamp, Kyle A. and Head-Gordon, Teresa and Rice, Julia E. and Swope, William C. and Martínez, Todd J. and Pande, Vijay S.}, author = {Wang, Lee-Ping and McKiernan, Keri A. and Gomes, Joseph and Beauchamp, Kyle A. and Head-Gordon, Teresa and Rice, Julia E. and Swope, William C. and Martínez, Todd J. and Pande, Vijay S.},
title = {Building a More Predictive Protein Force Field: A Systematic and Reproducible Route to AMBER-FB15}, title = {Building a More Predictive Protein Force Field: A Systematic and Reproducible Route to AMBER-FB15},
journal = {Journal of Physical Chemistry B}, journal = {Journal of Physical Chemistry B},
volume = {0}, volume = {121},
number = {ja}, number = {16},
pages = {null}, pages = {4023-4039},
year = {2017}, year = {2017},
type = {Journal Article}, type = {Journal Article},
doi = {10.1021/acs.jpcb.7b02320}, doi = {10.1021/acs.jpcb.7b02320},
......
...@@ -1158,6 +1158,21 @@ specified in three ways: ...@@ -1158,6 +1158,21 @@ specified in three ways:
* Per-donor parameters are defined by specifying a value for each donor group. * Per-donor parameters are defined by specifying a value for each donor group.
* Per-acceptor parameters are defined by specifying a value for each acceptor group. * Per-acceptor parameters are defined by specifying a value for each acceptor group.
CustomCVForce
*************
CustomCVForce computes an energy as a function of "collective variables". A
collective variable may be any scalar valued function of the particle positions
and other parameters. Each one is defined by a :code:`Force` object, so any
function that can be defined via any force class (either standard or custom) can
be used as a collective variable. The energy is then computed as
.. math::
E=f(...)
where *f*\ (...) is a user supplied mathematical expression of the collective
variables. It also may depend on user defined global parameters.
.. _writing-custom-expressions: .. _writing-custom-expressions:
...@@ -1557,17 +1572,18 @@ specific types of rules. They are: ...@@ -1557,17 +1572,18 @@ specific types of rules. They are:
:math:`\mathbf{r}_{13} = \mathbf{r}_{3}-\mathbf{r}_{1}`\ . This allows :math:`\mathbf{r}_{13} = \mathbf{r}_{3}-\mathbf{r}_{1}`\ . This allows
the virtual site to be located outside the plane of the three particles. the virtual site to be located outside the plane of the three particles.
* LocalCoordinatesSite: The locations of three other particles are used to compute a local * LocalCoordinatesSite: The locations of several other particles are used to compute a local
coordinate system, and the virtual site is placed at a fixed location in that coordinate coordinate system, and the virtual site is placed at a fixed location in that coordinate
system. The origin of the coordinate system and the directions of its x and y axes system. The number of particles used to define the coordinate system is user defined.
are each specified as a weighted sum of the locations of the three particles: The origin of the coordinate system and the directions of its x and y axes
are each specified as a weighted sum of the locations of the other particles:
.. math:: .. math::
\mathbf{o}={w}^{o}_{1}\mathbf{r}_{1} + {w}^{o}_{2}\mathbf{r}_{2} + {w}^{o}_{3}\mathbf{r}_{3} \mathbf{o}={w}^{o}_{1}\mathbf{r}_{1} + {w}^{o}_{2}\mathbf{r}_{2} + ...
\mathbf{dx}={w}^{x}_{1}\mathbf{r}_{1} + {w}^{x}_{2}\mathbf{r}_{2} + {w}^{x}_{3}\mathbf{r}_{3} \mathbf{dx}={w}^{x}_{1}\mathbf{r}_{1} + {w}^{x}_{2}\mathbf{r}_{2} + ...
\mathbf{dy}={w}^{y}_{1}\mathbf{r}_{1} + {w}^{y}_{2}\mathbf{r}_{2} + {w}^{y}_{3}\mathbf{r}_{3} \mathbf{dy}={w}^{y}_{1}\mathbf{r}_{1} + {w}^{y}_{2}\mathbf{r}_{2} + ...
\mathbf{dz}=\mathbf{dx}\times \mathbf{dy} \mathbf{dz}=\mathbf{dx}\times \mathbf{dy}
.. ..
......
...@@ -127,6 +127,14 @@ public: ...@@ -127,6 +127,14 @@ public:
* @param properties a set of values for platform-specific properties. Keys are the property names. * @param properties a set of values for platform-specific properties. Keys are the property names.
*/ */
virtual void contextCreated(ContextImpl& context, const std::map<std::string, std::string>& properties) const; virtual void contextCreated(ContextImpl& context, const std::map<std::string, std::string>& properties) const;
/**
* This is called whenever a new Context is created using ContextImpl::createLinkedContext(). It gives the
* Platform a chance to initialize the context and store platform-specific data in it.
*
* @param context the newly created context
* @param originalContext the original context it is linked to
*/
virtual void linkedContextCreated(ContextImpl& context, ContextImpl& originalContext) const;
/** /**
* This is called whenever a Context is deleted. It gives the Platform a chance to clean up * This is called whenever a Context is deleted. It gives the Platform a chance to clean up
* any platform-specific data that was stored in it. * any platform-specific data that was stored in it.
......
...@@ -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,43 @@ public: ...@@ -943,6 +944,43 @@ 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
* @param innerContext the context created by the CustomCVForce for computing collective variables
*/
virtual void initialize(const System& system, const CustomCVForce& force, ContextImpl& innerContext) = 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.
*/ */
...@@ -1295,8 +1333,9 @@ public: ...@@ -1295,8 +1333,9 @@ public:
* @param gridz the z size of the PME grid * @param gridz the z size of the PME grid
* @param numParticles the number of particles in the system * @param numParticles the number of particles in the system
* @param alpha the Ewald blending parameter * @param alpha the Ewald blending parameter
* @param deterministic whether it should attempt to make the resulting forces deterministic
*/ */
virtual void initialize(int gridx, int gridy, int gridz, int numParticles, double alpha) = 0; virtual void initialize(int gridx, int gridy, int gridz, int numParticles, double alpha, bool deterministic) = 0;
/** /**
* Begin computing the force and energy. * Begin computing the force and energy.
* *
...@@ -1368,8 +1407,9 @@ public: ...@@ -1368,8 +1407,9 @@ public:
* @param gridz the z size of the PME grid * @param gridz the z size of the PME grid
* @param numParticles the number of particles in the system * @param numParticles the number of particles in the system
* @param alpha the Ewald blending parameter * @param alpha the Ewald blending parameter
* @param deterministic whether it should attempt to make the resulting forces deterministic
*/ */
virtual void initialize(int gridx, int gridy, int gridz, int numParticles, double alpha) = 0; virtual void initialize(int gridx, int gridy, int gridz, int numParticles, double alpha, bool deterministic) = 0;
/** /**
* Begin computing the force and energy. * Begin computing the force and energy.
* *
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "openmm/OpenMMException.h" #include "openmm/OpenMMException.h"
#include "openmm/Kernel.h" #include "openmm/Kernel.h"
#include "openmm/KernelFactory.h" #include "openmm/KernelFactory.h"
#include "openmm/internal/ContextImpl.h"
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
#include <sstream> #include <sstream>
...@@ -113,6 +114,16 @@ void Platform::setPropertyDefaultValue(const string& property, const string& val ...@@ -113,6 +114,16 @@ void Platform::setPropertyDefaultValue(const string& property, const string& val
void Platform::contextCreated(ContextImpl& context, const map<string, string>& properties) const { void Platform::contextCreated(ContextImpl& context, const map<string, string>& properties) const {
} }
void Platform::linkedContextCreated(ContextImpl& context, ContextImpl& originalContext) const {
// The default implementation just copies over the properties and calls contextCreated().
// Subclasses may override this to do something different.
map<string, string> properties;
for (auto& name : getPropertyNames())
properties[name] = getPropertyValue(originalContext.getOwner(), name);
contextCreated(context, properties);
}
void Platform::contextDestroyed(ContextImpl& context) const { void Platform::contextDestroyed(ContextImpl& context) 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-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"
......
...@@ -263,8 +263,11 @@ public: ...@@ -263,8 +263,11 @@ public:
*/ */
const std::vector<std::vector<int> >& getMolecules() const; const std::vector<std::vector<int> >& getMolecules() const;
private: private:
friend class ContextImpl;
friend class Force; friend class Force;
friend class ForceImpl;
friend class Platform; friend class Platform;
Context(const System& system, Integrator& integrator, ContextImpl& linked);
ContextImpl& getImpl(); ContextImpl& getImpl();
const ContextImpl& getImpl() const; const ContextImpl& getImpl() const;
ContextImpl* impl; ContextImpl* impl;
......
#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 "Force.h"
#include "TabulatedFunction.h"
#include "internal/windowsExport.h"
#include <string>
#include <vector>
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);
/**
* Get the inner Context used for evaluating collective variables.
*
* When you create a Context for a System that contains a CustomCVForce, internally
* it creates a new System, adds the Forces that define the CVs to it, creates a new
* Context for that System, and uses it to evaluate the variables. In most cases you
* can ignore all of this. It is just an implementation detail. However, there are
* a few cases where you need to directly access that internal Context. For example,
* if you want to modify one of the Forces that defines a collective variable and
* call updateParametersInContext() on it, you need to pass that inner Context to it.
* This method returns a reference to it.
*
* @param context the Context containing the CustomCVForce
* @return the inner Context used to evaluate the collective variables
*/
Context& getInnerContext(Context& context);
/**
* 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_*/
...@@ -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) 2011-2016 Stanford University and the Authors. * * Portions copyright (c) 2011-2017 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "Integrator.h" #include "Integrator.h"
#include "TabulatedFunction.h"
#include "Vec3.h" #include "Vec3.h"
#include "openmm/Kernel.h" #include "openmm/Kernel.h"
#include "internal/windowsExport.h" #include "internal/windowsExport.h"
...@@ -241,6 +242,9 @@ namespace OpenMM { ...@@ -241,6 +242,9 @@ namespace OpenMM {
* 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.
* select(x,y,z) = z if x = 0, y otherwise. An expression may also involve intermediate quantities that are defined following the main expression, using ";" as a separator. * select(x,y,z) = z if x = 0, y otherwise. An expression may also involve intermediate quantities that are defined following the main expression, using ";" as a separator.
*
* 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 expressions.
*/ */
class OPENMM_EXPORT CustomIntegrator : public Integrator { class OPENMM_EXPORT CustomIntegrator : public Integrator {
...@@ -292,6 +296,7 @@ public: ...@@ -292,6 +296,7 @@ public:
* @param stepSize the step size with which to integrate the system (in picoseconds) * @param stepSize the step size with which to integrate the system (in picoseconds)
*/ */
CustomIntegrator(double stepSize); CustomIntegrator(double stepSize);
~CustomIntegrator();
/** /**
* Get the number of global variables that have been defined. * Get the number of global variables that have been defined.
*/ */
...@@ -310,6 +315,12 @@ public: ...@@ -310,6 +315,12 @@ public:
int getNumComputations() const { int getNumComputations() const {
return computations.size(); return computations.size();
} }
/**
* Get the number of tabulated functions that have been defined.
*/
int getNumTabulatedFunctions() const {
return functions.size();
}
/** /**
* Define a new global variable. * Define a new global variable.
* *
...@@ -495,6 +506,37 @@ public: ...@@ -495,6 +506,37 @@ public:
* will be an empty string. * will be an empty string.
*/ */
void getComputationStep(int index, ComputationType& type, std::string& variable, std::string& expression) const; void getComputationStep(int index, ComputationType& type, std::string& variable, std::string& expression) const;
/**
* Add a tabulated function that may appear in expressions.
*
* @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
* integrator takes over ownership of it, and deletes it when the integrator 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 expressions.
*
* @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 expressions.
*
* @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 expressions.
*
* @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 expression to use for computing the kinetic energy. The expression is evaluated * Get the expression to use for computing the kinetic energy. The expression is evaluated
* for every degree of freedom. Those values are then added together, and the sum * for every degree of freedom. Those values are then added together, and the sum
...@@ -560,11 +602,13 @@ protected: ...@@ -560,11 +602,13 @@ protected:
double computeKineticEnergy(); double computeKineticEnergy();
private: private:
class ComputationInfo; class ComputationInfo;
class FunctionInfo;
std::vector<std::string> globalNames; std::vector<std::string> globalNames;
std::vector<std::string> perDofNames; std::vector<std::string> perDofNames;
mutable std::vector<double> globalValues; mutable std::vector<double> globalValues;
std::vector<std::vector<Vec3> > perDofValues; std::vector<std::vector<Vec3> > perDofValues;
std::vector<ComputationInfo> computations; std::vector<ComputationInfo> computations;
std::vector<FunctionInfo> functions;
std::string kineticEnergy; std::string kineticEnergy;
mutable bool globalsAreCurrent; mutable bool globalsAreCurrent;
int randomNumberSeed; int randomNumberSeed;
...@@ -587,6 +631,20 @@ public: ...@@ -587,6 +631,20 @@ public:
} }
}; };
/**
* This is an internal class used to record information about a tabulated function.
* @private
*/
class CustomIntegrator::FunctionInfo {
public:
std::string name;
TabulatedFunction* function;
FunctionInfo() {
}
FunctionInfo(const std::string& name, TabulatedFunction* function) : name(name), function(function) {
}
};
} // namespace OpenMM } // namespace OpenMM
#endif /*OPENMM_CUSTOMINTEGRATOR_H_*/ #endif /*OPENMM_CUSTOMINTEGRATOR_H_*/
...@@ -52,11 +52,11 @@ namespace OpenMM { ...@@ -52,11 +52,11 @@ namespace OpenMM {
* part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter(). * part of the system definition, while values of global parameters may be modified during a simulation by calling Context::setParameter().
* Finally, call addTorsion() once for each torsion. After an torsion has been added, you can modify its parameters by calling setTorsionParameters(). * Finally, call addTorsion() once for each torsion. After an torsion has been added, you can modify its parameters by calling setTorsionParameters().
* This will have no effect on Contexts that already exist unless you call updateParametersInContext(). * This will have no effect on Contexts that already exist unless you call updateParametersInContext().
* theta is guaranteed to be in the range [-pi,+pi] * Note that theta is guaranteed to be in the range [-pi,+pi], which may cause issues with force discontinuities if the energy function does not respect this domain.
* *
* As an example, the following code creates a CustomTorsionForce that implements a harmonic potential: * As an example, the following code creates a CustomTorsionForce that implements a periodic potential:
* *
* <tt>CustomTorsionForce* force = new CustomTorsionForce("0.5*k*(theta-theta0)^2");</tt> * <tt>CustomTorsionForce* force = new CustomTorsionForce("0.5*k*(1-cos(theta-theta0))");</tt>
* *
* This force depends on two parameters: the spring constant k and equilibrium angle theta0. The following code defines these parameters: * This force depends on two parameters: the spring constant k and equilibrium angle theta0. The following code defines these parameters:
* *
...@@ -65,6 +65,10 @@ namespace OpenMM { ...@@ -65,6 +65,10 @@ namespace OpenMM {
* force->addPerTorsionParameter("theta0"); * force->addPerTorsionParameter("theta0");
* </pre></tt> * </pre></tt>
* *
* If a harmonic restraint is desired, it is important to be careful of the domain for theta, using an idiom like this:
*
* <tt>CustomTorsionForce* force = new CustomTorsionForce("0.5*k*min(dtheta, 2*pi-dtheta)^2; dtheta = abs(theta-theta0); pi = 3.1415926535");</tt>
*
* This class also has the ability to compute derivatives of the potential energy with respect to global parameters. * 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 * 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. * computed. You can then query its value in a Context by calling getState() on it.
......
...@@ -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) 2012-2014 Stanford University and the Authors. * * Portions copyright (c) 2012-2017 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -168,21 +168,21 @@ private: ...@@ -168,21 +168,21 @@ private:
}; };
/** /**
* This is a VirtualSite that uses the locations of three other particles to compute a local * This is a VirtualSite that uses the locations of several other particles to compute a local
* coordinate system, then places the virtual site at a fixed location in that coordinate * coordinate system, then places the virtual site at a fixed location in that coordinate
* system. The origin of the coordinate system and the directions of its x and y axes * system. The origin of the coordinate system and the directions of its x and y axes
* are each specified as a weighted sum of the locations of the three particles: * are each specified as a weighted sum of the locations of the other particles:
* *
* origin = w<sup>o</sup><sub>1</sub>r<sub>1</sub> + w<sup>o</sup><sub>2</sub>r<sub>2</sub> + w<sup>o</sup><sub>3</sub>r<sub>3</sub> * origin = w<sup>o</sup><sub>1</sub>r<sub>1</sub> + w<sup>o</sup><sub>2</sub>r<sub>2</sub> + w<sup>o</sup><sub>3</sub>r<sub>3</sub> + ...
* *
* xdir = w<sup>x</sup><sub>1</sub>r<sub>1</sub> + w<sup>x</sup><sub>2</sub>r<sub>2</sub> + w<sup>x</sup><sub>3</sub>r<sub>3</sub> * xdir = w<sup>x</sup><sub>1</sub>r<sub>1</sub> + w<sup>x</sup><sub>2</sub>r<sub>2</sub> + w<sup>x</sup><sub>3</sub>r<sub>3</sub> + ...
* *
* ydir = w<sup>y</sup><sub>1</sub>r<sub>1</sub> + w<sup>y</sup><sub>2</sub>r<sub>2</sub> + w<sup>y</sup><sub>3</sub>r<sub>3</sub> * ydir = w<sup>y</sup><sub>1</sub>r<sub>1</sub> + w<sup>y</sup><sub>2</sub>r<sub>2</sub> + w<sup>y</sup><sub>3</sub>r<sub>3</sub> + ...
* *
* For the origin, the three weights must add to one. For example if * For the origin, the weights must add to one. For example if
* (w<sup>o</sup><sub>1</sub>, w<sup>o</sup><sub>2</sub>, w<sup>o</sup><sub>3</sub>) = (1.0, 0.0, 0.0), * (w<sup>o</sup><sub>1</sub>, w<sup>o</sup><sub>2</sub>, w<sup>o</sup><sub>3</sub>) = (1.0, 0.0, 0.0),
* the origin of the local coordinate system is at the location of particle 1. For xdir and ydir, * the origin of the local coordinate system is at the location of particle 1. For xdir and ydir,
* the weights must add to zero. For excample, if * the weights must add to zero. For example, if
* (w<sup>x</sup><sub>1</sub>, w<sup>x</sup><sub>2</sub>, w<sup>x</sup><sub>3</sub>) = (-1.0, 0.5, 0.5), * (w<sup>x</sup><sub>1</sub>, w<sup>x</sup><sub>2</sub>, w<sup>x</sup><sub>3</sub>) = (-1.0, 0.5, 0.5),
* the x axis points from particle 1 toward the midpoint between particles 2 and 3. * the x axis points from particle 1 toward the midpoint between particles 2 and 3.
* *
...@@ -197,6 +197,17 @@ public: ...@@ -197,6 +197,17 @@ public:
/** /**
* Create a new LocalCoordinatesSite virtual site. * Create a new LocalCoordinatesSite virtual site.
* *
* @param particles the indices of the particle the site depends on
* @param originWeights the weight factors for the particles when computing the origin location
* @param xWeights the weight factors for the particles when computing xdir
* @param yWeights the weight factors for the particles when computing ydir
* @param localPosition the position of the virtual site in the local coordinate system
*/
LocalCoordinatesSite(const std::vector<int>& particles, const std::vector<double>& originWeights, const std::vector<double>& xWeights, const std::vector<double>& yWeights, const Vec3& localPosition);
/**
* Create a new LocalCoordinatesSite virtual site. This constructor assumes the site depends on
* exactly three other particles.
*
* @param particle1 the index of the first particle * @param particle1 the index of the first particle
* @param particle2 the index of the second particle * @param particle2 the index of the second particle
* @param particle3 the index of the third particle * @param particle3 the index of the third particle
...@@ -207,23 +218,42 @@ public: ...@@ -207,23 +218,42 @@ public:
*/ */
LocalCoordinatesSite(int particle1, int particle2, int particle3, const Vec3& originWeights, const Vec3& xWeights, const Vec3& yWeights, const Vec3& localPosition); LocalCoordinatesSite(int particle1, int particle2, int particle3, const Vec3& originWeights, const Vec3& xWeights, const Vec3& yWeights, const Vec3& localPosition);
/** /**
* Get the weight factors for the three particles when computing the origin location. * Get the weight factors for the particles when computing the origin location.
*/
void getOriginWeights(std::vector<double>& weights) const;
/**
* Get the weight factors for the particles when computing the origin location.
* This version assumes the site depends on exactly three other particles, and
* throws an exception if that is not the case.
*/
Vec3 getOriginWeights() const;
/**
* Get the weight factors for the particles when computing xdir.
*/
void getXWeights(std::vector<double>& weights) const;
/**
* Get the weight factors for the particles when computing xdir.
* This version assumes the site depends on exactly three other particles, and
* throws an exception if that is not the case.
*/ */
const Vec3& getOriginWeights() const; Vec3 getXWeights() const;
/** /**
* Get the weight factors for the three particles when computing xdir. * Get the weight factors for the particles when computing ydir.
*/ */
const Vec3& getXWeights() const; void getYWeights(std::vector<double>& weights) const;
/** /**
* Get the weight factors for the three particles when computing ydir. * Get the weight factors for the particles when computing ydir.
* This version assumes the site depends on exactly three other particles, and
* throws an exception if that is not the case.
*/ */
const Vec3& getYWeights() const; Vec3 getYWeights() const;
/** /**
* Get the position of the virtual site in the local coordinate system. * Get the position of the virtual site in the local coordinate system.
*/ */
const Vec3& getLocalPosition() const; const Vec3& getLocalPosition() const;
private: private:
Vec3 originWeights, xWeights, yWeights, localPosition; std::vector<double> originWeights, xWeights, yWeights;
Vec3 localPosition;
}; };
} // namespace OpenMM } // namespace OpenMM
......
...@@ -52,7 +52,7 @@ public: ...@@ -52,7 +52,7 @@ public:
const AndersenThermostat& getOwner() const { const AndersenThermostat& getOwner() const {
return owner; return owner;
} }
void updateContextState(ContextImpl& context); void updateContextState(ContextImpl& context, bool& forcesInvalid);
double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) { double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups) {
// This force doesn't apply forces to particles. // This force doesn't apply forces to particles.
return 0.0; return 0.0;
......
...@@ -52,7 +52,7 @@ public: ...@@ -52,7 +52,7 @@ public:
const CMAPTorsionForce& getOwner() const { const CMAPTorsionForce& getOwner() const {
return owner; return owner;
} }
void updateContextState(ContextImpl& context) { void updateContextState(ContextImpl& context, bool& forcesInvalid) {
// This force field doesn't update the state directly. // This force field doesn't update the state directly.
} }
double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups); double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups);
......
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